mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-23 06:05:47 +01:00
Expand psa_generate_tests to support constructor arguments
In macro_collector.py, base InputsForTest on PSAMacroEnumerator rather than PSAMacroCollector. It didn't make much sense to use PSAMacroCollector anymore since InputsForTest didn't use anything other than the constructor. psa_generate_tests now generates arguments for more macros. In particular, it now collects macro arguments from test_suite_psa_crypto_metadata. Algorithms with parameters are now supported. Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
parent
ae9f14b159
commit
b93f854f4c
@ -105,6 +105,16 @@ class PSAMacroEnumerator:
|
|||||||
'tag_length': [],
|
'tag_length': [],
|
||||||
'min_tag_length': [],
|
'min_tag_length': [],
|
||||||
} #type: Dict[str, List[str]]
|
} #type: Dict[str, List[str]]
|
||||||
|
self.include_intermediate = False
|
||||||
|
|
||||||
|
def is_internal_name(self, name: str) -> bool:
|
||||||
|
"""Whether this is an internal macro. Internal macros will be skipped."""
|
||||||
|
if not self.include_intermediate:
|
||||||
|
if name.endswith('_BASE') or name.endswith('_NONE'):
|
||||||
|
return True
|
||||||
|
if '_CATEGORY_' in name:
|
||||||
|
return True
|
||||||
|
return name.endswith('_FLAG') or name.endswith('_MASK')
|
||||||
|
|
||||||
def gather_arguments(self) -> None:
|
def gather_arguments(self) -> None:
|
||||||
"""Populate the list of values for macro arguments.
|
"""Populate the list of values for macro arguments.
|
||||||
@ -192,15 +202,6 @@ class PSAMacroCollector(PSAMacroEnumerator):
|
|||||||
self.key_types_from_group = {} #type: Dict[str, str]
|
self.key_types_from_group = {} #type: Dict[str, str]
|
||||||
self.algorithms_from_hash = {} #type: Dict[str, str]
|
self.algorithms_from_hash = {} #type: Dict[str, str]
|
||||||
|
|
||||||
def is_internal_name(self, name: str) -> bool:
|
|
||||||
"""Whether this is an internal macro. Internal macros will be skipped."""
|
|
||||||
if not self.include_intermediate:
|
|
||||||
if name.endswith('_BASE') or name.endswith('_NONE'):
|
|
||||||
return True
|
|
||||||
if '_CATEGORY_' in name:
|
|
||||||
return True
|
|
||||||
return name.endswith('_FLAG') or name.endswith('_MASK')
|
|
||||||
|
|
||||||
def record_algorithm_subtype(self, name: str, expansion: str) -> None:
|
def record_algorithm_subtype(self, name: str, expansion: str) -> None:
|
||||||
"""Record the subtype of an algorithm constructor.
|
"""Record the subtype of an algorithm constructor.
|
||||||
|
|
||||||
@ -301,7 +302,7 @@ class PSAMacroCollector(PSAMacroEnumerator):
|
|||||||
self.read_line(line)
|
self.read_line(line)
|
||||||
|
|
||||||
|
|
||||||
class InputsForTest(PSAMacroCollector):
|
class InputsForTest(PSAMacroEnumerator):
|
||||||
# pylint: disable=too-many-instance-attributes
|
# pylint: disable=too-many-instance-attributes
|
||||||
"""Accumulate information about macros to test.
|
"""Accumulate information about macros to test.
|
||||||
enumerate
|
enumerate
|
||||||
@ -408,7 +409,8 @@ enumerate
|
|||||||
name = m.group(1)
|
name = m.group(1)
|
||||||
self.all_declared.add(name)
|
self.all_declared.add(name)
|
||||||
if re.search(self._excluded_name_re, name) or \
|
if re.search(self._excluded_name_re, name) or \
|
||||||
name in self._excluded_names:
|
name in self._excluded_names or \
|
||||||
|
self.is_internal_name(name):
|
||||||
return
|
return
|
||||||
dest = self.table_by_prefix.get(m.group(2))
|
dest = self.table_by_prefix.get(m.group(2))
|
||||||
if dest is None:
|
if dest is None:
|
||||||
|
@ -94,23 +94,25 @@ class Information:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def remove_unwanted_macros(
|
def remove_unwanted_macros(
|
||||||
constructors: macro_collector.PSAMacroCollector
|
constructors: macro_collector.PSAMacroEnumerator
|
||||||
) -> None:
|
) -> None:
|
||||||
# Mbed TLS doesn't support DSA. Don't attempt to generate any related
|
# Mbed TLS doesn't support finite-field DH yet and will not support
|
||||||
# test case.
|
# finite-field DSA. Don't attempt to generate any related test case.
|
||||||
|
constructors.key_types.discard('PSA_KEY_TYPE_DH_KEY_PAIR')
|
||||||
|
constructors.key_types.discard('PSA_KEY_TYPE_DH_PUBLIC_KEY')
|
||||||
constructors.key_types.discard('PSA_KEY_TYPE_DSA_KEY_PAIR')
|
constructors.key_types.discard('PSA_KEY_TYPE_DSA_KEY_PAIR')
|
||||||
constructors.key_types.discard('PSA_KEY_TYPE_DSA_PUBLIC_KEY')
|
constructors.key_types.discard('PSA_KEY_TYPE_DSA_PUBLIC_KEY')
|
||||||
constructors.algorithms_from_hash.pop('PSA_ALG_DSA', None)
|
|
||||||
constructors.algorithms_from_hash.pop('PSA_ALG_DETERMINISTIC_DSA', None)
|
|
||||||
|
|
||||||
def read_psa_interface(self) -> macro_collector.PSAMacroCollector:
|
def read_psa_interface(self) -> macro_collector.PSAMacroEnumerator:
|
||||||
"""Return the list of known key types, algorithms, etc."""
|
"""Return the list of known key types, algorithms, etc."""
|
||||||
constructors = macro_collector.InputsForTest()
|
constructors = macro_collector.InputsForTest()
|
||||||
header_file_names = ['include/psa/crypto_values.h',
|
header_file_names = ['include/psa/crypto_values.h',
|
||||||
'include/psa/crypto_extra.h']
|
'include/psa/crypto_extra.h']
|
||||||
|
test_suites = ['tests/suites/test_suite_psa_crypto_metadata.data']
|
||||||
for header_file_name in header_file_names:
|
for header_file_name in header_file_names:
|
||||||
with open(header_file_name, 'rb') as header_file:
|
constructors.parse_header(header_file_name)
|
||||||
constructors.read_file(header_file)
|
for test_cases in test_suites:
|
||||||
|
constructors.parse_test_cases(test_cases)
|
||||||
self.remove_unwanted_macros(constructors)
|
self.remove_unwanted_macros(constructors)
|
||||||
constructors.gather_arguments()
|
constructors.gather_arguments()
|
||||||
return constructors
|
return constructors
|
||||||
@ -194,14 +196,18 @@ class NotSupported:
|
|||||||
)
|
)
|
||||||
# To be added: derive
|
# To be added: derive
|
||||||
|
|
||||||
|
ECC_KEY_TYPES = ('PSA_KEY_TYPE_ECC_KEY_PAIR',
|
||||||
|
'PSA_KEY_TYPE_ECC_PUBLIC_KEY')
|
||||||
|
|
||||||
def test_cases_for_not_supported(self) -> Iterator[test_case.TestCase]:
|
def test_cases_for_not_supported(self) -> Iterator[test_case.TestCase]:
|
||||||
"""Generate test cases that exercise the creation of keys of unsupported types."""
|
"""Generate test cases that exercise the creation of keys of unsupported types."""
|
||||||
for key_type in sorted(self.constructors.key_types):
|
for key_type in sorted(self.constructors.key_types):
|
||||||
|
if key_type in self.ECC_KEY_TYPES:
|
||||||
|
continue
|
||||||
kt = crypto_knowledge.KeyType(key_type)
|
kt = crypto_knowledge.KeyType(key_type)
|
||||||
yield from self.test_cases_for_key_type_not_supported(kt)
|
yield from self.test_cases_for_key_type_not_supported(kt)
|
||||||
for curve_family in sorted(self.constructors.ecc_curves):
|
for curve_family in sorted(self.constructors.ecc_curves):
|
||||||
for constr in ('PSA_KEY_TYPE_ECC_KEY_PAIR',
|
for constr in self.ECC_KEY_TYPES:
|
||||||
'PSA_KEY_TYPE_ECC_PUBLIC_KEY'):
|
|
||||||
kt = crypto_knowledge.KeyType(constr, [curve_family])
|
kt = crypto_knowledge.KeyType(constr, [curve_family])
|
||||||
yield from self.test_cases_for_key_type_not_supported(
|
yield from self.test_cases_for_key_type_not_supported(
|
||||||
kt, param_descr='type')
|
kt, param_descr='type')
|
||||||
@ -330,16 +336,9 @@ class StorageFormat:
|
|||||||
|
|
||||||
def all_keys_for_types(self) -> Iterator[StorageKey]:
|
def all_keys_for_types(self) -> Iterator[StorageKey]:
|
||||||
"""Generate test keys covering key types and their representations."""
|
"""Generate test keys covering key types and their representations."""
|
||||||
for key_type in sorted(self.constructors.key_types):
|
key_types = sorted(self.constructors.key_types)
|
||||||
|
for key_type in self.constructors.generate_expressions(key_types):
|
||||||
yield from self.keys_for_type(key_type)
|
yield from self.keys_for_type(key_type)
|
||||||
for key_type in sorted(self.constructors.key_types_from_curve):
|
|
||||||
for curve in sorted(self.constructors.ecc_curves):
|
|
||||||
yield from self.keys_for_type(key_type, [curve])
|
|
||||||
## Diffie-Hellman (FFDH) is not supported yet, either in
|
|
||||||
## crypto_knowledge.py or in Mbed TLS.
|
|
||||||
# for key_type in sorted(self.constructors.key_types_from_group):
|
|
||||||
# for group in sorted(self.constructors.dh_groups):
|
|
||||||
# yield from self.keys_for_type(key_type, [group])
|
|
||||||
|
|
||||||
def keys_for_algorithm(self, alg: str) -> Iterator[StorageKey]:
|
def keys_for_algorithm(self, alg: str) -> Iterator[StorageKey]:
|
||||||
"""Generate test keys for the specified algorithm."""
|
"""Generate test keys for the specified algorithm."""
|
||||||
@ -365,9 +364,9 @@ class StorageFormat:
|
|||||||
|
|
||||||
def all_keys_for_algorithms(self) -> Iterator[StorageKey]:
|
def all_keys_for_algorithms(self) -> Iterator[StorageKey]:
|
||||||
"""Generate test keys covering algorithm encodings."""
|
"""Generate test keys covering algorithm encodings."""
|
||||||
for alg in sorted(self.constructors.algorithms):
|
algorithms = sorted(self.constructors.algorithms)
|
||||||
|
for alg in self.constructors.generate_expressions(algorithms):
|
||||||
yield from self.keys_for_algorithm(alg)
|
yield from self.keys_for_algorithm(alg)
|
||||||
# To do: algorithm constructors with parameters
|
|
||||||
|
|
||||||
def all_test_cases(self) -> Iterator[test_case.TestCase]:
|
def all_test_cases(self) -> Iterator[test_case.TestCase]:
|
||||||
"""Generate all storage format test cases."""
|
"""Generate all storage format test cases."""
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user