blob: 1027f2c99c888f0a594af76a05a64c59b68e4a48 [file] [log] [blame]
Gilles Peskineb4063892019-07-27 21:36:44 +02001#!/usr/bin/env python3
2
Gabor Mezei9f2b8172024-08-06 12:02:18 +02003"""Mbed TLS and PSA configuration file manipulation library and tool
Gilles Peskineb4063892019-07-27 21:36:44 +02004
Fredrik Hessecc207bc2021-09-28 21:06:08 +02005Basic usage, to read the Mbed TLS configuration:
Gabor Mezei9f2b8172024-08-06 12:02:18 +02006 config = CombinedConfigFile()
Gilles Peskineb4063892019-07-27 21:36:44 +02007 if 'MBEDTLS_RSA_C' in config: print('RSA is enabled')
8"""
9
Bence Szépkúti1e148272020-08-07 13:07:28 +020010## Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +000011## SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Gilles Peskineb4063892019-07-27 21:36:44 +020012##
Gilles Peskineb4063892019-07-27 21:36:44 +020013
Gilles Peskine208e4ec2019-07-29 23:43:20 +020014import os
Gilles Peskineb4063892019-07-27 21:36:44 +020015import re
Gabor Mezei24d7cc72024-08-06 15:11:24 +020016import sys
Gilles Peskineb4063892019-07-27 21:36:44 +020017
Gabor Mezei0e9e4cb2024-09-10 16:16:35 +020018import framework_scripts_path # pylint: disable=unused-import
19from mbedtls_framework import config_common
Gabor Mezeid53080d2024-08-27 14:06:54 +020020
Gabor Mezeia12ed6b2024-09-09 17:20:49 +020021
Gilles Peskinee4c69552024-09-19 19:57:58 +020022def is_boolean_setting(name, value):
23 """Is this a boolean setting?
Gabor Mezeide6e1922024-06-28 17:10:50 +020024
Gilles Peskinee4c69552024-09-19 19:57:58 +020025 Mbed TLS boolean settings are enabled if the preprocessor macro is
26 defined, and disabled if the preprocessor macro is not defined. The
27 macro definition line in the configuration file has an empty expansion.
28
29 PSA_WANT_xxx settings are also boolean, but when they are enabled,
30 they expand to a nonzero value. We leave them undefined when they
31 are disabled. (Setting them to 0 currently means to enable them, but
32 this might change to mean disabling them. Currently we just never set
33 them to 0.)
Gabor Mezeide6e1922024-06-28 17:10:50 +020034 """
Gilles Peskinee4c69552024-09-19 19:57:58 +020035 if name.startswith('PSA_WANT_'):
36 return True
37 if not value:
38 return True
39 return False
Gilles Peskine53d41ae2019-07-27 23:31:53 +020040
Gilles Peskine00b91442024-09-19 20:13:49 +020041def realfull_adapter(_name, _value, _active):
Gilles Peskine36571d62024-09-19 19:58:56 +020042 """Activate all symbols.
Gilles Peskineba4162a2022-04-11 17:04:38 +020043
44 This is intended for building the documentation, including the
45 documentation of settings that are activated by defining an optional
Gilles Peskine36571d62024-09-19 19:58:56 +020046 preprocessor macro. There is no expectation that the resulting
47 configuration can be built.
Gilles Peskineba4162a2022-04-11 17:04:38 +020048 """
Gilles Peskineb4063892019-07-27 21:36:44 +020049 return True
50
Gabor Mezei542fd382024-06-10 14:07:42 +020051PSA_UNSUPPORTED_FEATURE = frozenset([
Gabor Mezei3678dee2024-06-04 19:58:43 +020052 'PSA_WANT_ALG_CBC_MAC',
53 'PSA_WANT_ALG_XTS',
54 'PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE',
55 'PSA_WANT_KEY_TYPE_DH_KEY_PAIR_DERIVE'
56])
57
Gabor Mezei542fd382024-06-10 14:07:42 +020058PSA_DEPRECATED_FEATURE = frozenset([
Gabor Mezei3678dee2024-06-04 19:58:43 +020059 'PSA_WANT_KEY_TYPE_ECC_KEY_PAIR',
60 'PSA_WANT_KEY_TYPE_RSA_KEY_PAIR'
61])
62
Gabor Mezei542fd382024-06-10 14:07:42 +020063PSA_UNSTABLE_FEATURE = frozenset([
Gabor Mezei3678dee2024-06-04 19:58:43 +020064 'PSA_WANT_ECC_SECP_K1_224'
65])
66
Gabor Mezei9b0f9e72024-06-26 18:08:17 +020067EXCLUDE_FROM_CRYPTO = PSA_UNSUPPORTED_FEATURE | \
68 PSA_DEPRECATED_FEATURE | \
69 PSA_UNSTABLE_FEATURE
Gabor Mezei542fd382024-06-10 14:07:42 +020070
Gilles Peskinecfffc282020-04-12 13:55:45 +020071# The goal of the full configuration is to have everything that can be tested
72# together. This includes deprecated or insecure options. It excludes:
73# * Options that require additional build dependencies or unusual hardware.
74# * Options that make testing less effective.
Gilles Peskinec9d04332020-04-16 20:50:17 +020075# * Options that are incompatible with other options, or more generally that
76# interact with other parts of the code in such a way that a bulk enabling
77# is not a good way to test them.
Gilles Peskinecfffc282020-04-12 13:55:45 +020078# * Options that remove features.
Gilles Peskinebbaa2b72020-04-12 13:33:57 +020079EXCLUDE_FROM_FULL = frozenset([
Gilles Peskinecfffc282020-04-12 13:55:45 +020080 #pylint: disable=line-too-long
Yanray Wanga8704672023-04-20 17:16:48 +080081 'MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH', # interacts with CTR_DRBG_128_BIT_KEY
Gilles Peskinea8861e02023-09-05 20:20:51 +020082 'MBEDTLS_AES_USE_HARDWARE_ONLY', # hardware dependency
Yanray Wang42be1ba2023-11-23 14:28:47 +080083 'MBEDTLS_BLOCK_CIPHER_NO_DECRYPT', # incompatible with ECB in PSA, CBC/XTS/NIST_KW/DES
Gilles Peskinec9d04332020-04-16 20:50:17 +020084 'MBEDTLS_CTR_DRBG_USE_128_BIT_KEY', # interacts with ENTROPY_FORCE_SHA256
Gilles Peskinecfffc282020-04-12 13:55:45 +020085 'MBEDTLS_DEPRECATED_REMOVED', # conflicts with deprecated options
Gilles Peskine90581ee2020-04-12 14:02:47 +020086 'MBEDTLS_DEPRECATED_WARNING', # conflicts with deprecated options
Gilles Peskinec9d04332020-04-16 20:50:17 +020087 'MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED', # influences the use of ECDH in TLS
Janos Follath5b7c38f2023-08-01 08:51:12 +010088 'MBEDTLS_ECP_WITH_MPI_UINT', # disables the default ECP and is experimental
Gilles Peskinec9d04332020-04-16 20:50:17 +020089 'MBEDTLS_ENTROPY_FORCE_SHA256', # interacts with CTR_DRBG_128_BIT_KEY
Gilles Peskinecfffc282020-04-12 13:55:45 +020090 'MBEDTLS_HAVE_SSE2', # hardware dependency
91 'MBEDTLS_MEMORY_BACKTRACE', # depends on MEMORY_BUFFER_ALLOC_C
92 'MBEDTLS_MEMORY_BUFFER_ALLOC_C', # makes sanitizers (e.g. ASan) less effective
93 'MBEDTLS_MEMORY_DEBUG', # depends on MEMORY_BUFFER_ALLOC_C
Gilles Peskinec9d04332020-04-16 20:50:17 +020094 'MBEDTLS_NO_64BIT_MULTIPLICATION', # influences anything that uses bignum
Gilles Peskinecfffc282020-04-12 13:55:45 +020095 'MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES', # removes a feature
96 'MBEDTLS_NO_PLATFORM_ENTROPY', # removes a feature
Gilles Peskinec9d04332020-04-16 20:50:17 +020097 'MBEDTLS_NO_UDBL_DIVISION', # influences anything that uses bignum
Gilles Peskineefaee9a2023-09-20 20:49:47 +020098 'MBEDTLS_PSA_P256M_DRIVER_ENABLED', # influences SECP256R1 KeyGen/ECDH/ECDSA
Gilles Peskinecfffc282020-04-12 13:55:45 +020099 'MBEDTLS_PLATFORM_NO_STD_FUNCTIONS', # removes a feature
David Horstmann6f8c95b2024-03-14 14:52:45 +0000100 'MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS', # removes a feature
Gilles Peskinef08b3f82020-11-13 17:36:48 +0100101 'MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG', # behavior change + build dependency
Gilles Peskinea22b95a2024-09-19 13:43:57 +0200102 'MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER', # interface and behavior change
Gilles Peskinecfffc282020-04-12 13:55:45 +0200103 'MBEDTLS_PSA_CRYPTO_SPM', # platform dependency (PSA SPM)
Gilles Peskinea08def92023-04-28 21:01:49 +0200104 'MBEDTLS_PSA_INJECT_ENTROPY', # conflicts with platform entropy sources
Gilles Peskinec9d04332020-04-16 20:50:17 +0200105 'MBEDTLS_RSA_NO_CRT', # influences the use of RSA in X.509 and TLS
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000106 'MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY', # interacts with *_USE_A64_CRYPTO_IF_PRESENT
Dave Rodgman9be3cf02023-10-11 14:47:55 +0100107 'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY', # interacts with *_USE_ARMV8_A_CRYPTO_IF_PRESENT
Tom Cosgrove87fbfb52022-03-15 10:51:52 +0000108 'MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY', # interacts with *_USE_A64_CRYPTO_IF_PRESENT
Dave Rodgman7cb635a2023-10-12 16:14:51 +0100109 'MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT', # setting *_USE_ARMV8_A_CRYPTO is sufficient
Manuel Pégourié-Gonnard6240def2020-07-10 09:35:54 +0200110 'MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN', # build dependency (clang+memsan)
Manuel Pégourié-Gonnard73afa372020-08-19 10:27:38 +0200111 'MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND', # build dependency (valgrind headers)
Hanno Beckere1113562019-06-12 13:59:14 +0100112 'MBEDTLS_X509_REMOVE_INFO', # removes a feature
Valerio Setti678e0fb2024-06-14 07:49:05 +0200113 'MBEDTLS_PSA_STATIC_KEY_SLOTS', # only relevant for embedded devices
114 'MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE', # only relevant for embedded devices
Gabor Mezei542fd382024-06-10 14:07:42 +0200115 *PSA_UNSUPPORTED_FEATURE,
116 *PSA_DEPRECATED_FEATURE,
117 *PSA_UNSTABLE_FEATURE
Gilles Peskinebbaa2b72020-04-12 13:33:57 +0200118])
119
Gilles Peskine32e889d2020-04-12 23:43:28 +0200120def is_seamless_alt(name):
Gilles Peskinec34faba2020-04-20 15:44:14 +0200121 """Whether the xxx_ALT symbol should be included in the full configuration.
Gilles Peskine32e889d2020-04-12 23:43:28 +0200122
Gilles Peskinec34faba2020-04-20 15:44:14 +0200123 Include alternative implementations of platform functions, which are
Gilles Peskine32e889d2020-04-12 23:43:28 +0200124 configurable function pointers that default to the built-in function.
125 This way we test that the function pointers exist and build correctly
126 without changing the behavior, and tests can verify that the function
127 pointers are used by modifying those pointers.
128
129 Exclude alternative implementations of library functions since they require
130 an implementation of the relevant functions and an xxx_alt.h header.
131 """
Gilles Peskinea8861e02023-09-05 20:20:51 +0200132 if name in (
133 'MBEDTLS_PLATFORM_GMTIME_R_ALT',
134 'MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT',
135 'MBEDTLS_PLATFORM_MS_TIME_ALT',
136 'MBEDTLS_PLATFORM_ZEROIZE_ALT',
137 ):
Gilles Peskinec34faba2020-04-20 15:44:14 +0200138 # Similar to non-platform xxx_ALT, requires platform_alt.h
139 return False
Gilles Peskine32e889d2020-04-12 23:43:28 +0200140 return name.startswith('MBEDTLS_PLATFORM_')
141
Gilles Peskine53d41ae2019-07-27 23:31:53 +0200142def include_in_full(name):
143 """Rules for symbols in the "full" configuration."""
Gabor Mezei542fd382024-06-10 14:07:42 +0200144 if name in EXCLUDE_FROM_FULL:
Gilles Peskine53d41ae2019-07-27 23:31:53 +0200145 return False
146 if name.endswith('_ALT'):
Gilles Peskine32e889d2020-04-12 23:43:28 +0200147 return is_seamless_alt(name)
Gilles Peskine53d41ae2019-07-27 23:31:53 +0200148 return True
149
Gilles Peskine00b91442024-09-19 20:13:49 +0200150def full_adapter(name, value, active):
Gilles Peskine53d41ae2019-07-27 23:31:53 +0200151 """Config adapter for "full"."""
Gilles Peskinee4c69552024-09-19 19:57:58 +0200152 if not is_boolean_setting(name, value):
Gilles Peskine53d41ae2019-07-27 23:31:53 +0200153 return active
154 return include_in_full(name)
155
Gilles Peskinecfffc282020-04-12 13:55:45 +0200156# The baremetal configuration excludes options that require a library or
157# operating system feature that is typically not present on bare metal
158# systems. Features that are excluded from "full" won't be in "baremetal"
159# either (unless explicitly turned on in baremetal_adapter) so they don't
160# need to be repeated here.
Gilles Peskinebbaa2b72020-04-12 13:33:57 +0200161EXCLUDE_FROM_BAREMETAL = frozenset([
Gilles Peskinecfffc282020-04-12 13:55:45 +0200162 #pylint: disable=line-too-long
Gilles Peskine98f8f952020-04-20 15:38:39 +0200163 'MBEDTLS_ENTROPY_NV_SEED', # requires a filesystem and FS_IO or alternate NV seed hooks
Gilles Peskinecfffc282020-04-12 13:55:45 +0200164 'MBEDTLS_FS_IO', # requires a filesystem
Gilles Peskinecfffc282020-04-12 13:55:45 +0200165 'MBEDTLS_HAVE_TIME', # requires a clock
166 'MBEDTLS_HAVE_TIME_DATE', # requires a clock
167 'MBEDTLS_NET_C', # requires POSIX-like networking
168 'MBEDTLS_PLATFORM_FPRINTF_ALT', # requires FILE* from stdio.h
Gilles Peskine98f8f952020-04-20 15:38:39 +0200169 'MBEDTLS_PLATFORM_NV_SEED_ALT', # requires a filesystem and ENTROPY_NV_SEED
170 'MBEDTLS_PLATFORM_TIME_ALT', # requires a clock and HAVE_TIME
171 'MBEDTLS_PSA_CRYPTO_SE_C', # requires a filesystem and PSA_CRYPTO_STORAGE_C
Gilles Peskinecfffc282020-04-12 13:55:45 +0200172 'MBEDTLS_PSA_CRYPTO_STORAGE_C', # requires a filesystem
173 'MBEDTLS_PSA_ITS_FILE_C', # requires a filesystem
174 'MBEDTLS_THREADING_C', # requires a threading interface
175 'MBEDTLS_THREADING_PTHREAD', # requires pthread
176 'MBEDTLS_TIMING_C', # requires a clock
Dave Rodgman9be3cf02023-10-11 14:47:55 +0100177 'MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT', # requires an OS for runtime-detection
Dave Rodgman5b89c552023-10-10 14:59:02 +0100178 'MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT', # requires an OS for runtime-detection
Dave Rodgmanbe7915a2023-10-11 10:46:38 +0100179 'MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT', # requires an OS for runtime-detection
Gilles Peskinebbaa2b72020-04-12 13:33:57 +0200180])
181
Gilles Peskine53d41ae2019-07-27 23:31:53 +0200182def keep_in_baremetal(name):
183 """Rules for symbols in the "baremetal" configuration."""
Gilles Peskinebbaa2b72020-04-12 13:33:57 +0200184 if name in EXCLUDE_FROM_BAREMETAL:
Gilles Peskine53d41ae2019-07-27 23:31:53 +0200185 return False
186 return True
187
Gilles Peskine00b91442024-09-19 20:13:49 +0200188def baremetal_adapter(name, value, active):
Gilles Peskine53d41ae2019-07-27 23:31:53 +0200189 """Config adapter for "baremetal"."""
Gilles Peskinee4c69552024-09-19 19:57:58 +0200190 if not is_boolean_setting(name, value):
Gilles Peskine53d41ae2019-07-27 23:31:53 +0200191 return active
192 if name == 'MBEDTLS_NO_PLATFORM_ENTROPY':
Gilles Peskinecfffc282020-04-12 13:55:45 +0200193 # No OS-provided entropy source
Gilles Peskine53d41ae2019-07-27 23:31:53 +0200194 return True
195 return include_in_full(name) and keep_in_baremetal(name)
196
Gilles Peskine120f29d2021-09-01 19:51:19 +0200197# This set contains options that are mostly for debugging or test purposes,
198# and therefore should be excluded when doing code size measurements.
199# Options that are their own module (such as MBEDTLS_ERROR_C) are not listed
200# and therefore will be included when doing code size measurements.
201EXCLUDE_FOR_SIZE = frozenset([
202 'MBEDTLS_DEBUG_C', # large code size increase in TLS
203 'MBEDTLS_SELF_TEST', # increases the size of many modules
204 'MBEDTLS_TEST_HOOKS', # only useful with the hosted test framework, increases code size
205])
206
Gilles Peskine00b91442024-09-19 20:13:49 +0200207def baremetal_size_adapter(name, value, active):
Gilles Peskine120f29d2021-09-01 19:51:19 +0200208 if name in EXCLUDE_FOR_SIZE:
209 return False
Gilles Peskine00b91442024-09-19 20:13:49 +0200210 return baremetal_adapter(name, value, active)
Gilles Peskine120f29d2021-09-01 19:51:19 +0200211
Gilles Peskine31987c62020-01-31 14:23:30 +0100212def include_in_crypto(name):
213 """Rules for symbols in a crypto configuration."""
214 if name.startswith('MBEDTLS_X509_') or \
Harry Ramseyc19f8ae2024-10-03 11:18:32 +0100215 name.startswith('MBEDTLS_VERSION_') or \
Gilles Peskine31987c62020-01-31 14:23:30 +0100216 name.startswith('MBEDTLS_SSL_') or \
217 name.startswith('MBEDTLS_KEY_EXCHANGE_'):
218 return False
219 if name in [
Gilles Peskinecfffc282020-04-12 13:55:45 +0200220 'MBEDTLS_DEBUG_C', # part of libmbedtls
221 'MBEDTLS_NET_C', # part of libmbedtls
Nayna Jainc9deb182020-11-16 19:03:12 +0000222 'MBEDTLS_PKCS7_C', # part of libmbedx509
Harry Ramsey08007ed2024-10-22 14:18:17 +0100223 'MBEDTLS_ERROR_C', # part of libmbedx509
224 'MBEDTLS_ERROR_STRERROR_DUMMY', # part of libmbedx509
Gilles Peskine31987c62020-01-31 14:23:30 +0100225 ]:
226 return False
Gabor Mezei542fd382024-06-10 14:07:42 +0200227 if name in EXCLUDE_FROM_CRYPTO:
228 return False
Gilles Peskine31987c62020-01-31 14:23:30 +0100229 return True
230
231def crypto_adapter(adapter):
232 """Modify an adapter to disable non-crypto symbols.
233
Gilles Peskine00b91442024-09-19 20:13:49 +0200234 ``crypto_adapter(adapter)(name, value, active)`` is like
235 ``adapter(name, value, active)``, but unsets all X.509 and TLS symbols.
Gilles Peskine31987c62020-01-31 14:23:30 +0100236 """
Gilles Peskine00b91442024-09-19 20:13:49 +0200237 def continuation(name, value, active):
Gilles Peskine31987c62020-01-31 14:23:30 +0100238 if not include_in_crypto(name):
239 return False
240 if adapter is None:
241 return active
Gilles Peskine00b91442024-09-19 20:13:49 +0200242 return adapter(name, value, active)
Gilles Peskine31987c62020-01-31 14:23:30 +0100243 return continuation
244
Gilles Peskineed5c21d2022-06-27 23:02:09 +0200245DEPRECATED = frozenset([
246 'MBEDTLS_PSA_CRYPTO_SE_C',
Gabor Mezei542fd382024-06-10 14:07:42 +0200247 *PSA_DEPRECATED_FEATURE
Gilles Peskineed5c21d2022-06-27 23:02:09 +0200248])
Gilles Peskine30de2e82020-04-20 21:39:22 +0200249def no_deprecated_adapter(adapter):
Gilles Peskinebe1d6092020-04-12 14:17:16 +0200250 """Modify an adapter to disable deprecated symbols.
251
Gilles Peskine00b91442024-09-19 20:13:49 +0200252 ``no_deprecated_adapter(adapter)(name, value, active)`` is like
253 ``adapter(name, value, active)``, but unsets all deprecated symbols
Gilles Peskinebe1d6092020-04-12 14:17:16 +0200254 and sets ``MBEDTLS_DEPRECATED_REMOVED``.
255 """
Gilles Peskine00b91442024-09-19 20:13:49 +0200256 def continuation(name, value, active):
Gilles Peskinebe1d6092020-04-12 14:17:16 +0200257 if name == 'MBEDTLS_DEPRECATED_REMOVED':
258 return True
Gilles Peskineed5c21d2022-06-27 23:02:09 +0200259 if name in DEPRECATED:
260 return False
Gilles Peskinebe1d6092020-04-12 14:17:16 +0200261 if adapter is None:
262 return active
Gilles Peskine00b91442024-09-19 20:13:49 +0200263 return adapter(name, value, active)
Gilles Peskinebe1d6092020-04-12 14:17:16 +0200264 return continuation
265
Paul Elliottfb81f772023-10-18 17:44:59 +0100266def no_platform_adapter(adapter):
267 """Modify an adapter to disable platform symbols.
268
Gilles Peskine00b91442024-09-19 20:13:49 +0200269 ``no_platform_adapter(adapter)(name, value, active)`` is like
270 ``adapter(name, value, active)``, but unsets all platform symbols other
Paul Elliottfb81f772023-10-18 17:44:59 +0100271 ``than MBEDTLS_PLATFORM_C.
272 """
Gilles Peskine00b91442024-09-19 20:13:49 +0200273 def continuation(name, value, active):
Paul Elliottfb81f772023-10-18 17:44:59 +0100274 # Allow MBEDTLS_PLATFORM_C but remove all other platform symbols.
275 if name.startswith('MBEDTLS_PLATFORM_') and name != 'MBEDTLS_PLATFORM_C':
276 return False
277 if adapter is None:
278 return active
Gilles Peskine00b91442024-09-19 20:13:49 +0200279 return adapter(name, value, active)
Paul Elliottfb81f772023-10-18 17:44:59 +0100280 return continuation
281
Gabor Mezeia12ed6b2024-09-09 17:20:49 +0200282
Gabor Mezei0e9e4cb2024-09-10 16:16:35 +0200283class MbedTLSConfigFile(config_common.ConfigFile):
Gabor Mezei62a9bd02024-06-07 13:44:40 +0200284 """Representation of an MbedTLS configuration file."""
285
Gabor Mezei3678dee2024-06-04 19:58:43 +0200286 _path_in_tree = 'include/mbedtls/mbedtls_config.h'
287 default_path = [_path_in_tree,
288 os.path.join(os.path.dirname(__file__),
289 os.pardir,
290 _path_in_tree),
291 os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))),
292 _path_in_tree)]
293
294 def __init__(self, filename=None):
Gabor Mezei93a6d1f2024-06-26 18:01:09 +0200295 super().__init__(self.default_path, 'Mbed TLS', filename)
Gabor Mezei3678dee2024-06-04 19:58:43 +0200296 self.current_section = 'header'
297
Gabor Mezeia12ed6b2024-09-09 17:20:49 +0200298
Gabor Mezei0e9e4cb2024-09-10 16:16:35 +0200299class CryptoConfigFile(config_common.ConfigFile):
Gabor Mezei4706fe72024-07-08 17:00:55 +0200300 """Representation of a Crypto configuration file."""
Gabor Mezei62a9bd02024-06-07 13:44:40 +0200301
Gabor Mezei3de65862024-07-08 16:14:10 +0200302 # Temporary, while Mbed TLS does not just rely on the TF-PSA-Crypto
303 # build system to build its crypto library. When it does, the
304 # condition can just be removed.
Gabor Mezei776ee902024-09-09 17:00:50 +0200305 _path_in_tree = ('include/psa/crypto_config.h'
306 if not os.path.isdir(os.path.join(os.path.dirname(__file__),
307 os.pardir,
308 'tf-psa-crypto')) else
309 'tf-psa-crypto/include/psa/crypto_config.h')
Gabor Mezei3678dee2024-06-04 19:58:43 +0200310 default_path = [_path_in_tree,
311 os.path.join(os.path.dirname(__file__),
312 os.pardir,
313 _path_in_tree),
314 os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))),
315 _path_in_tree)]
316
317 def __init__(self, filename=None):
Gabor Mezei93a6d1f2024-06-26 18:01:09 +0200318 super().__init__(self.default_path, 'Crypto', filename)
Gabor Mezei3678dee2024-06-04 19:58:43 +0200319
Gabor Mezeia12ed6b2024-09-09 17:20:49 +0200320
Gabor Mezei0e9e4cb2024-09-10 16:16:35 +0200321class MbedTLSConfig(config_common.Config):
Gabor Mezei62a9bd02024-06-07 13:44:40 +0200322 """Representation of the Mbed TLS configuration.
Gabor Mezei3678dee2024-06-04 19:58:43 +0200323
324 See the documentation of the `Config` class for methods to query
325 and modify the configuration.
326 """
Gabor Mezei4706fe72024-07-08 17:00:55 +0200327
Gabor Mezeiee521b62024-06-07 13:50:41 +0200328 def __init__(self, filename=None):
Gabor Mezei3678dee2024-06-04 19:58:43 +0200329 """Read the Mbed TLS configuration file."""
Gabor Mezei4706fe72024-07-08 17:00:55 +0200330
Gabor Mezei3678dee2024-06-04 19:58:43 +0200331 super().__init__()
Gabor Mezeid53080d2024-08-27 14:06:54 +0200332 configfile = MbedTLSConfigFile(filename)
333 self.configfiles.append(configfile)
Gabor Mezei0e9e4cb2024-09-10 16:16:35 +0200334 self.settings.update({name: config_common.Setting(configfile, active, name, value, section)
Gabor Mezei92065ed2024-06-07 13:47:59 +0200335 for (active, name, value, section)
Gabor Mezeid53080d2024-08-27 14:06:54 +0200336 in configfile.parse_file()})
Gabor Mezei3678dee2024-06-04 19:58:43 +0200337
338 def set(self, name, value=None):
Gabor Mezei4706fe72024-07-08 17:00:55 +0200339 """Set name to the given value and make it active."""
340
Gabor Mezei3678dee2024-06-04 19:58:43 +0200341 if name not in self.settings:
Gabor Mezeid53080d2024-08-27 14:06:54 +0200342 self._get_configfile().templates.append((name, '', '#define ' + name + ' '))
Gabor Mezeiee521b62024-06-07 13:50:41 +0200343
Gabor Mezei3678dee2024-06-04 19:58:43 +0200344 super().set(name, value)
Gilles Peskineb4063892019-07-27 21:36:44 +0200345
Gabor Mezeia12ed6b2024-09-09 17:20:49 +0200346
Gabor Mezei0e9e4cb2024-09-10 16:16:35 +0200347class CryptoConfig(config_common.Config):
Gabor Mezei62a9bd02024-06-07 13:44:40 +0200348 """Representation of the PSA crypto configuration.
Gabor Mezei3678dee2024-06-04 19:58:43 +0200349
350 See the documentation of the `Config` class for methods to query
351 and modify the configuration.
352 """
Gabor Mezei4706fe72024-07-08 17:00:55 +0200353
Gabor Mezeiee521b62024-06-07 13:50:41 +0200354 def __init__(self, filename=None):
Gabor Mezei3678dee2024-06-04 19:58:43 +0200355 """Read the PSA crypto configuration file."""
Gabor Mezei4706fe72024-07-08 17:00:55 +0200356
Gabor Mezei3678dee2024-06-04 19:58:43 +0200357 super().__init__()
Gabor Mezeid53080d2024-08-27 14:06:54 +0200358 configfile = CryptoConfigFile(filename)
359 self.configfiles.append(configfile)
Gabor Mezei0e9e4cb2024-09-10 16:16:35 +0200360 self.settings.update({name: config_common.Setting(configfile, active, name, value, section)
Gabor Mezei92065ed2024-06-07 13:47:59 +0200361 for (active, name, value, section)
Gabor Mezeid53080d2024-08-27 14:06:54 +0200362 in configfile.parse_file()})
Gabor Mezei3678dee2024-06-04 19:58:43 +0200363
Gabor Mezeid723b512024-06-07 15:31:52 +0200364 def set(self, name, value='1'):
Gabor Mezei4706fe72024-07-08 17:00:55 +0200365 """Set name to the given value and make it active."""
366
Gabor Mezei542fd382024-06-10 14:07:42 +0200367 if name in PSA_UNSUPPORTED_FEATURE:
Gabor Mezei92065ed2024-06-07 13:47:59 +0200368 raise ValueError(f'Feature is unsupported: \'{name}\'')
Gabor Mezei542fd382024-06-10 14:07:42 +0200369 if name in PSA_UNSTABLE_FEATURE:
Gabor Mezei92065ed2024-06-07 13:47:59 +0200370 raise ValueError(f'Feature is unstable: \'{name}\'')
Gabor Mezei3678dee2024-06-04 19:58:43 +0200371
372 if name not in self.settings:
Gabor Mezeid53080d2024-08-27 14:06:54 +0200373 self._get_configfile().templates.append((name, '', '#define ' + name + ' '))
Gabor Mezeiee521b62024-06-07 13:50:41 +0200374
Gabor Mezei3678dee2024-06-04 19:58:43 +0200375 super().set(name, value)
376
Gabor Mezeia12ed6b2024-09-09 17:20:49 +0200377
Gabor Mezei0e9e4cb2024-09-10 16:16:35 +0200378class CombinedConfig(config_common.Config):
Gabor Mezei62a9bd02024-06-07 13:44:40 +0200379 """Representation of MbedTLS and PSA crypto configuration
380
381 See the documentation of the `Config` class for methods to query
382 and modify the configuration.
383 """
Gabor Mezei3678dee2024-06-04 19:58:43 +0200384
Gabor Mezei3e2a5502024-06-28 17:27:19 +0200385 def __init__(self, *configs):
Gabor Mezeiee521b62024-06-07 13:50:41 +0200386 super().__init__()
Gabor Mezei3e2a5502024-06-28 17:27:19 +0200387 for config in configs:
388 if isinstance(config, MbedTLSConfigFile):
389 self.mbedtls_configfile = config
390 elif isinstance(config, CryptoConfigFile):
391 self.crypto_configfile = config
392 else:
393 raise ValueError(f'Invalid configfile: {config}')
Gabor Mezeid53080d2024-08-27 14:06:54 +0200394 self.configfiles.append(config)
Gabor Mezei3e2a5502024-06-28 17:27:19 +0200395
Gabor Mezei0e9e4cb2024-09-10 16:16:35 +0200396 self.settings.update({name: config_common.Setting(configfile, active, name, value, section)
Gabor Mezeiee521b62024-06-07 13:50:41 +0200397 for configfile in [self.mbedtls_configfile, self.crypto_configfile]
398 for (active, name, value, section) in configfile.parse_file()})
Gabor Mezei3678dee2024-06-04 19:58:43 +0200399
Gabor Mezei5034a1f2024-12-05 19:06:19 +0100400 _crypto_regexp = re.compile(r'^PSA_.*')
Gabor Mezeid53080d2024-08-27 14:06:54 +0200401 def _get_configfile(self, name=None):
Gabor Mezei4706fe72024-07-08 17:00:55 +0200402 """Find a config type for a setting name"""
403
Gabor Mezeiee521b62024-06-07 13:50:41 +0200404 if name in self.settings:
405 return self.settings[name].configfile
406 elif re.match(self._crypto_regexp, name):
407 return self.crypto_configfile
Gabor Mezei3678dee2024-06-04 19:58:43 +0200408 else:
Gabor Mezeiee521b62024-06-07 13:50:41 +0200409 return self.mbedtls_configfile
Gabor Mezei3678dee2024-06-04 19:58:43 +0200410
411 def set(self, name, value=None):
Gabor Mezei4706fe72024-07-08 17:00:55 +0200412 """Set name to the given value and make it active."""
413
Gabor Mezeiee521b62024-06-07 13:50:41 +0200414 configfile = self._get_configfile(name)
Gabor Mezei3678dee2024-06-04 19:58:43 +0200415
Gabor Mezeiee521b62024-06-07 13:50:41 +0200416 if configfile == self.crypto_configfile:
Gabor Mezei542fd382024-06-10 14:07:42 +0200417 if name in PSA_UNSUPPORTED_FEATURE:
Gabor Mezeiee521b62024-06-07 13:50:41 +0200418 raise ValueError(f'Feature is unsupported: \'{name}\'')
Gabor Mezei542fd382024-06-10 14:07:42 +0200419 if name in PSA_UNSTABLE_FEATURE:
Gabor Mezeiee521b62024-06-07 13:50:41 +0200420 raise ValueError(f'Feature is unstable: \'{name}\'')
421
Gabor Mezeid723b512024-06-07 15:31:52 +0200422 # The default value in the crypto config is '1'
Minos Galanakisa4a37372024-09-26 14:41:41 +0100423 if not value and re.match(self._crypto_regexp, name):
Gabor Mezeid723b512024-06-07 15:31:52 +0200424 value = '1'
425
Gabor Mezeic659c1b2024-08-06 17:37:55 +0200426 if name not in self.settings:
Gabor Mezeiee521b62024-06-07 13:50:41 +0200427 configfile.templates.append((name, '', '#define ' + name + ' '))
428
Gabor Mezeid53080d2024-08-27 14:06:54 +0200429 super().set(name, value)
Gabor Mezeiee521b62024-06-07 13:50:41 +0200430
Gabor Mezeidaf807f2024-08-14 11:33:46 +0200431 #pylint: disable=arguments-differ
Gabor Mezei3678dee2024-06-04 19:58:43 +0200432 def write(self, mbedtls_file=None, crypto_file=None):
Gabor Mezei62a9bd02024-06-07 13:44:40 +0200433 """Write the whole configuration to the file it was read from.
434
435 If mbedtls_file or crypto_file is specified, write the specific configuration
436 to the corresponding file instead.
Gabor Mezeif5f13082024-09-18 13:02:16 +0200437
Gabor Mezei317a2a32024-09-18 16:51:27 +0200438 Two file name parameters and not only one as in the super class as we handle
439 two configuration files in this class.
Gabor Mezei62a9bd02024-06-07 13:44:40 +0200440 """
Gabor Mezei4706fe72024-07-08 17:00:55 +0200441
Gabor Mezeiee521b62024-06-07 13:50:41 +0200442 self.mbedtls_configfile.write(self.settings, mbedtls_file)
443 self.crypto_configfile.write(self.settings, crypto_file)
Gabor Mezei3678dee2024-06-04 19:58:43 +0200444
Gabor Mezeiee521b62024-06-07 13:50:41 +0200445 def filename(self, name=None):
Gabor Mezeif5f13082024-09-18 13:02:16 +0200446 """Get the name of the config files.
Gabor Mezei4706fe72024-07-08 17:00:55 +0200447
448 If 'name' is specified return the name of the config file where it is defined.
449 """
450
Gabor Mezeiee521b62024-06-07 13:50:41 +0200451 if not name:
452 return [config.filename for config in [self.mbedtls_configfile, self.crypto_configfile]]
453
454 return self._get_configfile(name).filename
Gilles Peskineb4063892019-07-27 21:36:44 +0200455
Gabor Mezei24d7cc72024-08-06 15:11:24 +0200456
Gabor Mezei0e9e4cb2024-09-10 16:16:35 +0200457class MbedTLSConfigTool(config_common.ConfigTool):
Gabor Mezei24d7cc72024-08-06 15:11:24 +0200458 """Command line mbedtls_config.h and crypto_config.h manipulation tool."""
459
460 def __init__(self):
Gabor Mezeicd326bf2024-09-18 16:53:03 +0200461 super().__init__(MbedTLSConfigFile.default_path)
Gabor Mezei568808a2024-09-18 13:02:42 +0200462 self.config = CombinedConfig(MbedTLSConfigFile(self.args.file),
463 CryptoConfigFile(self.args.cryptofile))
Gabor Mezei24d7cc72024-08-06 15:11:24 +0200464
465 def custom_parser_options(self):
466 """Adds MbedTLS specific options for the parser."""
467
Gabor Mezeia12ed6b2024-09-09 17:20:49 +0200468 self.parser.add_argument(
469 '--cryptofile', '-c',
470 help="""Crypto file to read (and modify if requested). Default: {}."""
471 .format(CryptoConfigFile.default_path))
Gabor Mezei24d7cc72024-08-06 15:11:24 +0200472
Gabor Mezeia12ed6b2024-09-09 17:20:49 +0200473 self.add_adapter(
474 'baremetal', baremetal_adapter,
475 """Like full, but exclude features that require platform features
476 such as file input-output.
477 """)
478 self.add_adapter(
479 'baremetal_size', baremetal_size_adapter,
480 """Like baremetal, but exclude debugging features. Useful for code size measurements.
481 """)
482 self.add_adapter(
483 'full', full_adapter,
484 """Uncomment most features.
485 Exclude alternative implementations and platform support options, as well as
486 some options that are awkward to test.
487 """)
488 self.add_adapter(
489 'full_no_deprecated', no_deprecated_adapter(full_adapter),
490 """Uncomment most non-deprecated features.
491 Like "full", but without deprecated features.
492 """)
493 self.add_adapter(
494 'full_no_platform', no_platform_adapter(full_adapter),
495 """Uncomment most non-platform features. Like "full", but without platform features.
496 """)
497 self.add_adapter(
498 'realfull', realfull_adapter,
499 """Uncomment all boolean #defines.
500 Suitable for generating documentation, but not for building.
501 """)
502 self.add_adapter(
503 'crypto', crypto_adapter(None),
504 """Only include crypto features. Exclude X.509 and TLS.""")
505 self.add_adapter(
506 'crypto_baremetal', crypto_adapter(baremetal_adapter),
507 """Like baremetal, but with only crypto features, excluding X.509 and TLS.""")
508 self.add_adapter(
509 'crypto_full', crypto_adapter(full_adapter),
510 """Like full, but with only crypto features, excluding X.509 and TLS.""")
Gilles Peskineb4063892019-07-27 21:36:44 +0200511
Gilles Peskineb4063892019-07-27 21:36:44 +0200512
Gabor Mezei24d7cc72024-08-06 15:11:24 +0200513if __name__ == '__main__':
514 sys.exit(MbedTLSConfigTool().main())