1 /*
2 * CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 */
7 /*
8 * The NIST SP 800-90 DRBGs are described in the following publication.
9 *
10 * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-90r.pdf
11 */
12
13 #include "common.h"
14
15 #if defined(MBEDTLS_CTR_DRBG_C)
16
17 #include "mbedtls/ctr_drbg.h"
18 #include "mbedtls/platform_util.h"
19 #include "mbedtls/error.h"
20
21 #include <limits.h>
22 #include <string.h>
23
24 #if defined(MBEDTLS_FS_IO)
25 #include <stdio.h>
26 #endif
27
28 #include "mbedtls/platform.h"
29
30 /*
31 * CTR_DRBG context initialization
32 */
mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context * ctx)33 void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx)
34 {
35 memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context));
36 /* Indicate that the entropy nonce length is not set explicitly.
37 * See mbedtls_ctr_drbg_set_nonce_len(). */
38 ctx->reseed_counter = -1;
39
40 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
41 }
42
43 /*
44 * This function resets CTR_DRBG context to the state immediately
45 * after initial call of mbedtls_ctr_drbg_init().
46 */
mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context * ctx)47 void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx)
48 {
49 if (ctx == NULL) {
50 return;
51 }
52
53 #if defined(MBEDTLS_THREADING_C)
54 /* The mutex is initialized iff f_entropy is set. */
55 if (ctx->f_entropy != NULL) {
56 mbedtls_mutex_free(&ctx->mutex);
57 }
58 #endif
59 mbedtls_aes_free(&ctx->aes_ctx);
60 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context));
61 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
62 ctx->reseed_counter = -1;
63 }
64
mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context * ctx,int resistance)65 void mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context *ctx,
66 int resistance)
67 {
68 ctx->prediction_resistance = resistance;
69 }
70
mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context * ctx,size_t len)71 void mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context *ctx,
72 size_t len)
73 {
74 ctx->entropy_len = len;
75 }
76
mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context * ctx,size_t len)77 int mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context *ctx,
78 size_t len)
79 {
80 /* If mbedtls_ctr_drbg_seed() has already been called, it's
81 * too late. Return the error code that's closest to making sense. */
82 if (ctx->f_entropy != NULL) {
83 return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
84 }
85
86 if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
87 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
88 }
89 #if SIZE_MAX > INT_MAX
90 /* This shouldn't be an issue because
91 * MBEDTLS_CTR_DRBG_MAX_SEED_INPUT < INT_MAX in any sensible
92 * configuration, but make sure anyway. */
93 if (len > INT_MAX) {
94 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
95 }
96 #endif
97
98 /* For backward compatibility with Mbed TLS <= 2.19, store the
99 * entropy nonce length in a field that already exists, but isn't
100 * used until after the initial seeding. */
101 /* Due to the capping of len above, the value fits in an int. */
102 ctx->reseed_counter = (int) len;
103 return 0;
104 }
105
mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context * ctx,int interval)106 void mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context *ctx,
107 int interval)
108 {
109 ctx->reseed_interval = interval;
110 }
111
block_cipher_df(unsigned char * output,const unsigned char * data,size_t data_len)112 static int block_cipher_df(unsigned char *output,
113 const unsigned char *data, size_t data_len)
114 {
115 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
116 MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
117 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
118 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
119 unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
120 unsigned char *p, *iv;
121 mbedtls_aes_context aes_ctx;
122 int ret = 0;
123
124 int i, j;
125 size_t buf_len, use_len;
126
127 if (data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
128 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
129 }
130
131 memset(buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
132 MBEDTLS_CTR_DRBG_BLOCKSIZE + 16);
133 mbedtls_aes_init(&aes_ctx);
134
135 /*
136 * Construct IV (16 bytes) and S in buffer
137 * IV = Counter (in 32-bits) padded to 16 with zeroes
138 * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
139 * data || 0x80
140 * (Total is padded to a multiple of 16-bytes with zeroes)
141 */
142 p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
143 MBEDTLS_PUT_UINT32_BE(data_len, p, 0);
144 p += 4 + 3;
145 *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
146 memcpy(p, data, data_len);
147 p[data_len] = 0x80;
148
149 buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
150
151 for (i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++) {
152 key[i] = i;
153 }
154
155 if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key,
156 MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
157 goto exit;
158 }
159
160 /*
161 * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
162 */
163 for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
164 p = buf;
165 memset(chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE);
166 use_len = buf_len;
167
168 while (use_len > 0) {
169 for (i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++) {
170 chain[i] ^= p[i];
171 }
172 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
173 use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ?
174 MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
175
176 if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
177 chain, chain)) != 0) {
178 goto exit;
179 }
180 }
181
182 memcpy(tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE);
183
184 /*
185 * Update IV
186 */
187 buf[3]++;
188 }
189
190 /*
191 * Do final encryption with reduced data
192 */
193 if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
194 MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
195 goto exit;
196 }
197 iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
198 p = output;
199
200 for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
201 if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
202 iv, iv)) != 0) {
203 goto exit;
204 }
205 memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE);
206 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
207 }
208 exit:
209 mbedtls_aes_free(&aes_ctx);
210 /*
211 * tidy up the stack
212 */
213 mbedtls_platform_zeroize(buf, sizeof(buf));
214 mbedtls_platform_zeroize(tmp, sizeof(tmp));
215 mbedtls_platform_zeroize(key, sizeof(key));
216 mbedtls_platform_zeroize(chain, sizeof(chain));
217 if (0 != ret) {
218 /*
219 * wipe partial seed from memory
220 */
221 mbedtls_platform_zeroize(output, MBEDTLS_CTR_DRBG_SEEDLEN);
222 }
223
224 return ret;
225 }
226
227 /* CTR_DRBG_Update (SP 800-90A §10.2.1.2)
228 * ctr_drbg_update_internal(ctx, provided_data)
229 * implements
230 * CTR_DRBG_Update(provided_data, Key, V)
231 * with inputs and outputs
232 * ctx->aes_ctx = Key
233 * ctx->counter = V
234 */
ctr_drbg_update_internal(mbedtls_ctr_drbg_context * ctx,const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN])235 static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
236 const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN])
237 {
238 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
239 unsigned char *p = tmp;
240 int i, j;
241 int ret = 0;
242
243 memset(tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
244
245 for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
246 /*
247 * Increase counter
248 */
249 for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) {
250 if (++ctx->counter[i - 1] != 0) {
251 break;
252 }
253 }
254
255 /*
256 * Crypt counter block
257 */
258 if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
259 ctx->counter, p)) != 0) {
260 goto exit;
261 }
262
263 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
264 }
265
266 for (i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++) {
267 tmp[i] ^= data[i];
268 }
269
270 /*
271 * Update key and counter
272 */
273 if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
274 MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
275 goto exit;
276 }
277 memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
278 MBEDTLS_CTR_DRBG_BLOCKSIZE);
279
280 exit:
281 mbedtls_platform_zeroize(tmp, sizeof(tmp));
282 return ret;
283 }
284
285 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2)
286 * mbedtls_ctr_drbg_update(ctx, additional, add_len)
287 * implements
288 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
289 * security_strength) -> initial_working_state
290 * with inputs
291 * ctx->counter = all-bits-0
292 * ctx->aes_ctx = context from all-bits-0 key
293 * additional[:add_len] = entropy_input || nonce || personalization_string
294 * and with outputs
295 * ctx = initial_working_state
296 */
mbedtls_ctr_drbg_update_ret(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t add_len)297 int mbedtls_ctr_drbg_update_ret(mbedtls_ctr_drbg_context *ctx,
298 const unsigned char *additional,
299 size_t add_len)
300 {
301 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
302 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
303
304 if (add_len == 0) {
305 return 0;
306 }
307
308 if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) {
309 goto exit;
310 }
311 if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
312 goto exit;
313 }
314
315 exit:
316 mbedtls_platform_zeroize(add_input, sizeof(add_input));
317 return ret;
318 }
319
320 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t add_len)321 void mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context *ctx,
322 const unsigned char *additional,
323 size_t add_len)
324 {
325 /* MAX_INPUT would be more logical here, but we have to match
326 * block_cipher_df()'s limits since we can't propagate errors */
327 if (add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
328 add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
329 }
330 (void) mbedtls_ctr_drbg_update_ret(ctx, additional, add_len);
331 }
332 #endif /* MBEDTLS_DEPRECATED_REMOVED */
333
334 /* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2)
335 * mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len)
336 * implements
337 * CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
338 * -> new_working_state
339 * with inputs
340 * ctx contains working_state
341 * additional[:len] = additional_input
342 * and entropy_input comes from calling ctx->f_entropy
343 * for (ctx->entropy_len + nonce_len) bytes
344 * and with output
345 * ctx contains new_working_state
346 */
mbedtls_ctr_drbg_reseed_internal(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t len,size_t nonce_len)347 static int mbedtls_ctr_drbg_reseed_internal(mbedtls_ctr_drbg_context *ctx,
348 const unsigned char *additional,
349 size_t len,
350 size_t nonce_len)
351 {
352 unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
353 size_t seedlen = 0;
354 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
355
356 if (ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
357 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
358 }
359 if (nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len) {
360 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
361 }
362 if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len) {
363 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
364 }
365
366 memset(seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT);
367
368 /* Gather entropy_len bytes of entropy to seed state. */
369 if (0 != ctx->f_entropy(ctx->p_entropy, seed, ctx->entropy_len)) {
370 return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
371 }
372 seedlen += ctx->entropy_len;
373
374 /* Gather entropy for a nonce if requested. */
375 if (nonce_len != 0) {
376 if (0 != ctx->f_entropy(ctx->p_entropy, seed + seedlen, nonce_len)) {
377 return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
378 }
379 seedlen += nonce_len;
380 }
381
382 /* Add additional data if provided. */
383 if (additional != NULL && len != 0) {
384 memcpy(seed + seedlen, additional, len);
385 seedlen += len;
386 }
387
388 /* Reduce to 384 bits. */
389 if ((ret = block_cipher_df(seed, seed, seedlen)) != 0) {
390 goto exit;
391 }
392
393 /* Update state. */
394 if ((ret = ctr_drbg_update_internal(ctx, seed)) != 0) {
395 goto exit;
396 }
397 ctx->reseed_counter = 1;
398
399 exit:
400 mbedtls_platform_zeroize(seed, sizeof(seed));
401 return ret;
402 }
403
mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t len)404 int mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context *ctx,
405 const unsigned char *additional, size_t len)
406 {
407 return mbedtls_ctr_drbg_reseed_internal(ctx, additional, len, 0);
408 }
409
410 /* Return a "good" nonce length for CTR_DRBG. The chosen nonce length
411 * is sufficient to achieve the maximum security strength given the key
412 * size and entropy length. If there is enough entropy in the initial
413 * call to the entropy function to serve as both the entropy input and
414 * the nonce, don't make a second call to get a nonce. */
good_nonce_len(size_t entropy_len)415 static size_t good_nonce_len(size_t entropy_len)
416 {
417 if (entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2) {
418 return 0;
419 } else {
420 return (entropy_len + 1) / 2;
421 }
422 }
423
424 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2)
425 * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
426 * implements
427 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
428 * security_strength) -> initial_working_state
429 * with inputs
430 * custom[:len] = nonce || personalization_string
431 * where entropy_input comes from f_entropy for ctx->entropy_len bytes
432 * and with outputs
433 * ctx = initial_working_state
434 */
mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context * ctx,int (* f_entropy)(void *,unsigned char *,size_t),void * p_entropy,const unsigned char * custom,size_t len)435 int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx,
436 int (*f_entropy)(void *, unsigned char *, size_t),
437 void *p_entropy,
438 const unsigned char *custom,
439 size_t len)
440 {
441 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
442 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
443 size_t nonce_len;
444
445 memset(key, 0, MBEDTLS_CTR_DRBG_KEYSIZE);
446
447 /* The mutex is initialized iff f_entropy is set. */
448 #if defined(MBEDTLS_THREADING_C)
449 mbedtls_mutex_init(&ctx->mutex);
450 #endif
451
452 mbedtls_aes_init(&ctx->aes_ctx);
453
454 ctx->f_entropy = f_entropy;
455 ctx->p_entropy = p_entropy;
456
457 if (ctx->entropy_len == 0) {
458 ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
459 }
460 /* ctx->reseed_counter contains the desired amount of entropy to
461 * grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()).
462 * If it's -1, indicating that the entropy nonce length was not set
463 * explicitly, use a sufficiently large nonce for security. */
464 nonce_len = (ctx->reseed_counter >= 0 ?
465 (size_t) ctx->reseed_counter :
466 good_nonce_len(ctx->entropy_len));
467
468 /* Initialize with an empty key. */
469 if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
470 MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
471 return ret;
472 }
473
474 /* Do the initial seeding. */
475 if ((ret = mbedtls_ctr_drbg_reseed_internal(ctx, custom, len,
476 nonce_len)) != 0) {
477 return ret;
478 }
479 return 0;
480 }
481
482 /* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2)
483 * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
484 * implements
485 * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len])
486 * -> working_state_after_reseed
487 * if required, then
488 * CTR_DRBG_Generate(working_state_after_reseed,
489 * requested_number_of_bits, additional_input)
490 * -> status, returned_bits, new_working_state
491 * with inputs
492 * ctx contains working_state
493 * requested_number_of_bits = 8 * output_len
494 * additional[:add_len] = additional_input
495 * and entropy_input comes from calling ctx->f_entropy
496 * and with outputs
497 * status = SUCCESS (this function does the reseed internally)
498 * returned_bits = output[:output_len]
499 * ctx contains new_working_state
500 */
mbedtls_ctr_drbg_random_with_add(void * p_rng,unsigned char * output,size_t output_len,const unsigned char * additional,size_t add_len)501 int mbedtls_ctr_drbg_random_with_add(void *p_rng,
502 unsigned char *output, size_t output_len,
503 const unsigned char *additional, size_t add_len)
504 {
505 int ret = 0;
506 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
507 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
508 unsigned char *p = output;
509 unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
510 int i;
511 size_t use_len;
512
513 if (output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST) {
514 return MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG;
515 }
516
517 if (add_len > MBEDTLS_CTR_DRBG_MAX_INPUT) {
518 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
519 }
520
521 memset(add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
522
523 if (ctx->reseed_counter > ctx->reseed_interval ||
524 ctx->prediction_resistance) {
525 if ((ret = mbedtls_ctr_drbg_reseed(ctx, additional, add_len)) != 0) {
526 return ret;
527 }
528 add_len = 0;
529 }
530
531 if (add_len > 0) {
532 if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) {
533 goto exit;
534 }
535 if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
536 goto exit;
537 }
538 }
539
540 while (output_len > 0) {
541 /*
542 * Increase counter
543 */
544 for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) {
545 if (++ctx->counter[i - 1] != 0) {
546 break;
547 }
548 }
549
550 /*
551 * Crypt counter block
552 */
553 if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
554 ctx->counter, tmp)) != 0) {
555 goto exit;
556 }
557
558 use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE)
559 ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
560 /*
561 * Copy random block to destination
562 */
563 memcpy(p, tmp, use_len);
564 p += use_len;
565 output_len -= use_len;
566 }
567
568 if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
569 goto exit;
570 }
571
572 ctx->reseed_counter++;
573
574 exit:
575 mbedtls_platform_zeroize(add_input, sizeof(add_input));
576 mbedtls_platform_zeroize(tmp, sizeof(tmp));
577 return ret;
578 }
579
mbedtls_ctr_drbg_random(void * p_rng,unsigned char * output,size_t output_len)580 int mbedtls_ctr_drbg_random(void *p_rng, unsigned char *output,
581 size_t output_len)
582 {
583 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
584 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
585
586 #if defined(MBEDTLS_THREADING_C)
587 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
588 return ret;
589 }
590 #endif
591
592 ret = mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, NULL, 0);
593
594 #if defined(MBEDTLS_THREADING_C)
595 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
596 return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
597 }
598 #endif
599
600 return ret;
601 }
602
603 #if defined(MBEDTLS_FS_IO)
mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context * ctx,const char * path)604 int mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context *ctx,
605 const char *path)
606 {
607 int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
608 FILE *f;
609 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT];
610
611 if ((f = fopen(path, "wb")) == NULL) {
612 return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
613 }
614
615 if ((ret = mbedtls_ctr_drbg_random(ctx, buf,
616 MBEDTLS_CTR_DRBG_MAX_INPUT)) != 0) {
617 goto exit;
618 }
619
620 if (fwrite(buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f) !=
621 MBEDTLS_CTR_DRBG_MAX_INPUT) {
622 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
623 } else {
624 ret = 0;
625 }
626
627 exit:
628 mbedtls_platform_zeroize(buf, sizeof(buf));
629
630 fclose(f);
631 return ret;
632 }
633
mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context * ctx,const char * path)634 int mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context *ctx,
635 const char *path)
636 {
637 int ret = 0;
638 FILE *f = NULL;
639 size_t n;
640 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT];
641 unsigned char c;
642
643 if ((f = fopen(path, "rb")) == NULL) {
644 return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
645 }
646
647 n = fread(buf, 1, sizeof(buf), f);
648 if (fread(&c, 1, 1, f) != 0) {
649 ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
650 goto exit;
651 }
652 if (n == 0 || ferror(f)) {
653 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
654 goto exit;
655 }
656 fclose(f);
657 f = NULL;
658
659 ret = mbedtls_ctr_drbg_update_ret(ctx, buf, n);
660
661 exit:
662 mbedtls_platform_zeroize(buf, sizeof(buf));
663 if (f != NULL) {
664 fclose(f);
665 }
666 if (ret != 0) {
667 return ret;
668 }
669 return mbedtls_ctr_drbg_write_seed_file(ctx, path);
670 }
671 #endif /* MBEDTLS_FS_IO */
672
673 #if defined(MBEDTLS_SELF_TEST)
674
675 /* The CTR_DRBG NIST test vectors used here are available at
676 * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip
677 *
678 * The parameters used to derive the test data are:
679 *
680 * [AES-128 use df]
681 * [PredictionResistance = True/False]
682 * [EntropyInputLen = 128]
683 * [NonceLen = 64]
684 * [PersonalizationStringLen = 128]
685 * [AdditionalInputLen = 0]
686 * [ReturnedBitsLen = 512]
687 *
688 * [AES-256 use df]
689 * [PredictionResistance = True/False]
690 * [EntropyInputLen = 256]
691 * [NonceLen = 128]
692 * [PersonalizationStringLen = 256]
693 * [AdditionalInputLen = 0]
694 * [ReturnedBitsLen = 512]
695 *
696 */
697
698 #if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
699 static const unsigned char entropy_source_pr[] =
700 { 0x04, 0xd9, 0x49, 0xa6, 0xdc, 0xe8, 0x6e, 0xbb,
701 0xf1, 0x08, 0x77, 0x2b, 0x9e, 0x08, 0xca, 0x92,
702 0x65, 0x16, 0xda, 0x99, 0xa2, 0x59, 0xf3, 0xe8,
703 0x38, 0x7e, 0x3f, 0x6b, 0x51, 0x70, 0x7b, 0x20,
704 0xec, 0x53, 0xd0, 0x66, 0xc3, 0x0f, 0xe3, 0xb0,
705 0xe0, 0x86, 0xa6, 0xaa, 0x5f, 0x72, 0x2f, 0xad,
706 0xf7, 0xef, 0x06, 0xb8, 0xd6, 0x9c, 0x9d, 0xe8 };
707
708 static const unsigned char entropy_source_nopr[] =
709 { 0x07, 0x0d, 0x59, 0x63, 0x98, 0x73, 0xa5, 0x45,
710 0x27, 0x38, 0x22, 0x7b, 0x76, 0x85, 0xd1, 0xa9,
711 0x74, 0x18, 0x1f, 0x3c, 0x22, 0xf6, 0x49, 0x20,
712 0x4a, 0x47, 0xc2, 0xf3, 0x85, 0x16, 0xb4, 0x6f,
713 0x00, 0x2e, 0x71, 0xda, 0xed, 0x16, 0x9b, 0x5c };
714
715 static const unsigned char pers_pr[] =
716 { 0xbf, 0xa4, 0x9a, 0x8f, 0x7b, 0xd8, 0xb1, 0x7a,
717 0x9d, 0xfa, 0x45, 0xed, 0x21, 0x52, 0xb3, 0xad };
718
719 static const unsigned char pers_nopr[] =
720 { 0x4e, 0x61, 0x79, 0xd4, 0xc2, 0x72, 0xa1, 0x4c,
721 0xf1, 0x3d, 0xf6, 0x5e, 0xa3, 0xa6, 0xe5, 0x0f };
722
723 static const unsigned char result_pr[] =
724 { 0xc9, 0x0a, 0xaf, 0x85, 0x89, 0x71, 0x44, 0x66,
725 0x4f, 0x25, 0x0b, 0x2b, 0xde, 0xd8, 0xfa, 0xff,
726 0x52, 0x5a, 0x1b, 0x32, 0x5e, 0x41, 0x7a, 0x10,
727 0x1f, 0xef, 0x1e, 0x62, 0x23, 0xe9, 0x20, 0x30,
728 0xc9, 0x0d, 0xad, 0x69, 0xb4, 0x9c, 0x5b, 0xf4,
729 0x87, 0x42, 0xd5, 0xae, 0x5e, 0x5e, 0x43, 0xcc,
730 0xd9, 0xfd, 0x0b, 0x93, 0x4a, 0xe3, 0xd4, 0x06,
731 0x37, 0x36, 0x0f, 0x3f, 0x72, 0x82, 0x0c, 0xcf };
732
733 static const unsigned char result_nopr[] =
734 { 0x31, 0xc9, 0x91, 0x09, 0xf8, 0xc5, 0x10, 0x13,
735 0x3c, 0xd3, 0x96, 0xf9, 0xbc, 0x2c, 0x12, 0xc0,
736 0x7c, 0xc1, 0x61, 0x5f, 0xa3, 0x09, 0x99, 0xaf,
737 0xd7, 0xf2, 0x36, 0xfd, 0x40, 0x1a, 0x8b, 0xf2,
738 0x33, 0x38, 0xee, 0x1d, 0x03, 0x5f, 0x83, 0xb7,
739 0xa2, 0x53, 0xdc, 0xee, 0x18, 0xfc, 0xa7, 0xf2,
740 0xee, 0x96, 0xc6, 0xc2, 0xcd, 0x0c, 0xff, 0x02,
741 0x76, 0x70, 0x69, 0xaa, 0x69, 0xd1, 0x3b, 0xe8 };
742 #else /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
743
744 static const unsigned char entropy_source_pr[] =
745 { 0xca, 0x58, 0xfd, 0xf2, 0xb9, 0x77, 0xcb, 0x49,
746 0xd4, 0xe0, 0x5b, 0xe2, 0x39, 0x50, 0xd9, 0x8a,
747 0x6a, 0xb3, 0xc5, 0x2f, 0xdf, 0x74, 0xd5, 0x85,
748 0x8f, 0xd1, 0xba, 0x64, 0x54, 0x7b, 0xdb, 0x1e,
749 0xc5, 0xea, 0x24, 0xc0, 0xfa, 0x0c, 0x90, 0x15,
750 0x09, 0x20, 0x92, 0x42, 0x32, 0x36, 0x45, 0x45,
751 0x7d, 0x20, 0x76, 0x6b, 0xcf, 0xa2, 0x15, 0xc8,
752 0x2f, 0x9f, 0xbc, 0x88, 0x3f, 0x80, 0xd1, 0x2c,
753 0xb7, 0x16, 0xd1, 0x80, 0x9e, 0xe1, 0xc9, 0xb3,
754 0x88, 0x1b, 0x21, 0x45, 0xef, 0xa1, 0x7f, 0xce,
755 0xc8, 0x92, 0x35, 0x55, 0x2a, 0xd9, 0x1d, 0x8e,
756 0x12, 0x38, 0xac, 0x01, 0x4e, 0x38, 0x18, 0x76,
757 0x9c, 0xf2, 0xb6, 0xd4, 0x13, 0xb6, 0x2c, 0x77,
758 0xc0, 0xe7, 0xe6, 0x0c, 0x47, 0x44, 0x95, 0xbe };
759
760 static const unsigned char entropy_source_nopr[] =
761 { 0x4c, 0xfb, 0x21, 0x86, 0x73, 0x34, 0x6d, 0x9d,
762 0x50, 0xc9, 0x22, 0xe4, 0x9b, 0x0d, 0xfc, 0xd0,
763 0x90, 0xad, 0xf0, 0x4f, 0x5c, 0x3b, 0xa4, 0x73,
764 0x27, 0xdf, 0xcd, 0x6f, 0xa6, 0x3a, 0x78, 0x5c,
765 0x01, 0x69, 0x62, 0xa7, 0xfd, 0x27, 0x87, 0xa2,
766 0x4b, 0xf6, 0xbe, 0x47, 0xef, 0x37, 0x83, 0xf1,
767 0xb7, 0xec, 0x46, 0x07, 0x23, 0x63, 0x83, 0x4a,
768 0x1b, 0x01, 0x33, 0xf2, 0xc2, 0x38, 0x91, 0xdb,
769 0x4f, 0x11, 0xa6, 0x86, 0x51, 0xf2, 0x3e, 0x3a,
770 0x8b, 0x1f, 0xdc, 0x03, 0xb1, 0x92, 0xc7, 0xe7 };
771
772 static const unsigned char pers_pr[] =
773 { 0x5a, 0x70, 0x95, 0xe9, 0x81, 0x40, 0x52, 0x33,
774 0x91, 0x53, 0x7e, 0x75, 0xd6, 0x19, 0x9d, 0x1e,
775 0xad, 0x0d, 0xc6, 0xa7, 0xde, 0x6c, 0x1f, 0xe0,
776 0xea, 0x18, 0x33, 0xa8, 0x7e, 0x06, 0x20, 0xe9 };
777
778 static const unsigned char pers_nopr[] =
779 { 0x88, 0xee, 0xb8, 0xe0, 0xe8, 0x3b, 0xf3, 0x29,
780 0x4b, 0xda, 0xcd, 0x60, 0x99, 0xeb, 0xe4, 0xbf,
781 0x55, 0xec, 0xd9, 0x11, 0x3f, 0x71, 0xe5, 0xeb,
782 0xcb, 0x45, 0x75, 0xf3, 0xd6, 0xa6, 0x8a, 0x6b };
783
784 static const unsigned char result_pr[] =
785 { 0xce, 0x2f, 0xdb, 0xb6, 0xd9, 0xb7, 0x39, 0x85,
786 0x04, 0xc5, 0xc0, 0x42, 0xc2, 0x31, 0xc6, 0x1d,
787 0x9b, 0x5a, 0x59, 0xf8, 0x7e, 0x0d, 0xcc, 0x62,
788 0x7b, 0x65, 0x11, 0x55, 0x10, 0xeb, 0x9e, 0x3d,
789 0xa4, 0xfb, 0x1c, 0x6a, 0x18, 0xc0, 0x74, 0xdb,
790 0xdd, 0xe7, 0x02, 0x23, 0x63, 0x21, 0xd0, 0x39,
791 0xf9, 0xa7, 0xc4, 0x52, 0x84, 0x3b, 0x49, 0x40,
792 0x72, 0x2b, 0xb0, 0x6c, 0x9c, 0xdb, 0xc3, 0x43 };
793
794 static const unsigned char result_nopr[] =
795 { 0xa5, 0x51, 0x80, 0xa1, 0x90, 0xbe, 0xf3, 0xad,
796 0xaf, 0x28, 0xf6, 0xb7, 0x95, 0xe9, 0xf1, 0xf3,
797 0xd6, 0xdf, 0xa1, 0xb2, 0x7d, 0xd0, 0x46, 0x7b,
798 0x0c, 0x75, 0xf5, 0xfa, 0x93, 0x1e, 0x97, 0x14,
799 0x75, 0xb2, 0x7c, 0xae, 0x03, 0xa2, 0x96, 0x54,
800 0xe2, 0xf4, 0x09, 0x66, 0xea, 0x33, 0x64, 0x30,
801 0x40, 0xd1, 0x40, 0x0f, 0xe6, 0x77, 0x87, 0x3a,
802 0xf8, 0x09, 0x7c, 0x1f, 0xe9, 0xf0, 0x02, 0x98 };
803 #endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
804
805 static size_t test_offset;
ctr_drbg_self_test_entropy(void * data,unsigned char * buf,size_t len)806 static int ctr_drbg_self_test_entropy(void *data, unsigned char *buf,
807 size_t len)
808 {
809 const unsigned char *p = data;
810 memcpy(buf, p + test_offset, len);
811 test_offset += len;
812 return 0;
813 }
814
815 #define CHK(c) if ((c) != 0) \
816 { \
817 if (verbose != 0) \
818 mbedtls_printf("failed\n"); \
819 return 1; \
820 }
821
822 #define SELF_TEST_OUTPUT_DISCARD_LENGTH 64
823
824 /*
825 * Checkup routine
826 */
mbedtls_ctr_drbg_self_test(int verbose)827 int mbedtls_ctr_drbg_self_test(int verbose)
828 {
829 mbedtls_ctr_drbg_context ctx;
830 unsigned char buf[sizeof(result_pr)];
831
832 mbedtls_ctr_drbg_init(&ctx);
833
834 /*
835 * Based on a NIST CTR_DRBG test vector (PR = True)
836 */
837 if (verbose != 0) {
838 mbedtls_printf(" CTR_DRBG (PR = TRUE) : ");
839 }
840
841 test_offset = 0;
842 mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
843 mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2);
844 CHK(mbedtls_ctr_drbg_seed(&ctx,
845 ctr_drbg_self_test_entropy,
846 (void *) entropy_source_pr,
847 pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE));
848 mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_ON);
849 CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH));
850 CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_pr)));
851 CHK(memcmp(buf, result_pr, sizeof(result_pr)));
852
853 mbedtls_ctr_drbg_free(&ctx);
854
855 if (verbose != 0) {
856 mbedtls_printf("passed\n");
857 }
858
859 /*
860 * Based on a NIST CTR_DRBG test vector (PR = FALSE)
861 */
862 if (verbose != 0) {
863 mbedtls_printf(" CTR_DRBG (PR = FALSE): ");
864 }
865
866 mbedtls_ctr_drbg_init(&ctx);
867
868 test_offset = 0;
869 mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
870 mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2);
871 CHK(mbedtls_ctr_drbg_seed(&ctx,
872 ctr_drbg_self_test_entropy,
873 (void *) entropy_source_nopr,
874 pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE));
875 CHK(mbedtls_ctr_drbg_reseed(&ctx, NULL, 0));
876 CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH));
877 CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_nopr)));
878 CHK(memcmp(buf, result_nopr, sizeof(result_nopr)));
879
880 mbedtls_ctr_drbg_free(&ctx);
881
882 if (verbose != 0) {
883 mbedtls_printf("passed\n");
884 }
885
886 if (verbose != 0) {
887 mbedtls_printf("\n");
888 }
889
890 return 0;
891 }
892 #endif /* MBEDTLS_SELF_TEST */
893
894 #endif /* MBEDTLS_CTR_DRBG_C */
895