blob: fe15bc19c87699637e440597bd9f39ecaa2f7468 [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).
11G3. Allow isolation of short-term secrets (for example, TLS sesssion keys).
12G4. 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,
23it's more like each bit of G2-G5 is helped by some speficic 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é-Gonnardec3fd752022-01-17 11:29:18 +010042- it's incompatible with `MBEDTLS_ECP_RESTARTABLE`, and `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER`;
43- 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
47 `MBEDTLS_PSA_CRYPTO_C`, for backards compatibility reasons:
48 - when `MBEDTLS_PSA_CRYPTO_C` is enabled and used, applications need to call
49 `psa_crypto_init()` before TLS/X.509 uses PSA functions
50 - `MBEDTLS_PSA_CRYPTO_C` has a hard depend on `MBEDTLS_ENTROPY_C` but it's
51 currently possible to compilte TLS and X.509 without `MBEDTLS_ENTROPY_C`.
52 Also, we can't just auto-enable `MBEDTLS_ENTROPY_C` as it doesn't build
53 out of the box on all platforms.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +020054
55The downside of this approach is that until we feel ready to make
56`MBDEDTLS_USE_PSA_CRYPTO` non-optional (always enabled), we have to maintain
57two versions of some parts of the code: one using PSA, the other using the
58legacy APIs. However, see next section for strategies that can lower that
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +020059cost. The rest of this section explains the reasons for the
60incompatibilities mentioned above.
61
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +010062In the medium term (writing this in early 2020), we're going to look for ways
63to make `MBEDTLS_USE_PSA_CRYPTO` non-optional (always enabled).
64
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +020065### `MBEDTLS_ECP_RESTARTABLE`
66
67Currently this option controls not only the presence of restartable APIs in
68the crypto library, but also their use in the TLS and X.509 layers. Since PSA
69Crypto does not support restartable operations, there's a clear conflict: the
70TLS and X.509 layers can't both use only PSA APIs and get restartable
71behaviour.
72
73Supporting this in PSA is on our roadmap (it's been requested). But it's way
74below generalizing support for `MBEDTLS_USE_PSA_CRYPTO` for mainstream use
75cases on our priority list. So in the medium term `MBEDTLS_ECP_RESTARTABLE` is
76incompatible with `MBEDTLS_USE_PSA_CRYPTO`.
77
78Note: it is possible to make the options compatible at build time simply by
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +010079deciding that when `USE_PSA_CRYPTO` is enabled, PSA APIs are used except if
80restartable behaviour was requested at run-time (in addition to enabling
81`MBEDTLS_ECP_RESTARTABLE` in the build).
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +020082
83### `MBEDTLS_PSA_CRYPTO_CONFIG`
84
85X509 and TLS code use `MBEDTLS_xxx` macros to decide whether an algorithm is
86supported. This doesn't make `MBEDTLS_USE_PSA_CRYPTO` incompatible with
87`MBEDTLS_PSA_CRYPTO_CONFIG` per se, but it makes it incompatible with most
88useful uses of `MBEDTLS_PSA_CRYPTO_CONFIG`. The point of
89`MBEDTLS_PSA_CRYPTO_CONFIG` is to be able to build a library with support for
90an algorithm through a PSA driver only, without building the software
91implementation of that algorithm. But then the TLS code would consider the
92algorithm unavailable.
93
94This is tracked in https://github.com/ARMmbed/mbedtls/issues/3674 and
95https://github.com/ARMmbed/mbedtls/issues/3677. But now that I look at it with
96fresh eyes, I don't think the approach we were planning to use would actually
97works. This needs more design effort.
98
99This is something we need to support eventually, and several partners want it.
100I don't know what the priority is for `MBEDTLS_USE_PSA_CRYPTO` between
101improving driver support and covering more of the protocol. It seems to me
102that it'll be less work overall to first implement a good architecture for
103`MBEDTLS_USE_PSA_CRYPTO + MBEDTLS_PSA_CRYPTO_CONFIG` and then extend to more
104protocol featues, because implementing that architecture will require changes
105to the existing code and the less code there is at this point the better,
106whereas extending to more procotol features will require the same amount of
107work either way.
108
109### `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER`
110
111When `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER` is enabled, the library is
112built for use with an RPC server that dispatches PSA crypto function calls
113from multiple clients. In such a build, all the `psa_xxx` functions that take
114would normally take a `psa_key_id_t` as argument instead take a structure
115containing both the key id and the client id. And so if e.g. a TLS function
116calls `psa_import_key`, it would have to pass this structure, not just the
117`psa_key_id_t` key id.
118
119A solution is to use `mbedtls_svc_key_id_t` throughout instead of
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100120`psa_key_id_t`, and use similar abstractions to define values.
Manuel Pégourié-Gonnarda6c601c2021-10-27 14:12:44 +0200121
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100122That's what we're implemementing in early 2022, see
123https://github.com/ARMmbed/mbedtls/issues/5259
124
125### Backwars compatibility issues with making it always on
126
1271. Existing applications may not be calling `psa_crypto_init()` before using
128 TLS, X.509 or PK. We can try to work around that by calling (the relevant
129part of) it ourselves under the hood as needed, but that would likely require
130splitting init between the parts that can fail and the parts that can't (see
131https://github.com/ARM-software/psa-crypto-api/pull/536 for that).
1322. It's currently not possible to enable `MBEDTLS_PSA_CRYPTO_C` in
133 configurations that don't have `MBEDTLS_ENTROPY_C`, and we can't just
134auto-enable the latter, as it won't build or work out of the box on all
135platforms. There are two kinds of things we'd need to do if we want to work
136around that:
137 1. Make it possible to enable the parts of PSA Crypto that don't require an
138 RNG (typically, public key operations, symmetric crypto, some key
139management functions (destroy etc)) in configurations that don't have
140`ENTROPY_C`. This requires going through the PSA code base to adjust
141dependencies. Risk: there may be annoying dependencies, some of which may be
142surprising.
143 2. For operations that require an RNG, provide an alternative function
144 accepting an explicit `f_rng` parameter (see #5238), that would be
145available in entropy-less builds. (Then code using those functions still needs
146to have one version using it, for entropy-less builds, and one version using
147the standard function, for driver support in build with entropy.)
148
149See https://github.com/ARMmbed/mbedtls/issues/5156
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200150
151Taking advantage of the existing abstractions layers - or not
152=============================================================
153
154The Crypto library in Mbed TLS currently has 3 abstraction layers that offer
155algorithm-agnostic APIs for a class of algorithms:
156
157- MD for messages digests aka hashes (including HMAC)
158- Cipher for symmetric ciphers (included AEAD)
159- PK for asymmetric (aka public-key) cryptography (excluding key exchange)
160
161Note: key exchange (FFDH, ECDH) is not covered by an abstraction layer.
162
163These abstraction layers typically provide, in addition to the API for crypto
164operations, types and numerical identifiers for algorithms (for
165example `mbedtls_cipher_mode_t` and its values). The
166current strategy is to keep using those identifiers in most of the code, in
167particular in existing structures and public APIs, even when
168`MBEDTLS_USE_PSA_CRYPTO` is enabled. (This is not an issue for G1, G2, G3
169above, and is only potentially relevant for G4.)
170
171The are multiple strategies that can be used regarding the place of those
172layers in the migration to PSA.
173
174Silently call to PSA from the abstraction layer
175-----------------------------------------------
176
177- Provide a new definition (conditionally on `USE_PSA_CRYPTO`) of wrapper
178 functions in the abstraction layer, that calls PSA instead of the legacy
179crypto API.
180- Upside: changes contained to a single place, no need to change TLS or X.509
181 code anywhere.
182- Downside: tricky to implement if the PSA implementation is currently done on
183 top of that layer (dependency loop).
184
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100185This strategy is currently (late 2021) used for ECDSA signature
186verification in the PK layer, and could be extended to all operations in the
187PK layer.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200188
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200189This strategy is not very well suited to the Cipher layer, as the PSA
190implementation is currently done on top of that layer.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200191
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100192This strategy will probably be used for some time for the PK layer, while we
193figure out what the future of that layer is: parts of it (parse/write, ECDSA
194signatures in the format that X.509 & TLS want) are not covered by PSA, so
195they will need to keep existing in some way. Also the PK layer is also a good
196place for dispatching to either PSA or `mbedtls_xxx_restartable` while that
197part is not covered by PSA yet.
198
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200199Replace calls for each operation
200--------------------------------
201
202- For every operation that's done through this layer in TLS or X.509, just
203 replace function call with calls to PSA (conditionally on `USE_PSA_CRYPTO`)
204- Upside: conceptually simple, and if the PSA implementation is currently done
205 on top of that layer, avoids concerns about dependency loops.
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100206- Upside: opens the door to building TLS/X.509 without that layer, saving some
207 code size.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200208- Downside: TLS/X.509 code has to be done for each operation.
209
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100210This strategy is currently (late 2021) used for the MD layer. (Currently only
211a subset of calling places, but will be extended to all of them.)
212
213In the future (early 2022) we're going to use it for the Cipher layer as well.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200214
215Opt-in use of PSA from the abstraction layer
216--------------------------------------------
217
218- Provide a new way to set up a context that causes operations on that context
219 to be done via PSA.
220- Upside: changes mostly contained in one place, TLS/X.509 code only needs to
221 be changed when setting up the context, but not when using it. In
222 particular, no changes to/duplication of existing public APIs that expect a
223 key to be passed as a context of this layer (eg, `mbedtls_pk_context`).
224- Upside: avoids dependency loop when PSA implemented on top of that layer.
225- Downside: when the context is typically set up by the application, requires
226 changes in application code.
227
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200228This strategy is not useful when no context is used, for example with the
229one-shot function `mbedtls_md()`.
230
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200231There are two variants of this strategy: one where using the new setup
232function also allows for key isolation (the key is only held by PSA,
233supporting both G1 and G2 in that area), and one without isolation (the key is
234still stored outsde of PSA most of the time, supporting only G1).
235
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100236This strategy, with support for key isolation, is currently (end of 2021) used for ECDSA
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200237signature generation in the PK layer - see `mbedtls_pk_setup_opaque()`. This
238allows use of PSA-held private ECDSA keys in TLS and X.509 with no change to
239the TLS/X.509 code, but a contained change in the application. If could be
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100240extended to other private key operations in the PK layer, which is the plan as
241of early 2022.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200242
243This strategy, without key isolation, is also currently used in the Cipher
244layer - see `mbedtls_cipher_setup_psa()`. This allows use of PSA for cipher
245operations in TLS with no change to the application code, and a
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100246contained change in TLS code. (It currently only supports a subset of
247ciphers.) However, we'll move to the "Replace calls for each operation"
248strategy (early 2022), in the hope of being able to build without this layer
249in order to save some code size in the future.
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200250
251Note: for private key operations in the PK layer, both the "silent" and the
252"opt-in" strategy can apply, and can complement each other, as one provides
253support for key isolation, but at the (unavoidable) code of change in
254application code, while the other requires no application change to get
255support for drivers, but fails to provide isolation support.
256
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200257Summary
258-------
259
260Stategies currently used with each abstraction layer:
261
262- PK (for G1): silently call PSA
263- PK (for G2): opt-in use of PSA (new key type)
Manuel Pégourié-Gonnardec3fd752022-01-17 11:29:18 +0100264- Cipher (G1):
265 - late 2021: opt-in use of PSA (new setup function)
266 - early 2022: moving to "replace calls at each call site"
Manuel Pégourié-Gonnard09503592021-10-27 14:21:23 +0200267- MD (G1): replace calls at each call site
268
Manuel Pégourié-Gonnardb89fd952021-09-30 11:52:04 +0200269Migrating away from the legacy API
270==================================
271
272This section briefly introduces questions and possible plans towards G4,
273mainly as they relate to choices in previous stages.
274
275The role of the PK/Cipher/MD APIs in user migration
276---------------------------------------------------
277
278We're currently taking advantage of the existing PK and Cipher layers in order
279to reduce the number of places where library code needs to be changed. It's
280only natural to consider using the same strategy (with the PK, MD and Cipher
281layers) for facilitating migration of application code.
282
283Note: a necessary first step for that would be to make sure PSA is no longer
284implemented of top of the concerned layers
285
286### Zero-cost compatibility layer?
287
288The most favourable case is if we can have a zero-cost abstraction (no
289runtime, RAM usage or code size penalty), for example just a bunch of
290`#define`s, essentialy mapping `mbedtls_` APIs to their `psa_` equivalent.
291
292Unfortunately that's unlikely fully work. For example, the MD layer uses the
293same context type for hashes and HMACs, while the PSA API (rightfully) has
294distinct operation types. Similarly, the Cipher layer uses the same context
295type for unauthenticated and AEAD ciphers, which again the PSA API
296distinguishes.
297
298It is unclear how much value, if any, a zero-cost compatibility layer that's
299incomplete (for example, for MD covering only hashes, or for Cipher covering
300only AEAD) or differs significantly from the existing API (for example,
301introducing new context types) would provide to users.
302
303### Low-cost compatibility layers?
304
305Another possibility is to keep most or all of the existing API for the PK, MD
306and Cipher layers, implemented on top of PSA, aiming for the lowest possible
307cost. For example, `mbedtls_md_context_t` would be defined as a (tagged) union
308of `psa_hash_operation_t` and `psa_mac_operation_t`, then `mbedtls_md_setup()`
309would initialize the correct part, and the rest of the functions be simple
310wrappers around PSA functions. This would vastly reduce the complexity of the
311layers compared to the existing (no need to dispatch through function
312pointers, just call the corresponding PSA API).
313
314Since this would still represent a non-zero cost, not only in terms of code
315size, but also in terms of maintainance (testing, etc.) this would probably
316be a temporary solution: for example keep the compatibility layers in 4.0 (and
317make them optional), but remove them in 5.0.
318
319Again, this provides the most value to users if we can manage to keep the
320existing API unchanged. Their might be conflcits between this goal and that of
321reducing the cost, and judgment calls may need to be made.
322
323Note: when it comes to holding public keys in the PK layer, depending on how
324the rest of the code is structured, it may be worth holding the key data in
325memory controlled by the PK layer as opposed to a PSA key slot, moving it to a
326slot only when needed (see current `ecdsa_verify_wrap` when
327`MBEDTLS_USE_PSA_CRYPTO` is defined) For example, when parsing a large
328number, N, of X.509 certificates (for example the list of trusted roots), it
329might be undesirable to use N PSA key slots for their public keys as long as
330the certs are loaded. OTOH, this could also be addressed by merging the "X.509
331parsing on-demand" (#2478), and then the public key data would be held as
332bytes in the X.509 CRT structure, and only moved to a PK context / PSA slot
333when it's actually used.
334
335Note: the PK layer actually consists of two relatively distinct parts: crypto
336operations, which will be covered by PSA, and parsing/writing (exporting)
337from/to various formats, which is currently not fully covered by the PSA
338Crypto API.
339
340### Algorithm identifiers and other identifiers
341
342It should be easy to provide the user with a bunch of `#define`s for algorithm
343identifiers, for example `#define MBEDTLS_MD_SHA256 PSA_ALG_SHA_256`; most of
344those would be in the MD, Cipher and PK compatibility layers mentioned above,
345but there might be some in other modules that may be worth considering, for
346example identifiers for elliptic curves.
347
348### Lower layers
349
350Generally speaking, we would retire all of the low-level, non-generic modules,
351such as AES, SHA-256, RSA, DHM, ECDH, ECP, bignum, etc, without providing
352compatibility APIs for them. People would be encouraged to switch to the PSA
353API. (The compatiblity implementation of the existing PK, MD, Cipher APIs
354would mostly benefit people who already used those generic APis rather than
355the low-level, alg-specific ones.)
356
357### APIs in TLS and X.509
358
359Public APIs in TLS and X.509 may be affected by the migration in at least two
360ways:
361
3621. APIs that rely on a legacy `mbedtls_` crypto type: for example
363 `mbedtls_ssl_conf_own_cert()` to configure a (certificate and the
364associated) private key. Currently the private key is passed as a
365`mbedtls_pk_context` object, which would probably change to a `psa_key_id_t`.
366Since some users would probably still be using the compatibility PK layer, it
367would need a way to easily extract the PSA key ID from the PK context.
368
3692. APIs the accept list of identifiers: for example
370 `mbedtls_ssl_conf_curves()` taking a list of `mbedtls_ecp_group_id`s. This
371could be changed to accept a list of pairs (`psa_ecc_familiy_t`, size) but we
372should probably take this opportunity to move to a identifier independant from
373the underlying crypto implementation and use TLS-specific identifiers instead
374(based on IANA values or custom enums), as is currently done in the new
375`mbedtls_ssl_conf_groups()` API, see #4859).
376
377Testing
378-------
379
380An question that needs careful consideration when we come around to removing
381the low-level crypto APIs and making PK, MD and Cipher optional compatibility
382layers is to be sure to preserve testing quality. A lot of the existing test
383cases use the low level crypto APIs; we would need to either keep using that
384API for tests, or manually migrated test to the PSA Crypto API. Perhaps a
385combination of both, perhaps evolving gradually over time.