Skip to content

psa: Check generator validity before read #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions library/psa_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
size_t *capacity)
{
if( generator->alg == 0 )
{
/* This is a blank generator. */
return PSA_ERROR_BAD_STATE;
}

*capacity = generator->capacity;
return( PSA_SUCCESS );
}
Expand Down Expand Up @@ -3850,6 +3856,12 @@ psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
{
psa_status_t status;

if( generator->alg == 0 )
{
/* This is a blank generator. */
return PSA_ERROR_BAD_STATE;
}

if( output_length > generator->capacity )
{
generator->capacity = 0;
Expand All @@ -3858,11 +3870,10 @@ psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
status = PSA_ERROR_INSUFFICIENT_DATA;
goto exit;
}
if( output_length == 0 &&
generator->capacity == 0 && generator->alg == 0 )
if( output_length == 0 && generator->capacity == 0 )
{
/* Edge case: this is a blank or finished generator, and 0
* bytes were requested. The right error in this case could
/* Edge case: this is a finished generator, and 0 bytes
* were requested. The right error in this case could
* be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
* INSUFFICIENT_CAPACITY, which is right for a finished
* generator, for consistency with the case when
Expand Down Expand Up @@ -3911,7 +3922,13 @@ psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
exit:
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 );
generator->alg = alg;
memset( output, '!', output_length );
}
return( status );
Expand Down
22 changes: 11 additions & 11 deletions tests/suites/test_suite_psa_crypto.function
Original file line number Diff line number Diff line change
Expand Up @@ -3519,13 +3519,13 @@ void crypto_generator_init( )

memset( &zero, 0, sizeof( zero ) );

/* A default generator should have no capacity. */
PSA_ASSERT( psa_get_generator_capacity( &func, &capacity ) );
TEST_EQUAL( capacity, 0 );
PSA_ASSERT( psa_get_generator_capacity( &init, &capacity ) );
TEST_EQUAL( capacity, 0 );
PSA_ASSERT( psa_get_generator_capacity( &zero, &capacity ) );
TEST_EQUAL( capacity, 0 );
/* A default generator should not be able to report its capacity. */
TEST_EQUAL( psa_get_generator_capacity( &func, &capacity ),
PSA_ERROR_BAD_STATE );
TEST_EQUAL( psa_get_generator_capacity( &init, &capacity ),
PSA_ERROR_BAD_STATE );
TEST_EQUAL( psa_get_generator_capacity( &zero, &capacity ),
PSA_ERROR_BAD_STATE );

/* A default generator should be abortable without error. */
PSA_ASSERT( psa_generator_abort(&func) );
Expand Down Expand Up @@ -3632,18 +3632,18 @@ void test_derive_invalid_generator_tests( )
psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;

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 )
== PSA_SUCCESS ); // should be PSA_ERROR_BAD_STATE:#183
== PSA_ERROR_BAD_STATE );

PSA_ASSERT( psa_generator_abort( &generator ) );

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 )
== PSA_SUCCESS );// should be PSA_ERROR_BAD_STATE:#183
== PSA_ERROR_BAD_STATE );

exit:
psa_generator_abort( &generator );
Expand Down