blob: bdf3dca59a1931864917ba03af65c9c139ce658b [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Gilles Peskineef0624f2018-08-03 20:23:09 +02002#include "mbedtls/entropy.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00003#include "mbedtls/ctr_drbg.h"
Mohammad Azim Khan67735d52017-04-06 11:55:43 +01004#include "string.h"
Rich Evans00ab4702015-02-06 13:43:58 +00005
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +02006/* Modes for ctr_drbg_validate */
Gilles Peskine449bd832023-01-11 14:50:10 +01007enum reseed_mode {
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +02008 RESEED_NEVER, /* never reseed */
9 RESEED_FIRST, /* instantiate, reseed, generate, generate */
10 RESEED_SECOND, /* instantiate, generate, reseed, generate */
11 RESEED_ALWAYS /* prediction resistance, no explicit reseed */
12};
13
Nir Sonnenschein85fcb582018-08-29 23:38:57 +030014static size_t test_offset_idx = 0;
15static size_t test_max_idx = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +010016static int mbedtls_test_entropy_func(void *data, unsigned char *buf, size_t len)
Paul Bakker0e04d0e2011-11-27 14:46:59 +000017{
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +010018 const unsigned char *p = (unsigned char *) data;
Gilles Peskine449bd832023-01-11 14:50:10 +010019 if (test_offset_idx + len > test_max_idx) {
20 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
21 }
22 memcpy(buf, p + test_offset_idx, len);
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +010023 test_offset_idx += len;
Gilles Peskine449bd832023-01-11 14:50:10 +010024 return 0;
Paul Bakker0e04d0e2011-11-27 14:46:59 +000025}
Nir Sonnenschein6275be32018-08-29 10:25:30 +030026
Gilles Peskine449bd832023-01-11 14:50:10 +010027static void ctr_drbg_validate_internal(int reseed_mode, data_t *nonce,
28 int entropy_len_arg, data_t *entropy,
29 data_t *reseed,
30 data_t *add1, data_t *add2,
31 data_t *result)
Nir Sonnenschein6275be32018-08-29 10:25:30 +030032{
33 mbedtls_ctr_drbg_context ctx;
Gilles Peskine21e46b32023-10-17 16:35:20 +020034 mbedtls_ctr_drbg_init(&ctx);
Nir Sonnenschein6275be32018-08-29 10:25:30 +030035 unsigned char buf[64];
36
37 size_t entropy_chunk_len = (size_t) entropy_len_arg;
Gilles Peskine449bd832023-01-11 14:50:10 +010038 TEST_ASSERT(entropy_chunk_len <= sizeof(buf));
Nir Sonnenschein85fcb582018-08-29 23:38:57 +030039
Nir Sonnenschein6275be32018-08-29 10:25:30 +030040 test_offset_idx = 0;
Nir Sonnenschein6275be32018-08-29 10:25:30 +030041 test_max_idx = entropy->len;
42
Nir Sonnenschein85fcb582018-08-29 23:38:57 +030043 /* CTR_DRBG_Instantiate(entropy[:entropy->len], nonce, perso, <ignored>)
44 * where nonce||perso = nonce[nonce->len] */
Gilles Peskine449bd832023-01-11 14:50:10 +010045 mbedtls_ctr_drbg_set_entropy_len(&ctx, entropy_chunk_len);
46 mbedtls_ctr_drbg_set_nonce_len(&ctx, 0);
47 TEST_ASSERT(mbedtls_ctr_drbg_seed(
48 &ctx,
49 mbedtls_test_entropy_func, entropy->x,
50 nonce->x, nonce->len) == 0);
51 if (reseed_mode == RESEED_ALWAYS) {
Nir Sonnenschein6275be32018-08-29 10:25:30 +030052 mbedtls_ctr_drbg_set_prediction_resistance(
53 &ctx,
Gilles Peskine449bd832023-01-11 14:50:10 +010054 MBEDTLS_CTR_DRBG_PR_ON);
55 }
Nir Sonnenschein6275be32018-08-29 10:25:30 +030056
Gilles Peskine449bd832023-01-11 14:50:10 +010057 if (reseed_mode == RESEED_FIRST) {
Nir Sonnenschein85fcb582018-08-29 23:38:57 +030058 /* CTR_DRBG_Reseed(entropy[idx:idx+entropy->len],
59 * reseed[:reseed->len]) */
Gilles Peskine449bd832023-01-11 14:50:10 +010060 TEST_ASSERT(mbedtls_ctr_drbg_reseed(
61 &ctx,
62 reseed->x, reseed->len) == 0);
Nir Sonnenschein6275be32018-08-29 10:25:30 +030063 }
64
Nir Sonnenschein85fcb582018-08-29 23:38:57 +030065 /* CTR_DRBG_Generate(result->len * 8 bits, add1[:add1->len]) -> buf */
Nir Sonnenschein6275be32018-08-29 10:25:30 +030066 /* Then reseed if prediction resistance is enabled. */
Gilles Peskine449bd832023-01-11 14:50:10 +010067 TEST_ASSERT(mbedtls_ctr_drbg_random_with_add(
68 &ctx,
69 buf, result->len,
70 add1->x, add1->len) == 0);
Nir Sonnenschein6275be32018-08-29 10:25:30 +030071
72
Gilles Peskine449bd832023-01-11 14:50:10 +010073 if (reseed_mode == RESEED_SECOND) {
Nir Sonnenschein85fcb582018-08-29 23:38:57 +030074 /* CTR_DRBG_Reseed(entropy[idx:idx+entropy->len],
75 * reseed[:reseed->len]) */
Gilles Peskine449bd832023-01-11 14:50:10 +010076 TEST_ASSERT(mbedtls_ctr_drbg_reseed(
77 &ctx,
78 reseed->x, reseed->len) == 0);
Nir Sonnenschein6275be32018-08-29 10:25:30 +030079 }
80
81 /* CTR_DRBG_Generate(result->len * 8 bits, add2->x[:add2->len]) -> buf */
82 /* Then reseed if prediction resistance is enabled. */
Gilles Peskine449bd832023-01-11 14:50:10 +010083 TEST_ASSERT(mbedtls_ctr_drbg_random_with_add(
84 &ctx,
85 buf, result->len,
86 add2->x, add2->len) == 0);
87 TEST_ASSERT(memcmp(buf, result->x, result->len) == 0);
Nir Sonnenschein6275be32018-08-29 10:25:30 +030088
89exit:
Gilles Peskine449bd832023-01-11 14:50:10 +010090 mbedtls_ctr_drbg_free(&ctx);
Nir Sonnenschein6275be32018-08-29 10:25:30 +030091}
92
Janos Follatha16ee6b2023-10-04 19:05:26 +010093static const int thread_random_reps = 10;
94void *thread_random_function( void* ctx )
95{
96 unsigned char out[16];
97 memset(out, 0, sizeof(out));
98
99 for(int i = 0; i < thread_random_reps; i++) {
100 TEST_EQUAL(mbedtls_ctr_drbg_random_with_add((mbedtls_ctr_drbg_context*) ctx, out, sizeof(out), NULL, 0), 0);
101 }
102
103exit:
104 return NULL;
105}
Paul Bakker33b43f12013-08-20 11:48:36 +0200106/* END_HEADER */
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000107
Paul Bakker33b43f12013-08-20 11:48:36 +0200108/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109 * depends_on:MBEDTLS_CTR_DRBG_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200110 * END_DEPENDENCIES
111 */
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000112
Paul Bakker33b43f12013-08-20 11:48:36 +0200113/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100114void ctr_drbg_special_behaviours()
Paul Bakker185ccf72016-07-14 13:21:10 +0100115{
116 mbedtls_ctr_drbg_context ctx;
117 unsigned char output[512];
118 unsigned char additional[512];
119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 mbedtls_ctr_drbg_init(&ctx);
121 memset(output, 0, sizeof(output));
122 memset(additional, 0, sizeof(additional));
Paul Bakker185ccf72016-07-14 13:21:10 +0100123
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 TEST_ASSERT(mbedtls_ctr_drbg_random_with_add(&ctx,
125 output, MBEDTLS_CTR_DRBG_MAX_REQUEST + 1,
126 additional, 16) ==
127 MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG);
128 TEST_ASSERT(mbedtls_ctr_drbg_random_with_add(&ctx,
129 output, 16,
130 additional, MBEDTLS_CTR_DRBG_MAX_INPUT + 1) ==
131 MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG);
Paul Bakker185ccf72016-07-14 13:21:10 +0100132
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 TEST_ASSERT(mbedtls_ctr_drbg_reseed(&ctx, additional,
134 MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + 1) ==
135 MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG);
Andres Amaya Garcia6a543362017-01-17 23:04:22 +0000136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 mbedtls_ctr_drbg_set_entropy_len(&ctx, ~0);
138 TEST_ASSERT(mbedtls_ctr_drbg_reseed(&ctx, additional,
139 MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) ==
140 MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG);
Paul Bakker185ccf72016-07-14 13:21:10 +0100141exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100142 mbedtls_ctr_drbg_free(&ctx);
Paul Bakker185ccf72016-07-14 13:21:10 +0100143}
144/* END_CASE */
145
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +0200146
147/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100148void ctr_drbg_validate_no_reseed(data_t *add_init, data_t *entropy,
149 data_t *add1, data_t *add2,
150 data_t *result_string)
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +0200151{
Nir Sonnenscheinacedc912018-08-29 23:57:45 +0300152 data_t empty = { 0, 0 };
Valerio Settidc32ac22023-11-13 10:27:56 +0100153 AES_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 ctr_drbg_validate_internal(RESEED_NEVER, add_init,
155 entropy->len, entropy,
156 &empty, add1, add2,
157 result_string);
Valerio Settidc32ac22023-11-13 10:27:56 +0100158 AES_PSA_DONE();
Nir Sonnenschein85fcb582018-08-29 23:38:57 +0300159 goto exit; // goto is needed to avoid warning ( no test assertions in func)
Gilles Peskine5ef5a9a2018-08-03 20:27:50 +0200160}
161/* END_CASE */
162
163/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100164void ctr_drbg_validate_pr(data_t *add_init, data_t *entropy,
165 data_t *add1, data_t *add2,
166 data_t *result_string)
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000167{
Nir Sonnenscheinacedc912018-08-29 23:57:45 +0300168 data_t empty = { 0, 0 };
Valerio Settidc32ac22023-11-13 10:27:56 +0100169 AES_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 ctr_drbg_validate_internal(RESEED_ALWAYS, add_init,
171 entropy->len / 3, entropy,
172 &empty, add1, add2,
173 result_string);
Valerio Settidc32ac22023-11-13 10:27:56 +0100174 AES_PSA_DONE();
Nir Sonnenschein85fcb582018-08-29 23:38:57 +0300175 goto exit; // goto is needed to avoid warning ( no test assertions in func)
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000176}
Paul Bakker33b43f12013-08-20 11:48:36 +0200177/* END_CASE */
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000178
Paul Bakker33b43f12013-08-20 11:48:36 +0200179/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100180void ctr_drbg_validate_reseed_between(data_t *add_init, data_t *entropy,
181 data_t *add1, data_t *add_reseed,
182 data_t *add2, data_t *result_string)
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000183{
Valerio Settidc32ac22023-11-13 10:27:56 +0100184 AES_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 ctr_drbg_validate_internal(RESEED_SECOND, add_init,
186 entropy->len / 2, entropy,
187 add_reseed, add1, add2,
188 result_string);
Valerio Settidc32ac22023-11-13 10:27:56 +0100189 AES_PSA_DONE();
Nir Sonnenschein85fcb582018-08-29 23:38:57 +0300190 goto exit; // goto is needed to avoid warning ( no test assertions in func)
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000191}
Paul Bakker33b43f12013-08-20 11:48:36 +0200192/* END_CASE */
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100193
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100194/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100195void ctr_drbg_validate_reseed_first(data_t *add_init, data_t *entropy,
196 data_t *add1, data_t *add_reseed,
197 data_t *add2, data_t *result_string)
Nir Sonnenschein85fcb582018-08-29 23:38:57 +0300198{
Valerio Settidc32ac22023-11-13 10:27:56 +0100199 AES_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 ctr_drbg_validate_internal(RESEED_FIRST, add_init,
201 entropy->len / 2, entropy,
202 add_reseed, add1, add2,
203 result_string);
Valerio Settidc32ac22023-11-13 10:27:56 +0100204 AES_PSA_DONE();
Nir Sonnenschein85fcb582018-08-29 23:38:57 +0300205 goto exit; // goto is needed to avoid warning ( no test assertions in func)
206}
207/* END_CASE */
208
Gilles Peskine69971662019-10-23 19:39:36 +0200209/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100210void ctr_drbg_entropy_strength(int expected_bit_strength)
Gilles Peskine69971662019-10-23 19:39:36 +0200211{
212 unsigned char entropy[/*initial entropy*/ MBEDTLS_CTR_DRBG_ENTROPY_LEN +
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 /*nonce*/ MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN +
214 /*reseed*/ MBEDTLS_CTR_DRBG_ENTROPY_LEN];
Gilles Peskine69971662019-10-23 19:39:36 +0200215 mbedtls_ctr_drbg_context ctx;
216 size_t last_idx;
217 size_t byte_strength = expected_bit_strength / 8;
Nir Sonnenschein85fcb582018-08-29 23:38:57 +0300218
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 mbedtls_ctr_drbg_init(&ctx);
Valerio Settidc32ac22023-11-13 10:27:56 +0100220
221 AES_PSA_INIT();
Gilles Peskine69971662019-10-23 19:39:36 +0200222 test_offset_idx = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 test_max_idx = sizeof(entropy);
224 memset(entropy, 0, sizeof(entropy));
Gilles Peskine69971662019-10-23 19:39:36 +0200225
226 /* The initial seeding must grab at least byte_strength bytes of entropy
227 * for the entropy input and byte_strength/2 bytes for a nonce. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 TEST_ASSERT(mbedtls_ctr_drbg_seed(&ctx,
229 mbedtls_test_entropy_func, entropy,
230 NULL, 0) == 0);
231 TEST_ASSERT(test_offset_idx >= (byte_strength * 3 + 1) / 2);
Gilles Peskine69971662019-10-23 19:39:36 +0200232 last_idx = test_offset_idx;
233
234 /* A reseed must grab at least byte_strength bytes of entropy. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 TEST_ASSERT(mbedtls_ctr_drbg_reseed(&ctx, NULL, 0) == 0);
236 TEST_ASSERT(test_offset_idx - last_idx >= byte_strength);
Gilles Peskine69971662019-10-23 19:39:36 +0200237
238exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 mbedtls_ctr_drbg_free(&ctx);
Valerio Settidc32ac22023-11-13 10:27:56 +0100240 AES_PSA_DONE();
Gilles Peskine69971662019-10-23 19:39:36 +0200241}
242/* END_CASE */
Nir Sonnenschein85fcb582018-08-29 23:38:57 +0300243
244/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100245void ctr_drbg_entropy_usage(int entropy_nonce_len)
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100246{
247 unsigned char out[16];
248 unsigned char add[16];
249 unsigned char entropy[1024];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250 mbedtls_ctr_drbg_context ctx;
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100251 size_t i, reps = 10;
Gilles Peskine58b56ce2019-10-22 19:10:01 +0200252 size_t expected_idx = 0;
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100253
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 mbedtls_ctr_drbg_init(&ctx);
Valerio Settidc32ac22023-11-13 10:27:56 +0100255
256 AES_PSA_INIT();
257
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100258 test_offset_idx = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 test_max_idx = sizeof(entropy);
260 memset(entropy, 0, sizeof(entropy));
261 memset(out, 0, sizeof(out));
262 memset(add, 0, sizeof(add));
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100263
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 if (entropy_nonce_len >= 0) {
265 TEST_ASSERT(mbedtls_ctr_drbg_set_nonce_len(&ctx, entropy_nonce_len) == 0);
266 }
Gilles Peskinec949de02019-10-22 19:14:26 +0200267
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800268 /* Set reseed interval before seed */
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 mbedtls_ctr_drbg_set_reseed_interval(&ctx, 2 * reps);
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800270
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100271 /* Init must use entropy */
Gilles Peskine449bd832023-01-11 14:50:10 +0100272 TEST_ASSERT(mbedtls_ctr_drbg_seed(&ctx, mbedtls_test_entropy_func, entropy, NULL, 0) == 0);
Gilles Peskine58b56ce2019-10-22 19:10:01 +0200273 expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_LEN;
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 if (entropy_nonce_len >= 0) {
Gilles Peskinec949de02019-10-22 19:14:26 +0200275 expected_idx += entropy_nonce_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 } else {
Gilles Peskine69971662019-10-23 19:39:36 +0200277 expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN;
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 }
279 TEST_EQUAL(test_offset_idx, expected_idx);
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100280
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800281 /* By default, PR is off, and reseed interval was set to
282 * 2 * reps so the next few calls should not use entropy */
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 for (i = 0; i < reps; i++) {
284 TEST_ASSERT(mbedtls_ctr_drbg_random(&ctx, out, sizeof(out) - 4) == 0);
285 TEST_ASSERT(mbedtls_ctr_drbg_random_with_add(&ctx, out, sizeof(out) - 4,
286 add, sizeof(add)) == 0);
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100287 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 TEST_EQUAL(test_offset_idx, expected_idx);
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100289
290 /* While at it, make sure we didn't write past the requested length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 TEST_ASSERT(out[sizeof(out) - 4] == 0);
292 TEST_ASSERT(out[sizeof(out) - 3] == 0);
293 TEST_ASSERT(out[sizeof(out) - 2] == 0);
294 TEST_ASSERT(out[sizeof(out) - 1] == 0);
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100295
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800296 /* There have been 2 * reps calls to random. The next call should reseed */
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 TEST_ASSERT(mbedtls_ctr_drbg_random(&ctx, out, sizeof(out)) == 0);
Gilles Peskine58b56ce2019-10-22 19:10:01 +0200298 expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_LEN;
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 TEST_EQUAL(test_offset_idx, expected_idx);
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100300
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800301 /* Set reseed interval after seed */
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 mbedtls_ctr_drbg_set_reseed_interval(&ctx, 4 * reps + 1);
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800303
304 /* The next few calls should not reseed */
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 for (i = 0; i < (2 * reps); i++) {
306 TEST_ASSERT(mbedtls_ctr_drbg_random(&ctx, out, sizeof(out)) == 0);
307 TEST_ASSERT(mbedtls_ctr_drbg_random_with_add(&ctx, out, sizeof(out),
308 add, sizeof(add)) == 0);
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100309 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 TEST_EQUAL(test_offset_idx, expected_idx);
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100311
Dave Rodgman6dd757a2023-02-02 12:40:50 +0000312 /* Call update with too much data (sizeof(entropy) > MAX(_SEED)_INPUT).
Gilles Peskined9199932018-09-11 16:41:54 +0200313 * Make sure it's detected as an error and doesn't cause memory
314 * corruption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 TEST_ASSERT(mbedtls_ctr_drbg_update(
316 &ctx, entropy, sizeof(entropy)) != 0);
Manuel Pégourié-Gonnardf5f25b32014-11-27 14:04:56 +0100317
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100318 /* Now enable PR, so the next few calls should all reseed */
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_ON);
320 TEST_ASSERT(mbedtls_ctr_drbg_random(&ctx, out, sizeof(out)) == 0);
Gilles Peskine58b56ce2019-10-22 19:10:01 +0200321 expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_LEN;
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 TEST_EQUAL(test_offset_idx, expected_idx);
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100323
324 /* Finally, check setting entropy_len */
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 mbedtls_ctr_drbg_set_entropy_len(&ctx, 42);
326 TEST_ASSERT(mbedtls_ctr_drbg_random(&ctx, out, sizeof(out)) == 0);
Gilles Peskine58b56ce2019-10-22 19:10:01 +0200327 expected_idx += 42;
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 TEST_EQUAL(test_offset_idx, expected_idx);
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100329
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 mbedtls_ctr_drbg_set_entropy_len(&ctx, 13);
331 TEST_ASSERT(mbedtls_ctr_drbg_random(&ctx, out, sizeof(out)) == 0);
Gilles Peskine58b56ce2019-10-22 19:10:01 +0200332 expected_idx += 13;
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 TEST_EQUAL(test_offset_idx, expected_idx);
Paul Bakkera317a982014-06-18 16:44:11 +0200334
Paul Bakkerbd51b262014-07-10 15:26:12 +0200335exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 mbedtls_ctr_drbg_free(&ctx);
Valerio Settidc32ac22023-11-13 10:27:56 +0100337 AES_PSA_DONE();
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100338}
339/* END_CASE */
340
Janos Follatha16ee6b2023-10-04 19:05:26 +0100341/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD */
342void ctr_drbg_threads(data_t *expected_result, int reseed_interval)
343{
344#define THREAD_CNT 5
345 pthread_t threads[THREAD_CNT];
346
347 unsigned char out[16];
348 memset(out, 0, sizeof(out));
349
350 unsigned char entropy[1024];
351 memset(entropy, 0, sizeof(entropy));
352
353 test_offset_idx = 0;
354 test_max_idx = sizeof(entropy);
355
356 mbedtls_ctr_drbg_context ctx;
357 mbedtls_ctr_drbg_init(&ctx);
358
359 mbedtls_ctr_drbg_set_reseed_interval(&ctx, reseed_interval);
360
361 /* There are too many calls in this test to conveniently provide enough
362 * entropy for this to be on. Test cases can trigger reseeding by setting
363 * \p reseed_interval appropriately. */
364 mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_OFF);
365
366 TEST_EQUAL(
367 mbedtls_ctr_drbg_seed(&ctx, mbedtls_test_entropy_func, entropy, NULL, 0),
368 0);
369
370 for (size_t i = 0; i < THREAD_CNT; i++) {
371 TEST_EQUAL(
372 pthread_create(&threads[i], NULL,
373 thread_random_function, (void*) &ctx),
374 0);
375 }
376
377 for (size_t i = 0; i < THREAD_CNT; i++) {
378 TEST_EQUAL(pthread_join(threads[i], NULL), 0);
379 }
380
381 /* Take a last output for comparing and thus verifying the DRBG state */
382 TEST_EQUAL(mbedtls_ctr_drbg_random(&ctx, out, sizeof(out)), 0);
383
384 TEST_MEMORY_COMPARE(out, sizeof(out), expected_result->x, expected_result->len);
385
386exit:
387 mbedtls_ctr_drbg_free(&ctx);
388}
389#undef THREAD_CNT
390/* END_CASE */
391
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100393void ctr_drbg_seed_file(char *path, int ret)
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100394{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200395 mbedtls_ctr_drbg_context ctx;
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100396
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 mbedtls_ctr_drbg_init(&ctx);
Manuel Pégourié-Gonnard8d128ef2015-04-28 22:38:08 +0200398
Valerio Settidc32ac22023-11-13 10:27:56 +0100399 AES_PSA_INIT();
400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 TEST_ASSERT(mbedtls_ctr_drbg_seed(&ctx, mbedtls_test_rnd_std_rand,
402 NULL, NULL, 0) == 0);
403 TEST_ASSERT(mbedtls_ctr_drbg_write_seed_file(&ctx, path) == ret);
404 TEST_ASSERT(mbedtls_ctr_drbg_update_seed_file(&ctx, path) == ret);
Paul Bakkera317a982014-06-18 16:44:11 +0200405
Paul Bakkerbd51b262014-07-10 15:26:12 +0200406exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 mbedtls_ctr_drbg_free(&ctx);
Valerio Settidc32ac22023-11-13 10:27:56 +0100408 AES_PSA_DONE();
Manuel Pégourié-Gonnard7575daa2014-01-31 12:16:54 +0100409}
410/* END_CASE */
411
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200412/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +0100413void ctr_drbg_selftest()
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100414{
Valerio Settidc32ac22023-11-13 10:27:56 +0100415 AES_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 TEST_ASSERT(mbedtls_ctr_drbg_self_test(1) == 0);
Valerio Settidc32ac22023-11-13 10:27:56 +0100417 AES_PSA_DONE();
Manuel Pégourié-Gonnardb3b205e2014-01-31 12:04:06 +0100418}
419/* END_CASE */