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