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