Skip to content

Commit ee116e5

Browse files
committed
psa: Check generator validity before read
Check generator validity (i.e. that alg has been initialized) before allowing reads from the generator or allowing reads of the generator's capacity. This aligns our implementation with the documented error code behavior in our crypto.h and the PSA Crypto API.
1 parent 2d7e5fe commit ee116e5

File tree

2 files changed

+32
-15
lines changed

2 files changed

+32
-15
lines changed

library/psa_crypto.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3621,6 +3621,12 @@ psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
36213621
psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
36223622
size_t *capacity)
36233623
{
3624+
if( generator->alg == 0 )
3625+
{
3626+
/* This is a blank generator. */
3627+
return PSA_ERROR_BAD_STATE;
3628+
}
3629+
36243630
*capacity = generator->capacity;
36253631
return( PSA_SUCCESS );
36263632
}
@@ -3850,6 +3856,12 @@ psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
38503856
{
38513857
psa_status_t status;
38523858

3859+
if( generator->alg == 0 )
3860+
{
3861+
/* This is a blank generator. */
3862+
return PSA_ERROR_BAD_STATE;
3863+
}
3864+
38533865
if( output_length > generator->capacity )
38543866
{
38553867
generator->capacity = 0;
@@ -3858,11 +3870,10 @@ psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
38583870
status = PSA_ERROR_INSUFFICIENT_CAPACITY;
38593871
goto exit;
38603872
}
3861-
if( output_length == 0 &&
3862-
generator->capacity == 0 && generator->alg == 0 )
3873+
if( output_length == 0 && generator->capacity == 0 )
38633874
{
3864-
/* Edge case: this is a blank or finished generator, and 0
3865-
* bytes were requested. The right error in this case could
3875+
/* Edge case: this is a finished generator, and 0 bytes
3876+
* were requested. The right error in this case could
38663877
* be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
38673878
* INSUFFICIENT_CAPACITY, which is right for a finished
38683879
* generator, for consistency with the case when
@@ -3911,7 +3922,13 @@ psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
39113922
exit:
39123923
if( status != PSA_SUCCESS )
39133924
{
3925+
/* Preserve the algorithm upon errors, but clear all sensitive state.
3926+
* This allows us to differentiate between exhaused generators and
3927+
* blank generators, so we can return PSA_ERROR_BAD_STATE on blank
3928+
* generators. */
3929+
psa_algorithm_t alg = generator->alg;
39143930
psa_generator_abort( generator );
3931+
generator->alg = alg;
39153932
memset( output, '!', output_length );
39163933
}
39173934
return( status );

tests/suites/test_suite_psa_crypto.function

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3519,13 +3519,13 @@ void crypto_generator_init( )
35193519

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

3522-
/* A default generator should have no capacity. */
3523-
PSA_ASSERT( psa_get_generator_capacity( &func, &capacity ) );
3524-
TEST_EQUAL( capacity, 0 );
3525-
PSA_ASSERT( psa_get_generator_capacity( &init, &capacity ) );
3526-
TEST_EQUAL( capacity, 0 );
3527-
PSA_ASSERT( psa_get_generator_capacity( &zero, &capacity ) );
3528-
TEST_EQUAL( capacity, 0 );
3522+
/* A default generator should not be able to report its capacity. */
3523+
TEST_EQUAL( psa_get_generator_capacity( &func, &capacity ),
3524+
PSA_ERROR_BAD_STATE );
3525+
TEST_EQUAL( psa_get_generator_capacity( &init, &capacity ),
3526+
PSA_ERROR_BAD_STATE );
3527+
TEST_EQUAL( psa_get_generator_capacity( &zero, &capacity ),
3528+
PSA_ERROR_BAD_STATE );
35293529

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

36343634
TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
3635-
== PSA_ERROR_INSUFFICIENT_CAPACITY ); // should be PSA_ERROR_BAD_STATE:#183
3635+
== PSA_ERROR_BAD_STATE );
36363636

36373637
TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
3638-
== PSA_SUCCESS ); // should be PSA_ERROR_BAD_STATE:#183
3638+
== PSA_ERROR_BAD_STATE );
36393639

36403640
PSA_ASSERT( psa_generator_abort( &generator ) );
36413641

36423642
TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
3643-
== PSA_ERROR_INSUFFICIENT_CAPACITY ); // should be PSA_ERROR_BAD_STATE:#183
3643+
== PSA_ERROR_BAD_STATE );
36443644

36453645
TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
3646-
== PSA_SUCCESS );// should be PSA_ERROR_BAD_STATE:#183
3646+
== PSA_ERROR_BAD_STATE );
36473647

36483648
exit:
36493649
psa_generator_abort( &generator );

0 commit comments

Comments
 (0)