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 #if defined(MBEDTLS_THREADING_C)
61 mbedtls_mutex_init( &ctx->mutex );
62 #endif
63 }
64
65 /*
66 * This function resets CTR_DRBG context to the state immediately
67 * after initial call of mbedtls_ctr_drbg_init().
68 */
mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context * ctx)69 void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
70 {
71 if( ctx == NULL )
72 return;
73
74 #if defined(MBEDTLS_THREADING_C)
75 mbedtls_mutex_free( &ctx->mutex );
76 #endif
77 mbedtls_aes_free( &ctx->aes_ctx );
78 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
79 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
80 ctx->reseed_counter = -1;
81 #if defined(MBEDTLS_THREADING_C)
82 mbedtls_mutex_init( &ctx->mutex );
83 #endif
84 }
85
mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context * ctx,int resistance)86 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
87 int resistance )
88 {
89 ctx->prediction_resistance = resistance;
90 }
91
mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context * ctx,size_t len)92 void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
93 size_t len )
94 {
95 ctx->entropy_len = len;
96 }
97
mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context * ctx,size_t len)98 int mbedtls_ctr_drbg_set_nonce_len( mbedtls_ctr_drbg_context *ctx,
99 size_t len )
100 {
101 /* If mbedtls_ctr_drbg_seed() has already been called, it's
102 * too late. Return the error code that's closest to making sense. */
103 if( ctx->f_entropy != NULL )
104 return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
105
106 if( len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
107 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
108 #if SIZE_MAX > INT_MAX
109 /* This shouldn't be an issue because
110 * MBEDTLS_CTR_DRBG_MAX_SEED_INPUT < INT_MAX in any sensible
111 * configuration, but make sure anyway. */
112 if( len > INT_MAX )
113 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
114 #endif
115
116 /* For backward compatibility with Mbed TLS <= 2.19, store the
117 * entropy nonce length in a field that already exists, but isn't
118 * used until after the initial seeding. */
119 /* Due to the capping of len above, the value fits in an int. */
120 ctx->reseed_counter = (int) len;
121 return( 0 );
122 }
123
mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context * ctx,int interval)124 void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
125 int interval )
126 {
127 ctx->reseed_interval = interval;
128 }
129
block_cipher_df(unsigned char * output,const unsigned char * data,size_t data_len)130 static int block_cipher_df( unsigned char *output,
131 const unsigned char *data, size_t data_len )
132 {
133 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
134 MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
135 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
136 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
137 unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
138 unsigned char *p, *iv;
139 mbedtls_aes_context aes_ctx;
140 int ret = 0;
141
142 int i, j;
143 size_t buf_len, use_len;
144
145 if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
146 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
147
148 memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
149 MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
150 mbedtls_aes_init( &aes_ctx );
151
152 /*
153 * Construct IV (16 bytes) and S in buffer
154 * IV = Counter (in 32-bits) padded to 16 with zeroes
155 * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
156 * data || 0x80
157 * (Total is padded to a multiple of 16-bytes with zeroes)
158 */
159 p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
160 *p++ = ( data_len >> 24 ) & 0xff;
161 *p++ = ( data_len >> 16 ) & 0xff;
162 *p++ = ( data_len >> 8 ) & 0xff;
163 *p++ = ( data_len ) & 0xff;
164 p += 3;
165 *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
166 memcpy( p, data, data_len );
167 p[data_len] = 0x80;
168
169 buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
170
171 for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
172 key[i] = i;
173
174 if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key,
175 MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
176 {
177 goto exit;
178 }
179
180 /*
181 * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
182 */
183 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
184 {
185 p = buf;
186 memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE );
187 use_len = buf_len;
188
189 while( use_len > 0 )
190 {
191 for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ )
192 chain[i] ^= p[i];
193 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
194 use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
195 MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
196
197 if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT,
198 chain, chain ) ) != 0 )
199 {
200 goto exit;
201 }
202 }
203
204 memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
205
206 /*
207 * Update IV
208 */
209 buf[3]++;
210 }
211
212 /*
213 * Do final encryption with reduced data
214 */
215 if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp,
216 MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
217 {
218 goto exit;
219 }
220 iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
221 p = output;
222
223 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
224 {
225 if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT,
226 iv, iv ) ) != 0 )
227 {
228 goto exit;
229 }
230 memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
231 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
232 }
233 exit:
234 mbedtls_aes_free( &aes_ctx );
235 /*
236 * tidy up the stack
237 */
238 mbedtls_platform_zeroize( buf, sizeof( buf ) );
239 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
240 mbedtls_platform_zeroize( key, sizeof( key ) );
241 mbedtls_platform_zeroize( chain, sizeof( chain ) );
242 if( 0 != ret )
243 {
244 /*
245 * wipe partial seed from memory
246 */
247 mbedtls_platform_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
248 }
249
250 return( ret );
251 }
252
253 /* CTR_DRBG_Update (SP 800-90A §10.2.1.2)
254 * ctr_drbg_update_internal(ctx, provided_data)
255 * implements
256 * CTR_DRBG_Update(provided_data, Key, V)
257 * with inputs and outputs
258 * ctx->aes_ctx = Key
259 * ctx->counter = V
260 */
ctr_drbg_update_internal(mbedtls_ctr_drbg_context * ctx,const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN])261 static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
262 const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
263 {
264 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
265 unsigned char *p = tmp;
266 int i, j;
267 int ret = 0;
268
269 memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
270
271 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
272 {
273 /*
274 * Increase counter
275 */
276 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
277 if( ++ctx->counter[i - 1] != 0 )
278 break;
279
280 /*
281 * Crypt counter block
282 */
283 if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
284 ctx->counter, p ) ) != 0 )
285 {
286 goto exit;
287 }
288
289 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
290 }
291
292 for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ )
293 tmp[i] ^= data[i];
294
295 /*
296 * Update key and counter
297 */
298 if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp,
299 MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
300 {
301 goto exit;
302 }
303 memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
304 MBEDTLS_CTR_DRBG_BLOCKSIZE );
305
306 exit:
307 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
308 return( ret );
309 }
310
311 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2)
312 * mbedtls_ctr_drbg_update(ctx, additional, add_len)
313 * implements
314 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
315 * security_strength) -> initial_working_state
316 * with inputs
317 * ctx->counter = all-bits-0
318 * ctx->aes_ctx = context from all-bits-0 key
319 * additional[:add_len] = entropy_input || nonce || personalization_string
320 * and with outputs
321 * ctx = initial_working_state
322 */
mbedtls_ctr_drbg_update_ret(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t add_len)323 int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
324 const unsigned char *additional,
325 size_t add_len )
326 {
327 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
328 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
329
330 if( add_len == 0 )
331 return( 0 );
332
333 if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
334 goto exit;
335 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
336 goto exit;
337
338 exit:
339 mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
340 return( ret );
341 }
342
343 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t add_len)344 void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
345 const unsigned char *additional,
346 size_t add_len )
347 {
348 /* MAX_INPUT would be more logical here, but we have to match
349 * block_cipher_df()'s limits since we can't propagate errors */
350 if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
351 add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
352 (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
353 }
354 #endif /* MBEDTLS_DEPRECATED_REMOVED */
355
356 /* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2)
357 * mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len)
358 * implements
359 * CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
360 * -> new_working_state
361 * with inputs
362 * ctx contains working_state
363 * additional[:len] = additional_input
364 * and entropy_input comes from calling ctx->f_entropy
365 * for (ctx->entropy_len + nonce_len) bytes
366 * and with output
367 * ctx contains new_working_state
368 */
mbedtls_ctr_drbg_reseed_internal(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t len,size_t nonce_len)369 static int mbedtls_ctr_drbg_reseed_internal( mbedtls_ctr_drbg_context *ctx,
370 const unsigned char *additional,
371 size_t len,
372 size_t nonce_len )
373 {
374 unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
375 size_t seedlen = 0;
376 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
377
378 if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
379 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
380 if( nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
381 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
382 if( len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len )
383 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
384
385 memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
386
387 /* Gather entropy_len bytes of entropy to seed state. */
388 if( 0 != ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) )
389 {
390 return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
391 }
392 seedlen += ctx->entropy_len;
393
394 /* Gather entropy for a nonce if requested. */
395 if( nonce_len != 0 )
396 {
397 if( 0 != ctx->f_entropy( ctx->p_entropy, seed, nonce_len ) )
398 {
399 return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
400 }
401 seedlen += nonce_len;
402 }
403
404 /* Add additional data if provided. */
405 if( additional != NULL && len != 0 )
406 {
407 memcpy( seed + seedlen, additional, len );
408 seedlen += len;
409 }
410
411 /* Reduce to 384 bits. */
412 if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
413 goto exit;
414
415 /* Update state. */
416 if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
417 goto exit;
418 ctx->reseed_counter = 1;
419
420 exit:
421 mbedtls_platform_zeroize( seed, sizeof( seed ) );
422 return( ret );
423 }
424
mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t len)425 int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
426 const unsigned char *additional, size_t len )
427 {
428 return( mbedtls_ctr_drbg_reseed_internal( ctx, additional, len, 0 ) );
429 }
430
431 /* Return a "good" nonce length for CTR_DRBG. The chosen nonce length
432 * is sufficient to achieve the maximum security strength given the key
433 * size and entropy length. If there is enough entropy in the initial
434 * call to the entropy function to serve as both the entropy input and
435 * the nonce, don't make a second call to get a nonce. */
good_nonce_len(size_t entropy_len)436 static size_t good_nonce_len( size_t entropy_len )
437 {
438 if( entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 )
439 return( 0 );
440 else
441 return( ( entropy_len + 1 ) / 2 );
442 }
443
444 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2)
445 * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
446 * implements
447 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
448 * security_strength) -> initial_working_state
449 * with inputs
450 * custom[:len] = nonce || personalization_string
451 * where entropy_input comes from f_entropy for ctx->entropy_len bytes
452 * and with outputs
453 * ctx = initial_working_state
454 */
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)455 int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
456 int (*f_entropy)(void *, unsigned char *, size_t),
457 void *p_entropy,
458 const unsigned char *custom,
459 size_t len )
460 {
461 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
462 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
463 size_t nonce_len;
464
465 memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
466
467 mbedtls_aes_init( &ctx->aes_ctx );
468
469 ctx->f_entropy = f_entropy;
470 ctx->p_entropy = p_entropy;
471
472 if( ctx->entropy_len == 0 )
473 ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
474 /* ctx->reseed_counter contains the desired amount of entropy to
475 * grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()).
476 * If it's -1, indicating that the entropy nonce length was not set
477 * explicitly, use a sufficiently large nonce for security. */
478 nonce_len = ( ctx->reseed_counter >= 0 ?
479 (size_t) ctx->reseed_counter :
480 good_nonce_len( ctx->entropy_len ) );
481
482 /* Initialize with an empty key. */
483 if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key,
484 MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
485 {
486 return( ret );
487 }
488
489 /* Do the initial seeding. */
490 if( ( ret = mbedtls_ctr_drbg_reseed_internal( ctx, custom, len,
491 nonce_len ) ) != 0 )
492 {
493 return( ret );
494 }
495 return( 0 );
496 }
497
498 /* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2)
499 * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
500 * implements
501 * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len])
502 * -> working_state_after_reseed
503 * if required, then
504 * CTR_DRBG_Generate(working_state_after_reseed,
505 * requested_number_of_bits, additional_input)
506 * -> status, returned_bits, new_working_state
507 * with inputs
508 * ctx contains working_state
509 * requested_number_of_bits = 8 * output_len
510 * additional[:add_len] = additional_input
511 * and entropy_input comes from calling ctx->f_entropy
512 * and with outputs
513 * status = SUCCESS (this function does the reseed internally)
514 * returned_bits = output[:output_len]
515 * ctx contains new_working_state
516 */
mbedtls_ctr_drbg_random_with_add(void * p_rng,unsigned char * output,size_t output_len,const unsigned char * additional,size_t add_len)517 int mbedtls_ctr_drbg_random_with_add( void *p_rng,
518 unsigned char *output, size_t output_len,
519 const unsigned char *additional, size_t add_len )
520 {
521 int ret = 0;
522 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
523 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
524 unsigned char *p = output;
525 unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
526 int i;
527 size_t use_len;
528
529 if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST )
530 return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
531
532 if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT )
533 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
534
535 memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
536
537 if( ctx->reseed_counter > ctx->reseed_interval ||
538 ctx->prediction_resistance )
539 {
540 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
541 {
542 return( ret );
543 }
544 add_len = 0;
545 }
546
547 if( add_len > 0 )
548 {
549 if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
550 goto exit;
551 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
552 goto exit;
553 }
554
555 while( output_len > 0 )
556 {
557 /*
558 * Increase counter
559 */
560 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
561 if( ++ctx->counter[i - 1] != 0 )
562 break;
563
564 /*
565 * Crypt counter block
566 */
567 if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
568 ctx->counter, tmp ) ) != 0 )
569 {
570 goto exit;
571 }
572
573 use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE )
574 ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
575 /*
576 * Copy random block to destination
577 */
578 memcpy( p, tmp, use_len );
579 p += use_len;
580 output_len -= use_len;
581 }
582
583 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
584 goto exit;
585
586 ctx->reseed_counter++;
587
588 exit:
589 mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
590 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
591 return( ret );
592 }
593
mbedtls_ctr_drbg_random(void * p_rng,unsigned char * output,size_t output_len)594 int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output,
595 size_t output_len )
596 {
597 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
598 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
599
600 #if defined(MBEDTLS_THREADING_C)
601 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
602 return( ret );
603 #endif
604
605 ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 );
606
607 #if defined(MBEDTLS_THREADING_C)
608 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
609 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
610 #endif
611
612 return( ret );
613 }
614
615 #if defined(MBEDTLS_FS_IO)
mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context * ctx,const char * path)616 int 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 if( ( ret = mbedtls_ctr_drbg_random( ctx, buf,
627 MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
628 goto exit;
629
630 if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) !=
631 MBEDTLS_CTR_DRBG_MAX_INPUT )
632 {
633 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
634 }
635 else
636 {
637 ret = 0;
638 }
639
640 exit:
641 mbedtls_platform_zeroize( buf, sizeof( buf ) );
642
643 fclose( f );
644 return( ret );
645 }
646
mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context * ctx,const char * path)647 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx,
648 const char *path )
649 {
650 int ret = 0;
651 FILE *f = NULL;
652 size_t n;
653 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
654 unsigned char c;
655
656 if( ( f = fopen( path, "rb" ) ) == NULL )
657 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
658
659 n = fread( buf, 1, sizeof( buf ), f );
660 if( fread( &c, 1, 1, f ) != 0 )
661 {
662 ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
663 goto exit;
664 }
665 if( n == 0 || ferror( f ) )
666 {
667 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
668 goto exit;
669 }
670 fclose( f );
671 f = NULL;
672
673 ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
674
675 exit:
676 mbedtls_platform_zeroize( buf, sizeof( buf ) );
677 if( f != NULL )
678 fclose( f );
679 if( ret != 0 )
680 return( ret );
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 static const unsigned char entropy_source_pr[96] =
688 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
689 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
690 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
691 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
692 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
693 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
694 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
695 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
696 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
697 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
698 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
699 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
700
701 static const unsigned char entropy_source_nopr[64] =
702 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
703 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
704 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
705 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
706 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
707 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
708 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
709 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
710
711 static const unsigned char nonce_pers_pr[16] =
712 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
713 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
714
715 static const unsigned char nonce_pers_nopr[16] =
716 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
717 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
718
719 #if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
720 static const unsigned char result_pr[16] =
721 { 0x95, 0x3c, 0xa5, 0xbd, 0x44, 0x1, 0x34, 0xb7,
722 0x13, 0x58, 0x3e, 0x6a, 0x6c, 0x7e, 0x88, 0x8a };
723
724 static const unsigned char result_nopr[16] =
725 { 0x6c, 0x25, 0x27, 0x95, 0xa3, 0x62, 0xd6, 0xdb,
726 0x90, 0xfd, 0x69, 0xb5, 0x42, 0x9, 0x4b, 0x84 };
727 #else /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
728 static const unsigned char result_pr[16] =
729 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
730 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
731
732 static const unsigned char result_nopr[16] =
733 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
734 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
735 #endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
736
737 static size_t test_offset;
ctr_drbg_self_test_entropy(void * data,unsigned char * buf,size_t len)738 static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
739 size_t len )
740 {
741 const unsigned char *p = data;
742 memcpy( buf, p + test_offset, len );
743 test_offset += len;
744 return( 0 );
745 }
746
747 #define CHK( c ) if( (c) != 0 ) \
748 { \
749 if( verbose != 0 ) \
750 mbedtls_printf( "failed\n" ); \
751 return( 1 ); \
752 }
753
754 /*
755 * Checkup routine
756 */
mbedtls_ctr_drbg_self_test(int verbose)757 int mbedtls_ctr_drbg_self_test( int verbose )
758 {
759 mbedtls_ctr_drbg_context ctx;
760 unsigned char buf[16];
761
762 mbedtls_ctr_drbg_init( &ctx );
763
764 /*
765 * Based on a NIST CTR_DRBG test vector (PR = True)
766 */
767 if( verbose != 0 )
768 mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
769
770 test_offset = 0;
771 mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
772 mbedtls_ctr_drbg_set_nonce_len( &ctx, 0 );
773 CHK( mbedtls_ctr_drbg_seed( &ctx,
774 ctr_drbg_self_test_entropy,
775 (void *) entropy_source_pr,
776 nonce_pers_pr, 16 ) );
777 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
778 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
779 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
780 CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
781
782 mbedtls_ctr_drbg_free( &ctx );
783
784 if( verbose != 0 )
785 mbedtls_printf( "passed\n" );
786
787 /*
788 * Based on a NIST CTR_DRBG test vector (PR = FALSE)
789 */
790 if( verbose != 0 )
791 mbedtls_printf( " CTR_DRBG (PR = FALSE): " );
792
793 mbedtls_ctr_drbg_init( &ctx );
794
795 test_offset = 0;
796 mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
797 mbedtls_ctr_drbg_set_nonce_len( &ctx, 0 );
798 CHK( mbedtls_ctr_drbg_seed( &ctx,
799 ctr_drbg_self_test_entropy,
800 (void *) entropy_source_nopr,
801 nonce_pers_nopr, 16 ) );
802 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
803 CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
804 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
805 CHK( memcmp( buf, result_nopr, 16 ) );
806
807 mbedtls_ctr_drbg_free( &ctx );
808
809 if( verbose != 0 )
810 mbedtls_printf( "passed\n" );
811
812 if( verbose != 0 )
813 mbedtls_printf( "\n" );
814
815 return( 0 );
816 }
817 #endif /* MBEDTLS_SELF_TEST */
818
819 #endif /* MBEDTLS_CTR_DRBG_C */
820