blob: 312d5890c45531e6f4e1fac15b70631e9d8dd039 [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
Gabor Mezeifc719d62024-12-05 18:40:22 +010014import re
Gabor Mezei31911442024-11-20 17:05:16 +010015import os
16import sys
17
18import framework_scripts_path # pylint: disable=unused-import
19from mbedtls_framework import config_common
20
21
Gabor Mezeifc719d62024-12-05 18:40:22 +010022PSA_SYMBOL_REGEXP = re.compile(r'^PSA_.*')
23
Gabor Mezei31911442024-11-20 17:05:16 +010024PSA_UNSUPPORTED_FEATURE = frozenset([
25 'PSA_WANT_ALG_CBC_MAC',
26 'PSA_WANT_ALG_XTS',
27 'PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE',
28 'PSA_WANT_KEY_TYPE_DH_KEY_PAIR_DERIVE'
29])
30
Gabor Mezei871cde62024-11-20 17:08:19 +010031PSA_DEPRECATED_FEATURE = frozenset([
32 'PSA_WANT_KEY_TYPE_ECC_KEY_PAIR',
33 'PSA_WANT_KEY_TYPE_RSA_KEY_PAIR'
34])
35
Gabor Mezei31911442024-11-20 17:05:16 +010036PSA_UNSTABLE_FEATURE = frozenset([
37 'PSA_WANT_ECC_SECP_K1_224'
38])
39
Gabor Mezei871cde62024-11-20 17:08:19 +010040# The goal of the full configuration is to have everything that can be tested
41# together. This includes deprecated or insecure options. It excludes:
42# * Options that require additional build dependencies or unusual hardware.
43# * Options that make testing less effective.
44# * Options that are incompatible with other options, or more generally that
45# interact with other parts of the code in such a way that a bulk enabling
46# is not a good way to test them.
47# * Options that remove features.
48EXCLUDE_FROM_FULL = frozenset([
49 #pylint: disable=line-too-long
50 'MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH', # interacts with CTR_DRBG_128_BIT_KEY
51 'MBEDTLS_AES_USE_HARDWARE_ONLY', # hardware dependency
52 'MBEDTLS_BLOCK_CIPHER_NO_DECRYPT', # incompatible with ECB in PSA, CBC/XTS/NIST_KW/DES
53 'MBEDTLS_CTR_DRBG_USE_128_BIT_KEY', # interacts with ENTROPY_FORCE_SHA256
54 'MBEDTLS_DEPRECATED_REMOVED', # conflicts with deprecated options
55 'MBEDTLS_DEPRECATED_WARNING', # conflicts with deprecated options
56 'MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED', # influences the use of ECDH in TLS
57 'MBEDTLS_ECP_WITH_MPI_UINT', # disables the default ECP and is experimental
58 'MBEDTLS_ENTROPY_FORCE_SHA256', # interacts with CTR_DRBG_128_BIT_KEY
59 'MBEDTLS_HAVE_SSE2', # hardware dependency
60 'MBEDTLS_MEMORY_BACKTRACE', # depends on MEMORY_BUFFER_ALLOC_C
Ronald Crond98477d2024-12-11 13:44:10 +010061 'MBEDTLS_MEMORY_BUFFER_ALLOC_C', # makes sanitizers (e.g. ASan) less effective
Gabor Mezei871cde62024-11-20 17:08:19 +010062 'MBEDTLS_MEMORY_DEBUG', # depends on MEMORY_BUFFER_ALLOC_C
63 'MBEDTLS_NO_64BIT_MULTIPLICATION', # influences anything that uses bignum
64 'MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES', # removes a feature
65 'MBEDTLS_NO_PLATFORM_ENTROPY', # removes a feature
66 'MBEDTLS_NO_UDBL_DIVISION', # influences anything that uses bignum
67 'MBEDTLS_PSA_P256M_DRIVER_ENABLED', # influences SECP256R1 KeyGen/ECDH/ECDSA
68 'MBEDTLS_PLATFORM_NO_STD_FUNCTIONS', # removes a feature
69 'MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS', # removes a feature
70 'MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG', # behavior change + build dependency
71 'MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER', # interface and behavior change
72 'MBEDTLS_PSA_CRYPTO_SPM', # platform dependency (PSA SPM)
73 'MBEDTLS_PSA_INJECT_ENTROPY', # conflicts with platform entropy sources
74 'MBEDTLS_RSA_NO_CRT', # influences the use of RSA in X.509 and TLS
75 'MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY', # interacts with *_USE_A64_CRYPTO_IF_PRESENT
76 'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY', # interacts with *_USE_ARMV8_A_CRYPTO_IF_PRESENT
77 'MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY', # interacts with *_USE_A64_CRYPTO_IF_PRESENT
78 'MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT', # setting *_USE_ARMV8_A_CRYPTO is sufficient
79 'MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN', # build dependency (clang+memsan)
80 'MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND', # build dependency (valgrind headers)
Ronald Crond98477d2024-12-11 13:44:10 +010081 'MBEDTLS_PSA_STATIC_KEY_SLOTS', # only relevant for embedded devices
82 'MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE', # only relevant for embedded devices
Gabor Mezei871cde62024-11-20 17:08:19 +010083 *PSA_UNSUPPORTED_FEATURE,
84 *PSA_DEPRECATED_FEATURE,
85 *PSA_UNSTABLE_FEATURE
86])
87
88def is_boolean_setting(name, value):
89 """Is this a boolean setting?
90
91 Mbed TLS boolean settings are enabled if the preprocessor macro is
92 defined, and disabled if the preprocessor macro is not defined. The
93 macro definition line in the configuration file has an empty expansion.
94
95 PSA_WANT_xxx settings are also boolean, but when they are enabled,
96 they expand to a nonzero value. We leave them undefined when they
97 are disabled. (Setting them to 0 currently means to enable them, but
98 this might change to mean disabling them. Currently we just never set
99 them to 0.)
100 """
Gabor Mezeifc719d62024-12-05 18:40:22 +0100101 if re.match(PSA_SYMBOL_REGEXP, name):
Gabor Mezei871cde62024-11-20 17:08:19 +0100102 return True
103 if not value:
104 return True
105 return False
106
Gabor Mezei1a7bbe12024-12-05 10:17:13 +0100107def is_seamless_alt(name):
108 """Whether the xxx_ALT symbol should be included in the full configuration.
109
110 Include alternative implementations of platform functions, which are
111 configurable function pointers that default to the built-in function.
112 This way we test that the function pointers exist and build correctly
113 without changing the behavior, and tests can verify that the function
114 pointers are used by modifying those pointers.
115
116 Exclude alternative implementations of library functions since they require
117 an implementation of the relevant functions and an xxx_alt.h header.
118 """
119 if name in (
120 'MBEDTLS_PLATFORM_GMTIME_R_ALT',
121 'MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT',
122 'MBEDTLS_PLATFORM_MS_TIME_ALT',
123 'MBEDTLS_PLATFORM_ZEROIZE_ALT',
124 ):
125 # Similar to non-platform xxx_ALT, requires platform_alt.h
126 return False
127 return name.startswith('MBEDTLS_PLATFORM_')
128
Gabor Mezei871cde62024-11-20 17:08:19 +0100129def include_in_full(name):
130 """Rules for symbols in the "full" configuration."""
131 if name in EXCLUDE_FROM_FULL:
132 return False
Gabor Mezei1a7bbe12024-12-05 10:17:13 +0100133 if name.endswith('_ALT'):
134 return is_seamless_alt(name)
Gabor Mezei871cde62024-11-20 17:08:19 +0100135 return True
136
137def full_adapter(name, value, active):
138 """Config adapter for "full"."""
139 if not is_boolean_setting(name, value):
140 return active
141 return include_in_full(name)
142
Gabor Mezei31911442024-11-20 17:05:16 +0100143
Gabor Mezeiafc5fa52024-11-29 12:57:53 +0100144class TFPSACryptoConfigFile(config_common.ConfigFile):
Gabor Mezei31911442024-11-20 17:05:16 +0100145 """Representation of a TF PSA Crypto configuration file."""
146
Gabor Mezei37bf61e2024-11-29 12:59:26 +0100147 _path_in_tree = 'include/psa/crypto_config.h'
Gabor Mezei31911442024-11-20 17:05:16 +0100148 default_path = [_path_in_tree,
149 os.path.join(os.path.dirname(__file__),
150 os.pardir,
151 _path_in_tree),
Gabor Mezeic716aad2024-12-05 18:41:27 +0100152 os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
Gabor Mezei31911442024-11-20 17:05:16 +0100153 _path_in_tree)]
154
155 def __init__(self, filename=None):
Gabor Mezei1044a802024-11-29 12:58:44 +0100156 super().__init__(self.default_path, 'TF-PSA-Crypto', filename)
Gabor Mezei31911442024-11-20 17:05:16 +0100157
158
Gabor Mezeiafc5fa52024-11-29 12:57:53 +0100159class TFPSACryptoConfig(config_common.Config):
Gabor Mezei31911442024-11-20 17:05:16 +0100160 """Representation of the TF PSA Crypto configuration.
161
162 See the documentation of the `Config` class for methods to query
163 and modify the configuration.
164 """
165
Gabor Mezeifb368142024-12-05 10:11:46 +0100166 def __init__(self, filename=None):
Gabor Mezei31911442024-11-20 17:05:16 +0100167 """Read the PSA crypto configuration files."""
168
169 super().__init__()
Gabor Mezei680a7c32024-11-29 13:09:10 +0100170 configfile = TFPSACryptoConfigFile(filename)
171 self.configfiles.append(configfile)
Gabor Mezei31911442024-11-20 17:05:16 +0100172 self.settings.update({name: config_common.Setting(configfile, active, name, value, section)
Gabor Mezei31911442024-11-20 17:05:16 +0100173 for (active, name, value, section) in configfile.parse_file()})
174
175 def set(self, name, value=None):
176 """Set name to the given value and make it active."""
177
178 if name in PSA_UNSUPPORTED_FEATURE:
179 raise ValueError(f'Feature is unsupported: \'{name}\'')
180 if name in PSA_UNSTABLE_FEATURE:
181 raise ValueError(f'Feature is unstable: \'{name}\'')
182
183 if name not in self.settings:
184 self._get_configfile().templates.append((name, '', f'#define {name} '))
185
186 # Default value for PSA macros is '1'
Gabor Mezeifc719d62024-12-05 18:40:22 +0100187 if not value and re.match(PSA_SYMBOL_REGEXP, name):
Gabor Mezei31911442024-11-20 17:05:16 +0100188 value = '1'
189
190 super().set(name, value)
191
192
Gabor Mezeiafc5fa52024-11-29 12:57:53 +0100193class TFPSACryptoConfigTool(config_common.ConfigTool):
Gabor Mezei31911442024-11-20 17:05:16 +0100194 """Command line TF PSA Crypto config file manipulation tool."""
195
196 def __init__(self):
Gabor Mezei680a7c32024-11-29 13:09:10 +0100197 super().__init__(TFPSACryptoConfigFile.default_path[0])
198 self.config = TFPSACryptoConfig(self.args.file)
Gabor Mezei31911442024-11-20 17:05:16 +0100199
200 def custom_parser_options(self):
201 """Adds TF PSA Crypto specific options for the parser."""
202
Gabor Mezei871cde62024-11-20 17:08:19 +0100203 self.add_adapter(
204 'full', full_adapter,
205 """Uncomment most features.
206 Exclude alternative implementations and platform support options, as well as
207 some options that are awkward to test.
208 """)
209
Gabor Mezei31911442024-11-20 17:05:16 +0100210
211if __name__ == '__main__':
Gabor Mezeiafc5fa52024-11-29 12:57:53 +0100212 sys.exit(TFPSACryptoConfigTool().main())