Gabor Mezei | 3191144 | 2024-11-20 17:05:16 +0100 | [diff] [blame^] | 1 | #!/usr/bin/env python3 |
| 2 | |
| 3 | """TF PSA Crypto configuration file manipulation library and tool |
| 4 | |
| 5 | Basic usage, to read the TF PSA Crypto configuration: |
| 6 | config = TfPSACryptoConfig() |
| 7 | if 'PSA_WANT_ALG_MD5' in config: print('MD5 is enabled') |
| 8 | """ |
| 9 | |
| 10 | ## Copyright The Mbed TLS Contributors |
| 11 | ## SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later |
| 12 | ## |
| 13 | |
| 14 | import os |
| 15 | import sys |
| 16 | |
| 17 | import framework_scripts_path # pylint: disable=unused-import |
| 18 | from mbedtls_framework import config_common |
| 19 | |
| 20 | |
| 21 | PSA_UNSUPPORTED_FEATURE = frozenset([ |
| 22 | 'PSA_WANT_ALG_CBC_MAC', |
| 23 | 'PSA_WANT_ALG_XTS', |
| 24 | 'PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE', |
| 25 | 'PSA_WANT_KEY_TYPE_DH_KEY_PAIR_DERIVE' |
| 26 | ]) |
| 27 | |
| 28 | PSA_UNSTABLE_FEATURE = frozenset([ |
| 29 | 'PSA_WANT_ECC_SECP_K1_224' |
| 30 | ]) |
| 31 | |
| 32 | |
| 33 | class TfPSACryptoConfigFile(config_common.ConfigFile): |
| 34 | """Representation of a TF PSA Crypto configuration file.""" |
| 35 | |
| 36 | _path_in_tree = 'tf-psa-crypto/include/psa/crypto_config.h' |
| 37 | default_path = [_path_in_tree, |
| 38 | os.path.join(os.path.dirname(__file__), |
| 39 | os.pardir, |
| 40 | _path_in_tree), |
| 41 | os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), |
| 42 | _path_in_tree)] |
| 43 | |
| 44 | def __init__(self, filename=None): |
| 45 | super().__init__(self.default_path, 'Crypto', filename) |
| 46 | |
| 47 | |
| 48 | class TfPSACryptoConfig(config_common.Config): |
| 49 | """Representation of the TF PSA Crypto configuration. |
| 50 | |
| 51 | See the documentation of the `Config` class for methods to query |
| 52 | and modify the configuration. |
| 53 | """ |
| 54 | |
| 55 | def __init__(self, *configfiles): |
| 56 | """Read the PSA crypto configuration files.""" |
| 57 | |
| 58 | super().__init__() |
| 59 | self.configfiles.extend(configfiles) |
| 60 | self.settings.update({name: config_common.Setting(configfile, active, name, value, section) |
| 61 | for configfile in configfiles |
| 62 | for (active, name, value, section) in configfile.parse_file()}) |
| 63 | |
| 64 | def set(self, name, value=None): |
| 65 | """Set name to the given value and make it active.""" |
| 66 | |
| 67 | if name in PSA_UNSUPPORTED_FEATURE: |
| 68 | raise ValueError(f'Feature is unsupported: \'{name}\'') |
| 69 | if name in PSA_UNSTABLE_FEATURE: |
| 70 | raise ValueError(f'Feature is unstable: \'{name}\'') |
| 71 | |
| 72 | if name not in self.settings: |
| 73 | self._get_configfile().templates.append((name, '', f'#define {name} ')) |
| 74 | |
| 75 | # Default value for PSA macros is '1' |
| 76 | if name.startswith('PSA_') and not value: |
| 77 | value = '1' |
| 78 | |
| 79 | super().set(name, value) |
| 80 | |
| 81 | |
| 82 | class TfPSACryptoConfigTool(config_common.ConfigTool): |
| 83 | """Command line TF PSA Crypto config file manipulation tool.""" |
| 84 | |
| 85 | def __init__(self): |
| 86 | super().__init__(TfPSACryptoConfigFile.default_path[0], single_config=False) |
| 87 | configfiles = [TfPSACryptoConfigFile(file) for file in self.args.file] |
| 88 | self.config = TfPSACryptoConfig(*configfiles) |
| 89 | |
| 90 | def custom_parser_options(self): |
| 91 | """Adds TF PSA Crypto specific options for the parser.""" |
| 92 | |
| 93 | |
| 94 | if __name__ == '__main__': |
| 95 | sys.exit(TfPSACryptoConfigTool().main()) |