From f426e0f3031034e43bdc7fb86e3a67fa97ec610f Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 25 Feb 2019 17:42:03 +0100 Subject: [PATCH] Smoke-test operation contexts after setup+abort After a successful setup followed by abort, or after a failed setup from an inactive state, a context must be usable. Test this for hash, MAC and cipher contexts. --- tests/suites/test_suite_psa_crypto.function | 233 ++++++++++++++++---- 1 file changed, 188 insertions(+), 45 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 5c662d8f1..7da745654 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -14,6 +14,89 @@ /** An invalid export length that will never be set by psa_export_key(). */ static const size_t INVALID_EXPORT_LENGTH = ~0U; +/* A hash algorithm that is known to be supported. + * + * This is used in some smoke tests. + */ +#if defined(MBEDTLS_MD2_C) +#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD2 +#elif defined(MBEDTLS_MD4_C) +#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD4 +#elif defined(MBEDTLS_MD5_C) +#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5 +/* MBEDTLS_RIPEMD160_C omitted. This is necessary for the sake of + * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160 + * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be + * implausible anyway. */ +#elif defined(MBEDTLS_SHA1_C) +#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1 +#elif defined(MBEDTLS_SHA256_C) +#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256 +#elif defined(MBEDTLS_SHA512_C) +#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384 +#elif defined(MBEDTLS_SHA3_C) +#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256 +#else +#undef KNOWN_SUPPORTED_HASH_ALG +#endif + +/* A block cipher that is known to be supported. + * + * For simplicity's sake, stick to block ciphers with 16-byte blocks. + */ +#if defined(MBEDTLS_AES_C) +#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES +#elif defined(MBEDTLS_ARIA_C) +#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA +#elif defined(MBEDTLS_CAMELLIA_C) +#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA +#undef KNOWN_SUPPORTED_BLOCK_CIPHER +#endif + +/* A MAC mode that is known to be supported. + * + * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or + * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER. + * + * This is used in some smoke tests. + */ +#if defined(KNOWN_SUPPORTED_HASH_ALG) +#define KNOWN_SUPPORTED_MAC_ALG ( PSA_ALG_HMAC( KNOWN_SUPPORTED_HASH_ALG ) ) +#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC +#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C) +#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC +#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER +#else +#undef KNOWN_SUPPORTED_MAC_ALG +#undef KNOWN_SUPPORTED_MAC_KEY_TYPE +#endif + +/* A cipher algorithm and key type that are known to be supported. + * + * This is used in some smoke tests. + */ +#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CTR) +#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR +#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CBC) +#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING +#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_CFB) +#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB +#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CIPHER_MODE_OFB) +#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB +#else +#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG +#endif +#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG) +#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG +#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER +#elif defined(MBEDTLS_RC4_C) +#define KNOWN_SUPPORTED_CIPHER_ALG PSA_ALG_RC4 +#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE PSA_KEY_TYPE_RC4 +#else +#undef KNOWN_SUPPORTED_CIPHER_ALG +#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE +#endif + /** Test if a buffer contains a constant byte value. * * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`. @@ -120,6 +203,64 @@ static int construct_fake_rsa_key( unsigned char *buffer, return( len ); } +int exercise_mac_setup( psa_key_type_t key_type, + const unsigned char *key_bytes, + size_t key_length, + psa_algorithm_t alg, + psa_mac_operation_t *operation, + psa_status_t *status ) +{ + psa_key_handle_t handle = 0; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; + + PSA_ASSERT( psa_allocate_key( &handle ) ); + psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg ); + PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); + PSA_ASSERT( psa_import_key( handle, key_type, key_bytes, key_length ) ); + + *status = psa_mac_sign_setup( operation, handle, alg ); + if( *status == PSA_SUCCESS ) + { + PSA_ASSERT( psa_mac_abort( operation ) ); + } + + psa_destroy_key( handle ); + return( 1 ); + +exit: + psa_destroy_key( handle ); + return( 0 ); +} + +int exercise_cipher_setup( psa_key_type_t key_type, + const unsigned char *key_bytes, + size_t key_length, + psa_algorithm_t alg, + psa_cipher_operation_t *operation, + psa_status_t *status ) +{ + psa_key_handle_t handle = 0; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; + + PSA_ASSERT( psa_allocate_key( &handle ) ); + psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg ); + PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); + PSA_ASSERT( psa_import_key( handle, key_type, key_bytes, key_length ) ); + + *status = psa_cipher_encrypt_setup( operation, handle, alg ); + if( *status == PSA_SUCCESS ) + { + PSA_ASSERT( psa_cipher_abort( operation ) ); + } + + psa_destroy_key( handle ); + return( 1 ); + +exit: + psa_destroy_key( handle ); + return( 0 ); +} + static int exercise_mac_key( psa_key_handle_t handle, psa_key_usage_t usage, psa_algorithm_t alg ) @@ -287,26 +428,13 @@ static int exercise_signature_key( psa_key_handle_t handle, /* If the policy allows signing with any hash, just pick one. */ if( PSA_ALG_IS_HASH_AND_SIGN( alg ) && hash_alg == PSA_ALG_ANY_HASH ) { -#if defined(MBEDTLS_MD2_C) - hash_alg = PSA_ALG_MD2; -#elif defined(MBEDTLS_MD4_C) - hash_alg = PSA_ALG_MD4; -#elif defined(MBEDTLS_MD5_C) - hash_alg = PSA_ALG_MD5; - /* MBEDTLS_RIPEMD160_C omitted because Mbed TLS doesn't - * support it in RSA PKCS#1v1.5 signatures. */ -#elif defined(MBEDTLS_SHA1_C) - hash_alg = PSA_ALG_SHA_1; -#elif defined(MBEDTLS_SHA256_C) - hash_alg = PSA_ALG_SHA_256; -#elif defined(MBEDTLS_SHA512_C) - hash_alg = PSA_ALG_SHA_384; -#elif defined(MBEDTLS_SHA3_C) - hash_alg = PSA_ALG_SHA3_256; +#if defined(KNOWN_SUPPORTED_HASH_ALG) + hash_alg = KNOWN_SUPPORTED_HASH_ALG; + alg ^= PSA_ALG_ANY_HASH ^ hash_alg; #else test_fail( "No hash algorithm for hash-and-sign testing", __LINE__, __FILE__ ); + return( 1 ); #endif - alg ^= PSA_ALG_ANY_HASH ^ hash_alg; } if( usage & PSA_KEY_USAGE_SIGN ) @@ -1988,9 +2116,16 @@ void hash_setup( int alg_arg, PSA_ASSERT( psa_crypto_init( ) ); status = psa_hash_setup( &operation, alg ); - psa_hash_abort( &operation ); TEST_EQUAL( status, expected_status ); + if( status == PSA_SUCCESS ) + PSA_ASSERT( psa_hash_abort( &operation ) ); + /* Now the operation object should be reusable. */ +#if defined(KNOWN_SUPPORTED_HASH_ALG) + PSA_ASSERT( psa_hash_setup( &operation, KNOWN_SUPPORTED_HASH_ALG ) ); + PSA_ASSERT( psa_hash_abort( &operation ) ); +#endif + exit: mbedtls_psa_crypto_free( ); } @@ -2266,31 +2401,34 @@ void mac_setup( int key_type_arg, int alg_arg, int expected_status_arg ) { - psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_status_t expected_status = expected_status_arg; psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; - psa_key_policy_t policy = PSA_KEY_POLICY_INIT; - psa_status_t status; + psa_status_t status = PSA_ERROR_GENERIC_ERROR; +#if defined(KNOWN_SUPPORTED_MAC_ALG) + const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk"; +#endif PSA_ASSERT( psa_crypto_init( ) ); - PSA_ASSERT( psa_allocate_key( &handle ) ); - psa_key_policy_set_usage( &policy, - PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY, - alg ); - PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); - - PSA_ASSERT( psa_import_key( handle, key_type, - key->x, key->len ) ); - - status = psa_mac_sign_setup( &operation, handle, alg ); - psa_mac_abort( &operation ); + if( ! exercise_mac_setup( key_type, key->x, key->len, alg, + &operation, &status ) ) + goto exit; TEST_EQUAL( status, expected_status ); + /* The operation object should be reusable. */ +#if defined(KNOWN_SUPPORTED_MAC_ALG) + if( ! exercise_mac_setup( KNOWN_SUPPORTED_MAC_KEY_TYPE, + smoke_test_key_data, + sizeof( smoke_test_key_data ), + KNOWN_SUPPORTED_MAC_ALG, + &operation, &status ) ) + goto exit; + TEST_EQUAL( status, PSA_SUCCESS ); +#endif + exit: - psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -2560,29 +2698,34 @@ void cipher_setup( int key_type_arg, int alg_arg, int expected_status_arg ) { - psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_status_t expected_status = expected_status_arg; psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; - psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_status_t status; +#if defined(KNOWN_SUPPORTED_MAC_ALG) + const uint8_t smoke_test_key_data[16] = "kkkkkkkkkkkkkkkk"; +#endif PSA_ASSERT( psa_crypto_init( ) ); - PSA_ASSERT( psa_allocate_key( &handle ) ); - psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg ); - PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); - - PSA_ASSERT( psa_import_key( handle, key_type, - key->x, key->len ) ); - - status = psa_cipher_encrypt_setup( &operation, handle, alg ); - psa_cipher_abort( &operation ); + if( ! exercise_cipher_setup( key_type, key->x, key->len, alg, + &operation, &status ) ) + goto exit; TEST_EQUAL( status, expected_status ); + /* The operation object should be reusable. */ +#if defined(KNOWN_SUPPORTED_CIPHER_ALG) + if( ! exercise_cipher_setup( KNOWN_SUPPORTED_CIPHER_KEY_TYPE, + smoke_test_key_data, + sizeof( smoke_test_key_data ), + KNOWN_SUPPORTED_CIPHER_ALG, + &operation, &status ) ) + goto exit; + TEST_EQUAL( status, PSA_SUCCESS ); +#endif + exit: - psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */