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