diff --git a/scripts/mbedtls_dev/crypto_knowledge.py b/scripts/mbedtls_dev/crypto_knowledge.py index 73890f81a4..1bd011fe21 100644 --- a/scripts/mbedtls_dev/crypto_knowledge.py +++ b/scripts/mbedtls_dev/crypto_knowledge.py @@ -104,6 +104,10 @@ class KeyType: `self.name`. """ + def is_public(self) -> bool: + """Whether the key type is for public keys.""" + return self.name.endswith('_PUBLIC_KEY') + ECC_KEY_SIZES = { 'PSA_ECC_FAMILY_SECP_K1': (192, 224, 256), 'PSA_ECC_FAMILY_SECP_R1': (225, 256, 384, 521), @@ -242,8 +246,17 @@ class AlgorithmCategory(enum.Enum): PAKE = 10 def requires_key(self) -> bool: + """Whether operations in this category are set up with a key.""" return self not in {self.HASH, self.KEY_DERIVATION} + def is_asymmetric(self) -> bool: + """Whether operations in this category involve asymmetric keys.""" + return self in { + self.SIGN, + self.ASYMMETRIC_ENCRYPTION, + self.KEY_AGREEMENT + } + class AlgorithmNotRecognized(Exception): def __init__(self, expr: str) -> None: diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py index 81abce7bcb..ca94d7d324 100755 --- a/tests/scripts/generate_psa_tests.py +++ b/tests/scripts/generate_psa_tests.py @@ -314,6 +314,7 @@ class OpFail: NOT_SUPPORTED = 0 INVALID = 1 INCOMPATIBLE = 2 + PUBLIC = 3 def __init__(self, info: Information) -> None: self.constructors = info.constructors @@ -363,6 +364,8 @@ class OpFail: key_material = kt.key_material(kt.sizes_to_test()[0]) arguments += [key_type, test_case.hex_string(key_material)] arguments.append(alg.expression) + if category.is_asymmetric(): + arguments.append('1' if reason == self.Reason.PUBLIC else '0') error = ('NOT_SUPPORTED' if reason == self.Reason.NOT_SUPPORTED else 'INVALID_ARGUMENT') arguments.append('PSA_ERROR_' + error) @@ -393,13 +396,17 @@ class OpFail: """Generate failure test cases for one-key operations with the specified algorithm.""" for kt in self.key_types: key_is_compatible = kt.can_do(alg) - # To do: public key for a private key operation if key_is_compatible and alg.can_do(category): # Compatible key and operation, unsupported algorithm for dep in automatic_dependencies(alg.base_expression): yield self.make_test_case(alg, category, self.Reason.NOT_SUPPORTED, kt=kt, not_deps=frozenset([dep])) + # Public key for a private-key operation + if category.is_asymmetric() and kt.is_public(): + yield self.make_test_case(alg, category, + self.Reason.PUBLIC, + kt=kt) elif key_is_compatible: # Compatible key, incompatible operation, supported algorithm yield self.make_test_case(alg, category, diff --git a/tests/suites/test_suite_psa_crypto_op_fail.function b/tests/suites/test_suite_psa_crypto_op_fail.function index 4640649e54..4ab8b526d4 100644 --- a/tests/suites/test_suite_psa_crypto_op_fail.function +++ b/tests/suites/test_suite_psa_crypto_op_fail.function @@ -211,7 +211,8 @@ exit: /* BEGIN_CASE */ void sign_fail( int key_type_arg, data_t *key_data, - int alg_arg, int expected_status_arg ) + int alg_arg, int private_only, + int expected_status_arg ) { psa_status_t expected_status = expected_status_arg; psa_key_type_t key_type = key_type_arg; @@ -237,10 +238,13 @@ void sign_fail( int key_type_arg, data_t *key_data, psa_sign_hash( key_id, alg, input, sizeof( input ), output, sizeof( output ), &length ) ); - TEST_STATUS( expected_status, - psa_verify_hash( key_id, alg, - input, sizeof( input ), - output, sizeof( output ) ) ); + if( ! private_only ) + { + TEST_STATUS( expected_status, + psa_verify_hash( key_id, alg, + input, sizeof( input ), + output, sizeof( output ) ) ); + } exit: psa_destroy_key( key_id ); @@ -251,7 +255,8 @@ exit: /* BEGIN_CASE */ void asymmetric_encryption_fail( int key_type_arg, data_t *key_data, - int alg_arg, int expected_status_arg ) + int alg_arg, int private_only, + int expected_status_arg ) { psa_status_t expected_status = expected_status_arg; psa_key_type_t key_type = key_type_arg; @@ -273,12 +278,15 @@ void asymmetric_encryption_fail( int key_type_arg, data_t *key_data, key_data->x, key_data->len, &key_id ) ); - TEST_STATUS( expected_status, - psa_asymmetric_encrypt( key_id, alg, - plaintext, 1, - NULL, 0, - ciphertext, sizeof( ciphertext ), - &length ) ); + if( ! private_only ) + { + TEST_STATUS( expected_status, + psa_asymmetric_encrypt( key_id, alg, + plaintext, 1, + NULL, 0, + ciphertext, sizeof( ciphertext ), + &length ) ); + } TEST_STATUS( expected_status, psa_asymmetric_decrypt( key_id, alg, ciphertext, sizeof( ciphertext ), @@ -313,7 +321,8 @@ exit: /* BEGIN_CASE */ void key_agreement_fail( int key_type_arg, data_t *key_data, - int alg_arg, int expected_status_arg ) + int alg_arg, int private_only, + int expected_status_arg ) { psa_status_t expected_status = expected_status_arg; psa_key_type_t key_type = key_type_arg; @@ -359,6 +368,9 @@ void key_agreement_fail( int key_type_arg, data_t *key_data, public_key, public_key_length ) ); #endif + /* There are no public-key operations. */ + (void) private_only; + exit: psa_key_derivation_abort( &operation ); psa_destroy_key( key_id );