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