Skip to content

Commit ab43997

Browse files
committed
psa: Disallow use of invalid cipher contexts
Ensure that when doing cipher operations out of order, PSA_ERROR_BAD_STATE is returned as documented in crypto.h and the PSA Crypto specification.
1 parent 252ef28 commit ab43997

File tree

3 files changed

+171
-0
lines changed

3 files changed

+171
-0
lines changed

library/psa_crypto.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3073,6 +3073,12 @@ psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
30733073
psa_status_t status;
30743074
int ret;
30753075
size_t expected_output_size;
3076+
3077+
if( operation->alg == 0 )
3078+
{
3079+
return( PSA_ERROR_BAD_STATE );
3080+
}
3081+
30763082
if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
30773083
{
30783084
/* Take the unprocessed partial block left over from previous

tests/suites/test_suite_psa_crypto.data

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,10 @@ depends_on:MBEDTLS_ARC4_C:MBEDTLS_CIPHER_MODE_CTR
926926
# Either INVALID_ARGUMENT or NOT_SUPPORTED would be reasonable here
927927
cipher_setup:PSA_KEY_TYPE_ARC4:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CTR:PSA_ERROR_NOT_SUPPORTED
928928

929+
PSA cipher: bad order function calls
930+
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
931+
cipher_bad_order:
932+
929933
PSA symmetric encrypt: AES-CBC-nopad, 16 bytes, good
930934
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
931935
cipher_encrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":"a076ec9dfbe47d52afc357336f20743b":PSA_SUCCESS

tests/suites/test_suite_psa_crypto.function

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2447,6 +2447,9 @@ exit:
24472447
/* BEGIN_CASE */
24482448
void cipher_operation_init( )
24492449
{
2450+
const uint8_t input[1] = { 0 };
2451+
unsigned char output[1] = { 0 };
2452+
size_t output_length;
24502453
/* Test each valid way of initializing the object, except for `= {0}`, as
24512454
* Clang 5 complains when `-Wmissing-field-initializers` is used, even
24522455
* though it's OK by the C standard. We could test for this, but we'd need
@@ -2457,6 +2460,23 @@ void cipher_operation_init( )
24572460

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

2463+
/* A freshly-initialized cipher operation should not be usable. */
2464+
TEST_EQUAL( psa_cipher_update( &func,
2465+
input, sizeof( input ),
2466+
output, sizeof( output ),
2467+
&output_length ),
2468+
PSA_ERROR_BAD_STATE );
2469+
TEST_EQUAL( psa_cipher_update( &init,
2470+
input, sizeof( input ),
2471+
output, sizeof( output ),
2472+
&output_length ),
2473+
PSA_ERROR_BAD_STATE );
2474+
TEST_EQUAL( psa_cipher_update( &zero,
2475+
input, sizeof( input ),
2476+
output, sizeof( output ),
2477+
&output_length ),
2478+
PSA_ERROR_BAD_STATE );
2479+
24602480
/* A default cipher operation should be abortable without error. */
24612481
PSA_ASSERT( psa_cipher_abort( &func ) );
24622482
PSA_ASSERT( psa_cipher_abort( &init ) );
@@ -2497,6 +2517,147 @@ exit:
24972517
}
24982518
/* END_CASE */
24992519

2520+
/* BEGIN_CASE */
2521+
void cipher_bad_order( )
2522+
{
2523+
psa_key_handle_t handle = 0;
2524+
psa_key_type_t key_type = PSA_KEY_TYPE_AES;
2525+
psa_algorithm_t alg = PSA_ALG_CBC_PKCS7;
2526+
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
2527+
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
2528+
unsigned char iv[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2529+
const uint8_t key[] = {
2530+
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
2531+
0xaa, 0xaa, 0xaa, 0xaa };
2532+
const uint8_t text[] = {
2533+
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
2534+
0xbb, 0xbb, 0xbb, 0xbb };
2535+
uint8_t buffer[PSA_BLOCK_CIPHER_BLOCK_SIZE(PSA_KEY_TYPE_AES)] = { 0 };
2536+
size_t length = 0;
2537+
2538+
PSA_ASSERT( psa_crypto_init( ) );
2539+
PSA_ASSERT( psa_allocate_key( &handle ) );
2540+
psa_key_policy_set_usage( &policy,
2541+
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
2542+
alg );
2543+
PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
2544+
PSA_ASSERT( psa_import_key( handle, key_type,
2545+
key, sizeof(key) ) );
2546+
2547+
2548+
/* Generate an IV without calling setup beforehand. */
2549+
TEST_EQUAL( psa_cipher_generate_iv( &operation,
2550+
buffer, sizeof( buffer ),
2551+
&length ),
2552+
PSA_ERROR_BAD_STATE );
2553+
PSA_ASSERT( psa_cipher_abort( &operation ) );
2554+
2555+
/* Generate an IV twice in a row. */
2556+
PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2557+
PSA_ASSERT( psa_cipher_generate_iv( &operation,
2558+
buffer, sizeof( buffer ),
2559+
&length ) );
2560+
TEST_EQUAL( psa_cipher_generate_iv( &operation,
2561+
buffer, sizeof( buffer ),
2562+
&length ),
2563+
PSA_ERROR_BAD_STATE );
2564+
PSA_ASSERT( psa_cipher_abort( &operation ) );
2565+
2566+
/* Generate an IV after it's already set. */
2567+
PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2568+
PSA_ASSERT( psa_cipher_set_iv( &operation,
2569+
iv, sizeof( iv ) ) );
2570+
TEST_EQUAL( psa_cipher_generate_iv( &operation,
2571+
buffer, sizeof( buffer ),
2572+
&length ),
2573+
PSA_ERROR_BAD_STATE );
2574+
PSA_ASSERT( psa_cipher_abort( &operation ) );
2575+
2576+
/* Set an IV without calling setup beforehand. */
2577+
TEST_EQUAL( psa_cipher_set_iv( &operation,
2578+
iv, sizeof( iv ) ),
2579+
PSA_ERROR_BAD_STATE );
2580+
PSA_ASSERT( psa_cipher_abort( &operation ) );
2581+
2582+
/* Set an IV after it's already set. */
2583+
PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2584+
PSA_ASSERT( psa_cipher_set_iv( &operation,
2585+
iv, sizeof( iv ) ) );
2586+
TEST_EQUAL( psa_cipher_set_iv( &operation,
2587+
iv, sizeof( iv ) ),
2588+
PSA_ERROR_BAD_STATE );
2589+
PSA_ASSERT( psa_cipher_abort( &operation ) );
2590+
2591+
/* Set an IV after it's already generated. */
2592+
PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2593+
PSA_ASSERT( psa_cipher_generate_iv( &operation,
2594+
buffer, sizeof( buffer ),
2595+
&length ) );
2596+
TEST_EQUAL( psa_cipher_set_iv( &operation,
2597+
iv, sizeof( iv ) ),
2598+
PSA_ERROR_BAD_STATE );
2599+
PSA_ASSERT( psa_cipher_abort( &operation ) );
2600+
2601+
/* Call update without calling setup beforehand. */
2602+
TEST_EQUAL( psa_cipher_update( &operation,
2603+
text, sizeof( text ),
2604+
buffer, sizeof( buffer ),
2605+
&length ),
2606+
PSA_ERROR_BAD_STATE );
2607+
PSA_ASSERT( psa_cipher_abort( &operation ) );
2608+
2609+
/* Call update without an IV where an IV is required. */
2610+
TEST_EQUAL( psa_cipher_update( &operation,
2611+
text, sizeof( text ),
2612+
buffer, sizeof( buffer ),
2613+
&length ),
2614+
PSA_ERROR_BAD_STATE );
2615+
PSA_ASSERT( psa_cipher_abort( &operation ) );
2616+
2617+
/* Call update after finish. */
2618+
PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2619+
PSA_ASSERT( psa_cipher_set_iv( &operation,
2620+
iv, sizeof( iv ) ) );
2621+
PSA_ASSERT( psa_cipher_finish( &operation,
2622+
buffer, sizeof( buffer ), &length ) );
2623+
TEST_EQUAL( psa_cipher_update( &operation,
2624+
text, sizeof( text ),
2625+
buffer, sizeof( buffer ),
2626+
&length ),
2627+
PSA_ERROR_BAD_STATE );
2628+
PSA_ASSERT( psa_cipher_abort( &operation ) );
2629+
2630+
/* Call finish without calling setup beforehand. */
2631+
TEST_EQUAL( psa_cipher_finish( &operation,
2632+
buffer, sizeof( buffer ), &length ),
2633+
PSA_ERROR_BAD_STATE );
2634+
PSA_ASSERT( psa_cipher_abort( &operation ) );
2635+
2636+
/* Call finish without an IV where an IV is required. */
2637+
PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2638+
/* Not calling update means we are encrypting an empty buffer, which is OK
2639+
* for cipher modes with padding. */
2640+
TEST_EQUAL( psa_cipher_finish( &operation,
2641+
buffer, sizeof( buffer ), &length ),
2642+
PSA_ERROR_BAD_STATE );
2643+
PSA_ASSERT( psa_cipher_abort( &operation ) );
2644+
2645+
/* Call finish twice in a row. */
2646+
PSA_ASSERT( psa_cipher_encrypt_setup( &operation, handle, alg ) );
2647+
PSA_ASSERT( psa_cipher_set_iv( &operation,
2648+
iv, sizeof( iv ) ) );
2649+
PSA_ASSERT( psa_cipher_finish( &operation,
2650+
buffer, sizeof( buffer ), &length ) );
2651+
TEST_EQUAL( psa_cipher_finish( &operation,
2652+
buffer, sizeof( buffer ), &length ),
2653+
PSA_ERROR_BAD_STATE );
2654+
PSA_ASSERT( psa_cipher_abort( &operation ) );
2655+
2656+
exit:
2657+
mbedtls_psa_crypto_free( );
2658+
}
2659+
/* END_CASE */
2660+
25002661
/* BEGIN_CASE */
25012662
void cipher_encrypt( int alg_arg, int key_type_arg,
25022663
data_t *key,

0 commit comments

Comments
 (0)