blob: e5b4adc2c3debdc25ad44e2acadffac5d217bd18 [file] [log] [blame] [view]
Manuel Pégourié-Gonnard06adca42024-05-23 09:12:24 +02001This document explains feature guards macros to be used during the transition
2from legacy to PSA in order to determine whether a given cryptographic
3mechanism is available in the current build.
4
5We currently (as of Mbed TLS 3.6) have three sets of feature macros:
6- `PSA_WANT` macros;
7- legacy `MBEDTLS_xxx` macros;
8- transitional `MBEDTLS_xxx` macros that stem from the desire to be able to
9 use crypto mechanisms that are only provided by a driver (G5 in
10`strategy.md`).
11
12This document's goal is to shed some light on when to use which. It is mostly
13intended for maintainers.
14
15Since most transition macros come from driver-only work, it can be useful to
16check `docs/driver-only-builds.md` as well for background. (Note: as
17maintainers, for the best precision about what's supported of not with
18drivers, check the relevant `component_test_psa_crypto_config_accel_xxx`'s
19configuration, as well as the corresponding exclude list in
20`analyze_outcomes.py`.)
21
22General considerations
23======================
24
25This document only applies to Mbed TLS 3.6 TLS. By contrast:
26- in 2.28 we have no driver-only support, so the legacy guards `MBEDTLS_XXX`
27 should be used everywhere;
28- in 4.0 configuration will be purely based on PSA, so `PSA_WANT` macros
29 should be used everywhere.
30
31It is useful to consider the following domains:
32- The PSA domain: things declared in `include/psa/*.h`, implemented in
33 `library/psa_*.c` and tested in `tests/suites/test_suite_psa*`.
34- The pure TLS 1.3 domain: the parts of TLS 1.3 that are not in the `USE_PSA`
35 domain (see below). Those use PSA APIs unconditionally.
36- The `USE_PSA` domain: that's PK, X.509, most of TLS 1.2 and the parts of TLS
37 1.3 that are common with TLS 1.2 or are about public/private keys (see
38`docs/use-psa-crypto.md` for details).
39- The legacy crypto domain: a number of modules there will use crypto from
40 other modules, for example RSA and entropy will use hashes, PEM will use
41hashes and ciphers (from encrypted PEM), etc.
42
43The first two categories (PSA domain, pure TLS 1.3 domain) are simple: as a
44general rule, use `PSA_WANT` macros. (With very few exceptions, see
45`component_check_test_dependencies` in `all.sh`.) When it is necessary to
46check whether a mechanism is built-in or provided by a driver,
47`MBEDTLS_PSA_BUILTIN_xxx` and `MBEDTLS_PSA_ACCEL_xxx` macros should be used
48(but not legacy `MBEDTLS_xxx` macros).
49
50The other two categories (legacy and `USE_PSA` domains) tend to be more
51complex. There are different rules for different families of mechanisms, as
52detailed in the following sections.
53
54However as a general rule, it should always be correct for code in the
55`USE_PSA` domain to use expressions like `(!USE_PSA && MBEDTLS_xxx) ||
56(USE_PSA && PSA_WANT_xxx)`.
57
58Symmetric crypto
59================
60
61Hashes
62------
63
64**Hash vs HMAC:** Historically (since 2.0) we've had the generic hash
65interface, and the implementation of HMAC, in the same file controlled by a
Manuel Pégourié-Gonnard3342e802024-07-23 09:57:57 +020066single feature macro: `MBEDTLS_MD_C`. This has now been split in two:
Manuel Pégourié-Gonnard06adca42024-05-23 09:12:24 +020067- `MBEDTLS_MD_LIGHT` is about the generic hash interface; we could think of it
68 as `MBEDTLS_HASH_C`.
Manuel Pégourié-Gonnard3342e802024-07-23 09:57:57 +020069- `MBEDTLS_MD_C` is about the HMAC implementation; we could think of it as
Manuel Pégourié-Gonnard06adca42024-05-23 09:12:24 +020070 `MBEDTLS_HMAC_C` (auto-enabling `MBEDTLS_HASH_C`).
Manuel Pégourié-Gonnard3342e802024-07-23 09:57:57 +020071
Manuel Pégourié-Gonnard06adca42024-05-23 09:12:24 +020072(In fact, this is not the whole story: `MD_LIGHT` is the _core_ of the generic
73hash interface, excluding functions such as `mbedtls_md_list()` and
74`mbedtls_md_info_from_string()`, `mbedtls_md_file()`, etc. But I think the
75above should still provide a good intuition as first approximation.)
76
77Note that all users of hashes use either the PSA Crypto API or the `md.h` API.
78That is, no user, even in the legacy domain, uses the low-level hash APIs
79(`mbedtls_sha256` etc).
80
81**Helper macros:** in `config_adjust_legacy_crypto.h` we define a family of
82macro `MBEDTLS_MD_CAN_xxx`. These macros are defined (for available hashes) as
83soon as `MBEDTLS_MD_LIGHT` is enabled. This subset of `MD` is automatically
84enabled as soon as something from the legacy domain, or from the `USE_PSA`
Manuel Pégourié-Gonnard3342e802024-07-23 09:57:57 +020085domain, needs a hash. (Note that this includes `ENTROPY_C`, so in practice
Manuel Pégourié-Gonnard06adca42024-05-23 09:12:24 +020086`MD_LIGHT` is enabled in most builds.)
87
88Note that there is a rule, enforced by `config_adjust_psa_superset_legacy.h`,
89that all hashes that are enabled on the legacy side are also enabled on the
90PSA side. So, in practice, when `MD_LIGHT` is enabled, `PSA_WANT_ALG_xxx` and
91`MBEDTLS_MD_CAN_xxx` are equivalent.
92
93**Legacy and `USE_PSA` domains:** for hashes, `MBEDTLS_MD_CAN_xxx` (where
94`xxx` is the legacy name of the hash) can be used everywhere (except in the
95PSA domain which should use `PSA_WANT` as usual). No special include is
96required, `build_info.h` or `common.h` is enough.
97
98**Pure TLS 1.3 domain:** it is not easy to know which uses of hashes fall in
99this domain as opposed to the `USE_PSA` domain which looking at the code.
100Fortunately, `MD_CAN` and `PSA_WANT` macros can be used interchangeably, as
101per the note above.
102
103
104
105HMAC
106----
107
108**Legacy domain:** the code is using the `md.h` API. For this domain,
109availability of HMAC-xxx is determined by `MBEDTLS_MD_C && MBEDTLS_MD_CAN_xxx`
110(see previous subsection about `MD_CAN`). Modules in this domain that may use
111HMAC are PKCS5, PKCS7, HKDF, HMAC-DRBG and ECDSA deterministic.
112
113**`USE_PSA` domain:** code will use either the `md.h` API or the `psa_mac`
114API. It should check for the availability of HMAC-xxx with either:
115```
116((!MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_MD_C) ||
117 (MBEDTLS_USE_PSA_CRYPTO && PSA_WANT_ALG_HMAC)) &&
118MBEDTLS_MD_CAN_xxx
119```
120or
121```
122(!MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_MD_C && MBEDTLS_xxx_C) ||
123(MBEDTLS_USE_PSA_CRYPTO && PSA_WANT_ALG_HMAC && PSA_WANT_ALG_xxx)
124```
125or any equivalent condition (see note at the end of the previous section).
126The only module in this case is TLS, which currently depends on
127`USE_PSA_CRYPTO || MD_C`.
128
129Note: while writing this, it occurs to me that TLS 1.2 does not seem to be
130checking for `PSA_WANT_ALG_HMAC` before enabling CBC ciphersuites when
131`USE_PSA` is enabled, which I think it should. Builds with `USE_PSA` enabled,
132`PSA_WANT_ALG_HMAC` disabled and other requirements for CBC ciphersuites
133enabled, are probably broken (perhaps only at runtime when a CBC ciphersuite
134is negotiated).
135
136**Pure TLS 1.3 domain:** HMAC is used for the Finished message via PSA Crypto
137APIs. So, TLS 1.3 should depend on `PSA_WANT_ALG_HMAC` - doesn't seem to be
138enforced by `check_config.h` at the moment.
139
140Ciphers (AEAD and unauthenticated)
141----------------------------------
142
143**Overview of existing (internal) APIs:** we currently have 4 (families of)
144APIs for ciphers in the library:
145- Low-level API: `mbedtls_aes_xxx` etc. - used by `cipher.c` and some other
146 modules in the legacy domain.
147- Internal abstraction layer `block_cipher` for AES, ARIA and Camellia
148 primitives - used only by `gcm.c` and `ccm.c`, only when `CIPHER_C` is not
149enabled (for compatibility reasons).
150- Cipher: used by some modules in the legacy domain, and by the built-in PSA
151 implementation.
152- PSA: used by the `USE_PSA` domain when `MBEDTLS_USE_PSA_CRYPTO` is enabled.
153
154**Legacy domain:** most code here is using either `cipher.h` or low-level APIs
155like `aes.h`, and should use legacy macros like `MBEDTLS_AES_C` and
Manuel Pégourié-Gonnard3342e802024-07-23 09:57:57 +0200156`MBEDTLS_CIPHER_MODE_CBC`. This includes NIST-KW, CMAC, PKCS5/PKCS12 en/decryption
Manuel Pégourié-Gonnard06adca42024-05-23 09:12:24 +0200157functions, PEM decryption, PK parsing of encrypted keys. The only exceptions
158are `GCM` and `CCM` which use the internal abstraction layer `block_cipher`
159and check for availability of block ciphers using `MBEDTLS_CCM_GCM_CAN_xxx`
160macros defined in `config_adjut_legacy_crypto.h`.
161
162**`USE_PSA` domain:** here we should use conditions like the following in
163order to test for availability of ciphers and associated modes.
164```
165// is AES available?
166(!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_AES_C)) || \
167(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_AES))
168// is CBC available?
169(!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CIPHER_MODE_CBC)) || \
170(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CBC_NO_PADDING))
171// is GCM available?
172(!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_GCM_C)) || \
173(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_GCM))
174```
175Note: TLS is the only user of ciphers in the `USE_PSA` domain, and it defines
176`MBEDTLS_SSL_HAVE_xxx` macros in `config_adjust_legacy_crypto.h` for the
177ciphers and modes it needs to know about.
178
179**Pure TLS 1.3 domain:** none. All from TLS 1.3 are in the `USE_PSA` domain
180(common to TLS 1.2).
181
182Key derivation
183--------------
184
185**Legacy and `USE_PSA` domains:** no users here.
186
187**Pure TLS 1.3 domain:** TLS 1.3 is using HKDF via PSA Crypto APIs. We already
188enforce in `check_config.h` that TLS 1.3 depends on the appropriate `PSA_WANT`
189macros.
190
191Asymmetric crypto
192=================
193
194RSA
195---
196
197**Legacy domain and `USE_PSA` domain:** use `RSA_C` everywhere. (Note: there's
198no user of RSA in the legacy domain, and the only direct user in the `USE_PSA`
199domain is PK - both X.509 and TLS will only RSA via PK.)
200
201**Pure TLS 1.3 domain:** no use of RSA in this domain. All TLS 1.3 uses of RSA
202go through PK, hence are in the `USE_PSA` domain.
203
204FFDH
205----
206
207**Legacy domain and `USE_PSA` domain:** use `DHM_C`. The only user is TLS 1.2
208which is actually in the legacy domain - this is an exception where `USE_PSA`
209has no effect, because PSA doesn't cover the needs of TLS 1.2 here.
210
211**Pure TLS 1.3 domain:** use `PSA_WANT`. The TLS 1.3 code for Diffie-Hellman
212is common to ECDH and FFDH thanks to PSA Crypto APIs being generic enough. The
213parts about FFDH are guarded with `PSA_WANT_ALG_FFDH` (with the reasoning that
214this implies support for the corresponding key type).
215
216ECC
217---
218
219**Curves:** in `config_adjut_psa_superset_legacy.h` we ensure that all
220curves that are supported on the legacy side (`MBEDTLS_ECP_DP_xxx_ENABLED`)
221are also supported on the PSA side (`PSA_WANT_ECC_xxx`).
222
223In `config_adjust_legacy_crypto.h` we define macros `MBEDTLS_ECP_HAVE_xxx`.
224These macros are useful for data and functions that have users in several
225domains, such as `mbedtls_ecc_group_to_psa()`, or that have users only in the
226`USE_PSA` domain but want a simpler (if sub-optimal) condition, such as
227`mbedtls_oid_get_ec_grp()`.
228
229Strictly speaking, code in the `USE_PSA` domain should not use the above
230`MBEDTLS_ECP_HAVE_xxx` macros but conditions like
231```
232(!MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_ECP_DP_xxx_ENABLED) ||
233(MBEDTLS_USE_PSA_CRYPTO && PSA_WANT_ECC_xxx)
234```
235Note while writing: a lot of tests for things in the `USE_PSA` domain appear
236to be using `MBEDTLS_ECP_HAVE_xxx`. IMO this is incorrect, but not caught by
237the CI because I guess we don't run tests in configurations that have both
238`USE_PSA_CRYPTO` disabled, and some curves enabled only on the PSA side. My
239initial feeling is we don't care about such configurations as this point, and
240can leave the dependencies as they are until they're replaced with `PSA_WANT`
241macros in 4.0 anyway.
242
243**Legacy domain:** use the legacy macros `ECP_C`, `ECDH_C`, `ECDSA_C`,
244`ECJPAKE_C`, `MBEDTLS_ECP_DP_xxx_ENABLED`. (This is mostly just ECDH, ECDSA
245and EC J-PAKE using ECP.)
246
247**Key management, `USE_PSA` domain:** `MBEDTLS_PK_HAVE_ECC_KEYS` means that PK
248supports ECC key parsing and writing (and storage). It does not imply support
249for doing crypto operation with such keys - see `MBEDTLS_PK_CAN_ECDSA_xxx`
250above for that.
251
252**ECDH, `USE_PSA` domain:** this is just TLS 1.2. It's using the helper macro
253`MBEDTLS_CAN_ECDH` defined in `config_adjust_legacy_crypto.h` (which should
254probably be called `MBEDTLS_SSL_TLS1_2_CAN_ECDH` as it's only for TLS 1.2).
255(Note: the macro is not used directly in the code, it's only used as a
256dependency for relevant TLS 1.2 key exchanges. Then the code uses the guards
257for the key exchanges.)
258
259**ECDH, pure TLS 1.3 domain:** using `PSA_WANT_ALG_ECDH`.
260
261**ECDSA, `USE_PSA` domain:** should use the macros
262`MBEDTLS_PK_CAN_ECDSA_{SIGN,VERIFY,SOME}` that indicate support for signature
263generation, verification, or at least one of those, respectively. To check for
264support for signatures with a specific hash, combine
265`MBEDTLS_PK_CAN_ECDSA_xxx` with `MBEDTLS_MD_CAN_xxx`.
266
267**ECDSA, pure TLS 1.3 domain:** none - everything goes through PK.
268
269**EC J-PAKE, `USE_PSA` domain:** only used by TLS 1.2. The code is guarded by
270the corresponding `KEY_EXCHANGE` macro, which in `check_config.h` depends on
271the appropriate macros depending on whether `USE_PSA` is on or off.
272
273**EC J-PAKE, pure TLS 1.3 domain:** none - EC J-PAKE is TLS 1.2 (so far).
274
275**Related internal macros:**
276- `MBEDTLS_PK_USE_PSA_EC_DATA` is an internal switch of the PK module. When
277 it's not defined, PK stores ECC keys as a `struct mbedtls_ecxxx_keypair`;
278when it's defined, PK stores in a PSA -friendly format instead (PSA key slot
279for private keys, metadata + array of bytes with the PSA import/export format
280for the public part). This macro is only defined when `ECP_C` is not and
281`USE_PSA` is, see comments above its definition in `pk.h` for details.
282- `MBEDTLS_ECP_LIGHT` enables only a subset of `ecp.c`. This subset is pretty
283 much ad hoc: it's basically everything that doesn't depend on scalar
284multiplication (_the_ complex expensive operation in ECC arithmetic).
285Basically, this subset gives access to curve data (constants), key storage,
286basic parsing and writing. It is auto-enabled in some driver-only
287configurations where the user has disabled `ECP_C` because they have drivers
288for the crypto operations they use, but they've also asked for some things
289that are not supported by drivers yet, such as deterministic key derivation,
290or parsing of compressed keys - on those cases, `ECP_LIGHT` will support this
291needs without bringing back the full `ECP_C`.