blob: 882d68618d4cebc84dc20db21444f18bf62d1cf0 [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 Bakker18d32912011-12-10 21:42:49 +000041/*
42 * Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST
43 * tests to succeed (which require known length fixed entropy)
44 */
45int ctr_drbg_init_entropy_len(
46 ctr_drbg_context *ctx,
Paul Bakker0e04d0e2011-11-27 14:46:59 +000047 int (*f_entropy)(void *, unsigned char *, size_t),
48 void *p_entropy,
Paul Bakker1bc9efc2011-12-03 11:29:32 +000049 const unsigned char *custom,
Paul Bakker18d32912011-12-10 21:42:49 +000050 size_t len,
51 size_t entropy_len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +000052{
53 int ret;
Paul Bakker2bc7cf12011-11-29 10:50:51 +000054 unsigned char key[CTR_DRBG_KEYSIZE];
Paul Bakker0e04d0e2011-11-27 14:46:59 +000055
56 memset( ctx, 0, sizeof(ctr_drbg_context) );
Paul Bakker2bc7cf12011-11-29 10:50:51 +000057 memset( key, 0, CTR_DRBG_KEYSIZE );
Paul Bakker0e04d0e2011-11-27 14:46:59 +000058
59 ctx->f_entropy = f_entropy;
60 ctx->p_entropy = p_entropy;
61
Paul Bakker18d32912011-12-10 21:42:49 +000062 ctx->entropy_len = entropy_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +000063 ctx->reseed_interval = CTR_DRBG_RESEED_INTERVAL;
64
65 /*
66 * Initialize with an empty key
67 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +000068 aes_setkey_enc( &ctx->aes_ctx, key, CTR_DRBG_KEYBITS );
Paul Bakker0e04d0e2011-11-27 14:46:59 +000069
70 if( ( ret = ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
71 return( ret );
72
73 return( 0 );
74}
75
Paul Bakker18d32912011-12-10 21:42:49 +000076int ctr_drbg_init( 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{
82 return( ctr_drbg_init_entropy_len( ctx, f_entropy, p_entropy, custom, len,
83 CTR_DRBG_ENTROPY_LEN ) );
84}
85
Paul Bakker0e04d0e2011-11-27 14:46:59 +000086void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx, int resistance )
87{
88 ctx->prediction_resistance = resistance;
89}
90
91void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx, size_t len )
92{
93 ctx->entropy_len = len;
94}
95
96void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx, int interval )
97{
98 ctx->reseed_interval = interval;
99}
100
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000101int block_cipher_df( unsigned char *output,
102 const unsigned char *data, size_t data_len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000103{
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000104 unsigned char buf[CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16];
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000105 unsigned char tmp[CTR_DRBG_SEEDLEN];
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000106 unsigned char key[CTR_DRBG_KEYSIZE];
107 unsigned char chain[CTR_DRBG_BLOCKSIZE];
108 unsigned char *p = buf, *iv;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000109 aes_context aes_ctx;
110
111 int i, j, buf_len, use_len;
112
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000113 memset( buf, 0, CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16 );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000114
115 /*
116 * Construct IV (16 bytes) and S in buffer
117 * IV = Counter (in 32-bits) padded to 16 with zeroes
118 * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
119 * data || 0x80
120 * (Total is padded to a multiple of 16-bytes with zeroes)
121 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000122 p = buf + CTR_DRBG_BLOCKSIZE;
123 *p++ = ( data_len >> 24 ) & 0xff;
124 *p++ = ( data_len >> 16 ) & 0xff;
125 *p++ = ( data_len >> 8 ) & 0xff;
126 *p++ = ( data_len ) & 0xff;
127 p += 3;
128 *p++ = CTR_DRBG_SEEDLEN;
129 memcpy( p, data, data_len );
130 p[data_len] = 0x80;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000131
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000132 buf_len = CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000133
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000134 for( i = 0; i < CTR_DRBG_KEYSIZE; i++ )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000135 key[i] = i;
136
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000137 aes_setkey_enc( &aes_ctx, key, CTR_DRBG_KEYBITS );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000138
139 /*
140 * Reduce data to POLARSSL_CTR_DRBG_SEEDLEN bytes of data
141 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000142 for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000143 {
144 p = buf;
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000145 memset( chain, 0, CTR_DRBG_BLOCKSIZE );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000146 use_len = buf_len;
147
148 while( use_len > 0 )
149 {
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000150 for( i = 0; i < CTR_DRBG_BLOCKSIZE; i++ )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000151 chain[i] ^= p[i];
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000152 p += CTR_DRBG_BLOCKSIZE;
153 use_len -= CTR_DRBG_BLOCKSIZE;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000154
155 aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, chain, chain );
156 }
157
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000158 memcpy( tmp + j, chain, CTR_DRBG_BLOCKSIZE );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000159
160 /*
161 * Update IV
162 */
163 buf[3]++;
164 }
165
166 /*
167 * Do final encryption with reduced data
168 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000169 aes_setkey_enc( &aes_ctx, tmp, CTR_DRBG_KEYBITS );
170 iv = tmp + CTR_DRBG_KEYSIZE;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000171 p = output;
172
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000173 for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000174 {
175 aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, iv, iv );
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000176 memcpy( p, iv, CTR_DRBG_BLOCKSIZE );
177 p += CTR_DRBG_BLOCKSIZE;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000178 }
179
180 return( 0 );
181}
182
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000183int ctr_drbg_update_internal( ctr_drbg_context *ctx,
184 const unsigned char data[CTR_DRBG_SEEDLEN] )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000185{
186 unsigned char tmp[CTR_DRBG_SEEDLEN];
187 unsigned char *p = tmp;
188 int cb, i, j;
189
190 memset( tmp, 0, CTR_DRBG_SEEDLEN );
191
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000192 for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000193 {
194 /*
195 * Increase counter
196 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000197 i = CTR_DRBG_BLOCKSIZE - 1;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000198 do {
199 ctx->counter[i]++;
200 cb = ctx->counter[i] == 0;
201 } while( i-- && cb );
202
203 /*
204 * Crypt counter block
205 */
206 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, p );
207
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000208 p += CTR_DRBG_BLOCKSIZE;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000209 }
210
211 for( i = 0; i < CTR_DRBG_SEEDLEN; i++ )
212 tmp[i] ^= data[i];
213
214 /*
215 * Update key and counter
216 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000217 aes_setkey_enc( &ctx->aes_ctx, tmp, CTR_DRBG_KEYBITS );
218 memcpy( ctx->counter, tmp + CTR_DRBG_KEYSIZE, CTR_DRBG_BLOCKSIZE );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000219
220 return( 0 );
221}
222
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000223void ctr_drbg_update( ctr_drbg_context *ctx,
224 const unsigned char *additional, size_t add_len )
225{
226 unsigned char add_input[CTR_DRBG_SEEDLEN];
227
228 if( add_len > 0 )
229 {
230 block_cipher_df( add_input, additional, add_len );
231 ctr_drbg_update_internal( ctx, add_input );
232 }
233}
234
235int ctr_drbg_reseed( ctr_drbg_context *ctx,
236 const unsigned char *additional, size_t len )
237{
238 unsigned char seed[CTR_DRBG_MAX_SEED_INPUT];
239 size_t seedlen = 0;
240
241 if( ctx->entropy_len + len > CTR_DRBG_MAX_SEED_INPUT )
242 return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
243
244 memset( seed, 0, CTR_DRBG_MAX_SEED_INPUT );
245
246 /*
Paul Bakker69e095c2011-12-10 21:55:01 +0000247 * Gather enropy_len bytes of entropy to seed state
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000248 */
249 if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
250 ctx->entropy_len ) )
251 {
252 return( POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
253 }
254
255 seedlen += ctx->entropy_len;
256
257 /*
258 * Add additional data
259 */
260 if( additional && len )
261 {
262 memcpy( seed + seedlen, additional, len );
263 seedlen += len;
264 }
265
266 /*
267 * Reduce to 384 bits
268 */
269 block_cipher_df( seed, seed, seedlen );
270
271 /*
272 * Update state
273 */
274 ctr_drbg_update_internal( ctx, seed );
275 ctx->reseed_counter = 1;
276
277 return( 0 );
278}
279
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000280int ctr_drbg_random_with_add( void *p_rng,
281 unsigned char *output, size_t output_len,
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000282 const unsigned char *additional, size_t add_len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000283{
284 int ret = 0;
285 ctr_drbg_context *ctx = (ctr_drbg_context *) p_rng;
286 unsigned char add_input[CTR_DRBG_SEEDLEN];
287 unsigned char *p = output;
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000288 unsigned char tmp[CTR_DRBG_BLOCKSIZE];
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000289 int cb, i;
Paul Bakker23fd5ea2011-11-29 15:56:12 +0000290 size_t use_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000291
292 if( output_len > CTR_DRBG_MAX_REQUEST )
293 return( POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG );
294
295 if( add_len > CTR_DRBG_MAX_INPUT )
296 return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
297
298 memset( add_input, 0, CTR_DRBG_SEEDLEN );
299
300 if( ctx->reseed_counter > ctx->reseed_interval ||
301 ctx->prediction_resistance )
302 {
303 if( ( ret = ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
304 return( ret );
305
306 add_len = 0;
307 }
308
309 if( add_len > 0 )
310 {
311 block_cipher_df( add_input, additional, add_len );
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000312 ctr_drbg_update_internal( ctx, add_input );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000313 }
314
315 while( output_len > 0 )
316 {
317 /*
318 * Increase counter
319 */
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000320 i = CTR_DRBG_BLOCKSIZE - 1;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000321 do {
322 ctx->counter[i]++;
323 cb = ctx->counter[i] == 0;
324 } while( i-- && cb );
325
326 /*
327 * Crypt counter block
328 */
329 aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, tmp );
330
Paul Bakker23fd5ea2011-11-29 15:56:12 +0000331 use_len = (output_len > CTR_DRBG_BLOCKSIZE ) ? CTR_DRBG_BLOCKSIZE : output_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000332 /*
333 * Copy random block to destination
334 */
Paul Bakker23fd5ea2011-11-29 15:56:12 +0000335 memcpy( p, tmp, use_len );
336 p += use_len;
337 output_len -= use_len;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000338 }
339
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000340 ctr_drbg_update_internal( ctx, add_input );
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000341
342 ctx->reseed_counter++;
343
344 return( 0 );
345}
346
347int ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
348{
349 return ctr_drbg_random_with_add( p_rng, output, output_len, NULL, 0 );
350}
351
Paul Bakkerfc754a92011-12-05 13:23:51 +0000352#if defined(POLARSSL_FS_IO)
353int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path )
354{
355 int ret;
356 FILE *f;
357 unsigned char buf[ CTR_DRBG_MAX_INPUT ];
358
359 if( ( f = fopen( path, "wb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000360 return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000361
362 if( ( ret = ctr_drbg_random( ctx, buf, CTR_DRBG_MAX_INPUT ) ) != 0 )
363 return( ret );
364
365 if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT )
366 {
367 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000368 return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000369 }
370
371 fclose( f );
372 return( 0 );
373}
374
375int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path )
376{
377 FILE *f;
378 size_t n;
379 unsigned char buf[ CTR_DRBG_MAX_INPUT ];
380
381 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000382 return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000383
384 fseek( f, 0, SEEK_END );
385 n = (size_t) ftell( f );
386 fseek( f, 0, SEEK_SET );
387
388 if( n > CTR_DRBG_MAX_INPUT )
389 return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
390
391 if( fread( buf, 1, n, f ) != n )
392 {
393 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000394 return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000395 }
396
397 ctr_drbg_update( ctx, buf, n );
398
399 fclose( f );
400
401 return( ctr_drbg_write_seed_file( ctx, path ) );
402}
403#endif /* POLARSSL_FS_IO */
404
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000405#if defined(POLARSSL_SELF_TEST)
406
407#include <stdio.h>
408
409unsigned char entropy_source_pr[96] =
410 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
411 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
412 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
413 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
414 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
415 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
416 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
417 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
418 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
419 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
420 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
421 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
422
423unsigned char entropy_source_nopr[64] =
424 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
425 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
426 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
427 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
428 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
429 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
430 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
431 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
432
433unsigned char nonce_pers_pr[16] =
434 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
435 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
436
437unsigned char nonce_pers_nopr[16] =
438 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
439 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
440
441unsigned char result_pr[16] =
442 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
443 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
444
445unsigned char result_nopr[16] =
446 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
447 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
448
449int test_offset;
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000450int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, size_t len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000451{
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000452 unsigned char *p = data;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000453 memcpy( buf, p + test_offset, len );
454 test_offset += 32;
455 return( 0 );
456}
457
458/*
459 * Checkup routine
460 */
461int ctr_drbg_self_test( int verbose )
462{
463 ctr_drbg_context ctx;
464 unsigned char buf[16];
465
466 /*
467 * Based on a NIST CTR_DRBG test vector (PR = True)
468 */
469 if( verbose != 0 )
470 printf( " CTR_DRBG (PR = TRUE) : " );
471
472 test_offset = 0;
Paul Bakkere88186d2012-01-22 20:29:47 +0000473 if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_pr, nonce_pers_pr, 16, 32 ) != 0 )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000474 {
475 if( verbose != 0 )
476 printf( "failed\n" );
477
478 return( 1 );
479 }
480 ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON );
481
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000482 if( ctr_drbg_random( &ctx, buf, 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
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000490 if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000491 {
492 if( verbose != 0 )
493 printf( "failed\n" );
494
495 return( 1 );
496 }
497
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000498 if( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) != 0 )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000499 {
500 if( verbose != 0 )
501 printf( "failed\n" );
502
503 return( 1 );
504 }
505
506 if( verbose != 0 )
507 printf( "passed\n" );
508
509 /*
510 * Based on a NIST CTR_DRBG test vector (PR = FALSE)
511 */
512 if( verbose != 0 )
513 printf( " CTR_DRBG (PR = FALSE): " );
514
515 test_offset = 0;
Paul Bakkere88186d2012-01-22 20:29:47 +0000516 if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_nopr, nonce_pers_nopr, 16, 32 ) != 0 )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000517 {
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( ctr_drbg_reseed( &ctx, NULL, 0 ) != 0 )
533 {
534 if( verbose != 0 )
535 printf( "failed\n" );
536
537 return( 1 );
538 }
539
540 if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
541 {
542 if( verbose != 0 )
543 printf( "failed\n" );
544
545 return( 1 );
546 }
547
548 if( memcmp( buf, result_nopr, 16 ) != 0 )
549 {
550 if( verbose != 0 )
551 printf( "failed\n" );
552
553 return( 1 );
554 }
555
556 if( verbose != 0 )
557 printf( "passed\n" );
558
559 if( verbose != 0 )
560 printf( "\n" );
561
562 return( 0 );
563}
564#endif
565
566#endif