[LOCALSPL_WINETEST] Sync with Wine Staging 4.18. CORE-16441
[reactos.git] / dll / 3rdparty / mbedtls / ctr_drbg.c
1 /*
2 * CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * This file is part of mbed TLS (https://tls.mbed.org)
22 */
23 /*
24 * The NIST SP 800-90 DRBGs are described in the following publication.
25 *
26 * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
27 */
28
29 #if !defined(MBEDTLS_CONFIG_FILE)
30 #include "mbedtls/config.h"
31 #else
32 #include MBEDTLS_CONFIG_FILE
33 #endif
34
35 #if defined(MBEDTLS_CTR_DRBG_C)
36
37 #include "mbedtls/ctr_drbg.h"
38
39 #include <string.h>
40
41 #if defined(MBEDTLS_FS_IO)
42 #include <stdio.h>
43 #endif
44
45 #if defined(MBEDTLS_SELF_TEST)
46 #if defined(MBEDTLS_PLATFORM_C)
47 #include "mbedtls/platform.h"
48 #else
49 #include <stdio.h>
50 #define mbedtls_printf printf
51 #endif /* MBEDTLS_PLATFORM_C */
52 #endif /* MBEDTLS_SELF_TEST */
53
54 /* Implementation that should never be optimized out by the compiler */
55 static void mbedtls_zeroize( void *v, size_t n ) {
56 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
57 }
58
59 /*
60 * CTR_DRBG context initialization
61 */
62 void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
63 {
64 memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
65
66 #if defined(MBEDTLS_THREADING_C)
67 mbedtls_mutex_init( &ctx->mutex );
68 #endif
69 }
70
71 /*
72 * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
73 * NIST tests to succeed (which require known length fixed entropy)
74 */
75 int mbedtls_ctr_drbg_seed_entropy_len(
76 mbedtls_ctr_drbg_context *ctx,
77 int (*f_entropy)(void *, unsigned char *, size_t),
78 void *p_entropy,
79 const unsigned char *custom,
80 size_t len,
81 size_t entropy_len )
82 {
83 int ret;
84 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
85
86 memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
87
88 mbedtls_aes_init( &ctx->aes_ctx );
89
90 ctx->f_entropy = f_entropy;
91 ctx->p_entropy = p_entropy;
92
93 ctx->entropy_len = entropy_len;
94 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
95
96 /*
97 * Initialize with an empty key
98 */
99 if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
100 {
101 return( ret );
102 }
103
104 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
105 {
106 return( ret );
107 }
108 return( 0 );
109 }
110
111 int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
112 int (*f_entropy)(void *, unsigned char *, size_t),
113 void *p_entropy,
114 const unsigned char *custom,
115 size_t len )
116 {
117 return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len,
118 MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
119 }
120
121 void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
122 {
123 if( ctx == NULL )
124 return;
125
126 #if defined(MBEDTLS_THREADING_C)
127 mbedtls_mutex_free( &ctx->mutex );
128 #endif
129 mbedtls_aes_free( &ctx->aes_ctx );
130 mbedtls_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
131 }
132
133 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
134 {
135 ctx->prediction_resistance = resistance;
136 }
137
138 void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len )
139 {
140 ctx->entropy_len = len;
141 }
142
143 void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval )
144 {
145 ctx->reseed_interval = interval;
146 }
147
148 static int block_cipher_df( unsigned char *output,
149 const unsigned char *data, size_t data_len )
150 {
151 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
152 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
153 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
154 unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
155 unsigned char *p, *iv;
156 mbedtls_aes_context aes_ctx;
157 int ret = 0;
158
159 int i, j;
160 size_t buf_len, use_len;
161
162 if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
163 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
164
165 memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
166 mbedtls_aes_init( &aes_ctx );
167
168 /*
169 * Construct IV (16 bytes) and S in buffer
170 * IV = Counter (in 32-bits) padded to 16 with zeroes
171 * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
172 * data || 0x80
173 * (Total is padded to a multiple of 16-bytes with zeroes)
174 */
175 p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
176 *p++ = ( data_len >> 24 ) & 0xff;
177 *p++ = ( data_len >> 16 ) & 0xff;
178 *p++ = ( data_len >> 8 ) & 0xff;
179 *p++ = ( data_len ) & 0xff;
180 p += 3;
181 *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
182 memcpy( p, data, data_len );
183 p[data_len] = 0x80;
184
185 buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
186
187 for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
188 key[i] = i;
189
190 if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
191 {
192 goto exit;
193 }
194
195 /*
196 * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
197 */
198 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
199 {
200 p = buf;
201 memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE );
202 use_len = buf_len;
203
204 while( use_len > 0 )
205 {
206 for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ )
207 chain[i] ^= p[i];
208 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
209 use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
210 MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
211
212 if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ) ) != 0 )
213 {
214 goto exit;
215 }
216 }
217
218 memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
219
220 /*
221 * Update IV
222 */
223 buf[3]++;
224 }
225
226 /*
227 * Do final encryption with reduced data
228 */
229 if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
230 {
231 goto exit;
232 }
233 iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
234 p = output;
235
236 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
237 {
238 if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ) ) != 0 )
239 {
240 goto exit;
241 }
242 memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
243 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
244 }
245 exit:
246 mbedtls_aes_free( &aes_ctx );
247 /*
248 * tidy up the stack
249 */
250 mbedtls_zeroize( buf, sizeof( buf ) );
251 mbedtls_zeroize( tmp, sizeof( tmp ) );
252 mbedtls_zeroize( key, sizeof( key ) );
253 mbedtls_zeroize( chain, sizeof( chain ) );
254 if( 0 != ret )
255 {
256 /*
257 * wipe partial seed from memory
258 */
259 mbedtls_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
260 }
261
262 return( ret );
263 }
264
265 static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
266 const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
267 {
268 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
269 unsigned char *p = tmp;
270 int i, j;
271 int ret = 0;
272
273 memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
274
275 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
276 {
277 /*
278 * Increase counter
279 */
280 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
281 if( ++ctx->counter[i - 1] != 0 )
282 break;
283
284 /*
285 * Crypt counter block
286 */
287 if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 )
288 goto exit;
289
290 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
291 }
292
293 for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ )
294 tmp[i] ^= data[i];
295
296 /*
297 * Update key and counter
298 */
299 if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
300 goto exit;
301 memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
302
303 exit:
304 mbedtls_zeroize( tmp, sizeof( tmp ) );
305 return( ret );
306 }
307
308 int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
309 const unsigned char *additional,
310 size_t add_len )
311 {
312 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
313 int ret;
314
315 if( add_len == 0 )
316 return( 0 );
317
318 if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
319 goto exit;
320 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
321 goto exit;
322
323 exit:
324 mbedtls_zeroize( add_input, sizeof( add_input ) );
325 return( ret );
326 }
327
328 /* Deprecated function, kept for backward compatibility. */
329 void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
330 const unsigned char *additional,
331 size_t add_len )
332 {
333 /* MAX_INPUT would be more logical here, but we have to match
334 * block_cipher_df()'s limits since we can't propagate errors */
335 if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
336 add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
337 (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
338 }
339
340 int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
341 const unsigned char *additional, size_t len )
342 {
343 unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
344 size_t seedlen = 0;
345 int ret;
346
347 if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
348 len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
349 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
350
351 memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
352
353 /*
354 * Gather entropy_len bytes of entropy to seed state
355 */
356 if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
357 ctx->entropy_len ) )
358 {
359 return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
360 }
361
362 seedlen += ctx->entropy_len;
363
364 /*
365 * Add additional data
366 */
367 if( additional && len )
368 {
369 memcpy( seed + seedlen, additional, len );
370 seedlen += len;
371 }
372
373 /*
374 * Reduce to 384 bits
375 */
376 if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
377 goto exit;
378
379 /*
380 * Update state
381 */
382 if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
383 goto exit;
384 ctx->reseed_counter = 1;
385
386 exit:
387 mbedtls_zeroize( seed, sizeof( seed ) );
388 return( ret );
389 }
390
391 int mbedtls_ctr_drbg_random_with_add( void *p_rng,
392 unsigned char *output, size_t output_len,
393 const unsigned char *additional, size_t add_len )
394 {
395 int ret = 0;
396 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
397 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
398 unsigned char *p = output;
399 unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
400 int i;
401 size_t use_len;
402
403 if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST )
404 return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
405
406 if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT )
407 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
408
409 memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
410
411 if( ctx->reseed_counter > ctx->reseed_interval ||
412 ctx->prediction_resistance )
413 {
414 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
415 {
416 return( ret );
417 }
418 add_len = 0;
419 }
420
421 if( add_len > 0 )
422 {
423 if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
424 goto exit;
425 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
426 goto exit;
427 }
428
429 while( output_len > 0 )
430 {
431 /*
432 * Increase counter
433 */
434 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
435 if( ++ctx->counter[i - 1] != 0 )
436 break;
437
438 /*
439 * Crypt counter block
440 */
441 if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 )
442 goto exit;
443
444 use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
445 output_len;
446 /*
447 * Copy random block to destination
448 */
449 memcpy( p, tmp, use_len );
450 p += use_len;
451 output_len -= use_len;
452 }
453
454 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
455 goto exit;
456
457 ctx->reseed_counter++;
458
459 exit:
460 mbedtls_zeroize( add_input, sizeof( add_input ) );
461 mbedtls_zeroize( tmp, sizeof( tmp ) );
462 return( 0 );
463 }
464
465 int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
466 {
467 int ret;
468 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
469
470 #if defined(MBEDTLS_THREADING_C)
471 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
472 return( ret );
473 #endif
474
475 ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 );
476
477 #if defined(MBEDTLS_THREADING_C)
478 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
479 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
480 #endif
481
482 return( ret );
483 }
484
485 #if defined(MBEDTLS_FS_IO)
486 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
487 {
488 int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
489 FILE *f;
490 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
491
492 if( ( f = fopen( path, "wb" ) ) == NULL )
493 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
494
495 if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
496 goto exit;
497
498 if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT )
499 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
500 else
501 ret = 0;
502
503 exit:
504 mbedtls_zeroize( buf, sizeof( buf ) );
505
506 fclose( f );
507 return( ret );
508 }
509
510 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
511 {
512 int ret = 0;
513 FILE *f;
514 size_t n;
515 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
516
517 if( ( f = fopen( path, "rb" ) ) == NULL )
518 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
519
520 fseek( f, 0, SEEK_END );
521 n = (size_t) ftell( f );
522 fseek( f, 0, SEEK_SET );
523
524 if( n > MBEDTLS_CTR_DRBG_MAX_INPUT )
525 {
526 fclose( f );
527 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
528 }
529
530 if( fread( buf, 1, n, f ) != n )
531 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
532 else
533 ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
534
535 fclose( f );
536
537 mbedtls_zeroize( buf, sizeof( buf ) );
538
539 if( ret != 0 )
540 return( ret );
541
542 return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
543 }
544 #endif /* MBEDTLS_FS_IO */
545
546 #if defined(MBEDTLS_SELF_TEST)
547
548 static const unsigned char entropy_source_pr[96] =
549 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
550 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
551 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
552 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
553 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
554 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
555 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
556 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
557 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
558 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
559 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
560 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
561
562 static const unsigned char entropy_source_nopr[64] =
563 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
564 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
565 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
566 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
567 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
568 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
569 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
570 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
571
572 static const unsigned char nonce_pers_pr[16] =
573 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
574 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
575
576 static const unsigned char nonce_pers_nopr[16] =
577 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
578 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
579
580 static const unsigned char result_pr[16] =
581 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
582 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
583
584 static const unsigned char result_nopr[16] =
585 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
586 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
587
588 static size_t test_offset;
589 static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
590 size_t len )
591 {
592 const unsigned char *p = data;
593 memcpy( buf, p + test_offset, len );
594 test_offset += len;
595 return( 0 );
596 }
597
598 #define CHK( c ) if( (c) != 0 ) \
599 { \
600 if( verbose != 0 ) \
601 mbedtls_printf( "failed\n" ); \
602 return( 1 ); \
603 }
604
605 /*
606 * Checkup routine
607 */
608 int mbedtls_ctr_drbg_self_test( int verbose )
609 {
610 mbedtls_ctr_drbg_context ctx;
611 unsigned char buf[16];
612
613 mbedtls_ctr_drbg_init( &ctx );
614
615 /*
616 * Based on a NIST CTR_DRBG test vector (PR = True)
617 */
618 if( verbose != 0 )
619 mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
620
621 test_offset = 0;
622 CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
623 (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
624 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
625 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
626 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
627 CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
628
629 mbedtls_ctr_drbg_free( &ctx );
630
631 if( verbose != 0 )
632 mbedtls_printf( "passed\n" );
633
634 /*
635 * Based on a NIST CTR_DRBG test vector (PR = FALSE)
636 */
637 if( verbose != 0 )
638 mbedtls_printf( " CTR_DRBG (PR = FALSE): " );
639
640 mbedtls_ctr_drbg_init( &ctx );
641
642 test_offset = 0;
643 CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
644 (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
645 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
646 CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
647 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
648 CHK( memcmp( buf, result_nopr, 16 ) );
649
650 mbedtls_ctr_drbg_free( &ctx );
651
652 if( verbose != 0 )
653 mbedtls_printf( "passed\n" );
654
655 if( verbose != 0 )
656 mbedtls_printf( "\n" );
657
658 return( 0 );
659 }
660 #endif /* MBEDTLS_SELF_TEST */
661
662 #endif /* MBEDTLS_CTR_DRBG_C */