blob: 1e0ae190149b23515626c0e40e9b4b2215dc89a6 [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 Bakker732e1a82011-12-11 16:35:09 +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 Bakker732e1a82011-12-11 16:35:09 +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 Bakker732e1a82011-12-11 16:35:09 +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 Bakker732e1a82011-12-11 16:35:09 +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 Bakker732e1a82011-12-11 16:35:09 +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 Bakker732e1a82011-12-11 16:35:09 +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 )
Paul Bakker35138682013-09-11 13:28:00 +0200363 {
364 fclose( f );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000365 return( ret );
Paul Bakker35138682013-09-11 13:28:00 +0200366 }
Paul Bakkerfc754a92011-12-05 13:23:51 +0000367
368 if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT )
369 {
370 fclose( f );
Paul Bakker732e1a82011-12-11 16:35:09 +0000371 return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000372 }
373
374 fclose( f );
375 return( 0 );
376}
377
378int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path )
379{
380 FILE *f;
381 size_t n;
382 unsigned char buf[ CTR_DRBG_MAX_INPUT ];
383
384 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker732e1a82011-12-11 16:35:09 +0000385 return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000386
387 fseek( f, 0, SEEK_END );
388 n = (size_t) ftell( f );
389 fseek( f, 0, SEEK_SET );
390
391 if( n > CTR_DRBG_MAX_INPUT )
Paul Bakker35138682013-09-11 13:28:00 +0200392 {
393 fclose( f );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000394 return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
Paul Bakker35138682013-09-11 13:28:00 +0200395 }
Paul Bakkerfc754a92011-12-05 13:23:51 +0000396
397 if( fread( buf, 1, n, f ) != n )
398 {
399 fclose( f );
Paul Bakker732e1a82011-12-11 16:35:09 +0000400 return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
Paul Bakkerfc754a92011-12-05 13:23:51 +0000401 }
402
403 ctr_drbg_update( ctx, buf, n );
404
405 fclose( f );
406
407 return( ctr_drbg_write_seed_file( ctx, path ) );
408}
409#endif /* POLARSSL_FS_IO */
410
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000411#if defined(POLARSSL_SELF_TEST)
412
413#include <stdio.h>
414
415unsigned char entropy_source_pr[96] =
416 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
417 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
418 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
419 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
420 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
421 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
422 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
423 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
424 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
425 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
426 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
427 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
428
429unsigned char entropy_source_nopr[64] =
430 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
431 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
432 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
433 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
434 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
435 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
436 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
437 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
438
439unsigned char nonce_pers_pr[16] =
440 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
441 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
442
443unsigned char nonce_pers_nopr[16] =
444 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
445 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
446
447unsigned char result_pr[16] =
448 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
449 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
450
451unsigned char result_nopr[16] =
452 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
453 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
454
455int test_offset;
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000456int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, size_t len )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000457{
Paul Bakker1bc9efc2011-12-03 11:29:32 +0000458 unsigned char *p = data;
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000459 memcpy( buf, p + test_offset, len );
460 test_offset += 32;
461 return( 0 );
462}
463
464/*
465 * Checkup routine
466 */
467int ctr_drbg_self_test( int verbose )
468{
469 ctr_drbg_context ctx;
470 unsigned char buf[16];
471
472 /*
473 * Based on a NIST CTR_DRBG test vector (PR = True)
474 */
475 if( verbose != 0 )
476 printf( " CTR_DRBG (PR = TRUE) : " );
477
478 test_offset = 0;
Paul Bakkere2e36d32012-01-23 09:56:51 +0000479 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 +0000480 {
481 if( verbose != 0 )
482 printf( "failed\n" );
483
484 return( 1 );
485 }
486 ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON );
487
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000488 if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000489 {
490 if( verbose != 0 )
491 printf( "failed\n" );
492
493 return( 1 );
494 }
495
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000496 if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000497 {
498 if( verbose != 0 )
499 printf( "failed\n" );
500
501 return( 1 );
502 }
503
Paul Bakker2bc7cf12011-11-29 10:50:51 +0000504 if( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) != 0 )
Paul Bakker0e04d0e2011-11-27 14:46:59 +0000505 {
506 if( verbose != 0 )
507 printf( "failed\n" );
508
509 return( 1 );
510 }
511
512 if( verbose != 0 )
513 printf( "passed\n" );
514
515 /*
516 * Based on a NIST CTR_DRBG test vector (PR = FALSE)
517 */
518 if( verbose != 0 )
519 printf( " CTR_DRBG (PR = FALSE): " );
520
521 test_offset = 0;
Paul Bakkere2e36d32012-01-23 09:56:51 +0000522 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 +0000523 {
524 if( verbose != 0 )
525 printf( "failed\n" );
526
527 return( 1 );
528 }
529
530 if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
531 {
532 if( verbose != 0 )
533 printf( "failed\n" );
534
535 return( 1 );
536 }
537
538 if( ctr_drbg_reseed( &ctx, NULL, 0 ) != 0 )
539 {
540 if( verbose != 0 )
541 printf( "failed\n" );
542
543 return( 1 );
544 }
545
546 if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
547 {
548 if( verbose != 0 )
549 printf( "failed\n" );
550
551 return( 1 );
552 }
553
554 if( memcmp( buf, result_nopr, 16 ) != 0 )
555 {
556 if( verbose != 0 )
557 printf( "failed\n" );
558
559 return( 1 );
560 }
561
562 if( verbose != 0 )
563 printf( "passed\n" );
564
565 if( verbose != 0 )
566 printf( "\n" );
567
568 return( 0 );
569}
570#endif
571
572#endif