From 42a1453d146f6746cf46973f379e92406056a7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 21 May 2024 11:43:06 +0200 Subject: [PATCH 01/13] Update psa-limitations.md and add summary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just reflecting recent/on-going work. Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/psa-limitations.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md index 29d7c53303..ca3b44029b 100644 --- a/docs/architecture/psa-migration/psa-limitations.md +++ b/docs/architecture/psa-migration/psa-limitations.md @@ -11,6 +11,14 @@ is, of course, to actually do the migration work. Limitations relevant for G1 (performing crypto operations) ========================================================== +Executive summary +----------------- + +- Restartable/interruptible ECC operations: in progress (mid-2024). +- Arbitrary parameters for FFDH: will be dropped in 4.0. +- RSA-PSS parameters: already implemented safe though arguably non-compliant + solution in Mbed TLS 3.4, no complaints so far. + Restartable (aka interruptible) ECC operations ---------------------------------------------- @@ -27,20 +35,9 @@ both enabled, some operations that should be restartable are not (ECDH in TLS operations that should use PSA do not (signature generation & verification) as they use the legacy API instead, in order to get restartable behaviour. -Things that are in the API but not implemented yet --------------------------------------------------- - -PSA Crypto has an API for FFDH, but it's not implemented in Mbed TLS yet. -(Regarding FFDH, see the next section as well.) See issue [3261][ffdh] on -github. - -[ffdh]: https://github.com/Mbed-TLS/mbedtls/issues/3261 - Arbitrary parameters for FFDH ----------------------------- -(See also the first paragraph in the previous section.) - Currently, the PSA Crypto API can only perform FFDH with a limited set of well-known parameters (some of them defined in the spec, but implementations are free to extend that set). From 7237563d4bf720263078b68aecb9372cfa3bc2cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 21 May 2024 11:43:20 +0200 Subject: [PATCH 02/13] Update psa-migration/strategy.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just reflecting recent/on-going work. Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/strategy.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md index b985a77faa..4301ed353c 100644 --- a/docs/architecture/psa-migration/strategy.md +++ b/docs/architecture/psa-migration/strategy.md @@ -18,11 +18,15 @@ needs to be changed to use new APIs. For a more detailed account of what's implemented, see `docs/use-psa-crypto.md`, where new APIs are about (G2), and internal changes implement (G1). -As of early 2023, work towards G5 is in progress: Mbed TLS 3.3 and 3.4 saw -some improvements in this area, and more will be coming in future releases. +As of Mbed TLS 3.6 (early 2024, work towards G5 is well advanced: it is now +possible to have hashes/HMAC, ciphers/AEAD, and ECC provided only by drivers, +with some limitations. See `docs/driver-only-builds.md` for details. +The main gap is RSA in PK, X.509 and TLS; it should be resolved by 4.0 work. Generally speaking, the numbering above doesn't mean that each goal requires -the preceding ones to be completed. +the preceding ones to be completed. (As an example, much progress towards G5 +was made in 3.x, while G4 will be mostly 4.0 and probably not fully complete +until 5.0.) Compile-time options @@ -219,7 +223,12 @@ Strategies currently (early 2022) used with each abstraction layer: - PK (for G1): silently call PSA - PK (for G2): opt-in use of PSA (new key type) -- Cipher (G1): replace calls at each call site +- PK (for G5): store keys in PSA-friendly format when `ECP_C` is disabled and + `USE_PSA` is enabled +- Cipher (G1, TLS): replace calls at each call site +- Cipher (G5): create a new internal abstraction layer for (non-DES) block + ciphers that silently calls PSA when a driver is available, see + `md-cipher-dispatch.md`. - MD (G1, X.509 and TLS): replace calls at each call site (depending on `USE_PSA_CRYPTO`) - MD (G5): silently call PSA when a driver is available, see From 06adca465b1270fdaad7a77806ff697eb7a5089f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 23 May 2024 09:12:24 +0200 Subject: [PATCH 03/13] Add transition-guards.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/transition-guards.md | 290 ++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 docs/architecture/psa-migration/transition-guards.md diff --git a/docs/architecture/psa-migration/transition-guards.md b/docs/architecture/psa-migration/transition-guards.md new file mode 100644 index 0000000000..5ed7041671 --- /dev/null +++ b/docs/architecture/psa-migration/transition-guards.md @@ -0,0 +1,290 @@ +This document explains feature guards macros to be used during the transition +from legacy to PSA in order to determine whether a given cryptographic +mechanism is available in the current build. + +We currently (as of Mbed TLS 3.6) have three sets of feature macros: +- `PSA_WANT` macros; +- legacy `MBEDTLS_xxx` macros; +- transitional `MBEDTLS_xxx` macros that stem from the desire to be able to + use crypto mechanisms that are only provided by a driver (G5 in +`strategy.md`). + +This document's goal is to shed some light on when to use which. It is mostly +intended for maintainers. + +Since most transition macros come from driver-only work, it can be useful to +check `docs/driver-only-builds.md` as well for background. (Note: as +maintainers, for the best precision about what's supported of not with +drivers, check the relevant `component_test_psa_crypto_config_accel_xxx`'s +configuration, as well as the corresponding exclude list in +`analyze_outcomes.py`.) + +General considerations +====================== + +This document only applies to Mbed TLS 3.6 TLS. By contrast: +- in 2.28 we have no driver-only support, so the legacy guards `MBEDTLS_XXX` + should be used everywhere; +- in 4.0 configuration will be purely based on PSA, so `PSA_WANT` macros + should be used everywhere. + +It is useful to consider the following domains: +- The PSA domain: things declared in `include/psa/*.h`, implemented in + `library/psa_*.c` and tested in `tests/suites/test_suite_psa*`. +- The pure TLS 1.3 domain: the parts of TLS 1.3 that are not in the `USE_PSA` + domain (see below). Those use PSA APIs unconditionally. +- The `USE_PSA` domain: that's PK, X.509, most of TLS 1.2 and the parts of TLS + 1.3 that are common with TLS 1.2 or are about public/private keys (see +`docs/use-psa-crypto.md` for details). +- The legacy crypto domain: a number of modules there will use crypto from + other modules, for example RSA and entropy will use hashes, PEM will use +hashes and ciphers (from encrypted PEM), etc. + +The first two categories (PSA domain, pure TLS 1.3 domain) are simple: as a +general rule, use `PSA_WANT` macros. (With very few exceptions, see +`component_check_test_dependencies` in `all.sh`.) When it is necessary to +check whether a mechanism is built-in or provided by a driver, +`MBEDTLS_PSA_BUILTIN_xxx` and `MBEDTLS_PSA_ACCEL_xxx` macros should be used +(but not legacy `MBEDTLS_xxx` macros). + +The other two categories (legacy and `USE_PSA` domains) tend to be more +complex. There are different rules for different families of mechanisms, as +detailed in the following sections. + +However as a general rule, it should always be correct for code in the +`USE_PSA` domain to use expressions like `(!USE_PSA && MBEDTLS_xxx) || +(USE_PSA && PSA_WANT_xxx)`. + +Symmetric crypto +================ + +Hashes +------ + +**Hash vs HMAC:** Historically (since 2.0) we've had the generic hash +interface, and the implementation of HMAC, in the same file controlled by a +single feature macro: `MBEDTLS_MD_C`. This has now be split in two: +- `MBEDTLS_MD_LIGHT` is about the generic hash interface; we could think of it + as `MBEDTLS_HASH_C`. +- `MBEDTLS_MC_C` is about the HMAC implementation; we could think of it as + `MBEDTLS_HMAC_C` (auto-enabling `MBEDTLS_HASH_C`). +(In fact, this is not the whole story: `MD_LIGHT` is the _core_ of the generic +hash interface, excluding functions such as `mbedtls_md_list()` and +`mbedtls_md_info_from_string()`, `mbedtls_md_file()`, etc. But I think the +above should still provide a good intuition as first approximation.) + +Note that all users of hashes use either the PSA Crypto API or the `md.h` API. +That is, no user, even in the legacy domain, uses the low-level hash APIs +(`mbedtls_sha256` etc). + +**Helper macros:** in `config_adjust_legacy_crypto.h` we define a family of +macro `MBEDTLS_MD_CAN_xxx`. These macros are defined (for available hashes) as +soon as `MBEDTLS_MD_LIGHT` is enabled. This subset of `MD` is automatically +enabled as soon as something from the legacy domain, or from the `USE_PSA` +domain, needs a hash. (Note that this include `ENTROPY_C`, so in practice +`MD_LIGHT` is enabled in most builds.) + +Note that there is a rule, enforced by `config_adjust_psa_superset_legacy.h`, +that all hashes that are enabled on the legacy side are also enabled on the +PSA side. So, in practice, when `MD_LIGHT` is enabled, `PSA_WANT_ALG_xxx` and +`MBEDTLS_MD_CAN_xxx` are equivalent. + +**Legacy and `USE_PSA` domains:** for hashes, `MBEDTLS_MD_CAN_xxx` (where +`xxx` is the legacy name of the hash) can be used everywhere (except in the +PSA domain which should use `PSA_WANT` as usual). No special include is +required, `build_info.h` or `common.h` is enough. + +**Pure TLS 1.3 domain:** it is not easy to know which uses of hashes fall in +this domain as opposed to the `USE_PSA` domain which looking at the code. +Fortunately, `MD_CAN` and `PSA_WANT` macros can be used interchangeably, as +per the note above. + + + +HMAC +---- + +**Legacy domain:** the code is using the `md.h` API. For this domain, +availability of HMAC-xxx is determined by `MBEDTLS_MD_C && MBEDTLS_MD_CAN_xxx` +(see previous subsection about `MD_CAN`). Modules in this domain that may use +HMAC are PKCS5, PKCS7, HKDF, HMAC-DRBG and ECDSA deterministic. + +**`USE_PSA` domain:** code will use either the `md.h` API or the `psa_mac` +API. It should check for the availability of HMAC-xxx with either: +``` +((!MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_MD_C) || + (MBEDTLS_USE_PSA_CRYPTO && PSA_WANT_ALG_HMAC)) && +MBEDTLS_MD_CAN_xxx +``` +or +``` +(!MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_MD_C && MBEDTLS_xxx_C) || +(MBEDTLS_USE_PSA_CRYPTO && PSA_WANT_ALG_HMAC && PSA_WANT_ALG_xxx) +``` +or any equivalent condition (see note at the end of the previous section). +The only module in this case is TLS, which currently depends on +`USE_PSA_CRYPTO || MD_C`. + +Note: while writing this, it occurs to me that TLS 1.2 does not seem to be +checking for `PSA_WANT_ALG_HMAC` before enabling CBC ciphersuites when +`USE_PSA` is enabled, which I think it should. Builds with `USE_PSA` enabled, +`PSA_WANT_ALG_HMAC` disabled and other requirements for CBC ciphersuites +enabled, are probably broken (perhaps only at runtime when a CBC ciphersuite +is negotiated). + +**Pure TLS 1.3 domain:** HMAC is used for the Finished message via PSA Crypto +APIs. So, TLS 1.3 should depend on `PSA_WANT_ALG_HMAC` - doesn't seem to be +enforced by `check_config.h` at the moment. + +Ciphers (AEAD and unauthenticated) +---------------------------------- + +**Overview of existing (internal) APIs:** we currently have 4 (families of) +APIs for ciphers in the library: +- Low-level API: `mbedtls_aes_xxx` etc. - used by `cipher.c` and some other + modules in the legacy domain. +- Internal abstraction layer `block_cipher` for AES, ARIA and Camellia + primitives - used only by `gcm.c` and `ccm.c`, only when `CIPHER_C` is not +enabled (for compatibility reasons). +- Cipher: used by some modules in the legacy domain, and by the built-in PSA + implementation. +- PSA: used by the `USE_PSA` domain when `MBEDTLS_USE_PSA_CRYPTO` is enabled. + +**Legacy domain:** most code here is using either `cipher.h` or low-level APIs +like `aes.h`, and should use legacy macros like `MBEDTLS_AES_C` and +`MBEDTLS_CIPHER_MOD_CBC`. This includes NIST-KW, CMAC, PKCS5 en/decryption +functions, PEM decryption, PK parsing of encrypted keys. The only exceptions +are `GCM` and `CCM` which use the internal abstraction layer `block_cipher` +and check for availability of block ciphers using `MBEDTLS_CCM_GCM_CAN_xxx` +macros defined in `config_adjut_legacy_crypto.h`. + +**`USE_PSA` domain:** here we should use conditions like the following in +order to test for availability of ciphers and associated modes. +``` +// is AES available? +(!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_AES_C)) || \ +(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_AES)) +// is CBC available? +(!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_CIPHER_MODE_CBC)) || \ +(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_CBC_NO_PADDING)) +// is GCM available? +(!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_GCM_C)) || \ +(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_GCM)) +``` +Note: TLS is the only user of ciphers in the `USE_PSA` domain, and it defines +`MBEDTLS_SSL_HAVE_xxx` macros in `config_adjust_legacy_crypto.h` for the +ciphers and modes it needs to know about. + +**Pure TLS 1.3 domain:** none. All from TLS 1.3 are in the `USE_PSA` domain +(common to TLS 1.2). + +Key derivation +-------------- + +**Legacy and `USE_PSA` domains:** no users here. + +**Pure TLS 1.3 domain:** TLS 1.3 is using HKDF via PSA Crypto APIs. We already +enforce in `check_config.h` that TLS 1.3 depends on the appropriate `PSA_WANT` +macros. + +Asymmetric crypto +================= + +RSA +--- + +**Legacy domain and `USE_PSA` domain:** use `RSA_C` everywhere. (Note: there's +no user of RSA in the legacy domain, and the only direct user in the `USE_PSA` +domain is PK - both X.509 and TLS will only RSA via PK.) + +**Pure TLS 1.3 domain:** no use of RSA in this domain. All TLS 1.3 uses of RSA +go through PK, hence are in the `USE_PSA` domain. + +FFDH +---- + +**Legacy domain and `USE_PSA` domain:** use `DHM_C`. The only user is TLS 1.2 +which is actually in the legacy domain - this is an exception where `USE_PSA` +has no effect, because PSA doesn't cover the needs of TLS 1.2 here. + +**Pure TLS 1.3 domain:** use `PSA_WANT`. The TLS 1.3 code for Diffie-Hellman +is common to ECDH and FFDH thanks to PSA Crypto APIs being generic enough. The +parts about FFDH are guarded with `PSA_WANT_ALG_FFDH` (with the reasoning that +this implies support for the corresponding key type). + +ECC +--- + +**Curves:** in `config_adjut_psa_superset_legacy.h` we ensure that all +curves that are supported on the legacy side (`MBEDTLS_ECP_DP_xxx_ENABLED`) +are also supported on the PSA side (`PSA_WANT_ECC_xxx`). + +In `config_adjust_legacy_crypto.h` we define macros `MBEDTLS_ECP_HAVE_xxx`. +These macros are useful for data and functions that have users in several +domains, such as `mbedtls_ecc_group_to_psa()`, or that have users only in the +`USE_PSA` domain but want a simpler (if sub-optimal) condition, such as +`mbedtls_oid_get_ec_grp()`. + +Strictly speaking, code in the `USE_PSA` domain should not use the above +`MBEDTLS_ECP_HAVE_xxx` macros but conditions like +``` +(!MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_ECP_DP_xxx_ENABLED) || +(MBEDTLS_USE_PSA_CRYPTO && PSA_WANT_ECC_xxx) +``` +Note while writing: a lot of tests for things in the `USE_PSA` domain appear +to be using `MBEDTLS_ECP_HAVE_xxx`. IMO this is incorrect, but not caught by +the CI because I guess we don't run tests in configurations that have both +`USE_PSA_CRYPTO` disabled, and some curves enabled only on the PSA side. My +initial feeling is we don't care about such configurations as this point, and +can leave the dependencies as they are until they're replaced with `PSA_WANT` +macros in 4.0 anyway. + +**Legacy domain:** use the legacy macros `ECP_C`, `ECDH_C`, `ECDSA_C`, +`ECJPAKE_C`, `MBEDTLS_ECP_DP_xxx_ENABLED`. (This is mostly just ECDH, ECDSA +and EC J-PAKE using ECP.) + +**Key management, `USE_PSA` domain:** `MBEDTLS_PK_HAVE_ECC_KEYS` means that PK +supports ECC key parsing and writing (and storage). It does not imply support +for doing crypto operation with such keys - see `MBEDTLS_PK_CAN_ECDSA_xxx` +above for that. + +**ECDH, `USE_PSA` domain:** this is just TLS 1.2. It's using the helper macro +`MBEDTLS_CAN_ECDH` defined in `config_adjust_legacy_crypto.h` (which should +probably be called `MBEDTLS_SSL_TLS1_2_CAN_ECDH` as it's only for TLS 1.2). +(Note: the macro is not used directly in the code, it's only used as a +dependency for relevant TLS 1.2 key exchanges. Then the code uses the guards +for the key exchanges.) + +**ECDH, pure TLS 1.3 domain:** using `PSA_WANT_ALG_ECDH`. + +**ECDSA, `USE_PSA` domain:** should use the macros +`MBEDTLS_PK_CAN_ECDSA_{SIGN,VERIFY,SOME}` that indicate support for signature +generation, verification, or at least one of those, respectively. To check for +support for signatures with a specific hash, combine +`MBEDTLS_PK_CAN_ECDSA_xxx` with `MBEDTLS_MD_CAN_xxx`. + +**ECDSA, pure TLS 1.3 domain:** none - everything goes through PK. + +**EC J-PAKE, `USE_PSA` domain:** only used by TLS 1.2. The code is guarded by +the corresponding `KEY_EXCHANGE` macro, which in `check_config.h` depends on +the appropriate macros depending on whether `USE_PSA` is on or off. + +**EC J-PAKE, pure TLS 1.3 domain:** none - EC J-PAKE is TLS 1.2 (so far). + +**Related internal macros:** +- `MBEDTLS_PK_USE_PSA_EC_DATA` is an internal switch of the PK module. When + it's not defined, PK stores ECC keys as a `struct mbedtls_ecxxx_keypair`; +when it's defined, PK stores in a PSA -friendly format instead (PSA key slot +for private keys, metadata + array of bytes with the PSA import/export format +for the public part). This macro is only defined when `ECP_C` is not and +`USE_PSA` is, see comments above its definition in `pk.h` for details. +- `MBEDTLS_ECP_LIGHT` enables only a subset of `ecp.c`. This subset is pretty + much ad hoc: it's basically everything that doesn't depend on scalar +multiplication (_the_ complex expensive operation in ECC arithmetic). +Basically, this subset gives access to curve data (constants), key storage, +basic parsing and writing. It is auto-enabled in some driver-only +configurations where the user has disabled `ECP_C` because they have drivers +for the crypto operations they use, but they've also asked for some things +that are not supported by drivers yet, such as deterministic key derivation, +or parsing of compressed keys - on those cases, `ECP_LIGHT` will support this +needs without bringing back the full `ECP_C`. From 32bdf19a013a9bd05cfad0e6b5abf01567dbf018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 23 May 2024 09:13:21 +0200 Subject: [PATCH 04/13] Minor updates in doc/comments/debug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- docs/driver-only-builds.md | 2 -- library/ssl_tls12_client.c | 2 +- tests/scripts/components-configuration-crypto.sh | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/driver-only-builds.md b/docs/driver-only-builds.md index 5d950b068d..6bd92623a1 100644 --- a/docs/driver-only-builds.md +++ b/docs/driver-only-builds.md @@ -408,8 +408,6 @@ Note that the relationship between legacy (i.e. `MBEDTLS_xxx_C`) and PSA ### Partial acceleration for CCM/GCM -[This section depends on #8598 so it might be updated while that PR progresses.] - In case legacy CCM/GCM algorithms are enabled, it is still possible to benefit from PSA acceleration of the underlying block cipher by enabling support for ECB mode (`PSA_WANT_ALG_ECB_NO_PADDING` + `MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING`) diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index 9b2da5a39d..75783d08f1 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -1964,7 +1964,7 @@ static int ssl_write_encrypted_pms(mbedtls_ssl_context *ssl, ssl->out_msg + offset + len_bytes, olen, MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes, ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_rsa_pkcs1_encrypt", ret); + MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_encrypt", ret); return ret; } diff --git a/tests/scripts/components-configuration-crypto.sh b/tests/scripts/components-configuration-crypto.sh index da0e180801..fe33d4bc2e 100644 --- a/tests/scripts/components-configuration-crypto.sh +++ b/tests/scripts/components-configuration-crypto.sh @@ -1697,6 +1697,7 @@ config_psa_crypto_accel_rsa () { driver_only=$1 # Start from crypto_full config (no X.509, no TLS) + # Note: PK excluded in analyze_outcomes.py. helper_libtestdriver1_adjust_config "crypto_full" if [ "$driver_only" -eq 1 ]; then From 4837f726d17118b3df3603f33423fc364312f35f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 23 May 2024 09:26:31 +0200 Subject: [PATCH 05/13] Add links and missing ) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/strategy.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md index 4301ed353c..a89fe67ad4 100644 --- a/docs/architecture/psa-migration/strategy.md +++ b/docs/architecture/psa-migration/strategy.md @@ -18,9 +18,10 @@ needs to be changed to use new APIs. For a more detailed account of what's implemented, see `docs/use-psa-crypto.md`, where new APIs are about (G2), and internal changes implement (G1). -As of Mbed TLS 3.6 (early 2024, work towards G5 is well advanced: it is now +As of Mbed TLS 3.6 (early 2024), work towards G5 is well advanced: it is now possible to have hashes/HMAC, ciphers/AEAD, and ECC provided only by drivers, -with some limitations. See `docs/driver-only-builds.md` for details. +with some limitations. See +[`docs/driver-only-builds.md`](../../driver-only-builds.html) for details. The main gap is RSA in PK, X.509 and TLS; it should be resolved by 4.0 work. Generally speaking, the numbering above doesn't mean that each goal requires @@ -150,7 +151,7 @@ crypto API. This strategy is currently (early 2023) used for all operations in the PK layer; the MD layer uses a variant where it dispatches to PSA if a driver is available and the driver subsystem has been initialized, regardless of whether -`USE_PSA_CRYPTO` is enabled; see `md-cipher-dispatch.md` in the same directory +`USE_PSA_CRYPTO` is enabled; see [`md-cipher-dispatch.md`](md-cipher-dispatch.html) for details. This strategy is not very well suited to the Cipher layer, as the PSA @@ -176,7 +177,7 @@ Replace calls for each operation This strategy is currently (early 2023) used for the MD layer and the Cipher layer in X.509 and TLS. Crypto modules however always call to MD which may -then dispatch to PSA, see `md-cipher-dispatch.md`. +then dispatch to PSA, see [`md-cipher-dispatch.md`](md-cipher-dispatch.html). Opt-in use of PSA from the abstraction layer -------------------------------------------- @@ -228,11 +229,11 @@ Strategies currently (early 2022) used with each abstraction layer: - Cipher (G1, TLS): replace calls at each call site - Cipher (G5): create a new internal abstraction layer for (non-DES) block ciphers that silently calls PSA when a driver is available, see - `md-cipher-dispatch.md`. + [`md-cipher-dispatch.md`](md-cipher-dispatch.html). - MD (G1, X.509 and TLS): replace calls at each call site (depending on `USE_PSA_CRYPTO`) - MD (G5): silently call PSA when a driver is available, see - `md-cipher-dispatch.md`. + [`md-cipher-dispatch.md`](md-cipher-dispatch.html). Supporting builds with drivers without the software implementation @@ -301,7 +302,7 @@ Regarding PK, X.509, and TLS, this is mostly achieved with only a few gaps. (The strategy was outlined in the previous section.) Regarding libmbedcrypto: -- for hashes and ciphers, see `md-cipher-dispatch.md` in the same directory; +- for hashes and ciphers, see [`md-cipher-dispatch.md`](md-cipher-dispatch.html); - for ECC, we have no internal uses of the top-level algorithms (ECDSA, ECDH, ECJPAKE), however they all depend on `ECP_C` which in turn depends on `BIGNUM_C`. So, direct calls from TLS, X.509 and PK to ECP and Bignum will From 3342e800104af3fe3eee2c11e1199c673fd897bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 23 Jul 2024 09:57:57 +0200 Subject: [PATCH 06/13] Fix some typos & markdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gilles Peskine Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/transition-guards.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/architecture/psa-migration/transition-guards.md b/docs/architecture/psa-migration/transition-guards.md index 5ed7041671..e5b4adc2c3 100644 --- a/docs/architecture/psa-migration/transition-guards.md +++ b/docs/architecture/psa-migration/transition-guards.md @@ -63,11 +63,12 @@ Hashes **Hash vs HMAC:** Historically (since 2.0) we've had the generic hash interface, and the implementation of HMAC, in the same file controlled by a -single feature macro: `MBEDTLS_MD_C`. This has now be split in two: +single feature macro: `MBEDTLS_MD_C`. This has now been split in two: - `MBEDTLS_MD_LIGHT` is about the generic hash interface; we could think of it as `MBEDTLS_HASH_C`. -- `MBEDTLS_MC_C` is about the HMAC implementation; we could think of it as +- `MBEDTLS_MD_C` is about the HMAC implementation; we could think of it as `MBEDTLS_HMAC_C` (auto-enabling `MBEDTLS_HASH_C`). + (In fact, this is not the whole story: `MD_LIGHT` is the _core_ of the generic hash interface, excluding functions such as `mbedtls_md_list()` and `mbedtls_md_info_from_string()`, `mbedtls_md_file()`, etc. But I think the @@ -81,7 +82,7 @@ That is, no user, even in the legacy domain, uses the low-level hash APIs macro `MBEDTLS_MD_CAN_xxx`. These macros are defined (for available hashes) as soon as `MBEDTLS_MD_LIGHT` is enabled. This subset of `MD` is automatically enabled as soon as something from the legacy domain, or from the `USE_PSA` -domain, needs a hash. (Note that this include `ENTROPY_C`, so in practice +domain, needs a hash. (Note that this includes `ENTROPY_C`, so in practice `MD_LIGHT` is enabled in most builds.) Note that there is a rule, enforced by `config_adjust_psa_superset_legacy.h`, @@ -152,7 +153,7 @@ enabled (for compatibility reasons). **Legacy domain:** most code here is using either `cipher.h` or low-level APIs like `aes.h`, and should use legacy macros like `MBEDTLS_AES_C` and -`MBEDTLS_CIPHER_MOD_CBC`. This includes NIST-KW, CMAC, PKCS5 en/decryption +`MBEDTLS_CIPHER_MODE_CBC`. This includes NIST-KW, CMAC, PKCS5/PKCS12 en/decryption functions, PEM decryption, PK parsing of encrypted keys. The only exceptions are `GCM` and `CCM` which use the internal abstraction layer `block_cipher` and check for availability of block ciphers using `MBEDTLS_CCM_GCM_CAN_xxx` From b50b6387d5bcf974d1d66659ada3e74beaacbb0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 23 Jul 2024 10:12:01 +0200 Subject: [PATCH 07/13] Clarify a comment in all.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- tests/scripts/components-configuration-crypto.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/scripts/components-configuration-crypto.sh b/tests/scripts/components-configuration-crypto.sh index fe33d4bc2e..61ac0f9efd 100644 --- a/tests/scripts/components-configuration-crypto.sh +++ b/tests/scripts/components-configuration-crypto.sh @@ -1697,7 +1697,8 @@ config_psa_crypto_accel_rsa () { driver_only=$1 # Start from crypto_full config (no X.509, no TLS) - # Note: PK excluded in analyze_outcomes.py. + # Note: PK will be ignored when comparing driver to reference in + # analyze_outcomes.py helper_libtestdriver1_adjust_config "crypto_full" if [ "$driver_only" -eq 1 ]; then From 497523243689322a5a9501ef298bc4358029c690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 23 Jul 2024 12:58:35 +0200 Subject: [PATCH 08/13] Misc minor clarifications in transition-guards.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/transition-guards.md | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/docs/architecture/psa-migration/transition-guards.md b/docs/architecture/psa-migration/transition-guards.md index e5b4adc2c3..1193f75137 100644 --- a/docs/architecture/psa-migration/transition-guards.md +++ b/docs/architecture/psa-migration/transition-guards.md @@ -33,27 +33,29 @@ It is useful to consider the following domains: `library/psa_*.c` and tested in `tests/suites/test_suite_psa*`. - The pure TLS 1.3 domain: the parts of TLS 1.3 that are not in the `USE_PSA` domain (see below). Those use PSA APIs unconditionally. -- The `USE_PSA` domain: that's PK, X.509, most of TLS 1.2 and the parts of TLS - 1.3 that are common with TLS 1.2 or are about public/private keys (see -`docs/use-psa-crypto.md` for details). +- The `USE_PSA` domain (that is, code that calls PSA crypto APIs when + `USE_PSA` is enabled, and legacy crypto APIs otherwise): that's PK, X.509, +most of TLS 1.2 and the parts of TLS 1.3 that are common with TLS 1.2 or are +about public/private keys (see `docs/use-psa-crypto.md` for details). - The legacy crypto domain: a number of modules there will use crypto from other modules, for example RSA and entropy will use hashes, PEM will use hashes and ciphers (from encrypted PEM), etc. The first two categories (PSA domain, pure TLS 1.3 domain) are simple: as a general rule, use `PSA_WANT` macros. (With very few exceptions, see -`component_check_test_dependencies` in `all.sh`.) When it is necessary to +`component_check_test_dependencies` in `all.sh`.) In the rare instances where it is necessary to check whether a mechanism is built-in or provided by a driver, `MBEDTLS_PSA_BUILTIN_xxx` and `MBEDTLS_PSA_ACCEL_xxx` macros should be used (but not legacy `MBEDTLS_xxx` macros). -The other two categories (legacy and `USE_PSA` domains) tend to be more -complex. There are different rules for different families of mechanisms, as -detailed in the following sections. +For the `USE_PSA` domain, it should always be correct to use expressions like +`(!USE_PSA && MBEDTLS_xxx) || (USE_PSA && PSA_WANT_xxx)`. Sometimes, macros +are defined in order to avoid using long expressions everywhere; they will be +mentioned in the following sections. -However as a general rule, it should always be correct for code in the -`USE_PSA` domain to use expressions like `(!USE_PSA && MBEDTLS_xxx) || -(USE_PSA && PSA_WANT_xxx)`. +The remaining category, the legacy domain, tends to be more complex. There are +different rules for different families of mechanisms, as detailed in the +following sections. Symmetric crypto ================ @@ -74,9 +76,9 @@ hash interface, excluding functions such as `mbedtls_md_list()` and `mbedtls_md_info_from_string()`, `mbedtls_md_file()`, etc. But I think the above should still provide a good intuition as first approximation.) -Note that all users of hashes use either the PSA Crypto API or the `md.h` API. -That is, no user, even in the legacy domain, uses the low-level hash APIs -(`mbedtls_sha256` etc). +Note that all users of hashes in the library use either the PSA Crypto API or the `md.h` API. +That is, no user in the library, even in the legacy domain, uses the low-level hash APIs +(`mbedtls_sha256` etc). (That's not true of all example programs, though.) **Helper macros:** in `config_adjust_legacy_crypto.h` we define a family of macro `MBEDTLS_MD_CAN_xxx`. These macros are defined (for available hashes) as @@ -110,8 +112,9 @@ availability of HMAC-xxx is determined by `MBEDTLS_MD_C && MBEDTLS_MD_CAN_xxx` (see previous subsection about `MD_CAN`). Modules in this domain that may use HMAC are PKCS5, PKCS7, HKDF, HMAC-DRBG and ECDSA deterministic. -**`USE_PSA` domain:** code will use either the `md.h` API or the `psa_mac` -API. It should check for the availability of HMAC-xxx with either: +**`USE_PSA` domain:** code will use the `md.h` API when `USE_PSA` is disabled, +and the `psa_mac` API when `USE_PSA` is enabled. It should check for the +availability of HMAC-xxx with either: ``` ((!MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_MD_C) || (MBEDTLS_USE_PSA_CRYPTO && PSA_WANT_ALG_HMAC)) && @@ -135,7 +138,8 @@ is negotiated). **Pure TLS 1.3 domain:** HMAC is used for the Finished message via PSA Crypto APIs. So, TLS 1.3 should depend on `PSA_WANT_ALG_HMAC` - doesn't seem to be -enforced by `check_config.h` at the moment. +enforced by `check_config.h`, or documented in `mbedtls_config.h`, at the +moment. Ciphers (AEAD and unauthenticated) ---------------------------------- From a0465779c9b3d11304549ba94f3bf92fca12eec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 10 Sep 2024 11:01:57 +0200 Subject: [PATCH 09/13] Clarify summary of PSA limitations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/psa-limitations.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md index ca3b44029b..6dca0bce29 100644 --- a/docs/architecture/psa-migration/psa-limitations.md +++ b/docs/architecture/psa-migration/psa-limitations.md @@ -14,8 +14,8 @@ Limitations relevant for G1 (performing crypto operations) Executive summary ----------------- -- Restartable/interruptible ECC operations: in progress (mid-2024). -- Arbitrary parameters for FFDH: will be dropped in 4.0. +- Restartable/interruptible ECC operations: support in PSA will be added in 4.0. +- Arbitrary parameters for FFDH: use in TLS will be dropped in 4.0. - RSA-PSS parameters: already implemented safe though arguably non-compliant solution in Mbed TLS 3.4, no complaints so far. From 4ceb71f53de514bb3d5255c30537582aaf3ddd0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 26 Sep 2024 09:45:45 +0200 Subject: [PATCH 10/13] Update and refine notes on restartable ECC and 4.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/psa-limitations.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md index 6dca0bce29..235f331bd4 100644 --- a/docs/architecture/psa-migration/psa-limitations.md +++ b/docs/architecture/psa-migration/psa-limitations.md @@ -14,7 +14,10 @@ Limitations relevant for G1 (performing crypto operations) Executive summary ----------------- -- Restartable/interruptible ECC operations: support in PSA will be added in 4.0. +- Restartable/interruptible ECC operations: some operations (`sign_hash`) are + already supported in PSA, but not used by TLS. The remaining operations +(ECDH `key_agreement` and `export_public`) will be implemented in 4.0 or 4.x, +and used by TLS in 4.x. - Arbitrary parameters for FFDH: use in TLS will be dropped in 4.0. - RSA-PSS parameters: already implemented safe though arguably non-compliant solution in Mbed TLS 3.4, no complaints so far. From 60769762d2440214e7b716a5ffcd9d3af44e88d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 26 Sep 2024 09:54:30 +0200 Subject: [PATCH 11/13] Clarify the superset rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/transition-guards.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/architecture/psa-migration/transition-guards.md b/docs/architecture/psa-migration/transition-guards.md index 1193f75137..b72abfa140 100644 --- a/docs/architecture/psa-migration/transition-guards.md +++ b/docs/architecture/psa-migration/transition-guards.md @@ -88,9 +88,11 @@ domain, needs a hash. (Note that this includes `ENTROPY_C`, so in practice `MD_LIGHT` is enabled in most builds.) Note that there is a rule, enforced by `config_adjust_psa_superset_legacy.h`, -that all hashes that are enabled on the legacy side are also enabled on the -PSA side. So, in practice, when `MD_LIGHT` is enabled, `PSA_WANT_ALG_xxx` and -`MBEDTLS_MD_CAN_xxx` are equivalent. +that as soon as `PSA_CRYPTO_C` is enabled, all hashes that are enabled on the +legacy side are also enabled on the PSA side (the converse is not true: a hash +that's provided by a driver will typically be available only on the PSA side). So, in +practice, when `PSA_CRYPTO_C` and `MD_LIGHT` are both enabled, +`PSA_WANT_ALG_xxx` and `MBEDTLS_MD_CAN_xxx` are equivalent. **Legacy and `USE_PSA` domains:** for hashes, `MBEDTLS_MD_CAN_xxx` (where `xxx` is the legacy name of the hash) can be used everywhere (except in the @@ -220,9 +222,12 @@ this implies support for the corresponding key type). ECC --- -**Curves:** in `config_adjut_psa_superset_legacy.h` we ensure that all +**Curves:** in `config_adjut_psa_superset_legacy.h` we ensure that, as soon as +`PSA_CRYPTO_C` is enabled, all curves that are supported on the legacy side (`MBEDTLS_ECP_DP_xxx_ENABLED`) -are also supported on the PSA side (`PSA_WANT_ECC_xxx`). +are also supported on the PSA side (`PSA_WANT_ECC_xxx`). (The converse is not +true as a curve provided by a driver will typically only be available on the +PSA side). In `config_adjust_legacy_crypto.h` we define macros `MBEDTLS_ECP_HAVE_xxx`. These macros are useful for data and functions that have users in several From 83f62ffc09ffb360d01c8dd5af6a273ef2ef20c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 26 Sep 2024 10:14:55 +0200 Subject: [PATCH 12/13] Expand on key derivations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/transition-guards.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/architecture/psa-migration/transition-guards.md b/docs/architecture/psa-migration/transition-guards.md index b72abfa140..1df280e8e4 100644 --- a/docs/architecture/psa-migration/transition-guards.md +++ b/docs/architecture/psa-migration/transition-guards.md @@ -100,12 +100,10 @@ PSA domain which should use `PSA_WANT` as usual). No special include is required, `build_info.h` or `common.h` is enough. **Pure TLS 1.3 domain:** it is not easy to know which uses of hashes fall in -this domain as opposed to the `USE_PSA` domain which looking at the code. +this domain as opposed to the `USE_PSA` domain whithout looking at the code. Fortunately, `MD_CAN` and `PSA_WANT` macros can be used interchangeably, as per the note above. - - HMAC ---- @@ -188,7 +186,15 @@ ciphers and modes it needs to know about. Key derivation -------------- -**Legacy and `USE_PSA` domains:** no users here. +**Legacy domain:** the modules PKCS5 and PKCS12 both provide +key derivation (respectively PBKDF2-HMAC and PKCS12 derivation), and use it +for password-based encryption. (Note: PEM has an implementation of PBKDF1 but +it's internal.) + +**`USE_PSA` domain:** PK (parse) will use PKCS5 and PKCS12 encryption (hence +indirectly key derivation) if present in the build. The macros are +`MBEDTLS_PKCS5_C` and `MBEDTLS_PKCS12_C`. Note that even when `USE_PSA` is +enabled, PK parse will _not_ use PSA for the PBKDF2 part of PKCS5 decryption. **Pure TLS 1.3 domain:** TLS 1.3 is using HKDF via PSA Crypto APIs. We already enforce in `check_config.h` that TLS 1.3 depends on the appropriate `PSA_WANT` From 9fc3b7d24371ed1b4cc21d12d918b305649c6ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 26 Sep 2024 11:00:02 +0200 Subject: [PATCH 13/13] Expand on block cipher modes/derivatives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/transition-guards.md | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/docs/architecture/psa-migration/transition-guards.md b/docs/architecture/psa-migration/transition-guards.md index 1df280e8e4..dda65f15a2 100644 --- a/docs/architecture/psa-migration/transition-guards.md +++ b/docs/architecture/psa-migration/transition-guards.md @@ -144,13 +144,19 @@ moment. Ciphers (AEAD and unauthenticated) ---------------------------------- -**Overview of existing (internal) APIs:** we currently have 4 (families of) -APIs for ciphers in the library: -- Low-level API: `mbedtls_aes_xxx` etc. - used by `cipher.c` and some other - modules in the legacy domain. +**Overview of existing (internal) APIs:** we currently have 5 (families of) +APIs for ciphers (and associated constructs) in the library: +- Low-level API for primitives: `mbedtls_aes_xxx` etc. - used by `cipher.c` + and some other modules in the legacy domain. - Internal abstraction layer `block_cipher` for AES, ARIA and Camellia primitives - used only by `gcm.c` and `ccm.c`, only when `CIPHER_C` is not enabled (for compatibility reasons). +- Block cipher modes / derivatives: + - `mbedtls_gcm_xxx` and `mbedtls_ccm_xxx`, used by `cipher.c` and + the built-in PSA implementation; + - `mbedtls_nist_kw_xxx`, used by `cipher.c`; + - `mbedtls_cipher_cmac_xxx`, used by the built-in PSA implementation; + - `mbedtls_ctr_drbg_xxx`, used by PSA crypto's RNG subsystem. - Cipher: used by some modules in the legacy domain, and by the built-in PSA implementation. - PSA: used by the `USE_PSA` domain when `MBEDTLS_USE_PSA_CRYPTO` is enabled. @@ -159,9 +165,17 @@ enabled (for compatibility reasons). like `aes.h`, and should use legacy macros like `MBEDTLS_AES_C` and `MBEDTLS_CIPHER_MODE_CBC`. This includes NIST-KW, CMAC, PKCS5/PKCS12 en/decryption functions, PEM decryption, PK parsing of encrypted keys. The only exceptions -are `GCM` and `CCM` which use the internal abstraction layer `block_cipher` -and check for availability of block ciphers using `MBEDTLS_CCM_GCM_CAN_xxx` -macros defined in `config_adjut_legacy_crypto.h`. +are: +1. `GCM` and `CCM` use the internal abstraction layer `block_cipher` and check + for availability of block ciphers using `MBEDTLS_CCM_GCM_CAN_xxx` macros +defined in `config_adjut_legacy_crypto.h`. As a user, to check if AES-GCM is +available through the `mbedtls_gcm` API, you want to check for `MBEDTLS_GCM_C` +and `MBDTLS_CCM_GCM_CAN_AES`. +2. `CTR_DRBG` uses the low-level `mbedtls_aes_` API if it's available, + otherwise it uses the PSA API. There is no need for users of `CTR_DRBG` to +check if AES is available: `check_config.h` is already taking care of that, so +from a user's perspective as soon as `MBEDTLS_CTR_DRBG_C` is enabled, you can +use it without worrying about AES. **`USE_PSA` domain:** here we should use conditions like the following in order to test for availability of ciphers and associated modes.