blob: 7bb8247170e342c9741d0dcc3d3172fd85b18c34 [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
15Currently, some parts of (G1) and (G2) are implemented when
16`MBEDTLS_USE_PSA_CRYPTO` is enabled. For (G2) to take effect, the application
17needs to be changed to use new APIs.
18
19Generally speaking, the numbering above doesn't mean that each goal requires
Manuel Pégourié-Gonnard74979912021-10-27 14:00:08 +020020the preceding ones to be completed, for example G2-G5 could be done in any
21order; however they all either depend on G1 or are just much more convenient
22if G1 is done before (note that this is not a dependency on G1 being complete,
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +010023it's more like each bit of G2-G5 is helped by some specific bit in G1).
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +020024
25So, a solid intermediate goal would be to complete (G1) when
26`MBEDTLS_USA_PSA_CRYPTO` is enabled - that is, all crypto operations in X.509
27and TLS would be done via the PSA Crypto API.
28
29Compile-time options
30====================
31
32We currently have two compile-time options that are relevant to the migration:
33
34- `MBEDTLS_PSA_CRYPTO_C` - enabled by default, controls the presence of the PSA
35 Crypto APIs.
36- `MBEDTLS_USE_PSA_CRYPTO` - disabled by default (enabled in "full" config),
37 controls usage of PSA Crypto APIs to perform operations in X.509 and TLS
38(G1 above), as well as the availability of some new APIs (G2 above).
39
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +020040The reasons why `MBEDTLS_USE_PSA_CRYPTO` is optional and disabled by default
41are:
Manuel Pégourié-Gonnardce6c0872022-02-01 10:34:20 +010042- it's incompatible with `MBEDTLS_ECP_RESTARTABLE`;
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +010043- it does not work well with `MBEDTLS_PSA_CRYPTO_CONFIG` (could compile with
44 both of them, but then `MBEDTLS_PSA_CRYPTO_CONFIG` won't have the desired
45effect)
46- to avoid a hard/default dependency of TLS, X.509 and PK on
Manuel Pégourié-Gonnard80759c42022-02-08 10:33:11 +010047 `MBEDTLS_PSA_CRYPTO_C`, for backward compatibility reasons:
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +020048 - When `MBEDTLS_PSA_CRYPTO_C` is enabled and used, applications need to call
49 `psa_crypto_init()` before TLS/X.509 uses PSA functions. (This prevents us
50from even enabling the option by default.)
Manuel Pégourié-Gonnardce6c0872022-02-01 10:34:20 +010051 - `MBEDTLS_PSA_CRYPTO_C` has a hard depend on `MBEDTLS_ENTROPY_C ||
52 MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` but it's
53 currently possible to compilte TLS and X.509 without any of the options.
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +010054 Also, we can't just auto-enable `MBEDTLS_ENTROPY_C` as it doesn't build
Manuel Pégourié-Gonnardce6c0872022-02-01 10:34:20 +010055 out of the box on all platforms, and even less
56 `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` as it requires a user-provided RNG
57 function.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +020058
59The downside of this approach is that until we feel ready to make
60`MBDEDTLS_USE_PSA_CRYPTO` non-optional (always enabled), we have to maintain
61two versions of some parts of the code: one using PSA, the other using the
62legacy APIs. However, see next section for strategies that can lower that
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +020063cost. The rest of this section explains the reasons for the
64incompatibilities mentioned above.
65
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +020066At the time of writing (early 2022) it is unclear what could be done about the
67backward compatibility issues, and in particular if the cost of implementing
68solutions to these problems would be higher or lower than the cost of
69maintaining dual code paths until the next major version. (Note: these
70solutions would probably also solve other problems at the same time.)
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +010071
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +020072### `MBEDTLS_ECP_RESTARTABLE`
73
74Currently this option controls not only the presence of restartable APIs in
75the crypto library, but also their use in the TLS and X.509 layers. Since PSA
76Crypto does not support restartable operations, there's a clear conflict: the
77TLS and X.509 layers can't both use only PSA APIs and get restartable
78behaviour.
79
80Supporting this in PSA is on our roadmap (it's been requested). But it's way
81below generalizing support for `MBEDTLS_USE_PSA_CRYPTO` for “mainstream” use
82cases on our priority list. So in the medium term `MBEDTLS_ECP_RESTARTABLE` is
83incompatible with `MBEDTLS_USE_PSA_CRYPTO`.
84
85Note: it is possible to make the options compatible at build time simply by
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +010086deciding that when `USE_PSA_CRYPTO` is enabled, PSA APIs are used except if
87restartable behaviour was requested at run-time (in addition to enabling
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +020088`MBEDTLS_ECP_RESTARTABLE` in the build). This would require some work to
89dispatch operations as intended, and test.
90
91Currently (early 2022) the mild consensus seems to be that since we'll need to
92implement restartable in PSA anyway, it's probably not worth spending time on
93the compatibility issue while waiting for it to get a more satisfying
94resolution when PSA starts supporting restartable.
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +020095
96### `MBEDTLS_PSA_CRYPTO_CONFIG`
97
Manuel Pégourié-Gonnardce6c0872022-02-01 10:34:20 +010098(This section taken from a comment by Gilles.)
99
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +0200100X509 and TLS code use `MBEDTLS_xxx` macros to decide whether an algorithm is
101supported. This doesn't make `MBEDTLS_USE_PSA_CRYPTO` incompatible with
102`MBEDTLS_PSA_CRYPTO_CONFIG` per se, but it makes it incompatible with most
103useful uses of `MBEDTLS_PSA_CRYPTO_CONFIG`. The point of
104`MBEDTLS_PSA_CRYPTO_CONFIG` is to be able to build a library with support for
105an algorithm through a PSA driver only, without building the software
106implementation of that algorithm. But then the TLS code would consider the
107algorithm unavailable.
108
Dave Rodgman017a1992022-03-31 14:07:01 +0100109This is tracked in https://github.com/Mbed-TLS/mbedtls/issues/3674 and
110https://github.com/Mbed-TLS/mbedtls/issues/3677. But now that I look at it with
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +0200111fresh eyes, I don't think the approach we were planning to use would actually
112works. This needs more design effort.
113
114This is something we need to support eventually, and several partners want it.
115I don't know what the priority is for `MBEDTLS_USE_PSA_CRYPTO` between
116improving driver support and covering more of the protocol. It seems to me
117that it'll be less work overall to first implement a good architecture for
118`MBEDTLS_USE_PSA_CRYPTO + MBEDTLS_PSA_CRYPTO_CONFIG` and then extend to more
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +0100119protocol features, because implementing that architecture will require changes
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +0200120to the existing code and the less code there is at this point the better,
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +0100121whereas extending to more protocol features will require the same amount of
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +0200122work either way.
123
Manuel Pégourié-Gonnard80759c42022-02-08 10:33:11 +0100124### Backward compatibility issues with making it always on
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100125
1261. Existing applications may not be calling `psa_crypto_init()` before using
127 TLS, X.509 or PK. We can try to work around that by calling (the relevant
128part of) it ourselves under the hood as needed, but that would likely require
129splitting init between the parts that can fail and the parts that can't (see
130https://github.com/ARM-software/psa-crypto-api/pull/536 for that).
1312. It's currently not possible to enable `MBEDTLS_PSA_CRYPTO_C` in
132 configurations that don't have `MBEDTLS_ENTROPY_C`, and we can't just
133auto-enable the latter, as it won't build or work out of the box on all
134platforms. There are two kinds of things we'd need to do if we want to work
135around that:
136 1. Make it possible to enable the parts of PSA Crypto that don't require an
137 RNG (typically, public key operations, symmetric crypto, some key
138management functions (destroy etc)) in configurations that don't have
139`ENTROPY_C`. This requires going through the PSA code base to adjust
140dependencies. Risk: there may be annoying dependencies, some of which may be
141surprising.
142 2. For operations that require an RNG, provide an alternative function
143 accepting an explicit `f_rng` parameter (see #5238), that would be
144available in entropy-less builds. (Then code using those functions still needs
145to have one version using it, for entropy-less builds, and one version using
146the standard function, for driver support in build with entropy.)
147
Dave Rodgman017a1992022-03-31 14:07:01 +0100148See https://github.com/Mbed-TLS/mbedtls/issues/5156
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200149
150Taking advantage of the existing abstractions layers - or not
151=============================================================
152
153The Crypto library in Mbed TLS currently has 3 abstraction layers that offer
154algorithm-agnostic APIs for a class of algorithms:
155
156- MD for messages digests aka hashes (including HMAC)
157- Cipher for symmetric ciphers (included AEAD)
158- PK for asymmetric (aka public-key) cryptography (excluding key exchange)
159
160Note: key exchange (FFDH, ECDH) is not covered by an abstraction layer.
161
162These abstraction layers typically provide, in addition to the API for crypto
163operations, types and numerical identifiers for algorithms (for
164example `mbedtls_cipher_mode_t` and its values). The
165current strategy is to keep using those identifiers in most of the code, in
166particular in existing structures and public APIs, even when
167`MBEDTLS_USE_PSA_CRYPTO` is enabled. (This is not an issue for G1, G2, G3
168above, and is only potentially relevant for G4.)
169
170The are multiple strategies that can be used regarding the place of those
171layers in the migration to PSA.
172
173Silently call to PSA from the abstraction layer
174-----------------------------------------------
175
176- Provide a new definition (conditionally on `USE_PSA_CRYPTO`) of wrapper
177 functions in the abstraction layer, that calls PSA instead of the legacy
178crypto API.
179- Upside: changes contained to a single place, no need to change TLS or X.509
180 code anywhere.
181- Downside: tricky to implement if the PSA implementation is currently done on
182 top of that layer (dependency loop).
183
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200184This strategy is currently (early 2022) used for all operations in the PK
185layer.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200186
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200187This strategy is not very well suited to the Cipher layer, as the PSA
188implementation is currently done on top of that layer.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200189
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100190This strategy will probably be used for some time for the PK layer, while we
191figure out what the future of that layer is: parts of it (parse/write, ECDSA
192signatures in the format that X.509 & TLS want) are not covered by PSA, so
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200193they will need to keep existing in some way. (Also, the PK layer is a good
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100194place for dispatching to either PSA or `mbedtls_xxx_restartable` while that
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200195part is not covered by PSA yet, if we decide to do that.)
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100196
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200197Replace calls for each operation
198--------------------------------
199
200- For every operation that's done through this layer in TLS or X.509, just
201 replace function call with calls to PSA (conditionally on `USE_PSA_CRYPTO`)
202- Upside: conceptually simple, and if the PSA implementation is currently done
203 on top of that layer, avoids concerns about dependency loops.
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100204- Upside: opens the door to building TLS/X.509 without that layer, saving some
205 code size.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200206- Downside: TLS/X.509 code has to be done for each operation.
207
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200208This strategy is currently (early 2022) used for the MD layer and the Cipher
209layer.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200210
211Opt-in use of PSA from the abstraction layer
212--------------------------------------------
213
214- Provide a new way to set up a context that causes operations on that context
215 to be done via PSA.
216- Upside: changes mostly contained in one place, TLS/X.509 code only needs to
217 be changed when setting up the context, but not when using it. In
218 particular, no changes to/duplication of existing public APIs that expect a
219 key to be passed as a context of this layer (eg, `mbedtls_pk_context`).
220- Upside: avoids dependency loop when PSA implemented on top of that layer.
221- Downside: when the context is typically set up by the application, requires
222 changes in application code.
223
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200224This strategy is not useful when no context is used, for example with the
225one-shot function `mbedtls_md()`.
226
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200227There are two variants of this strategy: one where using the new setup
228function also allows for key isolation (the key is only held by PSA,
229supporting both G1 and G2 in that area), and one without isolation (the key is
Manuel Pégourié-Gonnard80759c42022-02-08 10:33:11 +0100230still stored outside of PSA most of the time, supporting only G1).
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200231
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200232This strategy, with support for key isolation, is currently (early 2022) used for
233private-key operations in the PK layer - see `mbedtls_pk_setup_opaque()`. This
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200234allows 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 +0200235the TLS/X.509 code, but a contained change in the application.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200236
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200237This strategy, without key isolation, was also previously used (until 3.1
238included) in the Cipher layer - see `mbedtls_cipher_setup_psa()`. This allowed
239use of PSA for cipher operations in TLS with no change to the application
240code, and a contained change in TLS code. (It only supported a subset of
241ciphers.)
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200242
243Note: for private key operations in the PK layer, both the "silent" and the
244"opt-in" strategy can apply, and can complement each other, as one provides
245support for key isolation, but at the (unavoidable) code of change in
246application code, while the other requires no application change to get
247support for drivers, but fails to provide isolation support.
248
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200249Summary
250-------
251
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200252Strategies currently (early 2022) used with each abstraction layer:
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200253
254- PK (for G1): silently call PSA
255- PK (for G2): opt-in use of PSA (new key type)
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200256- Cipher (G1): replace calls at each call site
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200257- MD (G1): replace calls at each call site
258
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200259Migrating away from the legacy API
260==================================
261
262This section briefly introduces questions and possible plans towards G4,
263mainly as they relate to choices in previous stages.
264
265The role of the PK/Cipher/MD APIs in user migration
266---------------------------------------------------
267
268We're currently taking advantage of the existing PK and Cipher layers in order
269to reduce the number of places where library code needs to be changed. It's
270only natural to consider using the same strategy (with the PK, MD and Cipher
271layers) for facilitating migration of application code.
272
273Note: a necessary first step for that would be to make sure PSA is no longer
274implemented of top of the concerned layers
275
276### Zero-cost compatibility layer?
277
278The most favourable case is if we can have a zero-cost abstraction (no
279runtime, RAM usage or code size penalty), for example just a bunch of
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +0100280`#define`s, essentially mapping `mbedtls_` APIs to their `psa_` equivalent.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200281
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200282Unfortunately that's unlikely to fully work. For example, the MD layer uses the
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200283same context type for hashes and HMACs, while the PSA API (rightfully) has
284distinct operation types. Similarly, the Cipher layer uses the same context
285type for unauthenticated and AEAD ciphers, which again the PSA API
286distinguishes.
287
288It is unclear how much value, if any, a zero-cost compatibility layer that's
289incomplete (for example, for MD covering only hashes, or for Cipher covering
290only AEAD) or differs significantly from the existing API (for example,
291introducing new context types) would provide to users.
292
293### Low-cost compatibility layers?
294
295Another possibility is to keep most or all of the existing API for the PK, MD
296and Cipher layers, implemented on top of PSA, aiming for the lowest possible
297cost. For example, `mbedtls_md_context_t` would be defined as a (tagged) union
298of `psa_hash_operation_t` and `psa_mac_operation_t`, then `mbedtls_md_setup()`
299would initialize the correct part, and the rest of the functions be simple
300wrappers around PSA functions. This would vastly reduce the complexity of the
301layers compared to the existing (no need to dispatch through function
302pointers, just call the corresponding PSA API).
303
304Since this would still represent a non-zero cost, not only in terms of code
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +0100305size, but also in terms of maintenance (testing, etc.) this would probably
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200306be a temporary solution: for example keep the compatibility layers in 4.0 (and
307make them optional), but remove them in 5.0.
308
309Again, this provides the most value to users if we can manage to keep the
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +0100310existing API unchanged. Their might be conflicts between this goal and that of
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200311reducing the cost, and judgment calls may need to be made.
312
313Note: when it comes to holding public keys in the PK layer, depending on how
314the rest of the code is structured, it may be worth holding the key data in
315memory controlled by the PK layer as opposed to a PSA key slot, moving it to a
316slot only when needed (see current `ecdsa_verify_wrap` when
317`MBEDTLS_USE_PSA_CRYPTO` is defined) For example, when parsing a large
318number, N, of X.509 certificates (for example the list of trusted roots), it
319might be undesirable to use N PSA key slots for their public keys as long as
320the certs are loaded. OTOH, this could also be addressed by merging the "X.509
321parsing on-demand" (#2478), and then the public key data would be held as
322bytes in the X.509 CRT structure, and only moved to a PK context / PSA slot
323when it's actually used.
324
325Note: the PK layer actually consists of two relatively distinct parts: crypto
326operations, which will be covered by PSA, and parsing/writing (exporting)
327from/to various formats, which is currently not fully covered by the PSA
328Crypto API.
329
330### Algorithm identifiers and other identifiers
331
332It should be easy to provide the user with a bunch of `#define`s for algorithm
333identifiers, for example `#define MBEDTLS_MD_SHA256 PSA_ALG_SHA_256`; most of
334those would be in the MD, Cipher and PK compatibility layers mentioned above,
335but there might be some in other modules that may be worth considering, for
336example identifiers for elliptic curves.
337
338### Lower layers
339
340Generally speaking, we would retire all of the low-level, non-generic modules,
341such as AES, SHA-256, RSA, DHM, ECDH, ECP, bignum, etc, without providing
342compatibility APIs for them. People would be encouraged to switch to the PSA
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +0100343API. (The compatibility implementation of the existing PK, MD, Cipher APIs
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200344would mostly benefit people who already used those generic APis rather than
345the low-level, alg-specific ones.)
346
347### APIs in TLS and X.509
348
349Public APIs in TLS and X.509 may be affected by the migration in at least two
350ways:
351
3521. APIs that rely on a legacy `mbedtls_` crypto type: for example
353 `mbedtls_ssl_conf_own_cert()` to configure a (certificate and the
354associated) private key. Currently the private key is passed as a
355`mbedtls_pk_context` object, which would probably change to a `psa_key_id_t`.
356Since some users would probably still be using the compatibility PK layer, it
357would need a way to easily extract the PSA key ID from the PK context.
358
3592. APIs the accept list of identifiers: for example
360 `mbedtls_ssl_conf_curves()` taking a list of `mbedtls_ecp_group_id`s. This
bootstrap-prime6dbbf442022-05-17 19:30:44 -0400361could be changed to accept a list of pairs (`psa_ecc_family_t`, size) but we
Manuel Pégourié-Gonnard8ebed212022-02-07 10:23:49 +0100362should probably take this opportunity to move to a identifier independent from
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200363the underlying crypto implementation and use TLS-specific identifiers instead
364(based on IANA values or custom enums), as is currently done in the new
365`mbedtls_ssl_conf_groups()` API, see #4859).
366
367Testing
368-------
369
370An question that needs careful consideration when we come around to removing
371the low-level crypto APIs and making PK, MD and Cipher optional compatibility
372layers is to be sure to preserve testing quality. A lot of the existing test
373cases use the low level crypto APIs; we would need to either keep using that
Manuel Pégourié-Gonnard2a47d232022-04-20 15:01:13 +0200374API for tests, or manually migrate tests to the PSA Crypto API. Perhaps a
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200375combination of both, perhaps evolving gradually over time.