s2n_drbg.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License").
  5. * You may not use this file except in compliance with the License.
  6. * A copy of the License is located at
  7. *
  8. * http://aws.amazon.com/apache2.0
  9. *
  10. * or in the "license" file accompanying this file. This file is distributed
  11. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  12. * express or implied. See the License for the specific language governing
  13. * permissions and limitations under the License.
  14. */
  15. #include "crypto/s2n_drbg.h"
  16. #include <openssl/evp.h>
  17. #include <sys/param.h>
  18. #include "utils/s2n_blob.h"
  19. #include "utils/s2n_random.h"
  20. #include "utils/s2n_safety.h"
  21. static bool ignore_prediction_resistance_for_testing = false;
  22. #define s2n_drbg_key_size(drgb) EVP_CIPHER_CTX_key_length((drbg)->ctx)
  23. #define s2n_drbg_seed_size(drgb) (S2N_DRBG_BLOCK_SIZE + s2n_drbg_key_size(drgb))
  24. /* This function is the same as s2n_increment_sequence_number
  25. but it does not check for overflow, since overflow is
  26. acceptable in DRBG */
  27. S2N_RESULT s2n_increment_drbg_counter(struct s2n_blob *counter)
  28. {
  29. for (uint32_t i = (uint32_t) counter->size; i > 0; i--) {
  30. counter->data[i - 1] += 1;
  31. if (counter->data[i - 1]) {
  32. break;
  33. }
  34. /* seq[i] wrapped, so let it carry */
  35. }
  36. return S2N_RESULT_OK;
  37. }
  38. static S2N_RESULT s2n_drbg_block_encrypt(EVP_CIPHER_CTX *ctx, uint8_t in[S2N_DRBG_BLOCK_SIZE], uint8_t out[S2N_DRBG_BLOCK_SIZE])
  39. {
  40. RESULT_ENSURE_REF(ctx);
  41. /* len is set by EVP_EncryptUpdate and checked post operation */
  42. int len = S2N_DRBG_BLOCK_SIZE;
  43. RESULT_GUARD_OSSL(EVP_EncryptUpdate(ctx, out, &len, in, S2N_DRBG_BLOCK_SIZE), S2N_ERR_DRBG);
  44. RESULT_ENSURE_EQ(len, S2N_DRBG_BLOCK_SIZE);
  45. return S2N_RESULT_OK;
  46. }
  47. static S2N_RESULT s2n_drbg_bits(struct s2n_drbg *drbg, struct s2n_blob *out)
  48. {
  49. RESULT_ENSURE_REF(drbg);
  50. RESULT_ENSURE_REF(drbg->ctx);
  51. RESULT_ENSURE_REF(out);
  52. struct s2n_blob value = { 0 };
  53. RESULT_GUARD_POSIX(s2n_blob_init(&value, drbg->v, sizeof(drbg->v)));
  54. uint32_t block_aligned_size = out->size - (out->size % S2N_DRBG_BLOCK_SIZE);
  55. /* Per NIST SP800-90A 10.2.1.2: */
  56. for (size_t i = 0; i < block_aligned_size; i += S2N_DRBG_BLOCK_SIZE) {
  57. RESULT_GUARD(s2n_increment_drbg_counter(&value));
  58. RESULT_GUARD(s2n_drbg_block_encrypt(drbg->ctx, drbg->v, out->data + i));
  59. drbg->bytes_used += S2N_DRBG_BLOCK_SIZE;
  60. }
  61. if (out->size <= block_aligned_size) {
  62. return S2N_RESULT_OK;
  63. }
  64. uint8_t spare_block[S2N_DRBG_BLOCK_SIZE];
  65. RESULT_GUARD(s2n_increment_drbg_counter(&value));
  66. RESULT_GUARD(s2n_drbg_block_encrypt(drbg->ctx, drbg->v, spare_block));
  67. drbg->bytes_used += S2N_DRBG_BLOCK_SIZE;
  68. RESULT_CHECKED_MEMCPY(out->data + block_aligned_size, spare_block, out->size - block_aligned_size);
  69. return S2N_RESULT_OK;
  70. }
  71. static S2N_RESULT s2n_drbg_update(struct s2n_drbg *drbg, struct s2n_blob *provided_data)
  72. {
  73. RESULT_ENSURE_REF(drbg);
  74. RESULT_ENSURE_REF(drbg->ctx);
  75. RESULT_ENSURE_REF(provided_data);
  76. RESULT_STACK_BLOB(temp_blob, s2n_drbg_seed_size(drgb), S2N_DRBG_MAX_SEED_SIZE);
  77. RESULT_ENSURE_EQ(provided_data->size, (uint32_t) s2n_drbg_seed_size(drbg));
  78. RESULT_GUARD(s2n_drbg_bits(drbg, &temp_blob));
  79. /* XOR in the provided data */
  80. for (uint32_t i = 0; i < provided_data->size; i++) {
  81. temp_blob.data[i] ^= provided_data->data[i];
  82. }
  83. /* Update the key and value */
  84. RESULT_GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, NULL, NULL, temp_blob.data, NULL), S2N_ERR_DRBG);
  85. RESULT_CHECKED_MEMCPY(drbg->v, temp_blob.data + s2n_drbg_key_size(drbg), S2N_DRBG_BLOCK_SIZE);
  86. return S2N_RESULT_OK;
  87. }
  88. static S2N_RESULT s2n_drbg_mix_in_entropy(struct s2n_drbg *drbg, struct s2n_blob *entropy, struct s2n_blob *ps)
  89. {
  90. RESULT_ENSURE_REF(drbg);
  91. RESULT_ENSURE_REF(drbg->ctx);
  92. RESULT_ENSURE_REF(entropy);
  93. RESULT_ENSURE_GTE(entropy->size, ps->size);
  94. for (uint32_t i = 0; i < ps->size; i++) {
  95. entropy->data[i] ^= ps->data[i];
  96. }
  97. RESULT_GUARD(s2n_drbg_update(drbg, entropy));
  98. return S2N_RESULT_OK;
  99. }
  100. static S2N_RESULT s2n_drbg_seed(struct s2n_drbg *drbg, struct s2n_blob *ps)
  101. {
  102. RESULT_STACK_BLOB(blob, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
  103. RESULT_GUARD(s2n_get_seed_entropy(&blob));
  104. RESULT_GUARD(s2n_drbg_mix_in_entropy(drbg, &blob, ps));
  105. drbg->bytes_used = 0;
  106. return S2N_RESULT_OK;
  107. }
  108. static S2N_RESULT s2n_drbg_mix(struct s2n_drbg *drbg, struct s2n_blob *ps)
  109. {
  110. if (s2n_unlikely(ignore_prediction_resistance_for_testing)) {
  111. RESULT_ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST);
  112. return S2N_RESULT_OK;
  113. }
  114. RESULT_STACK_BLOB(blob, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
  115. RESULT_GUARD(s2n_get_mix_entropy(&blob));
  116. RESULT_GUARD(s2n_drbg_mix_in_entropy(drbg, &blob, ps));
  117. drbg->mixes += 1;
  118. return S2N_RESULT_OK;
  119. }
  120. S2N_RESULT s2n_drbg_instantiate(struct s2n_drbg *drbg, struct s2n_blob *personalization_string, const s2n_drbg_mode mode)
  121. {
  122. RESULT_ENSURE_REF(drbg);
  123. RESULT_ENSURE_REF(personalization_string);
  124. drbg->ctx = EVP_CIPHER_CTX_new();
  125. RESULT_GUARD_PTR(drbg->ctx);
  126. RESULT_EVP_CTX_INIT(drbg->ctx);
  127. switch (mode) {
  128. case S2N_AES_128_CTR_NO_DF_PR:
  129. RESULT_GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, EVP_aes_128_ecb(), NULL, NULL, NULL), S2N_ERR_DRBG);
  130. break;
  131. case S2N_AES_256_CTR_NO_DF_PR:
  132. RESULT_GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, EVP_aes_256_ecb(), NULL, NULL, NULL), S2N_ERR_DRBG);
  133. break;
  134. default:
  135. RESULT_BAIL(S2N_ERR_DRBG);
  136. }
  137. RESULT_ENSURE_LTE(s2n_drbg_key_size(drbg), S2N_DRBG_MAX_KEY_SIZE);
  138. RESULT_ENSURE_LTE(s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
  139. static const uint8_t zero_key[S2N_DRBG_MAX_KEY_SIZE] = { 0 };
  140. /* Start off with zeroed data, per 10.2.1.3.1 item 4 and 5 */
  141. memset(drbg->v, 0, sizeof(drbg->v));
  142. RESULT_GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, NULL, NULL, zero_key, NULL), S2N_ERR_DRBG);
  143. /* Copy the personalization string */
  144. RESULT_STACK_BLOB(ps, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
  145. RESULT_GUARD_POSIX(s2n_blob_zero(&ps));
  146. RESULT_CHECKED_MEMCPY(ps.data, personalization_string->data, MIN(ps.size, personalization_string->size));
  147. /* Seed the DRBG */
  148. RESULT_GUARD(s2n_drbg_seed(drbg, &ps));
  149. return S2N_RESULT_OK;
  150. }
  151. S2N_RESULT s2n_drbg_generate(struct s2n_drbg *drbg, struct s2n_blob *blob)
  152. {
  153. RESULT_ENSURE_REF(drbg);
  154. RESULT_ENSURE_REF(drbg->ctx);
  155. RESULT_STACK_BLOB(zeros, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
  156. RESULT_ENSURE(blob->size <= S2N_DRBG_GENERATE_LIMIT, S2N_ERR_DRBG_REQUEST_SIZE);
  157. /* Mix in additional entropy for every randomness generation call. This
  158. * defense mechanism is referred to as "prediction resistance".
  159. * If we ever relax this defense, we must:
  160. * 1. Implement reseeding according to limit specified in
  161. * NIST SP800-90A 10.2.1 Table 3.
  162. * 2. Re-consider whether the current fork detection strategy is still
  163. * sufficient.
  164. */
  165. RESULT_GUARD(s2n_drbg_mix(drbg, &zeros));
  166. RESULT_GUARD(s2n_drbg_bits(drbg, blob));
  167. RESULT_GUARD(s2n_drbg_update(drbg, &zeros));
  168. return S2N_RESULT_OK;
  169. }
  170. S2N_RESULT s2n_drbg_wipe(struct s2n_drbg *drbg)
  171. {
  172. RESULT_ENSURE_REF(drbg);
  173. if (drbg->ctx) {
  174. RESULT_GUARD_OSSL(EVP_CIPHER_CTX_cleanup(drbg->ctx), S2N_ERR_DRBG);
  175. EVP_CIPHER_CTX_free(drbg->ctx);
  176. drbg->ctx = NULL;
  177. }
  178. *drbg = (struct s2n_drbg){ 0 };
  179. return S2N_RESULT_OK;
  180. }
  181. S2N_RESULT s2n_drbg_bytes_used(struct s2n_drbg *drbg, uint64_t *bytes_used)
  182. {
  183. RESULT_ENSURE_REF(drbg);
  184. RESULT_ENSURE_REF(bytes_used);
  185. *bytes_used = drbg->bytes_used;
  186. return S2N_RESULT_OK;
  187. }
  188. S2N_RESULT s2n_ignore_prediction_resistance_for_testing(bool ignore_bool)
  189. {
  190. RESULT_ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST);
  191. ignore_prediction_resistance_for_testing = ignore_bool;
  192. return S2N_RESULT_OK;
  193. }