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