From 5ad8ca2a5fb0769409aa47b8c9c5b781c83e7444 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 13 Jun 2023 19:49:18 +0200 Subject: [PATCH 01/88] Legacy-to-PSA transition guide Covers most modules, but missing most of ecp, ecdh and dhm. Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 1059 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1059 insertions(+) create mode 100644 docs/psa-transition.md diff --git a/docs/psa-transition.md b/docs/psa-transition.md new file mode 100644 index 0000000000..24facffa60 --- /dev/null +++ b/docs/psa-transition.md @@ -0,0 +1,1059 @@ +# Transitioning to the PSA API + +> I have code written for `mbedtls_` cryptography APIs. How do I migrate to `psa_` APIs? + +## Introduction + +Mbed TLS is gradually moving from legacy `mbedtls_xxx` APIs to newer `psa_xxx` APIs for cryptography. Note that this only concerns cryptography APIs, not X.509 or SSL/TLS APIs. + +This guide is intended to help migrate existing applications that use Mbed TLS for cryptography. It aims to cover common use cases, but cannot cover all possible scenarios. + +### Suggested reading + +This document is long, but you probably don't need to read all of it. You should start with the following sections: + +1. [Where can I find documentation?](#where-can-i-find-documentation) +2. [General considerations](#general-considerations) + +Then use the [summary of API modules](#summary-of-api-modules), the table of contents or a text search to locate the sections that interest you, based on what legacy interfaces your code is currently using. + +### Where can I find documentation? + +**Tutorial**: See the [getting started guide](https://mbed-tls.readthedocs.io/en/latest/getting_started/psa/). + +**Reference**: The [PSA Crypto API specification](https://arm-software.github.io/psa-api/crypto/) is available online. Mbed TLS implements a large subset of the specification which is documented in the [`psa/crypto*.h` headers](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto_8h/). + +### Additional resources + +* [Mbed TLS open issues](https://github.com/Mbed-TLS/mbedtls/issues) +* [PSA API open issues](https://github.com/ARM-software/psa-api/issues) (not just cryptography APIs) +* [Mbed TLS mailing list](https://lists.trustedfirmware.org/mailman3/lists/mbed-tls.lists.trustedfirmware.org/) + +### Why change the API? + +* Mbed TLS APIs are traditionally very transparent: the caller can access internal fields of operations. This is less true in the 3.x major version than before, but still the case to some extent. This offers applications some flexibility, but it removes flexibility from the implementation. For example, it is hard to support hardware acceleration, because the API constrains how the data must be represented. PSA APIs were designed to be more opaque, giving more freedom to the implementation. +* Mbed TLS legacy APIs require key material to be present in the application memory. The PSA Crypto API natively supports operations on keys stored in an external [location](https://arm-software.github.io/psa-api/crypto/1.1/api/keys/lifetimes.html#c.psa_key_location_t) (secure enclave, secure element, HSM, etc.). +* PSA APIs have [consistent conventions ](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#parameter-conventions) which many legacy APIs in Mbed TLS do not follow. For example, many legacy cryptography functions require the caller to know how large an output buffer needs to be based on the selected algorithm, whereas in the PSA API, all buffer arguments have a well-defined size and those sizes are checked. +* Mbed TLS legacy APIs require passing around a random generator argument where needed. This has historically been problematic with functions that were created without a RNG argument but later needed one as part of a security countermeasure. The PSA crypto subsystem maintains a global random generator, resolving this problem. + +### Migration timeline + +* Mbed TLS 2.15.0 (Nov 2018): first release with a draft implementation of the PSA API. +* Mbed TLS 2.18.0 (Jun 2019): The PSA API is available in the default build. +* Mbed TLS 3.1.0 (Dec 2021): TLS 1.3 support is the first major feature that requires the PSA API. +* Mbed TLS 4.0.0 (2024?): X.509 and TLS require the PSA API. Removal of some legacy crypto APIs. +* Mbed TLS 5.0.0 (??): Removal of the remaining non-PSA crypto APIs. + +## General considerations + +### Configuration of the PSA subsystem + +To make the PSA API available, make sure that the configuration option [`MBEDTLS_PSA_CRYPTO_C`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#c.MBEDTLS_PSA_CRYPTO_C) is enabled (it is enabled in the default configuration). + +You should probably enable [`MBEDTLS_USE_PSA_CRYPTO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a70fd7b97d5f11170546583f2095942a6) as well (it is disabled by default). This option causes the PK, X.509 and TLS modules to use PSA crypto under the hood. Some functions that facilitate the transition are only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled. + +By default, the PSA crypto API offers a similar set of cryptographic mechanisms as those offered by the legacy API. The PSA crypto API also has its own configuration mechanism; see “[Cryptographic mechanism availability](#cryptographic-mechanism-availability)”. + +### Header files + +Applications only need to include a single header file: +``` +#include +``` + +### General application layout + +Before any cryptographic operation, call [`psa_crypto_init`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__initialization/#group__initialization_1ga2de150803fc2f7dc6101d5af7e921dd9) and check that it succeeds. (A failure indicates an abnormal system state from which most applications cannot recover.) + +If you wish to free all resources associated with PSA cryptography, call [`mbedtls_psa_crypto_free`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__extra_8h/#_CPPv423mbedtls_psa_crypto_freev). + +The PSA subsystem has an internal random generator. As a consequence, you do not need to instantiate one manually (no need to create an `mbedtls_entropy_context` and a `mbedtls_xxx_drbg_context`). + +### Error codes + +Mbed TLS functions return a status of type `int`: 0 for success (or, occasionally, a positive value which is the output length), or a negative value `MBEDTLS_ERR_xxx` indicating an error. + +PSA functions return a status of type [`psa_status_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__error/#group__error_1ga05676e70ba5c6a7565aff3c36677c1f9): `PSA_SUCCESS == 0` for success, or a negative value [`PSA_ERROR_xxx`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__error/) indicating an error. + +## Summary of API modules + +| Header | Function prefix | PSA equivalent | +| ------ | --------------- | -------------- | +| `aes.h` | `mbedtls_aes_` | [Symmetric encryption](#symmetric-encryption) | +| `aria.h` | `mbedtls_aria_` | [Symmetric encryption](#symmetric-encryption) | +| `asn1.h` | `mbedtls_asn1_` | No change (not a crypto API) | +| `asn1write.h` | `mbedtls_asn1write_` | No change (not a crypto API) | +| `base64.h` | `mbedtls_base64_` | [PK format support interfaces](#pk-format-support-interfaces) | +| `bignum.h` | `mbedtls_bignum_` | None (no low-level arithmetic) | +| `build_info.h` | `MBEDTLS_` | No change (not a crypto API) | +| `camellia.h` | `mbedtls_camellia_` | [Symmetric encryption](#symmetric-encryption) | +| `ccm.h` | `mbedtls_ccm_` | [Symmetric encryption](#symmetric-encryption), [Authenticated cipher operations](#authenticated-cipher-operations) | +| `chacha20.h` | `mbedtls_chacha20_` | [Symmetric encryption](#symmetric-encryption) | +| `chachapoly.h` | `mbedtls_chachapoly_` | [Symmetric encryption](#symmetric-encryption) | +| `check_config.h` | N/A | No public APIs (internal support header) | +| `cipher.h` | `mbedtls_cipher_` | [Symmetric encryption](#symmetric-encryption) | +| `cmac.h` | `mbedtls_cmac_` | [Hashes and MAC](#hashes-and-mac), [MAC calculation](#mac-calculation) | +| `compat-2.x.h` | various | None (transitional APIs) | +| `config_psa.h` | N/A | No public APIs (internal support header) | +| `constant_time.h` | `mbedtls_constant_time_` | [Constant-time functions](#constant-time-functions) | +| `ctr_drbg.h` | `mbedtls_ctr_drbg_` | [Random generation interface](#random-generation-interface), [Deterministic pseudorandom generation](#deterministic-pseudorandom-generation) | +| `debug.h` | `mbedtls_debug_` | No change (not a crypto API) | +| `des.h` | `mbedtls_des_` | [Symmetric encryption](#symmetric-encryption) | +| `dhm.h` | `mbedtls_dhm_` | [Asymmetric cryptography](#asymmetric-cryptography) | +| `ecdh.h` | `mbedtls_ecdh_` | [Asymmetric cryptography](#asymmetric-cryptography) | +| `ecdsa.h` | `mbedtls_ecdsa_` | [Asymmetric cryptography](#asymmetric-cryptography) | +| `ecjpake.h` | `mbedtls_ecjpake_` | [EC-JPAKE](#ec-jpake) | +| `ecp.h` | `mbedtls_ecp_` | [Asymmetric cryptography](#asymmetric-cryptography) | +| `entropy.h` | `mbedtls_entropy_` | [Random generation interface](#random-generation-interface), [Entropy sources](#entropy-sources) | +| `error.h` | `mbedtls_error_` | [Error messages](#error-messages) | +| `gcm.h` | `mbedtls_gcm_` | [Symmetric encryption](#symmetric-encryption), [Authenticated cipher operations](#authenticated-cipher-operations) | +| `hkdf.h` | `mbedtls_hkdf_` | [HKDF](#hkdf) | +| `hmac_drbg.h` | `mbedtls_hmac_drbg_` | [Random generation interface](#random-generation-interface), [Deterministic pseudorandom generation](#deterministic-pseudorandom-generation) | +| `lms.h` | `mbedtls_lms_` | No migration path yet | +| `mbedtls_config.h` | `MBEDTLS_` | [Compile-time configuration](#compile-time-configuration) | +| `md.h` | `mbedtls_md_` | [Hashes and MAC](#hashes-and-mac) | +| `md5.h` | `mbedtls_md5_` | [Hashes and MAC](#hashes-and-mac) | +| `memory_buffer_alloc.h` | `mbedtls_memory_buffer_alloc_` | No change (not a crypto API) | +| `net_sockets.h` | `mbedtls_net_` | No change (not a crypto API) | +| `nist_kw.h` | `mbedtls_nist_kw_` | No migration path yet | +| `oid.h` | `mbedtls_oid_` | [PK format support interfaces](#pk-format-support-interfaces) | +| `pem.h` | `mbedtls_pem_` | [PK format support interfaces](#pk-format-support-interfaces) | +| `pk.h` | `mbedtls_pk_` | [Asymmetric cryptography](#asymmetric-cryptography) | +| `pkcs5.h` | `mbedtls_pkcs5_` | [PKCS#5 module](#pkcs5-module) | +| `pkcs7.h` | `mbedtls_pkcs7_` | No change (not a crypto API) | +| `pkcs12.h` | `mbedtls_pkcs12_` | [PKCS#12 module](#pkcs12-module) | +| `platform.h` | `mbedtls_platform_` | No change (not a crypto API) | +| `platform_time.h` | `mbedtls_platform_time_` | No change (not a crypto API) | +| `platform_util.h` | `mbedtls_platform_util_` | No change (not a crypto API) | +| `poly1305.h` | `mbedtls_poly1305_` | None (but there is Chacha20-Poly1305 [AEAD](#symmetric-encryption)) | +| `private_access.h` | N/A | No public APIs (internal support header) | +| `psa_util.h` | `mbedtls_psa_` | No public APIs (internal support header) | +| `ripemd160.h` | `mbedtls_ripemd160_` | [Hashes and MAC](#hashes-and-mac) | +| `rsa.h` | `mbedtls_rsa_` | [Asymmetric cryptography](#asymmetric-cryptography) | +| `sha1.h` | `mbedtls_sha1_` | [Hashes and MAC](#hashes-and-mac) | +| `sha3.h` | `mbedtls_sha3_` | [Hashes and MAC](#hashes-and-mac) | +| `sha256.h` | `mbedtls_sha256_` | [Hashes and MAC](#hashes-and-mac) | +| `sha512.h` | `mbedtls_sha512_` | [Hashes and MAC](#hashes-and-mac) | +| `ssl.h` | `mbedtls_ssl_` | No change (not a crypto API) | +| `ssl_cache.h` | `mbedtls_ssl_cache_` | No change (not a crypto API) | +| `ssl_ciphersuites.h` | `mbedtls_ssl_ciphersuites_` | No change (not a crypto API) | +| `ssl_cookie.h` | `mbedtls_ssl_cookie_` | No change (not a crypto API) | +| `ssl_ticket.h` | `mbedtls_ssl_ticket_` | No change (not a crypto API) | +| `threading.h` | `mbedtls_threading_` | No change (not a crypto API) | +| `timing.h` | `mbedtls_timing_` | No change (not a crypto API) | +| `version.h` | `mbedtls_version_` | No change (not a crypto API) | +| `x509.h` | `mbedtls_x509` | No change (not a crypto API) | +| `x509_crl.h` | `mbedtls_x509` | No change (not a crypto API) | +| `x509_crt.h` | `mbedtls_x509` | No change (not a crypto API) | +| `x509_csr.h` | `mbedtls_x509` | No change (not a crypto API) | + +## Compile-time configuration + +### Cryptographic mechanism availability + +**This section only applies if `MBEDTLS_PSA_CRYPTO_CONFIG` is enabled.** This option is disabled in the default configuration. + +When the configuration option [`MBEDTLS_PSA_CRYPTO_CONFIG`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a5aca5ddcffb586acad82f9aef26db056) is enabled, the cryptographic mechanisms available through the PSA API are determined by the contents of the header file `"psa/crypto_config.h"`. You can override the file location with the macro [`MBEDTLS_PSA_CRYPTO_CONFIG_FILE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a25f7e358caa101570cb9519705c2b873), and you can set [`MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1abd1870cc0d2681183a3018a7247cb137) to the path of an additional file (similar to `MBEDTLS_CONFIG_FILE` and `MBEDTLS_USER_CONFIG_FILE` for legacy configuration symbols). + +The availability of cryptographic mechanisms in the PSA API is based on a systematic pattern: + +* To make `PSA_ALG_aaa` available, enable `PSA_WANT_ALG_aaa`. + For parametrized algorithms, there is a `PSA_WANT_` symbols both for the main macro and for each argument. For example, to make `PSA_ALG_HMAC(PSA_ALG_SHA_256)` available, enable both `PSA_WANT_ALG_HMAC` and `PSA_WANT_ALG_SHA_256`. + +* To make `PSA_KEY_TYPE_ttt` available, enable `PSA_WANT_KEY_TYPE_ttt`. + + As an exception, starting in Mbed TLS 3.5.0, for key pair types, the feature selection is more fine-grained, with an additional suffix: + * `PSA_KEY_TYPE_xxx_USE` enables support for operations with a key of that type (for enabled algorithms). This is automatically enabled if any key creation method (`IMPORT`, `GENERATE` or `DERIVE`) is enabled. + * `PSA_KEY_TYPE_xxx_IMPORT` enables support for `psa_import_key` to import a key of that type. + * `PSA_KEY_TYPE_xxx_GENERATE` enables support for `psa_generate_key` to randomly generate a key of that type. + * `PSA_KEY_TYPE_xxx_DERIVE` enables support for `psa_key_derivation_output_key` to deterministically derive a key of that type. + * `PSA_KEY_TYPE_xxx_EXPORT` enables support for `psa_export_key` to export a key of that type. + + Enabling any support for a key pair type automatically enables support for the corresponding public key type, as well as support for `psa_export_public_key` on the private key. + +* To make `PSA_ECC_FAMILY_fff` available for size sss, enable `PSA_WANT_ECC_fff_sss`. + +Note that all `PSA_WANT_xxx` symbols must be set to a nonzero value. In particular, setting `PSA_WANT_xxx` to an empty value may not be handled consistently. + +For example, the following configuration enables hashing with SHA-256, AEAD with AES-GCM, signature with deterministic ECDSA using SHA-256 on the curve secp256r1 using a randomly generated key as well as the corresponding verification, and ECDH key exchange on secp256r1 and Curve25519. + +``` +#define PSA_WANT_ALG_SHA_256 1 + +#define PSA_WANT_KEY_TYPE_AES 1 +#define PSA_WANT_ALG_GCM 1 + +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1 +// ^^ In Mbed TLS <= 3.4, enable PSA_WANT_KEY_TYPE_ECC_KEY_PAIR instead +// ^^ implicitly enables PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_USE, PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY +#define PSA_WANT_ECC_SECP_R1_256 1 // secp256r1 (suitable for ECDSA and ECDH) +#define PSA_WANT_ECC_MONTGOMERY_255 1 // Curve25519 (suitable for ECDH) +#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1 +#define PSA_WANT_ALG_ECDH +``` + +If a mechanism is not enabled by `PSA_WANT_xxx`, Mbed TLS will often not include it, to reduce the size of the compiled library. However, this is not guaranteed: a mechanism that is not explicitly requested can be enabled because it is a dependency of another configuration option, because it is used internally, or because the granularity is not fine enough to distinguish between it and another mechanism that is requested. + +Under the hood, `PSA_WANT_xxx` enables the necessary legacy modules. Note that if a mechanism has a PSA accelerator driver, the corresponding legacy module is typically not needed. Thus applications that use a cryptographic mechanism both through the legacy API and through the PSA API need to explicitly enable both the `PSA_WANT_xxx` symbols and the `MBEDTLS_xxx` symbols. + +## Miscellaneous support modules + +### Error messages + +At the time of writing, there is no equivalent to the error messages provided by `mbedtls_strerror`. However, you can use the companion program `programs/psa/psa_constant_names` to convert various numbers (`psa_status_t`, `psa_algorithm_t`, `psa_key_type_t`, `psa_ecc_family_t`, `psa_dh_family_t`, `psa_key_usage_t`) to their input representation. The conversion doesn't depend on the library configuration or the target platform, so you can use a native build of this program even if you cross-compile your application. + +``` +$ programs/psa/psa_constant_names error -138 +PSA_ERROR_BUFFER_TOO_SMALL +$ programs/psa/psa_constant_names type 0x7112 +PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1) +$ programs/psa/psa_constant_names alg 0x06000609 +PSA_ALG_ECDSA(PSA_ALG_SHA_256) +``` + +The other functions in `error.h` are specific to the construction of Mbed TLS error code and are not relevant to the PSA API. PSA error codes are never the combination of multiple codes. + +### Constant-time functions + +The PSA API does not have an equivalent to the timing-side-channel-resistance utility functions in `constant_time.h`. Continue using `constant_time.h` as needed. + +Note that the PSA API does include features that reduce the need for `mbedtls_ct_memcmp`: + +* To compare a MAC with a reference value, use `psa_mac_verify` rather of `psa_mac_compute` followed by `mbedtls_ct_memcmp`, or use `psa_mac_verify_setup` and `psa_mac_verify_finish` in the multi-part case. See “[MAC calculation](#mac-calculation)”. +* The AEAD decryption functions take care of verifying the tag. See “[Authenticated cipher operations](#authenticated-cipher-operations)”. + +## Symmetric encryption + +All PSA APIs have algorithm agility, where the functions depend only on the nature of the operation and the choice of a specific algorithm comes from an argument. There is no special API for a particular block cipher (`aes.h`, `aria.h`, `camellia.h`, `des.h`), a particular block cipher mode (`ccm.h`, `gcm.h`) or a particular stream cipher (`chacha20.h`, `chachapoly.h`). To migrate code using those low-level modules, please follow the recommendations in the following sections, using the same principles as the corresponding `cipher.h` API. + +### Cipher mechanism selection + +Instead of `mbedtls_cipher_id_t` (`MBEDTLS_CIPHER_ID_xxx` constants), `mbedtls_cipher_type_t` (`MBEDTLS_CIPHER_base_size_mode` constants), `mbedtls_cipher_mode_t` (`MBEDTLS_CIPHER_MODE_xxx` constants) and `mbedtls_cipher_padding_t` (`MBEDTLS_CIPHER_PADDING_xxx` constants), use the [`PSA_KEY_TYPE_xxx` and `PSA_ALG_xxx` constants](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/). + +For modes that are based on a block cipher, the key type encodes the choice of block cipher: +[`PSA_KEY_TYPE_AES`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga6ee54579dcf278c677eda4bb1a29575e), +[`PSA_KEY_TYPE_ARIA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#c.PSA_KEY_TYPE_ARIA), +[`PSA_KEY_TYPE_CAMELLIA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gad8e5da742343fd5519f9d8a630c2ed81), +[`PSA_KEY_TYPE_DES`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga577562bfbbc691c820d55ec308333138). +The algorithm encodes the mode and if relevant the padding type: + +* Unauthenticated cipher modes: + [`PSA_ALG_CTR`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gad318309706a769cffdc64e4c7e06b2e9), + [`PSA_ALG_CFB`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0088c933e01d671f263a9a1f177cb5bc), + [`PSA_ALG_OFB`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gae96bb421fa634c6fa8f571f0112f1ddb), + [`PSA_ALG_XTS`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gaa722c0e426a797fd6d99623f59748125), + [`PSA_ALG_ECB_NO_PADDING`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab8f0609cd0f12cccc9c950fd5a81a0e3), + [`PSA_ALG_CBC_NO_PADDING`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gacb332d72716958880ee7f97d8365ae66), + [`PSA_ALG_CBC_PKCS7`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gaef50d2e9716eb6d476046608e4e0c78c), + [`PSA_ALG_CCM_STAR_NO_TAG`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga89627bb27ec3ce642853ab8554a88572). +* Other padding modes, which are obsolete, are not available in the PSA API. If you need them, handle the padding in your application code and use the `NO_PADDING` algorithm. +* AEAD modes: + [`PSA_ALG_CCM`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac2c0e7d21f1b2df5e76bcb4a8f84273c), + [`PSA_ALG_GCM`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0d7d02b15aaae490d38277d99f1c637c). +* KW/KWP modes are not available in the PSA API at the time of writing. + +For the ChaCha20 unauthenticated cipher, use [`PSA_KEY_TYPE_CHACHA20`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga901548883b3bce56cc21c3a22cf8d93c) with [`PSA_ALG_STREAM_CIPHER`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gad98c105198f7428f7d1dffcb2cd398cd). +For the Chacha20+Poly1305 AEAD, use [`PSA_KEY_TYPE_CHACHA20`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga901548883b3bce56cc21c3a22cf8d93c) with [`PSA_ALG_CHACHA20_POLY1305`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga1fec55093541640a71bdd022d4adfb9c) + +### Cipher mechanism availability + +For each key type value `PSA_KEY_TYPE_xxx`, the symbol `PSA_WANT_KEY_TYPE_xxx` is defined with a nonzero value if the library is built with support for that key type. For each algorithm value `PSA_ALG_yyy`, the symbol `PSA_WANT_ALG_yyy` is defined with a nonzero value if the library is built with support for that algorithm. Note that for a mechanism to be supported, both the key type and the algorithm must be supported. + +For example, to test if AES-CBC-PKCS7 is supported, in the legacy API, you could write: +``` +#if defined(MBEDTLS_AES_C) && \ + defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_CIPHER_PADDING_PKCS7) +``` +The equivalent in the PSA API is +``` +#if PSA_WANT_KEY_TYPE_AES && PSA_WANT_ALG_CBC_PKCS7 +``` + +### Cipher metadata + +Both APIs express key sizes in bits. Note however that in the PSA API, the size of a _buffer_ is always expressed in bytes, even if that buffer contains a key. + +The following table lists corresponding PSA macros for maximum-size macros that take all supported algorithms into account. + +| Legacy macro | PSA macro | +| ------------ | --------- | +| `MBEDTLS_MAX_IV_LENGTH` | [`PSA_CIPHER_IV_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_IV_MAX_SIZE), [`PSA_AEAD_NONCE_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#crypto__sizes_8h_1ac2a332765ba4ccfc24935d6f7f48fcc7) | +| `MBEDTLS_MAX_BLOCK_LENGTH` | [`PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) | +| `MBEDTLS_MAX_KEY_LENGTH` | no equivalent| + +There is no equivalent to the type `mbedtls_cipher_info_t` and the functions `mbedtls_cipher_info_from_type` and `mbedtls_cipher_info_from_values` in the PSA API because it is unnecessary. All macros and functions operate directly on key type values (`psa_key_type_t`, `PSA_KEY_TYPE_xxx` constants) and algorithm values (`psa_algorithm_t`, `PSA_ALG_xxx` constants). + +| Legacy function | PSA macro | +| --------------- | --------- | +| `mbedtls_cipher_info_get_iv_size` | [`PSA_CIPHER_IV_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_IV_LENGTH), [`PSA_AEAD_NONCE_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_NONCE_LENGTH) | +| `mbedtls_cipher_info_get_block_size` | not available (use specific macros for the IV, nonce or tag length) | + +The following features have no PSA equivalent: + +* `mbedtls_cipher_list`: the PSA API does not currently have a discovery mechanism for cryptographic mechanisms, but one may be added in the future. +* `mbedtls_cipher_info_has_variable_key_bitlen`, `mbedtls_cipher_info_has_variable_iv_size`: the PSA API does not currently have such mechanism for high-level metadata information. +* `mbedtls_cipher_info_from_string`: there is no equivalent of Mbed TLS's lookup based on a (nonstandard) name. + +### Cipher key management + +The legacy API and the PSA API have a different organization of operations in several respects: + +* In the legacy API, each operation object contains the necessary key material. In the PSA API, an operation object contains a reference to a key object. To perform a cryptographic operation, you must create a key object first. However, for a one-shot operation, you do not need an operation object, just a single function call. +* The legacy API uses the same interface for authenticated and non-authenticated ciphers, while the PSA API has separate functions. +* The legacy API uses the same functions for encryption and decryption, while the PSA API has separate functions where applicable. + +Here is an overview of the lifecycle of a key object. + +1. First define the attributes of the key by filling a [`psa_key_attributes_t` structure](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga0ec645e1fdafe59d591104451ebf5680). You need to set the following parameters: + * Call [`psa_set_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga6857ef0ecb3fa844d4536939d9c64025) to set the key type to the desired `PSA_KEY_TYPE_xxx` value (see “[Cipher mechanism selection](#cipher-mechanism-selection)”). + * Call [`psa_set_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaf61683ac87f87687a40262b5afbfa018) to set the key's size in bits. This is optional with `psa_import_key`, which determines the key size from the length of the key material. + * Call [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) to set the algorithm to the desired `PSA_ALG_xxx` value (see “[Cipher mechanism selection](#cipher-mechanism-selection)”). By design, the same key cannot be used with multiple algorithms. + * Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de) to enable at least [`PSA_KEY_USAGE_ENCRYPT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#c.PSA_KEY_USAGE_ENCRYPT) or [`PSA_KEY_USAGE_DECRYPT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#c.PSA_KEY_USAGE_DECRYPT), depending on which direction you want to use the key in. To allow both directions, use the flag mask `PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_ENCRYPT`. The same policy flags cover authenticated and non-authenticated encryption/decryption. +2. Call one of the key creation functions, passing the attributes defined in the previous step, to get an identifier of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t) to the key object. + * Use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b) to directly import key material. + * If the key is randomly generated, use [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). + * If the key is derived from other material (for example from a key exchange), use the [key derivation interface](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/) and create the key with [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1). +3. Call the functions in the following sections to perform operations on the key. The same key object can be used in multiple operations. +4. To free the resources used by the key object, call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) after all operations with that key are finished. + +### Unauthenticated cipher operations + +Recall the flow of an unauthenticated cipher operation in the legacy Mbed TLS cipher API: + +1. Create a cipher context of type `mbedtls_cipher_context_t` and initialize it with `mbedtls_cipher_init`. +2. Establish the operation parameters (algorithm, key, mode) with `mbedtls_cipher_setup`, `mbedtls_cipher_setkey` (or `mbedtls_cipher_setup_psa`), `mbedtls_cipher_set_padding_mode` if applicable. +3. Set the IV with `mbedtls_cipher_set_iv` (except for ECB which does not use an IV). +4. For a one-shot operation, call `mbedtls_cipher_crypt`. To pass the input in multiple parts, call `mbedtls_cipher_update` as many times as necessary followed by `mbedtls_cipher_finish`. +5. Finally free the resources associated with the operation object by calling `mbedtls_cipher_free`. + +For a one-shot operation (where the whole plaintext or ciphertext is passed as a single input), the equivalent flow with the PSA API is to call a single function: + +* [`psa_cipher_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga61f02fbfa681c2659546eca52277dbf1) to perform encryption with a random IV of the default size (indicated by [`PSA_CIPHER_IV_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_IV_LENGTH)). (To encrypt with a specified IV, use the multi-part API described below.) You can use the macro [`PSA_CIPHER_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. +* [`psa_cipher_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gab3593f5f14d8c0431dd306d80929215e) to perform decryption with a specified IV. You can use the macro [`PSA_CIPHER_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. + +For a multi-part operation, the equivalent flow with the PSA API is as follows: + +1. Create an operation object of type [`psa_cipher_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga1399de29db657e3737bb09927aae51fa) and zero-initialize it (or use the corresponding `INIT` macro). +2. Select the key and algorithm with [`psa_cipher_encrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga587374c0eb8137a572f8e2fc409bb2b4) or [`psa_cipher_decrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gaa4ba3a167066eaef2ea49abc5dcd1d4b) depending on the desired direction. +3. When encrypting with a random IV, use [`psa_cipher_generate_iv`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga29fd7d32a5729226a2f73e7b6487bd8a). When encrypting with a chosen IV, or when decrypting, set the IV with [`psa_cipher_set_iv`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga9caddac1a429a5032d6d4a907fb70ba1). Skip this step with ECB since it does not use an IV. +4. Call [`psa_cipher_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gac3ca27ac6682917c48247d01fd96cd0f) as many times as needed. You can use [`PSA_CIPHER_UPDATE_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_UPDATE_OUTPUT_SIZE) or [`PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#crypto__sizes_8h_1ab1f6598efd6a7dc56e7ad7e34719eb32) to determine the size of the output buffer. +5. Call [`psa_cipher_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga1dcb58b8befe23f8a4d7a1d49c99249b) to obtain the last part of the output. You can use [`PSA_CIPHER_FINISH_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_FINISH_OUTPUT_SIZE) or [`PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE) to determine the size of the output buffer. + +If you need to interrupt the operation after calling the setup function without calling the finish function, call [`psa_cipher_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gaad482cdca2098bca0620596aaa02eaa4). + +### Authenticated cipher operations + +Recall the flow of an authenticated cipher operation in the legacy Mbed TLS cipher API (or similar flows in the `chachapoly`, `ccm` and `gcm` modules): + +1. Create a cipher context of type `mbedtls_cipher_context_t` and initialize it with `mbedtls_cipher_init`. +2. Establish the operation parameters (algorithm, key, mode) with `mbedtls_cipher_setup`, `mbedtls_cipher_setkey` (or `mbedtls_cipher_setup_psa`), `mbedtls_cipher_set_padding_mode` if applicable. +3. Set the nonce with `mbedtls_cipher_set_iv` (or the `starts` function for low-level modules). For CCM, which requires direct use of the `ccm` module, also call `mbedtls_ccm_set_lengths` to set the length of the additional data and of the plaintext. +4. Call `mbedtls_cipher_update_ad` to pass the unencrypted additional data. +5. Call `mbedtls_cipher_update` as many times as necessary to pass the input plaintext or ciphertext. +6. Call `mbedtls_cipher_finish` to obtain the last part of the output. Then call `mbedtls_cipher_write_tag` (when encrypting) or `mbedtls_cipher_check_tag` (when decrypting) to process the authentication tag. +7. Finally free the resources associated with the operation object by calling `mbedtls_cipher_free`. + +Steps 3–6 can be replaced by a single call to `mbedtls_cipher_auth_encrypt_ext` or `mbedtls_cipher_auth_decrypt_ext` for a one-shot operation (where the whole plaintext or ciphertext is passed as a single input). + +For a one-shot operation, the PSA API allows you to call a single function: + +* [`psa_aead_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae72e1eb3c2da3ebd843bb9c8db8df509) to perform authenticated encryption with a random nonce of the default size (indicated by [`PSA_AEAD_NONCE_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_NONCE_LENGTH)), with the authentication tag written at the end of the output. (To encrypt with a specified nonce, or to separate the tag from the rest of the ciphertext, use the multi-part API described below.) You can use the macro [`PSA_AEAD_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_ENCRYPT_OUTPUT_SIZE) or [`PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. +* [`psa_aead_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae799f6196a22d50c216c947e0320d3ba) to perform authenticated decryption of a ciphertext with the authentication tag at the end. (If the tag is separate, use the multi-part API described below.) You can use the macro [`PSA_AEAD_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_SIZE) or [`PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. + +For a multi-part operation, the equivalent flow with the PSA API is as follows: + +1. Create an operation object of type [`psa_aead_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga14f6a01afbaa8c5b3d8c5d345cbaa3ed) and zero-initialize it (or use the corresponding `INIT` macro). +2. Select the key and algorithm with [`psa_aead_encrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga2732c40ce8f3619d41359a329e9b46c4) or [`psa_aead_decrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gaaa5c5018e67a7a6514b7e76b9a14de26) depending on the desired direction. +3. When encrypting with a random nonce, use [`psa_aead_generate_nonce`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga5799df1c555efd35970b65be51cb07d1). When encrypting with a chosen nonce, or when decrypting, set the nonce with [`psa_aead_set_nonce`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga59132751a6f843d038924cb217b5e13b). If the algorithm is CCM, you must also call [`psa_aead_set_lengths`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gad3431e28d05002c2a7b0760610176050) before or after setting the nonce (for other algorithms, this is permitted but not needed). +4. Call [`psa_aead_update_ad`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga6d0eed03f832e5c9c91cb8adf2882569) as many times as needed. +5. Call [`psa_aead_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gaf6d49864951ca42136b4a9b71ea26e5c) as many times as needed. You can use [`PSA_AEAD_UPDATE_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_UPDATE_OUTPUT_SIZE) or [`PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE) to determine the size of the output buffer. +6. Finally: + * When encrypting, call [`psa_aead_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga759791bbe1763b377c3b5447641f1fc8) to obtain the last part of the ciphertext and the authentication tag. You can use [`PSA_AEAD_FINISH_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_FINISH_OUTPUT_SIZE) or [`PSA_AEAD_FINISH_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_FINISH_OUTPUT_MAX_SIZE) to determine the size of the output buffer. + * When decrypting, call [`psa_aead_verify`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae0280e2e61a185b893c36d858453f0d0) to obtain the last part of the plaintext and check the authentication tag. You can use [`PSA_AEAD_VERIFY_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_VERIFY_OUTPUT_SIZE) or [`PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE) to determine the size of the output buffer. + +If you need to interrupt the operation after calling the setup function without calling the finish or verify function, call [`psa_aead_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae8a5f93d92318c8f592ee9fbb9d36ba0). + +### Miscellaneous cipher operation management + +The equivalent of `mbedtls_cipher_reset` is to call [`psa_cipher_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gaad482cdca2098bca0620596aaa02eaa4) or [`psa_aead_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae8a5f93d92318c8f592ee9fbb9d36ba0). Note that you must set the key again with a setup function: the PSA API does not have a special way to reuse an operation object with the same key. + +There is no equivalent for the `mbedtls_cipher_get_xxx` functions to extract information from an ongoing PSA cipher or AEAD operation. Applications that need this information will need to save it from the key and operation parameters. + +## Hashes and MAC + +The PSA API groups functions by purpose rather than by underlying primitive: there is a MAC API (equivalent to `md.h` for HMAC, and `cmac.h` for CMAC) and a hash API (equivalent to `md.h` for hashing). There is no special API for a particular hash algorithm (`md5.h`, `sha1.h`, `sha256.h`, `sha512.h`, `sha3.h`). To migrate code using those low-level modules, please follow the recommendations in the following section, using the same principles as the corresponding `md.h` API. + +The PSA API does have a direct interface for the AES-CMAC-PRF-128 from RFC 4615 at the time of writing. You can calculate it using the interface to AES-CMAC. + +### Hash mechanism selection + +The equivalent to `mbedtls_md_type_t` and `MBEDTLS_MD` constants is the type `psa_algorithm_t` and `PSA_ALG_xxx` constants (the type encompasses all categories of cryptographic algorithms, not just hashes). PSA offers a similar selection of algorithms, but note that SHA-1 and SHA-2 are spelled slightly differently. + +| Mbed TLS constant | PSA constant | +| ---------------------- | ------------------- | +| `MBEDTLS_MD_MD5` | `PSA_ALG_MD5` | +| `MBEDTLS_MD_SHA1` | `PSA_ALG_SHA_1` | +| `MBEDTLS_MD_SHA224` | `PSA_ALG_SHA_224` | +| `MBEDTLS_MD_SHA256` | `PSA_ALG_SHA_256` | +| `MBEDTLS_MD_SHA384` | `PSA_ALG_SHA_384` | +| `MBEDTLS_MD_SHA512` | `PSA_ALG_SHA_512` | +| `MBEDTLS_MD_RIPEMD160` | `PSA_ALG_RIPEMD160` | +| `MBEDTLS_MD_SHA3_224` | `PSA_ALG_SHA3_224` | +| `MBEDTLS_MD_SHA3_256` | `PSA_ALG_SHA3_256` | +| `MBEDTLS_MD_SHA3_384` | `PSA_ALG_SHA3_384` | +| `MBEDTLS_MD_SHA3_512` | `PSA_ALG_SHA3_512` | + +### MAC mechanism selection + +PSA Crypto has a generic API with the same functions for all MAC mechanisms. The mechanism is determined by a combination of an algorithm value of type [`psa_algorithm_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac2e4d47f1300d73c2f829a6d99252d69) and a key type value of type [`psa_key_type_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga63fce6880ca5933b5d6baa257febf1f6). + +* For HMAC, the algorithm is [`PSA_ALG_HMAC`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga70f397425684b3efcde1e0e34c28261f)`(hash)` where `hash` is the underlying hash algorithm (see “[Hash mechanism selection](#hash-mechanism-selection)”), + for example `PSA_ALG_HMAC(PSA_ALG_SHA_256)` for HMAC-SHA-256. + The key type is [`PSA_KEY_TYPE_HMAC`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_KEY_TYPE_HMAC) regardless of the hash algorithm. +* For CMAC, the algorithm is [`PSA_ALG_CMAC`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_ALG_CMAC) regardless of the underlying block cipher. The key type determines the block cipher: + [`PSA_KEY_TYPE_AES`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga6ee54579dcf278c677eda4bb1a29575e), + [`PSA_KEY_TYPE_ARIA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#c.PSA_KEY_TYPE_ARIA), + [`PSA_KEY_TYPE_CAMELLIA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gad8e5da742343fd5519f9d8a630c2ed81) or + [`PSA_KEY_TYPE_DES`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga577562bfbbc691c820d55ec308333138). + +### Hash and MAC mechanism availability + +For each key type value `PSA_KEY_TYPE_xxx`, the symbol `PSA_WANT_KEY_TYPE_xxx` is defined with a nonzero value if the library is built with support for that key type. For each algorithm value `PSA_ALG_yyy`, the symbol `PSA_WANT_ALG_yyy` is defined with a nonzero value if the library is built with support for that algorithm. For a compound mechanism, all parts must be supported. In particular, for HMAC, all three of `PSA_WANT_KEY_TYPE_HMAC`, `PSA_WANT_ALG_HMAC` and the underlying hash must be enabled. (A configuration with only one of `PSA_WANT_KEY_TYPE_HMAC` and `PSA_WANT_ALG_HMAC` is technically possible but not useful.) + +For example, to test if HMAC-SHA-256 is supported, in the legacy API, you could write: +``` +#if defined(MBEDTLS_MD_C) && defined(MBEDTLS_SHA256_C) +``` +The equivalent in the PSA API is +``` +#if PSA_WANT_KEY_TYPE_HMAC && PSA_WANT_ALG_HMAC && PSA_WANT_ALG_SHA_256 +``` + +To test if AES-CMAC is supported, in the legacy API, you could write: +``` +if defined(MBEDTLS_AES_C) && defined(MBEDTLS_CMAC_C) +``` +The equivalent in the PSA API is +``` +#if PSA_WANT_KEY_TYPE_AES && PSA_WANT_ALG_CMAC +``` + +### Hash algorithm metadata + +There is no equivalent to the type `mbedtls_md_info_t` and the functions `mbedtls_md_info_from_type` and `mbedtls_md_get_type` in the PSA API because it is unnecessary. All macros and functions operate directly on algorithm (`psa_algorithm_t`, `PSA_ALG_xxx` constants). + +| Legacy macro | PSA macro | +| ------------ | --------- | +| `MBEDTLS_MD_MAX_SIZE` | [`PSA_HASH_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_HASH_MAX_SIZE) | +| `MBEDTLS_MD_MAX_BLOCK_SIZE` | [`PSA_HMAC_MAX_HASH_BLOCK_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_HMAC_MAX_HASH_BLOCK_SIZE) | +| `mbedtls_md_get_size` | [`PSA_HASH_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_HASH_LENGTH) | +| `mbedtls_md_get_size_from_type` | [`PSA_HASH_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_HASH_LENGTH) | + +The following features have no PSA equivalent: + +* `mbedtls_md_list`: the PSA API does not currently have a discovery mechanism for cryptographic mechanisms, but one may be added in the future. +* `mbedtls_md_info_from_ctx` +* `mbedtls_cipher_info_from_string`, `mbedtls_md_get_name`: there is no equivalent of Mbed TLS's lookup based on a (nonstandard) name. + +### Hash calculation + +The equivalent of `mbedtls_md` for a one-shot hash calculation is [`psa_hash_compute`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1gac69f7f19d96a56c28cf3799d11b12156). In addition, to compare the hash of a message with an expected value, you can call [`psa_hash_compare`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga0c08f4797bec96b886c8c8d7acc2a553) instead of `mbedtls_md` followed by `memcmp` or a constant-time equivalent. + +For a multi-part hash calculation, the legacy process is as follows: + +1. Create a digest context of type `mbedtls_md_context_t` and initialize it with `mbedtls_md_init`. +2. Call `mbedtls_md_setup` to select the hash algorithm, with `hmac=0`. Then call `mbedtls_md_starts` to start the hash operation. +3. Call `mbedtls_md_update` as many times as necessary. +4. Call `mbedtls_md_finish`. If verifying the hash against an expected value, compare the result with the expected value. +5. Finally free the resources associated with the operation object by calling `mbedtls_md_free`. + +The equivalent process in the PSA API is as follows: + +1. Create an operation object of type [`psa_hash_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga3c4205d2ce66c4095fc5c78c25273fab) and zero-initialize it (or use the corresponding `INIT` macro). +2. Call [`psa_hash_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga8d72896cf70fc4d514c5c6b978912515) to specify the algorithm. +3. Call [`psa_hash_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga65b16ef97d7f650899b7db4b7d1112ff) as many times as necessary. +4. To obtain the hash, call [`psa_hash_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga4795fd06a0067b0adcd92e9627b8c97e). Alternatively, to verify the hash against an expected value, call [`psa_hash_verify`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga7be923c5700c9c70ef77ee9b76d1a5c0). + +If you need to interrupt the operation after calling the setup function without calling the finish or verify function, call [`psa_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1gab0b4d5f9912a615559497a467b532928). + +There is no equivalent to `mbedtls_md_file` in the PSA API. Load the file data and calculate its hash. + +### MAC key management + +The legacy API and the PSA API have a different organization of operations in several respects: + +* In the legacy API, each operation object contains the necessary key material. In the PSA API, an operation object contains a reference to a key object. To perform a cryptographic operation, you must create a key object first. However, for a one-shot operation, you do not need an operation object, just a single function call. +* The legacy API uses the same interface for authenticated and non-authenticated ciphers, while the PSA API has separate functions. +* The legacy API uses the same functions for encryption and decryption, while the PSA API has separate functions where applicable. + +Here is an overview of the lifecycle of a key object. + +1. First define the attributes of the key by filling a [`psa_key_attributes_t` structure](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga0ec645e1fdafe59d591104451ebf5680). You need to set the following parameters: + * Call [`psa_set_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga6857ef0ecb3fa844d4536939d9c64025) to set the key type to the desired `PSA_KEY_TYPE_xxx` value (see “[Cipher mechanism selection](#cipher-mechanism-selection)”). + * Call [`psa_set_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaf61683ac87f87687a40262b5afbfa018) to set the key's size in bits. This is optional with `psa_import_key`, which determines the key size from the length of the key material. + * Call [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) to set the algorithm to the desired `PSA_ALG_xxx` value (see “[Cipher mechanism selection](#cipher-mechanism-selection)”). By design, the same key cannot be used with multiple algorithms. + * Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de) to enable at least [`PSA_KEY_USAGE_SIGN_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#c.PSA_KEY_USAGE_SIGN_MESSAGE) to calculate a MAC or [`PSA_KEY_USAGE_VERIFY_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#c.PSA_KEY_USAGE_VERIFY_MESSAGE) to verify the MAC of a message. To allow both directions, use the flag mask `PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE`. +2. Call one of the key creation functions, passing the attributes defined in the previous step, to get an identifier of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t) to the key object. + * Use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b) to directly import key material. + * If the key is randomly generated, use [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). + * If the key is derived from other material (for example from a key exchange), use the [key derivation interface](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/) and create the key with [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1). +3. Call the functions in the following sections to perform operations on the key. The same key object can be used in multiple operations. +4. To free the resources used by the key object, call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) after all operations with that key are finished. + +### MAC calculation + +The process for a HMAC operation in the legacy API is as follows: + +1. Create a digest context of type `mbedtls_md_context_t` and initialize it with `mbedtls_md_init`. +2. Call `mbedtls_md_setup` to select the hash algorithm, with `hmac=1`. Then call `mbedtls_md_hmac_starts` to set the key. +3. Call `mbedtls_md_hmac_update` as many times as necessary. +4. Call `mbedtls_md_hmac_finish`. If verifying the MAC against an expected value, compare the result with the expected value. Note that this comparison should be in constant time to avoid a side channel vulnerability, for example using `mbedtls_ct_memcmp`. +5. Finally free the resources associated with the operation object by calling `mbedtls_md_free`. + +The process for a CMAC operation in the legacy API is as follows: + +1. Create a cipher context of type `mbedtls_cipher_context_t` and initialize it with `mbedtls_cipher_init`. +2. Call `mbedtls_cipher_setup` to select the block cipher. Then call `mbedtls_md_cmac_starts` to set the key. +3. Call `mbedtls_cipher_cmac_update` as many times as necessary. +4. Call `mbedtls_cipher_cmac_finish`. If verifying the MAC against an expected value, compare the result with the expected value. Note that this comparison should be in constant time to avoid a side channel vulnerability, for example using `mbedtls_ct_memcmp`. +5. Finally free the resources associated with the operation object by calling `mbedtls_cipher_free`. + +The process in the PSA API to calculate a MAC is as follows: + +1. Create an operation object of type [`psa_mac_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1ga78f0838b0c4e3db28b26355624d4bd37) and zero-initialize it (or use the corresponding `INIT` macro). +2. Call [`psa_mac_sign_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1ga03bc3e3c0b7e55b20d2a238e418d46cd) to specify the algorithm and the key. See “[MAC key management](#mac-key-management)” for how to obtain a key identifier. +3. Call [`psa_mac_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1ga5560af371497babefe03c9da4e8a1c05) as many times as necessary. +4. To obtain the MAC, call [`psa_mac_sign_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gac22bc0125580c96724a09226cfbc97f2). + +To verify a MAC against an expected value, use the following process instead: + +1. Create an operation object of type [`psa_mac_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1ga78f0838b0c4e3db28b26355624d4bd37) and zero-initialize it (or use the corresponding `INIT` macro). +2. Call [`psa_mac_verify_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1ga08ae327fcbc5f8e201172fe11e536984) to specify the algorithm and the key. See “[MAC key management](#mac-key-management)” for how to obtain a key identifier. +3. Call [`psa_mac_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1ga5560af371497babefe03c9da4e8a1c05) as many times as necessary. +4. To verify the MAC against an expected value, call [`psa_mac_verify_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gac92b2930d6728e1be4d011c05d485822). + +If you need to interrupt the operation after calling the setup function without calling the finish function, call [`psa_mac_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gacd8dd54855ba1bc0a03f104f252884fd). + +The PSA API also offers functions for a one-shot MAC calculation, similar to `mbedtls_cipher_cmac`: + +* [`psa_mac_compute`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gabf02ebd3595ea15436967092b5d52878) to calculate the MAC of a buffer in memory. +* [`psa_mac_verify`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gaf6988545df5d5e2466c34d753443b15a) to verify the MAC of a buffer in memory against an expected value. + +In both cases, see “[MAC key management](#mac-key-management)” for how to obtain a key identifier. + +### Miscellaneous hash or MAC operation management + +The equivalent of `mbedtls_md_reset`, `mbedtls_md_hmac_reset` or `mbedtls_cmac_reset` is to call [`psa_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1gab0b4d5f9912a615559497a467b532928) or [`psa_mac_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gacd8dd54855ba1bc0a03f104f252884fd). Note that you must call a setup function to specify the algorithm and the key (for MAC) again, and they can be different ones. + +The equivalent of `mbedtls_md_clone` to clone a hash operation is [`psa_hash_clone`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__hash/#group__hash_1ga39673348f3302b4646bd780034a5aeda). A PSA MAC operation cannot be cloned. + +## Key derivation + +### HKDF + +PSA Crypto provides access to HKDF, HKDF-Extract and HKDF-Expand via its [key derivation interface](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/). This is a generic interface using an operation object with one function call for each input and one function call for each output. + +1. Create an operation object of type [`psa_key_derivation_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga5f099b63799a0959c3d46718c86c2609) and zero-initialize it (or use the corresponding `INIT` macro). +2. Call [`psa_key_derivation_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gac0b6a76e45cceb1862752bf041701859) to select the algorithm, which is a value of type [`psa_algorithm_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac2e4d47f1300d73c2f829a6d99252d69). For HKDF and variants, use one of the macros [`PSA_ALG_HKDF`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_ALG_HKDF), [`PSA_ALG_HKDF_EXTRACT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_ALG_HKDF_EXTRACT) or [`PSA_ALG_HKDF_EXPAND`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_ALG_HKDF_EXPAND) with the [hash algorithm](#hash-mechanism-selection) passed as an argument. For example `PSA_ALG_HKDF(PSA_ALG_SHA_256)` selects HKDF-SHA-256. +3. Call [`psa_key_derivation_input_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga8fd934dfb0ca45cbf89542ef2a5494c2) on each of the inputs in the order listed below. (Use [`psa_key_derivation_input_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gab2d7ce8705dd8e4a093f4b8a21a0c15a) instead for an input that is a PSA key object.) The input step value for each step is as follows: + 1. [`PSA_KEY_DERIVATION_INPUT_SALT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__derivation/#group__derivation_1gab62757fb125243562c3947a752470d4a) for the salt used during the extraction step. Omit this step for HKDF-Expand. For HKDF, you may omit this step if the salt is empty. + 2. [`PSA_KEY_DERIVATION_INPUT_SECRET`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__derivation/#group__derivation_1ga0ddfbe764baba995c402b1b0ef59392e) for the secret input. + 3. [`PSA_KEY_DERIVATION_INPUT_INFO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__derivation/#group__derivation_1gacef8df989e09c769233f4b779acb5b7d) for the info string used during the expansion step. Omit this step for HKDF-Extract. +4. Call [`psa_key_derivation_output_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga06b7eb34a2fa88965f68e3d023fa12b9) to obtain the output of the derivation. You may call this function more than once to retrieve the output in successive chunks. Use [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1) instead if you want to use a chunk as a PSA key. +5. Call [`psa_key_derivation_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) to free the resources associated with the key derivation object. + +### PKCS#5 module + +Applications currently using `mbedtls_pkcs5_pbkdf2_hmac` or `mbedtls_pkcs5_pbkdf2_hmac_ext` can switch to the PSA key derivation API for PBKDF2 (not yet implemented at the time of writing, scheduled to be released in Mbed TLS 3.5). This is a generic interface using an operation object with one function call for each input and one function call for each output. + +1. Create an operation object of type [`psa_key_derivation_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga5f099b63799a0959c3d46718c86c2609) and zero-initialize it (or use the corresponding `INIT` macro). +2. Call [`psa_key_derivation_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gac0b6a76e45cceb1862752bf041701859) to select the algorithm, which is a value of type [`psa_algorithm_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac2e4d47f1300d73c2f829a6d99252d69). For PBKDF2-HMAC, select `PSA_ALG_PBKDF2_HMAC(hash)` where `hash` is the underlying hash algorithm (see “[Hash mechanism selection](#hash-mechanism-selection)”). +3. Call `psa_key_derivation_input_cost` with the step `PSA_KEY_DERIVATION_INPUT_COST` to select the iteration count. +4. Call [`psa_key_derivation_input_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga8fd934dfb0ca45cbf89542ef2a5494c2) on each of the inputs in the order listed below. (Use [`psa_key_derivation_input_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gab2d7ce8705dd8e4a093f4b8a21a0c15a) instead for an input that is a PSA key object.) The input step value for each step is as follows: + 1. [`PSA_KEY_DERIVATION_INPUT_SALT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__derivation/#group__derivation_1gab62757fb125243562c3947a752470d4a) for the salt used during the extraction step. You may repeat this step to pass the salt in pieces (for example a salt and a pepper). + 2. [`PSA_KEY_DERIVATION_INPUT_SECRET`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__derivation/#group__derivation_1ga0ddfbe764baba995c402b1b0ef59392e) for the password. +5. Call [`psa_key_derivation_output_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga06b7eb34a2fa88965f68e3d023fa12b9) to obtain the output of the derivation. You may call this function more than once to retrieve the output in successive chunks. + Use [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1) instead if you want to use a chunk as a PSA key. + If you want to verify the output against an expected value (for authentication, rather than to derive key material), call `psa_key_derivation_verify_bytes` or `psa_key_derivation_verify_key` instead of `psa_key_derivation_output_bytes`. +6. Call [`psa_key_derivation_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) to free the resources associated with the key derivation object. + +The function `mbedtls_pkcs5_pbes2` is only inteded as a support function to parse encrypted private keys in the PK module. It has no PSA equivalent. + +### PKCS#12 module + +The functions `mbedtls_pkcs12_derivation` and `mbedtls_pkcs12_pbes2` are only intended as supports function to parse encrypted private keys in the PK module. They have no PSA equivalent. + +## Random generation + +### Random generation interface + +The PSA subsystem has an internal random generator. As a consequence, you do not need to instantiate one manually, so most applications using PSA crypto do not need the interfaces from `entropy.h`, `ctr_drbg.` and `hmac_drbg.h`. + +The PSA API uses its internal random generator to generate keys (`psa_generate_key`), nonces for encryption (`psa_cipher_generate_iv`, `psa_cipher_encrypt`, `psa_aead_generate_nonce`, `psa_aead_encrypt`, `psa_asymmetric_encrypt`), and other random material as needed. If you need random data for some other purposes, call [`psa_generate_random`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). + +### Entropy sources + +Unless explicitly configured otherwise, the PSA random generator uses the default entropy sources configured through the legacy interface (`MBEDTLS_ENTROPY_xxx` symbols). Its set of sources is equivalent to an entropy object configured with `mbedtls_entropy_init`. + +A future version of Mbed TLS will include a PSA interface for configuring entropy sources. This is likely to replace the legacy interface in Mbed TLS 4.0. + +### Deterministic pseudorandom generation + +The PSA API does not have a dedicated interface for pseudorandom generation. The [key derivation interface](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/) can serve a similar purpose in some applications, but it does not offer CTR\_DRBG or HMAC\_DRBG. If you need these algorithms, keep using `ctr_drbg.h` and `hmac_drbg.h`, but note that they may be removed from the public API in Mbed TLS 4.0. + +## Asymmetric cryptography + +The PSA API supports RSA (see “[RSA mechanism selection](#rsa-mechanism-selection)”), elliptic curve cryptography (see “[ECC mechanism selection](#elliptic-curve-mechanism-selection)” and “[EC-JPAKE](#ec-jpake)”) and finite-field Diffie-Hellman (see “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)”). + +### Key lifecycle for asymmetric cryptography + +In the PSA API, keys are referenced by an identifier of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t). +(Some documentation references [`mbedtls_svc_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv420mbedtls_svc_key_id_t); the two types are identical except when the library is configured for use in a multi-client cryptography service.) +The PSA key identifier tends to play the same role as a `mbedtls_pk_context`, `mbedtls_rsa_context` or `mbedtls_ecp_keypair` structure in the legacy API; however there are major differences in the way the two APIs can be used to create keys or to obtain information about a key. + +Here is an overview of the lifecycle of a PSA key object. + +1. First define the attributes of the key by filling a [`psa_key_attributes_t` structure](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga0ec645e1fdafe59d591104451ebf5680). You need to set the following parameters: + * Call [`psa_set_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga6857ef0ecb3fa844d4536939d9c64025) to set the key type to the desired `PSA_KEY_TYPE_xxx` value (see “[RSA mechanism selection](#rsa-mechanism-selection)”, “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” and “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)”). + * Call [`psa_set_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaf61683ac87f87687a40262b5afbfa018) to set the key's conceptual size in bits. This is optional with `psa_import_key`, which determines the key size from the length of the key material. + * Call [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) to set the algorithm to the desired `PSA_ALG_xxx` value (see “[RSA mechanism selection](#rsa-mechanism-selection)”, “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” and “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)” as well as “[Public-key cryptography policies](#public-key-cryptography-policies)”). + * Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de) to enable the desired usage types (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). +2. Call one of the key creation functions, passing the attributes defined in the previous step, to get an identifier of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t) to the key object. + * Use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b) to directly import key material. + * If the key is randomly generated, use [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). + * If the key is derived from other material (for example from a key exchange), use the [key derivation interface](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/) and create the key with [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1). +3. Call the functions in the following sections to perform operations on the key. The same key object can be used in multiple operations. +4. To free the resources used by the key object, call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) after all operations with that key are finished. + +### Public-key cryptography policies + +A key's policy indicates what algorithm(s) it can be used with (usage algorithm policy) and what operations are permitted (usage flags). + +The following table lists the relevant usage flags for asymmetric cryptography. You can pass an bitwise-or of those flags to [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de). + +| Usage | Flag | +| ----- | ---- | +| export public key | 0 (always permitted) | +| export private key | [`PSA_KEY_USAGE_EXPORT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga7dddccdd1303176e87a4d20c87b589ed) | +| Sign a message directly | [`PSA_KEY_USAGE_SIGN_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga552117ac92b79500cae87d4e65a85c54) | +| Sign an already-calculated hash | at least one of [`PSA_KEY_USAGE_SIGN_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga552117ac92b79500cae87d4e65a85c54) or [`PSA_KEY_USAGE_SIGN_HASH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga552117ac92b79500cae87d4e65a85c54) | +| Verify a message directly | [`PSA_KEY_USAGE_VERIFY_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gabea7ec4173f4f943110329ac2953b2b1) | +| Verify an already-calculated hash | at least one of [`PSA_KEY_USAGE_VERIFY_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gabea7ec4173f4f943110329ac2953b2b1) or [`PSA_KEY_USAGE_VERIFY_HASH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gafadf131ef2182045e3483d03aadaa1bd) | +| Encryption | [`PSA_KEY_USAGE_`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga75153b296d045d529d97203a6a995dad) | +| Decryption | [`PSA_KEY_USAGE_`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gac3f2d2e5983db1edde9f142ca9bf8e6a) | +| Key agreement | [`PSA_KEY_USAGE_DERIVE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gaf19022acc5ef23cf12477f632b48a0b2) | + +The sections “[RSA mechanism selection](#rsa-mechanism-selection)”, “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” and “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)” cover the available algorithm values for each key type. Normally, a key can only be used with a single algorithm, following standard good practice. However, there are two ways to relax this requirement. + +* Many signature algorithms encode a hash algorithm. Sometimes the same key may need to be used to sign messages with multiple different hashes. In an algorithm policy, you can use [`PSA_ALG_ANY_HASH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_ALG_ANY_HASH) instead of a hash algorithm value to allow the key to be used with any hash. For example, `psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH))` allows the key to be used with RSASSA-PSS, with different hash algorithhms in each operation. +* In addition to the algorithm (or wildcard) selected with [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98), you can use [`psa_set_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaffa134b74aa52aa3ed9397fcab4005aa) to permit a second algorithm (or wildcard). This is intended for scenarios where a key is normally used with a single algorithm, but needs to be used with a different algorithm for enrollment (such as an ECDH key for which an ECDSA proof-of-possession is also required). + +### Asymmetric cryptographic mechanisms + +#### RSA mechanism selection + +The PK types `MBEDTLS_PK_RSA`, `MBEDTLS_PK_RSASSA_PSS` and `MBEDTLS_PK_RSA_ALT` correspond to RSA key types in the PSA API. In the PSA API, key pairs and public keys are separate object types. +See “[RSA-ALT interface](#rsa-alt-interface)” for more information about `MBEDTLS_PK_RSA_ALT`. + +The PSA API uses policies and algorithm parameters rather than key types to distinguish between `MBEDTLS_PK_RSA` and `MBEDTLS_PK_RSASSA_PSS`. The algorithm selection also replaces the use of `mbedtls_rsa_set_padding` on an `mbedtls_rsa_context` object. See the list of algorithms below and the signature and encryption sections for more information. + +An RSA public key has the type [`PSA_KEY_TYPE_RSA_PUBLIC_KEY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga9ba0878f56c8bcd1995ac017a74f513b). + +An RSA key pair has the type [`PSA_KEY_TYPE_RSA_KEY_PAIR`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga11745b110166e927e2abeabc7d532051). A key with this type can be used both for private-key and public-key operations (there is no separate key type for a private key without the corresponding public key). +You can always use a private key for operations on the corresponding public key (as long as the policy permits it). + +The following cryptographic algorithms work with RSA keys: + +* PKCS#1v1.5 RSA signature: [`PSA_ALG_RSA_PKCS1V15_SIGN`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga702ff75385a6ae7d4247033f479439af), [`PSA_ALG_RSA_PKCS1V15_SIGN_RAW`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga4215e2a78dcf834e9a625927faa2a817). +* PKCS#1v1.5 RSA encryption: [`PSA_ALG_RSA_PKCS1V15_CRYPT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga4c540d3abe43fb9abcb94f2bc51acef9). +* PKCS#1 RSASSA-PSS signature: [`PSA_ALG_RSA_PSS`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga62152bf4cb4bf6aace5e1be8f143564d), [`PSA_ALG_RSA_PSS_ANY_SALT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga9b7355a2cd6bde88177634d539127f2b). +* PKCS#1 RSAES-OAEP encryption: [`PSA_ALG_RSA_OAEP`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gaa1235dc3fdd9839c6c1b1a9857344c76). + +#### Elliptic curve mechanism selection + +The PK types `MBEDTLS_PK_ECKEY`, `MBEDTLS_PK_ECKEY_DH` and `MBEDTLS_PK_ECDSA` correspond to RSA key types in the PSA API. In the PSA API, key pairs and public keys are separate object types. The PSA API uses policies and algorithm parameters rather than key types to distinguish between the PK EC types. + +An ECC public key has the type [`PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gad54c03d3b47020e571a72cd01d978cf2) where `curve` is a curve family identifier. + +An ECC key pair has the type [`PSA_KEY_TYPE_ECC_KEY_PAIR(curve)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0b6f5d4d5037c54ffa850d8059c32df0) where `curve` is a curve family identifier. A key with this type can be used both for private-key and public-key operations (there is no separate key type for a private key without the corresponding public key). +You can always use a private key for operations on the corresponding public key (as long as the policy permits it). + +A curve is fully determined by a curve family identifier and the private key size in bits. The following table gives the correspondence between legacy and PSA elliptic curve designations. + +| Mbed TLS legacy curve identifier | PSA curve family | Curve bit-size | +| -------------------------------- | ---------------- | -------------- | +| `MBEDTLS_ECP_DP_SECP192R1` | [`PSA_ECC_FAMILY_SECP_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 192 | +| `MBEDTLS_ECP_DP_SECP224R1` | [`PSA_ECC_FAMILY_SECP_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 224 | +| `MBEDTLS_ECP_DP_SECP256R1` | [`PSA_ECC_FAMILY_SECP_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 256 | +| `MBEDTLS_ECP_DP_SECP384R1` | [`PSA_ECC_FAMILY_SECP_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 384 | +| `MBEDTLS_ECP_DP_SECP521R1` | [`PSA_ECC_FAMILY_SECP_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 521 | +| `MBEDTLS_ECP_DP_BP256R1` | [`PSA_ECC_FAMILY_BRAINPOOL_P_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac1643f1baf38b30d07c20a6eac697f15) | 256 | +| `MBEDTLS_ECP_DP_BP384R1` | [`PSA_ECC_FAMILY_BRAINPOOL_P_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac1643f1baf38b30d07c20a6eac697f15) | 384 | +| `MBEDTLS_ECP_DP_BP512R1` | [`PSA_ECC_FAMILY_BRAINPOOL_P_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac1643f1baf38b30d07c20a6eac697f15) | 512 | +| `MBEDTLS_ECP_DP_CURVE25519` | [`PSA_ECC_FAMILY_MONTGOMERY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga1f624c5cdaf25b21287af33024e1aff8) | 255 | +| `MBEDTLS_ECP_DP_SECP192K1` | [`PSA_ECC_FAMILY_SECP_K1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 192 | +| `MBEDTLS_ECP_DP_SECP224K1` | not supported | 224 | +| `MBEDTLS_ECP_DP_SECP256K1` | [`PSA_ECC_FAMILY_SECP_K1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 256 | +| `MBEDTLS_ECP_DP_CURVE448` | [`PSA_ECC_FAMILY_MONTGOMERY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga1f624c5cdaf25b21287af33024e1aff8) | 448 | + +The following cryptographic algorithms work with ECC keys: + +* ECDH key agreement (including X25519 and X448): [`PSA_ALG_ECDH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab2dbcf71b63785e7dd7b54a100edee43). +* ECDSA: [`PSA_ALG_ECDSA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7e3ce9f514a227d5ba5d8318870452e3), [`PSA_ALG_ECDSA_ANY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga51d6b6044a62e33cae0cf64bfc3b22a4), [`PSA_ALG_DETERMINISTIC_ECDSA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga11da566bcd341661c8de921e2ca5ed03). + +#### Diffie-Hellman mechanism selection + +A finite-field Diffie-Hellman public key has the type [`PSA_KEY_TYPE_DH_PUBLIC_KEY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gaa22f0f2ea89b929f2fadc19890cc5d5c). + +A finite-field Diffie-Hellman key pair has the type [`PSA_KEY_TYPE_DH_KEY_PAIR`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab4f857c4cd56f5fe65ded421e61bcc8c). A key with this type can be used both for private-key and public-key operations (there is no separate key type for a private key without the corresponding public key). + +The PSA API only supports Diffie-Hellman with predefined groups. A group is fully determined by a group family identifier and the public key size in bits. + +| Mbed TLS DH group P value | PSA DH group family | Bit-size | +| ------------------------- | ------------------- | -------- | +| `MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN` | [`PSA_DH_FAMILY_RFC7919`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7be917e67fe4a567fb36864035822ff7) | 2048 | +| `MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN` | [`PSA_DH_FAMILY_RFC7919`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7be917e67fe4a567fb36864035822ff7) | 3072 | +| `MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN` | [`PSA_DH_FAMILY_RFC7919`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7be917e67fe4a567fb36864035822ff7) | 4096 | +| `MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN` | [`PSA_DH_FAMILY_RFC7919`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7be917e67fe4a567fb36864035822ff7) | 6144 | +| `MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN` | [`PSA_DH_FAMILY_RFC7919`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7be917e67fe4a567fb36864035822ff7) | 8192 | + +A finite-field Diffie-Hellman key can be used for key agreement with the algorithm [`PSA_ALG_FFDH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0ebbb6f93a05b6511e6f108ffd2d1eb4). + +### Creating keys for asymmetric cryptography + +The easiest way to create a key pair object is by randomly generating it with [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). Compared with the low-level functions from the legacy API (`mbedtls_rsa_gen_key`, `mbedtls_ecp_gen_privkey`, `mbedtls_ecp_gen_keypair`, `mbedtls_ecp_gen_keypair_base`, `mbedtls_ecdsa_genkey`), this directly creates an object that can be used with high-level APIs, but removes some of the flexibility. Note that if you want to export the generated private key, you must pass the flag [`PSA_KEY_USAGE_EXPORT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga7dddccdd1303176e87a4d20c87b589ed) to [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de); exporting the public key with [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) is always permitted. + +For RSA keys, `psa_generate_key` always uses 65537 as the public exponent. If you need a different public exponent, use the legacy interface to create the key then import it as described in “[Importing legacy keys via the PK module](#importing-legacy-keys-via-the-pk-module)”. + +To create a key object from existing material, use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). While this function has the same basic goal as the PK parse functions (`mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`), it is limited to a single format that just contains the number(s) that make up the key, with very little metadata. This format is a substring of the formats accepted by the PK functions (except for finite-field Diffie-Hellman which the PK module does not support). The table below summarizes the PSA import/export format for key pairs and public keys; see the documentation of [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) for more details. + +| Key type | PSA import/export format | +| -------- | ------------------------ | +| RSA key pair | PKCS#1 RSAPrivateKey DER encoding (including both private exponent and CRT parameters) | +| RSA public key | PKCS#1 RSAPublicKey DER encoding | +| ECC key pair | Fixed-length private value (not containing the public key) | +| ECC public key (Weierstrass curve) | Fixed-length uncompressed point | +| ECC public key (Montgomery curve) | Fixed-length public value | +| FFDH key pair | Fixed-length private value (not containing the public key) | +| FFDH public key | Fixed-length public value | + +There is no equivalent of `mbedtls_pk_parse_keyfile` and `mbedtls_pk_parse_public_keyfile`. Either call the legacy function or load the file data manually. + +A future extension of the PSA API will support other import formats. Until those are implemented, see the following subsections for ways to use the PK module for key parsing and construct a PSA key object from the PK object. + +#### Importing legacy keys via the PK module + +You can use glue functions in the PK module to create a key object using the legacy API, then import that object into the PSA subsystem. This is useful for use cases that the PSA API does not currently cover, such as: + +* Parsing a key in a format with metadata without knowing its type ahead of time. +* Importing a key which you have in the form of a list of numbers, rather than the binary encoding required by `psa_import_key`. +* Importing a key with less information than what the PSA API needs, for example an ECC public key in compressed format, an RSA private key without the private exponent, or an RSA private key without the CRT parameters. +* Generating an RSA key with $e \ne 65537$. + +#### Importing a PK key by wrapping + +If you have a PK object, you can call `mbedtls_pk_wrap_as_opaque` to create a PSA key object with the same key material. (This function is only present in builds with `MBEDTLS_USE_PSA_CRYPTO` enabled. It is experimental and [will likely be replaced by a slightly different interface in a future version of Mbed TLS](https://github.com/Mbed-TLS/mbedtls/issues/7760)) This function automatically determines the PSA key type, and lets you specify the usage policy (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). Once you've called this function, you can destroy the PK object. This function calls `psa_import_key` internally; call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to destroy the PSA key object once your application no longer needs it. Common scenarios where this flow is useful are: + +* You have working code that's calling `mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`, `mbedtls_pk_parse_keyfile` or `mbedtls_pk_parse_public_keyfile` to create a PK object. +* You have working code that's using the `rsa.h` or `ecp.h` API to create a key object, and there is no PSA equivalent. + +You can use this flow to import an RSA key via a `mbedtls_rsa_context` object or an ECC key via a `mbedtls_ecp_keypair` object: + +1. Call `mbedtls_pk_init` then `mbedtls_pk_setup` to set up a PK context for the desired key type (`MBEDTLS_PK_RSA` or `MBEDTLS_PK_ECKEY`). +2. Call `mbedtls_pk_rsa` or `mbedtls_pk_ec` to obtain the underlying low-level context. +3. Call `mbedtls_rsa_xxx` or `mbedtls_ecp_xxx` functions to construct the desired key. For example: + * `mbedtls_rsa_import` or `mbedtls_rsa_import_raw` followed by `mbedtls_rsa_complete` to create an RSA private key without all the parameters required by the PSA API. + * `mbedtls_rsa_gen_key` to generate an RSA private key with a custom public exponent. +4. Call `mbedtls_pk_wrap_as_opaque` as described above to create a corresponding PSA key object. +5. Call `mbedtls_pk_free` to free the resources associated with the PK object. + +#### Importing a PK key by export-import + +This section explains how to export a PK object in the PSA import format. The process depends on the key type. You can use `mbedtls_pk_get_type` or `mbedtls_pk_can_do` to distinguish between RSA and ECC keys. The snippets below assume that the key is in an `mbedtls_pk_context pk`, and omit error checking. + +For an RSA private key: + +``` +unsigned char buf[PSA_EXPORT_KEY_PAIR_MAX_SIZE]; +size_t length = mbedtls_pk_write_key_der(&pk, buf, sizeof(buf)); +psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; +psa_set_key_attributes(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); +psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...); +psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...); +psa_key_id_t key_id = 0; +psa_import_key(&attributes, buf + sizeof(buf) - length, length, &key_id); +mbedtls_pk_free(&pk); +``` + +For an ECC private key (a future version of Mbed TLS [will provide a function to calculate the curve family](https://github.com/Mbed-TLS/mbedtls/issues/7764)): + +``` +unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; +size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk)); +mbedtls_ecp_keypair *ec = mbedtls_pk_ec(&pk); +mbedtls_ecp_write_key(ec, buf, length); +psa_ecc_curve_t curve = ...; // need to determine the curve family manually +psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; +psa_set_key_attributes(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); +psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...); +psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...); +psa_key_id_t key_id = 0; +psa_import_key(&attributes, buf, length, &key_id); +mbedtls_pk_free(&pk); +``` + +For an RSA or ECC public key: + +``` +unsigned char buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; +size_t length = mbedtls_pk_write_pubkey(&pk, buf, sizeof(buf)); +psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; +psa_set_key_attributes(&attributes, ...); // need to determine the type manually +psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...); +psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...); +psa_key_id_t key_id = 0; +psa_import_key(&attributes, buf + sizeof(buf) - length, length, &key_id); +mbedtls_pk_free(&pk); +``` + +#### Importing an elliptic curve key from ECP + +This section explains how to use the `ecp.h` API to create an elliptic curve key in a format suitable for `psa_import_key`. + +You can use this, for example, to import an ECC key in the form of a compressed point by calling `mbedtls_ecp_point_read_binary` then following the process below. + +The following code snippet illustrates how to import a private key which is initially in an `mbedtls_ecp_keypair` object. Error checks are omitted for simplicity. A future version of Mbed TLS [will provide a function to calculate the curve family](https://github.com/Mbed-TLS/mbedtls/issues/7764). + +``` +mbedtls_ecp_keypair ec; +mbedtls_ecp_keypair_init(&ec); +// Omitted: fill ec with key material +// (the public key will not be used and does not need to be set) +unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; +size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk)); +mbedtls_ecp_write_key(&ec, buf, length); +psa_ecc_curve_t curve = ...; // need to determine the curve family manually +psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; +psa_set_key_attributes(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); +psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...); +psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...); +psa_key_id_t key_id = 0; +psa_import_key(&attributes, buf, length, &key_id); +mbedtls_ecp_keypair_free(&ec); +``` +The following code snippet illustrates how to import a private key which is initially in an `mbedtls_ecp_keypair` object. Error checks are omitted for simplicity. + +``` +mbedtls_ecp_group grp; +mbedtls_ecp_group_init(&grp); +mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_...); +mbedtls_ecp_point pt; +mbedtls_ecp_point_init(&pt); +// Omitted: fill pt with key material +unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_PUBLIC_KEY_MAX_SIZE)]; +size_t length; +mbedtls_ecp_point_write_binary(&grp, &pt, &length, buf, sizeof(buf)); +psa_ecc_curve_t curve = ...; // need to determine the curve family manually +psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; +psa_set_key_attributes(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve)); +psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...); +psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...); +psa_key_id_t key_id = 0; +psa_import_key(&attributes, buf, length, &key_id); +mbedtls_ecp_point_free(&pt); +mbedtls_ecp_group_free(&grp); +``` + +### Key pair and public key metadata + +There is no equivalent to the type `mbedtls_pk_info_t` and the functions `mbedtls_pk_info_from_type` in the PSA API because it is unnecessary. All macros and functions operate directly on key type values (`psa_key_type_t`, `PSA_KEY_TYPE_xxx` constants) and algorithm values (`psa_algorithm_t`, `PSA_ALG_xxx` constants). + +You can call [`psa_get_key_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gacbbf5c11eac6cd70c87ffb936e1b9be2) to populate a structure with the attributes of a key, then functions such as [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918) and [`psa_get_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga5bee85c2164ad3d4c0d42501241eeb06) to obtain a key's type (`PSA_KEY_TYPE_xxx` value) and size (nominal size in bits). + +The bit-size from `psa_get_key_bits` is the same as the one from `mbedtls_pk_get_bitlen`. To convert to bytes as with `mbedtls_pk_get_len` or `mbedtls_rsa_get_len`, you can use the macro `PSA_BITS_TO_BYTES`; however note that the PSA API has generic macros for each related buffer size (export, signature size, etc.), so you should generally use those instead. The present document lists those macros where it explains the usage of the corresponding function. + +Most uses of `mbedtls_pk_get_type` and `mbedtls_pk_can_do` only require knowing a key's type as reported by [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918). If needed, you can also access a key's policy from its attributes, with [`psa_get_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaa1af20f142ca722222c6d98678a0c448), [`psa_get_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gac255da850a00bbed925390044f016b34) and [`psa_get_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga39803b62a97198cf630854db9b53c588). The algorithm policy also conveys the padding and hash information provided by `mbedtls_rsa_get_padding_mode` and `mbedtls_rsa_get_md_alg`. + +### Exporting a public key or a key pair + +To export a PSA key pair or public key, call [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf). If the key is a key pair, its policy must allow `PSA_KEY_USAGE_EXPORT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). + +To export a PSA public key or to export the public key of a PSA key pair object, call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062). This is always permitted regardless of the key's policy. + +The export format is the same format used for `psa_import_key`, described in “[Creating keys for asymmetric cryptography](#creating-keys-for-asymmetric-cryptography)” above. + +A future extension of the PSA API will support other export formats. Until those are implemented, see the following subsections for ways to use the PK module to format a PSA key. + +#### Exporting a PK key by wrapping + +You can wrap a PSA key object in a PK key context with `mbedtls_pk_setup_opaque`. This allows you to call functions such as `mbedtls_pk_write_key_der`, `mbedtls_pk_write_pubkey_der`, `mbedtls_pk_write_pubkey_pem`, `mbedtls_pk_write_key_pem` or `mbedtls_pk_write_pubkey` to export the key data in various formats. + +### Signature operations + +The equivalent of `mbedtls_pk_sign`, `mbedtls_rsa_pkcs1_sign`, `mbedtls_rsa_rsassa_pkcs1_v15_sign`, `mbedtls_rsa_rsassa_pss_sign` or `mbedtls_rsa_rsassa_pss_sign_ext` to sign an already calculated hash is [`psa_sign_hash`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga785e746a31a7b2a35ae5175c5ace3c5c). +The key must be a key pair allowing the usage `PSA_KEY_USAGE_SIGN_HASH` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). +Use [`PSA_SIGN_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_SIGN_OUTPUT_SIZE) or [`PSA_SIGNATURE_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_SIGNATURE_MAX_SIZE) (similar to `MBEDTLS_PK_SIGNATURE_MAX_SIZE`) to determine the size of the output buffer. + +The equivalent of `mbedtls_pk_verify` or `mbedtls_pk_verify_ext` to verify an already calculated hash is [`psa_verify_hash`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1gae2ffbf01e5266391aff22b101a49f5f5). +The key must be a public key or a key pair allowing the usage `PSA_KEY_USAGE_VERIFY_HASH` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). + +Generally, `psa_sign_hash` and `psa_verify_hash` require the input to have the correct length for the hash (this has historically not always been enforced in the corresponding legacy APIs). + +See also “[Restartable ECDSA signature](#restartable-ecdsa-signature)” for a restartable variant of this API. + +The PSA API also has functions [`psa_sign_message`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga963ecadae9c38c85826f9a13cf1529b9) and [`psa_verify_message`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga01c11f480b185a4268bebd013df7c14c). These functions combine the hash calculation with the signature calculation or verification. +For `psa_sign_message`, either the usage flag `PSA_KEY_USAGE_SIGN_MESSAGE` or `PSA_KEY_USAGE_SIGN_HASH` is sufficient. +For `psa_verify_message`, either the usage flag `PSA_KEY_USAGE_VERIFY_MESSAGE` or `PSA_KEY_USAGE_VERIFY_HASH` is sufficient. + +Most signature algorithms involve a hash algorithm. See “[Hash mechanism selection](#hash-mechanism-selection)”. + +The following subsections describe the PSA signature mechanisms that correspond to legacy Mbed TLS mechanisms. + +#### ECDSA signature + +In the PSA API, **the format of an ECDSA signature is the raw fixed-size format. This is different from the legacy API** which uses the ASN.1 DER format for ECDSA signatures. A future version of Mbed TLS [will provide a way to convert between the two formats](https://github.com/Mbed-TLS/mbedtls/issues/7765). + + +This is the mechanism provided by `mbedtls_pk_sign` and `mbedtls_pk_verify` for ECDSA keys, and by `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext`, `mbedtls_ecdsa_write_signature`, `mbedtls_ecdsa_write_signature` and `mbedtls_ecdsa_verify`, . + +The PSA API offers three algorithm constructors for ECDSA. They differ only for signature, and have exactly the same behavior for verification. + +* [`PSA_ALG_ECDSA(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7e3ce9f514a227d5ba5d8318870452e3) is a randomized ECDSA signature of a hash calculated with the algorithm `hash`. +* [`PSA_ALG_ECDSA_ANY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga51d6b6044a62e33cae0cf64bfc3b22a4) is equivalent to `PSA_ALG_ECDSA`, but does not require specifying a hash as part of the algorithm. It can only be used with `psa_sign_hash` and `psa_verify_hash`, with no constraint on the length of the hash. +* [`PSA_ALG_DETERMINISTIC_ECDSA(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga11da566bcd341661c8de921e2ca5ed03) is a deterministic ECDSA signature of a hash calculated with the algorithm `hash`. This is the same as the functionality offered by `MBEDTLS_ECDSA_DETERMINISTIC` in the legacy API. + * For `psa_sign_message` with `PSA_ALG_DETERMINISTIC_ECDSA`, the same hash algorithm is used to hash the message and to parametrize the deterministic signature generation. + +Unlike the legacy API, where `mbedtls_pk_sign` and `mbedtls_ecdsa_write_signature` automatically select deterministic ECDSA if both are available, the PSA API requires the application to select the preferred variant. ECDSA verification cannot distinguish between randomized and deterministic ECDSA (except in so far as if the same message is signed twice and the signatures are different, then at least one of the signatures is not the determinstic variant), so in most cases switching between the two is a compatible change. + +#### Restartable ECDSA signature + +There is a PSA API for interruptible public-key operations, offering similar functionality to the legacy restartable API (`mbedtls_pk_sign_restartable`, `mbedtls_pk_verify_restartable`, `mbedtls_ecdsa_sign_restartable`, `mbedtls_ecdsa_verify_restartable`, `mbedtls_ecdsa_write_signature_restartable`, `mbedtls_ecdsa_read_signature_restartable`). + +As of Mbed TLS 3.5, it is only implemented for ECDSA, for the same curves as the legacy API; this will likely be extended to ECDH in the short term. At the time of writing, no extension is planned to other curves or other algorithms. + +The flow of operations for an interruptible signature operation is as follows: + +1. Create an operation object of type [`psa_sign_hash_interruptible_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga6948d4653175b1b530a265540066a7e7) and zero-initialize it (or use the corresponding `INIT` macro). +2. Call [`psa_sign_hash_start`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga441988da830205182b3e791352537fac) with the private key object and the hash to verify. +3. Call [`psa_sign_hash_complete`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga79849aaa7004a85d2ffbc4b658a333dd) repeatedly until it returns a status other than `PSA_OPERATION_INCOMPLETE`. + +The flow of operations for an interruptible signature verification operation is as follows: + +1. Create an operation object of type [`psa_verify_hash_interruptible_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga537054cf4909ad1426331ae4ce7148bb) and zero-initialize it (or use the corresponding `INIT` macro). +2. Call [`psa_verify_hash_start`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga912eb51fb94056858f451f276ee289cb) with the private key object and the hash and signature to verify. +3. Call [`psa_verify_hash_complete`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga67fe82352bc2f8c0343e231a70a5bc7d) repeatedly until it returns a status other than `PSA_OPERATION_INCOMPLETE`. + +If you need to interrupt the operation after calling the start function without waiting for the complete function to return a success or failure status, call [`psa_sign_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1gae893a4813aa8e03bd201fe4f1bbbb403) or [`psa_verify_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga18dc9c0cc27d590c5e3b186094d90f88). + +Call [`psa_interruptible_set_max_ops`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga6d86790b31657c13705214f373af869e) to set the number of basic operations per call. This is the same unit as `mbedtls_ecp_set_max_ops`. + +#### PKCS#1 v1.5 RSA signature + +This mechanism corresponds to `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_rsa_pkcs1_sign` and `mbedtls_rsa_pkcs1_verify` for an RSA key, unless PSS has been selected with `mbedtls_rsa_set_padding` on the underlying RSA key context. This mechanism also corresponds to `mbedtls_rsa_rsassa_pkcs1_v15_sign` and `mbedtls_rsa_rsassa_pkcs1_v15_verify`. + +The PSA API has two algorithm constructors: + +* [`PSA_ALG_RSA_PKCS1V15_SIGN(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga702ff75385a6ae7d4247033f479439af) formats the hash as specified in PKCS#1. The hash algorithm corresponds to the `md_alg` parameter of the legacy functions. +* [`PSA_ALG_RSA_PKCS1V15_SIGN_RAW`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga4215e2a78dcf834e9a625927faa2a817) uses the “hash” input in lieu of a DigestInfo structure. This is the same as calling the legacy functions with `md_alg=MBEDTLS_MD_NONE`. + +#### PKCS#1 RSASSA-PSS signature + +This mechanism corresponds to `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext` for an RSA key, as well as `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_rsa_pkcs1_sign` and `mbedtls_rsa_pkcs1_verify` if PSS has been selected on the underlying RSA context with `mbedlts_rsa_set_padding`. +It also corresponds to `mbedtls_rsa_rsassa_pss_sign` and `mbedtls_rsa_rsassa_pss_sign_ext`, `mbedtls_rsa_rsassa_pss_verify` and `mbedtls_rsa_rsassa_pss_verify_ext`. + +The PSA API has two algorithm constructors: [`PSA_ALG_RSA_PSS(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga62152bf4cb4bf6aace5e1be8f143564d) and [`PSA_ALG_RSA_PSS_ANY_SALT(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga9b7355a2cd6bde88177634d539127f2b). The hash algorithm `hash` corresponds to the `md_alg` parameter passed to the legacy API. It is used to hash the message, to create the salted hash, and for the mask generation with MGF1. The PSA API does not support using different hash algorithms for these different purposes. + +With respect to the salt length: + +* When signing, the salt is random, and the salt length is the largest possible salt length up to the hash length. This is the same as passing `MBEDTLS_RSA_SALT_LEN_ANY` as the salt length to `xxx_ext` legacy functions or using a legacy function that does not have a `saltlen` argument. +* When verifying, `PSA_ALG_RSA_PSS` requires the the salt length to the largest possible salt length up to the hash length (i.e. the same that would be used for signing). +* When verifying, `PSA_ALG_RSA_PSS_ANY_SALT` accepts any salt length. This is the same as passing `MBEDTLS_RSA_SALT_LEN_ANY` as the salt length to `xxx_ext` legacy functions or using a legacy function that does not have a `saltlen` argument. + +### Asymmetric encryption and decryption + +The equivalent of `mbedtls_pk_encrypt`, `mbedtls_rsa_pkcs1_encrypt`, `mbedtls_rsa_rsaes_pkcs1_v15_encrypt` or `mbedtls_rsa_rsaes_oaep_encrypt` to encrypt a short message (typically a symmetric key) is [`psa_asymmetric_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1gaa17f61e4ddafd1823d2c834b3706c290). +The key must be a public key allowing the usage `PSA_KEY_USAGE_ENCRYPT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). +Use the macro [`PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#crypto__sizes_8h_1a66ba3bd93e5ec52870ccc3848778bad8) or [`PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE) to determine the output buffer size. + +The equivalent of `mbedtls_pk_decrypt`, `mbedtls_rsa_pkcs1_decrypt`, `mbedtls_rsa_rsaes_pkcs1_v15_decrypt` or `mbedtls_rsa_rsaes_oaep_decrypt` to decrypt a short message (typically a symmetric key) is [`psa_asymmetric_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga4f968756f6b22aab362b598b202d83d7). +The key must be a key pair allowing the usage `PSA_KEY_USAGE_DECRYPT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). +Use the macro [`PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#crypto__sizes_8h_1a61a246f3eac41989821d982e56fea6c1) or [`PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE) to determine the output buffer size. + +The following subsections describe the PSA asymmetric encryption mechanisms that correspond to legacy Mbed TLS mechanisms. + +#### RSA PKCS#1v1.5 encryption + +This is the mechanism used by the PK functions and by `mbedtls_rsa_pkcs1_{encrypt,decrypt}` unless `mbedtls_rsa_set_padding` has been called on the underlying RSA key context. +This is also the mechanism used by `mbedtls_rsa_rsaes_pkcs1_v15_{encrypt,decrypt}`. + +The PSA algorithm is [`PSA_ALG_RSA_PKCS1V15_CRYPT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga4c540d3abe43fb9abcb94f2bc51acef9). + +Beware that PKCS#1v1.5 decryption is subject to padding oracle attacks. Revealing when `psa_asymmetric_decrypt` returns `PSA_ERROR_INVALID_PADDING` may allow an adversary to decrypt arbitrary ciphertexts. + +#### RSA RSAES-OAEP + +This is the mechanism used by `mbedtls_rsa_rsaes_oaep_{encrypt,decrypt}`. + +The PSA algorithm is [`PSA_ALG_RSA_OAEP(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gaa1235dc3fdd9839c6c1b1a9857344c76) where `hash` is a hash algorithm value (`PSA_ALG_xxx`, see “[Hash mechanism selection](#hash-mechanism-selection)”). + +As with the PK API, the mask generation is MGF1, the label is empty, and the same hash algorithm is used for MGF1 and to hash the label. The PSA API does not offer a way to choose a different label or a different hash algorithm for the label. + +### PK functionality with no PSA equivalent + +There is no PSA equivalent of the debug functionality provided by `mbedtls_pk_debug`. Use `psa_export_key` to export the key if desired. + +There is no PSA equivalent to Mbed TLS's custom key type names exposed by `mbedtls_pk_get_name`. + +The PSA API does not expose partially constructed key objects. This makes the following functions unnecessary: + +* `mbedtls_rsa_copy`, `mbedtls_ecp_copy`: a PSA key object is immutable, so the copy would have to be identical. +* `mbedtls_pk_check_pair`, `mbedtls_rsa_check_privkey`, `mbedtls_rsa_check_pubkey`, `mbedtls_rsa_check_pub_priv`,`mbedtls_ecp_check_privkey`, `mbedtls_ecp_check_pubkey`, `mbedtls_ecp_check_pub_priv`: if a key has been constructed successfully, it is guaranteed to be valid. + +### Key agreement + +_(Section not written yet)_ + + + +### Additional information about Elliptic-curve cryptography + +_(Section not written yet)_ + + + +#### ECC functionality with no PSA equivalent + +There is no PSA equivalent of `mbedtls_ecdsa_can_do` to query the capabilities of a curve at runtime. Check the documentation of each curve family to see what algorithms it supports. + +There is no PSA equivalent to the types `mbedtls_ecdsa_context` and `mbedtls_ecdsa_restart_ctx`, and to basic ECDSA context manipulation functions including `mbedtls_ecdsa_from_keypair`, because they are not needed: the PSA API does not have ECDSA-specific context types. + +### Additional information about RSA + +#### RSA-ALT interface + +Implementers of the RSA-ALT interface (`MBEDTLS_PK_RSA_ALT` pk type, `mbedtls_pk_setup_rsa_alt` setup function) should migrate to the [PSA cryptoprocessor driver interface](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/psa-driver-example-and-guide.md). + +* If the purpose of the ALT interface is acceleration only: use the accelerator driver interface. This is fully transparent to application code. +* If the purpose of the ALT interface is to isolate the private key in a high-security environment: use the opaque driver interface. This is mostly transparent to user code. Code that uses a key via its key identifier does not need to know whether the key is transparent (equivalent of `MBEDTLS_PK_RSA`) or opaque (equivalent of `MBEDTLS_PK_RSA_ALT`). When creating a key, it will be transparent by default; to create an opaque key, call [`psa_set_key_lifetime`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gac03ccf09ca6d36cc3d5b43f8303db6f7) to set the key's location to the chosen location value for the driver, e.g. + ``` + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_PERSISTENCE_VOLATILE, MY_RSA_DRIVER_LOCATION)); + ``` + +The PSA subsystem uses its internal random generator both for randomized algorithms and to generate blinding value. As a consequence, none of the API functions take an RNG parameter. + +#### RSA functionality with no PSA equivalent + +The PSA API does not provide direct access to the exponentiation primitive as with `mbedtls_rsa_public` and `mbedtls_rsa_private`. If you need an RSA-based mechanism that is not supported by the PSA API, please contact us so that we can extend the API to support it. + +The PSA API does not support constructing RSA keys progressively from numbers with `mbedtls_rsa_import` or `mbedtls_rsa_import_raw` followed by `mbedtls_rsa_complete`. See “[Importing a PK key by wrapping](#importing-a-pk-key-by-wrapping)”. + +There is no direct equivalent of `mbedtls_rsa_export`, `mbedtls_rsa_export_raw` and `mbedtls_rsa_export_crt` to export some of the numbers in a key. You can export the whole key with `psa_export_key`, or with `psa_export_public_key` to export the public key from a key pair object. See also “[Exporting a public key or a key pair](#exporting-a-public-key-or-a-key-pair)”. + +### PK format support interfaces + +The interfaces in `base64.h`, `asn1.h`, `asn1write.h`, `oid.h` and `pem.h` are intended to support X.509 and key file formats. They have no PSA equivalent since they are not directly about cryptography. They remain unchanged in Mbed TLS 3.x. In the future, they are likely to move out of the cryptography part of Mbed TLS and into the public-key/X.509 part. + +## EC-JPAKE + +The PSA API exposes EC-JPAKE via the algorithm [`PSA_ALG_JPAKE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__extra_8h/#c.PSA_ALG_JPAKE) and the PAKE API functions. At the time of writing, the PAKE API is still experimental, but it should offer the same functionality as the legacy `ecjpake.h`. Please consult the documentation of your version of Mbed TLS for more information. From c7b53f3ab7cd66a0153b0d9273f13f46261408ef Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 13 Jun 2023 21:31:53 +0200 Subject: [PATCH 02/88] Mention mbedtls_psa_get_random Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 24facffa60..007beca74a 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -591,6 +591,11 @@ The PSA subsystem has an internal random generator. As a consequence, you do not The PSA API uses its internal random generator to generate keys (`psa_generate_key`), nonces for encryption (`psa_cipher_generate_iv`, `psa_cipher_encrypt`, `psa_aead_generate_nonce`, `psa_aead_encrypt`, `psa_asymmetric_encrypt`), and other random material as needed. If you need random data for some other purposes, call [`psa_generate_random`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). +If your application mixes uses of the PSA crypto API and the mbedtls API and you need to pass an RNG argument to a legacy or X.509/TLS function, include the header file `` and use: + +* [`mbedtls_psa_get_random`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#_CPPv422mbedtls_psa_get_randomPvPh6size_t) as the `f_rng` argument; +* [`MBEDTLS_PSA_RANDOM_STATE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#c.MBEDTLS_PSA_RANDOM_STATE) as the `p_rng` argument. + ### Entropy sources Unless explicitly configured otherwise, the PSA random generator uses the default entropy sources configured through the legacy interface (`MBEDTLS_ENTROPY_xxx` symbols). Its set of sources is equivalent to an entropy object configured with `mbedtls_entropy_init`. From b33d0ac532eea27b850deb8f27d2485606816e1f Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 15 Jun 2023 18:33:15 +0200 Subject: [PATCH 03/88] Mention self-tests Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 007beca74a..34f7a74f22 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -196,6 +196,10 @@ If a mechanism is not enabled by `PSA_WANT_xxx`, Mbed TLS will often not include Under the hood, `PSA_WANT_xxx` enables the necessary legacy modules. Note that if a mechanism has a PSA accelerator driver, the corresponding legacy module is typically not needed. Thus applications that use a cryptographic mechanism both through the legacy API and through the PSA API need to explicitly enable both the `PSA_WANT_xxx` symbols and the `MBEDTLS_xxx` symbols. +### Self-tests + +There is currently [no PSA equivalent to the self-tests](https://github.com/Mbed-TLS/mbedtls/issues/7781) enabled by `MBEDTLS_SELF_TEST`. + ## Miscellaneous support modules ### Error messages From 5bd4f17e4e48cbffb38b92534ad01ad0af8a879b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 15 Jun 2023 18:33:30 +0200 Subject: [PATCH 04/88] Cover ECDH and DHM Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 148 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 143 insertions(+), 5 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 34f7a74f22..80abd25a4e 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -712,9 +712,9 @@ The following cryptographic algorithms work with ECC keys: #### Diffie-Hellman mechanism selection -A finite-field Diffie-Hellman public key has the type [`PSA_KEY_TYPE_DH_PUBLIC_KEY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gaa22f0f2ea89b929f2fadc19890cc5d5c). +A finite-field Diffie-Hellman key pair has the type [`PSA_KEY_TYPE_DH_KEY_PAIR(group)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab4f857c4cd56f5fe65ded421e61bcc8c) where `group` is a group family as explained below. -A finite-field Diffie-Hellman key pair has the type [`PSA_KEY_TYPE_DH_KEY_PAIR`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab4f857c4cd56f5fe65ded421e61bcc8c). A key with this type can be used both for private-key and public-key operations (there is no separate key type for a private key without the corresponding public key). +A finite-field Diffie-Hellman public key has the type [`PSA_KEY_TYPE_DH_PUBLIC_KEY(group)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gaa22f0f2ea89b929f2fadc19890cc5d5c) where `group` is a group family as explained below. Due to the design of the API, there is rarely a need to use Diffie-Hellman public key objects. The PSA API only supports Diffie-Hellman with predefined groups. A group is fully determined by a group family identifier and the public key size in bits. @@ -1020,9 +1020,147 @@ The PSA API does not expose partially constructed key objects. This makes the fo ### Key agreement -_(Section not written yet)_ +The PSA API has a generic interface for key agreement, covering the main use of both `ecdh.h` and `dhm.h`. - +#### Diffie-Hellman key pair management + +The PSA API manipulates keys as such, rather than via an operation context. Thus, to use Diffie-Hellman, you need to create a key object, then perform the key exchange, then destroy the key. There is no equivalent to the types `mbedtls_ecdh_context` and `mbedtls_dhm_context`. + +Here is an overview of the lifecycle of a key object. + +1. First define the attributes of the key by filling a [`psa_key_attributes_t` structure](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga0ec645e1fdafe59d591104451ebf5680). You need to set the following parameters: + * Call [`psa_set_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga6857ef0ecb3fa844d4536939d9c64025) to set the key type to the desired `PSA_KEY_TYPE_xxx` value: + * [`PSA_KEY_TYPE_DH_KEY_PAIR(group)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab4f857c4cd56f5fe65ded421e61bcc8c) for finite-field Diffie-Hellman (see “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)”). + * [`PSA_KEY_TYPE_ECC_KEY_PAIR(curve)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0b6f5d4d5037c54ffa850d8059c32df0) for elliptic-curve Diffie-Hellman (see “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)”). + * Call [`psa_set_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaf61683ac87f87687a40262b5afbfa018) to set the private key size in bits. This is optional with `psa_import_key`, which determines the key size from the length of the key material. + * Call [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) to select the appropriate algorithm: + * [`PSA_ALG_ECDH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab2dbcf71b63785e7dd7b54a100edee43) or [`PSA_ALG_FFDH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga0ebbb6f93a05b6511e6f108ffd2d1eb4) for a raw key agreement. + * [`PSA_ALG_KEY_AGREEMENT(ka, kdf)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga78bb81cffb87a635c247725eeb2a2682) if the key will be used as part of a key derivation, where: + * `ka` is either `PSA_ALG_ECDH` or `PSA_ALG_FFDH`. + * `kdf` is a key derivation algorithm. + * Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de) to enable at least [`PSA_KEY_USAGE_DERIVE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#c.PSA_KEY_USAGE_DERIVE). See “[Public-key cryptography policies](#public-key-cryptography-policies)” for more information. +2. Call one of the key creation functions, passing the attributes defined in the previous step, to get an identifier of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t) to the key object. + * Use [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5) to generate a random key. This is normally the case for a Diffie-Hellman key. + * Use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b) to directly import key material. + * If the key is derived deterministically from other material, use the [key derivation interface](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/) and create the key with [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1). +3. Call the functions in the following sections to perform operations on the key. The same key object can be used in multiple operations. +4. To free the resources used by the key object, call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) after all operations with that key are finished. + +#### Performing a key agreement + +Call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) to obtain the public key that needs to be sent to the other party. +Use the macros [`PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE) or [`PSA_EXPORT_PUBLIC_KEY_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) to determine the size of the output buffer. + +Call [`psa_raw_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) to calculate the shared secret from your private key and the other party's public key. +Use the macros [`PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE) or [`PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. + +Call [`psa_key_derivation_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga2cd5a8ac906747d3204ec442db78745f) instead of `psa_raw_key_agreement` to use the resulting shared secret as the secret input to a key derivation. See “[HKDF](#hkdf)” for an example of the key derivation interface. + +#### Translating a legacy key agreement contextless flow + +A typical flow for ECDH using the legacy API without a context object is: + +1. Initialize objects: + * `mbedtls_ecp_group grp` for the curve; + * `mbedtls_mpi our_priv` for our private key; + * `mbedtls_ecp_point our_pub` for our public key; + * `mbedtls_ecp_point their_pub` for their public key (this may be the same variable as `our_pub` if the application does not need to hold both at the same time); + * `mbedtls_mpi z` for the shared secret (this may be the same variable as `our_priv` when doing ephemeral ECDH). +2. Call `mbedtls_ecp_group_load` on `grp` to select the curve. +3. Call `mbedtls_ecdh_gen_public` on `grp`, `our_priv` (output) and `our_pub` (output) to generate a key pair and retrieve the corresponding public key. +4. Send `our_pub` to the peer. Retriev the peer's public key and import it into `their_pub`. These two actions may be performed in either order. +5. Call `mbedtls_ecdh_compute_shared` on `grp`, `z` (output), `their_pub` and `our_priv`. +6. Use the raw shared secret `z`, typically, to construct a shared key. +7. Free `grp`, `our_priv`, `our_pub`, `their_pub` and `z`. + +The corresponding flow with the PSA API is as follows: + +1. Initialize objects: + * `psa_key_id_t our_key`: a handle to our key pair; + * `psa_key_attributes_t attributes`: key attributes used in steps 2–3;; + * `our_pub`: a buffer of size [`PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, bits)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE) (where `key_type` is the value passed to `psa_set_key_size` in step 2) or [`PSA_EXPORT_PUBLIC_KEY_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) to hold our key. + * `their_pub`: a buffer of the same size, to hold the peer's key. This can be the same as `our_pub` if the application does not need to hold both at the same time; + * `shared_secret`: a buffer of size [`PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, bits)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE) or [`PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE) (if not using a key derivation operation). +2. Prepare an attribute structure as desccribed in “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)”, in particular selecting the curve with `psa_set_key_type`. +3. Call [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5) on `attributes` and `our_key` (output) to generate a key pair, then [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on `our_key` and `our_pub` (output) to obtain our public key. +4. Send `our_pub` to the peer. Retriev the peer's public key and import it into `their_pub`. These two actions may be performed in either order. +5. Call [`psa_raw_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) on `our_key`, `their_pub` and `shared_secret` (output). + Alternatively, call `psa_key_derivation_key_agreement` to use the shared secret directly in a key derivation operation (see “[Performing a key agreement](#performing-a-key-agreement)”). +6. Call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) on `key_id`, and free the memory buffers. + +Steps 4–5 are only performed once for ephemeral Diffie-Hellman, but repeated multiple times for static Diffie-Hellman. + +#### Translating a legacy key agreement TLS server flow + +The legacy API offers the following flow for a Diffie-Hellman key agreement in a TLS server. This flow can also be used with other protocols, on the side of the party that selects the curve or group and sends its public key first. + +1. Setup phase: + 1. Initialize a context of type `mbedtls_ecdh_context` or `mbedtls_dhm_context` with `mbedtls_ecdh_init` or `mbedtls_dhm_init`. + 2. Call `mbedtls_ecdh_setup` or `mbedtls_dhm_set_group` to select the curve or group. + 3. Call `mbedtls_ecdh_make_params` or `mbedtls_dhm_make_params` to generate our key pair and obtain a TLS ServerKeyExchange message encoding the selected curve/group and our public key. +2. Send the ServerKeyExchange message to the peer. +3. Retrieve the peer's public key. +4. Call `mbedtls_ecdh_read_public` or `mbedtls_dhm_read_public` on the peer's public key, then call `mbedtls_ecdh_calc_secret` or `mbedtls_dhm_calc_secret` to calculate the shared secret. +5. Free the context with `mbedtls_ecdh_free` or `mbedtls_dhm_free`. + +The corresponding flow with the PSA API is as follows: + +1. Setup phase: + 1. Generate an ECDH or DHM key pair with `psa_generate_key` as described in “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)”. + 2. Call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) to obtain our public key. + 3. Format a ServerKeyExchange message containing the curve/group selection and our public key. +2. Send the ServerKeyExchange message to the peer. +3. Retrieve the peer's public key. +4. Call [`psa_raw_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) on `our_key`, `their_pub` and `shared_secret` (output). + Alternatively, call `psa_key_derivation_key_agreement` to use the shared secret directly in a key derivation operation (see “[Performing a key agreement](#performing-a-key-agreement)”). +5. Call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to free the resources associated with our key pair. + +#### Translating a legacy key agreement TLS client flow + +The legacy API offers the following flow for a Diffie-Hellman key agreement in a TLS client. This flow can also be used with other protocols, on the side of the party that receives a message indicating both the choice of curve or group, and the peer's public key. + +1. Upon reception of a TLS ServerKeyExchange message received from the peer, which encodes the selected curve/group and the peer's public key: + 1. Initialize a context of type `mbedtls_ecdh_context` or `mbedtls_dhm_context` with `mbedtls_ecdh_init` or `mbedtls_dhm_init`. + 2. Call `mbedtls_ecdh_read_params` or `mbedtls_dhm_read_params` to input the data from the ServerKeyExchange message. +2. Call `mbedtls_ecdh_make_public` or `mbedtls_dh_make_public` to generate our private key and export our public key. +3. Send our public key to the peer. +4. Call `mbedtls_ecdh_calc_secret` or `mbedtls_dhm_calc_secret` to calculate the shared secret. +5. Free the context with `mbedtls_ecdh_free` or `mbedtls_dhm_free`. + +The corresponding flow with the PSA API is as follows: + +1. Upon reception of a TLS ServerKeyExchange message received from the peer, which encodes the selected curve/group and the peer's public key: + 1. Decode the select curve/group and use this to determine a PSA key type (`PSA_KEY_TYPE_ECC_KEY_PAIR(curve)` or `PSA_KEY_TYPE_DH_KEY_PAIR(group)`), a key size and an algorithm. +2. Generate an ECDH or DHM key pair with `psa_generate_key` as described in “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)”. + Call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) to obtain our public key. +3. Send our public key to the peer. +4. Call [`psa_raw_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) on `our_key`, `their_pub` and `shared_secret` (output). + Alternatively, call `psa_key_derivation_key_agreement` to use the shared secret directly in a key derivation operation (see “[Performing a key agreement](#performing-a-key-agreement)”). +5. Call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to free the resources associated with our key pair. + +#### ECDH and DHM metadata functions + +The legacy function `mbedtls_ecdh_get_params` allows the application to retrieve an `mbedtls_ecp_keypair` containing either our key pair, or the peer's public key. The PSA equivalent depends on the use case: + +* With either side, accessing the group: call [`psa_get_key_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gacbbf5c11eac6cd70c87ffb936e1b9be2) on the key identifier, then [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918) and [`psa_get_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga5bee85c2164ad3d4c0d42501241eeb06) to obtain metadata about the key. +* With `MBEDTLS_ECDH_OURS`, accessing the public key: call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on PSA key identifier. +* With `MBEDTLS_ECDH_OURS`, accessing the private key: call [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) on the key identifier. Note that the key policy must allow `PSA_KEY_USAGE_EXPORT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). +* With `MBEDTLS_ECDH_THEIRS`, accessing the public key (there is no private key): there is no PSA equivalent since the PSA API only uses the peer's public key to immediately calculate the shared secret. If your application needs the peer's public key for some other purpose, store it separately. + +The functions `mbedtls_dhm_get_bitlen`, `mbedtls_dhm_get_len` and `mbedtls_dhm_get_value` allow the caller to obtain metadata about the keys used for the key exchange. The PSA equivalents access the key identifier: + +* `mbedtls_dhm_get_bitlen`, `mbedtls_dhm_get_len`: call [`psa_get_key_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gacbbf5c11eac6cd70c87ffb936e1b9be2) on the PSA key identifier, then [`psa_get_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga5bee85c2164ad3d4c0d42501241eeb06). +* `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_X` (our private key): call [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) on the key identifier. Note that the key policy must allow `PSA_KEY_USAGE_EXPORT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). +* `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_GX` (our public key): call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on PSA key identifier. +* `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_GY` (peer's public key): the there is no PSA equivalent since the PSA API only uses the peer's public key to immediately calculate the shared secret. If your application needs the peer's public key for some other purpose, store it separately. +* `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_K` (shared secret): this is the value calculated by `psa_raw_key_agreement` or `psa_key_derivation_key_agreement`. If you need to use it multiple times (for example to derive multiple values independently), call `psa_raw_key_agreement` and make a copy. +* `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_P` or `MBEDTLS_DHM_PARAM_G` (group parameters): [there is no PSA API to retrieve these values](https://github.com/Mbed-TLS/mbedtls/issues/7780). + +The PSA API for finite-field Diffie-Hellman only supports predefined groups. Therefore there is no equivalent to `mbedtls_dhm_parse_dhm`, `mbedtls_dhm_parse_dhmfile`, and the `MBEDTLS_DHM_xxx_BIN` macros. + +#### Restartable key agreement + +Restartable key agreement is not yet available through the PSA API. It will be added in a future version of the library. ### Additional information about Elliptic-curve cryptography @@ -1032,7 +1170,7 @@ _(Section not written yet)_ #### ECC functionality with no PSA equivalent -There is no PSA equivalent of `mbedtls_ecdsa_can_do` to query the capabilities of a curve at runtime. Check the documentation of each curve family to see what algorithms it supports. +There is no PSA equivalent of `mbedtls_ecdsa_can_do` and `mbedtls_ecdh_can_do` to query the capabilities of a curve at runtime. Check the documentation of each curve family to see what algorithms it supports. There is no PSA equivalent to the types `mbedtls_ecdsa_context` and `mbedtls_ecdsa_restart_ctx`, and to basic ECDSA context manipulation functions including `mbedtls_ecdsa_from_keypair`, because they are not needed: the PSA API does not have ECDSA-specific context types. From f75e65d90baeb812f303ebe6ee99553ced01396b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 15 Jun 2023 18:39:14 +0200 Subject: [PATCH 05/88] Rename PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_USE to ..._BASIC per https://github.com/Mbed-TLS/mbedtls/issues/7439#issuecomment-1592673401 and https://github.com/Mbed-TLS/mbedtls/pull/7774#discussion_r1230658660 State that EXPORT implies BASIC. Also fix missing `WANT_` parts. Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 80abd25a4e..ed6c016e79 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -163,11 +163,11 @@ The availability of cryptographic mechanisms in the PSA API is based on a system * To make `PSA_KEY_TYPE_ttt` available, enable `PSA_WANT_KEY_TYPE_ttt`. As an exception, starting in Mbed TLS 3.5.0, for key pair types, the feature selection is more fine-grained, with an additional suffix: - * `PSA_KEY_TYPE_xxx_USE` enables support for operations with a key of that type (for enabled algorithms). This is automatically enabled if any key creation method (`IMPORT`, `GENERATE` or `DERIVE`) is enabled. - * `PSA_KEY_TYPE_xxx_IMPORT` enables support for `psa_import_key` to import a key of that type. - * `PSA_KEY_TYPE_xxx_GENERATE` enables support for `psa_generate_key` to randomly generate a key of that type. - * `PSA_KEY_TYPE_xxx_DERIVE` enables support for `psa_key_derivation_output_key` to deterministically derive a key of that type. - * `PSA_KEY_TYPE_xxx_EXPORT` enables support for `psa_export_key` to export a key of that type. + * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` enables basic support for the key type, and in particular support for operations with a key of that type for enabled algorithms. This is automatically enabled if any of the other `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy` options is enabled. + * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_IMPORT` enables support for `psa_import_key` to import a key of that type. + * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_GENERATE` enables support for `psa_generate_key` to randomly generate a key of that type. + * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_DERIVE` enables support for `psa_key_derivation_output_key` to deterministically derive a key of that type. + * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_EXPORT` enables support for `psa_export_key` to export a key of that type. Enabling any support for a key pair type automatically enables support for the corresponding public key type, as well as support for `psa_export_public_key` on the private key. @@ -185,7 +185,7 @@ For example, the following configuration enables hashing with SHA-256, AEAD with #define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1 // ^^ In Mbed TLS <= 3.4, enable PSA_WANT_KEY_TYPE_ECC_KEY_PAIR instead -// ^^ implicitly enables PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_USE, PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY +// ^^ implicitly enables PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC, PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY #define PSA_WANT_ECC_SECP_R1_256 1 // secp256r1 (suitable for ECDSA and ECDH) #define PSA_WANT_ECC_MONTGOMERY_255 1 // Curve25519 (suitable for ECDH) #define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1 From 379ff8754d03ca23db2413e5b5eb687ed6fd5a02 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 15 Jun 2023 21:15:21 +0200 Subject: [PATCH 06/88] Cover ecp.h Also correct some statements about rsa/ecp/pk check functions. Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 87 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 8 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index ed6c016e79..c78d0e424f 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -196,6 +196,12 @@ If a mechanism is not enabled by `PSA_WANT_xxx`, Mbed TLS will often not include Under the hood, `PSA_WANT_xxx` enables the necessary legacy modules. Note that if a mechanism has a PSA accelerator driver, the corresponding legacy module is typically not needed. Thus applications that use a cryptographic mechanism both through the legacy API and through the PSA API need to explicitly enable both the `PSA_WANT_xxx` symbols and the `MBEDTLS_xxx` symbols. +### Optimization options + +When PSA Crypto mechanisms are implemented by the built-in code from Mbed TLS, the legacy optimization options (e.g. `MBEDTLS_SHA256_SMALLER`, `MBEDTLS_ECP_WINDOW_SIZE`, etc.) apply to the PSA implementation as well (they invoke the same code under the hood). + +The PSA Crypto API may use accelerator drivers. In this case any options controlling the driver behavior are driver-specific. + ### Self-tests There is currently [no PSA equivalent to the self-tests](https://github.com/Mbed-TLS/mbedtls/issues/7781) enabled by `MBEDTLS_SELF_TEST`. @@ -954,7 +960,7 @@ The flow of operations for an interruptible signature verification operation is If you need to interrupt the operation after calling the start function without waiting for the complete function to return a success or failure status, call [`psa_sign_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1gae893a4813aa8e03bd201fe4f1bbbb403) or [`psa_verify_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga18dc9c0cc27d590c5e3b186094d90f88). -Call [`psa_interruptible_set_max_ops`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga6d86790b31657c13705214f373af869e) to set the number of basic operations per call. This is the same unit as `mbedtls_ecp_set_max_ops`. +Call [`psa_interruptible_set_max_ops`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga6d86790b31657c13705214f373af869e) to set the number of basic operations per call. This is the same unit as `mbedtls_ecp_set_max_ops`. You can retrieve the current value with [`psa_interruptible_get_max_ops`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga73e66a6d93f2690b626fcea20ada62b2). The value is [`PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible/#group__interruptible_1gad19c1da7f6b7d59d5873d5b68eb943d4) if operations are not restartable, which corresponds to `mbedtls_ecp_restart_is_enabled()` being false. #### PKCS#1 v1.5 RSA signature @@ -1007,17 +1013,34 @@ The PSA algorithm is [`PSA_ALG_RSA_OAEP(hash)`](https://mbed-tls.readthedocs.io/ As with the PK API, the mask generation is MGF1, the label is empty, and the same hash algorithm is used for MGF1 and to hash the label. The PSA API does not offer a way to choose a different label or a different hash algorithm for the label. +### Private-public key consistency + +There is no direct equivalent of the functions `mbedtls_rsa_check_privkey`, `mbedtls_rsa_check_pubkey`,`mbedtls_ecp_check_privkey`, `mbedtls_ecp_check_pubkey`. The PSA API performs some basic checks when it imports a key, and may perform additional checks before performing an operation if needed, so it will never perform an operation on a key that does not satisfy these checks, but the details of when the check is performed may change between versions of the library. + +The legacy API provide functions `mbedtls_pk_check_pair`, `mbedtls_rsa_check_pub_priv` and `mbedtls_ecp_check_pub_priv`, which can be used to check the consistency between a private key and a public key. To perform such a check with the PSA API, you can export the public keys; this works because the PSA representation of public keys is canonical. + +* Prepare a key object containing the private key, for example with [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). +* Prepare a key object containing the public key, for example with [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). +* Export both public keys with [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) (this is possible regardless of the usage policies on the keys) and compare the output. + ``` + // Error checking omitted + unsigned char pub1[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; + unsigned char pub2[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; + size_t length1, length2; + psa_export_public_key(key1, pub1, sizeof(pub1), &length1); + psa_export_public_key(key2, pub2, sizeof(pub2), &length2); + if (length1 == length2 && !memcmp(pub1, pub2, length1)) + puts("The keys match"); + else + puts("The keys do not match"); + ``` + ### PK functionality with no PSA equivalent There is no PSA equivalent of the debug functionality provided by `mbedtls_pk_debug`. Use `psa_export_key` to export the key if desired. There is no PSA equivalent to Mbed TLS's custom key type names exposed by `mbedtls_pk_get_name`. -The PSA API does not expose partially constructed key objects. This makes the following functions unnecessary: - -* `mbedtls_rsa_copy`, `mbedtls_ecp_copy`: a PSA key object is immutable, so the copy would have to be identical. -* `mbedtls_pk_check_pair`, `mbedtls_rsa_check_privkey`, `mbedtls_rsa_check_pubkey`, `mbedtls_rsa_check_pub_priv`,`mbedtls_ecp_check_privkey`, `mbedtls_ecp_check_pubkey`, `mbedtls_ecp_check_pub_priv`: if a key has been constructed successfully, it is guaranteed to be valid. - ### Key agreement The PSA API has a generic interface for key agreement, covering the main use of both `ecdh.h` and `dhm.h`. @@ -1164,9 +1187,47 @@ Restartable key agreement is not yet available through the PSA API. It will be a ### Additional information about Elliptic-curve cryptography -_(Section not written yet)_ +#### Information about a curve - +The legacy API identifies a curve by an `MBEDTLS_ECP_DP_xxx` value of type `mbedtls_ecp_group_id`. The PSA API identifies a curve by a `PSA_ECC_FAMILY_xxx` value and the private value's bit-size. See “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” for the correspondence between the two sets of values. + +There is no PSA equivalent of the `mbedtls_ecp_group` data structure (and so no equivalent to `mbedtls_ecp_group_init`, `mbedtls_ecp_group_load`, `mbedtls_ecp_group_copy` and `mbedtls_ecp_group_free`) or of the `mbedtls_ecp_curve_info` data structure (and so no equivalent to `mbedtls_ecp_curve_info_from_grp_id`) because they are not needed. All API elements identify the curve directly by its family and size. + +The bit-size used by the PSA API is the size of the private key. For most curves, the PSA bit-size, the `bit_size` field in `mbedtls_ecp_curve_info`, the `nbits` field in `mbedtls_ecp_group` and the `pbits` field in `mbedtls_ecp_group` are the same. The following table lists curves for which they are different. + +| Curve | `grp->nbits` | `grp->pbits` | `curve_info->bit_size` | PSA bit-size | +| ----- | ------------ | ------------ | ---------------------- | ------------ | +| secp224k1 | 224 | 225 | 224 | not supported | +| Curve25519 | 253 | 255 | 256 | 255 | +| Curve448 | 446 | 448 | 448 | 448 | + +There is no exact PSA equivalent of the type `mbedtls_ecp_curve_type` and the function `mbedtls_ecp_get_type`, but the curve family encodes the same information. `PSA_ECC_FAMILY_MONTGOMERY` is the only Montgomery family. All other families supported in Mbed TLS 3.4.0 are short Weierstrass families. + +There is no PSA equivalent for the following functionality: + +* The `name` field of `mbedtls_ecp_curve_info`, and the function `mbedtls_ecp_curve_info_from_name`. There is no equivalent of Mbed TLS's lookup based on a (nonstandard) name. +* The `tls_id` field of `mbedtls_ecp_curve_info`, the constant `MBEDTLS_ECP_TLS_NAMED_CURVE`, and the functions `mbedtls_ecp_curve_info_from_tls_id`, `mbedtls_ecp_tls_read_group`, `mbedtls_ecp_tls_read_group_id` and `mbedtls_ecp_tls_write_group`. The PSA crypto API does not have this dedicated support for the TLS protocol. +* Retrieving the parameters of a curve from the fields of an `mbedtls_ecp_group` structure. + +#### Information about supported curves + +The PSA API does not currently have a discovery mechanism for cryptographic mechanisms (although one may be added in the future). Thus there is no equivalent for `MBEDTLS_ECP_DP_MAX` and the functions `mbedtls_ecp_curve_list` and `mbedtls_ecp_grp_id_list`. + +The API provies macros that give the maximum supported sizes for various kinds of objects. The following table lists equivalents for `MBEDTLS_ECP_MAX_xxx` macros. + +| Legacy macro | PSA equivalent | +| ------------ | -------------- | +| `MBEDTLS_ECP_MAX_BITS` | [`PSA_VENDOR_ECC_MAX_CURVE_BITS`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_VENDOR_ECC_MAX_CURVE_BITS) | +| `MBEDTLS_ECP_MAX_BYTES` | `PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)` | +| `MBEDTLS_ECP_MAX_PT_LEN` | [`PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE) | + +#### Restartable ECC + +The PSA API supports the equivalent of restartable operations, but only for signatures at the time of writing. See “[Restartable ECDSA signature](#restartable-ecdsa-signature)”. + +There is no PSA API for elliptic curve arithmetic as such, and therefore no equivalent of `mbedtls_ecp_restart_ctx` and functions that operate on it. + +There is PSA no equivalent of the `MBEDTLS_ECP_OPS_xxx` constants. #### ECC functionality with no PSA equivalent @@ -1174,6 +1235,14 @@ There is no PSA equivalent of `mbedtls_ecdsa_can_do` and `mbedtls_ecdh_can_do` t There is no PSA equivalent to the types `mbedtls_ecdsa_context` and `mbedtls_ecdsa_restart_ctx`, and to basic ECDSA context manipulation functions including `mbedtls_ecdsa_from_keypair`, because they are not needed: the PSA API does not have ECDSA-specific context types. +#### No curve arithmetic + +The PSA API is a cryptography API, not an arithmetic API. As a consequence, there is no PSA equivalent for the ECC arithmetic functionality exposed by `ecp.h`: + +* Manipulation of point objects and input-output: the type `mbedtls_ecp_point` and functions operating on it (`mbedtls_ecp_point_xxx`, `mbedtls_ecp_copy`, `mbedtls_ecp_{set,is}_zero`, `mbedtls_ecp_tls_{read,write}_point`). Note that the PSA export format for public keys corresponds to the uncompressed point format (`MBEDTLS_ECP_PF_UNCOMPRESSED`), so [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) are equivalent to `mbedtls_ecp_point_read_binary` and `mbedtls_ecp_point_write_binary` for uncompressed points. The PSA API does not currently support compressed points, but it is likely that such support will be added in the future. +* Manipulation of key pairs as such, with a bridge to bignum arithmetic (`mbedtls_ecp_keypair` type, `mbedtls_ecp_export`). However, the PSA export format for ECC private keys used by [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) is the same as the format used by `mbedtls_ecp_read_key` and `mbedtls_ecp_write_key`. +* Elliptic curve arithmetic (`mbedtls_ecp_mul`, `mbedtls_ecp_muladd` and their restartable variants). + ### Additional information about RSA #### RSA-ALT interface @@ -1197,6 +1266,8 @@ The PSA API does not support constructing RSA keys progressively from numbers wi There is no direct equivalent of `mbedtls_rsa_export`, `mbedtls_rsa_export_raw` and `mbedtls_rsa_export_crt` to export some of the numbers in a key. You can export the whole key with `psa_export_key`, or with `psa_export_public_key` to export the public key from a key pair object. See also “[Exporting a public key or a key pair](#exporting-a-public-key-or-a-key-pair)”. +A PSA key object is immutable, so there is no need for an equivalent of `mbedtls_rsa_copy`. (There is a function `psa_copy_key`, but it is only useful to make a copy of a key with a different policy of ownership; both concepts are out of scope of this document since they have no equivalent in the legacy API.) + ### PK format support interfaces The interfaces in `base64.h`, `asn1.h`, `asn1write.h`, `oid.h` and `pem.h` are intended to support X.509 and key file formats. They have no PSA equivalent since they are not directly about cryptography. They remain unchanged in Mbed TLS 3.x. In the future, they are likely to move out of the cryptography part of Mbed TLS and into the public-key/X.509 part. From 603f0fca6ef0ac56e94525a1db583845871894d9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 20 Jun 2023 23:38:21 +0200 Subject: [PATCH 07/88] The ECP curve name is the one from TLS, not one we made up Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index c78d0e424f..0659154524 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -1205,7 +1205,7 @@ There is no exact PSA equivalent of the type `mbedtls_ecp_curve_type` and the fu There is no PSA equivalent for the following functionality: -* The `name` field of `mbedtls_ecp_curve_info`, and the function `mbedtls_ecp_curve_info_from_name`. There is no equivalent of Mbed TLS's lookup based on a (nonstandard) name. +* The `name` field of `mbedtls_ecp_curve_info`, and the function `mbedtls_ecp_curve_info_from_name`. There is no equivalent of Mbed TLS's lookup based on the name used for the curve in TLS specifications. * The `tls_id` field of `mbedtls_ecp_curve_info`, the constant `MBEDTLS_ECP_TLS_NAMED_CURVE`, and the functions `mbedtls_ecp_curve_info_from_tls_id`, `mbedtls_ecp_tls_read_group`, `mbedtls_ecp_tls_read_group_id` and `mbedtls_ecp_tls_write_group`. The PSA crypto API does not have this dedicated support for the TLS protocol. * Retrieving the parameters of a curve from the fields of an `mbedtls_ecp_group` structure. From 909cf5a3ecc1e91c62e148f96f03400ca88869ff Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 20 Jun 2023 23:38:39 +0200 Subject: [PATCH 08/88] Show how to extract curve information from an ecp_keypair It's not pretty. Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 0659154524..fabac9c85a 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -800,16 +800,30 @@ psa_import_key(&attributes, buf + sizeof(buf) - length, length, &key_id); mbedtls_pk_free(&pk); ``` -For an ECC private key (a future version of Mbed TLS [will provide a function to calculate the curve family](https://github.com/Mbed-TLS/mbedtls/issues/7764)): +For an ECC private key (a future version of Mbed TLS [will provide a more direct way to find the curve family](https://github.com/Mbed-TLS/mbedtls/issues/7764)): ``` unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk)); mbedtls_ecp_keypair *ec = mbedtls_pk_ec(&pk); +psa_ecc_curve_t curve; +{ + mbedtls_ecp_group grp; + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point Q; + mbedtls_ecp_point_init(&Q); + mbedtls_mpi d; + mbedtls_mpi_init(&d); + mbedtls_ecp_export(ec, &grp, &d, &Q); + size_t bits; + curve = mbedtls_ecc_group_to_psa(grp.id, &bits); + mbedtls_ecp_group_free(&grp); + mbedtls_ecp_point_free(&Q); + mbedtls_mpi_free(&d); +} mbedtls_ecp_write_key(ec, buf, length); -psa_ecc_curve_t curve = ...; // need to determine the curve family manually psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; -psa_set_key_attributes(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); +psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve)); psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...); psa_set_key_algorithm(&attributes, PSA_ALGORITHM_...); psa_key_id_t key_id = 0; From 180915018dd04f6ad66faa3e9fc66813a221643d Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 28 Nov 2023 08:37:06 +0100 Subject: [PATCH 09/88] pem: auto add newlines to header/footer in mbedtls_pem_write_buffer() Signed-off-by: Valerio Setti --- include/mbedtls/pem.h | 3 +++ library/pem.c | 7 ++++++- library/x509write_crt.c | 4 ++-- library/x509write_csr.c | 4 ++-- tests/suites/test_suite_pem.data | 12 ++++++------ tests/suites/test_suite_pem.function | 6 +++--- 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/include/mbedtls/pem.h b/include/mbedtls/pem.h index cc617a9bcc..2fe19d026c 100644 --- a/include/mbedtls/pem.h +++ b/include/mbedtls/pem.h @@ -135,6 +135,9 @@ void mbedtls_pem_free(mbedtls_pem_context *ctx); * \param olen The address at which to store the total length written * or required (if \p buf_len is not enough). * + * \note Newlines are automatically appended to both header and + * footer. + * * \note You may pass \c NULL for \p buf and \c 0 for \p buf_len * to request the length of the resulting PEM buffer in * `*olen`. diff --git a/library/pem.c b/library/pem.c index 9500ffcf7f..7c0c447ee2 100644 --- a/library/pem.c +++ b/library/pem.c @@ -473,7 +473,10 @@ int mbedtls_pem_write_buffer(const char *header, const char *footer, size_t len = 0, use_len, add_len = 0; mbedtls_base64_encode(NULL, 0, &use_len, der_data, der_len); - add_len = strlen(header) + strlen(footer) + (((use_len > 2) ? (use_len - 2) : 0) / 64) + 1; + /* Newlines are appended to the end of both header and footer, so we + * account for an extra +2. */ + add_len = strlen(header) + strlen(footer) + 2 + \ + (((use_len > 2) ? (use_len - 2) : 0) / 64) + 1; if (use_len + add_len > buf_len) { *olen = use_len + add_len; @@ -493,6 +496,7 @@ int mbedtls_pem_write_buffer(const char *header, const char *footer, memcpy(p, header, strlen(header)); p += strlen(header); + *p++ = '\n'; c = encode_buf; while (use_len) { @@ -506,6 +510,7 @@ int mbedtls_pem_write_buffer(const char *header, const char *footer, memcpy(p, footer, strlen(footer)); p += strlen(footer); + *p++ = '\n'; *p++ = '\0'; *olen = p - buf; diff --git a/library/x509write_crt.c b/library/x509write_crt.c index 4c019eee4e..8d920f2676 100644 --- a/library/x509write_crt.c +++ b/library/x509write_crt.c @@ -651,8 +651,8 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, return (int) len; } -#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" -#define PEM_END_CRT "-----END CERTIFICATE-----\n" +#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----" +#define PEM_END_CRT "-----END CERTIFICATE-----" #if defined(MBEDTLS_PEM_WRITE_C) int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *crt, diff --git a/library/x509write_csr.c b/library/x509write_csr.c index 4e397553a4..5ee683ff12 100644 --- a/library/x509write_csr.c +++ b/library/x509write_csr.c @@ -302,8 +302,8 @@ int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf, return ret; } -#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" -#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" +#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----" +#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----" #if defined(MBEDTLS_PEM_WRITE_C) int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, diff --git a/tests/suites/test_suite_pem.data b/tests/suites/test_suite_pem.data index a4dff45f0b..238a0bc043 100644 --- a/tests/suites/test_suite_pem.data +++ b/tests/suites/test_suite_pem.data @@ -1,20 +1,20 @@ Standard PEM write -mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=\n-----END TEST-----\n" PEM write (zero data) -mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"":"-----START TEST-----\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"":"-----START TEST-----\n-----END TEST-----\n" PEM write (one byte) -mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"00":"-----START TEST-----\nAA==\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"00":"-----START TEST-----\nAA==\n-----END TEST-----\n" PEM write (more than line size) -mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=\n-----END TEST-----\n" PEM write (exactly two lines) -mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\n-----END TEST-----\n" PEM write (exactly two lines + 1) -mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F00":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAA==\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F00":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAA==\n-----END TEST-----\n" PEM write length reporting mbedtls_pem_write_buffer_lengths diff --git a/tests/suites/test_suite_pem.function b/tests/suites/test_suite_pem.function index 413dc551c3..cb652d4584 100644 --- a/tests/suites/test_suite_pem.function +++ b/tests/suites/test_suite_pem.function @@ -40,17 +40,17 @@ void mbedtls_pem_write_buffer_lengths() size_t olen_needed, olen; int ret; for (size_t l = 0; l <= sizeof(data); l++) { - ret = mbedtls_pem_write_buffer("\n", "\n", data, l, NULL, 0, &olen_needed); + ret = mbedtls_pem_write_buffer("", "", data, l, NULL, 0, &olen_needed); TEST_EQUAL(ret, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL); /* Test that a bigger buffer still only requires `olen_needed` */ - ret = mbedtls_pem_write_buffer("\n", "\n", data, l, buf, sizeof(buf), &olen); + ret = mbedtls_pem_write_buffer("", "", data, l, buf, sizeof(buf), &olen); TEST_EQUAL(ret, 0); TEST_EQUAL(olen_needed, olen); /* Test that a buffer of exactly `olen_needed` works */ memset(buf, 1, sizeof(buf)); - ret = mbedtls_pem_write_buffer("\n", "\n", data, l, buf, olen_needed, &olen); + ret = mbedtls_pem_write_buffer("", "", data, l, buf, olen_needed, &olen); TEST_EQUAL(ret, 0); TEST_EQUAL(olen_needed, olen); /* Test the function didn't overflow the given buffer */ From 854c737db101ebff76d944362d5c36ba296cef24 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 28 Nov 2023 08:37:57 +0100 Subject: [PATCH 10/88] pk: use common header/footer macros for pkwrite and pkparse Signed-off-by: Valerio Setti --- library/pk_internal.h | 14 ++++++++++++++ library/pkparse.c | 20 ++++++++------------ library/pkwrite.c | 10 ---------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/library/pk_internal.h b/library/pk_internal.h index 571b57e8b5..ae329554bc 100644 --- a/library/pk_internal.h +++ b/library/pk_internal.h @@ -21,6 +21,20 @@ #include "psa/crypto.h" #endif +/* Headers/footers for PEM files */ +#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----" +#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----" +#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----" +#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----" +#define PEM_BEGIN_PUBLIC_KEY_RSA "-----BEGIN RSA PUBLIC KEY-----" +#define PEM_END_PUBLIC_KEY_RSA "-----END RSA PUBLIC KEY-----" +#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----" +#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----" +#define PEM_BEGIN_PRIVATE_KEY_PKCS8 "-----BEGIN PRIVATE KEY-----" +#define PEM_END_PRIVATE_KEY_PKCS8 "-----END PRIVATE KEY-----" +#define PEM_BEGIN_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----BEGIN ENCRYPTED PRIVATE KEY-----" +#define PEM_END_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----END ENCRYPTED PRIVATE KEY-----" + #if defined(MBEDTLS_PSA_CRYPTO_C) #include "psa_util_internal.h" #define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status) diff --git a/library/pkparse.c b/library/pkparse.c index 3bb5f7be2e..608c85480d 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -1534,8 +1534,7 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk, ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; } else { ret = mbedtls_pem_read_buffer(&pem, - "-----BEGIN RSA PRIVATE KEY-----", - "-----END RSA PRIVATE KEY-----", + PEM_BEGIN_PRIVATE_KEY_RSA, PEM_END_PRIVATE_KEY_RSA, key, pwd, pwdlen, &len); } @@ -1564,8 +1563,8 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk, ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; } else { ret = mbedtls_pem_read_buffer(&pem, - "-----BEGIN EC PRIVATE KEY-----", - "-----END EC PRIVATE KEY-----", + PEM_BEGIN_PRIVATE_KEY_EC, + PEM_END_PRIVATE_KEY_EC, key, pwd, pwdlen, &len); } if (ret == 0) { @@ -1594,8 +1593,7 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk, ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; } else { ret = mbedtls_pem_read_buffer(&pem, - "-----BEGIN PRIVATE KEY-----", - "-----END PRIVATE KEY-----", + PEM_BEGIN_PRIVATE_KEY_PKCS8, PEM_END_PRIVATE_KEY_PKCS8, key, NULL, 0, &len); } if (ret == 0) { @@ -1616,8 +1614,8 @@ int mbedtls_pk_parse_key(mbedtls_pk_context *pk, ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; } else { ret = mbedtls_pem_read_buffer(&pem, - "-----BEGIN ENCRYPTED PRIVATE KEY-----", - "-----END ENCRYPTED PRIVATE KEY-----", + PEM_BEGIN_ENCRYPTED_PRIVATE_KEY_PKCS8, + PEM_END_ENCRYPTED_PRIVATE_KEY_PKCS8, key, NULL, 0, &len); } if (ret == 0) { @@ -1743,8 +1741,7 @@ int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx, ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; } else { ret = mbedtls_pem_read_buffer(&pem, - "-----BEGIN RSA PUBLIC KEY-----", - "-----END RSA PUBLIC KEY-----", + PEM_BEGIN_PUBLIC_KEY_RSA, PEM_END_PUBLIC_KEY_RSA, key, NULL, 0, &len); } @@ -1777,8 +1774,7 @@ int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx, ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; } else { ret = mbedtls_pem_read_buffer(&pem, - "-----BEGIN PUBLIC KEY-----", - "-----END PUBLIC KEY-----", + PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, key, NULL, 0, &len); } diff --git a/library/pkwrite.c b/library/pkwrite.c index 11c020473e..20961df2bc 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -724,16 +724,6 @@ int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, #if defined(MBEDTLS_PEM_WRITE_C) -#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" -#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" - -#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n" -#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n" -#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n" -#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n" -#define PEM_BEGIN_PRIVATE_KEY_PKCS8 "-----BEGIN PRIVATE KEY-----\n" -#define PEM_END_PRIVATE_KEY_PKCS8 "-----END PRIVATE KEY-----\n" - #define PUB_DER_MAX_BYTES \ (MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES > MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES ? \ MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES : MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES) From 605f03cb766dd21ea8d4096e32c1e70cb86d559f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 28 Nov 2023 12:46:39 +0100 Subject: [PATCH 11/88] pkwrite: reorganize code This commits just moves code around. The goal is to group together functions by guards and functionality: - RSA, EC, Opaque - internal VS public Signed-off-by: Valerio Setti --- library/pkwrite.c | 606 +++++++++++++++++++++++----------------------- 1 file changed, 302 insertions(+), 304 deletions(-) diff --git a/library/pkwrite.c b/library/pkwrite.c index 20961df2bc..30008b992d 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -18,9 +18,6 @@ #include -#if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif #if defined(MBEDTLS_ECP_C) #include "mbedtls/bignum.h" #include "mbedtls/ecp.h" @@ -32,9 +29,6 @@ #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PK_HAVE_ECC_KEYS) #include "pkwrite.h" #endif -#if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" -#endif #if defined(MBEDTLS_PEM_WRITE_C) #include "mbedtls/pem.h" #endif @@ -45,62 +39,9 @@ #endif #include "mbedtls/platform.h" -/* Helper for Montgomery curves */ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) -static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk) -{ - mbedtls_ecp_group_id id = mbedtls_pk_get_group_id(pk); - -#if defined(MBEDTLS_ECP_HAVE_CURVE25519) - if (id == MBEDTLS_ECP_DP_CURVE25519) { - return 1; - } -#endif -#if defined(MBEDTLS_ECP_HAVE_CURVE448) - if (id == MBEDTLS_ECP_DP_CURVE448) { - return 1; - } -#endif - return 0; -} - -#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_PEM_WRITE_C) -/* It is assumed that the input key is opaque */ -static psa_ecc_family_t pk_get_opaque_ec_family(const mbedtls_pk_context *pk) -{ - psa_ecc_family_t ec_family = 0; - psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT; - - if (psa_get_key_attributes(pk->priv_id, &key_attrs) != PSA_SUCCESS) { - return 0; - } - ec_family = PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&key_attrs)); - psa_reset_key_attributes(&key_attrs); - - return ec_family; -} -#endif /* MBETLS_USE_PSA_CRYPTO && MBEDTLS_PEM_WRITE_C */ -#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */ -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -/* It is assumed that the input key is opaque */ -static psa_key_type_t pk_get_opaque_key_type(const mbedtls_pk_context *pk) -{ - psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT; - psa_key_type_t opaque_key_type; - - if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) { - return 0; - } - opaque_key_type = psa_get_key_type(&opaque_attrs); - psa_reset_key_attributes(&opaque_attrs); - - return opaque_key_type; -} -#endif /* MBETLS_USE_PSA_CRYPTO */ - +/****************************************************************************** + * Internal functions for RSA keys. + ******************************************************************************/ #if defined(MBEDTLS_RSA_C) /* * RSAPublicKey ::= SEQUENCE { @@ -145,8 +86,119 @@ end_of_export: return (int) len; } + +static int pk_write_rsa_der(unsigned char **p, unsigned char *buf, + const mbedtls_pk_context *pk) +{ + size_t len = 0; + int ret; + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) { + uint8_t tmp[PSA_EXPORT_KEY_PAIR_MAX_SIZE]; + size_t tmp_len = 0; + + if (psa_export_key(pk->priv_id, tmp, sizeof(tmp), &tmp_len) != PSA_SUCCESS) { + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + *p -= tmp_len; + memcpy(*p, tmp, tmp_len); + len += tmp_len; + mbedtls_platform_zeroize(tmp, sizeof(tmp)); + } else +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + { + mbedtls_mpi T; /* Temporary holding the exported parameters */ + mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk); + + /* + * Export the parameters one after another to avoid simultaneous copies. + */ + + mbedtls_mpi_init(&T); + + /* Export QP */ + if ((ret = mbedtls_rsa_export_crt(rsa, NULL, NULL, &T)) != 0 || + (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { + goto end_of_export; + } + len += ret; + + /* Export DQ */ + if ((ret = mbedtls_rsa_export_crt(rsa, NULL, &T, NULL)) != 0 || + (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { + goto end_of_export; + } + len += ret; + + /* Export DP */ + if ((ret = mbedtls_rsa_export_crt(rsa, &T, NULL, NULL)) != 0 || + (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { + goto end_of_export; + } + len += ret; + + /* Export Q */ + if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, + &T, NULL, NULL)) != 0 || + (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { + goto end_of_export; + } + len += ret; + + /* Export P */ + if ((ret = mbedtls_rsa_export(rsa, NULL, &T, + NULL, NULL, NULL)) != 0 || + (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { + goto end_of_export; + } + len += ret; + + /* Export D */ + if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, + NULL, &T, NULL)) != 0 || + (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { + goto end_of_export; + } + len += ret; + + /* Export E */ + if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, + NULL, NULL, &T)) != 0 || + (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { + goto end_of_export; + } + len += ret; + + /* Export N */ + if ((ret = mbedtls_rsa_export(rsa, &T, NULL, + NULL, NULL, NULL)) != 0 || + (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { + goto end_of_export; + } + len += ret; + +end_of_export: + + mbedtls_mpi_free(&T); + if (ret < 0) { + return ret; + } + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 0)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, + buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE)); + } + + return (int) len; +} #endif /* MBEDTLS_RSA_C */ +/****************************************************************************** + * Internal functions for EC keys. + ******************************************************************************/ #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start, @@ -215,28 +267,6 @@ static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start, } #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ -/* - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * } - */ -static int pk_write_ec_param(unsigned char **p, unsigned char *start, - mbedtls_ecp_group_id grp_id) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - const char *oid; - size_t oid_len; - - if ((ret = mbedtls_oid_get_oid_by_ec_grp(grp_id, &oid, &oid_len)) != 0) { - return ret; - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len)); - - return (int) len; -} - /* * privateKey OCTET STRING -- always of length ceil(log2(n)/8) */ @@ -305,9 +335,174 @@ exit: return ret; } #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ + +/* + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * } + */ +static int pk_write_ec_param(unsigned char **p, unsigned char *start, + mbedtls_ecp_group_id grp_id) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len = 0; + const char *oid; + size_t oid_len; + + if ((ret = mbedtls_oid_get_oid_by_ec_grp(grp_id, &oid, &oid_len)) != 0) { + return ret; + } + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len)); + + return (int) len; +} + +#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) +static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk) +{ + mbedtls_ecp_group_id id = mbedtls_pk_get_group_id(pk); + +#if defined(MBEDTLS_ECP_HAVE_CURVE25519) + if (id == MBEDTLS_ECP_DP_CURVE25519) { + return 1; + } +#endif +#if defined(MBEDTLS_ECP_HAVE_CURVE448) + if (id == MBEDTLS_ECP_DP_CURVE448) { + return 1; + } +#endif + return 0; +} + +/* + * RFC8410 section 7 + * + * OneAsymmetricKey ::= SEQUENCE { + * version Version, + * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + * privateKey PrivateKey, + * attributes [0] IMPLICIT Attributes OPTIONAL, + * ..., + * [[2: publicKey [1] IMPLICIT PublicKey OPTIONAL ]], + * ... + * } + * ... + * CurvePrivateKey ::= OCTET STRING + */ +static int pk_write_ec_rfc8410_der(unsigned char **p, unsigned char *buf, + const mbedtls_pk_context *pk) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len = 0; + size_t oid_len = 0; + const char *oid; + mbedtls_ecp_group_id grp_id; + + /* privateKey */ + MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_OCTET_STRING)); + + grp_id = mbedtls_pk_get_group_id(pk); + /* privateKeyAlgorithm */ + if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(grp_id, &oid, &oid_len)) != 0) { + return ret; + } + MBEDTLS_ASN1_CHK_ADD(len, + mbedtls_asn1_write_algorithm_identifier_ext(p, buf, oid, oid_len, 0, 0)); + + /* version */ + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 0)); + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE)); + + return (int) len; +} +#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */ + +/* + * RFC 5915, or SEC1 Appendix C.4 + * + * ECPrivateKey ::= SEQUENCE { + * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + * privateKey OCTET STRING, + * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + * publicKey [1] BIT STRING OPTIONAL + * } + */ +static int pk_write_ec_der(unsigned char **p, unsigned char *buf, + const mbedtls_pk_context *pk) +{ + size_t len = 0; + int ret; + size_t pub_len = 0, par_len = 0; + mbedtls_ecp_group_id grp_id; + + /* publicKey */ + MBEDTLS_ASN1_CHK_ADD(pub_len, pk_write_ec_pubkey(p, buf, pk)); + + if (*p - buf < 1) { + return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; + } + (*p)--; + **p = 0; + pub_len += 1; + + MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len)); + MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_BIT_STRING)); + + MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len)); + MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | + MBEDTLS_ASN1_CONSTRUCTED | 1)); + len += pub_len; + + /* parameters */ + grp_id = mbedtls_pk_get_group_id(pk); + MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(p, buf, grp_id)); + MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_len(p, buf, par_len)); + MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_tag(p, buf, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | + MBEDTLS_ASN1_CONSTRUCTED | 0)); + len += par_len; + + /* privateKey */ + MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk)); + + /* version */ + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 1)); + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE)); + + return (int) len; +} #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ +/****************************************************************************** + * Internal functions for Opaque keys. + ******************************************************************************/ #if defined(MBEDTLS_USE_PSA_CRYPTO) +/* It is assumed that the input key is opaque */ +static psa_key_type_t pk_get_opaque_key_type(const mbedtls_pk_context *pk) +{ + psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT; + psa_key_type_t opaque_key_type; + + if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) { + return 0; + } + opaque_key_type = psa_get_key_type(&opaque_attrs); + psa_reset_key_attributes(&opaque_attrs); + + return opaque_key_type; +} + static int pk_write_opaque_pubkey(unsigned char **p, unsigned char *start, const mbedtls_pk_context *pk) { @@ -329,8 +524,28 @@ static int pk_write_opaque_pubkey(unsigned char **p, unsigned char *start, return (int) len; } + +#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && defined(MBEDTLS_PEM_WRITE_C) +/* It is assumed that the input key is opaque */ +static psa_ecc_family_t pk_get_opaque_ec_family(const mbedtls_pk_context *pk) +{ + psa_ecc_family_t ec_family = 0; + psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT; + + if (psa_get_key_attributes(pk->priv_id, &key_attrs) != PSA_SUCCESS) { + return 0; + } + ec_family = PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&key_attrs)); + psa_reset_key_attributes(&key_attrs); + + return ec_family; +} +#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && MBEDTLS_PEM_WRITE_C */ #endif /* MBEDTLS_USE_PSA_CRYPTO */ +/****************************************************************************** + * Public functions for writing private/public DER keys. + ******************************************************************************/ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start, const mbedtls_pk_context *key) { @@ -453,226 +668,6 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu return (int) len; } -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) -/* - * RFC8410 section 7 - * - * OneAsymmetricKey ::= SEQUENCE { - * version Version, - * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - * privateKey PrivateKey, - * attributes [0] IMPLICIT Attributes OPTIONAL, - * ..., - * [[2: publicKey [1] IMPLICIT PublicKey OPTIONAL ]], - * ... - * } - * ... - * CurvePrivateKey ::= OCTET STRING - */ -static int pk_write_ec_rfc8410_der(unsigned char **p, unsigned char *buf, - const mbedtls_pk_context *pk) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len = 0; - size_t oid_len = 0; - const char *oid; - mbedtls_ecp_group_id grp_id; - - /* privateKey */ - MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_OCTET_STRING)); - - grp_id = mbedtls_pk_get_group_id(pk); - /* privateKeyAlgorithm */ - if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(grp_id, &oid, &oid_len)) != 0) { - return ret; - } - MBEDTLS_ASN1_CHK_ADD(len, - mbedtls_asn1_write_algorithm_identifier_ext(p, buf, oid, oid_len, 0, 0)); - - /* version */ - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 0)); - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - return (int) len; -} -#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */ - -/* - * RFC 5915, or SEC1 Appendix C.4 - * - * ECPrivateKey ::= SEQUENCE { - * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - * privateKey OCTET STRING, - * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, - * publicKey [1] BIT STRING OPTIONAL - * } - */ -static int pk_write_ec_der(unsigned char **p, unsigned char *buf, - const mbedtls_pk_context *pk) -{ - size_t len = 0; - int ret; - size_t pub_len = 0, par_len = 0; - mbedtls_ecp_group_id grp_id; - - /* publicKey */ - MBEDTLS_ASN1_CHK_ADD(pub_len, pk_write_ec_pubkey(p, buf, pk)); - - if (*p - buf < 1) { - return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; - } - (*p)--; - **p = 0; - pub_len += 1; - - MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len)); - MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_BIT_STRING)); - - MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_len(p, buf, pub_len)); - MBEDTLS_ASN1_CHK_ADD(pub_len, mbedtls_asn1_write_tag(p, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 1)); - len += pub_len; - - /* parameters */ - grp_id = mbedtls_pk_get_group_id(pk); - MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(p, buf, grp_id)); - MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_len(p, buf, par_len)); - MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_tag(p, buf, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | - MBEDTLS_ASN1_CONSTRUCTED | 0)); - len += par_len; - - /* privateKey */ - MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_private(p, buf, pk)); - - /* version */ - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 1)); - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - - return (int) len; -} -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - -#if defined(MBEDTLS_RSA_C) -static int pk_write_rsa_der(unsigned char **p, unsigned char *buf, - const mbedtls_pk_context *pk) -{ - size_t len = 0; - int ret; - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) { - uint8_t tmp[PSA_EXPORT_KEY_PAIR_MAX_SIZE]; - size_t tmp_len = 0; - - if (psa_export_key(pk->priv_id, tmp, sizeof(tmp), &tmp_len) != PSA_SUCCESS) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - *p -= tmp_len; - memcpy(*p, tmp, tmp_len); - len += tmp_len; - mbedtls_platform_zeroize(tmp, sizeof(tmp)); - } else -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - { - mbedtls_mpi T; /* Temporary holding the exported parameters */ - mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk); - - /* - * Export the parameters one after another to avoid simultaneous copies. - */ - - mbedtls_mpi_init(&T); - - /* Export QP */ - if ((ret = mbedtls_rsa_export_crt(rsa, NULL, NULL, &T)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export DQ */ - if ((ret = mbedtls_rsa_export_crt(rsa, NULL, &T, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export DP */ - if ((ret = mbedtls_rsa_export_crt(rsa, &T, NULL, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export Q */ - if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, - &T, NULL, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export P */ - if ((ret = mbedtls_rsa_export(rsa, NULL, &T, - NULL, NULL, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export D */ - if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, - NULL, &T, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export E */ - if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, - NULL, NULL, &T)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { - goto end_of_export; - } - len += ret; - - /* Export N */ - if ((ret = mbedtls_rsa_export(rsa, &T, NULL, - NULL, NULL, NULL)) != 0 || - (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) { - goto end_of_export; - } - len += ret; - -end_of_export: - - mbedtls_mpi_free(&T); - if (ret < 0) { - return ret; - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 0)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, - buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); - } - - return (int) len; -} -#endif /* MBEDTLS_RSA_C */ - int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size) { unsigned char *c; @@ -722,6 +717,9 @@ int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; } +/****************************************************************************** + * Public functions for wrinting private/public PEM keys. + ******************************************************************************/ #if defined(MBEDTLS_PEM_WRITE_C) #define PUB_DER_MAX_BYTES \ From d5604bacc427542e43e69a7b1400cbb2d7e70363 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 28 Nov 2023 14:10:43 +0100 Subject: [PATCH 12/88] pkwrite: add internal defines for proper key buffer sizes Signed-off-by: Valerio Setti --- library/pkwrite.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/library/pkwrite.c b/library/pkwrite.c index 30008b992d..7a9cfedbd5 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -39,6 +39,21 @@ #endif #include "mbedtls/platform.h" +/* Helpers for properly sizing buffers aimed at holding public keys or + * key-pairs based on build symbols. */ +#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) +#define PK_MAX_EC_PUBLIC_KEY_SIZE PSA_EXPORT_PUBLIC_KEY_MAX_SIZE +#define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH +#else +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#define PK_MAX_EC_PUBLIC_KEY_SIZE PSA_EXPORT_PUBLIC_KEY_MAX_SIZE +#define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH +#else +#define PK_MAX_EC_PUBLIC_KEY_SIZE MBEDTLS_ECP_MAX_PT_LEN +#define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_ECP_MAX_BYTES +#endif +#endif + /****************************************************************************** * Internal functions for RSA keys. ******************************************************************************/ @@ -205,7 +220,7 @@ static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start, const mbedtls_pk_context *pk) { size_t len = 0; - uint8_t buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; + uint8_t buf[PK_MAX_EC_PUBLIC_KEY_SIZE]; if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) { if (psa_export_public_key(pk->priv_id, buf, sizeof(buf), &len) != PSA_SUCCESS) { @@ -230,11 +245,7 @@ static int pk_write_ec_pubkey(unsigned char **p, unsigned char *start, const mbedtls_pk_context *pk) { size_t len = 0; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - uint8_t buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; -#else - unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN]; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ + unsigned char buf[PK_MAX_EC_PUBLIC_KEY_SIZE]; mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*pk); int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -276,7 +287,7 @@ static int pk_write_ec_private(unsigned char **p, unsigned char *start, { size_t byte_length; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - unsigned char tmp[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH]; + unsigned char tmp[PK_MAX_EC_KEY_PAIR_SIZE]; psa_status_t status; if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) { @@ -304,14 +315,10 @@ static int pk_write_ec_private(unsigned char **p, unsigned char *start, { size_t byte_length; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - unsigned char tmp[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH]; - psa_status_t status; -#else - unsigned char tmp[MBEDTLS_ECP_MAX_BYTES]; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ + unsigned char tmp[PK_MAX_EC_KEY_PAIR_SIZE]; #if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_status_t status; if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) { status = psa_export_key(pk->priv_id, tmp, sizeof(tmp), &byte_length); if (status != PSA_SUCCESS) { From bcd305913fb9faf985197bf2cc5d871d5ad1ff28 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 28 Nov 2023 16:27:55 +0100 Subject: [PATCH 13/88] pk: move functions to verify RFC8410 group ID to pk_internal Signed-off-by: Valerio Setti --- library/pk_internal.h | 10 ++++++++++ library/pkparse.c | 6 ------ library/pkwrite.c | 17 ----------------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/library/pk_internal.h b/library/pk_internal.h index ae329554bc..ece2f82b7b 100644 --- a/library/pk_internal.h +++ b/library/pk_internal.h @@ -119,6 +119,16 @@ static inline mbedtls_ecp_group_id mbedtls_pk_get_group_id(const mbedtls_pk_cont #if defined(MBEDTLS_ECP_HAVE_CURVE25519) || defined(MBEDTLS_ECP_HAVE_CURVE448) #define MBEDTLS_PK_HAVE_RFC8410_CURVES #endif /* MBEDTLS_ECP_HAVE_CURVE25519 || MBEDTLS_ECP_DP_CURVE448 */ + +#define MBEDTLS_PK_IS_RFC8410_GROUP_ID(id) \ + ((id == MBEDTLS_ECP_DP_CURVE25519) || (id == MBEDTLS_ECP_DP_CURVE448)) + +static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk) +{ + mbedtls_ecp_group_id id = mbedtls_pk_get_group_id(pk); + + return MBEDTLS_PK_IS_RFC8410_GROUP_ID(id); +} #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ /* Helper for (deterministic) ECDSA */ diff --git a/library/pkparse.c b/library/pkparse.c index 608c85480d..0b5de8db3d 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -863,12 +863,6 @@ static int pk_get_pk_alg(unsigned char **p, return 0; } -/* Helper for Montgomery curves */ -#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) -#define MBEDTLS_PK_IS_RFC8410_GROUP_ID(id) \ - ((id == MBEDTLS_ECP_DP_CURVE25519) || (id == MBEDTLS_ECP_DP_CURVE448)) -#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */ - /* * SubjectPublicKeyInfo ::= SEQUENCE { * algorithm AlgorithmIdentifier, diff --git a/library/pkwrite.c b/library/pkwrite.c index 7a9cfedbd5..468df14663 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -366,23 +366,6 @@ static int pk_write_ec_param(unsigned char **p, unsigned char *start, } #if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) -static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk) -{ - mbedtls_ecp_group_id id = mbedtls_pk_get_group_id(pk); - -#if defined(MBEDTLS_ECP_HAVE_CURVE25519) - if (id == MBEDTLS_ECP_DP_CURVE25519) { - return 1; - } -#endif -#if defined(MBEDTLS_ECP_HAVE_CURVE448) - if (id == MBEDTLS_ECP_DP_CURVE448) { - return 1; - } -#endif - return 0; -} - /* * RFC8410 section 7 * From 677285a2998289d59ba264c77918e863f988fb1a Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 28 Nov 2023 16:45:50 +0100 Subject: [PATCH 14/88] Clarify "functions that facilitate the transition" Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index fabac9c85a..b25f8b2580 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -50,7 +50,7 @@ Then use the [summary of API modules](#summary-of-api-modules), the table of con To make the PSA API available, make sure that the configuration option [`MBEDTLS_PSA_CRYPTO_C`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#c.MBEDTLS_PSA_CRYPTO_C) is enabled (it is enabled in the default configuration). -You should probably enable [`MBEDTLS_USE_PSA_CRYPTO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a70fd7b97d5f11170546583f2095942a6) as well (it is disabled by default). This option causes the PK, X.509 and TLS modules to use PSA crypto under the hood. Some functions that facilitate the transition are only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled. +You should probably enable [`MBEDTLS_USE_PSA_CRYPTO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a70fd7b97d5f11170546583f2095942a6) as well (it is disabled by default). This option causes the PK, X.509 and TLS modules to use PSA crypto under the hood. Some functions that facilitate the transition (for example, to convert between metadata encodings or between key representations) are only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled. By default, the PSA crypto API offers a similar set of cryptographic mechanisms as those offered by the legacy API. The PSA crypto API also has its own configuration mechanism; see “[Cryptographic mechanism availability](#cryptographic-mechanism-availability)”. From 5403cb340ab348af7e7c1219cb968f7ee83f0f67 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 28 Nov 2023 18:03:03 +0100 Subject: [PATCH 15/88] typos Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index b25f8b2580..70a92c4831 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -587,11 +587,11 @@ Applications currently using `mbedtls_pkcs5_pbkdf2_hmac` or `mbedtls_pkcs5_pbkdf If you want to verify the output against an expected value (for authentication, rather than to derive key material), call `psa_key_derivation_verify_bytes` or `psa_key_derivation_verify_key` instead of `psa_key_derivation_output_bytes`. 6. Call [`psa_key_derivation_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) to free the resources associated with the key derivation object. -The function `mbedtls_pkcs5_pbes2` is only inteded as a support function to parse encrypted private keys in the PK module. It has no PSA equivalent. +The function `mbedtls_pkcs5_pbes2` is only intended as a support function to parse encrypted private keys in the PK module. It has no PSA equivalent. ### PKCS#12 module -The functions `mbedtls_pkcs12_derivation` and `mbedtls_pkcs12_pbes2` are only intended as supports function to parse encrypted private keys in the PK module. They have no PSA equivalent. +The functions `mbedtls_pkcs12_derivation` and `mbedtls_pkcs12_pbes2` are only intended as support functions to parse encrypted private keys in the PK module. They have no PSA equivalent. ## Random generation From 601d3a0bd736531129453b2195cd9dd902696eb4 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 28 Nov 2023 18:03:16 +0100 Subject: [PATCH 16/88] Add links to newly added functions Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 70a92c4831..9e4f4b5c6b 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -584,7 +584,7 @@ Applications currently using `mbedtls_pkcs5_pbkdf2_hmac` or `mbedtls_pkcs5_pbkdf 2. [`PSA_KEY_DERIVATION_INPUT_SECRET`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__derivation/#group__derivation_1ga0ddfbe764baba995c402b1b0ef59392e) for the password. 5. Call [`psa_key_derivation_output_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga06b7eb34a2fa88965f68e3d023fa12b9) to obtain the output of the derivation. You may call this function more than once to retrieve the output in successive chunks. Use [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1) instead if you want to use a chunk as a PSA key. - If you want to verify the output against an expected value (for authentication, rather than to derive key material), call `psa_key_derivation_verify_bytes` or `psa_key_derivation_verify_key` instead of `psa_key_derivation_output_bytes`. + If you want to verify the output against an expected value (for authentication, rather than to derive key material), call [`psa_key_derivation_verify_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gaf01520beb7ba932143ffe733b0795b08) or [`psa_key_derivation_verify_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gac041714e34a94742e8ee006ac7dfea5a) instead of `psa_key_derivation_output_bytes`. 6. Call [`psa_key_derivation_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) to free the resources associated with the key derivation object. The function `mbedtls_pkcs5_pbes2` is only intended as a support function to parse encrypted private keys in the PK module. It has no PSA equivalent. From d372da6201a7d7b04e9b595bbe638df9c9b3e7ea Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 28 Nov 2023 18:03:53 +0100 Subject: [PATCH 17/88] Expand on the removal of RNG boilerplate Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 9e4f4b5c6b..c840b0307f 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -597,7 +597,7 @@ The functions `mbedtls_pkcs12_derivation` and `mbedtls_pkcs12_pbes2` are only in ### Random generation interface -The PSA subsystem has an internal random generator. As a consequence, you do not need to instantiate one manually, so most applications using PSA crypto do not need the interfaces from `entropy.h`, `ctr_drbg.` and `hmac_drbg.h`. +The PSA subsystem has an internal random generator. As a consequence, you do not need to instantiate one manually, so most applications using PSA crypto do not need the interfaces from `entropy.h`, `ctr_drbg.` and `hmac_drbg.h`. See the next sections for remaining use cases for [entropy](#entropy-sources) and [DRBG](#deterministic-pseudorandom-generation). The PSA API uses its internal random generator to generate keys (`psa_generate_key`), nonces for encryption (`psa_cipher_generate_iv`, `psa_cipher_encrypt`, `psa_aead_generate_nonce`, `psa_aead_encrypt`, `psa_asymmetric_encrypt`), and other random material as needed. If you need random data for some other purposes, call [`psa_generate_random`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). @@ -606,6 +606,8 @@ If your application mixes uses of the PSA crypto API and the mbedtls API and you * [`mbedtls_psa_get_random`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#_CPPv422mbedtls_psa_get_randomPvPh6size_t) as the `f_rng` argument; * [`MBEDTLS_PSA_RANDOM_STATE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/psa__util_8h/#c.MBEDTLS_PSA_RANDOM_STATE) as the `p_rng` argument. +You can remove the Mbed TLS RNG boilerplate (`mbedtls_entropy_init`, `mbedtls_ctr_drbg_init`, `mbedtls_ctr_drbg_seed`, `mbedtls_ctr_drbg_random`, `mbedtls_ctr_drbg_free`, `mbedtls_entropy_free` — or `hmac_drbg` equivalents of the `ctr_drbg` functions) once you have finished replacing the references to `mbedtls_ctr_drbg_random` (or `mbedtls_hmac_drbg_random`) by `mbedtls_psa_get_random`. + ### Entropy sources Unless explicitly configured otherwise, the PSA random generator uses the default entropy sources configured through the legacy interface (`MBEDTLS_ENTROPY_xxx` symbols). Its set of sources is equivalent to an entropy object configured with `mbedtls_entropy_init`. From f9362b7324b1e4e4e6eb7a71420a68ae599d108b Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 29 Nov 2023 08:42:27 +0100 Subject: [PATCH 18/88] pk_internal: small renaming for mbedtls_pk_get_group_id() Signed-off-by: Valerio Setti --- library/pk_internal.h | 4 ++-- library/pkwrite.c | 8 ++++---- library/ssl_tls.c | 2 +- library/ssl_tls12_client.c | 2 +- library/ssl_tls12_server.c | 4 ++-- library/x509_crt.c | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/library/pk_internal.h b/library/pk_internal.h index ece2f82b7b..81807f1338 100644 --- a/library/pk_internal.h +++ b/library/pk_internal.h @@ -85,7 +85,7 @@ static inline mbedtls_ecp_keypair *mbedtls_pk_ec_rw(const mbedtls_pk_context pk) #endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */ #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -static inline mbedtls_ecp_group_id mbedtls_pk_get_group_id(const mbedtls_pk_context *pk) +static inline mbedtls_ecp_group_id mbedtls_pk_get_ec_group_id(const mbedtls_pk_context *pk) { mbedtls_ecp_group_id id; @@ -125,7 +125,7 @@ static inline mbedtls_ecp_group_id mbedtls_pk_get_group_id(const mbedtls_pk_cont static inline int mbedtls_pk_is_rfc8410(const mbedtls_pk_context *pk) { - mbedtls_ecp_group_id id = mbedtls_pk_get_group_id(pk); + mbedtls_ecp_group_id id = mbedtls_pk_get_ec_group_id(pk); return MBEDTLS_PK_IS_RFC8410_GROUP_ID(id); } diff --git a/library/pkwrite.c b/library/pkwrite.c index 468df14663..2ef723f153 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -395,7 +395,7 @@ static int pk_write_ec_rfc8410_der(unsigned char **p, unsigned char *buf, MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len)); MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, buf, MBEDTLS_ASN1_OCTET_STRING)); - grp_id = mbedtls_pk_get_group_id(pk); + grp_id = mbedtls_pk_get_ec_group_id(pk); /* privateKeyAlgorithm */ if ((ret = mbedtls_oid_get_oid_by_ec_grp_algid(grp_id, &oid, &oid_len)) != 0) { return ret; @@ -452,7 +452,7 @@ static int pk_write_ec_der(unsigned char **p, unsigned char *buf, len += pub_len; /* parameters */ - grp_id = mbedtls_pk_get_group_id(pk); + grp_id = mbedtls_pk_get_ec_group_id(pk); MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(p, buf, grp_id)); MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_len(p, buf, par_len)); MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_tag(p, buf, @@ -600,7 +600,7 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu pk_type = mbedtls_pk_get_type(key); #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) if (pk_type == MBEDTLS_PK_ECKEY) { - ec_grp_id = mbedtls_pk_get_group_id(key); + ec_grp_id = mbedtls_pk_get_ec_group_id(key); } #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ #if defined(MBEDTLS_USE_PSA_CRYPTO) @@ -609,7 +609,7 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) if (PSA_KEY_TYPE_IS_ECC(opaque_key_type)) { pk_type = MBEDTLS_PK_ECKEY; - ec_grp_id = mbedtls_pk_get_group_id(key); + ec_grp_id = mbedtls_pk_get_ec_group_id(key); } else #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ if (PSA_KEY_TYPE_IS_RSA(opaque_key_type)) { diff --git a/library/ssl_tls.c b/library/ssl_tls.c index b163e93c25..138c7f48ad 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -7422,7 +7422,7 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl, /* and in the unlikely case the above assumption no longer holds * we are making sure that pk_ec() here does not return a NULL */ - mbedtls_ecp_group_id grp_id = mbedtls_pk_get_group_id(pk); + mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(pk); if (grp_id == MBEDTLS_ECP_DP_NONE) { MBEDTLS_SSL_DEBUG_MSG(1, ("invalid group ID")); return MBEDTLS_ERR_SSL_INTERNAL_ERROR; diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index 9aa46bd154..7f1ddaf006 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -2016,7 +2016,7 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl) #if defined(MBEDTLS_USE_PSA_CRYPTO) uint16_t tls_id = 0; psa_key_type_t key_type = PSA_KEY_TYPE_NONE; - mbedtls_ecp_group_id grp_id = mbedtls_pk_get_group_id(peer_pk); + mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(peer_pk); if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) { MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)")); diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index b007e5c66e..54e1cd4f78 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -664,7 +664,7 @@ static int ssl_check_key_curve(mbedtls_pk_context *pk, uint16_t *curves_tls_id) { uint16_t *curr_tls_id = curves_tls_id; - mbedtls_ecp_group_id grp_id = mbedtls_pk_get_group_id(pk); + mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(pk); mbedtls_ecp_group_id curr_grp_id; while (*curr_tls_id != 0) { @@ -2651,7 +2651,7 @@ static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl) case MBEDTLS_PK_ECKEY_DH: case MBEDTLS_PK_ECDSA: key = mbedtls_pk_ec_rw(*pk); - grp_id = mbedtls_pk_get_group_id(pk); + grp_id = mbedtls_pk_get_ec_group_id(pk); if (grp_id == MBEDTLS_ECP_DP_NONE) { return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } diff --git a/library/x509_crt.c b/library/x509_crt.c index f41eb47d72..0c3e3fa609 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -222,7 +222,7 @@ static int x509_profile_check_key(const mbedtls_x509_crt_profile *profile, if (pk_alg == MBEDTLS_PK_ECDSA || pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH) { - const mbedtls_ecp_group_id gid = mbedtls_pk_get_group_id(pk); + const mbedtls_ecp_group_id gid = mbedtls_pk_get_ec_group_id(pk); if (gid == MBEDTLS_ECP_DP_NONE) { return -1; From a4f70fe3fe2c7ad55c6b550bc1090d5aedd80946 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 29 Nov 2023 15:05:47 +0100 Subject: [PATCH 19/88] pkwrite: simplify management of opaque keys Signed-off-by: Valerio Setti --- library/pkwrite.c | 160 ++++++++++++---------------------------------- 1 file changed, 41 insertions(+), 119 deletions(-) diff --git a/library/pkwrite.c b/library/pkwrite.c index 2ef723f153..900a804dc0 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -478,21 +478,6 @@ static int pk_write_ec_der(unsigned char **p, unsigned char *buf, * Internal functions for Opaque keys. ******************************************************************************/ #if defined(MBEDTLS_USE_PSA_CRYPTO) -/* It is assumed that the input key is opaque */ -static psa_key_type_t pk_get_opaque_key_type(const mbedtls_pk_context *pk) -{ - psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT; - psa_key_type_t opaque_key_type; - - if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) { - return 0; - } - opaque_key_type = psa_get_key_type(&opaque_attrs); - psa_reset_key_attributes(&opaque_attrs); - - return opaque_key_type; -} - static int pk_write_opaque_pubkey(unsigned char **p, unsigned char *start, const mbedtls_pk_context *pk) { @@ -514,25 +499,41 @@ static int pk_write_opaque_pubkey(unsigned char **p, unsigned char *start, return (int) len; } - -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && defined(MBEDTLS_PEM_WRITE_C) -/* It is assumed that the input key is opaque */ -static psa_ecc_family_t pk_get_opaque_ec_family(const mbedtls_pk_context *pk) -{ - psa_ecc_family_t ec_family = 0; - psa_key_attributes_t key_attrs = PSA_KEY_ATTRIBUTES_INIT; - - if (psa_get_key_attributes(pk->priv_id, &key_attrs) != PSA_SUCCESS) { - return 0; - } - ec_family = PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&key_attrs)); - psa_reset_key_attributes(&key_attrs); - - return ec_family; -} -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && MBEDTLS_PEM_WRITE_C */ #endif /* MBEDTLS_USE_PSA_CRYPTO */ +/****************************************************************************** + * Generic helpers + ******************************************************************************/ + +/* Extend the public mbedtls_pk_get_type() by getting key type also in case of + * opaque keys. */ +static mbedtls_pk_type_t pk_get_type_ext(const mbedtls_pk_context *pk) +{ + mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if (pk_type == MBEDTLS_PK_OPAQUE) { + psa_key_attributes_t opaque_attrs = PSA_KEY_ATTRIBUTES_INIT; + psa_key_type_t opaque_key_type; + + if (psa_get_key_attributes(pk->priv_id, &opaque_attrs) != PSA_SUCCESS) { + return MBEDTLS_PK_NONE; + } + opaque_key_type = psa_get_key_type(&opaque_attrs); + psa_reset_key_attributes(&opaque_attrs); + + if (PSA_KEY_TYPE_IS_ECC(opaque_key_type)) { + return MBEDTLS_PK_ECKEY; + } else if (PSA_KEY_TYPE_IS_RSA(opaque_key_type)) { + return MBEDTLS_PK_RSA; + } else { + return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; + } + } else +#endif + return pk_type; +} + /****************************************************************************** * Public functions for writing private/public DER keys. ******************************************************************************/ @@ -569,9 +570,6 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu int has_par = 1; size_t len = 0, par_len = 0, oid_len = 0; mbedtls_pk_type_t pk_type; -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - mbedtls_ecp_group_id ec_grp_id = MBEDTLS_ECP_DP_NONE; -#endif const char *oid = NULL; if (size == 0) { @@ -597,34 +595,11 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_BIT_STRING)); - pk_type = mbedtls_pk_get_type(key); -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (pk_type == MBEDTLS_PK_ECKEY) { - ec_grp_id = mbedtls_pk_get_ec_group_id(key); - } -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (pk_type == MBEDTLS_PK_OPAQUE) { - psa_key_type_t opaque_key_type = pk_get_opaque_key_type(key); -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (PSA_KEY_TYPE_IS_ECC(opaque_key_type)) { - pk_type = MBEDTLS_PK_ECKEY; - ec_grp_id = mbedtls_pk_get_ec_group_id(key); - } else -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - if (PSA_KEY_TYPE_IS_RSA(opaque_key_type)) { - /* The rest of the function works as for legacy RSA contexts. */ - pk_type = MBEDTLS_PK_RSA; - } - } - /* `pk_type` will have been changed to non-opaque by here if this function can handle it */ - if (pk_type == MBEDTLS_PK_OPAQUE) { - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ + pk_type = pk_get_type_ext(key); #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) if (pk_type == MBEDTLS_PK_ECKEY) { + mbedtls_ecp_group_id ec_grp_id = mbedtls_pk_get_ec_group_id(key); /* Some groups have their own AlgorithmIdentifier OID, others are handled * by mbedtls_oid_get_oid_by_pk_alg() below */ ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec_grp_id, &oid, &oid_len); @@ -661,15 +636,6 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, size_t size) { unsigned char *c; -#if defined(MBEDTLS_RSA_C) - int is_rsa_opaque = 0; -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - int is_ec_opaque = 0; -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_key_type_t opaque_key_type; -#endif /* MBEDTLS_USE_PSA_CRYPTO */ if (size == 0) { return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; @@ -677,25 +643,13 @@ int mbedtls_pk_write_key_der(const mbedtls_pk_context *key, unsigned char *buf, c = buf + size; -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) { - opaque_key_type = pk_get_opaque_key_type(key); #if defined(MBEDTLS_RSA_C) - is_rsa_opaque = PSA_KEY_TYPE_IS_RSA(opaque_key_type); -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - is_ec_opaque = PSA_KEY_TYPE_IS_ECC(opaque_key_type); -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_RSA_C) - if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) || is_rsa_opaque) { + if (pk_get_type_ext(key) == MBEDTLS_PK_RSA) { return pk_write_rsa_der(&c, buf, key); } else #endif /* MBEDTLS_RSA_C */ #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) || is_ec_opaque) { + if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) { #if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) if (mbedtls_pk_is_rfc8410(key)) { return pk_write_ec_rfc8410_der(&c, buf, key); @@ -756,55 +710,23 @@ int mbedtls_pk_write_key_pem(const mbedtls_pk_context *key, unsigned char *buf, } const char *begin, *end; size_t olen = 0; -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - int is_ec_opaque = 0; -#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) - int is_montgomery_opaque = 0; -#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */ -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ -#if defined(MBEDTLS_RSA_C) - int is_rsa_opaque = 0; -#endif if ((ret = mbedtls_pk_write_key_der(key, output_buf, PRV_DER_MAX_BYTES)) < 0) { goto cleanup; } -#if defined(MBEDTLS_USE_PSA_CRYPTO) - if (mbedtls_pk_get_type(key) == MBEDTLS_PK_OPAQUE) { - psa_key_type_t opaque_key_type = pk_get_opaque_key_type(key); - #if defined(MBEDTLS_RSA_C) - is_rsa_opaque = PSA_KEY_TYPE_IS_RSA(opaque_key_type); -#endif -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - is_ec_opaque = PSA_KEY_TYPE_IS_ECC(opaque_key_type); -#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) - if (pk_get_opaque_ec_family(key) == PSA_ECC_FAMILY_MONTGOMERY) { - is_montgomery_opaque = 1; - } -#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */ -#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ - } -#endif /* MBEDTLS_USE_PSA_CRYPTO */ - -#if defined(MBEDTLS_RSA_C) - if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) || is_rsa_opaque) { + if (pk_get_type_ext(key) == MBEDTLS_PK_RSA) { begin = PEM_BEGIN_PRIVATE_KEY_RSA; end = PEM_END_PRIVATE_KEY_RSA; } else #endif #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if ((mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) || is_ec_opaque) { -#if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES) - if (is_montgomery_opaque || - ((mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) && - (mbedtls_pk_is_rfc8410(key)))) { + if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) { + if (mbedtls_pk_is_rfc8410(key)) { begin = PEM_BEGIN_PRIVATE_KEY_PKCS8; end = PEM_END_PRIVATE_KEY_PKCS8; - } else -#endif /* MBEDTLS_PK_HAVE_RFC8410_CURVES */ - { + } else { begin = PEM_BEGIN_PRIVATE_KEY_EC; end = PEM_END_PRIVATE_KEY_EC; } From bcc004b549ef6e89a160e5d22aa0a102d6a99264 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 29 Nov 2023 17:16:55 +0100 Subject: [PATCH 20/88] pkwrite: some reshaping for Montgomery keys in mbedtls_pk_write_pubkey_der() Signed-off-by: Valerio Setti --- library/pkwrite.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/library/pkwrite.c b/library/pkwrite.c index 900a804dc0..15b8a8d343 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -598,27 +598,24 @@ int mbedtls_pk_write_pubkey_der(const mbedtls_pk_context *key, unsigned char *bu pk_type = pk_get_type_ext(key); #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) - if (pk_type == MBEDTLS_PK_ECKEY) { + if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) { mbedtls_ecp_group_id ec_grp_id = mbedtls_pk_get_ec_group_id(key); - /* Some groups have their own AlgorithmIdentifier OID, others are handled - * by mbedtls_oid_get_oid_by_pk_alg() below */ - ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec_grp_id, &oid, &oid_len); - - if (ret == 0) { - /* Currently, none of the supported algorithms that have their own - * AlgorithmIdentifier OID have any parameters */ + if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) { + ret = mbedtls_oid_get_oid_by_ec_grp_algid(ec_grp_id, &oid, &oid_len); + if (ret != 0) { + return ret; + } has_par = 0; - } else if (ret == MBEDTLS_ERR_OID_NOT_FOUND) { - MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec_grp_id)); } else { - return ret; + MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, ec_grp_id)); } } #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ + /* At this point oid_len is not null only for EC Montgomery keys. */ if (oid_len == 0) { - if ((ret = mbedtls_oid_get_oid_by_pk_alg(pk_type, &oid, - &oid_len)) != 0) { + ret = mbedtls_oid_get_oid_by_pk_alg(pk_type, &oid, &oid_len); + if (ret != 0) { return ret; } } From dfe6707fc7a997b98dc10278fd9a07be210cadf4 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 29 Nov 2023 21:12:39 +0100 Subject: [PATCH 21/88] Fix typos and make minor style improvements Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 60 +++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index c840b0307f..f3e8996a8e 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -33,8 +33,8 @@ Then use the [summary of API modules](#summary-of-api-modules), the table of con * Mbed TLS APIs are traditionally very transparent: the caller can access internal fields of operations. This is less true in the 3.x major version than before, but still the case to some extent. This offers applications some flexibility, but it removes flexibility from the implementation. For example, it is hard to support hardware acceleration, because the API constrains how the data must be represented. PSA APIs were designed to be more opaque, giving more freedom to the implementation. * Mbed TLS legacy APIs require key material to be present in the application memory. The PSA Crypto API natively supports operations on keys stored in an external [location](https://arm-software.github.io/psa-api/crypto/1.1/api/keys/lifetimes.html#c.psa_key_location_t) (secure enclave, secure element, HSM, etc.). -* PSA APIs have [consistent conventions ](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#parameter-conventions) which many legacy APIs in Mbed TLS do not follow. For example, many legacy cryptography functions require the caller to know how large an output buffer needs to be based on the selected algorithm, whereas in the PSA API, all buffer arguments have a well-defined size and those sizes are checked. -* Mbed TLS legacy APIs require passing around a random generator argument where needed. This has historically been problematic with functions that were created without a RNG argument but later needed one as part of a security countermeasure. The PSA crypto subsystem maintains a global random generator, resolving this problem. +* PSA APIs have [consistent conventions](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#parameter-conventions) which many legacy APIs in Mbed TLS do not follow. For example, many legacy cryptography functions require the caller to know how large an output buffer needs to be based on the selected algorithm, whereas in the PSA API, all buffer arguments have a well-defined size and those sizes are checked. +* Mbed TLS legacy APIs require passing around a random generator argument where needed. This has historically been problematic with functions that were created without an RNG argument but later needed one as part of a security countermeasure. The PSA crypto subsystem maintains a global random generator, resolving this problem. ### Migration timeline @@ -48,7 +48,7 @@ Then use the [summary of API modules](#summary-of-api-modules), the table of con ### Configuration of the PSA subsystem -To make the PSA API available, make sure that the configuration option [`MBEDTLS_PSA_CRYPTO_C`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#c.MBEDTLS_PSA_CRYPTO_C) is enabled (it is enabled in the default configuration). +To make the PSA API available, make sure that the configuration option [`MBEDTLS_PSA_CRYPTO_C`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#c.MBEDTLS_PSA_CRYPTO_C) is enabled. (It is enabled in the default configuration.) You should probably enable [`MBEDTLS_USE_PSA_CRYPTO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a70fd7b97d5f11170546583f2095942a6) as well (it is disabled by default). This option causes the PK, X.509 and TLS modules to use PSA crypto under the hood. Some functions that facilitate the transition (for example, to convert between metadata encodings or between key representations) are only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled. @@ -67,11 +67,11 @@ Before any cryptographic operation, call [`psa_crypto_init`](https://mbed-tls.re If you wish to free all resources associated with PSA cryptography, call [`mbedtls_psa_crypto_free`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__extra_8h/#_CPPv423mbedtls_psa_crypto_freev). -The PSA subsystem has an internal random generator. As a consequence, you do not need to instantiate one manually (no need to create an `mbedtls_entropy_context` and a `mbedtls_xxx_drbg_context`). +The PSA subsystem has an internal random generator. As a consequence, you do not need to instantiate one manually (no need to create an `mbedtls_entropy_context` and an `mbedtls_xxx_drbg_context`). ### Error codes -Mbed TLS functions return a status of type `int`: 0 for success (or, occasionally, a positive value which is the output length), or a negative value `MBEDTLS_ERR_xxx` indicating an error. +Mbed TLS functions return a status of type `int`: 0 for success (or occasionally a positive value which is the output length), or a negative value `MBEDTLS_ERR_xxx` indicating an error. PSA functions return a status of type [`psa_status_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__error/#group__error_1ga05676e70ba5c6a7565aff3c36677c1f9): `PSA_SUCCESS == 0` for success, or a negative value [`PSA_ERROR_xxx`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__error/) indicating an error. @@ -158,12 +158,12 @@ When the configuration option [`MBEDTLS_PSA_CRYPTO_CONFIG`](https://mbed-tls.rea The availability of cryptographic mechanisms in the PSA API is based on a systematic pattern: * To make `PSA_ALG_aaa` available, enable `PSA_WANT_ALG_aaa`. - For parametrized algorithms, there is a `PSA_WANT_` symbols both for the main macro and for each argument. For example, to make `PSA_ALG_HMAC(PSA_ALG_SHA_256)` available, enable both `PSA_WANT_ALG_HMAC` and `PSA_WANT_ALG_SHA_256`. + For parametrized algorithms, there is a `PSA_WANT_` symbol both for the main macro and for each argument. For example, to make `PSA_ALG_HMAC(PSA_ALG_SHA_256)` available, enable both `PSA_WANT_ALG_HMAC` and `PSA_WANT_ALG_SHA_256`. * To make `PSA_KEY_TYPE_ttt` available, enable `PSA_WANT_KEY_TYPE_ttt`. As an exception, starting in Mbed TLS 3.5.0, for key pair types, the feature selection is more fine-grained, with an additional suffix: - * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` enables basic support for the key type, and in particular support for operations with a key of that type for enabled algorithms. This is automatically enabled if any of the other `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy` options is enabled. + * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` enables basic support for the key type, and in particular support for operations with a key of that type for enabled algorithms. This is automatically enabled if any of the other `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy` options are enabled. * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_IMPORT` enables support for `psa_import_key` to import a key of that type. * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_GENERATE` enables support for `psa_generate_key` to randomly generate a key of that type. * `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_DERIVE` enables support for `psa_key_derivation_output_key` to deterministically derive a key of that type. @@ -173,7 +173,7 @@ The availability of cryptographic mechanisms in the PSA API is based on a system * To make `PSA_ECC_FAMILY_fff` available for size sss, enable `PSA_WANT_ECC_fff_sss`. -Note that all `PSA_WANT_xxx` symbols must be set to a nonzero value. In particular, setting `PSA_WANT_xxx` to an empty value may not be handled consistently. +Note that all `PSA_WANT_xxx` symbols must be set to a non-zero value. In particular, setting `PSA_WANT_xxx` to an empty value may not be handled consistently. For example, the following configuration enables hashing with SHA-256, AEAD with AES-GCM, signature with deterministic ECDSA using SHA-256 on the curve secp256r1 using a randomly generated key as well as the corresponding verification, and ECDH key exchange on secp256r1 and Curve25519. @@ -192,7 +192,7 @@ For example, the following configuration enables hashing with SHA-256, AEAD with #define PSA_WANT_ALG_ECDH ``` -If a mechanism is not enabled by `PSA_WANT_xxx`, Mbed TLS will often not include it, to reduce the size of the compiled library. However, this is not guaranteed: a mechanism that is not explicitly requested can be enabled because it is a dependency of another configuration option, because it is used internally, or because the granularity is not fine enough to distinguish between it and another mechanism that is requested. +If a mechanism is not enabled by `PSA_WANT_xxx`, Mbed TLS will normally not include it. This allows builds that use few features to have a small code size. However, this is not guaranteed: a mechanism that is not explicitly requested can be enabled because it is a dependency of another configuration option, because it is used internally, or because the granularity is not fine enough to distinguish between it and another mechanism that is requested. Under the hood, `PSA_WANT_xxx` enables the necessary legacy modules. Note that if a mechanism has a PSA accelerator driver, the corresponding legacy module is typically not needed. Thus applications that use a cryptographic mechanism both through the legacy API and through the PSA API need to explicitly enable both the `PSA_WANT_xxx` symbols and the `MBEDTLS_xxx` symbols. @@ -229,7 +229,7 @@ The PSA API does not have an equivalent to the timing-side-channel-resistance ut Note that the PSA API does include features that reduce the need for `mbedtls_ct_memcmp`: -* To compare a MAC with a reference value, use `psa_mac_verify` rather of `psa_mac_compute` followed by `mbedtls_ct_memcmp`, or use `psa_mac_verify_setup` and `psa_mac_verify_finish` in the multi-part case. See “[MAC calculation](#mac-calculation)”. +* To compare a MAC with a reference value, use `psa_mac_verify` rather than `psa_mac_compute` followed by `mbedtls_ct_memcmp`, or use `psa_mac_verify_setup` and `psa_mac_verify_finish` in the multi-part case. See “[MAC calculation](#mac-calculation)”. * The AEAD decryption functions take care of verifying the tag. See “[Authenticated cipher operations](#authenticated-cipher-operations)”. ## Symmetric encryption @@ -267,7 +267,7 @@ For the Chacha20+Poly1305 AEAD, use [`PSA_KEY_TYPE_CHACHA20`](https://mbed-tls.r ### Cipher mechanism availability -For each key type value `PSA_KEY_TYPE_xxx`, the symbol `PSA_WANT_KEY_TYPE_xxx` is defined with a nonzero value if the library is built with support for that key type. For each algorithm value `PSA_ALG_yyy`, the symbol `PSA_WANT_ALG_yyy` is defined with a nonzero value if the library is built with support for that algorithm. Note that for a mechanism to be supported, both the key type and the algorithm must be supported. +For each key type value `PSA_KEY_TYPE_xxx`, the symbol `PSA_WANT_KEY_TYPE_xxx` is defined with a non-zero value if the library is built with support for that key type. For each algorithm value `PSA_ALG_yyy`, the symbol `PSA_WANT_ALG_yyy` is defined with a non-zero value if the library is built with support for that algorithm. Note that for a mechanism to be supported, both the key type and the algorithm must be supported. For example, to test if AES-CBC-PKCS7 is supported, in the legacy API, you could write: ``` @@ -428,7 +428,7 @@ PSA Crypto has a generic API with the same functions for all MAC mechanisms. The ### Hash and MAC mechanism availability -For each key type value `PSA_KEY_TYPE_xxx`, the symbol `PSA_WANT_KEY_TYPE_xxx` is defined with a nonzero value if the library is built with support for that key type. For each algorithm value `PSA_ALG_yyy`, the symbol `PSA_WANT_ALG_yyy` is defined with a nonzero value if the library is built with support for that algorithm. For a compound mechanism, all parts must be supported. In particular, for HMAC, all three of `PSA_WANT_KEY_TYPE_HMAC`, `PSA_WANT_ALG_HMAC` and the underlying hash must be enabled. (A configuration with only one of `PSA_WANT_KEY_TYPE_HMAC` and `PSA_WANT_ALG_HMAC` is technically possible but not useful.) +For each key type value `PSA_KEY_TYPE_xxx`, the symbol `PSA_WANT_KEY_TYPE_xxx` is defined with a non-zero value if the library is built with support for that key type. For each algorithm value `PSA_ALG_yyy`, the symbol `PSA_WANT_ALG_yyy` is defined with a non-zero value if the library is built with support for that algorithm. For a compound mechanism, all parts must be supported. In particular, for HMAC, all three of `PSA_WANT_KEY_TYPE_HMAC`, `PSA_WANT_ALG_HMAC` and the underlying hash must be enabled. (A configuration with only one of `PSA_WANT_KEY_TYPE_HMAC` and `PSA_WANT_ALG_HMAC` is technically possible but not useful.) For example, to test if HMAC-SHA-256 is supported, in the legacy API, you could write: ``` @@ -626,7 +626,7 @@ The PSA API supports RSA (see “[RSA mechanism selection](#rsa-mechanism-select In the PSA API, keys are referenced by an identifier of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t). (Some documentation references [`mbedtls_svc_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv420mbedtls_svc_key_id_t); the two types are identical except when the library is configured for use in a multi-client cryptography service.) -The PSA key identifier tends to play the same role as a `mbedtls_pk_context`, `mbedtls_rsa_context` or `mbedtls_ecp_keypair` structure in the legacy API; however there are major differences in the way the two APIs can be used to create keys or to obtain information about a key. +The PSA key identifier tends to play the same role as an `mbedtls_pk_context`, `mbedtls_rsa_context` or `mbedtls_ecp_keypair` structure in the legacy API. However, there are major differences in the way the two APIs can be used to create keys or to obtain information about a key. Here is an overview of the lifecycle of a PSA key object. @@ -646,7 +646,7 @@ Here is an overview of the lifecycle of a PSA key object. A key's policy indicates what algorithm(s) it can be used with (usage algorithm policy) and what operations are permitted (usage flags). -The following table lists the relevant usage flags for asymmetric cryptography. You can pass an bitwise-or of those flags to [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de). +The following table lists the relevant usage flags for asymmetric cryptography. You can pass those flags (combined with bitwise-or) to [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de). | Usage | Flag | | ----- | ---- | @@ -662,7 +662,7 @@ The following table lists the relevant usage flags for asymmetric cryptography. The sections “[RSA mechanism selection](#rsa-mechanism-selection)”, “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” and “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)” cover the available algorithm values for each key type. Normally, a key can only be used with a single algorithm, following standard good practice. However, there are two ways to relax this requirement. -* Many signature algorithms encode a hash algorithm. Sometimes the same key may need to be used to sign messages with multiple different hashes. In an algorithm policy, you can use [`PSA_ALG_ANY_HASH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_ALG_ANY_HASH) instead of a hash algorithm value to allow the key to be used with any hash. For example, `psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH))` allows the key to be used with RSASSA-PSS, with different hash algorithhms in each operation. +* Many signature algorithms encode a hash algorithm. Sometimes the same key may need to be used to sign messages with multiple different hashes. In an algorithm policy, you can use [`PSA_ALG_ANY_HASH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__values_8h/#c.PSA_ALG_ANY_HASH) instead of a hash algorithm value to allow the key to be used with any hash. For example, `psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH))` allows the key to be used with RSASSA-PSS, with different hash algorithms in each operation. * In addition to the algorithm (or wildcard) selected with [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98), you can use [`psa_set_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaffa134b74aa52aa3ed9397fcab4005aa) to permit a second algorithm (or wildcard). This is intended for scenarios where a key is normally used with a single algorithm, but needs to be used with a different algorithm for enrollment (such as an ECDH key for which an ECDSA proof-of-possession is also required). ### Asymmetric cryptographic mechanisms @@ -764,17 +764,17 @@ You can use glue functions in the PK module to create a key object using the leg * Parsing a key in a format with metadata without knowing its type ahead of time. * Importing a key which you have in the form of a list of numbers, rather than the binary encoding required by `psa_import_key`. -* Importing a key with less information than what the PSA API needs, for example an ECC public key in compressed format, an RSA private key without the private exponent, or an RSA private key without the CRT parameters. +* Importing a key with less information than what the PSA API needs, for example an ECC public key in a compressed format, an RSA private key without the private exponent, or an RSA private key without the CRT parameters. * Generating an RSA key with $e \ne 65537$. #### Importing a PK key by wrapping -If you have a PK object, you can call `mbedtls_pk_wrap_as_opaque` to create a PSA key object with the same key material. (This function is only present in builds with `MBEDTLS_USE_PSA_CRYPTO` enabled. It is experimental and [will likely be replaced by a slightly different interface in a future version of Mbed TLS](https://github.com/Mbed-TLS/mbedtls/issues/7760)) This function automatically determines the PSA key type, and lets you specify the usage policy (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). Once you've called this function, you can destroy the PK object. This function calls `psa_import_key` internally; call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to destroy the PSA key object once your application no longer needs it. Common scenarios where this flow is useful are: +If you have a PK object, you can call `mbedtls_pk_wrap_as_opaque` to create a PSA key object with the same key material. (This function is only present in builds with `MBEDTLS_USE_PSA_CRYPTO` enabled. It is experimental and [will likely be replaced by a slightly different interface in a future version of Mbed TLS](https://github.com/Mbed-TLS/mbedtls/issues/7760)). This function automatically determines the PSA key type and lets you specify the usage policy (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). Once you've called this function, you can destroy the PK object. This function calls `psa_import_key` internally; call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to destroy the PSA key object once your application no longer needs it. Common scenarios where this flow is useful are: * You have working code that's calling `mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`, `mbedtls_pk_parse_keyfile` or `mbedtls_pk_parse_public_keyfile` to create a PK object. * You have working code that's using the `rsa.h` or `ecp.h` API to create a key object, and there is no PSA equivalent. -You can use this flow to import an RSA key via a `mbedtls_rsa_context` object or an ECC key via a `mbedtls_ecp_keypair` object: +You can use this flow to import an RSA key via an `mbedtls_rsa_context` object or an ECC key via an `mbedtls_ecp_keypair` object: 1. Call `mbedtls_pk_init` then `mbedtls_pk_setup` to set up a PK context for the desired key type (`MBEDTLS_PK_RSA` or `MBEDTLS_PK_ECKEY`). 2. Call `mbedtls_pk_rsa` or `mbedtls_pk_ec` to obtain the underlying low-level context. @@ -901,9 +901,9 @@ There is no equivalent to the type `mbedtls_pk_info_t` and the functions `mbedtl You can call [`psa_get_key_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gacbbf5c11eac6cd70c87ffb936e1b9be2) to populate a structure with the attributes of a key, then functions such as [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918) and [`psa_get_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga5bee85c2164ad3d4c0d42501241eeb06) to obtain a key's type (`PSA_KEY_TYPE_xxx` value) and size (nominal size in bits). -The bit-size from `psa_get_key_bits` is the same as the one from `mbedtls_pk_get_bitlen`. To convert to bytes as with `mbedtls_pk_get_len` or `mbedtls_rsa_get_len`, you can use the macro `PSA_BITS_TO_BYTES`; however note that the PSA API has generic macros for each related buffer size (export, signature size, etc.), so you should generally use those instead. The present document lists those macros where it explains the usage of the corresponding function. +The bit-size from `psa_get_key_bits` is the same as the one from `mbedtls_pk_get_bitlen`. To convert to bytes as `mbedtls_pk_get_len` or `mbedtls_rsa_get_len` do, you can use the macro `PSA_BITS_TO_BYTES`. However, note that the PSA API has generic macros for each related buffer size (export, signature size, etc.), so you should generally use those instead. The present document lists those macros where it explains the usage of the corresponding function. -Most uses of `mbedtls_pk_get_type` and `mbedtls_pk_can_do` only require knowing a key's type as reported by [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918). If needed, you can also access a key's policy from its attributes, with [`psa_get_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaa1af20f142ca722222c6d98678a0c448), [`psa_get_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gac255da850a00bbed925390044f016b34) and [`psa_get_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga39803b62a97198cf630854db9b53c588). The algorithm policy also conveys the padding and hash information provided by `mbedtls_rsa_get_padding_mode` and `mbedtls_rsa_get_md_alg`. +Most uses of `mbedtls_pk_get_type` and `mbedtls_pk_can_do` only require knowing a key's type as reported by [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918). If needed, you can also access a key's policy from its attributes with [`psa_get_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaa1af20f142ca722222c6d98678a0c448), [`psa_get_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gac255da850a00bbed925390044f016b34) and [`psa_get_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga39803b62a97198cf630854db9b53c588). The algorithm policy also conveys the padding and hash information provided by `mbedtls_rsa_get_padding_mode` and `mbedtls_rsa_get_md_alg`. ### Exporting a public key or a key pair @@ -943,9 +943,9 @@ The following subsections describe the PSA signature mechanisms that correspond #### ECDSA signature In the PSA API, **the format of an ECDSA signature is the raw fixed-size format. This is different from the legacy API** which uses the ASN.1 DER format for ECDSA signatures. A future version of Mbed TLS [will provide a way to convert between the two formats](https://github.com/Mbed-TLS/mbedtls/issues/7765). - + -This is the mechanism provided by `mbedtls_pk_sign` and `mbedtls_pk_verify` for ECDSA keys, and by `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext`, `mbedtls_ecdsa_write_signature`, `mbedtls_ecdsa_write_signature` and `mbedtls_ecdsa_verify`, . +This is the mechanism provided by `mbedtls_pk_sign` and `mbedtls_pk_verify` for ECDSA keys, as well as by `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext`, `mbedtls_ecdsa_write_signature`, `mbedtls_ecdsa_write_signature` and `mbedtls_ecdsa_verify`. The PSA API offers three algorithm constructors for ECDSA. They differ only for signature, and have exactly the same behavior for verification. @@ -1033,7 +1033,7 @@ As with the PK API, the mask generation is MGF1, the label is empty, and the sam There is no direct equivalent of the functions `mbedtls_rsa_check_privkey`, `mbedtls_rsa_check_pubkey`,`mbedtls_ecp_check_privkey`, `mbedtls_ecp_check_pubkey`. The PSA API performs some basic checks when it imports a key, and may perform additional checks before performing an operation if needed, so it will never perform an operation on a key that does not satisfy these checks, but the details of when the check is performed may change between versions of the library. -The legacy API provide functions `mbedtls_pk_check_pair`, `mbedtls_rsa_check_pub_priv` and `mbedtls_ecp_check_pub_priv`, which can be used to check the consistency between a private key and a public key. To perform such a check with the PSA API, you can export the public keys; this works because the PSA representation of public keys is canonical. +The legacy API provides functions `mbedtls_pk_check_pair`, `mbedtls_rsa_check_pub_priv` and `mbedtls_ecp_check_pub_priv`, which can be used to check the consistency between a private key and a public key. To perform such a check with the PSA API, you can export the public keys; this works because the PSA representation of public keys is canonical. * Prepare a key object containing the private key, for example with [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). * Prepare a key object containing the public key, for example with [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). @@ -1107,7 +1107,7 @@ A typical flow for ECDH using the legacy API without a context object is: * `mbedtls_mpi z` for the shared secret (this may be the same variable as `our_priv` when doing ephemeral ECDH). 2. Call `mbedtls_ecp_group_load` on `grp` to select the curve. 3. Call `mbedtls_ecdh_gen_public` on `grp`, `our_priv` (output) and `our_pub` (output) to generate a key pair and retrieve the corresponding public key. -4. Send `our_pub` to the peer. Retriev the peer's public key and import it into `their_pub`. These two actions may be performed in either order. +4. Send `our_pub` to the peer. Retrieve the peer's public key and import it into `their_pub`. These two actions may be performed in either order. 5. Call `mbedtls_ecdh_compute_shared` on `grp`, `z` (output), `their_pub` and `our_priv`. 6. Use the raw shared secret `z`, typically, to construct a shared key. 7. Free `grp`, `our_priv`, `our_pub`, `their_pub` and `z`. @@ -1122,7 +1122,7 @@ The corresponding flow with the PSA API is as follows: * `shared_secret`: a buffer of size [`PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, bits)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE) or [`PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE) (if not using a key derivation operation). 2. Prepare an attribute structure as desccribed in “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)”, in particular selecting the curve with `psa_set_key_type`. 3. Call [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5) on `attributes` and `our_key` (output) to generate a key pair, then [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on `our_key` and `our_pub` (output) to obtain our public key. -4. Send `our_pub` to the peer. Retriev the peer's public key and import it into `their_pub`. These two actions may be performed in either order. +4. Send `our_pub` to the peer. Retrieve the peer's public key and import it into `their_pub`. These two actions may be performed in either order. 5. Call [`psa_raw_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) on `our_key`, `their_pub` and `shared_secret` (output). Alternatively, call `psa_key_derivation_key_agreement` to use the shared secret directly in a key derivation operation (see “[Performing a key agreement](#performing-a-key-agreement)”). 6. Call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) on `key_id`, and free the memory buffers. @@ -1169,7 +1169,7 @@ The legacy API offers the following flow for a Diffie-Hellman key agreement in a The corresponding flow with the PSA API is as follows: 1. Upon reception of a TLS ServerKeyExchange message received from the peer, which encodes the selected curve/group and the peer's public key: - 1. Decode the select curve/group and use this to determine a PSA key type (`PSA_KEY_TYPE_ECC_KEY_PAIR(curve)` or `PSA_KEY_TYPE_DH_KEY_PAIR(group)`), a key size and an algorithm. + 1. Decode the selected curve/group and use this to determine a PSA key type (`PSA_KEY_TYPE_ECC_KEY_PAIR(curve)` or `PSA_KEY_TYPE_DH_KEY_PAIR(group)`), a key size and an algorithm. 2. Generate an ECDH or DHM key pair with `psa_generate_key` as described in “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)”. Call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) to obtain our public key. 3. Send our public key to the peer. @@ -1182,7 +1182,7 @@ The corresponding flow with the PSA API is as follows: The legacy function `mbedtls_ecdh_get_params` allows the application to retrieve an `mbedtls_ecp_keypair` containing either our key pair, or the peer's public key. The PSA equivalent depends on the use case: * With either side, accessing the group: call [`psa_get_key_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gacbbf5c11eac6cd70c87ffb936e1b9be2) on the key identifier, then [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918) and [`psa_get_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga5bee85c2164ad3d4c0d42501241eeb06) to obtain metadata about the key. -* With `MBEDTLS_ECDH_OURS`, accessing the public key: call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on PSA key identifier. +* With `MBEDTLS_ECDH_OURS`, accessing the public key: call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on the PSA key identifier. * With `MBEDTLS_ECDH_OURS`, accessing the private key: call [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) on the key identifier. Note that the key policy must allow `PSA_KEY_USAGE_EXPORT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). * With `MBEDTLS_ECDH_THEIRS`, accessing the public key (there is no private key): there is no PSA equivalent since the PSA API only uses the peer's public key to immediately calculate the shared secret. If your application needs the peer's public key for some other purpose, store it separately. @@ -1190,7 +1190,7 @@ The functions `mbedtls_dhm_get_bitlen`, `mbedtls_dhm_get_len` and `mbedtls_dhm_g * `mbedtls_dhm_get_bitlen`, `mbedtls_dhm_get_len`: call [`psa_get_key_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gacbbf5c11eac6cd70c87ffb936e1b9be2) on the PSA key identifier, then [`psa_get_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga5bee85c2164ad3d4c0d42501241eeb06). * `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_X` (our private key): call [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) on the key identifier. Note that the key policy must allow `PSA_KEY_USAGE_EXPORT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). -* `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_GX` (our public key): call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on PSA key identifier. +* `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_GX` (our public key): call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on the PSA key identifier. * `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_GY` (peer's public key): the there is no PSA equivalent since the PSA API only uses the peer's public key to immediately calculate the shared secret. If your application needs the peer's public key for some other purpose, store it separately. * `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_K` (shared secret): this is the value calculated by `psa_raw_key_agreement` or `psa_key_derivation_key_agreement`. If you need to use it multiple times (for example to derive multiple values independently), call `psa_raw_key_agreement` and make a copy. * `mbedtls_dhm_get_value` for `MBEDTLS_DHM_PARAM_P` or `MBEDTLS_DHM_PARAM_G` (group parameters): [there is no PSA API to retrieve these values](https://github.com/Mbed-TLS/mbedtls/issues/7780). @@ -1229,7 +1229,7 @@ There is no PSA equivalent for the following functionality: The PSA API does not currently have a discovery mechanism for cryptographic mechanisms (although one may be added in the future). Thus there is no equivalent for `MBEDTLS_ECP_DP_MAX` and the functions `mbedtls_ecp_curve_list` and `mbedtls_ecp_grp_id_list`. -The API provies macros that give the maximum supported sizes for various kinds of objects. The following table lists equivalents for `MBEDTLS_ECP_MAX_xxx` macros. +The API provides macros that give the maximum supported sizes for various kinds of objects. The following table lists equivalents for `MBEDTLS_ECP_MAX_xxx` macros. | Legacy macro | PSA equivalent | | ------------ | -------------- | @@ -1272,7 +1272,7 @@ Implementers of the RSA-ALT interface (`MBEDTLS_PK_RSA_ALT` pk type, `mbedtls_pk PSA_KEY_PERSISTENCE_VOLATILE, MY_RSA_DRIVER_LOCATION)); ``` -The PSA subsystem uses its internal random generator both for randomized algorithms and to generate blinding value. As a consequence, none of the API functions take an RNG parameter. +The PSA subsystem uses its internal random generator both for randomized algorithms and to generate blinding values. As a consequence, none of the API functions take an RNG parameter. #### RSA functionality with no PSA equivalent From d96aa1b5cddfd0666a3322058cdcd01d8b01ceb9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 29 Nov 2023 21:13:02 +0100 Subject: [PATCH 22/88] Say who to contact Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index f3e8996a8e..2783541235 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -1276,7 +1276,7 @@ The PSA subsystem uses its internal random generator both for randomized algorit #### RSA functionality with no PSA equivalent -The PSA API does not provide direct access to the exponentiation primitive as with `mbedtls_rsa_public` and `mbedtls_rsa_private`. If you need an RSA-based mechanism that is not supported by the PSA API, please contact us so that we can extend the API to support it. +The PSA API does not provide direct access to the exponentiation primitive as with `mbedtls_rsa_public` and `mbedtls_rsa_private`. If you need an RSA-based mechanism that is not supported by the PSA API, please [submit an issue on GitHub](https://github.com/ARM-software/psa-api/issues) so that we can extend the API to support it. The PSA API does not support constructing RSA keys progressively from numbers with `mbedtls_rsa_import` or `mbedtls_rsa_import_raw` followed by `mbedtls_rsa_complete`. See “[Importing a PK key by wrapping](#importing-a-pk-key-by-wrapping)”. From 3cc486aa11c96ea378431d7e62455bcfe04fb944 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 30 Nov 2023 08:09:47 +0100 Subject: [PATCH 23/88] pkparse: make pk_internal.h always available This is needed because now "pk_internal.h" contains defines for PEM strings Signed-off-by: Valerio Setti --- library/pkparse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/pkparse.c b/library/pkparse.c index 0b5de8db3d..1f6133e01e 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -15,6 +15,7 @@ #include "mbedtls/platform_util.h" #include "mbedtls/platform.h" #include "mbedtls/error.h" +#include "pk_internal.h" #include @@ -29,7 +30,6 @@ #endif #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) #include "mbedtls/ecp.h" -#include "pk_internal.h" #endif /* Extended formats */ From ad6d016b8f716539b0eae253ce81e2e05960f08b Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 30 Nov 2023 08:10:36 +0100 Subject: [PATCH 24/88] pkwrite: fix return value in pk_get_type_ext() Signed-off-by: Valerio Setti --- library/pkwrite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/pkwrite.c b/library/pkwrite.c index 15b8a8d343..c7eb1148b4 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -527,7 +527,7 @@ static mbedtls_pk_type_t pk_get_type_ext(const mbedtls_pk_context *pk) } else if (PSA_KEY_TYPE_IS_RSA(opaque_key_type)) { return MBEDTLS_PK_RSA; } else { - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; + return MBEDTLS_PK_NONE; } } else #endif From 396a2a3dcbc41b1184fce39a497cda5c0eb186b1 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 30 Nov 2023 11:02:06 +0100 Subject: [PATCH 25/88] Explain interruptible operations Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 2783541235..5bab124e24 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -958,9 +958,9 @@ Unlike the legacy API, where `mbedtls_pk_sign` and `mbedtls_ecdsa_write_signatur #### Restartable ECDSA signature -There is a PSA API for interruptible public-key operations, offering similar functionality to the legacy restartable API (`mbedtls_pk_sign_restartable`, `mbedtls_pk_verify_restartable`, `mbedtls_ecdsa_sign_restartable`, `mbedtls_ecdsa_verify_restartable`, `mbedtls_ecdsa_write_signature_restartable`, `mbedtls_ecdsa_read_signature_restartable`). +The legacy API includes an API for “restartable” ECC operations: the operation returns after doing partial computation, and can be resumed. This is intended for highly constrained devices where long cryptographic calculations need to be broken up to poll some inputs, where interrupt-based scheduling is not desired. The legacy API consists of the functions `mbedtls_pk_sign_restartable`, `mbedtls_pk_verify_restartable`, `mbedtls_ecdsa_sign_restartable`, `mbedtls_ecdsa_verify_restartable`, `mbedtls_ecdsa_write_signature_restartable`, `mbedtls_ecdsa_read_signature_restartable`, as well as several configuration and data manipulation functions. -As of Mbed TLS 3.5, it is only implemented for ECDSA, for the same curves as the legacy API; this will likely be extended to ECDH in the short term. At the time of writing, no extension is planned to other curves or other algorithms. +The PSA API offers similar functionality via “interruptible” public-key operations. As of Mbed TLS 3.5, it is only implemented for ECDSA, for the same curves as the legacy API. This will likely be extended to ECDH in the short term. At the time of writing, no extension is planned to other curves or other algorithms. The flow of operations for an interruptible signature operation is as follows: From 4d234f1edec0f583b512a6efa5d50448055a6783 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 30 Nov 2023 13:59:49 +0100 Subject: [PATCH 26/88] Editorial corrections Fix typos, copypasta, and other minor clarifications. Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 5bab124e24..54a1dd642d 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -338,7 +338,7 @@ Recall the flow of an unauthenticated cipher operation in the legacy Mbed TLS ci For a one-shot operation (where the whole plaintext or ciphertext is passed as a single input), the equivalent flow with the PSA API is to call a single function: -* [`psa_cipher_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga61f02fbfa681c2659546eca52277dbf1) to perform encryption with a random IV of the default size (indicated by [`PSA_CIPHER_IV_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_IV_LENGTH)). (To encrypt with a specified IV, use the multi-part API described below.) You can use the macro [`PSA_CIPHER_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. +* [`psa_cipher_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga61f02fbfa681c2659546eca52277dbf1) to perform encryption with a random IV of the default size (indicated by [`PSA_CIPHER_IV_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_IV_LENGTH)). (To encrypt with a specified IV, use the multi-part API described below.) You can use the macro [`PSA_CIPHER_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. * [`psa_cipher_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gab3593f5f14d8c0431dd306d80929215e) to perform decryption with a specified IV. You can use the macro [`PSA_CIPHER_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. For a multi-part operation, the equivalent flow with the PSA API is as follows: @@ -633,7 +633,7 @@ Here is an overview of the lifecycle of a PSA key object. 1. First define the attributes of the key by filling a [`psa_key_attributes_t` structure](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga0ec645e1fdafe59d591104451ebf5680). You need to set the following parameters: * Call [`psa_set_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga6857ef0ecb3fa844d4536939d9c64025) to set the key type to the desired `PSA_KEY_TYPE_xxx` value (see “[RSA mechanism selection](#rsa-mechanism-selection)”, “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” and “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)”). * Call [`psa_set_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaf61683ac87f87687a40262b5afbfa018) to set the key's conceptual size in bits. This is optional with `psa_import_key`, which determines the key size from the length of the key material. - * Call [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) to set the algorithm to the desired `PSA_ALG_xxx` value (see “[RSA mechanism selection](#rsa-mechanism-selection)”, “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” and “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)” as well as “[Public-key cryptography policies](#public-key-cryptography-policies)”). + * Call [`psa_set_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaeb8341ca52baa0279475ea3fd3bcdc98) to set the permitted algorithm to the desired `PSA_ALG_xxx` value (see “[RSA mechanism selection](#rsa-mechanism-selection)”, “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” and “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)” as well as “[Public-key cryptography policies](#public-key-cryptography-policies)”). * Call [`psa_set_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga42a65b3c4522ce9b67ea5ea7720e17de) to enable the desired usage types (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). 2. Call one of the key creation functions, passing the attributes defined in the previous step, to get an identifier of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t) to the key object. * Use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b) to directly import key material. @@ -656,8 +656,8 @@ The following table lists the relevant usage flags for asymmetric cryptography. | Sign an already-calculated hash | at least one of [`PSA_KEY_USAGE_SIGN_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga552117ac92b79500cae87d4e65a85c54) or [`PSA_KEY_USAGE_SIGN_HASH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga552117ac92b79500cae87d4e65a85c54) | | Verify a message directly | [`PSA_KEY_USAGE_VERIFY_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gabea7ec4173f4f943110329ac2953b2b1) | | Verify an already-calculated hash | at least one of [`PSA_KEY_USAGE_VERIFY_MESSAGE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gabea7ec4173f4f943110329ac2953b2b1) or [`PSA_KEY_USAGE_VERIFY_HASH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gafadf131ef2182045e3483d03aadaa1bd) | -| Encryption | [`PSA_KEY_USAGE_`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga75153b296d045d529d97203a6a995dad) | -| Decryption | [`PSA_KEY_USAGE_`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gac3f2d2e5983db1edde9f142ca9bf8e6a) | +| Encryption | [`PSA_KEY_USAGE_ENCRYPT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1ga75153b296d045d529d97203a6a995dad) | +| Decryption | [`PSA_KEY_USAGE_DECRYPT`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gac3f2d2e5983db1edde9f142ca9bf8e6a) | | Key agreement | [`PSA_KEY_USAGE_DERIVE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__policy/#group__policy_1gaf19022acc5ef23cf12477f632b48a0b2) | The sections “[RSA mechanism selection](#rsa-mechanism-selection)”, “[Elliptic curve mechanism selection](#elliptic-curve-mechanism-selection)” and “[Diffie-Hellman mechanism selection](#diffie-hellman-mechanism-selection)” cover the available algorithm values for each key type. Normally, a key can only be used with a single algorithm, following standard good practice. However, there are two ways to relax this requirement. @@ -688,7 +688,7 @@ The following cryptographic algorithms work with RSA keys: #### Elliptic curve mechanism selection -The PK types `MBEDTLS_PK_ECKEY`, `MBEDTLS_PK_ECKEY_DH` and `MBEDTLS_PK_ECDSA` correspond to RSA key types in the PSA API. In the PSA API, key pairs and public keys are separate object types. The PSA API uses policies and algorithm parameters rather than key types to distinguish between the PK EC types. +The PK types `MBEDTLS_PK_ECKEY`, `MBEDTLS_PK_ECKEY_DH` and `MBEDTLS_PK_ECDSA` correspond to elliptic-curve key types in the PSA API. In the PSA API, key pairs and public keys are separate object types. The PSA API uses policies and algorithm parameters rather than key types to distinguish between the PK EC types. An ECC public key has the type [`PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gad54c03d3b47020e571a72cd01d978cf2) where `curve` is a curve family identifier. @@ -717,6 +717,7 @@ The following cryptographic algorithms work with ECC keys: * ECDH key agreement (including X25519 and X448): [`PSA_ALG_ECDH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gab2dbcf71b63785e7dd7b54a100edee43). * ECDSA: [`PSA_ALG_ECDSA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga7e3ce9f514a227d5ba5d8318870452e3), [`PSA_ALG_ECDSA_ANY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga51d6b6044a62e33cae0cf64bfc3b22a4), [`PSA_ALG_DETERMINISTIC_ECDSA`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga11da566bcd341661c8de921e2ca5ed03). +* EC-JPAKE (see “[EC-JPAKE](#ec-jpake)”. #### Diffie-Hellman mechanism selection @@ -913,7 +914,7 @@ To export a PSA public key or to export the public key of a PSA key pair object, The export format is the same format used for `psa_import_key`, described in “[Creating keys for asymmetric cryptography](#creating-keys-for-asymmetric-cryptography)” above. -A future extension of the PSA API will support other export formats. Until those are implemented, see the following subsections for ways to use the PK module to format a PSA key. +A future extension of the PSA API will support other export formats. Until those are implemented, see “[Exporting a PK key by wrapping](#exporting-a-pk-key-by-wrapping)” for ways to use the PK module to format a PSA key. #### Exporting a PK key by wrapping @@ -974,7 +975,7 @@ The flow of operations for an interruptible signature verification operation is 2. Call [`psa_verify_hash_start`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga912eb51fb94056858f451f276ee289cb) with the private key object and the hash and signature to verify. 3. Call [`psa_verify_hash_complete`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga67fe82352bc2f8c0343e231a70a5bc7d) repeatedly until it returns a status other than `PSA_OPERATION_INCOMPLETE`. -If you need to interrupt the operation after calling the start function without waiting for the complete function to return a success or failure status, call [`psa_sign_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1gae893a4813aa8e03bd201fe4f1bbbb403) or [`psa_verify_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga18dc9c0cc27d590c5e3b186094d90f88). +If you need to cancel the operation after calling the start function without waiting for the loop calling the complete function to finish, call [`psa_sign_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1gae893a4813aa8e03bd201fe4f1bbbb403) or [`psa_verify_hash_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga18dc9c0cc27d590c5e3b186094d90f88). Call [`psa_interruptible_set_max_ops`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga6d86790b31657c13705214f373af869e) to set the number of basic operations per call. This is the same unit as `mbedtls_ecp_set_max_ops`. You can retrieve the current value with [`psa_interruptible_get_max_ops`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible__hash/#group__interruptible__hash_1ga73e66a6d93f2690b626fcea20ada62b2). The value is [`PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__interruptible/#group__interruptible_1gad19c1da7f6b7d59d5873d5b68eb943d4) if operations are not restartable, which corresponds to `mbedtls_ecp_restart_is_enabled()` being false. @@ -1003,7 +1004,7 @@ With respect to the salt length: ### Asymmetric encryption and decryption The equivalent of `mbedtls_pk_encrypt`, `mbedtls_rsa_pkcs1_encrypt`, `mbedtls_rsa_rsaes_pkcs1_v15_encrypt` or `mbedtls_rsa_rsaes_oaep_encrypt` to encrypt a short message (typically a symmetric key) is [`psa_asymmetric_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1gaa17f61e4ddafd1823d2c834b3706c290). -The key must be a public key allowing the usage `PSA_KEY_USAGE_ENCRYPT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). +The key must be a public key or a key pair allowing the usage `PSA_KEY_USAGE_ENCRYPT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). Use the macro [`PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#crypto__sizes_8h_1a66ba3bd93e5ec52870ccc3848778bad8) or [`PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE) to determine the output buffer size. The equivalent of `mbedtls_pk_decrypt`, `mbedtls_rsa_pkcs1_decrypt`, `mbedtls_rsa_rsaes_pkcs1_v15_decrypt` or `mbedtls_rsa_rsaes_oaep_decrypt` to decrypt a short message (typically a symmetric key) is [`psa_asymmetric_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga4f968756f6b22aab362b598b202d83d7). From 951cf39b3f445cc099f2369319f599e16ef5cf8c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 30 Nov 2023 14:01:20 +0100 Subject: [PATCH 27/88] Corrections and clarifications around asymmetric key formats Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 54a1dd642d..21f4388384 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -672,7 +672,7 @@ The sections “[RSA mechanism selection](#rsa-mechanism-selection)”, “[Elli The PK types `MBEDTLS_PK_RSA`, `MBEDTLS_PK_RSASSA_PSS` and `MBEDTLS_PK_RSA_ALT` correspond to RSA key types in the PSA API. In the PSA API, key pairs and public keys are separate object types. See “[RSA-ALT interface](#rsa-alt-interface)” for more information about `MBEDTLS_PK_RSA_ALT`. -The PSA API uses policies and algorithm parameters rather than key types to distinguish between `MBEDTLS_PK_RSA` and `MBEDTLS_PK_RSASSA_PSS`. The algorithm selection also replaces the use of `mbedtls_rsa_set_padding` on an `mbedtls_rsa_context` object. See the list of algorithms below and the signature and encryption sections for more information. +The PSA API uses policies and algorithm parameters rather than key types to distinguish between RSA-based mechanisms. The PSA algorithm selection corresponds to the `mbedtls_pk_type_t` value passed to `mbedtls_pk_{sign,verify}_ext`. It also replaces the use of `mbedtls_rsa_set_padding` on an `mbedtls_rsa_context` object. See the list of algorithms below and the signature and encryption sections for more information. An RSA public key has the type [`PSA_KEY_TYPE_RSA_PUBLIC_KEY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga9ba0878f56c8bcd1995ac017a74f513b). @@ -743,7 +743,7 @@ The easiest way to create a key pair object is by randomly generating it with [` For RSA keys, `psa_generate_key` always uses 65537 as the public exponent. If you need a different public exponent, use the legacy interface to create the key then import it as described in “[Importing legacy keys via the PK module](#importing-legacy-keys-via-the-pk-module)”. -To create a key object from existing material, use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). While this function has the same basic goal as the PK parse functions (`mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`), it is limited to a single format that just contains the number(s) that make up the key, with very little metadata. This format is a substring of the formats accepted by the PK functions (except for finite-field Diffie-Hellman which the PK module does not support). The table below summarizes the PSA import/export format for key pairs and public keys; see the documentation of [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) for more details. +To create a key object from existing material, use [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b). While this function has the same basic goal as the PK parse functions (`mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`), it is limited to a single format that just contains the number(s) that make up the key, with very little metadata. This format is a substring of one of the formats accepted by the PK functions (except for finite-field Diffie-Hellman which the PK module does not support). The table below summarizes the PSA import/export format for key pairs and public keys; see the documentation of [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) for more details. | Key type | PSA import/export format | | -------- | ------------------------ | @@ -854,7 +854,7 @@ This section explains how to use the `ecp.h` API to create an elliptic curve key You can use this, for example, to import an ECC key in the form of a compressed point by calling `mbedtls_ecp_point_read_binary` then following the process below. -The following code snippet illustrates how to import a private key which is initially in an `mbedtls_ecp_keypair` object. Error checks are omitted for simplicity. A future version of Mbed TLS [will provide a function to calculate the curve family](https://github.com/Mbed-TLS/mbedtls/issues/7764). +The following code snippet illustrates how to import a private key which is initially in an `mbedtls_ecp_keypair` object. (This includes `mbedtls_ecdsa_keypair` objects since that is just a type alias.) Error checks are omitted for simplicity. A future version of Mbed TLS [will provide a function to calculate the curve family](https://github.com/Mbed-TLS/mbedtls/issues/7764). ``` mbedtls_ecp_keypair ec; @@ -904,7 +904,7 @@ You can call [`psa_get_key_attributes`](https://mbed-tls.readthedocs.io/projects The bit-size from `psa_get_key_bits` is the same as the one from `mbedtls_pk_get_bitlen`. To convert to bytes as `mbedtls_pk_get_len` or `mbedtls_rsa_get_len` do, you can use the macro `PSA_BITS_TO_BYTES`. However, note that the PSA API has generic macros for each related buffer size (export, signature size, etc.), so you should generally use those instead. The present document lists those macros where it explains the usage of the corresponding function. -Most uses of `mbedtls_pk_get_type` and `mbedtls_pk_can_do` only require knowing a key's type as reported by [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918). If needed, you can also access a key's policy from its attributes with [`psa_get_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaa1af20f142ca722222c6d98678a0c448), [`psa_get_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gac255da850a00bbed925390044f016b34) and [`psa_get_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga39803b62a97198cf630854db9b53c588). The algorithm policy also conveys the padding and hash information provided by `mbedtls_rsa_get_padding_mode` and `mbedtls_rsa_get_md_alg`. +Most code that calls `mbedtls_pk_get_type` or `mbedtls_pk_can_do` only requires the key's type as reported by [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918). For code that uses both `mbedtls_pk_context` objects and PSA metadata encoding, [`mbedtls_pk_can_do_ext`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pk_8h/#pk_8h_1a256d3e8d4323a45aafa7d2b6c59a36f6) checks the compatibility between a key object and a mechanism. If needed, you can also access a key's policy from its attributes with [`psa_get_key_usage_flags`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gaa1af20f142ca722222c6d98678a0c448), [`psa_get_key_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gac255da850a00bbed925390044f016b34) and [`psa_get_key_enrollment_algorithm`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga39803b62a97198cf630854db9b53c588). The algorithm policy also conveys the padding and hash information provided by `mbedtls_rsa_get_padding_mode` and `mbedtls_rsa_get_md_alg`. ### Exporting a public key or a key pair @@ -993,7 +993,7 @@ The PSA API has two algorithm constructors: This mechanism corresponds to `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext` for an RSA key, as well as `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_rsa_pkcs1_sign` and `mbedtls_rsa_pkcs1_verify` if PSS has been selected on the underlying RSA context with `mbedlts_rsa_set_padding`. It also corresponds to `mbedtls_rsa_rsassa_pss_sign` and `mbedtls_rsa_rsassa_pss_sign_ext`, `mbedtls_rsa_rsassa_pss_verify` and `mbedtls_rsa_rsassa_pss_verify_ext`. -The PSA API has two algorithm constructors: [`PSA_ALG_RSA_PSS(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga62152bf4cb4bf6aace5e1be8f143564d) and [`PSA_ALG_RSA_PSS_ANY_SALT(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga9b7355a2cd6bde88177634d539127f2b). The hash algorithm `hash` corresponds to the `md_alg` parameter passed to the legacy API. It is used to hash the message, to create the salted hash, and for the mask generation with MGF1. The PSA API does not support using different hash algorithms for these different purposes. +The PSA API has two algorithm constructors: [`PSA_ALG_RSA_PSS(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga62152bf4cb4bf6aace5e1be8f143564d) and [`PSA_ALG_RSA_PSS_ANY_SALT(hash)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga9b7355a2cd6bde88177634d539127f2b). They differ only for verification, and have exactly the same behavior for signature. The hash algorithm `hash` corresponds to the `md_alg` parameter passed to the legacy API. It is used to hash the message, to create the salted hash, and for the mask generation with MGF1. The PSA API does not support using different hash algorithms for these different purposes. With respect to the salt length: From f7746bdd79e7bee875a2b4eb86162296f17d9775 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 30 Nov 2023 14:01:44 +0100 Subject: [PATCH 28/88] Correct lists of sign/verify functions Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 21f4388384..c62106cf39 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -922,12 +922,14 @@ You can wrap a PSA key object in a PK key context with `mbedtls_pk_setup_opaque` ### Signature operations -The equivalent of `mbedtls_pk_sign`, `mbedtls_rsa_pkcs1_sign`, `mbedtls_rsa_rsassa_pkcs1_v15_sign`, `mbedtls_rsa_rsassa_pss_sign` or `mbedtls_rsa_rsassa_pss_sign_ext` to sign an already calculated hash is [`psa_sign_hash`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga785e746a31a7b2a35ae5175c5ace3c5c). +The equivalent of `mbedtls_pk_sign` or `mbedtls_pk_sign_ext` to sign an already calculated hash is [`psa_sign_hash`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga785e746a31a7b2a35ae5175c5ace3c5c). The key must be a key pair allowing the usage `PSA_KEY_USAGE_SIGN_HASH` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). Use [`PSA_SIGN_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_SIGN_OUTPUT_SIZE) or [`PSA_SIGNATURE_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_SIGNATURE_MAX_SIZE) (similar to `MBEDTLS_PK_SIGNATURE_MAX_SIZE`) to determine the size of the output buffer. +This is also the equivalent of the type-specific functions `mbedtls_rsa_pkcs1_sign`, `mbedtls_rsa_rsassa_pkcs1_v15_sign`, `mbedtls_rsa_rsassa_pss_sign`, `mbedtls_rsa_rsassa_pss_sign_ext`, `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext` and `mbedtls_ecdsa_write_signature`. Note that the PSA API uses the raw format for ECDSA signatures, not the ASN.1 format; see “[ECDSA signature](#ecdsa-signature)” for more details. The equivalent of `mbedtls_pk_verify` or `mbedtls_pk_verify_ext` to verify an already calculated hash is [`psa_verify_hash`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1gae2ffbf01e5266391aff22b101a49f5f5). The key must be a public key or a key pair allowing the usage `PSA_KEY_USAGE_VERIFY_HASH` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). +This is also the equivalent of the type-specific functions `mbedtls_rsa_pkcs1_verify`, `mbedtls_rsa_rsassa_pkcs1_v15_verify`, `mbedtls_rsa_rsassa_pss_verify`, `mbedtls_rsa_rsassa_pss_verify_ext`, `mbedtls_ecdsa_verify` amd `mbedtls_ecdsa_read_signature`. Note that the PSA API uses the raw format for ECDSA signatures, not the ASN.1 format; see “[ECDSA signature](#ecdsa-signature)” for more details. Generally, `psa_sign_hash` and `psa_verify_hash` require the input to have the correct length for the hash (this has historically not always been enforced in the corresponding legacy APIs). @@ -943,10 +945,10 @@ The following subsections describe the PSA signature mechanisms that correspond #### ECDSA signature -In the PSA API, **the format of an ECDSA signature is the raw fixed-size format. This is different from the legacy API** which uses the ASN.1 DER format for ECDSA signatures. A future version of Mbed TLS [will provide a way to convert between the two formats](https://github.com/Mbed-TLS/mbedtls/issues/7765). +**Note: in the PSA API, the format of an ECDSA signature is the raw fixed-size format. This is different from the legacy API** which uses the ASN.1 DER format for ECDSA signatures. A future version of Mbed TLS [will provide a way to convert between the two formats](https://github.com/Mbed-TLS/mbedtls/issues/7765). -This is the mechanism provided by `mbedtls_pk_sign` and `mbedtls_pk_verify` for ECDSA keys, as well as by `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext`, `mbedtls_ecdsa_write_signature`, `mbedtls_ecdsa_write_signature` and `mbedtls_ecdsa_verify`. +ECDSA is the mechanism provided by `mbedtls_pk_sign` and `mbedtls_pk_verify` for ECDSA keys, as well as by `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext`, `mbedtls_ecdsa_write_signature`, `mbedtls_ecdsa_verify` and `mbedtls_ecdsa_read_signature`. The PSA API offers three algorithm constructors for ECDSA. They differ only for signature, and have exactly the same behavior for verification. From d79854b3f73fd9b0863c6fdc083cd861ae61a1da Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 30 Nov 2023 14:01:59 +0100 Subject: [PATCH 29/88] That's not what mbedtls_ecdh_get_params does Keep the discussion of how to retrieve information about a key exchange. This doesn't seem to have equivalent legacy ECDH APIs. Add a todo item for mbedtls_ecdh_get_params(). At this point I don't know where it fits. Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index c62106cf39..8b25aa347b 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -1064,6 +1064,8 @@ There is no PSA equivalent to Mbed TLS's custom key type names exposed by `mbedt The PSA API has a generic interface for key agreement, covering the main use of both `ecdh.h` and `dhm.h`. + + #### Diffie-Hellman key pair management The PSA API manipulates keys as such, rather than via an operation context. Thus, to use Diffie-Hellman, you need to create a key object, then perform the key exchange, then destroy the key. There is no equivalent to the types `mbedtls_ecdh_context` and `mbedtls_dhm_context`. @@ -1182,12 +1184,12 @@ The corresponding flow with the PSA API is as follows: #### ECDH and DHM metadata functions -The legacy function `mbedtls_ecdh_get_params` allows the application to retrieve an `mbedtls_ecp_keypair` containing either our key pair, or the peer's public key. The PSA equivalent depends on the use case: +You can obtain data and metadata from an ECDH key agreement through the PSA API as follows: * With either side, accessing the group: call [`psa_get_key_attributes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gacbbf5c11eac6cd70c87ffb936e1b9be2) on the key identifier, then [`psa_get_key_type`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1gae4fb812af4f57aa1ad85e335a865b918) and [`psa_get_key_bits`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__attributes/#group__attributes_1ga5bee85c2164ad3d4c0d42501241eeb06) to obtain metadata about the key. -* With `MBEDTLS_ECDH_OURS`, accessing the public key: call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on the PSA key identifier. -* With `MBEDTLS_ECDH_OURS`, accessing the private key: call [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) on the key identifier. Note that the key policy must allow `PSA_KEY_USAGE_EXPORT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). -* With `MBEDTLS_ECDH_THEIRS`, accessing the public key (there is no private key): there is no PSA equivalent since the PSA API only uses the peer's public key to immediately calculate the shared secret. If your application needs the peer's public key for some other purpose, store it separately. +* Accessing our public key: call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on the PSA key identifier. +* Accessing our private key: call [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) on the key identifier. Note that the key policy must allow `PSA_KEY_USAGE_EXPORT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). +* Accessing the peer's public key: there is no PSA equivalent since the PSA API only uses the peer's public key to immediately calculate the shared secret. If your application needs the peer's public key for some other purpose, store it separately. The functions `mbedtls_dhm_get_bitlen`, `mbedtls_dhm_get_len` and `mbedtls_dhm_get_value` allow the caller to obtain metadata about the keys used for the key exchange. The PSA equivalents access the key identifier: From dbcfc7dd956f889975fe978252c25bf1359b0460 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 30 Nov 2023 21:04:06 +0100 Subject: [PATCH 30/88] Be more informative about "No change" Distinguish between interfaces that won't change in 4.0, and interfaces that have no PSA equivalent but are likely to change in 4.0. Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 8b25aa347b..b02e2b8f10 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -81,9 +81,9 @@ PSA functions return a status of type [`psa_status_t`](https://mbed-tls.readthed | ------ | --------------- | -------------- | | `aes.h` | `mbedtls_aes_` | [Symmetric encryption](#symmetric-encryption) | | `aria.h` | `mbedtls_aria_` | [Symmetric encryption](#symmetric-encryption) | -| `asn1.h` | `mbedtls_asn1_` | No change (not a crypto API) | -| `asn1write.h` | `mbedtls_asn1write_` | No change (not a crypto API) | -| `base64.h` | `mbedtls_base64_` | [PK format support interfaces](#pk-format-support-interfaces) | +| `asn1.h` | `mbedtls_asn1_` | No change ([PK support interface](#pk-format-support-interfaces)) | +| `asn1write.h` | `mbedtls_asn1_write_` | No change ([PK support interface](#pk-format-support-interfaces)) | +| `base64.h` | `mbedtls_base64_` | No change ([PK support interface](#pk-format-support-interfaces)) | | `bignum.h` | `mbedtls_bignum_` | None (no low-level arithmetic) | | `build_info.h` | `MBEDTLS_` | No change (not a crypto API) | | `camellia.h` | `mbedtls_camellia_` | [Symmetric encryption](#symmetric-encryption) | @@ -109,15 +109,15 @@ PSA functions return a status of type [`psa_status_t`](https://mbed-tls.readthed | `gcm.h` | `mbedtls_gcm_` | [Symmetric encryption](#symmetric-encryption), [Authenticated cipher operations](#authenticated-cipher-operations) | | `hkdf.h` | `mbedtls_hkdf_` | [HKDF](#hkdf) | | `hmac_drbg.h` | `mbedtls_hmac_drbg_` | [Random generation interface](#random-generation-interface), [Deterministic pseudorandom generation](#deterministic-pseudorandom-generation) | -| `lms.h` | `mbedtls_lms_` | No migration path yet | +| `lms.h` | `mbedtls_lms_` | No change ([LMS signatures](#lms-signatures)) | | `mbedtls_config.h` | `MBEDTLS_` | [Compile-time configuration](#compile-time-configuration) | | `md.h` | `mbedtls_md_` | [Hashes and MAC](#hashes-and-mac) | | `md5.h` | `mbedtls_md5_` | [Hashes and MAC](#hashes-and-mac) | | `memory_buffer_alloc.h` | `mbedtls_memory_buffer_alloc_` | No change (not a crypto API) | | `net_sockets.h` | `mbedtls_net_` | No change (not a crypto API) | -| `nist_kw.h` | `mbedtls_nist_kw_` | No migration path yet | -| `oid.h` | `mbedtls_oid_` | [PK format support interfaces](#pk-format-support-interfaces) | -| `pem.h` | `mbedtls_pem_` | [PK format support interfaces](#pk-format-support-interfaces) | +| `nist_kw.h` | `mbedtls_nist_kw_` | Migration path not yet defined | +| `oid.h` | `mbedtls_oid_` | No change ([PK support interface](#pk-format-support-interfaces)) | +| `pem.h` | `mbedtls_pem_` | No change ([PK support interface](#pk-format-support-interfaces)) | | `pk.h` | `mbedtls_pk_` | [Asymmetric cryptography](#asymmetric-cryptography) | | `pkcs5.h` | `mbedtls_pkcs5_` | [PKCS#5 module](#pkcs5-module) | | `pkcs7.h` | `mbedtls_pkcs7_` | No change (not a crypto API) | @@ -1289,9 +1289,15 @@ There is no direct equivalent of `mbedtls_rsa_export`, `mbedtls_rsa_export_raw` A PSA key object is immutable, so there is no need for an equivalent of `mbedtls_rsa_copy`. (There is a function `psa_copy_key`, but it is only useful to make a copy of a key with a different policy of ownership; both concepts are out of scope of this document since they have no equivalent in the legacy API.) +### LMS signatures + +A future version of Mbed TLS will support LMS keys and signatures through the PSA API (`psa_generate_key`, `psa_export_public_key`, `psa_import_key`, `psa_sign_hash`, `psa_verify_hash`, etc.). However, this is likely to happen after Mbed TLS 4.0, therefore the next major version of Mbed TLS will likely keep the existing `lms.h` interface. + ### PK format support interfaces -The interfaces in `base64.h`, `asn1.h`, `asn1write.h`, `oid.h` and `pem.h` are intended to support X.509 and key file formats. They have no PSA equivalent since they are not directly about cryptography. They remain unchanged in Mbed TLS 3.x. In the future, they are likely to move out of the cryptography part of Mbed TLS and into the public-key/X.509 part. +The interfaces in `base64.h`, `asn1.h`, `asn1write.h`, `oid.h` and `pem.h` are intended to support X.509 and key file formats. They have no PSA equivalent since they are not directly about cryptography. + +In Mbed TLS 4.0, we are planning to keep the ASN.1 interfaces mostly unchanged. The evolution of Base64, OID and PEM as separate interfaces is still undecided at the time of writing. ## EC-JPAKE From 3ea22dcb5198b77bac5d2f3482e2d5f4d62a57c6 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 30 Nov 2023 21:07:24 +0100 Subject: [PATCH 31/88] Correct function names prefixes where they diverge from module names Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index b02e2b8f10..79780564a5 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -82,20 +82,20 @@ PSA functions return a status of type [`psa_status_t`](https://mbed-tls.readthed | `aes.h` | `mbedtls_aes_` | [Symmetric encryption](#symmetric-encryption) | | `aria.h` | `mbedtls_aria_` | [Symmetric encryption](#symmetric-encryption) | | `asn1.h` | `mbedtls_asn1_` | No change ([PK support interface](#pk-format-support-interfaces)) | -| `asn1write.h` | `mbedtls_asn1_write_` | No change ([PK support interface](#pk-format-support-interfaces)) | +| `asn1write.h` | `mbedtls_asn1write_` | No change ([PK support interface](#pk-format-support-interfaces)) | | `base64.h` | `mbedtls_base64_` | No change ([PK support interface](#pk-format-support-interfaces)) | -| `bignum.h` | `mbedtls_bignum_` | None (no low-level arithmetic) | +| `bignum.h` | `mbedtls_mpi_` | None (no low-level arithmetic) | | `build_info.h` | `MBEDTLS_` | No change (not a crypto API) | | `camellia.h` | `mbedtls_camellia_` | [Symmetric encryption](#symmetric-encryption) | | `ccm.h` | `mbedtls_ccm_` | [Symmetric encryption](#symmetric-encryption), [Authenticated cipher operations](#authenticated-cipher-operations) | | `chacha20.h` | `mbedtls_chacha20_` | [Symmetric encryption](#symmetric-encryption) | -| `chachapoly.h` | `mbedtls_chachapoly_` | [Symmetric encryption](#symmetric-encryption) | +| `chachapoly.h` | `mbedtls_chachapoly_` | [Symmetric encryption](#symmetric-encryption), [Authenticated cipher operations](#authenticated-cipher-operations) | | `check_config.h` | N/A | No public APIs (internal support header) | | `cipher.h` | `mbedtls_cipher_` | [Symmetric encryption](#symmetric-encryption) | -| `cmac.h` | `mbedtls_cmac_` | [Hashes and MAC](#hashes-and-mac), [MAC calculation](#mac-calculation) | +| `cmac.h` | `mbedtls_cipher_cmac_` | [Hashes and MAC](#hashes-and-mac), [MAC calculation](#mac-calculation) | | `compat-2.x.h` | various | None (transitional APIs) | | `config_psa.h` | N/A | No public APIs (internal support header) | -| `constant_time.h` | `mbedtls_constant_time_` | [Constant-time functions](#constant-time-functions) | +| `constant_time.h` | `mbedtls_ct_` | [Constant-time functions](#constant-time-functions) | | `ctr_drbg.h` | `mbedtls_ctr_drbg_` | [Random generation interface](#random-generation-interface), [Deterministic pseudorandom generation](#deterministic-pseudorandom-generation) | | `debug.h` | `mbedtls_debug_` | No change (not a crypto API) | | `des.h` | `mbedtls_des_` | [Symmetric encryption](#symmetric-encryption) | @@ -105,7 +105,7 @@ PSA functions return a status of type [`psa_status_t`](https://mbed-tls.readthed | `ecjpake.h` | `mbedtls_ecjpake_` | [EC-JPAKE](#ec-jpake) | | `ecp.h` | `mbedtls_ecp_` | [Asymmetric cryptography](#asymmetric-cryptography) | | `entropy.h` | `mbedtls_entropy_` | [Random generation interface](#random-generation-interface), [Entropy sources](#entropy-sources) | -| `error.h` | `mbedtls_error_` | [Error messages](#error-messages) | +| `error.h` | `mbedtls_*err*` | [Error messages](#error-messages) | | `gcm.h` | `mbedtls_gcm_` | [Symmetric encryption](#symmetric-encryption), [Authenticated cipher operations](#authenticated-cipher-operations) | | `hkdf.h` | `mbedtls_hkdf_` | [HKDF](#hkdf) | | `hmac_drbg.h` | `mbedtls_hmac_drbg_` | [Random generation interface](#random-generation-interface), [Deterministic pseudorandom generation](#deterministic-pseudorandom-generation) | @@ -123,11 +123,11 @@ PSA functions return a status of type [`psa_status_t`](https://mbed-tls.readthed | `pkcs7.h` | `mbedtls_pkcs7_` | No change (not a crypto API) | | `pkcs12.h` | `mbedtls_pkcs12_` | [PKCS#12 module](#pkcs12-module) | | `platform.h` | `mbedtls_platform_` | No change (not a crypto API) | -| `platform_time.h` | `mbedtls_platform_time_` | No change (not a crypto API) | -| `platform_util.h` | `mbedtls_platform_util_` | No change (not a crypto API) | +| `platform_time.h` | `mbedtls_*time*` | No change (not a crypto API) | +| `platform_util.h` | `mbedtls_platform_` | No change (not a crypto API) | | `poly1305.h` | `mbedtls_poly1305_` | None (but there is Chacha20-Poly1305 [AEAD](#symmetric-encryption)) | | `private_access.h` | N/A | No public APIs (internal support header) | -| `psa_util.h` | `mbedtls_psa_` | No public APIs (internal support header) | +| `psa_util.h` | N/A | No public APIs (internal support header) | | `ripemd160.h` | `mbedtls_ripemd160_` | [Hashes and MAC](#hashes-and-mac) | | `rsa.h` | `mbedtls_rsa_` | [Asymmetric cryptography](#asymmetric-cryptography) | | `sha1.h` | `mbedtls_sha1_` | [Hashes and MAC](#hashes-and-mac) | @@ -136,7 +136,7 @@ PSA functions return a status of type [`psa_status_t`](https://mbed-tls.readthed | `sha512.h` | `mbedtls_sha512_` | [Hashes and MAC](#hashes-and-mac) | | `ssl.h` | `mbedtls_ssl_` | No change (not a crypto API) | | `ssl_cache.h` | `mbedtls_ssl_cache_` | No change (not a crypto API) | -| `ssl_ciphersuites.h` | `mbedtls_ssl_ciphersuites_` | No change (not a crypto API) | +| `ssl_ciphersuites.h` | `mbedtls_ssl_ciphersuite_` | No change (not a crypto API) | | `ssl_cookie.h` | `mbedtls_ssl_cookie_` | No change (not a crypto API) | | `ssl_ticket.h` | `mbedtls_ssl_ticket_` | No change (not a crypto API) | | `threading.h` | `mbedtls_threading_` | No change (not a crypto API) | From 02112cc9a1ad23ef93bd7f96974e5aea623dcc10 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 30 Nov 2023 21:17:27 +0100 Subject: [PATCH 32/88] Update PBKDF2 availability for 3.5 Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 79780564a5..304b16c55c 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -574,7 +574,7 @@ PSA Crypto provides access to HKDF, HKDF-Extract and HKDF-Expand via its [key de ### PKCS#5 module -Applications currently using `mbedtls_pkcs5_pbkdf2_hmac` or `mbedtls_pkcs5_pbkdf2_hmac_ext` can switch to the PSA key derivation API for PBKDF2 (not yet implemented at the time of writing, scheduled to be released in Mbed TLS 3.5). This is a generic interface using an operation object with one function call for each input and one function call for each output. +Applications currently using `mbedtls_pkcs5_pbkdf2_hmac` or `mbedtls_pkcs5_pbkdf2_hmac_ext` can switch to the PSA key derivation API for PBKDF2. This is a generic interface using an operation object with one function call for each input and one function call for each output. 1. Create an operation object of type [`psa_key_derivation_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga5f099b63799a0959c3d46718c86c2609) and zero-initialize it (or use the corresponding `INIT` macro). 2. Call [`psa_key_derivation_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gac0b6a76e45cceb1862752bf041701859) to select the algorithm, which is a value of type [`psa_algorithm_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac2e4d47f1300d73c2f829a6d99252d69). For PBKDF2-HMAC, select `PSA_ALG_PBKDF2_HMAC(hash)` where `hash` is the underlying hash algorithm (see “[Hash mechanism selection](#hash-mechanism-selection)”). @@ -584,7 +584,7 @@ Applications currently using `mbedtls_pkcs5_pbkdf2_hmac` or `mbedtls_pkcs5_pbkdf 2. [`PSA_KEY_DERIVATION_INPUT_SECRET`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__derivation/#group__derivation_1ga0ddfbe764baba995c402b1b0ef59392e) for the password. 5. Call [`psa_key_derivation_output_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga06b7eb34a2fa88965f68e3d023fa12b9) to obtain the output of the derivation. You may call this function more than once to retrieve the output in successive chunks. Use [`psa_key_derivation_output_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gada7a6e17222ea9e7a6be6864a00316e1) instead if you want to use a chunk as a PSA key. - If you want to verify the output against an expected value (for authentication, rather than to derive key material), call [`psa_key_derivation_verify_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gaf01520beb7ba932143ffe733b0795b08) or [`psa_key_derivation_verify_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gac041714e34a94742e8ee006ac7dfea5a) instead of `psa_key_derivation_output_bytes`. + If you want to verify the output against an expected value (for authentication, rather than to derive key material), call [`psa_key_derivation_verify_bytes`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gaf01520beb7ba932143ffe733b0795b08) or [`psa_key_derivation_verify_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1gac041714e34a94742e8ee006ac7dfea5a) instead of `psa_key_derivation_output_bytes`. (Note that the `verify` functions are not yet present in the 3.5 release of Mbed TLS. They are expected to be released in version 3.6.0.) 6. Call [`psa_key_derivation_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) to free the resources associated with the key derivation object. The function `mbedtls_pkcs5_pbes2` is only intended as a support function to parse encrypted private keys in the PK module. It has no PSA equivalent. From c3fd0958ce9ad1271a476e80e7dd57a4e3818298 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 30 Nov 2023 21:18:04 +0100 Subject: [PATCH 33/88] typo Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 304b16c55c..f4245cf6a5 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -591,7 +591,7 @@ The function `mbedtls_pkcs5_pbes2` is only intended as a support function to par ### PKCS#12 module -The functions `mbedtls_pkcs12_derivation` and `mbedtls_pkcs12_pbes2` are only intended as support functions to parse encrypted private keys in the PK module. They have no PSA equivalent. +The functions `mbedtls_pkcs12_derivation` and `mbedtls_pkcs12_pbe` are only intended as support functions to parse encrypted private keys in the PK module. They have no PSA equivalent. ## Random generation From 1097d4e73168fea015fa23d5cada5e0530daead5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 30 Nov 2023 21:18:10 +0100 Subject: [PATCH 34/88] Minor clarification Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index f4245cf6a5..41ae99e7e0 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -52,7 +52,7 @@ To make the PSA API available, make sure that the configuration option [`MBEDTLS You should probably enable [`MBEDTLS_USE_PSA_CRYPTO`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/mbedtls__config_8h/#mbedtls__config_8h_1a70fd7b97d5f11170546583f2095942a6) as well (it is disabled by default). This option causes the PK, X.509 and TLS modules to use PSA crypto under the hood. Some functions that facilitate the transition (for example, to convert between metadata encodings or between key representations) are only available when `MBEDTLS_USE_PSA_CRYPTO` is enabled. -By default, the PSA crypto API offers a similar set of cryptographic mechanisms as those offered by the legacy API. The PSA crypto API also has its own configuration mechanism; see “[Cryptographic mechanism availability](#cryptographic-mechanism-availability)”. +By default, the PSA crypto API offers a similar set of cryptographic mechanisms as those offered by the legacy API (configured by `MBEDTLS_XXX` macros). The PSA crypto API also has its own configuration mechanism; see “[Cryptographic mechanism availability](#cryptographic-mechanism-availability)”. ### Header files From 8aec84f3a7d427c6ef6eca69801800cd61c484f3 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 4 Dec 2023 16:04:21 +0100 Subject: [PATCH 35/88] pkwrite: minor code reshape Signed-off-by: Valerio Setti --- library/pkwrite.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/pkwrite.c b/library/pkwrite.c index c7eb1148b4..bd592f4f69 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -44,15 +44,13 @@ #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) #define PK_MAX_EC_PUBLIC_KEY_SIZE PSA_EXPORT_PUBLIC_KEY_MAX_SIZE #define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH -#else -#if defined(MBEDTLS_USE_PSA_CRYPTO) +#elif defined(MBEDTLS_USE_PSA_CRYPTO) #define PK_MAX_EC_PUBLIC_KEY_SIZE PSA_EXPORT_PUBLIC_KEY_MAX_SIZE #define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH #else #define PK_MAX_EC_PUBLIC_KEY_SIZE MBEDTLS_ECP_MAX_PT_LEN #define PK_MAX_EC_KEY_PAIR_SIZE MBEDTLS_ECP_MAX_BYTES #endif -#endif /****************************************************************************** * Internal functions for RSA keys. From 2fffc45febbf883aa565176385f3ccd807697fb9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Dec 2023 22:22:07 +0100 Subject: [PATCH 36/88] fixup! Correct function names prefixes where they diverge from module names Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 41ae99e7e0..80b94213a0 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -82,7 +82,7 @@ PSA functions return a status of type [`psa_status_t`](https://mbed-tls.readthed | `aes.h` | `mbedtls_aes_` | [Symmetric encryption](#symmetric-encryption) | | `aria.h` | `mbedtls_aria_` | [Symmetric encryption](#symmetric-encryption) | | `asn1.h` | `mbedtls_asn1_` | No change ([PK support interface](#pk-format-support-interfaces)) | -| `asn1write.h` | `mbedtls_asn1write_` | No change ([PK support interface](#pk-format-support-interfaces)) | +| `asn1write.h` | `mbedtls_asn1_write_` | No change ([PK support interface](#pk-format-support-interfaces)) | | `base64.h` | `mbedtls_base64_` | No change ([PK support interface](#pk-format-support-interfaces)) | | `bignum.h` | `mbedtls_mpi_` | None (no low-level arithmetic) | | `build_info.h` | `MBEDTLS_` | No change (not a crypto API) | @@ -709,7 +709,7 @@ A curve is fully determined by a curve family identifier and the private key siz | `MBEDTLS_ECP_DP_BP512R1` | [`PSA_ECC_FAMILY_BRAINPOOL_P_R1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1gac1643f1baf38b30d07c20a6eac697f15) | 512 | | `MBEDTLS_ECP_DP_CURVE25519` | [`PSA_ECC_FAMILY_MONTGOMERY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga1f624c5cdaf25b21287af33024e1aff8) | 255 | | `MBEDTLS_ECP_DP_SECP192K1` | [`PSA_ECC_FAMILY_SECP_K1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 192 | -| `MBEDTLS_ECP_DP_SECP224K1` | not supported | 224 | +| `MBEDTLS_ECP_DP_SECP224K1` | not supported | N/A | | `MBEDTLS_ECP_DP_SECP256K1` | [`PSA_ECC_FAMILY_SECP_K1`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga48bb340b5544ba617b0f5b89542665a7) | 256 | | `MBEDTLS_ECP_DP_CURVE448` | [`PSA_ECC_FAMILY_MONTGOMERY`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__crypto__types/#group__crypto__types_1ga1f624c5cdaf25b21287af33024e1aff8) | 448 | From 06002c5624d55eb660e0949d8586d24f613d7a41 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Dec 2023 22:24:25 +0100 Subject: [PATCH 37/88] typos and minor clarifications Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 80b94213a0..cdc2ce11f9 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -597,7 +597,7 @@ The functions `mbedtls_pkcs12_derivation` and `mbedtls_pkcs12_pbe` are only inte ### Random generation interface -The PSA subsystem has an internal random generator. As a consequence, you do not need to instantiate one manually, so most applications using PSA crypto do not need the interfaces from `entropy.h`, `ctr_drbg.` and `hmac_drbg.h`. See the next sections for remaining use cases for [entropy](#entropy-sources) and [DRBG](#deterministic-pseudorandom-generation). +The PSA subsystem has an internal random generator. As a consequence, you do not need to instantiate one manually, so most applications using PSA crypto do not need the interfaces from `entropy.h`, `ctr_drbg.h` and `hmac_drbg.h`. See the next sections for remaining use cases for [entropy](#entropy-sources) and [DRBG](#deterministic-pseudorandom-generation). The PSA API uses its internal random generator to generate keys (`psa_generate_key`), nonces for encryption (`psa_cipher_generate_iv`, `psa_cipher_encrypt`, `psa_aead_generate_nonce`, `psa_aead_encrypt`, `psa_asymmetric_encrypt`), and other random material as needed. If you need random data for some other purposes, call [`psa_generate_random`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5). @@ -928,7 +928,7 @@ Use [`PSA_SIGN_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/dev This is also the equivalent of the type-specific functions `mbedtls_rsa_pkcs1_sign`, `mbedtls_rsa_rsassa_pkcs1_v15_sign`, `mbedtls_rsa_rsassa_pss_sign`, `mbedtls_rsa_rsassa_pss_sign_ext`, `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext` and `mbedtls_ecdsa_write_signature`. Note that the PSA API uses the raw format for ECDSA signatures, not the ASN.1 format; see “[ECDSA signature](#ecdsa-signature)” for more details. The equivalent of `mbedtls_pk_verify` or `mbedtls_pk_verify_ext` to verify an already calculated hash is [`psa_verify_hash`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1gae2ffbf01e5266391aff22b101a49f5f5). -The key must be a public key or a key pair allowing the usage `PSA_KEY_USAGE_VERIFY_HASH` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). +The key must be a public key (or a key pair) allowing the usage `PSA_KEY_USAGE_VERIFY_HASH` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). This is also the equivalent of the type-specific functions `mbedtls_rsa_pkcs1_verify`, `mbedtls_rsa_rsassa_pkcs1_v15_verify`, `mbedtls_rsa_rsassa_pss_verify`, `mbedtls_rsa_rsassa_pss_verify_ext`, `mbedtls_ecdsa_verify` amd `mbedtls_ecdsa_read_signature`. Note that the PSA API uses the raw format for ECDSA signatures, not the ASN.1 format; see “[ECDSA signature](#ecdsa-signature)” for more details. Generally, `psa_sign_hash` and `psa_verify_hash` require the input to have the correct length for the hash (this has historically not always been enforced in the corresponding legacy APIs). @@ -1006,7 +1006,7 @@ With respect to the salt length: ### Asymmetric encryption and decryption The equivalent of `mbedtls_pk_encrypt`, `mbedtls_rsa_pkcs1_encrypt`, `mbedtls_rsa_rsaes_pkcs1_v15_encrypt` or `mbedtls_rsa_rsaes_oaep_encrypt` to encrypt a short message (typically a symmetric key) is [`psa_asymmetric_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1gaa17f61e4ddafd1823d2c834b3706c290). -The key must be a public key or a key pair allowing the usage `PSA_KEY_USAGE_ENCRYPT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). +The key must be a public key (or a key pair) allowing the usage `PSA_KEY_USAGE_ENCRYPT` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). Use the macro [`PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#crypto__sizes_8h_1a66ba3bd93e5ec52870ccc3848778bad8) or [`PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE) to determine the output buffer size. The equivalent of `mbedtls_pk_decrypt`, `mbedtls_rsa_pkcs1_decrypt`, `mbedtls_rsa_rsaes_pkcs1_v15_decrypt` or `mbedtls_rsa_rsaes_oaep_decrypt` to decrypt a short message (typically a symmetric key) is [`psa_asymmetric_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga4f968756f6b22aab362b598b202d83d7). @@ -1064,7 +1064,9 @@ There is no PSA equivalent to Mbed TLS's custom key type names exposed by `mbedt The PSA API has a generic interface for key agreement, covering the main use of both `ecdh.h` and `dhm.h`. - + #### Diffie-Hellman key pair management @@ -1125,7 +1127,7 @@ The corresponding flow with the PSA API is as follows: * `our_pub`: a buffer of size [`PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, bits)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE) (where `key_type` is the value passed to `psa_set_key_size` in step 2) or [`PSA_EXPORT_PUBLIC_KEY_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) to hold our key. * `their_pub`: a buffer of the same size, to hold the peer's key. This can be the same as `our_pub` if the application does not need to hold both at the same time; * `shared_secret`: a buffer of size [`PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, bits)`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE) or [`PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE) (if not using a key derivation operation). -2. Prepare an attribute structure as desccribed in “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)”, in particular selecting the curve with `psa_set_key_type`. +2. Prepare an attribute structure as described in “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)”, in particular selecting the curve with `psa_set_key_type`. 3. Call [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5) on `attributes` and `our_key` (output) to generate a key pair, then [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) on `our_key` and `our_pub` (output) to obtain our public key. 4. Send `our_pub` to the peer. Retrieve the peer's public key and import it into `their_pub`. These two actions may be performed in either order. 5. Call [`psa_raw_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) on `our_key`, `their_pub` and `shared_secret` (output). @@ -1218,7 +1220,7 @@ The bit-size used by the PSA API is the size of the private key. For most curves | Curve | `grp->nbits` | `grp->pbits` | `curve_info->bit_size` | PSA bit-size | | ----- | ------------ | ------------ | ---------------------- | ------------ | -| secp224k1 | 224 | 225 | 224 | not supported | +| secp224k1 | 225 | 224 | 224 | not supported | | Curve25519 | 253 | 255 | 256 | 255 | | Curve448 | 446 | 448 | 448 | 448 | From 5eeca33749a072576a988e3884a878c541005570 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Dec 2023 22:35:12 +0100 Subject: [PATCH 38/88] Use "workflow" rather than "flow" for clarity Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index cdc2ce11f9..184dcef4e5 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -328,7 +328,7 @@ Here is an overview of the lifecycle of a key object. ### Unauthenticated cipher operations -Recall the flow of an unauthenticated cipher operation in the legacy Mbed TLS cipher API: +Recall the workflow of an unauthenticated cipher operation in the legacy Mbed TLS cipher API: 1. Create a cipher context of type `mbedtls_cipher_context_t` and initialize it with `mbedtls_cipher_init`. 2. Establish the operation parameters (algorithm, key, mode) with `mbedtls_cipher_setup`, `mbedtls_cipher_setkey` (or `mbedtls_cipher_setup_psa`), `mbedtls_cipher_set_padding_mode` if applicable. @@ -336,12 +336,12 @@ Recall the flow of an unauthenticated cipher operation in the legacy Mbed TLS ci 4. For a one-shot operation, call `mbedtls_cipher_crypt`. To pass the input in multiple parts, call `mbedtls_cipher_update` as many times as necessary followed by `mbedtls_cipher_finish`. 5. Finally free the resources associated with the operation object by calling `mbedtls_cipher_free`. -For a one-shot operation (where the whole plaintext or ciphertext is passed as a single input), the equivalent flow with the PSA API is to call a single function: +For a one-shot operation (where the whole plaintext or ciphertext is passed as a single input), the equivalent workflow with the PSA API is to call a single function: * [`psa_cipher_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga61f02fbfa681c2659546eca52277dbf1) to perform encryption with a random IV of the default size (indicated by [`PSA_CIPHER_IV_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_IV_LENGTH)). (To encrypt with a specified IV, use the multi-part API described below.) You can use the macro [`PSA_CIPHER_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. * [`psa_cipher_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gab3593f5f14d8c0431dd306d80929215e) to perform decryption with a specified IV. You can use the macro [`PSA_CIPHER_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. -For a multi-part operation, the equivalent flow with the PSA API is as follows: +For a multi-part operation, the equivalent workflow with the PSA API is as follows: 1. Create an operation object of type [`psa_cipher_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga1399de29db657e3737bb09927aae51fa) and zero-initialize it (or use the corresponding `INIT` macro). 2. Select the key and algorithm with [`psa_cipher_encrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga587374c0eb8137a572f8e2fc409bb2b4) or [`psa_cipher_decrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gaa4ba3a167066eaef2ea49abc5dcd1d4b) depending on the desired direction. @@ -353,7 +353,7 @@ If you need to interrupt the operation after calling the setup function without ### Authenticated cipher operations -Recall the flow of an authenticated cipher operation in the legacy Mbed TLS cipher API (or similar flows in the `chachapoly`, `ccm` and `gcm` modules): +Recall the workflow of an authenticated cipher operation in the legacy Mbed TLS cipher API (or similar workflows in the `chachapoly`, `ccm` and `gcm` modules): 1. Create a cipher context of type `mbedtls_cipher_context_t` and initialize it with `mbedtls_cipher_init`. 2. Establish the operation parameters (algorithm, key, mode) with `mbedtls_cipher_setup`, `mbedtls_cipher_setkey` (or `mbedtls_cipher_setup_psa`), `mbedtls_cipher_set_padding_mode` if applicable. @@ -370,7 +370,7 @@ For a one-shot operation, the PSA API allows you to call a single function: * [`psa_aead_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae72e1eb3c2da3ebd843bb9c8db8df509) to perform authenticated encryption with a random nonce of the default size (indicated by [`PSA_AEAD_NONCE_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_NONCE_LENGTH)), with the authentication tag written at the end of the output. (To encrypt with a specified nonce, or to separate the tag from the rest of the ciphertext, use the multi-part API described below.) You can use the macro [`PSA_AEAD_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_ENCRYPT_OUTPUT_SIZE) or [`PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. * [`psa_aead_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae799f6196a22d50c216c947e0320d3ba) to perform authenticated decryption of a ciphertext with the authentication tag at the end. (If the tag is separate, use the multi-part API described below.) You can use the macro [`PSA_AEAD_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_SIZE) or [`PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. -For a multi-part operation, the equivalent flow with the PSA API is as follows: +For a multi-part operation, the equivalent workflow with the PSA API is as follows: 1. Create an operation object of type [`psa_aead_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga14f6a01afbaa8c5b3d8c5d345cbaa3ed) and zero-initialize it (or use the corresponding `INIT` macro). 2. Select the key and algorithm with [`psa_aead_encrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga2732c40ce8f3619d41359a329e9b46c4) or [`psa_aead_decrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gaaa5c5018e67a7a6514b7e76b9a14de26) depending on the desired direction. @@ -770,12 +770,12 @@ You can use glue functions in the PK module to create a key object using the leg #### Importing a PK key by wrapping -If you have a PK object, you can call `mbedtls_pk_wrap_as_opaque` to create a PSA key object with the same key material. (This function is only present in builds with `MBEDTLS_USE_PSA_CRYPTO` enabled. It is experimental and [will likely be replaced by a slightly different interface in a future version of Mbed TLS](https://github.com/Mbed-TLS/mbedtls/issues/7760)). This function automatically determines the PSA key type and lets you specify the usage policy (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). Once you've called this function, you can destroy the PK object. This function calls `psa_import_key` internally; call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to destroy the PSA key object once your application no longer needs it. Common scenarios where this flow is useful are: +If you have a PK object, you can call `mbedtls_pk_wrap_as_opaque` to create a PSA key object with the same key material. (This function is only present in builds with `MBEDTLS_USE_PSA_CRYPTO` enabled. It is experimental and [will likely be replaced by a slightly different interface in a future version of Mbed TLS](https://github.com/Mbed-TLS/mbedtls/issues/7760)). This function automatically determines the PSA key type and lets you specify the usage policy (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). Once you've called this function, you can destroy the PK object. This function calls `psa_import_key` internally; call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to destroy the PSA key object once your application no longer needs it. Common scenarios where this workflow is useful are: * You have working code that's calling `mbedtls_pk_parse_key`, `mbedtls_pk_parse_public_key`, `mbedtls_pk_parse_subpubkey`, `mbedtls_pk_parse_keyfile` or `mbedtls_pk_parse_public_keyfile` to create a PK object. * You have working code that's using the `rsa.h` or `ecp.h` API to create a key object, and there is no PSA equivalent. -You can use this flow to import an RSA key via an `mbedtls_rsa_context` object or an ECC key via an `mbedtls_ecp_keypair` object: +You can use this workflow to import an RSA key via an `mbedtls_rsa_context` object or an ECC key via an `mbedtls_ecp_keypair` object: 1. Call `mbedtls_pk_init` then `mbedtls_pk_setup` to set up a PK context for the desired key type (`MBEDTLS_PK_RSA` or `MBEDTLS_PK_ECKEY`). 2. Call `mbedtls_pk_rsa` or `mbedtls_pk_ec` to obtain the underlying low-level context. @@ -1102,9 +1102,9 @@ Use the macros [`PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE`](https://mbed-tls.readthedoc Call [`psa_key_derivation_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga2cd5a8ac906747d3204ec442db78745f) instead of `psa_raw_key_agreement` to use the resulting shared secret as the secret input to a key derivation. See “[HKDF](#hkdf)” for an example of the key derivation interface. -#### Translating a legacy key agreement contextless flow +#### Translating a legacy key agreement contextless workflow -A typical flow for ECDH using the legacy API without a context object is: +A typical workflow for ECDH using the legacy API without a context object is: 1. Initialize objects: * `mbedtls_ecp_group grp` for the curve; @@ -1119,7 +1119,7 @@ A typical flow for ECDH using the legacy API without a context object is: 6. Use the raw shared secret `z`, typically, to construct a shared key. 7. Free `grp`, `our_priv`, `our_pub`, `their_pub` and `z`. -The corresponding flow with the PSA API is as follows: +The corresponding workflow with the PSA API is as follows: 1. Initialize objects: * `psa_key_id_t our_key`: a handle to our key pair; @@ -1136,9 +1136,9 @@ The corresponding flow with the PSA API is as follows: Steps 4–5 are only performed once for ephemeral Diffie-Hellman, but repeated multiple times for static Diffie-Hellman. -#### Translating a legacy key agreement TLS server flow +#### Translating a legacy key agreement TLS server workflow -The legacy API offers the following flow for a Diffie-Hellman key agreement in a TLS server. This flow can also be used with other protocols, on the side of the party that selects the curve or group and sends its public key first. +The legacy API offers the following workflow for a Diffie-Hellman key agreement in a TLS server. This workflow can also be used with other protocols, on the side of the party that selects the curve or group and sends its public key first. 1. Setup phase: 1. Initialize a context of type `mbedtls_ecdh_context` or `mbedtls_dhm_context` with `mbedtls_ecdh_init` or `mbedtls_dhm_init`. @@ -1149,7 +1149,7 @@ The legacy API offers the following flow for a Diffie-Hellman key agreement in a 4. Call `mbedtls_ecdh_read_public` or `mbedtls_dhm_read_public` on the peer's public key, then call `mbedtls_ecdh_calc_secret` or `mbedtls_dhm_calc_secret` to calculate the shared secret. 5. Free the context with `mbedtls_ecdh_free` or `mbedtls_dhm_free`. -The corresponding flow with the PSA API is as follows: +The corresponding workflow with the PSA API is as follows: 1. Setup phase: 1. Generate an ECDH or DHM key pair with `psa_generate_key` as described in “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)”. @@ -1161,9 +1161,9 @@ The corresponding flow with the PSA API is as follows: Alternatively, call `psa_key_derivation_key_agreement` to use the shared secret directly in a key derivation operation (see “[Performing a key agreement](#performing-a-key-agreement)”). 5. Call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to free the resources associated with our key pair. -#### Translating a legacy key agreement TLS client flow +#### Translating a legacy key agreement TLS client workflow -The legacy API offers the following flow for a Diffie-Hellman key agreement in a TLS client. This flow can also be used with other protocols, on the side of the party that receives a message indicating both the choice of curve or group, and the peer's public key. +The legacy API offers the following workflow for a Diffie-Hellman key agreement in a TLS client. This workflow can also be used with other protocols, on the side of the party that receives a message indicating both the choice of curve or group, and the peer's public key. 1. Upon reception of a TLS ServerKeyExchange message received from the peer, which encodes the selected curve/group and the peer's public key: 1. Initialize a context of type `mbedtls_ecdh_context` or `mbedtls_dhm_context` with `mbedtls_ecdh_init` or `mbedtls_dhm_init`. @@ -1173,7 +1173,7 @@ The legacy API offers the following flow for a Diffie-Hellman key agreement in a 4. Call `mbedtls_ecdh_calc_secret` or `mbedtls_dhm_calc_secret` to calculate the shared secret. 5. Free the context with `mbedtls_ecdh_free` or `mbedtls_dhm_free`. -The corresponding flow with the PSA API is as follows: +The corresponding workflow with the PSA API is as follows: 1. Upon reception of a TLS ServerKeyExchange message received from the peer, which encodes the selected curve/group and the peer's public key: 1. Decode the selected curve/group and use this to determine a PSA key type (`PSA_KEY_TYPE_ECC_KEY_PAIR(curve)` or `PSA_KEY_TYPE_DH_KEY_PAIR(group)`), a key size and an algorithm. From d921391bf4d6d9783b3cf41e8f3018bc478774b4 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Dec 2023 22:35:34 +0100 Subject: [PATCH 39/88] Note a few things about PAKE (thanks Manuel) Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 184dcef4e5..fdf6cdae52 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -1304,3 +1304,9 @@ In Mbed TLS 4.0, we are planning to keep the ASN.1 interfaces mostly unchanged. ## EC-JPAKE The PSA API exposes EC-JPAKE via the algorithm [`PSA_ALG_JPAKE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__extra_8h/#c.PSA_ALG_JPAKE) and the PAKE API functions. At the time of writing, the PAKE API is still experimental, but it should offer the same functionality as the legacy `ecjpake.h`. Please consult the documentation of your version of Mbed TLS for more information. + +Please note a few differences between the two APIs: the legacy API is geared towards the use of EC-JPAKE in TLS 1.2, whereas the PSA API is protocol-agnostic. + +* The PSA API is finer-grained and offers more flexibility in message ordering. Where the legacy API makes a single function call, the PSA API may require multiple calls. +* The legacy API uses the TLS 1.2 wire format in the input or output format of several functions. In particular, one of the messages embeds the curve identifier in the TLS protocol. The PSA API uses protocol-agnostic formats. +* The legacy API always applies the key derivation specified by TLS 1.2 to the shared secret. With the PSA API, use a key derivation with `PSA_ALG_TLS12_ECJPAKE_TO_PMS` for the same calculation. From 76bc64e101b5321f89e5cfeabccc9a61c89de969 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Dec 2023 22:49:18 +0100 Subject: [PATCH 40/88] Diffie-Hellman: several clarifications and corrections Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index fdf6cdae52..cb76c3d579 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -1115,9 +1115,8 @@ A typical workflow for ECDH using the legacy API without a context object is: 2. Call `mbedtls_ecp_group_load` on `grp` to select the curve. 3. Call `mbedtls_ecdh_gen_public` on `grp`, `our_priv` (output) and `our_pub` (output) to generate a key pair and retrieve the corresponding public key. 4. Send `our_pub` to the peer. Retrieve the peer's public key and import it into `their_pub`. These two actions may be performed in either order. -5. Call `mbedtls_ecdh_compute_shared` on `grp`, `z` (output), `their_pub` and `our_priv`. -6. Use the raw shared secret `z`, typically, to construct a shared key. -7. Free `grp`, `our_priv`, `our_pub`, `their_pub` and `z`. +5. Call `mbedtls_ecdh_compute_shared` on `grp`, `z` (output), `their_pub` and `our_priv`. Use the raw shared secret `z`, typically, to construct a shared key. +6. Free `grp`, `our_priv`, `our_pub`, `their_pub` and `z`. The corresponding workflow with the PSA API is as follows: @@ -1134,11 +1133,11 @@ The corresponding workflow with the PSA API is as follows: Alternatively, call `psa_key_derivation_key_agreement` to use the shared secret directly in a key derivation operation (see “[Performing a key agreement](#performing-a-key-agreement)”). 6. Call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) on `key_id`, and free the memory buffers. -Steps 4–5 are only performed once for ephemeral Diffie-Hellman, but repeated multiple times for static Diffie-Hellman. +Steps 4–6 are only performed once for a "true" ephemeral Diffie-Hellman. They may be repeated multiple times for a "fake ephemeral" Diffie-Hellman where the same private key is used for multiple key exchanges, but it not saved. -#### Translating a legacy key agreement TLS server workflow +#### Translating a legacy ephemeral key agreement TLS server workflow -The legacy API offers the following workflow for a Diffie-Hellman key agreement in a TLS server. This workflow can also be used with other protocols, on the side of the party that selects the curve or group and sends its public key first. +The legacy API offers the following workflow for an ephemeral Diffie-Hellman key agreement in a TLS 1.2 server. The PSA version of this workflow can also be used with other protocols, on the side of the party that selects the curve or group and sends its public key first. 1. Setup phase: 1. Initialize a context of type `mbedtls_ecdh_context` or `mbedtls_dhm_context` with `mbedtls_ecdh_init` or `mbedtls_dhm_init`. @@ -1161,9 +1160,9 @@ The corresponding workflow with the PSA API is as follows: Alternatively, call `psa_key_derivation_key_agreement` to use the shared secret directly in a key derivation operation (see “[Performing a key agreement](#performing-a-key-agreement)”). 5. Call [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2) to free the resources associated with our key pair. -#### Translating a legacy key agreement TLS client workflow +#### Translating a legacy ephemeral key agreement TLS client workflow -The legacy API offers the following workflow for a Diffie-Hellman key agreement in a TLS client. This workflow can also be used with other protocols, on the side of the party that receives a message indicating both the choice of curve or group, and the peer's public key. +The legacy API offers the following workflow for an ephemeral Diffie-Hellman key agreement in a TLS 1.2 client. The PSA version of this workflow can also be used with other protocols, on the side of the party that receives a message indicating both the choice of curve or group, and the peer's public key. 1. Upon reception of a TLS ServerKeyExchange message received from the peer, which encodes the selected curve/group and the peer's public key: 1. Initialize a context of type `mbedtls_ecdh_context` or `mbedtls_dhm_context` with `mbedtls_ecdh_init` or `mbedtls_dhm_init`. @@ -1206,7 +1205,7 @@ The PSA API for finite-field Diffie-Hellman only supports predefined groups. The #### Restartable key agreement -Restartable key agreement is not yet available through the PSA API. It will be added in a future version of the library. +Restartable key agreement (enabled by `mbedtls_ecdh_enable_restart`) is not yet available through the PSA API. It will be added under the name “interruptible key agreement” in a future version of the library, with an interface that's similar to the interruptible signature interface described in “[Restartable ECDSA signature](#restartable-ecdsa-signature)”. ### Additional information about Elliptic-curve cryptography From 32dfaf485c1f606391161ce2212555bfd6bcd537 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Dec 2023 23:14:25 +0100 Subject: [PATCH 41/88] More information about output buffer sizes Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index cb76c3d579..e9261c782c 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -75,6 +75,10 @@ Mbed TLS functions return a status of type `int`: 0 for success (or occasionally PSA functions return a status of type [`psa_status_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__error/#group__error_1ga05676e70ba5c6a7565aff3c36677c1f9): `PSA_SUCCESS == 0` for success, or a negative value [`PSA_ERROR_xxx`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__error/) indicating an error. +### Memory management + +Functions that output data require an output buffer of sufficient size. For all PSA crypto API functions that have an output buffer, there is a corresponding macro, generally called `PSA_XXX_OUTPUT_SIZE`, that calculates a sufficient size for the output buffer, given the relevant parameters. In some cases, there may be macros with less precision which can be resolved at compile time. For example, for the size of a buffer containing a hash, you can use `PSA_HASH_LENGTH(hash_alg)` where `hash_alg` is a specific hash algorithm, or `PSA_HASH_MAX_SIZE` for a buffer that is long enough for any supported hash. See the relevant sections of this document and of the reference documentation for more details. + ## Summary of API modules | Header | Function prefix | PSA equivalent | @@ -338,16 +342,16 @@ Recall the workflow of an unauthenticated cipher operation in the legacy Mbed TL For a one-shot operation (where the whole plaintext or ciphertext is passed as a single input), the equivalent workflow with the PSA API is to call a single function: -* [`psa_cipher_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga61f02fbfa681c2659546eca52277dbf1) to perform encryption with a random IV of the default size (indicated by [`PSA_CIPHER_IV_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_IV_LENGTH)). (To encrypt with a specified IV, use the multi-part API described below.) You can use the macro [`PSA_CIPHER_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. -* [`psa_cipher_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gab3593f5f14d8c0431dd306d80929215e) to perform decryption with a specified IV. You can use the macro [`PSA_CIPHER_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. +* [`psa_cipher_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga61f02fbfa681c2659546eca52277dbf1) to perform encryption with a random IV of the default size (indicated by [`PSA_CIPHER_IV_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_IV_LENGTH)). (To encrypt with a specified IV, use the multi-part API described below.) You can use the macro [`PSA_CIPHER_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer. +* [`psa_cipher_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gab3593f5f14d8c0431dd306d80929215e) to perform decryption with a specified IV. You can use the macro [`PSA_CIPHER_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_SIZE) or [`PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer. For a multi-part operation, the equivalent workflow with the PSA API is as follows: 1. Create an operation object of type [`psa_cipher_operation_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga1399de29db657e3737bb09927aae51fa) and zero-initialize it (or use the corresponding `INIT` macro). 2. Select the key and algorithm with [`psa_cipher_encrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga587374c0eb8137a572f8e2fc409bb2b4) or [`psa_cipher_decrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gaa4ba3a167066eaef2ea49abc5dcd1d4b) depending on the desired direction. 3. When encrypting with a random IV, use [`psa_cipher_generate_iv`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga29fd7d32a5729226a2f73e7b6487bd8a). When encrypting with a chosen IV, or when decrypting, set the IV with [`psa_cipher_set_iv`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga9caddac1a429a5032d6d4a907fb70ba1). Skip this step with ECB since it does not use an IV. -4. Call [`psa_cipher_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gac3ca27ac6682917c48247d01fd96cd0f) as many times as needed. You can use [`PSA_CIPHER_UPDATE_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_UPDATE_OUTPUT_SIZE) or [`PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#crypto__sizes_8h_1ab1f6598efd6a7dc56e7ad7e34719eb32) to determine the size of the output buffer. -5. Call [`psa_cipher_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga1dcb58b8befe23f8a4d7a1d49c99249b) to obtain the last part of the output. You can use [`PSA_CIPHER_FINISH_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_FINISH_OUTPUT_SIZE) or [`PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE) to determine the size of the output buffer. +4. Call [`psa_cipher_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gac3ca27ac6682917c48247d01fd96cd0f) as many times as needed. You can use [`PSA_CIPHER_UPDATE_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_UPDATE_OUTPUT_SIZE) or [`PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#crypto__sizes_8h_1ab1f6598efd6a7dc56e7ad7e34719eb32) to determine a sufficient size for the output buffer. +5. Call [`psa_cipher_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1ga1dcb58b8befe23f8a4d7a1d49c99249b) to obtain the last part of the output. You can use [`PSA_CIPHER_FINISH_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_FINISH_OUTPUT_SIZE) or [`PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer. If you need to interrupt the operation after calling the setup function without calling the finish function, call [`psa_cipher_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__cipher/#group__cipher_1gaad482cdca2098bca0620596aaa02eaa4). @@ -367,8 +371,8 @@ Steps 3–6 can be replaced by a single call to `mbedtls_cipher_auth_encrypt_ext For a one-shot operation, the PSA API allows you to call a single function: -* [`psa_aead_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae72e1eb3c2da3ebd843bb9c8db8df509) to perform authenticated encryption with a random nonce of the default size (indicated by [`PSA_AEAD_NONCE_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_NONCE_LENGTH)), with the authentication tag written at the end of the output. (To encrypt with a specified nonce, or to separate the tag from the rest of the ciphertext, use the multi-part API described below.) You can use the macro [`PSA_AEAD_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_ENCRYPT_OUTPUT_SIZE) or [`PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. -* [`psa_aead_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae799f6196a22d50c216c947e0320d3ba) to perform authenticated decryption of a ciphertext with the authentication tag at the end. (If the tag is separate, use the multi-part API described below.) You can use the macro [`PSA_AEAD_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_SIZE) or [`PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. +* [`psa_aead_encrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae72e1eb3c2da3ebd843bb9c8db8df509) to perform authenticated encryption with a random nonce of the default size (indicated by [`PSA_AEAD_NONCE_LENGTH`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_NONCE_LENGTH)), with the authentication tag written at the end of the output. (To encrypt with a specified nonce, or to separate the tag from the rest of the ciphertext, use the multi-part API described below.) You can use the macro [`PSA_AEAD_ENCRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_ENCRYPT_OUTPUT_SIZE) or [`PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer. +* [`psa_aead_decrypt`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae799f6196a22d50c216c947e0320d3ba) to perform authenticated decryption of a ciphertext with the authentication tag at the end. (If the tag is separate, use the multi-part API described below.) You can use the macro [`PSA_AEAD_DECRYPT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_SIZE) or [`PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer. For a multi-part operation, the equivalent workflow with the PSA API is as follows: @@ -376,10 +380,10 @@ For a multi-part operation, the equivalent workflow with the PSA API is as follo 2. Select the key and algorithm with [`psa_aead_encrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga2732c40ce8f3619d41359a329e9b46c4) or [`psa_aead_decrypt_setup`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gaaa5c5018e67a7a6514b7e76b9a14de26) depending on the desired direction. 3. When encrypting with a random nonce, use [`psa_aead_generate_nonce`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga5799df1c555efd35970b65be51cb07d1). When encrypting with a chosen nonce, or when decrypting, set the nonce with [`psa_aead_set_nonce`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga59132751a6f843d038924cb217b5e13b). If the algorithm is CCM, you must also call [`psa_aead_set_lengths`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gad3431e28d05002c2a7b0760610176050) before or after setting the nonce (for other algorithms, this is permitted but not needed). 4. Call [`psa_aead_update_ad`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga6d0eed03f832e5c9c91cb8adf2882569) as many times as needed. -5. Call [`psa_aead_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gaf6d49864951ca42136b4a9b71ea26e5c) as many times as needed. You can use [`PSA_AEAD_UPDATE_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_UPDATE_OUTPUT_SIZE) or [`PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE) to determine the size of the output buffer. +5. Call [`psa_aead_update`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gaf6d49864951ca42136b4a9b71ea26e5c) as many times as needed. You can use [`PSA_AEAD_UPDATE_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_UPDATE_OUTPUT_SIZE) or [`PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer. 6. Finally: - * When encrypting, call [`psa_aead_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga759791bbe1763b377c3b5447641f1fc8) to obtain the last part of the ciphertext and the authentication tag. You can use [`PSA_AEAD_FINISH_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_FINISH_OUTPUT_SIZE) or [`PSA_AEAD_FINISH_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_FINISH_OUTPUT_MAX_SIZE) to determine the size of the output buffer. - * When decrypting, call [`psa_aead_verify`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae0280e2e61a185b893c36d858453f0d0) to obtain the last part of the plaintext and check the authentication tag. You can use [`PSA_AEAD_VERIFY_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_VERIFY_OUTPUT_SIZE) or [`PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE) to determine the size of the output buffer. + * When encrypting, call [`psa_aead_finish`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1ga759791bbe1763b377c3b5447641f1fc8) to obtain the last part of the ciphertext and the authentication tag. You can use [`PSA_AEAD_FINISH_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_FINISH_OUTPUT_SIZE) or [`PSA_AEAD_FINISH_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_FINISH_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer. + * When decrypting, call [`psa_aead_verify`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae0280e2e61a185b893c36d858453f0d0) to obtain the last part of the plaintext and check the authentication tag. You can use [`PSA_AEAD_VERIFY_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_VERIFY_OUTPUT_SIZE) or [`PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer. If you need to interrupt the operation after calling the setup function without calling the finish or verify function, call [`psa_aead_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__aead/#group__aead_1gae8a5f93d92318c8f592ee9fbb9d36ba0). @@ -924,7 +928,7 @@ You can wrap a PSA key object in a PK key context with `mbedtls_pk_setup_opaque` The equivalent of `mbedtls_pk_sign` or `mbedtls_pk_sign_ext` to sign an already calculated hash is [`psa_sign_hash`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1ga785e746a31a7b2a35ae5175c5ace3c5c). The key must be a key pair allowing the usage `PSA_KEY_USAGE_SIGN_HASH` (see “[Public-key cryptography policies](#public-key-cryptography-policies)”). -Use [`PSA_SIGN_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_SIGN_OUTPUT_SIZE) or [`PSA_SIGNATURE_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_SIGNATURE_MAX_SIZE) (similar to `MBEDTLS_PK_SIGNATURE_MAX_SIZE`) to determine the size of the output buffer. +Use [`PSA_SIGN_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_SIGN_OUTPUT_SIZE) or [`PSA_SIGNATURE_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_SIGNATURE_MAX_SIZE) (similar to `MBEDTLS_PK_SIGNATURE_MAX_SIZE`) to determine a sufficient size for the output buffer. This is also the equivalent of the type-specific functions `mbedtls_rsa_pkcs1_sign`, `mbedtls_rsa_rsassa_pkcs1_v15_sign`, `mbedtls_rsa_rsassa_pss_sign`, `mbedtls_rsa_rsassa_pss_sign_ext`, `mbedtls_ecdsa_sign`, `mbedtls_ecdsa_sign_det_ext` and `mbedtls_ecdsa_write_signature`. Note that the PSA API uses the raw format for ECDSA signatures, not the ASN.1 format; see “[ECDSA signature](#ecdsa-signature)” for more details. The equivalent of `mbedtls_pk_verify` or `mbedtls_pk_verify_ext` to verify an already calculated hash is [`psa_verify_hash`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__asymmetric/#group__asymmetric_1gae2ffbf01e5266391aff22b101a49f5f5). @@ -1095,10 +1099,10 @@ Here is an overview of the lifecycle of a key object. #### Performing a key agreement Call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) to obtain the public key that needs to be sent to the other party. -Use the macros [`PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE) or [`PSA_EXPORT_PUBLIC_KEY_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) to determine the size of the output buffer. +Use the macros [`PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE) or [`PSA_EXPORT_PUBLIC_KEY_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) to determine a sufficient size for the output buffer. Call [`psa_raw_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga90fdd2716124d0bd258826184824675f) to calculate the shared secret from your private key and the other party's public key. -Use the macros [`PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE) or [`PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE) to determine the size of the output buffer. +Use the macros [`PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE) or [`PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__sizes_8h/#c.PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE) to determine a sufficient size for the output buffer. Call [`psa_key_derivation_key_agreement`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__derivation/#group__key__derivation_1ga2cd5a8ac906747d3204ec442db78745f) instead of `psa_raw_key_agreement` to use the resulting shared secret as the secret input to a key derivation. See “[HKDF](#hkdf)” for an example of the key derivation interface. From e5044a0eb2a1b23d69045d2e10e264f4bd16ff0e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 4 Dec 2023 23:14:45 +0100 Subject: [PATCH 42/88] Add a generic section about key management Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index e9261c782c..d0a0de6565 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -77,8 +77,28 @@ PSA functions return a status of type [`psa_status_t`](https://mbed-tls.readthed ### Memory management +Apart from keys, as described in “[Key management](#key-management)” below, APIs that need to preserve state between function calls store this state in a structure allocated by the calling code. For example, multipart operations store state in a multipart operation object. + +All PSA operation objects must be zero-initialized (or equivalently, initialized with the provided `PSA_XXX_INIT` macro or `psa_xxx_init()` function) before calling any API function. + Functions that output data require an output buffer of sufficient size. For all PSA crypto API functions that have an output buffer, there is a corresponding macro, generally called `PSA_XXX_OUTPUT_SIZE`, that calculates a sufficient size for the output buffer, given the relevant parameters. In some cases, there may be macros with less precision which can be resolved at compile time. For example, for the size of a buffer containing a hash, you can use `PSA_HASH_LENGTH(hash_alg)` where `hash_alg` is a specific hash algorithm, or `PSA_HASH_MAX_SIZE` for a buffer that is long enough for any supported hash. See the relevant sections of this document and of the reference documentation for more details. +#### Key management + +One of the major differences between the legacy API and the PSA API is that in the PSA API, access to keys is indirect. Operations that require a key take a parameter of type [`psa_key_id_t`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/crypto__types_8h/#_CPPv412psa_key_id_t), which is an identifier for the key. This allows the API to be used with keys that are not directly accessible to the application, for example because they are stored in a secure environment that does not allow the key material to be exported. + +To use a key: + +1. First create a key object with a key creation function. The two most common ones are [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b) if you have the key material available and [`psa_generate_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__random/#group__random_1ga1985eae417dfbccedf50d5fff54ea8c5) to create a random key. The key creation function has the key identifier as an output parameter. +2. Use the key as desired, passing the key identifier obtained during the key creation. +3. Finally destroy the key object with [`psa_destroy_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__key__management/#group__key__management_1ga5f52644312291335682fbc0292c43cd2). + +See “[Cipher key management](#cipher-key-management)”, “[MAC key management](#mac-key-management)”, “[Key lifecycle for asymmetric cryptography](#key-lifecycle-for-asymmetric-cryptography)”, “[Creating keys for asymmetric cryptography](#creating-keys-for-asymmetric-cryptography)” and “[Diffie-Hellman key pair management](#diffie-hellman-key-pair-management)” for more details about key management in specific workflows, including information about choosing the key's attributes. + +If you need access to the key material, call [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf). If you need the public key corresponding to a key pair object, call [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062). + +Note that a key consumes a key store entry, which is distinct from heap memory, until it is destroyed or the application exits. (This is not true for persistent keys, which instead consume disk space. Since persistent keys have no analog in the legacy API, we will not discuss them further in this document.) + ## Summary of API modules | Header | Function prefix | PSA equivalent | From 9f55e8e44267ab76bcae94184716122b6729b517 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 5 Dec 2023 22:21:09 +0100 Subject: [PATCH 43/88] Add a section about ALT implementations Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index d0a0de6565..acfd64ab19 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -226,6 +226,12 @@ When PSA Crypto mechanisms are implemented by the built-in code from Mbed TLS, t The PSA Crypto API may use accelerator drivers. In this case any options controlling the driver behavior are driver-specific. +### Alternative implementations (`MBEDTLS_xxx_ALT` options) + +In the Mbed TLS legacy interface, you can replace some cryptographic primitives and modes by an alternative implementation, by enabling configuration options of the form `MBEDTLS_xxx_ALT` and linking with your own implementation of the affected function or module. Alternative implementations remain supported in Mbed TLS 3.x even if the application code uses the PSA API. However, they will be removed from the next version of the library. + +The corresponding PSA feature is accelerator drivers. To implement an accelerator driver, see the [PSA cryptoprocessor driver example and guide](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/psa-driver-example-and-guide.md). In an application that uses both the legacy interface and the PSA interface for the same mechanism, only some algorithms support calling a PSA driver from the legacy interface. See the [Guide to driver-only builds](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/driver-only-builds.md) for more information. + ### Self-tests There is currently [no PSA equivalent to the self-tests](https://github.com/Mbed-TLS/mbedtls/issues/7781) enabled by `MBEDTLS_SELF_TEST`. From 0308d79a340b88463610afa5af3703258fb2d10e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 12 Dec 2023 19:20:30 +0100 Subject: [PATCH 44/88] Fix some MAC-related function names Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index acfd64ab19..7e3eceb904 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -427,7 +427,7 @@ The PSA API does have a direct interface for the AES-CMAC-PRF-128 from RFC 4615 ### Hash mechanism selection -The equivalent to `mbedtls_md_type_t` and `MBEDTLS_MD` constants is the type `psa_algorithm_t` and `PSA_ALG_xxx` constants (the type encompasses all categories of cryptographic algorithms, not just hashes). PSA offers a similar selection of algorithms, but note that SHA-1 and SHA-2 are spelled slightly differently. +The equivalent to `mbedtls_md_type_t` and `MBEDTLS_MD_XXX` constants is the type `psa_algorithm_t` and `PSA_ALG_xxx` constants (the type encompasses all categories of cryptographic algorithms, not just hashes). PSA offers a similar selection of algorithms, but note that SHA-1 and SHA-2 are spelled slightly differently. | Mbed TLS constant | PSA constant | | ---------------------- | ------------------- | @@ -574,7 +574,7 @@ To verify a MAC against an expected value, use the following process instead: If you need to interrupt the operation after calling the setup function without calling the finish function, call [`psa_mac_abort`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gacd8dd54855ba1bc0a03f104f252884fd). -The PSA API also offers functions for a one-shot MAC calculation, similar to `mbedtls_cipher_cmac`: +The PSA API also offers functions for a one-shot MAC calculation, similar to `mbedtls_cipher_cmac` and `mbedtls_md_hmac`: * [`psa_mac_compute`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gabf02ebd3595ea15436967092b5d52878) to calculate the MAC of a buffer in memory. * [`psa_mac_verify`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group___m_a_c/#group___m_a_c_1gaf6988545df5d5e2466c34d753443b15a) to verify the MAC of a buffer in memory against an expected value. From 5feac959a5f18af7f6de9f8634179de30418b0f2 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 12 Dec 2023 19:20:45 +0100 Subject: [PATCH 45/88] Correct and clarify discussion of AES-CMAC-PRF-128 Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 7e3eceb904..8cb94ccd53 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -423,7 +423,7 @@ There is no equivalent for the `mbedtls_cipher_get_xxx` functions to extract inf The PSA API groups functions by purpose rather than by underlying primitive: there is a MAC API (equivalent to `md.h` for HMAC, and `cmac.h` for CMAC) and a hash API (equivalent to `md.h` for hashing). There is no special API for a particular hash algorithm (`md5.h`, `sha1.h`, `sha256.h`, `sha512.h`, `sha3.h`). To migrate code using those low-level modules, please follow the recommendations in the following section, using the same principles as the corresponding `md.h` API. -The PSA API does have a direct interface for the AES-CMAC-PRF-128 from RFC 4615 at the time of writing. You can calculate it using the interface to AES-CMAC. +The PSA API does not have a direct interface for the AES-CMAC-PRF-128 algorithm from RFC 4615 calculated by `mbedtls_aes_cmac_prf_128` at the time of writing. You can implement it using the MAC interface with an AES key and the CMAC algorithm. ### Hash mechanism selection From 1ef1eb234fe18b2dfeedde4e524eb6688c1e23e3 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 13 Dec 2023 11:09:47 +0100 Subject: [PATCH 46/88] Clarify psa_constant_names Signed-off-by: Gilles Peskine --- docs/psa-transition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 8cb94ccd53..067ffafbd3 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -240,7 +240,7 @@ There is currently [no PSA equivalent to the self-tests](https://github.com/Mbed ### Error messages -At the time of writing, there is no equivalent to the error messages provided by `mbedtls_strerror`. However, you can use the companion program `programs/psa/psa_constant_names` to convert various numbers (`psa_status_t`, `psa_algorithm_t`, `psa_key_type_t`, `psa_ecc_family_t`, `psa_dh_family_t`, `psa_key_usage_t`) to their input representation. The conversion doesn't depend on the library configuration or the target platform, so you can use a native build of this program even if you cross-compile your application. +At the time of writing, there is no equivalent to the error messages provided by `mbedtls_strerror`. However, you can use the companion program `programs/psa/psa_constant_names` to convert various numbers (`psa_status_t`, `psa_algorithm_t`, `psa_key_type_t`, `psa_ecc_family_t`, `psa_dh_family_t`, `psa_key_usage_t`) to a programmer-friendly representation. The conversion doesn't depend on the library configuration or the target platform, so you can use a native build of this program even if you cross-compile your application. ``` $ programs/psa/psa_constant_names error -138 From f3c04f3f47c242924a9927c6c411bb5464aa1107 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 5 Dec 2023 12:06:11 +0000 Subject: [PATCH 47/88] Better definition of MBEDTLS_IS_BIG_ENDIAN for IAR Signed-off-by: Dave Rodgman --- library/alignment.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/library/alignment.h b/library/alignment.h index 4aab8e0275..634d610469 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -224,10 +224,25 @@ static inline uint64_t mbedtls_bswap64(uint64_t x) #endif /* !defined(MBEDTLS_BSWAP64) */ #if !defined(__BYTE_ORDER__) + +#if defined(__LITTLE_ENDIAN__) +/* IAR defines __xxx_ENDIAN__, but not __BYTE_ORDER__ */ +#define MBEDTLS_IS_BIG_ENDIAN 0 +#elif defined(__BIG_ENDIAN__) +#define MBEDTLS_IS_BIG_ENDIAN 1 +#else static const uint16_t mbedtls_byte_order_detector = { 0x100 }; #define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01) +#endif + #else -#define MBEDTLS_IS_BIG_ENDIAN ((__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__)) + +#if (__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__) +#define MBEDTLS_IS_BIG_ENDIAN 1 +#else +#define MBEDTLS_IS_BIG_ENDIAN 0 +#endif + #endif /* !defined(__BYTE_ORDER__) */ /** From 650674bb41f2147be7eeb1d25913e45aa0dc4b39 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 5 Dec 2023 12:16:48 +0000 Subject: [PATCH 48/88] Add MBEDTLS_BSWAPxx intrinsics for IAR Signed-off-by: Dave Rodgman --- library/alignment.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/library/alignment.h b/library/alignment.h index 634d610469..9e1e044ec6 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -180,6 +180,16 @@ inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x) #define MBEDTLS_BSWAP32 __rev #endif +/* Detect IAR built-in byteswap routine */ +#if defined(__IAR_SYSTEMS_ICC__) +#if defined(__ARM_ACLE) +#include +#define MBEDTLS_BSWAP16(x) ((uint16_t) __rev16((uint32_t) (x))) +#define MBEDTLS_BSWAP32 __rev +#define MBEDTLS_BSWAP64 __revll +#endif +#endif + /* * Where compiler built-ins are not present, fall back to C code that the * compiler may be able to detect and transform into the relevant bswap or From 69928dbe86cefd1640b2fa08f6f8d896bde255d3 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 14 Dec 2023 12:09:18 +0000 Subject: [PATCH 49/88] Fix compile warning from IAR Signed-off-by: Dave Rodgman --- library/ccm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ccm.c b/library/ccm.c index 6700dc743d..6b137d7bf9 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -91,7 +91,7 @@ int mbedtls_ccm_setkey(mbedtls_ccm_context *ctx, } #endif - return 0; + return ret; } /* From eb075c5de48e3c029e61e7509dad856cb311e34c Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 4 Oct 2023 18:38:14 +0100 Subject: [PATCH 50/88] Add cmake build type for tsan Building with clang ThreadSanitizer can now be done by setting the build type: cmake -D CMAKE_BUILD_TYPE:String=TSan . (ThreadSanitizer is available in clang 3.2 and gcc 4.8, README.md states that we test with clang 3.8 and gcc 5.4.) Signed-off-by: Janos Follath --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36baa3b402..3badb5f726 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,7 +117,7 @@ endif() # If this is the root project add longer list of available CMAKE_BUILD_TYPE values if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} - CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull" + CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull TSan" FORCE) endif() @@ -208,6 +208,7 @@ if(CMAKE_COMPILER_IS_GNU) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-overflow=2 -Wformat-truncation") endif() set(CMAKE_C_FLAGS_RELEASE "-O2") + set(CMAKE_C_FLAGS_TSAN "-fsanitize=thread -g3 -O2") set(CMAKE_C_FLAGS_DEBUG "-O0 -g3") set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage") set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3") @@ -219,6 +220,7 @@ endif(CMAKE_COMPILER_IS_GNU) if(CMAKE_COMPILER_IS_CLANG) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral") set(CMAKE_C_FLAGS_RELEASE "-O2") + set(CMAKE_C_FLAGS_TSAN "-fsanitize=thread -g3 -O2") set(CMAKE_C_FLAGS_DEBUG "-O0 -g3") set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage") set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3") From 9338cac0509a862e64135799472f0c24bf2efc79 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 4 Oct 2023 18:55:39 +0100 Subject: [PATCH 51/88] Add tsan to all.sh component_test_tsan now builds and tests the library with clang ThreadSanitizer enabled. There are no multi-threaded unit tests so far, the goal is that they are automatically tested with TSan when they are added. Signed-off-by: Janos Follath --- tests/scripts/all.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 40a8fe0bf4..05fc1a0d54 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -2159,6 +2159,18 @@ component_release_test_valgrind_constant_flow_psa () { make memcheck } +component_test_tsan () { + msg "build: TSan (clang)" + scripts/config.py set MBEDTLS_THREADING_C + scripts/config.py set MBEDTLS_THREADING_PTHREAD + + CC=clang cmake -D CMAKE_BUILD_TYPE:String=TSan . + make + + msg "test: main suites (TSan)" + make test +} + component_test_default_no_deprecated () { # Test that removing the deprecated features from the default # configuration leaves something consistent. From a16ee6b7d4789c501baf5955e492cc27189b2706 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 4 Oct 2023 19:05:26 +0100 Subject: [PATCH 52/88] Add multi-threaded unit test The unit test we add is designed to fail. The goal is to test the tests and show that they catch the problem. A later commit will fix the unit test and will make it pass. Signed-off-by: Janos Follath --- tests/suites/test_suite_ctr_drbg.data | 6 +++ tests/suites/test_suite_ctr_drbg.function | 64 +++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/tests/suites/test_suite_ctr_drbg.data b/tests/suites/test_suite_ctr_drbg.data index a72d8afa0d..70206e7d9a 100644 --- a/tests/suites/test_suite_ctr_drbg.data +++ b/tests/suites/test_suite_ctr_drbg.data @@ -1096,5 +1096,11 @@ ctr_drbg_seed_file:"no_such_dir/file":MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR CTR_DRBG Special Behaviours ctr_drbg_special_behaviours: +CTR_DRBG Threads: no reseed +ctr_drbg_threads:"1fafa98bc83d95e10f2d5ed339a553e1":10000 + +CTR_DRBG Threads: reseed +ctr_drbg_threads:"0d2dda60286dc738ddcc2dd3520bb988":25 + CTR_DRBG self test ctr_drbg_selftest: diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index 066e70b352..bdf3dca59a 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -90,6 +90,19 @@ exit: mbedtls_ctr_drbg_free(&ctx); } +static const int thread_random_reps = 10; +void *thread_random_function( void* ctx ) +{ + unsigned char out[16]; + memset(out, 0, sizeof(out)); + + for(int i = 0; i < thread_random_reps; i++) { + TEST_EQUAL(mbedtls_ctr_drbg_random_with_add((mbedtls_ctr_drbg_context*) ctx, out, sizeof(out), NULL, 0), 0); + } + +exit: + return NULL; +} /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -325,6 +338,57 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD */ +void ctr_drbg_threads(data_t *expected_result, int reseed_interval) +{ +#define THREAD_CNT 5 + pthread_t threads[THREAD_CNT]; + + unsigned char out[16]; + memset(out, 0, sizeof(out)); + + unsigned char entropy[1024]; + memset(entropy, 0, sizeof(entropy)); + + test_offset_idx = 0; + test_max_idx = sizeof(entropy); + + mbedtls_ctr_drbg_context ctx; + mbedtls_ctr_drbg_init(&ctx); + + mbedtls_ctr_drbg_set_reseed_interval(&ctx, reseed_interval); + + /* There are too many calls in this test to conveniently provide enough + * entropy for this to be on. Test cases can trigger reseeding by setting + * \p reseed_interval appropriately. */ + mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_OFF); + + TEST_EQUAL( + mbedtls_ctr_drbg_seed(&ctx, mbedtls_test_entropy_func, entropy, NULL, 0), + 0); + + for (size_t i = 0; i < THREAD_CNT; i++) { + TEST_EQUAL( + pthread_create(&threads[i], NULL, + thread_random_function, (void*) &ctx), + 0); + } + + for (size_t i = 0; i < THREAD_CNT; i++) { + TEST_EQUAL(pthread_join(threads[i], NULL), 0); + } + + /* Take a last output for comparing and thus verifying the DRBG state */ + TEST_EQUAL(mbedtls_ctr_drbg_random(&ctx, out, sizeof(out)), 0); + + TEST_MEMORY_COMPARE(out, sizeof(out), expected_result->x, expected_result->len); + +exit: + mbedtls_ctr_drbg_free(&ctx); +} +#undef THREAD_CNT +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_FS_IO */ void ctr_drbg_seed_file(char *path, int ret) { From 178bf3ee8acdb40a10dbd149ee301cd87679b056 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 4 Oct 2023 19:08:23 +0100 Subject: [PATCH 53/88] Fix failing multi-threaded unit test Signed-off-by: Janos Follath --- tests/suites/test_suite_ctr_drbg.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index bdf3dca59a..0f1237c7e0 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -97,7 +97,7 @@ void *thread_random_function( void* ctx ) memset(out, 0, sizeof(out)); for(int i = 0; i < thread_random_reps; i++) { - TEST_EQUAL(mbedtls_ctr_drbg_random_with_add((mbedtls_ctr_drbg_context*) ctx, out, sizeof(out), NULL, 0), 0); + TEST_EQUAL(mbedtls_ctr_drbg_random((mbedtls_ctr_drbg_context*) ctx, out, sizeof(out)), 0); } exit: From 20b2efa2930e801c61ef1e9390cea1e11aad0e84 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Tue, 21 Nov 2023 14:46:51 +0000 Subject: [PATCH 54/88] Fix missing include Signed-off-by: Paul Elliott --- tests/suites/test_suite_ctr_drbg.function | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index 0f1237c7e0..7123d146cb 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -3,6 +3,10 @@ #include "mbedtls/ctr_drbg.h" #include "string.h" +#if defined(MBEDTLS_THREADING_PTHREAD) +#include "mbedtls/threading.h" +#endif + /* Modes for ctr_drbg_validate */ enum reseed_mode { RESEED_NEVER, /* never reseed */ From bda25dd29c64d91b2df7a223f424b0bd3624e8af Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Tue, 21 Nov 2023 17:07:40 +0000 Subject: [PATCH 55/88] Add re-seeding option to test Signed-off-by: Paul Elliott --- tests/suites/test_suite_ctr_drbg.data | 4 +-- tests/suites/test_suite_ctr_drbg.function | 33 ++++++++++++++--------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/tests/suites/test_suite_ctr_drbg.data b/tests/suites/test_suite_ctr_drbg.data index 70206e7d9a..827d74a4aa 100644 --- a/tests/suites/test_suite_ctr_drbg.data +++ b/tests/suites/test_suite_ctr_drbg.data @@ -1097,10 +1097,10 @@ CTR_DRBG Special Behaviours ctr_drbg_special_behaviours: CTR_DRBG Threads: no reseed -ctr_drbg_threads:"1fafa98bc83d95e10f2d5ed339a553e1":10000 +ctr_drbg_threads:"1fafa98bc83d95e10f2d5ed339a553e1":0 CTR_DRBG Threads: reseed -ctr_drbg_threads:"0d2dda60286dc738ddcc2dd3520bb988":25 +ctr_drbg_threads:"B10A961F2EA39927B4C48AEDDD299026":1 CTR_DRBG self test ctr_drbg_selftest: diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index 7123d146cb..72cbf7bc99 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -343,29 +343,37 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD */ -void ctr_drbg_threads(data_t *expected_result, int reseed_interval) +void ctr_drbg_threads(data_t *expected_result, int reseed) { #define THREAD_CNT 5 pthread_t threads[THREAD_CNT]; unsigned char out[16]; + unsigned char *entropy = NULL; + + const size_t n_random_calls = THREAD_CNT * thread_random_reps + 1; + memset(out, 0, sizeof(out)); - unsigned char entropy[1024]; - memset(entropy, 0, sizeof(entropy)); - - test_offset_idx = 0; - test_max_idx = sizeof(entropy); - mbedtls_ctr_drbg_context ctx; mbedtls_ctr_drbg_init(&ctx); - mbedtls_ctr_drbg_set_reseed_interval(&ctx, reseed_interval); + test_offset_idx = 0; - /* There are too many calls in this test to conveniently provide enough - * entropy for this to be on. Test cases can trigger reseeding by setting - * \p reseed_interval appropriately. */ - mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_OFF); + if (reseed == 0) { + mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_OFF); + mbedtls_ctr_drbg_set_reseed_interval(&ctx, n_random_calls + 1); + + TEST_CALLOC(entropy, MBEDTLS_CTR_DRBG_ENTROPY_LEN); + test_max_idx = MBEDTLS_CTR_DRBG_ENTROPY_LEN; + } else { + const size_t entropy_size = (n_random_calls + 1) * MBEDTLS_CTR_DRBG_ENTROPY_LEN; + + mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_ON); + + TEST_CALLOC(entropy, entropy_size); + test_max_idx = entropy_size; + } TEST_EQUAL( mbedtls_ctr_drbg_seed(&ctx, mbedtls_test_entropy_func, entropy, NULL, 0), @@ -389,6 +397,7 @@ void ctr_drbg_threads(data_t *expected_result, int reseed_interval) exit: mbedtls_ctr_drbg_free(&ctx); + mbedtls_free(entropy); } #undef THREAD_CNT /* END_CASE */ From bbdfc8ad2c8a8479c161d0601f67a41c23c9256b Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Thu, 23 Nov 2023 14:07:43 +0000 Subject: [PATCH 56/88] Add TsanDbg, standardise Tsan with other sanitisers Signed-off-by: Paul Elliott --- CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3badb5f726..ad056466ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,7 +117,7 @@ endif() # If this is the root project add longer list of available CMAKE_BUILD_TYPE values if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} - CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull TSan" + CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull TSan TSanDbg" FORCE) endif() @@ -208,11 +208,12 @@ if(CMAKE_COMPILER_IS_GNU) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat-overflow=2 -Wformat-truncation") endif() set(CMAKE_C_FLAGS_RELEASE "-O2") - set(CMAKE_C_FLAGS_TSAN "-fsanitize=thread -g3 -O2") set(CMAKE_C_FLAGS_DEBUG "-O0 -g3") set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage") set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3") set(CMAKE_C_FLAGS_ASANDBG "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls") + set(CMAKE_C_FLAGS_TSAN "-fsanitize=thread -O3") + set(CMAKE_C_FLAGS_TSANDBG "-fsanitize=thread -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls") set(CMAKE_C_FLAGS_CHECK "-Os") set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual") endif(CMAKE_COMPILER_IS_GNU) @@ -220,13 +221,14 @@ endif(CMAKE_COMPILER_IS_GNU) if(CMAKE_COMPILER_IS_CLANG) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral") set(CMAKE_C_FLAGS_RELEASE "-O2") - set(CMAKE_C_FLAGS_TSAN "-fsanitize=thread -g3 -O2") set(CMAKE_C_FLAGS_DEBUG "-O0 -g3") set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage") set(CMAKE_C_FLAGS_ASAN "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3") set(CMAKE_C_FLAGS_ASANDBG "-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls") set(CMAKE_C_FLAGS_MEMSAN "-fsanitize=memory -O3") set(CMAKE_C_FLAGS_MEMSANDBG "-fsanitize=memory -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2") + set(CMAKE_C_FLAGS_TSAN "-fsanitize=thread -O3") + set(CMAKE_C_FLAGS_TSANDBG "-fsanitize=thread -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls") set(CMAKE_C_FLAGS_CHECK "-Os") endif(CMAKE_COMPILER_IS_CLANG) From 8860021abcc77872d6e016d3a27b014b4fe775d3 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Thu, 23 Nov 2023 14:24:30 +0000 Subject: [PATCH 57/88] Fix false claim of variables used unitialised GCC with TSan + O3 causes an error where it claims key_len and iv_len may be used uninitialised. This is, as far as I can tell incorrect (the only way it could not be set is in the error case, and then it is not used), however the simplest option seemed to be just to fix it. Signed-off-by: Paul Elliott --- library/ssl_tls13_keys.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index a6a2915d86..9b775ec954 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -1140,8 +1140,8 @@ static int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl, size_t hash_len; unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; size_t transcript_len; - size_t key_len; - size_t iv_len; + size_t key_len = 0; + size_t iv_len = 0; mbedtls_ssl_tls13_early_secrets tls13_early_secrets; mbedtls_ssl_handshake_params *handshake = ssl->handshake; @@ -1341,8 +1341,8 @@ static int ssl_tls13_generate_handshake_keys(mbedtls_ssl_context *ssl, size_t hash_len; unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; size_t transcript_len; - size_t key_len; - size_t iv_len; + size_t key_len = 0; + size_t iv_len = 0; mbedtls_ssl_handshake_params *handshake = ssl->handshake; const mbedtls_ssl_ciphersuite_t *ciphersuite_info = @@ -1592,7 +1592,7 @@ static int ssl_tls13_generate_application_keys( size_t hash_len; /* Variables relating to the cipher for the chosen ciphersuite. */ - size_t key_len, iv_len; + size_t key_len = 0, iv_len = 0; MBEDTLS_SSL_DEBUG_MSG(2, ("=> derive application traffic keys")); From 2667eda785009e075a12e4d291bff7e6fd08f54d Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Wed, 29 Nov 2023 15:53:00 +0000 Subject: [PATCH 58/88] Explicitly link tests with pthreads Required to use pthreads within tests. Signed-off-by: Paul Elliott --- tests/CMakeLists.txt | 3 +++ tests/Makefile | 1 + 2 files changed, 4 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0869aaa018..68bc57f5a5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,5 +1,8 @@ +find_package(Threads) + set(libs ${mbedtls_target} + ${CMAKE_THREAD_LIBS_INIT} ) # Set the project root directory if it's not already defined, as may happen if diff --git a/tests/Makefile b/tests/Makefile index 2249a55df6..bcc3b9307f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -57,6 +57,7 @@ else DLEXT ?= so EXEXT= SHARED_SUFFIX= +LOCAL_LDFLAGS += -lpthread endif ifdef WINDOWS From 6a997c9994694b7c338a8ad8ebc22489872239c3 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Thu, 30 Nov 2023 14:47:17 +0000 Subject: [PATCH 59/88] Fix code style Signed-off-by: Paul Elliott --- tests/suites/test_suite_ctr_drbg.function | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index 72cbf7bc99..5a77c1d433 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -95,13 +95,13 @@ exit: } static const int thread_random_reps = 10; -void *thread_random_function( void* ctx ) +void *thread_random_function(void *ctx) { unsigned char out[16]; memset(out, 0, sizeof(out)); - for(int i = 0; i < thread_random_reps; i++) { - TEST_EQUAL(mbedtls_ctr_drbg_random((mbedtls_ctr_drbg_context*) ctx, out, sizeof(out)), 0); + for (int i = 0; i < thread_random_reps; i++) { + TEST_EQUAL(mbedtls_ctr_drbg_random((mbedtls_ctr_drbg_context *) ctx, out, sizeof(out)), 0); } exit: @@ -382,7 +382,7 @@ void ctr_drbg_threads(data_t *expected_result, int reseed) for (size_t i = 0; i < THREAD_CNT; i++) { TEST_EQUAL( pthread_create(&threads[i], NULL, - thread_random_function, (void*) &ctx), + thread_random_function, (void *) &ctx), 0); } From 811c600d88108b6df02e86168666e9a931e643ba Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Thu, 30 Nov 2023 19:04:28 +0000 Subject: [PATCH 60/88] Guard tests correctly All guarded options change output, thus failing the test. Signed-off-by: Paul Elliott --- tests/suites/test_suite_ctr_drbg.data | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/suites/test_suite_ctr_drbg.data b/tests/suites/test_suite_ctr_drbg.data index 827d74a4aa..1cc51e302f 100644 --- a/tests/suites/test_suite_ctr_drbg.data +++ b/tests/suites/test_suite_ctr_drbg.data @@ -1097,9 +1097,11 @@ CTR_DRBG Special Behaviours ctr_drbg_special_behaviours: CTR_DRBG Threads: no reseed +depends_on:!MBEDTLS_CTR_DRBG_USE_128_BIT_KEY:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_ENTROPY_FORCE_SHA256:MBEDTLS_SHA512_C ctr_drbg_threads:"1fafa98bc83d95e10f2d5ed339a553e1":0 CTR_DRBG Threads: reseed +depends_on:!MBEDTLS_CTR_DRBG_USE_128_BIT_KEY:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_ENTROPY_FORCE_SHA256:MBEDTLS_SHA512_C ctr_drbg_threads:"B10A961F2EA39927B4C48AEDDD299026":1 CTR_DRBG self test From fed410f58e4370cbd6025d959ac6084fe5864d73 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Thu, 30 Nov 2023 20:40:55 +0000 Subject: [PATCH 61/88] Increase entropy buffer sizes Signed-off-by: Paul Elliott --- tests/suites/test_suite_ctr_drbg.function | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index 5a77c1d433..329c222cf9 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -364,10 +364,11 @@ void ctr_drbg_threads(data_t *expected_result, int reseed) mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_OFF); mbedtls_ctr_drbg_set_reseed_interval(&ctx, n_random_calls + 1); - TEST_CALLOC(entropy, MBEDTLS_CTR_DRBG_ENTROPY_LEN); - test_max_idx = MBEDTLS_CTR_DRBG_ENTROPY_LEN; + TEST_CALLOC(entropy, MBEDTLS_CTR_DRBG_ENTROPY_LEN + MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN); + test_max_idx = MBEDTLS_CTR_DRBG_ENTROPY_LEN + MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN; } else { - const size_t entropy_size = (n_random_calls + 1) * MBEDTLS_CTR_DRBG_ENTROPY_LEN; + const size_t entropy_size = ((n_random_calls + 1) * MBEDTLS_CTR_DRBG_ENTROPY_LEN) + + MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN; mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_ON); From bb0e48f94f456e099ae58848537c22c87438ea9f Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 1 Dec 2023 18:05:19 +0000 Subject: [PATCH 62/88] Make number of threads a test argument Remove hard coded number of threads. Signed-off-by: Paul Elliott --- tests/suites/test_suite_ctr_drbg.data | 4 ++-- tests/suites/test_suite_ctr_drbg.function | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/suites/test_suite_ctr_drbg.data b/tests/suites/test_suite_ctr_drbg.data index 1cc51e302f..b519da8951 100644 --- a/tests/suites/test_suite_ctr_drbg.data +++ b/tests/suites/test_suite_ctr_drbg.data @@ -1098,11 +1098,11 @@ ctr_drbg_special_behaviours: CTR_DRBG Threads: no reseed depends_on:!MBEDTLS_CTR_DRBG_USE_128_BIT_KEY:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_ENTROPY_FORCE_SHA256:MBEDTLS_SHA512_C -ctr_drbg_threads:"1fafa98bc83d95e10f2d5ed339a553e1":0 +ctr_drbg_threads:"1fafa98bc83d95e10f2d5ed339a553e1":0:5 CTR_DRBG Threads: reseed depends_on:!MBEDTLS_CTR_DRBG_USE_128_BIT_KEY:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_ENTROPY_FORCE_SHA256:MBEDTLS_SHA512_C -ctr_drbg_threads:"B10A961F2EA39927B4C48AEDDD299026":1 +ctr_drbg_threads:"B10A961F2EA39927B4C48AEDDD299026":1:5 CTR_DRBG self test ctr_drbg_selftest: diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index 329c222cf9..a5a85a0eba 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -343,16 +343,17 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD */ -void ctr_drbg_threads(data_t *expected_result, int reseed) +void ctr_drbg_threads(data_t *expected_result, int reseed, int arg_thread_count) { -#define THREAD_CNT 5 - pthread_t threads[THREAD_CNT]; + size_t thread_count = (size_t) arg_thread_count; + pthread_t *threads = NULL; unsigned char out[16]; unsigned char *entropy = NULL; - const size_t n_random_calls = THREAD_CNT * thread_random_reps + 1; + const size_t n_random_calls = thread_count * thread_random_reps + 1; + TEST_CALLOC(threads, sizeof(pthread_t) * thread_count); memset(out, 0, sizeof(out)); mbedtls_ctr_drbg_context ctx; @@ -380,14 +381,14 @@ void ctr_drbg_threads(data_t *expected_result, int reseed) mbedtls_ctr_drbg_seed(&ctx, mbedtls_test_entropy_func, entropy, NULL, 0), 0); - for (size_t i = 0; i < THREAD_CNT; i++) { + for (size_t i = 0; i < thread_count; i++) { TEST_EQUAL( pthread_create(&threads[i], NULL, thread_random_function, (void *) &ctx), 0); } - for (size_t i = 0; i < THREAD_CNT; i++) { + for (size_t i = 0; i < thread_count; i++) { TEST_EQUAL(pthread_join(threads[i], NULL), 0); } @@ -399,8 +400,8 @@ void ctr_drbg_threads(data_t *expected_result, int reseed) exit: mbedtls_ctr_drbg_free(&ctx); mbedtls_free(entropy); + mbedtls_free(threads); } -#undef THREAD_CNT /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_FS_IO */ From 356597f077c32d7206e252ecd93780a4c61e931e Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 1 Dec 2023 18:09:41 +0000 Subject: [PATCH 63/88] Make TSan test run operate on full config Signed-off-by: Paul Elliott --- tests/scripts/all.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 05fc1a0d54..315c6e5cd7 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -2161,6 +2161,7 @@ component_release_test_valgrind_constant_flow_psa () { component_test_tsan () { msg "build: TSan (clang)" + scripts/config.py full scripts/config.py set MBEDTLS_THREADING_C scripts/config.py set MBEDTLS_THREADING_PTHREAD From 80fa88e2fab1850e2b5eb38eb8bc2759a7606269 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Fri, 24 Nov 2023 17:12:24 +0000 Subject: [PATCH 64/88] Remove warning with GCC 12 and TSan Compiler is unhappy that the return from mbedtls_cipher_get_name() could be NULL as this is used in a printf statement. Signed-off-by: Paul Elliott --- programs/aes/crypt_and_hash.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c index 226718bc63..f15b85e2c0 100644 --- a/programs/aes/crypt_and_hash.c +++ b/programs/aes/crypt_and_hash.c @@ -103,7 +103,14 @@ int main(int argc, char *argv[]) list = mbedtls_cipher_list(); while (*list) { cipher_info = mbedtls_cipher_info_from_type(*list); - mbedtls_printf(" %s\n", mbedtls_cipher_info_get_name(cipher_info)); + if (cipher_info) { + const char *name = mbedtls_cipher_info_get_name(cipher_info); + + if (name) { + mbedtls_printf(" %s\n", mbedtls_cipher_info_get_name(cipher_info)); + } + } + list++; } From be978a8c4fc52965b486125f2993251025b1a399 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Thu, 7 Dec 2023 11:46:04 +0000 Subject: [PATCH 65/88] Add option to pass make variables to depends.py Signed-off-by: Paul Elliott --- tests/scripts/depends.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/scripts/depends.py b/tests/scripts/depends.py index 38c184a6ae..5fe26f158b 100755 --- a/tests/scripts/depends.py +++ b/tests/scripts/depends.py @@ -381,7 +381,7 @@ class DomainData: def __init__(self, options, conf): """Gather data about the library and establish a list of domains to test.""" - build_command = [options.make_command, 'CFLAGS=-Werror'] + build_command = [options.make_command] + options.make_vars.split(' ') + ['CFLAGS=-Werror'] build_and_test = [build_command, [options.make_command, 'test']] self.all_config_symbols = set(conf.settings.keys()) # Find hash modules by name. @@ -526,6 +526,9 @@ def main(): parser.add_argument('--make-command', metavar='CMD', help='Command to run instead of make (e.g. gmake)', action='store', default='make') + parser.add_argument('--make-vars', + help='optional variable/value pairs to pass to make', + action='store', default='') parser.add_argument('--unset-use-psa', help='Unset MBEDTLS_USE_PSA_CRYPTO before any test', action='store_true', dest='unset_use_psa') From 6587959a32f978aeb02766c27cf30b04d8a245e1 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Thu, 7 Dec 2023 20:08:10 +0000 Subject: [PATCH 66/88] Add ability to pass make variables to psa_collect_statuses.py Signed-off-by: Paul Elliott --- tests/scripts/psa_collect_statuses.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/scripts/psa_collect_statuses.py b/tests/scripts/psa_collect_statuses.py index 11bbebcc1f..6291d7898e 100755 --- a/tests/scripts/psa_collect_statuses.py +++ b/tests/scripts/psa_collect_statuses.py @@ -82,10 +82,15 @@ def collect_status_logs(options): cwd='tests', stdout=sys.stderr) with open(os.devnull, 'w') as devnull: - make_q_ret = subprocess.call(['make', '-q', 'lib', 'tests'], - stdout=devnull, stderr=devnull) + build_command = ['make', '-q'] + options.make_vars.split(' ') + \ + ['lib', 'tests'] + make_q_ret = subprocess.call(build_command, stdout=devnull, + stderr=devnull) + print("blagh") if make_q_ret != 0: - subprocess.check_call(['make', 'RECORD_PSA_STATUS_COVERAGE_LOG=1'], + build_command = ['make'] + options.make_vars.split(' ') + \ + ['RECORD_PSA_STATUS_COVERAGE_LOG=1'] + subprocess.check_call(build_command, stdout=sys.stderr) rebuilt = True subprocess.check_call(['make', 'test'], @@ -112,6 +117,9 @@ def main(): help='Log file location (default: {})'.format( DEFAULT_STATUS_LOG_FILE )) + parser.add_argument('--make-vars', + help='optional variable/value pairs to pass to make', + action='store', default='') parser.add_argument('--psa-constant-names', metavar='PROGRAM', default=DEFAULT_PSA_CONSTANT_NAMES, help='Path to psa_constant_names (default: {})'.format( From 20a95bc09a540918da70d4e96d8a615cea934692 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Wed, 6 Dec 2023 19:24:49 +0000 Subject: [PATCH 67/88] Remove explicit linking of PThread in make This would break platforms that do not have pthread. Put the linking instead behind a define and add this define where required to all.sh. Signed-off-by: Paul Elliott --- tests/Makefile | 3 + tests/scripts/all.sh | 169 ++++++++++++++++++++++--------------------- 2 files changed, 89 insertions(+), 83 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index bcc3b9307f..72429a6429 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -57,8 +57,11 @@ else DLEXT ?= so EXEXT= SHARED_SUFFIX= + +ifdef PTHREAD LOCAL_LDFLAGS += -lpthread endif +endif ifdef WINDOWS PYTHON ?= python diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 315c6e5cd7..65203e8771 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -216,6 +216,9 @@ pre_initialize_variables () { esac SUPPORTED_COMPONENTS="$SUPPORTED_COMPONENTS $component" done + + # Option to enable linking with pthreads under make + MAKE_THREADING_FLAGS="PTHREAD=1" } # Test whether the component $1 is included in the command line patterns. @@ -930,7 +933,7 @@ helper_get_psa_key_type_list() { # Here "things" are PSA_WANT_ symbols but with PSA_WANT_ removed. helper_libtestdriver1_make_drivers() { loc_accel_flags=$( echo "$1 ${2-}" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' ) - make CC=$ASAN_CC -C tests libtestdriver1.a CFLAGS=" $ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC -C tests libtestdriver1.a CFLAGS=" $ASAN_CFLAGS $loc_accel_flags" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # Build the main libraries, programs and tests, @@ -948,7 +951,7 @@ helper_libtestdriver1_make_main() { # we need flags both with and without the LIBTESTDRIVER1_ prefix loc_accel_flags=$( echo "$loc_accel_list" | sed 's/[^ ]* */-DLIBTESTDRIVER1_MBEDTLS_PSA_ACCEL_&/g' ) loc_accel_flags="$loc_accel_flags $( echo "$loc_accel_list" | sed 's/[^ ]* */-DMBEDTLS_PSA_ACCEL_&/g' )" - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -I../tests/include -I../tests -I../../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS" "$@" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -I../tests/include -I../tests -I../../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS" $MAKE_THREADING_FLAGS "$@" } ################################################################ @@ -1443,7 +1446,7 @@ component_test_psa_external_rng_no_drbg_classic () { # When MBEDTLS_USE_PSA_CRYPTO is disabled and there is no DRBG, # the SSL test programs don't have an RNG and can't work. Explicitly # make them use the PSA RNG with -DMBEDTLS_TEST_USE_PSA_CRYPTO_RNG. - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DMBEDTLS_TEST_USE_PSA_CRYPTO_RNG" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DMBEDTLS_TEST_USE_PSA_CRYPTO_RNG" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, classic crypto - main suites" make test @@ -1462,7 +1465,7 @@ component_test_psa_external_rng_no_drbg_use_psa () { scripts/config.py unset MBEDTLS_CTR_DRBG_C scripts/config.py unset MBEDTLS_HMAC_DRBG_C scripts/config.py unset MBEDTLS_ECDSA_DETERMINISTIC # requires HMAC_DRBG - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG, PSA crypto - main suites" make test @@ -1477,7 +1480,7 @@ component_test_psa_external_rng_use_psa_crypto () { scripts/config.py set MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG scripts/config.py set MBEDTLS_USE_PSA_CRYPTO scripts/config.py unset MBEDTLS_CTR_DRBG_C - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS msg "test: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG" make test @@ -1495,7 +1498,7 @@ component_test_psa_inject_entropy () { scripts/config.py unset MBEDTLS_PLATFORM_NV_SEED_ALT scripts/config.py unset MBEDTLS_PLATFORM_STD_NV_SEED_READ scripts/config.py unset MBEDTLS_PLATFORM_STD_NV_SEED_WRITE - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS '-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS '-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS msg "test: full + MBEDTLS_PSA_INJECT_ENTROPY" make test @@ -1529,14 +1532,14 @@ component_test_crypto_full_md_light_only () { # Note: MD-light is auto-enabled in build_info.h by modules that need it, # which we haven't disabled, so no need to explicitly enable it. - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS # Make sure we don't have the HMAC functions, but the hashing functions not grep mbedtls_md_hmac library/md.o grep mbedtls_md library/md.o msg "test: crypto_full with only the light subset of MD" - make test + make $MAKE_THREADING_FLAGS test } component_test_full_no_cipher () { @@ -1562,7 +1565,7 @@ component_test_full_no_cipher () { scripts/config.py unset MBEDTLS_LMS_PRIVATE msg "test: full no CIPHER no PSA_CRYPTO_C" - make test + make $MAKE_THREADING_FLAGS test } # This is a common configurator and test function that is used in: @@ -1611,7 +1614,7 @@ common_test_full_no_cipher_with_psa_crypto () { scripts/config.py unset MBEDTLS_PKCS12_C scripts/config.py unset MBEDTLS_PKCS5_C - make + make $MAKE_THREADING_FLAGS # Ensure that CIPHER_C was not re-enabled not grep mbedtls_cipher_init library/cipher.o @@ -1644,7 +1647,7 @@ component_test_full_no_ccm() { # PSA_WANT_ALG_CCM to be re-enabled. scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CCM - make + make $MAKE_THREADING_FLAGS msg "test: full no PSA_WANT_ALG_CCM" make test @@ -1672,7 +1675,7 @@ component_test_full_no_ccm_star_no_tag() { scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_NO_PADDING scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CBC_PKCS7 - make + make $MAKE_THREADING_FLAGS # Ensure MBEDTLS_PSA_BUILTIN_CIPHER was not enabled not grep mbedtls_psa_cipher library/psa_crypto_cipher.o @@ -1729,7 +1732,7 @@ component_test_full_no_bignum () { scripts/config.py unset MBEDTLS_SSL_ASYNC_PRIVATE scripts/config.py unset MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK - make + make $MAKE_THREADING_FLAGS msg "test: full minus bignum" make test @@ -2007,7 +2010,7 @@ component_test_small_mbedtls_ssl_dtls_max_buffering () { component_test_psa_collect_statuses () { msg "build+test: psa_collect_statuses" # ~30s scripts/config.py full - tests/scripts/psa_collect_statuses.py + tests/scripts/psa_collect_statuses.py --make-vars="$MAKE_THREADING_FLAGS" # Check that psa_crypto_init() succeeded at least once grep -q '^0:psa_crypto_init:' tests/statuses.log rm -f tests/statuses.log @@ -2186,7 +2189,7 @@ component_test_default_no_deprecated () { component_test_full_no_deprecated () { msg "build: make, full_no_deprecated config" # ~ 30s scripts/config.py full_no_deprecated - make CC=gcc CFLAGS='-O -Werror -Wall -Wextra' + make CC=gcc CFLAGS='-O -Werror -Wall -Wextra' $MAKE_THREADING_FLAGS msg "test: make, full_no_deprecated config" # ~ 5s make test @@ -2203,7 +2206,7 @@ component_test_full_no_deprecated_deprecated_warning () { scripts/config.py full_no_deprecated scripts/config.py unset MBEDTLS_DEPRECATED_REMOVED scripts/config.py set MBEDTLS_DEPRECATED_WARNING - make CC=gcc CFLAGS='-O -Werror -Wall -Wextra' + make CC=gcc CFLAGS='-O -Werror -Wall -Wextra' $MAKE_THREADING_FLAGS msg "test: make, full_no_deprecated config, MBEDTLS_DEPRECATED_WARNING" # ~ 5s make test @@ -2223,7 +2226,7 @@ component_test_full_deprecated_warning () { # By default those are disabled when MBEDTLS_DEPRECATED_WARNING is set. # Expect warnings from '#warning' directives in check_config.h and # from the use of deprecated functions in test suites. - make CC=gcc CFLAGS='-O -Werror -Wall -Wextra -Wno-error=deprecated-declarations -Wno-error=cpp -DMBEDTLS_TEST_DEPRECATED' tests + make CC=gcc CFLAGS='-O -Werror -Wall -Wextra -Wno-error=deprecated-declarations -Wno-error=cpp -DMBEDTLS_TEST_DEPRECATED' $MAKE_THREADING_FLAGS tests msg "test: full config + MBEDTLS_TEST_DEPRECATED" # ~ 30s make test @@ -2248,7 +2251,7 @@ component_build_crypto_default () { component_build_crypto_full () { msg "build: make, crypto only, full config" scripts/config.py crypto_full - make CFLAGS='-O1 -Werror' + make CFLAGS='-O1 -Werror' $MAKE_THREADING_FLAGS are_empty_libraries library/libmbedx509.* library/libmbedtls.* } @@ -2308,73 +2311,73 @@ support_build_baremetal () { # depends.py family of tests component_test_depends_py_cipher_id () { msg "test/build: depends.py cipher_id (gcc)" - tests/scripts/depends.py cipher_id --unset-use-psa + tests/scripts/depends.py cipher_id --unset-use-psa --make-vars="$MAKE_THREADING_FLAGS" } component_test_depends_py_cipher_chaining () { msg "test/build: depends.py cipher_chaining (gcc)" - tests/scripts/depends.py cipher_chaining --unset-use-psa + tests/scripts/depends.py cipher_chaining --unset-use-psa --make-vars="$MAKE_THREADING_FLAGS" } component_test_depends_py_cipher_padding () { msg "test/build: depends.py cipher_padding (gcc)" - tests/scripts/depends.py cipher_padding --unset-use-psa + tests/scripts/depends.py cipher_padding --unset-use-psa --make-vars="$MAKE_THREADING_FLAGS" } component_test_depends_py_curves () { msg "test/build: depends.py curves (gcc)" - tests/scripts/depends.py curves --unset-use-psa + tests/scripts/depends.py curves --unset-use-psa --make-vars="$MAKE_THREADING_FLAGS" } component_test_depends_py_hashes () { msg "test/build: depends.py hashes (gcc)" - tests/scripts/depends.py hashes --unset-use-psa + tests/scripts/depends.py hashes --unset-use-psa --make-vars="$MAKE_THREADING_FLAGS" } component_test_depends_py_kex () { msg "test/build: depends.py kex (gcc)" - tests/scripts/depends.py kex --unset-use-psa + tests/scripts/depends.py kex --unset-use-psa --make-vars="$MAKE_THREADING_FLAGS" } component_test_depends_py_pkalgs () { msg "test/build: depends.py pkalgs (gcc)" - tests/scripts/depends.py pkalgs --unset-use-psa + tests/scripts/depends.py pkalgs --unset-use-psa --make-vars="$MAKE_THREADING_FLAGS" } # PSA equivalents of the depends.py tests component_test_depends_py_cipher_id_psa () { msg "test/build: depends.py cipher_id (gcc) with MBEDTLS_USE_PSA_CRYPTO defined" - tests/scripts/depends.py cipher_id + tests/scripts/depends.py cipher_id --make-vars="$MAKE_THREADING_FLAGS" } component_test_depends_py_cipher_chaining_psa () { msg "test/build: depends.py cipher_chaining (gcc) with MBEDTLS_USE_PSA_CRYPTO defined" - tests/scripts/depends.py cipher_chaining + tests/scripts/depends.py cipher_chaining --make-vars="$MAKE_THREADING_FLAGS" } component_test_depends_py_cipher_padding_psa () { msg "test/build: depends.py cipher_padding (gcc) with MBEDTLS_USE_PSA_CRYPTO defined" - tests/scripts/depends.py cipher_padding + tests/scripts/depends.py cipher_padding --make-vars="$MAKE_THREADING_FLAGS" } component_test_depends_py_curves_psa () { msg "test/build: depends.py curves (gcc) with MBEDTLS_USE_PSA_CRYPTO defined" - tests/scripts/depends.py curves + tests/scripts/depends.py curves --make-vars="$MAKE_THREADING_FLAGS" } component_test_depends_py_hashes_psa () { msg "test/build: depends.py hashes (gcc) with MBEDTLS_USE_PSA_CRYPTO defined" - tests/scripts/depends.py hashes + tests/scripts/depends.py hashes --make-vars="$MAKE_THREADING_FLAGS" } component_test_depends_py_kex_psa () { msg "test/build: depends.py kex (gcc) with MBEDTLS_USE_PSA_CRYPTO defined" - tests/scripts/depends.py kex + tests/scripts/depends.py kex --make-vars="$MAKE_THREADING_FLAGS" } component_test_depends_py_pkalgs_psa () { msg "test/build: depends.py pkalgs (gcc) with MBEDTLS_USE_PSA_CRYPTO defined" - tests/scripts/depends.py pkalgs + tests/scripts/depends.py pkalgs --make-vars="$MAKE_THREADING_FLAGS" } component_build_no_pk_rsa_alt_support () { @@ -2386,7 +2389,7 @@ component_build_no_pk_rsa_alt_support () { scripts/config.py set MBEDTLS_X509_CRT_WRITE_C # Only compile - this is primarily to test for compile issues - make CC=gcc CFLAGS='-Werror -Wall -Wextra -I../tests/include/alt-dummy' + make CC=gcc CFLAGS='-Werror -Wall -Wextra -I../tests/include/alt-dummy' $MAKE_THREADING_FLAGS } component_build_module_alt () { @@ -2600,7 +2603,7 @@ component_test_psa_crypto_config_reference_ffdh () { # Disable things that are not supported scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - make + make $MAKE_THREADING_FLAGS msg "test suites: full with non-accelerated FFDH alg" make test @@ -2639,7 +2642,7 @@ component_test_psa_crypto_config_accel_pake() { # ------------- msg "test: full with accelerated PAKE" - make test + make $MAKE_THREADING_FLAGS test } component_test_psa_crypto_config_accel_ecc_some_key_types () { @@ -2699,7 +2702,7 @@ component_test_psa_crypto_config_accel_ecc_some_key_types () { # ------------- msg "test suites: full with accelerated EC algs and some key types" - make test + make $MAKE_THREADING_FLAGS test } # Run tests with only (non-)Weierstrass accelerated @@ -2898,7 +2901,7 @@ component_test_psa_crypto_config_accel_ecc_ecp_light_only () { # ------------- msg "test suites: full with accelerated EC algs" - make test + make $MAKE_THREADING_FLAGS test msg "ssl-opt: full with accelerated EC algs" tests/ssl-opt.sh @@ -2910,7 +2913,7 @@ component_test_psa_crypto_config_reference_ecc_ecp_light_only () { config_psa_crypto_config_ecp_light_only 0 - make + make $MAKE_THREADING_FLAGS msg "test suites: full with non-accelerated EC algs" make test @@ -3003,7 +3006,7 @@ component_test_psa_crypto_config_accel_ecc_no_ecp_at_all () { # ------------- msg "test: full + accelerated EC algs - ECP" - make test + make $MAKE_THREADING_FLAGS test msg "ssl-opt: full + accelerated EC algs - ECP" tests/ssl-opt.sh @@ -3017,7 +3020,7 @@ component_test_psa_crypto_config_reference_ecc_no_ecp_at_all () { config_psa_crypto_no_ecp_at_all 0 - make + make $MAKE_THREADING_FLAGS msg "test: full + non accelerated EC algs" make test @@ -3180,7 +3183,7 @@ common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum () { msg "test suites: full + accelerated $accel_text algs + USE_PSA - $removed_text - DHM - BIGNUM" - make test + make $MAKE_THREADING_FLAGS test msg "ssl-opt: full + accelerated $accel_text algs + USE_PSA - $removed_text - BIGNUM" tests/ssl-opt.sh @@ -3211,7 +3214,7 @@ common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum () { config_psa_crypto_config_accel_ecc_ffdh_no_bignum 0 "$test_target" - make + make $MAKE_THREADING_FLAGS msg "test suites: full + non accelerated EC algs + USE_PSA" make test @@ -3330,7 +3333,7 @@ build_full_minus_something_and_test_tls () { scripts/config.py unset $sym done - make + make $MAKE_THREADING_FLAGS msg "test: full minus something, test TLS" ( cd tests; ./test_suite_ssl ) @@ -3369,7 +3372,7 @@ build_and_test_psa_want_key_pair_partial() { # crypto_config.h so we just disable the one we don't want. scripts/config.py -f "$CRYPTO_CONFIG_H" unset "$disabled_psa_want" - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS msg "test: full - MBEDTLS_USE_PSA_CRYPTO - ${disabled_psa_want}" make test @@ -3435,7 +3438,7 @@ component_test_psa_crypto_config_accel_rsa_crypto () { # ------------- msg "test: crypto_full with accelerated RSA" - make test + make $MAKE_THREADING_FLAGS test } component_test_psa_crypto_config_reference_rsa_crypto () { @@ -3447,7 +3450,7 @@ component_test_psa_crypto_config_reference_rsa_crypto () { # Build # ----- - make + make $MAKE_THREADING_FLAGS # Run the tests # ------------- @@ -3649,7 +3652,7 @@ component_test_psa_crypto_config_reference_hash_use_psa() { config_psa_crypto_hash_use_psa 0 - make + make $MAKE_THREADING_FLAGS msg "test: full without accelerated hashes" make test @@ -3814,7 +3817,7 @@ component_test_psa_crypto_config_accel_cipher_aead () { # ------------- msg "test: full config with accelerated cipher and AEAD" - make test + make $MAKE_THREADING_FLAGS test msg "ssl-opt: full config with accelerated cipher and AEAD" tests/ssl-opt.sh @@ -3827,7 +3830,7 @@ component_test_psa_crypto_config_reference_cipher_aead () { msg "build: full config with non-accelerated cipher and AEAD" common_psa_crypto_config_accel_cipher_aead - make + make $MAKE_THREADING_FLAGS msg "test: full config with non-accelerated cipher and AEAD" make test @@ -3844,7 +3847,7 @@ component_test_aead_chachapoly_disabled() { scripts/config.py full scripts/config.py unset MBEDTLS_CHACHAPOLY_C scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CHACHA20_POLY1305 - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS msg "test: full minus CHACHAPOLY" make test @@ -3857,7 +3860,7 @@ component_test_aead_only_ccm() { scripts/config.py unset MBEDTLS_GCM_C scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_CHACHA20_POLY1305 scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_GCM - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS msg "test: full minus CHACHAPOLY and GCM" make test @@ -3888,7 +3891,7 @@ component_build_psa_accel_alg_ecdh() { scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_ECDH -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_ECDH -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator HMAC code is in place and ready to test. @@ -3898,7 +3901,7 @@ component_build_psa_accel_alg_hmac() { scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_HMAC -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_HMAC -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator HKDF code is in place and ready to test. @@ -3911,7 +3914,7 @@ component_build_psa_accel_alg_hkdf() { # Make sure to unset TLS1_3 since it requires HKDF_C and will not build properly without it. scripts/config.py unset MBEDTLS_SSL_PROTO_TLS1_3 # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_HKDF -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_HKDF -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator MD5 code is in place and ready to test. @@ -3930,7 +3933,7 @@ component_build_psa_accel_alg_md5() { scripts/config.py unset MBEDTLS_LMS_C scripts/config.py unset MBEDTLS_LMS_PRIVATE # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_MD5 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_MD5 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator RIPEMD160 code is in place and ready to test. @@ -3949,7 +3952,7 @@ component_build_psa_accel_alg_ripemd160() { scripts/config.py unset MBEDTLS_LMS_C scripts/config.py unset MBEDTLS_LMS_PRIVATE # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator SHA1 code is in place and ready to test. @@ -3968,7 +3971,7 @@ component_build_psa_accel_alg_sha1() { scripts/config.py unset MBEDTLS_LMS_C scripts/config.py unset MBEDTLS_LMS_PRIVATE # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_1 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_1 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator SHA224 code is in place and ready to test. @@ -3984,7 +3987,7 @@ component_build_psa_accel_alg_sha224() { scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_512 scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_224 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_224 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator SHA256 code is in place and ready to test. @@ -4000,7 +4003,7 @@ component_build_psa_accel_alg_sha256() { scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_384 scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_SHA_512 # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_256 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_256 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator SHA384 code is in place and ready to test. @@ -4018,7 +4021,7 @@ component_build_psa_accel_alg_sha384() { scripts/config.py unset MBEDTLS_LMS_C scripts/config.py unset MBEDTLS_LMS_PRIVATE # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_384 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_384 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator SHA512 code is in place and ready to test. @@ -4037,7 +4040,7 @@ component_build_psa_accel_alg_sha512() { scripts/config.py unset MBEDTLS_LMS_C scripts/config.py unset MBEDTLS_LMS_PRIVATE # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_512 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_SHA_512 -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator RSA code is in place and ready to test. @@ -4051,7 +4054,7 @@ component_build_psa_accel_alg_rsa_pkcs1v15_crypt() { scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_OAEP scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PSS # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator RSA code is in place and ready to test. @@ -4065,7 +4068,7 @@ component_build_psa_accel_alg_rsa_pkcs1v15_sign() { scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_OAEP scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PSS # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator RSA code is in place and ready to test. @@ -4079,7 +4082,7 @@ component_build_psa_accel_alg_rsa_oaep() { scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_SIGN scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PSS # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_OAEP -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_OAEP -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator RSA code is in place and ready to test. @@ -4093,7 +4096,7 @@ component_build_psa_accel_alg_rsa_pss() { scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_PKCS1V15_SIGN scripts/config.py -f "$CRYPTO_CONFIG_H" unset PSA_WANT_ALG_RSA_OAEP # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator RSA code is in place and ready to test. @@ -4108,7 +4111,7 @@ component_build_psa_accel_key_type_rsa_key_pair() { scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1 scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1 # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } # This should be renamed to test and updated once the accelerator RSA code is in place and ready to test. @@ -4120,7 +4123,7 @@ component_build_psa_accel_key_type_rsa_public_key() { scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_ALG_RSA_PSS 1 scripts/config.py -f "$CRYPTO_CONFIG_H" set PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1 # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY -I../tests/include" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY -I../tests/include" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS } @@ -4289,7 +4292,7 @@ component_test_no_platform () { # Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19, # to re-enable platform integration features otherwise disabled in C99 builds make CC=gcc CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -Os -D_DEFAULT_SOURCE' lib programs - make CC=gcc CFLAGS='-Werror -Wall -Wextra -Os' test + make CC=gcc CFLAGS='-Werror -Wall -Wextra -Os' $MAKE_THREADING_FLAGS test } component_build_no_std_function () { @@ -4307,14 +4310,14 @@ component_build_no_ssl_srv () { msg "build: full config except SSL server, make, gcc" # ~ 30s scripts/config.py full scripts/config.py unset MBEDTLS_SSL_SRV_C - make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1' + make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1' $MAKE_THREADING_FLAGS } component_build_no_ssl_cli () { msg "build: full config except SSL client, make, gcc" # ~ 30s scripts/config.py full scripts/config.py unset MBEDTLS_SSL_CLI_C - make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1' + make CC=gcc CFLAGS='-Werror -Wall -Wextra -O1' $MAKE_THREADING_FLAGS } component_build_no_sockets () { @@ -4489,7 +4492,7 @@ component_test_platform_calloc_macro () { component_test_malloc_0_null () { msg "build: malloc(0) returns NULL (ASan+UBSan build)" scripts/config.py full - make CC=$ASAN_CC CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"$PWD/tests/configs/user-config-malloc-0-null.h\"' $ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"$PWD/tests/configs/user-config-malloc-0-null.h\"' $ASAN_CFLAGS" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS msg "test: malloc(0) returns NULL (ASan+UBSan build)" make test @@ -5101,7 +5104,7 @@ component_test_psa_crypto_drivers () { loc_cflags="${loc_cflags} '-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-for-test.h\"'" loc_cflags="${loc_cflags} -I../tests/include -O2" - make CC=$ASAN_CC CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS" + make CC=$ASAN_CC CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS" $MAKE_THREADING_FLAGS msg "test: full + test drivers dispatching to builtins" make test @@ -5128,7 +5131,7 @@ test_build_opt () { $cc --version for opt in "$@"; do msg "build/test: $cc $opt, $info" # ~ 30s - make CC="$cc" CFLAGS="$opt -std=c99 -pedantic -Wall -Wextra -Werror" + make CC="$cc" CFLAGS="$opt -std=c99 -pedantic -Wall -Wextra -Werror" $MAKE_THREADING_FLAGS # We're confident enough in compilers to not run _all_ the tests, # but at least run the unit tests. In particular, runs with # optimizations use inline assembly whereas runs with -O0 @@ -5183,7 +5186,7 @@ component_build_mbedtls_config_file () { msg "build: make with MBEDTLS_CONFIG_FILE" # ~40s scripts/config.py -w full_config.h full echo '#error "MBEDTLS_CONFIG_FILE is not working"' >"$CONFIG_H" - make CFLAGS="-I '$PWD' -DMBEDTLS_CONFIG_FILE='\"full_config.h\"'" + make CFLAGS="-I '$PWD' -DMBEDTLS_CONFIG_FILE='\"full_config.h\"'" $MAKE_THREADING_FLAGS # Make sure this feature is enabled. We'll disable it in the next phase. programs/test/query_compile_time_config MBEDTLS_NIST_KW_C make clean @@ -5192,7 +5195,7 @@ component_build_mbedtls_config_file () { # In the user config, disable one feature (for simplicity, pick a feature # that nothing else depends on). echo '#undef MBEDTLS_NIST_KW_C' >user_config.h - make CFLAGS="-I '$PWD' -DMBEDTLS_CONFIG_FILE='\"full_config.h\"' -DMBEDTLS_USER_CONFIG_FILE='\"user_config.h\"'" + make CFLAGS="-I '$PWD' -DMBEDTLS_CONFIG_FILE='\"full_config.h\"' -DMBEDTLS_USER_CONFIG_FILE='\"user_config.h\"'" $MAKE_THREADING_FLAGS not programs/test/query_compile_time_config MBEDTLS_NIST_KW_C rm -f user_config.h full_config.h @@ -5251,7 +5254,7 @@ component_test_m32_no_asm () { scripts/config.py unset MBEDTLS_HAVE_ASM scripts/config.py unset MBEDTLS_PADLOCK_C scripts/config.py unset MBEDTLS_AESNI_C # AESNI for 32-bit is tested in test_aesni_m32 - make CC=gcc CFLAGS="$ASAN_CFLAGS -m32" LDFLAGS="-m32 $ASAN_CFLAGS" + make CC=gcc CFLAGS="$ASAN_CFLAGS -m32" LDFLAGS="-m32 $ASAN_CFLAGS" $MAKE_THREADING_FLAGS msg "test: i386, make, gcc, no asm (ASan build)" make test @@ -5269,7 +5272,7 @@ component_test_m32_o2 () { msg "build: i386, make, gcc -O2 (ASan build)" # ~ 30s scripts/config.py full scripts/config.py unset MBEDTLS_AESNI_C # AESNI for 32-bit is tested in test_aesni_m32 - make CC=gcc CFLAGS="$ASAN_CFLAGS -m32" LDFLAGS="-m32 $ASAN_CFLAGS" + make CC=gcc CFLAGS="$ASAN_CFLAGS -m32" LDFLAGS="-m32 $ASAN_CFLAGS" $MAKE_THREADING_FLAGS msg "test: i386, make, gcc -O2 (ASan build)" make test @@ -5304,7 +5307,7 @@ support_test_m32_everest () { component_test_mx32 () { msg "build: 64-bit ILP32, make, gcc" # ~ 30s scripts/config.py full - make CC=gcc CFLAGS='-Werror -Wall -Wextra -mx32' LDFLAGS='-mx32' + make CC=gcc CFLAGS='-Werror -Wall -Wextra -mx32' LDFLAGS='-mx32' $MAKE_THREADING_FLAGS msg "test: 64-bit ILP32, make, gcc" make test @@ -5368,7 +5371,7 @@ component_test_no_udbl_division () { msg "build: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s scripts/config.py full scripts/config.py set MBEDTLS_NO_UDBL_DIVISION - make CFLAGS='-Werror -O1' + make CFLAGS='-Werror -O1' $MAKE_THREADING_FLAGS msg "test: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s make test @@ -5378,7 +5381,7 @@ component_test_no_64bit_multiplication () { msg "build: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s scripts/config.py full scripts/config.py set MBEDTLS_NO_64BIT_MULTIPLICATION - make CFLAGS='-Werror -O1' + make CFLAGS='-Werror -O1' $MAKE_THREADING_FLAGS msg "test: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s make test @@ -5392,7 +5395,7 @@ component_test_no_strings () { scripts/config.py unset MBEDTLS_ERROR_C scripts/config.py set MBEDTLS_ERROR_STRERROR_DUMMY scripts/config.py unset MBEDTLS_VERSION_FEATURES - make CFLAGS='-Werror -Os' + make CFLAGS='-Werror -Os' $MAKE_THREADING_FLAGS msg "test: no strings" # ~ 10s make test @@ -5403,7 +5406,7 @@ component_test_no_x509_info () { scripts/config.pl full scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests scripts/config.pl set MBEDTLS_X509_REMOVE_INFO - make CFLAGS='-Werror -O2' + make CFLAGS='-Werror -O2' $MAKE_THREADING_FLAGS msg "test: full + MBEDTLS_X509_REMOVE_INFO" # ~ 10s make test @@ -6006,7 +6009,7 @@ component_build_zeroize_checks () { scripts/config.py full # Only compile - we're looking for sizeof-pointer-memaccess warnings - make CC=gcc CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-zeroize-memset.h\"' -DMBEDTLS_TEST_DEFINES_ZEROIZE -Werror -Wsizeof-pointer-memaccess" + make CC=gcc CFLAGS="'-DMBEDTLS_USER_CONFIG_FILE=\"../tests/configs/user-config-zeroize-memset.h\"' -DMBEDTLS_TEST_DEFINES_ZEROIZE -Werror -Wsizeof-pointer-memaccess" $MAKE_THREADING_FLAGS } From 40f0ec246ea68195e74ffe20c3d8f4c700f732d2 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Mon, 11 Dec 2023 17:40:54 +0000 Subject: [PATCH 68/88] Remove requirement for SHA512 from ctr_drbg test Set the entropy len prior to doing the test to ensure the outcome is the same regardless of whether SHA512 or SHA256 is used. Signed-off-by: Paul Elliott --- tests/suites/test_suite_ctr_drbg.data | 4 ++-- tests/suites/test_suite_ctr_drbg.function | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/suites/test_suite_ctr_drbg.data b/tests/suites/test_suite_ctr_drbg.data index b519da8951..f314ac603b 100644 --- a/tests/suites/test_suite_ctr_drbg.data +++ b/tests/suites/test_suite_ctr_drbg.data @@ -1097,11 +1097,11 @@ CTR_DRBG Special Behaviours ctr_drbg_special_behaviours: CTR_DRBG Threads: no reseed -depends_on:!MBEDTLS_CTR_DRBG_USE_128_BIT_KEY:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_ENTROPY_FORCE_SHA256:MBEDTLS_SHA512_C +depends_on:!MBEDTLS_CTR_DRBG_USE_128_BIT_KEY:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH ctr_drbg_threads:"1fafa98bc83d95e10f2d5ed339a553e1":0:5 CTR_DRBG Threads: reseed -depends_on:!MBEDTLS_CTR_DRBG_USE_128_BIT_KEY:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:!MBEDTLS_ENTROPY_FORCE_SHA256:MBEDTLS_SHA512_C +depends_on:!MBEDTLS_CTR_DRBG_USE_128_BIT_KEY:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH ctr_drbg_threads:"B10A961F2EA39927B4C48AEDDD299026":1:5 CTR_DRBG self test diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index a5a85a0eba..504f28a6ef 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -353,6 +353,9 @@ void ctr_drbg_threads(data_t *expected_result, int reseed, int arg_thread_count) const size_t n_random_calls = thread_count * thread_random_reps + 1; + /* Based on the size of MBEDTLS_CTR_DRBG_ENTROPY_LEN for SHA512. */ + const size_t entropy_len = 48; + TEST_CALLOC(threads, sizeof(pthread_t) * thread_count); memset(out, 0, sizeof(out)); @@ -361,14 +364,18 @@ void ctr_drbg_threads(data_t *expected_result, int reseed, int arg_thread_count) test_offset_idx = 0; + /* Need to do this, otherwise if we are forced into using SHA256 for + * whaever reason, output will differ. */ + mbedtls_ctr_drbg_set_entropy_len(&ctx, entropy_len); + if (reseed == 0) { mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_OFF); mbedtls_ctr_drbg_set_reseed_interval(&ctx, n_random_calls + 1); - TEST_CALLOC(entropy, MBEDTLS_CTR_DRBG_ENTROPY_LEN + MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN); - test_max_idx = MBEDTLS_CTR_DRBG_ENTROPY_LEN + MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN; + TEST_CALLOC(entropy, entropy_len + MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN); + test_max_idx = entropy_len + MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN; } else { - const size_t entropy_size = ((n_random_calls + 1) * MBEDTLS_CTR_DRBG_ENTROPY_LEN) + const size_t entropy_size = ((n_random_calls + 1) * entropy_len) + MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN; mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_ON); From 79dc6dad81a897caca0fe24cfce5be81925e48dc Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Mon, 11 Dec 2023 17:52:03 +0000 Subject: [PATCH 69/88] Improve make pthread linking mechanism Signed-off-by: Paul Elliott --- programs/Makefile | 2 +- tests/Makefile | 2 +- tests/scripts/all.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/programs/Makefile b/programs/Makefile index a3fa81679f..ebdadc0567 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -139,7 +139,7 @@ APPS = \ x509/req_app \ # End of APPS -ifdef PTHREAD +ifeq ($(THREADING),pthread) APPS += ssl/ssl_pthread_server endif diff --git a/tests/Makefile b/tests/Makefile index 72429a6429..29197b7c71 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -58,7 +58,7 @@ DLEXT ?= so EXEXT= SHARED_SUFFIX= -ifdef PTHREAD +ifeq ($(THREADING),pthread) LOCAL_LDFLAGS += -lpthread endif endif diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 65203e8771..933c563d30 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -218,7 +218,7 @@ pre_initialize_variables () { done # Option to enable linking with pthreads under make - MAKE_THREADING_FLAGS="PTHREAD=1" + MAKE_THREADING_FLAGS="THREADING=pthread" } # Test whether the component $1 is included in the command line patterns. From e4b3f75298321d14fc20817ad2817d040788bb3f Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Mon, 11 Dec 2023 17:57:16 +0000 Subject: [PATCH 70/88] Remove unnecessary check Signed-off-by: Paul Elliott --- programs/aes/crypt_and_hash.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c index f15b85e2c0..b2cd704710 100644 --- a/programs/aes/crypt_and_hash.c +++ b/programs/aes/crypt_and_hash.c @@ -103,14 +103,11 @@ int main(int argc, char *argv[]) list = mbedtls_cipher_list(); while (*list) { cipher_info = mbedtls_cipher_info_from_type(*list); - if (cipher_info) { - const char *name = mbedtls_cipher_info_get_name(cipher_info); + const char *name = mbedtls_cipher_info_get_name(cipher_info); - if (name) { - mbedtls_printf(" %s\n", mbedtls_cipher_info_get_name(cipher_info)); - } + if (name) { + mbedtls_printf(" %s\n", mbedtls_cipher_info_get_name(cipher_info)); } - list++; } From 445af3c25ad86c3ea6dc1a68a1eb5663a7e17a8a Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Mon, 11 Dec 2023 18:05:32 +0000 Subject: [PATCH 71/88] Move test dependancies to function file Dependancies are determined by code in this case. Signed-off-by: Paul Elliott --- tests/suites/test_suite_ctr_drbg.data | 1 - tests/suites/test_suite_ctr_drbg.function | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/suites/test_suite_ctr_drbg.data b/tests/suites/test_suite_ctr_drbg.data index f314ac603b..028a07f80d 100644 --- a/tests/suites/test_suite_ctr_drbg.data +++ b/tests/suites/test_suite_ctr_drbg.data @@ -1097,7 +1097,6 @@ CTR_DRBG Special Behaviours ctr_drbg_special_behaviours: CTR_DRBG Threads: no reseed -depends_on:!MBEDTLS_CTR_DRBG_USE_128_BIT_KEY:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH ctr_drbg_threads:"1fafa98bc83d95e10f2d5ed339a553e1":0:5 CTR_DRBG Threads: reseed diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index 504f28a6ef..c60f8cd650 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -342,7 +342,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD */ +/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD:!MBEDTLS_CTR_DRBG_USE_128_BIT_KEY:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ void ctr_drbg_threads(data_t *expected_result, int reseed, int arg_thread_count) { size_t thread_count = (size_t) arg_thread_count; From 22dbaf05b6ce1189d1af58bbd144406d827fc813 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Mon, 18 Dec 2023 18:18:04 +0000 Subject: [PATCH 72/88] Add AES_PSA_INIT() to thread test case Tests were failing when PSA was being used in ctr_drbg_seed() as PSA was not initialised. Signed-off-by: Paul Elliott --- tests/suites/test_suite_ctr_drbg.function | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index c60f8cd650..1f0a072c7c 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -356,6 +356,8 @@ void ctr_drbg_threads(data_t *expected_result, int reseed, int arg_thread_count) /* Based on the size of MBEDTLS_CTR_DRBG_ENTROPY_LEN for SHA512. */ const size_t entropy_len = 48; + AES_PSA_INIT(); + TEST_CALLOC(threads, sizeof(pthread_t) * thread_count); memset(out, 0, sizeof(out)); @@ -408,6 +410,8 @@ exit: mbedtls_ctr_drbg_free(&ctx); mbedtls_free(entropy); mbedtls_free(threads); + + AES_PSA_DONE(); } /* END_CASE */ From 9deb54900eb5d9f21724f9f016bba1b87e7f143c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 18 Dec 2023 21:01:18 +0100 Subject: [PATCH 73/88] Document the domain_parameters_size==SIZE_MAX hack It was introduced in https://github.com/Mbed-TLS/mbedtls/pull/8616 but not documented. Signed-off-by: Gilles Peskine --- include/psa/crypto_struct.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 5639ad05d4..1eb2463cee 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -254,6 +254,18 @@ struct psa_key_attributes_s { #if defined(MBEDTLS_PSA_CRYPTO_SE_C) psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number); #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + /* Unlike normal buffers, there are three cases for domain_parameters + * and domain_parameters_size: + * - domain_parameters_size == SIZE_MAX && domain_parameters == NULL: + * Access to domain parameters is not supported for this key. + * This is a hack which should not exist, intended for keys managed + * by a driver that doesn't support domain parameters. + * - domain_parameters_size == 0 && domain_parameters == NULL: + * The domain parameters are empty. + * - domain_parameters_size > 0 && + * domain_parameters == valid pointer to domain_parameters_size bytes: + * The domain parameters are non-empty. + */ void *MBEDTLS_PRIVATE(domain_parameters); size_t MBEDTLS_PRIVATE(domain_parameters_size); }; From 4bb5740a7d0a5518de23635484847928e09600a7 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 4 Dec 2023 16:11:59 +0100 Subject: [PATCH 74/88] Revert "pem: auto add newlines to header/footer in mbedtls_pem_write_buffer()" This reverts commit 180915018dd04f6ad66faa3e9fc66813a221643d. Signed-off-by: Valerio Setti --- include/mbedtls/pem.h | 3 --- library/pem.c | 7 +------ library/x509write_crt.c | 4 ++-- library/x509write_csr.c | 4 ++-- tests/suites/test_suite_pem.data | 12 ++++++------ tests/suites/test_suite_pem.function | 6 +++--- 6 files changed, 14 insertions(+), 22 deletions(-) diff --git a/include/mbedtls/pem.h b/include/mbedtls/pem.h index 2fe19d026c..cc617a9bcc 100644 --- a/include/mbedtls/pem.h +++ b/include/mbedtls/pem.h @@ -135,9 +135,6 @@ void mbedtls_pem_free(mbedtls_pem_context *ctx); * \param olen The address at which to store the total length written * or required (if \p buf_len is not enough). * - * \note Newlines are automatically appended to both header and - * footer. - * * \note You may pass \c NULL for \p buf and \c 0 for \p buf_len * to request the length of the resulting PEM buffer in * `*olen`. diff --git a/library/pem.c b/library/pem.c index 7c0c447ee2..9500ffcf7f 100644 --- a/library/pem.c +++ b/library/pem.c @@ -473,10 +473,7 @@ int mbedtls_pem_write_buffer(const char *header, const char *footer, size_t len = 0, use_len, add_len = 0; mbedtls_base64_encode(NULL, 0, &use_len, der_data, der_len); - /* Newlines are appended to the end of both header and footer, so we - * account for an extra +2. */ - add_len = strlen(header) + strlen(footer) + 2 + \ - (((use_len > 2) ? (use_len - 2) : 0) / 64) + 1; + add_len = strlen(header) + strlen(footer) + (((use_len > 2) ? (use_len - 2) : 0) / 64) + 1; if (use_len + add_len > buf_len) { *olen = use_len + add_len; @@ -496,7 +493,6 @@ int mbedtls_pem_write_buffer(const char *header, const char *footer, memcpy(p, header, strlen(header)); p += strlen(header); - *p++ = '\n'; c = encode_buf; while (use_len) { @@ -510,7 +506,6 @@ int mbedtls_pem_write_buffer(const char *header, const char *footer, memcpy(p, footer, strlen(footer)); p += strlen(footer); - *p++ = '\n'; *p++ = '\0'; *olen = p - buf; diff --git a/library/x509write_crt.c b/library/x509write_crt.c index 8d920f2676..4c019eee4e 100644 --- a/library/x509write_crt.c +++ b/library/x509write_crt.c @@ -651,8 +651,8 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, return (int) len; } -#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----" -#define PEM_END_CRT "-----END CERTIFICATE-----" +#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" +#define PEM_END_CRT "-----END CERTIFICATE-----\n" #if defined(MBEDTLS_PEM_WRITE_C) int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *crt, diff --git a/library/x509write_csr.c b/library/x509write_csr.c index 5ee683ff12..4e397553a4 100644 --- a/library/x509write_csr.c +++ b/library/x509write_csr.c @@ -302,8 +302,8 @@ int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf, return ret; } -#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----" -#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----" +#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" +#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" #if defined(MBEDTLS_PEM_WRITE_C) int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, diff --git a/tests/suites/test_suite_pem.data b/tests/suites/test_suite_pem.data index 238a0bc043..a4dff45f0b 100644 --- a/tests/suites/test_suite_pem.data +++ b/tests/suites/test_suite_pem.data @@ -1,20 +1,20 @@ Standard PEM write -mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=\n-----END TEST-----\n" PEM write (zero data) -mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"":"-----START TEST-----\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"":"-----START TEST-----\n-----END TEST-----\n" PEM write (one byte) -mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"00":"-----START TEST-----\nAA==\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"00":"-----START TEST-----\nAA==\n-----END TEST-----\n" PEM write (more than line size) -mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=\n-----END TEST-----\n" PEM write (exactly two lines) -mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\n-----END TEST-----\n" PEM write (exactly two lines + 1) -mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F00":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAA==\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F00":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAA==\n-----END TEST-----\n" PEM write length reporting mbedtls_pem_write_buffer_lengths diff --git a/tests/suites/test_suite_pem.function b/tests/suites/test_suite_pem.function index cb652d4584..413dc551c3 100644 --- a/tests/suites/test_suite_pem.function +++ b/tests/suites/test_suite_pem.function @@ -40,17 +40,17 @@ void mbedtls_pem_write_buffer_lengths() size_t olen_needed, olen; int ret; for (size_t l = 0; l <= sizeof(data); l++) { - ret = mbedtls_pem_write_buffer("", "", data, l, NULL, 0, &olen_needed); + ret = mbedtls_pem_write_buffer("\n", "\n", data, l, NULL, 0, &olen_needed); TEST_EQUAL(ret, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL); /* Test that a bigger buffer still only requires `olen_needed` */ - ret = mbedtls_pem_write_buffer("", "", data, l, buf, sizeof(buf), &olen); + ret = mbedtls_pem_write_buffer("\n", "\n", data, l, buf, sizeof(buf), &olen); TEST_EQUAL(ret, 0); TEST_EQUAL(olen_needed, olen); /* Test that a buffer of exactly `olen_needed` works */ memset(buf, 1, sizeof(buf)); - ret = mbedtls_pem_write_buffer("", "", data, l, buf, olen_needed, &olen); + ret = mbedtls_pem_write_buffer("\n", "\n", data, l, buf, olen_needed, &olen); TEST_EQUAL(ret, 0); TEST_EQUAL(olen_needed, olen); /* Test the function didn't overflow the given buffer */ From 7f062a58fb3a3aa4803d922576c0f1da17adc0ea Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 4 Dec 2023 16:29:56 +0100 Subject: [PATCH 75/88] pkwrite: add newlines when calling mbedtls_pem_write_buffer() New defines, which are shared with the pkparse module, lack the new line so we manually add it when invoking mbedtls_pem_write_buffer(). Signed-off-by: Valerio Setti --- library/pkwrite.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/library/pkwrite.c b/library/pkwrite.c index bd592f4f69..1f0d3990ed 100644 --- a/library/pkwrite.c +++ b/library/pkwrite.c @@ -683,7 +683,7 @@ int mbedtls_pk_write_pubkey_pem(const mbedtls_pk_context *key, unsigned char *bu goto cleanup; } - if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, + if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_PUBLIC_KEY "\n", PEM_END_PUBLIC_KEY "\n", output_buf + PUB_DER_MAX_BYTES - ret, ret, buf, size, &olen)) != 0) { goto cleanup; @@ -712,18 +712,18 @@ int mbedtls_pk_write_key_pem(const mbedtls_pk_context *key, unsigned char *buf, #if defined(MBEDTLS_RSA_C) if (pk_get_type_ext(key) == MBEDTLS_PK_RSA) { - begin = PEM_BEGIN_PRIVATE_KEY_RSA; - end = PEM_END_PRIVATE_KEY_RSA; + begin = PEM_BEGIN_PRIVATE_KEY_RSA "\n"; + end = PEM_END_PRIVATE_KEY_RSA "\n"; } else #endif #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) if (pk_get_type_ext(key) == MBEDTLS_PK_ECKEY) { if (mbedtls_pk_is_rfc8410(key)) { - begin = PEM_BEGIN_PRIVATE_KEY_PKCS8; - end = PEM_END_PRIVATE_KEY_PKCS8; + begin = PEM_BEGIN_PRIVATE_KEY_PKCS8 "\n"; + end = PEM_END_PRIVATE_KEY_PKCS8 "\n"; } else { - begin = PEM_BEGIN_PRIVATE_KEY_EC; - end = PEM_END_PRIVATE_KEY_EC; + begin = PEM_BEGIN_PRIVATE_KEY_EC "\n"; + end = PEM_END_PRIVATE_KEY_EC "\n"; } } else #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */ From 5ad95393636cf06627eecef9effd397f9e39e376 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 19 Dec 2023 12:22:46 +0100 Subject: [PATCH 76/88] Remove DSA and DH domain parameters from the documentation Mbed TLS doesn't support DSA at all, and doesn't support domain parameters for FFDH (only predefined groups). Signed-off-by: Gilles Peskine --- include/psa/crypto_extra.h | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index f7207a1be2..f39d1eb0be 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -428,6 +428,7 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, * of psa_set_key_type() when you need to specify domain parameters. * * The format for the required domain parameters varies based on the key type. + * Mbed TLS supports the following key type with domain parameters: * * - For RSA keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY or #PSA_KEY_TYPE_RSA_KEY_PAIR), * the domain parameter data consists of the public exponent, @@ -437,32 +438,6 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, * key data and the exponent recorded in the attribute structure is ignored. * As an exception, the public exponent 65537 is represented by an empty * byte string. - * - For DSA keys (#PSA_KEY_TYPE_DSA_PUBLIC_KEY or #PSA_KEY_TYPE_DSA_KEY_PAIR), - * the `Dss-Params` format as defined by RFC 3279 §2.3.2. - * ``` - * Dss-Params ::= SEQUENCE { - * p INTEGER, - * q INTEGER, - * g INTEGER - * } - * ``` - * - For Diffie-Hellman key exchange keys - * (#PSA_KEY_TYPE_DH_PUBLIC_KEY(#PSA_DH_FAMILY_CUSTOM) or - * #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_FAMILY_CUSTOM)), the - * `DomainParameters` format as defined by RFC 3279 §2.3.3. - * ``` - * DomainParameters ::= SEQUENCE { - * p INTEGER, -- odd prime, p=jq +1 - * g INTEGER, -- generator, g - * q INTEGER, -- factor of p-1 - * j INTEGER OPTIONAL, -- subgroup factor - * validationParams ValidationParams OPTIONAL - * } - * ValidationParams ::= SEQUENCE { - * seed BIT STRING, - * pgenCounter INTEGER - * } - * ``` * * \note This function may allocate memory or other resources. * Once you have called this function on an attribute structure, From 1a9e05bf080e9ce770fd56ba88c25c52b4c38498 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 19 Dec 2023 12:23:22 +0100 Subject: [PATCH 77/88] Note that domain parameters are not supported with drivers Signed-off-by: Gilles Peskine --- include/psa/crypto_extra.h | 8 ++++++++ include/psa/crypto_struct.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index f39d1eb0be..f132f7ed99 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -446,6 +446,9 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, * \note This is an experimental extension to the interface. It may change * in future versions of the library. * + * \note Due to an implementation limitation, domain parameters are ignored + * for keys that are managed by a driver. + * * \param[in,out] attributes Attribute structure where the specified domain * parameters will be stored. * If this function fails, the content of @@ -476,6 +479,9 @@ psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes, * \note This is an experimental extension to the interface. It may change * in future versions of the library. * + * \note Due to an implementation limitation, domain parameters are not + * supported with keys that are managed by a driver. + * * \param[in] attributes The key attribute structure to query. * \param[out] data On success, the key domain parameters. * \param data_size Size of the \p data buffer in bytes. @@ -488,6 +494,8 @@ psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes, * * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription + * \retval #PSA_ERROR_NOT_SUPPORTED + * The key is managed by a driver. */ psa_status_t psa_get_key_domain_parameters( const psa_key_attributes_t *attributes, diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 1eb2463cee..5e52ffde06 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -259,7 +259,7 @@ struct psa_key_attributes_s { * - domain_parameters_size == SIZE_MAX && domain_parameters == NULL: * Access to domain parameters is not supported for this key. * This is a hack which should not exist, intended for keys managed - * by a driver that doesn't support domain parameters. + * by a driver, because drivers don't support domain parameters. * - domain_parameters_size == 0 && domain_parameters == NULL: * The domain parameters are empty. * - domain_parameters_size > 0 && From a70b3c24f6e4cb44c049961ecd84196eed6491a4 Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> Date: Sun, 16 Jul 2023 12:06:13 +0300 Subject: [PATCH 78/88] rsa: minor comment/guard improvements This brings some improvements to comments/ function prototypes that relate to PKCS#1. Signed-off-by: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> --- include/mbedtls/mbedtls_config.h | 2 ++ include/mbedtls/rsa.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 758a514249..a3e3f83474 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -2191,6 +2191,8 @@ * Enable parsing and verification of X.509 certificates, CRLs and CSRS * signed with RSASSA-PSS (aka PKCS#1 v2.1). * + * Requires: MBEDTLS_PKCS1_V21 + * * Comment this macro to disallow using RSASSA-PSS in certificates. */ #define MBEDTLS_X509_RSASSA_PSS_SUPPORT diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h index df665240d1..e5e172f9c1 100644 --- a/include/mbedtls/rsa.h +++ b/include/mbedtls/rsa.h @@ -869,6 +869,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx, const unsigned char *hash, unsigned char *sig); +#if defined(MBEDTLS_PKCS1_V21) /** * \brief This function performs a PKCS#1 v2.1 PSS signature * operation (RSASSA-PSS-SIGN). @@ -969,6 +970,7 @@ int mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, unsigned int hashlen, const unsigned char *hash, unsigned char *sig); +#endif /* MBEDTLS_PKCS1_V21 */ /** * \brief This function performs a public RSA operation and checks From 80ca4932847874c4ebe595e43cdcdb36fc4d5668 Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> Date: Sun, 16 Jul 2023 12:12:09 +0300 Subject: [PATCH 79/88] gitignore: add clangd index files https://clangd.llvm.org/design/indexing#backgroundindex Signed-off-by: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 185bd7a1d7..4f29d5be50 100644 --- a/.gitignore +++ b/.gitignore @@ -63,5 +63,7 @@ massif-* /cscope*.out /tags -# Clangd compilation database +# clangd compilation database compile_commands.json +# clangd index files +/.cache/clangd/index/ From 8174662b648d03c5503dfea15a57106ca7dd5312 Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> Date: Sun, 16 Jul 2023 13:06:06 +0300 Subject: [PATCH 80/88] pk: implement non-PSA mbedtls_pk_sign_ext() This makes the function always available with its its implementation depending on MBEDTLS_USE_PSA_CRYPTO. Related dependencies and tests are updated as well. Fixes #7583. Signed-off-by: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> --- ChangeLog.d/non-psa-pk-implementation.txt | 4 + include/mbedtls/config_adjust_legacy_crypto.h | 6 +- include/mbedtls/pk.h | 4 +- library/pk.c | 41 ++++++--- library/pk_wrap.c | 4 +- library/pk_wrap.h | 16 ++-- tests/suites/test_suite_pk.data | 48 +++++------ tests/suites/test_suite_pk.function | 83 +++++++++++-------- 8 files changed, 120 insertions(+), 86 deletions(-) create mode 100644 ChangeLog.d/non-psa-pk-implementation.txt diff --git a/ChangeLog.d/non-psa-pk-implementation.txt b/ChangeLog.d/non-psa-pk-implementation.txt new file mode 100644 index 0000000000..88ed006544 --- /dev/null +++ b/ChangeLog.d/non-psa-pk-implementation.txt @@ -0,0 +1,4 @@ +Changes + * mbedtls_pk_sign_ext() is now available even without PSA + (MBEDTLS_PSA_CRYPTO_C). This improves uniformity in the PK module; + it now only depends on MBEDTLS_USE_PSA_CRYPTO for its use of PSA. diff --git a/include/mbedtls/config_adjust_legacy_crypto.h b/include/mbedtls/config_adjust_legacy_crypto.h index e66d67a1b7..74d037df43 100644 --- a/include/mbedtls/config_adjust_legacy_crypto.h +++ b/include/mbedtls/config_adjust_legacy_crypto.h @@ -235,9 +235,9 @@ #define MBEDTLS_PSA_CRYPTO_CLIENT #endif /* MBEDTLS_PSA_CRYPTO_C */ -/* The PK wrappers need pk_write functions to format RSA key objects - * when they are dispatching to the PSA API. This happens under USE_PSA_CRYPTO, - * and also even without USE_PSA_CRYPTO for mbedtls_pk_sign_ext(). */ +/* The PK wrappers need pk_write/pk_parse functions to format RSA key objects + * when they are dispatching to the PSA API. This happens under MBEDTLS_USE_PSA_CRYPTO, + * and even under just MBEDTLS_PSA_CRYPTO_C in psa_crypto_rsa.c. */ #if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_RSA_C) #define MBEDTLS_PK_C #define MBEDTLS_PK_WRITE_C diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index 24b11886b9..355bf10346 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -28,7 +28,7 @@ #include "mbedtls/ecdsa.h" #endif -#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_PSA_CRYPTO_C) #include "psa/crypto.h" #endif @@ -615,7 +615,6 @@ int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, unsigned char *sig, size_t sig_size, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); -#if defined(MBEDTLS_PSA_CRYPTO_C) /** * \brief Make signature given a signature type. * @@ -652,7 +651,6 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, unsigned char *sig, size_t sig_size, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); -#endif /* MBEDTLS_PSA_CRYPTO_C */ /** * \brief Restartable version of \c mbedtls_pk_sign() diff --git a/library/pk.c b/library/pk.c index 957f64ed1e..344d29fd53 100644 --- a/library/pk.c +++ b/library/pk.c @@ -579,7 +579,7 @@ int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, return PSA_PK_RSA_TO_MBEDTLS_ERR(status); } else -#endif +#endif /* MBEDTLS_USE_PSA_CRYPTO */ { if (sig_len < mbedtls_pk_get_len(ctx)) { return MBEDTLS_ERR_RSA_VERIFY_FAILED; @@ -672,7 +672,6 @@ int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, f_rng, p_rng, NULL); } -#if defined(MBEDTLS_PSA_CRYPTO_C) /* * Make a signature given a signature type. */ @@ -684,11 +683,6 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) { -#if defined(MBEDTLS_RSA_C) - psa_algorithm_t psa_md_alg; -#endif /* MBEDTLS_RSA_C */ - *sig_len = 0; - if (ctx->pk_info == NULL) { return MBEDTLS_ERR_PK_BAD_INPUT_DATA; } @@ -702,8 +696,10 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, sig, sig_size, sig_len, f_rng, p_rng); } -#if defined(MBEDTLS_RSA_C) - psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); +#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + const psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); if (psa_md_alg == 0) { return MBEDTLS_ERR_PK_BAD_INPUT_DATA; } @@ -720,12 +716,31 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, return mbedtls_pk_psa_rsa_sign_ext(PSA_ALG_RSA_PSS(psa_md_alg), ctx->pk_ctx, hash, hash_len, sig, sig_size, sig_len); -#else /* MBEDTLS_RSA_C */ - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; -#endif /* !MBEDTLS_RSA_C */ +#else /* MBEDTLS_USE_PSA_CRYPTO */ + if (sig_size < mbedtls_pk_get_len(ctx)) { + return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; + } + + if (pk_hashlen_helper(md_alg, &hash_len) != 0) { + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + + mbedtls_rsa_context *const rsa_ctx = mbedtls_pk_rsa(*ctx); + + const int ret = mbedtls_rsa_rsassa_pss_sign(rsa_ctx, f_rng, p_rng, md_alg, + (unsigned int) hash_len, hash, sig); + if (ret == 0) { + *sig_len = rsa_ctx->len; + } + return ret; + +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#else + return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; +#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ } -#endif /* MBEDTLS_PSA_CRYPTO_C */ /* * Decrypt message diff --git a/library/pk_wrap.c b/library/pk_wrap.c index 0fb3c42176..b1fbd861d8 100644 --- a/library/pk_wrap.c +++ b/library/pk_wrap.c @@ -281,7 +281,7 @@ static int rsa_verify_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, } #endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_USE_PSA_CRYPTO) int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t alg, mbedtls_rsa_context *rsa_ctx, const unsigned char *hash, size_t hash_len, @@ -344,7 +344,7 @@ cleanup: } return ret; } -#endif /* MBEDTLS_PSA_CRYPTO_C */ +#endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_USE_PSA_CRYPTO) static int rsa_sign_wrap(mbedtls_pk_context *pk, mbedtls_md_type_t md_alg, diff --git a/library/pk_wrap.h b/library/pk_wrap.h index 28c815a772..a6237bf638 100644 --- a/library/pk_wrap.h +++ b/library/pk_wrap.h @@ -131,6 +131,14 @@ int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa_ecdsa(psa_status_t status); #endif #endif +#if defined(MBEDTLS_RSA_C) +int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t psa_alg_md, + mbedtls_rsa_context *rsa_ctx, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t sig_size, + size_t *sig_len); +#endif /* MBEDTLS_RSA_C */ + #endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_PSA_CRYPTO_C) @@ -143,14 +151,6 @@ int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa_rsa(psa_status_t status); #endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */ #endif /* !MBEDTLS_DEPRECATED_REMOVED */ -#if defined(MBEDTLS_RSA_C) -int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t psa_alg_md, - mbedtls_rsa_context *rsa_ctx, - const unsigned char *hash, size_t hash_len, - unsigned char *sig, size_t sig_size, - size_t *sig_len); -#endif /* MBEDTLS_RSA_C */ - #endif /* MBEDTLS_PSA_CRYPTO_C */ #endif /* MBEDTLS_PK_WRAP_H */ diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index e69749140a..af1e20c46a 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -621,62 +621,62 @@ PSA wrapped sign: RSA PKCS1 v1.5 depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_GENPRIME:MBEDTLS_PK_WRITE_C pk_psa_sign:1024:PSA_KEY_TYPE_RSA_KEY_PAIR:1024 -PK Sign ext:RSA2048,PK_RSA,MD_SHA256 +PK sign ext: RSA2048, PK_RSA, MD_SHA256 depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256:MBEDTLS_RSA_C:MBEDTLS_RSA_GEN_KEY_MIN_BITS <= 2048 -pk_psa_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSA:MBEDTLS_MD_SHA256 +pk_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSA:MBEDTLS_MD_SHA256 -PK Sign ext:RSA2048,PK_RSASSA_PSS,MD_SHA256 +PK sign ext: RSA2048, PK_RSASSA_PSS, MD_SHA256 depends_on:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256:MBEDTLS_RSA_C:MBEDTLS_RSA_GEN_KEY_MIN_BITS <= 2048 -pk_psa_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSASSA_PSS:MBEDTLS_MD_SHA256 +pk_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSASSA_PSS:MBEDTLS_MD_SHA256 -PK Sign ext:RSA2048,PK_RSA,MD_SHA384 +PK sign ext: RSA2048, PK_RSA, MD_SHA384 depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA384:MBEDTLS_RSA_C:MBEDTLS_RSA_GEN_KEY_MIN_BITS <= 2048 -pk_psa_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSA:MBEDTLS_MD_SHA384 +pk_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSA:MBEDTLS_MD_SHA384 -PK Sign ext:RSA2048,PK_RSASSA_PSS,MD_SHA384 +PK sign ext: RSA2048, PK_RSASSA_PSS, MD_SHA384 depends_on:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA384:MBEDTLS_RSA_C:MBEDTLS_RSA_GEN_KEY_MIN_BITS <= 2048 -pk_psa_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSASSA_PSS:MBEDTLS_MD_SHA384 +pk_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSASSA_PSS:MBEDTLS_MD_SHA384 -PK Sign ext:RSA2048,PK_RSA,MD_SHA512 +PK sign ext: RSA2048, PK_RSA, MD_SHA512 depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA512:MBEDTLS_RSA_C:MBEDTLS_RSA_GEN_KEY_MIN_BITS <= 2048 -pk_psa_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSA:MBEDTLS_MD_SHA512 +pk_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSA:MBEDTLS_MD_SHA512 -PK Sign ext:RSA2048,PK_RSASSA_PSS,MD_SHA512 +PK sign ext: RSA2048, PK_RSASSA_PSS, MD_SHA512 depends_on:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512:MBEDTLS_RSA_C:MBEDTLS_RSA_GEN_KEY_MIN_BITS <= 2048 -pk_psa_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSASSA_PSS:MBEDTLS_MD_SHA512 +pk_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSASSA_PSS:MBEDTLS_MD_SHA512 -PK Sign ext:SECP256R1,PK_ECDSA,MD_SHA256 +PK sign ext: SECP256R1, PK_ECDSA, MD_SHA256 depends_on:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256 -pk_psa_sign_ext:MBEDTLS_PK_ECDSA:MBEDTLS_ECP_DP_SECP256R1:MBEDTLS_PK_ECDSA:MBEDTLS_MD_SHA256 +pk_sign_ext:MBEDTLS_PK_ECDSA:MBEDTLS_ECP_DP_SECP256R1:MBEDTLS_PK_ECDSA:MBEDTLS_MD_SHA256 -PK Sign ext:SECP384R1,PK_ECDSA,MD_SHA384 +PK sign ext: SECP384R1, PK_ECDSA, MD_SHA384 depends_on:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_MD_CAN_SHA384 -pk_psa_sign_ext:MBEDTLS_PK_ECDSA:MBEDTLS_ECP_DP_SECP384R1:MBEDTLS_PK_ECDSA:MBEDTLS_MD_SHA384 +pk_sign_ext:MBEDTLS_PK_ECDSA:MBEDTLS_ECP_DP_SECP384R1:MBEDTLS_PK_ECDSA:MBEDTLS_MD_SHA384 -PK Sign ext:SECP521R1,PK_ECDSA,MD_SHA512 +PK sign ext: SECP521R1, PK_ECDSA, MD_SHA512 depends_on:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_ECP_HAVE_SECP521R1:MBEDTLS_MD_CAN_SHA512 -pk_psa_sign_ext:MBEDTLS_PK_ECDSA:MBEDTLS_ECP_DP_SECP521R1:MBEDTLS_PK_ECDSA:MBEDTLS_MD_SHA512 +pk_sign_ext:MBEDTLS_PK_ECDSA:MBEDTLS_ECP_DP_SECP521R1:MBEDTLS_PK_ECDSA:MBEDTLS_MD_SHA512 -PK wrapped Sign ext:RSA2048,PK_RSA,MD_SHA256 +PSA wrapped sign ext: RSA2048, PK_RSA, MD_SHA256 depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA256:MBEDTLS_RSA_C pk_psa_wrap_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSA:MBEDTLS_MD_SHA256 -PK wrapped Sign ext:RSA2048,PK_RSASSA_PSS,MD_SHA256 +PSA wrapped sign ext: RSA2048, PK_RSASSA_PSS, MD_SHA256 depends_on:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA256:MBEDTLS_RSA_C pk_psa_wrap_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSASSA_PSS:MBEDTLS_MD_SHA256 -PK wrapped Sign ext:RSA2048,PK_RSA,MD_SHA384 +PSA wrapped sign ext: RSA2048, PK_RSA, MD_SHA384 depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA384:MBEDTLS_RSA_C pk_psa_wrap_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSA:MBEDTLS_MD_SHA384 -PK wrapped Sign ext:RSA2048,PK_RSASSA_PSS,MD_SHA384 +PSA wrapped sign ext: RSA2048, PK_RSASSA_PSS, MD_SHA384 depends_on:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA384:MBEDTLS_RSA_C pk_psa_wrap_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSASSA_PSS:MBEDTLS_MD_SHA384 -PK wrapped Sign ext:RSA2048,PK_RSA,MD_SHA512 +PSA wrapped sign ext: RSA2048, PK_RSA, MD_SHA512 depends_on:MBEDTLS_PKCS1_V15:MBEDTLS_MD_CAN_SHA512:MBEDTLS_RSA_C pk_psa_wrap_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSA:MBEDTLS_MD_SHA512 -PK wrapped Sign ext:RSA2048,PK_RSASSA_PSS,MD_SHA512 +PSA wrapped sign ext: RSA2048, PK_RSASSA_PSS, MD_SHA512 depends_on:MBEDTLS_PKCS1_V21:MBEDTLS_MD_CAN_SHA512:MBEDTLS_RSA_C pk_psa_wrap_sign_ext:MBEDTLS_PK_RSA:2048:MBEDTLS_PK_RSASSA_PSS:MBEDTLS_MD_SHA512 diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index fa0b03b343..5255febb72 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -407,6 +407,16 @@ void pk_invalid_param() buf, buf_size, &buf_size, NULL, NULL, NULL)); + TEST_EQUAL(MBEDTLS_ERR_PK_BAD_INPUT_DATA, + mbedtls_pk_sign_ext(pk_type, &ctx, MBEDTLS_MD_NONE, + NULL, buf_size, + buf, buf_size, &buf_size, + NULL, NULL)); + TEST_EQUAL(MBEDTLS_ERR_PK_BAD_INPUT_DATA, + mbedtls_pk_sign_ext(pk_type, &ctx, MBEDTLS_MD_SHA256, + NULL, 0, + buf, buf_size, &buf_size, + NULL, NULL)); exit: mbedtls_pk_free(&ctx); USE_PSA_DONE(); @@ -435,14 +445,6 @@ void valid_parameters() TEST_ASSERT(mbedtls_pk_get_len(NULL) == 0); TEST_ASSERT(mbedtls_pk_can_do(NULL, MBEDTLS_PK_NONE) == 0); - TEST_ASSERT(mbedtls_pk_sign_restartable(&pk, - MBEDTLS_MD_NONE, - NULL, 0, - buf, sizeof(buf), &len, - mbedtls_test_rnd_std_rand, NULL, - NULL) == - MBEDTLS_ERR_PK_BAD_INPUT_DATA); - TEST_ASSERT(mbedtls_pk_sign_restartable(&pk, MBEDTLS_MD_NONE, NULL, 0, @@ -458,6 +460,13 @@ void valid_parameters() mbedtls_test_rnd_std_rand, NULL) == MBEDTLS_ERR_PK_BAD_INPUT_DATA); + TEST_ASSERT(mbedtls_pk_sign_ext(MBEDTLS_PK_NONE, &pk, + MBEDTLS_MD_NONE, + NULL, 0, + buf, sizeof(buf), &len, + mbedtls_test_rnd_std_rand, NULL) == + MBEDTLS_ERR_PK_BAD_INPUT_DATA); + TEST_ASSERT(mbedtls_pk_verify_restartable(&pk, MBEDTLS_MD_NONE, NULL, 0, @@ -1175,22 +1184,31 @@ void pk_rsa_overflow() memset(hash, 0x2a, sizeof(hash)); memset(sig, 0, sizeof(sig)); - TEST_ASSERT(mbedtls_pk_setup(&pk, - mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0); + TEST_EQUAL(mbedtls_pk_setup(&pk, + mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)), 0); #if defined(MBEDTLS_PKCS1_V21) - TEST_ASSERT(mbedtls_pk_verify_ext(MBEDTLS_PK_RSASSA_PSS, NULL, &pk, - MBEDTLS_MD_NONE, hash, hash_len, sig, sig_len) == - MBEDTLS_ERR_PK_BAD_INPUT_DATA); + TEST_EQUAL(mbedtls_pk_verify_ext(MBEDTLS_PK_RSASSA_PSS, NULL, &pk, + MBEDTLS_MD_NONE, hash, hash_len, sig, sig_len), + MBEDTLS_ERR_PK_BAD_INPUT_DATA); #endif /* MBEDTLS_PKCS1_V21 */ - TEST_ASSERT(mbedtls_pk_verify(&pk, MBEDTLS_MD_NONE, hash, hash_len, - sig, sig_len) == MBEDTLS_ERR_PK_BAD_INPUT_DATA); + TEST_EQUAL(mbedtls_pk_verify(&pk, MBEDTLS_MD_NONE, hash, hash_len, + sig, sig_len), + MBEDTLS_ERR_PK_BAD_INPUT_DATA); - TEST_ASSERT(mbedtls_pk_sign(&pk, MBEDTLS_MD_NONE, hash, hash_len, - sig, sizeof(sig), &sig_len, - mbedtls_test_rnd_std_rand, NULL) - == MBEDTLS_ERR_PK_BAD_INPUT_DATA); +#if defined(MBEDTLS_PKCS1_V21) + TEST_EQUAL(mbedtls_pk_sign_ext(MBEDTLS_PK_RSASSA_PSS, &pk, + MBEDTLS_MD_NONE, hash, hash_len, + sig, sizeof(sig), &sig_len, + mbedtls_test_rnd_std_rand, NULL), + MBEDTLS_ERR_PK_BAD_INPUT_DATA); +#endif /* MBEDTLS_PKCS1_V21 */ + + TEST_EQUAL(mbedtls_pk_sign(&pk, MBEDTLS_MD_NONE, hash, hash_len, + sig, sizeof(sig), &sig_len, + mbedtls_test_rnd_std_rand, NULL), + MBEDTLS_ERR_PK_BAD_INPUT_DATA); exit: mbedtls_pk_free(&pk); @@ -1440,14 +1458,14 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_GENPRIME */ -void pk_psa_sign_ext(int pk_type, int parameter, int key_pk_type, int md_alg) +/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */ +void pk_sign_ext(int pk_type, int parameter, int key_pk_type, int md_alg) { /* See the description of pk_genkey() for the description of the `parameter` argument. */ mbedtls_pk_context pk; size_t sig_len; unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; - unsigned char hash[PSA_HASH_MAX_SIZE]; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; size_t hash_len = mbedtls_md_get_size_from_type(md_alg); void const *options = NULL; mbedtls_pk_rsassa_pss_options rsassa_pss_options; @@ -1455,16 +1473,15 @@ void pk_psa_sign_ext(int pk_type, int parameter, int key_pk_type, int md_alg) memset(sig, 0, sizeof(sig)); mbedtls_pk_init(&pk); - PSA_INIT(); + MD_OR_USE_PSA_INIT(); - TEST_ASSERT(mbedtls_pk_setup(&pk, - mbedtls_pk_info_from_type(pk_type)) == 0); + TEST_EQUAL(mbedtls_pk_setup(&pk, + mbedtls_pk_info_from_type(pk_type)), 0); + TEST_EQUAL(pk_genkey(&pk, parameter), 0); - TEST_ASSERT(pk_genkey(&pk, parameter) == 0); - - TEST_ASSERT(mbedtls_pk_sign_ext(key_pk_type, &pk, md_alg, hash, hash_len, - sig, sizeof(sig), &sig_len, - mbedtls_test_rnd_std_rand, NULL) == 0); + TEST_EQUAL(mbedtls_pk_sign_ext(key_pk_type, &pk, md_alg, hash, hash_len, + sig, sizeof(sig), &sig_len, + mbedtls_test_rnd_std_rand, NULL), 0); if (key_pk_type == MBEDTLS_PK_RSASSA_PSS) { rsassa_pss_options.mgf1_hash_id = md_alg; @@ -1472,11 +1489,11 @@ void pk_psa_sign_ext(int pk_type, int parameter, int key_pk_type, int md_alg) rsassa_pss_options.expected_salt_len = hash_len; options = (const void *) &rsassa_pss_options; } - TEST_ASSERT(mbedtls_pk_verify_ext(key_pk_type, options, &pk, md_alg, - hash, hash_len, sig, sig_len) == 0); + TEST_EQUAL(mbedtls_pk_verify_ext(key_pk_type, options, &pk, md_alg, + hash, hash_len, sig, sig_len), 0); exit: mbedtls_pk_free(&pk); - PSA_DONE(); + MD_OR_USE_PSA_DONE(); } /* END_CASE */ From 573dc23141211980d43f9746e54c4f776b733f49 Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> Date: Sun, 10 Dec 2023 14:57:51 +0200 Subject: [PATCH 81/88] rsa: introduce rsa_internal_rsassa_pss_sign_no_mode_check() And use it in the non-PSA version of mbedtls_pk_sign_ext() to bypass checks that didn't succeed when used by TLS 1.3. That is because in the failing scenarios the padding of the RSA context is not set to PKCS_V21. See the discussion on PR #7930 for more details. Signed-off-by: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> --- library/pk.c | 7 +++-- library/rsa.c | 65 +++++++++++++++++++++++++++++---------- library/rsa_alt_helpers.h | 6 ++-- library/rsa_internal.h | 42 +++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 23 deletions(-) create mode 100644 library/rsa_internal.h diff --git a/library/pk.c b/library/pk.c index 344d29fd53..929af3c653 100644 --- a/library/pk.c +++ b/library/pk.c @@ -18,6 +18,9 @@ #if defined(MBEDTLS_RSA_C) #include "mbedtls/rsa.h" +#if defined(MBEDTLS_PKCS1_V21) && !defined(MBEDTLS_USE_PSA_CRYPTO) +#include "rsa_internal.h" +#endif #endif #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) #include "mbedtls/ecp.h" @@ -728,8 +731,8 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type, mbedtls_rsa_context *const rsa_ctx = mbedtls_pk_rsa(*ctx); - const int ret = mbedtls_rsa_rsassa_pss_sign(rsa_ctx, f_rng, p_rng, md_alg, - (unsigned int) hash_len, hash, sig); + const int ret = mbedtls_rsa_rsassa_pss_sign_no_mode_check(rsa_ctx, f_rng, p_rng, md_alg, + (unsigned int) hash_len, hash, sig); if (ret == 0) { *sig_len = rsa_ctx->len; } diff --git a/library/rsa.c b/library/rsa.c index 1bf5d13ca6..2b9f85b739 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -29,6 +29,7 @@ #include "mbedtls/rsa.h" #include "rsa_alt_helpers.h" +#include "rsa_internal.h" #include "mbedtls/oid.h" #include "mbedtls/platform_util.h" #include "mbedtls/error.h" @@ -1712,14 +1713,14 @@ int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx, } #if defined(MBEDTLS_PKCS1_V21) -static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng, - mbedtls_md_type_t md_alg, - unsigned int hashlen, - const unsigned char *hash, - int saltlen, - unsigned char *sig) +static int rsa_rsassa_pss_sign_no_mode_check(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + int saltlen, + unsigned char *sig) { size_t olen; unsigned char *p = sig; @@ -1727,15 +1728,12 @@ static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, size_t slen, min_slen, hlen, offset = 0; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t msb; + mbedtls_md_type_t hash_id; if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; } - if (ctx->padding != MBEDTLS_RSA_PKCS_V21) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - } - if (f_rng == NULL) { return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; } @@ -1754,7 +1752,11 @@ static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, } } - hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id); + hash_id = (mbedtls_md_type_t) ctx->hash_id; + if (hash_id == MBEDTLS_MD_NONE) { + hash_id = md_alg; + } + hlen = mbedtls_md_get_size_from_type(hash_id); if (hlen == 0) { return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; } @@ -1797,7 +1799,7 @@ static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, p += slen; /* Generate H = Hash( M' ) */ - ret = hash_mprime(hash, hashlen, salt, slen, p, (mbedtls_md_type_t) ctx->hash_id); + ret = hash_mprime(hash, hashlen, salt, slen, p, hash_id); if (ret != 0) { return ret; } @@ -1808,8 +1810,7 @@ static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, } /* maskedDB: Apply dbMask to DB */ - ret = mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen, - (mbedtls_md_type_t) ctx->hash_id); + ret = mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen, hash_id); if (ret != 0) { return ret; } @@ -1823,6 +1824,37 @@ static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, return mbedtls_rsa_private(ctx, f_rng, p_rng, sig, sig); } +static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + int saltlen, + unsigned char *sig) +{ + if (ctx->padding != MBEDTLS_RSA_PKCS_V21) { + return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + } + if (ctx->hash_id == MBEDTLS_MD_NONE) { + return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + } + return rsa_rsassa_pss_sign_no_mode_check(ctx, f_rng, p_rng, md_alg, hashlen, hash, saltlen, + sig); +} + +int mbedtls_rsa_rsassa_pss_sign_no_mode_check(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig) +{ + return rsa_rsassa_pss_sign_no_mode_check(ctx, f_rng, p_rng, md_alg, + hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig); +} + /* * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function with * the option to pass in the salt length. @@ -1840,7 +1872,6 @@ int mbedtls_rsa_rsassa_pss_sign_ext(mbedtls_rsa_context *ctx, hashlen, hash, saltlen, sig); } - /* * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function */ diff --git a/library/rsa_alt_helpers.h b/library/rsa_alt_helpers.h index ca0840b2a9..052b02491e 100644 --- a/library/rsa_alt_helpers.h +++ b/library/rsa_alt_helpers.h @@ -37,11 +37,9 @@ /* * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * */ - -#ifndef MBEDTLS_RSA_INTERNAL_H -#define MBEDTLS_RSA_INTERNAL_H +#ifndef MBEDTLS_RSA_ALT_HELPERS_H +#define MBEDTLS_RSA_ALT_HELPERS_H #include "mbedtls/build_info.h" diff --git a/library/rsa_internal.h b/library/rsa_internal.h new file mode 100644 index 0000000000..4081ac6398 --- /dev/null +++ b/library/rsa_internal.h @@ -0,0 +1,42 @@ +/** + * \file rsa_internal.h + * + * \brief Internal-only RSA public-key cryptosystem API. + * + * This file declares RSA-related functions that are to be used + * only from within the Mbed TLS library itself. + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_RSA_INTERNAL_H +#define MBEDTLS_RSA_INTERNAL_H + +#include "mbedtls/rsa.h" + +#if defined(MBEDTLS_PKCS1_V21) +/** + * \brief This function is analogue to \c mbedtls_rsa_rsassa_pss_sign(). + * The only difference between them is that this function is more flexible + * on the parameters of \p ctx that are set with \c mbedtls_rsa_set_padding(). + * + * \note Compared to its counterpart, this function: + * - does not check the padding setting of \p ctx. + * - allows the hash_id of \p ctx to be MBEDTLS_MD_NONE, + * in which case it uses \p md_alg as the hash_id. + * + * \note Refer to \c mbedtls_rsa_rsassa_pss_sign() for a description + * of the functioning and parameters of this function. + */ +int mbedtls_rsa_rsassa_pss_sign_no_mode_check(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig); +#endif /* MBEDTLS_PKCS1_V21 */ + +#endif /* rsa_internal.h */ From 9c69348c24a5770936069c3c18bd312a341c7845 Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> Date: Thu, 14 Dec 2023 21:40:54 +0200 Subject: [PATCH 82/88] pk test suite: rename the parameter named parameter Signed-off-by: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> --- tests/suites/test_suite_pk.function | 73 ++++++++++++++--------------- 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 5255febb72..226598c724 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -84,25 +84,25 @@ exit: /** Generate a key of the desired type. * - * \param pk The PK object to fill. It must have been initialized - * with mbedtls_pk_setup(). - * \param parameter - For RSA keys, the key size in bits. - * - For EC keys, the curve (\c MBEDTLS_ECP_DP_xxx). + * \param pk The PK object to fill. It must have been initialized + * with mbedtls_pk_setup(). + * \param curve_or_keybits - For RSA keys, the key size in bits. + * - For EC keys, the curve (\c MBEDTLS_ECP_DP_xxx). * - * \return The status from the underlying type-specific key - * generation function. - * \return -1 if the key type is not recognized. + * \return The status from the underlying type-specific key + * generation function. + * \return -1 if the key type is not recognized. */ -static int pk_genkey(mbedtls_pk_context *pk, int parameter) +static int pk_genkey(mbedtls_pk_context *pk, int curve_or_keybits) { - ((void) pk); - (void) parameter; + (void) pk; + (void) curve_or_keybits; #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME) if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA) { return mbedtls_rsa_gen_key(mbedtls_pk_rsa(*pk), mbedtls_test_rnd_std_rand, NULL, - parameter, 3); + curve_or_keybits, 3); } #endif #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) @@ -112,7 +112,7 @@ static int pk_genkey(mbedtls_pk_context *pk, int parameter) int ret; #if defined(MBEDTLS_ECP_C) - ret = mbedtls_ecp_group_load(&mbedtls_pk_ec_rw(*pk)->grp, parameter); + ret = mbedtls_ecp_group_load(&mbedtls_pk_ec_rw(*pk)->grp, curve_or_keybits); if (ret != 0) { return ret; } @@ -123,7 +123,7 @@ static int pk_genkey(mbedtls_pk_context *pk, int parameter) #endif /* MBEDTLS_ECP_C */ #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - ret = pk_genkey_ec(pk, parameter); + ret = pk_genkey_ec(pk, curve_or_keybits); if (ret != 0) { return ret; } @@ -319,7 +319,7 @@ exit: /* BEGIN_CASE depends_on:MBEDTLS_USE_PSA_CRYPTO */ void pk_can_do_ext(int opaque_key, int key_type, int key_usage, int key_alg, - int key_alg2, int parameter, int alg_check, int usage_check, + int key_alg2, int curve_or_keybits, int alg_check, int usage_check, int result) { mbedtls_pk_context pk; @@ -336,7 +336,7 @@ void pk_can_do_ext(int opaque_key, int key_type, int key_usage, int key_alg, psa_set_key_enrollment_algorithm(&attributes, key_alg2); } psa_set_key_type(&attributes, key_type); - psa_set_key_bits(&attributes, parameter); + psa_set_key_bits(&attributes, curve_or_keybits); PSA_ASSERT(psa_generate_key(&attributes, &key)); @@ -350,7 +350,7 @@ void pk_can_do_ext(int opaque_key, int key_type, int key_usage, int key_alg, } else { TEST_EQUAL(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(key_type)), 0); - TEST_EQUAL(pk_genkey(&pk, parameter), 0); + TEST_EQUAL(pk_genkey(&pk, curve_or_keybits), 0); TEST_EQUAL(mbedtls_pk_get_type(&pk), key_type); } @@ -545,7 +545,7 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -void pk_utils(int type, int parameter, int bitlen, int len, char *name) +void pk_utils(int type, int curve_or_keybits, int bitlen, int len, char *name) { mbedtls_pk_context pk; @@ -553,7 +553,7 @@ void pk_utils(int type, int parameter, int bitlen, int len, char *name) USE_PSA_INIT(); TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(type)) == 0); - TEST_ASSERT(pk_genkey(&pk, parameter) == 0); + TEST_ASSERT(pk_genkey(&pk, curve_or_keybits) == 0); TEST_ASSERT((int) mbedtls_pk_get_type(&pk) == type); TEST_ASSERT(mbedtls_pk_can_do(&pk, type)); @@ -857,7 +857,7 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_MD_CAN_SHA256 */ -void pk_sign_verify(int type, int parameter, int sign_ret, int verify_ret) +void pk_sign_verify(int type, int curve_or_keybits, int sign_ret, int verify_ret) { mbedtls_pk_context pk; size_t sig_len; @@ -883,7 +883,7 @@ void pk_sign_verify(int type, int parameter, int sign_ret, int verify_ret) memset(sig, 0, sizeof(sig)); TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(type)) == 0); - TEST_ASSERT(pk_genkey(&pk, parameter) == 0); + TEST_ASSERT(pk_genkey(&pk, curve_or_keybits) == 0); TEST_ASSERT(mbedtls_pk_sign_restartable(&pk, MBEDTLS_MD_SHA256, hash, hash_len, @@ -1304,8 +1304,7 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_MD_CAN_SHA256:MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_TEST_PK_PSA_SIGN */ -void pk_psa_sign(int parameter_arg, - int psa_type_arg, int expected_bits_arg) +void pk_psa_sign(int curve_or_keybits, int psa_type, int expected_bits) { mbedtls_pk_context pk; unsigned char hash[32]; @@ -1318,8 +1317,6 @@ void pk_psa_sign(int parameter_arg, int ret; mbedtls_svc_key_id_t key_id; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_type_t expected_type = psa_type_arg; - size_t expected_bits = expected_bits_arg; /* * This tests making signatures with a wrapped PSA key: @@ -1333,19 +1330,19 @@ void pk_psa_sign(int parameter_arg, USE_PSA_INIT(); #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME) - if (PSA_KEY_TYPE_IS_RSA(psa_type_arg)) { + if (PSA_KEY_TYPE_IS_RSA(psa_type)) { /* Create legacy RSA public/private key in PK context. */ TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == 0); TEST_ASSERT(mbedtls_rsa_gen_key(mbedtls_pk_rsa(pk), mbedtls_test_rnd_std_rand, NULL, - parameter_arg, 3) == 0); + curve_or_keybits, 3) == 0); alg_psa = PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256); } else #endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */ #if defined(MBEDTLS_PK_CAN_ECDSA_SIGN) - if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(psa_type_arg)) { - mbedtls_ecp_group_id grpid = parameter_arg; + if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(psa_type)) { + mbedtls_ecp_group_id grpid = curve_or_keybits; /* Create legacy EC public/private key in PK context. */ TEST_ASSERT(mbedtls_pk_setup(&pk, @@ -1356,7 +1353,7 @@ void pk_psa_sign(int parameter_arg, } else #endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */ { - (void) parameter_arg; + (void) curve_or_keybits; TEST_ASSUME(!"Opaque PK key not supported in this configuration"); } @@ -1384,8 +1381,8 @@ void pk_psa_sign(int parameter_arg, PSA_ALG_NONE) == 0); PSA_ASSERT(psa_get_key_attributes(key_id, &attributes)); - TEST_EQUAL(psa_get_key_type(&attributes), expected_type); - TEST_EQUAL(psa_get_key_bits(&attributes), expected_bits); + TEST_EQUAL(psa_get_key_type(&attributes), (psa_key_type_t) psa_type); + TEST_EQUAL(psa_get_key_bits(&attributes), (size_t) expected_bits); TEST_EQUAL(psa_get_key_lifetime(&attributes), PSA_KEY_LIFETIME_VOLATILE); @@ -1396,7 +1393,7 @@ void pk_psa_sign(int parameter_arg, hash, sizeof(hash), sig, sizeof(sig), &sig_len, NULL, NULL) == 0); /* Only opaque EC keys support verification. */ - if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(psa_type_arg)) { + if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(psa_type)) { TEST_ASSERT(mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256, hash, sizeof(hash), sig, sig_len) == 0); } @@ -1438,7 +1435,7 @@ void pk_psa_sign(int parameter_arg, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)), 0); TEST_EQUAL(mbedtls_ecp_group_load( &(mbedtls_pk_ec_rw(pk)->grp), - (mbedtls_ecp_group_id) parameter_arg), 0); + (mbedtls_ecp_group_id) curve_or_keybits), 0); TEST_EQUAL(mbedtls_ecp_point_read_binary(&(mbedtls_pk_ec_ro(pk)->grp), &(mbedtls_pk_ec_rw(pk)->Q), pkey_legacy_start, klen_legacy), 0); @@ -1459,9 +1456,8 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */ -void pk_sign_ext(int pk_type, int parameter, int key_pk_type, int md_alg) +void pk_sign_ext(int pk_type, int curve_or_keybits, int key_pk_type, int md_alg) { - /* See the description of pk_genkey() for the description of the `parameter` argument. */ mbedtls_pk_context pk; size_t sig_len; unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; @@ -1477,7 +1473,7 @@ void pk_sign_ext(int pk_type, int parameter, int key_pk_type, int md_alg) TEST_EQUAL(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(pk_type)), 0); - TEST_EQUAL(pk_genkey(&pk, parameter), 0); + TEST_EQUAL(pk_genkey(&pk, curve_or_keybits), 0); TEST_EQUAL(mbedtls_pk_sign_ext(key_pk_type, &pk, md_alg, hash, hash_len, sig, sizeof(sig), &sig_len, @@ -1498,9 +1494,8 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_GENPRIME:MBEDTLS_USE_PSA_CRYPTO */ -void pk_psa_wrap_sign_ext(int pk_type, int parameter, int key_pk_type, int md_alg) +void pk_psa_wrap_sign_ext(int pk_type, int key_bits, int key_pk_type, int md_alg) { - /* See the description of mbedtls_rsa_gen_key() for the description of the `parameter` argument. */ mbedtls_pk_context pk; size_t sig_len, pkey_len; mbedtls_svc_key_id_t key_id; @@ -1524,7 +1519,7 @@ void pk_psa_wrap_sign_ext(int pk_type, int parameter, int key_pk_type, int md_al mbedtls_pk_info_from_type(pk_type)), 0); TEST_EQUAL(mbedtls_rsa_gen_key(mbedtls_pk_rsa(pk), mbedtls_test_rnd_std_rand, NULL, - parameter, 3), 0); + key_bits, 3), 0); /* Export underlying public key for re-importing in a legacy context. */ ret = mbedtls_pk_write_pubkey_der(&pk, pkey, sizeof(pkey)); From 1941af087c3ab4e1ea1f796af959fe926e3a4a4d Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> Date: Thu, 14 Dec 2023 21:48:52 +0200 Subject: [PATCH 83/88] pk_wrap: remove last references to MBEDTLS_PSA_CRYPTO_C Deprecated functions are removed and #ifdefs are updated accordingly. Signed-off-by: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> --- library/pk_wrap.c | 122 +--------------------------------------------- library/pk_wrap.h | 22 +-------- 2 files changed, 3 insertions(+), 141 deletions(-) diff --git a/library/pk_wrap.c b/library/pk_wrap.c index b1fbd861d8..88572f815c 100644 --- a/library/pk_wrap.c +++ b/library/pk_wrap.c @@ -30,11 +30,8 @@ #include "pkwrite.h" #endif -#if defined(MBEDTLS_PSA_CRYPTO_C) -#include "psa_util_internal.h" -#endif - #if defined(MBEDTLS_USE_PSA_CRYPTO) +#include "psa_util_internal.h" #include "psa/crypto.h" #if defined(MBEDTLS_PK_CAN_ECDSA_SOME) @@ -49,123 +46,6 @@ #include #include -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(MBEDTLS_PSA_CRYPTO_C) -int mbedtls_pk_error_from_psa(psa_status_t status) -{ - switch (status) { - case PSA_SUCCESS: - return 0; - case PSA_ERROR_INVALID_HANDLE: - return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; - case PSA_ERROR_NOT_PERMITTED: - return MBEDTLS_ERR_ERROR_GENERIC_ERROR; - case PSA_ERROR_BUFFER_TOO_SMALL: - return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL; - case PSA_ERROR_NOT_SUPPORTED: - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - case PSA_ERROR_INVALID_ARGUMENT: - return MBEDTLS_ERR_PK_INVALID_ALG; - case PSA_ERROR_INSUFFICIENT_MEMORY: - return MBEDTLS_ERR_PK_ALLOC_FAILED; - case PSA_ERROR_BAD_STATE: - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - case PSA_ERROR_COMMUNICATION_FAILURE: - case PSA_ERROR_HARDWARE_FAILURE: - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - case PSA_ERROR_DATA_CORRUPT: - case PSA_ERROR_DATA_INVALID: - case PSA_ERROR_STORAGE_FAILURE: - return MBEDTLS_ERR_PK_FILE_IO_ERROR; - case PSA_ERROR_CORRUPTION_DETECTED: - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - default: - return MBEDTLS_ERR_ERROR_GENERIC_ERROR; - } -} - -#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \ - defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) -int mbedtls_pk_error_from_psa_rsa(psa_status_t status) -{ - switch (status) { - case PSA_ERROR_NOT_PERMITTED: - case PSA_ERROR_INVALID_ARGUMENT: - case PSA_ERROR_INVALID_HANDLE: - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; - case PSA_ERROR_BUFFER_TOO_SMALL: - return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; - case PSA_ERROR_INSUFFICIENT_ENTROPY: - return MBEDTLS_ERR_RSA_RNG_FAILED; - case PSA_ERROR_INVALID_SIGNATURE: - return MBEDTLS_ERR_RSA_VERIFY_FAILED; - case PSA_ERROR_INVALID_PADDING: - return MBEDTLS_ERR_RSA_INVALID_PADDING; - case PSA_SUCCESS: - return 0; - case PSA_ERROR_NOT_SUPPORTED: - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - case PSA_ERROR_INSUFFICIENT_MEMORY: - return MBEDTLS_ERR_PK_ALLOC_FAILED; - case PSA_ERROR_BAD_STATE: - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - case PSA_ERROR_COMMUNICATION_FAILURE: - case PSA_ERROR_HARDWARE_FAILURE: - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - case PSA_ERROR_DATA_CORRUPT: - case PSA_ERROR_DATA_INVALID: - case PSA_ERROR_STORAGE_FAILURE: - return MBEDTLS_ERR_PK_FILE_IO_ERROR; - case PSA_ERROR_CORRUPTION_DETECTED: - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - default: - return MBEDTLS_ERR_ERROR_GENERIC_ERROR; - } -} -#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */ -#endif /* MBEDTLS_PSA_CRYPTO_C */ - -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) -int mbedtls_pk_error_from_psa_ecdsa(psa_status_t status) -{ - switch (status) { - case PSA_ERROR_NOT_PERMITTED: - case PSA_ERROR_INVALID_ARGUMENT: - return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - case PSA_ERROR_INVALID_HANDLE: - return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; - case PSA_ERROR_BUFFER_TOO_SMALL: - return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; - case PSA_ERROR_INSUFFICIENT_ENTROPY: - return MBEDTLS_ERR_ECP_RANDOM_FAILED; - case PSA_ERROR_INVALID_SIGNATURE: - return MBEDTLS_ERR_ECP_VERIFY_FAILED; - case PSA_SUCCESS: - return 0; - case PSA_ERROR_NOT_SUPPORTED: - return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; - case PSA_ERROR_INSUFFICIENT_MEMORY: - return MBEDTLS_ERR_PK_ALLOC_FAILED; - case PSA_ERROR_BAD_STATE: - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - case PSA_ERROR_COMMUNICATION_FAILURE: - case PSA_ERROR_HARDWARE_FAILURE: - return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; - case PSA_ERROR_DATA_CORRUPT: - case PSA_ERROR_DATA_INVALID: - case PSA_ERROR_STORAGE_FAILURE: - return MBEDTLS_ERR_PK_FILE_IO_ERROR; - case PSA_ERROR_CORRUPTION_DETECTED: - return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - default: - return MBEDTLS_ERR_ERROR_GENERIC_ERROR; - } -} -#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ -#endif /* MBEDTLS_USE_PSA_CRYPTO */ -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - #if defined(MBEDTLS_RSA_C) static int rsa_can_do(mbedtls_pk_type_t type) { diff --git a/library/pk_wrap.h b/library/pk_wrap.h index a6237bf638..be096da53a 100644 --- a/library/pk_wrap.h +++ b/library/pk_wrap.h @@ -15,9 +15,9 @@ #include "mbedtls/pk.h" -#if defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_USE_PSA_CRYPTO) #include "psa/crypto.h" -#endif /* MBEDTLS_PSA_CRYPTO_C */ +#endif struct mbedtls_pk_info_t { /** Public key type */ @@ -125,12 +125,6 @@ extern const mbedtls_pk_info_t mbedtls_rsa_alt_info; extern const mbedtls_pk_info_t mbedtls_ecdsa_opaque_info; extern const mbedtls_pk_info_t mbedtls_rsa_opaque_info; -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) -int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa_ecdsa(psa_status_t status); -#endif -#endif - #if defined(MBEDTLS_RSA_C) int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t psa_alg_md, mbedtls_rsa_context *rsa_ctx, @@ -141,16 +135,4 @@ int mbedtls_pk_psa_rsa_sign_ext(psa_algorithm_t psa_alg_md, #endif /* MBEDTLS_USE_PSA_CRYPTO */ -#if defined(MBEDTLS_PSA_CRYPTO_C) -#if !defined(MBEDTLS_DEPRECATED_REMOVED) -int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa(psa_status_t status); - -#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) || \ - defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) -int MBEDTLS_DEPRECATED mbedtls_pk_error_from_psa_rsa(psa_status_t status); -#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */ -#endif /* !MBEDTLS_DEPRECATED_REMOVED */ - -#endif /* MBEDTLS_PSA_CRYPTO_C */ - #endif /* MBEDTLS_PK_WRAP_H */ From bad170e159ad9505301b973a0e22c05e74af622a Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> Date: Thu, 14 Dec 2023 22:03:12 +0200 Subject: [PATCH 84/88] pk: remove last references to MBEDTLS_PSA_CRYPTO_C They are replaced by MBEDTLS_USE_PSA_CRYPTO. Signed-off-by: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> --- include/mbedtls/pk.h | 15 +++++---------- library/pk.c | 6 +++--- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index 355bf10346..27768bd35a 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -28,7 +28,7 @@ #include "mbedtls/ecdsa.h" #endif -#if defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_USE_PSA_CRYPTO) #include "psa/crypto.h" #endif @@ -229,7 +229,7 @@ typedef struct mbedtls_pk_context { void *MBEDTLS_PRIVATE(pk_ctx); /**< Underlying public key context */ /* The following field is used to store the ID of a private key in the * following cases: - * - opaque key when MBEDTLS_PSA_CRYPTO_C is defined + * - opaque key when MBEDTLS_USE_PSA_CRYPTO is defined * - normal key when MBEDTLS_PK_USE_PSA_EC_DATA is defined. In this case: * - the pk_ctx above is not not used to store the private key anymore. * Actually that field not populated at all in this case because also @@ -239,15 +239,10 @@ typedef struct mbedtls_pk_context { * * Note: this private key storing solution only affects EC keys, not the * other ones. The latters still use the pk_ctx to store their own - * context. - * - * Note: this priv_id is guarded by MBEDTLS_PSA_CRYPTO_C and not by - * MBEDTLS_PK_USE_PSA_EC_DATA (as the public counterpart below) because, - * when working with opaque keys, it can be used also in - * mbedtls_pk_sign_ext for RSA keys. */ -#if defined(MBEDTLS_PSA_CRYPTO_C) + * context. */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) mbedtls_svc_key_id_t MBEDTLS_PRIVATE(priv_id); /**< Key ID for opaque keys */ -#endif /* MBEDTLS_PSA_CRYPTO_C */ +#endif /* MBEDTLS_USE_PSA_CRYPTO */ /* The following fields are meant for storing the public key in raw format * which is handy for: * - easily importing it into the PSA context diff --git a/library/pk.c b/library/pk.c index 929af3c653..61ac0dfab0 100644 --- a/library/pk.c +++ b/library/pk.c @@ -29,7 +29,7 @@ #include "mbedtls/ecdsa.h" #endif -#if defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_USE_PSA_CRYPTO) #include "psa_util_internal.h" #include "md_psa.h" #endif @@ -44,9 +44,9 @@ void mbedtls_pk_init(mbedtls_pk_context *ctx) { ctx->pk_info = NULL; ctx->pk_ctx = NULL; -#if defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_USE_PSA_CRYPTO) ctx->priv_id = MBEDTLS_SVC_KEY_ID_INIT; -#endif /* MBEDTLS_PSA_CRYPTO_C */ +#endif /* MBEDTLS_USE_PSA_CRYPTO */ #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) memset(ctx->pub_raw, 0, sizeof(ctx->pub_raw)); ctx->pub_raw_len = 0; From 5297e43eec42f590718814ab6c9b364d5145bc1d Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> Date: Thu, 14 Dec 2023 22:12:07 +0200 Subject: [PATCH 85/88] non-psa-pk-implementation: rephrase the changelog entry And remove the comment on the uniformity in the PK module with regards to PSA_CRYPTO_C not being referenced anymore; end users are probably not interested in that. Signed-off-by: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> --- ChangeLog.d/non-psa-pk-implementation.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ChangeLog.d/non-psa-pk-implementation.txt b/ChangeLog.d/non-psa-pk-implementation.txt index 88ed006544..a7129a6da6 100644 --- a/ChangeLog.d/non-psa-pk-implementation.txt +++ b/ChangeLog.d/non-psa-pk-implementation.txt @@ -1,4 +1,3 @@ Changes - * mbedtls_pk_sign_ext() is now available even without PSA - (MBEDTLS_PSA_CRYPTO_C). This improves uniformity in the PK module; - it now only depends on MBEDTLS_USE_PSA_CRYPTO for its use of PSA. + * mbedtls_pk_sign_ext() is now always available, not just when + PSA (MBEDTLS_PSA_CRYPTO_C) is enabled. \ No newline at end of file From 9f41770313af84b63d82f6ca768eb66457b36374 Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> Date: Sat, 16 Dec 2023 15:28:51 +0200 Subject: [PATCH 86/88] pk_*: remove remaining references to MBEDTLS_PSA_CRYPTO_C For real this time. Signed-off-by: Tomi Fontanilles <129057597+tomi-font@users.noreply.github.com> --- library/pk_internal.h | 22 ++++++++++------------ library/pk_wrap.c | 8 ++++---- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/library/pk_internal.h b/library/pk_internal.h index 81807f1338..d4b140aeff 100644 --- a/library/pk_internal.h +++ b/library/pk_internal.h @@ -19,7 +19,16 @@ #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "psa/crypto.h" -#endif + +#include "psa_util_internal.h" +#define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status) +#define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ + psa_to_pk_rsa_errors, \ + psa_pk_status_to_mbedtls) +#define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ + psa_to_pk_ecdsa_errors, \ + psa_pk_status_to_mbedtls) +#endif /* MBEDTLS_USE_PSA_CRYPTO */ /* Headers/footers for PEM files */ #define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----" @@ -35,17 +44,6 @@ #define PEM_BEGIN_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----BEGIN ENCRYPTED PRIVATE KEY-----" #define PEM_END_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----END ENCRYPTED PRIVATE KEY-----" -#if defined(MBEDTLS_PSA_CRYPTO_C) -#include "psa_util_internal.h" -#define PSA_PK_TO_MBEDTLS_ERR(status) psa_pk_status_to_mbedtls(status) -#define PSA_PK_RSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_pk_rsa_errors, \ - psa_pk_status_to_mbedtls) -#define PSA_PK_ECDSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ - psa_to_pk_ecdsa_errors, \ - psa_pk_status_to_mbedtls) -#endif - #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) /** * Public function mbedtls_pk_ec() can be used to get direct access to the diff --git a/library/pk_wrap.c b/library/pk_wrap.c index 88572f815c..9247945230 100644 --- a/library/pk_wrap.c +++ b/library/pk_wrap.c @@ -26,14 +26,14 @@ #include "mbedtls/ecdsa.h" #endif -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PSA_CRYPTO_C) -#include "pkwrite.h" -#endif - #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "psa_util_internal.h" #include "psa/crypto.h" +#if defined(MBEDTLS_RSA_C) +#include "pkwrite.h" +#endif + #if defined(MBEDTLS_PK_CAN_ECDSA_SOME) #include "mbedtls/asn1write.h" #include "mbedtls/asn1.h" From e6a664ed65a00478da7334f6bf3adf488205ec8c Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Mon, 18 Dec 2023 11:40:44 +0200 Subject: [PATCH 87/88] changelog: fix missing newline at end of file Signed-off-by: Tomi Fontanilles --- ChangeLog.d/non-psa-pk-implementation.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/non-psa-pk-implementation.txt b/ChangeLog.d/non-psa-pk-implementation.txt index a7129a6da6..535bbf55e6 100644 --- a/ChangeLog.d/non-psa-pk-implementation.txt +++ b/ChangeLog.d/non-psa-pk-implementation.txt @@ -1,3 +1,3 @@ Changes * mbedtls_pk_sign_ext() is now always available, not just when - PSA (MBEDTLS_PSA_CRYPTO_C) is enabled. \ No newline at end of file + PSA (MBEDTLS_PSA_CRYPTO_C) is enabled. From 851d8df58d2f1aa9e691e61321f29411bfaa843d Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Tue, 19 Dec 2023 15:44:52 +0200 Subject: [PATCH 88/88] fix/work around dependency issues when !MBEDTLS_ECP_C Signed-off-by: Tomi Fontanilles --- include/mbedtls/debug.h | 2 +- library/pk_internal.h | 4 ++-- library/pkparse.c | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/debug.h b/include/mbedtls/debug.h index 9a17488d2b..922e5bec52 100644 --- a/include/mbedtls/debug.h +++ b/include/mbedtls/debug.h @@ -230,7 +230,7 @@ void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level, const char *text, const mbedtls_mpi *X); #endif -#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_LIGHT) /** * \brief Print an ECP point to the debug output. This function is always * used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the diff --git a/library/pk_internal.h b/library/pk_internal.h index d4b140aeff..025ee8b019 100644 --- a/library/pk_internal.h +++ b/library/pk_internal.h @@ -44,7 +44,7 @@ #define PEM_BEGIN_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----BEGIN ENCRYPTED PRIVATE KEY-----" #define PEM_END_ENCRYPTED_PRIVATE_KEY_PKCS8 "-----END ENCRYPTED PRIVATE KEY-----" -#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) +#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA) /** * Public function mbedtls_pk_ec() can be used to get direct access to the * wrapped ecp_keypair structure pointed to the pk_ctx. However this is not @@ -80,7 +80,7 @@ static inline mbedtls_ecp_keypair *mbedtls_pk_ec_rw(const mbedtls_pk_context pk) return NULL; } } -#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */ +#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */ #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) static inline mbedtls_ecp_group_id mbedtls_pk_get_ec_group_id(const mbedtls_pk_context *pk) diff --git a/library/pkparse.c b/library/pkparse.c index c33b74203b..6ce7fcf1d1 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -15,6 +15,7 @@ #include "mbedtls/platform_util.h" #include "mbedtls/platform.h" #include "mbedtls/error.h" +#include "mbedtls/ecp.h" #include "pk_internal.h" #include @@ -28,9 +29,6 @@ #if defined(MBEDTLS_RSA_C) #include "mbedtls/rsa.h" #endif -#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) -#include "mbedtls/ecp.h" -#endif /* Extended formats */ #if defined(MBEDTLS_PEM_PARSE_C)