quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

strategy.md (25485B)


      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 
      9 G1. Use PSA Crypto drivers when available.
     10 G2. Allow isolation of long-term secrets (for example, private keys).
     11 G3. Allow isolation of short-term secrets (for example, TLS session keys).
     12 G4. Have a clean, unified API for Crypto (retire the legacy API).
     13 G5. Code size: compile out our implementation when a driver is available.
     14 
     15 As of Mbed TLS 3.2, most of (G1) and all of (G2) is 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. For a more detailed account of what's
     18 implemented, see `docs/use-psa-crypto.md`, where new APIs are about (G2), and
     19 internal changes implement (G1).
     20 
     21 As of Mbed TLS 3.6 (early 2024), work towards G5 is well advanced: it is now
     22 possible to have hashes/HMAC, ciphers/AEAD, and ECC provided only by drivers,
     23 with some limitations. See
     24 [`docs/driver-only-builds.md`](../../driver-only-builds.html) for details.
     25 The main gap is RSA in PK, X.509 and TLS; it should be resolved by 4.0 work.
     26 
     27 Generally speaking, the numbering above doesn't mean that each goal requires
     28 the preceding ones to be completed. (As an example, much progress towards G5
     29 was made in 3.x, while G4 will be mostly 4.0 and probably not fully complete
     30 until 5.0.)
     31 
     32 
     33 Compile-time options
     34 ====================
     35 
     36 We currently have a few compile-time options that are relevant to the migration:
     37 
     38 - `MBEDTLS_PSA_CRYPTO_C` - enabled by default, controls the presence of the PSA
     39   Crypto APIs with their implementations. (Builds with only
     40   `MBEDTLS_PSA_CRYPTO_CLIENT`, where PSA crypto APIs are present but
     41   implemented via third-party code, are out of scope of this document.)
     42 - `MBEDTLS_USE_PSA_CRYPTO` - disabled by default (enabled in "full" config),
     43   controls usage of PSA Crypto APIs to perform operations in X.509 and TLS
     44 (G1 above), as well as the availability of some new APIs (G2 above).
     45 - `PSA_CRYPTO_CONFIG` - disabled by default, supports builds with drivers and
     46   without the corresponding software implementation (G5 above).
     47 
     48 The reasons why `MBEDTLS_USE_PSA_CRYPTO` is optional and disabled by default
     49 are:
     50 - it's not fully compatible with `MBEDTLS_ECP_RESTARTABLE`: you can enable
     51   both, but then you won't get the full effect of RESTARTBLE (see the
     52 documentation of this option in `mbedtls_config.h`);
     53 - to avoid a hard/default dependency of TLS, X.509 and PK on
     54   `MBEDTLS_PSA_CRYPTO_C`, for backward compatibility reasons:
     55   - When `MBEDTLS_PSA_CRYPTO_C` is enabled and used, applications need to call
     56     `psa_crypto_init()` before TLS/X.509 uses PSA functions. (This prevents us
     57 from even enabling the option by default.)
     58   - `MBEDTLS_PSA_CRYPTO_C` has a hard dependency on `MBEDTLS_ENTROPY_C ||
     59     MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` but it's
     60     currently possible to compile TLS and X.509 without any of the options.
     61     Also, we can't just auto-enable `MBEDTLS_ENTROPY_C` as it doesn't build
     62     out of the box on all platforms, and even less
     63     `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` as it requires a user-provided RNG
     64     function.
     65 
     66 The downside of this approach is that until we are able to make
     67 `MBDEDTLS_USE_PSA_CRYPTO` non-optional (always enabled), we have to maintain
     68 two versions of some parts of the code: one using PSA, the other using the
     69 legacy APIs. However, see next section for strategies that can lower that
     70 cost. The rest of this section explains the reasons for the
     71 incompatibilities mentioned above.
     72 
     73 At the time of writing (early 2022) it is unclear what could be done about the
     74 backward compatibility issues, and in particular if the cost of implementing
     75 solutions to these problems would be higher or lower than the cost of
     76 maintaining dual code paths until the next major version. (Note: these
     77 solutions would probably also solve other problems at the same time.)
     78 
     79 ### `MBEDTLS_ECP_RESTARTABLE`
     80 
     81 Currently this option controls not only the presence of restartable APIs in
     82 the crypto library, but also their use in the TLS and X.509 layers. Since PSA
     83 Crypto does not support restartable operations, there's a clear conflict: the
     84 TLS and X.509 layers can't both use only PSA APIs and get restartable
     85 behaviour.
     86 
     87 Support for restartable (aka interruptible) ECDSA sign/verify operation was
     88 added to PSA in Mbed TLS 3.4, but support for ECDH is not present yet.
     89 
     90 It will then require follow-up work to make use of the new PSA APIs in
     91 PK/X.509/TLS in all places where we currently allow restartable operations.
     92 
     93 ### Backward compatibility issues with making `MBEDTLS_USE_PSA_CRYPTO` always on
     94 
     95 1. Existing applications may not be calling `psa_crypto_init()` before using
     96    TLS, X.509 or PK. We can try to work around that by calling (the relevant
     97 part of) it ourselves under the hood as needed, but that would likely require
     98 splitting init between the parts that can fail and the parts that can't (see
     99 <https://github.com/ARM-software/psa-crypto-api/pull/536> for that).
    100 2. It's currently not possible to enable `MBEDTLS_PSA_CRYPTO_C` in
    101    configurations that don't have `MBEDTLS_ENTROPY_C`, and we can't just
    102 auto-enable the latter, as it won't build or work out of the box on all
    103 platforms. There are two kinds of things we'd need to do if we want to work
    104 around that:
    105    1. Make it possible to enable the parts of PSA Crypto that don't require an
    106       RNG (typically, public key operations, symmetric crypto, some key
    107 management functions (destroy etc)) in configurations that don't have
    108 `ENTROPY_C`. This requires going through the PSA code base to adjust
    109 dependencies. Risk: there may be annoying dependencies, some of which may be
    110 surprising.
    111    2. For operations that require an RNG, provide an alternative function
    112       accepting an explicit `f_rng` parameter (see #5238), that would be
    113 available in entropy-less builds. (Then code using those functions still needs
    114 to have one version using it, for entropy-less builds, and one version using
    115 the standard function, for driver support in build with entropy.)
    116 
    117 See <https://github.com/Mbed-TLS/mbedtls/issues/5156>.
    118 
    119 Taking advantage of the existing abstractions layers - or not
    120 =============================================================
    121 
    122 The Crypto library in Mbed TLS currently has 3 abstraction layers that offer
    123 algorithm-agnostic APIs for a class of algorithms:
    124 
    125 - MD for messages digests aka hashes (including HMAC)
    126 - Cipher for symmetric ciphers (included AEAD)
    127 - PK for asymmetric (aka public-key) cryptography (excluding key exchange)
    128 
    129 Note: key exchange (FFDH, ECDH) is not covered by an abstraction layer.
    130 
    131 These abstraction layers typically provide, in addition to the API for crypto
    132 operations, types and numerical identifiers for algorithms (for
    133 example `mbedtls_cipher_mode_t` and its values). The
    134 current strategy is to keep using those identifiers in most of the code, in
    135 particular in existing structures and public APIs, even when
    136 `MBEDTLS_USE_PSA_CRYPTO` is enabled. (This is not an issue for G1, G2, G3
    137 above, and is only potentially relevant for G4.)
    138 
    139 The are multiple strategies that can be used regarding the place of those
    140 layers in the migration to PSA.
    141 
    142 Silently call to PSA from the abstraction layer
    143 -----------------------------------------------
    144 
    145 - Provide a new definition (conditionally on `USE_PSA_CRYPTO`) of wrapper
    146   functions in the abstraction layer, that calls PSA instead of the legacy
    147 crypto API.
    148 - Upside: changes contained to a single place, no need to change TLS or X.509
    149   code anywhere.
    150 - Downside: tricky to implement if the PSA implementation is currently done on
    151   top of that layer (dependency loop).
    152 
    153 This strategy is currently (early 2023) used for all operations in the PK
    154 layer; the MD layer uses a variant where it dispatches to PSA if a driver is
    155 available and the driver subsystem has been initialized, regardless of whether
    156 `USE_PSA_CRYPTO` is enabled; see [`md-cipher-dispatch.md`](md-cipher-dispatch.html)
    157 for details.
    158 
    159 This strategy is not very well suited to the Cipher layer, as the PSA
    160 implementation is currently done on top of that layer.
    161 
    162 This strategy will probably be used for some time for the PK layer, while we
    163 figure out what the future of that layer is: parts of it (parse/write, ECDSA
    164 signatures in the format that X.509 & TLS want) are not covered by PSA, so
    165 they will need to keep existing in some way. (Also, the PK layer is a good
    166 place for dispatching to either PSA or `mbedtls_xxx_restartable` while that
    167 part is not covered by PSA yet, if we decide to do that.)
    168 
    169 Replace calls for each operation
    170 --------------------------------
    171 
    172 - For every operation that's done through this layer in TLS or X.509, just
    173   replace function call with calls to PSA (conditionally on `USE_PSA_CRYPTO`)
    174 - Upside: conceptually simple, and if the PSA implementation is currently done
    175   on top of that layer, avoids concerns about dependency loops.
    176 - Upside: opens the door to building TLS/X.509 without that layer, saving some
    177   code size.
    178 - Downside: TLS/X.509 code has to be done for each operation.
    179 
    180 This strategy is currently (early 2023) used for the MD layer and the Cipher
    181 layer in X.509 and TLS. Crypto modules however always call to MD which may
    182 then dispatch to PSA, see [`md-cipher-dispatch.md`](md-cipher-dispatch.html).
    183 
    184 Opt-in use of PSA from the abstraction layer
    185 --------------------------------------------
    186 
    187 - Provide a new way to set up a context that causes operations on that context
    188   to be done via PSA.
    189 - Upside: changes mostly contained in one place, TLS/X.509 code only needs to
    190   be changed when setting up the context, but not when using it. In
    191   particular, no changes to/duplication of existing public APIs that expect a
    192   key to be passed as a context of this layer (eg, `mbedtls_pk_context`).
    193 - Upside: avoids dependency loop when PSA implemented on top of that layer.
    194 - Downside: when the context is typically set up by the application, requires
    195   changes in application code.
    196 
    197 This strategy is not useful when no context is used, for example with the
    198 one-shot function `mbedtls_md()`.
    199 
    200 There are two variants of this strategy: one where using the new setup
    201 function also allows for key isolation (the key is only held by PSA,
    202 supporting both G1 and G2 in that area), and one without isolation (the key is
    203 still stored outside of PSA most of the time, supporting only G1).
    204 
    205 This strategy, with support for key isolation, is currently (early 2022) used for
    206 private-key operations in the PK layer - see `mbedtls_pk_setup_opaque()`. This
    207 allows use of PSA-held private ECDSA keys in TLS and X.509 with no change to
    208 the TLS/X.509 code, but a contained change in the application.
    209 
    210 This strategy, without key isolation, was also previously used (until 3.1
    211 included) in the Cipher layer - see `mbedtls_cipher_setup_psa()`. This allowed
    212 use of PSA for cipher operations in TLS with no change to the application
    213 code, and a contained change in TLS code. (It only supported a subset of
    214 ciphers.)
    215 
    216 Note: for private key operations in the PK layer, both the "silent" and the
    217 "opt-in" strategy can apply, and can complement each other, as one provides
    218 support for key isolation, but at the (unavoidable) code of change in
    219 application code, while the other requires no application change to get
    220 support for drivers, but fails to provide isolation support.
    221 
    222 Summary
    223 -------
    224 
    225 Strategies currently (early 2022) used with each abstraction layer:
    226 
    227 - PK (for G1): silently call PSA
    228 - PK (for G2): opt-in use of PSA (new key type)
    229 - PK (for G5): store keys in PSA-friendly format when `ECP_C` is disabled and
    230   `USE_PSA` is enabled
    231 - Cipher (G1, TLS): replace calls at each call site
    232 - Cipher (G5): create a new internal abstraction layer for (non-DES) block
    233   ciphers that silently calls PSA when a driver is available, see
    234   [`md-cipher-dispatch.md`](md-cipher-dispatch.html).
    235 - MD (G1, X.509 and TLS): replace calls at each call site (depending on
    236   `USE_PSA_CRYPTO`)
    237 - MD (G5): silently call PSA when a driver is available, see
    238   [`md-cipher-dispatch.md`](md-cipher-dispatch.html).
    239 
    240 
    241 Supporting builds with drivers without the software implementation
    242 ==================================================================
    243 
    244 This section presents a plan towards G5: save code size by compiling out our
    245 software implementation when a driver is available.
    246 
    247 Let's expand a bit on the definition of the goal: in such a configuration
    248 (driver used, software implementation and abstraction layer compiled out),
    249 we want:
    250 
    251 a. the library to build in a reasonably-complete configuration,
    252 b. with all tests passing,
    253 c. and no more tests skipped than the same configuration with software
    254    implementation.
    255 
    256 Criterion (c) ensures not only test coverage, but that driver-based builds are
    257 at feature parity with software-based builds.
    258 
    259 We can roughly divide the work needed to get there in the following steps:
    260 
    261 0. Have a working driver interface for the algorithms we want to replace.
    262 1. Have users of these algorithms call to PSA or an abstraction layer than can
    263    dispatch to PSA, but not the low-level legacy API, for all operations.
    264 (This is G1, and for PK, X.509 and TLS this is controlled by
    265 `MBEDTLS_USE_PSA_CRYPTO`.) This needs to be done in the library and tests.
    266 2. Have users of these algorithms not depend on the legacy API for information
    267    management (getting a size for a given algorithm, etc.)
    268 3. Adapt compile-time guards used to query availability of a given algorithm;
    269    this needs to be done in the library (for crypto operations and data) and
    270 tests.
    271 
    272 Note: the first two steps enable use of drivers, but not by themselves removal
    273 of the software implementation.
    274 
    275 Note: the fact that step 1 is not achieved for all of libmbedcrypto (see
    276 below) is the reason why criterion (a) has "a reasonably-complete
    277 configuration", to allow working around internal crypto dependencies when
    278 working on other parts such as X.509 and TLS - for example, a configuration
    279 without RSA PKCS#1 v2.1 still allows reasonable use of X.509 and TLS.
    280 
    281 Note: this is a conceptual division that will sometimes translate to how the
    282 work is divided into PRs, sometimes not. For example, in situations where it's
    283 not possible to achieve good test coverage at the end of step 1 or step 2, it
    284 is preferable to group with the next step(s) in the same PR until good test
    285 coverage can be reached.
    286 
    287 **Status as of end of March 2023 (shortly after 3.4):**
    288 
    289 - Step 0 is achieved for most algorithms, with only a few gaps remaining.
    290 - Step 1 is achieved for most of PK, X.509, and TLS when
    291   `MBEDTLS_USE_PSA_CRYPTO` is enabled with only a few gaps remaining (see
    292   docs/use-psa-crypto.md).
    293 - Step 1 is achieved for the crypto library regarding hashes: everything uses
    294   MD (not low-level hash APIs), which then dispatches to PSA if applicable.
    295 - Step 1 is not achieved for all of the crypto library when it come to
    296   ciphers. For example,`ctr_drbg.c` calls the legacy API `mbedtls_aes`.
    297 - Step 2 is achieved for most of X.509 and TLS (same gaps as step 1) when
    298   `MBEDTLS_USE_PSA_CRYPTO` is enabled.
    299 - Step 3 is done for hashes and top-level ECC modules (ECDSA, ECDH, ECJPAKE).
    300 
    301 **Strategy for step 1:**
    302 
    303 Regarding PK, X.509, and TLS, this is mostly achieved with only a few gaps.
    304 (The strategy was outlined in the previous section.)
    305 
    306 Regarding libmbedcrypto:
    307 - for hashes and ciphers, see [`md-cipher-dispatch.md`](md-cipher-dispatch.html);
    308 - for ECC, we have no internal uses of the top-level algorithms (ECDSA, ECDH,
    309   ECJPAKE), however they all depend on `ECP_C` which in turn depends on
    310 `BIGNUM_C`. So, direct calls from TLS, X.509 and PK to ECP and Bignum will
    311 need to be replaced; see <https://github.com/Mbed-TLS/mbedtls/issues/6839> and
    312 linked issues for a summary of intermediate steps and open points.
    313 
    314 **Strategy for step 2:**
    315 
    316 The most satisfying situation here is when we can just use the PSA Crypto API
    317 for information management as well. However sometimes it may not be
    318 convenient, for example in parts of the code that accept old-style identifiers
    319 (such as `mbedtls_md_type_t`) in their API and can't assume PSA to be
    320 compiled in (such as `rsa.c`).
    321 
    322 When using an existing abstraction layer such as MD, it can provide
    323 information management functions. In other cases, information that was in a
    324 low-level module but logically belongs in a higher-level module can be moved
    325 to that module (for example, TLS identifiers of curves and there conversion
    326 to/from PSA or legacy identifiers belongs in TLS, not `ecp.c`).
    327 
    328 **Strategy for step 3:**
    329 
    330 There are currently two (complementary) ways for crypto-using code to check if a
    331 particular algorithm is supported: using `MBEDTLS_xxx` macros, and using
    332 `PSA_WANT_xxx` macros. For example, PSA-based code that want to use SHA-256
    333 will check for `PSA_WANT_ALG_SHA_256`, while legacy-based code that wants to
    334 use SHA-256 will check for `MBEDTLS_SHA256_C` if using the `mbedtls_sha256`
    335 API, or for `MBEDTLS_MD_C && MBEDTLS_SHA256_C` if using the `mbedtls_md` API.
    336 
    337 Code that obeys `MBEDTLS_USE_PSA_CRYPTO` will want to use one of the two
    338 dependencies above depending on whether `MBEDTLS_USE_PSA_CRYPTO` is defined:
    339 if it is, the code want the algorithm available in PSA, otherwise, it wants it
    340 available via the legacy API(s) is it using (MD and/or low-level).
    341 
    342 As much as possible, we're trying to create for each algorithm a single new
    343 macro that can be used to express dependencies everywhere (except pure PSA
    344 code that should always use `PSA_WANT`). For example, for hashes this is the
    345 `MBEDTLS_MD_CAN_xxx` family. For ECC algorithms, we have similar
    346 `MBEDTLS_PK_CAN_xxx` macros.
    347 
    348 Note that in order to achieve that goal, even for code that obeys
    349 `USE_PSA_CRYPTO`, it is useful to impose that all algorithms that are
    350 available via the legacy APIs are also available via PSA.
    351 
    352 Executing step 3 will mostly consist of using the right dependency macros in
    353 the right places (once the previous steps are done).
    354 
    355 **Note on testing**
    356 
    357 Since supporting driver-only builds is not about adding features, but about
    358 supporting existing features in new types of builds, testing will not involve
    359 adding cases to the test suites, but instead adding new components in `all.sh`
    360 that build and run tests in newly-supported configurations. For example, if
    361 we're making some part of the library work with hashes provided only by
    362 drivers when `MBEDTLS_USE_PSA_CRYPTO` is defined, there should be a place in
    363 `all.sh` that builds and run tests in such a configuration.
    364 
    365 There is however a risk, especially in step 3 where we change how dependencies
    366 are expressed (sometimes in bulk), to get things wrong in a way that would
    367 result in more tests being skipped, which is easy to miss. Care must be
    368 taken to ensure this does not happen. The following criteria can be used:
    369 
    370 1. The sets of tests skipped in the default config and the full config must be
    371   the same before and after the PR that implements step 3. This is tested
    372 manually for each PR that changes dependency declarations by using the script
    373 `outcome-analysis.sh` in the present directory.
    374 2. The set of tests skipped in the driver-only build is the same as in an
    375   equivalent software-based configuration. This is tested automatically by the
    376 CI in the "Results analysis" stage, by running
    377 `tests/scripts/analyze_outcomes.py`. See the
    378 `analyze_driver_vs_reference_xxx` actions in the script and the comments above
    379 their declaration for how to do that locally.
    380 
    381 
    382 Migrating away from the legacy API
    383 ==================================
    384 
    385 This section briefly introduces questions and possible plans towards G4,
    386 mainly as they relate to choices in previous stages.
    387 
    388 The role of the PK/Cipher/MD APIs in user migration
    389 ---------------------------------------------------
    390 
    391 We're currently taking advantage of the existing PK layer in order
    392 to reduce the number of places where library code needs to be changed. It's
    393 only natural to consider using the same strategy (with the PK, MD and Cipher
    394 layers) for facilitating migration of application code.
    395 
    396 Note: a necessary first step for that would be to make sure PSA is no longer
    397 implemented of top of the concerned layers
    398 
    399 ### Zero-cost compatibility layer?
    400 
    401 The most favourable case is if we can have a zero-cost abstraction (no
    402 runtime, RAM usage or code size penalty), for example just a bunch of
    403 `#define`s, essentially mapping `mbedtls_` APIs to their `psa_` equivalent.
    404 
    405 Unfortunately that's unlikely to fully work. For example, the MD layer uses the
    406 same context type for hashes and HMACs, while the PSA API (rightfully) has
    407 distinct operation types. Similarly, the Cipher layer uses the same context
    408 type for unauthenticated and AEAD ciphers, which again the PSA API
    409 distinguishes.
    410 
    411 It is unclear how much value, if any, a zero-cost compatibility layer that's
    412 incomplete (for example, for MD covering only hashes, or for Cipher covering
    413 only AEAD) or differs significantly from the existing API (for example,
    414 introducing new context types) would provide to users.
    415 
    416 ### Low-cost compatibility layers?
    417 
    418 Another possibility is to keep most or all of the existing API for the PK, MD
    419 and Cipher layers, implemented on top of PSA, aiming for the lowest possible
    420 cost. For example, `mbedtls_md_context_t` would be defined as a (tagged) union
    421 of `psa_hash_operation_t` and `psa_mac_operation_t`, then `mbedtls_md_setup()`
    422 would initialize the correct part, and the rest of the functions be simple
    423 wrappers around PSA functions. This would vastly reduce the complexity of the
    424 layers compared to the existing (no need to dispatch through function
    425 pointers, just call the corresponding PSA API).
    426 
    427 Since this would still represent a non-zero cost, not only in terms of code
    428 size, but also in terms of maintenance (testing, etc.) this would probably
    429 be a temporary solution: for example keep the compatibility layers in 4.0 (and
    430 make them optional), but remove them in 5.0.
    431 
    432 Again, this provides the most value to users if we can manage to keep the
    433 existing API unchanged. Their might be conflicts between this goal and that of
    434 reducing the cost, and judgment calls may need to be made.
    435 
    436 Note: when it comes to holding public keys in the PK layer, depending on how
    437 the rest of the code is structured, it may be worth holding the key data in
    438 memory controlled by the PK layer as opposed to a PSA key slot, moving it to a
    439 slot only when needed (see current `ecdsa_verify_wrap` when
    440 `MBEDTLS_USE_PSA_CRYPTO` is defined)  For example, when parsing a large
    441 number, N, of X.509 certificates (for example the list of trusted roots), it
    442 might be undesirable to use N PSA key slots for their public keys as long as
    443 the certs are loaded. OTOH, this could also be addressed by merging the "X.509
    444 parsing on-demand" (#2478), and then the public key data would be held as
    445 bytes in the X.509 CRT structure, and only moved to a PK context / PSA slot
    446 when it's actually used.
    447 
    448 Note: the PK layer actually consists of two relatively distinct parts: crypto
    449 operations, which will be covered by PSA, and parsing/writing (exporting)
    450 from/to various formats, which is currently not fully covered by the PSA
    451 Crypto API.
    452 
    453 ### Algorithm identifiers and other identifiers
    454 
    455 It should be easy to provide the user with a bunch of `#define`s for algorithm
    456 identifiers, for example `#define MBEDTLS_MD_SHA256 PSA_ALG_SHA_256`; most of
    457 those would be in the MD, Cipher and PK compatibility layers mentioned above,
    458 but there might be some in other modules that may be worth considering, for
    459 example identifiers for elliptic curves.
    460 
    461 ### Lower layers
    462 
    463 Generally speaking, we would retire all of the low-level, non-generic modules,
    464 such as AES, SHA-256, RSA, DHM, ECDH, ECP, bignum, etc, without providing
    465 compatibility APIs for them. People would be encouraged to switch to the PSA
    466 API. (The compatibility implementation of the existing PK, MD, Cipher APIs
    467 would mostly benefit people who already used those generic APis rather than
    468 the low-level, alg-specific ones.)
    469 
    470 ### APIs in TLS and X.509
    471 
    472 Public APIs in TLS and X.509 may be affected by the migration in at least two
    473 ways:
    474 
    475 1. APIs that rely on a legacy `mbedtls_` crypto type: for example
    476    `mbedtls_ssl_conf_own_cert()` to configure a (certificate and the
    477 associated) private key. Currently the private key is passed as a
    478 `mbedtls_pk_context` object, which would probably change to a `psa_key_id_t`.
    479 Since some users would probably still be using the compatibility PK layer, it
    480 would need a way to easily extract the PSA key ID from the PK context.
    481 
    482 2. APIs the accept list of identifiers: for example
    483    `mbedtls_ssl_conf_curves()` taking a list of `mbedtls_ecp_group_id`s. This
    484 could be changed to accept a list of pairs (`psa_ecc_family_t`, size) but we
    485 should probably take this opportunity to move to a identifier independent from
    486 the underlying crypto implementation and use TLS-specific identifiers instead
    487 (based on IANA values or custom enums), as is currently done in the new
    488 `mbedtls_ssl_conf_groups()` API, see #4859).
    489 
    490 Testing
    491 -------
    492 
    493 An question that needs careful consideration when we come around to removing
    494 the low-level crypto APIs and making PK, MD and Cipher optional compatibility
    495 layers is to be sure to preserve testing quality. A lot of the existing test
    496 cases use the low level crypto APIs; we would need to either keep using that
    497 API for tests, or manually migrate tests to the PSA Crypto API. Perhaps a
    498 combination of both, perhaps evolving gradually over time.