SE keys: test that no function goes crazy

Run all functions that take a key handle as input with a key that is
in a secure element. All calls are expected to error out one way or
another (not permitted by policy, invalid key type, method not
implemented in the secure element, ...). The goal of this test is to
ensure that nothing bad happens (e.g. invalid pointer dereference).

Run with various key types and algorithms to get good coverage.
This commit is contained in:
Gilles Peskine 2019-07-24 13:45:36 +02:00
parent d1cd766e96
commit 105736653f
2 changed files with 287 additions and 0 deletions

View file

@ -39,5 +39,59 @@ key_creation_import_export:0:1
SE key import-export, check after restart (slot 3)
key_creation_import_export:3:1
Key creation smoke test: AES-CTR
key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CTR:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Key creation smoke test: AES-CBC
key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CBC_NO_PADDING:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Key creation smoke test: AES-CMAC
key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Key creation smoke test: AES-CCM
key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Key creation smoke test: AES-GCM
key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Key creation smoke test: CAMELLIA-CTR
key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CTR:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Key creation smoke test: CAMELLIA-CBC
key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CBC_NO_PADDING:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Key creation smoke test: CAMELLIA-CMAC
key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Key creation smoke test: CAMELLIA-CCM
key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Key creation smoke test: CAMELLIA-CCM
key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Key creation smoke test: HMAC-SHA-256
key_creation_smoke:PSA_KEY_TYPE_HMAC:PSA_ALG_HMAC( PSA_ALG_SHA_256 ):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Key creation smoke test: HKDF-SHA-256
key_creation_smoke:PSA_KEY_TYPE_DERIVE:PSA_ALG_HKDF( PSA_ALG_SHA_256 ):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Key creation smoke test: RSA PKCS#1v1.5 signature
key_creation_smoke:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
Key creation smoke test: RSA PKCS#1v1.5 encryption
key_creation_smoke:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_CRYPT:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
Key creation smoke test: RSA OAEP encryption
key_creation_smoke:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_OAEP( PSA_ALG_SHA_256 ):"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
Key creation smoke test: ECDSA secp256r1
key_creation_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_ECDSA_ANY:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee"
Key creation smoke test: ECDH secp256r1
key_creation_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_ECDH:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee"
Key creation smoke test: ECDH secp256r1 with HKDF
key_creation_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_KEY_AGREEMENT( PSA_ALG_ECDH, PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee"
Generate key: not supported
generate_key_not_supported:PSA_KEY_TYPE_AES:128

View file

@ -33,6 +33,50 @@
/****************************************************************/
/* Miscellaneous driver methods */
/****************************************************************/
/* Allocate slot numbers with a monotonic counter. */
static psa_status_t counter_allocate( psa_drv_se_context_t *context,
void *persistent_data,
const psa_key_attributes_t *attributes,
psa_key_slot_number_t *slot_number )
{
psa_key_slot_number_t *p_counter = persistent_data;
(void) attributes;
if( context->persistent_data_size != sizeof( psa_key_slot_number_t ) )
return( PSA_ERROR_DETECTED_BY_DRIVER );
++*p_counter;
if( *p_counter == 0 )
return( PSA_ERROR_INSUFFICIENT_STORAGE );
*slot_number = *p_counter;
return( PSA_SUCCESS );
}
/* Null import: do nothing, but pretend it worked. */
static psa_status_t null_import( psa_drv_se_context_t *context,
psa_key_slot_number_t slot_number,
psa_key_lifetime_t lifetime,
psa_key_type_t type,
psa_algorithm_t algorithm,
psa_key_usage_t usage,
const uint8_t *p_data,
size_t data_length )
{
(void) context;
(void) slot_number;
(void) lifetime;
(void) type;
(void) algorithm;
(void) usage;
(void) p_data;
(void) data_length;
return( PSA_SUCCESS );
}
/****************************************************************/
/* RAM-based test driver */
/****************************************************************/
@ -134,6 +178,136 @@ static psa_status_t ram_allocate( psa_drv_se_context_t *context,
/* Other test helper functions */
/****************************************************************/
/* Check that a function's return status is "smoke-free", i.e. that
* it's an acceptable error code when calling an API function that operates
* on a key with potentially bogus parameters. */
static int is_status_smoke_free( psa_status_t status )
{
switch( status )
{
case PSA_SUCCESS:
case PSA_ERROR_NOT_SUPPORTED:
case PSA_ERROR_NOT_PERMITTED:
case PSA_ERROR_BUFFER_TOO_SMALL:
case PSA_ERROR_INVALID_ARGUMENT:
case PSA_ERROR_INVALID_SIGNATURE:
case PSA_ERROR_INVALID_PADDING:
return( 1 );
default:
return( 0 );
}
}
#define SMOKE_ASSERT( expr ) \
TEST_ASSERT( is_status_smoke_free( expr ) )
/* Smoke test a key. There are mostly no wrong answers here since we pass
* mostly bogus parameters: the goal is to ensure that there is no memory
* corruption or crash. This test function is most useful when run under
* an environment with sanity checks such as ASan or MSan. */
static int smoke_test_key( psa_key_handle_t handle )
{
int ok = 0;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_mac_operation_t mac_operation = PSA_MAC_OPERATION_INIT;
psa_cipher_operation_t cipher_operation = PSA_CIPHER_OPERATION_INIT;
psa_key_derivation_operation_t derivation_operation =
PSA_KEY_DERIVATION_OPERATION_INIT;
uint8_t buffer[80]; /* large enough for a public key for ECDH */
size_t length;
psa_key_handle_t handle2 = 0;
SMOKE_ASSERT( psa_get_key_attributes( handle, &attributes ) );
SMOKE_ASSERT( psa_export_key( handle,
buffer, sizeof( buffer ), &length ) );
SMOKE_ASSERT( psa_export_public_key( handle,
buffer, sizeof( buffer ), &length ) );
SMOKE_ASSERT( psa_copy_key( handle, &attributes, &handle2 ) );
if( handle2 != 0 )
PSA_ASSERT( psa_close_key( handle2 ) );
SMOKE_ASSERT( psa_mac_sign_setup( &mac_operation, handle, PSA_ALG_CMAC ) );
PSA_ASSERT( psa_mac_abort( &mac_operation ) );
SMOKE_ASSERT( psa_mac_verify_setup( &mac_operation, handle,
PSA_ALG_HMAC( PSA_ALG_SHA_256 ) ) );
PSA_ASSERT( psa_mac_abort( &mac_operation ) );
SMOKE_ASSERT( psa_cipher_encrypt_setup( &cipher_operation, handle,
PSA_ALG_CTR ) );
PSA_ASSERT( psa_cipher_abort( &cipher_operation ) );
SMOKE_ASSERT( psa_cipher_decrypt_setup( &cipher_operation, handle,
PSA_ALG_CTR ) );
PSA_ASSERT( psa_cipher_abort( &cipher_operation ) );
SMOKE_ASSERT( psa_aead_encrypt( handle, PSA_ALG_CCM,
buffer, sizeof( buffer ),
NULL, 0,
buffer, sizeof( buffer),
buffer, sizeof( buffer), &length ) );
SMOKE_ASSERT( psa_aead_decrypt( handle, PSA_ALG_CCM,
buffer, sizeof( buffer ),
NULL, 0,
buffer, sizeof( buffer),
buffer, sizeof( buffer), &length ) );
SMOKE_ASSERT( psa_asymmetric_sign( handle, PSA_ALG_ECDSA_ANY,
buffer, 32,
buffer, sizeof( buffer ), &length ) );
SMOKE_ASSERT( psa_asymmetric_verify( handle, PSA_ALG_ECDSA_ANY,
buffer, 32,
buffer, sizeof( buffer ) ) );
SMOKE_ASSERT( psa_asymmetric_encrypt( handle, PSA_ALG_RSA_PKCS1V15_CRYPT,
buffer, 10, NULL, 0,
buffer, sizeof( buffer ), &length ) );
SMOKE_ASSERT( psa_asymmetric_decrypt( handle, PSA_ALG_RSA_PKCS1V15_CRYPT,
buffer, sizeof( buffer ), NULL, 0,
buffer, sizeof( buffer ), &length ) );
#if defined(MBEDTLS_SHA256_C)
/* Try the key in a plain key derivation. */
PSA_ASSERT( psa_key_derivation_setup( &derivation_operation,
PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ) );
PSA_ASSERT( psa_key_derivation_input_bytes( &derivation_operation,
PSA_KEY_DERIVATION_INPUT_SALT,
NULL, 0 ) );
SMOKE_ASSERT( psa_key_derivation_input_key( &derivation_operation,
PSA_KEY_DERIVATION_INPUT_SECRET,
handle ) );
PSA_ASSERT( psa_key_derivation_abort( &derivation_operation ) );
/* If the key is asymmetric, try it in a key agreement, both as
* part of a derivation operation and standalone. */
if( psa_export_public_key( handle, buffer, sizeof( buffer ), &length ) ==
PSA_SUCCESS )
{
psa_algorithm_t alg =
PSA_ALG_KEY_AGREEMENT( PSA_ALG_ECDH,
PSA_ALG_HKDF( PSA_ALG_SHA_256 ) );
PSA_ASSERT( psa_key_derivation_setup( &derivation_operation, alg ) );
PSA_ASSERT( psa_key_derivation_input_bytes(
&derivation_operation, PSA_KEY_DERIVATION_INPUT_SALT,
NULL, 0 ) );
SMOKE_ASSERT( psa_key_derivation_key_agreement(
&derivation_operation,
PSA_KEY_DERIVATION_INPUT_SECRET,
handle, buffer, length ) );
PSA_ASSERT( psa_key_derivation_abort( &derivation_operation ) );
SMOKE_ASSERT( psa_raw_key_agreement(
alg, handle, buffer, length,
buffer, sizeof( buffer ), &length ) );
}
#endif /* MBEDTLS_SHA256_C */
ok = 1;
exit:
psa_reset_key_attributes( &attributes );
return( ok );
}
#define MAX_KEY_ID_FOR_TEST 10
static void psa_purge_storage( void )
{
@ -289,6 +463,65 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE */
void key_creation_smoke( int type_arg, int alg_arg,
data_t *key_material )
{
psa_key_type_t type = type_arg;
psa_algorithm_t alg = alg_arg;
psa_drv_se_t driver;
psa_drv_se_key_management_t key_management;
psa_key_lifetime_t lifetime = 2;
psa_key_id_t id = 1;
psa_key_handle_t handle = 0;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
memset( &driver, 0, sizeof( driver ) );
memset( &key_management, 0, sizeof( key_management ) );
driver.hal_version = PSA_DRV_SE_HAL_VERSION;
driver.key_management = &key_management;
driver.persistent_data_size = sizeof( psa_key_slot_number_t );
key_management.p_allocate = counter_allocate;
key_management.p_import = null_import;
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
PSA_ASSERT( psa_crypto_init( ) );
/* Create a key. */
psa_set_key_id( &attributes, id );
psa_set_key_lifetime( &attributes, lifetime );
psa_set_key_usage_flags( &attributes,
PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY |
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT |
PSA_KEY_USAGE_EXPORT );
psa_set_key_algorithm( &attributes, alg );
psa_set_key_type( &attributes, type );
PSA_ASSERT( psa_import_key( &attributes,
key_material->x, key_material->len,
&handle ) );
/* Do stuff with the key. */
if( ! smoke_test_key( handle ) )
goto exit;
/* Restart and try again. */
mbedtls_psa_crypto_free( );
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
PSA_ASSERT( psa_crypto_init( ) );
PSA_ASSERT( psa_open_key( id, &handle ) );
if( ! smoke_test_key( handle ) )
goto exit;
/* We're done. */
PSA_ASSERT( psa_destroy_key( handle ) );
exit:
PSA_DONE( );
ram_slots_reset( );
psa_purge_storage( );
}
/* END_CASE */
/* BEGIN_CASE */
void generate_key_not_supported( int type_arg, int bits_arg )
{