diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 1f96ae079..40c676a5d 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1379,7 +1379,13 @@ psa_status_t psa_hash_setup( psa_hash_operation_t *operation, psa_algorithm_t alg ) { int ret; - operation->alg = 0; + + /* A context must be freshly initialized before it can be set up. */ + if( operation->alg != 0 ) + { + return( PSA_ERROR_BAD_STATE ); + } + switch( alg ) { #if defined(MBEDTLS_MD2_C) @@ -1998,6 +2004,12 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg ); psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg ); + /* A context must be freshly initialized before it can be set up. */ + if( operation->alg != 0 ) + { + return( PSA_ERROR_BAD_STATE ); + } + status = psa_mac_init( operation, full_length_alg ); if( status != PSA_SUCCESS ) return( status ); @@ -2909,6 +2921,12 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT ); + /* A context must be freshly initialized before it can be set up. */ + if( operation->alg != 0 ) + { + return( PSA_ERROR_BAD_STATE ); + } + status = psa_cipher_init( operation, alg ); if( status != PSA_SUCCESS ) return( status ); diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 2499102a5..9ea6cc09b 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -2012,6 +2012,12 @@ void hash_bad_order( ) PSA_ASSERT( psa_crypto_init( ) ); + /* Call setup twice in a row. */ + PSA_ASSERT( psa_hash_setup( &operation, alg ) ); + TEST_EQUAL( psa_hash_setup( &operation, alg ), + PSA_ERROR_BAD_STATE ); + PSA_ASSERT( psa_hash_abort( &operation ) ); + /* Call update without calling setup beforehand. */ TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ), PSA_ERROR_BAD_STATE ); @@ -2336,6 +2342,14 @@ void mac_bad_order( ) PSA_ERROR_BAD_STATE ); PSA_ASSERT( psa_mac_abort( &operation ) ); + /* Call setup twice in a row. */ + PSA_ASSERT( psa_mac_sign_setup( &operation, + handle, alg ) ); + TEST_EQUAL( psa_mac_sign_setup( &operation, + handle, alg ), + PSA_ERROR_BAD_STATE ); + PSA_ASSERT( psa_mac_abort( &operation ) ); + /* Call update after sign finish. */ PSA_ASSERT( psa_mac_sign_setup( &operation, handle, alg ) ); @@ -2601,6 +2615,18 @@ void cipher_bad_order( ) key, sizeof(key) ) ); + /* Call encrypt setup twice in a row. */ + PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) ); + TEST_EQUAL( psa_cipher_encrypt_setup( &operation, handle, alg ), + PSA_ERROR_BAD_STATE ); + PSA_ASSERT( psa_cipher_abort( &operation ) ); + + /* Call decrypt setup twice in a row. */ + PSA_ASSERT( psa_cipher_decrypt_setup( &operation, handle, alg ) ); + TEST_EQUAL( psa_cipher_decrypt_setup( &operation, handle, alg ), + PSA_ERROR_BAD_STATE ); + PSA_ASSERT( psa_cipher_abort( &operation ) ); + /* Generate an IV without calling setup beforehand. */ TEST_EQUAL( psa_cipher_generate_iv( &operation, buffer, sizeof( buffer ),