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