From 7ee4cc302a113edf92ff231573a52eb5b3964ba9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 28 Nov 2023 15:49:57 +0100 Subject: [PATCH 001/215] Create legacy-API bridge API design document Do the analysis for hashes. Signed-off-by: Gilles Peskine --- .../psa-migration/psa-legacy-bridges.md | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 docs/architecture/psa-migration/psa-legacy-bridges.md diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md new file mode 100644 index 000000000..e8f20b2b6 --- /dev/null +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -0,0 +1,137 @@ +Bridges between legacy and PSA crypto APIs +========================================== + +## Introduction + +### Goal of this document + +This document explores the needs of applications that use both Mbed TLS legacy crypto interfaces and PSA crypto interfaces. Based on [requirements](#requirements), we [analyze gaps](#gap-analysis) and [API design](#api-design). + +This is a design document. The target audience is library maintainers. See the companion document [“Transitioning to the PSA API”](../../psa-transition.md) for a user focus on the same topic. + +### Keywords + +* [TODO] A part of the analysis that isn't finished. +* [QUESTION] A specific aspect of the design where there are several plausible decisions. +* [ACTION] A finalized part of the design that will need to be carried out. + +### Context + +Mbed TLS 3.x supports two cryptographic APIs: + +* The legacy API `mbedtls_xxx` is inherited from PolarSSL. +* The PSA API `psa_xxx` was introduced in Mbed TLS 2.17. + +Mbed TLS is gradually shifting from the legacy API to the PSA API. Mbed TLS 4.0 will be the first version where the PSA API is considered the main API, and large parts of the legacy API will be removed. + +In Mbed TLS 4.0, the cryptography will be provided by a separate project [TF-PSA-Crypto](https://github.com/Mbed-TLS/TF-PSA-Crypto). For simplicity, in this document, we just refer to the whole as “Mbed TLS”. + +### Document history + +This document was originally written when preparing Mbed TLS 3.6. Mbed TLS 3.6 includes both PSA and legacy APIs covering largely overlapping ground. Many legacy APIs will be removed in Mbed TLS 4.0. + +## Requirements + +### Why mix APIs? + +There is functionality that is tied to one API and is not directly available in the other API: + +* Only PSA fully supports PSA accelerators and secure element integration. +* Only PSA supports isolating cryptographic material in a secure service. +* The legacy API has features that are not present (yet) in PSA, notably parsing and formatting asymmetric keys. + +The legacy API can partially leverage PSA features via `MBEDTLS_USE_PSA_CRYPTO`, but this has limited scope. + +In addition, many applications cannot be migrated in a single go. For large projects, it is impractical to rewrite a significant part of the code all at once. (For example, Mbed TLS itself will have taken more than 6 years to transition.) Projects that use one or more library in addition to Mbed TLS must follow the evolution of these libraries, each of which might have its own pace. + +### Where mixing happens + +Mbed TLS can be, and normally is, built with support for both APIs. Therefore no special effort is necessary to allow an application to use both APIs. + +Special effort is necessary to use both APIs as part of the implementation of the same feature. From an informal analysis of typical application requirements, we identify four parts of the use of cryptography which can be provided by different APIs: + +* Metadata manipulation: parsing and producing encrypted or signed files, finding mutually supported algorithms in a network protocol negotiation, etc. +* Key management: parsing, generating, deriving and formatting cryptographic keys. +* Data manipulation other than keys. In practice, most data formats within the scope of the legacy crypto APIs are trivial (ciphertexts, hashes, MACs, shared secrets). The one exception is ECDSA signatures. +* Cryptographic operations: hash, sign, encrypt, etc. + +From this, we deduce the following requirements: + +* Convert between PSA and legacy metadata. +* Creating a key with the legacy API and consuming it in the PSA API. +* Creating a key with the PSA API and consuming it in the legacy API. +* Manipulating data formats, other than keys, where the PSA API is lacking. + +### Scope limitations + +The goal of this document is to bridge the legacy API and the PSA API. The goal is not to provide a PSA way to do everything that is currently possible with the legacy API. The PSA API is less flexible in some regards, and extending it is out of scope in the present study. + +With respect to the legacy API, we do not consider functionality of low-level modules for individual algorithms. Our focus is on applications that use high-level legacy crypto modules (md, cipher, pk) and need to combine that with uses of the PSA APIs. + +## Gap analysis + +Based on “[Where mixing happens](#where-mixing-happens)”, we focus the gap analysis on two topics: metadata and keys. This chapter explores the gaps in each family of cryptographic mechanisms. + +### Generic metadata gaps + +#### Need for error code conversion + +[QUESTION] Do we need public functions to convert between `MBEDTLS_ERR_xxx` error codes and `PSA_ERROR_xxx` error codes? We have such functions for internal use. + +### Hash gap analysis + +Hashes do not involve keys, and involves no nontrivial data format. Therefore the only gap is with metadata, namely specifying a hash algorithm. + +Hashes are often used as building blocks for other mechanisms (HMAC, signatures, key derivation, etc.). Therefore metadata about hashes is relevant not only when calculating hashes, but also when performing many other cryptographic operations. + +Gap: functions to convert between `psa_algorithm_t` hash algorithms and `mbedtls_md_type_t`. Such functions exist in Mbed TLS 3.5 (`mbedtls_md_psa_alg_from_type`, `mbedtls_md_type_from_psa_alg`) but they are declared only in private headers. + +### MAC gap analysis + +[TODO] + +### Cipher and AEAD gap analysis + +[TODO] + +### Key derivation gap analysis + +[TODO] + +### Random generation gap analysis + +[TODO] + +### Asymmetric cryptography gap analysis + +[TODO] + +## New APIs + +This section presents new APIs to implement based on the [gap analysis](#gap-analysis). + +### Hash APIs + +Based on the [gap analysis](#hash-gap-analysis): + +[ACTION] Move `mbedtls_md_psa_alg_from_type` and `mbedtls_md_type_from_psa_alg` from `library/md_psa.h` to `include/mbedtls/md.h`. + +### MAC APIs + +[TODO] + +### Cipher and AEAD APIs + +[TODO] + +### Key derivation APIs + +[TODO] + +### Random generation APIs + +[TODO] + +### Asymmetric cryptography APIs + +[TODO] From e6886102ef23ad38dd8e3ac8df1e26f34c22c75e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 21 Jun 2023 18:22:06 +0200 Subject: [PATCH 002/215] New function mbedtls_ecp_keypair_get_group_id Add a simple function to get the group id from a key object. This information is available via mbedtls_ecp_export, but that function consumes a lot of memory, which is a waste if all you need is to identify the curve. Signed-off-by: Gilles Peskine --- include/mbedtls/ecp.h | 12 ++++++++++++ library/ecp.c | 6 ++++++ tests/suites/test_suite_ecp.function | 6 ++++++ 3 files changed, 24 insertions(+) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 7f5e88080..a29a6f7a6 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1323,6 +1323,18 @@ int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); +/** \brief Query the group that a key pair belongs to. + * + * \param key The key pair to query. + * + * \return The group ID for the group registered in the key pair + * object. + * This is \c MBEDTLS_ECP_DP_NONE if no group has been set + * in the key pair object. + */ +mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id( + const mbedtls_ecp_keypair *key); + /** * \brief This function exports generic key-pair parameters. * diff --git a/library/ecp.c b/library/ecp.c index ee86cbc6e..351e9e8fe 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -3357,6 +3357,12 @@ cleanup: } #endif /* MBEDTLS_ECP_C */ +mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id( + const mbedtls_ecp_keypair *key) +{ + return key->grp.id; +} + /* * Export generic key-pair parameters. */ diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 575162480..58d54ed08 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1030,6 +1030,7 @@ void mbedtls_ecp_gen_key(int id) &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0); + TEST_EQUAL(mbedtls_ecp_keypair_get_group_id(&key), id); TEST_ASSERT(mbedtls_ecp_check_pubkey(&key.grp, &key.Q) == 0); TEST_ASSERT(mbedtls_ecp_check_privkey(&key.grp, &key.d) == 0); @@ -1052,6 +1053,7 @@ void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonica TEST_ASSERT(ret == expected); if (expected == 0) { + TEST_EQUAL(mbedtls_ecp_keypair_get_group_id(&key), grp_id); ret = mbedtls_ecp_check_privkey(&key.grp, &key.d); TEST_ASSERT(ret == 0); @@ -1233,6 +1235,10 @@ void ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int inval TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0); TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0); TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0); + + /* Check consistency with the group id */ + TEST_EQUAL(export_grp.id, + mbedtls_ecp_keypair_get_group_id(&key)); } exit: From ba5b5d67aa10e3c7dc5d2136efc226368df1b262 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 21 Jun 2023 18:24:04 +0200 Subject: [PATCH 003/215] Support partial export from mbedtls_ecp_keypair Sometimes you don't need to have all the parts of a key pair object. Relax the behavior of mbedtls_ecp_keypair so that you can extract just the parts that you need. Signed-off-by: Gilles Peskine --- include/mbedtls/ecp.h | 9 ++++++--- library/ecp.c | 6 +++--- tests/suites/test_suite_ecp.function | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index a29a6f7a6..9effb725d 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1338,13 +1338,16 @@ mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id( /** * \brief This function exports generic key-pair parameters. * + * Each of the output parameters can be a null pointer + * if you do not need that parameter. + * * \param key The key pair to export from. * \param grp Slot for exported ECP group. - * It must point to an initialized ECP group. + * It must either be null or point to an initialized ECP group. * \param d Slot for the exported secret value. - * It must point to an initialized mpi. + * It must either be null or point to an initialized mpi. * \param Q Slot for the exported public value. - * It must point to an initialized ECP point. + * It must either be null or point to an initialized ECP point. * * \return \c 0 on success, * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. diff --git a/library/ecp.c b/library/ecp.c index 351e9e8fe..b4da3c50f 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -3371,15 +3371,15 @@ int mbedtls_ecp_export(const mbedtls_ecp_keypair *key, mbedtls_ecp_group *grp, { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - if ((ret = mbedtls_ecp_group_copy(grp, &key->grp)) != 0) { + if (grp != NULL && (ret = mbedtls_ecp_group_copy(grp, &key->grp)) != 0) { return ret; } - if ((ret = mbedtls_mpi_copy(d, &key->d)) != 0) { + if (d != NULL && (ret = mbedtls_mpi_copy(d, &key->d)) != 0) { return ret; } - if ((ret = mbedtls_ecp_copy(Q, &key->Q)) != 0) { + if (Q != NULL && (ret = mbedtls_ecp_copy(Q, &key->Q)) != 0) { return ret; } diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 58d54ed08..a4c86e283 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1239,6 +1239,20 @@ void ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int inval /* Check consistency with the group id */ TEST_EQUAL(export_grp.id, mbedtls_ecp_keypair_get_group_id(&key)); + + /* Test null arguments */ + mbedtls_ecp_group_free(&export_grp); + mbedtls_mpi_free(&export_d); + mbedtls_ecp_point_free(&export_Q); + mbedtls_ecp_group_init(&export_grp); + mbedtls_mpi_init(&export_d); + mbedtls_ecp_point_init(&export_Q); + TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp, NULL, NULL), 0); + TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0); + TEST_EQUAL(mbedtls_ecp_export(&key, NULL, &export_d, NULL), 0); + TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0); + TEST_EQUAL(mbedtls_ecp_export(&key, NULL, NULL, &export_Q), 0); + TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0); } exit: From 091a85a7624aa452f46d3090718631907c04f215 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 21 Jun 2023 19:51:28 +0200 Subject: [PATCH 004/215] Promise mbedtls_ecp_read_key doesn't overwrite the public key Signed-off-by: Gilles Peskine --- include/mbedtls/ecp.h | 10 ++++++++++ tests/suites/test_suite_ecp.function | 15 +++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 9effb725d..f1690085a 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1262,6 +1262,16 @@ int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, /** * \brief This function reads an elliptic curve private key. * + * \note This function does not set the public key in the + * key pair object. Without a public key, the key pair object + * cannot be used with operations that require the public key. + * + * \note If a public key has already been set in the key pair + * object, this function does not check that it is consistent + * with the private key. Call mbedtls_ecp_check_pub_priv() + * after setting both the public key and the private key + * to make that check. + * * \param grp_id The ECP group identifier. * \param key The destination key. * \param buf The buffer containing the binary representation of the diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index a4c86e283..aefb57a58 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1044,11 +1044,16 @@ void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonica { int ret = 0; mbedtls_ecp_keypair key; - mbedtls_ecp_keypair key2; - mbedtls_ecp_keypair_init(&key); + mbedtls_ecp_keypair key2; mbedtls_ecp_keypair_init(&key2); +#if defined(MBEDTLS_BIGNUM_C) + TEST_EQUAL(mbedtls_mpi_lset(&key.Q.X, 1), 0); + TEST_EQUAL(mbedtls_mpi_lset(&key.Q.Y, 2), 0); + TEST_EQUAL(mbedtls_mpi_lset(&key.Q.Z, 3), 0); +#endif + ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len); TEST_ASSERT(ret == expected); @@ -1057,6 +1062,12 @@ void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonica ret = mbedtls_ecp_check_privkey(&key.grp, &key.d); TEST_ASSERT(ret == 0); +#if defined(MBEDTLS_BIGNUM_C) + TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.X, 1), 0); + TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.Y, 2), 0); + TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.Z, 3), 0); +#endif + if (canonical) { unsigned char buf[MBEDTLS_ECP_MAX_BYTES]; From 28240323d3246908aff6379022bebf5678673c98 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 21 Jun 2023 19:52:11 +0200 Subject: [PATCH 005/215] New function mbedtls_ecp_set_public_key Set the public key in a key pair. This complements mbedtls_ecp_read_key and the functions can be used in either order. Document the need to call check functions separately. Signed-off-by: Gilles Peskine --- include/mbedtls/ecp.h | 32 +++++++++ library/ecp.c | 19 +++++ tests/suites/test_suite_ecp.data | 42 +++++++++++ tests/suites/test_suite_ecp.function | 103 +++++++++++++++++++++++++++ 4 files changed, 196 insertions(+) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index f1690085a..96f030d1f 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1259,6 +1259,38 @@ int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); +/** \brief Set the public key in a key pair object. + * + * \note This function does not check that the point actually + * belongs to the given group. Call mbedtls_ecp_check_pubkey() + * on \p Q before calling this function to check that. + * + * \note This function does not check that the public key matches + * the private key that is already in \p key, if any. + * To check the consistency of the resulting key pair object, + * call mbedtls_ecp_check_pub_priv() after setting both + * the public key and the private key. + * + * \param grp_id The ECP group identifier. + * \param key The key pair object. It must be initialized. + * If its group has already been set, it must match \p grp_id. + * If its group has not been set, it will be set to \p grp_id. + * If the public key has already been set, it is overwritten. + * \param Q The public key to copy. This must be a point on the + * curve indicated by \p grp_id. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p key does not + * match \p grp_id. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for + * the group is not implemented. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id, + mbedtls_ecp_keypair *key, + const mbedtls_ecp_point *Q); + /** * \brief This function reads an elliptic curve private key. * diff --git a/library/ecp.c b/library/ecp.c index b4da3c50f..bb0cf6905 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -3198,6 +3198,25 @@ int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, } #endif /* MBEDTLS_ECP_C */ +int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id, + mbedtls_ecp_keypair *key, + const mbedtls_ecp_point *Q) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if (key->grp.id == MBEDTLS_ECP_DP_NONE) { + /* Group not set yet */ + if ((ret = mbedtls_ecp_group_load(&key->grp, grp_id)) != 0) { + return ret; + } + } else if (key->grp.id != grp_id) { + /* Group mismatch */ + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + return mbedtls_ecp_copy(&key->Q, Q); +} + + #define ECP_CURVE25519_KEY_SIZE 32 #define ECP_CURVE448_KEY_SIZE 56 /* diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 100299195..8bf288b79 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -581,6 +581,48 @@ genkey_mx_known_answer:447:"ffffffffffffffffffffffffffffffffffffffffffffffffffff ECP generate Montgomery key: Curve448, not enough entropy genkey_mx_known_answer:447:"4f0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536":"" +ECP set public key: invalid group (0) +ecp_set_public_key_group_check:MBEDTLS_ECP_DP_NONE:MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE + +ECP set public key: valid group (secp256r1) +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_set_public_key_group_check:MBEDTLS_ECP_DP_SECP256R1:0 + +ECP set public key: group not supported (secp256r1) +depends_on:!MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_set_public_key_group_check:MBEDTLS_ECP_DP_SECP256R1:MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE + +ECP set public key: bad group (not in enum) +ecp_set_public_key_group_check:MBEDTLS_ECP_DP_MAX:MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE + +ECP set public key: good, secp256r1 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_set_public_key_good:MBEDTLS_ECP_DP_SECP256R1:"04e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e0e1ff20e1ffe120e1e1e173287170a761308491683e345cacaebb500c96e1a7bbd37772968b2c951f0579" + +ECP set public key: good, Curve25519 +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_set_public_key_good:MBEDTLS_ECP_DP_CURVE25519:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a" + +ECP set public key after private: good, secp256r1 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_set_public_key_after_private:MBEDTLS_ECP_DP_SECP256R1:"70726976617465206b6579":MBEDTLS_ECP_DP_SECP256R1:"04e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e0e1ff20e1ffe120e1e1e173287170a761308491683e345cacaebb500c96e1a7bbd37772968b2c951f0579" + +ECP set public key after private: good, Curve25519 +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_set_public_key_after_private:MBEDTLS_ECP_DP_CURVE25519:"70076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c6a":MBEDTLS_ECP_DP_CURVE25519:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a" + +ECP set public key after private: secp256r1 then secp256k1 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP256K1_ENABLED +ecp_set_public_key_after_private:MBEDTLS_ECP_DP_SECP256R1:"70726976617465206b6579":MBEDTLS_ECP_DP_SECP256K1:"04e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e0e1ff20e1ffe120e1e1e173287170a761308491683e345cacaebb500c96e1a7bbd37772968b2c951f0579" + +ECP set public key after private: secp256r1 then secp384r1 +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED +ecp_set_public_key_after_private:MBEDTLS_ECP_DP_SECP256R1:"70726976617465206b6579":MBEDTLS_ECP_DP_SECP384R1:"04aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaae1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e0e1ff20e1ffe120e1e1e173287170a761308491683e345cacaebb500c96e1a7bbd37772968b2c951f0579bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + +ECP set public key after private: secp384r1 then secp256r1 +depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_set_public_key_after_private:MBEDTLS_ECP_DP_SECP384R1:"70726976617465206b6579":MBEDTLS_ECP_DP_SECP256R1:"04e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e0e1ff20e1ffe120e1e1e173287170a761308491683e345cacaebb500c96e1a7bbd37772968b2c951f0579" + ECP read key #1 (short weierstrass, too small) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"00":MBEDTLS_ERR_ECP_INVALID_KEY:0 diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index aefb57a58..53b78d900 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1039,6 +1039,109 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void ecp_set_public_key_group_check(int grp_id, int expected_ret) +{ + mbedtls_ecp_keypair key; + mbedtls_ecp_keypair_init(&key); + mbedtls_ecp_point Q; + mbedtls_ecp_point_init(&Q); + + TEST_EQUAL(mbedtls_ecp_set_public_key(grp_id, &key, &Q), + expected_ret); + +exit: + mbedtls_ecp_keypair_free(&key); + mbedtls_ecp_point_free(&Q); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void ecp_set_public_key_good(int grp_id, data_t *public_data) +{ + mbedtls_ecp_keypair key; + mbedtls_ecp_keypair_init(&key); + mbedtls_ecp_group grp; + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point Q; + mbedtls_ecp_point_init(&Q); + + TEST_EQUAL(mbedtls_ecp_group_load(&grp, grp_id), 0); + TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &Q, + public_data->x, public_data->len), + 0); + + /* Freshly initialized key */ + TEST_EQUAL(mbedtls_ecp_set_public_key(grp_id, &key, &Q), 0); + TEST_EQUAL(key.grp.id, grp_id); + TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &Q), 0); + +#if defined(MBEDTLS_BIGNUM_C) + /* Key with a public key already set to a different value */ + TEST_EQUAL(mbedtls_mpi_add_int(&key.Q.X, &key.Q.X, 1), 0); + TEST_EQUAL(mbedtls_mpi_add_int(&key.Q.Y, &key.Q.Y, 1), 0); + TEST_EQUAL(mbedtls_mpi_add_int(&key.Q.Z, &key.Q.Z, 1), 0); + TEST_EQUAL(mbedtls_ecp_set_public_key(grp_id, &key, &Q), 0); + TEST_EQUAL(key.grp.id, grp_id); + TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &Q), 0); +#endif + +exit: + mbedtls_ecp_keypair_free(&key); + mbedtls_ecp_group_free(&grp); + mbedtls_ecp_point_free(&Q); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void ecp_set_public_key_after_private(int private_grp_id, data_t *private_data, + int public_grp_id, data_t *public_data) +{ + mbedtls_ecp_keypair key; + mbedtls_ecp_keypair_init(&key); + mbedtls_ecp_group grp; + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point Q; + mbedtls_ecp_point_init(&Q); +#if defined(MBEDTLS_BIGNUM_C) + mbedtls_mpi d; + mbedtls_mpi_init(&d); +#endif + + TEST_EQUAL(mbedtls_ecp_group_load(&grp, public_grp_id), 0); + TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &Q, + public_data->x, public_data->len), + 0); + TEST_EQUAL(mbedtls_ecp_read_key(private_grp_id, &key, + private_data->x, private_data->len), + 0); +#if defined(MBEDTLS_BIGNUM_C) + TEST_EQUAL(mbedtls_mpi_copy(&d, &key.d), 0); +#endif + + int ret = mbedtls_ecp_set_public_key(public_grp_id, &key, &Q); + + if (private_grp_id == public_grp_id) { + TEST_EQUAL(ret, 0); + TEST_EQUAL(key.grp.id, public_grp_id); + TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &Q), 0); +#if defined(MBEDTLS_BIGNUM_C) + TEST_EQUAL(mbedtls_mpi_cmp_mpi(&d, &key.d), 0); +#endif + } else { + TEST_EQUAL(ret, MBEDTLS_ERR_ECP_BAD_INPUT_DATA); + } + +exit: + mbedtls_ecp_keypair_free(&key); + mbedtls_ecp_group_free(&grp); + mbedtls_ecp_point_free(&Q); +#if defined(MBEDTLS_BIGNUM_C) + mbedtls_mpi_free(&d); +#endif +} +/* END_CASE */ + /* BEGIN_CASE */ void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical) { From 7ea72026cde2d9c9e0cc6141f0d8f34493163189 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 21 Jun 2023 20:39:08 +0200 Subject: [PATCH 006/215] New function mbedtls_ecp_keypair_calc_public For when you calculate or import a private key, and then need to calculate the public key. Signed-off-by: Gilles Peskine --- include/mbedtls/ecp.h | 17 ++++++++++++++ library/ecp.c | 8 +++++++ tests/suites/test_suite_ecp.data | 18 +++++++++++++++ tests/suites/test_suite_ecp.function | 34 ++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 96f030d1f..1847f2cb2 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1365,6 +1365,23 @@ int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); +/** \brief Calculate the public key from a private key in a key pair. + * + * \param key A keypair structure. It must have a private key set. + * If the public key is set, it will be overwritten. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c + * NULL if \p f_rng doesn't need a context. + * + * \return \c 0 on success. The key pair object can be used for + * operations that require the public key. + * \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX + * error code on calculation failure. + */ +int mbedtls_ecp_keypair_calc_public( + mbedtls_ecp_keypair *key, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); + /** \brief Query the group that a key pair belongs to. * * \param key The key pair to query. diff --git a/library/ecp.c b/library/ecp.c index bb0cf6905..43f7d6930 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -3374,6 +3374,14 @@ cleanup: return ret; } + +int mbedtls_ecp_keypair_calc_public(mbedtls_ecp_keypair *key, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + return mbedtls_ecp_mul(&key->grp, &key->Q, &key->d, &key->grp.G, + f_rng, p_rng); +} #endif /* MBEDTLS_ECP_C */ mbedtls_ecp_group_id mbedtls_ecp_keypair_get_group_id( diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 8bf288b79..01fdc477f 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -529,6 +529,24 @@ ECP check public-private #7 (wrong Qy) depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED mbedtls_ecp_check_pub_priv:MBEDTLS_ECP_DP_SECP256R1:"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edfe":MBEDTLS_ECP_DP_SECP256R1:"00f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":"37cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f76822596292":"4ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edfe":MBEDTLS_ERR_ECP_BAD_INPUT_DATA +ECP calculate public: secp256r1, good +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_calc_public:MBEDTLS_ECP_DP_SECP256R1:"00f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":0:"0437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edff" + +ECP calculate public: secp256r1, private value out of range +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_calc_public:MBEDTLS_ECP_DP_SECP256R1:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":MBEDTLS_ERR_ECP_INVALID_KEY:"" + +# Alice's private key from rfc 7748, masked and adjusted for endianness +# because the test function wants the little-endian representation. +ECP calculate public: Curve25519, good +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_calc_public:MBEDTLS_ECP_DP_CURVE25519:"6a2cb91da5fb77b12a99c0eb872f4cdf4566b25172c1163c7da518730a6d0770":0:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a" + +ECP calculate public: Curve25519, private value not masked +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_calc_public:MBEDTLS_ECP_DP_CURVE25519:"2a2cb91da5fb77b12a99c0eb872f4cdf4566b25172c1163c7da518730a6d0770":MBEDTLS_ERR_ECP_INVALID_KEY:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a" + ECP gen keypair [#1] depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED mbedtls_ecp_gen_keypair:MBEDTLS_ECP_DP_SECP192R1 diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 53b78d900..8c8d32699 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -988,6 +988,40 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */ +void ecp_calc_public(int grp_id, data_t *private, + int expected_ret, data_t *expected_public) +{ + mbedtls_ecp_keypair key; + mbedtls_ecp_keypair_init(&key); + mbedtls_test_rnd_pseudo_info rnd_info; + memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info)); + + TEST_EQUAL(mbedtls_ecp_group_load(&key.grp, grp_id), 0); + TEST_EQUAL(mbedtls_mpi_read_binary(&key.d, private->x, private->len), 0); + + TEST_EQUAL(mbedtls_ecp_keypair_calc_public(&key, + &mbedtls_test_rnd_pseudo_rand, &rnd_info), + expected_ret); + + if (expected_ret == 0) { + TEST_EQUAL(mbedtls_ecp_check_pub_priv(&key, &key, + &mbedtls_test_rnd_pseudo_rand, &rnd_info), + 0); + unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN]; + size_t length; + TEST_EQUAL(mbedtls_ecp_point_write_binary(&key.grp, &key.Q, + MBEDTLS_ECP_PF_UNCOMPRESSED, + &length, buf, sizeof(buf)), + 0); + ASSERT_COMPARE(expected_public->x, expected_public->len, buf, length); + } + +exit: + mbedtls_ecp_keypair_free(&key); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_ECP_C */ void mbedtls_ecp_gen_keypair(int id) { From ad5e437c8e185d6a6d5ffc5c6e295475d560669c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 22 Dec 2023 21:59:46 +0100 Subject: [PATCH 007/215] mbedtls_ecp_read_key: explain how to set the public key Signed-off-by: Gilles Peskine --- include/mbedtls/ecp.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 1847f2cb2..fc0a7636b 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1297,6 +1297,11 @@ int mbedtls_ecp_set_public_key(mbedtls_ecp_group_id grp_id, * \note This function does not set the public key in the * key pair object. Without a public key, the key pair object * cannot be used with operations that require the public key. + * Call mbedtls_ecp_keypair_calc_public() to set the public + * key from the private key. Alternatively, you can call + * mbedtls_ecp_set_public_key() to set the public key part, + * and then optionally mbedtls_ecp_check_pub_priv() to check + * that the private and public parts are consistent. * * \note If a public key has already been set in the key pair * object, this function does not check that it is consistent From 6dd87384ae26c5c828997b582b78265f7c355d50 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 22 Jun 2023 20:27:19 +0200 Subject: [PATCH 008/215] Rename variable that's a C++ keyword It gave uncrustify trouble (https://github.com/uncrustify/uncrustify/issues/4044) Signed-off-by: Gilles Peskine --- tests/suites/test_suite_ecp.function | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 8c8d32699..354a92cec 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -989,7 +989,7 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_ECP_C */ -void ecp_calc_public(int grp_id, data_t *private, +void ecp_calc_public(int grp_id, data_t *private_data, int expected_ret, data_t *expected_public) { mbedtls_ecp_keypair key; @@ -998,7 +998,8 @@ void ecp_calc_public(int grp_id, data_t *private, memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info)); TEST_EQUAL(mbedtls_ecp_group_load(&key.grp, grp_id), 0); - TEST_EQUAL(mbedtls_mpi_read_binary(&key.d, private->x, private->len), 0); + TEST_EQUAL(mbedtls_mpi_read_binary(&key.d, + private_data->x, private_data->len), 0); TEST_EQUAL(mbedtls_ecp_keypair_calc_public(&key, &mbedtls_test_rnd_pseudo_rand, &rnd_info), From 62e33bcc64c05027a5873830b7a26dbdbb84f282 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 22 Jun 2023 22:27:32 +0200 Subject: [PATCH 009/215] New function mbedtls_ecp_write_public_key Directly export the public part of a key pair without having to go through intermediate objects (using mbedtls_ecp_point_write_binary would require a group object and a point object). Signed-off-by: Gilles Peskine --- include/mbedtls/ecp.h | 26 ++++++++++++++++++++++++ library/ecp.c | 12 +++++++++++ tests/suites/test_suite_ecp.function | 30 +++++++++++++++++++--------- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index fc0a7636b..619a8a51a 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1346,6 +1346,32 @@ int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key, unsigned char *buf, size_t buflen); +/** + * \brief This function exports an elliptic curve public key. + * + * \param key The public key. + * \param format The point format. This must be either + * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. + * (For groups without these formats, this parameter is + * ignored. But it still has to be either of the above + * values.) + * \param olen The address at which to store the length of + * the output in Bytes. This must not be \c NULL. + * \param buf The output buffer. This must be a writable buffer + * of length \p buflen Bytes. + * \param buflen The length of the output buffer \p buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer + * is too small to hold the point. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format + * or the export for the given group is not implemented. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_write_public_key(mbedtls_ecp_keypair *key, + int format, size_t *olen, + unsigned char *buf, size_t buflen); + /** * \brief This function checks that the keypair objects * \p pub and \p prv have the same group and the diff --git a/library/ecp.c b/library/ecp.c index 43f7d6930..12924bf32 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -3333,6 +3333,18 @@ cleanup: return ret; } +/* + * Write a public key. + */ +int mbedtls_ecp_write_public_key(mbedtls_ecp_keypair *key, + int format, size_t *olen, + unsigned char *buf, size_t buflen) +{ + return mbedtls_ecp_point_write_binary(&key->grp, &key->Q, + format, olen, buf, buflen); +} + + #if defined(MBEDTLS_ECP_C) /* * Check a public-private key pair diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 354a92cec..ced4ca387 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -590,29 +590,41 @@ void ecp_write_binary(int id, char *x, char *y, char *z, int format, { mbedtls_ecp_group grp; mbedtls_ecp_point P; + mbedtls_ecp_keypair key; unsigned char buf[256]; size_t olen; memset(buf, 0, sizeof(buf)); mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P); + mbedtls_ecp_keypair_init(&key); - TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); + TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0); - TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x) == 0); - TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y) == 0); - TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z) == 0); - - TEST_ASSERT(mbedtls_ecp_point_write_binary(&grp, &P, format, - &olen, buf, blen) == ret); + TEST_EQUAL(mbedtls_test_read_mpi(&P.X, x), 0); + TEST_EQUAL(mbedtls_test_read_mpi(&P.Y, y), 0); + TEST_EQUAL(mbedtls_test_read_mpi(&P.Z, z), 0); + TEST_EQUAL(mbedtls_ecp_point_write_binary(&grp, &P, format, + &olen, buf, blen), ret); if (ret == 0) { - TEST_ASSERT(olen <= MBEDTLS_ECP_MAX_PT_LEN); - TEST_ASSERT(mbedtls_test_hexcmp(buf, out->x, olen, out->len) == 0); + TEST_LE_U(olen, MBEDTLS_ECP_MAX_PT_LEN); + ASSERT_COMPARE(buf, olen, + out->x, out->len); + } + + memset(buf, 0, blen); + TEST_EQUAL(mbedtls_ecp_set_public_key(grp.id, &key, &P), 0); + TEST_EQUAL(mbedtls_ecp_write_public_key(&key, format, + &olen, buf, blen), ret); + if (ret == 0) { + ASSERT_COMPARE(buf, olen, + out->x, out->len); } exit: mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P); + mbedtls_ecp_keypair_free(&key); } /* END_CASE */ From 52cc2a6368872eb2116bc3ed1066e884920e91fa Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 22 Jun 2023 22:32:05 +0200 Subject: [PATCH 010/215] Use new mbedtls_ecp_keypair functions in sample programs This eliminates the use of MBEDTLS_PRIVATE in sample programs to access fields of an mbedtls_ecp_keypair structure. When displaying elliptic curve points, the program now display the coordinates in the standard form instead of the internal representation. The auxiliary function show_ecp_key is present in three programs. It's more complex than the previous code which was also triplicated. There's no good place for such auxiliary functions that don't belong in the library and are used in multiple sample programs. Signed-off-by: Gilles Peskine --- programs/pkey/ecdsa.c | 23 +++++---- programs/pkey/gen_key.c | 75 ++++++++++++++++++++++++--- programs/pkey/key_app.c | 94 ++++++++++++++++++++++++++-------- programs/pkey/key_app_writer.c | 82 +++++++++++++++++++++++++---- 4 files changed, 228 insertions(+), 46 deletions(-) diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c index afd6fb31a..5664b8c4e 100644 --- a/programs/pkey/ecdsa.c +++ b/programs/pkey/ecdsa.c @@ -60,8 +60,8 @@ static void dump_pubkey(const char *title, mbedtls_ecdsa_context *key) unsigned char buf[300]; size_t len; - if (mbedtls_ecp_point_write_binary(&key->MBEDTLS_PRIVATE(grp), &key->MBEDTLS_PRIVATE(Q), - MBEDTLS_ECP_PF_UNCOMPRESSED, &len, buf, sizeof(buf)) != 0) { + if (mbedtls_ecp_write_public_key(key, MBEDTLS_ECP_PF_UNCOMPRESSED, + &len, buf, sizeof(buf)) != 0) { mbedtls_printf("internal error\n"); return; } @@ -79,6 +79,8 @@ int main(int argc, char *argv[]) int ret = 1; int exit_code = MBEDTLS_EXIT_FAILURE; mbedtls_ecdsa_context ctx_sign, ctx_verify; + mbedtls_ecp_point Q; + mbedtls_ecp_point_init(&Q); mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; unsigned char message[100]; @@ -128,7 +130,10 @@ int main(int argc, char *argv[]) goto exit; } - mbedtls_printf(" ok (key size: %d bits)\n", (int) ctx_sign.MBEDTLS_PRIVATE(grp).pbits); + mbedtls_ecp_group_id grp_id = mbedtls_ecp_keypair_get_group_id(&ctx_sign); + const mbedtls_ecp_curve_info *curve_info = + mbedtls_ecp_curve_info_from_grp_id(grp_id); + mbedtls_printf(" ok (key size: %d bits)\n", (int) curve_info->bit_size); dump_pubkey(" + Public key: ", &ctx_sign); @@ -174,16 +179,13 @@ int main(int argc, char *argv[]) mbedtls_printf(" . Preparing verification context..."); fflush(stdout); - if ((ret = - mbedtls_ecp_group_copy(&ctx_verify.MBEDTLS_PRIVATE(grp), - &ctx_sign.MBEDTLS_PRIVATE(grp))) != 0) { - mbedtls_printf(" failed\n ! mbedtls_ecp_group_copy returned %d\n", ret); + if ((ret = mbedtls_ecp_export(&ctx_sign, NULL, NULL, &Q)) != 0) { + mbedtls_printf(" failed\n ! mbedtls_ecp_export returned %d\n", ret); goto exit; } - if ((ret = - mbedtls_ecp_copy(&ctx_verify.MBEDTLS_PRIVATE(Q), &ctx_sign.MBEDTLS_PRIVATE(Q))) != 0) { - mbedtls_printf(" failed\n ! mbedtls_ecp_copy returned %d\n", ret); + if ((ret = mbedtls_ecp_set_public_key(grp_id, &ctx_verify, &Q)) != 0) { + mbedtls_printf(" failed\n ! mbedtls_ecp_set_public_key returned %d\n", ret); goto exit; } @@ -208,6 +210,7 @@ exit: mbedtls_ecdsa_free(&ctx_verify); mbedtls_ecdsa_free(&ctx_sign); + mbedtls_ecp_point_free(&Q); mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c index f6bb23787..cbdf5b760 100644 --- a/programs/pkey/gen_key.c +++ b/programs/pkey/gen_key.c @@ -160,6 +160,71 @@ static int write_private_key(mbedtls_pk_context *key, const char *output_file) return 0; } +#if defined(MBEDTLS_ECP_C) +static int show_ecp_key(const mbedtls_ecp_keypair *ecp, int has_private) +{ + int ret = 0; + + const mbedtls_ecp_curve_info *curve_info = + mbedtls_ecp_curve_info_from_grp_id( + mbedtls_ecp_keypair_get_group_id(ecp)); + mbedtls_printf("curve: %s\n", curve_info->name); + + mbedtls_ecp_group grp; + mbedtls_ecp_group_init(&grp); + mbedtls_mpi D; + mbedtls_mpi_init(&D); + mbedtls_ecp_point pt; + mbedtls_ecp_point_init(&pt); + mbedtls_mpi X, Y; + mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); + + MBEDTLS_MPI_CHK(mbedtls_ecp_export(ecp, &grp, + (has_private ? &D : NULL), + &pt)); + + unsigned char point_bin[MBEDTLS_ECP_MAX_PT_LEN]; + size_t len = 0; + MBEDTLS_MPI_CHK(mbedtls_ecp_point_write_binary( + &grp, &pt, MBEDTLS_ECP_PF_UNCOMPRESSED, + &len, point_bin, sizeof(point_bin))); + switch (mbedtls_ecp_get_type(&grp)) { + case MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS: + if ((len & 1) == 0 || point_bin[0] != 0x04) { + /* Point in an unxepected format. This shouldn't happen. */ + ret = -1; + goto cleanup; + } + MBEDTLS_MPI_CHK( + mbedtls_mpi_read_binary(&X, point_bin + 1, len / 2)); + MBEDTLS_MPI_CHK( + mbedtls_mpi_read_binary(&Y, point_bin + 1 + len / 2, len / 2)); + mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL); + mbedtls_mpi_write_file("Y_Q: ", &Y, 16, NULL); + break; + case MBEDTLS_ECP_TYPE_MONTGOMERY: + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, point_bin, len)); + mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL); + break; + default: + mbedtls_printf( + "This program does not yet support listing coordinates for this curve type.\n"); + break; + } + + if (has_private) { + mbedtls_mpi_write_file("D: ", &D, 16, NULL); + } + +cleanup: + mbedtls_ecp_group_free(&grp); + mbedtls_mpi_free(&D); + mbedtls_ecp_point_free(&pt); + mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); + return ret; +} +#endif + int main(int argc, char *argv[]) { int ret = 1; @@ -365,12 +430,10 @@ usage: #endif #if defined(MBEDTLS_ECP_C) if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_ECKEY) { - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(key); - mbedtls_printf("curve: %s\n", - mbedtls_ecp_curve_info_from_grp_id(ecp->MBEDTLS_PRIVATE(grp).id)->name); - mbedtls_mpi_write_file("X_Q: ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, NULL); - mbedtls_mpi_write_file("Y_Q: ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, NULL); - mbedtls_mpi_write_file("D: ", &ecp->MBEDTLS_PRIVATE(d), 16, NULL); + if (show_ecp_key(mbedtls_pk_ec(key), 1) != 0) { + mbedtls_printf(" failed\n ! could not export ECC parameters\n\n"); + goto exit; + } } else #endif mbedtls_printf(" ! key type not supported\n"); diff --git a/programs/pkey/key_app.c b/programs/pkey/key_app.c index 194c4102d..e3a696605 100644 --- a/programs/pkey/key_app.c +++ b/programs/pkey/key_app.c @@ -53,6 +53,71 @@ int main(void) #else +#if defined(MBEDTLS_ECP_C) +static int show_ecp_key(const mbedtls_ecp_keypair *ecp, int has_private) +{ + int ret = 0; + + const mbedtls_ecp_curve_info *curve_info = + mbedtls_ecp_curve_info_from_grp_id( + mbedtls_ecp_keypair_get_group_id(ecp)); + mbedtls_printf("curve: %s\n", curve_info->name); + + mbedtls_ecp_group grp; + mbedtls_ecp_group_init(&grp); + mbedtls_mpi D; + mbedtls_mpi_init(&D); + mbedtls_ecp_point pt; + mbedtls_ecp_point_init(&pt); + mbedtls_mpi X, Y; + mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); + + MBEDTLS_MPI_CHK(mbedtls_ecp_export(ecp, &grp, + (has_private ? &D : NULL), + &pt)); + + unsigned char point_bin[MBEDTLS_ECP_MAX_PT_LEN]; + size_t len = 0; + MBEDTLS_MPI_CHK(mbedtls_ecp_point_write_binary( + &grp, &pt, MBEDTLS_ECP_PF_UNCOMPRESSED, + &len, point_bin, sizeof(point_bin))); + switch (mbedtls_ecp_get_type(&grp)) { + case MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS: + if ((len & 1) == 0 || point_bin[0] != 0x04) { + /* Point in an unxepected format. This shouldn't happen. */ + ret = -1; + goto cleanup; + } + MBEDTLS_MPI_CHK( + mbedtls_mpi_read_binary(&X, point_bin + 1, len / 2)); + MBEDTLS_MPI_CHK( + mbedtls_mpi_read_binary(&Y, point_bin + 1 + len / 2, len / 2)); + mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL); + mbedtls_mpi_write_file("Y_Q: ", &Y, 16, NULL); + break; + case MBEDTLS_ECP_TYPE_MONTGOMERY: + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, point_bin, len)); + mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL); + break; + default: + mbedtls_printf( + "This program does not yet support listing coordinates for this curve type.\n"); + break; + } + + if (has_private) { + mbedtls_mpi_write_file("D: ", &D, 16, NULL); + } + +cleanup: + mbedtls_ecp_group_free(&grp); + mbedtls_mpi_free(&D); + mbedtls_ecp_point_free(&pt); + mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); + return ret; +} +#endif + /* * global options */ @@ -219,17 +284,10 @@ usage: #endif #if defined(MBEDTLS_ECP_C) if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_ECKEY) { - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(pk); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(X): ", - &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, - NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Y): ", - &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, - NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Z): ", - &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16, - NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("D : ", &ecp->MBEDTLS_PRIVATE(d), 16, NULL)); + if (show_ecp_key(mbedtls_pk_ec(pk), 1) != 0) { + mbedtls_printf(" failed\n ! could not export ECC parameters\n\n"); + goto cleanup; + } } else #endif { @@ -269,16 +327,10 @@ usage: #endif #if defined(MBEDTLS_ECP_C) if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_ECKEY) { - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(pk); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(X): ", - &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, - NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Y): ", - &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, - NULL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_write_file("Q(Z): ", - &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16, - NULL)); + if (show_ecp_key(mbedtls_pk_ec(pk), 0) != 0) { + mbedtls_printf(" failed\n ! could not export ECC parameters\n\n"); + goto cleanup; + } } else #endif { diff --git a/programs/pkey/key_app_writer.c b/programs/pkey/key_app_writer.c index c07c56464..cc4c4dc72 100644 --- a/programs/pkey/key_app_writer.c +++ b/programs/pkey/key_app_writer.c @@ -176,6 +176,71 @@ static int write_private_key(mbedtls_pk_context *key, const char *output_file) return 0; } +#if defined(MBEDTLS_ECP_C) +static int show_ecp_key(const mbedtls_ecp_keypair *ecp, int has_private) +{ + int ret = 0; + + const mbedtls_ecp_curve_info *curve_info = + mbedtls_ecp_curve_info_from_grp_id( + mbedtls_ecp_keypair_get_group_id(ecp)); + mbedtls_printf("curve: %s\n", curve_info->name); + + mbedtls_ecp_group grp; + mbedtls_ecp_group_init(&grp); + mbedtls_mpi D; + mbedtls_mpi_init(&D); + mbedtls_ecp_point pt; + mbedtls_ecp_point_init(&pt); + mbedtls_mpi X, Y; + mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); + + MBEDTLS_MPI_CHK(mbedtls_ecp_export(ecp, &grp, + (has_private ? &D : NULL), + &pt)); + + unsigned char point_bin[MBEDTLS_ECP_MAX_PT_LEN]; + size_t len = 0; + MBEDTLS_MPI_CHK(mbedtls_ecp_point_write_binary( + &grp, &pt, MBEDTLS_ECP_PF_UNCOMPRESSED, + &len, point_bin, sizeof(point_bin))); + switch (mbedtls_ecp_get_type(&grp)) { + case MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS: + if ((len & 1) == 0 || point_bin[0] != 0x04) { + /* Point in an unxepected format. This shouldn't happen. */ + ret = -1; + goto cleanup; + } + MBEDTLS_MPI_CHK( + mbedtls_mpi_read_binary(&X, point_bin + 1, len / 2)); + MBEDTLS_MPI_CHK( + mbedtls_mpi_read_binary(&Y, point_bin + 1 + len / 2, len / 2)); + mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL); + mbedtls_mpi_write_file("Y_Q: ", &Y, 16, NULL); + break; + case MBEDTLS_ECP_TYPE_MONTGOMERY: + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, point_bin, len)); + mbedtls_mpi_write_file("X_Q: ", &X, 16, NULL); + break; + default: + mbedtls_printf( + "This program does not yet support listing coordinates for this curve type.\n"); + break; + } + + if (has_private) { + mbedtls_mpi_write_file("D: ", &D, 16, NULL); + } + +cleanup: + mbedtls_ecp_group_free(&grp); + mbedtls_mpi_free(&D); + mbedtls_ecp_point_free(&pt); + mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); + return ret; +} +#endif + int main(int argc, char *argv[]) { int ret = 1; @@ -338,11 +403,10 @@ usage: #endif #if defined(MBEDTLS_ECP_C) if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_ECKEY) { - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(key); - mbedtls_mpi_write_file("Q(X): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, NULL); - mbedtls_mpi_write_file("Q(Y): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, NULL); - mbedtls_mpi_write_file("Q(Z): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16, NULL); - mbedtls_mpi_write_file("D : ", &ecp->MBEDTLS_PRIVATE(d), 16, NULL); + if (show_ecp_key(mbedtls_pk_ec(key), 1) != 0) { + mbedtls_printf(" failed\n ! could not export ECC parameters\n\n"); + goto exit; + } } else #endif mbedtls_printf("key type not supported yet\n"); @@ -384,10 +448,10 @@ usage: #endif #if defined(MBEDTLS_ECP_C) if (mbedtls_pk_get_type(&key) == MBEDTLS_PK_ECKEY) { - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(key); - mbedtls_mpi_write_file("Q(X): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), 16, NULL); - mbedtls_mpi_write_file("Q(Y): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), 16, NULL); - mbedtls_mpi_write_file("Q(Z): ", &ecp->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 16, NULL); + if (show_ecp_key(mbedtls_pk_ec(key), 0) != 0) { + mbedtls_printf(" failed\n ! could not export ECC parameters\n\n"); + goto exit; + } } else #endif mbedtls_printf("key type not supported yet\n"); From 9552a52f5f334bf0f0eba5bcb8221c9d6ff29ea1 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Sat, 23 Dec 2023 18:44:20 +0100 Subject: [PATCH 011/215] Declare dependency on bignum in sample programs Signed-off-by: Gilles Peskine --- programs/pkey/gen_key.c | 32 +++++++++++++----------------- programs/pkey/key_app_writer.c | 36 +++++++++++++++------------------- 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c index cbdf5b760..6914c9390 100644 --- a/programs/pkey/gen_key.c +++ b/programs/pkey/gen_key.c @@ -9,8 +9,19 @@ #include "mbedtls/platform.h" -#if defined(MBEDTLS_PK_WRITE_C) && defined(MBEDTLS_FS_IO) && \ - defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_CTR_DRBG_C) +#if !defined(MBEDTLS_PK_WRITE_C) || !defined(MBEDTLS_PEM_WRITE_C) || \ + !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_ENTROPY_C) || \ + !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_BIGNUM_C) +int main(void) +{ + mbedtls_printf("MBEDTLS_PK_WRITE_C and/or MBEDTLS_FS_IO and/or " + "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or " + "MBEDTLS_PEM_WRITE_C and/or MBEDTLS_BIGNUM_C " + "not defined.\n"); + mbedtls_exit(0); +} +#else + #include "mbedtls/error.h" #include "mbedtls/pk.h" #include "mbedtls/ecdsa.h" @@ -61,7 +72,6 @@ int dev_random_entropy_poll(void *data, unsigned char *output, return 0; } #endif /* !_WIN32 */ -#endif #if defined(MBEDTLS_ECP_C) #define DFL_EC_CURVE mbedtls_ecp_curve_list()->grp_id @@ -96,19 +106,6 @@ int dev_random_entropy_poll(void *data, unsigned char *output, USAGE_DEV_RANDOM \ "\n" -#if !defined(MBEDTLS_PK_WRITE_C) || !defined(MBEDTLS_PEM_WRITE_C) || \ - !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_ENTROPY_C) || \ - !defined(MBEDTLS_CTR_DRBG_C) -int main(void) -{ - mbedtls_printf("MBEDTLS_PK_WRITE_C and/or MBEDTLS_FS_IO and/or " - "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or " - "MBEDTLS_PEM_WRITE_C" - "not defined.\n"); - mbedtls_exit(0); -} -#else - /* * global options @@ -478,5 +475,4 @@ exit: mbedtls_exit(exit_code); } -#endif /* MBEDTLS_PK_WRITE_C && MBEDTLS_PEM_WRITE_C && MBEDTLS_FS_IO && - * MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ +#endif /* program viability conditions */ diff --git a/programs/pkey/key_app_writer.c b/programs/pkey/key_app_writer.c index cc4c4dc72..60f992e43 100644 --- a/programs/pkey/key_app_writer.c +++ b/programs/pkey/key_app_writer.c @@ -9,9 +9,21 @@ #include "mbedtls/platform.h" -#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_PK_WRITE_C) && \ - defined(MBEDTLS_FS_IO) && \ - defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_CTR_DRBG_C) +#if !defined(MBEDTLS_PK_PARSE_C) || \ + !defined(MBEDTLS_PK_WRITE_C) || \ + !defined(MBEDTLS_FS_IO) || \ + !defined(MBEDTLS_ENTROPY_C) || \ + !defined(MBEDTLS_CTR_DRBG_C) || \ + !defined(MBEDTLS_BIGNUM_C) +int main(void) +{ + mbedtls_printf("MBEDTLS_PK_PARSE_C and/or MBEDTLS_PK_WRITE_C and/or " + "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or " + "MBEDTLS_FS_IO and/or MBEDTLS_BIGNUM_C not defined.\n"); + mbedtls_exit(0); +} +#else + #include "mbedtls/error.h" #include "mbedtls/pk.h" #include "mbedtls/error.h" @@ -21,7 +33,6 @@ #include #include -#endif #if defined(MBEDTLS_PEM_WRITE_C) #define USAGE_OUT \ @@ -66,20 +77,6 @@ USAGE_OUT \ "\n" -#if !defined(MBEDTLS_PK_PARSE_C) || \ - !defined(MBEDTLS_PK_WRITE_C) || \ - !defined(MBEDTLS_FS_IO) || \ - !defined(MBEDTLS_ENTROPY_C) || \ - !defined(MBEDTLS_CTR_DRBG_C) -int main(void) -{ - mbedtls_printf("MBEDTLS_PK_PARSE_C and/or MBEDTLS_PK_WRITE_C and/or " - "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or " - "MBEDTLS_FS_IO not defined.\n"); - mbedtls_exit(0); -} -#else - /* * global options @@ -495,5 +492,4 @@ exit: mbedtls_exit(exit_code); } -#endif /* MBEDTLS_PK_PARSE_C && MBEDTLS_PK_WRITE_C && MBEDTLS_FS_IO && - MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ +#endif /* program viability conditions */ From 3b17ae78d2123cfb8f1596ff4a9c85d288ba50c2 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 23 Jun 2023 11:08:39 +0200 Subject: [PATCH 012/215] Add ECP-heavy-only test cases to the driver parity analysis ignore list Signed-off-by: Gilles Peskine --- tests/scripts/analyze_outcomes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py index d3ea8c0e1..96d4e46bb 100755 --- a/tests/scripts/analyze_outcomes.py +++ b/tests/scripts/analyze_outcomes.py @@ -325,6 +325,7 @@ KNOWN_TASKS = { # is required. 'test_suite_ecp': [ re.compile(r'ECP check public-private .*'), + re.compile(r'ECP calculate public: .*'), re.compile(r'ECP gen keypair .*'), re.compile(r'ECP point muladd .*'), re.compile(r'ECP point multiplication .*'), From 28e9d86cbc23ea4f202f9dc639cd3a2925dbc5fe Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 21 Jun 2023 20:40:55 +0200 Subject: [PATCH 013/215] Changelog entry for the new ECP functions Signed-off-by: Gilles Peskine --- ChangeLog.d/ecp-keypair-utilities.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ChangeLog.d/ecp-keypair-utilities.txt diff --git a/ChangeLog.d/ecp-keypair-utilities.txt b/ChangeLog.d/ecp-keypair-utilities.txt new file mode 100644 index 000000000..6f9714aaa --- /dev/null +++ b/ChangeLog.d/ecp-keypair-utilities.txt @@ -0,0 +1,5 @@ +Features + * Add utility functions to manipulate mbedtls_ecp_keypair objects, filling + gaps made by making its fields private: mbedtls_ecp_set_public_key(), + mbedtls_ecp_write_public_key(), mbedtls_ecp_keypair_calc_public(), + mbedtls_ecp_keypair_get_group_id(). Fixes #5017, #5441, #8367, #8652. From 8f1307adcd818f628014d97a77ffb21e06b8d9fc Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 25 Dec 2023 21:42:23 +0100 Subject: [PATCH 014/215] Asymmetric cryptography: rough draft Still many open questions Signed-off-by: Gilles Peskine --- .../psa-migration/psa-legacy-bridges.md | 194 +++++++++++++++++- 1 file changed, 189 insertions(+), 5 deletions(-) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index e8f20b2b6..75a05fc24 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -12,7 +12,7 @@ This is a design document. The target audience is library maintainers. See the c ### Keywords * [TODO] A part of the analysis that isn't finished. -* [QUESTION] A specific aspect of the design where there are several plausible decisions. +* [OPEN] Open question: a specific aspect of the design where there are several plausible decisions. * [ACTION] A finalized part of the design that will need to be carried out. ### Context @@ -70,13 +70,18 @@ With respect to the legacy API, we do not consider functionality of low-level mo ## Gap analysis +The document [“Transitioning to the PSA API”](../../psa-transition.md) enumerates the public header files in Mbed TLS 3.4 and the API elements (especially enums and functions) that they provide, listing PSA equivalents where they exist. There are gaps in two cases: + +* Where the PSA equivalents do not provide the same functionality. A typical example is parsing and formatting asymmetric keys. +* To convert between data representations used by legacy APIs and data representations used by PSA APIs. + Based on “[Where mixing happens](#where-mixing-happens)”, we focus the gap analysis on two topics: metadata and keys. This chapter explores the gaps in each family of cryptographic mechanisms. ### Generic metadata gaps #### Need for error code conversion -[QUESTION] Do we need public functions to convert between `MBEDTLS_ERR_xxx` error codes and `PSA_ERROR_xxx` error codes? We have such functions for internal use. +[OPEN] Do we need public functions to convert between `MBEDTLS_ERR_xxx` error codes and `PSA_ERROR_xxx` error codes? We have such functions for internal use. ### Hash gap analysis @@ -104,17 +109,101 @@ Gap: functions to convert between `psa_algorithm_t` hash algorithms and `mbedtls ### Asymmetric cryptography gap analysis -[TODO] +#### Asymmetric cryptography metadata + +The legacy API only has generic support for two key types: RSA and ECC, via the pk module. The type of ECC keys is divided in subtypes: one for each curve. The legacy API also supports DHM (Diffie-Hellman-Merkle = FFDH: finite-field Diffie-Hellman) keys, but those are not integrated in the pk module. + +An RSA or ECC key can potentially be used for different algorithms in the scope of the pk module: + +* RSA: PKCS#1v1.5 signature, PSS signature, PKCS#1v1.5 encryption, OAEP encryption. +* ECC: ECDSA signature (randomized or deterministic), ECDH key agreement. + +ECC keys are also involved in EC-JPAKE, but this happens internally: the EC-JPAKE interface only needs one piece of metadata, namely, to identify a curve. + +Since there is no algorithm that can be used with multiple types, and PSA keys have a policy that (for the most part) limits them to one algorithm, there does not seem to be a need to convert between legacy and PSA asymmetric key types on their own. The useful metadata conversions are: + +* Selecting an **elliptic curve**. + + This means converting between an `mbedtls_ecp_group_id` and a pair of `{psa_ecc_family_t; size_t}`. + + This is fulfilled by `mbedtls_ecc_group_to_psa` and `mbedtls_ecc_group_of_psa`, which were introduced into the public API after Mbed TLS 3.5. + +* Selecting A **DHM group**. + + PSA only supports predefined groups, whereas legacy only supports ad hoc groups. An existing application referring to `MBEDTLS_DHM_RFC7919_FFDHExxx` values would need to refer to `PSA_DH_FAMILY_RFC7919`; an existing application using arbitrary groups cannot migrate to PSA. + +* Simultaneously supporting **a key type and an algorithm**. + + On the legacy side, this is an `mbedtls_pk_type_t` value and more. For ECDSA, the choice between randomized and deterministic is made at compile time. For RSA, the choice of encryption or signature algorithm is made either by configuring the underlying `mbedtls_rsa_context` or when calling the operation function. + + On the PSA side, this is a `psa_key_type_t` value and an algorithm which is normally encoded as policy information in a `psa_key_attributes_t`. The algorithm is also needed in its own right when calling operation functions. + +#### Using a legacy key pair or public key with PSA + +There are several scenarios where an application has a legacy key pair or public key (`mbedtls_pk_context`) and needs to create a PSA key object (`psa_key_id_t`). + +Reasons for creating a legacy key object, where it's impossible or impractical to directly create a PSA key: + +* A very common case where the input is a legacy key object is parsing. PSA does not (yet) have an equivalent of the `mbedtls_pk_parse_xxx` functions. +* The PSA key creation interface is less flexible in some cases. In particular, PSA RSA key generation does not (yet) allow choosing the public exponent. +* The pk object may be created by a part of the application (or a third-party library) that hasn't been migrated to the PSA API yet. + +Reasons for needing a PSA key object: + +* Using the key in TLS 1.3 or some third-party interface that takes a PSA key identifier as input. +* Benefiting from a PSA accelerator, or from PSA's world separation, even without `MBEDTLS_USE_PSA_CRYPTO`. (Not a priority scenario: we generally expect people to activate `MBEDTLS_USE_PSA_CRYPTO` at an early stage of their migration to PSA.) + +Gap: a way to create a PSA key object from an `mbedtls_pk_context`. This partially exists in the form of `mbedtls_pk_wrap_as_opaque`, but it is not fully satisfactory, for reasons that are detailed in “[API to create a PSA key from a PK context](#api-to-create-a-psa-key-from-a-pk-context)” below. + +#### Using a PSA key as a PK context + +There are several scenarios where an application has a PSA key and needs to use it through an interface that wants an `mbedtls_pk_context` object. Typically, there is an existing key in the PSA key store (possibly in a secure element and non-exportable), and the key needs to be used in an interface that requires a `mbedtls_pk_context *` input, such as Mbed TLS's X.509 API or a similar third-party interface, or the `mbedtls_pk_write_xxx` interfaces which do not (yet) have PSA equivalents. + +There is a function `mbedtls_pk_setup_opaque` that mostly does this. However, it has several limitations: + +* It creates a PK key of type `MBEDTLS_PK_OPAQUE` that wraps the PSA key. This is good enough in some scenarios, but not others. For example, it's ok for pkwrite, because we've upgraded the pkwrite code to handle `MBEDTLS_PK_OPAQUE`. That doesn't help users of third-party libraries that haven't yet been upgraded. +* It ties the lifetime of the PK object to the PSA key, which is error-prone: if the PSA key is destroyed but the PK object isn't, there is no way to reliably detect any subsequent misuse of the PK object. +* It is only available under `MBEDTLS_USE_PSA_CRYPTO`. (Not a priority concern: we generally expect people to activate `MBEDTLS_USE_PSA_CRYPTO` at an early stage of their migration to PSA.) + +Gap: a way to copy a PSA key into a PK context. This can only be expected to work if the PSA key is exportable. + +[OPEN] Is `mbedtls_pk_setup_opaque` ok or do we want to tweak it? + +#### Signature formats + +The pk module uses signature formats intended for X.509. The PSA module uses the simplest sensible signature format. + +* For RSA, the formats are the same. +* For ECDSA, PSA uses a fixed-size concatenation of (r,s), whereas X.509 and pk use an ASN.1 DER encoding of the sequence (r,s). + +Gap: We need APIs to convert between these two formats. The conversion code already exists under the hood, but it's in pieces that can't be called directly. + +There is a design choice here: do we provide conversions functions for ECDSA specifically, or do we provide conversion functions that take an algorithm as argument and just happen to be a no-op with RSA? One factor is plausible extensions. These conversions functions will remain useful in Mbed TLS 4.x and perhaps beyond. We will at least add EdDSA support, and its signature encoding is the fixed-size concatenation (r,s) even in X.509. We may well also add support for some post-quantum signatures, and their concrete format is still uncertain. + +Given the uncertainty, it would be nice to provide a sufficiently generic interface to convert between the PSA and the pk signature format, parametrized by the algorithm. However, it is difficult to predict exactly what parameters are needed. For example, converting from an ASN.1 ECDSA signature to (r,s) requires the knowledge of the curve, or at least the curve's size. + +#### Asymmetric cryptography TODO + +[TODO] Other gaps? ## New APIs This section presents new APIs to implement based on the [gap analysis](#gap-analysis). +### General notes + +Each action to implement a function entails: + +* Implement the library function. +* Document it precisely, including error conditions. +* Unit-test it. +* Mention it where relevant in the PSA transition guide. + ### Hash APIs Based on the [gap analysis](#hash-gap-analysis): -[ACTION] Move `mbedtls_md_psa_alg_from_type` and `mbedtls_md_type_from_psa_alg` from `library/md_psa.h` to `include/mbedtls/md.h`. +[ACTION] [#8340](https://github.com/Mbed-TLS/mbedtls/issues/8340) Move `mbedtls_md_psa_alg_from_type` and `mbedtls_md_type_from_psa_alg` from `library/md_psa.h` to `include/mbedtls/md.h`. ### MAC APIs @@ -134,4 +223,99 @@ Based on the [gap analysis](#hash-gap-analysis): ### Asymmetric cryptography APIs -[TODO] +#### Asymmetric cryptography metadata APIs + +Based on the [gap analysis](#asymmetric-cryptography-metadata): + +* No further work is needed about RSA specifically. The amount of metadata other than hashes is sufficiently small to be handled in ad hoc ways in applications, and hashes have [their own conversions](#hash-apis). +* No further work is needed about ECC specifically. We have just added adequate functions. +* No further work is needed about DHM specifically. There is no good way to translate the relevant information. +* [OPEN] Is there a decent way to convert between `mbedtls_pk_type_t` plus extra information, and `psa_key_type_t` plus policy information? The two APIs are different in crucial ways, with different splits between key type, policy information and operation algorithm. + +#### API to create a PSA key from a PK context + +Based on the [gap analysis](#using-a-legacy-key-pair-or-public-key-with-psa): + +Given an `mbedtls_pk_context`, we want a function that creates a PSA key with the same key material and algorithm. “Same key material” is straightforward, but “same algorithm” is not, because a PK context has incomplete algorithm information. For example, there is no way to distinguish between an RSA key that is intended for signature or for encryption. Between algorithms of the same nature, there is no way to distinguish a key intended for PKCS#1v1.5 and one intended for PKCS#1v2.1 (OAEP/PSS): this is indicated in the underlying RSA context, but the indication there is only a default that can be overridden by calling `mbedtls_pk_{sign,verify}_ext`. Also there is no way to distinguish between `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)` and `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`: in the legacy interface, this is only determined when actually doing a signature/verification operation. Therefore the function that creates the PSA key needs extra information to indicate which algorithm to put in the key's policy. + +When creating a PSA key, apart from the key material, the key is determined by attributes, which fall under three categories: + +* Type and size. These are directly related to the key material and can be deduced from it if the key material is in a structured format, which is the case with an `mbedtls_pk_context` input. +* Policy. This includes the chosen algorithm, which as discussed above cannot be fully deduced from the `mbedtls_pk_context` object. Just choosing one algorithm is problematic because it doesn't allow implementation-specific extensions, such as Mbed TLS's enrollment algorithm. The intended usage flags cannot be deduced from the PK context either, but the conversion function could sensibly just enable all the relevant usage flags. Users who want a more restrictive usage can call `psa_copy_key` and `psa_destroy_key` to obtain a PSA key object with a more restrictive usage. +* Persistence and location. This is completely orthogonal to the information from the `mbedtls_pk_context` object. It is convenient, but not necessary, for the conversion function to allow customizing these aspects. If it doesn't, users can call the conversion function and then call `psa_copy_key` and `psa_destroy_key` to move the key to its desired location. + +To allow the full flexibility around policies, and make the creation of a persistent key more convenient, the conversion function shall take a `const psa_key_attributes_t *` input, like all other functions that create a PSA key. In addition, there shall be a helper function to populate a `psa_key_attributes_t` with a sensible default. This lets the caller choose a more flexible, or just different usage policy, unlike the default-then-copy approach which only allows restricting the policy. + +This is close to the existing function `mbedtls_pk_wrap_as_opaque`, but does not bake in the implementation-specific consideration that a PSA key has exactly two algorithms, and also allows the caller to benefit from default for the policy in more cases. + +[ACTION] Implement `mbedtls_pk_get_psa_attributes` and `mbedtls_pk_import_into_psa` as described below. These functions are available whenever `MBEDTLS_PK_C` and `MBEDTLS_PSA_CRYPTO_CLIENT` are both defined. Deprecate `mbedtls_pk_wrap_as_opaque`. + +``` +int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk, + psa_key_attributes_t *attributes); +int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, + const psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t *key_id); +``` + +* `mbedtls_pk_get_psa_attributes` does not change the id/lifetime fields of the attributes (which indicate a volatile key by default). +* `mbedtls_pk_get_psa_attributes` sets the type and size based on what's in the pk context. + * The key type is a key pair if the context contains a private key, and a public key if the context only contains a public key. +* `mbedtls_pk_get_psa_attributes` sets all the potentially applicable usage flags: `EXPORT`, `COPY`; `VERIFY_HASH | VERIFY_MESSAGE` or `ENCRYPT` as applicable for both public keys and key pairs; `SIGN` or `DECRYPT` as applicable for a key pair. +* [OPEN] What is the default algorithm for `mbedtls_pk_get_psa_attributes`? Suggestion: assume signature by default. For RSA, either `PSA_RSA_PKCS1_V15_SIGN(PSA_ALG_ANY_HASH)` or `PSA_ALG_RSA_PSS(hash_alg)` depending on the RSA context's padding mode. For ECC, `PSA_ALG_DETERMINISTIC_ECDSA` if `MBEDTLS_ECDSA_DETERMINISTIC` is enabled and `PSA_ALG_ECDSA` otherwise. +* [OPEN] Or does `mbedtls_pk_get_psa_attributes` need an extra argument indicating how to treat RSA and ECC keys? +* `mbedtls_pk_import_into_psa` checks that the type field in the attributes is consistent with the content of the `mbedtls_pk_context` object (RSA/ECC, and availability of the private key). + * The key type can be a public key even if the private key is available. +* `mbedtls_pk_import_into_psa` does not need to check the bit-size in the attributes: `psa_import_key` will do enough checks. +* `mbedtls_pk_import_into_psa` does not check that the policy in the attributes is sensible. That's on the user. + +#### API to copy a PSA key to a PK context + +Based on the [gap analysis](#using-a-psa-key-as-a-pk-context): + +[ACTION] Implement `mbedtls_pk_copy_from_psa` as described below. + +``` +int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, + mbedtls_pk_context *pk); +``` + +* `pk` must be initialized, but not set up. +* It is an error if the key is neither a key pair nor a public key. +* It is an error if the key is not exportable. +* The resulting pk object has a transparent type, not `MBEDTLS_PK_OPAQUE`. +* Once this function returns, the pk object is completely independent of the PSA key. +* Calling `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt` on the resulting pk context will perform an algorithm that is compatible with the PSA key's primary algorithm policy (`psa_get_key_algorithm`), but with no restriction on the hash (as if the policy had `PSA_ALG_ANY_HASH` instead of a specific hash, and with `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` merged with `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)`). For ECDSA, the choice of deterministic vs randomized will be based on the compile-time setting `MBEDTLS_ECDSA_DETERMINISTIC`, like `mbedtls_pk_sign` today. + * [OPEN] How do we distinguish between signature-only and encryption-only RSA keys? Do we just allow both (e.g. a PSS key gets generalized into a PSS/OAEP key)? + * [OPEN] What about `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext`? + +[OPEN] Should there be a way to use a different algorithm? This can be resolved by `psa_copy_key` on the input to tweak the policy if needed. + +#### API to create a PK object that wraps a PSA key + +Based on the [gap analysis](#using-a-psa-key-as-a-pk-context): + +[ACTION] Clarify the documentation of `mbedtls_pk_setup_opaque` regarding which algorithms the resulting key will perform with `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt`. + +[OPEN] What about `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext`? + +#### API to convert between signature formats + +Based on the [gap analysis](#signature-formats): + +[ACTION] [#7765](https://github.com/Mbed-TLS/mbedtls/issues/7765) Implement `mbedtls_ecdsa_raw_to_der` and `mbedtls_ecdsa_der_to_raw` as described below. + +``` +int mbedtls_ecdsa_raw_to_der(const unsigned char *raw, size_t raw_len, + unsigned char *der, size_t der_size, size_t *der_len); +int mbedtls_ecdsa_der_to_raw(const unsigned char *der, size_t der_len, + unsigned char *raw, size_t raw_size, size_t *raw_len, + size_t bits); +``` + +* These functions convert between the signature format used by `mbedtls_pk_{sign,verify}{,_ext}` and the signature format used by `psa_{sign,verify}_{hash,message}`. +* The input and output buffers can overlap. +* [OPEN] Should we maybe use a different interface that is better integrated with ASN.1 and X.509 parsing and writing functions in Mbed TLS? That is: + * DER production writes from right to left in the destination buffer. + * DER parsing takes a pointer-to-pointer to the start of the buffer and an end pointer, instead of pointer-to-start and size. + * Names should match the patterns found in X.509 and ASN.1 parsing and writing function. From 93cdb778352ca5a59d9074aecc9f3359abaabe06 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 2 Jan 2024 13:15:04 +0100 Subject: [PATCH 015/215] Minor clarifications Signed-off-by: Gilles Peskine --- .../psa-migration/psa-legacy-bridges.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index 75a05fc24..5798728c2 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -111,12 +111,12 @@ Gap: functions to convert between `psa_algorithm_t` hash algorithms and `mbedtls #### Asymmetric cryptography metadata -The legacy API only has generic support for two key types: RSA and ECC, via the pk module. The type of ECC keys is divided in subtypes: one for each curve. The legacy API also supports DHM (Diffie-Hellman-Merkle = FFDH: finite-field Diffie-Hellman) keys, but those are not integrated in the pk module. +The legacy API only has generic support for two key types: RSA and ECC, via the pk module. ECC keys can also be further classified according to their curve. The legacy API also supports DHM (Diffie-Hellman-Merkle = FFDH: finite-field Diffie-Hellman) keys, but those are not integrated in the pk module. An RSA or ECC key can potentially be used for different algorithms in the scope of the pk module: * RSA: PKCS#1v1.5 signature, PSS signature, PKCS#1v1.5 encryption, OAEP encryption. -* ECC: ECDSA signature (randomized or deterministic), ECDH key agreement. +* ECC: ECDSA signature (randomized or deterministic), ECDH key agreement (via `mbedtls_pk_ec`). ECC keys are also involved in EC-JPAKE, but this happens internally: the EC-JPAKE interface only needs one piece of metadata, namely, to identify a curve. @@ -142,7 +142,7 @@ Since there is no algorithm that can be used with multiple types, and PSA keys h There are several scenarios where an application has a legacy key pair or public key (`mbedtls_pk_context`) and needs to create a PSA key object (`psa_key_id_t`). -Reasons for creating a legacy key object, where it's impossible or impractical to directly create a PSA key: +Reasons for first creating a legacy key object, where it's impossible or impractical to directly create a PSA key: * A very common case where the input is a legacy key object is parsing. PSA does not (yet) have an equivalent of the `mbedtls_pk_parse_xxx` functions. * The PSA key creation interface is less flexible in some cases. In particular, PSA RSA key generation does not (yet) allow choosing the public exponent. @@ -157,7 +157,7 @@ Gap: a way to create a PSA key object from an `mbedtls_pk_context`. This partial #### Using a PSA key as a PK context -There are several scenarios where an application has a PSA key and needs to use it through an interface that wants an `mbedtls_pk_context` object. Typically, there is an existing key in the PSA key store (possibly in a secure element and non-exportable), and the key needs to be used in an interface that requires a `mbedtls_pk_context *` input, such as Mbed TLS's X.509 API or a similar third-party interface, or the `mbedtls_pk_write_xxx` interfaces which do not (yet) have PSA equivalents. +There are several scenarios where an application has a PSA key and needs to use it through an interface that wants an `mbedtls_pk_context` object. Typically, there is an existing key in the PSA key store (possibly in a secure element and non-exportable), and the key needs to be used in an interface that requires a `mbedtls_pk_context *` input, such as Mbed TLS's X.509 and TLS APIs or a similar third-party interface, or the `mbedtls_pk_write_xxx` interfaces which do not (yet) have PSA equivalents. There is a function `mbedtls_pk_setup_opaque` that mostly does this. However, it has several limitations: @@ -165,6 +165,11 @@ There is a function `mbedtls_pk_setup_opaque` that mostly does this. However, it * It ties the lifetime of the PK object to the PSA key, which is error-prone: if the PSA key is destroyed but the PK object isn't, there is no way to reliably detect any subsequent misuse of the PK object. * It is only available under `MBEDTLS_USE_PSA_CRYPTO`. (Not a priority concern: we generally expect people to activate `MBEDTLS_USE_PSA_CRYPTO` at an early stage of their migration to PSA.) +It therefore appears that we need two ways to “convert” a PSA key to PK: + +* Wrapping, which is what `mbedtls_pk_setup_opaque` does. This works for any PSA key but is limited by the key's lifetime and creates a PK object with limited functionality. +* Copying, which requires a new function. This requires an exportable key but creates a fully independent, fully functional PK object. + Gap: a way to copy a PSA key into a PK context. This can only be expected to work if the PSA key is exportable. [OPEN] Is `mbedtls_pk_setup_opaque` ok or do we want to tweak it? @@ -180,7 +185,7 @@ Gap: We need APIs to convert between these two formats. The conversion code alre There is a design choice here: do we provide conversions functions for ECDSA specifically, or do we provide conversion functions that take an algorithm as argument and just happen to be a no-op with RSA? One factor is plausible extensions. These conversions functions will remain useful in Mbed TLS 4.x and perhaps beyond. We will at least add EdDSA support, and its signature encoding is the fixed-size concatenation (r,s) even in X.509. We may well also add support for some post-quantum signatures, and their concrete format is still uncertain. -Given the uncertainty, it would be nice to provide a sufficiently generic interface to convert between the PSA and the pk signature format, parametrized by the algorithm. However, it is difficult to predict exactly what parameters are needed. For example, converting from an ASN.1 ECDSA signature to (r,s) requires the knowledge of the curve, or at least the curve's size. +Given the uncertainty, it would be nice to provide a sufficiently generic interface to convert between the PSA and the pk signature format, parametrized by the algorithm. However, it is difficult to predict exactly what parameters are needed. For example, converting from an ASN.1 ECDSA signature to (r,s) requires the knowledge of the curve, or at least the curve's size. Therefore we are not going to add a generic function at this stage. #### Asymmetric cryptography TODO @@ -263,7 +268,7 @@ int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, * The key type is a key pair if the context contains a private key, and a public key if the context only contains a public key. * `mbedtls_pk_get_psa_attributes` sets all the potentially applicable usage flags: `EXPORT`, `COPY`; `VERIFY_HASH | VERIFY_MESSAGE` or `ENCRYPT` as applicable for both public keys and key pairs; `SIGN` or `DECRYPT` as applicable for a key pair. * [OPEN] What is the default algorithm for `mbedtls_pk_get_psa_attributes`? Suggestion: assume signature by default. For RSA, either `PSA_RSA_PKCS1_V15_SIGN(PSA_ALG_ANY_HASH)` or `PSA_ALG_RSA_PSS(hash_alg)` depending on the RSA context's padding mode. For ECC, `PSA_ALG_DETERMINISTIC_ECDSA` if `MBEDTLS_ECDSA_DETERMINISTIC` is enabled and `PSA_ALG_ECDSA` otherwise. -* [OPEN] Or does `mbedtls_pk_get_psa_attributes` need an extra argument indicating how to treat RSA and ECC keys? +* [OPEN] Or does `mbedtls_pk_get_psa_attributes` need an extra argument that conveys some kind of policy for RSA keys and, independently, some kind of policy for ECC keys? * `mbedtls_pk_import_into_psa` checks that the type field in the attributes is consistent with the content of the `mbedtls_pk_context` object (RSA/ECC, and availability of the private key). * The key type can be a public key even if the private key is available. * `mbedtls_pk_import_into_psa` does not need to check the bit-size in the attributes: `psa_import_key` will do enough checks. From a7226a1f60fa08f2f8de65d67241b7aaad8a9693 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 2 Jan 2024 13:15:14 +0100 Subject: [PATCH 016/215] Our TLS 1.3 API doesn't actually require PSA key identifiers Signed-off-by: Gilles Peskine --- docs/architecture/psa-migration/psa-legacy-bridges.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index 5798728c2..6ffe28f09 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -150,7 +150,7 @@ Reasons for first creating a legacy key object, where it's impossible or impract Reasons for needing a PSA key object: -* Using the key in TLS 1.3 or some third-party interface that takes a PSA key identifier as input. +* Using the key with third-party interface that takes a PSA key identifier as input. (Mbed TLS itself has a few TLS functions that take PSA key identifiers, but as of Mbed TLS 3.5, it is always possible to use a legacy key instead.) * Benefiting from a PSA accelerator, or from PSA's world separation, even without `MBEDTLS_USE_PSA_CRYPTO`. (Not a priority scenario: we generally expect people to activate `MBEDTLS_USE_PSA_CRYPTO` at an early stage of their migration to PSA.) Gap: a way to create a PSA key object from an `mbedtls_pk_context`. This partially exists in the form of `mbedtls_pk_wrap_as_opaque`, but it is not fully satisfactory, for reasons that are detailed in “[API to create a PSA key from a PK context](#api-to-create-a-psa-key-from-a-pk-context)” below. From f80dcc5f8bb54ae441be07a5cac3c77c22e70263 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 2 Jan 2024 13:15:47 +0100 Subject: [PATCH 017/215] Resolve ECDSA conversion API: don't use an ASN.1 interface Signed-off-by: Gilles Peskine --- docs/architecture/psa-migration/psa-legacy-bridges.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index 6ffe28f09..0c3e05a65 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -187,6 +187,8 @@ There is a design choice here: do we provide conversions functions for ECDSA spe Given the uncertainty, it would be nice to provide a sufficiently generic interface to convert between the PSA and the pk signature format, parametrized by the algorithm. However, it is difficult to predict exactly what parameters are needed. For example, converting from an ASN.1 ECDSA signature to (r,s) requires the knowledge of the curve, or at least the curve's size. Therefore we are not going to add a generic function at this stage. +For ECDSA, there are two plausible APIs: follow the ASN.1/X.509 write/parse APIs, or present an ordinary input/output API. The ASN.1 APIs are the way they are to accommodate nested TLV structures. But ECDSA signatures do not appear nested in TLV structures in either TLS (there's just a signature field) or X.509 (the signature is inside a BITSTRING, not directly in a SEQUENCE). So there does not seem to be a need for an ASN.1-like API for the ASN.1 format, just the format conversion itself in a buffer that just contains the signature. + #### Asymmetric cryptography TODO [TODO] Other gaps? @@ -320,7 +322,3 @@ int mbedtls_ecdsa_der_to_raw(const unsigned char *der, size_t der_len, * These functions convert between the signature format used by `mbedtls_pk_{sign,verify}{,_ext}` and the signature format used by `psa_{sign,verify}_{hash,message}`. * The input and output buffers can overlap. -* [OPEN] Should we maybe use a different interface that is better integrated with ASN.1 and X.509 parsing and writing functions in Mbed TLS? That is: - * DER production writes from right to left in the destination buffer. - * DER parsing takes a pointer-to-pointer to the start of the buffer and an end pointer, instead of pointer-to-start and size. - * Names should match the patterns found in X.509 and ASN.1 parsing and writing function. From 9fe1c699a8a73a528878f3072c5ee127a3928f84 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 2 Jan 2024 13:16:31 +0100 Subject: [PATCH 018/215] Clarify PSA-to-PK copy intent Signed-off-by: Gilles Peskine --- docs/architecture/psa-migration/psa-legacy-bridges.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index 0c3e05a65..064b7d278 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -290,9 +290,10 @@ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, * `pk` must be initialized, but not set up. * It is an error if the key is neither a key pair nor a public key. * It is an error if the key is not exportable. -* The resulting pk object has a transparent type, not `MBEDTLS_PK_OPAQUE`. +* The resulting pk object has a transparent type, not `MBEDTLS_PK_OPAQUE`. That's `MBEDTLS_PK_RSA` for RSA keys (since pk objects don't use `MBEDTLS_PK_RSASSA_PSS)` as a type, and `MBEDTLS_PK_ECKEY` for ECC keys (following the example of pkparse). * Once this function returns, the pk object is completely independent of the PSA key. * Calling `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt` on the resulting pk context will perform an algorithm that is compatible with the PSA key's primary algorithm policy (`psa_get_key_algorithm`), but with no restriction on the hash (as if the policy had `PSA_ALG_ANY_HASH` instead of a specific hash, and with `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` merged with `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)`). For ECDSA, the choice of deterministic vs randomized will be based on the compile-time setting `MBEDTLS_ECDSA_DETERMINISTIC`, like `mbedtls_pk_sign` today. + * The primary intent of this requirement is to allow an application to switch to PSA for creating the key material (for example to benefit from a PSA accelerator driver, or to start using a secure element), without modifying the code that consumes the key. For RSA keys, the PSA primary algorithm policy is how one conveys the same information as RSA key padding information in the legacy API. [ACTION] Convey this in the documentation. * [OPEN] How do we distinguish between signature-only and encryption-only RSA keys? Do we just allow both (e.g. a PSS key gets generalized into a PSS/OAEP key)? * [OPEN] What about `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext`? From 45c3cae8a5b9c6282d3ffb3efd980ac92f5a4288 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 2 Jan 2024 13:26:04 +0100 Subject: [PATCH 019/215] md: move PSA conversion functions from md_psa.h to psa_util.h Signed-off-by: Valerio Setti --- include/mbedtls/psa_util.h | 37 +++++++++++++++++++++++++++++++++++++ library/md_psa.h | 37 ------------------------------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index 5f6a05315..249b8d421 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -148,6 +148,43 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve, int bits_is_sloppy); #endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ +/** + * \brief This function returns the PSA algorithm identifier + * associated with the given digest type. + * + * \param md_type The type of digest to search for. Must not be NONE. + * + * \warning If \p md_type is \c MBEDTLS_MD_NONE, this function will + * not return \c PSA_ALG_NONE, but an invalid algorithm. + * + * \warning This function does not check if the algorithm is + * supported, it always returns the corresponding identifier. + * + * \return The PSA algorithm identifier associated with \p md_type, + * regardless of whether it is supported or not. + */ +static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type) +{ + return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) md_type; +} + +/** + * \brief This function returns the given digest type + * associated with the PSA algorithm identifier. + * + * \param psa_alg The PSA algorithm identifier to search for. + * + * \warning This function does not check if the algorithm is + * supported, it always returns the corresponding identifier. + * + * \return The MD type associated with \p psa_alg, + * regardless of whether it is supported or not. + */ +static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg) +{ + return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK); +} + /**@}*/ #endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/library/md_psa.h b/library/md_psa.h index b201263b1..028ba2409 100644 --- a/library/md_psa.h +++ b/library/md_psa.h @@ -15,43 +15,6 @@ #include "mbedtls/md.h" #include "psa/crypto.h" -/** - * \brief This function returns the PSA algorithm identifier - * associated with the given digest type. - * - * \param md_type The type of digest to search for. Must not be NONE. - * - * \warning If \p md_type is \c MBEDTLS_MD_NONE, this function will - * not return \c PSA_ALG_NONE, but an invalid algorithm. - * - * \warning This function does not check if the algorithm is - * supported, it always returns the corresponding identifier. - * - * \return The PSA algorithm identifier associated with \p md_type, - * regardless of whether it is supported or not. - */ -static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type) -{ - return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) md_type; -} - -/** - * \brief This function returns the given digest type - * associated with the PSA algorithm identifier. - * - * \param psa_alg The PSA algorithm identifier to search for. - * - * \warning This function does not check if the algorithm is - * supported, it always returns the corresponding identifier. - * - * \return The MD type associated with \p psa_alg, - * regardless of whether it is supported or not. - */ -static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg) -{ - return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK); -} - /** Convert PSA status to MD error code. * * \param status PSA status. From 384fbde49a4e9d6b87dac45217557eed06267661 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 2 Jan 2024 13:26:40 +0100 Subject: [PATCH 020/215] library/tests: replace md_psa.h with psa_util.h as include file for MD conversion Signed-off-by: Valerio Setti --- library/pk.c | 2 +- library/pk_wrap.c | 2 +- library/psa_crypto.c | 2 +- library/psa_crypto_ecp.c | 2 +- library/psa_crypto_rsa.c | 2 +- library/ssl_ciphersuites.c | 2 +- library/ssl_cookie.c | 2 +- library/ssl_tls.c | 1 + library/ssl_tls13_client.c | 2 +- library/ssl_tls13_generic.c | 2 +- library/ssl_tls13_keys.c | 2 +- library/ssl_tls13_server.c | 2 +- library/x509_crt.c | 2 +- library/x509write_crt.c | 2 +- library/x509write_csr.c | 2 +- tests/src/test_helpers/ssl_helpers.c | 2 +- tests/suites/test_suite_constant_time_hmac.function | 2 +- tests/suites/test_suite_md.function | 2 +- tests/suites/test_suite_pk.function | 2 +- tests/suites/test_suite_x509write.function | 2 +- 20 files changed, 20 insertions(+), 19 deletions(-) diff --git a/library/pk.c b/library/pk.c index 61ac0dfab..926183701 100644 --- a/library/pk.c +++ b/library/pk.c @@ -31,7 +31,7 @@ #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "psa_util_internal.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" #endif #include diff --git a/library/pk_wrap.c b/library/pk_wrap.c index 924794523..c23265022 100644 --- a/library/pk_wrap.c +++ b/library/pk_wrap.c @@ -13,7 +13,7 @@ #include "pk_wrap.h" #include "pk_internal.h" #include "mbedtls/error.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" /* Even if RSA not activated, for the sake of RSA-alt */ #include "mbedtls/rsa.h" diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 10d17b6df..a20dafaf0 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -70,7 +70,7 @@ #include "mbedtls/sha1.h" #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) || \ diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index e4a372d24..41641549c 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -14,7 +14,7 @@ #include "psa_crypto_core.h" #include "psa_crypto_ecp.h" #include "psa_crypto_random_impl.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" #include #include diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c index 0679f41ea..7b58ea22a 100644 --- a/library/psa_crypto_rsa.c +++ b/library/psa_crypto_rsa.c @@ -16,7 +16,7 @@ #include "psa_crypto_random_impl.h" #include "psa_crypto_rsa.h" #include "psa_crypto_hash.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" #include #include diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c index 6224ef205..23619a26c 100644 --- a/library/ssl_ciphersuites.c +++ b/library/ssl_ciphersuites.c @@ -17,7 +17,7 @@ #include "mbedtls/ssl.h" #include "ssl_misc.h" #if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "md_psa.h" +#include "mbedtls/psa_util.h" #endif #include diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c index ee81eb420..2772cac4b 100644 --- a/library/ssl_cookie.c +++ b/library/ssl_cookie.c @@ -24,7 +24,7 @@ #include #if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "md_psa.h" +#include "mbedtls/psa_util.h" /* Define a local translating function to save code size by not using too many * arguments in each translating place. */ static int local_err_translation(psa_status_t status) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index e1fb1283e..28bf1d8a0 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -29,6 +29,7 @@ #include #if defined(MBEDTLS_USE_PSA_CRYPTO) +#include "mbedtls/psa_util.h" #include "md_psa.h" #include "psa_util_internal.h" #include "psa/crypto.h" diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index ae1136431..ffaffe925 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -19,7 +19,7 @@ #include "ssl_client.h" #include "ssl_tls13_keys.h" #include "ssl_debug_helpers.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) /* Define a local translating function to save code size by not using too many diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index fe2a2eba7..30b444d59 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -17,7 +17,7 @@ #include "mbedtls/platform.h" #include "mbedtls/constant_time.h" #include "psa/crypto.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" #include "ssl_misc.h" #include "ssl_tls13_invasive.h" diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index 9b775ec95..edb453c3e 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -22,7 +22,7 @@ #include "ssl_tls13_invasive.h" #include "psa/crypto.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" /* Define a local translating function to save code size by not using too many * arguments in each translating place. */ diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index fe7a674d6..82b6bfcec 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -14,7 +14,7 @@ #include "mbedtls/platform.h" #include "mbedtls/constant_time.h" #include "mbedtls/oid.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" #include "ssl_misc.h" #include "ssl_tls13_keys.h" diff --git a/library/x509_crt.c b/library/x509_crt.c index 4e7672e37..84b92a891 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -35,7 +35,7 @@ #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "psa/crypto.h" #include "psa_util_internal.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" #endif /* MBEDTLS_USE_PSA_CRYPTO */ #include "pk_internal.h" diff --git a/library/x509write_crt.c b/library/x509write_crt.c index 44b6b1781..913b15a70 100644 --- a/library/x509write_crt.c +++ b/library/x509write_crt.c @@ -33,7 +33,7 @@ #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "psa/crypto.h" #include "psa_util_internal.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" #endif /* MBEDTLS_USE_PSA_CRYPTO */ void mbedtls_x509write_crt_init(mbedtls_x509write_cert *ctx) diff --git a/library/x509write_csr.c b/library/x509write_csr.c index 254da69a9..af75e7f72 100644 --- a/library/x509write_csr.c +++ b/library/x509write_csr.c @@ -24,7 +24,7 @@ #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "psa/crypto.h" #include "psa_util_internal.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" #endif /* MBEDTLS_USE_PSA_CRYPTO */ #include diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index d02d30539..6233580b9 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -9,7 +9,7 @@ */ #include -#include "md_psa.h" +#include "mbedtls/psa_util.h" #if defined(MBEDTLS_SSL_TLS_C) #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) diff --git a/tests/suites/test_suite_constant_time_hmac.function b/tests/suites/test_suite_constant_time_hmac.function index 9d9aa3c77..0e870d80f 100644 --- a/tests/suites/test_suite_constant_time_hmac.function +++ b/tests/suites/test_suite_constant_time_hmac.function @@ -3,7 +3,7 @@ #include #include #include -#include "md_psa.h" +#include "mbedtls/psa_util.h" #include #include diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function index 866ff588f..2a885e237 100644 --- a/tests/suites/test_suite_md.function +++ b/tests/suites/test_suite_md.function @@ -1,6 +1,6 @@ /* BEGIN_HEADER */ #include "mbedtls/md.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" #include "mbedtls/oid.h" #include "mbedtls/asn1.h" diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 226598c72..f05444317 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -16,7 +16,7 @@ * but the test code generator requires test case data to be valid C code * unconditionally (https://github.com/Mbed-TLS/mbedtls/issues/2023). */ #include "psa/crypto.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" /* Used for properly sizing the key buffer in pk_genkey_ec() */ #include "psa_util_internal.h" diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function index b59fd48f3..543b441ff 100644 --- a/tests/suites/test_suite_x509write.function +++ b/tests/suites/test_suite_x509write.function @@ -7,7 +7,7 @@ #include "mbedtls/rsa.h" #include "mbedtls/asn1write.h" #include "mbedtls/pk.h" -#include "md_psa.h" +#include "mbedtls/psa_util.h" #if defined(MBEDTLS_RSA_C) int mbedtls_rsa_decrypt_func(void *ctx, size_t *olen, From 3d2e0f5f42b9ac646f63d67e442f4af0f8a3fe4f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 2 Jan 2024 14:57:19 +0100 Subject: [PATCH 021/215] psa_util: add algorithm's availability checks for MD conversion functions Signed-off-by: Valerio Setti --- include/mbedtls/psa_util.h | 27 +++------- library/psa_util.c | 106 +++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 21 deletions(-) diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index 249b8d421..e8fb3de61 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -152,21 +152,12 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve, * \brief This function returns the PSA algorithm identifier * associated with the given digest type. * - * \param md_type The type of digest to search for. Must not be NONE. + * \param md_type The type of digest to search for. * - * \warning If \p md_type is \c MBEDTLS_MD_NONE, this function will - * not return \c PSA_ALG_NONE, but an invalid algorithm. - * - * \warning This function does not check if the algorithm is - * supported, it always returns the corresponding identifier. - * - * \return The PSA algorithm identifier associated with \p md_type, - * regardless of whether it is supported or not. + * \return The PSA algorithm identifier associated with \p md_type; + * #PSA_ALG_NONE if the algorithm is unuspported or invalid. */ -static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type) -{ - return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) md_type; -} +psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type); /** * \brief This function returns the given digest type @@ -174,16 +165,10 @@ static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_ * * \param psa_alg The PSA algorithm identifier to search for. * - * \warning This function does not check if the algorithm is - * supported, it always returns the corresponding identifier. - * * \return The MD type associated with \p psa_alg, - * regardless of whether it is supported or not. + * #MBEDTLS_MD_NONE if the algorithm is unsupported or invalid. */ -static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg) -{ - return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK); -} +mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg); /**@}*/ diff --git a/library/psa_util.c b/library/psa_util.c index 9b06de273..bb054a33f 100644 --- a/library/psa_util.c +++ b/library/psa_util.c @@ -330,4 +330,110 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve, } #endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ +psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type) +{ + switch (md_type) { +#if defined(PSA_WANT_ALG_MD5) + case MBEDTLS_MD_MD5: + return PSA_ALG_MD5; +#endif +#if defined(PSA_WANT_ALG_RIPEMD160) + case MBEDTLS_MD_RIPEMD160: + return PSA_ALG_RIPEMD160; +#endif +#if defined(PSA_WANT_ALG_SHA_1) + case MBEDTLS_MD_SHA1: + return PSA_ALG_SHA_1; +#endif +#if defined(PSA_WANT_ALG_SHA_224) + case MBEDTLS_MD_SHA224: + return PSA_ALG_SHA_224; +#endif +#if defined(PSA_WANT_ALG_SHA_256) + case MBEDTLS_MD_SHA256: + return PSA_ALG_SHA_256; +#endif +#if defined(PSA_WANT_ALG_SHA_384) + case MBEDTLS_MD_SHA384: + return PSA_ALG_SHA_384; +#endif +#if defined(PSA_WANT_ALG_SHA_512) + case MBEDTLS_MD_SHA512: + return PSA_ALG_SHA_512; +#endif +#if defined(PSA_WANT_ALG_SHA3_224) + case MBEDTLS_MD_SHA3_224: + return PSA_ALG_SHA3_224; +#endif +#if defined(PSA_WANT_ALG_SHA3_256) + case MBEDTLS_MD_SHA3_256: + return PSA_ALG_SHA3_256; +#endif +#if defined(PSA_WANT_ALG_SHA3_384) + case MBEDTLS_MD_SHA3_384: + return PSA_ALG_SHA3_384; +#endif +#if defined(PSA_WANT_ALG_SHA3_512) + case MBEDTLS_MD_SHA3_512: + return PSA_ALG_SHA3_512; +#endif + case MBEDTLS_MD_NONE: + default: + return PSA_ALG_NONE; + } +} + +mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg) +{ + switch (psa_alg) { +#if defined(PSA_WANT_ALG_MD5) + case PSA_ALG_MD5: + return MBEDTLS_MD_MD5; +#endif +#if defined(PSA_WANT_ALG_RIPEMD160) + case PSA_ALG_RIPEMD160: + return MBEDTLS_MD_RIPEMD160; +#endif +#if defined(PSA_WANT_ALG_SHA_1) + case PSA_ALG_SHA_1: + return MBEDTLS_MD_SHA1; +#endif +#if defined(PSA_WANT_ALG_SHA_224) + case PSA_ALG_SHA_224: + return MBEDTLS_MD_SHA224; +#endif +#if defined(PSA_WANT_ALG_SHA_256) + case PSA_ALG_SHA_256: + return MBEDTLS_MD_SHA256; +#endif +#if defined(PSA_WANT_ALG_SHA_384) + case PSA_ALG_SHA_384: + return MBEDTLS_MD_SHA384; +#endif +#if defined(PSA_WANT_ALG_SHA_512) + case PSA_ALG_SHA_512: + return MBEDTLS_MD_SHA512; +#endif +#if defined(PSA_WANT_ALG_SHA3_224) + case PSA_ALG_SHA3_224: + return MBEDTLS_MD_SHA3_224; +#endif +#if defined(PSA_WANT_ALG_SHA3_256) + case PSA_ALG_SHA3_256: + return MBEDTLS_MD_SHA3_256; +#endif +#if defined(PSA_WANT_ALG_SHA3_384) + case PSA_ALG_SHA3_384: + return MBEDTLS_MD_SHA3_384; +#endif +#if defined(PSA_WANT_ALG_SHA3_512) + case PSA_ALG_SHA3_512: + return MBEDTLS_MD_SHA3_512; +#endif + case PSA_ALG_NONE: + default: + return MBEDTLS_MD_NONE; + } +} + #endif /* MBEDTLS_PSA_CRYPTO_C */ From 2c1070b39700be8a6fcda5f2266e8bbe5ac42e1c Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 2 Jan 2024 14:58:22 +0100 Subject: [PATCH 022/215] test_suite_md: improve md_to_from_psa() test function and related data Signed-off-by: Valerio Setti --- tests/suites/test_suite_md.data | 48 +++++++++++++++++++++++++++-- tests/suites/test_suite_md.function | 24 +++------------ 2 files changed, 51 insertions(+), 21 deletions(-) diff --git a/tests/suites/test_suite_md.data b/tests/suites/test_suite_md.data index fb9b5effa..b831500d6 100644 --- a/tests/suites/test_suite_md.data +++ b/tests/suites/test_suite_md.data @@ -2,8 +2,52 @@ MD list mbedtls_md_list: -MD <-> PSA conversion -md_to_from_psa: +MD <-> PSA conversion - MD5 +depends_on:PSA_WANT_ALG_MD5 +md_to_from_psa:MBEDTLS_MD_MD5:PSA_ALG_MD5 + +MD <-> PSA conversion - RIPEMD160 +depends_on:PSA_WANT_ALG_RIPEMD160 +md_to_from_psa:MBEDTLS_MD_RIPEMD160:PSA_ALG_RIPEMD160 + +MD <-> PSA conversion - SHA1 +depends_on:PSA_WANT_ALG_SHA_1 +md_to_from_psa:MBEDTLS_MD_SHA1:PSA_ALG_SHA_1 + +MD <-> PSA conversion - SHA224 +depends_on:PSA_WANT_ALG_SHA_224 +md_to_from_psa:MBEDTLS_MD_SHA224:PSA_ALG_SHA_224 + +MD <-> PSA conversion - SHA256 +depends_on:PSA_WANT_ALG_SHA_256 +md_to_from_psa:MBEDTLS_MD_SHA256:PSA_ALG_SHA_256 + +MD <-> PSA conversion - SHA384 +depends_on:PSA_WANT_ALG_SHA_384 +md_to_from_psa:MBEDTLS_MD_SHA384:PSA_ALG_SHA_384 + +MD <-> PSA conversion - SHA512 +depends_on:PSA_WANT_ALG_SHA_512 +md_to_from_psa:MBEDTLS_MD_SHA512:PSA_ALG_SHA_512 + +MD <-> PSA conversion - SHA3_224 +depends_on:PSA_WANT_ALG_SHA3_224 +md_to_from_psa:MBEDTLS_MD_SHA3_224:PSA_ALG_SHA3_224 + +MD <-> PSA conversion - SHA3_256 +depends_on:PSA_WANT_ALG_SHA3_256 +md_to_from_psa:MBEDTLS_MD_SHA3_256:PSA_ALG_SHA3_256 + +MD <-> PSA conversion - SHA3_384 +depends_on:PSA_WANT_ALG_SHA3_384 +md_to_from_psa:MBEDTLS_MD_SHA3_384:PSA_ALG_SHA3_384 + +MD <-> PSA conversion - SHA3_512 +depends_on:PSA_WANT_ALG_SHA3_512 +md_to_from_psa:MBEDTLS_MD_SHA3_512:PSA_ALG_SHA3_512 + +MD <-> PSA conversion - NONE +md_to_from_psa:MBEDTLS_MD_NONE:PSA_ALG_NONE MD NULL/uninitialised arguments md_null_args: diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function index 2a885e237..0a8e4216e 100644 --- a/tests/suites/test_suite_md.function +++ b/tests/suites/test_suite_md.function @@ -4,10 +4,6 @@ #include "mbedtls/oid.h" #include "mbedtls/asn1.h" - -#define MD_PSA(md, psa) \ - TEST_EQUAL(mbedtls_md_psa_alg_from_type(md), psa); \ - TEST_EQUAL(mbedtls_md_type_from_psa_alg(psa), md); /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -63,23 +59,13 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C */ -void md_to_from_psa() +void md_to_from_psa(int md_alg_arg, int psa_alg_arg) { - /* We use a simplified implementation that relies on numerical values - * being aligned, so make sure they remain so. */ - MD_PSA(MBEDTLS_MD_MD5, PSA_ALG_MD5); - MD_PSA(MBEDTLS_MD_RIPEMD160, PSA_ALG_RIPEMD160); - MD_PSA(MBEDTLS_MD_SHA1, PSA_ALG_SHA_1); - MD_PSA(MBEDTLS_MD_SHA224, PSA_ALG_SHA_224); - MD_PSA(MBEDTLS_MD_SHA256, PSA_ALG_SHA_256); - MD_PSA(MBEDTLS_MD_SHA384, PSA_ALG_SHA_384); - MD_PSA(MBEDTLS_MD_SHA512, PSA_ALG_SHA_512); - MD_PSA(MBEDTLS_MD_SHA3_224, PSA_ALG_SHA3_224); - MD_PSA(MBEDTLS_MD_SHA3_256, PSA_ALG_SHA3_256); - MD_PSA(MBEDTLS_MD_SHA3_384, PSA_ALG_SHA3_384); - MD_PSA(MBEDTLS_MD_SHA3_512, PSA_ALG_SHA3_512); + mbedtls_md_type_t md_alg = md_alg_arg; + psa_algorithm_t psa_alg = psa_alg_arg; - /* Don't test for NONE<->NONE as this is not guaranteed */ + TEST_EQUAL(mbedtls_md_psa_alg_from_type(md_alg), psa_alg); \ + TEST_EQUAL(mbedtls_md_type_from_psa_alg(psa_alg), md_alg); } /* END_CASE */ From a835d6da087ff55e9ec103074bba805490862140 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 2 Jan 2024 15:02:19 +0100 Subject: [PATCH 023/215] changelog: document MD's conversion functions Signed-off-by: Valerio Setti --- ChangeLog.d/8664.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ChangeLog.d/8664.txt diff --git a/ChangeLog.d/8664.txt b/ChangeLog.d/8664.txt new file mode 100644 index 000000000..03e297c18 --- /dev/null +++ b/ChangeLog.d/8664.txt @@ -0,0 +1,4 @@ +Features + * mbedtls_md_psa_alg_from_type() and mbedtls_md_type_from_psa_alg() helper + functions were added to convert from mbedtls_md_type_t to psa_algorithm_t + and viceversa. From a87cd17b35325092ebb7933ccad61303de89b12a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 2 Jan 2024 15:12:37 +0100 Subject: [PATCH 024/215] psa-transition: update with MD translation functions Signed-off-by: Valerio Setti --- docs/psa-transition.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 067ffafbd..48beb80a3 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -443,6 +443,10 @@ The equivalent to `mbedtls_md_type_t` and `MBEDTLS_MD_XXX` constants is the type | `MBEDTLS_MD_SHA3_384` | `PSA_ALG_SHA3_384` | | `MBEDTLS_MD_SHA3_512` | `PSA_ALG_SHA3_512` | +The following helper functions can be used to convert between the 2 types: +- `mbedtls_md_psa_alg_from_type()` converts from legacy `mbedtls_md_type_t` to PSA's `psa_algorithm_t`. +- `mbedtls_md_type_from_psa_alg()` converts from PSA's `psa_algorithm_t` to legacy `mbedtls_md_type_t`. + ### 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). From 39b7bba8a08ad1fd171659ea8f231627a6f3367c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 2 Jan 2024 17:56:54 +0100 Subject: [PATCH 025/215] Make input parameter const Signed-off-by: Gilles Peskine --- include/mbedtls/ecp.h | 2 +- library/ecp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 619a8a51a..76aef32fb 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -1368,7 +1368,7 @@ int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key, * or the export for the given group is not implemented. * \return Another negative error code on other kinds of failure. */ -int mbedtls_ecp_write_public_key(mbedtls_ecp_keypair *key, +int mbedtls_ecp_write_public_key(const mbedtls_ecp_keypair *key, int format, size_t *olen, unsigned char *buf, size_t buflen); diff --git a/library/ecp.c b/library/ecp.c index 12924bf32..758d54bd7 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -3336,7 +3336,7 @@ cleanup: /* * Write a public key. */ -int mbedtls_ecp_write_public_key(mbedtls_ecp_keypair *key, +int mbedtls_ecp_write_public_key(const mbedtls_ecp_keypair *key, int format, size_t *olen, unsigned char *buf, size_t buflen) { From 5d867872dda985052ac9304f06f7060f4f15e261 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 2 Jan 2024 17:57:51 +0100 Subject: [PATCH 026/215] Improve readability of null-argument tests Signed-off-by: Gilles Peskine --- tests/suites/test_suite_ecp.function | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index ced4ca387..c8be4e581 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1401,17 +1401,21 @@ void ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int inval TEST_EQUAL(export_grp.id, mbedtls_ecp_keypair_get_group_id(&key)); - /* Test null arguments */ + /* Test null arguments: grp only */ mbedtls_ecp_group_free(&export_grp); - mbedtls_mpi_free(&export_d); - mbedtls_ecp_point_free(&export_Q); mbedtls_ecp_group_init(&export_grp); - mbedtls_mpi_init(&export_d); - mbedtls_ecp_point_init(&export_Q); TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp, NULL, NULL), 0); TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0); + + /* Test null arguments: d only */ + mbedtls_mpi_free(&export_d); + mbedtls_mpi_init(&export_d); TEST_EQUAL(mbedtls_ecp_export(&key, NULL, &export_d, NULL), 0); TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0); + + /* Test null arguments: Q only */ + mbedtls_ecp_point_free(&export_Q); + mbedtls_ecp_point_init(&export_Q); TEST_EQUAL(mbedtls_ecp_export(&key, NULL, NULL, &export_Q), 0); TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0); } From a10d112e456bfebab8a55757d8ef1efc7d90e54d Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 3 Jan 2024 14:08:10 +0100 Subject: [PATCH 027/215] Remove useless guards on MBEDTLS_BIGNUM_C All of ECP requires the bignum module and there is no plan to change that, so guarding a few bits of code is just noise. Signed-off-by: Gilles Peskine --- tests/suites/test_suite_ecp.function | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index c8be4e581..295fe7f15 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1123,7 +1123,6 @@ void ecp_set_public_key_good(int grp_id, data_t *public_data) TEST_EQUAL(key.grp.id, grp_id); TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &Q), 0); -#if defined(MBEDTLS_BIGNUM_C) /* Key with a public key already set to a different value */ TEST_EQUAL(mbedtls_mpi_add_int(&key.Q.X, &key.Q.X, 1), 0); TEST_EQUAL(mbedtls_mpi_add_int(&key.Q.Y, &key.Q.Y, 1), 0); @@ -1131,7 +1130,6 @@ void ecp_set_public_key_good(int grp_id, data_t *public_data) TEST_EQUAL(mbedtls_ecp_set_public_key(grp_id, &key, &Q), 0); TEST_EQUAL(key.grp.id, grp_id); TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &Q), 0); -#endif exit: mbedtls_ecp_keypair_free(&key); @@ -1150,10 +1148,8 @@ void ecp_set_public_key_after_private(int private_grp_id, data_t *private_data, mbedtls_ecp_group_init(&grp); mbedtls_ecp_point Q; mbedtls_ecp_point_init(&Q); -#if defined(MBEDTLS_BIGNUM_C) mbedtls_mpi d; mbedtls_mpi_init(&d); -#endif TEST_EQUAL(mbedtls_ecp_group_load(&grp, public_grp_id), 0); TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &Q, @@ -1162,9 +1158,7 @@ void ecp_set_public_key_after_private(int private_grp_id, data_t *private_data, TEST_EQUAL(mbedtls_ecp_read_key(private_grp_id, &key, private_data->x, private_data->len), 0); -#if defined(MBEDTLS_BIGNUM_C) TEST_EQUAL(mbedtls_mpi_copy(&d, &key.d), 0); -#endif int ret = mbedtls_ecp_set_public_key(public_grp_id, &key, &Q); @@ -1172,9 +1166,7 @@ void ecp_set_public_key_after_private(int private_grp_id, data_t *private_data, TEST_EQUAL(ret, 0); TEST_EQUAL(key.grp.id, public_grp_id); TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &Q), 0); -#if defined(MBEDTLS_BIGNUM_C) TEST_EQUAL(mbedtls_mpi_cmp_mpi(&d, &key.d), 0); -#endif } else { TEST_EQUAL(ret, MBEDTLS_ERR_ECP_BAD_INPUT_DATA); } @@ -1183,9 +1175,7 @@ exit: mbedtls_ecp_keypair_free(&key); mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&Q); -#if defined(MBEDTLS_BIGNUM_C) mbedtls_mpi_free(&d); -#endif } /* END_CASE */ @@ -1198,11 +1188,9 @@ void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonica mbedtls_ecp_keypair key2; mbedtls_ecp_keypair_init(&key2); -#if defined(MBEDTLS_BIGNUM_C) TEST_EQUAL(mbedtls_mpi_lset(&key.Q.X, 1), 0); TEST_EQUAL(mbedtls_mpi_lset(&key.Q.Y, 2), 0); TEST_EQUAL(mbedtls_mpi_lset(&key.Q.Z, 3), 0); -#endif ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len); TEST_ASSERT(ret == expected); @@ -1212,11 +1200,9 @@ void mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonica ret = mbedtls_ecp_check_privkey(&key.grp, &key.d); TEST_ASSERT(ret == 0); -#if defined(MBEDTLS_BIGNUM_C) TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.X, 1), 0); TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.Y, 2), 0); TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.Z, 3), 0); -#endif if (canonical) { unsigned char buf[MBEDTLS_ECP_MAX_BYTES]; From 2a185c30af0ea800335b179e0af59cbccd88ae0c Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 4 Jan 2024 13:31:36 +0100 Subject: [PATCH 028/215] changelog: rename changelog file to reflect the number of the related issue Signed-off-by: Valerio Setti --- ChangeLog.d/{8664.txt => 8340.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ChangeLog.d/{8664.txt => 8340.txt} (100%) diff --git a/ChangeLog.d/8664.txt b/ChangeLog.d/8340.txt similarity index 100% rename from ChangeLog.d/8664.txt rename to ChangeLog.d/8340.txt From 04cccef256e2f66ead467e46e38c483e5765b2a2 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 4 Jan 2024 13:33:12 +0100 Subject: [PATCH 029/215] changelog: improve wording Signed-off-by: Valerio Setti --- ChangeLog.d/8340.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog.d/8340.txt b/ChangeLog.d/8340.txt index 03e297c18..78e84f7da 100644 --- a/ChangeLog.d/8340.txt +++ b/ChangeLog.d/8340.txt @@ -1,4 +1,4 @@ Features - * mbedtls_md_psa_alg_from_type() and mbedtls_md_type_from_psa_alg() helper - functions were added to convert from mbedtls_md_type_t to psa_algorithm_t - and viceversa. + * Add functions mbedtls_md_psa_alg_from_type() and + mbedtls_md_type_from_psa_alg() to convert between mbedtls_md_type_t and + psa_algorithm_t and vice versa. From d7dc7ff91cc5c2638d7ee41b61fa5af25668c25e Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 21 Dec 2023 16:40:43 +0000 Subject: [PATCH 030/215] Update psa_key_slot_t Remove the `status` field and replace with the `state` field. Remove the `lock_count` field and replace with the `registered_readers` field. Add documentation which describes how and why these fields are to be used. Signed-off-by: Ryan Everett --- library/psa_crypto_core.h | 50 ++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 46c57755e..9ea482da2 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -35,8 +35,10 @@ int psa_can_do_hash(psa_algorithm_t hash_alg); typedef enum { PSA_SLOT_EMPTY = 0, - PSA_SLOT_OCCUPIED, -} psa_key_slot_status_t; + PSA_SLOT_FILLING, + PSA_SLOT_FULL, + PSA_SLOT_PENDING_DELETION, +} psa_key_slot_state_t; /** The data structure representing a key slot, containing key material * and metadata for one key. @@ -44,18 +46,39 @@ typedef enum { typedef struct { psa_core_key_attributes_t attr; - psa_key_slot_status_t status; + /* + * The current state of the key slot, as described in + * docs/architecture/psa-thread-safety/psa-thread-safety.md. + * + * Library functions can modify the state of a key slot by calling + * psa_key_slot_state_transition. + * + * The state variable is used to help determine whether library functions + * which operate on the slot succeed. For example, psa_finish_key_creation, + * which transfers the state of a slot from PSA_SLOT_FILLING to + * PSA_SLOT_FULL, must fail with error code PSA_ERROR_BAD_STATE + * if the state of the slot is not PSA_SLOT_FILLING. + * + * Library functions which traverse the array of key slots only consider + * slots that are in a suitable state for the function. + * For example, psa_get_and_lock_key_slot_in_memory, which finds a slot + * containing a given key ID, will only check slots whose state variable is + * PSA_SLOT_FULL. */ + psa_key_slot_state_t state; /* - * Number of locks on the key slot held by the library. + * Number of functions registered as reading the material in the key slot. * - * This counter is incremented by one each time a library function - * retrieves through one of the dedicated internal API a pointer to the - * key slot. + * Library functions must not write directly to registered_readers + * (unless the slot's state is PSA_SLOT_FILLING and the slot needs to be + * wiped following a failed key creation). * - * This counter is decremented by one each time a library function stops - * accessing the key slot and states it by calling the - * psa_unlock_key_slot() API. + * A function must call psa_register_read(slot) before reading the current + * contents of the slot for an operation. + * They then must call psa_unregister_read(slot) once they have finished + * reading the current contents of the slot. + * A function must call psa_key_slot_has_readers(slot) to check if + * the slot is in use for reading. * * This counter is used to prevent resetting the key slot while the library * may access it. For example, such control is needed in the following @@ -66,10 +89,9 @@ typedef struct { * the library cannot be reclaimed to free a key slot to load the * persistent key. * . In case of a multi-threaded application where one thread asks to close - * or purge or destroy a key while it is in used by the library through - * another thread. - */ - size_t lock_count; + * or purge or destroy a key while it is in use by the library through + * another thread. */ + size_t registered_readers; /* Dynamically allocated key data buffer. * Format as specified in psa_export_key(). */ From aa33c512cc489d18cbb48b6b64aa959046a83dd1 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 21 Dec 2023 17:32:07 +0000 Subject: [PATCH 031/215] Update psa_wipe_key_slot Change psa_wipe_key_slot to use the new state system. Signed-off-by: Ryan Everett --- library/psa_crypto.c | 16 +++++++++++----- library/psa_crypto_core.h | 9 ++++++--- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 10d17b6df..7a76c0bbf 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -981,18 +981,23 @@ psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot) * Persistent storage is not affected. */ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot) { + if (slot->state != PSA_SLOT_PENDING_DELETION) { + return PSA_ERROR_BAD_STATE; + } + psa_status_t status = psa_remove_key_data_from_memory(slot); /* * As the return error code may not be handled in case of multiple errors, - * do our best to report an unexpected lock counter. Assert with - * MBEDTLS_TEST_HOOK_TEST_ASSERT that the lock counter is equal to one: + * do our best to report an unexpected amount of registered readers. + * Assert with MBEDTLS_TEST_HOOK_TEST_ASSERT that registered_readers is + * equal to one: * if the MBEDTLS_TEST_HOOKS configuration option is enabled and the * function is called as part of the execution of a test suite, the * execution of the test suite is stopped in error if the assertion fails. */ - if (slot->lock_count != 1) { - MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->lock_count == 1); + if (slot->registered_readers != 1) { + MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 1); status = PSA_ERROR_CORRUPTION_DETECTED; } @@ -1003,7 +1008,8 @@ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot) * key material can linger until all operations are completed. */ /* At this point, key material and other type-specific content has * been wiped. Clear remaining metadata. We can call memset and not - * zeroize because the metadata is not particularly sensitive. */ + * zeroize because the metadata is not particularly sensitive. + * This memset also sets the slot's state to PSA_SLOT_EMPTY. */ memset(slot, 0, sizeof(*slot)); return status; } diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 9ea482da2..5c1edafe7 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -200,13 +200,16 @@ static inline psa_key_slot_number_t psa_key_slot_get_slot_number( /** Completely wipe a slot in memory, including its policy. * * Persistent storage is not affected. + * Sets the slot's state to PSA_SLOT_EMPTY. * * \param[in,out] slot The key slot to wipe. * * \retval #PSA_SUCCESS - * Success. This includes the case of a key slot that was - * already fully wiped. - * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * The slot has been successfully wiped. + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * The amount of registered readers was not equal to 1. + * \retval #PSA_ERROR_BAD_STATE + * The slot's state was not PSA_SLOT_PENDING_DELETION. */ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot); From 62aa79ac5c4dd4623af9a04a0caa96bcb6c23580 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 2 Jan 2024 16:21:03 +0000 Subject: [PATCH 032/215] Implement psa_key_slot_has_readers and remove psa_is_key_slot_occupied Remove psa_is_key_slot_occupied, any function which calls this can just check the state variable instead. Replace psa_is_key_slot_locked with psa_key_slot_has_readers. References to the now removed functions are changed in future commits. Signed-off-by: Ryan Everett --- library/psa_crypto_core.h | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 5c1edafe7..3b5c63497 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -106,31 +106,15 @@ typedef struct { #define PSA_KA_MASK_INTERNAL_ONLY ( \ 0) -/** Test whether a key slot is occupied. - * - * A key slot is occupied iff the key type is nonzero. This works because - * no valid key can have 0 as its key type. +/** Test whether a key slot has any registered readers. * * \param[in] slot The key slot to test. * - * \return 1 if the slot is occupied, 0 otherwise. + * \return 1 if the slot has any registered readers, 0 otherwise. */ -static inline int psa_is_key_slot_occupied(const psa_key_slot_t *slot) +static inline int psa_key_slot_has_readers(const psa_key_slot_t *slot) { - return slot->status == PSA_SLOT_OCCUPIED; -} - -/** Test whether a key slot is locked. - * - * A key slot is locked iff its lock counter is strictly greater than 0. - * - * \param[in] slot The key slot to test. - * - * \return 1 if the slot is locked, 0 otherwise. - */ -static inline int psa_is_key_slot_locked(const psa_key_slot_t *slot) -{ - return slot->lock_count > 0; + return slot->registered_readers > 0; } /** Retrieve flags from psa_key_slot_t::attr::core::flags. From 39cc9d755e20827cb7ebc3cde53065def94e2ef6 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 21 Dec 2023 17:57:14 +0000 Subject: [PATCH 033/215] Implement psa_register_read and psa_unregister_read Replaces psa_lock_key_slot and psa_unlock_key_slot. Future commits will remove the calls to locking/unlocking functions, and add calls to registering/unregistering functions. Signed-off-by: Ryan Everett --- library/psa_crypto_slot_management.c | 25 ++++++++++++----- library/psa_crypto_slot_management.h | 40 +++++++++++++++++----------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 5ecc3a76c..32881e5e9 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -394,26 +394,37 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ } -psa_status_t psa_unlock_key_slot(psa_key_slot_t *slot) +psa_status_t psa_unregister_read(psa_key_slot_t *slot) { if (slot == NULL) { return PSA_SUCCESS; } + if ((slot->state != PSA_SLOT_FULL) && + (slot->state != PSA_SLOT_PENDING_DELETION)) { + return PSA_ERROR_BAD_STATE; + } - if (slot->lock_count > 0) { - slot->lock_count--; + /* If we are the last reader and the slot is marked for deletion, + * we must wipe the slot here. */ + if ((slot->state == PSA_SLOT_PENDING_DELETION) && + (slot->registered_readers == 1)) { + return psa_wipe_key_slot(slot); + } + + if (psa_key_slot_has_readers(slot)) { + slot->registered_readers--; return PSA_SUCCESS; } /* * As the return error code may not be handled in case of multiple errors, - * do our best to report if the lock counter is equal to zero. Assert with - * MBEDTLS_TEST_HOOK_TEST_ASSERT that the lock counter is strictly greater - * than zero: if the MBEDTLS_TEST_HOOKS configuration option is enabled and + * do our best to report if there are no registered readers. Assert with + * MBEDTLS_TEST_HOOK_TEST_ASSERT that there are registered readers: + * if the MBEDTLS_TEST_HOOKS configuration option is enabled and * the function is called as part of the execution of a test suite, the * execution of the test suite is stopped in error if the assertion fails. */ - MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->lock_count > 0); + MBEDTLS_TEST_HOOK_TEST_ASSERT(psa_key_slot_has_readers(slot)); return PSA_ERROR_CORRUPTION_DETECTED; } diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index 6041a3528..c38876d3d 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -113,32 +113,39 @@ void psa_wipe_all_key_slots(void); psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id, psa_key_slot_t **p_slot); -/** Lock a key slot. +/** Register as a reader of a key slot. * - * This function increments the key slot lock counter by one. + * This function increments the key slot registered reader counter by one. * * \param[in] slot The key slot. * * \retval #PSA_SUCCESS - The key slot lock counter was incremented. + The key slot registered reader counter was incremented. * \retval #PSA_ERROR_CORRUPTION_DETECTED - * The lock counter already reached its maximum value and was not + * The reader counter already reached its maximum value and was not * increased. + * \retval #PSA_ERROR_BAD_STATE + * The slot's state was not PSA_SLOT_FULL. */ -static inline psa_status_t psa_lock_key_slot(psa_key_slot_t *slot) +static inline psa_status_t psa_register_read(psa_key_slot_t *slot) { - if (slot->lock_count >= SIZE_MAX) { + if (slot->state != PSA_SLOT_FULL) { + return PSA_ERROR_BAD_STATE; + } + if (slot->registered_readers >= SIZE_MAX) { return PSA_ERROR_CORRUPTION_DETECTED; } - - slot->lock_count++; + slot->registered_readers++; return PSA_SUCCESS; } -/** Unlock a key slot. +/** Unregister from reading a key slot. * - * This function decrements the key slot lock counter by one. + * This function decrements the key slot registered reader counter by one. + * If the state of the slot is PSA_SLOT_PENDING_DELETION, + * and there is only one registered reader (the caller), + * this function will call psa_wipe_slot(). * * \note To ease the handling of errors in retrieving a key slot * a NULL input pointer is valid, and the function returns @@ -146,13 +153,16 @@ static inline psa_status_t psa_lock_key_slot(psa_key_slot_t *slot) * * \param[in] slot The key slot. * \retval #PSA_SUCCESS - * \p slot is NULL or the key slot lock counter has been - * decremented successfully. + * \p slot is NULL or the key slot reader counter has been + * decremented (and potentially wiped) successfully. * \retval #PSA_ERROR_CORRUPTION_DETECTED - * The lock counter was equal to 0. - * + * registered_readers was equal to 0. + * \retval #PSA_ERROR_BAD_STATE + * The slot's state was neither PSA_SLOT_FULL nor + * PSA_SLOT_PENDING_DELETION, or a wipe was attempted and + * the slot's state was not PSA_SLOT_PENDING_DELETION. */ -psa_status_t psa_unlock_key_slot(psa_key_slot_t *slot); +psa_status_t psa_unregister_read(psa_key_slot_t *slot); /** Test whether a lifetime designates a key in an external cryptoprocessor. * From 4a78277cb2684ca0e9615ba390ecee87d27dde06 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 4 Jan 2024 10:53:26 +0000 Subject: [PATCH 034/215] Implement psa_key_slot_state_transition This inline function is used in every case we want to change the state of a slot, except for where we do not care about what the state of the slot was before. Signed-off-by: Ryan Everett --- library/psa_crypto_slot_management.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index c38876d3d..f0bbed98f 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -112,6 +112,31 @@ void psa_wipe_all_key_slots(void); */ psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id, psa_key_slot_t **p_slot); +/** Change the state of a key slot. + * + * This function changes the state of the key slot from expected_state to + * new state. If the state of the slot was not expected_state, the state is + * unchanged. + * + * \param[in] slot The key slot. + * \param[in] expected_state The current state of the slot. + * \param[in] new_state The new state of the slot. + * + * \retval #PSA_SUCCESS + The key slot's state variable is new_state. + * \retval #PSA_ERROR_BAD_STATE + * The slot's state was not expected_state. + */ +static inline psa_status_t psa_key_slot_state_transition( + psa_key_slot_t *slot, psa_key_slot_state_t expected_state, + psa_key_slot_state_t new_state) +{ + if (slot->state != expected_state) { + return PSA_ERROR_BAD_STATE; + } + slot->state = new_state; + return PSA_SUCCESS; +} /** Register as a reader of a key slot. * From 2afb5160110f54a5d89e968723b3dbb940de42b7 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 22 Dec 2023 15:59:45 +0000 Subject: [PATCH 035/215] Update and rename psa_get_empty_key_slot Rename to psa_reserve_free_key_slot, as this function reserves a slot which is free (not always empty) for filling. Implement necessary state transitions and state checks. Rename unlocked_persistent_key_slot to unused_persistent_key_slot. Signed-off-by: Ryan Everett --- library/psa_crypto_slot_management.c | 39 +++++++++++++++++----------- library/psa_crypto_slot_management.h | 24 ++++++++++------- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 32881e5e9..0f480fb09 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -147,30 +147,31 @@ void psa_wipe_all_key_slots(void) global_data.key_slots_initialized = 0; } -psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id, - psa_key_slot_t **p_slot) +psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, + psa_key_slot_t **p_slot) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t slot_idx; - psa_key_slot_t *selected_slot, *unlocked_persistent_key_slot; + psa_key_slot_t *selected_slot, *unused_persistent_key_slot; if (!global_data.key_slots_initialized) { status = PSA_ERROR_BAD_STATE; goto error; } - selected_slot = unlocked_persistent_key_slot = NULL; + selected_slot = unused_persistent_key_slot = NULL; for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) { psa_key_slot_t *slot = &global_data.key_slots[slot_idx]; - if (!psa_is_key_slot_occupied(slot)) { + if (slot->state == PSA_SLOT_EMPTY) { selected_slot = slot; break; } - if ((unlocked_persistent_key_slot == NULL) && - (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) && - (!psa_is_key_slot_locked(slot))) { - unlocked_persistent_key_slot = slot; + if ((unused_persistent_key_slot == NULL) && + (slot->state == PSA_SLOT_FULL) && + (!psa_key_slot_has_readers(slot)) && + (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime))) { + unused_persistent_key_slot = slot; } } @@ -182,16 +183,24 @@ psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id, * storage. */ if ((selected_slot == NULL) && - (unlocked_persistent_key_slot != NULL)) { - selected_slot = unlocked_persistent_key_slot; - selected_slot->lock_count = 1; - psa_wipe_key_slot(selected_slot); + (unused_persistent_key_slot != NULL)) { + selected_slot = unused_persistent_key_slot; + psa_register_read(selected_slot); + /* If the state is not changed then psa_wipe_key_slot + * will report an error. */ + psa_key_slot_state_transition(selected_slot, PSA_SLOT_FULL, + PSA_SLOT_PENDING_DELETION); + status = psa_wipe_key_slot(selected_slot); + if (status != PSA_SUCCESS) { + goto error; + } } if (selected_slot != NULL) { - status = psa_lock_key_slot(selected_slot); + status = psa_key_slot_state_transition(selected_slot, PSA_SLOT_EMPTY, + PSA_SLOT_FILLING); if (status != PSA_SUCCESS) { - goto error; + return status; } *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN + diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index f0bbed98f..b2cf57011 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -95,23 +95,29 @@ psa_status_t psa_initialize_key_slots(void); * This does not affect persistent storage. */ void psa_wipe_all_key_slots(void); -/** Find a free key slot. +/** Find a free key slot and reserve it to be filled with a key. * - * This function returns a key slot that is available for use and is in its - * ground state (all-bits-zero). On success, the key slot is locked. It is - * the responsibility of the caller to unlock the key slot when it does not - * access it anymore. + * This function finds a key slot that is free, + * sets its state to PSA_SLOT_FILLING and then returns the slot. + * + * On success, the key slot's state is PSA_SLOT_FILLING. + * It is the responsibility of the caller to change the slot's state to + * PSA_SLOT_EMPTY/FULL once key creation has finished. * * \param[out] volatile_key_id On success, volatile key identifier * associated to the returned slot. * \param[out] p_slot On success, a pointer to the slot. * * \retval #PSA_SUCCESS \emptydescription - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription - * \retval #PSA_ERROR_BAD_STATE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * There were no free key slots. + * \retval #PSA_ERROR_BAD_STATE + * This function attempted to operate on a key slot which was in an + * unexpected state. */ -psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id, - psa_key_slot_t **p_slot); +psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, + psa_key_slot_t **p_slot); + /** Change the state of a key slot. * * This function changes the state of the key slot from expected_state to From b69118ebd0b7aa63d5b7c9b2c17f295aa4c854f8 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 2 Jan 2024 15:54:32 +0000 Subject: [PATCH 036/215] Update key creation functions to use the new key slot states Update psa_start_key_creation, psa_finish_key_creation and psa_fail_key_creation. Signed-off-by: Ryan Everett --- library/psa_crypto.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 7a76c0bbf..3c5bbbdf6 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1576,8 +1576,9 @@ static psa_status_t psa_validate_key_attributes( * In case of failure at any step, stop the sequence and call * psa_fail_key_creation(). * - * On success, the key slot is locked. It is the responsibility of the caller - * to unlock the key slot when it does not access it anymore. + * On success, the key slot's state is PSA_SLOT_FILLING. + * It is the responsibility of the caller to change the slot's state to + * PSA_SLOT_EMPTY/FULL once key creation has finished. * * \param method An identification of the calling function. * \param[in] attributes Key attributes for the new key. @@ -1608,7 +1609,7 @@ static psa_status_t psa_start_key_creation( return status; } - status = psa_get_empty_key_slot(&volatile_key_id, p_slot); + status = psa_reserve_free_key_slot(&volatile_key_id, p_slot); if (status != PSA_SUCCESS) { return status; } @@ -1634,7 +1635,7 @@ static psa_status_t psa_start_key_creation( /* Erase external-only flags from the internal copy. To access * external-only flags, query `attributes`. Thanks to the check * in psa_validate_key_attributes(), this leaves the dual-use - * flags and any internal flag that psa_get_empty_key_slot() + * flags and any internal flag that psa_reserve_free_key_slot() * may have set. */ slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY; @@ -1686,8 +1687,6 @@ static psa_status_t psa_start_key_creation( } #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - slot->status = PSA_SLOT_OCCUPIED; - return PSA_SUCCESS; } @@ -1699,9 +1698,9 @@ static psa_status_t psa_start_key_creation( * See the documentation of psa_start_key_creation() for the intended use * of this function. * - * If the finalization succeeds, the function unlocks the key slot (it was - * locked by psa_start_key_creation()) and the key slot cannot be accessed - * anymore as part of the key creation process. + * If the finalization succeeds, the function sets the key slot's state to + * PSA_SLOT_FULL, and the key slot can no longer be accessed as part of the + * key creation process. * * \param[in,out] slot Pointer to the slot with key material. * \param[in] driver The secure element driver for the key, @@ -1717,6 +1716,7 @@ static psa_status_t psa_start_key_creation( * \retval #PSA_ERROR_DATA_INVALID \emptydescription * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE \emptydescription * * \return If this function fails, the key slot is an invalid state. * You must call psa_fail_key_creation() to wipe and free the slot. @@ -1777,7 +1777,8 @@ static psa_status_t psa_finish_key_creation( if (status == PSA_SUCCESS) { *key = slot->attr.id; - status = psa_unlock_key_slot(slot); + status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING, + PSA_SLOT_FULL); if (status != PSA_SUCCESS) { *key = MBEDTLS_SVC_KEY_ID_INIT; } @@ -1792,7 +1793,7 @@ static psa_status_t psa_finish_key_creation( * or after psa_finish_key_creation() fails. In other circumstances, this * function may not clean up persistent storage. * See the documentation of psa_start_key_creation() for the intended use - * of this function. + * of this function. Sets the slot's state to PSA_SLOT_EMPTY. * * \param[in,out] slot Pointer to the slot with key material. * \param[in] driver The secure element driver for the key, @@ -1824,6 +1825,11 @@ static void psa_fail_key_creation(psa_key_slot_t *slot, (void) psa_crypto_stop_transaction(); #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + /* Prepare the key slot to be wiped, and then wipe it. */ + slot->registered_readers = 1; + psa_key_slot_state_transition(slot, PSA_SLOT_FILLING, + PSA_SLOT_PENDING_DELETION); + psa_wipe_key_slot(slot); } From 098c6659ada1a89194caddcf8bc7334a463f502b Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Wed, 3 Jan 2024 13:03:36 +0000 Subject: [PATCH 037/215] Update psa_get_and_lock_key_slot_X functions Signed-off-by: Ryan Everett --- library/psa_crypto.c | 14 ++++++++------ library/psa_crypto_slot_management.c | 19 ++++++++++++++++--- library/psa_crypto_slot_management.h | 9 ++++++--- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 3c5bbbdf6..a27fd42c4 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -881,8 +881,9 @@ static psa_status_t psa_restrict_key_policy( * In case of a persistent key, the function loads the description of the key * into a key slot if not already done. * - * On success, the returned key slot is locked. It is the responsibility of - * the caller to unlock the key slot when it does not access it anymore. + * On success, the returned key slot has been registered for reading. + * It is the responsibility of the caller to call psa_unregister_read(slot) + * when they have finished reading the contents of the slot. */ static psa_status_t psa_get_and_lock_key_slot_with_policy( mbedtls_svc_key_id_t key, @@ -926,7 +927,7 @@ static psa_status_t psa_get_and_lock_key_slot_with_policy( error: *p_slot = NULL; - psa_unlock_key_slot(slot); + psa_unregister_read(slot); return status; } @@ -941,8 +942,9 @@ error: * psa_get_and_lock_key_slot_with_policy() when there is no opaque key support * for a cryptographic operation. * - * On success, the returned key slot is locked. It is the responsibility of the - * caller to unlock the key slot when it does not access it anymore. + * On success, the returned key slot has been registered for reading. + * It is the responsibility of the caller to call psa_unregister_read(slot) + * when they have finished reading the contents of the slot. */ static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy( mbedtls_svc_key_id_t key, @@ -957,7 +959,7 @@ static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy( } if (psa_key_lifetime_is_external((*p_slot)->attr.lifetime)) { - psa_unlock_key_slot(*p_slot); + psa_unregister_read(*p_slot); *p_slot = NULL; return PSA_ERROR_NOT_SUPPORTED; } diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 0f480fb09..4846e33ea 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -108,7 +108,9 @@ static psa_status_t psa_get_and_lock_key_slot_in_memory( for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) { slot = &global_data.key_slots[slot_idx]; - if (mbedtls_svc_key_id_equal(key, slot->attr.id)) { + /* Only consider slots which are in a full state. */ + if ((slot->state == PSA_SLOT_FULL) && + (mbedtls_svc_key_id_equal(key, slot->attr.id))) { break; } } @@ -117,7 +119,7 @@ static psa_status_t psa_get_and_lock_key_slot_in_memory( } if (status == PSA_SUCCESS) { - status = psa_lock_key_slot(slot); + status = psa_register_read(slot); if (status == PSA_SUCCESS) { *p_slot = slot; } @@ -367,7 +369,7 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) psa_key_id_t volatile_key_id; - status = psa_get_empty_key_slot(&volatile_key_id, p_slot); + status = psa_reserve_free_key_slot(&volatile_key_id, p_slot); if (status != PSA_SUCCESS) { return status; } @@ -388,13 +390,24 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ if (status != PSA_SUCCESS) { + /* Prepare the key slot to be wiped, and then wipe it. + * Don't overwrite status as a BAD_STATE error here + * can be reported in the psa_wipe_key_slot call. */ + (*p_slot)->registered_readers = 1; + psa_key_slot_state_transition((*p_slot), PSA_SLOT_FILLING, + PSA_SLOT_PENDING_DELETION); psa_wipe_key_slot(*p_slot); + if (status == PSA_ERROR_DOES_NOT_EXIST) { status = PSA_ERROR_INVALID_HANDLE; } } else { /* Add implicit usage flags. */ psa_extend_key_usage_flags(&(*p_slot)->attr.policy.usage); + + psa_key_slot_state_transition((*p_slot), PSA_SLOT_FILLING, + PSA_SLOT_FULL); + status = psa_register_read(*p_slot); } return status; diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index b2cf57011..5858b1851 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -54,8 +54,9 @@ static inline int psa_key_id_is_volatile(psa_key_id_t key_id) * In case of a persistent key, the function loads the description of the key * into a key slot if not already done. * - * On success, the returned key slot is locked. It is the responsibility of - * the caller to unlock the key slot when it does not access it anymore. + * On success, the returned key slot has been registered for reading. + * It is the responsibility of the caller to call psa_unregister_read(slot) + * when they have finished reading the contents of the slot. * * \param key Key identifier to query. * \param[out] p_slot On success, `*p_slot` contains a pointer to the @@ -67,7 +68,9 @@ static inline int psa_key_id_is_volatile(psa_key_id_t key_id) * description of the key identified by \p key. * The key slot counter has been incremented. * \retval #PSA_ERROR_BAD_STATE - * The library has not been initialized. + * The library has not been initialized. Or, + * this call was operating on a key slot and found the slot in + * an invalid state for the operation. * \retval #PSA_ERROR_INVALID_HANDLE * \p key is not a valid key identifier. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY From c70ce576bd8856a8efa99d4353700bd3130d000b Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Wed, 3 Jan 2024 16:04:33 +0000 Subject: [PATCH 038/215] Update psa_destroy_key, psa_purge_key and psa_close_key This does not yet implement destruction while a key is in use for psa_destroy_key; that will be implemented in a separate pr. (I am not sure if I am allowed to change the documentation in the include files.) Signed-off-by: Ryan Everett --- include/psa/crypto.h | 8 ++++++-- include/psa/crypto_compat.h | 4 +++- library/psa_crypto.c | 8 +++++--- library/psa_crypto_slot_management.c | 19 +++++++++++-------- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index fe10ee0e4..fd1928a65 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -415,7 +415,9 @@ void psa_reset_key_attributes(psa_key_attributes_t *attributes); * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize - * results in this error code. + * results in this error code. Or, + * this call was operating on a key slot and found the slot in + * an invalid state for the operation. */ psa_status_t psa_purge_key(mbedtls_svc_key_id_t key); @@ -555,7 +557,9 @@ psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize - * results in this error code. + * results in this error code. Or, + * this call was operating on a key slot and found the slot in + * an invalid state for the operation. */ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key); diff --git a/include/psa/crypto_compat.h b/include/psa/crypto_compat.h index f896fae1c..bfc00164b 100644 --- a/include/psa/crypto_compat.h +++ b/include/psa/crypto_compat.h @@ -142,7 +142,9 @@ psa_status_t psa_open_key(mbedtls_svc_key_id_t key, * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize - * results in this error code. + * results in this error code. Or, + * this call was operating on a key slot and found the slot in + * an invalid state for the operation. */ psa_status_t psa_close_key(psa_key_handle_t handle); diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a27fd42c4..3e49d0a75 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1048,11 +1048,13 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key) * implemented), the key should be destroyed when all accesses have * stopped. */ - if (slot->lock_count > 1) { - psa_unlock_key_slot(slot); + if (slot->registered_readers > 1) { + psa_unregister_read(slot); return PSA_ERROR_GENERIC_ERROR; } + slot->state = PSA_SLOT_PENDING_DELETION; + if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) { /* Refuse the destruction of a read-only key (which may or may not work * if we attempt it, depending on whether the key is merely read-only @@ -1126,7 +1128,7 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key) exit: status = psa_wipe_key_slot(slot); - /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */ + /* Prioritize an error from wiping over a storage error */ if (status != PSA_SUCCESS) { overall_status = status; } diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 4846e33ea..a21388a0b 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -539,11 +539,14 @@ psa_status_t psa_close_key(psa_key_handle_t handle) return status; } - if (slot->lock_count <= 1) { - return psa_wipe_key_slot(slot); - } else { - return psa_unlock_key_slot(slot); + if (slot->registered_readers == 1) { + status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL, + PSA_SLOT_PENDING_DELETION); + if (status != PSA_SUCCESS) { + return status; + } } + return psa_unregister_read(slot); } psa_status_t psa_purge_key(mbedtls_svc_key_id_t key) @@ -557,11 +560,11 @@ psa_status_t psa_purge_key(mbedtls_svc_key_id_t key) } if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) && - (slot->lock_count <= 1)) { - return psa_wipe_key_slot(slot); - } else { - return psa_unlock_key_slot(slot); + (slot->registered_readers == 1)) { + psa_key_slot_state_transition(slot, PSA_SLOT_FULL, + PSA_SLOT_PENDING_DELETION); } + return psa_unregister_read(slot); } void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats) From eb27dc0f3a95e0c75b45a3366e862324b90bc742 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Wed, 3 Jan 2024 16:19:12 +0000 Subject: [PATCH 039/215] Update psa_load_X_key_into_slot These functions (on success) take a slot from PSA_SLOT_FILLING to PSA_SLOT_FULL. Signed-off-by: Ryan Everett --- library/psa_crypto_slot_management.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index a21388a0b..3d997a50c 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -250,7 +250,8 @@ static psa_status_t psa_load_persistent_key_into_slot(psa_key_slot_t *slot) slot, data->slot_number, sizeof(data->slot_number)); if (status == PSA_SUCCESS) { - slot->status = PSA_SLOT_OCCUPIED; + status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING, + PSA_SLOT_FULL); } goto exit; } @@ -261,7 +262,8 @@ static psa_status_t psa_load_persistent_key_into_slot(psa_key_slot_t *slot) goto exit; } - slot->status = PSA_SLOT_OCCUPIED; + status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING, + PSA_SLOT_FULL); exit: psa_free_persistent_key_data(key_data, key_data_length); @@ -335,8 +337,9 @@ static psa_status_t psa_load_builtin_key_into_slot(psa_key_slot_t *slot) /* Copy actual key length and core attributes into the slot on success */ slot->key.bytes = key_buffer_length; slot->attr = attributes.core; - slot->status = PSA_SLOT_OCCUPIED; + status = psa_key_slot_state_transition(slot, PSA_SLOT_FILLING, + PSA_SLOT_FULL); exit: if (status != PSA_SUCCESS) { psa_remove_key_data_from_memory(slot); From 1b70a07eca5bd44bef32203c59ecf5f033246f64 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 4 Jan 2024 10:32:49 +0000 Subject: [PATCH 040/215] Replace psa_unlock_key_slot calls in operations which act on FULL slots Replaces calls to psa_unlock_key_slot with calls to psa_unregister_read. All instances follow a pattern of a call to psa_get_and_lock_key_slot_X, followed by some code which reads from a slot, followed by a call to psa_unregister_read. Signed-off-by: Ryan Everett --- library/psa_crypto.c | 44 ++++++++++++++-------------- library/psa_crypto_slot_management.c | 2 +- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 3e49d0a75..da5e5be77 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1253,7 +1253,7 @@ psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key, psa_reset_key_attributes(attributes); } - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -1349,7 +1349,7 @@ psa_status_t psa_export_key(mbedtls_svc_key_id_t key, slot->key.data, slot->key.bytes, data, data_size, data_length); - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -1463,7 +1463,7 @@ psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, data, data_size, data_length); exit: - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -2141,7 +2141,7 @@ exit: psa_fail_key_creation(target_slot, driver); } - unlock_status = psa_unlock_key_slot(source_slot); + unlock_status = psa_unregister_read(source_slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -2462,7 +2462,7 @@ exit: psa_mac_abort(operation); } - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -2648,7 +2648,7 @@ exit: psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length); - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -2792,7 +2792,7 @@ exit: psa_wipe_tag_output_buffer(signature, status, signature_size, *signature_length); - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -2840,7 +2840,7 @@ static psa_status_t psa_verify_internal(mbedtls_svc_key_id_t key, signature, signature_length); } - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; @@ -3107,7 +3107,7 @@ psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, alg, input, input_length, salt, salt_length, output, output_size, output_length); exit: - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -3159,7 +3159,7 @@ psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, output, output_size, output_length); exit: - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -3268,7 +3268,7 @@ exit: psa_sign_hash_abort_internal(operation); } - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); if (unlock_status != PSA_SUCCESS) { operation->error_occurred = 1; @@ -3413,7 +3413,7 @@ psa_status_t psa_verify_hash_start( psa_verify_hash_abort_internal(operation); } - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); if (unlock_status != PSA_SUCCESS) { operation->error_occurred = 1; @@ -3985,7 +3985,7 @@ exit: psa_cipher_abort(operation); } - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -4230,7 +4230,7 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, output_size - default_iv_length, output_length); exit: - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); if (status == PSA_SUCCESS) { status = unlock_status; } @@ -4291,7 +4291,7 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, output, output_size, output_length); exit: - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); if (status == PSA_SUCCESS) { status = unlock_status; } @@ -4417,7 +4417,7 @@ psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, } exit: - psa_unlock_key_slot(slot); + psa_unregister_read(slot); return status; } @@ -4472,7 +4472,7 @@ psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, } exit: - psa_unlock_key_slot(slot); + psa_unregister_read(slot); return status; } @@ -4584,7 +4584,7 @@ static psa_status_t psa_aead_setup(psa_aead_operation_t *operation, operation->key_type = psa_get_key_type(&attributes); exit: - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); if (status == PSA_SUCCESS) { status = unlock_status; @@ -6907,7 +6907,7 @@ psa_status_t psa_key_derivation_input_key( slot->key.data, slot->key.bytes); - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -7064,7 +7064,7 @@ psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *op } } - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -7125,7 +7125,7 @@ exit: *output_length = output_size; } - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } @@ -7799,7 +7799,7 @@ exit: if (status != PSA_SUCCESS) { psa_pake_abort(operation); } - unlock_status = psa_unlock_key_slot(slot); + unlock_status = psa_unregister_read(slot); return (status == PSA_SUCCESS) ? unlock_status : status; } diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 3d997a50c..3c16de334 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -516,7 +516,7 @@ psa_status_t psa_open_key(mbedtls_svc_key_id_t key, psa_key_handle_t *handle) *handle = key; - return psa_unlock_key_slot(slot); + return psa_unregister_read(slot); #else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ (void) key; From 6cd2b8db960e30cdd858a695b8618731c3225cc0 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 4 Jan 2024 12:10:18 +0000 Subject: [PATCH 041/215] Update psa_wipe_all_key_slots This will still wipe the slot regardless of state/readers. Signed-off-by: Ryan Everett --- library/psa_crypto_slot_management.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 3c16de334..a8be912b7 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -143,7 +143,8 @@ void psa_wipe_all_key_slots(void) for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) { psa_key_slot_t *slot = &global_data.key_slots[slot_idx]; - slot->lock_count = 1; + slot->registered_readers = 1; + slot->state = PSA_SLOT_PENDING_DELETION; (void) psa_wipe_key_slot(slot); } global_data.key_slots_initialized = 0; From 6a9c14b918da52d614fcff92df382b03aa366ff9 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 4 Jan 2024 12:13:45 +0000 Subject: [PATCH 042/215] Update mbedtls_psa_get_stats Uses readers to report "locked_slots", and slot state empty to report "empty_slots". Signed-off-by: Ryan Everett --- library/psa_crypto_slot_management.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index a8be912b7..ef76dcb89 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -579,10 +579,10 @@ void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats) for (slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++) { const psa_key_slot_t *slot = &global_data.key_slots[slot_idx]; - if (psa_is_key_slot_locked(slot)) { + if (psa_key_slot_has_readers(slot)) { ++stats->locked_slots; } - if (!psa_is_key_slot_occupied(slot)) { + if (slot->state == PSA_SLOT_EMPTY) { ++stats->empty_slots; continue; } From 3742f7c4b46d85369e8691efbf0f291a6f0d9830 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 5 Jan 2024 10:37:58 +0100 Subject: [PATCH 043/215] changelog: improve wording Signed-off-by: Valerio Setti --- ChangeLog.d/8340.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/8340.txt b/ChangeLog.d/8340.txt index 78e84f7da..5664bf170 100644 --- a/ChangeLog.d/8340.txt +++ b/ChangeLog.d/8340.txt @@ -1,4 +1,4 @@ Features * Add functions mbedtls_md_psa_alg_from_type() and mbedtls_md_type_from_psa_alg() to convert between mbedtls_md_type_t and - psa_algorithm_t and vice versa. + psa_algorithm_t. From 98f5db9fca7fa9dc3a30c3264b720e41589d713d Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 5 Jan 2024 18:17:38 +0100 Subject: [PATCH 044/215] psa_util: fix typo in comment Signed-off-by: Valerio Setti --- include/mbedtls/psa_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index e8fb3de61..7fcc9d2b0 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -155,7 +155,7 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve, * \param md_type The type of digest to search for. * * \return The PSA algorithm identifier associated with \p md_type; - * #PSA_ALG_NONE if the algorithm is unuspported or invalid. + * #PSA_ALG_NONE if the algorithm is unsupported or invalid. */ psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type); From cd38f2720678fffd28669aa1625695106060695f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 9 Jan 2024 08:41:03 +0100 Subject: [PATCH 045/215] Revert "psa_util: fix typo in comment" This reverts commit 98f5db9fca7fa9dc3a30c3264b720e41589d713d. Signed-off-by: Valerio Setti --- include/mbedtls/psa_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index 7fcc9d2b0..e8fb3de61 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -155,7 +155,7 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve, * \param md_type The type of digest to search for. * * \return The PSA algorithm identifier associated with \p md_type; - * #PSA_ALG_NONE if the algorithm is unsupported or invalid. + * #PSA_ALG_NONE if the algorithm is unuspported or invalid. */ psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type); From 9b2d738ccde53c4643a9905f548509e2a8457d86 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 9 Jan 2024 08:41:21 +0100 Subject: [PATCH 046/215] Revert "test_suite_md: improve md_to_from_psa() test function and related data" This reverts commit 2c1070b39700be8a6fcda5f2266e8bbe5ac42e1c. Signed-off-by: Valerio Setti --- tests/suites/test_suite_md.data | 48 ++--------------------------- tests/suites/test_suite_md.function | 24 ++++++++++++--- 2 files changed, 21 insertions(+), 51 deletions(-) diff --git a/tests/suites/test_suite_md.data b/tests/suites/test_suite_md.data index b831500d6..fb9b5effa 100644 --- a/tests/suites/test_suite_md.data +++ b/tests/suites/test_suite_md.data @@ -2,52 +2,8 @@ MD list mbedtls_md_list: -MD <-> PSA conversion - MD5 -depends_on:PSA_WANT_ALG_MD5 -md_to_from_psa:MBEDTLS_MD_MD5:PSA_ALG_MD5 - -MD <-> PSA conversion - RIPEMD160 -depends_on:PSA_WANT_ALG_RIPEMD160 -md_to_from_psa:MBEDTLS_MD_RIPEMD160:PSA_ALG_RIPEMD160 - -MD <-> PSA conversion - SHA1 -depends_on:PSA_WANT_ALG_SHA_1 -md_to_from_psa:MBEDTLS_MD_SHA1:PSA_ALG_SHA_1 - -MD <-> PSA conversion - SHA224 -depends_on:PSA_WANT_ALG_SHA_224 -md_to_from_psa:MBEDTLS_MD_SHA224:PSA_ALG_SHA_224 - -MD <-> PSA conversion - SHA256 -depends_on:PSA_WANT_ALG_SHA_256 -md_to_from_psa:MBEDTLS_MD_SHA256:PSA_ALG_SHA_256 - -MD <-> PSA conversion - SHA384 -depends_on:PSA_WANT_ALG_SHA_384 -md_to_from_psa:MBEDTLS_MD_SHA384:PSA_ALG_SHA_384 - -MD <-> PSA conversion - SHA512 -depends_on:PSA_WANT_ALG_SHA_512 -md_to_from_psa:MBEDTLS_MD_SHA512:PSA_ALG_SHA_512 - -MD <-> PSA conversion - SHA3_224 -depends_on:PSA_WANT_ALG_SHA3_224 -md_to_from_psa:MBEDTLS_MD_SHA3_224:PSA_ALG_SHA3_224 - -MD <-> PSA conversion - SHA3_256 -depends_on:PSA_WANT_ALG_SHA3_256 -md_to_from_psa:MBEDTLS_MD_SHA3_256:PSA_ALG_SHA3_256 - -MD <-> PSA conversion - SHA3_384 -depends_on:PSA_WANT_ALG_SHA3_384 -md_to_from_psa:MBEDTLS_MD_SHA3_384:PSA_ALG_SHA3_384 - -MD <-> PSA conversion - SHA3_512 -depends_on:PSA_WANT_ALG_SHA3_512 -md_to_from_psa:MBEDTLS_MD_SHA3_512:PSA_ALG_SHA3_512 - -MD <-> PSA conversion - NONE -md_to_from_psa:MBEDTLS_MD_NONE:PSA_ALG_NONE +MD <-> PSA conversion +md_to_from_psa: MD NULL/uninitialised arguments md_null_args: diff --git a/tests/suites/test_suite_md.function b/tests/suites/test_suite_md.function index 0a8e4216e..2a885e237 100644 --- a/tests/suites/test_suite_md.function +++ b/tests/suites/test_suite_md.function @@ -4,6 +4,10 @@ #include "mbedtls/oid.h" #include "mbedtls/asn1.h" + +#define MD_PSA(md, psa) \ + TEST_EQUAL(mbedtls_md_psa_alg_from_type(md), psa); \ + TEST_EQUAL(mbedtls_md_type_from_psa_alg(psa), md); /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -59,13 +63,23 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C */ -void md_to_from_psa(int md_alg_arg, int psa_alg_arg) +void md_to_from_psa() { - mbedtls_md_type_t md_alg = md_alg_arg; - psa_algorithm_t psa_alg = psa_alg_arg; + /* We use a simplified implementation that relies on numerical values + * being aligned, so make sure they remain so. */ + MD_PSA(MBEDTLS_MD_MD5, PSA_ALG_MD5); + MD_PSA(MBEDTLS_MD_RIPEMD160, PSA_ALG_RIPEMD160); + MD_PSA(MBEDTLS_MD_SHA1, PSA_ALG_SHA_1); + MD_PSA(MBEDTLS_MD_SHA224, PSA_ALG_SHA_224); + MD_PSA(MBEDTLS_MD_SHA256, PSA_ALG_SHA_256); + MD_PSA(MBEDTLS_MD_SHA384, PSA_ALG_SHA_384); + MD_PSA(MBEDTLS_MD_SHA512, PSA_ALG_SHA_512); + MD_PSA(MBEDTLS_MD_SHA3_224, PSA_ALG_SHA3_224); + MD_PSA(MBEDTLS_MD_SHA3_256, PSA_ALG_SHA3_256); + MD_PSA(MBEDTLS_MD_SHA3_384, PSA_ALG_SHA3_384); + MD_PSA(MBEDTLS_MD_SHA3_512, PSA_ALG_SHA3_512); - TEST_EQUAL(mbedtls_md_psa_alg_from_type(md_alg), psa_alg); \ - TEST_EQUAL(mbedtls_md_type_from_psa_alg(psa_alg), md_alg); + /* Don't test for NONE<->NONE as this is not guaranteed */ } /* END_CASE */ From dd2afcd881df115474eb12f9aa877b35530ec799 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 9 Jan 2024 08:41:29 +0100 Subject: [PATCH 047/215] Revert "psa_util: add algorithm's availability checks for MD conversion functions" This reverts commit 3d2e0f5f42b9ac646f63d67e442f4af0f8a3fe4f. Signed-off-by: Valerio Setti --- include/mbedtls/psa_util.h | 27 +++++++--- library/psa_util.c | 106 ------------------------------------- 2 files changed, 21 insertions(+), 112 deletions(-) diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index e8fb3de61..249b8d421 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -152,12 +152,21 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve, * \brief This function returns the PSA algorithm identifier * associated with the given digest type. * - * \param md_type The type of digest to search for. + * \param md_type The type of digest to search for. Must not be NONE. * - * \return The PSA algorithm identifier associated with \p md_type; - * #PSA_ALG_NONE if the algorithm is unuspported or invalid. + * \warning If \p md_type is \c MBEDTLS_MD_NONE, this function will + * not return \c PSA_ALG_NONE, but an invalid algorithm. + * + * \warning This function does not check if the algorithm is + * supported, it always returns the corresponding identifier. + * + * \return The PSA algorithm identifier associated with \p md_type, + * regardless of whether it is supported or not. */ -psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type); +static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type) +{ + return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) md_type; +} /** * \brief This function returns the given digest type @@ -165,10 +174,16 @@ psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type); * * \param psa_alg The PSA algorithm identifier to search for. * + * \warning This function does not check if the algorithm is + * supported, it always returns the corresponding identifier. + * * \return The MD type associated with \p psa_alg, - * #MBEDTLS_MD_NONE if the algorithm is unsupported or invalid. + * regardless of whether it is supported or not. */ -mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg); +static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg) +{ + return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK); +} /**@}*/ diff --git a/library/psa_util.c b/library/psa_util.c index bb054a33f..9b06de273 100644 --- a/library/psa_util.c +++ b/library/psa_util.c @@ -330,110 +330,4 @@ mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve, } #endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ -psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type) -{ - switch (md_type) { -#if defined(PSA_WANT_ALG_MD5) - case MBEDTLS_MD_MD5: - return PSA_ALG_MD5; -#endif -#if defined(PSA_WANT_ALG_RIPEMD160) - case MBEDTLS_MD_RIPEMD160: - return PSA_ALG_RIPEMD160; -#endif -#if defined(PSA_WANT_ALG_SHA_1) - case MBEDTLS_MD_SHA1: - return PSA_ALG_SHA_1; -#endif -#if defined(PSA_WANT_ALG_SHA_224) - case MBEDTLS_MD_SHA224: - return PSA_ALG_SHA_224; -#endif -#if defined(PSA_WANT_ALG_SHA_256) - case MBEDTLS_MD_SHA256: - return PSA_ALG_SHA_256; -#endif -#if defined(PSA_WANT_ALG_SHA_384) - case MBEDTLS_MD_SHA384: - return PSA_ALG_SHA_384; -#endif -#if defined(PSA_WANT_ALG_SHA_512) - case MBEDTLS_MD_SHA512: - return PSA_ALG_SHA_512; -#endif -#if defined(PSA_WANT_ALG_SHA3_224) - case MBEDTLS_MD_SHA3_224: - return PSA_ALG_SHA3_224; -#endif -#if defined(PSA_WANT_ALG_SHA3_256) - case MBEDTLS_MD_SHA3_256: - return PSA_ALG_SHA3_256; -#endif -#if defined(PSA_WANT_ALG_SHA3_384) - case MBEDTLS_MD_SHA3_384: - return PSA_ALG_SHA3_384; -#endif -#if defined(PSA_WANT_ALG_SHA3_512) - case MBEDTLS_MD_SHA3_512: - return PSA_ALG_SHA3_512; -#endif - case MBEDTLS_MD_NONE: - default: - return PSA_ALG_NONE; - } -} - -mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg) -{ - switch (psa_alg) { -#if defined(PSA_WANT_ALG_MD5) - case PSA_ALG_MD5: - return MBEDTLS_MD_MD5; -#endif -#if defined(PSA_WANT_ALG_RIPEMD160) - case PSA_ALG_RIPEMD160: - return MBEDTLS_MD_RIPEMD160; -#endif -#if defined(PSA_WANT_ALG_SHA_1) - case PSA_ALG_SHA_1: - return MBEDTLS_MD_SHA1; -#endif -#if defined(PSA_WANT_ALG_SHA_224) - case PSA_ALG_SHA_224: - return MBEDTLS_MD_SHA224; -#endif -#if defined(PSA_WANT_ALG_SHA_256) - case PSA_ALG_SHA_256: - return MBEDTLS_MD_SHA256; -#endif -#if defined(PSA_WANT_ALG_SHA_384) - case PSA_ALG_SHA_384: - return MBEDTLS_MD_SHA384; -#endif -#if defined(PSA_WANT_ALG_SHA_512) - case PSA_ALG_SHA_512: - return MBEDTLS_MD_SHA512; -#endif -#if defined(PSA_WANT_ALG_SHA3_224) - case PSA_ALG_SHA3_224: - return MBEDTLS_MD_SHA3_224; -#endif -#if defined(PSA_WANT_ALG_SHA3_256) - case PSA_ALG_SHA3_256: - return MBEDTLS_MD_SHA3_256; -#endif -#if defined(PSA_WANT_ALG_SHA3_384) - case PSA_ALG_SHA3_384: - return MBEDTLS_MD_SHA3_384; -#endif -#if defined(PSA_WANT_ALG_SHA3_512) - case PSA_ALG_SHA3_512: - return MBEDTLS_MD_SHA3_512; -#endif - case PSA_ALG_NONE: - default: - return MBEDTLS_MD_NONE; - } -} - #endif /* MBEDTLS_PSA_CRYPTO_C */ From ddba51e6c9120869c15bd931d4dad9bd3d35e787 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 21 Dec 2023 10:16:33 +0100 Subject: [PATCH 048/215] psa: rename "mbedtls_ecc_group_of_psa" to "mbedtls_ecc_group_from_psa" Signed-off-by: Valerio Setti --- include/mbedtls/psa_util.h | 6 +++--- library/pk_internal.h | 4 ++-- library/pkparse.c | 2 +- library/psa_crypto.c | 2 +- library/psa_crypto_ecp.c | 6 +++--- library/psa_util.c | 6 +++--- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index 5f6a05315..5368e040e 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -143,9 +143,9 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, * \return #MBEDTLS_ECP_DP_NONE if \p bits is not * correct for \p curve. */ -mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve, - size_t bits, - int bits_is_sloppy); +mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, + size_t bits, + int bits_is_sloppy); #endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ /**@}*/ diff --git a/library/pk_internal.h b/library/pk_internal.h index 025ee8b01..642a0c7bb 100644 --- a/library/pk_internal.h +++ b/library/pk_internal.h @@ -98,13 +98,13 @@ static inline mbedtls_ecp_group_id mbedtls_pk_get_ec_group_id(const mbedtls_pk_c } opaque_key_type = psa_get_key_type(&opaque_attrs); curve = PSA_KEY_TYPE_ECC_GET_FAMILY(opaque_key_type); - id = mbedtls_ecc_group_of_psa(curve, psa_get_key_bits(&opaque_attrs), 0); + id = mbedtls_ecc_group_from_psa(curve, psa_get_key_bits(&opaque_attrs), 0); psa_reset_key_attributes(&opaque_attrs); } else #endif /* MBEDTLS_USE_PSA_CRYPTO */ { #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - id = mbedtls_ecc_group_of_psa(pk->ec_family, pk->ec_bits, 0); + id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits, 0); #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ id = mbedtls_pk_ec_ro(*pk)->grp.id; #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ diff --git a/library/pkparse.c b/library/pkparse.c index d36fa3f83..ef3aff22b 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -250,7 +250,7 @@ static int pk_ecc_set_pubkey_psa_ecp_fallback(mbedtls_pk_context *pk, mbedtls_ecp_group_id ecp_group_id; int ret; - ecp_group_id = mbedtls_ecc_group_of_psa(pk->ec_family, pk->ec_bits, 0); + ecp_group_id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits, 0); mbedtls_ecp_keypair_init(&ecp_key); ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id); diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a8baa6b6f..d39310981 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5708,7 +5708,7 @@ static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper( psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( slot->attr.type); mbedtls_ecp_group_id grp_id = - mbedtls_ecc_group_of_psa(curve, bits, 0); + mbedtls_ecc_group_from_psa(curve, bits, 0); if (grp_id == MBEDTLS_ECP_DP_NONE) { ret = MBEDTLS_ERR_ASN1_INVALID_DATA; diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index e4a372d24..3f2ec23e3 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -83,8 +83,8 @@ psa_status_t mbedtls_psa_ecp_load_representation( mbedtls_ecp_keypair_init(ecp); /* Load the group. */ - grp_id = mbedtls_ecc_group_of_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type), - curve_bits, !explicit_bits); + grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type), + curve_bits, !explicit_bits); if (grp_id == MBEDTLS_ECP_DP_NONE) { /* We can't distinguish between a nonsensical family/size combination * (which would warrant PSA_ERROR_INVALID_ARGUMENT) and a @@ -285,7 +285,7 @@ psa_status_t mbedtls_psa_ecp_generate_key( psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( attributes->core.type); mbedtls_ecp_group_id grp_id = - mbedtls_ecc_group_of_psa(curve, attributes->core.bits, 0); + mbedtls_ecc_group_from_psa(curve, attributes->core.bits, 0); const mbedtls_ecp_curve_info *curve_info = mbedtls_ecp_curve_info_from_grp_id(grp_id); diff --git a/library/psa_util.c b/library/psa_util.c index 36b7175df..f4685dbc6 100644 --- a/library/psa_util.c +++ b/library/psa_util.c @@ -252,9 +252,9 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, } } -mbedtls_ecp_group_id mbedtls_ecc_group_of_psa(psa_ecc_family_t curve, - size_t bits, - int bits_is_sloppy) +mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, + size_t bits, + int bits_is_sloppy) { switch (curve) { case PSA_ECC_FAMILY_SECP_R1: From d36c313b53b4ba45561bbcde9408f8c0f39b8ece Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 21 Dec 2023 14:03:51 +0100 Subject: [PATCH 049/215] psa: remove bits_is_sloppy parameter from mbedtls_ecc_group_from_psa() Signed-off-by: Valerio Setti --- include/mbedtls/psa_util.h | 3 +-- library/pk_internal.h | 4 ++-- library/pkparse.c | 2 +- library/psa_crypto.c | 2 +- library/psa_crypto_ecp.c | 16 ++++++++++++++-- library/psa_util.c | 16 +++------------- 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index 5368e040e..e1dd822e5 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -144,8 +144,7 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, * correct for \p curve. */ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, - size_t bits, - int bits_is_sloppy); + size_t bits); #endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ /**@}*/ diff --git a/library/pk_internal.h b/library/pk_internal.h index 642a0c7bb..3d5adf8de 100644 --- a/library/pk_internal.h +++ b/library/pk_internal.h @@ -98,13 +98,13 @@ static inline mbedtls_ecp_group_id mbedtls_pk_get_ec_group_id(const mbedtls_pk_c } opaque_key_type = psa_get_key_type(&opaque_attrs); curve = PSA_KEY_TYPE_ECC_GET_FAMILY(opaque_key_type); - id = mbedtls_ecc_group_from_psa(curve, psa_get_key_bits(&opaque_attrs), 0); + id = mbedtls_ecc_group_from_psa(curve, psa_get_key_bits(&opaque_attrs)); psa_reset_key_attributes(&opaque_attrs); } else #endif /* MBEDTLS_USE_PSA_CRYPTO */ { #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) - id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits, 0); + id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits); #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ id = mbedtls_pk_ec_ro(*pk)->grp.id; #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ diff --git a/library/pkparse.c b/library/pkparse.c index ef3aff22b..5f95545af 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -250,7 +250,7 @@ static int pk_ecc_set_pubkey_psa_ecp_fallback(mbedtls_pk_context *pk, mbedtls_ecp_group_id ecp_group_id; int ret; - ecp_group_id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits, 0); + ecp_group_id = mbedtls_ecc_group_from_psa(pk->ec_family, pk->ec_bits); mbedtls_ecp_keypair_init(&ecp_key); ret = mbedtls_ecp_group_load(&(ecp_key.grp), ecp_group_id); diff --git a/library/psa_crypto.c b/library/psa_crypto.c index d39310981..850f20610 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5708,7 +5708,7 @@ static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper( psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( slot->attr.type); mbedtls_ecp_group_id grp_id = - mbedtls_ecc_group_from_psa(curve, bits, 0); + mbedtls_ecc_group_from_psa(curve, bits); if (grp_id == MBEDTLS_ECP_DP_NONE) { ret = MBEDTLS_ERR_ASN1_INVALID_DATA; diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index 3f2ec23e3..20ef29c12 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -41,6 +41,7 @@ psa_status_t mbedtls_psa_ecp_load_representation( psa_status_t status; mbedtls_ecp_keypair *ecp = NULL; size_t curve_bytes = data_length; + size_t curve_bits_check; int explicit_bits = (curve_bits != 0); if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) && @@ -84,7 +85,7 @@ psa_status_t mbedtls_psa_ecp_load_representation( /* Load the group. */ grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type), - curve_bits, !explicit_bits); + curve_bits); if (grp_id == MBEDTLS_ECP_DP_NONE) { /* We can't distinguish between a nonsensical family/size combination * (which would warrant PSA_ERROR_INVALID_ARGUMENT) and a @@ -96,6 +97,17 @@ psa_status_t mbedtls_psa_ecp_load_representation( goto exit; } + /* Get the exact number of bits which are necessary for this key. This is + * used to validate the "curve_bits" input parameter (only in case it was + * provided). + * Note: we intentionally ignore the return value of mbedtls_ecc_group_to_psa() + * because we are only interested in the curve's bit size. */ + mbedtls_ecc_group_to_psa(grp_id, &curve_bits_check); + if (explicit_bits && (curve_bits_check != curve_bits)) { + status = PSA_ERROR_NOT_SUPPORTED; + goto exit; + } + status = mbedtls_to_psa_error( mbedtls_ecp_group_load(&ecp->grp, grp_id)); if (status != PSA_SUCCESS) { @@ -285,7 +297,7 @@ psa_status_t mbedtls_psa_ecp_generate_key( psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( attributes->core.type); mbedtls_ecp_group_id grp_id = - mbedtls_ecc_group_from_psa(curve, attributes->core.bits, 0); + mbedtls_ecc_group_from_psa(curve, attributes->core.bits); const mbedtls_ecp_curve_info *curve_info = mbedtls_ecp_curve_info_from_grp_id(grp_id); diff --git a/library/psa_util.c b/library/psa_util.c index f4685dbc6..abd7a5f6b 100644 --- a/library/psa_util.c +++ b/library/psa_util.c @@ -253,8 +253,7 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, } mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, - size_t bits, - int bits_is_sloppy) + size_t bits) { switch (curve) { case PSA_ECC_FAMILY_SECP_R1: @@ -277,12 +276,8 @@ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, #endif #if defined(PSA_WANT_ECC_SECP_R1_521) case 521: - return MBEDTLS_ECP_DP_SECP521R1; case 528: - if (bits_is_sloppy) { - return MBEDTLS_ECP_DP_SECP521R1; - } - break; + return MBEDTLS_ECP_DP_SECP521R1; #endif } break; @@ -308,12 +303,8 @@ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, switch (bits) { #if defined(PSA_WANT_ECC_MONTGOMERY_255) case 255: - return MBEDTLS_ECP_DP_CURVE25519; case 256: - if (bits_is_sloppy) { - return MBEDTLS_ECP_DP_CURVE25519; - } - break; + return MBEDTLS_ECP_DP_CURVE25519; #endif #if defined(PSA_WANT_ECC_MONTGOMERY_448) case 448: @@ -340,7 +331,6 @@ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, break; } - (void) bits_is_sloppy; return MBEDTLS_ECP_DP_NONE; } #endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ From 673868be5df7918878c78b98f4ef87f7ec76b7a8 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 21 Dec 2023 14:48:31 +0100 Subject: [PATCH 050/215] psa_crypto_ecp: add helper for checking EC parameters This commit also updates "test_suite_psa_crypto.data" replacing PSA_ERROR_NOT_SUPPORTED with PSA_ERROR_INVALID_ARGUMENT when a wrong bit size is provided while importing key. Signed-off-by: Valerio Setti --- library/psa_crypto_ecp.c | 78 +++++++++++++++++++------ tests/suites/test_suite_psa_crypto.data | 6 +- 2 files changed, 63 insertions(+), 21 deletions(-) diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index 20ef29c12..866ef7956 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -32,6 +32,60 @@ defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) +/* Helper function to verify if the provided EC's family and key bit size are + * valid. */ +static int check_ecc_parameters(psa_ecc_family_t family, size_t bits, int allow_bit_size_roundup) +{ + switch (family) { + case PSA_ECC_FAMILY_SECP_R1: + switch (bits) { + case 192: + case 224: + case 256: + case 384: + case 521: + return PSA_SUCCESS; + case 528: + if (allow_bit_size_roundup) { + return PSA_SUCCESS; + } + } + break; + + case PSA_ECC_FAMILY_BRAINPOOL_P_R1: + switch (bits) { + case 256: + case 384: + case 512: + return PSA_SUCCESS; + } + break; + + case PSA_ECC_FAMILY_MONTGOMERY: + switch (bits) { + case 448: + case 255: + return PSA_SUCCESS; + case 256: + if (allow_bit_size_roundup) { + return PSA_SUCCESS; + } + } + break; + + case PSA_ECC_FAMILY_SECP_K1: + switch (bits) { + case 192: + case 224: + case 256: + return PSA_SUCCESS; + } + break; + } + + return PSA_ERROR_INVALID_ARGUMENT; +} + psa_status_t mbedtls_psa_ecp_load_representation( psa_key_type_t type, size_t curve_bits, const uint8_t *data, size_t data_length, @@ -41,7 +95,6 @@ psa_status_t mbedtls_psa_ecp_load_representation( psa_status_t status; mbedtls_ecp_keypair *ecp = NULL; size_t curve_bytes = data_length; - size_t curve_bits_check; int explicit_bits = (curve_bits != 0); if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) && @@ -83,27 +136,16 @@ psa_status_t mbedtls_psa_ecp_load_representation( } mbedtls_ecp_keypair_init(ecp); + status = check_ecc_parameters(PSA_KEY_TYPE_ECC_GET_FAMILY(type), curve_bits, + !explicit_bits); + if (status != PSA_SUCCESS) { + goto exit; + } + /* Load the group. */ grp_id = mbedtls_ecc_group_from_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type), curve_bits); if (grp_id == MBEDTLS_ECP_DP_NONE) { - /* We can't distinguish between a nonsensical family/size combination - * (which would warrant PSA_ERROR_INVALID_ARGUMENT) and a - * well-regarded curve that Mbed TLS just doesn't know about (which - * would warrant PSA_ERROR_NOT_SUPPORTED). For uniformity with how - * curves that Mbed TLS knows about but for which support is disabled - * at build time, return NOT_SUPPORTED. */ - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - - /* Get the exact number of bits which are necessary for this key. This is - * used to validate the "curve_bits" input parameter (only in case it was - * provided). - * Note: we intentionally ignore the return value of mbedtls_ecc_group_to_psa() - * because we are only interested in the curve's bit size. */ - mbedtls_ecc_group_to_psa(grp_id, &curve_bits_check); - if (explicit_bits && (curve_bits_check != curve_bits)) { status = PSA_ERROR_NOT_SUPPORTED; goto exit; } diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 1bd8b6500..0cb800573 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -684,7 +684,7 @@ import_with_data:"":PSA_KEY_TYPE_RAW_DATA:8:PSA_ERROR_INVALID_ARGUMENT PSA import EC keypair: explicit bit-size=255 for secp256r1 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256 -import_with_data:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):255:PSA_ERROR_NOT_SUPPORTED +import_with_data:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):255:PSA_ERROR_INVALID_ARGUMENT PSA import EC keypair: explicit bit-size=521 for secp521r1 (good) depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_521 @@ -692,7 +692,7 @@ import_with_data:"01b1b6ad07bb79e7320da59860ea28e055284f6058f279de666e06d435d2af PSA import EC keypair: explicit bit-size=528 for secp521r1 (bad) depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_521 -import_with_data:"01b1b6ad07bb79e7320da59860ea28e055284f6058f279de666e06d435d2af7bda28d99fa47b7dd0963e16b0073078ee8b8a38d966a582f46d19ff95df3ad9685aae":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):528:PSA_ERROR_NOT_SUPPORTED +import_with_data:"01b1b6ad07bb79e7320da59860ea28e055284f6058f279de666e06d435d2af7bda28d99fa47b7dd0963e16b0073078ee8b8a38d966a582f46d19ff95df3ad9685aae":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):528:PSA_ERROR_INVALID_ARGUMENT PSA import EC keypair: explicit bit-size, DER format depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256 @@ -716,7 +716,7 @@ import_with_data:"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba0120 PSA import EC keypair: implicit bit-size, not a valid length depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256 -import_with_data:"0123456789abcdef0123456789abcdef":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):0:PSA_ERROR_NOT_SUPPORTED +import_with_data:"0123456789abcdef0123456789abcdef":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):0:PSA_ERROR_INVALID_ARGUMENT PSA import EC keypair: secp256r1, all-bits-zero (bad) depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT:PSA_WANT_ECC_SECP_R1_256 From 3b7663de29940dd6b6c00995711936f50ebf7c62 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 21 Dec 2023 14:56:14 +0100 Subject: [PATCH 051/215] psa_util: update the documentation of ECC conversion functions Signed-off-by: Valerio Setti --- include/mbedtls/psa_util.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index e1dd822e5..a2604e1f3 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -109,9 +109,6 @@ extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state; #include /** Convert an ECC curve identifier from the Mbed TLS encoding to PSA. - * - * \note This function is provided solely for the convenience of - * Mbed TLS and may be removed at any time without notice. * * \param grpid An Mbed TLS elliptic curve identifier * (`MBEDTLS_ECP_DP_xxx`). @@ -125,9 +122,6 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, size_t *bits); /** Convert an ECC curve identifier from the PSA encoding to Mbed TLS. - * - * \note This function is provided solely for the convenience of - * Mbed TLS and may be removed at any time without notice. * * \param curve A PSA elliptic curve identifier * (`PSA_ECC_FAMILY_xxx`). From bf999cb22ec7de888cf3ca3baf79bca137f53f57 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 28 Dec 2023 17:48:13 +0100 Subject: [PATCH 052/215] test_suite_psa_crypto: add test functions and cases for ECC conversion functions Signed-off-by: Valerio Setti --- tests/suites/test_suite_psa_crypto.data | 55 +++++++++++++++++++++ tests/suites/test_suite_psa_crypto.function | 29 +++++++++++ 2 files changed, 84 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 0cb800573..d2fa84250 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7406,3 +7406,58 @@ persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY PSA derive persistent key: HKDF SHA-256, exportable persistent_key_load_key_from_storage:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_TYPE_RAW_DATA:1024:PSA_KEY_USAGE_EXPORT:0:DERIVE_KEY + +ECP group ID <-> PSA family - SECP192R1 +depends_on:PSA_WANT_ECC_SECP_R1_192 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP192R1 + +ECP group ID <-> PSA family - SECP224R1 +depends_on:PSA_WANT_ECC_SECP_R1_224 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP224R1 + +ECP group ID <-> PSA family - SECP256R1 +depends_on:PSA_WANT_ECC_SECP_R1_256 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP256R1 + +ECP group ID <-> PSA family - SECP384R1 +depends_on:PSA_WANT_ECC_SECP_R1_384 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP384R1 + +ECP group ID <-> PSA family - SECP521R1 +depends_on:PSA_WANT_ECC_SECP_R1_521 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP521R1 + +ECP group ID <-> PSA family - BP256R1 +depends_on:PSA_WANT_ECC_BRAINPOOL_P_R1_256 +ecc_conversion_functions:MBEDTLS_ECP_DP_BP256R1 + +ECP group ID <-> PSA family - BP384R1 +depends_on:PSA_WANT_ECC_BRAINPOOL_P_R1_384 +ecc_conversion_functions:MBEDTLS_ECP_DP_BP384R1 + +ECP group ID <-> PSA family - BP512R1 +depends_on:PSA_WANT_ECC_BRAINPOOL_P_R1_512 +ecc_conversion_functions:MBEDTLS_ECP_DP_BP512R1 + +ECP group ID <-> PSA family - CURVE25519 +depends_on:PSA_WANT_ECC_MONTGOMERY_255 +ecc_conversion_functions:MBEDTLS_ECP_DP_CURVE25519 + +ECP group ID <-> PSA family - SECP192K1 +depends_on:PSA_WANT_ECC_SECP_K1_192 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP192K1 + +ECP group ID <-> PSA family - SECP224K1 +depends_on:PSA_WANT_ECC_SECP_K1_224 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP224K1 + +ECP group ID <-> PSA family - SECP256K1 +depends_on:PSA_WANT_ECC_SECP_K1_256 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP256K1 + +ECP group ID <-> PSA family - CURVE448 +depends_on:PSA_WANT_ECC_MONTGOMERY_448 +ecc_conversion_functions:MBEDTLS_ECP_DP_CURVE448 + +ECP group ID <-> PSA family - fail +ecc_conversion_functions_fail: \ No newline at end of file diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 4c08a9017..a2d156d4e 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -6,6 +6,8 @@ #include "mbedtls/oid.h" #include "common.h" +#include "mbedtls/psa_util.h" + /* For MBEDTLS_CTR_DRBG_MAX_REQUEST, knowing that psa_generate_random() * uses mbedtls_ctr_drbg internally. */ #include "mbedtls/ctr_drbg.h" @@ -9479,6 +9481,33 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void ecc_conversion_functions(int grp_id_arg) +{ + mbedtls_ecp_group_id grp_id = grp_id_arg; + psa_ecc_family_t ecc_family; + size_t bits; + + ecc_family = mbedtls_ecc_group_to_psa(grp_id, &bits); + TEST_ASSERT(ecc_family != 0); + TEST_EQUAL(grp_id, mbedtls_ecc_group_from_psa(ecc_family, bits)); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void ecc_conversion_functions_fail(void) +{ + psa_ecc_family_t ecc_family; + size_t bits; + + // Pick an invalid group ID (MBEDTLS_ECP_DP_CURVE448 is the last enum) + ecc_family = mbedtls_ecc_group_to_psa(MBEDTLS_ECP_DP_CURVE448 + 1, &bits); + TEST_EQUAL(ecc_family, 0); + + TEST_EQUAL(MBEDTLS_ECP_DP_NONE, mbedtls_ecc_group_from_psa(PSA_ECC_FAMILY_SECP_R1, 0)); +} +/* END_CASE */ + /* BEGIN_CASE */ void key_agreement_output(int alg_arg, int our_key_type_arg, data_t *our_key_data, From 90e764c1bff2416eadfca2a901786c98f32966f5 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 28 Dec 2023 18:16:33 +0100 Subject: [PATCH 053/215] changelog: added documentation for the 2 new public functions Signed-off-by: Valerio Setti --- ChangeLog.d/7764.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ChangeLog.d/7764.txt diff --git a/ChangeLog.d/7764.txt b/ChangeLog.d/7764.txt new file mode 100644 index 000000000..be332cd60 --- /dev/null +++ b/ChangeLog.d/7764.txt @@ -0,0 +1,4 @@ +Features + * mbedtls_ecc_group_to_psa() and mbedtls_ecc_group_from_psa() helper + functions were added to convert from mbedtls_ecp_group_id to + psa_ecc_family_t and curve's bit size and viceversa, respectively. \ No newline at end of file From dc33200b74db515ef0e031d97f8207282ed41e06 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 28 Dec 2023 18:28:11 +0100 Subject: [PATCH 054/215] psa-transition: extend "Elliptic curve mechanism selection" Signed-off-by: Valerio Setti --- docs/psa-transition.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/psa-transition.md b/docs/psa-transition.md index 067ffafbd..71b3d68f9 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -743,6 +743,10 @@ A curve is fully determined by a curve family identifier and the private key siz | `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 helper functions can be used to convert between the 2 types: +- `mbedtls_ecc_group_to_psa()` converts from the legacy curve type identifier to PSA curve family and bit-size. +- `mbedtls_ecc_group_from_psa()` converts from PSA curve family and bit-size to the legacy identifier. + 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). From 0e608807e36e46c06abcd7bd1bdb8c6cef2c3f66 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 29 Dec 2023 11:46:44 +0100 Subject: [PATCH 055/215] psa: let mbedtls_ecc_group_from_psa() accept only exact bit lengths Signed-off-by: Valerio Setti --- include/mbedtls/psa_util.h | 9 ++------- library/psa_crypto_ecp.c | 30 +++++++++++++++--------------- library/psa_util.c | 2 -- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index a2604e1f3..cfb4bce58 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -126,16 +126,11 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, * \param curve A PSA elliptic curve identifier * (`PSA_ECC_FAMILY_xxx`). * \param bits The bit-length of a private key on \p curve. - * \param bits_is_sloppy If true, \p bits may be the bit-length rounded up - * to the nearest multiple of 8. This allows the caller - * to infer the exact curve from the length of a key - * which is supplied as a byte string. * * \return The corresponding Mbed TLS elliptic curve identifier * (`MBEDTLS_ECP_DP_xxx`). - * \return #MBEDTLS_ECP_DP_NONE if \c curve is not recognized. - * \return #MBEDTLS_ECP_DP_NONE if \p bits is not - * correct for \p curve. + * \return #MBEDTLS_ECP_DP_NONE if the combination of \c curve + * and \p bits is not recognized. */ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, size_t bits); diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index 866ef7956..3c5aa729b 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -32,13 +32,16 @@ defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) -/* Helper function to verify if the provided EC's family and key bit size are - * valid. */ -static int check_ecc_parameters(psa_ecc_family_t family, size_t bits, int allow_bit_size_roundup) +/* Helper function to verify if the provided EC's family and key bit size are valid. + * + * Note: "bits" parameter is used both as input and output and it might be updated + * in case provided input value is not multiple of 8 ("sloppy" bits). + */ +static int check_ecc_parameters(psa_ecc_family_t family, size_t *bits) { switch (family) { case PSA_ECC_FAMILY_SECP_R1: - switch (bits) { + switch (*bits) { case 192: case 224: case 256: @@ -46,14 +49,13 @@ static int check_ecc_parameters(psa_ecc_family_t family, size_t bits, int allow_ case 521: return PSA_SUCCESS; case 528: - if (allow_bit_size_roundup) { - return PSA_SUCCESS; - } + *bits = 521; + return PSA_SUCCESS; } break; case PSA_ECC_FAMILY_BRAINPOOL_P_R1: - switch (bits) { + switch (*bits) { case 256: case 384: case 512: @@ -62,19 +64,18 @@ static int check_ecc_parameters(psa_ecc_family_t family, size_t bits, int allow_ break; case PSA_ECC_FAMILY_MONTGOMERY: - switch (bits) { + switch (*bits) { case 448: case 255: return PSA_SUCCESS; case 256: - if (allow_bit_size_roundup) { - return PSA_SUCCESS; - } + *bits = 255; + return PSA_SUCCESS; } break; case PSA_ECC_FAMILY_SECP_K1: - switch (bits) { + switch (*bits) { case 192: case 224: case 256: @@ -136,8 +137,7 @@ psa_status_t mbedtls_psa_ecp_load_representation( } mbedtls_ecp_keypair_init(ecp); - status = check_ecc_parameters(PSA_KEY_TYPE_ECC_GET_FAMILY(type), curve_bits, - !explicit_bits); + status = check_ecc_parameters(PSA_KEY_TYPE_ECC_GET_FAMILY(type), &curve_bits); if (status != PSA_SUCCESS) { goto exit; } diff --git a/library/psa_util.c b/library/psa_util.c index abd7a5f6b..28b028552 100644 --- a/library/psa_util.c +++ b/library/psa_util.c @@ -276,7 +276,6 @@ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, #endif #if defined(PSA_WANT_ECC_SECP_R1_521) case 521: - case 528: return MBEDTLS_ECP_DP_SECP521R1; #endif } @@ -303,7 +302,6 @@ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, switch (bits) { #if defined(PSA_WANT_ECC_MONTGOMERY_255) case 255: - case 256: return MBEDTLS_ECP_DP_CURVE25519; #endif #if defined(PSA_WANT_ECC_MONTGOMERY_448) From ad819679a55a36338d8c1ba4e72db69d11409646 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 29 Dec 2023 12:14:41 +0100 Subject: [PATCH 056/215] test_suite_psa_crypto: explicitly check return values of conversion functions Signed-off-by: Valerio Setti --- tests/suites/test_suite_psa_crypto.data | 31 ++++++++++---------- tests/suites/test_suite_psa_crypto.function | 32 ++++++++------------- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index d2fa84250..501cbb783 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7409,55 +7409,56 @@ persistent_key_load_key_from_storage:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b ECP group ID <-> PSA family - SECP192R1 depends_on:PSA_WANT_ECC_SECP_R1_192 -ecc_conversion_functions:MBEDTLS_ECP_DP_SECP192R1 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP192R1:PSA_ECC_FAMILY_SECP_R1:192 ECP group ID <-> PSA family - SECP224R1 depends_on:PSA_WANT_ECC_SECP_R1_224 -ecc_conversion_functions:MBEDTLS_ECP_DP_SECP224R1 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP224R1:PSA_ECC_FAMILY_SECP_R1:224 ECP group ID <-> PSA family - SECP256R1 depends_on:PSA_WANT_ECC_SECP_R1_256 -ecc_conversion_functions:MBEDTLS_ECP_DP_SECP256R1 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP256R1:PSA_ECC_FAMILY_SECP_R1:256 ECP group ID <-> PSA family - SECP384R1 depends_on:PSA_WANT_ECC_SECP_R1_384 -ecc_conversion_functions:MBEDTLS_ECP_DP_SECP384R1 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP384R1:PSA_ECC_FAMILY_SECP_R1:384 ECP group ID <-> PSA family - SECP521R1 depends_on:PSA_WANT_ECC_SECP_R1_521 -ecc_conversion_functions:MBEDTLS_ECP_DP_SECP521R1 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP521R1:PSA_ECC_FAMILY_SECP_R1:521 ECP group ID <-> PSA family - BP256R1 depends_on:PSA_WANT_ECC_BRAINPOOL_P_R1_256 -ecc_conversion_functions:MBEDTLS_ECP_DP_BP256R1 +ecc_conversion_functions:MBEDTLS_ECP_DP_BP256R1:PSA_ECC_FAMILY_BRAINPOOL_P_R1:256 ECP group ID <-> PSA family - BP384R1 depends_on:PSA_WANT_ECC_BRAINPOOL_P_R1_384 -ecc_conversion_functions:MBEDTLS_ECP_DP_BP384R1 +ecc_conversion_functions:MBEDTLS_ECP_DP_BP384R1:PSA_ECC_FAMILY_BRAINPOOL_P_R1:384 ECP group ID <-> PSA family - BP512R1 depends_on:PSA_WANT_ECC_BRAINPOOL_P_R1_512 -ecc_conversion_functions:MBEDTLS_ECP_DP_BP512R1 +ecc_conversion_functions:MBEDTLS_ECP_DP_BP512R1:PSA_ECC_FAMILY_BRAINPOOL_P_R1:512 ECP group ID <-> PSA family - CURVE25519 depends_on:PSA_WANT_ECC_MONTGOMERY_255 -ecc_conversion_functions:MBEDTLS_ECP_DP_CURVE25519 +ecc_conversion_functions:MBEDTLS_ECP_DP_CURVE25519:PSA_ECC_FAMILY_MONTGOMERY:255 ECP group ID <-> PSA family - SECP192K1 depends_on:PSA_WANT_ECC_SECP_K1_192 -ecc_conversion_functions:MBEDTLS_ECP_DP_SECP192K1 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP192K1:PSA_ECC_FAMILY_SECP_K1:192 ECP group ID <-> PSA family - SECP224K1 depends_on:PSA_WANT_ECC_SECP_K1_224 -ecc_conversion_functions:MBEDTLS_ECP_DP_SECP224K1 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP224K1:PSA_ECC_FAMILY_SECP_K1:224 ECP group ID <-> PSA family - SECP256K1 depends_on:PSA_WANT_ECC_SECP_K1_256 -ecc_conversion_functions:MBEDTLS_ECP_DP_SECP256K1 +ecc_conversion_functions:MBEDTLS_ECP_DP_SECP256K1:PSA_ECC_FAMILY_SECP_K1:256 ECP group ID <-> PSA family - CURVE448 depends_on:PSA_WANT_ECC_MONTGOMERY_448 -ecc_conversion_functions:MBEDTLS_ECP_DP_CURVE448 +ecc_conversion_functions:MBEDTLS_ECP_DP_CURVE448:PSA_ECC_FAMILY_MONTGOMERY:448 + +ECP group ID <-> PSA family - Wrong values +ecc_conversion_functions:MBEDTLS_ECP_DP_MAX:0:0 -ECP group ID <-> PSA family - fail -ecc_conversion_functions_fail: \ No newline at end of file diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index a2d156d4e..ec8afe705 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -9481,30 +9481,22 @@ exit: } /* END_CASE */ -/* BEGIN_CASE */ -void ecc_conversion_functions(int grp_id_arg) +/* BEGIN_CASE depends_on:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ +void ecc_conversion_functions(int grp_id_arg, int psa_family_arg, int bits_arg) { mbedtls_ecp_group_id grp_id = grp_id_arg; - psa_ecc_family_t ecc_family; - size_t bits; + psa_ecc_family_t ecc_family = psa_family_arg; + size_t bits = bits_arg; + size_t bits_tmp; - ecc_family = mbedtls_ecc_group_to_psa(grp_id, &bits); - TEST_ASSERT(ecc_family != 0); - TEST_EQUAL(grp_id, mbedtls_ecc_group_from_psa(ecc_family, bits)); -} -/* END_CASE */ + TEST_EQUAL(ecc_family, mbedtls_ecc_group_to_psa(grp_id, &bits_tmp)); + TEST_EQUAL(bits, bits_tmp); -/* BEGIN_CASE */ -void ecc_conversion_functions_fail(void) -{ - psa_ecc_family_t ecc_family; - size_t bits; - - // Pick an invalid group ID (MBEDTLS_ECP_DP_CURVE448 is the last enum) - ecc_family = mbedtls_ecc_group_to_psa(MBEDTLS_ECP_DP_CURVE448 + 1, &bits); - TEST_EQUAL(ecc_family, 0); - - TEST_EQUAL(MBEDTLS_ECP_DP_NONE, mbedtls_ecc_group_from_psa(PSA_ECC_FAMILY_SECP_R1, 0)); + if (grp_id != MBEDTLS_ECP_DP_MAX) { + TEST_EQUAL(grp_id, mbedtls_ecc_group_from_psa(ecc_family, bits)); + } else { + TEST_EQUAL(MBEDTLS_ECP_DP_NONE, mbedtls_ecc_group_from_psa(ecc_family, bits)); + } } /* END_CASE */ From 8bd330dff554dfbf3e170463bcd21d31e2405595 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 29 Dec 2023 13:35:58 +0100 Subject: [PATCH 057/215] changelog: add missing newline Signed-off-by: Valerio Setti --- ChangeLog.d/7764.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/7764.txt b/ChangeLog.d/7764.txt index be332cd60..5eb14b4d2 100644 --- a/ChangeLog.d/7764.txt +++ b/ChangeLog.d/7764.txt @@ -1,4 +1,4 @@ Features * mbedtls_ecc_group_to_psa() and mbedtls_ecc_group_from_psa() helper functions were added to convert from mbedtls_ecp_group_id to - psa_ecc_family_t and curve's bit size and viceversa, respectively. \ No newline at end of file + psa_ecc_family_t and curve's bit size and viceversa, respectively. From 0bc8598d20071c1a8ae122cdeae74f7c53ba0e62 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 3 Jan 2024 15:22:46 +0100 Subject: [PATCH 058/215] psa_util: properly handle secp224r1 private key size Signed-off-by: Valerio Setti --- library/psa_crypto_ecp.c | 5 +++++ library/psa_util.c | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index 3c5aa729b..f38efff67 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -80,6 +80,11 @@ static int check_ecc_parameters(psa_ecc_family_t family, size_t *bits) case 224: case 256: return PSA_SUCCESS; + /* secp224k1 has 224-bit coordinates but 225-bit private keys. + * This means that private keys are represented with 232 bits. */ + case 232: + *bits = 225; + return PSA_SUCCESS; } break; } diff --git a/library/psa_util.c b/library/psa_util.c index 28b028552..971f965e4 100644 --- a/library/psa_util.c +++ b/library/psa_util.c @@ -232,8 +232,10 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, return PSA_ECC_FAMILY_SECP_K1; #endif #if defined(MBEDTLS_ECP_HAVE_SECP224K1) + /* secp224k1 has 224-bit coordinates but 225-bit private keys. + * The nominal key size in PSA is the private key size, hence 225. */ case MBEDTLS_ECP_DP_SECP224K1: - *bits = 224; + *bits = 225; return PSA_ECC_FAMILY_SECP_K1; #endif #if defined(MBEDTLS_ECP_HAVE_SECP256K1) @@ -318,7 +320,9 @@ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, return MBEDTLS_ECP_DP_SECP192K1; #endif #if defined(PSA_WANT_ECC_SECP_K1_224) - case 224: + /* secp224k1 has 224-bit coordinates but 225-bit private keys. + * The nominal key size in PSA is the private key size, hence 225. */ + case 225: return MBEDTLS_ECP_DP_SECP224K1; #endif #if defined(PSA_WANT_ECC_SECP_K1_256) From fc8a48a9e34d0bd42a0b8c6aaffeffc11391f230 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 4 Jan 2024 09:03:23 +0100 Subject: [PATCH 059/215] changelog: fix working Signed-off-by: Valerio Setti --- ChangeLog.d/7764.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog.d/7764.txt b/ChangeLog.d/7764.txt index 5eb14b4d2..0734fb911 100644 --- a/ChangeLog.d/7764.txt +++ b/ChangeLog.d/7764.txt @@ -1,4 +1,4 @@ Features - * mbedtls_ecc_group_to_psa() and mbedtls_ecc_group_from_psa() helper - functions were added to convert from mbedtls_ecp_group_id to - psa_ecc_family_t and curve's bit size and viceversa, respectively. + * Add functions mbedtls_ecc_group_to_psa() and mbedtls_ecc_group_from_psa() + to convert between mbedtls_ecp_group_id and psa_ecc_family_t and curve's + bit size and vice versa, respectively. From afa01c7394a2e02b060f741f56c3614f7af70b86 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 4 Jan 2024 09:47:50 +0100 Subject: [PATCH 060/215] psa-transition: update "Elliptic curve mechanism selection" section - add hyperlinks for the conversion functions. - move conversion functions' description before the legacy<->PSA table. Signed-off-by: Valerio Setti --- 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 71b3d68f9..617426cfd 100644 --- a/docs/psa-transition.md +++ b/docs/psa-transition.md @@ -725,7 +725,11 @@ An ECC public key has the type [`PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve)`](https://mb 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. +A curve is fully determined by a curve family identifier and the private key size in bits. You can use the following functions to convert between the PSA and legacy elliptic curve designations: +- [`mbedtls_ecc_group_to_psa()`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__psa__tls__helpers/#group__psa__tls__helpers_1ga9c83c095adfec7da99401cf81e164f99) converts from the legacy curve type identifier to PSA curve family and bit-size. +- [`mbedtls_ecc_group_from_psa()`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__psa__tls__helpers/#group__psa__tls__helpers_1ga6243eb619d5b2f5fe4667811adeb8a12) converts from PSA curve family and bit-size to the legacy identifier. + +The following table gives the correspondence between legacy and PSA elliptic curve designations. | Mbed TLS legacy curve identifier | PSA curve family | Curve bit-size | | -------------------------------- | ---------------- | -------------- | @@ -743,10 +747,6 @@ A curve is fully determined by a curve family identifier and the private key siz | `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 helper functions can be used to convert between the 2 types: -- `mbedtls_ecc_group_to_psa()` converts from the legacy curve type identifier to PSA curve family and bit-size. -- `mbedtls_ecc_group_from_psa()` converts from PSA curve family and bit-size to the legacy identifier. - 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). From 4ba0c61eda41c5873879d670e58842e4f6196f52 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 4 Jan 2024 09:51:25 +0100 Subject: [PATCH 061/215] test_suite_psa_crypto: add test case for ECP conversion with null values Signed-off-by: Valerio Setti --- tests/suites/test_suite_psa_crypto.data | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 501cbb783..c0916e067 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7459,6 +7459,9 @@ ECP group ID <-> PSA family - CURVE448 depends_on:PSA_WANT_ECC_MONTGOMERY_448 ecc_conversion_functions:MBEDTLS_ECP_DP_CURVE448:PSA_ECC_FAMILY_MONTGOMERY:448 +ECP group ID <-> PSA family - Null values +ecc_conversion_functions:MBEDTLS_ECP_DP_NONE:0:0 + ECP group ID <-> PSA family - Wrong values ecc_conversion_functions:MBEDTLS_ECP_DP_MAX:0:0 From ac739524740747292352b8b8393e7fdbe244b6d2 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 4 Jan 2024 10:22:01 +0100 Subject: [PATCH 062/215] test_suite_psa_crypto: improve failing tests for EC conversion functions Signed-off-by: Valerio Setti --- tests/suites/test_suite_psa_crypto.data | 2 +- tests/suites/test_suite_psa_crypto.function | 30 ++++++++++++++++----- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index c0916e067..eda6f5d8c 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7463,5 +7463,5 @@ ECP group ID <-> PSA family - Null values ecc_conversion_functions:MBEDTLS_ECP_DP_NONE:0:0 ECP group ID <-> PSA family - Wrong values -ecc_conversion_functions:MBEDTLS_ECP_DP_MAX:0:0 +ecc_conversion_functions_fail diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index ec8afe705..1112cfcd5 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -9491,15 +9491,33 @@ void ecc_conversion_functions(int grp_id_arg, int psa_family_arg, int bits_arg) TEST_EQUAL(ecc_family, mbedtls_ecc_group_to_psa(grp_id, &bits_tmp)); TEST_EQUAL(bits, bits_tmp); - - if (grp_id != MBEDTLS_ECP_DP_MAX) { - TEST_EQUAL(grp_id, mbedtls_ecc_group_from_psa(ecc_family, bits)); - } else { - TEST_EQUAL(MBEDTLS_ECP_DP_NONE, mbedtls_ecc_group_from_psa(ecc_family, bits)); - } + TEST_EQUAL(grp_id, mbedtls_ecc_group_from_psa(ecc_family, bits)); } /* END_CASE */ +/* BEGIN_CASE depends_on:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ +void ecc_conversion_functions_fail() +{ + size_t bits; + + /* Invalid legacy curve identifier. */ + TEST_EQUAL(0, mbedtls_ecc_group_to_psa(MBEDTLS_ECP_DP_NONE, &bits)); + TEST_EQUAL(0, bits); + + /* Invalid PSA EC family. */ + TEST_EQUAL(MBEDTLS_ECP_DP_NONE, mbedtls_ecc_group_from_psa(0, 192)); + /* Invalid bit-size for a valid EC family. */ + TEST_EQUAL(MBEDTLS_ECP_DP_NONE, mbedtls_ecc_group_from_psa(PSA_ECC_FAMILY_SECP_R1, 512)); + + /* Twisted-Edward curves are not supported yet. */ + TEST_EQUAL(MBEDTLS_ECP_DP_NONE, + mbedtls_ecc_group_from_psa(PSA_ECC_FAMILY_TWISTED_EDWARDS, 255)); + TEST_EQUAL(MBEDTLS_ECP_DP_NONE, + mbedtls_ecc_group_from_psa(PSA_ECC_FAMILY_TWISTED_EDWARDS, 448)); +} +/* END_CASE */ + + /* BEGIN_CASE */ void key_agreement_output(int alg_arg, int our_key_type_arg, data_t *our_key_data, From 65df79303fafe853809dc392f8eb91d2bddec31d Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 4 Jan 2024 10:58:36 +0100 Subject: [PATCH 063/215] psa_crypto_ecp: return unsupported for secp224k1 in check_ecc_parameters() Signed-off-by: Valerio Setti --- library/psa_crypto_ecp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index f38efff67..d6b640cf7 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -77,14 +77,14 @@ static int check_ecc_parameters(psa_ecc_family_t family, size_t *bits) case PSA_ECC_FAMILY_SECP_K1: switch (*bits) { case 192: - case 224: case 256: return PSA_SUCCESS; - /* secp224k1 has 224-bit coordinates but 225-bit private keys. - * This means that private keys are represented with 232 bits. */ + /* secp224k1 is not and will not be supported in PSA (#3541). + * Note: secp224k1 has 225-bit private keys which are rounded + * up to 232 for their representation. */ + case 224: case 232: - *bits = 225; - return PSA_SUCCESS; + return PSA_ERROR_NOT_SUPPORTED; } break; } From 7863627bd6fe7320542095fde87eae093b30a61d Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 4 Jan 2024 13:17:04 +0100 Subject: [PATCH 064/215] psa_util: remove support for secp224k1 in EC conversion functions Signed-off-by: Valerio Setti --- library/psa_util.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/library/psa_util.c b/library/psa_util.c index 971f965e4..d833299e8 100644 --- a/library/psa_util.c +++ b/library/psa_util.c @@ -232,11 +232,7 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, return PSA_ECC_FAMILY_SECP_K1; #endif #if defined(MBEDTLS_ECP_HAVE_SECP224K1) - /* secp224k1 has 224-bit coordinates but 225-bit private keys. - * The nominal key size in PSA is the private key size, hence 225. */ - case MBEDTLS_ECP_DP_SECP224K1: - *bits = 225; - return PSA_ECC_FAMILY_SECP_K1; + /* secp224k1 is not and will not be supported in PSA (#3541). */ #endif #if defined(MBEDTLS_ECP_HAVE_SECP256K1) case MBEDTLS_ECP_DP_SECP256K1: @@ -320,10 +316,7 @@ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, return MBEDTLS_ECP_DP_SECP192K1; #endif #if defined(PSA_WANT_ECC_SECP_K1_224) - /* secp224k1 has 224-bit coordinates but 225-bit private keys. - * The nominal key size in PSA is the private key size, hence 225. */ - case 225: - return MBEDTLS_ECP_DP_SECP224K1; + /* secp224k1 is not and will not be supported in PSA (#3541). */ #endif #if defined(PSA_WANT_ECC_SECP_K1_256) case 256: From eca07140f3c160eba07cf63c34c1d2495c925b40 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 4 Jan 2024 13:17:31 +0100 Subject: [PATCH 065/215] psa_util: update documentation of EC conversion functions Signed-off-by: Valerio Setti --- include/mbedtls/psa_util.h | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index cfb4bce58..d0d95ae19 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -112,11 +112,16 @@ extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state; * * \param grpid An Mbed TLS elliptic curve identifier * (`MBEDTLS_ECP_DP_xxx`). - * \param[out] bits On success, the bit size of the curve. + * \param[out] bits On success the bit size of the curve; 0 on failure. * - * \return The corresponding PSA elliptic curve identifier + * \return On success the corresponding PSA elliptic curve identifier * (`PSA_ECC_FAMILY_xxx`). - * \return \c 0 on failure (\p grpid is not recognized). + * \return \c 0 if \p grpid is not supported. + * + * \note A successful conversion means that the curve is supported + * in PSA. Legacy support (`mbedtls_ecp_xxx`) is only + * enabled if the curve is builtin (see + * `config_adjust_legacy_from_psa.h` for details). */ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, size_t *bits); @@ -127,10 +132,23 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, * (`PSA_ECC_FAMILY_xxx`). * \param bits The bit-length of a private key on \p curve. * - * \return The corresponding Mbed TLS elliptic curve identifier - * (`MBEDTLS_ECP_DP_xxx`). + * \return On success the corresponding Mbed TLS elliptic curve + * identifier (`MBEDTLS_ECP_DP_xxx`). * \return #MBEDTLS_ECP_DP_NONE if the combination of \c curve - * and \p bits is not recognized. + * and \p bits is not supported or invalid: + * - not supported means that the proper `PSA_WANT_ECC_xxx` + * symbol is not enabled for the requested curve. + * - invalid if `PSA_WANT_ECC_xxx` is enabled, but the + * combination of \p curve and \p bits are not correct + * for that curve. + * \return #MBEDTLS_ECP_DP_NONE for secp224k1 curve, no matter + * what the status of `PSA_WANT_ECC_SECP_K1_224` is, because + * this curve is not and will not be supported in PSA (#3541). + * + * \note A successful conversion means that the curve is supported + * in PSA. Legacy support (`mbedtls_ecp_xxx`) is only + * enabled if the curve is builtin (see + * `config_adjust_legacy_from_psa.h` for details). */ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, size_t bits); From db6e02902de5c399e37fc9f171f117d1c9afa962 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 5 Jan 2024 10:15:45 +0100 Subject: [PATCH 066/215] test_suite_psa_crypto: test also MBEDTLS_ECP_DP_MAX in ecc_conversion_functions_fail() Signed-off-by: Valerio Setti --- tests/suites/test_suite_psa_crypto.function | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 1112cfcd5..7b6f5ae04 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -9500,7 +9500,9 @@ void ecc_conversion_functions_fail() { size_t bits; - /* Invalid legacy curve identifier. */ + /* Invalid legacy curve identifiers. */ + TEST_EQUAL(0, mbedtls_ecc_group_to_psa(MBEDTLS_ECP_DP_MAX, &bits)); + TEST_EQUAL(0, bits); TEST_EQUAL(0, mbedtls_ecc_group_to_psa(MBEDTLS_ECP_DP_NONE, &bits)); TEST_EQUAL(0, bits); From 0d438fa390355958c0745f0393859110029f0bf6 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 5 Jan 2024 10:33:51 +0100 Subject: [PATCH 067/215] psa_crypto_ecp: fix comment for secp224k1 in check_ecc_parameters Signed-off-by: Valerio Setti --- library/psa_crypto_ecp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index d6b640cf7..4d9a59baa 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -80,8 +80,8 @@ static int check_ecc_parameters(psa_ecc_family_t family, size_t *bits) case 256: return PSA_SUCCESS; /* secp224k1 is not and will not be supported in PSA (#3541). - * Note: secp224k1 has 225-bit private keys which are rounded - * up to 232 for their representation. */ + * Note: secp224k1 has 224-bit coordinates but 225-bit private + * keys which are rounded up to 232 for their representation. */ case 224: case 232: return PSA_ERROR_NOT_SUPPORTED; From 2622b1dab364d29923035189620a44a5109d0c20 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 5 Jan 2024 10:36:33 +0100 Subject: [PATCH 068/215] changelog: improve wording Signed-off-by: Valerio Setti --- ChangeLog.d/7764.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/7764.txt b/ChangeLog.d/7764.txt index 0734fb911..983058403 100644 --- a/ChangeLog.d/7764.txt +++ b/ChangeLog.d/7764.txt @@ -1,4 +1,4 @@ Features * Add functions mbedtls_ecc_group_to_psa() and mbedtls_ecc_group_from_psa() to convert between mbedtls_ecp_group_id and psa_ecc_family_t and curve's - bit size and vice versa, respectively. + bit size. From 3afdd02e378f4e901845ad7d6f00e7379073d497 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 9 Jan 2024 08:50:20 +0100 Subject: [PATCH 069/215] changelog: improve wording Signed-off-by: Valerio Setti --- ChangeLog.d/7764.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ChangeLog.d/7764.txt b/ChangeLog.d/7764.txt index 983058403..4cd20798a 100644 --- a/ChangeLog.d/7764.txt +++ b/ChangeLog.d/7764.txt @@ -1,4 +1,3 @@ Features * Add functions mbedtls_ecc_group_to_psa() and mbedtls_ecc_group_from_psa() - to convert between mbedtls_ecp_group_id and psa_ecc_family_t and curve's - bit size. + to convert between Mbed TLS and PSA curve identifiers. From d0aa9c1316e4fdc98c3e5f501bf9aa1e0b3342b0 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 9 Jan 2024 09:10:44 +0100 Subject: [PATCH 070/215] psa_util: update documentation for PSA conversion functions Signed-off-by: Valerio Setti --- include/mbedtls/psa_util.h | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index d0d95ae19..f36d89ad6 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -114,14 +114,11 @@ extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state; * (`MBEDTLS_ECP_DP_xxx`). * \param[out] bits On success the bit size of the curve; 0 on failure. * - * \return On success the corresponding PSA elliptic curve identifier - * (`PSA_ECC_FAMILY_xxx`). - * \return \c 0 if \p grpid is not supported. - * - * \note A successful conversion means that the curve is supported - * in PSA. Legacy support (`mbedtls_ecp_xxx`) is only - * enabled if the curve is builtin (see - * `config_adjust_legacy_from_psa.h` for details). + * \return If the curve is supported in the PSA API, this function + * returns the proper PSA curve identifier + * (`PSA_ECC_FAMILY_xxx`). This holds even if the curve is + * not supported by the ECP module. + * \return \c 0 if the curve is not supported in the PSA API. */ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, size_t *bits); @@ -132,23 +129,11 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, * (`PSA_ECC_FAMILY_xxx`). * \param bits The bit-length of a private key on \p curve. * - * \return On success the corresponding Mbed TLS elliptic curve + * \return If the curve is supported in the PSA API, this function + * returns the corresponding Mbed TLS elliptic curve * identifier (`MBEDTLS_ECP_DP_xxx`). * \return #MBEDTLS_ECP_DP_NONE if the combination of \c curve - * and \p bits is not supported or invalid: - * - not supported means that the proper `PSA_WANT_ECC_xxx` - * symbol is not enabled for the requested curve. - * - invalid if `PSA_WANT_ECC_xxx` is enabled, but the - * combination of \p curve and \p bits are not correct - * for that curve. - * \return #MBEDTLS_ECP_DP_NONE for secp224k1 curve, no matter - * what the status of `PSA_WANT_ECC_SECP_K1_224` is, because - * this curve is not and will not be supported in PSA (#3541). - * - * \note A successful conversion means that the curve is supported - * in PSA. Legacy support (`mbedtls_ecp_xxx`) is only - * enabled if the curve is builtin (see - * `config_adjust_legacy_from_psa.h` for details). + * and \p bits is not supported. */ mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, size_t bits); From 39faa9cad4e83293094e74b2a39bab8914109994 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 9 Jan 2024 09:11:22 +0100 Subject: [PATCH 071/215] psa_util: rename parameter of mbedtls_ecc_group_from_psa The new name better reflects the fact that the 1st parameter is just the EC family and not the curve. Signed-off-by: Valerio Setti --- include/mbedtls/psa_util.h | 4 ++-- library/psa_util.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index f36d89ad6..1b142562e 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -125,7 +125,7 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, /** Convert an ECC curve identifier from the PSA encoding to Mbed TLS. * - * \param curve A PSA elliptic curve identifier + * \param family A PSA elliptic curve family identifier * (`PSA_ECC_FAMILY_xxx`). * \param bits The bit-length of a private key on \p curve. * @@ -135,7 +135,7 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, * \return #MBEDTLS_ECP_DP_NONE if the combination of \c curve * and \p bits is not supported. */ -mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, +mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family, size_t bits); #endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ diff --git a/library/psa_util.c b/library/psa_util.c index d833299e8..41586e262 100644 --- a/library/psa_util.c +++ b/library/psa_util.c @@ -250,10 +250,10 @@ psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid, } } -mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t curve, +mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family, size_t bits) { - switch (curve) { + switch (family) { case PSA_ECC_FAMILY_SECP_R1: switch (bits) { #if defined(PSA_WANT_ECC_SECP_R1_192) From 19ec9e4f66eabb8e8fa71f0cca69b1fb74095c4d Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 9 Jan 2024 13:45:05 +0100 Subject: [PATCH 072/215] psa_crypto_ecp: remove support for secp224k1 Since this curve is not supported in PSA (and it will not ever be in the future), we save a few bytes. Signed-off-by: Valerio Setti --- library/psa_crypto_ecp.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index 4d9a59baa..61c941479 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -77,14 +77,9 @@ static int check_ecc_parameters(psa_ecc_family_t family, size_t *bits) case PSA_ECC_FAMILY_SECP_K1: switch (*bits) { case 192: + /* secp224k1 is not and will not be supported in PSA (#3541). */ case 256: return PSA_SUCCESS; - /* secp224k1 is not and will not be supported in PSA (#3541). - * Note: secp224k1 has 224-bit coordinates but 225-bit private - * keys which are rounded up to 232 for their representation. */ - case 224: - case 232: - return PSA_ERROR_NOT_SUPPORTED; } break; } From 67223bb50178bab8138f5633f88fa366bb340179 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 12 Jan 2024 16:37:07 +0000 Subject: [PATCH 073/215] add support for AES-CTR to benchmark Signed-off-by: Dave Rodgman --- programs/test/benchmark.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index 755a7311a..6f7f69bda 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -507,7 +507,7 @@ typedef struct { char md5, ripemd160, sha1, sha256, sha512, sha3_224, sha3_256, sha3_384, sha3_512, des3, des, - aes_cbc, aes_cfb128, aes_cfb8, aes_gcm, aes_ccm, aes_xts, chachapoly, + aes_cbc, aes_cfb128, aes_cfb8, aes_ctr, aes_gcm, aes_ccm, aes_xts, chachapoly, aes_cmac, des3_cmac, aria, camellia, chacha20, poly1305, @@ -571,6 +571,8 @@ int main(int argc, char *argv[]) todo.aes_cfb128 = 1; } else if (strcmp(argv[i], "aes_cfb8") == 0) { todo.aes_cfb8 = 1; + } else if (strcmp(argv[i], "aes_ctr") == 0) { + todo.aes_ctr = 1; } else if (strcmp(argv[i], "aes_xts") == 0) { todo.aes_xts = 1; } else if (strcmp(argv[i], "aes_gcm") == 0) { @@ -774,6 +776,31 @@ int main(int argc, char *argv[]) mbedtls_aes_free(&aes); } #endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + if (todo.aes_ctr) { + int keysize; + mbedtls_aes_context aes; + + uint8_t stream_block[16]; + size_t nc_off; + + mbedtls_aes_init(&aes); + for (keysize = 128; keysize <= 256; keysize += 64) { + mbedtls_snprintf(title, sizeof(title), "AES-CTR-%d", keysize); + + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + memset(stream_block, 0, sizeof(stream_block)); + nc_off = 0; + + CHECK_AND_CONTINUE(mbedtls_aes_setkey_enc(&aes, tmp, keysize)); + + TIME_AND_TSC(title, mbedtls_aes_crypt_ctr(&aes, BUFSIZE, &nc_off, tmp, stream_block, + buf, buf)); + } + mbedtls_aes_free(&aes); + } +#endif #if defined(MBEDTLS_CIPHER_MODE_XTS) if (todo.aes_xts) { int keysize; From f202c2968b9c83ffe948ad5af788a7d035acc87a Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 15 Jan 2024 10:42:37 +0100 Subject: [PATCH 074/215] test_suite_psa_crypto: test asymmetric encryption/decryption also with opaque keys Signed-off-by: Valerio Setti --- tests/suites/test_suite_psa_crypto.data | 20 +++++++++++-------- tests/suites/test_suite_psa_crypto.function | 22 ++++++++++++++++----- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 1bd8b6500..e6acfb20f 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1025,35 +1025,39 @@ aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_AEAD_WITH_ PSA key policy: asymmetric encryption, encrypt | decrypt depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT -asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT +asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT:0 PSA key policy: asymmetric encryption, wrong algorithm (v1.5/OAEP) depends_on:PSA_WANT_ALG_RSA_OAEP:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT -asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256) +asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):0 PSA key policy: asymmetric encryption, wrong algorithm (OAEP with different hash) depends_on:PSA_WANT_ALG_RSA_OAEP:PSA_WANT_ALG_SHA_224:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT -asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_224):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256) +asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_224):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):0 PSA key policy: asymmetric encryption, alg=0 in policy depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT -asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT +asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT:0 PSA key policy: asymmetric encryption, ANY_HASH in policy is not meaningful depends_on:PSA_WANT_ALG_RSA_OAEP:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT -asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_OAEP(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256) +asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_OAEP(PSA_ALG_ANY_HASH):PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):0 PSA key policy: asymmetric encryption, encrypt but not decrypt depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT -asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT +asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT:0 PSA key policy: asymmetric encryption, decrypt but not encrypt depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT -asymmetric_encryption_key_policy:PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT +asymmetric_encryption_key_policy:PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT:0 PSA key policy: asymmetric encryption, neither encrypt nor decrypt depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT -asymmetric_encryption_key_policy:0:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT +asymmetric_encryption_key_policy:0:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT:0 + +PSA key policy: asymmetric encryption, opaque key, encrypt | decrypt +depends_on:PSA_CRYPTO_DRIVER_TEST:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT +asymmetric_encryption_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_ALG_RSA_PKCS1V15_CRYPT:1 PSA key policy: asymmetric signature, sign | verify hash, PKCS#1v1.5 SHA-256 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 4c08a9017..f67508c5f 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -2107,7 +2107,8 @@ void asymmetric_encryption_key_policy(int policy_usage_arg, int policy_alg, int key_type, data_t *key_data, - int exercise_alg) + int exercise_alg, + int use_opaque_key) { mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -2124,6 +2125,11 @@ void asymmetric_encryption_key_policy(int policy_usage_arg, psa_set_key_algorithm(&attributes, policy_alg); psa_set_key_type(&attributes, key_type); + if (use_opaque_key) { + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_PERSISTENCE_VOLATILE, TEST_DRIVER_LOCATION)); + } + PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, &key)); @@ -2142,8 +2148,11 @@ void asymmetric_encryption_key_policy(int policy_usage_arg, NULL, 0, buffer, buffer_length, &output_length); - if (policy_alg == exercise_alg && - (policy_usage & PSA_KEY_USAGE_ENCRYPT) != 0) { + if (use_opaque_key) { + /* Encryption/decryption is opaque keys is currently not supported. */ + TEST_EQUAL(status, PSA_ERROR_NOT_SUPPORTED); + } else if (policy_alg == exercise_alg && + (policy_usage & PSA_KEY_USAGE_ENCRYPT) != 0) { PSA_ASSERT(status); } else { TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED); @@ -2157,8 +2166,11 @@ void asymmetric_encryption_key_policy(int policy_usage_arg, NULL, 0, buffer, buffer_length, &output_length); - if (policy_alg == exercise_alg && - (policy_usage & PSA_KEY_USAGE_DECRYPT) != 0) { + if (use_opaque_key) { + /* Encryption/decryption is opaque keys is currently not supported. */ + TEST_EQUAL(status, PSA_ERROR_NOT_SUPPORTED); + } else if (policy_alg == exercise_alg && + (policy_usage & PSA_KEY_USAGE_DECRYPT) != 0) { TEST_EQUAL(status, PSA_ERROR_INVALID_PADDING); } else { TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED); From 5bb454aace1db636dc7128a48eb5d7328b018639 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 15 Jan 2024 10:43:16 +0100 Subject: [PATCH 075/215] psa_crypto: allow asymmetric encryption/decryption also with opaque keys Signed-off-by: Valerio Setti --- library/psa_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a8baa6b6f..e4ecdd08c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3080,7 +3080,7 @@ psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, return PSA_ERROR_INVALID_ARGUMENT; } - status = psa_get_and_lock_transparent_key_slot_with_policy( + status = psa_get_and_lock_key_slot_with_policy( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg); if (status != PSA_SUCCESS) { return status; @@ -3132,7 +3132,7 @@ psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, return PSA_ERROR_INVALID_ARGUMENT; } - status = psa_get_and_lock_transparent_key_slot_with_policy( + status = psa_get_and_lock_key_slot_with_policy( key, &slot, PSA_KEY_USAGE_DECRYPT, alg); if (status != PSA_SUCCESS) { return status; From c4f984f2a579307dbffeda22e7b5a96d606fd34d Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 12 Jan 2024 18:29:01 +0000 Subject: [PATCH 076/215] Iterate in 16-byte chunks Signed-off-by: Dave Rodgman --- library/aes.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/library/aes.c b/library/aes.c index f4b9739f7..ced8a3263 100644 --- a/library/aes.c +++ b/library/aes.c @@ -1441,36 +1441,42 @@ int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx, const unsigned char *input, unsigned char *output) { - int c, i; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; - n = *nc_off; + size_t offset = *nc_off; - if (n > 0x0F) { + if (offset > 0x0F) { return MBEDTLS_ERR_AES_BAD_INPUT_DATA; } - while (length--) { - if (n == 0) { + for (size_t i = 0; i < length;) { + size_t n = 16; + if (offset == 0) { ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block); if (ret != 0) { goto exit; } - - for (i = 16; i > 0; i--) { - if (++nonce_counter[i - 1] != 0) { + for (int j = 16; j > 0; j--) { + if (++nonce_counter[j - 1] != 0) { break; } } + } else { + n -= offset; } - c = *input++; - *output++ = (unsigned char) (c ^ stream_block[n]); - n = (n + 1) & 0x0F; + if (n > (length - i)) { + n = (length - i); + } + mbedtls_xor(&output[i], &input[i], &stream_block[offset], n); + // offset might be non-zero for the last block, but in that case, we don't use it again + offset = 0; + i += n; } - *nc_off = n; + // capture offset for future resumption + *nc_off = (*nc_off + length) % 16; + ret = 0; exit: From 4755e6bda47e8722ade10b0a86d1e94e89c312f1 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 12 Jan 2024 16:35:59 +0000 Subject: [PATCH 077/215] Relax psa_wipe_key_slot to allow states other than SLOT_PENDING_DELETION psa_wipe_key_slot can now be called on a slot in any state, if the slot's state is PSA_SLOT_FULL or PSA_SLOT_PENDING_DELETION then there must be exactly 1 registered reader. Remove the state changing calls that are no longer necessary. Signed-off-by: Ryan Everett --- library/psa_crypto.c | 14 +++----------- library/psa_crypto_core.h | 7 ++----- library/psa_crypto_slot_management.c | 25 ++++++------------------- library/psa_crypto_slot_management.h | 2 +- 4 files changed, 12 insertions(+), 36 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index da5e5be77..1f6450025 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -983,10 +983,6 @@ psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot) * Persistent storage is not affected. */ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot) { - if (slot->state != PSA_SLOT_PENDING_DELETION) { - return PSA_ERROR_BAD_STATE; - } - psa_status_t status = psa_remove_key_data_from_memory(slot); /* @@ -998,7 +994,9 @@ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot) * function is called as part of the execution of a test suite, the * execution of the test suite is stopped in error if the assertion fails. */ - if (slot->registered_readers != 1) { + if (((slot->state == PSA_SLOT_FULL) || + (slot->state == PSA_SLOT_PENDING_DELETION)) && + (slot->registered_readers != 1)) { MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 1); status = PSA_ERROR_CORRUPTION_DETECTED; } @@ -1828,12 +1826,6 @@ static void psa_fail_key_creation(psa_key_slot_t *slot, * itself. */ (void) psa_crypto_stop_transaction(); #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - - /* Prepare the key slot to be wiped, and then wipe it. */ - slot->registered_readers = 1; - psa_key_slot_state_transition(slot, PSA_SLOT_FILLING, - PSA_SLOT_PENDING_DELETION); - psa_wipe_key_slot(slot); } diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 3b5c63497..f11df9f36 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -70,8 +70,6 @@ typedef struct { * Number of functions registered as reading the material in the key slot. * * Library functions must not write directly to registered_readers - * (unless the slot's state is PSA_SLOT_FILLING and the slot needs to be - * wiped following a failed key creation). * * A function must call psa_register_read(slot) before reading the current * contents of the slot for an operation. @@ -191,9 +189,8 @@ static inline psa_key_slot_number_t psa_key_slot_get_slot_number( * \retval #PSA_SUCCESS * The slot has been successfully wiped. * \retval #PSA_ERROR_CORRUPTION_DETECTED - * The amount of registered readers was not equal to 1. - * \retval #PSA_ERROR_BAD_STATE - * The slot's state was not PSA_SLOT_PENDING_DELETION. + * The slot's state was PSA_SLOT_FULL or PSA_SLOT_PENDING_DELETION, and + * the amount of registered readers was not equal to 1. */ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot); diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index ef76dcb89..e7ea8efb4 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -189,10 +189,6 @@ psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, (unused_persistent_key_slot != NULL)) { selected_slot = unused_persistent_key_slot; psa_register_read(selected_slot); - /* If the state is not changed then psa_wipe_key_slot - * will report an error. */ - psa_key_slot_state_transition(selected_slot, PSA_SLOT_FULL, - PSA_SLOT_PENDING_DELETION); status = psa_wipe_key_slot(selected_slot); if (status != PSA_SUCCESS) { goto error; @@ -394,12 +390,6 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ if (status != PSA_SUCCESS) { - /* Prepare the key slot to be wiped, and then wipe it. - * Don't overwrite status as a BAD_STATE error here - * can be reported in the psa_wipe_key_slot call. */ - (*p_slot)->registered_readers = 1; - psa_key_slot_state_transition((*p_slot), PSA_SLOT_FILLING, - PSA_SLOT_PENDING_DELETION); psa_wipe_key_slot(*p_slot); if (status == PSA_ERROR_DOES_NOT_EXIST) { @@ -544,13 +534,10 @@ psa_status_t psa_close_key(psa_key_handle_t handle) return status; } if (slot->registered_readers == 1) { - status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL, - PSA_SLOT_PENDING_DELETION); - if (status != PSA_SUCCESS) { - return status; - } + return psa_wipe_key_slot(slot); + } else { + return psa_unregister_read(slot); } - return psa_unregister_read(slot); } psa_status_t psa_purge_key(mbedtls_svc_key_id_t key) @@ -565,10 +552,10 @@ psa_status_t psa_purge_key(mbedtls_svc_key_id_t key) if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) && (slot->registered_readers == 1)) { - psa_key_slot_state_transition(slot, PSA_SLOT_FULL, - PSA_SLOT_PENDING_DELETION); + return psa_wipe_key_slot(slot); + } else { + return psa_unregister_read(slot); } - return psa_unregister_read(slot); } void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats) diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index 5858b1851..9b8e89132 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -179,7 +179,7 @@ static inline psa_status_t psa_register_read(psa_key_slot_t *slot) * This function decrements the key slot registered reader counter by one. * If the state of the slot is PSA_SLOT_PENDING_DELETION, * and there is only one registered reader (the caller), - * this function will call psa_wipe_slot(). + * this function will call psa_wipe_key_slot(). * * \note To ease the handling of errors in retrieving a key slot * a NULL input pointer is valid, and the function returns From dfe8bf86a8957cf93795584cba2eb5603d40f84c Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 12 Jan 2024 17:45:05 +0000 Subject: [PATCH 078/215] Return CORRUPTION_DETECTED instead of BAD_SLOT when the slot's state is wrong These error codes are only returned if the program has been tampered with, so they should be CORRUPTION_DETECTED. Signed-off-by: Ryan Everett --- include/psa/crypto.h | 8 ++------ include/psa/crypto_compat.h | 4 +--- library/psa_crypto.c | 1 - library/psa_crypto_core.h | 2 +- library/psa_crypto_slot_management.c | 2 +- library/psa_crypto_slot_management.h | 29 ++++++++++++---------------- 6 files changed, 17 insertions(+), 29 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index fd1928a65..fe10ee0e4 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -415,9 +415,7 @@ void psa_reset_key_attributes(psa_key_attributes_t *attributes); * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize - * results in this error code. Or, - * this call was operating on a key slot and found the slot in - * an invalid state for the operation. + * results in this error code. */ psa_status_t psa_purge_key(mbedtls_svc_key_id_t key); @@ -557,9 +555,7 @@ psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize - * results in this error code. Or, - * this call was operating on a key slot and found the slot in - * an invalid state for the operation. + * results in this error code. */ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key); diff --git a/include/psa/crypto_compat.h b/include/psa/crypto_compat.h index bfc00164b..f896fae1c 100644 --- a/include/psa/crypto_compat.h +++ b/include/psa/crypto_compat.h @@ -142,9 +142,7 @@ psa_status_t psa_open_key(mbedtls_svc_key_id_t key, * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize - * results in this error code. Or, - * this call was operating on a key slot and found the slot in - * an invalid state for the operation. + * results in this error code. */ psa_status_t psa_close_key(psa_key_handle_t handle); diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 1f6450025..2a8183e04 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1718,7 +1718,6 @@ static psa_status_t psa_start_key_creation( * \retval #PSA_ERROR_DATA_INVALID \emptydescription * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription - * \retval #PSA_ERROR_BAD_STATE \emptydescription * * \return If this function fails, the key slot is an invalid state. * You must call psa_fail_key_creation() to wipe and free the slot. diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index f11df9f36..376337e16 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -56,7 +56,7 @@ typedef struct { * The state variable is used to help determine whether library functions * which operate on the slot succeed. For example, psa_finish_key_creation, * which transfers the state of a slot from PSA_SLOT_FILLING to - * PSA_SLOT_FULL, must fail with error code PSA_ERROR_BAD_STATE + * PSA_SLOT_FULL, must fail with error code PSA_ERROR_CORRUPTION_DETECTED * if the state of the slot is not PSA_SLOT_FILLING. * * Library functions which traverse the array of key slots only consider diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index e7ea8efb4..3accacff0 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -417,7 +417,7 @@ psa_status_t psa_unregister_read(psa_key_slot_t *slot) } if ((slot->state != PSA_SLOT_FULL) && (slot->state != PSA_SLOT_PENDING_DELETION)) { - return PSA_ERROR_BAD_STATE; + return PSA_ERROR_CORRUPTION_DETECTED; } /* If we are the last reader and the slot is marked for deletion, diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index 9b8e89132..0b0d7b320 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -68,9 +68,7 @@ static inline int psa_key_id_is_volatile(psa_key_id_t key_id) * description of the key identified by \p key. * The key slot counter has been incremented. * \retval #PSA_ERROR_BAD_STATE - * The library has not been initialized. Or, - * this call was operating on a key slot and found the slot in - * an invalid state for the operation. + * The library has not been initialized. * \retval #PSA_ERROR_INVALID_HANDLE * \p key is not a valid key identifier. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -114,7 +112,8 @@ void psa_wipe_all_key_slots(void); * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_INSUFFICIENT_MEMORY * There were no free key slots. - * \retval #PSA_ERROR_BAD_STATE + * \retval #PSA_ERROR_BAD_STATE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED * This function attempted to operate on a key slot which was in an * unexpected state. */ @@ -133,7 +132,7 @@ psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, * * \retval #PSA_SUCCESS The key slot's state variable is new_state. - * \retval #PSA_ERROR_BAD_STATE + * \retval #PSA_ERROR_CORRUPTION_DETECTED * The slot's state was not expected_state. */ static inline psa_status_t psa_key_slot_state_transition( @@ -141,7 +140,7 @@ static inline psa_status_t psa_key_slot_state_transition( psa_key_slot_state_t new_state) { if (slot->state != expected_state) { - return PSA_ERROR_BAD_STATE; + return PSA_ERROR_CORRUPTION_DETECTED; } slot->state = new_state; return PSA_SUCCESS; @@ -157,16 +156,12 @@ static inline psa_status_t psa_key_slot_state_transition( The key slot registered reader counter was incremented. * \retval #PSA_ERROR_CORRUPTION_DETECTED * The reader counter already reached its maximum value and was not - * increased. - * \retval #PSA_ERROR_BAD_STATE - * The slot's state was not PSA_SLOT_FULL. + * increased, or the slot's state was not PSA_SLOT_FULL. */ static inline psa_status_t psa_register_read(psa_key_slot_t *slot) { - if (slot->state != PSA_SLOT_FULL) { - return PSA_ERROR_BAD_STATE; - } - if (slot->registered_readers >= SIZE_MAX) { + if ((slot->state != PSA_SLOT_FULL) || + (slot->registered_readers >= SIZE_MAX)) { return PSA_ERROR_CORRUPTION_DETECTED; } slot->registered_readers++; @@ -190,11 +185,11 @@ static inline psa_status_t psa_register_read(psa_key_slot_t *slot) * \p slot is NULL or the key slot reader counter has been * decremented (and potentially wiped) successfully. * \retval #PSA_ERROR_CORRUPTION_DETECTED - * registered_readers was equal to 0. - * \retval #PSA_ERROR_BAD_STATE * The slot's state was neither PSA_SLOT_FULL nor - * PSA_SLOT_PENDING_DELETION, or a wipe was attempted and - * the slot's state was not PSA_SLOT_PENDING_DELETION. + * PSA_SLOT_PENDING_DELETION. + * Or a wipe was attempted and the slot's state was not + * PSA_SLOT_PENDING_DELETION. + * Or registered_readers was equal to 0. */ psa_status_t psa_unregister_read(psa_key_slot_t *slot); From 709120a9ceb73dd02578d487caebee0a51491767 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Mon, 15 Jan 2024 11:19:03 +0000 Subject: [PATCH 079/215] Revert change to return behaviour in psa_reserve_free_key_slot This change was a mistake, we still need to wipe the pointers here. Signed-off-by: Ryan Everett --- library/psa_crypto_slot_management.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 3accacff0..8d7ff908e 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -199,7 +199,7 @@ psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, status = psa_key_slot_state_transition(selected_slot, PSA_SLOT_EMPTY, PSA_SLOT_FILLING); if (status != PSA_SUCCESS) { - return status; + goto error; } *volatile_key_id = PSA_KEY_ID_VOLATILE_MIN + From 1d32a577645cc188793ffd1401d84a05fa39e0ca Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Mon, 15 Jan 2024 11:27:58 +0000 Subject: [PATCH 080/215] Revert change to psa_destroy_key documentation Signed-off-by: Ryan Everett --- library/psa_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 2a8183e04..d15ace559 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1126,7 +1126,7 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key) exit: status = psa_wipe_key_slot(slot); - /* Prioritize an error from wiping over a storage error */ + /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */ if (status != PSA_SUCCESS) { overall_status = status; } From b49cf1019d32e204c13839fba9ac329d623a1105 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Sat, 13 Jan 2024 16:40:58 +0000 Subject: [PATCH 081/215] Introduce mbedtls_ctr_increment_counter Signed-off-by: Dave Rodgman --- library/ctr.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 library/ctr.h diff --git a/library/ctr.h b/library/ctr.h new file mode 100644 index 000000000..a6b84cdeb --- /dev/null +++ b/library/ctr.h @@ -0,0 +1,30 @@ +/** + * \file ctr.h + * + * \brief This file contains common functionality for counter algorithms. + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "common.h" + +/** + * \brief Increment a big-endian 16-byte value. + * This is quite performance-sensitive for AES-CTR and CTR-DRBG. + * + * \param n A 16-byte value to be incremented. + */ +static inline void mbedtls_ctr_increment_counter(uint8_t n[16]) +{ + // The 32-bit version seems to perform about the same as a 64-bit version + // on 64-bit architectures, so no need to define a 64-bit version. + for (int i = 3;; i--) { + uint32_t x = MBEDTLS_GET_UINT32_BE(n, i << 2); + x += 1; + MBEDTLS_PUT_UINT32_BE(x, n, i << 2); + if (x != 0 || i == 0) { + break; + } + } +} From ae730348e9c983410d343c14940e08550bcb58b4 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Sat, 13 Jan 2024 17:31:13 +0000 Subject: [PATCH 082/215] Add tests for mbedtls_ctr_increment_counter Signed-off-by: Dave Rodgman --- tests/suites/test_suite_ctr_drbg.data | 45 ++++++++++++++ tests/suites/test_suite_ctr_drbg.function | 73 +++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/tests/suites/test_suite_ctr_drbg.data b/tests/suites/test_suite_ctr_drbg.data index 028a07f80..89dfb9792 100644 --- a/tests/suites/test_suite_ctr_drbg.data +++ b/tests/suites/test_suite_ctr_drbg.data @@ -1105,3 +1105,48 @@ ctr_drbg_threads:"B10A961F2EA39927B4C48AEDDD299026":1:5 CTR_DRBG self test ctr_drbg_selftest: + +Increment counter rollover +ctr_increment_rollover + +Increment counter 00 +ctr_increment:"00" + +Increment counter ff00 +ctr_increment:"ff00" + +Increment counter ff0000 +ctr_increment:"ff0000" + +Increment counter ff000000 +ctr_increment:"ff000000" + +Increment counter ff00000000 +ctr_increment:"ff00000000" + +Increment counter ff0000000000 +ctr_increment:"ff0000000000" + +Increment counter ff000000000000 +ctr_increment:"ff000000000000" + +Increment counter 01 +ctr_increment:"01" + +Increment counter ff01 +ctr_increment:"ff01" + +Increment counter ff0001 +ctr_increment:"ff0001" + +Increment counter ff000001 +ctr_increment:"ff000001" + +Increment counter ff00000001 +ctr_increment:"ff00000001" + +Increment counter ff0000000001 +ctr_increment:"ff0000000001" + +Increment counter ff000000000001 +ctr_increment:"ff000000000001" diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index 1f0a072c7..425c43ef1 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -2,6 +2,7 @@ #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" #include "string.h" +#include "ctr.h" #if defined(MBEDTLS_THREADING_PTHREAD) #include "mbedtls/threading.h" @@ -443,3 +444,75 @@ void ctr_drbg_selftest() AES_PSA_DONE(); } /* END_CASE */ + +/* BEGIN_CASE */ +void ctr_increment_rollover() +{ + uint8_t c[16]; + uint8_t r[16]; + + // test all increments from 2^n - 1 to 2^n (i.e. where we roll over into the next bit) + for (int n = 0; n <= 128; n++) { + memset(c, 0, 16); + memset(r, 0, 16); + + // set least significant (highest address) n bits to 1, i.e. generate (2^n - 1) + for (int i = 0; i < n; i++) { + int bit = i % 8; + int byte = (i / 8); + c[15 - byte] |= 1 << bit; + } + // increment to get 2^n + mbedtls_ctr_increment_counter(c); + + // now generate a reference result equal to 2^n - i.e. set only bit (n + 1) + // if n == 127, this will not set any bits (i.e. wraps to 0). + int bit = n % 8; + int byte = n / 8; + if (byte < 16) { + r[15 - byte] = 1 << bit; + } + + TEST_MEMORY_COMPARE(c, 16, r, 16); + } + + uint64_t lsb = 10, msb = 20; + MBEDTLS_PUT_UINT64_BE(msb, c, 0); + MBEDTLS_PUT_UINT64_BE(lsb, c, 8); + memcpy(r, c, 16); + mbedtls_ctr_increment_counter(c); + for (int i = 15; i >= 0; i--) { + r[i] += 1; + if (r[i] != 0) { + break; + } + } + TEST_MEMORY_COMPARE(c, 16, r, 16); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void ctr_increment(data_t *x) +{ + uint8_t c[16]; + uint8_t r[16]; + + // initialise c and r from test argument + memset(c, 0, 16); + memcpy(c, x->x, x->len); + memcpy(r, c, 16); + + // increment c + mbedtls_ctr_increment_counter(c); + // increment reference + for (int i = 15; i >= 0; i--) { + r[i] += 1; + if (r[i] != 0) { + break; + } + } + + // test that mbedtls_ctr_increment_counter behaviour matches reference + TEST_MEMORY_COMPARE(c, 16, r, 16); +} +/* END_CASE */ From 591ff05384f36658022f3c67f408dbc903ec8897 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Sat, 13 Jan 2024 16:42:38 +0000 Subject: [PATCH 083/215] Use optimised counter increment in AES-CTR and CTR-DRBG Signed-off-by: Dave Rodgman --- library/aes.c | 7 ++----- library/ctr_drbg.c | 17 +++++------------ 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/library/aes.c b/library/aes.c index ced8a3263..b1a5c3ed1 100644 --- a/library/aes.c +++ b/library/aes.c @@ -53,6 +53,7 @@ #endif #include "mbedtls/platform.h" +#include "ctr.h" /* * This is a convenience shorthand macro to check if we need reverse S-box and @@ -1456,11 +1457,7 @@ int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx, if (ret != 0) { goto exit; } - for (int j = 16; j > 0; j--) { - if (++nonce_counter[j - 1] != 0) { - break; - } - } + mbedtls_ctr_increment_counter(nonce_counter); } else { n -= offset; } diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c index da34f950b..f3995f709 100644 --- a/library/ctr_drbg.c +++ b/library/ctr_drbg.c @@ -14,6 +14,7 @@ #if defined(MBEDTLS_CTR_DRBG_C) +#include "ctr.h" #include "mbedtls/ctr_drbg.h" #include "mbedtls/platform_util.h" #include "mbedtls/error.h" @@ -333,7 +334,7 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx, { unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; unsigned char *p = tmp; - int i, j; + int j; int ret = 0; #if !defined(MBEDTLS_AES_C) psa_status_t status; @@ -346,11 +347,7 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx, /* * Increase counter */ - for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) { - if (++ctx->counter[i - 1] != 0) { - break; - } - } + mbedtls_ctr_increment_counter(ctx->counter); /* * Crypt counter block @@ -652,13 +649,9 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng, while (output_len > 0) { /* - * Increase counter + * Increase counter (treat it as a 128-bit big-endian integer). */ - for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) { - if (++ctx->counter[i - 1] != 0) { - break; - } - } + mbedtls_ctr_increment_counter(ctx->counter); /* * Crypt counter block From 174eeff235f2d3c8290a5709811669332521685b Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Sat, 13 Jan 2024 16:43:18 +0000 Subject: [PATCH 084/215] Save 14 bytes in CTR-DRBG Signed-off-by: Dave Rodgman --- library/ctr_drbg.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c index f3995f709..30574679f 100644 --- a/library/ctr_drbg.c +++ b/library/ctr_drbg.c @@ -369,9 +369,7 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx, p += MBEDTLS_CTR_DRBG_BLOCKSIZE; } - for (i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++) { - tmp[i] ^= data[i]; - } + mbedtls_xor(tmp, tmp, data, MBEDTLS_CTR_DRBG_SEEDLEN); /* * Update key and counter @@ -614,10 +612,11 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng, { int ret = 0; mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; - unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; unsigned char *p = output; - unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE]; - int i; + struct { + unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; + unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE]; + } locals; size_t use_len; if (output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST) { @@ -628,7 +627,7 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng, return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG; } - memset(add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN); + memset(locals.add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN); if (ctx->reseed_counter > ctx->reseed_interval || ctx->prediction_resistance) { @@ -639,10 +638,10 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng, } if (add_len > 0) { - if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) { + if ((ret = block_cipher_df(locals.add_input, additional, add_len)) != 0) { goto exit; } - if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) { + if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) { goto exit; } } @@ -658,7 +657,7 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng, */ #if defined(MBEDTLS_AES_C) if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, - ctx->counter, tmp)) != 0) { + ctx->counter, locals.tmp)) != 0) { goto exit; } #else @@ -678,20 +677,19 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng, /* * Copy random block to destination */ - memcpy(p, tmp, use_len); + memcpy(p, locals.tmp, use_len); p += use_len; output_len -= use_len; } - if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) { + if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) { goto exit; } ctx->reseed_counter++; exit: - mbedtls_platform_zeroize(add_input, sizeof(add_input)); - mbedtls_platform_zeroize(tmp, sizeof(tmp)); + mbedtls_platform_zeroize(&locals, sizeof(locals)); return ret; } From 46697da5b3b555148c7e5a46aaf70393c6a48eb3 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Sun, 14 Jan 2024 12:59:49 +0000 Subject: [PATCH 085/215] Make gcm counter increment more efficient Signed-off-by: Dave Rodgman --- library/gcm.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/library/gcm.c b/library/gcm.c index 20d55c0a8..c677ca4d7 100644 --- a/library/gcm.c +++ b/library/gcm.c @@ -401,12 +401,9 @@ int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx, /* Increment the counter. */ static void gcm_incr(unsigned char y[16]) { - size_t i; - for (i = 16; i > 12; i--) { - if (++y[i - 1] != 0) { - break; - } - } + uint32_t x = MBEDTLS_GET_UINT32_BE(y, 12); + x++; + MBEDTLS_PUT_UINT32_BE(x, y, 12); } /* Calculate and apply the encryption mask. Process use_len bytes of data, From 66a827fc8394f67096f6f3ea7eb11ddbe8ad6616 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 15 Jan 2024 15:00:52 +0100 Subject: [PATCH 086/215] test_driver_key_management: make opaque [un]wrapping functions public Signed-off-by: Valerio Setti --- tests/include/test/drivers/key_management.h | 8 ++++++++ tests/src/drivers/test_driver_key_management.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/include/test/drivers/key_management.h b/tests/include/test/drivers/key_management.h index 526adbb91..9a68777ec 100644 --- a/tests/include/test/drivers/key_management.h +++ b/tests/include/test/drivers/key_management.h @@ -67,6 +67,14 @@ void mbedtls_test_transparent_free(void); psa_status_t mbedtls_test_opaque_init(void); void mbedtls_test_opaque_free(void); +psa_status_t mbedtls_test_opaque_wrap_key( + const uint8_t *key, size_t key_length, uint8_t *wrapped_key_buffer, + size_t wrapped_key_buffer_size, size_t *wrapped_key_buffer_length); + +psa_status_t mbedtls_test_opaque_unwrap_key( + const uint8_t *wrapped_key, size_t wrapped_key_length, uint8_t *key_buffer, + size_t key_buffer_size, size_t *key_buffer_length); + psa_status_t mbedtls_test_transparent_generate_key( const psa_key_attributes_t *attributes, uint8_t *key, size_t key_size, size_t *key_length); diff --git a/tests/src/drivers/test_driver_key_management.c b/tests/src/drivers/test_driver_key_management.c index d522ebfe8..4188c25c1 100644 --- a/tests/src/drivers/test_driver_key_management.c +++ b/tests/src/drivers/test_driver_key_management.c @@ -125,7 +125,7 @@ static size_t mbedtls_test_opaque_get_base_size() * The argument wrapped_key_buffer_length is filled with the wrapped * key_size on success. * */ -static psa_status_t mbedtls_test_opaque_wrap_key( +psa_status_t mbedtls_test_opaque_wrap_key( const uint8_t *key, size_t key_length, uint8_t *wrapped_key_buffer, @@ -159,7 +159,7 @@ static psa_status_t mbedtls_test_opaque_wrap_key( * The argument key_buffer_length is filled with the unwrapped(clear) * key_size on success. * */ -static psa_status_t mbedtls_test_opaque_unwrap_key( +psa_status_t mbedtls_test_opaque_unwrap_key( const uint8_t *wrapped_key, size_t wrapped_key_length, uint8_t *key_buffer, From 62b6f10f64f8454b3aba38fda05257356cd56541 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 15 Jan 2024 15:03:17 +0100 Subject: [PATCH 087/215] test_driver_asymmetric_encryption: implement opaque [en/de]cryption functions Signed-off-by: Valerio Setti --- .../test_driver_asymmetric_encryption.c | 78 +++++++++++++------ 1 file changed, 55 insertions(+), 23 deletions(-) diff --git a/tests/src/drivers/test_driver_asymmetric_encryption.c b/tests/src/drivers/test_driver_asymmetric_encryption.c index ff46387d5..4fc8c9d34 100644 --- a/tests/src/drivers/test_driver_asymmetric_encryption.c +++ b/tests/src/drivers/test_driver_asymmetric_encryption.c @@ -13,11 +13,15 @@ #include "psa_crypto_rsa.h" #include "string.h" #include "test/drivers/asymmetric_encryption.h" +#include "test/drivers/key_management.h" #if defined(MBEDTLS_TEST_LIBTESTDRIVER1) #include "libtestdriver1/library/psa_crypto_rsa.h" #endif +#define PSA_RSA_KEY_PAIR_MAX_SIZE \ + PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) + mbedtls_test_driver_asymmetric_encryption_hooks_t mbedtls_test_driver_asymmetric_encryption_hooks = MBEDTLS_TEST_DRIVER_ASYMMETRIC_ENCRYPTION_INIT; @@ -104,7 +108,7 @@ psa_status_t mbedtls_test_transparent_asymmetric_decrypt( } /* - * opaque versions - TODO + * opaque versions */ psa_status_t mbedtls_test_opaque_asymmetric_encrypt( const psa_key_attributes_t *attributes, const uint8_t *key, @@ -112,17 +116,31 @@ psa_status_t mbedtls_test_opaque_asymmetric_encrypt( size_t input_length, const uint8_t *salt, size_t salt_length, uint8_t *output, size_t output_size, size_t *output_length) { - (void) attributes; - (void) key; - (void) key_length; - (void) alg; - (void) input; - (void) input_length; - (void) salt; - (void) salt_length; - (void) output; - (void) output_size; - (void) output_length; + unsigned char unwrapped_key[PSA_RSA_KEY_PAIR_MAX_SIZE]; + size_t unwrapped_key_length; + psa_status_t status; + + status = mbedtls_test_opaque_unwrap_key(key, key_length, + unwrapped_key, sizeof(unwrapped_key), + &unwrapped_key_length); + if (status != PSA_SUCCESS) { + return status; + } + +#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ + (defined(MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP) || defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT)) + return libtestdriver1_mbedtls_psa_asymmetric_encrypt( + (const libtestdriver1_psa_key_attributes_t *) attributes, + unwrapped_key, unwrapped_key_length, + alg, input, input_length, salt, salt_length, + output, output_size, output_length); +#else + return mbedtls_psa_asymmetric_encrypt( + attributes, unwrapped_key, unwrapped_key_length, + alg, input, input_length, salt, salt_length, + output, output_size, output_length); +#endif + return PSA_ERROR_NOT_SUPPORTED; } @@ -132,17 +150,31 @@ psa_status_t mbedtls_test_opaque_asymmetric_decrypt( size_t input_length, const uint8_t *salt, size_t salt_length, uint8_t *output, size_t output_size, size_t *output_length) { - (void) attributes; - (void) key; - (void) key_length; - (void) alg; - (void) input; - (void) input_length; - (void) salt; - (void) salt_length; - (void) output; - (void) output_size; - (void) output_length; + unsigned char unwrapped_key[PSA_RSA_KEY_PAIR_MAX_SIZE]; + size_t unwrapped_key_length; + psa_status_t status; + + status = mbedtls_test_opaque_unwrap_key(key, key_length, + unwrapped_key, sizeof(unwrapped_key), + &unwrapped_key_length); + if (status != PSA_SUCCESS) { + return status; + } + +#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ + (defined(MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP) || defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT)) + return libtestdriver1_mbedtls_psa_asymmetric_decrypt( + (const libtestdriver1_psa_key_attributes_t *) attributes, + unwrapped_key, unwrapped_key_length, + alg, input, input_length, salt, salt_length, + output, output_size, output_length); +#else + return mbedtls_psa_asymmetric_decrypt( + attributes, unwrapped_key, unwrapped_key_length, + alg, input, input_length, salt, salt_length, + output, output_size, output_length); +#endif + return PSA_ERROR_NOT_SUPPORTED; } From 4860a6c7acc281bf581f972147d09c0407bebbe1 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 15 Jan 2024 15:05:24 +0100 Subject: [PATCH 088/215] test_suite_psa_crypto: revert known failing checks for [en|de]cryption with opaque keys Signed-off-by: Valerio Setti --- tests/suites/test_suite_psa_crypto.function | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index f67508c5f..60c4f30d8 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -2148,11 +2148,8 @@ void asymmetric_encryption_key_policy(int policy_usage_arg, NULL, 0, buffer, buffer_length, &output_length); - if (use_opaque_key) { - /* Encryption/decryption is opaque keys is currently not supported. */ - TEST_EQUAL(status, PSA_ERROR_NOT_SUPPORTED); - } else if (policy_alg == exercise_alg && - (policy_usage & PSA_KEY_USAGE_ENCRYPT) != 0) { + if (policy_alg == exercise_alg && + (policy_usage & PSA_KEY_USAGE_ENCRYPT) != 0) { PSA_ASSERT(status); } else { TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED); @@ -2166,11 +2163,8 @@ void asymmetric_encryption_key_policy(int policy_usage_arg, NULL, 0, buffer, buffer_length, &output_length); - if (use_opaque_key) { - /* Encryption/decryption is opaque keys is currently not supported. */ - TEST_EQUAL(status, PSA_ERROR_NOT_SUPPORTED); - } else if (policy_alg == exercise_alg && - (policy_usage & PSA_KEY_USAGE_DECRYPT) != 0) { + if (policy_alg == exercise_alg && + (policy_usage & PSA_KEY_USAGE_DECRYPT) != 0) { TEST_EQUAL(status, PSA_ERROR_INVALID_PADDING); } else { TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED); From 4cc6fb90393e3d271e8e00a28410f4904095a411 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Sun, 14 Jan 2024 18:13:05 +0000 Subject: [PATCH 089/215] add test for multipart AES-CTR Signed-off-by: Dave Rodgman --- tests/suites/test_suite_aes.ctr.data | 119 +++++++++++++++++++++++++++ tests/suites/test_suite_aes.function | 72 ++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 tests/suites/test_suite_aes.ctr.data diff --git a/tests/suites/test_suite_aes.ctr.data b/tests/suites/test_suite_aes.ctr.data new file mode 100644 index 000000000..6ce7c01fc --- /dev/null +++ b/tests/suites/test_suite_aes.ctr.data @@ -0,0 +1,119 @@ +AES-CTR aes_encrypt_ctr_multipart 1 1 +aes_encrypt_ctr_multipart:1:1 + +AES-CTR aes_encrypt_ctr_multipart 2 1 +aes_encrypt_ctr_multipart:2:1 + +AES-CTR aes_encrypt_ctr_multipart 2 2 +aes_encrypt_ctr_multipart:2:2 + +AES-CTR aes_encrypt_ctr_multipart 4 1 +aes_encrypt_ctr_multipart:4:1 + +AES-CTR aes_encrypt_ctr_multipart 4 2 +aes_encrypt_ctr_multipart:4:2 + +AES-CTR aes_encrypt_ctr_multipart 15 1 +aes_encrypt_ctr_multipart:15:1 + +AES-CTR aes_encrypt_ctr_multipart 15 2 +aes_encrypt_ctr_multipart:15:2 + +AES-CTR aes_encrypt_ctr_multipart 15 8 +aes_encrypt_ctr_multipart:15:8 + +AES-CTR aes_encrypt_ctr_multipart 15 15 +aes_encrypt_ctr_multipart:15:15 + +AES-CTR aes_encrypt_ctr_multipart 16 1 +aes_encrypt_ctr_multipart:16:1 + +AES-CTR aes_encrypt_ctr_multipart 16 2 +aes_encrypt_ctr_multipart:16:2 + +AES-CTR aes_encrypt_ctr_multipart 16 8 +aes_encrypt_ctr_multipart:16:8 + +AES-CTR aes_encrypt_ctr_multipart 16 15 +aes_encrypt_ctr_multipart:16:15 + +AES-CTR aes_encrypt_ctr_multipart 16 16 +aes_encrypt_ctr_multipart:16:16 + +AES-CTR aes_encrypt_ctr_multipart 17 1 +aes_encrypt_ctr_multipart:17:1 + +AES-CTR aes_encrypt_ctr_multipart 17 2 +aes_encrypt_ctr_multipart:17:2 + +AES-CTR aes_encrypt_ctr_multipart 17 8 +aes_encrypt_ctr_multipart:17:8 + +AES-CTR aes_encrypt_ctr_multipart 17 15 +aes_encrypt_ctr_multipart:17:15 + +AES-CTR aes_encrypt_ctr_multipart 17 16 +aes_encrypt_ctr_multipart:17:16 + +AES-CTR aes_encrypt_ctr_multipart 63 1 +aes_encrypt_ctr_multipart:63:1 + +AES-CTR aes_encrypt_ctr_multipart 63 2 +aes_encrypt_ctr_multipart:63:2 + +AES-CTR aes_encrypt_ctr_multipart 63 8 +aes_encrypt_ctr_multipart:63:8 + +AES-CTR aes_encrypt_ctr_multipart 63 15 +aes_encrypt_ctr_multipart:63:15 + +AES-CTR aes_encrypt_ctr_multipart 63 16 +aes_encrypt_ctr_multipart:63:16 + +AES-CTR aes_encrypt_ctr_multipart 63 17 +aes_encrypt_ctr_multipart:63:17 + +AES-CTR aes_encrypt_ctr_multipart 64 1 +aes_encrypt_ctr_multipart:64:1 + +AES-CTR aes_encrypt_ctr_multipart 64 2 +aes_encrypt_ctr_multipart:64:2 + +AES-CTR aes_encrypt_ctr_multipart 64 8 +aes_encrypt_ctr_multipart:64:8 + +AES-CTR aes_encrypt_ctr_multipart 64 15 +aes_encrypt_ctr_multipart:64:15 + +AES-CTR aes_encrypt_ctr_multipart 64 16 +aes_encrypt_ctr_multipart:64:16 + +AES-CTR aes_encrypt_ctr_multipart 64 17 +aes_encrypt_ctr_multipart:64:17 + +AES-CTR aes_encrypt_ctr_multipart 1024 1 +aes_encrypt_ctr_multipart:1024:1 + +AES-CTR aes_encrypt_ctr_multipart 1024 10 +aes_encrypt_ctr_multipart:1024:10 + +AES-CTR aes_encrypt_ctr_multipart 1024 15 +aes_encrypt_ctr_multipart:1024:15 + +AES-CTR aes_encrypt_ctr_multipart 1024 16 +aes_encrypt_ctr_multipart:1024:16 + +AES-CTR aes_encrypt_ctr_multipart 1024 63 +aes_encrypt_ctr_multipart:1024:63 + +AES-CTR aes_encrypt_ctr_multipart 1024 64 +aes_encrypt_ctr_multipart:1024:64 + +AES-CTR aes_encrypt_ctr_multipart 1024 65 +aes_encrypt_ctr_multipart:1024:65 + +AES-CTR aes_encrypt_ctr_multipart 1024 1023 +aes_encrypt_ctr_multipart:1024:1023 + +AES-CTR aes_encrypt_ctr_multipart 1024 1024 +aes_encrypt_ctr_multipart:1024:1024 diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function index 2ca3f7f20..f4950a083 100644 --- a/tests/suites/test_suite_aes.function +++ b/tests/suites/test_suite_aes.function @@ -88,6 +88,78 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */ +void aes_encrypt_ctr_multipart(int length, int step_size) +{ + unsigned char key[16]; + unsigned char ctr_a[16]; + unsigned char ctr_b[16]; + unsigned char stream_block_a[16]; + unsigned char stream_block_b[16]; + unsigned char *input = NULL; + unsigned char *output_a = NULL; + unsigned char *output_b = NULL; + mbedtls_aes_context ctx; + size_t nc_off_a, nc_off_b; + + TEST_ASSERT(length >= 0); + TEST_ASSERT(step_size > 0); + + TEST_CALLOC(input, length); + TEST_CALLOC(output_a, length); + TEST_CALLOC(output_b, length); + + // set up a random key + mbedtls_test_rnd_std_rand(NULL, key, sizeof(key)); + + // random input + mbedtls_test_rnd_std_rand(NULL, input, sizeof(input)); + + + // complete encryption in one call + mbedtls_aes_init(&ctx); + TEST_ASSERT(mbedtls_aes_setkey_enc(&ctx, key, sizeof(key) * 8) == 0); + memset(ctr_a, 0, sizeof(ctr_a)); + memset(stream_block_a, 0, sizeof(stream_block_a)); + nc_off_a = 0; + TEST_EQUAL(mbedtls_aes_crypt_ctr(&ctx, length, &nc_off_a, ctr_a, + stream_block_a, input, output_a), 0); + mbedtls_aes_free(&ctx); + + + // encrypt in multiple steps of varying size + mbedtls_aes_init(&ctx); + TEST_ASSERT(mbedtls_aes_setkey_enc(&ctx, key, sizeof(key) * 8) == 0); + memset(ctr_b, 0, sizeof(ctr_b)); + memset(stream_block_b, 0, sizeof(stream_block_b)); + nc_off_b = 0; + size_t remaining = length; + unsigned char *ip = input, *op = output_b; + while (remaining != 0) { + size_t l = MIN(remaining, (size_t) step_size); + step_size *= 2; + remaining -= l; + TEST_EQUAL(mbedtls_aes_crypt_ctr(&ctx, l, &nc_off_b, ctr_b, stream_block_b, ip, op), 0); + ip += l; + op += l; + } + + // finally, validate that multiple steps produced same result as single-pass + TEST_MEMORY_COMPARE(output_a, length, output_b, length); + TEST_MEMORY_COMPARE(ctr_a, sizeof(ctr_a), ctr_b, sizeof(ctr_b)); + TEST_MEMORY_COMPARE(stream_block_a, sizeof(stream_block_a), + stream_block_b, sizeof(stream_block_b)); + TEST_EQUAL(nc_off_a, nc_off_b); + +exit: + mbedtls_free(input); + mbedtls_free(output_a); + mbedtls_free(output_b); + + mbedtls_aes_free(&ctx); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */ void aes_decrypt_ecb(data_t *key_str, data_t *src_str, data_t *dst, int setkey_result) From 24ad1b59e884df644d872149bb662b9c0cb9eb87 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Sun, 14 Jan 2024 23:52:27 +0000 Subject: [PATCH 090/215] Add NIST AES-CTR test vectors Signed-off-by: Dave Rodgman --- tests/suites/test_suite_aes.ctr.data | 16 ++++++++++ tests/suites/test_suite_aes.function | 46 ++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/tests/suites/test_suite_aes.ctr.data b/tests/suites/test_suite_aes.ctr.data index 6ce7c01fc..85c4c9645 100644 --- a/tests/suites/test_suite_aes.ctr.data +++ b/tests/suites/test_suite_aes.ctr.data @@ -1,3 +1,19 @@ +# Test vectors from NIST Special Publication 800-38A 2001 Edition +# Recommendation for Block Edition Cipher Modes of Operation + +# as below, but corrupt the key to check the test catches it +AES-CTR NIST 128 bad +aes_ctr:"00000000000000000000000000000000":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee":1 + +AES-CTR NIST 128 +aes_ctr:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee":0 + +AES-CTR NIST 192 +aes_ctr:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050":0 + +AES-CTR NIST 256 +aes_ctr:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"601ec313775789a5b7a7f504bbf3d228f443e3ca4d62b59aca84e990cacaf5c52b0930daa23de94ce87017ba2d84988ddfc9c58db67aada613c2dd08457941a6":0 + AES-CTR aes_encrypt_ctr_multipart 1 1 aes_encrypt_ctr_multipart:1:1 diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function index f4950a083..7b1306a82 100644 --- a/tests/suites/test_suite_aes.function +++ b/tests/suites/test_suite_aes.function @@ -88,6 +88,52 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */ +void aes_ctr(data_t *key, data_t *ictr, data_t *pt, data_t *ct, int expected) +{ + unsigned char *output = NULL; + unsigned char ctr[16]; + unsigned char stream_block[16]; + mbedtls_aes_context ctx; + + // sanity checks on test input + TEST_ASSERT(pt->len == ct->len); + TEST_ASSERT(key->len == 16 || key->len == 24 || key->len == 32); + + TEST_CALLOC(output, pt->len); + + // expected result is always success on zero-length input, so skip len == 0 if expecting failure + for (size_t len = (expected == 0 ? 0 : 1); len <= pt->len; len++) { + for (int i = 0; i < 2; i++) { + mbedtls_aes_init(&ctx); + TEST_ASSERT(mbedtls_aes_setkey_enc(&ctx, key->x, key->len * 8) == 0); + + memcpy(ctr, ictr->x, 16); + memset(stream_block, 0, 16); + memset(output, 0, pt->len); + + size_t nc_off = 0; + + if (i == 0) { + // encrypt + TEST_EQUAL(mbedtls_aes_crypt_ctr(&ctx, len, &nc_off, ctr, + stream_block, pt->x, output), 0); + TEST_ASSERT(!!memcmp(output, ct->x, len) == expected); + } else { + // decrypt + TEST_EQUAL(mbedtls_aes_crypt_ctr(&ctx, len, &nc_off, ctr, + stream_block, ct->x, output), 0); + TEST_ASSERT(!!memcmp(output, pt->x, len) == expected); + } + } + } + +exit: + mbedtls_free(output); + mbedtls_aes_free(&ctx); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CTR */ void aes_encrypt_ctr_multipart(int length, int step_size) { From 9f97566c0442066e01fedd28e5ce47b24baf158b Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Sun, 14 Jan 2024 23:55:20 +0000 Subject: [PATCH 091/215] Add Changelog Signed-off-by: Dave Rodgman --- ChangeLog.d/ctr-perf.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ChangeLog.d/ctr-perf.txt diff --git a/ChangeLog.d/ctr-perf.txt b/ChangeLog.d/ctr-perf.txt new file mode 100644 index 000000000..bc04080bf --- /dev/null +++ b/ChangeLog.d/ctr-perf.txt @@ -0,0 +1,3 @@ +Features + * Improve performance of AES-GCM, AES-CTR and CTR-DRBG when + hardware accelerated AES is not present (around 13-23% on 64-bit Arm). From 333ca8fdfc0c41852aadbf55e60100a6db5d09ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bence=20Sz=C3=A9pk=C3=BAti?= Date: Tue, 16 Jan 2024 17:05:19 +0100 Subject: [PATCH 092/215] Migrate to new RTD redirect format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migrate to the new redirect format introduced by ReadTheDocs in readthedocs/readthedocs.org#10881 Signed-off-by: Bence Szépkúti --- docs/redirects.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/redirects.yaml b/docs/redirects.yaml index 7ea1d9550..969ffe43c 100644 --- a/docs/redirects.yaml +++ b/docs/redirects.yaml @@ -7,5 +7,5 @@ # expose it. - type: exact - from_url: /projects/api/en/latest/$rest - to_url: /projects/api/en/development/ + from_url: /projects/api/en/latest/* + to_url: /projects/api/en/development/:splat From b7778b2388c2bdae733a7d702432faf41b718d80 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 16 Jan 2024 16:27:34 +0000 Subject: [PATCH 093/215] Fix ASAN error in test Signed-off-by: Dave Rodgman --- tests/suites/test_suite_aes.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function index 7b1306a82..9118a9865 100644 --- a/tests/suites/test_suite_aes.function +++ b/tests/suites/test_suite_aes.function @@ -159,7 +159,7 @@ void aes_encrypt_ctr_multipart(int length, int step_size) mbedtls_test_rnd_std_rand(NULL, key, sizeof(key)); // random input - mbedtls_test_rnd_std_rand(NULL, input, sizeof(input)); + mbedtls_test_rnd_std_rand(NULL, input, length); // complete encryption in one call From 7e5b7f91ca8efd5252a36765502ce9115ba73e61 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 16 Jan 2024 17:28:25 +0000 Subject: [PATCH 094/215] Fix error in ctr_drbg Signed-off-by: Dave Rodgman --- library/ctr_drbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c index 30574679f..66d9d28c5 100644 --- a/library/ctr_drbg.c +++ b/library/ctr_drbg.c @@ -665,7 +665,7 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng, size_t tmp_len; status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter), - tmp, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len); + locals.tmp, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len); if (status != PSA_SUCCESS) { ret = psa_generic_status_to_mbedtls(status); goto exit; From 9039ba572b102f32fd1418c1ab6d6cd8edc30dbc Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 16 Jan 2024 18:38:55 +0000 Subject: [PATCH 095/215] Fix test dependencies Signed-off-by: Dave Rodgman --- tests/suites/test_suite_aes.ctr.data | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/suites/test_suite_aes.ctr.data b/tests/suites/test_suite_aes.ctr.data index 85c4c9645..a14823666 100644 --- a/tests/suites/test_suite_aes.ctr.data +++ b/tests/suites/test_suite_aes.ctr.data @@ -9,9 +9,11 @@ AES-CTR NIST 128 aes_ctr:"2b7e151628aed2a6abf7158809cf4f3c":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee":0 AES-CTR NIST 192 +depends_on:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH aes_ctr:"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050":0 AES-CTR NIST 256 +depends_on:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH aes_ctr:"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4":"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff":"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710":"601ec313775789a5b7a7f504bbf3d228f443e3ca4d62b59aca84e990cacaf5c52b0930daa23de94ce87017ba2d84988ddfc9c58db67aada613c2dd08457941a6":0 AES-CTR aes_encrypt_ctr_multipart 1 1 From 584dc80d965541e1e93301d4e9b1d7f719168c32 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 16 Jan 2024 16:43:07 +0100 Subject: [PATCH 096/215] add changelog Signed-off-by: Valerio Setti --- ChangeLog.d/8461.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ChangeLog.d/8461.txt diff --git a/ChangeLog.d/8461.txt b/ChangeLog.d/8461.txt new file mode 100644 index 000000000..459e47bd2 --- /dev/null +++ b/ChangeLog.d/8461.txt @@ -0,0 +1,4 @@ +Bugfix + * Fix unsupported PSA asymmetric encryption and dectryption + (psa_asymmetric_[en|de]crypt) with opaque keys. + Resolves #8461. From 32294044e14cf166e77b3d4e3bbaac156700808c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 17 Jan 2024 10:07:55 +0100 Subject: [PATCH 097/215] Generalize mbedtls_pk_setup_opaque beyond MBEDTLS_USE_PSA_CRYPTO It's useful in applications that want to use some PSA opaque keys regardless of whether all pk operations go through PSA. Signed-off-by: Gilles Peskine --- docs/architecture/psa-migration/psa-legacy-bridges.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index 064b7d278..738e0ab2f 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -163,7 +163,7 @@ There is a function `mbedtls_pk_setup_opaque` that mostly does this. However, it * It creates a PK key of type `MBEDTLS_PK_OPAQUE` that wraps the PSA key. This is good enough in some scenarios, but not others. For example, it's ok for pkwrite, because we've upgraded the pkwrite code to handle `MBEDTLS_PK_OPAQUE`. That doesn't help users of third-party libraries that haven't yet been upgraded. * It ties the lifetime of the PK object to the PSA key, which is error-prone: if the PSA key is destroyed but the PK object isn't, there is no way to reliably detect any subsequent misuse of the PK object. -* It is only available under `MBEDTLS_USE_PSA_CRYPTO`. (Not a priority concern: we generally expect people to activate `MBEDTLS_USE_PSA_CRYPTO` at an early stage of their migration to PSA.) +* It is only available under `MBEDTLS_USE_PSA_CRYPTO`. This is not a priority concern, since we generally expect people to activate `MBEDTLS_USE_PSA_CRYPTO` at an early stage of their migration to PSA. However, this function is useful to use specific PSA keys in X.509/TLS regardless of whether X.509/TLS use the PSA API for all cryptographic operations, so this is a wart in the current API. It therefore appears that we need two ways to “convert” a PSA key to PK: @@ -305,6 +305,8 @@ Based on the [gap analysis](#using-a-psa-key-as-a-pk-context): [ACTION] Clarify the documentation of `mbedtls_pk_setup_opaque` regarding which algorithms the resulting key will perform with `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt`. +[ACTION] Provide `mbedtls_pk_setup_opaque` whenever `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, not just when `MBEDTLS_USE_PSA_CRYPTO` is enabled. This is nice-to-have, not critical. Update `use-psa-crypto.md` accordingly. + [OPEN] What about `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext`? #### API to convert between signature formats From 89ca6c7e72b351cf63f321031b94661d7185f4fd Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 17 Jan 2024 10:08:56 +0100 Subject: [PATCH 098/215] typo Signed-off-by: Gilles Peskine --- docs/architecture/psa-migration/psa-legacy-bridges.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index 738e0ab2f..79b08aa14 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -290,7 +290,7 @@ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, * `pk` must be initialized, but not set up. * It is an error if the key is neither a key pair nor a public key. * It is an error if the key is not exportable. -* The resulting pk object has a transparent type, not `MBEDTLS_PK_OPAQUE`. That's `MBEDTLS_PK_RSA` for RSA keys (since pk objects don't use `MBEDTLS_PK_RSASSA_PSS)` as a type, and `MBEDTLS_PK_ECKEY` for ECC keys (following the example of pkparse). +* The resulting pk object has a transparent type, not `MBEDTLS_PK_OPAQUE`. That's `MBEDTLS_PK_RSA` for RSA keys (since pk objects don't use `MBEDTLS_PK_RSASSA_PSS` as a type), and `MBEDTLS_PK_ECKEY` for ECC keys (following the example of pkparse). * Once this function returns, the pk object is completely independent of the PSA key. * Calling `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt` on the resulting pk context will perform an algorithm that is compatible with the PSA key's primary algorithm policy (`psa_get_key_algorithm`), but with no restriction on the hash (as if the policy had `PSA_ALG_ANY_HASH` instead of a specific hash, and with `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` merged with `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)`). For ECDSA, the choice of deterministic vs randomized will be based on the compile-time setting `MBEDTLS_ECDSA_DETERMINISTIC`, like `mbedtls_pk_sign` today. * The primary intent of this requirement is to allow an application to switch to PSA for creating the key material (for example to benefit from a PSA accelerator driver, or to start using a secure element), without modifying the code that consumes the key. For RSA keys, the PSA primary algorithm policy is how one conveys the same information as RSA key padding information in the legacy API. [ACTION] Convey this in the documentation. From 5a64c426936997fb0128635548e147af977ae1b5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 17 Jan 2024 10:09:16 +0100 Subject: [PATCH 099/215] Reference ongoing work Signed-off-by: Gilles Peskine --- docs/architecture/psa-migration/psa-legacy-bridges.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index 79b08aa14..e37f50ff4 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -126,7 +126,7 @@ Since there is no algorithm that can be used with multiple types, and PSA keys h This means converting between an `mbedtls_ecp_group_id` and a pair of `{psa_ecc_family_t; size_t}`. - This is fulfilled by `mbedtls_ecc_group_to_psa` and `mbedtls_ecc_group_of_psa`, which were introduced into the public API after Mbed TLS 3.5. + This is fulfilled by `mbedtls_ecc_group_to_psa` and `mbedtls_ecc_group_from_psa`, which were introduced into the public API between Mbed TLS 3.5 and 3.6 ([#8664](https://github.com/Mbed-TLS/mbedtls/pull/8664)). * Selecting A **DHM group**. From 885248c8ee824fafabd56a915ce0b941e4380631 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 17 Jan 2024 11:06:31 +0000 Subject: [PATCH 100/215] Add header guards Signed-off-by: Dave Rodgman --- library/ctr.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/ctr.h b/library/ctr.h index a6b84cdeb..aa48fb9e7 100644 --- a/library/ctr.h +++ b/library/ctr.h @@ -7,6 +7,9 @@ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ +#ifndef MBEDTLS_CTR_H +#define MBEDTLS_CTR_H + #include "common.h" /** @@ -28,3 +31,5 @@ static inline void mbedtls_ctr_increment_counter(uint8_t n[16]) } } } + +#endif /* MBEDTLS_CTR_H */ From 42a025dc9cc26e5f185e3edf6811268c7702a30c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 17 Jan 2024 12:35:15 +0100 Subject: [PATCH 101/215] Reference filed issues All PK-related actions are now covered. Signed-off-by: Gilles Peskine --- docs/architecture/psa-migration/psa-legacy-bridges.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index e37f50ff4..873fc39be 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -255,7 +255,7 @@ To allow the full flexibility around policies, and make the creation of a persis This is close to the existing function `mbedtls_pk_wrap_as_opaque`, but does not bake in the implementation-specific consideration that a PSA key has exactly two algorithms, and also allows the caller to benefit from default for the policy in more cases. -[ACTION] Implement `mbedtls_pk_get_psa_attributes` and `mbedtls_pk_import_into_psa` as described below. These functions are available whenever `MBEDTLS_PK_C` and `MBEDTLS_PSA_CRYPTO_CLIENT` are both defined. Deprecate `mbedtls_pk_wrap_as_opaque`. +[ACTION] [#8708](https://github.com/Mbed-TLS/mbedtls/issues/8708) Implement `mbedtls_pk_get_psa_attributes` and `mbedtls_pk_import_into_psa` as described below. These functions are available whenever `MBEDTLS_PK_C` and `MBEDTLS_PSA_CRYPTO_CLIENT` are both defined. Deprecate `mbedtls_pk_wrap_as_opaque`. ``` int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk, @@ -280,7 +280,7 @@ int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, Based on the [gap analysis](#using-a-psa-key-as-a-pk-context): -[ACTION] Implement `mbedtls_pk_copy_from_psa` as described below. +[ACTION] [#8709](https://github.com/Mbed-TLS/mbedtls/issues/8709) Implement `mbedtls_pk_copy_from_psa` as described below. ``` int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, @@ -293,7 +293,7 @@ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, * The resulting pk object has a transparent type, not `MBEDTLS_PK_OPAQUE`. That's `MBEDTLS_PK_RSA` for RSA keys (since pk objects don't use `MBEDTLS_PK_RSASSA_PSS` as a type), and `MBEDTLS_PK_ECKEY` for ECC keys (following the example of pkparse). * Once this function returns, the pk object is completely independent of the PSA key. * Calling `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt` on the resulting pk context will perform an algorithm that is compatible with the PSA key's primary algorithm policy (`psa_get_key_algorithm`), but with no restriction on the hash (as if the policy had `PSA_ALG_ANY_HASH` instead of a specific hash, and with `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` merged with `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)`). For ECDSA, the choice of deterministic vs randomized will be based on the compile-time setting `MBEDTLS_ECDSA_DETERMINISTIC`, like `mbedtls_pk_sign` today. - * The primary intent of this requirement is to allow an application to switch to PSA for creating the key material (for example to benefit from a PSA accelerator driver, or to start using a secure element), without modifying the code that consumes the key. For RSA keys, the PSA primary algorithm policy is how one conveys the same information as RSA key padding information in the legacy API. [ACTION] Convey this in the documentation. + * The primary intent of this requirement is to allow an application to switch to PSA for creating the key material (for example to benefit from a PSA accelerator driver, or to start using a secure element), without modifying the code that consumes the key. For RSA keys, the PSA primary algorithm policy is how one conveys the same information as RSA key padding information in the legacy API. Convey this in the documentation. * [OPEN] How do we distinguish between signature-only and encryption-only RSA keys? Do we just allow both (e.g. a PSS key gets generalized into a PSS/OAEP key)? * [OPEN] What about `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext`? @@ -303,9 +303,9 @@ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, Based on the [gap analysis](#using-a-psa-key-as-a-pk-context): -[ACTION] Clarify the documentation of `mbedtls_pk_setup_opaque` regarding which algorithms the resulting key will perform with `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt`. +[ACTION] [#8712](https://github.com/Mbed-TLS/mbedtls/issues/8712) Clarify the documentation of `mbedtls_pk_setup_opaque` regarding which algorithms the resulting key will perform with `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt`. -[ACTION] Provide `mbedtls_pk_setup_opaque` whenever `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, not just when `MBEDTLS_USE_PSA_CRYPTO` is enabled. This is nice-to-have, not critical. Update `use-psa-crypto.md` accordingly. +[ACTION] [#8710](https://github.com/Mbed-TLS/mbedtls/issues/8710) Provide `mbedtls_pk_setup_opaque` whenever `MBEDTLS_PSA_CRYPTO_CLIENT` is enabled, not just when `MBEDTLS_USE_PSA_CRYPTO` is enabled. This is nice-to-have, not critical. Update `use-psa-crypto.md` accordingly. [OPEN] What about `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext`? From 7ed542e0f1aea1673f2b8bb3079c294e04777558 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Wed, 17 Jan 2024 11:39:09 +0000 Subject: [PATCH 102/215] Implement delayed deletion in psa_destroy_key and some cleanup Signed-off-by: Ryan Everett --- library/psa_crypto.c | 80 +++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index d15ace559..565b5e14c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -987,18 +987,41 @@ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot) /* * As the return error code may not be handled in case of multiple errors, - * do our best to report an unexpected amount of registered readers. - * Assert with MBEDTLS_TEST_HOOK_TEST_ASSERT that registered_readers is - * equal to one: + * do our best to report an unexpected amount of registered readers or + * an unexpected state. + * Assert with MBEDTLS_TEST_HOOK_TEST_ASSERT that the slot is valid for + * wiping. * if the MBEDTLS_TEST_HOOKS configuration option is enabled and the * function is called as part of the execution of a test suite, the * execution of the test suite is stopped in error if the assertion fails. */ - if (((slot->state == PSA_SLOT_FULL) || - (slot->state == PSA_SLOT_PENDING_DELETION)) && - (slot->registered_readers != 1)) { - MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 1); - status = PSA_ERROR_CORRUPTION_DETECTED; + switch (slot->state) { + case PSA_SLOT_FULL: + /* In this state psa_wipe_key_slot() must only be called if the + * caller is the last reader. */ + case PSA_SLOT_PENDING_DELETION: + /* In this state psa_wipe_key_slot() must only be called if the + * caller is the last reader. */ + if (slot->registered_readers != 1) { + MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 1); + status = PSA_ERROR_CORRUPTION_DETECTED; + } + break; + case PSA_SLOT_FILLING: + /* In this state registered_readers must be 0. */ + if (slot->registered_readers != 0) { + MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->registered_readers == 0); + status = PSA_ERROR_CORRUPTION_DETECTED; + } + break; + case PSA_SLOT_EMPTY: + /* The slot is already empty, it cannot be wiped. */ + MBEDTLS_TEST_HOOK_TEST_ASSERT(slot->state != PSA_SLOT_EMPTY); + status = PSA_ERROR_CORRUPTION_DETECTED; + break; + default: + /* The slot's state is invalid. */ + status = PSA_ERROR_CORRUPTION_DETECTED; } /* Multipart operations may still be using the key. This is safe @@ -1028,29 +1051,25 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key) } /* - * Get the description of the key in a key slot. In case of a persistent - * key, this will load the key description from persistent memory if not - * done yet. We cannot avoid this loading as without it we don't know if + * Get the description of the key in a key slot, and register to read it. + * In the case of a persistent key, this will load the key description + * from persistent memory if not done yet. + * We cannot avoid this loading as without it we don't know if * the key is operated by an SE or not and this information is needed by - * the current implementation. - */ + * the current implementation. */ status = psa_get_and_lock_key_slot(key, &slot); if (status != PSA_SUCCESS) { return status; } - /* - * If the key slot containing the key description is under access by the - * library (apart from the present access), the key cannot be destroyed - * yet. For the time being, just return in error. Eventually (to be - * implemented), the key should be destroyed when all accesses have - * stopped. - */ - if (slot->registered_readers > 1) { - psa_unregister_read(slot); - return PSA_ERROR_GENERIC_ERROR; - } - + /* Set the key slot containing the key description's state to + * PENDING_DELETION. This stops new operations from registering + * to read the slot. Current readers can safely continue to access + * the key within the slot; the last registered reader will + * automatically wipe the slot when they call psa_unregister_read(). + * If the key is persistent, we can now delete the copy of the key + * from memory. If the key is opaque, we require the driver to + * deal with the deletion. */ slot->state = PSA_SLOT_PENDING_DELETION; if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) { @@ -1099,6 +1118,9 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key) #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) { + /* Destroy the copy of the persistent key from memory. + * The slot will still hold a copy of the key until the last reader + * unregisters. */ status = psa_destroy_persistent_key(slot->attr.id); if (overall_status == PSA_SUCCESS) { overall_status = status; @@ -1125,8 +1147,11 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key) #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ exit: - status = psa_wipe_key_slot(slot); - /* Prioritize CORRUPTION_DETECTED from wiping over a storage error */ + /* Unregister from reading the slot. If we are the last active reader + * then this will wipe the slot. */ + status = psa_unregister_read(slot); + /* Prioritize CORRUPTION_DETECTED from unregistering over + * a storage error. */ if (status != PSA_SUCCESS) { overall_status = status; } @@ -1825,6 +1850,7 @@ static void psa_fail_key_creation(psa_key_slot_t *slot, * itself. */ (void) psa_crypto_stop_transaction(); #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + psa_wipe_key_slot(slot); } From 38a2b7a6a3215b2d062da23b9945bbecd889e277 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Wed, 17 Jan 2024 11:45:44 +0000 Subject: [PATCH 103/215] Extend psa_wipe_key_slot documentation Signed-off-by: Ryan Everett --- library/psa_crypto_core.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 376337e16..b5b9c5451 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -190,7 +190,10 @@ static inline psa_key_slot_number_t psa_key_slot_get_slot_number( * The slot has been successfully wiped. * \retval #PSA_ERROR_CORRUPTION_DETECTED * The slot's state was PSA_SLOT_FULL or PSA_SLOT_PENDING_DELETION, and - * the amount of registered readers was not equal to 1. + * the amount of registered readers was not equal to 1. Or, + * the slot's state was PSA_SLOT_EMPTY. Or, + * the slot's state was PSA_SLOT_FILLING, and the amount + * of registered readers was not equal to 0. */ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot); From 702d9f65f681f9b493c774a0fdd61ccf9e23a305 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 17 Jan 2024 12:58:25 +0100 Subject: [PATCH 104/215] Resolve several open questions as nothing special to do Signed-off-by: Gilles Peskine --- .../psa-migration/psa-legacy-bridges.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index 873fc39be..7fe03d779 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -81,7 +81,11 @@ Based on “[Where mixing happens](#where-mixing-happens)”, we focus the gap a #### Need for error code conversion -[OPEN] Do we need public functions to convert between `MBEDTLS_ERR_xxx` error codes and `PSA_ERROR_xxx` error codes? We have such functions for internal use. +Do we need public functions to convert between `MBEDTLS_ERR_xxx` error codes and `PSA_ERROR_xxx` error codes? We have such functions for internal use. + +Mbed TLS needs these conversions because it has many functions that expose one API (legacy/API) but are implemented on top of the other API. Most applications would convert legacy and PSA error code to their own error codes, and converting between `MBEDTLS_ERR_xxx` error codes and `PSA_ERROR_xxx` is not particularly helpful for that. Application code might need such conversion functions when implementing an X.509 or TLS callback (returning `MBEDTLS_ERR_xxx`) on top of PSA functions, but this is a very limited use case. + +Conclusion: no need for public error code conversion functions. ### Hash gap analysis @@ -172,7 +176,7 @@ It therefore appears that we need two ways to “convert” a PSA key to PK: Gap: a way to copy a PSA key into a PK context. This can only be expected to work if the PSA key is exportable. -[OPEN] Is `mbedtls_pk_setup_opaque` ok or do we want to tweak it? +After some discussion, have not identified anything we want to change in the behavior of `mbedtls_pk_setup_opaque`. We only want to generalize it to non-`MBEDTLS_USE_PSA_CRYPTO` and to document it better. #### Signature formats @@ -238,6 +242,7 @@ Based on the [gap analysis](#asymmetric-cryptography-metadata): * No further work is needed about ECC specifically. We have just added adequate functions. * No further work is needed about DHM specifically. There is no good way to translate the relevant information. * [OPEN] Is there a decent way to convert between `mbedtls_pk_type_t` plus extra information, and `psa_key_type_t` plus policy information? The two APIs are different in crucial ways, with different splits between key type, policy information and operation algorithm. + Thinking so far: there isn't really a nice way to present this conversion. For a specific key, `mbedtls_pk_get_psa_attributes` and `mbedtls_pk_copy_from_psa` do the job. #### API to create a PSA key from a PK context @@ -292,12 +297,10 @@ int mbedtls_pk_copy_from_psa(mbedtls_svc_key_id_t key_id, * It is an error if the key is not exportable. * The resulting pk object has a transparent type, not `MBEDTLS_PK_OPAQUE`. That's `MBEDTLS_PK_RSA` for RSA keys (since pk objects don't use `MBEDTLS_PK_RSASSA_PSS` as a type), and `MBEDTLS_PK_ECKEY` for ECC keys (following the example of pkparse). * Once this function returns, the pk object is completely independent of the PSA key. -* Calling `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt` on the resulting pk context will perform an algorithm that is compatible with the PSA key's primary algorithm policy (`psa_get_key_algorithm`), but with no restriction on the hash (as if the policy had `PSA_ALG_ANY_HASH` instead of a specific hash, and with `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` merged with `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)`). For ECDSA, the choice of deterministic vs randomized will be based on the compile-time setting `MBEDTLS_ECDSA_DETERMINISTIC`, like `mbedtls_pk_sign` today. +* Calling `mbedtls_pk_sign`, `mbedtls_pk_verify`, `mbedtls_pk_encrypt`, `mbedtls_pk_decrypt` on the resulting pk context will perform an algorithm that is compatible with the PSA key's primary algorithm policy (`psa_get_key_algorithm`) if that is a matching operation type (sign/verify, encrypt/decrypt), but with no restriction on the hash (as if the policy had `PSA_ALG_ANY_HASH` instead of a specific hash, and with `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` merged with `PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)`). + * For ECDSA, the choice of deterministic vs randomized will be based on the compile-time setting `MBEDTLS_ECDSA_DETERMINISTIC`, like `mbedtls_pk_sign` today. + * For an RSA key, the output key will allow both encrypt/decrypt and sign/verify regardless of the original key's policy. The original key's policy determines the output key's padding mode. * The primary intent of this requirement is to allow an application to switch to PSA for creating the key material (for example to benefit from a PSA accelerator driver, or to start using a secure element), without modifying the code that consumes the key. For RSA keys, the PSA primary algorithm policy is how one conveys the same information as RSA key padding information in the legacy API. Convey this in the documentation. - * [OPEN] How do we distinguish between signature-only and encryption-only RSA keys? Do we just allow both (e.g. a PSS key gets generalized into a PSS/OAEP key)? - * [OPEN] What about `mbedtls_pk_sign_ext` and `mbedtls_pk_verify_ext`? - -[OPEN] Should there be a way to use a different algorithm? This can be resolved by `psa_copy_key` on the input to tweak the policy if needed. #### API to create a PK object that wraps a PSA key From d5b04a0c639f7f148f33c3e224b0731fea3f1dc0 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 17 Jan 2024 14:29:21 +0100 Subject: [PATCH 105/215] Add a usage parameter to mbedtls_pk_get_psa_attributes Let the user specify whether to use the key as a sign/verify key, an encrypt/decrypt key or a key agreement key. Also let the user indicate if they just want the public part when the input is a key pair. Based on a discussion in https://github.com/Mbed-TLS/mbedtls/pull/8682#discussion_r1444936480 Signed-off-by: Gilles Peskine --- .../psa-migration/psa-legacy-bridges.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index 7fe03d779..3039968b3 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -264,6 +264,7 @@ This is close to the existing function `mbedtls_pk_wrap_as_opaque`, but does not ``` int mbedtls_pk_get_psa_attributes(const mbedtls_pk_context *pk, + psa_key_usage_flags_t usage, psa_key_attributes_t *attributes); int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, const psa_key_attributes_t *attributes, @@ -271,11 +272,21 @@ int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, ``` * `mbedtls_pk_get_psa_attributes` does not change the id/lifetime fields of the attributes (which indicate a volatile key by default). + * [OPEN] Or should it reset them to 0? Resetting is more convenient for the case where the pk key is a `MBEDTLS_PK_OPAQUE`. But that's an uncommon use case. It's probably less surprising if this function leaves the lifetime-related alone, since its job is to set the type-related and policy-related attributes. * `mbedtls_pk_get_psa_attributes` sets the type and size based on what's in the pk context. - * The key type is a key pair if the context contains a private key, and a public key if the context only contains a public key. -* `mbedtls_pk_get_psa_attributes` sets all the potentially applicable usage flags: `EXPORT`, `COPY`; `VERIFY_HASH | VERIFY_MESSAGE` or `ENCRYPT` as applicable for both public keys and key pairs; `SIGN` or `DECRYPT` as applicable for a key pair. -* [OPEN] What is the default algorithm for `mbedtls_pk_get_psa_attributes`? Suggestion: assume signature by default. For RSA, either `PSA_RSA_PKCS1_V15_SIGN(PSA_ALG_ANY_HASH)` or `PSA_ALG_RSA_PSS(hash_alg)` depending on the RSA context's padding mode. For ECC, `PSA_ALG_DETERMINISTIC_ECDSA` if `MBEDTLS_ECDSA_DETERMINISTIC` is enabled and `PSA_ALG_ECDSA` otherwise. -* [OPEN] Or does `mbedtls_pk_get_psa_attributes` need an extra argument that conveys some kind of policy for RSA keys and, independently, some kind of policy for ECC keys? + * The key type is a key pair if the context contains a private key and the indicated usage is a private-key usage. The key type is a public key if the context only contains a public key, in which case a private-key usage is an error. +* `mbedtls_pk_get_psa_attributes` sets the usage flags based on the `usage` parameter. It extends the usage to other usage that is possible: + * `EXPORT` and `COPY` are always set. + * If `SIGN_{HASH,MESSAGE}` is set then so is `VERIFY_{HASH,MESSAGE}`. + * If `DECRYPT` is set then so is `ENCRYPT`. + * It is an error if `usage` has more than one flag set, or has a usage that is incompatible with the key type. +* `mbedtls_pk_get_psa_attributes` sets the algorithm usage policy based on information in the key object and on `usage`. + * For an RSA key with the `MBEDTLS_RSA_PKCS_V15` padding mode, the algorithm policy is `PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH)` for a sign/verify usage, and `PSA_ALG_RSA_PKCS1V15_CRYPT` for an encrypt/decrypt usage. + * For an RSA key with the `MBEDTLS_RSA_PKCS_V15` padding mode, the algorithm policy is `PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH)` for a sign/verify usage, and `PSA_ALG_RSA_OAEP(hash)` for an encrypt/decrypt usage where `hash` is from the RSA key's parameters. (Note that `PSA_ALG_ANY_HASH` is only allowed in signature algorithms.) + * For an `MBEDTLS_PK_ECKEY` or `MBEDTLS_PK_ECDSA` with a sign/verify usage, the algorithm policy is `PSA_ALG_DETERMINISTIC_ECDSA` if `MBEDTLS_ECDSA_DETERMINISTIC` is enabled and `PSA_ALG_ECDSA` otherwise. In either case, the hash policy is `PSA_ALG_ANY_HASH`. + * For an `MBEDTLS_PK_ECKEY` or `MBEDTLS_PK_ECDKEY_DH` with the usage `PSA_KEY_USAGE_DERIVE`, the algorithm is `PSA_ALG_ECDH`. + * For a `MBEDTLS_PK_OPAQUE`, this function reads the attributes of the existing PK key and copies them (without overriding the lifetime and key identifier in `attributes`), then applies a public-key restriction if needed. + * Public-key restriction: if `usage` is a public-key usage, change the type to the corresponding public-key type, and remove private-key usage flags from the usage flags read from the existing key. * `mbedtls_pk_import_into_psa` checks that the type field in the attributes is consistent with the content of the `mbedtls_pk_context` object (RSA/ECC, and availability of the private key). * The key type can be a public key even if the private key is available. * `mbedtls_pk_import_into_psa` does not need to check the bit-size in the attributes: `psa_import_key` will do enough checks. From dd77343381161e09a63b4694001da3957e27d3a7 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 17 Jan 2024 14:33:32 +0100 Subject: [PATCH 106/215] Open question for ECDSA signature that can be resolved during implementation Signed-off-by: Gilles Peskine --- docs/architecture/psa-migration/psa-legacy-bridges.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index 3039968b3..fb0070597 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -339,3 +339,5 @@ int mbedtls_ecdsa_der_to_raw(const unsigned char *der, size_t der_len, * These functions convert between the signature format used by `mbedtls_pk_{sign,verify}{,_ext}` and the signature format used by `psa_{sign,verify}_{hash,message}`. * The input and output buffers can overlap. + +[OPEN] Should these functions rely on the ASN.1 module? To be decided when implementing. From 4a0ba80bdbf9b2ef1f44071cdabc733962870d69 Mon Sep 17 00:00:00 2001 From: Ryan Everett <144035422+Ryan-Everett-arm@users.noreply.github.com> Date: Wed, 17 Jan 2024 14:12:33 +0000 Subject: [PATCH 107/215] Clarify psa_destroy_key documentation Co-authored-by: Janos Follath Signed-off-by: Ryan Everett <144035422+Ryan-Everett-arm@users.noreply.github.com> --- library/psa_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 565b5e14c..56265c197 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1118,7 +1118,7 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key) #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) if (!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) { - /* Destroy the copy of the persistent key from memory. + /* Destroy the copy of the persistent key from storage. * The slot will still hold a copy of the key until the last reader * unregisters. */ status = psa_destroy_persistent_key(slot->attr.id); From 43ff242a8b0e2a6d7488e502eb70c55e31a057c4 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 18 Jan 2024 08:42:38 +0100 Subject: [PATCH 108/215] changelog: fix typo Signed-off-by: Valerio Setti --- ChangeLog.d/8461.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/8461.txt b/ChangeLog.d/8461.txt index 459e47bd2..d6a65f070 100644 --- a/ChangeLog.d/8461.txt +++ b/ChangeLog.d/8461.txt @@ -1,4 +1,4 @@ Bugfix - * Fix unsupported PSA asymmetric encryption and dectryption + * Fix unsupported PSA asymmetric encryption and decryption (psa_asymmetric_[en|de]crypt) with opaque keys. Resolves #8461. From 4f34b155f52fa1015cfe3f1177ed5739e7d07dc7 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Thu, 18 Jan 2024 08:44:13 +0100 Subject: [PATCH 109/215] test_driver_key_management: keep mbedtls_test_opaque_wrap_key() private Only mbedtls_test_opaque_unwrap_key() is actually needed by other test drivers to deal with opaque keys. mbedtls_test_opaque_wrap_key() can be kept private to test_driver_key_management.c. Signed-off-by: Valerio Setti --- tests/include/test/drivers/key_management.h | 4 ---- tests/src/drivers/test_driver_key_management.c | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/include/test/drivers/key_management.h b/tests/include/test/drivers/key_management.h index 9a68777ec..7b5c4c7bf 100644 --- a/tests/include/test/drivers/key_management.h +++ b/tests/include/test/drivers/key_management.h @@ -67,10 +67,6 @@ void mbedtls_test_transparent_free(void); psa_status_t mbedtls_test_opaque_init(void); void mbedtls_test_opaque_free(void); -psa_status_t mbedtls_test_opaque_wrap_key( - const uint8_t *key, size_t key_length, uint8_t *wrapped_key_buffer, - size_t wrapped_key_buffer_size, size_t *wrapped_key_buffer_length); - psa_status_t mbedtls_test_opaque_unwrap_key( const uint8_t *wrapped_key, size_t wrapped_key_length, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length); diff --git a/tests/src/drivers/test_driver_key_management.c b/tests/src/drivers/test_driver_key_management.c index 4188c25c1..a3d532d51 100644 --- a/tests/src/drivers/test_driver_key_management.c +++ b/tests/src/drivers/test_driver_key_management.c @@ -125,7 +125,7 @@ static size_t mbedtls_test_opaque_get_base_size() * The argument wrapped_key_buffer_length is filled with the wrapped * key_size on success. * */ -psa_status_t mbedtls_test_opaque_wrap_key( +static psa_status_t mbedtls_test_opaque_wrap_key( const uint8_t *key, size_t key_length, uint8_t *wrapped_key_buffer, From 491f7e5ac3f03e247571f3c5088619bf8a807051 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Mon, 8 Jan 2024 11:04:21 +0000 Subject: [PATCH 110/215] Define key_slot_mutex Signed-off-by: Ryan Everett --- library/psa_crypto_slot_management.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 8d7ff908e..2d24e6deb 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -23,10 +23,27 @@ #include #include #include "mbedtls/platform.h" +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif typedef struct { psa_key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT]; uint8_t key_slots_initialized; + +#if defined(MBEDTLS_THREADING_C) + /* + * A mutex used to make the PSA subsystem thread safe. + * + * key_slot_mutex protects key_slots[i].registered_readers and + * key_slots[i].state for all valid i. + * + * This mutex must be held when any read from or write to a state or + * registered_readers field is performed, i.e. when calling functions: + * psa_key_slot_state_transition, psa_register_read, psa_unregister_read, + * psa_key_slot_has_readers and psa_wipe_key_slot. */ + mbedtls_threading_mutex_t MBEDTLS_PRIVATE(key_slot_mutex); +#endif } psa_global_data_t; static psa_global_data_t global_data; From 846889355c0863e4b16745c535e425b66050f4cc Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Mon, 8 Jan 2024 11:10:03 +0000 Subject: [PATCH 111/215] Initialize and free the key slot mutex Signed-off-by: Ryan Everett --- library/psa_crypto_slot_management.c | 17 ++++++++++++++++- library/psa_crypto_slot_management.h | 8 ++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 2d24e6deb..180aecb58 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -147,7 +147,14 @@ static psa_status_t psa_get_and_lock_key_slot_in_memory( psa_status_t psa_initialize_key_slots(void) { - /* Nothing to do: program startup and psa_wipe_all_key_slots() both +#if defined(MBEDTLS_THREADING_C) + /* Initialize the global key slot mutex. */ + if (!global_data.key_slots_initialized) { + mbedtls_mutex_init(&global_data.key_slot_mutex); + } +#endif + + /* Program startup and psa_wipe_all_key_slots() both * guarantee that the key slots are initialized to all-zero, which * means that all the key slots are in a valid, empty state. */ global_data.key_slots_initialized = 1; @@ -164,6 +171,14 @@ void psa_wipe_all_key_slots(void) slot->state = PSA_SLOT_PENDING_DELETION; (void) psa_wipe_key_slot(slot); } + +#if defined(MBEDTLS_THREADING_C) + /* Free the global key slot mutex. */ + if (global_data.key_slots_initialized) { + mbedtls_mutex_free(&global_data.key_slot_mutex); + } +#endif + global_data.key_slots_initialized = 0; } diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index 0b0d7b320..01778f899 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -85,6 +85,10 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, psa_key_slot_t **p_slot); /** Initialize the key slot structures. + * If multi-threading is enabled then initialize the key slot mutex. + * This function is not thread-safe, + * if called by competing threads the key slot mutex may be initialized + * more than once. * * \retval #PSA_SUCCESS * Currently this function always succeeds. @@ -92,6 +96,10 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, psa_status_t psa_initialize_key_slots(void); /** Delete all data from key slots in memory. + * If multi-threading is enabled then free the key slot mutex. + * This function is not thread-safe, + * if called by competing threads the key slot mutex may be freed + * more than once. * * This does not affect persistent storage. */ void psa_wipe_all_key_slots(void); From 0e3b677cf4600bec736020715f85909f4534c5dd Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Mon, 8 Jan 2024 11:11:39 +0000 Subject: [PATCH 112/215] Support PSA_ERROR_SERVICE_FAILURE To be returned in the case where mbedtls_mutex_lock and mbedtls_mutex_unlock fail. Signed-off-by: Ryan Everett --- include/psa/crypto_values.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index 8d30bf0fb..90d98fdb7 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -279,6 +279,11 @@ * to read from a resource. */ #define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143) +/** This can be returned if a function can no longer operate correctly. + * For example, if an essential initialization operation failed or + * a mutex operation failed. */ +#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t)-144) + /** The key identifier is not valid. See also :ref:\`key-handles\`. */ #define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136) From fb02d57de790dc4cc27b5f9a43c4433c13a5ed60 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Mon, 8 Jan 2024 11:13:03 +0000 Subject: [PATCH 113/215] Document the thread safety of the primitive key slot functions Signed-off-by: Ryan Everett --- library/psa_crypto_core.h | 4 ++++ library/psa_crypto_slot_management.h | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 1edd63e25..7b167248e 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -117,6 +117,8 @@ typedef struct { 0) /** Test whether a key slot has any registered readers. + * If multi-threading is enabled, the caller must hold the + * global key slot mutex. * * \param[in] slot The key slot to test. * @@ -195,6 +197,8 @@ static inline psa_key_slot_number_t psa_key_slot_get_slot_number( * * Persistent storage is not affected. * Sets the slot's state to PSA_SLOT_EMPTY. + * If multi-threading is enabled, the caller must hold the + * global key slot mutex. * * \param[in,out] slot The key slot to wipe. * diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index 01778f899..fc46257f2 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -134,6 +134,9 @@ psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id, * new state. If the state of the slot was not expected_state, the state is * unchanged. * + * If multi-threading is enabled, the caller must hold the + * global key slot mutex. + * * \param[in] slot The key slot. * \param[in] expected_state The current state of the slot. * \param[in] new_state The new state of the slot. @@ -157,7 +160,8 @@ static inline psa_status_t psa_key_slot_state_transition( /** Register as a reader of a key slot. * * This function increments the key slot registered reader counter by one. - * + * If multi-threading is enabled, the caller must hold the + * global key slot mutex. * \param[in] slot The key slot. * * \retval #PSA_SUCCESS @@ -182,7 +186,9 @@ static inline psa_status_t psa_register_read(psa_key_slot_t *slot) * This function decrements the key slot registered reader counter by one. * If the state of the slot is PSA_SLOT_PENDING_DELETION, * and there is only one registered reader (the caller), - * this function will call psa_wipe_key_slot(). + * this function will call psa_wipe_slot(). + * If multi-threading is enabled, the caller must hold the + * global key slot mutex. * * \note To ease the handling of errors in retrieving a key slot * a NULL input pointer is valid, and the function returns From d929106f361297a9a495545307f0e6183aa88b12 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 17 Jan 2024 09:48:06 +0100 Subject: [PATCH 114/215] ssl_ciphersuites: move internal functions declarations to a private header Signed-off-by: Valerio Setti --- include/mbedtls/ssl_ciphersuites.h | 139 ------------------------- library/ssl_ciphersuites_internal.h | 154 ++++++++++++++++++++++++++++ library/ssl_misc.h | 1 + 3 files changed, 155 insertions(+), 139 deletions(-) create mode 100644 library/ssl_ciphersuites_internal.h diff --git a/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h index 8cecbb625..f755ef304 100644 --- a/include/mbedtls/ssl_ciphersuites.h +++ b/include/mbedtls/ssl_ciphersuites.h @@ -463,18 +463,6 @@ const int *mbedtls_ssl_list_ciphersuites(void); const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string(const char *ciphersuite_name); const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id(int ciphersuite_id); -#if defined(MBEDTLS_PK_C) -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg(const mbedtls_ssl_ciphersuite_t *info); -#if defined(MBEDTLS_USE_PSA_CRYPTO) -psa_algorithm_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(const mbedtls_ssl_ciphersuite_t *info); -psa_key_usage_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(const mbedtls_ssl_ciphersuite_t *info); -#endif -mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg(const mbedtls_ssl_ciphersuite_t *info); -#endif - -int mbedtls_ssl_ciphersuite_uses_ec(const mbedtls_ssl_ciphersuite_t *info); -int mbedtls_ssl_ciphersuite_uses_psk(const mbedtls_ssl_ciphersuite_t *info); - static inline const char *mbedtls_ssl_ciphersuite_get_name(const mbedtls_ssl_ciphersuite_t *info) { return info->MBEDTLS_PRIVATE(name); @@ -482,133 +470,6 @@ static inline const char *mbedtls_ssl_ciphersuite_get_name(const mbedtls_ssl_cip size_t mbedtls_ssl_ciphersuite_get_cipher_key_bitlen(const mbedtls_ssl_ciphersuite_t *info); -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED) -static inline int mbedtls_ssl_ciphersuite_has_pfs(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECJPAKE: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED) -static inline int mbedtls_ssl_ciphersuite_no_pfs(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_PSK: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_ecdh(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */ - -static inline int mbedtls_ssl_ciphersuite_cert_req_allowed(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return 1; - - default: - return 0; - } -} - -static inline int mbedtls_ssl_ciphersuite_uses_srv_cert(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_RSA: - case MBEDTLS_KEY_EXCHANGE_RSA_PSK: - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return 1; - - default: - return 0; - } -} - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_dhe(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_DHE_PSK: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) */ - -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_ecdhe(const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) */ - -#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) -static inline int mbedtls_ssl_ciphersuite_uses_server_signature( - const mbedtls_ssl_ciphersuite_t *info) -{ - switch (info->MBEDTLS_PRIVATE(key_exchange)) { - case MBEDTLS_KEY_EXCHANGE_DHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: - case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: - return 1; - - default: - return 0; - } -} -#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ - #ifdef __cplusplus } #endif diff --git a/library/ssl_ciphersuites_internal.h b/library/ssl_ciphersuites_internal.h new file mode 100644 index 000000000..27ff72106 --- /dev/null +++ b/library/ssl_ciphersuites_internal.h @@ -0,0 +1,154 @@ +/** + * \file ssl_ciphersuites_internal.h + * + * \brief Internal part of the public "ssl_ciphersuites.h". + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H +#define MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H + +#include "mbedtls/pk.h" + +#if defined(MBEDTLS_PK_C) +mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg(const mbedtls_ssl_ciphersuite_t *info); +#if defined(MBEDTLS_USE_PSA_CRYPTO) +psa_algorithm_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(const mbedtls_ssl_ciphersuite_t *info); +psa_key_usage_t mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(const mbedtls_ssl_ciphersuite_t *info); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ +mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg(const mbedtls_ssl_ciphersuite_t *info); +#endif /* MBEDTLS_PK_C */ + +int mbedtls_ssl_ciphersuite_uses_ec(const mbedtls_ssl_ciphersuite_t *info); +int mbedtls_ssl_ciphersuite_uses_psk(const mbedtls_ssl_ciphersuite_t *info); + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED) +static inline int mbedtls_ssl_ciphersuite_has_pfs(const mbedtls_ssl_ciphersuite_t *info) +{ + switch (info->MBEDTLS_PRIVATE(key_exchange)) { + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_PSK: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECJPAKE: + return 1; + + default: + return 0; + } +} +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED) +static inline int mbedtls_ssl_ciphersuite_no_pfs(const mbedtls_ssl_ciphersuite_t *info) +{ + switch (info->MBEDTLS_PRIVATE(key_exchange)) { + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_PSK: + case MBEDTLS_KEY_EXCHANGE_RSA_PSK: + return 1; + + default: + return 0; + } +} +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_ecdh(const mbedtls_ssl_ciphersuite_t *info) +{ + switch (info->MBEDTLS_PRIVATE(key_exchange)) { + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + return 1; + + default: + return 0; + } +} +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */ + +static inline int mbedtls_ssl_ciphersuite_cert_req_allowed(const mbedtls_ssl_ciphersuite_t *info) +{ + switch (info->MBEDTLS_PRIVATE(key_exchange)) { + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + return 1; + + default: + return 0; + } +} + +static inline int mbedtls_ssl_ciphersuite_uses_srv_cert(const mbedtls_ssl_ciphersuite_t *info) +{ + switch (info->MBEDTLS_PRIVATE(key_exchange)) { + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_RSA_PSK: + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + return 1; + + default: + return 0; + } +} + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_dhe(const mbedtls_ssl_ciphersuite_t *info) +{ + switch (info->MBEDTLS_PRIVATE(key_exchange)) { + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_PSK: + return 1; + + default: + return 0; + } +} +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) */ + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_ecdhe(const mbedtls_ssl_ciphersuite_t *info) +{ + switch (info->MBEDTLS_PRIVATE(key_exchange)) { + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: + return 1; + + default: + return 0; + } +} +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) */ + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_server_signature( + const mbedtls_ssl_ciphersuite_t *info) +{ + switch (info->MBEDTLS_PRIVATE(key_exchange)) { + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + return 1; + + default: + return 0; + } +} +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ + +#endif /* MBEDTLS_SSL_CIPHERSUITES_INTERNAL_H */ diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 96afe7628..7cbc6af60 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -44,6 +44,7 @@ #endif #include "mbedtls/pk.h" +#include "ssl_ciphersuites_internal.h" #include "pk_internal.h" #include "common.h" From a184fd0516b5a059d9e9a0ab3912345385ff9b72 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Thu, 11 Jan 2024 10:05:00 +0000 Subject: [PATCH 115/215] programs/dh_client/server: Replaced mbedtls_sha1 with mbedtls_sha256 Signed-off-by: Minos Galanakis --- programs/pkey/dh_client.c | 16 ++++++++-------- programs/pkey/dh_server.c | 15 +++++++-------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c index 0cb156268..d8fc86fa0 100644 --- a/programs/pkey/dh_client.c +++ b/programs/pkey/dh_client.c @@ -14,8 +14,7 @@ #if defined(MBEDTLS_AES_C) && defined(MBEDTLS_DHM_C) && \ defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_NET_C) && \ defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA256) && \ - defined(MBEDTLS_FS_IO) && defined(MBEDTLS_CTR_DRBG_C) && \ - defined(MBEDTLS_MD_CAN_SHA1) + defined(MBEDTLS_FS_IO) && defined(MBEDTLS_CTR_DRBG_C) #include "mbedtls/net_sockets.h" #include "mbedtls/aes.h" #include "mbedtls/dhm.h" @@ -30,18 +29,19 @@ #define SERVER_NAME "localhost" #define SERVER_PORT "11999" +#define MBEDTLS_MD_CAN_SHA256_MAX_SIZE 32 #if !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_DHM_C) || \ !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NET_C) || \ !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_MD_CAN_SHA256) || \ - !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_CTR_DRBG_C) || \ - !defined(MBEDTLS_SHA1_C) + !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_CTR_DRBG_C) + int main(void) { mbedtls_printf("MBEDTLS_AES_C and/or MBEDTLS_DHM_C and/or MBEDTLS_ENTROPY_C " "and/or MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or " "MBEDTLS_MD_CAN_SHA256 and/or MBEDTLS_FS_IO and/or " - "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_SHA1_C not defined.\n"); + "MBEDTLS_CTR_DRBG_C not defined.\n"); mbedtls_exit(0); } @@ -65,7 +65,7 @@ int main(void) unsigned char *p, *end; unsigned char buf[2048]; - unsigned char hash[32]; + unsigned char hash[MBEDTLS_MD_CAN_SHA256_MAX_SIZE]; const char *pers = "dh_client"; mbedtls_entropy_context entropy; @@ -187,13 +187,13 @@ int main(void) goto exit; } - if ((ret = mbedtls_sha1(buf, (int) (p - 2 - buf), hash)) != 0) { + if ((ret = mbedtls_sha256(buf, (int) (p - 2 - buf), hash, 0)) != 0) { mbedtls_printf(" failed\n ! mbedtls_sha1 returned %d\n\n", ret); goto exit; } if ((ret = mbedtls_rsa_pkcs1_verify(&rsa, MBEDTLS_MD_SHA256, - 32, hash, p)) != 0) { + MBEDTLS_MD_CAN_SHA256_MAX_SIZE, hash, p)) != 0) { mbedtls_printf(" failed\n ! mbedtls_rsa_pkcs1_verify returned %d\n\n", ret); goto exit; } diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c index adddbf2fb..11c2b28c6 100644 --- a/programs/pkey/dh_server.c +++ b/programs/pkey/dh_server.c @@ -14,8 +14,7 @@ #if defined(MBEDTLS_AES_C) && defined(MBEDTLS_DHM_C) && \ defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_NET_C) && \ defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA256) && \ - defined(MBEDTLS_FS_IO) && defined(MBEDTLS_CTR_DRBG_C) && \ - defined(MBEDTLS_MD_CAN_SHA1) + defined(MBEDTLS_FS_IO) && defined(MBEDTLS_CTR_DRBG_C) #include "mbedtls/net_sockets.h" #include "mbedtls/aes.h" #include "mbedtls/dhm.h" @@ -30,18 +29,18 @@ #define SERVER_PORT "11999" #define PLAINTEXT "==Hello there!==" +#define MBEDTLS_MD_CAN_SHA256_MAX_SIZE 32 #if !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_DHM_C) || \ !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NET_C) || \ !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_MD_CAN_SHA256) || \ - !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_CTR_DRBG_C) || \ - !defined(MBEDTLS_SHA1_C) + !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_CTR_DRBG_C) int main(void) { mbedtls_printf("MBEDTLS_AES_C and/or MBEDTLS_DHM_C and/or MBEDTLS_ENTROPY_C " "and/or MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or " "MBEDTLS_MD_CAN_SHA256 and/or MBEDTLS_FS_IO and/or " - "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_SHA1_C not defined.\n"); + "MBEDTLS_CTR_DRBG_C not defined.\n"); mbedtls_exit(0); } #else @@ -57,7 +56,7 @@ int main(void) mbedtls_net_context listen_fd, client_fd; unsigned char buf[2048]; - unsigned char hash[32]; + unsigned char hash[MBEDTLS_MD_CAN_SHA256_MAX_SIZE]; unsigned char buf2[2]; const char *pers = "dh_server"; @@ -186,7 +185,7 @@ int main(void) /* * 5. Sign the parameters and send them */ - if ((ret = mbedtls_sha1(buf, n, hash)) != 0) { + if ((ret = mbedtls_sha256(buf, n, hash, 0)) != 0) { mbedtls_printf(" failed\n ! mbedtls_sha1 returned %d\n\n", ret); goto exit; } @@ -195,7 +194,7 @@ int main(void) buf[n + 1] = (unsigned char) (rsa.MBEDTLS_PRIVATE(len)); if ((ret = mbedtls_rsa_pkcs1_sign(&rsa, NULL, NULL, MBEDTLS_MD_SHA256, - 32, hash, buf + n + 2)) != 0) { + MBEDTLS_MD_CAN_SHA256_MAX_SIZE, hash, buf + n + 2)) != 0) { mbedtls_printf(" failed\n ! mbedtls_rsa_pkcs1_sign returned %d\n\n", ret); goto exit; } From f4dfd1c8a5282ea0a9d0641d2fd6dd0649a5c92f Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 12 Jan 2024 16:06:15 +0000 Subject: [PATCH 116/215] programs/dh_client/server: Added entropy source to `mbedtls_rsa_pkcs1_sign()` Signed-off-by: Minos Galanakis --- programs/pkey/dh_server.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c index 11c2b28c6..7d7618be1 100644 --- a/programs/pkey/dh_server.c +++ b/programs/pkey/dh_server.c @@ -193,8 +193,9 @@ int main(void) buf[n] = (unsigned char) (rsa.MBEDTLS_PRIVATE(len) >> 8); buf[n + 1] = (unsigned char) (rsa.MBEDTLS_PRIVATE(len)); - if ((ret = mbedtls_rsa_pkcs1_sign(&rsa, NULL, NULL, MBEDTLS_MD_SHA256, - MBEDTLS_MD_CAN_SHA256_MAX_SIZE, hash, buf + n + 2)) != 0) { + if ((ret = mbedtls_rsa_pkcs1_sign(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg, + MBEDTLS_MD_SHA256, MBEDTLS_MD_CAN_SHA256_MAX_SIZE, + hash, buf + n + 2)) != 0) { mbedtls_printf(" failed\n ! mbedtls_rsa_pkcs1_sign returned %d\n\n", ret); goto exit; } From b6a96195fb188d9e0e0bc4b4e2c70a78db116d03 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 12 Jan 2024 14:34:14 +0000 Subject: [PATCH 117/215] programs_dh_client/server: Updated programs to use `mbedtls_rsa_get_len()` Signed-off-by: Minos Galanakis --- programs/pkey/dh_client.c | 16 +++++++++------- programs/pkey/dh_server.c | 7 ++++--- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c index d8fc86fa0..774051c5d 100644 --- a/programs/pkey/dh_client.c +++ b/programs/pkey/dh_client.c @@ -66,6 +66,7 @@ int main(void) unsigned char *p, *end; unsigned char buf[2048]; unsigned char hash[MBEDTLS_MD_CAN_SHA256_MAX_SIZE]; + mbedtls_mpi N, E; const char *pers = "dh_client"; mbedtls_entropy_context entropy; @@ -78,6 +79,8 @@ int main(void) mbedtls_dhm_init(&dhm); mbedtls_aes_init(&aes); mbedtls_ctr_drbg_init(&ctr_drbg); + mbedtls_mpi_init(&N); + mbedtls_mpi_init(&E); /* * 1. Setup the RNG @@ -106,16 +109,13 @@ int main(void) } mbedtls_rsa_init(&rsa); - - if ((ret = mbedtls_mpi_read_file(&rsa.MBEDTLS_PRIVATE(N), 16, f)) != 0 || - (ret = mbedtls_mpi_read_file(&rsa.MBEDTLS_PRIVATE(E), 16, f)) != 0) { + if ((ret = mbedtls_mpi_read_file(&N, 16, f)) != 0 || + (ret = mbedtls_mpi_read_file(&E, 16, f)) != 0 || + (ret = mbedtls_rsa_import(&rsa, &N, NULL, NULL, NULL, &E) != 0)) { mbedtls_printf(" failed\n ! mbedtls_mpi_read_file returned %d\n\n", ret); fclose(f); goto exit; } - - rsa.MBEDTLS_PRIVATE(len) = (mbedtls_mpi_bitlen(&rsa.MBEDTLS_PRIVATE(N)) + 7) >> 3; - fclose(f); /* @@ -182,7 +182,7 @@ int main(void) p += 2; - if ((n = (size_t) (end - p)) != rsa.MBEDTLS_PRIVATE(len)) { + if ((n = (size_t) (end - p)) != mbedtls_rsa_get_len(&rsa)) { mbedtls_printf(" failed\n ! Invalid RSA signature size\n\n"); goto exit; } @@ -273,6 +273,8 @@ exit: mbedtls_dhm_free(&dhm); mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); + mbedtls_mpi_free(&N); + mbedtls_mpi_free(&E); mbedtls_exit(exit_code); } diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c index 7d7618be1..0c6cebc10 100644 --- a/programs/pkey/dh_server.c +++ b/programs/pkey/dh_server.c @@ -190,8 +190,9 @@ int main(void) goto exit; } - buf[n] = (unsigned char) (rsa.MBEDTLS_PRIVATE(len) >> 8); - buf[n + 1] = (unsigned char) (rsa.MBEDTLS_PRIVATE(len)); + const size_t rsa_key_len = mbedtls_rsa_get_len(&rsa); + buf[n] = (unsigned char) (rsa_key_len >> 8); + buf[n + 1] = (unsigned char) (rsa_key_len); if ((ret = mbedtls_rsa_pkcs1_sign(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_MD_SHA256, MBEDTLS_MD_CAN_SHA256_MAX_SIZE, @@ -200,7 +201,7 @@ int main(void) goto exit; } - buflen = n + 2 + rsa.MBEDTLS_PRIVATE(len); + buflen = n + 2 + rsa_key_len; buf2[0] = (unsigned char) (buflen >> 8); buf2[1] = (unsigned char) (buflen); From ee757d35dfaf370792408b7232d31783e9f94653 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 12 Jan 2024 15:06:20 +0000 Subject: [PATCH 118/215] programs_rsa_encrypt/decrypt: Updated programs to use `mbedtls_rsa_get_len()` Signed-off-by: Minos Galanakis --- programs/pkey/rsa_decrypt.c | 2 +- programs/pkey/rsa_encrypt.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/pkey/rsa_decrypt.c b/programs/pkey/rsa_decrypt.c index 76bfddf5c..a84af50d7 100644 --- a/programs/pkey/rsa_decrypt.c +++ b/programs/pkey/rsa_decrypt.c @@ -133,7 +133,7 @@ int main(int argc, char *argv[]) fclose(f); - if (i != rsa.MBEDTLS_PRIVATE(len)) { + if (i != mbedtls_rsa_get_len(&rsa)) { mbedtls_printf("\n ! Invalid RSA signature format\n\n"); goto exit; } diff --git a/programs/pkey/rsa_encrypt.c b/programs/pkey/rsa_encrypt.c index 4bbb54e7d..6538f8a99 100644 --- a/programs/pkey/rsa_encrypt.c +++ b/programs/pkey/rsa_encrypt.c @@ -126,7 +126,7 @@ int main(int argc, char *argv[]) goto exit; } - for (i = 0; i < rsa.MBEDTLS_PRIVATE(len); i++) { + for (i = 0; i < mbedtls_rsa_get_len(&rsa); i++) { mbedtls_fprintf(f, "%02X%s", buf[i], (i + 1) % 16 == 0 ? "\r\n" : " "); } From 992f0b8427d88dd3dd6e232406cc8271c3b32407 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 12 Jan 2024 15:07:24 +0000 Subject: [PATCH 119/215] programs_rsa_rsa_sign: Updated program to use `mbedtls_rsa_get_len()` Signed-off-by: Minos Galanakis --- programs/pkey/rsa_sign.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/pkey/rsa_sign.c b/programs/pkey/rsa_sign.c index 9d8ebe39a..e14953bc3 100644 --- a/programs/pkey/rsa_sign.c +++ b/programs/pkey/rsa_sign.c @@ -131,7 +131,7 @@ int main(int argc, char *argv[]) goto exit; } - for (i = 0; i < rsa.MBEDTLS_PRIVATE(len); i++) { + for (i = 0; i < mbedtls_rsa_get_len(&rsa); i++) { mbedtls_fprintf(f, "%02X%s", buf[i], (i + 1) % 16 == 0 ? "\r\n" : " "); } From 6e92df12c272a6a8ba328e1de1f5290442345989 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 12 Jan 2024 15:13:47 +0000 Subject: [PATCH 120/215] programs_rsa_rsa_verify: Updated program to use `mbedtls_rsa_get_len()` Signed-off-by: Minos Galanakis --- programs/pkey/rsa_verify.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/programs/pkey/rsa_verify.c b/programs/pkey/rsa_verify.c index e7d72fd52..4a9af77fa 100644 --- a/programs/pkey/rsa_verify.c +++ b/programs/pkey/rsa_verify.c @@ -37,11 +37,14 @@ int main(int argc, char *argv[]) int exit_code = MBEDTLS_EXIT_FAILURE; size_t i; mbedtls_rsa_context rsa; + mbedtls_mpi N, E; unsigned char hash[32]; unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; char filename[512]; mbedtls_rsa_init(&rsa); + mbedtls_mpi_init(&N); + mbedtls_mpi_init(&E); if (argc != 2) { mbedtls_printf("usage: rsa_verify \n"); @@ -62,15 +65,13 @@ int main(int argc, char *argv[]) goto exit; } - if ((ret = mbedtls_mpi_read_file(&rsa.MBEDTLS_PRIVATE(N), 16, f)) != 0 || - (ret = mbedtls_mpi_read_file(&rsa.MBEDTLS_PRIVATE(E), 16, f)) != 0) { + if ((ret = mbedtls_mpi_read_file(&N, 16, f)) != 0 || + (ret = mbedtls_mpi_read_file(&E, 16, f)) != 0 || + (ret = mbedtls_rsa_import(&rsa, &N, NULL, NULL, NULL, &E) != 0)) { mbedtls_printf(" failed\n ! mbedtls_mpi_read_file returned %d\n\n", ret); fclose(f); goto exit; } - - rsa.MBEDTLS_PRIVATE(len) = (mbedtls_mpi_bitlen(&rsa.MBEDTLS_PRIVATE(N)) + 7) >> 3; - fclose(f); /* @@ -91,7 +92,7 @@ int main(int argc, char *argv[]) fclose(f); - if (i != rsa.MBEDTLS_PRIVATE(len)) { + if (i != mbedtls_rsa_get_len(&rsa)) { mbedtls_printf("\n ! Invalid RSA signature format\n\n"); goto exit; } @@ -124,6 +125,8 @@ int main(int argc, char *argv[]) exit: mbedtls_rsa_free(&rsa); + mbedtls_mpi_free(&N); + mbedtls_mpi_free(&E); mbedtls_exit(exit_code); } From 7c8448842dd461e69290c794e70662ab2e25c5f3 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Mon, 15 Jan 2024 17:03:58 +0000 Subject: [PATCH 121/215] programs_dh_client/server: Updated to query digest size using `mbedtls_md_info_from_type()`. Signed-off-by: Minos Galanakis --- programs/pkey/dh_client.c | 13 +++++++++---- programs/pkey/dh_server.c | 14 ++++++++++---- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c index 774051c5d..1b5ba407e 100644 --- a/programs/pkey/dh_client.c +++ b/programs/pkey/dh_client.c @@ -29,7 +29,6 @@ #define SERVER_NAME "localhost" #define SERVER_PORT "11999" -#define MBEDTLS_MD_CAN_SHA256_MAX_SIZE 32 #if !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_DHM_C) || \ !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NET_C) || \ @@ -60,12 +59,12 @@ int main(void) int ret = 1; int exit_code = MBEDTLS_EXIT_FAILURE; - size_t n, buflen; + size_t n, buflen, mdlen; mbedtls_net_context server_fd; unsigned char *p, *end; unsigned char buf[2048]; - unsigned char hash[MBEDTLS_MD_CAN_SHA256_MAX_SIZE]; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; mbedtls_mpi N, E; const char *pers = "dh_client"; @@ -187,13 +186,19 @@ int main(void) goto exit; } + mdlen = mbedtls_md_get_size(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256)); + if (mdlen == 0) { + mbedtls_printf(" failed\n ! Invalid digest type\n\n"); + goto exit; + } + if ((ret = mbedtls_sha256(buf, (int) (p - 2 - buf), hash, 0)) != 0) { mbedtls_printf(" failed\n ! mbedtls_sha1 returned %d\n\n", ret); goto exit; } if ((ret = mbedtls_rsa_pkcs1_verify(&rsa, MBEDTLS_MD_SHA256, - MBEDTLS_MD_CAN_SHA256_MAX_SIZE, hash, p)) != 0) { + mdlen, hash, p)) != 0) { mbedtls_printf(" failed\n ! mbedtls_rsa_pkcs1_verify returned %d\n\n", ret); goto exit; } diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c index 0c6cebc10..11c28fb51 100644 --- a/programs/pkey/dh_server.c +++ b/programs/pkey/dh_server.c @@ -29,7 +29,6 @@ #define SERVER_PORT "11999" #define PLAINTEXT "==Hello there!==" -#define MBEDTLS_MD_CAN_SHA256_MAX_SIZE 32 #if !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_DHM_C) || \ !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NET_C) || \ @@ -52,11 +51,11 @@ int main(void) int ret = 1; int exit_code = MBEDTLS_EXIT_FAILURE; - size_t n, buflen; + size_t n, buflen, mdlen; mbedtls_net_context listen_fd, client_fd; unsigned char buf[2048]; - unsigned char hash[MBEDTLS_MD_CAN_SHA256_MAX_SIZE]; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; unsigned char buf2[2]; const char *pers = "dh_server"; @@ -185,6 +184,13 @@ int main(void) /* * 5. Sign the parameters and send them */ + + mdlen = mbedtls_md_get_size(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256)); + if (mdlen == 0) { + mbedtls_printf(" failed\n ! Invalid digest type\n\n"); + goto exit; + } + if ((ret = mbedtls_sha256(buf, n, hash, 0)) != 0) { mbedtls_printf(" failed\n ! mbedtls_sha1 returned %d\n\n", ret); goto exit; @@ -195,7 +201,7 @@ int main(void) buf[n + 1] = (unsigned char) (rsa_key_len); if ((ret = mbedtls_rsa_pkcs1_sign(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg, - MBEDTLS_MD_SHA256, MBEDTLS_MD_CAN_SHA256_MAX_SIZE, + MBEDTLS_MD_SHA256, mdlen, hash, buf + n + 2)) != 0) { mbedtls_printf(" failed\n ! mbedtls_rsa_pkcs1_sign returned %d\n\n", ret); goto exit; From b4f5076270c4636934aa1114d08ba19eca9b673d Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 17 Jan 2024 10:24:52 +0100 Subject: [PATCH 122/215] debug: move internal functions declarations to an internal header file Signed-off-by: Valerio Setti --- include/mbedtls/debug.h | 159 +---------------------- library/debug.c | 2 +- library/debug_internal.h | 172 +++++++++++++++++++++++++ library/ssl_client.c | 2 +- library/ssl_msg.c | 2 +- library/ssl_tls.c | 2 +- library/ssl_tls12_client.c | 2 +- library/ssl_tls12_server.c | 2 +- library/ssl_tls13_client.c | 2 +- library/ssl_tls13_generic.c | 2 +- library/ssl_tls13_keys.c | 2 +- library/ssl_tls13_server.c | 2 +- tests/suites/test_suite_debug.function | 2 +- 13 files changed, 184 insertions(+), 169 deletions(-) create mode 100644 library/debug_internal.h diff --git a/include/mbedtls/debug.h b/include/mbedtls/debug.h index 922e5bec5..424ed4b3f 100644 --- a/include/mbedtls/debug.h +++ b/include/mbedtls/debug.h @@ -149,165 +149,8 @@ extern "C" { */ void mbedtls_debug_set_threshold(int threshold); -/** - * \brief Print a message to the debug output. This function is always used - * through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl - * context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the message has occurred in - * \param line line number the message has occurred at - * \param format format specifier, in printf format - * \param ... variables used by the format specifier - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(5, 6); - -/** - * \brief Print the return value of a function to the debug output. This - * function is always used through the MBEDTLS_SSL_DEBUG_RET() macro, - * which supplies the ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text the name of the function that returned the error - * \param ret the return code value - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, int ret); - -/** - * \brief Output a buffer of size len bytes to the debug output. This function - * is always used through the MBEDTLS_SSL_DEBUG_BUF() macro, - * which supplies the ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text a name or label for the buffer being dumped. Normally the - * variable or buffer name - * \param buf the buffer to be outputted - * \param len length of the buffer - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, const char *text, - const unsigned char *buf, size_t len); - -#if defined(MBEDTLS_BIGNUM_C) -/** - * \brief Print a MPI variable to the debug output. This function is always - * used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the - * ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text a name or label for the MPI being output. Normally the - * variable name - * \param X the MPI variable - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_mpi *X); -#endif - -#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 - * ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text a name or label for the ECP point being output. Normally the - * variable name - * \param X the ECP point - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_ecp_point *X); -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO) -/** - * \brief Print a X.509 certificate structure to the debug output. This - * function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro, - * which supplies the ssl context, file and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param text a name or label for the certificate being output - * \param crt X.509 certificate structure - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const char *text, const mbedtls_x509_crt *crt); -#endif - -/* Note: the MBEDTLS_ECDH_C guard here is mandatory because this debug function - only works for the built-in implementation. */ -#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) && \ - defined(MBEDTLS_ECDH_C) -typedef enum { - MBEDTLS_DEBUG_ECDH_Q, - MBEDTLS_DEBUG_ECDH_QP, - MBEDTLS_DEBUG_ECDH_Z, -} mbedtls_debug_ecdh_attr; - -/** - * \brief Print a field of the ECDH structure in the SSL context to the debug - * output. This function is always used through the - * MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file - * and line number parameters. - * - * \param ssl SSL context - * \param level error level of the debug message - * \param file file the error has occurred in - * \param line line number the error has occurred in - * \param ecdh the ECDH context - * \param attr the identifier of the attribute being output - * - * \attention This function is intended for INTERNAL usage within the - * library only. - */ -void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level, - const char *file, int line, - const mbedtls_ecdh_context *ecdh, - mbedtls_debug_ecdh_attr attr); -#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED && - MBEDTLS_ECDH_C */ - #ifdef __cplusplus } #endif -#endif /* debug.h */ +#endif /* MBEDTLS_DEBUG_H */ diff --git a/library/debug.c b/library/debug.c index a9d58e55b..c36ed3c5c 100644 --- a/library/debug.c +++ b/library/debug.c @@ -11,7 +11,7 @@ #include "mbedtls/platform.h" -#include "mbedtls/debug.h" +#include "debug_internal.h" #include "mbedtls/error.h" #include diff --git a/library/debug_internal.h b/library/debug_internal.h new file mode 100644 index 000000000..4523b4633 --- /dev/null +++ b/library/debug_internal.h @@ -0,0 +1,172 @@ +/** + * \file debug_internal.h + * + * \brief Internal part of the public "debug.h". + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_DEBUG_INTERNAL_H +#define MBEDTLS_DEBUG_INTERNAL_H + +#include "mbedtls/debug.h" + +/** + * \brief Print a message to the debug output. This function is always used + * through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl + * context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the message has occurred in + * \param line line number the message has occurred at + * \param format format specifier, in printf format + * \param ... variables used by the format specifier + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(5, 6); + +/** + * \brief Print the return value of a function to the debug output. This + * function is always used through the MBEDTLS_SSL_DEBUG_RET() macro, + * which supplies the ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text the name of the function that returned the error + * \param ret the return code value + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, int ret); + +/** + * \brief Output a buffer of size len bytes to the debug output. This function + * is always used through the MBEDTLS_SSL_DEBUG_BUF() macro, + * which supplies the ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text a name or label for the buffer being dumped. Normally the + * variable or buffer name + * \param buf the buffer to be outputted + * \param len length of the buffer + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, const char *text, + const unsigned char *buf, size_t len); + +#if defined(MBEDTLS_BIGNUM_C) +/** + * \brief Print a MPI variable to the debug output. This function is always + * used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the + * ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text a name or label for the MPI being output. Normally the + * variable name + * \param X the MPI variable + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_mpi *X); +#endif + +#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 + * ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text a name or label for the ECP point being output. Normally the + * variable name + * \param X the ECP point + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_ecp_point *X); +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO) +/** + * \brief Print a X.509 certificate structure to the debug output. This + * function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro, + * which supplies the ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text a name or label for the certificate being output + * \param crt X.509 certificate structure + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_x509_crt *crt); +#endif + +/* Note: the MBEDTLS_ECDH_C guard here is mandatory because this debug function + only works for the built-in implementation. */ +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) && \ + defined(MBEDTLS_ECDH_C) +typedef enum { + MBEDTLS_DEBUG_ECDH_Q, + MBEDTLS_DEBUG_ECDH_QP, + MBEDTLS_DEBUG_ECDH_Z, +} mbedtls_debug_ecdh_attr; + +/** + * \brief Print a field of the ECDH structure in the SSL context to the debug + * output. This function is always used through the + * MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file + * and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param ecdh the ECDH context + * \param attr the identifier of the attribute being output + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const mbedtls_ecdh_context *ecdh, + mbedtls_debug_ecdh_attr attr); +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED && + MBEDTLS_ECDH_C */ + +#endif /* MBEDTLS_DEBUG_INTERNAL_H */ diff --git a/library/ssl_client.c b/library/ssl_client.c index d585ca524..6d988a837 100644 --- a/library/ssl_client.c +++ b/library/ssl_client.c @@ -12,7 +12,7 @@ #include -#include "mbedtls/debug.h" +#include "debug_internal.h" #include "mbedtls/error.h" #include "mbedtls/platform.h" diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 6579c9686..5753cf9f0 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -18,7 +18,7 @@ #include "mbedtls/ssl.h" #include "ssl_misc.h" -#include "mbedtls/debug.h" +#include "debug_internal.h" #include "mbedtls/error.h" #include "mbedtls/platform_util.h" #include "mbedtls/version.h" diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 8c1e37251..bd1380aa7 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -20,7 +20,7 @@ #include "ssl_debug_helpers.h" #include "ssl_misc.h" -#include "mbedtls/debug.h" +#include "debug_internal.h" #include "mbedtls/error.h" #include "mbedtls/platform_util.h" #include "mbedtls/version.h" diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index 0c5af87f4..c3a803706 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -14,7 +14,7 @@ #include "mbedtls/ssl.h" #include "ssl_client.h" #include "ssl_misc.h" -#include "mbedtls/debug.h" +#include "debug_internal.h" #include "mbedtls/error.h" #include "mbedtls/constant_time.h" diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 5a9f6ca4e..f242faa1e 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -13,7 +13,7 @@ #include "mbedtls/ssl.h" #include "ssl_misc.h" -#include "mbedtls/debug.h" +#include "debug_internal.h" #include "mbedtls/error.h" #include "mbedtls/platform_util.h" #include "constant_time_internal.h" diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 5c668bdf2..86dd0ec59 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -11,7 +11,7 @@ #include -#include "mbedtls/debug.h" +#include "debug_internal.h" #include "mbedtls/error.h" #include "mbedtls/platform.h" diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index 47fa65c18..202631fe6 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -12,7 +12,7 @@ #include #include "mbedtls/error.h" -#include "mbedtls/debug.h" +#include "debug_internal.h" #include "mbedtls/oid.h" #include "mbedtls/platform.h" #include "mbedtls/constant_time.h" diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c index 9b775ec95..d79e70c0e 100644 --- a/library/ssl_tls13_keys.c +++ b/library/ssl_tls13_keys.c @@ -13,7 +13,7 @@ #include #include "mbedtls/hkdf.h" -#include "mbedtls/debug.h" +#include "debug_internal.h" #include "mbedtls/error.h" #include "mbedtls/platform.h" diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 6e2866a11..29c9f6c6b 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -9,7 +9,7 @@ #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3) -#include "mbedtls/debug.h" +#include "debug_internal.h" #include "mbedtls/error.h" #include "mbedtls/platform.h" #include "mbedtls/constant_time.h" diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function index b9610406b..eeefc9597 100644 --- a/tests/suites/test_suite_debug.function +++ b/tests/suites/test_suite_debug.function @@ -1,5 +1,5 @@ /* BEGIN_HEADER */ -#include "mbedtls/debug.h" +#include "debug_internal.h" #include "string.h" #include "mbedtls/pk.h" From 25b282ebfe5cb84e73d6194e83dc8d6c5d9a25e4 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 17 Jan 2024 10:55:32 +0100 Subject: [PATCH 123/215] x509: move internal functions declarations to a private header Signed-off-by: Valerio Setti --- include/mbedtls/pkcs7.h | 1 - include/mbedtls/x509.h | 197 +------------------ library/pkcs7.c | 2 +- library/ssl_misc.h | 1 + library/x509.c | 2 +- library/x509_create.c | 2 +- library/x509_crl.c | 1 + library/x509_crt.c | 1 + library/x509_csr.c | 1 + library/x509_internal.h | 213 +++++++++++++++++++++ library/x509write.c | 1 + library/x509write_crt.c | 1 + library/x509write_csr.c | 2 +- tests/suites/test_suite_pkcs7.function | 1 + tests/suites/test_suite_x509parse.function | 1 + tests/suites/test_suite_x509write.function | 1 + 16 files changed, 228 insertions(+), 200 deletions(-) create mode 100644 library/x509_internal.h diff --git a/include/mbedtls/pkcs7.h b/include/mbedtls/pkcs7.h index 70b25a9c6..e9b482208 100644 --- a/include/mbedtls/pkcs7.h +++ b/include/mbedtls/pkcs7.h @@ -41,7 +41,6 @@ #include "mbedtls/build_info.h" #include "mbedtls/asn1.h" -#include "mbedtls/x509.h" #include "mbedtls/x509_crt.h" /** diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h index e2e06679b..be6361285 100644 --- a/include/mbedtls/x509.h +++ b/include/mbedtls/x509.h @@ -307,6 +307,7 @@ typedef struct mbedtls_x509_san_list { mbedtls_x509_san_list; /** \} name Structures for parsing X.509 certificates, CRLs and CSRs */ +/** \} addtogroup x509_module */ /** * \brief Store the certificate DN in printable form into buf; @@ -321,201 +322,7 @@ mbedtls_x509_san_list; */ int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn); -/** - * \brief Return the next relative DN in an X509 name. - * - * \note Intended use is to compare function result to dn->next - * in order to detect boundaries of multi-valued RDNs. - * - * \param dn Current node in the X509 name - * - * \return Pointer to the first attribute-value pair of the - * next RDN in sequence, or NULL if end is reached. - */ -static inline mbedtls_x509_name *mbedtls_x509_dn_get_next( - mbedtls_x509_name *dn) -{ - while (dn->MBEDTLS_PRIVATE(next_merged) && dn->next != NULL) { - dn = dn->next; - } - return dn->next; -} - -/** - * \brief Store the certificate serial in printable form into buf; - * no more than size characters will be written. - * - * \param buf Buffer to write to - * \param size Maximum size of buffer - * \param serial The X509 serial to represent - * - * \return The length of the string written (not including the - * terminated nul byte), or a negative error code. - */ -int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial); - -/** - * \brief Compare pair of mbedtls_x509_time. - * - * \param t1 mbedtls_x509_time to compare - * \param t2 mbedtls_x509_time to compare - * - * \return < 0 if t1 is before t2 - * 0 if t1 equals t2 - * > 0 if t1 is after t2 - */ -int mbedtls_x509_time_cmp(const mbedtls_x509_time *t1, const mbedtls_x509_time *t2); - -#if defined(MBEDTLS_HAVE_TIME_DATE) -/** - * \brief Fill mbedtls_x509_time with provided mbedtls_time_t. - * - * \param tt mbedtls_time_t to convert - * \param now mbedtls_x509_time to fill with converted mbedtls_time_t - * - * \return \c 0 on success - * \return A non-zero return value on failure. - */ -int mbedtls_x509_time_gmtime(mbedtls_time_t tt, mbedtls_x509_time *now); -#endif /* MBEDTLS_HAVE_TIME_DATE */ - -/** - * \brief Check a given mbedtls_x509_time against the system time - * and tell if it's in the past. - * - * \note Intended usage is "if( is_past( valid_to ) ) ERROR". - * Hence the return value of 1 if on internal errors. - * - * \param to mbedtls_x509_time to check - * - * \return 1 if the given time is in the past or an error occurred, - * 0 otherwise. - */ -int mbedtls_x509_time_is_past(const mbedtls_x509_time *to); - -/** - * \brief Check a given mbedtls_x509_time against the system time - * and tell if it's in the future. - * - * \note Intended usage is "if( is_future( valid_from ) ) ERROR". - * Hence the return value of 1 if on internal errors. - * - * \param from mbedtls_x509_time to check - * - * \return 1 if the given time is in the future or an error occurred, - * 0 otherwise. - */ -int mbedtls_x509_time_is_future(const mbedtls_x509_time *from); - -/** - * \brief This function parses an item in the SubjectAlternativeNames - * extension. Please note that this function might allocate - * additional memory for a subject alternative name, thus - * mbedtls_x509_free_subject_alt_name has to be called - * to dispose of this additional memory afterwards. - * - * \param san_buf The buffer holding the raw data item of the subject - * alternative name. - * \param san The target structure to populate with the parsed presentation - * of the subject alternative name encoded in \p san_buf. - * - * \note Supported GeneralName types, as defined in RFC 5280: - * "rfc822Name", "dnsName", "directoryName", - * "uniformResourceIdentifier" and "hardware_module_name" - * of type "otherName", as defined in RFC 4108. - * - * \note This function should be called on a single raw data of - * subject alternative name. For example, after successful - * certificate parsing, one must iterate on every item in the - * \c crt->subject_alt_names sequence, and pass it to - * this function. - * - * \warning The target structure contains pointers to the raw data of the - * parsed certificate, and its lifetime is restricted by the - * lifetime of the certificate. - * - * \return \c 0 on success - * \return #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported - * SAN type. - * \return Another negative value for any other failure. - */ -int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf, - mbedtls_x509_subject_alternative_name *san); -/** - * \brief Unallocate all data related to subject alternative name - * - * \param san SAN structure - extra memory owned by this structure will be freed - */ -void mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name *san); - -/** \} addtogroup x509_module */ - -/* - * Internal module functions. You probably do not want to use these unless you - * know you do. - */ -int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end, - mbedtls_x509_name *cur); -int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg); -int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg, mbedtls_x509_buf *params); -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) -int mbedtls_x509_get_rsassa_pss_params(const mbedtls_x509_buf *params, - mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, - int *salt_len); -#endif -int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig); -int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, - mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, - void **sig_opts); -int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end, - mbedtls_x509_time *t); -int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *serial); -int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *ext, int tag); -#if !defined(MBEDTLS_X509_REMOVE_INFO) -int mbedtls_x509_sig_alg_gets(char *buf, size_t size, const mbedtls_x509_buf *sig_oid, - mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, - const void *sig_opts); -#endif -int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name); int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *name); -int mbedtls_x509_set_extension(mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, - int critical, const unsigned char *val, - size_t val_len); -int mbedtls_x509_write_extensions(unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first); -int mbedtls_x509_write_names(unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first); -int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len, - unsigned char *sig, size_t size, - mbedtls_pk_type_t pk_alg); -int mbedtls_x509_get_ns_cert_type(unsigned char **p, - const unsigned char *end, - unsigned char *ns_cert_type); -int mbedtls_x509_get_key_usage(unsigned char **p, - const unsigned char *end, - unsigned int *key_usage); -int mbedtls_x509_get_subject_alt_name(unsigned char **p, - const unsigned char *end, - mbedtls_x509_sequence *subject_alt_name); -int mbedtls_x509_get_subject_alt_name_ext(unsigned char **p, - const unsigned char *end, - mbedtls_x509_sequence *subject_alt_name); -int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size, - const mbedtls_x509_sequence - *subject_alt_name, - const char *prefix); -int mbedtls_x509_info_cert_type(char **buf, size_t *size, - unsigned char ns_cert_type); -int mbedtls_x509_info_key_usage(char **buf, size_t *size, - unsigned int key_usage); - -int mbedtls_x509_write_set_san_common(mbedtls_asn1_named_data **extensions, - const mbedtls_x509_san_list *san_list); /** * \brief This function parses a CN string as an IP address. @@ -547,4 +354,4 @@ size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst); } #endif -#endif /* x509.h */ +#endif /* MBEDTLS_X509_H */ diff --git a/library/pkcs7.c b/library/pkcs7.c index 0869c2e07..3aac662ba 100644 --- a/library/pkcs7.c +++ b/library/pkcs7.c @@ -7,7 +7,7 @@ #include "mbedtls/build_info.h" #if defined(MBEDTLS_PKCS7_C) #include "mbedtls/pkcs7.h" -#include "mbedtls/x509.h" +#include "x509_internal.h" #include "mbedtls/asn1.h" #include "mbedtls/x509_crt.h" #include "mbedtls/x509_crl.h" diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 7cbc6af60..101b2046e 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -45,6 +45,7 @@ #include "mbedtls/pk.h" #include "ssl_ciphersuites_internal.h" +#include "x509_internal.h" #include "pk_internal.h" #include "common.h" diff --git a/library/x509.c b/library/x509.c index b7b71f33c..f97fb4458 100644 --- a/library/x509.c +++ b/library/x509.c @@ -19,7 +19,7 @@ #if defined(MBEDTLS_X509_USE_C) -#include "mbedtls/x509.h" +#include "x509_internal.h" #include "mbedtls/asn1.h" #include "mbedtls/error.h" #include "mbedtls/oid.h" diff --git a/library/x509_create.c b/library/x509_create.c index f7a17e712..839b5df22 100644 --- a/library/x509_create.c +++ b/library/x509_create.c @@ -9,7 +9,7 @@ #if defined(MBEDTLS_X509_CREATE_C) -#include "mbedtls/x509.h" +#include "x509_internal.h" #include "mbedtls/asn1write.h" #include "mbedtls/error.h" #include "mbedtls/oid.h" diff --git a/library/x509_crl.c b/library/x509_crl.c index fdbad238a..7901992e2 100644 --- a/library/x509_crl.c +++ b/library/x509_crl.c @@ -20,6 +20,7 @@ #if defined(MBEDTLS_X509_CRL_PARSE_C) #include "mbedtls/x509_crl.h" +#include "x509_internal.h" #include "mbedtls/error.h" #include "mbedtls/oid.h" #include "mbedtls/platform_util.h" diff --git a/library/x509_crt.c b/library/x509_crt.c index 4e7672e37..730f6ef99 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -22,6 +22,7 @@ #if defined(MBEDTLS_X509_CRT_PARSE_C) #include "mbedtls/x509_crt.h" +#include "x509_internal.h" #include "mbedtls/error.h" #include "mbedtls/oid.h" #include "mbedtls/platform_util.h" diff --git a/library/x509_csr.c b/library/x509_csr.c index 79b158964..813d64466 100644 --- a/library/x509_csr.c +++ b/library/x509_csr.c @@ -20,6 +20,7 @@ #if defined(MBEDTLS_X509_CSR_PARSE_C) #include "mbedtls/x509_csr.h" +#include "x509_internal.h" #include "mbedtls/error.h" #include "mbedtls/oid.h" #include "mbedtls/platform_util.h" diff --git a/library/x509_internal.h b/library/x509_internal.h new file mode 100644 index 000000000..e1be393b4 --- /dev/null +++ b/library/x509_internal.h @@ -0,0 +1,213 @@ +/** + * \file x509.h + * + * \brief Internal part of the public "x509.h". + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_X509_INTERNAL_H +#define MBEDTLS_X509_INTERNAL_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include "mbedtls/x509.h" +#include "mbedtls/asn1.h" +#include "mbedtls/pk.h" + +#if defined(MBEDTLS_RSA_C) +#include "mbedtls/rsa.h" +#endif + +/** + * \brief Return the next relative DN in an X509 name. + * + * \note Intended use is to compare function result to dn->next + * in order to detect boundaries of multi-valued RDNs. + * + * \param dn Current node in the X509 name + * + * \return Pointer to the first attribute-value pair of the + * next RDN in sequence, or NULL if end is reached. + */ +static inline mbedtls_x509_name *mbedtls_x509_dn_get_next( + mbedtls_x509_name *dn) +{ + while (dn->MBEDTLS_PRIVATE(next_merged) && dn->next != NULL) { + dn = dn->next; + } + return dn->next; +} + +/** + * \brief Store the certificate serial in printable form into buf; + * no more than size characters will be written. + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param serial The X509 serial to represent + * + * \return The length of the string written (not including the + * terminated nul byte), or a negative error code. + */ +int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial); + +/** + * \brief Compare pair of mbedtls_x509_time. + * + * \param t1 mbedtls_x509_time to compare + * \param t2 mbedtls_x509_time to compare + * + * \return < 0 if t1 is before t2 + * 0 if t1 equals t2 + * > 0 if t1 is after t2 + */ +int mbedtls_x509_time_cmp(const mbedtls_x509_time *t1, const mbedtls_x509_time *t2); + +#if defined(MBEDTLS_HAVE_TIME_DATE) +/** + * \brief Fill mbedtls_x509_time with provided mbedtls_time_t. + * + * \param tt mbedtls_time_t to convert + * \param now mbedtls_x509_time to fill with converted mbedtls_time_t + * + * \return \c 0 on success + * \return A non-zero return value on failure. + */ +int mbedtls_x509_time_gmtime(mbedtls_time_t tt, mbedtls_x509_time *now); +#endif /* MBEDTLS_HAVE_TIME_DATE */ + +/** + * \brief Check a given mbedtls_x509_time against the system time + * and tell if it's in the past. + * + * \note Intended usage is "if( is_past( valid_to ) ) ERROR". + * Hence the return value of 1 if on internal errors. + * + * \param to mbedtls_x509_time to check + * + * \return 1 if the given time is in the past or an error occurred, + * 0 otherwise. + */ +int mbedtls_x509_time_is_past(const mbedtls_x509_time *to); + +/** + * \brief Check a given mbedtls_x509_time against the system time + * and tell if it's in the future. + * + * \note Intended usage is "if( is_future( valid_from ) ) ERROR". + * Hence the return value of 1 if on internal errors. + * + * \param from mbedtls_x509_time to check + * + * \return 1 if the given time is in the future or an error occurred, + * 0 otherwise. + */ +int mbedtls_x509_time_is_future(const mbedtls_x509_time *from); + +/** + * \brief This function parses an item in the SubjectAlternativeNames + * extension. Please note that this function might allocate + * additional memory for a subject alternative name, thus + * mbedtls_x509_free_subject_alt_name has to be called + * to dispose of this additional memory afterwards. + * + * \param san_buf The buffer holding the raw data item of the subject + * alternative name. + * \param san The target structure to populate with the parsed presentation + * of the subject alternative name encoded in \p san_buf. + * + * \note Supported GeneralName types, as defined in RFC 5280: + * "rfc822Name", "dnsName", "directoryName", + * "uniformResourceIdentifier" and "hardware_module_name" + * of type "otherName", as defined in RFC 4108. + * + * \note This function should be called on a single raw data of + * subject alternative name. For example, after successful + * certificate parsing, one must iterate on every item in the + * \c crt->subject_alt_names sequence, and pass it to + * this function. + * + * \warning The target structure contains pointers to the raw data of the + * parsed certificate, and its lifetime is restricted by the + * lifetime of the certificate. + * + * \return \c 0 on success + * \return #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported + * SAN type. + * \return Another negative value for any other failure. + */ +int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf, + mbedtls_x509_subject_alternative_name *san); +/** + * \brief Unallocate all data related to subject alternative name + * + * \param san SAN structure - extra memory owned by this structure will be freed + */ +void mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name *san); + +int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end, + mbedtls_x509_name *cur); +int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *alg); +int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *alg, mbedtls_x509_buf *params); +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) +int mbedtls_x509_get_rsassa_pss_params(const mbedtls_x509_buf *params, + mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, + int *salt_len); +#endif +int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig); +int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, + mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, + void **sig_opts); +int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end, + mbedtls_x509_time *t); +int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *serial); +int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *ext, int tag); +#if !defined(MBEDTLS_X509_REMOVE_INFO) +int mbedtls_x509_sig_alg_gets(char *buf, size_t size, const mbedtls_x509_buf *sig_oid, + mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, + const void *sig_opts); +#endif +int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name); +int mbedtls_x509_set_extension(mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, + int critical, const unsigned char *val, + size_t val_len); +int mbedtls_x509_write_extensions(unsigned char **p, unsigned char *start, + mbedtls_asn1_named_data *first); +int mbedtls_x509_write_names(unsigned char **p, unsigned char *start, + mbedtls_asn1_named_data *first); +int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + unsigned char *sig, size_t size, + mbedtls_pk_type_t pk_alg); +int mbedtls_x509_get_ns_cert_type(unsigned char **p, + const unsigned char *end, + unsigned char *ns_cert_type); +int mbedtls_x509_get_key_usage(unsigned char **p, + const unsigned char *end, + unsigned int *key_usage); +int mbedtls_x509_get_subject_alt_name(unsigned char **p, + const unsigned char *end, + mbedtls_x509_sequence *subject_alt_name); +int mbedtls_x509_get_subject_alt_name_ext(unsigned char **p, + const unsigned char *end, + mbedtls_x509_sequence *subject_alt_name); +int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size, + const mbedtls_x509_sequence + *subject_alt_name, + const char *prefix); +int mbedtls_x509_info_cert_type(char **buf, size_t *size, + unsigned char ns_cert_type); +int mbedtls_x509_info_key_usage(char **buf, size_t *size, + unsigned int key_usage); + +int mbedtls_x509_write_set_san_common(mbedtls_asn1_named_data **extensions, + const mbedtls_x509_san_list *san_list); + +#endif /* MBEDTLS_X509_INTERNAL_H */ diff --git a/library/x509write.c b/library/x509write.c index d434df507..4704900d3 100644 --- a/library/x509write.c +++ b/library/x509write.c @@ -8,6 +8,7 @@ #if defined(MBEDTLS_X509_CSR_WRITE_C) || defined(MBEDTLS_X509_CRT_WRITE_C) #include "mbedtls/x509_crt.h" +#include "x509_internal.h" #include "mbedtls/asn1write.h" #include "mbedtls/error.h" #include "mbedtls/oid.h" diff --git a/library/x509write_crt.c b/library/x509write_crt.c index 44b6b1781..2a1a5e219 100644 --- a/library/x509write_crt.c +++ b/library/x509write_crt.c @@ -16,6 +16,7 @@ #if defined(MBEDTLS_X509_CRT_WRITE_C) #include "mbedtls/x509_crt.h" +#include "x509_internal.h" #include "mbedtls/asn1write.h" #include "mbedtls/error.h" #include "mbedtls/oid.h" diff --git a/library/x509write_csr.c b/library/x509write_csr.c index 254da69a9..0a3620257 100644 --- a/library/x509write_csr.c +++ b/library/x509write_csr.c @@ -14,7 +14,7 @@ #if defined(MBEDTLS_X509_CSR_WRITE_C) -#include "mbedtls/x509.h" +#include "x509_internal.h" #include "mbedtls/x509_csr.h" #include "mbedtls/asn1write.h" #include "mbedtls/error.h" diff --git a/tests/suites/test_suite_pkcs7.function b/tests/suites/test_suite_pkcs7.function index 65384a855..4c8bf233e 100644 --- a/tests/suites/test_suite_pkcs7.function +++ b/tests/suites/test_suite_pkcs7.function @@ -4,6 +4,7 @@ #include "mbedtls/x509.h" #include "mbedtls/x509_crt.h" #include "mbedtls/x509_crl.h" +#include "x509_internal.h" #include "mbedtls/oid.h" #include "sys/types.h" #include "sys/stat.h" diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index c2a2f556d..66477e0d1 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -4,6 +4,7 @@ #include "mbedtls/x509_crt.h" #include "mbedtls/x509_crl.h" #include "mbedtls/x509_csr.h" +#include "x509_internal.h" #include "mbedtls/pem.h" #include "mbedtls/oid.h" #include "mbedtls/base64.h" diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function index 503d9764c..765866bb2 100644 --- a/tests/suites/test_suite_x509write.function +++ b/tests/suites/test_suite_x509write.function @@ -2,6 +2,7 @@ #include "mbedtls/bignum.h" #include "mbedtls/x509_crt.h" #include "mbedtls/x509_csr.h" +#include "x509_internal.h" #include "mbedtls/pem.h" #include "mbedtls/oid.h" #include "mbedtls/rsa.h" From 639d5678b5466bff184b9fc3199fea2202d2dc73 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 17 Jan 2024 11:04:56 +0100 Subject: [PATCH 124/215] pk: move mbedtls_pk_load_file to pk_internal Signed-off-by: Valerio Setti --- include/mbedtls/pk.h | 8 -------- library/pk_internal.h | 4 ++++ library/x509_internal.h | 2 +- tests/suites/test_suite_pkwrite.function | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index 27768bd35..2fdcaefd3 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -1042,14 +1042,6 @@ int mbedtls_pk_write_pubkey(unsigned char **p, unsigned char *start, const mbedtls_pk_context *key); #endif /* MBEDTLS_PK_WRITE_C */ -/* - * Internal module functions. You probably do not want to use these unless you - * know you do. - */ -#if defined(MBEDTLS_FS_IO) -int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n); -#endif - #if defined(MBEDTLS_USE_PSA_CRYPTO) /** * \brief Turn an EC or RSA key into an opaque one. diff --git a/library/pk_internal.h b/library/pk_internal.h index 025ee8b01..9cab6a5bb 100644 --- a/library/pk_internal.h +++ b/library/pk_internal.h @@ -144,4 +144,8 @@ MBEDTLS_STATIC_TESTABLE int mbedtls_pk_parse_key_pkcs8_encrypted_der( int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); #endif +#if defined(MBEDTLS_FS_IO) +int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n); +#endif + #endif /* MBEDTLS_PK_INTERNAL_H */ diff --git a/library/x509_internal.h b/library/x509_internal.h index e1be393b4..15e097a15 100644 --- a/library/x509_internal.h +++ b/library/x509_internal.h @@ -15,7 +15,7 @@ #include "mbedtls/x509.h" #include "mbedtls/asn1.h" -#include "mbedtls/pk.h" +#include "pk_internal.h" #if defined(MBEDTLS_RSA_C) #include "mbedtls/rsa.h" diff --git a/tests/suites/test_suite_pkwrite.function b/tests/suites/test_suite_pkwrite.function index 733909ebc..c7600903f 100644 --- a/tests/suites/test_suite_pkwrite.function +++ b/tests/suites/test_suite_pkwrite.function @@ -1,5 +1,5 @@ /* BEGIN_HEADER */ -#include "mbedtls/pk.h" +#include "pk_internal.h" #include "mbedtls/pem.h" #include "mbedtls/oid.h" #include "psa/crypto_sizes.h" From 558da2ffd3f414ba221d907fb026f716a29b5f09 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 19 Jan 2024 12:59:28 +0000 Subject: [PATCH 125/215] Move key_slot_mutex to threading.h Make this a global mutex so that we don't have to init and free it. Also rename the mutex to follow the convention Signed-off-by: Ryan Everett --- include/mbedtls/threading.h | 14 +++++++++++++ library/psa_crypto_slot_management.c | 31 +--------------------------- library/psa_crypto_slot_management.h | 10 +-------- library/threading.c | 9 ++++++++ 4 files changed, 25 insertions(+), 39 deletions(-) diff --git a/include/mbedtls/threading.h b/include/mbedtls/threading.h index b504233bd..b4e050241 100644 --- a/include/mbedtls/threading.h +++ b/include/mbedtls/threading.h @@ -100,6 +100,20 @@ extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex; extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; #endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ +#if defined(MBEDTLS_PSA_CRYPTO_C) +/* + * A mutex used to make the PSA subsystem thread safe. + * + * key_slot_mutex protects the registered_readers and + * state variable for all key slots in &global_data.key_slots. + * + * This mutex must be held when any read from or write to a state or + * registered_readers field is performed, i.e. when calling functions: + * psa_key_slot_state_transition(), psa_register_read(), psa_unregister_read(), + * psa_key_slot_has_readers() and psa_wipe_key_slot(). */ +extern mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex; +#endif + #endif /* MBEDTLS_THREADING_C */ #ifdef __cplusplus diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 180aecb58..47ace359d 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -30,20 +30,6 @@ typedef struct { psa_key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT]; uint8_t key_slots_initialized; - -#if defined(MBEDTLS_THREADING_C) - /* - * A mutex used to make the PSA subsystem thread safe. - * - * key_slot_mutex protects key_slots[i].registered_readers and - * key_slots[i].state for all valid i. - * - * This mutex must be held when any read from or write to a state or - * registered_readers field is performed, i.e. when calling functions: - * psa_key_slot_state_transition, psa_register_read, psa_unregister_read, - * psa_key_slot_has_readers and psa_wipe_key_slot. */ - mbedtls_threading_mutex_t MBEDTLS_PRIVATE(key_slot_mutex); -#endif } psa_global_data_t; static psa_global_data_t global_data; @@ -147,14 +133,7 @@ static psa_status_t psa_get_and_lock_key_slot_in_memory( psa_status_t psa_initialize_key_slots(void) { -#if defined(MBEDTLS_THREADING_C) - /* Initialize the global key slot mutex. */ - if (!global_data.key_slots_initialized) { - mbedtls_mutex_init(&global_data.key_slot_mutex); - } -#endif - - /* Program startup and psa_wipe_all_key_slots() both + /* Nothing to do: program startup and psa_wipe_all_key_slots() both * guarantee that the key slots are initialized to all-zero, which * means that all the key slots are in a valid, empty state. */ global_data.key_slots_initialized = 1; @@ -171,14 +150,6 @@ void psa_wipe_all_key_slots(void) slot->state = PSA_SLOT_PENDING_DELETION; (void) psa_wipe_key_slot(slot); } - -#if defined(MBEDTLS_THREADING_C) - /* Free the global key slot mutex. */ - if (global_data.key_slots_initialized) { - mbedtls_mutex_free(&global_data.key_slot_mutex); - } -#endif - global_data.key_slots_initialized = 0; } diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index fc46257f2..4c0721d3b 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -85,10 +85,6 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, psa_key_slot_t **p_slot); /** Initialize the key slot structures. - * If multi-threading is enabled then initialize the key slot mutex. - * This function is not thread-safe, - * if called by competing threads the key slot mutex may be initialized - * more than once. * * \retval #PSA_SUCCESS * Currently this function always succeeds. @@ -96,10 +92,6 @@ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, psa_status_t psa_initialize_key_slots(void); /** Delete all data from key slots in memory. - * If multi-threading is enabled then free the key slot mutex. - * This function is not thread-safe, - * if called by competing threads the key slot mutex may be freed - * more than once. * * This does not affect persistent storage. */ void psa_wipe_all_key_slots(void); @@ -186,7 +178,7 @@ static inline psa_status_t psa_register_read(psa_key_slot_t *slot) * This function decrements the key slot registered reader counter by one. * If the state of the slot is PSA_SLOT_PENDING_DELETION, * and there is only one registered reader (the caller), - * this function will call psa_wipe_slot(). + * this function will call psa_wipe_key_slot(). * If multi-threading is enabled, the caller must hold the * global key slot mutex. * diff --git a/library/threading.c b/library/threading.c index 873b5077b..94404acb8 100644 --- a/library/threading.c +++ b/library/threading.c @@ -148,6 +148,9 @@ void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *), #if defined(THREADING_USE_GMTIME) mbedtls_mutex_init(&mbedtls_threading_gmtime_mutex); #endif +#if defined(MBEDTLS_PSA_CRYPTO_C) + mbedtls_mutext_init(&mbedtls_threading_key_slot_mutex); +#endif } /* @@ -161,6 +164,9 @@ void mbedtls_threading_free_alt(void) #if defined(THREADING_USE_GMTIME) mbedtls_mutex_free(&mbedtls_threading_gmtime_mutex); #endif +#if defined(MBEDTLS_PSA_CRYPTO_C) + mbedtls_mutex_free(&mbedtls_threading_key_slot_mutex); +#endif } #endif /* MBEDTLS_THREADING_ALT */ @@ -176,5 +182,8 @@ mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT; #if defined(THREADING_USE_GMTIME) mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; #endif +#if defined(MBEDTLS_PSA_CRYPTO_C) +mbedtls_threading_mutex_t mbedtls_threading_key_slot_mutex MUTEX_INIT; +#endif #endif /* MBEDTLS_THREADING_C */ From 7aeacc1ec4b832b43c512067323156705e686fe2 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 19 Jan 2024 13:02:58 +0000 Subject: [PATCH 126/215] Add empty line in register_read comment Signed-off-by: Ryan Everett --- library/psa_crypto_slot_management.h | 1 + 1 file changed, 1 insertion(+) diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index 4c0721d3b..002429b93 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -154,6 +154,7 @@ static inline psa_status_t psa_key_slot_state_transition( * This function increments the key slot registered reader counter by one. * If multi-threading is enabled, the caller must hold the * global key slot mutex. + * * \param[in] slot The key slot. * * \retval #PSA_SUCCESS From 63952b7de5f1ef0e18b9c7ada084a9a7a64d452b Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 19 Jan 2024 13:45:19 +0000 Subject: [PATCH 127/215] Fix typo Signed-off-by: Ryan Everett --- library/threading.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/threading.c b/library/threading.c index 94404acb8..c28290fb7 100644 --- a/library/threading.c +++ b/library/threading.c @@ -149,7 +149,7 @@ void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *), mbedtls_mutex_init(&mbedtls_threading_gmtime_mutex); #endif #if defined(MBEDTLS_PSA_CRYPTO_C) - mbedtls_mutext_init(&mbedtls_threading_key_slot_mutex); + mbedtls_mutex_init(&mbedtls_threading_key_slot_mutex); #endif } From 69b5a860644510e0315b9ec65991d5e111e81f15 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 19 Jan 2024 14:02:08 +0000 Subject: [PATCH 128/215] Improve mbedtls_xor for IAR Signed-off-by: Dave Rodgman --- library/common.h | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/library/common.h b/library/common.h index e532777e7..5c73e8a66 100644 --- a/library/common.h +++ b/library/common.h @@ -191,21 +191,30 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned uint8x16_t x = veorq_u8(v1, v2); vst1q_u8(r + i, x); } + // This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case + // where n is a constant multiple of 16. + // It makes no difference for others (e.g. recent gcc and clang) if n is a compile-time + // constant, and very little difference if n is not a compile-time constant. + if (n % 16 != 0) #elif defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64) /* This codepath probably only makes sense on architectures with 64-bit registers */ for (; (i + 8) <= n; i += 8) { uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i); mbedtls_put_unaligned_uint64(r + i, x); } + if (n % 8 != 0) #else for (; (i + 4) <= n; i += 4) { uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); mbedtls_put_unaligned_uint32(r + i, x); } + if (n % 4 != 0) #endif #endif - for (; i < n; i++) { - r[i] = a[i] ^ b[i]; + { + for (; i < n; i++) { + r[i] = a[i] ^ b[i]; + } } } @@ -236,15 +245,23 @@ static inline void mbedtls_xor_no_simd(unsigned char *r, uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i); mbedtls_put_unaligned_uint64(r + i, x); } + // This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case + // where n is a constant multiple of 8. + // It makes no difference for others (e.g. recent gcc and clang) if n is a compile-time + // constant, and very little difference if n is not a compile-time constant. + if (n % 8 != 0) #else for (; (i + 4) <= n; i += 4) { uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); mbedtls_put_unaligned_uint32(r + i, x); } + if (n % 4 != 0) #endif #endif - for (; i < n; i++) { - r[i] = a[i] ^ b[i]; + { + for (; i < n; i++) { + r[i] = a[i] ^ b[i]; + } } } From 7d8c99abb08a9e0716cd9bb9747cffce1a7d235a Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 19 Jan 2024 14:02:58 +0000 Subject: [PATCH 129/215] Move MBEDTLS_COMPILER_IS_GCC defn into alignment.h Signed-off-by: Dave Rodgman --- library/alignment.h | 8 ++++++++ library/common.h | 9 --------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/library/alignment.h b/library/alignment.h index 9e1e044ec..219f4f0af 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -15,6 +15,14 @@ #include #include +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && !defined(__clang__) \ + && !defined(__llvm__) && !defined(__INTEL_COMPILER) +/* Defined if the compiler really is gcc and not clang, etc */ +#define MBEDTLS_COMPILER_IS_GCC +#define MBEDTLS_GCC_VERSION \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + /* * Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory * accesses are known to be efficient. diff --git a/library/common.h b/library/common.h index 5c73e8a66..faefd64ea 100644 --- a/library/common.h +++ b/library/common.h @@ -27,15 +27,6 @@ #define MBEDTLS_HAVE_NEON_INTRINSICS #endif - -#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && !defined(__clang__) \ - && !defined(__llvm__) && !defined(__INTEL_COMPILER) -/* Defined if the compiler really is gcc and not clang, etc */ -#define MBEDTLS_COMPILER_IS_GCC -#define MBEDTLS_GCC_VERSION \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#endif - /** Helper to define a function as static except when building invasive tests. * * If a function is only used inside its own source file and should be From db8915287e183e642254565f9058ace93aabcf8a Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Tue, 16 Jan 2024 13:32:31 +0000 Subject: [PATCH 130/215] programs_dh_client/server: Changed mdlen type to unsigned integer. Signed-off-by: Minos Galanakis --- programs/pkey/dh_client.c | 5 +++-- programs/pkey/dh_server.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c index 1b5ba407e..e8469141a 100644 --- a/programs/pkey/dh_client.c +++ b/programs/pkey/dh_client.c @@ -59,7 +59,8 @@ int main(void) int ret = 1; int exit_code = MBEDTLS_EXIT_FAILURE; - size_t n, buflen, mdlen; + unsigned int mdlen; + size_t n, buflen; mbedtls_net_context server_fd; unsigned char *p, *end; @@ -186,7 +187,7 @@ int main(void) goto exit; } - mdlen = mbedtls_md_get_size(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256)); + mdlen = (unsigned int) mbedtls_md_get_size(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256)); if (mdlen == 0) { mbedtls_printf(" failed\n ! Invalid digest type\n\n"); goto exit; diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c index 11c28fb51..c08b0dc39 100644 --- a/programs/pkey/dh_server.c +++ b/programs/pkey/dh_server.c @@ -51,7 +51,8 @@ int main(void) int ret = 1; int exit_code = MBEDTLS_EXIT_FAILURE; - size_t n, buflen, mdlen; + unsigned int mdlen; + size_t n, buflen; mbedtls_net_context listen_fd, client_fd; unsigned char buf[2048]; @@ -185,7 +186,7 @@ int main(void) * 5. Sign the parameters and send them */ - mdlen = mbedtls_md_get_size(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256)); + mdlen = (unsigned int) mbedtls_md_get_size(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256)); if (mdlen == 0) { mbedtls_printf(" failed\n ! Invalid digest type\n\n"); goto exit; From 42151380aff54e6f76ee428a2bc57ec825bd3a6f Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Fri, 19 Jan 2024 13:36:57 +0000 Subject: [PATCH 131/215] programs_dh_client/server: Updated config guards. Adjusted to use `MBEDTLS_SHA256_C` instead of `MBEDTLS_MD_CAN_SHA256` since the former is being used in accelerated driver configurations. Signed-off-by: Minos Galanakis --- programs/pkey/dh_client.c | 11 +++++------ programs/pkey/dh_server.c | 10 +++++----- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c index e8469141a..165cee240 100644 --- a/programs/pkey/dh_client.c +++ b/programs/pkey/dh_client.c @@ -13,13 +13,13 @@ #if defined(MBEDTLS_AES_C) && defined(MBEDTLS_DHM_C) && \ defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_NET_C) && \ - defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA256) && \ + defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) && \ defined(MBEDTLS_FS_IO) && defined(MBEDTLS_CTR_DRBG_C) #include "mbedtls/net_sockets.h" #include "mbedtls/aes.h" #include "mbedtls/dhm.h" #include "mbedtls/rsa.h" -#include "mbedtls/sha1.h" +#include "mbedtls/sha256.h" #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" @@ -32,15 +32,14 @@ #if !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_DHM_C) || \ !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NET_C) || \ - !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_MD_CAN_SHA256) || \ + !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_SHA256_C) || \ !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_CTR_DRBG_C) - int main(void) { mbedtls_printf("MBEDTLS_AES_C and/or MBEDTLS_DHM_C and/or MBEDTLS_ENTROPY_C " "and/or MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or " "MBEDTLS_MD_CAN_SHA256 and/or MBEDTLS_FS_IO and/or " - "MBEDTLS_CTR_DRBG_C not defined.\n"); + "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_SHA1_C not defined.\n"); mbedtls_exit(0); } @@ -194,7 +193,7 @@ int main(void) } if ((ret = mbedtls_sha256(buf, (int) (p - 2 - buf), hash, 0)) != 0) { - mbedtls_printf(" failed\n ! mbedtls_sha1 returned %d\n\n", ret); + mbedtls_printf(" failed\n ! mbedtls_sha256 returned %d\n\n", ret); goto exit; } diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c index c08b0dc39..91bac0ef4 100644 --- a/programs/pkey/dh_server.c +++ b/programs/pkey/dh_server.c @@ -13,13 +13,13 @@ #if defined(MBEDTLS_AES_C) && defined(MBEDTLS_DHM_C) && \ defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_NET_C) && \ - defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA256) && \ + defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) && \ defined(MBEDTLS_FS_IO) && defined(MBEDTLS_CTR_DRBG_C) #include "mbedtls/net_sockets.h" #include "mbedtls/aes.h" #include "mbedtls/dhm.h" #include "mbedtls/rsa.h" -#include "mbedtls/sha1.h" +#include "mbedtls/sha256.h" #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" @@ -32,14 +32,14 @@ #if !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_DHM_C) || \ !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NET_C) || \ - !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_MD_CAN_SHA256) || \ + !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_SHA256_C) || \ !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_CTR_DRBG_C) int main(void) { mbedtls_printf("MBEDTLS_AES_C and/or MBEDTLS_DHM_C and/or MBEDTLS_ENTROPY_C " "and/or MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or " "MBEDTLS_MD_CAN_SHA256 and/or MBEDTLS_FS_IO and/or " - "MBEDTLS_CTR_DRBG_C not defined.\n"); + "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_SHA1_C not defined.\n"); mbedtls_exit(0); } #else @@ -193,7 +193,7 @@ int main(void) } if ((ret = mbedtls_sha256(buf, n, hash, 0)) != 0) { - mbedtls_printf(" failed\n ! mbedtls_sha1 returned %d\n\n", ret); + mbedtls_printf(" failed\n ! mbedtls_sha256 returned %d\n\n", ret); goto exit; } From c581264977e2b0309697fddc4a345ba1c4d02544 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 19 Jan 2024 14:04:28 +0000 Subject: [PATCH 132/215] Fix unaligned access on old compilers Add an alternative implementation of unaligned access that is efficient for IAR and old versions of gcc. Signed-off-by: Dave Rodgman --- library/alignment.h | 74 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/library/alignment.h b/library/alignment.h index 219f4f0af..e7318c2ac 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -45,6 +45,46 @@ #define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS #endif +#if defined(__IAR_SYSTEMS_ICC__) && \ + (defined(MBEDTLS_ARCH_IS_ARM64) || defined(MBEDTLS_ARCH_IS_ARM32) \ + || defined(__ICCRX__) || defined(__ICCRL78__) || defined(__ICCRISCV__)) +#pragma language=save +#pragma language=extended +#define MBEDTLS_POP_IAR_LANGUAGE_PRAGMA +/* IAR recommend this technique for accessing unaligned data in + * https://www.iar.com/knowledge/support/technical-notes/compiler/accessing-unaligned-data + * This results in a single load / store instruction (if unaligned access is supported). + * According to that document, this is only supported on certain architectures. + */ + #define UINT_UNALIGNED +typedef uint16_t __packed mbedtls_uint16_unaligned_t; +typedef uint32_t __packed mbedtls_uint32_unaligned_t; +typedef uint64_t __packed mbedtls_uint64_unaligned_t; +#elif defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 40504) && \ + ((MBEDTLS_GCC_VERSION < 90300) || (!defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS))) +/* + * Old versions of gcc, depending on how the target is specified, may generate a branch to memcpy + * for calls like `memcpy(dest, src, 4)` rather than generating some LDR or LDRB instructions + * (similar for stores). + * Recent versions where unaligned access is not enabled also do this. + * + * For performance (and code size, in some cases), we want to avoid the branch and just generate + * some inline load/store instructions since the access is small and constant-size. + * + * The manual states: + * "The aligned attribute specifies a minimum alignment for the variable or structure field, + * measured in bytes." + * https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html + * + * Tested with several versions of GCC from 4.5.0 up to 9.3.0 + * We don't enable for older than 4.5.0 as this has not been tested. + */ + #define UINT_UNALIGNED +typedef uint16_t __attribute__((__aligned__(1))) mbedtls_uint16_unaligned_t; +typedef uint32_t __attribute__((__aligned__(1))) mbedtls_uint32_unaligned_t; +typedef uint64_t __attribute__((__aligned__(1))) mbedtls_uint64_unaligned_t; + #endif + /** * Read the unsigned 16 bits integer from the given address, which need not * be aligned. @@ -55,7 +95,12 @@ inline uint16_t mbedtls_get_unaligned_uint16(const void *p) { uint16_t r; +#if defined(UINT_UNALIGNED) + mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p; + r = *p16; +#else memcpy(&r, p, sizeof(r)); +#endif return r; } @@ -68,7 +113,12 @@ inline uint16_t mbedtls_get_unaligned_uint16(const void *p) */ inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x) { +#if defined(UINT_UNALIGNED) + mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p; + *p16 = x; +#else memcpy(p, &x, sizeof(x)); +#endif } /** @@ -81,7 +131,12 @@ inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x) inline uint32_t mbedtls_get_unaligned_uint32(const void *p) { uint32_t r; +#if defined(UINT_UNALIGNED) + mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p; + r = *p32; +#else memcpy(&r, p, sizeof(r)); +#endif return r; } @@ -94,7 +149,12 @@ inline uint32_t mbedtls_get_unaligned_uint32(const void *p) */ inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x) { +#if defined(UINT_UNALIGNED) + mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p; + *p32 = x; +#else memcpy(p, &x, sizeof(x)); +#endif } /** @@ -107,7 +167,12 @@ inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x) inline uint64_t mbedtls_get_unaligned_uint64(const void *p) { uint64_t r; +#if defined(UINT_UNALIGNED) + mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p; + r = *p64; +#else memcpy(&r, p, sizeof(r)); +#endif return r; } @@ -120,9 +185,18 @@ inline uint64_t mbedtls_get_unaligned_uint64(const void *p) */ inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x) { +#if defined(UINT_UNALIGNED) + mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p; + *p64 = x; +#else memcpy(p, &x, sizeof(x)); +#endif } +#if defined(MBEDTLS_POP_IAR_LANGUAGE_PRAGMA) +#pragma language=restore +#endif + /** Byte Reading Macros * * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th From 55b5dd2cfc3c751368ddf262d7fb1b8ba7540bdc Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 19 Jan 2024 14:06:52 +0000 Subject: [PATCH 133/215] Make unaligned accessors always inline Signed-off-by: Dave Rodgman --- library/alignment.h | 48 +++++++++++++++++++++++++++++++++++------ library/platform_util.c | 12 ----------- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/library/alignment.h b/library/alignment.h index e7318c2ac..b61301922 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -85,6 +85,12 @@ typedef uint32_t __attribute__((__aligned__(1))) mbedtls_uint32_unaligned_t; typedef uint64_t __attribute__((__aligned__(1))) mbedtls_uint64_unaligned_t; #endif +/* + * We try to force mbedtls_(get|put)_unaligned_uintXX to be always inline, because this results + * in code that is both smaller and faster. IAR and gcc both benefit from this when optimising + * for size. + */ + /** * Read the unsigned 16 bits integer from the given address, which need not * be aligned. @@ -92,7 +98,12 @@ typedef uint64_t __attribute__((__aligned__(1))) mbedtls_uint64_unaligned_t; * \param p pointer to 2 bytes of data * \return Data at the given address */ -inline uint16_t mbedtls_get_unaligned_uint16(const void *p) +#if defined(__IAR_SYSTEMS_ICC__) +#pragma inline = forced +#elif defined(__GNUC__) +__attribute__((always_inline)) +#endif +static inline uint16_t mbedtls_get_unaligned_uint16(const void *p) { uint16_t r; #if defined(UINT_UNALIGNED) @@ -111,7 +122,12 @@ inline uint16_t mbedtls_get_unaligned_uint16(const void *p) * \param p pointer to 2 bytes of data * \param x data to write */ -inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x) +#if defined(__IAR_SYSTEMS_ICC__) +#pragma inline = forced +#elif defined(__GNUC__) +__attribute__((always_inline)) +#endif +static inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x) { #if defined(UINT_UNALIGNED) mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p; @@ -128,7 +144,12 @@ inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x) * \param p pointer to 4 bytes of data * \return Data at the given address */ -inline uint32_t mbedtls_get_unaligned_uint32(const void *p) +#if defined(__IAR_SYSTEMS_ICC__) +#pragma inline = forced +#elif defined(__GNUC__) +__attribute__((always_inline)) +#endif +static inline uint32_t mbedtls_get_unaligned_uint32(const void *p) { uint32_t r; #if defined(UINT_UNALIGNED) @@ -147,7 +168,12 @@ inline uint32_t mbedtls_get_unaligned_uint32(const void *p) * \param p pointer to 4 bytes of data * \param x data to write */ -inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x) +#if defined(__IAR_SYSTEMS_ICC__) +#pragma inline = forced +#elif defined(__GNUC__) +__attribute__((always_inline)) +#endif +static inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x) { #if defined(UINT_UNALIGNED) mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p; @@ -164,7 +190,12 @@ inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x) * \param p pointer to 8 bytes of data * \return Data at the given address */ -inline uint64_t mbedtls_get_unaligned_uint64(const void *p) +#if defined(__IAR_SYSTEMS_ICC__) +#pragma inline = forced +#elif defined(__GNUC__) +__attribute__((always_inline)) +#endif +static inline uint64_t mbedtls_get_unaligned_uint64(const void *p) { uint64_t r; #if defined(UINT_UNALIGNED) @@ -183,7 +214,12 @@ inline uint64_t mbedtls_get_unaligned_uint64(const void *p) * \param p pointer to 8 bytes of data * \param x data to write */ -inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x) +#if defined(__IAR_SYSTEMS_ICC__) +#pragma inline = forced +#elif defined(__GNUC__) +__attribute__((always_inline)) +#endif +static inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x) { #if defined(UINT_UNALIGNED) mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p; diff --git a/library/platform_util.c b/library/platform_util.c index 63643d26f..e79fc5c8e 100644 --- a/library/platform_util.c +++ b/library/platform_util.c @@ -226,18 +226,6 @@ extern inline void mbedtls_xor(unsigned char *r, const unsigned char *b, size_t n); -extern inline uint16_t mbedtls_get_unaligned_uint16(const void *p); - -extern inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x); - -extern inline uint32_t mbedtls_get_unaligned_uint32(const void *p); - -extern inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x); - -extern inline uint64_t mbedtls_get_unaligned_uint64(const void *p); - -extern inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x); - #if defined(MBEDTLS_HAVE_TIME) && !defined(MBEDTLS_PLATFORM_MS_TIME_ALT) #include From 18d90d75195fb56834360c42a4f06318afa3cccc Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 19 Jan 2024 14:08:04 +0000 Subject: [PATCH 134/215] Make mbedtls_xor always inline Signed-off-by: Dave Rodgman --- library/common.h | 18 +++++++++++++++++- library/platform_util.c | 9 --------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/library/common.h b/library/common.h index faefd64ea..760dff49e 100644 --- a/library/common.h +++ b/library/common.h @@ -158,6 +158,12 @@ static inline const unsigned char *mbedtls_buffer_offset_const( return p == NULL ? NULL : p + n; } +/* Always inline mbedtls_xor for similar reasons as mbedtls_xor_no_simd. */ +#if defined(__IAR_SYSTEMS_ICC__) +#pragma inline = forced +#elif defined(__GNUC__) +__attribute__((always_inline)) +#endif /** * Perform a fast block XOR operation, such that * r[i] = a[i] ^ b[i] where 0 <= i < n @@ -169,7 +175,10 @@ static inline const unsigned char *mbedtls_buffer_offset_const( * \param b Pointer to input (buffer of at least \p n bytes) * \param n Number of bytes to process. */ -inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned char *b, size_t n) +static inline void mbedtls_xor(unsigned char *r, + const unsigned char *a, + const unsigned char *b, + size_t n) { size_t i = 0; #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) @@ -209,6 +218,13 @@ inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned } } +/* Always inline mbedtls_xor_no_simd as we see significant perf regressions when it does not get + * inlined (e.g., observed about 3x perf difference in gcm_mult_largetable with gcc 7 - 12) */ +#if defined(__IAR_SYSTEMS_ICC__) +#pragma inline = forced +#elif defined(__GNUC__) +__attribute__((always_inline)) +#endif /** * Perform a fast block XOR operation, such that * r[i] = a[i] ^ b[i] where 0 <= i < n diff --git a/library/platform_util.c b/library/platform_util.c index e79fc5c8e..9f5dcb874 100644 --- a/library/platform_util.c +++ b/library/platform_util.c @@ -217,15 +217,6 @@ struct tm *mbedtls_platform_gmtime_r(const mbedtls_time_t *tt, void (*mbedtls_test_hook_test_fail)(const char *, int, const char *); #endif /* MBEDTLS_TEST_HOOKS */ -/* - * Provide external definitions of some inline functions so that the compiler - * has the option to not inline them - */ -extern inline void mbedtls_xor(unsigned char *r, - const unsigned char *a, - const unsigned char *b, - size_t n); - #if defined(MBEDTLS_HAVE_TIME) && !defined(MBEDTLS_PLATFORM_MS_TIME_ALT) #include From 2143a4ad1fc79e3e601e078f86aafcb6fbabcc71 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 19 Jan 2024 14:08:17 +0000 Subject: [PATCH 135/215] Improve mbedtls_xor docs Signed-off-by: Dave Rodgman --- library/common.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/library/common.h b/library/common.h index 760dff49e..3b1c7e1e7 100644 --- a/library/common.h +++ b/library/common.h @@ -174,6 +174,14 @@ __attribute__((always_inline)) * \param a Pointer to input (buffer of at least \p n bytes) * \param b Pointer to input (buffer of at least \p n bytes) * \param n Number of bytes to process. + * + * \note Depending on the situation, it may be faster to use either mbedtls_xor or + * mbedtls_xor_no_simd (these are functionally equivalent). + * If the result is used immediately after the xor operation in non-SIMD code (e.g, in + * AES-CBC), there may be additional latency to transfer the data from SIMD to scalar + * registers, and in this case, mbedtls_xor_no_simd may be faster. In other cases where + * the result is not used immediately (e.g., in AES-CTR), mbedtls_xor may be faster. + * For targets without SIMD support, they will behave the same. */ static inline void mbedtls_xor(unsigned char *r, const unsigned char *a, @@ -238,6 +246,14 @@ __attribute__((always_inline)) * \param a Pointer to input (buffer of at least \p n bytes) * \param b Pointer to input (buffer of at least \p n bytes) * \param n Number of bytes to process. + * + * \note Depending on the situation, it may be faster to use either mbedtls_xor or + * mbedtls_xor_no_simd (these are functionally equivalent). + * If the result is used immediately after the xor operation in non-SIMD code (e.g, in + * AES-CBC), there may be additional latency to transfer the data from SIMD to scalar + * registers, and in this case, mbedtls_xor_no_simd may be faster. In other cases where + * the result is not used immediately (e.g., in AES-CTR), mbedtls_xor may be faster. + * For targets without SIMD support, they will behave the same. */ static inline void mbedtls_xor_no_simd(unsigned char *r, const unsigned char *a, From 7470557855e5eecb74064a7e1773995e03bd622a Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 19 Jan 2024 14:29:32 +0000 Subject: [PATCH 136/215] Add changelog entry Signed-off-by: Dave Rodgman --- ChangeLog.d/iar-gcc-perf.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 ChangeLog.d/iar-gcc-perf.txt diff --git a/ChangeLog.d/iar-gcc-perf.txt b/ChangeLog.d/iar-gcc-perf.txt new file mode 100644 index 000000000..fb0fbb10d --- /dev/null +++ b/ChangeLog.d/iar-gcc-perf.txt @@ -0,0 +1,2 @@ +Features + * Improve performance for gcc (versions older than 9.3.0) and IAR. From 00b4eeb0b3b8569ee371dd91a0a6fac6ebc0ee34 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 19 Jan 2024 16:06:41 +0000 Subject: [PATCH 137/215] Improve comments Signed-off-by: Dave Rodgman --- library/common.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/library/common.h b/library/common.h index 3b1c7e1e7..2eb917037 100644 --- a/library/common.h +++ b/library/common.h @@ -158,7 +158,7 @@ static inline const unsigned char *mbedtls_buffer_offset_const( return p == NULL ? NULL : p + n; } -/* Always inline mbedtls_xor for similar reasons as mbedtls_xor_no_simd. */ +/* Always inline mbedtls_xor() for similar reasons as mbedtls_xor_no_simd(). */ #if defined(__IAR_SYSTEMS_ICC__) #pragma inline = forced #elif defined(__GNUC__) @@ -175,12 +175,12 @@ __attribute__((always_inline)) * \param b Pointer to input (buffer of at least \p n bytes) * \param n Number of bytes to process. * - * \note Depending on the situation, it may be faster to use either mbedtls_xor or - * mbedtls_xor_no_simd (these are functionally equivalent). + * \note Depending on the situation, it may be faster to use either mbedtls_xor() or + * mbedtls_xor_no_simd() (these are functionally equivalent). * If the result is used immediately after the xor operation in non-SIMD code (e.g, in * AES-CBC), there may be additional latency to transfer the data from SIMD to scalar - * registers, and in this case, mbedtls_xor_no_simd may be faster. In other cases where - * the result is not used immediately (e.g., in AES-CTR), mbedtls_xor may be faster. + * registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where + * the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster. * For targets without SIMD support, they will behave the same. */ static inline void mbedtls_xor(unsigned char *r, @@ -199,10 +199,10 @@ static inline void mbedtls_xor(unsigned char *r, uint8x16_t x = veorq_u8(v1, v2); vst1q_u8(r + i, x); } - // This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case - // where n is a constant multiple of 16. - // It makes no difference for others (e.g. recent gcc and clang) if n is a compile-time - // constant, and very little difference if n is not a compile-time constant. + /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case + * where n is a constant multiple of 16. + * It makes no difference for others (e.g. recent gcc and clang) if n is a compile-time + * constant, and very little difference if n is not a compile-time constant. */ if (n % 16 != 0) #elif defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64) /* This codepath probably only makes sense on architectures with 64-bit registers */ @@ -226,7 +226,7 @@ static inline void mbedtls_xor(unsigned char *r, } } -/* Always inline mbedtls_xor_no_simd as we see significant perf regressions when it does not get +/* Always inline mbedtls_xor_no_simd() as we see significant perf regressions when it does not get * inlined (e.g., observed about 3x perf difference in gcm_mult_largetable with gcc 7 - 12) */ #if defined(__IAR_SYSTEMS_ICC__) #pragma inline = forced @@ -237,7 +237,7 @@ __attribute__((always_inline)) * Perform a fast block XOR operation, such that * r[i] = a[i] ^ b[i] where 0 <= i < n * - * In some situations, this can perform better than mbedtls_xor (e.g., it's about 5% + * In some situations, this can perform better than mbedtls_xor() (e.g., it's about 5% * better in AES-CBC). * * \param r Pointer to result (buffer of at least \p n bytes). \p r @@ -247,12 +247,12 @@ __attribute__((always_inline)) * \param b Pointer to input (buffer of at least \p n bytes) * \param n Number of bytes to process. * - * \note Depending on the situation, it may be faster to use either mbedtls_xor or - * mbedtls_xor_no_simd (these are functionally equivalent). + * \note Depending on the situation, it may be faster to use either mbedtls_xor() or + * mbedtls_xor_no_simd() (these are functionally equivalent). * If the result is used immediately after the xor operation in non-SIMD code (e.g, in * AES-CBC), there may be additional latency to transfer the data from SIMD to scalar - * registers, and in this case, mbedtls_xor_no_simd may be faster. In other cases where - * the result is not used immediately (e.g., in AES-CTR), mbedtls_xor may be faster. + * registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where + * the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster. * For targets without SIMD support, they will behave the same. */ static inline void mbedtls_xor_no_simd(unsigned char *r, @@ -268,10 +268,10 @@ static inline void mbedtls_xor_no_simd(unsigned char *r, uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i); mbedtls_put_unaligned_uint64(r + i, x); } - // This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case - // where n is a constant multiple of 8. - // It makes no difference for others (e.g. recent gcc and clang) if n is a compile-time - // constant, and very little difference if n is not a compile-time constant. + /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case + * where n is a constant multiple of 16. + * It makes no difference for others (e.g. recent gcc and clang) if n is a compile-time + * constant, and very little difference if n is not a compile-time constant. */ if (n % 8 != 0) #else for (; (i + 4) <= n; i += 4) { From 336efeec50cc237a7c1e03a0744d3188a7f805fd Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 19 Jan 2024 16:38:53 +0000 Subject: [PATCH 138/215] Move MBEDTLS_COMPILER_IS_GCC & MBEDTLS_GCC_VERSION into build_info Signed-off-by: Dave Rodgman --- include/mbedtls/build_info.h | 8 ++++++++ library/alignment.h | 8 +------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h index 7a70e2543..c0b724c83 100644 --- a/include/mbedtls/build_info.h +++ b/include/mbedtls/build_info.h @@ -83,6 +83,14 @@ #endif #endif +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && !defined(__clang__) \ + && !defined(__llvm__) && !defined(__INTEL_COMPILER) +/* Defined if the compiler really is gcc and not clang, etc */ +#define MBEDTLS_COMPILER_IS_GCC +#define MBEDTLS_GCC_VERSION \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) #define _CRT_SECURE_NO_DEPRECATE 1 #endif diff --git a/library/alignment.h b/library/alignment.h index b61301922..26f15261c 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -15,13 +15,7 @@ #include #include -#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && !defined(__clang__) \ - && !defined(__llvm__) && !defined(__INTEL_COMPILER) -/* Defined if the compiler really is gcc and not clang, etc */ -#define MBEDTLS_COMPILER_IS_GCC -#define MBEDTLS_GCC_VERSION \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#endif +#include "mbedtls/build_info.h" /* * Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory From 075f8797ac35925089116959c98366ccd2cb00e6 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 19 Jan 2024 16:48:42 +0000 Subject: [PATCH 139/215] Remove include of build_info.h Signed-off-by: Dave Rodgman --- library/alignment.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/alignment.h b/library/alignment.h index 26f15261c..248f29bc7 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -15,8 +15,6 @@ #include #include -#include "mbedtls/build_info.h" - /* * Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory * accesses are known to be efficient. From 297c6089159e0a8c0195ca18777ce904b83fedcd Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 19 Jan 2024 08:15:33 +0100 Subject: [PATCH 140/215] tls13: cli: Fix setting of early data transform Fix setting of early data transform when we do not send dummy CCS for middlebox compatibility. Signed-off-by: Ronald Cron --- library/ssl_tls13_client.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index a3d33a34f..76f0f1896 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1236,10 +1236,6 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl) const mbedtls_ssl_ciphersuite_t *ciphersuite_info; if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) { -#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) - mbedtls_ssl_handshake_set_state( - ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO); -#endif MBEDTLS_SSL_DEBUG_MSG( 1, ("Set hs psk for early data when writing the first psk")); @@ -1294,6 +1290,15 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl) return ret; } +#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) + mbedtls_ssl_handshake_set_state( + ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO); +#else + MBEDTLS_SSL_DEBUG_MSG( + 1, ("Switch to early data keys for outbound traffic")); + mbedtls_ssl_set_outbound_transform( + ssl, ssl->handshake->transform_earlydata); +#endif } #endif /* MBEDTLS_SSL_EARLY_DATA */ return 0; @@ -3067,19 +3072,19 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl) } break; +#if defined(MBEDTLS_SSL_EARLY_DATA) case MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO: ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl); if (ret == 0) { mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO); -#if defined(MBEDTLS_SSL_EARLY_DATA) MBEDTLS_SSL_DEBUG_MSG( 1, ("Switch to early data keys for outbound traffic")); mbedtls_ssl_set_outbound_transform( ssl, ssl->handshake->transform_earlydata); -#endif } break; +#endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) From 77abfe67db1ff1bdae3ff1c93e7878e8ee0826f8 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 15 Jan 2024 11:17:31 +0100 Subject: [PATCH 141/215] ssl_helpers.c: Add ticket write/parse test functions Add ticket write/parse test functions as defined by mbedtls_ssl_ticket_write/parse_t. They are intended to be used in negative testing involving tickets. Signed-off-by: Ronald Cron --- tests/include/test/ssl_helpers.h | 10 ++++++++++ tests/src/test_helpers/ssl_helpers.c | 30 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h index d03c62414..1f41966d6 100644 --- a/tests/include/test/ssl_helpers.h +++ b/tests/include/test/ssl_helpers.h @@ -589,6 +589,16 @@ int mbedtls_test_tweak_tls13_certificate_msg_vector_len( int *expected_result, mbedtls_ssl_chk_buf_ptr_args *args); #endif /* MBEDTLS_TEST_HOOKS */ +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +int mbedtls_test_ticket_write( + void *p_ticket, const mbedtls_ssl_session *session, + unsigned char *start, const unsigned char *end, + size_t *tlen, uint32_t *ticket_lifetime); + +int mbedtls_test_ticket_parse(void *p_ticket, mbedtls_ssl_session *session, + unsigned char *buf, size_t len); +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + #define ECJPAKE_TEST_PWD "bla" #if defined(MBEDTLS_USE_PSA_CRYPTO) diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 2368a7654..b13d7e38b 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -2419,4 +2419,34 @@ int mbedtls_test_tweak_tls13_certificate_msg_vector_len( return 0; } #endif /* MBEDTLS_TEST_HOOKS */ + +/* Functions for session ticket tests */ +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +int mbedtls_test_ticket_write( + void *p_ticket, const mbedtls_ssl_session *session, + unsigned char *start, const unsigned char *end, + size_t *tlen, uint32_t *lifetime) +{ + int ret; + ((void) p_ticket); + + if ((ret = mbedtls_ssl_session_save(session, start, end - start, + tlen)) != 0) { + return ret; + } + + /* Maximum ticket lifetime as defined in RFC 8446 */ + *lifetime = 7 * 24 * 3600; + + return 0; +} + +int mbedtls_test_ticket_parse(void *p_ticket, mbedtls_ssl_session *session, + unsigned char *buf, size_t len) +{ + ((void) p_ticket); + + return mbedtls_ssl_session_load(session, buf, len); +} +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ #endif /* MBEDTLS_SSL_TLS_C */ From d903a86e52f21a65b45fa27699aabfe2d9a8cd81 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 15 Jan 2024 15:57:17 +0100 Subject: [PATCH 142/215] tests: tls13: Add session resume with ticket unit test This aims to provide a basis for negative testing around TLS 1.3 ticket, replacing eventually the negative tests done in ssl-opt.sh using the dummy_ticket option. Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.data | 3 + tests/suites/test_suite_ssl.function | 93 ++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index de998e3ff..37895f0b7 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3270,3 +3270,6 @@ ssl_ecjpake_set_password:1 Test Elliptic curves' info parsing elliptic_curve_get_properties + +TLS 1.3 resume session with ticket +tls13_resume_session_with_ticket diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 8a03d1b97..9ca2058b4 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3519,3 +3519,96 @@ exit: MD_OR_USE_PSA_DONE(); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */ +void tls13_resume_session_with_ticket() +{ + int ret = -1; + unsigned char buf[64]; + mbedtls_test_ssl_endpoint client_ep, server_ep; + mbedtls_test_handshake_test_options client_options; + mbedtls_test_handshake_test_options server_options; + mbedtls_ssl_session saved_session; + + /* + * Test set-up + */ + mbedtls_platform_zeroize(&client_ep, sizeof(client_ep)); + mbedtls_platform_zeroize(&server_ep, sizeof(server_ep)); + mbedtls_test_init_handshake_options(&client_options); + mbedtls_test_init_handshake_options(&server_options); + mbedtls_ssl_session_init(&saved_session); + + MD_OR_USE_PSA_INIT(); + + client_options.pk_alg = MBEDTLS_PK_ECDSA; + ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, + &client_options, NULL, NULL, NULL, + NULL); + TEST_EQUAL(ret, 0); + + server_options.pk_alg = MBEDTLS_PK_ECDSA; + ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, + &server_options, NULL, NULL, NULL, + NULL); + mbedtls_ssl_conf_session_tickets_cb(&server_ep.conf, + mbedtls_test_ticket_write, + mbedtls_test_ticket_parse, + NULL); + TEST_EQUAL(ret, 0); + + ret = mbedtls_test_mock_socket_connect(&(client_ep.socket), + &(server_ep.socket), 1024); + TEST_EQUAL(ret, 0); + + /* + * Run initial handshake: ephemeral key exchange mode, certificate with + * RSA key, signed with PKCS15, verified with PKCS21. Then, get the ticket + * sent by the server at the end of its handshake sequence. + */ + TEST_ASSERT(mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + MBEDTLS_SSL_HANDSHAKE_OVER) == 0); + + do { + ret = mbedtls_ssl_read(&(client_ep.ssl), buf, sizeof(buf)); + } while (ret != MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET); + + /* + * Save client session and reset the SSL context of the two endpoints. + */ + ret = mbedtls_ssl_get_session(&(client_ep.ssl), &saved_session); + TEST_EQUAL(ret, 0); + + ret = mbedtls_ssl_session_reset(&(client_ep.ssl)); + TEST_EQUAL(ret, 0); + + ret = mbedtls_ssl_session_reset(&(server_ep.ssl)); + TEST_EQUAL(ret, 0); + + /* + * Set saved session on client side and handshake using the ticket + * included in that session. + */ + + ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session); + TEST_EQUAL(ret, 0); + + TEST_ASSERT(mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + MBEDTLS_SSL_HANDSHAKE_WRAPUP) == 0); + + TEST_EQUAL(server_ep.ssl.handshake->resume, 1); + TEST_EQUAL(server_ep.ssl.handshake->new_session_tickets_count, 1); + TEST_EQUAL(server_ep.ssl.handshake->key_exchange_mode, + MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL); + +exit: + mbedtls_test_ssl_endpoint_free(&client_ep, NULL); + mbedtls_test_ssl_endpoint_free(&server_ep, NULL); + mbedtls_test_free_handshake_options(&client_options); + mbedtls_test_free_handshake_options(&server_options); + mbedtls_ssl_session_free(&saved_session); + MD_OR_USE_PSA_DONE(); +} +/* END_CASE */ From ec3408d70769163b890ac7bc0c628dde8cc9ae7a Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 16 Jan 2024 17:50:40 +0100 Subject: [PATCH 143/215] tests: ssl: Move setting of debug callback Move the setting of the debug callback to the endpoint initialization function. That way, no need to repeat it in various testing scenarios. Signed-off-by: Ronald Cron --- tests/src/test_helpers/ssl_helpers.c | 39 ++++++++++++++++------------ 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index b13d7e38b..51957463c 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -841,6 +841,23 @@ int mbedtls_test_ssl_endpoint_init( } #endif +#if defined(MBEDTLS_DEBUG_C) +#if defined(MBEDTLS_SSL_SRV_C) + if (endpoint_type == MBEDTLS_SSL_IS_SERVER && + options->srv_log_fun != NULL) { + mbedtls_ssl_conf_dbg(&(ep->conf), options->srv_log_fun, + options->srv_log_obj); + } +#endif +#if defined(MBEDTLS_SSL_CLI_C) + if (endpoint_type == MBEDTLS_SSL_IS_CLIENT && + options->cli_log_fun != NULL) { + mbedtls_ssl_conf_dbg(&(ep->conf), options->cli_log_fun, + options->cli_log_obj); + } +#endif +#endif /* MBEDTLS_DEBUG_C */ + ret = mbedtls_test_ssl_endpoint_certificate_init(ep, options->pk_alg, options->opaque_alg, options->opaque_alg2, @@ -1977,6 +1994,12 @@ void mbedtls_test_ssl_perform_handshake( mbedtls_test_message_socket_init(&server_context); mbedtls_test_message_socket_init(&client_context); +#if defined(MBEDTLS_DEBUG_C) + if (options->cli_log_fun || options->srv_log_fun) { + mbedtls_debug_set_threshold(4); + } +#endif + /* Client side */ if (options->dtls != 0) { TEST_ASSERT(mbedtls_test_ssl_endpoint_init(&client, @@ -2000,14 +2023,6 @@ void mbedtls_test_ssl_perform_handshake( set_ciphersuite(&client.conf, options->cipher, forced_ciphersuite); } -#if defined(MBEDTLS_DEBUG_C) - if (options->cli_log_fun) { - mbedtls_debug_set_threshold(4); - mbedtls_ssl_conf_dbg(&client.conf, options->cli_log_fun, - options->cli_log_obj); - } -#endif - /* Server side */ if (options->dtls != 0) { TEST_ASSERT(mbedtls_test_ssl_endpoint_init(&server, @@ -2072,14 +2087,6 @@ void mbedtls_test_ssl_perform_handshake( } #endif /* MBEDTLS_SSL_RENEGOTIATION */ -#if defined(MBEDTLS_DEBUG_C) - if (options->srv_log_fun) { - mbedtls_debug_set_threshold(4); - mbedtls_ssl_conf_dbg(&server.conf, options->srv_log_fun, - options->srv_log_obj); - } -#endif - TEST_ASSERT(mbedtls_test_mock_socket_connect(&(client.socket), &(server.socket), BUFFSIZE) == 0); From a8dd81b4dee78a4063f33e76702362740298813c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 16 Jan 2024 17:50:52 +0100 Subject: [PATCH 144/215] tests: tls13: Add early data unit test This aims to provide a basis for negative testing around TLS 1.3 early data. Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.data | 3 + tests/suites/test_suite_ssl.function | 157 +++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 37895f0b7..c06c0a746 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -3273,3 +3273,6 @@ elliptic_curve_get_properties TLS 1.3 resume session with ticket tls13_resume_session_with_ticket + +TLS 1.3 early data +tls13_early_data diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 9ca2058b4..a8982495d 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -12,6 +12,48 @@ #define SSL_MESSAGE_QUEUE_INIT { NULL, 0, 0, 0 } +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \ + defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_DEBUG_C) && \ + defined(MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE) && \ + defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) && \ + defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) && \ + defined(MBEDTLS_MD_CAN_SHA256) && \ + defined(MBEDTLS_ECP_HAVE_SECP256R1) && defined(MBEDTLS_ECP_HAVE_SECP384R1) && \ + defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) && defined(MBEDTLS_SSL_SESSION_TICKETS) +/* + * The implementation of the function should be based on + * mbedtls_ssl_write_early_data() eventually. The current version aims at + * removing the dependency on mbedtls_ssl_write_early_data() for the + * development and testing of reading early data. + */ +static int write_early_data(mbedtls_ssl_context *ssl, + unsigned char *buf, size_t len) +{ + int ret = mbedtls_ssl_get_max_out_record_payload(ssl); + + TEST_ASSERT(ret > 0); + TEST_ASSERT(len <= (size_t) ret); + + ret = mbedtls_ssl_flush_output(ssl); + TEST_EQUAL(ret, 0); + TEST_EQUAL(ssl->out_left, 0); + + ssl->out_msglen = len; + ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; + if (len > 0) { + memcpy(ssl->out_msg, buf, len); + } + + ret = mbedtls_ssl_write_record(ssl, 1); + TEST_EQUAL(ret, 0); + + ret = len; + +exit: + return ret; +} +#endif + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -3612,3 +3654,118 @@ exit: MD_OR_USE_PSA_DONE(); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */ +void tls13_early_data() +{ + int ret = -1; + unsigned char buf[64]; + const char *early_data = "This is early data."; + size_t early_data_len = strlen(early_data); + mbedtls_test_ssl_endpoint client_ep, server_ep; + mbedtls_test_handshake_test_options client_options; + mbedtls_test_handshake_test_options server_options; + mbedtls_ssl_session saved_session; + mbedtls_test_ssl_log_pattern server_pattern = { NULL, 0 }; + + /* + * Test set-up + */ + mbedtls_platform_zeroize(&client_ep, sizeof(client_ep)); + mbedtls_platform_zeroize(&server_ep, sizeof(server_ep)); + mbedtls_test_init_handshake_options(&client_options); + mbedtls_test_init_handshake_options(&server_options); + mbedtls_ssl_session_init(&saved_session); + + MD_OR_USE_PSA_INIT(); + + client_options.pk_alg = MBEDTLS_PK_ECDSA; + ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, + &client_options, NULL, NULL, NULL, + NULL); + TEST_EQUAL(ret, 0); + mbedtls_ssl_conf_early_data(&client_ep.conf, MBEDTLS_SSL_EARLY_DATA_ENABLED); + + server_options.pk_alg = MBEDTLS_PK_ECDSA; + server_options.srv_log_fun = mbedtls_test_ssl_log_analyzer; + server_options.srv_log_obj = &server_pattern; + server_pattern.pattern = early_data; + ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, + &server_options, NULL, NULL, NULL, + NULL); + TEST_EQUAL(ret, 0); + mbedtls_ssl_conf_session_tickets_cb(&server_ep.conf, + mbedtls_test_ticket_write, + mbedtls_test_ticket_parse, + NULL); + mbedtls_ssl_conf_early_data(&server_ep.conf, MBEDTLS_SSL_EARLY_DATA_ENABLED); + + ret = mbedtls_test_mock_socket_connect(&(client_ep.socket), + &(server_ep.socket), 1024); + TEST_EQUAL(ret, 0); + + /* + * Run initial handshake: ephemeral key exchange mode, certificate with + * RSA key, signed with PKCS15, verified with PKCS21. Then, get the ticket + * sent by the server at the end of its handshake sequence. + */ + TEST_ASSERT(mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + MBEDTLS_SSL_HANDSHAKE_OVER) == 0); + + do { + ret = mbedtls_ssl_read(&(client_ep.ssl), buf, sizeof(buf)); + } while (ret != MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET); + + /* + * Save client session and reset the SSL context of the two endpoints. + */ + ret = mbedtls_ssl_get_session(&(client_ep.ssl), &saved_session); + TEST_EQUAL(ret, 0); + + ret = mbedtls_ssl_session_reset(&(client_ep.ssl)); + TEST_EQUAL(ret, 0); + + ret = mbedtls_ssl_session_reset(&(server_ep.ssl)); + TEST_EQUAL(ret, 0); + + /* + * Set saved session on client side and start handshake using the ticket + * included in that session. + */ + + ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session); + TEST_EQUAL(ret, 0); + + mbedtls_debug_set_threshold(3); + + TEST_ASSERT(mbedtls_test_move_handshake_to_state( + &(client_ep.ssl), &(server_ep.ssl), + MBEDTLS_SSL_SERVER_HELLO) == 0); + + TEST_ASSERT(client_ep.ssl.early_data_status != + MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); + TEST_EQUAL(server_pattern.counter, 0); + + ret = write_early_data(&(client_ep.ssl), (unsigned char *) early_data, + early_data_len); + TEST_EQUAL(ret, early_data_len); + + TEST_ASSERT(mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + MBEDTLS_SSL_CLIENT_FINISHED) == 0); + + TEST_EQUAL(server_ep.ssl.early_data_status, + MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED); + TEST_EQUAL(server_pattern.counter, 1); + +exit: + mbedtls_test_ssl_endpoint_free(&client_ep, NULL); + mbedtls_test_ssl_endpoint_free(&server_ep, NULL); + mbedtls_test_free_handshake_options(&client_options); + mbedtls_test_free_handshake_options(&server_options); + mbedtls_ssl_session_free(&saved_session); + mbedtls_debug_set_threshold(0); + MD_OR_USE_PSA_DONE(); +} +/* END_CASE */ From f8fdbb517457c5a90d9011a68467da7e8bdf7a22 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 22 Jan 2024 09:13:41 +0100 Subject: [PATCH 145/215] tests: tls13: Run early data test only in TLS 1.3 only config Temporary workaround to not run the early data test in Windows-2013 where there is an issue with mbedtls_vsnprintf(). Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index a8982495d..234181d76 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -12,7 +12,8 @@ #define SSL_MESSAGE_QUEUE_INIT { NULL, 0, 0, 0 } -#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \ +#if (!defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ + defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \ defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_DEBUG_C) && \ defined(MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE) && \ defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) && \ @@ -3655,7 +3656,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */ +/* BEGIN_CASE depends_on:!MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */ void tls13_early_data() { int ret = -1; From 3c129dd6aa54cd83cbeb8c7bb13f8c75752a00dc Mon Sep 17 00:00:00 2001 From: v1gnesh Date: Mon, 22 Jan 2024 15:59:49 +0530 Subject: [PATCH 146/215] Update entropy_poll.c Signed-off-by: v1gnesh --- library/entropy_poll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/entropy_poll.c b/library/entropy_poll.c index de2e0387a..bd21e2d22 100644 --- a/library/entropy_poll.c +++ b/library/entropy_poll.c @@ -29,7 +29,7 @@ #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ - !defined(__HAIKU__) && !defined(__midipix__) + !defined(__HAIKU__) && !defined(__midipix__) && !defined(__MVS__) #error \ "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in mbedtls_config.h" #endif From d0b55edea39b3da311ecb384d7c4d49dd924feb3 Mon Sep 17 00:00:00 2001 From: v1gnesh Date: Mon, 22 Jan 2024 17:13:56 +0530 Subject: [PATCH 147/215] Create 8726.txt changelog entry Signed-off-by: v1gnesh --- ChangeLog.d/8726.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ChangeLog.d/8726.txt diff --git a/ChangeLog.d/8726.txt b/ChangeLog.d/8726.txt new file mode 100644 index 000000000..dc789b434 --- /dev/null +++ b/ChangeLog.d/8726.txt @@ -0,0 +1,3 @@ +Features + * Add platform support for z/OS. + From bf4b5ed7a4e02358cb008bb43c20f5f3c309b7c1 Mon Sep 17 00:00:00 2001 From: Chien Wong Date: Mon, 22 Jan 2024 20:43:54 +0800 Subject: [PATCH 148/215] Add back restriction on AD length of GCM Fixes: bd513bb53d80276431161e5a64a2ae61740c4e68 Signed-off-by: Chien Wong --- library/gcm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/gcm.c b/library/gcm.c index c677ca4d7..b31003f83 100644 --- a/library/gcm.c +++ b/library/gcm.c @@ -354,9 +354,12 @@ int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx, { const unsigned char *p; size_t use_len, offset; + uint64_t new_add_len; - /* IV is limited to 2^64 bits, so 2^61 bytes */ - if ((uint64_t) add_len >> 61 != 0) { + /* AD is limited to 2^64 bits, ie 2^61 bytes + * Also check for possible overflow */ + new_add_len = ctx->add_len + add_len; + if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) { return MBEDTLS_ERR_GCM_BAD_INPUT; } From 858bc65d7485b8af9c49e96d0cf0bf803606a120 Mon Sep 17 00:00:00 2001 From: Chien Wong Date: Mon, 22 Jan 2024 20:47:26 +0800 Subject: [PATCH 149/215] Add comment on impossible overflows Signed-off-by: Chien Wong --- library/gcm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/gcm.c b/library/gcm.c index b31003f83..337145b71 100644 --- a/library/gcm.c +++ b/library/gcm.c @@ -542,6 +542,9 @@ int mbedtls_gcm_finish(mbedtls_gcm_context *ctx, (void) output_size; *output_length = 0; + /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes + * and AD length is restricted to 2^64 bits, ie 2^61 bytes so neither of + * the two multiplications would overflow. */ orig_len = ctx->len * 8; orig_add_len = ctx->add_len * 8; From 1c7629c1c03fcc74781bc448d5b4d5d6ffd7219c Mon Sep 17 00:00:00 2001 From: Jonathan Winzig Date: Tue, 9 Jan 2024 15:19:42 +0100 Subject: [PATCH 150/215] Add tests for Issue #8687 Signed-off-by: Jonathan Winzig --- tests/suites/test_suite_x509write.data | 6 ++++++ tests/suites/test_suite_x509write.function | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data index 0f190286b..f1d4e34a5 100644 --- a/tests/suites/test_suite_x509write.data +++ b/tests/suites/test_suite_x509write.data @@ -265,3 +265,9 @@ mbedtls_x509_string_to_names:"C=NL, 2.5.4.10.234.532=#0C084F6666737061726B, OU=P Check max serial length x509_set_serial_check: + +Check max extension length (Max-1) +x509_set_extension_length_check:0xFFFFFFFE + +Check max extension length (Max) +x509_set_extension_length_check:0xFFFFFFFF \ No newline at end of file diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function index a7ed26295..7ec655727 100644 --- a/tests/suites/test_suite_x509write.function +++ b/tests/suites/test_suite_x509write.function @@ -750,3 +750,24 @@ exit: USE_PSA_DONE(); } /* END_CASE */ + +/* BEGIN_CASE */ +void x509_set_extension_length_check(int val_len) +{ + int ret = 0; + + mbedtls_x509write_csr ctx; + mbedtls_x509write_csr_init(&ctx); + + unsigned char buf[EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH] = { 0 }; + unsigned char *p = buf + sizeof(buf); + + ret = mbedtls_x509_set_extension(&(ctx.MBEDTLS_PRIVATE(extensions)), + MBEDTLS_OID_EXTENDED_KEY_USAGE, + MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE), + 0, + p, + val_len); + TEST_ASSERT(ret == MBEDTLS_ERR_X509_BAD_INPUT_DATA || ret == MBEDTLS_ERR_X509_ALLOC_FAILED); +} +/* END_CASE */ From 63b5e216f8fcaff0f6b87bb05ffd5631158ac3c4 Mon Sep 17 00:00:00 2001 From: Jonathan Winzig Date: Tue, 9 Jan 2024 15:20:03 +0100 Subject: [PATCH 151/215] Fix Issue #8687 Signed-off-by: Jonathan Winzig --- library/x509_create.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/x509_create.c b/library/x509_create.c index 5e732d67f..2c17cb10c 100644 --- a/library/x509_create.c +++ b/library/x509_create.c @@ -380,6 +380,10 @@ int mbedtls_x509_set_extension(mbedtls_asn1_named_data **head, const char *oid, { mbedtls_asn1_named_data *cur; + if (0xFFFFFFFF == (uint32_t) val_len) { + return MBEDTLS_ERR_X509_BAD_INPUT_DATA; + } + if ((cur = mbedtls_asn1_store_named_data(head, oid, oid_len, NULL, val_len + 1)) == NULL) { return MBEDTLS_ERR_X509_ALLOC_FAILED; From a0c9448beaa6df9d4305c6d85fc659f10eb4ee80 Mon Sep 17 00:00:00 2001 From: Jonathan Winzig Date: Tue, 9 Jan 2024 16:41:10 +0100 Subject: [PATCH 152/215] Update fix to be more platform-independent Co-authored-by: David Horstmann Signed-off-by: Jonathan Winzig --- library/x509_create.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/x509_create.c b/library/x509_create.c index 2c17cb10c..751ee08ed 100644 --- a/library/x509_create.c +++ b/library/x509_create.c @@ -380,7 +380,7 @@ int mbedtls_x509_set_extension(mbedtls_asn1_named_data **head, const char *oid, { mbedtls_asn1_named_data *cur; - if (0xFFFFFFFF == (uint32_t) val_len) { + if (val_len > (SIZE_MAX - 1)) { return MBEDTLS_ERR_X509_BAD_INPUT_DATA; } From 93f5240ae594a5f88907a57264a1a73ee1886189 Mon Sep 17 00:00:00 2001 From: Jonathan Winzig Date: Tue, 9 Jan 2024 16:47:12 +0100 Subject: [PATCH 153/215] Add missing newline at the end of test_suite_x509write.data Signed-off-by: Jonathan Winzig --- tests/suites/test_suite_x509write.data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data index f1d4e34a5..6aa0dadb6 100644 --- a/tests/suites/test_suite_x509write.data +++ b/tests/suites/test_suite_x509write.data @@ -270,4 +270,4 @@ Check max extension length (Max-1) x509_set_extension_length_check:0xFFFFFFFE Check max extension length (Max) -x509_set_extension_length_check:0xFFFFFFFF \ No newline at end of file +x509_set_extension_length_check:0xFFFFFFFF From 144bfde1cd10ab6e1647628fe10ead0057395648 Mon Sep 17 00:00:00 2001 From: Jonathan Winzig Date: Tue, 9 Jan 2024 17:39:42 +0100 Subject: [PATCH 154/215] Update test-data to use SIZE_MAX Co-authored-by: David Horstmann Signed-off-by: Jonathan Winzig --- tests/suites/test_suite_x509write.data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data index 6aa0dadb6..e41de849b 100644 --- a/tests/suites/test_suite_x509write.data +++ b/tests/suites/test_suite_x509write.data @@ -270,4 +270,4 @@ Check max extension length (Max-1) x509_set_extension_length_check:0xFFFFFFFE Check max extension length (Max) -x509_set_extension_length_check:0xFFFFFFFF +x509_set_extension_length_check:SIZE_MAX From acd35a55c849ea0de8ffac164801cc75f286a7bd Mon Sep 17 00:00:00 2001 From: Jonathan Winzig Date: Tue, 9 Jan 2024 17:47:10 +0100 Subject: [PATCH 155/215] Remove unneeded testcase Signed-off-by: Jonathan Winzig --- tests/suites/test_suite_x509write.data | 7 ++----- tests/suites/test_suite_x509write.function | 6 +++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data index e41de849b..f63ae2bea 100644 --- a/tests/suites/test_suite_x509write.data +++ b/tests/suites/test_suite_x509write.data @@ -266,8 +266,5 @@ mbedtls_x509_string_to_names:"C=NL, 2.5.4.10.234.532=#0C084F6666737061726B, OU=P Check max serial length x509_set_serial_check: -Check max extension length (Max-1) -x509_set_extension_length_check:0xFFFFFFFE - -Check max extension length (Max) -x509_set_extension_length_check:SIZE_MAX +Check max extension length +x509_set_extension_length_check: diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function index 7ec655727..11b5f2a02 100644 --- a/tests/suites/test_suite_x509write.function +++ b/tests/suites/test_suite_x509write.function @@ -752,7 +752,7 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -void x509_set_extension_length_check(int val_len) +void x509_set_extension_length_check() { int ret = 0; @@ -767,7 +767,7 @@ void x509_set_extension_length_check(int val_len) MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE), 0, p, - val_len); - TEST_ASSERT(ret == MBEDTLS_ERR_X509_BAD_INPUT_DATA || ret == MBEDTLS_ERR_X509_ALLOC_FAILED); + SIZE_MAX); + TEST_ASSERT(MBEDTLS_ERR_X509_BAD_INPUT_DATA == ret); } /* END_CASE */ From af553bf719be37876abe20fbb057fb44b4a6a6e5 Mon Sep 17 00:00:00 2001 From: Jonathan Winzig Date: Tue, 9 Jan 2024 18:31:11 +0100 Subject: [PATCH 156/215] Add required dependency to the testcase Co-authored-by: Paul Elliott <62069445+paul-elliott-arm@users.noreply.github.com> Signed-off-by: Jonathan Winzig --- tests/suites/test_suite_x509write.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function index 11b5f2a02..c557ee00e 100644 --- a/tests/suites/test_suite_x509write.function +++ b/tests/suites/test_suite_x509write.function @@ -751,7 +751,7 @@ exit: } /* END_CASE */ -/* BEGIN_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_X509_CSR_WRITE_C */ void x509_set_extension_length_check() { int ret = 0; From 968a92865966b35334655e65547da5f288722769 Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Tue, 16 Jan 2024 11:16:56 +0000 Subject: [PATCH 157/215] Add Changelog for #8687 Signed-off-by: Paul Elliott --- ChangeLog.d/fix_int_overflow_x509_extension | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 ChangeLog.d/fix_int_overflow_x509_extension diff --git a/ChangeLog.d/fix_int_overflow_x509_extension b/ChangeLog.d/fix_int_overflow_x509_extension new file mode 100644 index 000000000..2a679284f --- /dev/null +++ b/ChangeLog.d/fix_int_overflow_x509_extension @@ -0,0 +1,8 @@ +Security + * Fix a failure to validate input when writing x509 extensions lengths which + could result in an integer overflow, causing a zero-length buffer to be + allocated to hold the extension. The extension would then be copied into + the buffer, causing a heap buffer overflow. + + + From d6b096532c936390d9a085dedb6444cee069a3ba Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 21 Nov 2023 09:33:54 +0000 Subject: [PATCH 158/215] Make RSA unblinding constant flow Signed-off-by: Janos Follath --- library/rsa.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index db0b0f74f..32a26500e 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -28,6 +28,7 @@ #if defined(MBEDTLS_RSA_C) #include "mbedtls/rsa.h" +#include "bignum_core.h" #include "rsa_alt_helpers.h" #include "mbedtls/oid.h" #include "mbedtls/platform_util.h" @@ -969,6 +970,40 @@ cleanup: return ret; } +/* + * Unblind + * T = T * Vf mod N + */ +int rsa_unblind(mbedtls_mpi* T, mbedtls_mpi* Vf, mbedtls_mpi* N) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p); + const size_t nlimbs = N->n; + const size_t tlimbs = mbedtls_mpi_core_montmul_working_limbs(nlimbs); + mbedtls_mpi RR, M_T; + + mbedtls_mpi_init(&RR); + mbedtls_mpi_init(&M_T); + + MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N)); + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&M_T, tlimbs)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(T, nlimbs)); + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Vf, nlimbs)); + + // T = T * R mod N + mbedtls_mpi_core_to_mont_rep(T->p, T->p, N->p, nlimbs, mm, RR.p, M_T.p); + // T = T * Vf mod N + mbedtls_mpi_core_montmul(T->p, T->p, Vf->p, nlimbs, N->p, nlimbs, mm, M_T.p); + +cleanup: + + mbedtls_mpi_free(&RR); + mbedtls_mpi_free(&M_T); + + return ret; +} + /* * Exponent blinding supposed to prevent side-channel attacks using multiple * traces of measurements to recover the RSA key. The more collisions are there, @@ -1160,8 +1195,7 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, * Unblind * T = T * Vf mod N */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &T, &ctx->Vf)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &T, &ctx->N)); + MBEDTLS_MPI_CHK(rsa_unblind(&T, &ctx->Vf, &ctx->N)); /* Verify the result to prevent glitching attacks. */ MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&C, &T, &ctx->E, From 6bcbc925bfe6f56c2d9871e34126cde37181ee14 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 21 Nov 2023 09:46:43 +0000 Subject: [PATCH 159/215] Extend blinding to RSA result check Signed-off-by: Janos Follath --- library/rsa.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index 32a26500e..5b6bf404a 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1113,8 +1113,6 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, goto cleanup; } - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&I, &T)); - /* * Blinding * T = T * Vi mod N @@ -1123,6 +1121,8 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &T, &ctx->Vi)); MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &T, &ctx->N)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&I, &T)); + /* * Exponent blinding */ @@ -1191,12 +1191,6 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&T, &TQ, &TP)); #endif /* MBEDTLS_RSA_NO_CRT */ - /* - * Unblind - * T = T * Vf mod N - */ - MBEDTLS_MPI_CHK(rsa_unblind(&T, &ctx->Vf, &ctx->N)); - /* Verify the result to prevent glitching attacks. */ MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&C, &T, &ctx->E, &ctx->N, &ctx->RN)); @@ -1205,6 +1199,12 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, goto cleanup; } + /* + * Unblind + * T = T * Vf mod N + */ + MBEDTLS_MPI_CHK(rsa_unblind(&T, &ctx->Vf, &ctx->N)); + olen = ctx->len; MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen)); From a865fc951ead31a8f85bbee5d7d11bfa1a28de27 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 21 Nov 2023 09:57:27 +0000 Subject: [PATCH 160/215] Add Changelog for the Marvin attack fix Signed-off-by: Janos Follath --- ChangeLog.d/fix-Marvin-attack.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ChangeLog.d/fix-Marvin-attack.txt diff --git a/ChangeLog.d/fix-Marvin-attack.txt b/ChangeLog.d/fix-Marvin-attack.txt new file mode 100644 index 000000000..f729304ee --- /dev/null +++ b/ChangeLog.d/fix-Marvin-attack.txt @@ -0,0 +1,6 @@ +Security + * Fix a timing side channel in RSA private operations. This side channel + could be sufficient for a local attacker to recover the plaintext. It + requires the attecker to send a large number of messages for decryption. + For details, see "Everlasting ROBOT: the Marvin Attack", Hubert Kario. + Reported by Hubert Kario, Red Hat. From 100dcddfca3c10179bc55e3c3dd82b4a468c6809 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 21 Nov 2023 12:48:52 +0000 Subject: [PATCH 161/215] Make local function static Signed-off-by: Janos Follath --- library/rsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/rsa.c b/library/rsa.c index 5b6bf404a..2dc6dae8d 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -974,7 +974,7 @@ cleanup: * Unblind * T = T * Vf mod N */ -int rsa_unblind(mbedtls_mpi* T, mbedtls_mpi* Vf, mbedtls_mpi* N) +static int rsa_unblind(mbedtls_mpi* T, mbedtls_mpi* Vf, mbedtls_mpi* N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p); From a62a554071a0599bb7522d08c4c605588715e508 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 21 Nov 2023 14:20:08 +0000 Subject: [PATCH 162/215] Fix style Signed-off-by: Janos Follath --- library/rsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/rsa.c b/library/rsa.c index 2dc6dae8d..97e7228da 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -974,7 +974,7 @@ cleanup: * Unblind * T = T * Vf mod N */ -static int rsa_unblind(mbedtls_mpi* T, mbedtls_mpi* Vf, mbedtls_mpi* N) +static int rsa_unblind(mbedtls_mpi *T, mbedtls_mpi *Vf, mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p); From e6750b2a0bf750d35172bdef12c2dcfc28213207 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 27 Dec 2023 10:22:59 +0000 Subject: [PATCH 163/215] RSA: document Montgomery trick in unblind Signed-off-by: Janos Follath --- library/rsa.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index 97e7228da..f57909b71 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -991,9 +991,14 @@ static int rsa_unblind(mbedtls_mpi *T, mbedtls_mpi *Vf, mbedtls_mpi *N) MBEDTLS_MPI_CHK(mbedtls_mpi_grow(T, nlimbs)); MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Vf, nlimbs)); - // T = T * R mod N + /* T = T * Vf mod N + * Reminder: montmul(A, B, N) = A * B * R^-1 mod N + * Usually both operands are multiplied by R mod N beforehand (by calling + * `to_mont_rep()` on them), yielding a result that's also * R mod N (aka + * "in the Montgomery domain"). Here we only multiply one operand by R mod + * N, so the result is directly what we want - no need to call + * `from_mont_rep()` on it. */ mbedtls_mpi_core_to_mont_rep(T->p, T->p, N->p, nlimbs, mm, RR.p, M_T.p); - // T = T * Vf mod N mbedtls_mpi_core_montmul(T->p, T->p, Vf->p, nlimbs, N->p, nlimbs, mm, M_T.p); cleanup: From 47ee7708123347a925aac44709e53a13d1c486e8 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 27 Dec 2023 10:33:00 +0000 Subject: [PATCH 164/215] RSA: remove unneeded temporaries Signed-off-by: Janos Follath --- library/rsa.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index f57909b71..111af680f 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1056,18 +1056,9 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, /* Temporaries holding the blinded exponents for * the mod p resp. mod q computation (if used). */ mbedtls_mpi DP_blind, DQ_blind; - - /* Pointers to actual exponents to be used - either the unblinded - * or the blinded ones, depending on the presence of a PRNG. */ - mbedtls_mpi *DP = &ctx->DP; - mbedtls_mpi *DQ = &ctx->DQ; #else /* Temporary holding the blinded exponent (if used). */ mbedtls_mpi D_blind; - - /* Pointer to actual exponent to be used - either the unblinded - * or the blinded one, depending on the presence of a PRNG. */ - mbedtls_mpi *D = &ctx->D; #endif /* MBEDTLS_RSA_NO_CRT */ /* Temporaries holding the initial input and the double @@ -1143,8 +1134,6 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&D_blind, &P1, &Q1)); MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&D_blind, &D_blind, &R)); MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&D_blind, &D_blind, &ctx->D)); - - D = &D_blind; #else /* * DP_blind = ( P - 1 ) * R + DP @@ -1155,8 +1144,6 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&DP_blind, &DP_blind, &ctx->DP)); - DP = &DP_blind; - /* * DQ_blind = ( Q - 1 ) * R + DQ */ @@ -1165,12 +1152,10 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&DQ_blind, &Q1, &R)); MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&DQ_blind, &DQ_blind, &ctx->DQ)); - - DQ = &DQ_blind; #endif /* MBEDTLS_RSA_NO_CRT */ #if defined(MBEDTLS_RSA_NO_CRT) - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, D, &ctx->N, &ctx->RN)); + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &D_blind, &ctx->N, &ctx->RN)); #else /* * Faster decryption using the CRT @@ -1179,8 +1164,8 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, * TQ = input ^ dQ mod Q */ - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TP, &T, DP, &ctx->P, &ctx->RP)); - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TQ, &T, DQ, &ctx->Q, &ctx->RQ)); + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TP, &T, &DP_blind, &ctx->P, &ctx->RP)); + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TQ, &T, &DQ_blind, &ctx->Q, &ctx->RQ)); /* * T = (TP - TQ) * (Q^-1 mod P) mod P From b4b8f3df3b88fec865d4c2698b94b7f3c08229c1 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 27 Dec 2023 10:44:36 +0000 Subject: [PATCH 165/215] RSA: improve readability Signed-off-by: Janos Follath --- library/rsa.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index 111af680f..0ca0bfead 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -974,7 +974,7 @@ cleanup: * Unblind * T = T * Vf mod N */ -static int rsa_unblind(mbedtls_mpi *T, mbedtls_mpi *Vf, mbedtls_mpi *N) +static int rsa_unblind(mbedtls_mpi *T, mbedtls_mpi *Vf, const mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p); @@ -1063,7 +1063,7 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, /* Temporaries holding the initial input and the double * checked result; should be the same in the end. */ - mbedtls_mpi I, C; + mbedtls_mpi input_blinded, check_result_blinded; if (f_rng == NULL) { return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; @@ -1098,8 +1098,8 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, mbedtls_mpi_init(&TP); mbedtls_mpi_init(&TQ); #endif - mbedtls_mpi_init(&I); - mbedtls_mpi_init(&C); + mbedtls_mpi_init(&input_blinded); + mbedtls_mpi_init(&check_result_blinded); /* End of MPI initialization */ @@ -1117,7 +1117,7 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &T, &ctx->Vi)); MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &T, &ctx->N)); - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&I, &T)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&input_blinded, &T)); /* * Exponent blinding @@ -1182,9 +1182,9 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, #endif /* MBEDTLS_RSA_NO_CRT */ /* Verify the result to prevent glitching attacks. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&C, &T, &ctx->E, + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&check_result_blinded, &T, &ctx->E, &ctx->N, &ctx->RN)); - if (mbedtls_mpi_cmp_mpi(&C, &I) != 0) { + if (mbedtls_mpi_cmp_mpi(&check_result_blinded, &input_blinded) != 0) { ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; goto cleanup; } @@ -1222,8 +1222,8 @@ cleanup: mbedtls_mpi_free(&TP); mbedtls_mpi_free(&TQ); #endif - mbedtls_mpi_free(&C); - mbedtls_mpi_free(&I); + mbedtls_mpi_free(&check_result_blinded); + mbedtls_mpi_free(&input_blinded); if (ret != 0 && ret >= -0x007f) { return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_PRIVATE_FAILED, ret); From 16ab76bbe774806079e2d5cab0c4209a4f7b0602 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 27 Dec 2023 10:47:21 +0000 Subject: [PATCH 166/215] Fix typo Signed-off-by: Janos Follath --- ChangeLog.d/fix-Marvin-attack.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog.d/fix-Marvin-attack.txt b/ChangeLog.d/fix-Marvin-attack.txt index f729304ee..017f7b1f8 100644 --- a/ChangeLog.d/fix-Marvin-attack.txt +++ b/ChangeLog.d/fix-Marvin-attack.txt @@ -1,6 +1,6 @@ Security * Fix a timing side channel in RSA private operations. This side channel could be sufficient for a local attacker to recover the plaintext. It - requires the attecker to send a large number of messages for decryption. + requires the attacker to send a large number of messages for decryption. For details, see "Everlasting ROBOT: the Marvin Attack", Hubert Kario. Reported by Hubert Kario, Red Hat. From 393df9c99512337b403bbe80a3a3cee30f277fc6 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Fri, 29 Dec 2023 11:14:58 +0000 Subject: [PATCH 167/215] Add warning for PKCS 1.5 decryption Any timing variance dependant on the output of this function enables a Bleichenbacher attack. It is extremely difficult to use safely. In the Marvin attack paper (https://people.redhat.com/~hkario/marvin/marvin-attack-paper.pdf) the author suggests that implementations of PKCS 1.5 decryption that don't include a countermeasure should be considered inherently dangerous. They suggest that all libraries implement the same countermeasure, as implementing different countermeasures across libraries enables the Bleichenbacher attack as well. This is extremely fragile and therefore we don't implement it. The use of PKCS 1.5 in Mbed TLS implements the countermeasures recommended in the TLS standard (7.4.7.1 of RFC 5246) and is not vulnerable. Add a warning to PKCS 1.5 decryption to warn users about this. Signed-off-by: Janos Follath --- include/mbedtls/rsa.h | 9 +++++++++ include/psa/crypto_values.h | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h index df665240d..be831f19d 100644 --- a/include/mbedtls/rsa.h +++ b/include/mbedtls/rsa.h @@ -684,6 +684,10 @@ int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx, * It is the generic wrapper for performing a PKCS#1 decryption * operation. * + * \warning When \p ctx->padding is set to #MBEDTLS_RSA_PKCS_V15, + * mbedtls_rsa_rsaes_pkcs1_v15_decrypt() is called, which is an + * inherently dangerous function (CWE-242). + * * \note The output buffer length \c output_max_len should be * as large as the size \p ctx->len of \p ctx->N (for example, * 128 Bytes if RSA-1024 is used) to be able to hold an @@ -720,6 +724,11 @@ int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx, * \brief This function performs a PKCS#1 v1.5 decryption * operation (RSAES-PKCS1-v1_5-DECRYPT). * + * \warning This is an inherently dangerous function (CWE-242). Unless + * it is used in a side channel free and safe way (eg. + * implementing the TLS protocol as per 7.4.7.1 of RFC 5246), + * the calling code is vulnerable. + * * \note The output buffer length \c output_max_len should be * as large as the size \p ctx->len of \p ctx->N, for example, * 128 Bytes if RSA-1024 is used, to be able to hold an diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index 5e33f6bd5..a17879b94 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -1736,6 +1736,13 @@ 0) /** RSA PKCS#1 v1.5 encryption. + * + * \warning Calling psa_asymmetric_decrypt() with this algorithm as a + * parameter is considered an inherently dangerous function + * (CWE-242). Unless it is used in a side channel free and safe + * way (eg. implementing the TLS protocol as per 7.4.7.1 of + * RFC 5246), the calling code is vulnerable. + * */ #define PSA_ALG_RSA_PKCS1V15_CRYPT ((psa_algorithm_t) 0x07000200) From 0d57f1034e2ebd1b29e1adb8620b1f0b16b6fe80 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 11 Jan 2024 14:24:02 +0000 Subject: [PATCH 168/215] Update Marvin fix Changelog entry Upon further consideration we think that a remote attacker close to the victim might be able to have precise enough timing information to exploit the side channel as well. Update the Changelog to reflect this. Signed-off-by: Janos Follath --- ChangeLog.d/fix-Marvin-attack.txt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog.d/fix-Marvin-attack.txt b/ChangeLog.d/fix-Marvin-attack.txt index 017f7b1f8..763533c25 100644 --- a/ChangeLog.d/fix-Marvin-attack.txt +++ b/ChangeLog.d/fix-Marvin-attack.txt @@ -1,6 +1,8 @@ Security - * Fix a timing side channel in RSA private operations. This side channel - could be sufficient for a local attacker to recover the plaintext. It - requires the attacker to send a large number of messages for decryption. - For details, see "Everlasting ROBOT: the Marvin Attack", Hubert Kario. - Reported by Hubert Kario, Red Hat. + * Fix a timing side channel in private key RSA operations. This side channel + could be sufficient for an attacker to recover the plaintext. A local + attacker or a remote attacker who is close to the victim on the network + might have precise enough timing measurements to exploit this. It requires + the attacker to send a large number of messages for decryption. For + details, see "Everlasting ROBOT: the Marvin Attack", Hubert Kario. Reported + by Hubert Kario, Red Hat. From 6ba416968b0c14336141501b90ef9b34ec3a3eff Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 22 Jan 2024 15:40:12 +0000 Subject: [PATCH 169/215] Assemble Changelog Signed-off-by: Dave Rodgman --- ChangeLog | 15 +++++++++++++++ ChangeLog.d/fix-Marvin-attack.txt | 8 -------- ChangeLog.d/fix_int_overflow_x509_extension | 8 -------- 3 files changed, 15 insertions(+), 16 deletions(-) delete mode 100644 ChangeLog.d/fix-Marvin-attack.txt delete mode 100644 ChangeLog.d/fix_int_overflow_x509_extension diff --git a/ChangeLog b/ChangeLog index 28c45f718..28f2654b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ Mbed TLS ChangeLog (Sorted per branch, date) += Mbed TLS 3.5.2 branch released 2024-01-26 + +Security + * Fix a timing side channel in private key RSA operations. This side channel + could be sufficient for an attacker to recover the plaintext. A local + attacker or a remote attacker who is close to the victim on the network + might have precise enough timing measurements to exploit this. It requires + the attacker to send a large number of messages for decryption. For + details, see "Everlasting ROBOT: the Marvin Attack", Hubert Kario. Reported + by Hubert Kario, Red Hat. + * Fix a failure to validate input when writing x509 extensions lengths which + could result in an integer overflow, causing a zero-length buffer to be + allocated to hold the extension. The extension would then be copied into + the buffer, causing a heap buffer overflow. + = Mbed TLS 3.5.1 branch released 2023-11-06 Changes diff --git a/ChangeLog.d/fix-Marvin-attack.txt b/ChangeLog.d/fix-Marvin-attack.txt deleted file mode 100644 index 763533c25..000000000 --- a/ChangeLog.d/fix-Marvin-attack.txt +++ /dev/null @@ -1,8 +0,0 @@ -Security - * Fix a timing side channel in private key RSA operations. This side channel - could be sufficient for an attacker to recover the plaintext. A local - attacker or a remote attacker who is close to the victim on the network - might have precise enough timing measurements to exploit this. It requires - the attacker to send a large number of messages for decryption. For - details, see "Everlasting ROBOT: the Marvin Attack", Hubert Kario. Reported - by Hubert Kario, Red Hat. diff --git a/ChangeLog.d/fix_int_overflow_x509_extension b/ChangeLog.d/fix_int_overflow_x509_extension deleted file mode 100644 index 2a679284f..000000000 --- a/ChangeLog.d/fix_int_overflow_x509_extension +++ /dev/null @@ -1,8 +0,0 @@ -Security - * Fix a failure to validate input when writing x509 extensions lengths which - could result in an integer overflow, causing a zero-length buffer to be - allocated to hold the extension. The extension would then be copied into - the buffer, causing a heap buffer overflow. - - - From e23d6479cc5925fa6221d3ca010334ad18302f4e Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 22 Jan 2024 15:45:49 +0000 Subject: [PATCH 170/215] Bump version ./scripts/bump_version.sh --version 3.5.1 Signed-off-by: Dave Rodgman --- CMakeLists.txt | 2 +- doxygen/input/doc_mainpage.h | 2 +- doxygen/mbedtls.doxyfile | 2 +- include/mbedtls/build_info.h | 8 ++++---- library/CMakeLists.txt | 6 +++--- tests/suites/test_suite_version.data | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87a41d75c..4321db8c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -377,7 +377,7 @@ if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL) write_basic_package_version_file( "cmake/MbedTLSConfigVersion.cmake" COMPATIBILITY SameMajorVersion - VERSION 3.5.1) + VERSION 3.5.2) install( FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/MbedTLSConfig.cmake" diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h index c391c59ce..17762d726 100644 --- a/doxygen/input/doc_mainpage.h +++ b/doxygen/input/doc_mainpage.h @@ -10,7 +10,7 @@ */ /** - * @mainpage Mbed TLS v3.5.1 API Documentation + * @mainpage Mbed TLS v3.5.2 API Documentation * * This documentation describes the internal structure of Mbed TLS. It was * automatically generated from specially formatted comment blocks in diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile index 89048f221..cbbb7597f 100644 --- a/doxygen/mbedtls.doxyfile +++ b/doxygen/mbedtls.doxyfile @@ -1,4 +1,4 @@ -PROJECT_NAME = "Mbed TLS v3.5.1" +PROJECT_NAME = "Mbed TLS v3.5.2" OUTPUT_DIRECTORY = ../apidoc/ FULL_PATH_NAMES = NO OPTIMIZE_OUTPUT_FOR_C = YES diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h index c4fab1205..87e3c2ea1 100644 --- a/include/mbedtls/build_info.h +++ b/include/mbedtls/build_info.h @@ -26,16 +26,16 @@ */ #define MBEDTLS_VERSION_MAJOR 3 #define MBEDTLS_VERSION_MINOR 5 -#define MBEDTLS_VERSION_PATCH 1 +#define MBEDTLS_VERSION_PATCH 2 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x03050100 -#define MBEDTLS_VERSION_STRING "3.5.1" -#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.5.1" +#define MBEDTLS_VERSION_NUMBER 0x03050200 +#define MBEDTLS_VERSION_STRING "3.5.2" +#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.5.2" /* Macros for build-time platform detection */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index eeda06aee..fcd00a0ab 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -296,7 +296,7 @@ endif(USE_STATIC_MBEDTLS_LIBRARY) if(USE_SHARED_MBEDTLS_LIBRARY) set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR}) add_library(${mbedcrypto_target} SHARED ${src_crypto}) - set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.5.1 SOVERSION 15) + set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 3.5.2 SOVERSION 15) target_link_libraries(${mbedcrypto_target} PUBLIC ${libs}) if(TARGET ${everest_target}) @@ -308,11 +308,11 @@ if(USE_SHARED_MBEDTLS_LIBRARY) endif() add_library(${mbedx509_target} SHARED ${src_x509}) - set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.5.1 SOVERSION 6) + set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.5.2 SOVERSION 6) target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target}) add_library(${mbedtls_target} SHARED ${src_tls}) - set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.5.1 SOVERSION 20) + set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.5.2 SOVERSION 20) target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target}) endif(USE_SHARED_MBEDTLS_LIBRARY) diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data index faa31662a..6290331c1 100644 --- a/tests/suites/test_suite_version.data +++ b/tests/suites/test_suite_version.data @@ -1,8 +1,8 @@ Check compile time library version -check_compiletime_version:"3.5.1" +check_compiletime_version:"3.5.2" Check runtime library version -check_runtime_version:"3.5.1" +check_runtime_version:"3.5.2" Check for MBEDTLS_VERSION_C check_feature:"MBEDTLS_VERSION_C":0 From 00b530e3957061a06663e1785dc923ee0b7e7c95 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 23 Jan 2024 09:36:34 +0000 Subject: [PATCH 171/215] Limit compiler hint to compilers that are known to benefit from it Signed-off-by: Dave Rodgman --- library/common.h | 50 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/library/common.h b/library/common.h index 2eb917037..937c80284 100644 --- a/library/common.h +++ b/library/common.h @@ -199,30 +199,40 @@ static inline void mbedtls_xor(unsigned char *r, uint8x16_t x = veorq_u8(v1, v2); vst1q_u8(r + i, x); } +#if defined(__IAR_SYSTEMS_ICC__) /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case * where n is a constant multiple of 16. - * It makes no difference for others (e.g. recent gcc and clang) if n is a compile-time - * constant, and very little difference if n is not a compile-time constant. */ - if (n % 16 != 0) + * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time + * constant, and is a very small perf regression if n is not a compile-time constant. */ + if (n % 16 == 0) { + return; + } +#endif #elif defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64) /* This codepath probably only makes sense on architectures with 64-bit registers */ for (; (i + 8) <= n; i += 8) { uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i); mbedtls_put_unaligned_uint64(r + i, x); } - if (n % 8 != 0) +#if defined(__IAR_SYSTEMS_ICC__) + if (n % 8 == 0) { + return; + } +#endif #else for (; (i + 4) <= n; i += 4) { uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); mbedtls_put_unaligned_uint32(r + i, x); } - if (n % 4 != 0) +#if defined(__IAR_SYSTEMS_ICC__) + if (n % 4 == 0) { + return; + } #endif #endif - { - for (; i < n; i++) { - r[i] = a[i] ^ b[i]; - } +#endif + for (; i < n; i++) { + r[i] = a[i] ^ b[i]; } } @@ -268,23 +278,29 @@ static inline void mbedtls_xor_no_simd(unsigned char *r, uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i); mbedtls_put_unaligned_uint64(r + i, x); } +#if defined(__IAR_SYSTEMS_ICC__) /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case * where n is a constant multiple of 16. - * It makes no difference for others (e.g. recent gcc and clang) if n is a compile-time - * constant, and very little difference if n is not a compile-time constant. */ - if (n % 8 != 0) + * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time + * constant, and is a very small perf regression if n is not a compile-time constant. */ + if (n % 8 == 0) { + return; + } +#endif #else for (; (i + 4) <= n; i += 4) { uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); mbedtls_put_unaligned_uint32(r + i, x); } - if (n % 4 != 0) +#if defined(__IAR_SYSTEMS_ICC__) + if (n % 4 == 0) { + return; + } #endif #endif - { - for (; i < n; i++) { - r[i] = a[i] ^ b[i]; - } +#endif + for (; i < n; i++) { + r[i] = a[i] ^ b[i]; } } From 468c02cf617234626c4008aae821f7245ec14117 Mon Sep 17 00:00:00 2001 From: v1gnesh Date: Tue, 23 Jan 2024 15:29:40 +0530 Subject: [PATCH 172/215] Update ChangeLog.d/8726.txt Co-authored-by: Janos Follath Signed-off-by: v1gnesh --- ChangeLog.d/8726.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ChangeLog.d/8726.txt b/ChangeLog.d/8726.txt index dc789b434..c1e5a4015 100644 --- a/ChangeLog.d/8726.txt +++ b/ChangeLog.d/8726.txt @@ -1,3 +1,2 @@ Features - * Add platform support for z/OS. - + * Add partial platform support for z/OS. From c64280a2d71f6e88835787b2121857f063af7029 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 23 Jan 2024 10:03:22 +0000 Subject: [PATCH 173/215] Fix comment typo Signed-off-by: Dave Rodgman --- library/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/common.h b/library/common.h index 937c80284..3936ffdfe 100644 --- a/library/common.h +++ b/library/common.h @@ -280,7 +280,7 @@ static inline void mbedtls_xor_no_simd(unsigned char *r, } #if defined(__IAR_SYSTEMS_ICC__) /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case - * where n is a constant multiple of 16. + * where n is a constant multiple of 8. * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time * constant, and is a very small perf regression if n is not a compile-time constant. */ if (n % 8 == 0) { From 019c2a7817c702f5d7826bc14badf2a5c7a36c4d Mon Sep 17 00:00:00 2001 From: Chien Wong Date: Tue, 23 Jan 2024 21:38:06 +0800 Subject: [PATCH 174/215] Handle sizeof(size_t) > sizeof(uint64_t) Signed-off-by: Chien Wong --- library/gcm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/library/gcm.c b/library/gcm.c index 337145b71..033cb5901 100644 --- a/library/gcm.c +++ b/library/gcm.c @@ -358,7 +358,12 @@ int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx, /* AD is limited to 2^64 bits, ie 2^61 bytes * Also check for possible overflow */ - new_add_len = ctx->add_len + add_len; +#if SIZE_MAX > 0xFFFFFFFFFFFFFFFFULL + if (add_len > 0xFFFFFFFFFFFFFFFFULL) { + return MBEDTLS_ERR_GCM_BAD_INPUT; + } +#endif + new_add_len = ctx->add_len + (uint64_t) add_len; if (new_add_len < ctx->add_len || new_add_len >> 61 != 0) { return MBEDTLS_ERR_GCM_BAD_INPUT; } From d6d6a76e46526a396bc2fb4a2b0ab239b26db5d6 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 23 Jan 2024 18:24:21 +0000 Subject: [PATCH 175/215] Add ..._GOTO_RETURN macro Signed-off-by: Ryan Everett --- library/psa_crypto_core.h | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 7b167248e..85eeb1a6d 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -20,6 +20,9 @@ #include "psa/crypto.h" #include "psa/crypto_se_driver.h" +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif /** * Tell if PSA is ready for this hash. @@ -111,6 +114,50 @@ typedef struct { } key; } psa_key_slot_t; +typedef enum { + PSA_MUTEX_LOCK = 0, + PSA_MUTEX_UNLOCK, +} psa_mutex_operation_t; + +/** If threading is enabled: perform a lock or unlock operation on the + * key slot mutex. + * Call with parameter PSA_MUTEX_LOCK to perform a lock operation. + * Call with parameter PSA_MUTEX_UNLOCK to perform an unlock operation. + * Returns PSA_ERROR_SERVICE_FAILURE if the operation fails + * and status was PSA_SUCCESS. + * If threading is not enabled, do nothing. + * + * Assumptions: + * psa_status_t status exists. + * op is PSA_MUTEX_LOCK or PSA_MUTEX_UNLOCK. + */ +#if defined(MBEDTLS_THREADING_C) +#define PSA_KEY_SLOT_MUTEX_LOCKFUNC_RETURN(op) \ + do \ + { \ + if (op == PSA_MUTEX_LOCK) { \ + if (mbedtls_mutex_lock( \ + &mbedtls_threading_key_slot_mutex) != 0) { \ + if (status == PSA_SUCCESS) { \ + return PSA_ERROR_SERVICE_FAILURE; \ + } \ + return status; \ + } \ + } \ + if (op == PSA_MUTEX_UNLOCK) { \ + if (mbedtls_mutex_unlock( \ + &mbedtls_threading_key_slot_mutex) != 0) { \ + if (status == PSA_SUCCESS) { \ + return PSA_ERROR_SERVICE_FAILURE; \ + } \ + return status; \ + } \ + } \ + } while (0); +#else +#define PSA_KEY_SLOT_MUTEX_LOCKFUNC_RETURN(op) do { } while (0) +#endif + /* A mask of key attribute flags used only internally. * Currently there aren't any. */ #define PSA_KA_MASK_INTERNAL_ONLY ( \ From 90afb132e067b57a2bbc12c986ac5112e91fc201 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 23 Jan 2024 18:24:36 +0000 Subject: [PATCH 176/215] Add ..._GOTO_EXIT macro Signed-off-by: Ryan Everett --- library/psa_crypto_core.h | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 85eeb1a6d..8b5ac26c6 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -158,6 +158,46 @@ typedef enum { #define PSA_KEY_SLOT_MUTEX_LOCKFUNC_RETURN(op) do { } while (0) #endif +/** If threading is enabled: perform a lock or unlock operation on the + * key slot mutex. + * Call with parameter PSA_MUTEX_LOCK to perform a lock operation. + * Call with parameter PSA_MUTEX_UNLOCK to perform an unlock operation. + * This will goto the exit label if the operation fails, + * setting status to PSA_SERVICE_FAILURE if status was PSA_SUCCESS. + * If threading is not enabled, do nothing. + * + * Assumptions: + * psa_status_t status exists. + * Label exit: exists. + * op is PSA_MUTEX_LOCK or PSA_MUTEX_UNLOCK. + */ +#if defined(MBEDTLS_THREADING_C) +#define PSA_KEY_SLOT_MUTEX_LOCKFUNC_GOTO_EXIT(op) \ + do \ + { \ + if (op == PSA_MUTEX_LOCK) { \ + if (mbedtls_mutex_lock( \ + &mbedtls_threading_key_slot_mutex) != 0) { \ + if (status == PSA_SUCCESS) { \ + status = PSA_ERROR_SERVICE_FAILURE; \ + } \ + goto exit; \ + } \ + } \ + if (op == PSA_MUTEX_UNLOCK) { \ + if (mbedtls_mutex_unlock( \ + &mbedtls_threading_key_slot_mutex) != 0) { \ + if (status == PSA_SUCCESS) { \ + status = PSA_ERROR_SERVICE_FAILURE; \ + } \ + goto exit; \ + } \ + } \ + } while (0); +#else +#define PSA_KEY_SLOT_MUTEX_LOCKFUNC_GOTO_EXIT(op) do { } while (0) +#endif + /* A mask of key attribute flags used only internally. * Currently there aren't any. */ #define PSA_KA_MASK_INTERNAL_ONLY ( \ From cb05ce30e990f7e60c47b18af95cf21c8213a614 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Tue, 23 Jan 2024 19:25:10 +0000 Subject: [PATCH 177/215] Minor fixes to locking macros Signed-off-by: Ryan Everett --- library/psa_crypto_core.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 8b5ac26c6..0e9f83fae 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -144,7 +144,7 @@ typedef enum { return status; \ } \ } \ - if (op == PSA_MUTEX_UNLOCK) { \ + else if (op == PSA_MUTEX_UNLOCK) { \ if (mbedtls_mutex_unlock( \ &mbedtls_threading_key_slot_mutex) != 0) { \ if (status == PSA_SUCCESS) { \ @@ -163,7 +163,7 @@ typedef enum { * Call with parameter PSA_MUTEX_LOCK to perform a lock operation. * Call with parameter PSA_MUTEX_UNLOCK to perform an unlock operation. * This will goto the exit label if the operation fails, - * setting status to PSA_SERVICE_FAILURE if status was PSA_SUCCESS. + * setting status to PSA_ERROR_SERVICE_FAILURE if status was PSA_SUCCESS. * If threading is not enabled, do nothing. * * Assumptions: @@ -184,7 +184,7 @@ typedef enum { goto exit; \ } \ } \ - if (op == PSA_MUTEX_UNLOCK) { \ + else if (op == PSA_MUTEX_UNLOCK) { \ if (mbedtls_mutex_unlock( \ &mbedtls_threading_key_slot_mutex) != 0) { \ if (status == PSA_SUCCESS) { \ From daca7a3979c22da155ec9dce49ab1abf3b65d3a9 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 24 Jan 2024 09:49:11 +0000 Subject: [PATCH 178/215] Update BRANCHES.md Signed-off-by: Dave Rodgman --- BRANCHES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BRANCHES.md b/BRANCHES.md index c085b1616..b71247f3e 100644 --- a/BRANCHES.md +++ b/BRANCHES.md @@ -106,6 +106,6 @@ The following branches are currently maintained: - [`development`](https://github.com/Mbed-TLS/mbedtls/) - [`mbedtls-2.28`](https://github.com/Mbed-TLS/mbedtls/tree/mbedtls-2.28) maintained until at least the end of 2024, see - . + . Users are urged to always use the latest version of a maintained branch. From 99ff1f505b706006c75c3d2047e7b19ed5f6ac81 Mon Sep 17 00:00:00 2001 From: Chien Wong Date: Wed, 24 Jan 2024 20:44:01 +0800 Subject: [PATCH 179/215] Add test cases on GCM AD, input, IV length Signed-off-by: Chien Wong --- tests/suites/test_suite_gcm.function | 107 ++++++++++++++++++++++++++ tests/suites/test_suite_gcm.misc.data | 12 +++ 2 files changed, 119 insertions(+) diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function index 599c9266e..07a6e4593 100644 --- a/tests/suites/test_suite_gcm.function +++ b/tests/suites/test_suite_gcm.function @@ -153,6 +153,20 @@ exit: mbedtls_free(output); } +static void gcm_reset_ctx(mbedtls_gcm_context *ctx, const uint8_t *key, + size_t key_bits, const uint8_t *iv, size_t iv_len, + int starts_ret) +{ + int mode = MBEDTLS_GCM_ENCRYPT; + mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES; + + mbedtls_gcm_init(ctx); + TEST_EQUAL(mbedtls_gcm_setkey(ctx, valid_cipher, key, key_bits), 0); + TEST_EQUAL(starts_ret, mbedtls_gcm_starts(ctx, mode, iv, iv_len)); +exit: + /* empty */ +} + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -478,6 +492,99 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void gcm_invalid_iv_len(void) +{ + mbedtls_gcm_context ctx; + uint8_t b16[16] = { 0 }; + + gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, 0, MBEDTLS_ERR_GCM_BAD_INPUT); + mbedtls_gcm_free(&ctx); + +#if SIZE_MAX >= UINT64_MAX + gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, 1ULL << 61, MBEDTLS_ERR_GCM_BAD_INPUT); + mbedtls_gcm_free(&ctx); +#endif + + goto exit; /* To suppress error that exit is defined but not used */ +exit: + /* empty */ +} +/* END_CASE */ + +/* BEGIN_CASE */ +/* + * Test if GCM rejects total ad_len >= 2^61 bytes. + * Also test if GCM handles potential total ad_len overflow properly. + + * Only testable on platforms where sizeof(size_t) >= 8. + */ +void gcm_add_len_too_long(void) +{ +#if SIZE_MAX >= UINT64_MAX + mbedtls_gcm_context ctx; + uint8_t b16[16] = { 0 }; + + gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); + TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, 1ULL << 61), + MBEDTLS_ERR_GCM_BAD_INPUT); + mbedtls_gcm_free(&ctx); + + gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); + TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, 1), 0); + TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, (1ULL << 61) - 1), + MBEDTLS_ERR_GCM_BAD_INPUT); + mbedtls_gcm_free(&ctx); + + gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); + TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, 1), 0); + TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, UINT64_MAX), MBEDTLS_ERR_GCM_BAD_INPUT); + +exit: + mbedtls_gcm_free(&ctx); +#endif +} +/* END_CASE */ + +/* BEGIN_CASE */ +/* + * Test if GCM rejects total input length > 2^36 - 32 bytes. + * Also test if GCM handles potential total input length overflow properly. + + * Only testable on platforms where sizeof(size_t) >= 8. + */ +void gcm_input_len_too_long(void) +{ +#if SIZE_MAX >= UINT64_MAX + mbedtls_gcm_context ctx; + uint8_t b16[16] = { 0 }; + size_t out_len; + uint64_t len_max = (1ULL << 36) - 32; + + gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); + TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max + 1, b16, len_max + 1, + &out_len), + MBEDTLS_ERR_GCM_BAD_INPUT); + mbedtls_gcm_free(&ctx); + + gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); + TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, b16, 1, &out_len), 0); + TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max, b16, len_max, &out_len), + MBEDTLS_ERR_GCM_BAD_INPUT); + mbedtls_gcm_free(&ctx); + + gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); + TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, b16, 1, &out_len), 0); + TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, UINT64_MAX, b16, UINT64_MAX, + &out_len), + MBEDTLS_ERR_GCM_BAD_INPUT); + +exit: + mbedtls_gcm_free(&ctx); +#endif +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST:MBEDTLS_CCM_GCM_CAN_AES */ void gcm_selftest() { diff --git a/tests/suites/test_suite_gcm.misc.data b/tests/suites/test_suite_gcm.misc.data index f22b7a3b7..57f05caf5 100644 --- a/tests/suites/test_suite_gcm.misc.data +++ b/tests/suites/test_suite_gcm.misc.data @@ -1,2 +1,14 @@ GCM - Invalid parameters gcm_invalid_param: + +GCM - Invalid IV length +depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +gcm_invalid_iv_len: + +GCM - Additional data length too long +depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +gcm_add_len_too_long: + +GCM - Input length too long +depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +gcm_input_len_too_long: From 3877d4858b666b6596743a8fcfdb7b1c6ea54ec5 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Wed, 24 Jan 2024 13:26:26 +0000 Subject: [PATCH 180/215] Refactor macros Signed-off-by: Ryan Everett --- library/psa_crypto_core.h | 93 +++++++++++---------------------------- 1 file changed, 26 insertions(+), 67 deletions(-) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 0e9f83fae..dc376d7eb 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -114,88 +114,47 @@ typedef struct { } key; } psa_key_slot_t; -typedef enum { - PSA_MUTEX_LOCK = 0, - PSA_MUTEX_UNLOCK, -} psa_mutex_operation_t; +#if defined(MBEDTLS_THREADING_C) -/** If threading is enabled: perform a lock or unlock operation on the - * key slot mutex. - * Call with parameter PSA_MUTEX_LOCK to perform a lock operation. - * Call with parameter PSA_MUTEX_UNLOCK to perform an unlock operation. +/** Perform a mutex operation and return immediately upon failure. + * * Returns PSA_ERROR_SERVICE_FAILURE if the operation fails * and status was PSA_SUCCESS. - * If threading is not enabled, do nothing. * * Assumptions: * psa_status_t status exists. - * op is PSA_MUTEX_LOCK or PSA_MUTEX_UNLOCK. + * f is a mutex operation which returns 0 upon success. */ -#if defined(MBEDTLS_THREADING_C) -#define PSA_KEY_SLOT_MUTEX_LOCKFUNC_RETURN(op) \ - do \ - { \ - if (op == PSA_MUTEX_LOCK) { \ - if (mbedtls_mutex_lock( \ - &mbedtls_threading_key_slot_mutex) != 0) { \ - if (status == PSA_SUCCESS) { \ - return PSA_ERROR_SERVICE_FAILURE; \ - } \ - return status; \ - } \ - } \ - else if (op == PSA_MUTEX_UNLOCK) { \ - if (mbedtls_mutex_unlock( \ - &mbedtls_threading_key_slot_mutex) != 0) { \ - if (status == PSA_SUCCESS) { \ - return PSA_ERROR_SERVICE_FAILURE; \ - } \ - return status; \ - } \ - } \ +#define PSA_THREADING_CHK_RET(f) \ + do \ + { \ + if ((f) != 0) { \ + if (status == PSA_SUCCESS) { \ + return PSA_ERROR_SERVICE_FAILURE; \ + } \ + return status; \ + } \ } while (0); -#else -#define PSA_KEY_SLOT_MUTEX_LOCKFUNC_RETURN(op) do { } while (0) -#endif -/** If threading is enabled: perform a lock or unlock operation on the - * key slot mutex. - * Call with parameter PSA_MUTEX_LOCK to perform a lock operation. - * Call with parameter PSA_MUTEX_UNLOCK to perform an unlock operation. - * This will goto the exit label if the operation fails, - * setting status to PSA_ERROR_SERVICE_FAILURE if status was PSA_SUCCESS. - * If threading is not enabled, do nothing. +/** Perform a mutex operation and goto exit on failure. + * + * Sets status to PSA_ERROR_SERVICE_FAILURE if status was PSA_SUCCESS. * * Assumptions: * psa_status_t status exists. * Label exit: exists. - * op is PSA_MUTEX_LOCK or PSA_MUTEX_UNLOCK. + * f is a mutex operation which returns 0 upon success. */ -#if defined(MBEDTLS_THREADING_C) -#define PSA_KEY_SLOT_MUTEX_LOCKFUNC_GOTO_EXIT(op) \ - do \ - { \ - if (op == PSA_MUTEX_LOCK) { \ - if (mbedtls_mutex_lock( \ - &mbedtls_threading_key_slot_mutex) != 0) { \ - if (status == PSA_SUCCESS) { \ - status = PSA_ERROR_SERVICE_FAILURE; \ - } \ - goto exit; \ - } \ - } \ - else if (op == PSA_MUTEX_UNLOCK) { \ - if (mbedtls_mutex_unlock( \ - &mbedtls_threading_key_slot_mutex) != 0) { \ - if (status == PSA_SUCCESS) { \ - status = PSA_ERROR_SERVICE_FAILURE; \ - } \ - goto exit; \ - } \ - } \ +#define PSA_THREADING_CHK_GOTO_EXIT(f) \ + do \ + { \ + if ((f) != 0) { \ + if (status == PSA_SUCCESS) { \ + status = PSA_ERROR_SERVICE_FAILURE; \ + } \ + goto exit; \ + } \ } while (0); -#else -#define PSA_KEY_SLOT_MUTEX_LOCKFUNC_GOTO_EXIT(op) do { } while (0) #endif /* A mask of key attribute flags used only internally. From 92c17c456c6cef1058598062b207c032d8b9fad3 Mon Sep 17 00:00:00 2001 From: Chien Wong Date: Thu, 25 Jan 2024 19:11:03 +0800 Subject: [PATCH 181/215] Use separate input/output buffer. Explain why error is expected Signed-off-by: Chien Wong --- tests/suites/test_suite_gcm.function | 43 ++++++++++++++++------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function index 07a6e4593..e23d8d03d 100644 --- a/tests/suites/test_suite_gcm.function +++ b/tests/suites/test_suite_gcm.function @@ -493,15 +493,20 @@ exit: /* END_CASE */ /* BEGIN_CASE */ +/* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of IV should + * satisfy 1 <= bit_len(IV) <= 2^64 - 1. */ void gcm_invalid_iv_len(void) { mbedtls_gcm_context ctx; uint8_t b16[16] = { 0 }; + // Invalid IV length 0 gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, 0, MBEDTLS_ERR_GCM_BAD_INPUT); mbedtls_gcm_free(&ctx); + // Only testable on platforms where sizeof(size_t) >= 8. #if SIZE_MAX >= UINT64_MAX + // Invalid IV length 2^61 gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, 1ULL << 61, MBEDTLS_ERR_GCM_BAD_INPUT); mbedtls_gcm_free(&ctx); #endif @@ -513,30 +518,31 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -/* - * Test if GCM rejects total ad_len >= 2^61 bytes. - * Also test if GCM handles potential total ad_len overflow properly. - - * Only testable on platforms where sizeof(size_t) >= 8. - */ void gcm_add_len_too_long(void) { + // Only testable on platforms where sizeof(size_t) >= 8. #if SIZE_MAX >= UINT64_MAX mbedtls_gcm_context ctx; uint8_t b16[16] = { 0 }; + /* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of AD should + * be <= 2^64 - 1, ie < 2^64. This is the minimum invalid length in bytes. */ + uint64_t len_max = 1ULL << 61; gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); - TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, 1ULL << 61), + // Feed AD that just exceeds the length limit + TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, len_max), MBEDTLS_ERR_GCM_BAD_INPUT); mbedtls_gcm_free(&ctx); gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); + // Feed AD that just exceeds the length limit in two calls TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, 1), 0); - TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, (1ULL << 61) - 1), + TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, len_max - 1), MBEDTLS_ERR_GCM_BAD_INPUT); mbedtls_gcm_free(&ctx); gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); + // Test if potential total AD length overflow is handled properly TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, 1), 0); TEST_EQUAL(mbedtls_gcm_update_ad(&ctx, b16, UINT64_MAX), MBEDTLS_ERR_GCM_BAD_INPUT); @@ -547,35 +553,36 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -/* - * Test if GCM rejects total input length > 2^36 - 32 bytes. - * Also test if GCM handles potential total input length overflow properly. - - * Only testable on platforms where sizeof(size_t) >= 8. - */ void gcm_input_len_too_long(void) { + // Only testable on platforms where sizeof(size_t) >= 8 #if SIZE_MAX >= UINT64_MAX mbedtls_gcm_context ctx; uint8_t b16[16] = { 0 }; + uint8_t out[1]; size_t out_len; + /* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of input should + * be <= 2^39 - 256. This is the maximum valid length in bytes. */ uint64_t len_max = (1ULL << 36) - 32; gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); - TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max + 1, b16, len_max + 1, + // Feed input that just exceeds the length limit + TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max + 1, out, len_max + 1, &out_len), MBEDTLS_ERR_GCM_BAD_INPUT); mbedtls_gcm_free(&ctx); gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); - TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, b16, 1, &out_len), 0); + // Feed input that just exceeds the length limit in two calls + TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, out, 1, &out_len), 0); TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max, b16, len_max, &out_len), MBEDTLS_ERR_GCM_BAD_INPUT); mbedtls_gcm_free(&ctx); gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); - TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, b16, 1, &out_len), 0); - TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, UINT64_MAX, b16, UINT64_MAX, + // Test if potential total input length overflow is handled properly + TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, out, 1, &out_len), 0); + TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, UINT64_MAX, out, UINT64_MAX, &out_len), MBEDTLS_ERR_GCM_BAD_INPUT); From ef56795fd273b36a712dde7987a10fd54065ec79 Mon Sep 17 00:00:00 2001 From: Chien Wong Date: Thu, 25 Jan 2024 19:22:50 +0800 Subject: [PATCH 182/215] Fix 1 forgotten separate input/output buffer Signed-off-by: Chien Wong --- tests/suites/test_suite_gcm.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function index e23d8d03d..dac2a5df2 100644 --- a/tests/suites/test_suite_gcm.function +++ b/tests/suites/test_suite_gcm.function @@ -575,7 +575,7 @@ void gcm_input_len_too_long(void) gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, sizeof(b16), 0); // Feed input that just exceeds the length limit in two calls TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, 1, out, 1, &out_len), 0); - TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max, b16, len_max, &out_len), + TEST_EQUAL(mbedtls_gcm_update(&ctx, b16, len_max, out, len_max, &out_len), MBEDTLS_ERR_GCM_BAD_INPUT); mbedtls_gcm_free(&ctx); From da2a33de0f2d0f7f179220d1a92f788d1459c3e3 Mon Sep 17 00:00:00 2001 From: Sergei Trofimovich Date: Thu, 25 Jan 2024 20:48:56 +0000 Subject: [PATCH 183/215] tests: fix `calloc()` argument list (`gcc-14` fix) `gcc-14` added a new `-Wcalloc-transposed-args` warning recently. It detected minor infelicity in `calloc()` API usage in `mbedtls`: In file included from /build/mbedtls/tests/include/test/ssl_helpers.h:19, from /build/mbedtls/tests/src/test_helpers/ssl_helpers.c:11: /build/mbedtls/tests/src/test_helpers/ssl_helpers.c: In function 'mbedtls_test_init_handshake_options': /build/mbedtls/tests/include/test/macros.h:128:46: error: 'calloc' sizes specified with 'sizeof' in the earlier argument and not in the later argument [-Werror=calloc-transposed-args] 128 | (pointer) = mbedtls_calloc(sizeof(*(pointer)), \ | ^ Signed-off-by: Sergei Trofimovich --- tests/include/test/macros.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/include/test/macros.h b/tests/include/test/macros.h index 8de9c4d95..a73e06fca 100644 --- a/tests/include/test/macros.h +++ b/tests/include/test/macros.h @@ -125,8 +125,8 @@ do { \ TEST_ASSERT((pointer) == NULL); \ if ((item_count) != 0) { \ - (pointer) = mbedtls_calloc(sizeof(*(pointer)), \ - (item_count)); \ + (pointer) = mbedtls_calloc((item_count), \ + sizeof(*(pointer))); \ TEST_ASSERT((pointer) != NULL); \ } \ } while (0) @@ -155,8 +155,8 @@ #define TEST_CALLOC_NONNULL(pointer, item_count) \ do { \ TEST_ASSERT((pointer) == NULL); \ - (pointer) = mbedtls_calloc(sizeof(*(pointer)), \ - (item_count)); \ + (pointer) = mbedtls_calloc((item_count), \ + sizeof(*(pointer))); \ if (((pointer) == NULL) && ((item_count) == 0)) { \ (pointer) = mbedtls_calloc(1, 1); \ } \ @@ -175,8 +175,8 @@ do { \ TEST_ASSERT((pointer) == NULL); \ if ((item_count) != 0) { \ - (pointer) = mbedtls_calloc(sizeof(*(pointer)), \ - (item_count)); \ + (pointer) = mbedtls_calloc((item_count), \ + sizeof(*(pointer))); \ TEST_ASSUME((pointer) != NULL); \ } \ } while (0) From 2a6cb5c88104d92496365d77bbb0a91f803d2241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98rjan=20Malde?= Date: Fri, 26 Jan 2024 12:51:35 +0000 Subject: [PATCH 184/215] fix build for midipix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ørjan Malde --- library/entropy_poll.c | 2 +- library/platform_util.c | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/library/entropy_poll.c b/library/entropy_poll.c index bd21e2d22..794ee03a8 100644 --- a/library/entropy_poll.c +++ b/library/entropy_poll.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ -#if defined(__linux__) && !defined(_GNU_SOURCE) +#if defined(__linux__) || defined(__midipix__) && !defined(_GNU_SOURCE) /* Ensure that syscall() is available even when compiling with -std=c99 */ #define _GNU_SOURCE #endif diff --git a/library/platform_util.c b/library/platform_util.c index 9f5dcb874..eafb0aa91 100644 --- a/library/platform_util.c +++ b/library/platform_util.c @@ -151,10 +151,10 @@ void mbedtls_zeroize_and_free(void *buf, size_t len) #include #if !defined(_WIN32) && (defined(unix) || \ defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ - defined(__MACH__))) + defined(__MACH__)) || defined__midipix__) #include #endif /* !_WIN32 && (unix || __unix || __unix__ || - * (__APPLE__ && __MACH__)) */ + * (__APPLE__ && __MACH__) || __midipix__) */ #if !((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L) || \ (defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \ @@ -222,9 +222,10 @@ void (*mbedtls_test_hook_test_fail)(const char *, int, const char *); #include #if !defined(_WIN32) && \ (defined(unix) || defined(__unix) || defined(__unix__) || \ - (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__)) + (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__) || defined(__midipix__)) #include -#endif /* !_WIN32 && (unix || __unix || __unix__ || (__APPLE__ && __MACH__) || __HAIKU__) */ +#endif \ + /* !_WIN32 && (unix || __unix || __unix__ || (__APPLE__ && __MACH__) || __HAIKU__ || __midipix__) */ #if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 199309L) || defined(__HAIKU__) mbedtls_ms_time_t mbedtls_ms_time(void) { @@ -232,7 +233,7 @@ mbedtls_ms_time_t mbedtls_ms_time(void) struct timespec tv; mbedtls_ms_time_t current_ms; -#if defined(__linux__) && defined(CLOCK_BOOTTIME) +#if defined(__linux__) && defined(CLOCK_BOOTTIME) || defined(__midipix__) ret = clock_gettime(CLOCK_BOOTTIME, &tv); #else ret = clock_gettime(CLOCK_MONOTONIC, &tv); From 9e4eeff6e0b3e1ab4d60517998d6137e153c4a27 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 30 Jan 2024 13:51:18 +0000 Subject: [PATCH 185/215] Fix comment about verison of clang required for 'build_aes_armce' Signed-off-by: Tom Cosgrove --- tests/scripts/all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 44930d28b..9e45e0fee 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -4750,7 +4750,7 @@ component_build_aes_aesce_armcc () { } support_build_aes_armce() { - # clang >= 4 is required to build with AES extensions + # clang >= 11 is required to build with AES extensions ver="$(clang --version|grep version|sed -E 's#.*version ([0-9]+).*#\1#')" [ "${ver}" -ge 11 ] } From d4c373a597ea27edcbcd2104e907315493605f68 Mon Sep 17 00:00:00 2001 From: Tom Cosgrove Date: Tue, 30 Jan 2024 13:56:38 +0000 Subject: [PATCH 186/215] Refactor all.sh clang version detection code Prevents a script failure when attempting to run build_aes_armce on a system without clang Signed-off-by: Tom Cosgrove --- tests/scripts/all.sh | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 9e45e0fee..315a66b14 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -821,6 +821,14 @@ pre_generate_files() { fi } +clang_version() { + if command -v clang > /dev/null ; then + clang --version|grep version|sed -E 's#.*version ([0-9]+).*#\1#' + else + echo 0 # report version 0 for "no clang" + fi +} + ################################################################ #### Helpers for components using libtestdriver1 ################################################################ @@ -4692,14 +4700,8 @@ component_test_aesni_m32 () { # ~ 60s } support_test_aesni_m32_clang() { - support_test_aesni_m32 && if command -v clang > /dev/null ; then - # clang >= 4 is required to build with target attributes - clang_ver="$(clang --version|grep version|sed -E 's#.*version ([0-9]+).*#\1#')" - [[ "${clang_ver}" -ge 4 ]] - else - # clang not available - false - fi + # clang >= 4 is required to build with target attributes + support_test_aesni_m32 && [[ $(clang_version) -ge 4 ]] } component_test_aesni_m32_clang() { @@ -4751,8 +4753,7 @@ component_build_aes_aesce_armcc () { support_build_aes_armce() { # clang >= 11 is required to build with AES extensions - ver="$(clang --version|grep version|sed -E 's#.*version ([0-9]+).*#\1#')" - [ "${ver}" -ge 11 ] + [[ $(clang_version) -ge 11 ]] } component_build_aes_armce () { @@ -4807,15 +4808,8 @@ component_build_aes_armce () { } support_build_sha_armce() { - if command -v clang > /dev/null ; then - # clang >= 4 is required to build with SHA extensions - clang_ver="$(clang --version|grep version|sed -E 's#.*version ([0-9]+).*#\1#')" - - [[ "${clang_ver}" -ge 4 ]] - else - # clang not available - false - fi + # clang >= 4 is required to build with SHA extensions + [[ $(clang_version) -ge 4 ]] } component_build_sha_armce () { From 36dee75368a0db0aa262f0dda0c53400b2ccd0f8 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 30 Jan 2024 16:15:17 +0100 Subject: [PATCH 187/215] Update ECDSA signature conversion based on experimentation Signed-off-by: Gilles Peskine --- docs/architecture/psa-migration/psa-legacy-bridges.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/architecture/psa-migration/psa-legacy-bridges.md b/docs/architecture/psa-migration/psa-legacy-bridges.md index fb0070597..e09d23c49 100644 --- a/docs/architecture/psa-migration/psa-legacy-bridges.md +++ b/docs/architecture/psa-migration/psa-legacy-bridges.md @@ -282,7 +282,7 @@ int mbedtls_pk_import_into_psa(const mbedtls_pk_context *pk, * It is an error if `usage` has more than one flag set, or has a usage that is incompatible with the key type. * `mbedtls_pk_get_psa_attributes` sets the algorithm usage policy based on information in the key object and on `usage`. * For an RSA key with the `MBEDTLS_RSA_PKCS_V15` padding mode, the algorithm policy is `PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH)` for a sign/verify usage, and `PSA_ALG_RSA_PKCS1V15_CRYPT` for an encrypt/decrypt usage. - * For an RSA key with the `MBEDTLS_RSA_PKCS_V15` padding mode, the algorithm policy is `PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH)` for a sign/verify usage, and `PSA_ALG_RSA_OAEP(hash)` for an encrypt/decrypt usage where `hash` is from the RSA key's parameters. (Note that `PSA_ALG_ANY_HASH` is only allowed in signature algorithms.) + * For an RSA key with the `MBEDTLS_RSA_PKCS_V21` padding mode, the algorithm policy is `PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_ANY_HASH)` for a sign/verify usage, and `PSA_ALG_RSA_OAEP(hash)` for an encrypt/decrypt usage where `hash` is from the RSA key's parameters. (Note that `PSA_ALG_ANY_HASH` is only allowed in signature algorithms.) * For an `MBEDTLS_PK_ECKEY` or `MBEDTLS_PK_ECDSA` with a sign/verify usage, the algorithm policy is `PSA_ALG_DETERMINISTIC_ECDSA` if `MBEDTLS_ECDSA_DETERMINISTIC` is enabled and `PSA_ALG_ECDSA` otherwise. In either case, the hash policy is `PSA_ALG_ANY_HASH`. * For an `MBEDTLS_PK_ECKEY` or `MBEDTLS_PK_ECDKEY_DH` with the usage `PSA_KEY_USAGE_DERIVE`, the algorithm is `PSA_ALG_ECDH`. * For a `MBEDTLS_PK_OPAQUE`, this function reads the attributes of the existing PK key and copies them (without overriding the lifetime and key identifier in `attributes`), then applies a public-key restriction if needed. @@ -331,7 +331,8 @@ Based on the [gap analysis](#signature-formats): ``` int mbedtls_ecdsa_raw_to_der(const unsigned char *raw, size_t raw_len, - unsigned char *der, size_t der_size, size_t *der_len); + unsigned char *der, size_t der_size, size_t *der_len, + size_t bits); int mbedtls_ecdsa_der_to_raw(const unsigned char *der, size_t der_len, unsigned char *raw, size_t raw_size, size_t *raw_len, size_t bits); @@ -339,5 +340,5 @@ int mbedtls_ecdsa_der_to_raw(const unsigned char *der, size_t der_len, * These functions convert between the signature format used by `mbedtls_pk_{sign,verify}{,_ext}` and the signature format used by `psa_{sign,verify}_{hash,message}`. * The input and output buffers can overlap. - -[OPEN] Should these functions rely on the ASN.1 module? To be decided when implementing. +* The `bits` parameter is necessary in the DER-to-raw direction because the DER format lacks leading zeros, so something else needs to convey the size of (r,s). The `bits` parameter is not needed in the raw-to-DER direction, but [it can help catch errors](https://github.com/Mbed-TLS/mbedtls/pull/8681#discussion_r1445980971) and the information is readily available in practice. +* Should these functions rely on the ASN.1 module? We experimented [calling ASN.1 functions](https://github.com/Mbed-TLS/mbedtls/pull/8681), [reimplementing simpler ASN.1 functions](https://github.com/Mbed-TLS/mbedtls/pull/8696), and [providing the functions from the ASN.1 module](https://github.com/Mbed-TLS/mbedtls/pull/8703). Providing the functions from the ASN.1 module [won on a compromise of code size and simplicity](https://github.com/Mbed-TLS/mbedtls/issues/7765#issuecomment-1893670015). From cbb9caead4c4ba5d80d6cb01386518ef6d05eaaa Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 16 Feb 2023 23:40:40 +0100 Subject: [PATCH 188/215] Changelog for building SHA-256 and 512 with old libc Linux/Aarch64: support SHA acceleration detection with older libc On Linux on aarch64 (64-bit ARMv8) processors, we use getauxval() to detect whether the runtime environment supports SHA-256 or SHA-512 acceleration. Some libc do not define the necessary HWCAP_xxx constants to analyze the result of getauxval(), either because they don't bother or because they're too old to recognize the values we need (for example, HWCAP_SHA2 appeared in Glibc 2.24 and HWCAP_SHA512 appeared in Glibc 2.27). In such cases, assume that the values are the same as in the kernel ABI and define the constants manually. Signed-off-by: Gilles Peskine Signed-off-by: Dave Rodgman --- ChangeLog.d/linux-aarch64-hwcap.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ChangeLog.d/linux-aarch64-hwcap.txt diff --git a/ChangeLog.d/linux-aarch64-hwcap.txt b/ChangeLog.d/linux-aarch64-hwcap.txt new file mode 100644 index 000000000..23af87824 --- /dev/null +++ b/ChangeLog.d/linux-aarch64-hwcap.txt @@ -0,0 +1,4 @@ +Bugfix + * On Linux on ARMv8, fix a build error with SHA-256 and SHA-512 + acceleration detection when the libc headers do not define the + corresponding constant. Reported by valord577. From dae21d3808be93c30fda318b19657b4db6ad2b5d Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Tue, 30 Jan 2024 15:31:42 +0000 Subject: [PATCH 189/215] Support SHA-512 hwcap detection on old libc Signed-off-by: Dave Rodgman --- library/sha512.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/sha512.c b/library/sha512.c index 601125445..6dcea8da5 100644 --- a/library/sha512.c +++ b/library/sha512.c @@ -102,6 +102,14 @@ # if defined(__linux__) /* Our preferred method of detection is getauxval() */ # include +# if !defined(HWCAP_SHA512) +/* The same header that declares getauxval() should provide the HWCAP_xxx + * constants to analyze its return value. However, the libc may be too + * old to have the constant that we need. So if it's missing, assume that + * the value is the same one used by the Linux kernel ABI. + */ +# define HWCAP_SHA512 (1 << 21) +# endif # endif /* Use SIGILL on Unix, and fall back to it on Linux */ # include From faf026c67cf8054b8be8a42091f700a1b1417744 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 31 Jan 2024 14:32:06 +0100 Subject: [PATCH 190/215] Explain purpose of test specific write/parse ticket functions Signed-off-by: Ronald Cron --- tests/src/test_helpers/ssl_helpers.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index 51957463c..980c19218 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -2427,7 +2427,13 @@ int mbedtls_test_tweak_tls13_certificate_msg_vector_len( } #endif /* MBEDTLS_TEST_HOOKS */ -/* Functions for session ticket tests */ +/* + * Functions for tests based on tickets. Implementations of the + * write/parse ticket interfaces as defined by mbedtls_ssl_ticket_write/parse_t. + * Basically same implementations as in ticket.c without the encryption. That + * way we can tweak easily tickets characteristics to simulate misbehaving + * peers. + */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) int mbedtls_test_ticket_write( void *p_ticket, const mbedtls_ssl_session *session, From 095a3a5a299d5e7a2adab71bc2aa25d5f44606a0 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 31 Jan 2024 14:34:22 +0100 Subject: [PATCH 191/215] Fix PSA init and done macros in TLS unit tests Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 234181d76..65fed181b 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3582,7 +3582,7 @@ void tls13_resume_session_with_ticket() mbedtls_test_init_handshake_options(&server_options); mbedtls_ssl_session_init(&saved_session); - MD_OR_USE_PSA_INIT(); + PSA_INIT(); client_options.pk_alg = MBEDTLS_PK_ECDSA; ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, @@ -3652,7 +3652,7 @@ exit: mbedtls_test_free_handshake_options(&client_options); mbedtls_test_free_handshake_options(&server_options); mbedtls_ssl_session_free(&saved_session); - MD_OR_USE_PSA_DONE(); + PSA_DONE(); } /* END_CASE */ @@ -3678,7 +3678,7 @@ void tls13_early_data() mbedtls_test_init_handshake_options(&server_options); mbedtls_ssl_session_init(&saved_session); - MD_OR_USE_PSA_INIT(); + PSA_INIT(); client_options.pk_alg = MBEDTLS_PK_ECDSA; ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT, @@ -3767,6 +3767,6 @@ exit: mbedtls_test_free_handshake_options(&server_options); mbedtls_ssl_session_free(&saved_session); mbedtls_debug_set_threshold(0); - MD_OR_USE_PSA_DONE(); + PSA_DONE(); } /* END_CASE */ From 5de9c6f295fcc4328c6c94af0aa217a1a43ae2d7 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 31 Jan 2024 14:45:16 +0100 Subject: [PATCH 192/215] Fix and add comments in ticket and early data test function Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 65fed181b..9b282dc53 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3606,8 +3606,9 @@ void tls13_resume_session_with_ticket() /* * Run initial handshake: ephemeral key exchange mode, certificate with - * RSA key, signed with PKCS15, verified with PKCS21. Then, get the ticket - * sent by the server at the end of its handshake sequence. + * SECP256R1 key, CA certificate with SECP384R1 key, ECDSA signature + * algorithm. Then, get the ticket sent by the server at the end of its + * handshake sequence. */ TEST_ASSERT(mbedtls_test_move_handshake_to_state( &(server_ep.ssl), &(client_ep.ssl), @@ -3637,6 +3638,11 @@ void tls13_resume_session_with_ticket() ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session); TEST_EQUAL(ret, 0); + /* + * Run the handshake up to MBEDTLS_SSL_HANDSHAKE_WRAPUP and not + * MBEDTLS_SSL_HANDSHAKE_OVER to preserve handshake data for the checks + * below. + */ TEST_ASSERT(mbedtls_test_move_handshake_to_state( &(server_ep.ssl), &(client_ep.ssl), MBEDTLS_SSL_HANDSHAKE_WRAPUP) == 0); @@ -3656,6 +3662,11 @@ exit: } /* END_CASE */ +/* + * The !MBEDTLS_SSL_PROTO_TLS1_2 dependency of tls13_early_data() below is + * a temporary workaround to not run the test in Windows-2013 where there is + * an issue with mbedtls_vsnprintf(). + */ /* BEGIN_CASE depends_on:!MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */ void tls13_early_data() { @@ -3707,8 +3718,9 @@ void tls13_early_data() /* * Run initial handshake: ephemeral key exchange mode, certificate with - * RSA key, signed with PKCS15, verified with PKCS21. Then, get the ticket - * sent by the server at the end of its handshake sequence. + * SECP256R1 key, CA certificate with SECP384R1 key, ECDSA signature + * algorithm. Then, get the ticket sent by the server at the end of its + * handshake sequence. */ TEST_ASSERT(mbedtls_test_move_handshake_to_state( &(server_ep.ssl), &(client_ep.ssl), From eb84534ee3e77dede536f13744d19a4b392831db Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 31 Jan 2024 14:48:23 +0100 Subject: [PATCH 193/215] Use TEST_EQUAL instead of TEST_ASSERT where possible Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 30 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 9b282dc53..d26407e2d 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3610,9 +3610,9 @@ void tls13_resume_session_with_ticket() * algorithm. Then, get the ticket sent by the server at the end of its * handshake sequence. */ - TEST_ASSERT(mbedtls_test_move_handshake_to_state( - &(server_ep.ssl), &(client_ep.ssl), - MBEDTLS_SSL_HANDSHAKE_OVER) == 0); + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + MBEDTLS_SSL_HANDSHAKE_OVER), 0); do { ret = mbedtls_ssl_read(&(client_ep.ssl), buf, sizeof(buf)); @@ -3643,9 +3643,9 @@ void tls13_resume_session_with_ticket() * MBEDTLS_SSL_HANDSHAKE_OVER to preserve handshake data for the checks * below. */ - TEST_ASSERT(mbedtls_test_move_handshake_to_state( - &(server_ep.ssl), &(client_ep.ssl), - MBEDTLS_SSL_HANDSHAKE_WRAPUP) == 0); + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + MBEDTLS_SSL_HANDSHAKE_WRAPUP), 0); TEST_EQUAL(server_ep.ssl.handshake->resume, 1); TEST_EQUAL(server_ep.ssl.handshake->new_session_tickets_count, 1); @@ -3722,9 +3722,9 @@ void tls13_early_data() * algorithm. Then, get the ticket sent by the server at the end of its * handshake sequence. */ - TEST_ASSERT(mbedtls_test_move_handshake_to_state( - &(server_ep.ssl), &(client_ep.ssl), - MBEDTLS_SSL_HANDSHAKE_OVER) == 0); + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + MBEDTLS_SSL_HANDSHAKE_OVER), 0); do { ret = mbedtls_ssl_read(&(client_ep.ssl), buf, sizeof(buf)); @@ -3752,9 +3752,9 @@ void tls13_early_data() mbedtls_debug_set_threshold(3); - TEST_ASSERT(mbedtls_test_move_handshake_to_state( - &(client_ep.ssl), &(server_ep.ssl), - MBEDTLS_SSL_SERVER_HELLO) == 0); + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(client_ep.ssl), &(server_ep.ssl), + MBEDTLS_SSL_SERVER_HELLO), 0); TEST_ASSERT(client_ep.ssl.early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); @@ -3764,9 +3764,9 @@ void tls13_early_data() early_data_len); TEST_EQUAL(ret, early_data_len); - TEST_ASSERT(mbedtls_test_move_handshake_to_state( - &(server_ep.ssl), &(client_ep.ssl), - MBEDTLS_SSL_CLIENT_FINISHED) == 0); + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + MBEDTLS_SSL_CLIENT_FINISHED), 0); TEST_EQUAL(server_ep.ssl.early_data_status, MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED); From 6823247376c67aaf52badb20c5bcad69bf3a53b4 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Wed, 31 Jan 2024 15:59:06 +0000 Subject: [PATCH 194/215] Fix compile warning in tests Signed-off-by: Dave Rodgman --- tests/suites/test_suite_gcm.function | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function index dac2a5df2..0af4209f4 100644 --- a/tests/suites/test_suite_gcm.function +++ b/tests/suites/test_suite_gcm.function @@ -165,6 +165,7 @@ static void gcm_reset_ctx(mbedtls_gcm_context *ctx, const uint8_t *key, TEST_EQUAL(starts_ret, mbedtls_gcm_starts(ctx, mode, iv, iv_len)); exit: /* empty */ + return; } /* END_HEADER */ @@ -514,6 +515,7 @@ void gcm_invalid_iv_len(void) goto exit; /* To suppress error that exit is defined but not used */ exit: /* empty */ + return; } /* END_CASE */ From ba8e9addd9c968ae25fa251dc0c40459f9c555f9 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Thu, 1 Feb 2024 13:54:46 +0000 Subject: [PATCH 195/215] Fix test dependencies Signed-off-by: Dave Rodgman --- tests/suites/test_suite_gcm.misc.data | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_gcm.misc.data b/tests/suites/test_suite_gcm.misc.data index 57f05caf5..108630ee8 100644 --- a/tests/suites/test_suite_gcm.misc.data +++ b/tests/suites/test_suite_gcm.misc.data @@ -2,13 +2,13 @@ GCM - Invalid parameters gcm_invalid_param: GCM - Invalid IV length -depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +depends_on:MBEDTLS_GCM_C:MBEDTLS_CCM_GCM_CAN_AES gcm_invalid_iv_len: GCM - Additional data length too long -depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +depends_on:MBEDTLS_GCM_C:MBEDTLS_CCM_GCM_CAN_AES gcm_add_len_too_long: GCM - Input length too long -depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +depends_on:MBEDTLS_GCM_C:MBEDTLS_CCM_GCM_CAN_AES gcm_input_len_too_long: From 149b0e7ca2e19bbc2d0aff72615e7727fdbd844c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 5 Jan 2024 14:25:03 +0100 Subject: [PATCH 196/215] ssl.h: Fix comment Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 36295269a..3e6b1e605 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1843,7 +1843,7 @@ struct mbedtls_ssl_context { #if defined(MBEDTLS_SSL_EARLY_DATA) int MBEDTLS_PRIVATE(early_data_status); -#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */ +#endif /** Callback to export key block and master secret */ mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys); From 5d0ae9021f28e317cfe7a2a10852dacb163c5872 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 5 Jan 2024 14:20:35 +0100 Subject: [PATCH 197/215] tls13: srv: Refine early data status The main purpose is to know from the status if early data can be received of not and why. Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 24 ++++++++++++++++++++---- library/ssl_misc.h | 20 +++++++++++++++++++- library/ssl_tls.c | 10 ++++++++++ library/ssl_tls13_server.c | 3 +++ 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 3e6b1e605..f478a18eb 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1644,6 +1644,26 @@ struct mbedtls_ssl_context { */ mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version); +#if defined(MBEDTLS_SSL_EARLY_DATA) + /** + * On client side, status of the negotiation of the use of early data. + * See the documentation of mbedtls_ssl_get_early_data_status() for more + * information. + * + * On server side, internal only, status of early data in the course of an + * handshake. One of MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN, + * #MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED, + * #MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED, + * MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED and + * MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED. + * + * Reset to #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT or + * MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN, at the beginning of a new + * handshake. + */ + int MBEDTLS_PRIVATE(early_data_status); +#endif + unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */ #if defined(MBEDTLS_X509_CRT_PARSE_C) @@ -1841,10 +1861,6 @@ struct mbedtls_ssl_context { * and #MBEDTLS_SSL_CID_DISABLED. */ #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ -#if defined(MBEDTLS_SSL_EARLY_DATA) - int MBEDTLS_PRIVATE(early_data_status); -#endif - /** Callback to export key block and master secret */ mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys); void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */ diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 96afe7628..943940826 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2132,8 +2132,26 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl, size_t *out_len); #if defined(MBEDTLS_SSL_SRV_C) -#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED \ +/* Additional internal early data status, server side only. */ +/* + * The server has not received the ClientHello yet, the status of early data + * is thus unknown. + */ +#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN \ MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT + +/* + * The server has received the ClientHello, it contained no early data + * extension. + */ +#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED 3 + +/* + * The server has received the early data extension, it has accepted early + * data and received the end of early data message from the client marking the + * end of early data reception. + */ +#define MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED 4 #endif /* MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_EARLY_DATA */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 0bc18f126..72db821a6 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1098,6 +1098,16 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl) return MBEDTLS_ERR_SSL_ALLOC_FAILED; } +#if defined(MBEDTLS_SSL_EARLY_DATA) +#if defined(MBEDTLS_SSL_SRV_C) + MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN == 0, + "MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN not equal to 0"); +#endif + MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT == 0, + "MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT not equal to 0"); + ssl->early_data_status = 0; +#endif + /* Initialize structures */ mbedtls_ssl_session_init(ssl->session_negotiate); ssl_handshake_params_init(ssl->handshake); diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 904bb5b6f..ff501c8a9 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -3024,6 +3024,9 @@ static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl) MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_end_of_early_data( ssl, buf, buf + buf_len)); + ssl->early_data_status = + MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED; + MBEDTLS_SSL_DEBUG_MSG( 1, ("Switch to handshake keys for inbound traffic" "( K_recv = handshake )")); From 739a1d42469e9f65aa39ca1b5615a33eb58c961e Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Thu, 8 Dec 2022 21:10:25 +0800 Subject: [PATCH 198/215] tls: Add internal function ssl_read_application_data() The function will be used by mbedtls_ssl_read_early_data() as well. Signed-off-by: Jerry Yu Signed-off-by: Ronald Cron --- library/ssl_msg.c | 66 +++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 6579c9686..e76976751 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -5647,13 +5647,54 @@ static int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl) return MBEDTLS_ERR_SSL_INTERNAL_ERROR; } +/* + * brief Read at most 'len' application data bytes from the input + * buffer. + * + * param ssl SSL context: + * - First byte of application data not read yet in the input + * buffer located at address `in_offt`. + * - The number of bytes of data not read yet is `in_msglen`. + * param buf buffer that will hold the data + * param len maximum number of bytes to read + * + * note The function updates the fields `in_offt` and `in_msglen` + * according to the number of bytes read. + * + * return The number of bytes read. + */ +static int ssl_read_application_data( + mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) +{ + size_t n = (len < ssl->in_msglen) ? len : ssl->in_msglen; + + if (len != 0) { + memcpy(buf, ssl->in_offt, n); + ssl->in_msglen -= n; + } + + /* Zeroising the plaintext buffer to erase unused application data + from the memory. */ + mbedtls_platform_zeroize(ssl->in_offt, n); + + if (ssl->in_msglen == 0) { + /* all bytes consumed */ + ssl->in_offt = NULL; + ssl->keep_current_message = 0; + } else { + /* more data available */ + ssl->in_offt += n; + } + + return (int) n; +} + /* * Receive application data decrypted from the SSL layer */ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t n; if (ssl == NULL || ssl->conf == NULL) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; @@ -5817,30 +5858,11 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) #endif /* MBEDTLS_SSL_PROTO_DTLS */ } - n = (len < ssl->in_msglen) - ? len : ssl->in_msglen; - - if (len != 0) { - memcpy(buf, ssl->in_offt, n); - ssl->in_msglen -= n; - } - - /* Zeroising the plaintext buffer to erase unused application data - from the memory. */ - mbedtls_platform_zeroize(ssl->in_offt, n); - - if (ssl->in_msglen == 0) { - /* all bytes consumed */ - ssl->in_offt = NULL; - ssl->keep_current_message = 0; - } else { - /* more data available */ - ssl->in_offt += n; - } + ret = ssl_read_application_data(ssl, buf, len); MBEDTLS_SSL_DEBUG_MSG(2, ("<= read")); - return (int) n; + return ret; } /* From 6a5904db458b4eb0a673b33e6050524e172c1d9a Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Wed, 6 Dec 2023 17:11:12 +0800 Subject: [PATCH 199/215] tls13: srv: Move early data size check placeholder Signed-off-by: Jerry Yu Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index ff501c8a9..3b560e799 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -2911,6 +2911,13 @@ static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl) if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) { MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data")); + /* RFC 8446 section 4.6.1 + * + * A server receiving more than max_early_data_size bytes of 0-RTT data + * SHOULD terminate the connection with an "unexpected_message" alert. + * + * TODO: Add received data size check here. + */ return SSL_GOT_EARLY_DATA; } @@ -2956,14 +2963,6 @@ static int ssl_tls13_process_early_application_data(mbedtls_ssl_context *ssl) ssl->in_msg[ssl->in_msglen] = 0; MBEDTLS_SSL_DEBUG_MSG(3, ("\n%s", ssl->in_msg)); - /* RFC 8446 section 4.6.1 - * - * A server receiving more than max_early_data_size bytes of 0-RTT data - * SHOULD terminate the connection with an "unexpected_message" alert. - * - * TODO: Add received data size check here. - */ - return 0; } From 032985c351020a1e82e485d8146d1bdb01404d58 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Wed, 6 Dec 2023 17:59:33 +0800 Subject: [PATCH 200/215] Add MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA error code Signed-off-by: Jerry Yu Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 46 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index f478a18eb..22ceb3904 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -90,8 +90,17 @@ #define MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET -0x7B00 /** Not possible to read early data */ #define MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA -0x7B80 +/** + * Early data has been received as part of an on-going handshake. + * This error code can be returned only on server side. This error code can be + * returned by mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), + * mbedtls_ssl_read() and mbedtls_ssl_write() if early data has been received + * as part of the handshake sequence they triggered. To read the early + * data, call mbedtls_ssl_read_early_data(). + */ +#define MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA -0x7C00 /** Not possible to write early data */ -#define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C00 +#define MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA -0x7C80 /* Error space gap */ /* Error space gap */ /* Error space gap */ @@ -4749,6 +4758,11 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, * \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use * and the client did not demonstrate reachability yet - in * this case you must stop using the context (see below). + * \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as + * defined in RFC 8446 (TLS 1.3 specification), has been + * received as part of the handshake. This is server specific. + * You must call mbedtls_ssl_read_early_data() to read the + * early data before to resume the handshake. * \return Another SSL error code - in this case you must stop using * the context (see below). * @@ -4757,7 +4771,8 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, * #MBEDTLS_ERR_SSL_WANT_READ, * #MBEDTLS_ERR_SSL_WANT_WRITE, * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or + * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, * you must stop using the SSL context for reading or writing, * and either free it or call \c mbedtls_ssl_session_reset() * on it before re-using it for a new connection; the current @@ -4826,8 +4841,9 @@ static inline int mbedtls_ssl_is_handshake_over(mbedtls_ssl_context *ssl) * * \warning If this function returns something other than \c 0, * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using + * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or + * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, you must stop using * the SSL context for reading or writing, and either free it * or call \c mbedtls_ssl_session_reset() on it before * re-using it for a new connection; the current connection @@ -4895,6 +4911,12 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl); * \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server * side of a DTLS connection and the client is initiating a * new connection using the same source port. See below. + * \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as + * defined in RFC 8446 (TLS 1.3 specification), has been + * received as part of an handshake triggered by the function. + * This is server specific. You must call + * mbedtls_ssl_read_early_data() to read the early data before + * to resume the reading of post handshake application data. * \return Another SSL error code - in this case you must stop using * the context (see below). * @@ -4903,8 +4925,9 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl); * #MBEDTLS_ERR_SSL_WANT_READ, * #MBEDTLS_ERR_SSL_WANT_WRITE, * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CLIENT_RECONNECT, + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, + * #MBEDTLS_ERR_SSL_CLIENT_RECONNECT or + * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, * you must stop using the SSL context for reading or writing, * and either free it or call \c mbedtls_ssl_session_reset() * on it before re-using it for a new connection; the current @@ -4969,6 +4992,12 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len); * operation is in progress (see mbedtls_ecp_set_max_ops()) - * in this case you must call this function again to complete * the handshake when you're done attending other tasks. + * \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as + * defined in RFC 8446 (TLS 1.3 specification), has been + * received as part of an handshake triggered by the function. + * This is server specific. You must call + * mbedtls_ssl_read_early_data() to read the early data before + * to resume the writing of application data. * \return Another SSL error code - in this case you must stop using * the context (see below). * @@ -4976,8 +5005,9 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len); * a non-negative value, * #MBEDTLS_ERR_SSL_WANT_READ, * #MBEDTLS_ERR_SSL_WANT_WRITE, - * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, + * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or + * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA, * you must stop using the SSL context for reading or writing, * and either free it or call \c mbedtls_ssl_session_reset() * on it before re-using it for a new connection; the current From 3a04562ace1ba39667c80173fb4cfb74008bb922 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 8 Jan 2024 18:44:59 +0100 Subject: [PATCH 201/215] Update mbedtls_ssl_read_early_data() definition Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 22ceb3904..7f1bd8f16 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5075,8 +5075,11 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); #if defined(MBEDTLS_SSL_SRV_C) /** - * \brief Read at most 'len' application data bytes while performing - * the handshake (early data). + * \brief Read at most 'len' bytes of early data + * + * \note This API is server specific. + * + * \note Early data is defined in the TLS 1.3 specification, RFC 8446. * * \note This function behaves mainly as mbedtls_ssl_read(). The * specification of mbedtls_ssl_read() relevant to TLS 1.3 @@ -5084,10 +5087,19 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); * function and the present documentation is restricted to the * differences with mbedtls_ssl_read(). * + * \note This function can be used in conjunction with + * mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), + * mbedtls_ssl_read() and mbedtls_ssl_write() to read early + * data when these functions return + * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA. + * * \param ssl SSL context * \param buf buffer that will hold the data * \param len maximum number of bytes to read * + * \note Unlike mbedtls_ssl_read(), this function does not return + * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA. + * * \return One additional specific return value: * #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA. * @@ -5112,11 +5124,6 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); * \p ssl but this does not preclude for using it with * mbedtls_ssl_write(), mbedtls_ssl_read() or * mbedtls_ssl_handshake(). - * - * \note When a server wants to retrieve early data, it is expected - * that this function starts the handshake for the SSL context - * \p ssl. But this is not mandatory. - * */ int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len); From d9ca354dbd760f68c716b773dd2e844b8a22010f Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Wed, 6 Dec 2023 17:23:52 +0800 Subject: [PATCH 202/215] tls13: srv: Add mbedtls_ssl_read_early_data() API Signed-off-by: Jerry Yu Signed-off-by: Ronald Cron --- library/ssl_msg.c | 49 ++++++++++++++++++++++++++++++++++++++ library/ssl_tls13_server.c | 26 ++------------------ 2 files changed, 51 insertions(+), 24 deletions(-) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index e76976751..825ca8fe9 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -5865,6 +5865,55 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) return ret; } + +#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) +int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl, + unsigned char *buf, size_t len) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const struct mbedtls_ssl_config *conf; + unsigned char *p = buf; + + if (ssl == NULL || ((conf = ssl->conf) == NULL)) { + return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + } + + if ((!mbedtls_ssl_conf_is_tls13_enabled(conf)) || + (conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) || + (conf->early_data_enabled != MBEDTLS_SSL_EARLY_DATA_ENABLED)) { + return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; + } + + if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) { + return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; + } + + if ((ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN) && + (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED)) { + return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; + } + + ret = mbedtls_ssl_handshake(ssl); + if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) { + if (ssl->in_offt == NULL) { + /* Set the reading pointer */ + ssl->in_offt = ssl->in_msg; + } + ret = ssl_read_application_data(ssl, p, len); + } else if (ret == 0) { + /* + * If the handshake is completed, return immediately that early data + * cannot be read anymore. This potentially saves another call to this + * API and when the function returns 0, it only means that zero byte + * of early data has been received. + */ + return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; + } + + return ret; +} +#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA */ + /* * Send application data to be encrypted by the SSL layer, taking care of max * fragment length and buffer size. diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 3b560e799..97ce5c276 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -2943,29 +2943,6 @@ static int ssl_tls13_parse_end_of_early_data(mbedtls_ssl_context *ssl, return 0; } -MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_process_early_application_data(mbedtls_ssl_context *ssl) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - - if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) { - MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); - return ret; - } - - /* - * Output early data - * - * For the time being, we print received data via debug message. - * - * TODO: Remove it when `mbedtls_ssl_read_early_data` is ready. - */ - ssl->in_msg[ssl->in_msglen] = 0; - MBEDTLS_SSL_DEBUG_MSG(3, ("\n%s", ssl->in_msg)); - - return 0; -} - /* * RFC 8446 section A.2 * @@ -3039,7 +3016,8 @@ static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl) ssl_tls13_prepare_for_handshake_second_flight(ssl); } else if (ret == SSL_GOT_EARLY_DATA) { - MBEDTLS_SSL_PROC_CHK(ssl_tls13_process_early_application_data(ssl)); + ret = MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA; + goto cleanup; } else { MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; From 192e0f9b1d8f81044bb70b2c9b60f117b9e0cde2 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Fri, 16 Dec 2022 18:55:06 +0800 Subject: [PATCH 203/215] ssl_server2: Add read early data support Signed-off-by: Jerry Yu Signed-off-by: Ronald Cron --- programs/ssl/ssl_server2.c | 14 ++++++++++++++ tests/data_files/tls13_early_data.txt | 1 + 2 files changed, 15 insertions(+) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 598d38cac..48b2282c9 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1612,6 +1612,7 @@ int main(int argc, char *argv[]) #if defined(MBEDTLS_SSL_EARLY_DATA) int tls13_early_data_enabled = MBEDTLS_SSL_EARLY_DATA_DISABLED; #endif + #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf)); #if defined(MBEDTLS_MEMORY_DEBUG) @@ -3450,6 +3451,19 @@ handshake: fflush(stdout); while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { +#if defined(MBEDTLS_SSL_EARLY_DATA) + if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) { + memset(buf, 0, opt.buffer_size); + ret = mbedtls_ssl_read_early_data(&ssl, buf, opt.buffer_size); + if (ret > 0) { + buf[ret] = '\0'; + mbedtls_printf(" %d early data bytes read\n\n%s\n", + ret, (char *) buf); + } + continue; + } +#endif /* MBEDTLS_SSL_EARLY_DATA */ + #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS && ssl_async_keys.inject_error == SSL_ASYNC_INJECT_ERROR_CANCEL) { diff --git a/tests/data_files/tls13_early_data.txt b/tests/data_files/tls13_early_data.txt index 0c84b0720..95811fd39 100644 --- a/tests/data_files/tls13_early_data.txt +++ b/tests/data_files/tls13_early_data.txt @@ -1,3 +1,4 @@ EarlyData context: line 0 lf EarlyData context: line 1 lf +EarlyData context: line 2 lf EarlyData context: If it appears, that means early_data received. From 579bd4d46b3b253deea9fcfc8bd5826aad088b00 Mon Sep 17 00:00:00 2001 From: Jerry Yu Date: Thu, 16 Nov 2023 15:37:10 +0800 Subject: [PATCH 204/215] Update early data test Signed-off-by: Jerry Yu Signed-off-by: Ronald Cron --- tests/opt-testcases/tls13-misc.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh index c1682e3cf..b6894de81 100755 --- a/tests/opt-testcases/tls13-misc.sh +++ b/tests/opt-testcases/tls13-misc.sh @@ -506,4 +506,7 @@ run_test "TLS 1.3 G->m: EarlyData: feature is enabled, good." \ -s "Sent max_early_data_size=$EARLY_DATA_INPUT_LEN" \ -s "ClientHello: early_data(42) extension exists." \ -s "EncryptedExtensions: early_data(42) extension exists." \ - -s "$( tail -1 $EARLY_DATA_INPUT )" + -s "$( head -1 $EARLY_DATA_INPUT )" \ + -s "$( tail -1 $EARLY_DATA_INPUT )" \ + -s "200 early data bytes read" \ + -s "106 early data bytes read" From 7b6ee9482e71a47488278a7e1d68d8681f03e174 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 12 Jan 2024 10:29:55 +0100 Subject: [PATCH 205/215] tls13: srv: Reject early data in case of HRR Signed-off-by: Ronald Cron --- library/ssl_tls13_server.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 97ce5c276..6933d1a05 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1780,7 +1780,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, } #if defined(MBEDTLS_SSL_EARLY_DATA) -static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl) +static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl, + int hrr_required) { mbedtls_ssl_handshake_params *handshake = ssl->handshake; @@ -1801,6 +1802,11 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl) return; } + if (hrr_required) { + MBEDTLS_SSL_DEBUG_MSG(1, ("EarlyData: rejected, HRR required.")); + return; + } + if (!handshake->resume) { /* We currently support early data only in the case of PSKs established via a NewSessionTicket message thus in the case of a session @@ -1858,7 +1864,8 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl) /* Update the handshake state machine */ MBEDTLS_CHECK_RETURN_CRITICAL -static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl) +static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl, + int hrr_required) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -1882,8 +1889,8 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl) } #if defined(MBEDTLS_SSL_EARLY_DATA) - /* There is enough information, update early data state. */ - ssl_tls13_update_early_data_status(ssl); + /* There is enough information, update early data status. */ + ssl_tls13_update_early_data_status(ssl, hrr_required); if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { ret = mbedtls_ssl_tls13_compute_early_transform(ssl); @@ -1893,6 +1900,8 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl) return ret; } } +#else + ((void) hrr_required); #endif /* MBEDTLS_SSL_EARLY_DATA */ return 0; @@ -1947,7 +1956,9 @@ static int ssl_tls13_process_client_hello(mbedtls_ssl_context *ssl) return 0; } - MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_client_hello(ssl)); + MBEDTLS_SSL_PROC_CHK( + ssl_tls13_postprocess_client_hello(ssl, parse_client_hello_ret == + SSL_CLIENT_HELLO_HRR_REQUIRED)); if (SSL_CLIENT_HELLO_OK == parse_client_hello_ret) { mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO); From 7d21cded3f0bf8fe7096f253585cf19547a5deb4 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 30 Jan 2024 14:37:55 +0100 Subject: [PATCH 206/215] ssl.h: Simplify guard MBEDTLS_SSL_EARLY_DATA implies MBEDTLS_SSL_PROTO_TLS1_3 thus MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_EARLY_DATA is equivalent to MBEDTLS_SSL_EARLY_DATA. Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 7f1bd8f16..610ed2711 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -2018,7 +2018,7 @@ void mbedtls_ssl_conf_transport(mbedtls_ssl_config *conf, int transport); */ void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode); -#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_EARLY_DATA) +#if defined(MBEDTLS_SSL_EARLY_DATA) /** * \brief Set the early data mode * Default: disabled on server and client @@ -2073,7 +2073,7 @@ void mbedtls_ssl_conf_max_early_data_size( mbedtls_ssl_config *conf, uint32_t max_early_data_size); #endif /* MBEDTLS_SSL_SRV_C */ -#endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_EARLY_DATA */ +#endif /* MBEDTLS_SSL_EARLY_DATA */ #if defined(MBEDTLS_X509_CRT_PARSE_C) /** From 0883b8b625a5531f2fc8a61b6b0417f00f76f91e Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 30 Jan 2024 16:13:34 +0100 Subject: [PATCH 207/215] tls13: Introduce early_data_state SSL context field Introduce early_data_state SSL context field to distinguish better this internal state from the status values defined for the mbedtls_ssl_get_early_data_status() API. Distinguish also between the client and server states. Note that the client state are going to be documented and reworked as part of the implementation of mbedtls_ssl_write_early_data(). Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 61 ++++++++++++++++++++++++++++--------- library/ssl_debug_helpers.h | 5 +++ library/ssl_misc.h | 24 --------------- library/ssl_msg.c | 6 ++-- library/ssl_tls.c | 8 +---- library/ssl_tls13_client.c | 14 ++++----- library/ssl_tls13_server.c | 22 ++++++------- 7 files changed, 74 insertions(+), 66 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 610ed2711..bf3085291 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1621,6 +1621,49 @@ struct mbedtls_ssl_config { #endif }; +#if defined(MBEDTLS_SSL_EARLY_DATA) +enum mbedtls_ssl_cli_early_data_state { + MBEDTLS_SSL_CLI_EARLY_DATA_STATE_NOT_SENT, + MBEDTLS_SSL_CLI_EARLY_DATA_STATE_ACCEPTED, + MBEDTLS_SSL_CLI_EARLY_DATA_STATE_REJECTED +}; + +/* + * MBEDTLS_SSL_SRV_EARLY_DATA_STATE_WAITING_CH: + * The server is waiting for the ClientHello. + * + * MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING: + * The server has received a ClientHello indicating early data and has + * accepted them. It is now expecting early data and the end of early + * data message. + * + * MBEDTLS_SSL_SRV_EARLY_DATA_STATE_REJECTED: + * The server has received a ClientHello indicating early data and has + * rejected them. + * + * MBEDTLS_SSL_SRV_EARLY_DATA_STATE_NOT_RECEIVED: + * The server has received a ClientHello, no indication of early data. + * + * MBEDTLS_SSL_SRV_EARLY_DATA_STATE_EOED_RECEIVED + * The server has received the early data extension, it has accepted early + * data and received the end of early data message from the client marking + * the end of early data reception. + */ + +enum mbedtls_ssl_srv_early_data_state { + MBEDTLS_SSL_SRV_EARLY_DATA_STATE_WAITING_CH, + MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING, + MBEDTLS_SSL_SRV_EARLY_DATA_STATE_REJECTED, + MBEDTLS_SSL_SRV_EARLY_DATA_STATE_NOT_RECEIVED, + MBEDTLS_SSL_SRV_EARLY_DATA_STATE_EOED_RECEIVED +}; + +union mbedtls_ssl_early_data_state { + enum mbedtls_ssl_cli_early_data_state cli; + enum mbedtls_ssl_srv_early_data_state srv; +}; +#endif /* MBEDTLS_SSL_EARLY_DATA */ + struct mbedtls_ssl_context { const mbedtls_ssl_config *MBEDTLS_PRIVATE(conf); /*!< configuration information */ @@ -1655,22 +1698,10 @@ struct mbedtls_ssl_context { #if defined(MBEDTLS_SSL_EARLY_DATA) /** - * On client side, status of the negotiation of the use of early data. - * See the documentation of mbedtls_ssl_get_early_data_status() for more - * information. - * - * On server side, internal only, status of early data in the course of an - * handshake. One of MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN, - * #MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED, - * #MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED, - * MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED and - * MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED. - * - * Reset to #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT or - * MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN, at the beginning of a new - * handshake. + * State of the sending (client side) or reception (server side) of early + * data. Reset to the initial state at the beginning of a new handshake. */ - int MBEDTLS_PRIVATE(early_data_status); + union mbedtls_ssl_early_data_state MBEDTLS_PRIVATE(early_data_state); #endif unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */ diff --git a/library/ssl_debug_helpers.h b/library/ssl_debug_helpers.h index 2b0e73772..3410c9022 100644 --- a/library/ssl_debug_helpers.h +++ b/library/ssl_debug_helpers.h @@ -49,6 +49,11 @@ void mbedtls_ssl_print_ticket_flags(const mbedtls_ssl_context *ssl, unsigned int flags); #endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_EARLY_DATA) +const char *mbedtls_ssl_cli_early_data_state_str(enum mbedtls_ssl_cli_early_data_state in); +const char *mbedtls_ssl_srv_early_data_state_str(enum mbedtls_ssl_srv_early_data_state in); +#endif + #define MBEDTLS_SSL_PRINT_EXTS(level, hs_msg_type, extensions_mask) \ mbedtls_ssl_print_extensions(ssl, level, __FILE__, __LINE__, \ hs_msg_type, extensions_mask, NULL) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 943940826..2a488bbdb 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2130,30 +2130,6 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl, unsigned char *buf, const unsigned char *end, size_t *out_len); - -#if defined(MBEDTLS_SSL_SRV_C) -/* Additional internal early data status, server side only. */ -/* - * The server has not received the ClientHello yet, the status of early data - * is thus unknown. - */ -#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN \ - MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT - -/* - * The server has received the ClientHello, it contained no early data - * extension. - */ -#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED 3 - -/* - * The server has received the early data extension, it has accepted early - * data and received the end of early data message from the client marking the - * end of early data reception. - */ -#define MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED 4 -#endif /* MBEDTLS_SSL_SRV_C */ - #endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 825ca8fe9..c6ba1158d 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -5888,8 +5888,10 @@ int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl, return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; } - if ((ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN) && - (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED)) { + if ((ssl->early_data_state.srv != + MBEDTLS_SSL_SRV_EARLY_DATA_STATE_WAITING_CH) && + (ssl->early_data_state.srv != + MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING)) { return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; } diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 72db821a6..50a8cd209 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1099,13 +1099,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl) } #if defined(MBEDTLS_SSL_EARLY_DATA) -#if defined(MBEDTLS_SSL_SRV_C) - MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN == 0, - "MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN not equal to 0"); -#endif - MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT == 0, - "MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT not equal to 0"); - ssl->early_data_status = 0; + ssl->early_data_state.cli = 0; #endif /* Initialize structures */ diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 76f0f1896..94bbfe85a 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1195,10 +1195,10 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl, * `accepted` if the EncryptedExtension message contain an early data * indication extension. */ - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; + ssl->early_data_state.cli = MBEDTLS_SSL_CLI_EARLY_DATA_STATE_REJECTED; } else { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write early_data extension")); - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT; + ssl->early_data_state.cli = MBEDTLS_SSL_CLI_EARLY_DATA_STATE_NOT_SENT; } #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -1235,7 +1235,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl) size_t psk_len; const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) { + if (ssl->early_data_state.cli == MBEDTLS_SSL_CLI_EARLY_DATA_STATE_REJECTED) { MBEDTLS_SSL_DEBUG_MSG( 1, ("Set hs psk for early data when writing the first psk")); @@ -1916,7 +1916,7 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl) * cases we compute it here. */ #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT || + if (ssl->early_data_state.cli == MBEDTLS_SSL_CLI_EARLY_DATA_STATE_NOT_SENT || handshake->key_exchange_mode == MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL) #endif @@ -2228,7 +2228,7 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl) return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; } - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; + ssl->early_data_state.cli = MBEDTLS_SSL_CLI_EARLY_DATA_STATE_ACCEPTED; } #endif @@ -2565,9 +2565,9 @@ static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl) } #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { + if (ssl->early_data_state.cli == MBEDTLS_SSL_CLI_EARLY_DATA_STATE_ACCEPTED) { mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA); - } else if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) { + } else if (ssl->early_data_state.cli == MBEDTLS_SSL_CLI_EARLY_DATA_STATE_REJECTED) { mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE); } else #endif /* MBEDTLS_SSL_EARLY_DATA */ diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 6933d1a05..9fcea5821 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1780,8 +1780,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, } #if defined(MBEDTLS_SSL_EARLY_DATA) -static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl, - int hrr_required) +static void ssl_tls13_update_early_data_state(mbedtls_ssl_context *ssl, + int hrr_required) { mbedtls_ssl_handshake_params *handshake = ssl->handshake; @@ -1789,11 +1789,11 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl, MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) == 0) { MBEDTLS_SSL_DEBUG_MSG( 1, ("EarlyData: no early data extension received.")); - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED; + ssl->early_data_state.srv = MBEDTLS_SSL_SRV_EARLY_DATA_STATE_NOT_RECEIVED; return; } - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; + ssl->early_data_state.srv = MBEDTLS_SSL_SRV_EARLY_DATA_STATE_REJECTED; if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) { MBEDTLS_SSL_DEBUG_MSG( @@ -1856,7 +1856,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl, return; } - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; + ssl->early_data_state.srv = MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING; } #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -1890,9 +1890,9 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_EARLY_DATA) /* There is enough information, update early data status. */ - ssl_tls13_update_early_data_status(ssl, hrr_required); + ssl_tls13_update_early_data_state(ssl, hrr_required); - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { + if (ssl->early_data_state.srv == MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING) { ret = mbedtls_ssl_tls13_compute_early_transform(ssl); if (ret != 0) { MBEDTLS_SSL_DEBUG_RET( @@ -2541,7 +2541,7 @@ static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_ALPN */ #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { + if (ssl->early_data_state.srv == MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING) { ret = mbedtls_ssl_tls13_write_early_data_ext( ssl, 0, p, end, &output_len); if (ret != 0) { @@ -2868,7 +2868,7 @@ static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl) } #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { + if (ssl->early_data_state.srv == MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING) { /* See RFC 8446 section A.2 for more information */ MBEDTLS_SSL_DEBUG_MSG( 1, ("Switch to early keys for inbound traffic. " @@ -3011,8 +3011,8 @@ static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl) MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_end_of_early_data( ssl, buf, buf + buf_len)); - ssl->early_data_status = - MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED; + ssl->early_data_state.srv = + MBEDTLS_SSL_SRV_EARLY_DATA_STATE_EOED_RECEIVED; MBEDTLS_SSL_DEBUG_MSG( 1, ("Switch to handshake keys for inbound traffic" From 2c4308958d613f47b33003beba0c087419c24895 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 30 Jan 2024 18:11:11 +0100 Subject: [PATCH 208/215] ssl.h: Fix comments Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index bf3085291..485ff57af 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -4793,7 +4793,7 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, * defined in RFC 8446 (TLS 1.3 specification), has been * received as part of the handshake. This is server specific. * You must call mbedtls_ssl_read_early_data() to read the - * early data before to resume the handshake. + * early data before resuming the handshake. * \return Another SSL error code - in this case you must stop using * the context (see below). * @@ -4947,7 +4947,7 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl); * received as part of an handshake triggered by the function. * This is server specific. You must call * mbedtls_ssl_read_early_data() to read the early data before - * to resume the reading of post handshake application data. + * resuming the reading of post handshake application data. * \return Another SSL error code - in this case you must stop using * the context (see below). * @@ -5028,7 +5028,7 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len); * received as part of an handshake triggered by the function. * This is server specific. You must call * mbedtls_ssl_read_early_data() to read the early data before - * to resume the writing of application data. + * resuming the writing of application data. * \return Another SSL error code - in this case you must stop using * the context (see below). * From 44d70a5f2341b3664b8be81a37b94ee97773c4bc Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 30 Jan 2024 18:16:47 +0100 Subject: [PATCH 209/215] tls13: early data: Improve documentation Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 75 ++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 485ff57af..ccabbc239 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -92,11 +92,12 @@ #define MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA -0x7B80 /** * Early data has been received as part of an on-going handshake. - * This error code can be returned only on server side. This error code can be - * returned by mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), - * mbedtls_ssl_read() and mbedtls_ssl_write() if early data has been received - * as part of the handshake sequence they triggered. To read the early - * data, call mbedtls_ssl_read_early_data(). + * This error code can be returned only on server side if and only if early + * data has been enabled by means of the mbedtls_ssl_conf_early_data() API. + * This error code can then be returned by mbedtls_ssl_handshake(), + * mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or mbedtls_ssl_write() if + * early data has been received as part of the handshake sequence they + * triggered. To read the early data, call mbedtls_ssl_read_early_data(). */ #define MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA -0x7C00 /** Not possible to write early data */ @@ -2057,14 +2058,23 @@ void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode); * \param conf The SSL configuration to use. * \param early_data_enabled can be: * - * MBEDTLS_SSL_EARLY_DATA_DISABLED: early data functionality is disabled - * This is the default on client and server. + * MBEDTLS_SSL_EARLY_DATA_DISABLED: + * Early data functionality is disabled. This is the default on client and + * server. * - * MBEDTLS_SSL_EARLY_DATA_ENABLED: early data functionality is enabled and - * may be negotiated in the handshake. Application using - * early data functionality needs to be aware of the - * lack of replay protection of the early data application - * payloads. + * MBEDTLS_SSL_EARLY_DATA_ENABLED: + * Early data functionality is enabled and may be negotiated in the handshake. + * Application using early data functionality needs to be aware that the + * security properties for early data (also refered to as 0-RTT data) are + * weaker than those for other kinds of TLS data. See the documentation of + * mbedtls_ssl_write_early_data() and mbedtls_ssl_read_early_data() for more + * information. + * When early data functionality is enabled on server and only in that case, + * the call to one of the APIs that trigger or resume an handshake sequence, + * namely mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), + * mbedtls_ssl_read() or mbedtls_ssl_write() may return with the error code + * MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA indicating that some early data have + * been received. To read the early data, call mbedtls_ssl_read_early_data(). * * \warning This interface is experimental and may change without notice. * @@ -4791,9 +4801,11 @@ int mbedtls_ssl_get_session(const mbedtls_ssl_context *ssl, * this case you must stop using the context (see below). * \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as * defined in RFC 8446 (TLS 1.3 specification), has been - * received as part of the handshake. This is server specific. - * You must call mbedtls_ssl_read_early_data() to read the - * early data before resuming the handshake. + * received as part of the handshake. This is server specific + * and may occur only if the early data feature has been + * enabled on server (see mbedtls_ssl_conf_early_data() + * documentation). You must call mbedtls_ssl_read_early_data() + * to read the early data before resuming the handshake. * \return Another SSL error code - in this case you must stop using * the context (see below). * @@ -4944,10 +4956,11 @@ int mbedtls_ssl_renegotiate(mbedtls_ssl_context *ssl); * new connection using the same source port. See below. * \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as * defined in RFC 8446 (TLS 1.3 specification), has been - * received as part of an handshake triggered by the function. - * This is server specific. You must call - * mbedtls_ssl_read_early_data() to read the early data before - * resuming the reading of post handshake application data. + * received as part of the handshake. This is server specific + * and may occur only if the early data feature has been + * enabled on server (see mbedtls_ssl_conf_early_data() + * documentation). You must call mbedtls_ssl_read_early_data() + * to read the early data before resuming the handshake. * \return Another SSL error code - in this case you must stop using * the context (see below). * @@ -5025,10 +5038,11 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len); * the handshake when you're done attending other tasks. * \return #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA if early data, as * defined in RFC 8446 (TLS 1.3 specification), has been - * received as part of an handshake triggered by the function. - * This is server specific. You must call - * mbedtls_ssl_read_early_data() to read the early data before - * resuming the writing of application data. + * received as part of the handshake. This is server specific + * and may occur only if the early data feature has been + * enabled on server (see mbedtls_ssl_conf_early_data() + * documentation). You must call mbedtls_ssl_read_early_data() + * to read the early data before resuming the handshake. * \return Another SSL error code - in this case you must stop using * the context (see below). * @@ -5111,6 +5125,21 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); * \note This API is server specific. * * \note Early data is defined in the TLS 1.3 specification, RFC 8446. + * IMPORTANT NOTE from section 2.3 of the specification: + * + * The security properties for 0-RTT data are weaker than + * those for other kinds of TLS data. Specifically: + * - This data is not forward secret, as it is encrypted + * solely under keys derived using the offered PSK. + * - There are no guarantees of non-replay between connections. + * Protection against replay for ordinary TLS 1.3 1-RTT data + * is provided via the server's Random value, but 0-RTT data + * does not depend on the ServerHello and therefore has + * weaker guarantees. This is especially relevant if the + * data is authenticated either with TLS client + * authentication or inside the application protocol. The + * same warnings apply to any use of the + * early_exporter_master_secret. * * \note This function behaves mainly as mbedtls_ssl_read(). The * specification of mbedtls_ssl_read() relevant to TLS 1.3 From ed7d4bfda589684c59aaadc14e4bfdba07f7cd3d Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 31 Jan 2024 07:55:19 +0100 Subject: [PATCH 210/215] tls13: srv: Simplify mbedtls_ssl_read_early_data() API Do not progress the handshake in the API, just read early data if some has been detected by a previous call to mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or mbedtls_ssl_write(). Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 44 +++++++++----------------------------- library/ssl_msg.c | 42 ++++-------------------------------- library/ssl_tls13_server.c | 4 ++++ 3 files changed, 18 insertions(+), 72 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index ccabbc239..5644f08c8 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -5141,49 +5141,25 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); * same warnings apply to any use of the * early_exporter_master_secret. * - * \note This function behaves mainly as mbedtls_ssl_read(). The - * specification of mbedtls_ssl_read() relevant to TLS 1.3 - * (thus not the parts specific to (D)TLS 1.2) applies to this - * function and the present documentation is restricted to the - * differences with mbedtls_ssl_read(). - * - * \note This function can be used in conjunction with + * \note This function is used in conjunction with * mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), * mbedtls_ssl_read() and mbedtls_ssl_write() to read early * data when these functions return * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA. * - * \param ssl SSL context + * \param ssl SSL context, it must have been initialized and set up. * \param buf buffer that will hold the data * \param len maximum number of bytes to read * - * \note Unlike mbedtls_ssl_read(), this function does not return + * \return The (positive) number of bytes read if successful. + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid. + * \return #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA if it is not + * possible to read early data for the SSL context \p ssl. Note + * that this function is intended to be called for an SSL + * context \p ssl only after a call to mbedtls_ssl_handshake(), + * mbedtls_ssl_handshake_step(), mbedtls_ssl_read() or + * mbedtls_ssl_write() for \p ssl that has returned * #MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA. - * - * \return One additional specific return value: - * #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA. - * - * #MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA is returned when it - * is not possible to read early data for the SSL context - * \p ssl. - * - * It may have been possible and it is not possible - * anymore because the server received the End of Early Data - * message or the maximum number of allowed early data for the - * PSK in use has been reached. - * - * It may never have been possible and will never be possible - * for the SSL context \p ssl because the use of early data - * is disabled for that context or more generally the context - * is not suitably configured to enable early data or the - * client does not use early data or the first call to the - * function was done while the handshake was already too - * advanced to gather and accept early data. - * - * It is not possible to read early data for the SSL context - * \p ssl but this does not preclude for using it with - * mbedtls_ssl_write(), mbedtls_ssl_read() or - * mbedtls_ssl_handshake(). */ int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len); diff --git a/library/ssl_msg.c b/library/ssl_msg.c index c6ba1158d..3547f6798 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -5865,54 +5865,20 @@ int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) return ret; } - #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA) int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const struct mbedtls_ssl_config *conf; - unsigned char *p = buf; - - if (ssl == NULL || ((conf = ssl->conf) == NULL)) { + if (ssl == NULL || (ssl->conf == NULL)) { return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } - if ((!mbedtls_ssl_conf_is_tls13_enabled(conf)) || - (conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) || - (conf->early_data_enabled != MBEDTLS_SSL_EARLY_DATA_ENABLED)) { + if ((ssl->state != MBEDTLS_SSL_END_OF_EARLY_DATA) || + (ssl->in_offt == NULL)) { return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; } - if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) { - return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; - } - - if ((ssl->early_data_state.srv != - MBEDTLS_SSL_SRV_EARLY_DATA_STATE_WAITING_CH) && - (ssl->early_data_state.srv != - MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING)) { - return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; - } - - ret = mbedtls_ssl_handshake(ssl); - if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) { - if (ssl->in_offt == NULL) { - /* Set the reading pointer */ - ssl->in_offt = ssl->in_msg; - } - ret = ssl_read_application_data(ssl, p, len); - } else if (ret == 0) { - /* - * If the handshake is completed, return immediately that early data - * cannot be read anymore. This potentially saves another call to this - * API and when the function returns 0, it only means that zero byte - * of early data has been received. - */ - return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; - } - - return ret; + return ssl_read_application_data(ssl, buf, len); } #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA */ diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 9fcea5821..5b90dd5c7 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -2929,6 +2929,10 @@ static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl) * * TODO: Add received data size check here. */ + if (ssl->in_offt == NULL) { + /* Set the reading pointer */ + ssl->in_offt = ssl->in_msg; + } return SSL_GOT_EARLY_DATA; } From 164537c4a65b66dcd57a0a2e074304c5ffb9cf03 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 1 Feb 2024 18:05:47 +0100 Subject: [PATCH 211/215] tls13: early data: Improve, add comments Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 5 +++-- library/ssl_msg.c | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 5644f08c8..2aae32ea2 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -2074,7 +2074,8 @@ void mbedtls_ssl_conf_authmode(mbedtls_ssl_config *conf, int authmode); * namely mbedtls_ssl_handshake(), mbedtls_ssl_handshake_step(), * mbedtls_ssl_read() or mbedtls_ssl_write() may return with the error code * MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA indicating that some early data have - * been received. To read the early data, call mbedtls_ssl_read_early_data(). + * been received. To read the early data, call mbedtls_ssl_read_early_data() + * before calling the original function again. * * \warning This interface is experimental and may change without notice. * @@ -5124,7 +5125,7 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl); * * \note This API is server specific. * - * \note Early data is defined in the TLS 1.3 specification, RFC 8446. + * \warning Early data is defined in the TLS 1.3 specification, RFC 8446. * IMPORTANT NOTE from section 2.3 of the specification: * * The security properties for 0-RTT data are weaker than diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 3547f6798..20501c940 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -5873,6 +5873,10 @@ int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl, return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; } + /* + * The server may receive early data only while waiting for the End of + * Early Data handshake message. + */ if ((ssl->state != MBEDTLS_SSL_END_OF_EARLY_DATA) || (ssl->in_offt == NULL)) { return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA; From 3b9034544e7fd2f5dc634795c8c3996506de7a10 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 1 Feb 2024 18:11:05 +0100 Subject: [PATCH 212/215] Revert "tls13: Introduce early_data_state SSL context field" This reverts commit 0883b8b625a5531f2fc8a61b6b0417f00f76f91e. Due to the scope reduction of mbedtls_ssl_read_early_data() it is not necessary anymore to refine the usage of early_data_status/state rather the opposite. Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 61 +++++++++---------------------------- library/ssl_debug_helpers.h | 5 --- library/ssl_misc.h | 24 +++++++++++++++ library/ssl_tls.c | 8 ++++- library/ssl_tls13_client.c | 14 ++++----- library/ssl_tls13_server.c | 22 ++++++------- 6 files changed, 64 insertions(+), 70 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 2aae32ea2..635804d3a 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1622,49 +1622,6 @@ struct mbedtls_ssl_config { #endif }; -#if defined(MBEDTLS_SSL_EARLY_DATA) -enum mbedtls_ssl_cli_early_data_state { - MBEDTLS_SSL_CLI_EARLY_DATA_STATE_NOT_SENT, - MBEDTLS_SSL_CLI_EARLY_DATA_STATE_ACCEPTED, - MBEDTLS_SSL_CLI_EARLY_DATA_STATE_REJECTED -}; - -/* - * MBEDTLS_SSL_SRV_EARLY_DATA_STATE_WAITING_CH: - * The server is waiting for the ClientHello. - * - * MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING: - * The server has received a ClientHello indicating early data and has - * accepted them. It is now expecting early data and the end of early - * data message. - * - * MBEDTLS_SSL_SRV_EARLY_DATA_STATE_REJECTED: - * The server has received a ClientHello indicating early data and has - * rejected them. - * - * MBEDTLS_SSL_SRV_EARLY_DATA_STATE_NOT_RECEIVED: - * The server has received a ClientHello, no indication of early data. - * - * MBEDTLS_SSL_SRV_EARLY_DATA_STATE_EOED_RECEIVED - * The server has received the early data extension, it has accepted early - * data and received the end of early data message from the client marking - * the end of early data reception. - */ - -enum mbedtls_ssl_srv_early_data_state { - MBEDTLS_SSL_SRV_EARLY_DATA_STATE_WAITING_CH, - MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING, - MBEDTLS_SSL_SRV_EARLY_DATA_STATE_REJECTED, - MBEDTLS_SSL_SRV_EARLY_DATA_STATE_NOT_RECEIVED, - MBEDTLS_SSL_SRV_EARLY_DATA_STATE_EOED_RECEIVED -}; - -union mbedtls_ssl_early_data_state { - enum mbedtls_ssl_cli_early_data_state cli; - enum mbedtls_ssl_srv_early_data_state srv; -}; -#endif /* MBEDTLS_SSL_EARLY_DATA */ - struct mbedtls_ssl_context { const mbedtls_ssl_config *MBEDTLS_PRIVATE(conf); /*!< configuration information */ @@ -1699,10 +1656,22 @@ struct mbedtls_ssl_context { #if defined(MBEDTLS_SSL_EARLY_DATA) /** - * State of the sending (client side) or reception (server side) of early - * data. Reset to the initial state at the beginning of a new handshake. + * On client side, status of the negotiation of the use of early data. + * See the documentation of mbedtls_ssl_get_early_data_status() for more + * information. + * + * On server side, internal only, status of early data in the course of an + * handshake. One of MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN, + * #MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED, + * #MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED, + * MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED and + * MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED. + * + * Reset to #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT or + * MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN, at the beginning of a new + * handshake. */ - union mbedtls_ssl_early_data_state MBEDTLS_PRIVATE(early_data_state); + int MBEDTLS_PRIVATE(early_data_status); #endif unsigned MBEDTLS_PRIVATE(badmac_seen); /*!< records with a bad MAC received */ diff --git a/library/ssl_debug_helpers.h b/library/ssl_debug_helpers.h index 3410c9022..2b0e73772 100644 --- a/library/ssl_debug_helpers.h +++ b/library/ssl_debug_helpers.h @@ -49,11 +49,6 @@ void mbedtls_ssl_print_ticket_flags(const mbedtls_ssl_context *ssl, unsigned int flags); #endif /* MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS */ -#if defined(MBEDTLS_SSL_EARLY_DATA) -const char *mbedtls_ssl_cli_early_data_state_str(enum mbedtls_ssl_cli_early_data_state in); -const char *mbedtls_ssl_srv_early_data_state_str(enum mbedtls_ssl_srv_early_data_state in); -#endif - #define MBEDTLS_SSL_PRINT_EXTS(level, hs_msg_type, extensions_mask) \ mbedtls_ssl_print_extensions(ssl, level, __FILE__, __LINE__, \ hs_msg_type, extensions_mask, NULL) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 2a488bbdb..943940826 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2130,6 +2130,30 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl, unsigned char *buf, const unsigned char *end, size_t *out_len); + +#if defined(MBEDTLS_SSL_SRV_C) +/* Additional internal early data status, server side only. */ +/* + * The server has not received the ClientHello yet, the status of early data + * is thus unknown. + */ +#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN \ + MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT + +/* + * The server has received the ClientHello, it contained no early data + * extension. + */ +#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED 3 + +/* + * The server has received the early data extension, it has accepted early + * data and received the end of early data message from the client marking the + * end of early data reception. + */ +#define MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED 4 +#endif /* MBEDTLS_SSL_SRV_C */ + #endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 50a8cd209..72db821a6 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1099,7 +1099,13 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl) } #if defined(MBEDTLS_SSL_EARLY_DATA) - ssl->early_data_state.cli = 0; +#if defined(MBEDTLS_SSL_SRV_C) + MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN == 0, + "MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN not equal to 0"); +#endif + MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT == 0, + "MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT not equal to 0"); + ssl->early_data_status = 0; #endif /* Initialize structures */ diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 94bbfe85a..76f0f1896 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1195,10 +1195,10 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl, * `accepted` if the EncryptedExtension message contain an early data * indication extension. */ - ssl->early_data_state.cli = MBEDTLS_SSL_CLI_EARLY_DATA_STATE_REJECTED; + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; } else { MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write early_data extension")); - ssl->early_data_state.cli = MBEDTLS_SSL_CLI_EARLY_DATA_STATE_NOT_SENT; + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT; } #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -1235,7 +1235,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl) size_t psk_len; const mbedtls_ssl_ciphersuite_t *ciphersuite_info; - if (ssl->early_data_state.cli == MBEDTLS_SSL_CLI_EARLY_DATA_STATE_REJECTED) { + if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) { MBEDTLS_SSL_DEBUG_MSG( 1, ("Set hs psk for early data when writing the first psk")); @@ -1916,7 +1916,7 @@ static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl) * cases we compute it here. */ #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_state.cli == MBEDTLS_SSL_CLI_EARLY_DATA_STATE_NOT_SENT || + if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT || handshake->key_exchange_mode == MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL) #endif @@ -2228,7 +2228,7 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl) return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; } - ssl->early_data_state.cli = MBEDTLS_SSL_CLI_EARLY_DATA_STATE_ACCEPTED; + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; } #endif @@ -2565,9 +2565,9 @@ static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl) } #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_state.cli == MBEDTLS_SSL_CLI_EARLY_DATA_STATE_ACCEPTED) { + if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA); - } else if (ssl->early_data_state.cli == MBEDTLS_SSL_CLI_EARLY_DATA_STATE_REJECTED) { + } else if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) { mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE); } else #endif /* MBEDTLS_SSL_EARLY_DATA */ diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 5b90dd5c7..4bdb7e7b8 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1780,8 +1780,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, } #if defined(MBEDTLS_SSL_EARLY_DATA) -static void ssl_tls13_update_early_data_state(mbedtls_ssl_context *ssl, - int hrr_required) +static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl, + int hrr_required) { mbedtls_ssl_handshake_params *handshake = ssl->handshake; @@ -1789,11 +1789,11 @@ static void ssl_tls13_update_early_data_state(mbedtls_ssl_context *ssl, MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) == 0) { MBEDTLS_SSL_DEBUG_MSG( 1, ("EarlyData: no early data extension received.")); - ssl->early_data_state.srv = MBEDTLS_SSL_SRV_EARLY_DATA_STATE_NOT_RECEIVED; + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED; return; } - ssl->early_data_state.srv = MBEDTLS_SSL_SRV_EARLY_DATA_STATE_REJECTED; + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) { MBEDTLS_SSL_DEBUG_MSG( @@ -1856,7 +1856,7 @@ static void ssl_tls13_update_early_data_state(mbedtls_ssl_context *ssl, return; } - ssl->early_data_state.srv = MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING; + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; } #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -1890,9 +1890,9 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_EARLY_DATA) /* There is enough information, update early data status. */ - ssl_tls13_update_early_data_state(ssl, hrr_required); + ssl_tls13_update_early_data_status(ssl, hrr_required); - if (ssl->early_data_state.srv == MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING) { + if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { ret = mbedtls_ssl_tls13_compute_early_transform(ssl); if (ret != 0) { MBEDTLS_SSL_DEBUG_RET( @@ -2541,7 +2541,7 @@ static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_ALPN */ #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_state.srv == MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING) { + if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { ret = mbedtls_ssl_tls13_write_early_data_ext( ssl, 0, p, end, &output_len); if (ret != 0) { @@ -2868,7 +2868,7 @@ static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl) } #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_state.srv == MBEDTLS_SSL_SRV_EARLY_DATA_STATE_ACCEPTING) { + if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { /* See RFC 8446 section A.2 for more information */ MBEDTLS_SSL_DEBUG_MSG( 1, ("Switch to early keys for inbound traffic. " @@ -3015,8 +3015,8 @@ static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl) MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_end_of_early_data( ssl, buf, buf + buf_len)); - ssl->early_data_state.srv = - MBEDTLS_SSL_SRV_EARLY_DATA_STATE_EOED_RECEIVED; + ssl->early_data_status = + MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED; MBEDTLS_SSL_DEBUG_MSG( 1, ("Switch to handshake keys for inbound traffic" From 78a38f607cdc4fc5292eefa6d6489a49bc9b1e58 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 1 Feb 2024 18:30:31 +0100 Subject: [PATCH 213/215] tls13: srv: Do not use early_data_status Due to the scope reduction for mbedtls_ssl_read_early_data(), on server as early data state variable we now only need a flag in the handshake context indicating if the server has accepted early data or not. Signed-off-by: Ronald Cron --- include/mbedtls/ssl.h | 16 +++--------- library/ssl_misc.h | 28 +++------------------ library/ssl_tls.c | 10 ++------ library/ssl_tls13_server.c | 37 +++++++++++----------------- tests/suites/test_suite_ssl.function | 3 +-- 5 files changed, 26 insertions(+), 68 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 635804d3a..b0633609d 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1654,22 +1654,14 @@ struct mbedtls_ssl_context { */ mbedtls_ssl_protocol_version MBEDTLS_PRIVATE(tls_version); -#if defined(MBEDTLS_SSL_EARLY_DATA) +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) /** - * On client side, status of the negotiation of the use of early data. + * Status of the negotiation of the use of early data. * See the documentation of mbedtls_ssl_get_early_data_status() for more * information. * - * On server side, internal only, status of early data in the course of an - * handshake. One of MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN, - * #MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED, - * #MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED, - * MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED and - * MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED. - * - * Reset to #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT or - * MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN, at the beginning of a new - * handshake. + * Reset to #MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT when the context is + * reset. */ int MBEDTLS_PRIVATE(early_data_status); #endif diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 943940826..c9632f97b 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -650,6 +650,10 @@ struct mbedtls_ssl_handshake_params { /* Flag indicating if a CertificateRequest message has been sent * to the client or not. */ uint8_t certificate_request_sent; +#if defined(MBEDTLS_SSL_EARLY_DATA) + /* Flag indicating if the server has accepted early data or not. */ + uint8_t early_data_accepted; +#endif #endif /* MBEDTLS_SSL_SRV_C */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) @@ -2130,30 +2134,6 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl, unsigned char *buf, const unsigned char *end, size_t *out_len); - -#if defined(MBEDTLS_SSL_SRV_C) -/* Additional internal early data status, server side only. */ -/* - * The server has not received the ClientHello yet, the status of early data - * is thus unknown. - */ -#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN \ - MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT - -/* - * The server has received the ClientHello, it contained no early data - * extension. - */ -#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED 3 - -/* - * The server has received the early data extension, it has accepted early - * data and received the end of early data message from the client marking the - * end of early data reception. - */ -#define MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED 4 -#endif /* MBEDTLS_SSL_SRV_C */ - #endif /* MBEDTLS_SSL_EARLY_DATA */ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 72db821a6..c952add9b 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1098,14 +1098,8 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl) return MBEDTLS_ERR_SSL_ALLOC_FAILED; } -#if defined(MBEDTLS_SSL_EARLY_DATA) -#if defined(MBEDTLS_SSL_SRV_C) - MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN == 0, - "MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN not equal to 0"); -#endif - MBEDTLS_STATIC_ASSERT(MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT == 0, - "MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT not equal to 0"); - ssl->early_data_status = 0; +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) + ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT; #endif /* Initialize structures */ diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 4bdb7e7b8..8bd70ef02 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -1780,8 +1780,8 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, } #if defined(MBEDTLS_SSL_EARLY_DATA) -static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl, - int hrr_required) +static int ssl_tls13_is_early_data_accepted(mbedtls_ssl_context *ssl, + int hrr_required) { mbedtls_ssl_handshake_params *handshake = ssl->handshake; @@ -1789,22 +1789,19 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl, MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) == 0) { MBEDTLS_SSL_DEBUG_MSG( 1, ("EarlyData: no early data extension received.")); - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_RECEIVED; - return; + return 0; } - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED; - if (ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_DISABLED) { MBEDTLS_SSL_DEBUG_MSG( 1, ("EarlyData: rejected, feature disabled in server configuration.")); - return; + return 0; } if (hrr_required) { MBEDTLS_SSL_DEBUG_MSG(1, ("EarlyData: rejected, HRR required.")); - return; + return 0; } if (!handshake->resume) { @@ -1813,7 +1810,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl, resumption. */ MBEDTLS_SSL_DEBUG_MSG( 1, ("EarlyData: rejected, not a session resumption.")); - return; + return 0; } /* RFC 8446 4.2.10 @@ -1836,7 +1833,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 1, ("EarlyData: rejected, the selected key in " "`pre_shared_key` is not the first one.")); - return; + return 0; } if (handshake->ciphersuite_info->id != @@ -1844,7 +1841,7 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 1, ("EarlyData: rejected, the selected ciphersuite is not the one " "of the selected pre-shared key.")); - return; + return 0; } @@ -1853,11 +1850,10 @@ static void ssl_tls13_update_early_data_status(mbedtls_ssl_context *ssl, 1, ("EarlyData: rejected, early_data not allowed in ticket " "permission bits.")); - return; + return 0; } - ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED; - + return 1; } #endif /* MBEDTLS_SSL_EARLY_DATA */ @@ -1889,10 +1885,10 @@ static int ssl_tls13_postprocess_client_hello(mbedtls_ssl_context *ssl, } #if defined(MBEDTLS_SSL_EARLY_DATA) - /* There is enough information, update early data status. */ - ssl_tls13_update_early_data_status(ssl, hrr_required); + ssl->handshake->early_data_accepted = + ssl_tls13_is_early_data_accepted(ssl, hrr_required); - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { + if (ssl->handshake->early_data_accepted) { ret = mbedtls_ssl_tls13_compute_early_transform(ssl); if (ret != 0) { MBEDTLS_SSL_DEBUG_RET( @@ -2541,7 +2537,7 @@ static int ssl_tls13_write_encrypted_extensions_body(mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_ALPN */ #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { + if (ssl->handshake->early_data_accepted) { ret = mbedtls_ssl_tls13_write_early_data_ext( ssl, 0, p, end, &output_len); if (ret != 0) { @@ -2868,7 +2864,7 @@ static int ssl_tls13_write_server_finished(mbedtls_ssl_context *ssl) } #if defined(MBEDTLS_SSL_EARLY_DATA) - if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) { + if (ssl->handshake->early_data_accepted) { /* See RFC 8446 section A.2 for more information */ MBEDTLS_SSL_DEBUG_MSG( 1, ("Switch to early keys for inbound traffic. " @@ -3015,9 +3011,6 @@ static int ssl_tls13_process_end_of_early_data(mbedtls_ssl_context *ssl) MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_end_of_early_data( ssl, buf, buf + buf_len)); - ssl->early_data_status = - MBEDTLS_SSL_EARLY_DATA_STATUS_END_OF_EARLY_DATA_RECEIVED; - MBEDTLS_SSL_DEBUG_MSG( 1, ("Switch to handshake keys for inbound traffic" "( K_recv = handshake )")); diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index d26407e2d..12b048f38 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -3768,8 +3768,7 @@ void tls13_early_data() &(server_ep.ssl), &(client_ep.ssl), MBEDTLS_SSL_CLIENT_FINISHED), 0); - TEST_EQUAL(server_ep.ssl.early_data_status, - MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED); + TEST_EQUAL(server_ep.ssl.handshake->early_data_accepted, 1); TEST_EQUAL(server_pattern.counter, 1); exit: From 38dbab9f8d3adaba6ffb12769d420565d365e060 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 1 Feb 2024 19:31:56 +0100 Subject: [PATCH 214/215] tests: ssl: Adjust early data test Signed-off-by: Ronald Cron --- tests/suites/test_suite_ssl.function | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index 12b048f38..2d1a757e4 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -12,8 +12,7 @@ #define SSL_MESSAGE_QUEUE_INIT { NULL, 0, 0, 0 } -#if (!defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ - defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \ +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \ defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_DEBUG_C) && \ defined(MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE) && \ defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) && \ @@ -3662,12 +3661,7 @@ exit: } /* END_CASE */ -/* - * The !MBEDTLS_SSL_PROTO_TLS1_2 dependency of tls13_early_data() below is - * a temporary workaround to not run the test in Windows-2013 where there is - * an issue with mbedtls_vsnprintf(). - */ -/* BEGIN_CASE depends_on:!MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */ +/* BEGIN_CASE depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */ void tls13_early_data() { int ret = -1; @@ -3678,7 +3672,6 @@ void tls13_early_data() mbedtls_test_handshake_test_options client_options; mbedtls_test_handshake_test_options server_options; mbedtls_ssl_session saved_session; - mbedtls_test_ssl_log_pattern server_pattern = { NULL, 0 }; /* * Test set-up @@ -3699,9 +3692,6 @@ void tls13_early_data() mbedtls_ssl_conf_early_data(&client_ep.conf, MBEDTLS_SSL_EARLY_DATA_ENABLED); server_options.pk_alg = MBEDTLS_PK_ECDSA; - server_options.srv_log_fun = mbedtls_test_ssl_log_analyzer; - server_options.srv_log_obj = &server_pattern; - server_pattern.pattern = early_data; ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER, &server_options, NULL, NULL, NULL, NULL); @@ -3750,15 +3740,12 @@ void tls13_early_data() ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session); TEST_EQUAL(ret, 0); - mbedtls_debug_set_threshold(3); - TEST_EQUAL(mbedtls_test_move_handshake_to_state( &(client_ep.ssl), &(server_ep.ssl), MBEDTLS_SSL_SERVER_HELLO), 0); TEST_ASSERT(client_ep.ssl.early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT); - TEST_EQUAL(server_pattern.counter, 0); ret = write_early_data(&(client_ep.ssl), (unsigned char *) early_data, early_data_len); @@ -3766,10 +3753,16 @@ void tls13_early_data() TEST_EQUAL(mbedtls_test_move_handshake_to_state( &(server_ep.ssl), &(client_ep.ssl), - MBEDTLS_SSL_CLIENT_FINISHED), 0); + MBEDTLS_SSL_CLIENT_FINISHED), MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA); TEST_EQUAL(server_ep.ssl.handshake->early_data_accepted, 1); - TEST_EQUAL(server_pattern.counter, 1); + TEST_EQUAL(mbedtls_ssl_read_early_data(&(server_ep.ssl), buf, sizeof(buf)), + early_data_len); + TEST_MEMORY_COMPARE(buf, early_data_len, early_data, early_data_len); + + TEST_EQUAL(mbedtls_test_move_handshake_to_state( + &(server_ep.ssl), &(client_ep.ssl), + MBEDTLS_SSL_HANDSHAKE_OVER), 0); exit: mbedtls_test_ssl_endpoint_free(&client_ep, NULL); @@ -3777,7 +3770,6 @@ exit: mbedtls_test_free_handshake_options(&client_options); mbedtls_test_free_handshake_options(&server_options); mbedtls_ssl_session_free(&saved_session); - mbedtls_debug_set_threshold(0); PSA_DONE(); } /* END_CASE */ From 12285c5c7c658a92cecc05a095e36d8d256d828a Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 2 Feb 2024 17:52:41 +0000 Subject: [PATCH 215/215] Add calls to BLOCK_CIPHER_PSA_INIT / BLOCK_CIPHER_PSA_DONE Signed-off-by: Dave Rodgman --- tests/suites/test_suite_gcm.function | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function index 0af4209f4..8bb7b8b8e 100644 --- a/tests/suites/test_suite_gcm.function +++ b/tests/suites/test_suite_gcm.function @@ -499,8 +499,11 @@ exit: void gcm_invalid_iv_len(void) { mbedtls_gcm_context ctx; + mbedtls_gcm_init(&ctx); uint8_t b16[16] = { 0 }; + BLOCK_CIPHER_PSA_INIT(); + // Invalid IV length 0 gcm_reset_ctx(&ctx, b16, sizeof(b16) * 8, b16, 0, MBEDTLS_ERR_GCM_BAD_INPUT); mbedtls_gcm_free(&ctx); @@ -514,8 +517,8 @@ void gcm_invalid_iv_len(void) goto exit; /* To suppress error that exit is defined but not used */ exit: - /* empty */ - return; + mbedtls_gcm_free(&ctx); + BLOCK_CIPHER_PSA_DONE(); } /* END_CASE */ @@ -525,7 +528,10 @@ void gcm_add_len_too_long(void) // Only testable on platforms where sizeof(size_t) >= 8. #if SIZE_MAX >= UINT64_MAX mbedtls_gcm_context ctx; + mbedtls_gcm_init(&ctx); uint8_t b16[16] = { 0 }; + BLOCK_CIPHER_PSA_INIT(); + /* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of AD should * be <= 2^64 - 1, ie < 2^64. This is the minimum invalid length in bytes. */ uint64_t len_max = 1ULL << 61; @@ -550,6 +556,7 @@ void gcm_add_len_too_long(void) exit: mbedtls_gcm_free(&ctx); + BLOCK_CIPHER_PSA_DONE(); #endif } /* END_CASE */ @@ -563,6 +570,9 @@ void gcm_input_len_too_long(void) uint8_t b16[16] = { 0 }; uint8_t out[1]; size_t out_len; + mbedtls_gcm_init(&ctx); + BLOCK_CIPHER_PSA_INIT(); + /* NISP SP 800-38D, Section 5.2.1.1 requires that bit length of input should * be <= 2^39 - 256. This is the maximum valid length in bytes. */ uint64_t len_max = (1ULL << 36) - 32; @@ -590,6 +600,7 @@ void gcm_input_len_too_long(void) exit: mbedtls_gcm_free(&ctx); + BLOCK_CIPHER_PSA_DONE(); #endif } /* END_CASE */