31 #if !defined(POLARSSL_CONFIG_FILE)
34 #include POLARSSL_CONFIG_FILE
37 #if defined(POLARSSL_CTR_DRBG_C)
41 #if defined(POLARSSL_FS_IO)
45 #if defined(POLARSSL_PLATFORM_C)
48 #define polarssl_printf printf
57 int (*f_entropy)(
void *,
unsigned char *,
size_t),
59 const unsigned char *custom,
87 int (*f_entropy)(
void *,
unsigned char *,
size_t),
89 const unsigned char *custom,
111 static int block_cipher_df(
unsigned char *output,
112 const unsigned char *data,
size_t data_len )
118 unsigned char *p, *iv;
122 size_t buf_len, use_len;
134 *p++ = ( data_len >> 24 ) & 0xff;
135 *p++ = ( data_len >> 16 ) & 0xff;
136 *p++ = ( data_len >> 8 ) & 0xff;
137 *p++ = ( data_len ) & 0xff;
140 memcpy( p, data, data_len );
143 buf_len = CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
156 memset( chain, 0, CTR_DRBG_BLOCKSIZE );
165 CTR_DRBG_BLOCKSIZE : use_len;
170 memcpy( tmp + j, chain, CTR_DRBG_BLOCKSIZE );
188 memcpy( p, iv, CTR_DRBG_BLOCKSIZE );
196 const unsigned char data[CTR_DRBG_SEEDLEN] )
199 unsigned char *p = tmp;
202 memset( tmp, 0, CTR_DRBG_SEEDLEN );
209 for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- )
210 if( ++ctx->
counter[i - 1] != 0 )
228 memcpy( ctx->
counter, tmp + CTR_DRBG_KEYSIZE, CTR_DRBG_BLOCKSIZE );
234 const unsigned char *additional,
size_t add_len )
240 block_cipher_df( add_input, additional, add_len );
241 ctr_drbg_update_internal( ctx, add_input );
246 const unsigned char *additional,
size_t len )
270 if( additional && len )
272 memcpy( seed + seedlen, additional, len );
279 block_cipher_df( seed, seed, seedlen );
284 ctr_drbg_update_internal( ctx, seed );
291 unsigned char *output,
size_t output_len,
292 const unsigned char *additional,
size_t add_len )
297 unsigned char *p = output;
308 memset( add_input, 0, CTR_DRBG_SEEDLEN );
321 block_cipher_df( add_input, additional, add_len );
322 ctr_drbg_update_internal( ctx, add_input );
325 while( output_len > 0 )
330 for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- )
331 if( ++ctx->
counter[i - 1] != 0 )
344 memcpy( p, tmp, use_len );
346 output_len -= use_len;
349 ctr_drbg_update_internal( ctx, add_input );
356 int ctr_drbg_random(
void *p_rng,
unsigned char *output,
size_t output_len )
361 #if defined(POLARSSL_FS_IO)
368 if( ( f = fopen( path,
"wb" ) ) == NULL )
393 if( ( f = fopen( path,
"rb" ) ) == NULL )
396 fseek( f, 0, SEEK_END );
397 n = (size_t) ftell( f );
398 fseek( f, 0, SEEK_SET );
406 if( fread( buf, 1, n, f ) != n )
420 #if defined(POLARSSL_SELF_TEST)
424 static unsigned char entropy_source_pr[96] =
425 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
426 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
427 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
428 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
429 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
430 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
431 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
432 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
433 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
434 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
435 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
436 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
438 static unsigned char entropy_source_nopr[64] =
439 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
440 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
441 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
442 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
443 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
444 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
445 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
446 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
448 static const unsigned char nonce_pers_pr[16] =
449 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
450 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
452 static const unsigned char nonce_pers_nopr[16] =
453 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
454 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
456 static const unsigned char result_pr[16] =
457 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
458 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
460 static const unsigned char result_nopr[16] =
461 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
462 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
464 static size_t test_offset;
465 static int ctr_drbg_self_test_entropy(
void *data,
unsigned char *buf,
468 const unsigned char *p = data;
469 memcpy( buf, p + test_offset, len );
474 #define CHK( c ) if( (c) != 0 ) \
477 polarssl_printf( "failed\n" ); \
487 unsigned char buf[16];
497 entropy_source_pr, nonce_pers_pr, 16, 32 ) );
501 CHK( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) );
514 entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
518 CHK( memcmp( buf, result_nopr, 16 ) );
#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)