Merge pull request #57 from Patater/check-generator-validity

psa: Check generator validity before read
This commit is contained in:
Jaeden Amero 2019-02-18 19:22:19 +00:00 committed by GitHub
commit 065c426d75
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 15 deletions

View file

@ -3621,6 +3621,12 @@ psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator, psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
size_t *capacity) size_t *capacity)
{ {
if( generator->alg == 0 )
{
/* This is a blank generator. */
return PSA_ERROR_BAD_STATE;
}
*capacity = generator->capacity; *capacity = generator->capacity;
return( PSA_SUCCESS ); return( PSA_SUCCESS );
} }
@ -3850,6 +3856,12 @@ psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
{ {
psa_status_t status; psa_status_t status;
if( generator->alg == 0 )
{
/* This is a blank generator. */
return PSA_ERROR_BAD_STATE;
}
if( output_length > generator->capacity ) if( output_length > generator->capacity )
{ {
generator->capacity = 0; generator->capacity = 0;
@ -3858,11 +3870,10 @@ psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
status = PSA_ERROR_INSUFFICIENT_DATA; status = PSA_ERROR_INSUFFICIENT_DATA;
goto exit; goto exit;
} }
if( output_length == 0 && if( output_length == 0 && generator->capacity == 0 )
generator->capacity == 0 && generator->alg == 0 )
{ {
/* Edge case: this is a blank or finished generator, and 0 /* Edge case: this is a finished generator, and 0 bytes
* bytes were requested. The right error in this case could * were requested. The right error in this case could
* be either INSUFFICIENT_CAPACITY or BAD_STATE. Return * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
* INSUFFICIENT_CAPACITY, which is right for a finished * INSUFFICIENT_CAPACITY, which is right for a finished
* generator, for consistency with the case when * generator, for consistency with the case when
@ -3911,7 +3922,13 @@ psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
exit: exit:
if( status != PSA_SUCCESS ) if( status != PSA_SUCCESS )
{ {
/* Preserve the algorithm upon errors, but clear all sensitive state.
* This allows us to differentiate between exhausted generators and
* blank generators, so we can return PSA_ERROR_BAD_STATE on blank
* generators. */
psa_algorithm_t alg = generator->alg;
psa_generator_abort( generator ); psa_generator_abort( generator );
generator->alg = alg;
memset( output, '!', output_length ); memset( output, '!', output_length );
} }
return( status ); return( status );

View file

@ -3519,13 +3519,13 @@ void crypto_generator_init( )
memset( &zero, 0, sizeof( zero ) ); memset( &zero, 0, sizeof( zero ) );
/* A default generator should have no capacity. */ /* A default generator should not be able to report its capacity. */
PSA_ASSERT( psa_get_generator_capacity( &func, &capacity ) ); TEST_EQUAL( psa_get_generator_capacity( &func, &capacity ),
TEST_EQUAL( capacity, 0 ); PSA_ERROR_BAD_STATE );
PSA_ASSERT( psa_get_generator_capacity( &init, &capacity ) ); TEST_EQUAL( psa_get_generator_capacity( &init, &capacity ),
TEST_EQUAL( capacity, 0 ); PSA_ERROR_BAD_STATE );
PSA_ASSERT( psa_get_generator_capacity( &zero, &capacity ) ); TEST_EQUAL( psa_get_generator_capacity( &zero, &capacity ),
TEST_EQUAL( capacity, 0 ); PSA_ERROR_BAD_STATE );
/* A default generator should be abortable without error. */ /* A default generator should be abortable without error. */
PSA_ASSERT( psa_generator_abort(&func) ); PSA_ASSERT( psa_generator_abort(&func) );
@ -3632,18 +3632,18 @@ void test_derive_invalid_generator_tests( )
psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size ) TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
== PSA_ERROR_INSUFFICIENT_DATA ); // should be PSA_ERROR_BAD_STATE:#183 == PSA_ERROR_BAD_STATE );
TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity ) TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
== PSA_SUCCESS ); // should be PSA_ERROR_BAD_STATE:#183 == PSA_ERROR_BAD_STATE );
PSA_ASSERT( psa_generator_abort( &generator ) ); PSA_ASSERT( psa_generator_abort( &generator ) );
TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size ) TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
== PSA_ERROR_INSUFFICIENT_DATA ); // should be PSA_ERROR_BAD_STATE:#183 == PSA_ERROR_BAD_STATE );
TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity ) TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
== PSA_SUCCESS );// should be PSA_ERROR_BAD_STATE:#183 == PSA_ERROR_BAD_STATE );
exit: exit:
psa_generator_abort( &generator ); psa_generator_abort( &generator );