PolarSSL v1.2.12
ctr_drbg.c
Go to the documentation of this file.
1 /*
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 
37 #if defined(POLARSSL_FS_IO)
38 #include <stdio.h>
39 #endif
40 
41 /*
42  * Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST
43  * tests to succeed (which require known length fixed entropy)
44  */
45 int ctr_drbg_init_entropy_len(
46  ctr_drbg_context *ctx,
47  int (*f_entropy)(void *, unsigned char *, size_t),
48  void *p_entropy,
49  const unsigned char *custom,
50  size_t len,
51  size_t entropy_len );
52 
53 int ctr_drbg_init_entropy_len(
54  ctr_drbg_context *ctx,
55  int (*f_entropy)(void *, unsigned char *, size_t),
56  void *p_entropy,
57  const unsigned char *custom,
58  size_t len,
59  size_t entropy_len )
60 {
61  int ret;
62  unsigned char key[CTR_DRBG_KEYSIZE];
63 
64  memset( ctx, 0, sizeof(ctr_drbg_context) );
65  memset( key, 0, CTR_DRBG_KEYSIZE );
66 
67  ctx->f_entropy = f_entropy;
68  ctx->p_entropy = p_entropy;
69 
70  ctx->entropy_len = entropy_len;
72 
73  /*
74  * Initialize with an empty key
75  */
77 
78  if( ( ret = ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
79  return( ret );
80 
81  return( 0 );
82 }
83 
85  int (*f_entropy)(void *, unsigned char *, size_t),
86  void *p_entropy,
87  const unsigned char *custom,
88  size_t len )
89 {
90  return( ctr_drbg_init_entropy_len( ctx, f_entropy, p_entropy, custom, len,
92 }
93 
94 void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx, int resistance )
95 {
96  ctx->prediction_resistance = resistance;
97 }
98 
99 void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx, size_t len )
100 {
101  ctx->entropy_len = len;
102 }
103 
104 void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx, int interval )
105 {
106  ctx->reseed_interval = interval;
107 }
108 
109 static int block_cipher_df( unsigned char *output,
110  const unsigned char *data, size_t data_len )
111 {
112  unsigned char buf[CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16];
113  unsigned char tmp[CTR_DRBG_SEEDLEN];
114  unsigned char key[CTR_DRBG_KEYSIZE];
115  unsigned char chain[CTR_DRBG_BLOCKSIZE];
116  unsigned char *p, *iv;
117  aes_context aes_ctx;
118 
119  int i, j, buf_len, use_len;
120 
121  memset( buf, 0, CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16 );
122 
123  /*
124  * Construct IV (16 bytes) and S in buffer
125  * IV = Counter (in 32-bits) padded to 16 with zeroes
126  * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
127  * data || 0x80
128  * (Total is padded to a multiple of 16-bytes with zeroes)
129  */
130  p = buf + CTR_DRBG_BLOCKSIZE;
131  *p++ = ( data_len >> 24 ) & 0xff;
132  *p++ = ( data_len >> 16 ) & 0xff;
133  *p++ = ( data_len >> 8 ) & 0xff;
134  *p++ = ( data_len ) & 0xff;
135  p += 3;
136  *p++ = CTR_DRBG_SEEDLEN;
137  memcpy( p, data, data_len );
138  p[data_len] = 0x80;
139 
140  buf_len = CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
141 
142  for( i = 0; i < CTR_DRBG_KEYSIZE; i++ )
143  key[i] = i;
144 
145  aes_setkey_enc( &aes_ctx, key, CTR_DRBG_KEYBITS );
146 
147  /*
148  * Reduce data to POLARSSL_CTR_DRBG_SEEDLEN bytes of data
149  */
150  for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
151  {
152  p = buf;
153  memset( chain, 0, CTR_DRBG_BLOCKSIZE );
154  use_len = buf_len;
155 
156  while( use_len > 0 )
157  {
158  for( i = 0; i < CTR_DRBG_BLOCKSIZE; i++ )
159  chain[i] ^= p[i];
160  p += CTR_DRBG_BLOCKSIZE;
161  use_len -= CTR_DRBG_BLOCKSIZE;
162 
163  aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, chain, chain );
164  }
165 
166  memcpy( tmp + j, chain, CTR_DRBG_BLOCKSIZE );
167 
168  /*
169  * Update IV
170  */
171  buf[3]++;
172  }
173 
174  /*
175  * Do final encryption with reduced data
176  */
177  aes_setkey_enc( &aes_ctx, tmp, CTR_DRBG_KEYBITS );
178  iv = tmp + CTR_DRBG_KEYSIZE;
179  p = output;
180 
181  for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
182  {
183  aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, iv, iv );
184  memcpy( p, iv, CTR_DRBG_BLOCKSIZE );
185  p += CTR_DRBG_BLOCKSIZE;
186  }
187 
188  return( 0 );
189 }
190 
191 static int ctr_drbg_update_internal( ctr_drbg_context *ctx,
192  const unsigned char data[CTR_DRBG_SEEDLEN] )
193 {
194  unsigned char tmp[CTR_DRBG_SEEDLEN];
195  unsigned char *p = tmp;
196  int i, j;
197 
198  memset( tmp, 0, CTR_DRBG_SEEDLEN );
199 
200  for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
201  {
202  /*
203  * Increase counter
204  */
205  for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- )
206  if( ++ctx->counter[i - 1] != 0 )
207  break;
208 
209  /*
210  * Crypt counter block
211  */
212  aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, p );
213 
214  p += CTR_DRBG_BLOCKSIZE;
215  }
216 
217  for( i = 0; i < CTR_DRBG_SEEDLEN; i++ )
218  tmp[i] ^= data[i];
219 
220  /*
221  * Update key and counter
222  */
223  aes_setkey_enc( &ctx->aes_ctx, tmp, CTR_DRBG_KEYBITS );
224  memcpy( ctx->counter, tmp + CTR_DRBG_KEYSIZE, CTR_DRBG_BLOCKSIZE );
225 
226  return( 0 );
227 }
228 
230  const unsigned char *additional, size_t add_len )
231 {
232  unsigned char add_input[CTR_DRBG_SEEDLEN];
233 
234  if( add_len > 0 )
235  {
236  block_cipher_df( add_input, additional, add_len );
237  ctr_drbg_update_internal( ctx, add_input );
238  }
239 }
240 
242  const unsigned char *additional, size_t len )
243 {
244  unsigned char seed[CTR_DRBG_MAX_SEED_INPUT];
245  size_t seedlen = 0;
246 
247  if( ctx->entropy_len + len > CTR_DRBG_MAX_SEED_INPUT )
249 
250  memset( seed, 0, CTR_DRBG_MAX_SEED_INPUT );
251 
252  /*
253  * Gather enropy_len bytes of entropy to seed state
254  */
255  if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
256  ctx->entropy_len ) )
257  {
259  }
260 
261  seedlen += ctx->entropy_len;
262 
263  /*
264  * Add additional data
265  */
266  if( additional && len )
267  {
268  memcpy( seed + seedlen, additional, len );
269  seedlen += len;
270  }
271 
272  /*
273  * Reduce to 384 bits
274  */
275  block_cipher_df( seed, seed, seedlen );
276 
277  /*
278  * Update state
279  */
280  ctr_drbg_update_internal( ctx, seed );
281  ctx->reseed_counter = 1;
282 
283  return( 0 );
284 }
285 
286 int ctr_drbg_random_with_add( void *p_rng,
287  unsigned char *output, size_t output_len,
288  const unsigned char *additional, size_t add_len )
289 {
290  int ret = 0;
291  ctr_drbg_context *ctx = (ctr_drbg_context *) p_rng;
292  unsigned char add_input[CTR_DRBG_SEEDLEN];
293  unsigned char *p = output;
294  unsigned char tmp[CTR_DRBG_BLOCKSIZE];
295  int i;
296  size_t use_len;
297 
298  if( output_len > CTR_DRBG_MAX_REQUEST )
300 
301  if( add_len > CTR_DRBG_MAX_INPUT )
303 
304  memset( add_input, 0, CTR_DRBG_SEEDLEN );
305 
306  if( ctx->reseed_counter > ctx->reseed_interval ||
307  ctx->prediction_resistance )
308  {
309  if( ( ret = ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
310  return( ret );
311 
312  add_len = 0;
313  }
314 
315  if( add_len > 0 )
316  {
317  block_cipher_df( add_input, additional, add_len );
318  ctr_drbg_update_internal( ctx, add_input );
319  }
320 
321  while( output_len > 0 )
322  {
323  /*
324  * Increase counter
325  */
326  for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- )
327  if( ++ctx->counter[i - 1] != 0 )
328  break;
329 
330  /*
331  * Crypt counter block
332  */
333  aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, tmp );
334 
335  use_len = (output_len > CTR_DRBG_BLOCKSIZE ) ? CTR_DRBG_BLOCKSIZE : output_len;
336  /*
337  * Copy random block to destination
338  */
339  memcpy( p, tmp, use_len );
340  p += use_len;
341  output_len -= use_len;
342  }
343 
344  ctr_drbg_update_internal( ctx, add_input );
345 
346  ctx->reseed_counter++;
347 
348  return( 0 );
349 }
350 
351 int ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
352 {
353  return ctr_drbg_random_with_add( p_rng, output, output_len, NULL, 0 );
354 }
355 
356 #if defined(POLARSSL_FS_IO)
357 int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path )
358 {
359  int ret;
360  FILE *f;
361  unsigned char buf[ CTR_DRBG_MAX_INPUT ];
362 
363  if( ( f = fopen( path, "wb" ) ) == NULL )
365 
366  if( ( ret = ctr_drbg_random( ctx, buf, CTR_DRBG_MAX_INPUT ) ) != 0 )
367  {
368  fclose( f );
369  return( ret );
370  }
371 
372  if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT )
373  {
374  fclose( f );
376  }
377 
378  fclose( f );
379  return( 0 );
380 }
381 
382 int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path )
383 {
384  FILE *f;
385  size_t n;
386  unsigned char buf[ CTR_DRBG_MAX_INPUT ];
387 
388  if( ( f = fopen( path, "rb" ) ) == NULL )
390 
391  fseek( f, 0, SEEK_END );
392  n = (size_t) ftell( f );
393  fseek( f, 0, SEEK_SET );
394 
395  if( n > CTR_DRBG_MAX_INPUT )
396  {
397  fclose( f );
399  }
400 
401  if( fread( buf, 1, n, f ) != n )
402  {
403  fclose( f );
405  }
406 
407  ctr_drbg_update( ctx, buf, n );
408 
409  fclose( f );
410 
411  return( ctr_drbg_write_seed_file( ctx, path ) );
412 }
413 #endif /* POLARSSL_FS_IO */
414 
415 #if defined(POLARSSL_SELF_TEST)
416 
417 #include <stdio.h>
418 
419 unsigned char entropy_source_pr[96] =
420  { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
421  0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
422  0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
423  0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
424  0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
425  0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
426  0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
427  0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
428  0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
429  0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
430  0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
431  0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
432 
433 unsigned char entropy_source_nopr[64] =
434  { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
435  0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
436  0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
437  0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
438  0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
439  0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
440  0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
441  0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
442 
443 unsigned char nonce_pers_pr[16] =
444  { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
445  0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
446 
447 unsigned char nonce_pers_nopr[16] =
448  { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
449  0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
450 
451 unsigned char result_pr[16] =
452  { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
453  0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
454 
455 unsigned char result_nopr[16] =
456  { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
457  0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
458 
459 static size_t test_offset;
460 static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
461  size_t len )
462 {
463  unsigned char *p = data;
464  memcpy( buf, p + test_offset, len );
465  test_offset += 32;
466  return( 0 );
467 }
468 
469 /*
470  * Checkup routine
471  */
472 int ctr_drbg_self_test( int verbose )
473 {
474  ctr_drbg_context ctx;
475  unsigned char buf[16];
476 
477  /*
478  * Based on a NIST CTR_DRBG test vector (PR = True)
479  */
480  if( verbose != 0 )
481  printf( " CTR_DRBG (PR = TRUE) : " );
482 
483  test_offset = 0;
484  if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_pr, nonce_pers_pr, 16, 32 ) != 0 )
485  {
486  if( verbose != 0 )
487  printf( "failed\n" );
488 
489  return( 1 );
490  }
492 
493  if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
494  {
495  if( verbose != 0 )
496  printf( "failed\n" );
497 
498  return( 1 );
499  }
500 
501  if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
502  {
503  if( verbose != 0 )
504  printf( "failed\n" );
505 
506  return( 1 );
507  }
508 
509  if( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) != 0 )
510  {
511  if( verbose != 0 )
512  printf( "failed\n" );
513 
514  return( 1 );
515  }
516 
517  if( verbose != 0 )
518  printf( "passed\n" );
519 
520  /*
521  * Based on a NIST CTR_DRBG test vector (PR = FALSE)
522  */
523  if( verbose != 0 )
524  printf( " CTR_DRBG (PR = FALSE): " );
525 
526  test_offset = 0;
527  if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_nopr, nonce_pers_nopr, 16, 32 ) != 0 )
528  {
529  if( verbose != 0 )
530  printf( "failed\n" );
531 
532  return( 1 );
533  }
534 
535  if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
536  {
537  if( verbose != 0 )
538  printf( "failed\n" );
539 
540  return( 1 );
541  }
542 
543  if( ctr_drbg_reseed( &ctx, NULL, 0 ) != 0 )
544  {
545  if( verbose != 0 )
546  printf( "failed\n" );
547 
548  return( 1 );
549  }
550 
551  if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
552  {
553  if( verbose != 0 )
554  printf( "failed\n" );
555 
556  return( 1 );
557  }
558 
559  if( memcmp( buf, result_nopr, 16 ) != 0 )
560  {
561  if( verbose != 0 )
562  printf( "failed\n" );
563 
564  return( 1 );
565  }
566 
567  if( verbose != 0 )
568  printf( "passed\n" );
569 
570  if( verbose != 0 )
571  printf( "\n" );
572 
573  return( 0 );
574 }
575 #endif
576 
577 #endif