Be more explicit about key pair usage dependencies

Make the code that generates the test case be explicit about which usage(s)
will be needed for key pairs (`PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_uuu`). Allow
more than one usage specifier.

Do not systematically generalize BASIC to also include IMPORT and EXPORT:
not all tests actually need this, and our test configurations don't try to
have BASIC without IMPORT and EXPORT at the moment because we don't track
those dependencies accurately in manually written tests anyway.

Fix a bug whereby any usage other than BASIC or GENERATE led to the
dependency being silently dropped.

No change to the generated output.

Signed-off-by: Gilles Peskine <[email protected]>
This commit is contained in:
Gilles Peskine
2025-01-09 18:24:59 +01:00
parent fe852d3b9a
commit 8c23ac8520
3 changed files with 17 additions and 25 deletions
+9 -6
View File
@@ -42,7 +42,7 @@ def test_case_for_key_type_not_supported(
.format(verb, short_key_type, bits, adverb))
tc.set_function(verb + '_not_supported')
tc.set_key_bits(bits)
tc.set_key_pair_usage(verb.upper())
tc.set_key_pair_usage([verb.upper()])
tc.set_arguments([key_type] + list(args))
tc.set_dependencies(dependencies)
tc.skip_if_any_not_implemented(dependencies)
@@ -87,9 +87,11 @@ class KeyTypeNotSupported:
generate_dependencies = []
else:
generate_dependencies = \
psa_information.fix_key_pair_dependencies(import_dependencies, 'GENERATE')
psa_information.fix_key_pair_dependencies(import_dependencies,
['GENERATE'])
import_dependencies = \
psa_information.fix_key_pair_dependencies(import_dependencies, 'BASIC')
psa_information.fix_key_pair_dependencies(import_dependencies,
['BASIC', 'IMPORT', 'EXPORT'])
for bits in kt.sizes_to_test():
yield test_case_for_key_type_not_supported(
'import', kt.expression, bits,
@@ -155,7 +157,7 @@ def test_case_for_key_generation(
.format(short_key_type, bits))
tc.set_function('generate_key')
tc.set_key_bits(bits)
tc.set_key_pair_usage('GENERATE')
tc.set_key_pair_usage(['GENERATE'])
tc.set_arguments([key_type] + list(args) + [result])
return tc
@@ -258,7 +260,8 @@ class OpFail:
pretty_reason,
' with ' + pretty_type if pretty_type else ''))
dependencies = psa_information.automatic_dependencies(alg.base_expression, key_type)
dependencies = psa_information.fix_key_pair_dependencies(dependencies, 'BASIC')
dependencies = psa_information.fix_key_pair_dependencies(dependencies,
['BASIC', 'IMPORT', 'EXPORT'])
for i, dep in enumerate(dependencies):
if dep in not_deps:
dependencies[i] = '!' + dep
@@ -481,7 +484,7 @@ class StorageFormat:
tc.add_dependencies(psa_information.generate_deps_from_description(key.description))
tc.set_function('key_storage_' + verb)
tc.set_key_bits(key.bits)
tc.set_key_pair_usage('BASIC')
tc.set_key_pair_usage(['BASIC', 'EXPORT', 'IMPORT'])
if self.forward:
extra_arguments = []
else:
+5 -16
View File
@@ -139,29 +139,18 @@ def generate_deps_from_description(
return dep_list
def tweak_key_pair_dependency(dep: str, usage: str):
def tweak_key_pair_dependency(dep: str, usages: List[str]) -> List[str]:
"""
This helper function add the proper suffix to PSA_WANT_KEY_TYPE_xxx_KEY_PAIR
symbols according to the required usage.
"""
ret_list = list()
if dep.endswith('KEY_PAIR'):
if usage == "BASIC":
# BASIC automatically includes IMPORT and EXPORT for test purposes (see
# config_psa.h).
ret_list.append(re.sub(r'KEY_PAIR', r'KEY_PAIR_BASIC', dep))
ret_list.append(re.sub(r'KEY_PAIR', r'KEY_PAIR_IMPORT', dep))
ret_list.append(re.sub(r'KEY_PAIR', r'KEY_PAIR_EXPORT', dep))
elif usage == "GENERATE":
ret_list.append(re.sub(r'KEY_PAIR', r'KEY_PAIR_GENERATE', dep))
else:
# No replacement to do in this case
ret_list.append(dep)
return ret_list
return [dep + '_' + usage for usage in usages]
return [dep]
def fix_key_pair_dependencies(dep_list: List[str], usage: str):
def fix_key_pair_dependencies(dep_list: List[str], usages: List[str]) -> List[str]:
new_list = [new_deps
for dep in dep_list
for new_deps in tweak_key_pair_dependency(dep, usage)]
for new_deps in tweak_key_pair_dependency(dep, usages)]
return new_list
+3 -3
View File
@@ -71,7 +71,7 @@ class TestCase(test_case.TestCase):
self.automatic_dependencies = set() #type: Set[str]
self.dependency_prefix = dependency_prefix #type: Optional[str]
self.key_bits = None #type: Optional[int]
self.key_pair_usage = None #type: Optional[str]
self.key_pair_usage = None #type: Optional[List[str]]
def set_key_bits(self, key_bits: Optional[int]) -> None:
"""Use the given key size for automatic dependency generation.
@@ -83,8 +83,8 @@ class TestCase(test_case.TestCase):
"""
self.key_bits = key_bits
def set_key_pair_usage(self, key_pair_usage: Optional[str]) -> None:
"""Use the given suffix for key pair dependencies.
def set_key_pair_usage(self, key_pair_usage: Optional[List[str]]) -> None:
"""Use the given suffixes for key pair dependencies.
Call this function before set_arguments() if relevant.