From ed34695e08f01dcee3e6079cc103301efbb16a39 Mon Sep 17 00:00:00 2001 From: Moran Peker Date: Thu, 5 Jul 2018 15:22:45 +0300 Subject: [PATCH 1/7] Fix tests in test_suite_psa_crypto to set policy usage --- tests/suites/test_suite_psa_crypto.function | 30 +++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index c90447f81..9128e8fc5 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1041,6 +1041,7 @@ void cipher_encrypt( int alg_arg, int key_type_arg, size_t function_output_length = 0; size_t total_output_length = 0; psa_cipher_operation_t operation; + psa_key_policy_t policy; TEST_ASSERT( key != NULL ); TEST_ASSERT( input != NULL ); @@ -1054,6 +1055,10 @@ void cipher_encrypt( int alg_arg, int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg ); + TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_import_key( key_slot, key_type, key->x, key->len ) == PSA_SUCCESS ); @@ -1111,6 +1116,7 @@ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, size_t function_output_length = 0; size_t total_output_length = 0; psa_cipher_operation_t operation; + psa_key_policy_t policy; TEST_ASSERT( key != NULL ); TEST_ASSERT( input != NULL ); @@ -1124,6 +1130,10 @@ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg ); + TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_import_key( key_slot, key_type, key->x, key->len ) == PSA_SUCCESS ); @@ -1184,6 +1194,7 @@ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, size_t function_output_length = 0; size_t total_output_length = 0; psa_cipher_operation_t operation; + psa_key_policy_t policy; TEST_ASSERT( key != NULL ); TEST_ASSERT( input != NULL ); @@ -1197,6 +1208,10 @@ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg ); + TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_import_key( key_slot, key_type, key->x, key->len ) == PSA_SUCCESS ); @@ -1259,6 +1274,7 @@ void cipher_decrypt( int alg_arg, int key_type_arg, size_t function_output_length = 0; size_t total_output_length = 0; psa_cipher_operation_t operation; + psa_key_policy_t policy; TEST_ASSERT( key != NULL ); TEST_ASSERT( input != NULL ); @@ -1272,6 +1288,10 @@ void cipher_decrypt( int alg_arg, int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg ); + TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_import_key( key_slot, key_type, key->x, key->len ) == PSA_SUCCESS ); @@ -1333,6 +1353,7 @@ void cipher_verify_output( int alg_arg, int key_type_arg, size_t function_output_length = 0; psa_cipher_operation_t operation1; psa_cipher_operation_t operation2; + psa_key_policy_t policy; TEST_ASSERT( key != NULL ); TEST_ASSERT( input != NULL ); @@ -1341,6 +1362,10 @@ void cipher_verify_output( int alg_arg, int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); + TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_import_key( key_slot, key_type, key->x, key->len ) == PSA_SUCCESS ); @@ -1420,6 +1445,7 @@ void cipher_verify_output_multipart( int alg_arg, size_t function_output_length; psa_cipher_operation_t operation1; psa_cipher_operation_t operation2; + psa_key_policy_t policy; TEST_ASSERT( key != NULL ); TEST_ASSERT( input != NULL ); @@ -1428,6 +1454,10 @@ void cipher_verify_output_multipart( int alg_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); + TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_import_key( key_slot, key_type, key->x, key->len ) == PSA_SUCCESS ); From b0b255c82a4df82807c58636eb61cad999fb277f Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 6 Jul 2018 17:01:38 +0200 Subject: [PATCH 2/7] Always access key slots through accessor functions New functions psa_get_key_slot(), psa_get_empty_key_slot(), psa_get_key_from_slot() to access a key slot object from a key slot number. These functions perform all requisite validations: * psa_get_key_slot() verifies that the key slot number is in range. * psa_get_empty_key_slot() verifies that the slot is empty. * psa_get_key_from_slot() verifies that the slot contains a key with a suitable policy. Always use these functions so as to make sure that the requisite validations are always performed. --- library/psa_crypto.c | 254 ++++++++++++++++++++++++++----------------- 1 file changed, 152 insertions(+), 102 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 6dff2f532..f156d0c27 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -339,6 +339,72 @@ static psa_status_t mbedtls_to_psa_error( int ret ) } } +/* Retrieve a key slot, occupied or not. */ +static psa_status_t psa_get_key_slot( psa_key_slot_t key, + key_slot_t **p_slot ) +{ + if( key == 0 || key > PSA_KEY_SLOT_COUNT ) + return( PSA_ERROR_INVALID_ARGUMENT ); + + *p_slot = &global_data.key_slots[key]; + return( PSA_SUCCESS ); +} + +/* Retrieve an empty key slot (slot with no key data, but possibly + * with some metadata such as a policy). */ +static psa_status_t psa_get_empty_key_slot( psa_key_slot_t key, + key_slot_t **p_slot ) +{ + psa_status_t status; + key_slot_t *slot = NULL; + + *p_slot = NULL; + + status = psa_get_key_slot( key, &slot ); + if( status != PSA_SUCCESS ) + return( status ); + + if( slot->type != PSA_KEY_TYPE_NONE ) + return( PSA_ERROR_OCCUPIED_SLOT ); + + *p_slot = slot; + return( status ); +} + +/* Retrieve a slot which must contain a key. The key must have allow all + * the usage flags set in \p usage. If \p alg is nonzero, the key must + * allow operations with this algorithm. */ +static psa_status_t psa_get_key_from_slot( psa_key_slot_t key, + key_slot_t **p_slot, + psa_key_usage_t usage, + psa_algorithm_t alg ) +{ + psa_status_t status; + key_slot_t *slot = NULL; + + *p_slot = NULL; + + status = psa_get_key_slot( key, &slot ); + if( status != PSA_SUCCESS ) + return( status ); + if( slot->type == PSA_KEY_TYPE_NONE ) + return( PSA_ERROR_EMPTY_SLOT ); + + /* Enforce that usage policy for the key slot contains all the flags + * required by the usage parameter. There is one exception: public + * keys can always be exported, so we treat public key objects as + * if they had the export flag. */ + if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ) + usage &= ~PSA_KEY_USAGE_EXPORT; + if( ( slot->policy.usage & usage ) != usage ) + return( PSA_ERROR_NOT_PERMITTED ); + if( alg != 0 && ( alg != slot->policy.alg ) ) + return( PSA_ERROR_NOT_PERMITTED ); + + *p_slot = slot; + return( PSA_SUCCESS ); +} + /****************************************************************/ @@ -481,16 +547,13 @@ psa_status_t psa_import_key( psa_key_slot_t key, size_t data_length ) { key_slot_t *slot; - - if( key == 0 || key > PSA_KEY_SLOT_COUNT ) - return( PSA_ERROR_INVALID_ARGUMENT ); - slot = &global_data.key_slots[key]; - if( slot->type != PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_OCCUPIED_SLOT ); + psa_status_t status = PSA_SUCCESS; + status = psa_get_empty_key_slot( key, &slot ); + if( status != PSA_SUCCESS ) + return( status ); if( key_type_is_raw_bytes( type ) ) { - psa_status_t status; /* Ensure that a bytes-to-bit conversion won't overflow. */ if( data_length > SIZE_MAX / 8 ) return( PSA_ERROR_NOT_SUPPORTED ); @@ -510,7 +573,6 @@ psa_status_t psa_import_key( psa_key_slot_t key, { int ret; mbedtls_pk_context pk; - psa_status_t status = PSA_SUCCESS; mbedtls_pk_init( &pk ); if( PSA_KEY_TYPE_IS_KEYPAIR( type ) ) ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 ); @@ -583,10 +645,12 @@ psa_status_t psa_import_key( psa_key_slot_t key, psa_status_t psa_destroy_key( psa_key_slot_t key ) { key_slot_t *slot; + psa_status_t status; + + status = psa_get_key_slot( key, &slot ); + if( status != PSA_SUCCESS ) + return( status ); - if( key == 0 || key > PSA_KEY_SLOT_COUNT ) - return( PSA_ERROR_INVALID_ARGUMENT ); - slot = &global_data.key_slots[key]; if( slot->type == PSA_KEY_TYPE_NONE ) { /* No key material to clean, but do zeroize the slot below to wipe @@ -629,16 +693,19 @@ psa_status_t psa_get_key_information( psa_key_slot_t key, size_t *bits ) { key_slot_t *slot; + psa_status_t status; - if( key == 0 || key > PSA_KEY_SLOT_COUNT ) - return( PSA_ERROR_EMPTY_SLOT ); - slot = &global_data.key_slots[key]; if( type != NULL ) - *type = slot->type; + *type = 0; if( bits != NULL ) *bits = 0; + status = psa_get_key_slot( key, &slot ); + if( status != PSA_SUCCESS ) + return( status ); if( slot->type == PSA_KEY_TYPE_NONE ) return( PSA_ERROR_EMPTY_SLOT ); + if( type != NULL ) + *type = slot->type; if( key_type_is_raw_bytes( slot->type ) ) { @@ -679,6 +746,13 @@ static psa_status_t psa_internal_export_key( psa_key_slot_t key, int export_public_key ) { key_slot_t *slot; + psa_status_t status; + /* Exporting a public key doesn't require a usage flag. If we're + * called by psa_export_public_key(), don't require the EXPORT flag. + * If we're called by psa_export_key(), do require the EXPORT flag; + * if the key turns out to be public key object, psa_get_key_from_slot() + * will ignore this flag. */ + psa_key_usage_t usage = export_public_key ? 0 : PSA_KEY_USAGE_EXPORT; /* Set the key to empty now, so that even when there are errors, we always * set data_length to a value between 0 and data_size. On error, setting @@ -686,20 +760,12 @@ static psa_status_t psa_internal_export_key( psa_key_slot_t key, * unlikely to be accepted anywhere. */ *data_length = 0; - if( key == 0 || key > PSA_KEY_SLOT_COUNT ) - return( PSA_ERROR_EMPTY_SLOT ); - slot = &global_data.key_slots[key]; - if( slot->type == PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_EMPTY_SLOT ); - + status = psa_get_key_from_slot( key, &slot, usage, 0 ); + if( status != PSA_SUCCESS ) + return( status ); if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) ) return( PSA_ERROR_INVALID_ARGUMENT ); - if( ! export_public_key && - ! PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) && - ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 ) - return( PSA_ERROR_NOT_PERMITTED ); - if( key_type_is_raw_bytes( slot->type ) ) { if( slot->data.raw.bytes > data_size ) @@ -1424,13 +1490,17 @@ psa_status_t psa_mac_start( psa_mac_operation_t *operation, if( status != PSA_SUCCESS ) return( status ); - slot = &global_data.key_slots[key]; - if( slot->type == PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_EMPTY_SLOT ); + status = psa_get_key_from_slot( key, &slot, 0, alg ); + if( status != PSA_SUCCESS ) + return( status ); + /* Since this function is called identically for a sign or verify + * operation, we don't know yet whether the operation is permitted. + * Store the part of the key policy that we can't check in the + * operation structure. psa_mac_finish() or psa_mac_verify() will + * check that remaining part. */ if( ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) != 0 ) operation->key_usage_sign = 1; - if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 ) operation->key_usage_verify = 1; @@ -1919,27 +1989,14 @@ psa_status_t psa_asymmetric_sign( psa_key_slot_t key, (void) salt; (void) salt_length; - if( key == 0 || key > PSA_KEY_SLOT_COUNT ) - { - status = PSA_ERROR_EMPTY_SLOT; + status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_SIGN, alg ); + if( status != PSA_SUCCESS ) goto exit; - } - slot = &global_data.key_slots[key]; - if( slot->type == PSA_KEY_TYPE_NONE ) - { - status = PSA_ERROR_EMPTY_SLOT; - goto exit; - } if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) { status = PSA_ERROR_INVALID_ARGUMENT; goto exit; } - if( ! ( slot->policy.usage & PSA_KEY_USAGE_SIGN ) ) - { - status = PSA_ERROR_NOT_PERMITTED; - goto exit; - } #if defined(MBEDTLS_RSA_C) if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ) @@ -1999,17 +2056,14 @@ psa_status_t psa_asymmetric_verify( psa_key_slot_t key, size_t signature_length ) { key_slot_t *slot; + psa_status_t status; (void) salt; (void) salt_length; - if( key == 0 || key > PSA_KEY_SLOT_COUNT ) - return( PSA_ERROR_INVALID_ARGUMENT ); - slot = &global_data.key_slots[key]; - if( slot->type == PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_EMPTY_SLOT ); - if( ! ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) ) - return( PSA_ERROR_NOT_PERMITTED ); + status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_VERIFY, alg ); + if( status != PSA_SUCCESS ) + return( status ); #if defined(MBEDTLS_RSA_C) if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR || @@ -2054,19 +2108,17 @@ psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key, size_t *output_length ) { key_slot_t *slot; + psa_status_t status; + (void) salt; (void) salt_length; *output_length = 0; - if( key == 0 || key > PSA_KEY_SLOT_COUNT ) - return( PSA_ERROR_INVALID_ARGUMENT ); - slot = &global_data.key_slots[key]; - if( slot->type == PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_EMPTY_SLOT ); + status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); + if( status != PSA_SUCCESS ) + return( status ); if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) return( PSA_ERROR_INVALID_ARGUMENT ); - if( ! ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) ) - return( PSA_ERROR_NOT_PERMITTED ); #if defined(MBEDTLS_RSA_C) if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR || @@ -2121,19 +2173,17 @@ psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key, size_t *output_length ) { key_slot_t *slot; + psa_status_t status; + (void) salt; (void) salt_length; *output_length = 0; - if( key == 0 || key > PSA_KEY_SLOT_COUNT ) - return( PSA_ERROR_EMPTY_SLOT ); - slot = &global_data.key_slots[key]; - if( slot->type == PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_EMPTY_SLOT ); + status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg ); + if( status != PSA_SUCCESS ) + return( status ); if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) return( PSA_ERROR_INVALID_ARGUMENT ); - if( ! ( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) ) - return( PSA_ERROR_NOT_PERMITTED ); #if defined(MBEDTLS_RSA_C) if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ) @@ -2216,6 +2266,9 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, psa_key_type_t key_type; size_t key_bits; const mbedtls_cipher_info_t *cipher_info = NULL; + psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ? + PSA_KEY_USAGE_ENCRYPT : + PSA_KEY_USAGE_DECRYPT ); status = psa_cipher_init( operation, alg ); if( status != PSA_SUCCESS ) @@ -2224,7 +2277,9 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, status = psa_get_key_information( key, &key_type, &key_bits ); if( status != PSA_SUCCESS ) return( status ); - slot = &global_data.key_slots[key]; + status = psa_get_key_from_slot( key, &slot, usage, alg); + if( status != PSA_SUCCESS ) + return( status ); cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL ); if( cipher_info == NULL ) @@ -2525,13 +2580,14 @@ psa_status_t psa_set_key_policy( psa_key_slot_t key, const psa_key_policy_t *policy ) { key_slot_t *slot; + psa_status_t status; - if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL ) + if( policy == NULL ) return( PSA_ERROR_INVALID_ARGUMENT ); - slot = &global_data.key_slots[key]; - if( slot->type != PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_OCCUPIED_SLOT ); + status = psa_get_empty_key_slot( key, &slot ); + if( status != PSA_SUCCESS ) + return( status ); if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | @@ -2549,11 +2605,14 @@ psa_status_t psa_get_key_policy( psa_key_slot_t key, psa_key_policy_t *policy ) { key_slot_t *slot; + psa_status_t status; - if( key == 0 || key > PSA_KEY_SLOT_COUNT || policy == NULL ) + if( policy == NULL ) return( PSA_ERROR_INVALID_ARGUMENT ); - slot = &global_data.key_slots[key]; + status = psa_get_key_slot( key, &slot ); + if( status != PSA_SUCCESS ) + return( status ); *policy = slot->policy; @@ -2570,11 +2629,11 @@ psa_status_t psa_get_key_lifetime( psa_key_slot_t key, psa_key_lifetime_t *lifetime ) { key_slot_t *slot; + psa_status_t status; - if( key == 0 || key > PSA_KEY_SLOT_COUNT ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - slot = &global_data.key_slots[key]; + status = psa_get_key_slot( key, &slot ); + if( status != PSA_SUCCESS ) + return( status ); *lifetime = slot->lifetime; @@ -2585,18 +2644,16 @@ psa_status_t psa_set_key_lifetime( psa_key_slot_t key, psa_key_lifetime_t lifetime ) { key_slot_t *slot; - - if( key == 0 || key > PSA_KEY_SLOT_COUNT ) - return( PSA_ERROR_INVALID_ARGUMENT ); + psa_status_t status; if( lifetime != PSA_KEY_LIFETIME_VOLATILE && lifetime != PSA_KEY_LIFETIME_PERSISTENT && lifetime != PSA_KEY_LIFETIME_WRITE_ONCE) return( PSA_ERROR_INVALID_ARGUMENT ); - slot = &global_data.key_slots[key]; - if( slot->type != PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_OCCUPIED_SLOT ); + status = psa_get_empty_key_slot( key, &slot ); + if( status != PSA_SUCCESS ) + return( status ); if( lifetime != PSA_KEY_LIFETIME_VOLATILE ) return( PSA_ERROR_NOT_SUPPORTED ); @@ -2639,18 +2696,15 @@ psa_status_t psa_aead_encrypt( psa_key_slot_t key, status = psa_get_key_information( key, &key_type, &key_bits ); if( status != PSA_SUCCESS ) return( status ); - slot = &global_data.key_slots[key]; - if( slot->type == PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_EMPTY_SLOT ); + status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); + if( status != PSA_SUCCESS ) + return( status ); cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, &cipher_id ); if( cipher_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); - if( ( slot->policy.usage & PSA_KEY_USAGE_ENCRYPT ) == 0 ) - return( PSA_ERROR_NOT_PERMITTED ); - if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) != PSA_KEY_TYPE_CATEGORY_SYMMETRIC ) return( PSA_ERROR_INVALID_ARGUMENT ); @@ -2787,18 +2841,15 @@ psa_status_t psa_aead_decrypt( psa_key_slot_t key, status = psa_get_key_information( key, &key_type, &key_bits ); if( status != PSA_SUCCESS ) return( status ); - slot = &global_data.key_slots[key]; - if( slot->type == PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_EMPTY_SLOT ); + status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg ); + if( status != PSA_SUCCESS ) + return( status ); cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, &cipher_id ); if( cipher_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); - if( !( slot->policy.usage & PSA_KEY_USAGE_DECRYPT ) ) - return( PSA_ERROR_NOT_PERMITTED ); - if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) != PSA_KEY_TYPE_CATEGORY_SYMMETRIC ) return( PSA_ERROR_INVALID_ARGUMENT ); @@ -2903,19 +2954,18 @@ psa_status_t psa_generate_key( psa_key_slot_t key, size_t parameters_size ) { key_slot_t *slot; + psa_status_t status; - if( key == 0 || key > PSA_KEY_SLOT_COUNT ) - return( PSA_ERROR_INVALID_ARGUMENT ); - slot = &global_data.key_slots[key]; - if( slot->type != PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_OCCUPIED_SLOT ); if( parameters == NULL && parameters_size != 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); + status = psa_get_empty_key_slot( key, &slot ); + if( status != PSA_SUCCESS ) + return( status ); + if( key_type_is_raw_bytes( type ) ) { - psa_status_t status = prepare_raw_data_slot( type, bits, - &slot->data.raw ); + status = prepare_raw_data_slot( type, bits, &slot->data.raw ); if( status != PSA_SUCCESS ) return( status ); status = psa_generate_random( slot->data.raw.data, From b870b188ad2007424bdabb9c1a7bc2a4975c37bb Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 6 Jul 2018 16:02:09 +0200 Subject: [PATCH 3/7] New internal function psa_get_key_bits Isolate the code of psa_get_key_information that calculates the bit size of a key into its own function which can be called by functions that have a key slot pointer. --- library/psa_crypto.c | 51 ++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index f156d0c27..63dbcce47 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -688,6 +688,24 @@ psa_status_t psa_destroy_key( psa_key_slot_t key ) return( PSA_SUCCESS ); } +/* Return the size of the key in the given slot, in bits. */ +static size_t psa_get_key_bits( const key_slot_t *slot ) +{ + if( key_type_is_raw_bytes( slot->type ) ) + return( slot->data.raw.bytes * 8 ); +#if defined(MBEDTLS_RSA_C) + if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY || + slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ) + return( mbedtls_rsa_get_bitlen( slot->data.rsa ) ); +#endif /* defined(MBEDTLS_RSA_C) */ +#if defined(MBEDTLS_ECP_C) + if( PSA_KEY_TYPE_IS_ECC( slot->type ) ) + return( slot->data.ecp->grp.pbits ); +#endif /* defined(MBEDTLS_ECP_C) */ + /* Shouldn't happen except on an empty slot. */ + return( 0 ); +} + psa_status_t psa_get_key_information( psa_key_slot_t key, psa_key_type_t *type, size_t *bits ) @@ -702,40 +720,13 @@ psa_status_t psa_get_key_information( psa_key_slot_t key, status = psa_get_key_slot( key, &slot ); if( status != PSA_SUCCESS ) return( status ); + if( slot->type == PSA_KEY_TYPE_NONE ) return( PSA_ERROR_EMPTY_SLOT ); if( type != NULL ) *type = slot->type; - - if( key_type_is_raw_bytes( slot->type ) ) - { - if( bits != NULL ) - *bits = slot->data.raw.bytes * 8; - } - else -#if defined(MBEDTLS_RSA_C) - if( slot->type == PSA_KEY_TYPE_RSA_PUBLIC_KEY || - slot->type == PSA_KEY_TYPE_RSA_KEYPAIR ) - { - if( bits != NULL ) - *bits = mbedtls_rsa_get_bitlen( slot->data.rsa ); - } - else -#endif /* defined(MBEDTLS_RSA_C) */ -#if defined(MBEDTLS_ECP_C) - if( PSA_KEY_TYPE_IS_ECC( slot->type ) ) - { - if( bits != NULL ) - *bits = slot->data.ecp->grp.pbits; - } - else -#endif /* defined(MBEDTLS_ECP_C) */ - { - /* Shouldn't happen: the key type is not any type that we - * put in. */ - return( PSA_ERROR_TAMPERING_DETECTED ); - } - + if( bits != NULL ) + *bits = psa_get_key_bits( slot ); return( PSA_SUCCESS ); } From ab1d7ab89f66c08a32912c434558ba3268a7a98b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 6 Jul 2018 16:07:47 +0200 Subject: [PATCH 4/7] Don't call psa_get_key_information internally When you have a key slot pointer, read the key type directly, and call psa_get_key_bits to get the bit size. --- library/psa_crypto.c | 47 +++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 63dbcce47..d730bd821 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1469,7 +1469,6 @@ psa_status_t psa_mac_start( psa_mac_operation_t *operation, { psa_status_t status; key_slot_t *slot; - psa_key_type_t key_type; size_t key_bits; const mbedtls_cipher_info_t *cipher_info = NULL; @@ -1477,10 +1476,6 @@ psa_status_t psa_mac_start( psa_mac_operation_t *operation, if( status != PSA_SUCCESS ) return( status ); - status = psa_get_key_information( key, &key_type, &key_bits ); - if( status != PSA_SUCCESS ) - return( status ); - status = psa_get_key_from_slot( key, &slot, 0, alg ); if( status != PSA_SUCCESS ) return( status ); @@ -1495,9 +1490,12 @@ psa_status_t psa_mac_start( psa_mac_operation_t *operation, if( ( slot->policy.usage & PSA_KEY_USAGE_VERIFY ) != 0 ) operation->key_usage_verify = 1; + key_bits = psa_get_key_bits( slot ); + if( ! PSA_ALG_IS_HMAC( alg ) ) { - cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL ); + cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, + NULL ); if( cipher_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); operation->mac_size = cipher_info->block_size; @@ -1515,7 +1513,7 @@ psa_status_t psa_mac_start( psa_mac_operation_t *operation, default: #if defined(MBEDTLS_MD_C) if( PSA_ALG_IS_HMAC( alg ) ) - status = psa_hmac_start( operation, key_type, slot, alg ); + status = psa_hmac_start( operation, slot->type, slot, alg ); else #endif /* MBEDTLS_MD_C */ return( PSA_ERROR_NOT_SUPPORTED ); @@ -2254,7 +2252,6 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; psa_status_t status; key_slot_t *slot; - psa_key_type_t key_type; size_t key_bits; const mbedtls_cipher_info_t *cipher_info = NULL; psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ? @@ -2265,14 +2262,12 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, if( status != PSA_SUCCESS ) return( status ); - status = psa_get_key_information( key, &key_type, &key_bits ); - if( status != PSA_SUCCESS ) - return( status ); status = psa_get_key_from_slot( key, &slot, usage, alg); if( status != PSA_SUCCESS ) return( status ); + key_bits = psa_get_key_bits( slot ); - cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits, NULL ); + cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL ); if( cipher_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); @@ -2284,7 +2279,7 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, } #if defined(MBEDTLS_DES_C) - if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 ) + if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 ) { /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */ unsigned char keys[24]; @@ -2336,11 +2331,11 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, operation->key_set = 1; operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ? - PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) : + PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) : 1 ); if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || alg == PSA_ALG_CTR ) { - operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ); + operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ); } return( PSA_SUCCESS ); @@ -2675,7 +2670,6 @@ psa_status_t psa_aead_encrypt( psa_key_slot_t key, int ret; psa_status_t status; key_slot_t *slot; - psa_key_type_t key_type; size_t key_bits; uint8_t *tag; size_t tag_length; @@ -2684,19 +2678,17 @@ psa_status_t psa_aead_encrypt( psa_key_slot_t key, *ciphertext_length = 0; - status = psa_get_key_information( key, &key_type, &key_bits ); - if( status != PSA_SUCCESS ) - return( status ); status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); + key_bits = psa_get_key_bits( slot ); - cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, + cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, &cipher_id ); if( cipher_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); - if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) != + if( ( slot->type & PSA_KEY_TYPE_CATEGORY_MASK ) != PSA_KEY_TYPE_CATEGORY_SYMMETRIC ) return( PSA_ERROR_INVALID_ARGUMENT ); @@ -2705,7 +2697,7 @@ psa_status_t psa_aead_encrypt( psa_key_slot_t key, mbedtls_gcm_context gcm; tag_length = 16; - if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 ) + if( PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) != 16 ) return( PSA_ERROR_INVALID_ARGUMENT ); //make sure we have place to hold the tag in the ciphertext buffer @@ -2736,7 +2728,7 @@ psa_status_t psa_aead_encrypt( psa_key_slot_t key, mbedtls_ccm_context ccm; tag_length = 16; - if( PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) != 16 ) + if( PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) != 16 ) return( PSA_ERROR_INVALID_ARGUMENT ); if( nonce_length < 7 || nonce_length > 13 ) @@ -2820,7 +2812,6 @@ psa_status_t psa_aead_decrypt( psa_key_slot_t key, int ret; psa_status_t status; key_slot_t *slot; - psa_key_type_t key_type; size_t key_bits; const uint8_t *tag; size_t tag_length; @@ -2829,19 +2820,17 @@ psa_status_t psa_aead_decrypt( psa_key_slot_t key, *plaintext_length = 0; - status = psa_get_key_information( key, &key_type, &key_bits ); - if( status != PSA_SUCCESS ) - return( status ); status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); + key_bits = psa_get_key_bits( slot ); - cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, + cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, &cipher_id ); if( cipher_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); - if( ( key_type & PSA_KEY_TYPE_CATEGORY_MASK ) != + if( ( slot->type & PSA_KEY_TYPE_CATEGORY_MASK ) != PSA_KEY_TYPE_CATEGORY_SYMMETRIC ) return( PSA_ERROR_INVALID_ARGUMENT ); From 69e033aea05618084e3ac3aa1b264c617c717c21 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 6 Jul 2018 15:47:54 +0200 Subject: [PATCH 5/7] RSA encryption: accept input=NULL if ilen=0 In mbedtls_rsa_rsaes_oaep_encrypt and mbedtls_rsa_rsaes_pkcs1_v15_encrypt, if the input length is 0 (which is unusual and mostly useless, but permitted) then it is fine for the input pointer to be NULL. Don't return an error in this case. When `input` is NULL, `memcpy( p, input, ilen )` has undefined behavior even if `ilen` is zero. So skip the `memcpy` call in this case. Likewise, in `mbedtls_rsa_rsaes_oaep_decrypt` and `mbedtls_rsa_rsaes_pkcs1_v15_decrypt`, skip the `memcpy` call if `*olen` is zero. --- library/rsa.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index ad196391f..499d14540 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1122,7 +1122,8 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, p += hlen; p += olen - 2 * hlen - 2 - ilen; *p++ = 1; - memcpy( p, input, ilen ); + if( ilen != 0 ) + memcpy( p, input, ilen ); mbedtls_md_init( &md_ctx ); if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) @@ -1169,7 +1170,9 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); // We don't check p_rng because it won't be dereferenced here - if( f_rng == NULL || input == NULL || output == NULL ) + if( f_rng == NULL || output == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + if( ilen != 0 && input == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); olen = ctx->len; @@ -1209,7 +1212,8 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, } *p++ = 0; - memcpy( p, input, ilen ); + if( ilen != 0 ) + memcpy( p, input, ilen ); return( ( mode == MBEDTLS_RSA_PUBLIC ) ? mbedtls_rsa_public( ctx, output, output ) @@ -1373,7 +1377,8 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, } *olen = ilen - (p - buf); - memcpy( output, p, *olen ); + if( *olen != 0 ) + memcpy( output, p, *olen ); ret = 0; cleanup: @@ -1471,7 +1476,8 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, } *olen = ilen - (p - buf); - memcpy( output, p, *olen ); + if( *olen != 0 ) + memcpy( output, p, *olen ); ret = 0; cleanup: From 76f5c7b6a874edb4de057d159827d8c8dbd2d70c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 6 Jul 2018 16:53:09 +0200 Subject: [PATCH 6/7] Tests: cover policy checks for all operations Add tests of key policy checks for MAC, cipher, AEAD, asymmetric encryption and asymmetric signature. For each category, test with/without the requisite usage flag in each direction, and test algorithm mismatch. --- tests/suites/test_suite_psa_crypto.data | 102 ++++++- tests/suites/test_suite_psa_crypto.function | 282 +++++++++++++++++--- 2 files changed, 348 insertions(+), 36 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index b281cb3af..f1075bbac 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -138,11 +138,105 @@ import_rsa_made_up:PSA_VENDOR_RSA_MAX_KEY_BITS+8:0:PSA_ERROR_NOT_SUPPORTED PSA key policy set and get key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE -PSA key policy enforcement: export -key_policy_fail:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_ERROR_NOT_PERMITTED:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24" +PSA key policy: MAC, sign | verify +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C +mac_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256) -PSA key policy enforcement: sign -key_policy_fail:PSA_KEY_USAGE_SIGN:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_ERROR_NOT_PERMITTED:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24" +PSA key policy: MAC, wrong algorithm +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C +mac_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_224) + +PSA key policy: MAC, sign but not verify +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C +mac_key_policy:PSA_KEY_USAGE_SIGN:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256) + +PSA key policy: MAC, verify but not sign +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C +mac_key_policy:PSA_KEY_USAGE_VERIFY:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256) + +PSA key policy: MAC, neither sign nor verify +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C +mac_key_policy:0:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256) + +PSA key policy: cipher, encrypt | decrypt +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR +cipher_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CTR + +PSA key policy: cipher, wrong algorithm +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR:MBEDTLS_CIPHER_MODE_CBC +cipher_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE + +PSA key policy: cipher, encrypt but not decrypt +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR +cipher_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CTR + +PSA key policy: cipher, decrypt but not encrypt +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR +cipher_key_policy:PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CTR + +PSA key policy: cipher, neither encrypt nor decrypt +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR +cipher_key_policy:0:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_CTR + +PSA key policy: AEAD, encrypt | decrypt +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM + +PSA key policy: AEAD, wrong algorithm +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C:MBEDTLS_GCM_C +aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":16:16:PSA_ALG_GCM + +PSA key policy: AEAD, encrypt but not decrypt +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM + +PSA key policy: AEAD, decrypt but not encrypt +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_key_policy:PSA_KEY_USAGE_DECRYPT:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM + +PSA key policy: AEAD, neither encrypt nor decrypt +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_key_policy:0:PSA_ALG_CCM:PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:16:PSA_ALG_CCM + +PSA key policy: asymmetric encryption, encrypt | decrypt +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT + +PSA key policy: asymmetric encryption, wrong algorithm +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C +asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256) + +PSA key policy: asymmetric encryption, encrypt but not decrypt +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT + +PSA key policy: asymmetric encryption, decrypt but not encrypt +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +asymmetric_encryption_key_policy:PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT + +PSA key policy: asymmetric encryption, neither encrypt nor decrypt +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +asymmetric_encryption_key_policy:0:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT + +PSA key policy: asymmetric signature, sign | verify +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW + +PSA key policy: asymmetric signature, wrong algorithm +depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C +asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PSS(PSA_ALG_SHA_224) + +PSA key policy: asymmetric signature, sign but not verify +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +asymmetric_signature_key_policy:PSA_KEY_USAGE_SIGN:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW + +PSA key policy: asymmetric signature, verify but not sign +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +asymmetric_signature_key_policy:PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW + +PSA key policy: asymmetric signature, neither sign nor verify +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +asymmetric_signature_key_policy:0:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_TYPE_RSA_KEYPAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_SIGN_RAW PSA key lifetime: set and get volatile key_lifetime:PSA_KEY_LIFETIME_VOLATILE diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 9128e8fc5..977222bbf 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -723,49 +723,267 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -void key_policy_fail( int usage_arg, int alg_arg, int expected_status, - data_t *keypair ) +void mac_key_policy( int policy_usage, + int policy_alg, + int key_type, + data_t *key_data, + int exercise_alg ) { int key_slot = 1; - psa_algorithm_t alg = alg_arg; - psa_key_usage_t usage = usage_arg; - size_t signature_length = 0; psa_key_policy_t policy; - int actual_status = PSA_SUCCESS; + psa_mac_operation_t operation; + psa_status_t status; + unsigned char mac[PSA_MAC_MAX_SIZE]; + size_t output_length; TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); - psa_key_policy_set_usage( &policy, usage, alg ); + psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); - if( usage & PSA_KEY_USAGE_EXPORT ) - { - TEST_ASSERT( keypair != NULL ); - TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( keypair->len ) ); - TEST_ASSERT( psa_import_key( key_slot, - PSA_KEY_TYPE_RSA_KEYPAIR, - keypair->x, - keypair->len ) == PSA_SUCCESS ); - actual_status = psa_asymmetric_sign( key_slot, alg, - NULL, 0, - NULL, 0, - NULL, 0, &signature_length ); - } + TEST_ASSERT( psa_import_key( key_slot, key_type, + key_data->x, key_data->len ) == PSA_SUCCESS ); - if( usage & PSA_KEY_USAGE_SIGN ) - { - size_t data_length; - TEST_ASSERT( keypair != NULL ); - TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( keypair->len ) ); - TEST_ASSERT( psa_import_key( key_slot, - PSA_KEY_TYPE_RSA_KEYPAIR, - keypair->x, - keypair->len ) == PSA_SUCCESS ); - actual_status = psa_export_key( key_slot, NULL, 0, &data_length ); - } + status = psa_mac_start( &operation, key_slot, exercise_alg ); + if( status == PSA_SUCCESS ) + status = psa_mac_finish( &operation, + mac, sizeof( mac ), &output_length ); + if( policy_alg == exercise_alg && + ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 ) + TEST_ASSERT( status == PSA_SUCCESS ); + else + TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); + psa_mac_abort( &operation ); - TEST_ASSERT( actual_status == expected_status ); + memset( mac, 0, sizeof( mac ) ); + status = psa_mac_start( &operation, key_slot, exercise_alg ); + if( status == PSA_SUCCESS ) + status = psa_mac_verify( &operation, mac, sizeof( mac ) ); + if( policy_alg == exercise_alg && + ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 ) + TEST_ASSERT( status == PSA_ERROR_INVALID_SIGNATURE ); + else + TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); + +exit: + psa_mac_abort( &operation ); + psa_destroy_key( key_slot ); + mbedtls_psa_crypto_free( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void cipher_key_policy( int policy_usage, + int policy_alg, + int key_type, + data_t *key_data, + int exercise_alg ) +{ + int key_slot = 1; + psa_key_policy_t policy; + psa_cipher_operation_t operation; + psa_status_t status; + + TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); + TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_import_key( key_slot, key_type, + key_data->x, key_data->len ) == PSA_SUCCESS ); + + status = psa_encrypt_setup( &operation, key_slot, exercise_alg ); + if( policy_alg == exercise_alg && + ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 ) + TEST_ASSERT( status == PSA_SUCCESS ); + else + TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); + psa_cipher_abort( &operation ); + + status = psa_decrypt_setup( &operation, key_slot, exercise_alg ); + if( policy_alg == exercise_alg && + ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 ) + TEST_ASSERT( status == PSA_SUCCESS ); + else + TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); + +exit: + psa_cipher_abort( &operation ); + psa_destroy_key( key_slot ); + mbedtls_psa_crypto_free( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void aead_key_policy( int policy_usage, + int policy_alg, + int key_type, + data_t *key_data, + int nonce_length_arg, + int tag_length_arg, + int exercise_alg ) +{ + int key_slot = 1; + psa_key_policy_t policy; + psa_status_t status; + unsigned char nonce[16] = {0}; + size_t nonce_length = nonce_length_arg; + unsigned char tag[16]; + size_t tag_length = tag_length_arg; + size_t output_length; + + TEST_ASSERT( nonce_length <= sizeof( nonce ) ); + TEST_ASSERT( tag_length <= sizeof( tag ) ); + + TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); + TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_import_key( key_slot, key_type, + key_data->x, key_data->len ) == PSA_SUCCESS ); + + status = psa_aead_encrypt( key_slot, exercise_alg, + nonce, nonce_length, + NULL, 0, + NULL, 0, + tag, tag_length, + &output_length ); + if( policy_alg == exercise_alg && + ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 ) + TEST_ASSERT( status == PSA_SUCCESS ); + else + TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); + + memset( tag, 0, sizeof( tag ) ); + status = psa_aead_decrypt( key_slot, exercise_alg, + nonce, nonce_length, + NULL, 0, + tag, tag_length, + NULL, 0, + &output_length ); + if( policy_alg == exercise_alg && + ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 ) + TEST_ASSERT( status == PSA_ERROR_INVALID_SIGNATURE ); + else + TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); + +exit: + psa_destroy_key( key_slot ); + mbedtls_psa_crypto_free( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void asymmetric_encryption_key_policy( int policy_usage, + int policy_alg, + int key_type, + data_t *key_data, + int exercise_alg ) +{ + int key_slot = 1; + psa_key_policy_t policy; + psa_status_t status; + size_t key_bits; + size_t buffer_length; + unsigned char *buffer = NULL; + size_t output_length; + + TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); + TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_import_key( key_slot, key_type, + key_data->x, key_data->len ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_get_key_information( key_slot, + NULL, + &key_bits ) == PSA_SUCCESS ); + buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, + exercise_alg ); + buffer = mbedtls_calloc( 1, buffer_length ); + TEST_ASSERT( buffer != NULL ); + + status = psa_asymmetric_encrypt( key_slot, exercise_alg, + NULL, 0, + NULL, 0, + buffer, buffer_length, + &output_length ); + if( policy_alg == exercise_alg && + ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 ) + TEST_ASSERT( status == PSA_SUCCESS ); + else + TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); + + memset( buffer, 0, buffer_length ); + status = psa_asymmetric_decrypt( key_slot, exercise_alg, + buffer, buffer_length, + NULL, 0, + buffer, buffer_length, + &output_length ); + if( policy_alg == exercise_alg && + ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 ) + TEST_ASSERT( status == PSA_ERROR_INVALID_PADDING ); + else + TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); + +exit: + psa_destroy_key( key_slot ); + mbedtls_psa_crypto_free( ); + mbedtls_free( buffer ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void asymmetric_signature_key_policy( int policy_usage, + int policy_alg, + int key_type, + data_t *key_data, + int exercise_alg ) +{ + int key_slot = 1; + psa_key_policy_t policy; + psa_status_t status; + unsigned char payload[16] = {1}; + size_t payload_length = sizeof( payload ); + unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0}; + size_t signature_length; + + TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); + TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_import_key( key_slot, key_type, + key_data->x, key_data->len ) == PSA_SUCCESS ); + + status = psa_asymmetric_sign( key_slot, exercise_alg, + payload, payload_length, + NULL, 0, + signature, sizeof( signature ), + &signature_length ); + if( policy_alg == exercise_alg && + ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 ) + TEST_ASSERT( status == PSA_SUCCESS ); + else + TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); + + memset( signature, 0, sizeof( signature ) ); + status = psa_asymmetric_verify( key_slot, exercise_alg, + payload, payload_length, + NULL, 0, + signature, sizeof( signature ) ); + if( policy_alg == exercise_alg && + ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 ) + TEST_ASSERT( status == PSA_ERROR_INVALID_SIGNATURE ); + else + TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); exit: psa_destroy_key( key_slot ); From ab4152b3d4e7ec7284ae04f5791385aa324e94e4 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 6 Jul 2018 16:12:42 +0200 Subject: [PATCH 7/7] Diversify export tests without the export usage flag Test both with a symmetric key and with a key pair. --- tests/suites/test_suite_psa_crypto.data | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index f1075bbac..72c602181 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -53,10 +53,6 @@ PSA import/export RSA public key: export buffer too small depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:-1:PSA_ERROR_BUFFER_TOO_SMALL:1 -PSA import/export RSA keypair: policy forbids export -depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C -import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_ENCRYPT:1024:0:PSA_ERROR_NOT_PERMITTED:1 - PSA import/export RSA keypair: good, 1024-bit depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:0:PSA_SUCCESS:1 @@ -117,6 +113,22 @@ PSA import/export EC secp384r1: good depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED import_export:"3081a402010104303f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76aa00706052b81040022a16403620004d9c662b50ba29ca47990450e043aeaf4f0c69b15676d112f622a71c93059af999691c5680d2b44d111579db12f4a413a2ed5c45fcfb67b5b63e00b91ebe59d09a6b1ac2c0c4282aa12317ed5914f999bc488bb132e8342cc36f2ca5e3379c747":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP384R1):PSA_ALG_ECDSA_ANY:PSA_KEY_USAGE_EXPORT:384:0:PSA_SUCCESS:1 +PSA import/export AES key: policy forbids export +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR +import_export:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:PSA_ALG_CTR:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:128:0:PSA_ERROR_NOT_PERMITTED:1 + +PSA import/export HMAC key: policy forbids export +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C +import_export:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_HMAC:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:256:0:PSA_ERROR_NOT_PERMITTED:1 + +PSA import/export RSA keypair: policy forbids export (crypt) +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:1024:0:PSA_ERROR_NOT_PERMITTED:1 + +PSA import/export RSA keypair: policy forbids export (sign) +depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:1024:0:PSA_ERROR_NOT_PERMITTED:1 + PSA import EC keypair secp384r1: valid key but wrong curve (secp256r1) depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED import:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP384R1):PSA_ERROR_INVALID_ARGUMENT