33 #if defined(POLARSSL_CTR_DRBG_C)
37 #if defined(POLARSSL_FS_IO)
47 int (*f_entropy)(
void *,
unsigned char *,
size_t),
49 const unsigned char *custom,
77 int (*f_entropy)(
void *,
unsigned char *,
size_t),
79 const unsigned char *custom,
101 static int block_cipher_df(
unsigned char *output,
102 const unsigned char *data,
size_t data_len )
108 unsigned char *p, *iv;
112 size_t buf_len, use_len;
124 *p++ = ( data_len >> 24 ) & 0xff;
125 *p++ = ( data_len >> 16 ) & 0xff;
126 *p++ = ( data_len >> 8 ) & 0xff;
127 *p++ = ( data_len ) & 0xff;
130 memcpy( p, data, data_len );
133 buf_len = CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
146 memset( chain, 0, CTR_DRBG_BLOCKSIZE );
155 CTR_DRBG_BLOCKSIZE : use_len;
160 memcpy( tmp + j, chain, CTR_DRBG_BLOCKSIZE );
178 memcpy( p, iv, CTR_DRBG_BLOCKSIZE );
186 const unsigned char data[CTR_DRBG_SEEDLEN] )
189 unsigned char *p = tmp;
192 memset( tmp, 0, CTR_DRBG_SEEDLEN );
199 for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- )
200 if( ++ctx->
counter[i - 1] != 0 )
218 memcpy( ctx->
counter, tmp + CTR_DRBG_KEYSIZE, CTR_DRBG_BLOCKSIZE );
224 const unsigned char *additional,
size_t add_len )
230 block_cipher_df( add_input, additional, add_len );
231 ctr_drbg_update_internal( ctx, add_input );
236 const unsigned char *additional,
size_t len )
260 if( additional && len )
262 memcpy( seed + seedlen, additional, len );
269 block_cipher_df( seed, seed, seedlen );
274 ctr_drbg_update_internal( ctx, seed );
281 unsigned char *output,
size_t output_len,
282 const unsigned char *additional,
size_t add_len )
287 unsigned char *p = output;
298 memset( add_input, 0, CTR_DRBG_SEEDLEN );
311 block_cipher_df( add_input, additional, add_len );
312 ctr_drbg_update_internal( ctx, add_input );
315 while( output_len > 0 )
320 for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- )
321 if( ++ctx->
counter[i - 1] != 0 )
333 memcpy( p, tmp, use_len );
335 output_len -= use_len;
338 ctr_drbg_update_internal( ctx, add_input );
345 int ctr_drbg_random(
void *p_rng,
unsigned char *output,
size_t output_len )
350 #if defined(POLARSSL_FS_IO)
357 if( ( f = fopen( path,
"wb" ) ) == NULL )
382 if( ( f = fopen( path,
"rb" ) ) == NULL )
385 fseek( f, 0, SEEK_END );
386 n = (size_t) ftell( f );
387 fseek( f, 0, SEEK_SET );
395 if( fread( buf, 1, n, f ) != n )
409 #if defined(POLARSSL_SELF_TEST)
413 unsigned char entropy_source_pr[96] =
414 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
415 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
416 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
417 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
418 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
419 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
420 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
421 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
422 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
423 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
424 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
425 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
427 unsigned char entropy_source_nopr[64] =
428 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
429 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
430 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
431 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
432 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
433 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
434 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
435 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
437 unsigned char nonce_pers_pr[16] =
438 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
439 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
441 unsigned char nonce_pers_nopr[16] =
442 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
443 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
445 unsigned char result_pr[16] =
446 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
447 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
449 unsigned char result_nopr[16] =
450 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
451 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
454 static int ctr_drbg_self_test_entropy(
void *data,
unsigned char *buf,
457 unsigned char *p = data;
458 memcpy( buf, p + test_offset, len );
469 unsigned char buf[16];
475 printf(
" CTR_DRBG (PR = TRUE) : " );
481 printf(
"failed\n" );
490 printf(
"failed\n" );
498 printf(
"failed\n" );
503 if( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) != 0 )
506 printf(
"failed\n" );
512 printf(
"passed\n" );
518 printf(
" CTR_DRBG (PR = FALSE): " );
524 printf(
"failed\n" );
532 printf(
"failed\n" );
540 printf(
"failed\n" );
548 printf(
"failed\n" );
553 if( memcmp( buf, result_nopr, 16 ) != 0 )
556 printf(
"failed\n" );
562 printf(
"passed\n" );
#define POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
The entropy source failed.
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.
#define CTR_DRBG_MAX_INPUT
Maximum number of additional input bytes.
#define CTR_DRBG_MAX_SEED_INPUT
Maximum size of (re)seed buffer.
#define CTR_DRBG_RESEED_INTERVAL
Interval before reseed is performed by default.
Configuration options (set of defines)
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.
#define CTR_DRBG_BLOCKSIZE
Block size used by the cipher.
#define CTR_DRBG_ENTROPY_LEN
Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256)
int prediction_resistance
#define POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG
Too many random requested in single call.
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.
#define POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR
Read/write error in file.
unsigned char counter[16]
int ctr_drbg_reseed(ctr_drbg_context *ctx, const unsigned char *additional, size_t len)
CTR_DRBG reseeding (extracts data from entropy source)
#define POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG
Input too large (Entropy + additional).
CTR_DRBG context structure.
#define CTR_DRBG_SEEDLEN
The seed length (counter + AES key)
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.
int(* f_entropy)(void *, unsigned char *, size_t)
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.
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)