blob: 7288e600ce8aeb88d1d986ce984e0c161901e7bb [file] [log] [blame] [view]
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +02001This document explains the strategy that was used so far in starting the
2migration to PSA Crypto and mentions future perspectives and open questions.
3
4Goals
5=====
6
7Several benefits are expected from migrating to PSA Crypto:
8
Manuel Pégourié-Gonnard74979912021-10-27 14:00:08 +02009G1. Use PSA Crypto drivers when available.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +020010G2. Allow isolation of long-term secrets (for example, private keys).
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +010011G3. Allow isolation of short-term secrets (for example, TLS session keys).
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +020012G4. Have a clean, unified API for Crypto (retire the legacy API).
Manuel Pégourié-Gonnard74979912021-10-27 14:00:08 +020013G5. Code size: compile out our implementation when a driver is available.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +020014
Manuel Pégourié-Gonnard481846c2022-07-12 09:27:39 +020015As of Mbed TLS 3.2, most of (G1) and all of (G2) is implemented when
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +020016`MBEDTLS_USE_PSA_CRYPTO` is enabled. For (G2) to take effect, the application
Manuel Pégourié-Gonnard481846c2022-07-12 09:27:39 +020017needs to be changed to use new APIs. For a more detailled account of what's
18implemented, see `docs/use-psa-crypto.md`, where new APIs are about (G2), and
19internal changes implement (G1).
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +020020
21Generally speaking, the numbering above doesn't mean that each goal requires
Manuel Pégourié-Gonnard481846c2022-07-12 09:27:39 +020022the preceding ones to be completed.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +020023
24Compile-time options
25====================
26
27We currently have two compile-time options that are relevant to the migration:
28
29- `MBEDTLS_PSA_CRYPTO_C` - enabled by default, controls the presence of the PSA
30 Crypto APIs.
31- `MBEDTLS_USE_PSA_CRYPTO` - disabled by default (enabled in "full" config),
32 controls usage of PSA Crypto APIs to perform operations in X.509 and TLS
33(G1 above), as well as the availability of some new APIs (G2 above).
34
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +020035The reasons why `MBEDTLS_USE_PSA_CRYPTO` is optional and disabled by default
36are:
Manuel Pégourié-Gonnardce6c0872022-02-01 10:34:20 +010037- it's incompatible with `MBEDTLS_ECP_RESTARTABLE`;
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +010038- to avoid a hard/default dependency of TLS, X.509 and PK on
Manuel Pégourié-Gonnard80759c42022-02-08 10:33:11 +010039 `MBEDTLS_PSA_CRYPTO_C`, for backward compatibility reasons:
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +020040 - When `MBEDTLS_PSA_CRYPTO_C` is enabled and used, applications need to call
41 `psa_crypto_init()` before TLS/X.509 uses PSA functions. (This prevents us
42from even enabling the option by default.)
Manuel Pégourié-Gonnardce6c0872022-02-01 10:34:20 +010043 - `MBEDTLS_PSA_CRYPTO_C` has a hard depend on `MBEDTLS_ENTROPY_C ||
44 MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` but it's
45 currently possible to compilte TLS and X.509 without any of the options.
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +010046 Also, we can't just auto-enable `MBEDTLS_ENTROPY_C` as it doesn't build
Manuel Pégourié-Gonnardce6c0872022-02-01 10:34:20 +010047 out of the box on all platforms, and even less
48 `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` as it requires a user-provided RNG
49 function.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +020050
Manuel Pégourié-Gonnard481846c2022-07-12 09:27:39 +020051The downside of this approach is that until we are able to make
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +020052`MBDEDTLS_USE_PSA_CRYPTO` non-optional (always enabled), we have to maintain
53two versions of some parts of the code: one using PSA, the other using the
54legacy APIs. However, see next section for strategies that can lower that
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +020055cost. The rest of this section explains the reasons for the
56incompatibilities mentioned above.
57
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +020058At the time of writing (early 2022) it is unclear what could be done about the
59backward compatibility issues, and in particular if the cost of implementing
60solutions to these problems would be higher or lower than the cost of
61maintaining dual code paths until the next major version. (Note: these
62solutions would probably also solve other problems at the same time.)
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +010063
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +020064### `MBEDTLS_ECP_RESTARTABLE`
65
66Currently this option controls not only the presence of restartable APIs in
67the crypto library, but also their use in the TLS and X.509 layers. Since PSA
68Crypto does not support restartable operations, there's a clear conflict: the
69TLS and X.509 layers can't both use only PSA APIs and get restartable
70behaviour.
71
Manuel Pégourié-Gonnard481846c2022-07-12 09:27:39 +020072Supporting this in PSA is on our roadmap and currently planned for end of
732022, see <https://github.com/orgs/Mbed-TLS/projects/1#column-18883250>.
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +020074
Manuel Pégourié-Gonnard481846c2022-07-12 09:27:39 +020075It will then require follow-up work to make use of the new PSA API in
76PK/X.509/TLS in all places where we currently allow restartable operations.
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +020077
Manuel Pégourié-Gonnard481846c2022-07-12 09:27:39 +020078### Backward compatibility issues with making `MBEDTLS_USE_PSA_CRYPTO` always on
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +010079
801. Existing applications may not be calling `psa_crypto_init()` before using
81 TLS, X.509 or PK. We can try to work around that by calling (the relevant
82part of) it ourselves under the hood as needed, but that would likely require
83splitting init between the parts that can fail and the parts that can't (see
Manuel Pégourié-Gonnard481846c2022-07-12 09:27:39 +020084<https://github.com/ARM-software/psa-crypto-api/pull/536> for that).
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100852. It's currently not possible to enable `MBEDTLS_PSA_CRYPTO_C` in
86 configurations that don't have `MBEDTLS_ENTROPY_C`, and we can't just
87auto-enable the latter, as it won't build or work out of the box on all
88platforms. There are two kinds of things we'd need to do if we want to work
89around that:
90 1. Make it possible to enable the parts of PSA Crypto that don't require an
91 RNG (typically, public key operations, symmetric crypto, some key
92management functions (destroy etc)) in configurations that don't have
93`ENTROPY_C`. This requires going through the PSA code base to adjust
94dependencies. Risk: there may be annoying dependencies, some of which may be
95surprising.
96 2. For operations that require an RNG, provide an alternative function
97 accepting an explicit `f_rng` parameter (see #5238), that would be
98available in entropy-less builds. (Then code using those functions still needs
99to have one version using it, for entropy-less builds, and one version using
100the standard function, for driver support in build with entropy.)
101
Manuel Pégourié-Gonnard481846c2022-07-12 09:27:39 +0200102See <https://github.com/Mbed-TLS/mbedtls/issues/5156>.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200103
104Taking advantage of the existing abstractions layers - or not
105=============================================================
106
107The Crypto library in Mbed TLS currently has 3 abstraction layers that offer
108algorithm-agnostic APIs for a class of algorithms:
109
110- MD for messages digests aka hashes (including HMAC)
111- Cipher for symmetric ciphers (included AEAD)
112- PK for asymmetric (aka public-key) cryptography (excluding key exchange)
113
114Note: key exchange (FFDH, ECDH) is not covered by an abstraction layer.
115
116These abstraction layers typically provide, in addition to the API for crypto
117operations, types and numerical identifiers for algorithms (for
118example `mbedtls_cipher_mode_t` and its values). The
119current strategy is to keep using those identifiers in most of the code, in
120particular in existing structures and public APIs, even when
121`MBEDTLS_USE_PSA_CRYPTO` is enabled. (This is not an issue for G1, G2, G3
122above, and is only potentially relevant for G4.)
123
124The are multiple strategies that can be used regarding the place of those
125layers in the migration to PSA.
126
127Silently call to PSA from the abstraction layer
128-----------------------------------------------
129
130- Provide a new definition (conditionally on `USE_PSA_CRYPTO`) of wrapper
131 functions in the abstraction layer, that calls PSA instead of the legacy
132crypto API.
133- Upside: changes contained to a single place, no need to change TLS or X.509
134 code anywhere.
135- Downside: tricky to implement if the PSA implementation is currently done on
136 top of that layer (dependency loop).
137
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200138This strategy is currently (early 2022) used for all operations in the PK
139layer.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200140
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200141This strategy is not very well suited to the Cipher layer, as the PSA
142implementation is currently done on top of that layer.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200143
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100144This strategy will probably be used for some time for the PK layer, while we
145figure out what the future of that layer is: parts of it (parse/write, ECDSA
146signatures in the format that X.509 & TLS want) are not covered by PSA, so
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200147they will need to keep existing in some way. (Also, the PK layer is a good
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100148place for dispatching to either PSA or `mbedtls_xxx_restartable` while that
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200149part is not covered by PSA yet, if we decide to do that.)
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100150
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200151Replace calls for each operation
152--------------------------------
153
154- For every operation that's done through this layer in TLS or X.509, just
155 replace function call with calls to PSA (conditionally on `USE_PSA_CRYPTO`)
156- Upside: conceptually simple, and if the PSA implementation is currently done
157 on top of that layer, avoids concerns about dependency loops.
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100158- Upside: opens the door to building TLS/X.509 without that layer, saving some
159 code size.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200160- Downside: TLS/X.509 code has to be done for each operation.
161
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200162This strategy is currently (early 2022) used for the MD layer and the Cipher
163layer.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200164
165Opt-in use of PSA from the abstraction layer
166--------------------------------------------
167
168- Provide a new way to set up a context that causes operations on that context
169 to be done via PSA.
170- Upside: changes mostly contained in one place, TLS/X.509 code only needs to
171 be changed when setting up the context, but not when using it. In
172 particular, no changes to/duplication of existing public APIs that expect a
173 key to be passed as a context of this layer (eg, `mbedtls_pk_context`).
174- Upside: avoids dependency loop when PSA implemented on top of that layer.
175- Downside: when the context is typically set up by the application, requires
176 changes in application code.
177
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200178This strategy is not useful when no context is used, for example with the
179one-shot function `mbedtls_md()`.
180
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200181There are two variants of this strategy: one where using the new setup
182function also allows for key isolation (the key is only held by PSA,
183supporting both G1 and G2 in that area), and one without isolation (the key is
Manuel Pégourié-Gonnard80759c42022-02-08 10:33:11 +0100184still stored outside of PSA most of the time, supporting only G1).
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200185
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200186This strategy, with support for key isolation, is currently (early 2022) used for
187private-key operations in the PK layer - see `mbedtls_pk_setup_opaque()`. This
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200188allows use of PSA-held private ECDSA keys in TLS and X.509 with no change to
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200189the TLS/X.509 code, but a contained change in the application.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200190
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200191This strategy, without key isolation, was also previously used (until 3.1
192included) in the Cipher layer - see `mbedtls_cipher_setup_psa()`. This allowed
193use of PSA for cipher operations in TLS with no change to the application
194code, and a contained change in TLS code. (It only supported a subset of
195ciphers.)
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200196
197Note: for private key operations in the PK layer, both the "silent" and the
198"opt-in" strategy can apply, and can complement each other, as one provides
199support for key isolation, but at the (unavoidable) code of change in
200application code, while the other requires no application change to get
201support for drivers, but fails to provide isolation support.
202
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200203Summary
204-------
205
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200206Strategies currently (early 2022) used with each abstraction layer:
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200207
208- PK (for G1): silently call PSA
209- PK (for G2): opt-in use of PSA (new key type)
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200210- Cipher (G1): replace calls at each call site
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200211- MD (G1): replace calls at each call site
212
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200213Migrating away from the legacy API
214==================================
215
216This section briefly introduces questions and possible plans towards G4,
217mainly as they relate to choices in previous stages.
218
219The role of the PK/Cipher/MD APIs in user migration
220---------------------------------------------------
221
Manuel Pégourié-Gonnard481846c2022-07-12 09:27:39 +0200222We're currently taking advantage of the existing PK layer in order
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200223to reduce the number of places where library code needs to be changed. It's
224only natural to consider using the same strategy (with the PK, MD and Cipher
225layers) for facilitating migration of application code.
226
227Note: a necessary first step for that would be to make sure PSA is no longer
228implemented of top of the concerned layers
229
230### Zero-cost compatibility layer?
231
232The most favourable case is if we can have a zero-cost abstraction (no
233runtime, RAM usage or code size penalty), for example just a bunch of
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +0100234`#define`s, essentially mapping `mbedtls_` APIs to their `psa_` equivalent.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200235
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200236Unfortunately that's unlikely to fully work. For example, the MD layer uses the
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200237same context type for hashes and HMACs, while the PSA API (rightfully) has
238distinct operation types. Similarly, the Cipher layer uses the same context
239type for unauthenticated and AEAD ciphers, which again the PSA API
240distinguishes.
241
242It is unclear how much value, if any, a zero-cost compatibility layer that's
243incomplete (for example, for MD covering only hashes, or for Cipher covering
244only AEAD) or differs significantly from the existing API (for example,
245introducing new context types) would provide to users.
246
247### Low-cost compatibility layers?
248
249Another possibility is to keep most or all of the existing API for the PK, MD
250and Cipher layers, implemented on top of PSA, aiming for the lowest possible
251cost. For example, `mbedtls_md_context_t` would be defined as a (tagged) union
252of `psa_hash_operation_t` and `psa_mac_operation_t`, then `mbedtls_md_setup()`
253would initialize the correct part, and the rest of the functions be simple
254wrappers around PSA functions. This would vastly reduce the complexity of the
255layers compared to the existing (no need to dispatch through function
256pointers, just call the corresponding PSA API).
257
258Since this would still represent a non-zero cost, not only in terms of code
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +0100259size, but also in terms of maintenance (testing, etc.) this would probably
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200260be a temporary solution: for example keep the compatibility layers in 4.0 (and
261make them optional), but remove them in 5.0.
262
263Again, this provides the most value to users if we can manage to keep the
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +0100264existing API unchanged. Their might be conflicts between this goal and that of
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200265reducing the cost, and judgment calls may need to be made.
266
267Note: when it comes to holding public keys in the PK layer, depending on how
268the rest of the code is structured, it may be worth holding the key data in
269memory controlled by the PK layer as opposed to a PSA key slot, moving it to a
270slot only when needed (see current `ecdsa_verify_wrap` when
271`MBEDTLS_USE_PSA_CRYPTO` is defined) For example, when parsing a large
272number, N, of X.509 certificates (for example the list of trusted roots), it
273might be undesirable to use N PSA key slots for their public keys as long as
274the certs are loaded. OTOH, this could also be addressed by merging the "X.509
275parsing on-demand" (#2478), and then the public key data would be held as
276bytes in the X.509 CRT structure, and only moved to a PK context / PSA slot
277when it's actually used.
278
279Note: the PK layer actually consists of two relatively distinct parts: crypto
280operations, which will be covered by PSA, and parsing/writing (exporting)
281from/to various formats, which is currently not fully covered by the PSA
282Crypto API.
283
284### Algorithm identifiers and other identifiers
285
286It should be easy to provide the user with a bunch of `#define`s for algorithm
287identifiers, for example `#define MBEDTLS_MD_SHA256 PSA_ALG_SHA_256`; most of
288those would be in the MD, Cipher and PK compatibility layers mentioned above,
289but there might be some in other modules that may be worth considering, for
290example identifiers for elliptic curves.
291
292### Lower layers
293
294Generally speaking, we would retire all of the low-level, non-generic modules,
295such as AES, SHA-256, RSA, DHM, ECDH, ECP, bignum, etc, without providing
296compatibility APIs for them. People would be encouraged to switch to the PSA
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +0100297API. (The compatibility implementation of the existing PK, MD, Cipher APIs
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200298would mostly benefit people who already used those generic APis rather than
299the low-level, alg-specific ones.)
300
301### APIs in TLS and X.509
302
303Public APIs in TLS and X.509 may be affected by the migration in at least two
304ways:
305
3061. APIs that rely on a legacy `mbedtls_` crypto type: for example
307 `mbedtls_ssl_conf_own_cert()` to configure a (certificate and the
308associated) private key. Currently the private key is passed as a
309`mbedtls_pk_context` object, which would probably change to a `psa_key_id_t`.
310Since some users would probably still be using the compatibility PK layer, it
311would need a way to easily extract the PSA key ID from the PK context.
312
3132. APIs the accept list of identifiers: for example
314 `mbedtls_ssl_conf_curves()` taking a list of `mbedtls_ecp_group_id`s. This
bootstrap-prime6dbbf442022-05-17 19:30:44 -0400315could be changed to accept a list of pairs (`psa_ecc_family_t`, size) but we
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +0100316should probably take this opportunity to move to a identifier independent from
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200317the underlying crypto implementation and use TLS-specific identifiers instead
318(based on IANA values or custom enums), as is currently done in the new
319`mbedtls_ssl_conf_groups()` API, see #4859).
320
321Testing
322-------
323
324An question that needs careful consideration when we come around to removing
325the low-level crypto APIs and making PK, MD and Cipher optional compatibility
326layers is to be sure to preserve testing quality. A lot of the existing test
327cases use the low level crypto APIs; we would need to either keep using that
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200328API for tests, or manually migrate tests to the PSA Crypto API. Perhaps a
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200329combination of both, perhaps evolving gradually over time.