blob: 6611c3d7b73460548714cabcc26565bae086ce57 [file] [log] [blame]
Paul Bakker0e04d0e2011-11-27 14:46:59 +00001/*
2 * CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
3 *
4 * Copyright (C) 2006-2011, Brainspark B.V.
5 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * The NIST SP 800-90 DRBGs are described in the following publucation.
27 *
28 * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
29 */
30
31#include "polarssl/config.h"
32
33#if defined(POLARSSL_CTR_DRBG_C)
34
35#include "polarssl/ctr_drbg.h"
36
Paul Bakkerfc754a92011-12-05 13:23:51 +000037#if defined(POLARSSL_FS_IO)
38#include <stdio.h>
39#endif
40
Paul Bakker0e04d0e2011-11-27 14:46:59 +000041int ctr_drbg_init( ctr_drbg_context *ctx,
42 int (*f_entropy)(void *, unsigned char *, size_t),
43 void *p_entropy,
Paul Bakker1bc9efc2011-12-03 11:29:32 +000044 const unsigned char *custom,
Paul Bakker0e04d0e2011-11-27 14:46:59 +000045 size_t len )
46{
47 int ret;
Paul Bakker2bc7cf12011-11-29 10:50:51 +000048 unsigned char key[CTR_DRBG_KEYSIZE];
Paul Bakker0e04d0e2011-11-27 14:46:59 +000049
50 memset( ctx, 0, sizeof(ctr_drbg_context) );
Paul Bakker2bc7cf12011-11-29 10:50:51 +000051 memset( key, 0, CTR_DRBG_KEYSIZE );
Paul Bakker0e04d0e2011-11-27 14:46:59 +000052
53 ctx->f_entropy = f_entropy;
54 ctx->p_entropy = p_entropy;
55
56 ctx->entropy_len = CTR_DRBG_ENTROPY_LEN;
57 ctx->reseed_interval = CTR_DRBG_RESEED_INTERVAL;
58
59 /*
60 * Initialize with an empty key
61 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +000062 aes_setkey_enc( &ctx->aes_ctx, key, CTR_DRBG_KEYBITS );
Paul Bakker0e04d0e2011-11-27 14:46:59 +000063
64 if( ( ret = ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
65 return( ret );
66
67 return( 0 );
68}
69
70void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx, int resistance )
71{
72 ctx->prediction_resistance = resistance;
73}
74
75void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx, size_t len )
76{
77 ctx->entropy_len = len;
78}
79
80void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx, int interval )
81{
82 ctx->reseed_interval = interval;
83}
84
Paul Bakker1bc9efc2011-12-03 11:29:32 +000085int block_cipher_df( unsigned char *output,
86 const unsigned char *data, size_t data_len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +000087{
Paul Bakker2bc7cf12011-11-29 10:50:51 +000088 unsigned char buf[CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16];
Paul Bakker0e04d0e2011-11-27 14:46:59 +000089 unsigned char tmp[CTR_DRBG_SEEDLEN];
Paul Bakker2bc7cf12011-11-29 10:50:51 +000090 unsigned char key[CTR_DRBG_KEYSIZE];
91 unsigned char chain[CTR_DRBG_BLOCKSIZE];
92 unsigned char *p = buf, *iv;
Paul Bakker0e04d0e2011-11-27 14:46:59 +000093 aes_context aes_ctx;
94
95 int i, j, buf_len, use_len;
96
Paul Bakker2bc7cf12011-11-29 10:50:51 +000097 memset( buf, 0, CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16 );
Paul Bakker0e04d0e2011-11-27 14:46:59 +000098
99 /*
100 * Construct IV (16 bytes) and S in buffer
101 * IV = Counter (in 32-bits) padded to 16 with zeroes
102 * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
103 * data || 0x80
104 * (Total is padded to a multiple of 16-bytes with zeroes)
105 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000106 p = buf + CTR_DRBG_BLOCKSIZE;
107 *p++ = ( data_len >> 24 ) & 0xff;
108 *p++ = ( data_len >> 16 ) & 0xff;
109 *p++ = ( data_len >> 8 ) & 0xff;
110 *p++ = ( data_len ) & 0xff;
111 p += 3;
112 *p++ = CTR_DRBG_SEEDLEN;
113 memcpy( p, data, data_len );
114 p[data_len] = 0x80;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000115
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000116 buf_len = CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000117
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000118 for( i = 0; i < CTR_DRBG_KEYSIZE; i++ )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000119 key[i] = i;
120
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000121 aes_setkey_enc( &aes_ctx, key, CTR_DRBG_KEYBITS );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000122
123 /*
124 * Reduce data to POLARSSL_CTR_DRBG_SEEDLEN bytes of data
125 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000126 for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000127 {
128 p = buf;
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000129 memset( chain, 0, CTR_DRBG_BLOCKSIZE );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000130 use_len = buf_len;
131
132 while( use_len > 0 )
133 {
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000134 for( i = 0; i < CTR_DRBG_BLOCKSIZE; i++ )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000135 chain[i] ^= p[i];
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000136 p += CTR_DRBG_BLOCKSIZE;
137 use_len -= CTR_DRBG_BLOCKSIZE;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000138
139 aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, chain, chain );
140 }
141
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000142 memcpy( tmp + j, chain, CTR_DRBG_BLOCKSIZE );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000143
144 /*
145 * Update IV
146 */
147 buf[3]++;
148 }
149
150 /*
151 * Do final encryption with reduced data
152 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000153 aes_setkey_enc( &aes_ctx, tmp, CTR_DRBG_KEYBITS );
154 iv = tmp + CTR_DRBG_KEYSIZE;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000155 p = output;
156
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000157 for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000158 {
159 aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, iv, iv );
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000160 memcpy( p, iv, CTR_DRBG_BLOCKSIZE );
161 p += CTR_DRBG_BLOCKSIZE;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000162 }
163
164 return( 0 );
165}
166
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000167int ctr_drbg_update_internal( ctr_drbg_context *ctx,
168 const unsigned char data[CTR_DRBG_SEEDLEN] )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000169{
170 unsigned char tmp[CTR_DRBG_SEEDLEN];
171 unsigned char *p = tmp;
172 int cb, i, j;
173
174 memset( tmp, 0, CTR_DRBG_SEEDLEN );
175
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000176 for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000177 {
178 /*
179 * Increase counter
180 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000181 i = CTR_DRBG_BLOCKSIZE - 1;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000182 do {
183 ctx->counter[i]++;
184 cb = ctx->counter[i] == 0;
185 } while( i-- && cb );
186
187 /*
188 * Crypt counter block
189 */
190 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, p );
191
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000192 p += CTR_DRBG_BLOCKSIZE;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000193 }
194
195 for( i = 0; i < CTR_DRBG_SEEDLEN; i++ )
196 tmp[i] ^= data[i];
197
198 /*
199 * Update key and counter
200 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000201 aes_setkey_enc( &ctx->aes_ctx, tmp, CTR_DRBG_KEYBITS );
202 memcpy( ctx->counter, tmp + CTR_DRBG_KEYSIZE, CTR_DRBG_BLOCKSIZE );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000203
204 return( 0 );
205}
206
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000207void ctr_drbg_update( ctr_drbg_context *ctx,
208 const unsigned char *additional, size_t add_len )
209{
210 unsigned char add_input[CTR_DRBG_SEEDLEN];
211
212 if( add_len > 0 )
213 {
214 block_cipher_df( add_input, additional, add_len );
215 ctr_drbg_update_internal( ctx, add_input );
216 }
217}
218
219int ctr_drbg_reseed( ctr_drbg_context *ctx,
220 const unsigned char *additional, size_t len )
221{
222 unsigned char seed[CTR_DRBG_MAX_SEED_INPUT];
223 size_t seedlen = 0;
224
225 if( ctx->entropy_len + len > CTR_DRBG_MAX_SEED_INPUT )
226 return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
227
228 memset( seed, 0, CTR_DRBG_MAX_SEED_INPUT );
229
230 /*
231 * Gather POLARSSL_CTR_DRBG_ENTROPYLEN bytes of entropy to seed state
232 */
233 if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
234 ctx->entropy_len ) )
235 {
236 return( POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
237 }
238
239 seedlen += ctx->entropy_len;
240
241 /*
242 * Add additional data
243 */
244 if( additional && len )
245 {
246 memcpy( seed + seedlen, additional, len );
247 seedlen += len;
248 }
249
250 /*
251 * Reduce to 384 bits
252 */
253 block_cipher_df( seed, seed, seedlen );
254
255 /*
256 * Update state
257 */
258 ctr_drbg_update_internal( ctx, seed );
259 ctx->reseed_counter = 1;
260
261 return( 0 );
262}
263
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000264int ctr_drbg_random_with_add( void *p_rng,
265 unsigned char *output, size_t output_len,
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000266 const unsigned char *additional, size_t add_len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000267{
268 int ret = 0;
269 ctr_drbg_context *ctx = (ctr_drbg_context *) p_rng;
270 unsigned char add_input[CTR_DRBG_SEEDLEN];
271 unsigned char *p = output;
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000272 unsigned char tmp[CTR_DRBG_BLOCKSIZE];
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000273 int cb, i;
Paul Bakker23fd5ea2011-11-29 15:56:12 +0000274 size_t use_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000275
276 if( output_len > CTR_DRBG_MAX_REQUEST )
277 return( POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG );
278
279 if( add_len > CTR_DRBG_MAX_INPUT )
280 return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
281
282 memset( add_input, 0, CTR_DRBG_SEEDLEN );
283
284 if( ctx->reseed_counter > ctx->reseed_interval ||
285 ctx->prediction_resistance )
286 {
287 if( ( ret = ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
288 return( ret );
289
290 add_len = 0;
291 }
292
293 if( add_len > 0 )
294 {
295 block_cipher_df( add_input, additional, add_len );
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000296 ctr_drbg_update_internal( ctx, add_input );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000297 }
298
299 while( output_len > 0 )
300 {
301 /*
302 * Increase counter
303 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000304 i = CTR_DRBG_BLOCKSIZE - 1;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000305 do {
306 ctx->counter[i]++;
307 cb = ctx->counter[i] == 0;
308 } while( i-- && cb );
309
310 /*
311 * Crypt counter block
312 */
313 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, tmp );
314
Paul Bakker23fd5ea2011-11-29 15:56:12 +0000315 use_len = (output_len > CTR_DRBG_BLOCKSIZE ) ? CTR_DRBG_BLOCKSIZE : output_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000316 /*
317 * Copy random block to destination
318 */
Paul Bakker23fd5ea2011-11-29 15:56:12 +0000319 memcpy( p, tmp, use_len );
320 p += use_len;
321 output_len -= use_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000322 }
323
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000324 ctr_drbg_update_internal( ctx, add_input );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000325
326 ctx->reseed_counter++;
327
328 return( 0 );
329}
330
331int ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
332{
333 return ctr_drbg_random_with_add( p_rng, output, output_len, NULL, 0 );
334}
335
Paul Bakkerfc754a92011-12-05 13:23:51 +0000336#if defined(POLARSSL_FS_IO)
337int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path )
338{
339 int ret;
340 FILE *f;
341 unsigned char buf[ CTR_DRBG_MAX_INPUT ];
342
343 if( ( f = fopen( path, "wb" ) ) == NULL )
344 return( 1 );
345
346 if( ( ret = ctr_drbg_random( ctx, buf, CTR_DRBG_MAX_INPUT ) ) != 0 )
347 return( ret );
348
349 if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT )
350 {
351 fclose( f );
352 return( 1 );
353 }
354
355 fclose( f );
356 return( 0 );
357}
358
359int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path )
360{
361 FILE *f;
362 size_t n;
363 unsigned char buf[ CTR_DRBG_MAX_INPUT ];
364
365 if( ( f = fopen( path, "rb" ) ) == NULL )
366 return( 1 );
367
368 fseek( f, 0, SEEK_END );
369 n = (size_t) ftell( f );
370 fseek( f, 0, SEEK_SET );
371
372 if( n > CTR_DRBG_MAX_INPUT )
373 return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
374
375 if( fread( buf, 1, n, f ) != n )
376 {
377 fclose( f );
378 return( 1 );
379 }
380
381 ctr_drbg_update( ctx, buf, n );
382
383 fclose( f );
384
385 return( ctr_drbg_write_seed_file( ctx, path ) );
386}
387#endif /* POLARSSL_FS_IO */
388
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000389#if defined(POLARSSL_SELF_TEST)
390
391#include <stdio.h>
392
393unsigned char entropy_source_pr[96] =
394 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
395 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
396 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
397 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
398 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
399 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
400 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
401 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
402 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
403 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
404 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
405 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
406
407unsigned char entropy_source_nopr[64] =
408 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
409 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
410 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
411 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
412 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
413 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
414 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
415 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
416
417unsigned char nonce_pers_pr[16] =
418 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
419 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
420
421unsigned char nonce_pers_nopr[16] =
422 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
423 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
424
425unsigned char result_pr[16] =
426 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
427 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
428
429unsigned char result_nopr[16] =
430 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
431 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
432
433int test_offset;
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000434int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, size_t len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000435{
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000436 unsigned char *p = data;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000437 memcpy( buf, p + test_offset, len );
438 test_offset += 32;
439 return( 0 );
440}
441
442/*
443 * Checkup routine
444 */
445int ctr_drbg_self_test( int verbose )
446{
447 ctr_drbg_context ctx;
448 unsigned char buf[16];
449
450 /*
451 * Based on a NIST CTR_DRBG test vector (PR = True)
452 */
453 if( verbose != 0 )
454 printf( " CTR_DRBG (PR = TRUE) : " );
455
456 test_offset = 0;
457 if( ctr_drbg_init( &ctx, ctr_drbg_self_test_entropy, entropy_source_pr, nonce_pers_pr, 16 ) != 0 )
458 {
459 if( verbose != 0 )
460 printf( "failed\n" );
461
462 return( 1 );
463 }
464 ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON );
465
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000466 if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000467 {
468 if( verbose != 0 )
469 printf( "failed\n" );
470
471 return( 1 );
472 }
473
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000474 if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000475 {
476 if( verbose != 0 )
477 printf( "failed\n" );
478
479 return( 1 );
480 }
481
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000482 if( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) != 0 )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000483 {
484 if( verbose != 0 )
485 printf( "failed\n" );
486
487 return( 1 );
488 }
489
490 if( verbose != 0 )
491 printf( "passed\n" );
492
493 /*
494 * Based on a NIST CTR_DRBG test vector (PR = FALSE)
495 */
496 if( verbose != 0 )
497 printf( " CTR_DRBG (PR = FALSE): " );
498
499 test_offset = 0;
500 if( ctr_drbg_init( &ctx, ctr_drbg_self_test_entropy, entropy_source_nopr, nonce_pers_nopr, 16 ) != 0 )
501 {
502 if( verbose != 0 )
503 printf( "failed\n" );
504
505 return( 1 );
506 }
507
508 if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
509 {
510 if( verbose != 0 )
511 printf( "failed\n" );
512
513 return( 1 );
514 }
515
516 if( ctr_drbg_reseed( &ctx, NULL, 0 ) != 0 )
517 {
518 if( verbose != 0 )
519 printf( "failed\n" );
520
521 return( 1 );
522 }
523
524 if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
525 {
526 if( verbose != 0 )
527 printf( "failed\n" );
528
529 return( 1 );
530 }
531
532 if( memcmp( buf, result_nopr, 16 ) != 0 )
533 {
534 if( verbose != 0 )
535 printf( "failed\n" );
536
537 return( 1 );
538 }
539
540 if( verbose != 0 )
541 printf( "passed\n" );
542
543 if( verbose != 0 )
544 printf( "\n" );
545
546 return( 0 );
547}
548#endif
549
550#endif