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