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_ret(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t add_len)315 int mbedtls_ctr_drbg_update_ret( 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 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t add_len)336 void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
337 const unsigned char *additional,
338 size_t add_len )
339 {
340 /* MAX_INPUT would be more logical here, but we have to match
341 * block_cipher_df()'s limits since we can't propagate errors */
342 if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
343 add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
344 (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
345 }
346 #endif /* MBEDTLS_DEPRECATED_REMOVED */
347
348 /* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2)
349 * mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len)
350 * implements
351 * CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
352 * -> new_working_state
353 * with inputs
354 * ctx contains working_state
355 * additional[:len] = additional_input
356 * and entropy_input comes from calling ctx->f_entropy
357 * for (ctx->entropy_len + nonce_len) bytes
358 * and with output
359 * ctx contains new_working_state
360 */
mbedtls_ctr_drbg_reseed_internal(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t len,size_t nonce_len)361 static int mbedtls_ctr_drbg_reseed_internal( mbedtls_ctr_drbg_context *ctx,
362 const unsigned char *additional,
363 size_t len,
364 size_t nonce_len )
365 {
366 unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
367 size_t seedlen = 0;
368 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
369
370 if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
371 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
372 if( nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
373 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
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 memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
378
379 /* Gather entropy_len bytes of entropy to seed state. */
380 if( 0 != ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) )
381 {
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 {
389 if( 0 != ctx->f_entropy( ctx->p_entropy, seed + seedlen, nonce_len ) )
390 {
391 return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
392 }
393 seedlen += nonce_len;
394 }
395
396 /* Add additional data if provided. */
397 if( additional != NULL && len != 0 )
398 {
399 memcpy( seed + seedlen, additional, len );
400 seedlen += len;
401 }
402
403 /* Reduce to 384 bits. */
404 if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
405 goto exit;
406
407 /* Update state. */
408 if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
409 goto exit;
410 ctx->reseed_counter = 1;
411
412 exit:
413 mbedtls_platform_zeroize( seed, sizeof( seed ) );
414 return( ret );
415 }
416
mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t len)417 int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
418 const unsigned char *additional, size_t len )
419 {
420 return( mbedtls_ctr_drbg_reseed_internal( ctx, additional, len, 0 ) );
421 }
422
423 /* Return a "good" nonce length for CTR_DRBG. The chosen nonce length
424 * is sufficient to achieve the maximum security strength given the key
425 * size and entropy length. If there is enough entropy in the initial
426 * call to the entropy function to serve as both the entropy input and
427 * the nonce, don't make a second call to get a nonce. */
good_nonce_len(size_t entropy_len)428 static size_t good_nonce_len( size_t entropy_len )
429 {
430 if( entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 )
431 return( 0 );
432 else
433 return( ( entropy_len + 1 ) / 2 );
434 }
435
436 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A §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 */
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)447 int 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 /* ctx->reseed_counter contains the desired amount of entropy to
472 * grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()).
473 * If it's -1, indicating that the entropy nonce length was not set
474 * explicitly, use a sufficiently large nonce for security. */
475 nonce_len = ( ctx->reseed_counter >= 0 ?
476 (size_t) ctx->reseed_counter :
477 good_nonce_len( ctx->entropy_len ) );
478
479 /* Initialize with an empty key. */
480 if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key,
481 MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
482 {
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 {
490 return( ret );
491 }
492 return( 0 );
493 }
494
495 /* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2)
496 * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
497 * implements
498 * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len])
499 * -> working_state_after_reseed
500 * if required, then
501 * CTR_DRBG_Generate(working_state_after_reseed,
502 * requested_number_of_bits, additional_input)
503 * -> status, returned_bits, new_working_state
504 * with inputs
505 * ctx contains working_state
506 * requested_number_of_bits = 8 * output_len
507 * additional[:add_len] = additional_input
508 * and entropy_input comes from calling ctx->f_entropy
509 * and with outputs
510 * status = SUCCESS (this function does the reseed internally)
511 * returned_bits = output[:output_len]
512 * ctx contains new_working_state
513 */
mbedtls_ctr_drbg_random_with_add(void * p_rng,unsigned char * output,size_t output_len,const unsigned char * additional,size_t add_len)514 int mbedtls_ctr_drbg_random_with_add( void *p_rng,
515 unsigned char *output, size_t output_len,
516 const unsigned char *additional, size_t add_len )
517 {
518 int ret = 0;
519 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
520 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
521 unsigned char *p = output;
522 unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
523 int i;
524 size_t use_len;
525
526 if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST )
527 return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
528
529 if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT )
530 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
531
532 memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
533
534 if( ctx->reseed_counter > ctx->reseed_interval ||
535 ctx->prediction_resistance )
536 {
537 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
538 {
539 return( ret );
540 }
541 add_len = 0;
542 }
543
544 if( add_len > 0 )
545 {
546 if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
547 goto exit;
548 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
549 goto exit;
550 }
551
552 while( output_len > 0 )
553 {
554 /*
555 * Increase counter
556 */
557 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
558 if( ++ctx->counter[i - 1] != 0 )
559 break;
560
561 /*
562 * Crypt counter block
563 */
564 if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
565 ctx->counter, tmp ) ) != 0 )
566 {
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 ctx->reseed_counter++;
584
585 exit:
586 mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
587 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
588 return( ret );
589 }
590
mbedtls_ctr_drbg_random(void * p_rng,unsigned char * output,size_t output_len)591 int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output,
592 size_t output_len )
593 {
594 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
595 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
596
597 #if defined(MBEDTLS_THREADING_C)
598 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
599 return( ret );
600 #endif
601
602 ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 );
603
604 #if defined(MBEDTLS_THREADING_C)
605 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
606 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
607 #endif
608
609 return( ret );
610 }
611
612 #if defined(MBEDTLS_FS_IO)
mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context * ctx,const char * path)613 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx,
614 const char *path )
615 {
616 int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
617 FILE *f;
618 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
619
620 if( ( f = fopen( path, "wb" ) ) == NULL )
621 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
622
623 if( ( ret = mbedtls_ctr_drbg_random( ctx, buf,
624 MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
625 goto exit;
626
627 if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) !=
628 MBEDTLS_CTR_DRBG_MAX_INPUT )
629 {
630 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
631 }
632 else
633 {
634 ret = 0;
635 }
636
637 exit:
638 mbedtls_platform_zeroize( buf, sizeof( buf ) );
639
640 fclose( f );
641 return( ret );
642 }
643
mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context * ctx,const char * path)644 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx,
645 const char *path )
646 {
647 int ret = 0;
648 FILE *f = NULL;
649 size_t n;
650 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
651 unsigned char c;
652
653 if( ( f = fopen( path, "rb" ) ) == NULL )
654 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
655
656 n = fread( buf, 1, sizeof( buf ), f );
657 if( fread( &c, 1, 1, f ) != 0 )
658 {
659 ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
660 goto exit;
661 }
662 if( n == 0 || ferror( f ) )
663 {
664 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
665 goto exit;
666 }
667 fclose( f );
668 f = NULL;
669
670 ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
671
672 exit:
673 mbedtls_platform_zeroize( buf, sizeof( buf ) );
674 if( f != NULL )
675 fclose( f );
676 if( ret != 0 )
677 return( ret );
678 return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
679 }
680 #endif /* MBEDTLS_FS_IO */
681
682 #if defined(MBEDTLS_SELF_TEST)
683
684 /* The CTR_DRBG NIST test vectors used here are available at
685 * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip
686 *
687 * The parameters used to derive the test data are:
688 *
689 * [AES-128 use df]
690 * [PredictionResistance = True/False]
691 * [EntropyInputLen = 128]
692 * [NonceLen = 64]
693 * [PersonalizationStringLen = 128]
694 * [AdditionalInputLen = 0]
695 * [ReturnedBitsLen = 512]
696 *
697 * [AES-256 use df]
698 * [PredictionResistance = True/False]
699 * [EntropyInputLen = 256]
700 * [NonceLen = 128]
701 * [PersonalizationStringLen = 256]
702 * [AdditionalInputLen = 0]
703 * [ReturnedBitsLen = 512]
704 *
705 */
706
707 #if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
708 static const unsigned char entropy_source_pr[] =
709 { 0x04, 0xd9, 0x49, 0xa6, 0xdc, 0xe8, 0x6e, 0xbb,
710 0xf1, 0x08, 0x77, 0x2b, 0x9e, 0x08, 0xca, 0x92,
711 0x65, 0x16, 0xda, 0x99, 0xa2, 0x59, 0xf3, 0xe8,
712 0x38, 0x7e, 0x3f, 0x6b, 0x51, 0x70, 0x7b, 0x20,
713 0xec, 0x53, 0xd0, 0x66, 0xc3, 0x0f, 0xe3, 0xb0,
714 0xe0, 0x86, 0xa6, 0xaa, 0x5f, 0x72, 0x2f, 0xad,
715 0xf7, 0xef, 0x06, 0xb8, 0xd6, 0x9c, 0x9d, 0xe8 };
716
717 static const unsigned char entropy_source_nopr[] =
718 { 0x07, 0x0d, 0x59, 0x63, 0x98, 0x73, 0xa5, 0x45,
719 0x27, 0x38, 0x22, 0x7b, 0x76, 0x85, 0xd1, 0xa9,
720 0x74, 0x18, 0x1f, 0x3c, 0x22, 0xf6, 0x49, 0x20,
721 0x4a, 0x47, 0xc2, 0xf3, 0x85, 0x16, 0xb4, 0x6f,
722 0x00, 0x2e, 0x71, 0xda, 0xed, 0x16, 0x9b, 0x5c };
723
724 static const unsigned char pers_pr[] =
725 { 0xbf, 0xa4, 0x9a, 0x8f, 0x7b, 0xd8, 0xb1, 0x7a,
726 0x9d, 0xfa, 0x45, 0xed, 0x21, 0x52, 0xb3, 0xad };
727
728 static const unsigned char pers_nopr[] =
729 { 0x4e, 0x61, 0x79, 0xd4, 0xc2, 0x72, 0xa1, 0x4c,
730 0xf1, 0x3d, 0xf6, 0x5e, 0xa3, 0xa6, 0xe5, 0x0f };
731
732 static const unsigned char result_pr[] =
733 { 0xc9, 0x0a, 0xaf, 0x85, 0x89, 0x71, 0x44, 0x66,
734 0x4f, 0x25, 0x0b, 0x2b, 0xde, 0xd8, 0xfa, 0xff,
735 0x52, 0x5a, 0x1b, 0x32, 0x5e, 0x41, 0x7a, 0x10,
736 0x1f, 0xef, 0x1e, 0x62, 0x23, 0xe9, 0x20, 0x30,
737 0xc9, 0x0d, 0xad, 0x69, 0xb4, 0x9c, 0x5b, 0xf4,
738 0x87, 0x42, 0xd5, 0xae, 0x5e, 0x5e, 0x43, 0xcc,
739 0xd9, 0xfd, 0x0b, 0x93, 0x4a, 0xe3, 0xd4, 0x06,
740 0x37, 0x36, 0x0f, 0x3f, 0x72, 0x82, 0x0c, 0xcf };
741
742 static const unsigned char result_nopr[] =
743 { 0x31, 0xc9, 0x91, 0x09, 0xf8, 0xc5, 0x10, 0x13,
744 0x3c, 0xd3, 0x96, 0xf9, 0xbc, 0x2c, 0x12, 0xc0,
745 0x7c, 0xc1, 0x61, 0x5f, 0xa3, 0x09, 0x99, 0xaf,
746 0xd7, 0xf2, 0x36, 0xfd, 0x40, 0x1a, 0x8b, 0xf2,
747 0x33, 0x38, 0xee, 0x1d, 0x03, 0x5f, 0x83, 0xb7,
748 0xa2, 0x53, 0xdc, 0xee, 0x18, 0xfc, 0xa7, 0xf2,
749 0xee, 0x96, 0xc6, 0xc2, 0xcd, 0x0c, 0xff, 0x02,
750 0x76, 0x70, 0x69, 0xaa, 0x69, 0xd1, 0x3b, 0xe8 };
751 #else /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
752
753 static const unsigned char entropy_source_pr[] =
754 { 0xca, 0x58, 0xfd, 0xf2, 0xb9, 0x77, 0xcb, 0x49,
755 0xd4, 0xe0, 0x5b, 0xe2, 0x39, 0x50, 0xd9, 0x8a,
756 0x6a, 0xb3, 0xc5, 0x2f, 0xdf, 0x74, 0xd5, 0x85,
757 0x8f, 0xd1, 0xba, 0x64, 0x54, 0x7b, 0xdb, 0x1e,
758 0xc5, 0xea, 0x24, 0xc0, 0xfa, 0x0c, 0x90, 0x15,
759 0x09, 0x20, 0x92, 0x42, 0x32, 0x36, 0x45, 0x45,
760 0x7d, 0x20, 0x76, 0x6b, 0xcf, 0xa2, 0x15, 0xc8,
761 0x2f, 0x9f, 0xbc, 0x88, 0x3f, 0x80, 0xd1, 0x2c,
762 0xb7, 0x16, 0xd1, 0x80, 0x9e, 0xe1, 0xc9, 0xb3,
763 0x88, 0x1b, 0x21, 0x45, 0xef, 0xa1, 0x7f, 0xce,
764 0xc8, 0x92, 0x35, 0x55, 0x2a, 0xd9, 0x1d, 0x8e,
765 0x12, 0x38, 0xac, 0x01, 0x4e, 0x38, 0x18, 0x76,
766 0x9c, 0xf2, 0xb6, 0xd4, 0x13, 0xb6, 0x2c, 0x77,
767 0xc0, 0xe7, 0xe6, 0x0c, 0x47, 0x44, 0x95, 0xbe };
768
769 static const unsigned char entropy_source_nopr[] =
770 { 0x4c, 0xfb, 0x21, 0x86, 0x73, 0x34, 0x6d, 0x9d,
771 0x50, 0xc9, 0x22, 0xe4, 0x9b, 0x0d, 0xfc, 0xd0,
772 0x90, 0xad, 0xf0, 0x4f, 0x5c, 0x3b, 0xa4, 0x73,
773 0x27, 0xdf, 0xcd, 0x6f, 0xa6, 0x3a, 0x78, 0x5c,
774 0x01, 0x69, 0x62, 0xa7, 0xfd, 0x27, 0x87, 0xa2,
775 0x4b, 0xf6, 0xbe, 0x47, 0xef, 0x37, 0x83, 0xf1,
776 0xb7, 0xec, 0x46, 0x07, 0x23, 0x63, 0x83, 0x4a,
777 0x1b, 0x01, 0x33, 0xf2, 0xc2, 0x38, 0x91, 0xdb,
778 0x4f, 0x11, 0xa6, 0x86, 0x51, 0xf2, 0x3e, 0x3a,
779 0x8b, 0x1f, 0xdc, 0x03, 0xb1, 0x92, 0xc7, 0xe7 };
780
781 static const unsigned char pers_pr[] =
782 { 0x5a, 0x70, 0x95, 0xe9, 0x81, 0x40, 0x52, 0x33,
783 0x91, 0x53, 0x7e, 0x75, 0xd6, 0x19, 0x9d, 0x1e,
784 0xad, 0x0d, 0xc6, 0xa7, 0xde, 0x6c, 0x1f, 0xe0,
785 0xea, 0x18, 0x33, 0xa8, 0x7e, 0x06, 0x20, 0xe9 };
786
787 static const unsigned char pers_nopr[] =
788 { 0x88, 0xee, 0xb8, 0xe0, 0xe8, 0x3b, 0xf3, 0x29,
789 0x4b, 0xda, 0xcd, 0x60, 0x99, 0xeb, 0xe4, 0xbf,
790 0x55, 0xec, 0xd9, 0x11, 0x3f, 0x71, 0xe5, 0xeb,
791 0xcb, 0x45, 0x75, 0xf3, 0xd6, 0xa6, 0x8a, 0x6b };
792
793 static const unsigned char result_pr[] =
794 { 0xce, 0x2f, 0xdb, 0xb6, 0xd9, 0xb7, 0x39, 0x85,
795 0x04, 0xc5, 0xc0, 0x42, 0xc2, 0x31, 0xc6, 0x1d,
796 0x9b, 0x5a, 0x59, 0xf8, 0x7e, 0x0d, 0xcc, 0x62,
797 0x7b, 0x65, 0x11, 0x55, 0x10, 0xeb, 0x9e, 0x3d,
798 0xa4, 0xfb, 0x1c, 0x6a, 0x18, 0xc0, 0x74, 0xdb,
799 0xdd, 0xe7, 0x02, 0x23, 0x63, 0x21, 0xd0, 0x39,
800 0xf9, 0xa7, 0xc4, 0x52, 0x84, 0x3b, 0x49, 0x40,
801 0x72, 0x2b, 0xb0, 0x6c, 0x9c, 0xdb, 0xc3, 0x43 };
802
803 static const unsigned char result_nopr[] =
804 { 0xa5, 0x51, 0x80, 0xa1, 0x90, 0xbe, 0xf3, 0xad,
805 0xaf, 0x28, 0xf6, 0xb7, 0x95, 0xe9, 0xf1, 0xf3,
806 0xd6, 0xdf, 0xa1, 0xb2, 0x7d, 0xd0, 0x46, 0x7b,
807 0x0c, 0x75, 0xf5, 0xfa, 0x93, 0x1e, 0x97, 0x14,
808 0x75, 0xb2, 0x7c, 0xae, 0x03, 0xa2, 0x96, 0x54,
809 0xe2, 0xf4, 0x09, 0x66, 0xea, 0x33, 0x64, 0x30,
810 0x40, 0xd1, 0x40, 0x0f, 0xe6, 0x77, 0x87, 0x3a,
811 0xf8, 0x09, 0x7c, 0x1f, 0xe9, 0xf0, 0x02, 0x98 };
812 #endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
813
814 static size_t test_offset;
ctr_drbg_self_test_entropy(void * data,unsigned char * buf,size_t len)815 static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
816 size_t len )
817 {
818 const unsigned char *p = data;
819 memcpy( buf, p + test_offset, len );
820 test_offset += len;
821 return( 0 );
822 }
823
824 #define CHK( c ) if( (c) != 0 ) \
825 { \
826 if( verbose != 0 ) \
827 mbedtls_printf( "failed\n" ); \
828 return( 1 ); \
829 }
830
831 #define SELF_TEST_OUPUT_DISCARD_LENGTH 64
832
833 /*
834 * Checkup routine
835 */
mbedtls_ctr_drbg_self_test(int verbose)836 int mbedtls_ctr_drbg_self_test( int verbose )
837 {
838 mbedtls_ctr_drbg_context ctx;
839 unsigned char buf[ sizeof( result_pr ) ];
840
841 mbedtls_ctr_drbg_init( &ctx );
842
843 /*
844 * Based on a NIST CTR_DRBG test vector (PR = True)
845 */
846 if( verbose != 0 )
847 mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
848
849 test_offset = 0;
850 mbedtls_ctr_drbg_set_entropy_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE );
851 mbedtls_ctr_drbg_set_nonce_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2 );
852 CHK( mbedtls_ctr_drbg_seed( &ctx,
853 ctr_drbg_self_test_entropy,
854 (void *) entropy_source_pr,
855 pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
856 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
857 CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
858 CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_pr ) ) );
859 CHK( memcmp( buf, result_pr, sizeof( result_pr ) ) );
860
861 mbedtls_ctr_drbg_free( &ctx );
862
863 if( verbose != 0 )
864 mbedtls_printf( "passed\n" );
865
866 /*
867 * Based on a NIST CTR_DRBG test vector (PR = FALSE)
868 */
869 if( verbose != 0 )
870 mbedtls_printf( " CTR_DRBG (PR = FALSE): " );
871
872 mbedtls_ctr_drbg_init( &ctx );
873
874 test_offset = 0;
875 mbedtls_ctr_drbg_set_entropy_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
876 mbedtls_ctr_drbg_set_nonce_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2 );
877 CHK( mbedtls_ctr_drbg_seed( &ctx,
878 ctr_drbg_self_test_entropy,
879 (void *) entropy_source_nopr,
880 pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
881 CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
882 CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
883 CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_nopr ) ) );
884 CHK( memcmp( buf, result_nopr, sizeof( result_nopr ) ) );
885
886 mbedtls_ctr_drbg_free( &ctx );
887
888 if( verbose != 0 )
889 mbedtls_printf( "passed\n" );
890
891 if( verbose != 0 )
892 mbedtls_printf( "\n" );
893
894 return( 0 );
895 }
896 #endif /* MBEDTLS_SELF_TEST */
897
898 #endif /* MBEDTLS_CTR_DRBG_C */
899