From 0994049614cc0d7f1710a5584475a1187b6d41c5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 26 Jan 2021 22:16:30 +0100 Subject: [PATCH] New framework for generating PSA test cases automatically This commit creates a script to generate test cases automatically based on enumerating PSA key types, algorithms and other classifications of cryptographic mechanisms. Subsequent commits will implement the generation of test cases. Signed-off-by: Gilles Peskine --- tests/scripts/generate_psa_tests.py | 71 +++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100755 tests/scripts/generate_psa_tests.py diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py new file mode 100755 index 000000000..a1641106f --- /dev/null +++ b/tests/scripts/generate_psa_tests.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +"""Generate test data for PSA cryptographic mechanisms. +""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import sys +from typing import TypeVar + +import scripts_path # pylint: disable=unused-import +from mbedtls_dev import macro_collector + +T = TypeVar('T') #pylint: disable=invalid-name + +class TestGenerator: + """Gather information and generate test data.""" + + def __init__(self, options): + self.test_suite_directory = self.get_option(options, 'directory', + 'tests/suites') + self.constructors = self.read_psa_interface() + + @staticmethod + def get_option(options, name: str, default: T) -> T: + value = getattr(options, name, None) + return default if value is None else value + + @staticmethod + def remove_unwanted_macros( + constructors: macro_collector.PSAMacroCollector + ) -> None: + # Mbed TLS doesn't support DSA. Don't attempt to generate any related + # test case. + constructors.key_types.discard('PSA_KEY_TYPE_DSA_KEY_PAIR') + 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: + """Return the list of known key types, algorithms, etc.""" + constructors = macro_collector.PSAMacroCollector() + header_file_names = ['include/psa/crypto_values.h', + 'include/psa/crypto_extra.h'] + for header_file_name in header_file_names: + with open(header_file_name, 'rb') as header_file: + constructors.read_file(header_file) + self.remove_unwanted_macros(constructors) + return constructors + +def main(args): + """Command line entry point.""" + parser = argparse.ArgumentParser(description=__doc__) + options = parser.parse_args(args) + generator = TestGenerator(options) + +if __name__ == '__main__': + main(sys.argv[1:])