diff --git a/scripts/mbedtls_dev/test_case.py b/scripts/mbedtls_dev/test_case.py index d01e1432b..11117fcdd 100644 --- a/scripts/mbedtls_dev/test_case.py +++ b/scripts/mbedtls_dev/test_case.py @@ -42,6 +42,7 @@ class TestCase: self.dependencies = [] #type: List[str] self.function = None #type: Optional[str] self.arguments = [] #type: List[str] + self.result = '' #type: str def add_comment(self, *lines: str) -> None: self.comments += lines @@ -58,6 +59,9 @@ class TestCase: def set_arguments(self, arguments: List[str]) -> None: self.arguments = arguments + def set_result(self, result: str) -> None: + self.result = result + def check_completeness(self) -> None: if self.description is None: raise MissingDescription @@ -81,9 +85,11 @@ class TestCase: out.write(self.description + '\n') if self.dependencies: out.write('depends_on:' + ':'.join(self.dependencies) + '\n') - out.write(self.function + ':' + ':'.join(self.arguments) + '\n') - - + out.write(self.function + ':' + ':'.join(self.arguments)) + if self.result: + out.write(':' + self.result + '\n') + else: + out.write('\n') def write_data_file(filename: str, test_cases: Iterable[TestCase], diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py index 64c43b2e1..add8fe52e 100755 --- a/tests/scripts/generate_psa_tests.py +++ b/tests/scripts/generate_psa_tests.py @@ -255,6 +255,83 @@ class NotSupported: yield from self.test_cases_for_key_type_not_supported( kt, 0, param_descr='curve') +def test_case_for_key_generation( + key_type: str, bits: int, + dependencies: List[str], + *args: str, + result: str = '', + param_descr: str = '', +) -> test_case.TestCase: + """Return one test case exercising a key generation. + """ + hack_dependencies_not_implemented(dependencies) + tc = test_case.TestCase() + short_key_type = re.sub(r'PSA_(KEY_TYPE|ECC_FAMILY)_', r'', key_type) + tc.set_description('PSA {} {}-bit' + .format( short_key_type, bits)) + tc.set_dependencies(dependencies) + tc.set_function('generate_key') + tc.set_arguments([key_type] + list(args)) + tc.set_result(result) + + return tc + +class KeyGenerate: + """Generate positive and negative (invalid argument) test cases for key generation.""" + + def __init__(self, info: Information) -> None: + self.constructors = info.constructors + + def test_cases_for_key_type_key_generation( + self, + kt: crypto_knowledge.KeyType, + param: Optional[int] = None, + param_descr: str = '', + ) -> Iterator[test_case.TestCase]: + """Return test cases exercising key generation. + + All key types can be generated except for public keys. For public key + PSA_ERROR_INVALID_ARGUMENT status is expected. + """ + result = 'PSA_SUCCESS' + + import_dependencies = [psa_want_symbol(kt.name)] + if kt.params is not None: + import_dependencies += [psa_want_symbol(sym) + for i, sym in enumerate(kt.params)] + if kt.name.endswith('_PUBLIC_KEY'): + generate_dependencies = [] + result = 'PSA_ERROR_INVALID_ARGUMENT' + else: + generate_dependencies = import_dependencies + for bits in kt.sizes_to_test(): + yield test_case_for_key_generation( + kt.expression, bits, + finish_family_dependencies(generate_dependencies, bits), + str(bits), + result, + param_descr=param_descr + ) + + ECC_KEY_TYPES = ('PSA_KEY_TYPE_ECC_KEY_PAIR', + 'PSA_KEY_TYPE_ECC_PUBLIC_KEY') + + def test_cases_for_key_generation(self) -> Iterator[test_case.TestCase]: + """Generate test cases that exercise the generation of keys.""" + for key_type in sorted(self.constructors.key_types): + if key_type in self.ECC_KEY_TYPES: + continue + kt = crypto_knowledge.KeyType(key_type) + yield from self.test_cases_for_key_type_key_generation(kt) + for curve_family in sorted(self.constructors.ecc_curves): + for constr in self.ECC_KEY_TYPES: + kt = crypto_knowledge.KeyType(constr, [curve_family]) + yield from self.test_cases_for_key_type_key_generation( + kt, param_descr='type') + yield from self.test_cases_for_key_type_key_generation( + kt, 0, param_descr='curve') + + class StorageKey(psa_storage.Key): """Representation of a key for storage format testing.""" @@ -676,6 +753,8 @@ class TestGenerator: test_case.write_data_file(filename, test_cases) TARGETS = { + 'test_suite_psa_crypto_generate_key.generated': + lambda info: KeyGenerate(info).test_cases_for_key_generation(), 'test_suite_psa_crypto_not_supported.generated': lambda info: NotSupported(info).test_cases_for_not_supported(), 'test_suite_psa_crypto_storage_format.current': diff --git a/tests/suites/test_suite_psa_crypto_generate_key.function b/tests/suites/test_suite_psa_crypto_generate_key.function new file mode 100644 index 000000000..7404d382a --- /dev/null +++ b/tests/suites/test_suite_psa_crypto_generate_key.function @@ -0,0 +1,54 @@ +/* BEGIN_HEADER */ + +#include "psa/crypto.h" +#include "test/psa_crypto_helpers.h" + +#define INVALID_KEY_ID mbedtls_svc_key_id_make( 0, 0xfedcba98 ) + +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_PSA_CRYPTO_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE */ +void generate_key( int key_type, int bits, int result) +{ + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + mbedtls_svc_key_id_t key_id = INVALID_KEY_ID; + + // key lifetiem, usage flags, algorithm are irrelevant for this test + psa_key_lifetime_t _key_life_time = (psa_key_lifetime_t) 0; + psa_key_usage_t _key_usage_flags = (psa_key_usage_t) 0; + psa_algorithm_t _key_algorithm = (psa_algorithm_t) 0; + psa_key_type_t _key_type = (psa_key_type_t) key_type; + size_t _key_bits = (size_t) bits; + psa_status_t _result = (psa_status_t) result; + + PSA_ASSERT( psa_crypto_init( ) ); + psa_set_key_lifetime( &attributes, _key_life_time ); + psa_set_key_usage_flags( &attributes, _key_usage_flags ); + psa_set_key_algorithm( &attributes, _key_algorithm ); + psa_set_key_type( &attributes, _key_type ); + psa_set_key_bits( &attributes, _key_bits ); + TEST_EQUAL( psa_generate_key( &attributes, &key_id ), + _result ); + + // Verify attributes of the created key on success + if (_result == PSA_SUCCESS) + { + psa_key_attributes_t key_attributes = {0}; + PSA_ASSERT( psa_get_key_attributes( key_id, &key_attributes ) ); + TEST_EQUAL( psa_get_key_lifetime( &key_attributes ), 0 ); + TEST_EQUAL( psa_get_key_usage_flags( &key_attributes ), 0 ); + TEST_EQUAL( psa_get_key_algorithm( &key_attributes ), 0 ); + TEST_EQUAL( psa_get_key_type( &key_attributes ), _key_type ); + TEST_EQUAL( psa_get_key_bits( &key_attributes ), _key_bits ); + } + +exit: + psa_destroy_key( key_id ); + PSA_DONE( ); +} +/* END_CASE */