From 0c6575a84dd77076b9f976396b07e3b39f56d316 Mon Sep 17 00:00:00 2001 From: Darryl Green Date: Wed, 7 Nov 2018 16:05:30 +0000 Subject: [PATCH] psa: Extend psa_generate_key to support persistent lifetimes --- library/psa_crypto.c | 41 +++++++++- tests/suites/test_suite_psa_crypto.data | 30 +++++++- tests/suites/test_suite_psa_crypto.function | 76 ++++++++++++++++--- ...t_suite_psa_crypto_persistent_key.function | 1 + 4 files changed, 136 insertions(+), 12 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 74c3cfc0b..58cb73830 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1107,6 +1107,37 @@ psa_status_t psa_export_public_key( psa_key_slot_t key, data_length, 1 ) ); } +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) +static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t key, + key_slot_t *slot, + size_t bits ) +{ + psa_status_t status; + uint8_t *data; + size_t key_length; + size_t data_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type, bits ); + data = mbedtls_calloc( 1, data_size ); + /* Get key data in export format */ + status = psa_internal_export_key( slot, data, data_size, &key_length, 0 ); + if( status != PSA_SUCCESS ) + { + slot->type = PSA_KEY_TYPE_NONE; + goto exit; + } + /* Store in file location */ + status = psa_save_persistent_key( key, slot->type, &slot->policy, + data, key_length ); + if( status != PSA_SUCCESS ) + { + slot->type = PSA_KEY_TYPE_NONE; + } +exit: + mbedtls_zeroize( data, key_length ); + mbedtls_free( data ); + return( status ); +} +#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ + /****************************************************************/ @@ -4309,7 +4340,15 @@ psa_status_t psa_generate_key( psa_key_slot_t key, return( PSA_ERROR_NOT_SUPPORTED ); slot->type = type; - return( PSA_SUCCESS ); + +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) + if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT ) + { + return( psa_save_generated_persistent_key( key, slot, bits ) ); + } +#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ + + return( status ); } diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 7e70de38a..e1c1b0545 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1837,4 +1837,32 @@ validate_module_init_key_based: persistent key can be accessed after in-memory deletion: AES, 128 bits, CTR depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PSA_CRYPTO_STORAGE_C -persistent_key_load_key_from_storage:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR +persistent_key_load_key_from_storage:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:IMPORT_KEY:PSA_SUCCESS + +PSA generate persistent key: raw data, 8 bits +depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C +persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:GENERATE_KEY:PSA_SUCCESS + +PSA generate persistent key: AES, 128 bits, CTR +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR:MBEDTLS_PSA_CRYPTO_STORAGE_C +persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:GENERATE_KEY:PSA_SUCCESS + +PSA generate persistent key: DES, 64 bits, CBC-nopad +depends_on:MBEDTLS_DES_C:MBEDTLS_PSA_CRYPTO_STORAGE_C +persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_DES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:GENERATE_KEY:PSA_SUCCESS + +PSA generate persistent key: RSA, 1024 bits, good, sign (PSS SHA-256) +depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C:MBEDTLS_PSA_CRYPTO_STORAGE_C +persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):GENERATE_KEY:PSA_SUCCESS + +PSA generate persistent key: ECC, SECP256R1, good +depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDSA_C:MBEDTLS_PSA_CRYPTO_STORAGE_C +persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):256:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:GENERATE_KEY:PSA_SUCCESS + +PSA derive persistent key: HKDF SHA-256 +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:MBEDTLS_PSA_CRYPTO_STORAGE_C +persistent_key_load_key_from_storage:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_TYPE_RAW_DATA:1024:PSA_KEY_USAGE_EXPORT:0:DERIVE_KEY:PSA_SUCCESS + +PSA generate persistent key: AES, 128 bits, CTR +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR:MBEDTLS_PSA_CRYPTO_STORAGE_C +persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:GENERATE_KEY:PSA_ERROR_NOT_PERMITTED diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 4692dbe84..53295befa 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -844,6 +844,13 @@ static psa_key_usage_t usage_to_exercise( psa_key_type_t type, } } + +typedef enum { + IMPORT_KEY = 0, + GENERATE_KEY = 1, + DERIVE_KEY = 2 +} generate_method; + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -4034,9 +4041,11 @@ void validate_module_init_key_based( ) /* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */ void persistent_key_load_key_from_storage( data_t *data, int type_arg, int bits, int usage_arg, - int alg_arg ) + int alg_arg, int generation_method, + int export_status ) { psa_key_slot_t slot = 1; + psa_key_slot_t base_key = 2; psa_key_type_t type = (psa_key_type_t) type_arg; psa_key_type_t type_get; size_t bits_get; @@ -4044,6 +4053,9 @@ void persistent_key_load_key_from_storage( data_t *data, int type_arg, psa_key_policy_t policy_get; psa_key_usage_t policy_usage = (psa_key_usage_t) usage_arg; psa_algorithm_t policy_alg = (psa_algorithm_t) alg_arg; + psa_key_policy_t base_policy_set; + psa_algorithm_t base_policy_alg = PSA_ALG_HKDF(PSA_ALG_SHA_256); + psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; unsigned char *first_export = NULL; unsigned char *second_export = NULL; size_t export_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits ); @@ -4064,14 +4076,44 @@ void persistent_key_load_key_from_storage( data_t *data, int type_arg, policy_alg ); TEST_ASSERT( psa_set_key_policy( slot, &policy_set ) == PSA_SUCCESS ); + switch( generation_method ) + { + case IMPORT_KEY: + /* Import the key */ + TEST_ASSERT( psa_import_key( slot, type, + data->x, data->len ) == PSA_SUCCESS ); + break; - /* Import the key */ - TEST_ASSERT( psa_import_key( slot, type, - data->x, data->len ) == PSA_SUCCESS ); + case GENERATE_KEY: + /* Generate a key */ + TEST_ASSERT( psa_generate_key( slot, type, bits, + NULL, 0 ) == PSA_SUCCESS ); + break; + + case DERIVE_KEY: + /* Create base key */ + psa_key_policy_init( &base_policy_set ); + + psa_key_policy_set_usage( &base_policy_set, PSA_KEY_USAGE_DERIVE, + base_policy_alg ); + TEST_ASSERT( psa_set_key_policy( + base_key, &base_policy_set ) == PSA_SUCCESS ); + TEST_ASSERT( psa_import_key( base_key, PSA_KEY_TYPE_DERIVE, + data->x, data->len ) == PSA_SUCCESS ); + /* Derive a key. */ + TEST_ASSERT( psa_key_derivation( &generator, base_key, + base_policy_alg, + NULL, 0, NULL, 0, + export_size ) == PSA_SUCCESS ); + TEST_ASSERT( psa_generator_import_key( + slot, PSA_KEY_TYPE_RAW_DATA, + bits, &generator ) == PSA_SUCCESS ); + break; + } /* Export the key */ TEST_ASSERT( psa_export_key( slot, first_export, export_size, - &first_exported_length ) == PSA_SUCCESS ); + &first_exported_length ) == export_status ); /* Shutdown and restart */ mbedtls_psa_crypto_free(); @@ -4096,13 +4138,27 @@ void persistent_key_load_key_from_storage( data_t *data, int type_arg, /* Export the key again */ TEST_ASSERT( psa_export_key( slot, second_export, export_size, - &second_exported_length ) == PSA_SUCCESS ); + &second_exported_length ) == export_status ); - ASSERT_COMPARE( first_export, first_exported_length, - second_export, second_exported_length ); + if( export_status == PSA_SUCCESS ) + { + ASSERT_COMPARE( first_export, first_exported_length, + second_export, second_exported_length ); - ASSERT_COMPARE( data->x, data->len, - first_export, first_exported_length ); + switch( generation_method ) + { + case IMPORT_KEY: + ASSERT_COMPARE( data->x, data->len, + first_export, first_exported_length ); + break; + default: + break; + } + } + + /* Do something with the key according to its type and permitted usage. */ + if( ! exercise_key( slot, policy_usage, policy_alg ) ) + goto exit; exit: mbedtls_free( first_export ); diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index 505f1f9e1..0ede6e6c8 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -16,6 +16,7 @@ typedef struct { uint8_t data_len[4]; uint8_t key_data[]; } psa_persistent_key_storage_format; + /* END_HEADER */ /* BEGIN_DEPENDENCIES