blob: 8002392e2a17917b25e38d2f9a3206838ae4e306 [file] [log] [blame]
Gabor Mezei31911442024-11-20 17:05:16 +01001#!/usr/bin/env python3
2
3"""TF PSA Crypto configuration file manipulation library and tool
4
5Basic usage, to read the TF PSA Crypto configuration:
Gabor Mezeiafc5fa52024-11-29 12:57:53 +01006 config = TFPSACryptoConfig()
Gabor Mezei31911442024-11-20 17:05:16 +01007 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
14import os
15import sys
16
17import framework_scripts_path # pylint: disable=unused-import
18from mbedtls_framework import config_common
19
20
21PSA_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
Gabor Mezei871cde62024-11-20 17:08:19 +010028PSA_DEPRECATED_FEATURE = frozenset([
29 'PSA_WANT_KEY_TYPE_ECC_KEY_PAIR',
30 'PSA_WANT_KEY_TYPE_RSA_KEY_PAIR'
31])
32
Gabor Mezei31911442024-11-20 17:05:16 +010033PSA_UNSTABLE_FEATURE = frozenset([
34 'PSA_WANT_ECC_SECP_K1_224'
35])
36
Gabor Mezei871cde62024-11-20 17:08:19 +010037# The goal of the full configuration is to have everything that can be tested
38# together. This includes deprecated or insecure options. It excludes:
39# * Options that require additional build dependencies or unusual hardware.
40# * Options that make testing less effective.
41# * Options that are incompatible with other options, or more generally that
42# interact with other parts of the code in such a way that a bulk enabling
43# is not a good way to test them.
44# * Options that remove features.
45EXCLUDE_FROM_FULL = frozenset([
46 #pylint: disable=line-too-long
47 'MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH', # interacts with CTR_DRBG_128_BIT_KEY
48 'MBEDTLS_AES_USE_HARDWARE_ONLY', # hardware dependency
49 'MBEDTLS_BLOCK_CIPHER_NO_DECRYPT', # incompatible with ECB in PSA, CBC/XTS/NIST_KW/DES
50 'MBEDTLS_CTR_DRBG_USE_128_BIT_KEY', # interacts with ENTROPY_FORCE_SHA256
51 'MBEDTLS_DEPRECATED_REMOVED', # conflicts with deprecated options
52 'MBEDTLS_DEPRECATED_WARNING', # conflicts with deprecated options
53 'MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED', # influences the use of ECDH in TLS
54 'MBEDTLS_ECP_WITH_MPI_UINT', # disables the default ECP and is experimental
55 'MBEDTLS_ENTROPY_FORCE_SHA256', # interacts with CTR_DRBG_128_BIT_KEY
56 'MBEDTLS_HAVE_SSE2', # hardware dependency
57 'MBEDTLS_MEMORY_BACKTRACE', # depends on MEMORY_BUFFER_ALLOC_C
58 'MBEDTLS_MEMORY_DEBUG', # depends on MEMORY_BUFFER_ALLOC_C
59 'MBEDTLS_NO_64BIT_MULTIPLICATION', # influences anything that uses bignum
60 'MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES', # removes a feature
61 'MBEDTLS_NO_PLATFORM_ENTROPY', # removes a feature
62 'MBEDTLS_NO_UDBL_DIVISION', # influences anything that uses bignum
63 'MBEDTLS_PSA_P256M_DRIVER_ENABLED', # influences SECP256R1 KeyGen/ECDH/ECDSA
64 'MBEDTLS_PLATFORM_NO_STD_FUNCTIONS', # removes a feature
65 'MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS', # removes a feature
66 'MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG', # behavior change + build dependency
67 'MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER', # interface and behavior change
68 'MBEDTLS_PSA_CRYPTO_SPM', # platform dependency (PSA SPM)
69 'MBEDTLS_PSA_INJECT_ENTROPY', # conflicts with platform entropy sources
70 'MBEDTLS_RSA_NO_CRT', # influences the use of RSA in X.509 and TLS
71 'MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY', # interacts with *_USE_A64_CRYPTO_IF_PRESENT
72 'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY', # interacts with *_USE_ARMV8_A_CRYPTO_IF_PRESENT
73 'MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY', # interacts with *_USE_A64_CRYPTO_IF_PRESENT
74 'MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT', # setting *_USE_ARMV8_A_CRYPTO is sufficient
75 'MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN', # build dependency (clang+memsan)
76 'MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND', # build dependency (valgrind headers)
77 'MBEDTLS_X509_REMOVE_INFO', # removes a feature
78 *PSA_UNSUPPORTED_FEATURE,
79 *PSA_DEPRECATED_FEATURE,
80 *PSA_UNSTABLE_FEATURE
81])
82
83def is_boolean_setting(name, value):
84 """Is this a boolean setting?
85
86 Mbed TLS boolean settings are enabled if the preprocessor macro is
87 defined, and disabled if the preprocessor macro is not defined. The
88 macro definition line in the configuration file has an empty expansion.
89
90 PSA_WANT_xxx settings are also boolean, but when they are enabled,
91 they expand to a nonzero value. We leave them undefined when they
92 are disabled. (Setting them to 0 currently means to enable them, but
93 this might change to mean disabling them. Currently we just never set
94 them to 0.)
95 """
96 if name.startswith('PSA_WANT_'):
97 return True
98 if not value:
99 return True
100 return False
101
102def include_in_full(name):
103 """Rules for symbols in the "full" configuration."""
104 if name in EXCLUDE_FROM_FULL:
105 return False
106 return True
107
108def full_adapter(name, value, active):
109 """Config adapter for "full"."""
110 if not is_boolean_setting(name, value):
111 return active
112 return include_in_full(name)
113
Gabor Mezei31911442024-11-20 17:05:16 +0100114
Gabor Mezeiafc5fa52024-11-29 12:57:53 +0100115class TFPSACryptoConfigFile(config_common.ConfigFile):
Gabor Mezei31911442024-11-20 17:05:16 +0100116 """Representation of a TF PSA Crypto configuration file."""
117
Gabor Mezei37bf61e2024-11-29 12:59:26 +0100118 _path_in_tree = 'include/psa/crypto_config.h'
Gabor Mezei31911442024-11-20 17:05:16 +0100119 default_path = [_path_in_tree,
120 os.path.join(os.path.dirname(__file__),
121 os.pardir,
122 _path_in_tree),
123 os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))),
124 _path_in_tree)]
125
126 def __init__(self, filename=None):
Gabor Mezei1044a802024-11-29 12:58:44 +0100127 super().__init__(self.default_path, 'TF-PSA-Crypto', filename)
Gabor Mezei31911442024-11-20 17:05:16 +0100128
129
Gabor Mezeiafc5fa52024-11-29 12:57:53 +0100130class TFPSACryptoConfig(config_common.Config):
Gabor Mezei31911442024-11-20 17:05:16 +0100131 """Representation of the TF PSA Crypto configuration.
132
133 See the documentation of the `Config` class for methods to query
134 and modify the configuration.
135 """
136
Gabor Mezeifb368142024-12-05 10:11:46 +0100137 def __init__(self, filename=None):
Gabor Mezei31911442024-11-20 17:05:16 +0100138 """Read the PSA crypto configuration files."""
139
140 super().__init__()
Gabor Mezei680a7c32024-11-29 13:09:10 +0100141 configfile = TFPSACryptoConfigFile(filename)
142 self.configfiles.append(configfile)
Gabor Mezei31911442024-11-20 17:05:16 +0100143 self.settings.update({name: config_common.Setting(configfile, active, name, value, section)
Gabor Mezei31911442024-11-20 17:05:16 +0100144 for (active, name, value, section) in configfile.parse_file()})
145
146 def set(self, name, value=None):
147 """Set name to the given value and make it active."""
148
149 if name in PSA_UNSUPPORTED_FEATURE:
150 raise ValueError(f'Feature is unsupported: \'{name}\'')
151 if name in PSA_UNSTABLE_FEATURE:
152 raise ValueError(f'Feature is unstable: \'{name}\'')
153
154 if name not in self.settings:
155 self._get_configfile().templates.append((name, '', f'#define {name} '))
156
157 # Default value for PSA macros is '1'
158 if name.startswith('PSA_') and not value:
159 value = '1'
160
161 super().set(name, value)
162
163
Gabor Mezeiafc5fa52024-11-29 12:57:53 +0100164class TFPSACryptoConfigTool(config_common.ConfigTool):
Gabor Mezei31911442024-11-20 17:05:16 +0100165 """Command line TF PSA Crypto config file manipulation tool."""
166
167 def __init__(self):
Gabor Mezei680a7c32024-11-29 13:09:10 +0100168 super().__init__(TFPSACryptoConfigFile.default_path[0])
169 self.config = TFPSACryptoConfig(self.args.file)
Gabor Mezei31911442024-11-20 17:05:16 +0100170
171 def custom_parser_options(self):
172 """Adds TF PSA Crypto specific options for the parser."""
173
Gabor Mezei871cde62024-11-20 17:08:19 +0100174 self.add_adapter(
175 'full', full_adapter,
176 """Uncomment most features.
177 Exclude alternative implementations and platform support options, as well as
178 some options that are awkward to test.
179 """)
180
Gabor Mezei31911442024-11-20 17:05:16 +0100181
182if __name__ == '__main__':
Gabor Mezeiafc5fa52024-11-29 12:57:53 +0100183 sys.exit(TFPSACryptoConfigTool().main())