Merge remote-tracking branch 'restricted/pr/512' into development
This commit is contained in:
commit
51b8a2fa87
6 changed files with 235 additions and 101 deletions
15
ChangeLog
15
ChangeLog
|
@ -16,6 +16,21 @@ Security
|
|||
plaintexts and forge RSA signatures. Other asymmetric algorithms may
|
||||
have been similarly vulnerable. Reported by Eyal Ronen, Robert Gillham,
|
||||
Daniel Genkin, Adi Shamir, David Wong and Yuval Yarom.
|
||||
* Wipe sensitive buffers on the stack in the CTR_DRBG and HMAC_DRBG
|
||||
modules.
|
||||
|
||||
API Changes
|
||||
* The following functions in the random generator modules have been
|
||||
deprecated and replaced as shown below. The new functions change
|
||||
the return type from void to int to allow returning error codes when
|
||||
using MBEDTLS_<MODULE>_ALT for the underlying AES or message digest
|
||||
primitive. Fixes #1798.
|
||||
mbedtls_ctr_drbg_update() -> mbedtls_ctr_drbg_update_ret()
|
||||
mbedtls_hmac_drbg_update() -> mbedtls_hmac_drbg_update_ret()
|
||||
|
||||
New deprecations
|
||||
* Deprecate mbedtls_ctr_drbg_update and mbedtls_hmac_drbg_update
|
||||
in favor of functions that can return an error code.
|
||||
|
||||
= mbed TLS 2.14.0 branch released 2018-11-19
|
||||
|
||||
|
|
|
@ -239,18 +239,20 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
|
|||
/**
|
||||
* \brief This function updates the state of the CTR_DRBG context.
|
||||
*
|
||||
* \note If \p add_len is greater than
|
||||
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
|
||||
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
|
||||
* The remaining Bytes are silently discarded.
|
||||
*
|
||||
* \param ctx The CTR_DRBG context.
|
||||
* \param additional The data to update the state with.
|
||||
* \param add_len Length of \p additional data.
|
||||
* \param add_len Length of \p additional in bytes. This must be at
|
||||
* most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if
|
||||
* \p add_len is more than
|
||||
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
|
||||
* \return An error from the underlying AES cipher on failure.
|
||||
*/
|
||||
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t add_len );
|
||||
int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional,
|
||||
size_t add_len );
|
||||
|
||||
/**
|
||||
* \brief This function updates a CTR_DRBG instance with additional
|
||||
|
@ -290,6 +292,35 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
|
|||
int mbedtls_ctr_drbg_random( void *p_rng,
|
||||
unsigned char *output, size_t output_len );
|
||||
|
||||
|
||||
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
#define MBEDTLS_DEPRECATED
|
||||
#endif
|
||||
/**
|
||||
* \brief This function updates the state of the CTR_DRBG context.
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_ctr_drbg_update_ret()
|
||||
* in 2.16.0.
|
||||
*
|
||||
* \note If \p add_len is greater than
|
||||
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
|
||||
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
|
||||
* The remaining Bytes are silently discarded.
|
||||
*
|
||||
* \param ctx The CTR_DRBG context.
|
||||
* \param additional The data to update the state with.
|
||||
* \param add_len Length of \p additional data.
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update(
|
||||
mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional,
|
||||
size_t add_len );
|
||||
#undef MBEDTLS_DEPRECATED
|
||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
/**
|
||||
* \brief This function writes a seed file.
|
||||
|
|
|
@ -195,10 +195,13 @@ void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
|
|||
* \param additional Additional data to update state with, or NULL
|
||||
* \param add_len Length of additional data, or 0
|
||||
*
|
||||
* \return \c 0 on success, or an error from the underlying
|
||||
* hash calculation.
|
||||
*
|
||||
* \note Additional data is optional, pass NULL and 0 as second
|
||||
* third argument if no additional data is being used.
|
||||
*/
|
||||
void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
|
||||
int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t add_len );
|
||||
|
||||
/**
|
||||
|
@ -257,6 +260,31 @@ int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len
|
|||
*/
|
||||
void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx );
|
||||
|
||||
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
#define MBEDTLS_DEPRECATED
|
||||
#endif
|
||||
/**
|
||||
* \brief HMAC_DRBG update state
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_hmac_drbg_update_ret()
|
||||
* in 2.16.0.
|
||||
*
|
||||
* \param ctx HMAC_DRBG context
|
||||
* \param additional Additional data to update state with, or NULL
|
||||
* \param add_len Length of additional data, or 0
|
||||
*
|
||||
* \note Additional data is optional, pass NULL and 0 as second
|
||||
* third argument if no additional data is being used.
|
||||
*/
|
||||
MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update(
|
||||
mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t add_len );
|
||||
#undef MBEDTLS_DEPRECATED
|
||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
/**
|
||||
* \brief Write a seed file
|
||||
|
|
|
@ -299,9 +299,7 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
|
|||
* Crypt counter block
|
||||
*/
|
||||
if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
|
||||
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
|
||||
}
|
||||
|
@ -313,12 +311,12 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
|
|||
* Update key and counter
|
||||
*/
|
||||
if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
|
||||
|
||||
return( 0 );
|
||||
exit:
|
||||
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2)
|
||||
|
@ -333,23 +331,39 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
|
|||
* and with outputs
|
||||
* ctx = initial_working_state
|
||||
*/
|
||||
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t add_len )
|
||||
int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional,
|
||||
size_t add_len )
|
||||
{
|
||||
unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
|
||||
int ret;
|
||||
|
||||
if( add_len > 0 )
|
||||
{
|
||||
/* MAX_INPUT would be more logical here, but we have to match
|
||||
* block_cipher_df()'s limits since we can't propagate errors */
|
||||
if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
|
||||
add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
|
||||
if( add_len == 0 )
|
||||
return( 0 );
|
||||
|
||||
block_cipher_df( add_input, additional, add_len );
|
||||
ctr_drbg_update_internal( ctx, add_input );
|
||||
}
|
||||
if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
|
||||
goto exit;
|
||||
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional,
|
||||
size_t add_len )
|
||||
{
|
||||
/* MAX_INPUT would be more logical here, but we have to match
|
||||
* block_cipher_df()'s limits since we can't propagate errors */
|
||||
if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
|
||||
add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
|
||||
(void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
|
||||
}
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
/* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2)
|
||||
* mbedtls_ctr_drbg_reseed(ctx, additional, len)
|
||||
* implements
|
||||
|
@ -399,20 +413,18 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
|
|||
* Reduce to 384 bits
|
||||
*/
|
||||
if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
|
||||
/*
|
||||
* Update state
|
||||
*/
|
||||
if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
ctx->reseed_counter = 1;
|
||||
|
||||
return( 0 );
|
||||
exit:
|
||||
mbedtls_platform_zeroize( seed, sizeof( seed ) );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2)
|
||||
|
@ -467,13 +479,9 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
|
|||
if( add_len > 0 )
|
||||
{
|
||||
if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
|
||||
while( output_len > 0 )
|
||||
|
@ -489,9 +497,7 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
|
|||
* Crypt counter block
|
||||
*/
|
||||
if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
|
||||
use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
|
||||
output_len;
|
||||
|
@ -504,12 +510,13 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
|
|||
}
|
||||
|
||||
if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
goto exit;
|
||||
|
||||
ctx->reseed_counter++;
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
|
||||
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
@ -561,35 +568,36 @@ exit:
|
|||
int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
|
||||
{
|
||||
int ret = 0;
|
||||
FILE *f;
|
||||
FILE *f = NULL;
|
||||
size_t n;
|
||||
unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
|
||||
unsigned char c;
|
||||
|
||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
|
||||
|
||||
fseek( f, 0, SEEK_END );
|
||||
n = (size_t) ftell( f );
|
||||
fseek( f, 0, SEEK_SET );
|
||||
|
||||
if( n > MBEDTLS_CTR_DRBG_MAX_INPUT )
|
||||
n = fread( buf, 1, sizeof( buf ), f );
|
||||
if( fread( &c, 1, 1, f ) != 0 )
|
||||
{
|
||||
fclose( f );
|
||||
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
|
||||
ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( fread( buf, 1, n, f ) != n )
|
||||
if( n == 0 || ferror( f ) )
|
||||
{
|
||||
ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
|
||||
else
|
||||
mbedtls_ctr_drbg_update( ctx, buf, n );
|
||||
|
||||
goto exit;
|
||||
}
|
||||
fclose( f );
|
||||
f = NULL;
|
||||
|
||||
ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize( buf, sizeof( buf ) );
|
||||
|
||||
if( f != NULL )
|
||||
fclose( f );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
|
||||
}
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
|
|
@ -66,31 +66,60 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
|
|||
/*
|
||||
* HMAC_DRBG update, using optional additional data (10.1.2.2)
|
||||
*/
|
||||
void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t add_len )
|
||||
int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional,
|
||||
size_t add_len )
|
||||
{
|
||||
size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
|
||||
unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
|
||||
unsigned char sep[1];
|
||||
unsigned char K[MBEDTLS_MD_MAX_SIZE];
|
||||
int ret;
|
||||
|
||||
for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
|
||||
{
|
||||
/* Step 1 or 4 */
|
||||
mbedtls_md_hmac_reset( &ctx->md_ctx );
|
||||
mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
|
||||
mbedtls_md_hmac_update( &ctx->md_ctx, sep, 1 );
|
||||
if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
|
||||
goto exit;
|
||||
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
|
||||
ctx->V, md_len ) ) != 0 )
|
||||
goto exit;
|
||||
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
|
||||
sep, 1 ) ) != 0 )
|
||||
goto exit;
|
||||
if( rounds == 2 )
|
||||
mbedtls_md_hmac_update( &ctx->md_ctx, additional, add_len );
|
||||
mbedtls_md_hmac_finish( &ctx->md_ctx, K );
|
||||
{
|
||||
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
|
||||
additional, add_len ) ) != 0 )
|
||||
goto exit;
|
||||
}
|
||||
if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
/* Step 2 or 5 */
|
||||
mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len );
|
||||
mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
|
||||
mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
|
||||
if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
|
||||
goto exit;
|
||||
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
|
||||
ctx->V, md_len ) ) != 0 )
|
||||
goto exit;
|
||||
if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize( K, sizeof( K ) );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional,
|
||||
size_t add_len )
|
||||
{
|
||||
(void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
|
||||
}
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
/*
|
||||
* Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
|
||||
*/
|
||||
|
@ -108,10 +137,13 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
|
|||
* Use the V memory location, which is currently all 0, to initialize the
|
||||
* MD context with an all-zero key. Then set V to its initial value.
|
||||
*/
|
||||
mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, mbedtls_md_get_size( md_info ) );
|
||||
if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
|
||||
mbedtls_md_get_size( md_info ) ) ) != 0 )
|
||||
return( ret );
|
||||
memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
|
||||
|
||||
mbedtls_hmac_drbg_update( ctx, data, data_len );
|
||||
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -124,6 +156,7 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
|
|||
{
|
||||
unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
|
||||
size_t seedlen;
|
||||
int ret;
|
||||
|
||||
/* III. Check input length */
|
||||
if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
|
||||
|
@ -135,7 +168,8 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
|
|||
memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
|
||||
|
||||
/* IV. Gather entropy_len bytes of entropy for the seed */
|
||||
if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 )
|
||||
if( ( ret = ctx->f_entropy( ctx->p_entropy,
|
||||
seed, ctx->entropy_len ) ) != 0 )
|
||||
return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
|
||||
|
||||
seedlen = ctx->entropy_len;
|
||||
|
@ -148,13 +182,16 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
|
|||
}
|
||||
|
||||
/* 2. Update state */
|
||||
mbedtls_hmac_drbg_update( ctx, seed, seedlen );
|
||||
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
/* 3. Reset reseed_counter */
|
||||
ctx->reseed_counter = 1;
|
||||
|
||||
exit:
|
||||
/* 4. Done */
|
||||
return( 0 );
|
||||
mbedtls_platform_zeroize( seed, seedlen );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -180,7 +217,8 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
|
|||
* Use the V memory location, which is currently all 0, to initialize the
|
||||
* MD context with an all-zero key. Then set V to its initial value.
|
||||
*/
|
||||
mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size );
|
||||
if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
|
||||
return( ret );
|
||||
memset( ctx->V, 0x01, md_size );
|
||||
|
||||
ctx->f_entropy = f_entropy;
|
||||
|
@ -273,16 +311,24 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
|
|||
|
||||
/* 2. Use additional data if any */
|
||||
if( additional != NULL && add_len != 0 )
|
||||
mbedtls_hmac_drbg_update( ctx, additional, add_len );
|
||||
{
|
||||
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
|
||||
additional, add_len ) ) != 0 )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* 3, 4, 5. Generate bytes */
|
||||
while( left != 0 )
|
||||
{
|
||||
size_t use_len = left > md_len ? md_len : left;
|
||||
|
||||
mbedtls_md_hmac_reset( &ctx->md_ctx );
|
||||
mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
|
||||
mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V );
|
||||
if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
|
||||
goto exit;
|
||||
if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
|
||||
ctx->V, md_len ) ) != 0 )
|
||||
goto exit;
|
||||
if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
memcpy( out, ctx->V, use_len );
|
||||
out += use_len;
|
||||
|
@ -290,13 +336,16 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
|
|||
}
|
||||
|
||||
/* 6. Update */
|
||||
mbedtls_hmac_drbg_update( ctx, additional, add_len );
|
||||
if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
|
||||
additional, add_len ) ) != 0 )
|
||||
goto exit;
|
||||
|
||||
/* 7. Update reseed counter */
|
||||
ctx->reseed_counter++;
|
||||
|
||||
exit:
|
||||
/* 8. Done */
|
||||
return( 0 );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -368,35 +417,36 @@ exit:
|
|||
int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
|
||||
{
|
||||
int ret = 0;
|
||||
FILE *f;
|
||||
FILE *f = NULL;
|
||||
size_t n;
|
||||
unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
|
||||
unsigned char c;
|
||||
|
||||
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||
return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
|
||||
|
||||
fseek( f, 0, SEEK_END );
|
||||
n = (size_t) ftell( f );
|
||||
fseek( f, 0, SEEK_SET );
|
||||
|
||||
if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
|
||||
n = fread( buf, 1, sizeof( buf ), f );
|
||||
if( fread( &c, 1, 1, f ) != 0 )
|
||||
{
|
||||
fclose( f );
|
||||
return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
|
||||
ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( fread( buf, 1, n, f ) != n )
|
||||
if( n == 0 || ferror( f ) )
|
||||
{
|
||||
ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
|
||||
else
|
||||
mbedtls_hmac_drbg_update( ctx, buf, n );
|
||||
|
||||
goto exit;
|
||||
}
|
||||
fclose( f );
|
||||
f = NULL;
|
||||
|
||||
ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
|
||||
|
||||
exit:
|
||||
mbedtls_platform_zeroize( buf, sizeof( buf ) );
|
||||
|
||||
if( f != NULL )
|
||||
fclose( f );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
|
||||
}
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
|
|
@ -244,9 +244,11 @@ void ctr_drbg_entropy_usage( )
|
|||
}
|
||||
TEST_ASSERT( last_idx == test_offset_idx );
|
||||
|
||||
/* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT)
|
||||
* (just make sure it doesn't cause memory corruption) */
|
||||
mbedtls_ctr_drbg_update( &ctx, entropy, sizeof( entropy ) );
|
||||
/* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT).
|
||||
* Make sure it's detected as an error and doesn't cause memory
|
||||
* corruption. */
|
||||
TEST_ASSERT( mbedtls_ctr_drbg_update_ret(
|
||||
&ctx, entropy, sizeof( entropy ) ) != 0 );
|
||||
|
||||
/* Now enable PR, so the next few calls should all reseed */
|
||||
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
|
||||
|
|
Loading…
Reference in a new issue