Merge pull request #8887 from gilles-peskine-arm/pk_import_into_psa-fix_doxygen_code_blocks
Fix intended code blocks that were not suitably indented
diff --git a/ChangeLog.d/8824.txt b/ChangeLog.d/8824.txt
index abc305f..6d6bcb7 100644
--- a/ChangeLog.d/8824.txt
+++ b/ChangeLog.d/8824.txt
@@ -1,7 +1,8 @@
Bugfix
* Fix mbedtls_pk_sign(), mbedtls_pk_verify(), mbedtls_pk_decrypt() and
mbedtls_pk_encrypt() on non-opaque RSA keys to honor the padding mode in
- the RSA context. Before, if MBEDTLS_USE_PSA_CRYPTO was enabled, they always
- used PKCS#1 v1.5 even when the RSA context was configured for PKCS#1 v2.1
- (PSS/OAEP). Fixes #8824.
+ the RSA context. Before, if MBEDTLS_USE_PSA_CRYPTO was enabled and the
+ RSA context was configured for PKCS#1 v2.1 (PSS/OAEP), the sign/verify
+ functions performed a PKCS#1 v1.5 signature instead and the
+ encrypt/decrypt functions returned an error. Fixes #8824.
diff --git a/ChangeLog.d/8825.txt b/ChangeLog.d/8825.txt
new file mode 100644
index 0000000..914bd08
--- /dev/null
+++ b/ChangeLog.d/8825.txt
@@ -0,0 +1,6 @@
+Features
+ * mbedtls_psa_get_random() is always available as soon as
+ MBEDTLS_PSA_CRYPTO_CLIENT is enabled at build time and psa_crypto_init() is
+ called at runtime. This together with MBEDTLS_PSA_RANDOM_STATE can be
+ used as random number generator function (f_rng) and context (p_rng) in
+ legacy functions.
diff --git a/ChangeLog.d/add_get_ecp_group_id.txt b/ChangeLog.d/add_get_ecp_group_id.txt
new file mode 100644
index 0000000..3328062
--- /dev/null
+++ b/ChangeLog.d/add_get_ecp_group_id.txt
@@ -0,0 +1,3 @@
+Features
+ * Add new accessor to expose the private group id member of
+ `mbedtls_ecdh_context` structure.
diff --git a/ChangeLog.d/ecp_write_key.txt b/ChangeLog.d/ecp_write_key.txt
new file mode 100644
index 0000000..73354c8
--- /dev/null
+++ b/ChangeLog.d/ecp_write_key.txt
@@ -0,0 +1,8 @@
+Features
+ * The new function mbedtls_ecp_write_key_ext() is similar to
+ mbedtls_ecp_write_key(), but can be used without separately calculating
+ the output length.
+
+New deprecations
+ * mbedtls_ecp_write_key() is deprecated in favor of
+ mbedtls_ecp_write_key_ext().
diff --git a/ChangeLog.d/fix-ssl-session-serialization-config.txt b/ChangeLog.d/fix-ssl-session-serialization-config.txt
new file mode 100644
index 0000000..ca1cc81
--- /dev/null
+++ b/ChangeLog.d/fix-ssl-session-serialization-config.txt
@@ -0,0 +1,4 @@
+Bugfix
+ * Fix missing bitflags in SSL session serialization headers. Their absence
+ allowed SSL sessions saved in one configuration to be loaded in a
+ different, incompatible configuration.
diff --git a/ChangeLog.d/use_exp_mod_core.txt b/ChangeLog.d/use_exp_mod_core.txt
new file mode 100644
index 0000000..8f7193a
--- /dev/null
+++ b/ChangeLog.d/use_exp_mod_core.txt
@@ -0,0 +1,6 @@
+Changes
+ * mbedtls_mpi_exp_mod and code that uses it, notably RSA and DHM operations,
+ have changed their speed/memory compromise as part of a proactive security
+ improvement. The new default value of MBEDTLS_MPI_WINDOW_SIZE roughly
+ preserves the current speed, at the expense of increasing memory
+ consumption.
diff --git a/ChangeLog.d/x509-add-ca_istrue.txt b/ChangeLog.d/x509-add-ca_istrue.txt
new file mode 100644
index 0000000..c950dbc
--- /dev/null
+++ b/ChangeLog.d/x509-add-ca_istrue.txt
@@ -0,0 +1,5 @@
+Features
+ * Add new accessor to expose the `MBEDTLS_PRIVATE(ca_istrue)` member of
+ `mbedtls_x509_crt` structure. This requires setting
+ the MBEDTLS_X509_EXT_BASIC_CONSTRAINTS bit in the certificate's
+ ext_types field.
diff --git a/docs/psa-driver-example-and-guide.md b/docs/psa-driver-example-and-guide.md
index d041723..aa825ad 100644
--- a/docs/psa-driver-example-and-guide.md
+++ b/docs/psa-driver-example-and-guide.md
@@ -157,11 +157,11 @@
```
#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED)
- if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
+ if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
PSA_ALG_IS_ECDSA(alg) &&
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
- PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 &&
- attributes->core.bits == 256 )
+ PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
+ psa_get_key_bits(attributes) == 256 )
{
status = p256_transparent_sign_hash( attributes,
key_buffer,
diff --git a/docs/psa-transition.md b/docs/psa-transition.md
index e89128c..94b57eb 100644
--- a/docs/psa-transition.md
+++ b/docs/psa-transition.md
@@ -845,7 +845,6 @@
```
unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
-size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk));
mbedtls_ecp_keypair *ec = mbedtls_pk_ec(&pk);
psa_ecc_curve_t curve;
{
@@ -862,7 +861,8 @@
mbedtls_ecp_point_free(&Q);
mbedtls_mpi_free(&d);
}
-mbedtls_ecp_write_key(ec, buf, length);
+size_t length;
+mbedtls_ecp_write_key_ext(ec, &length, buf, sizeof(buf));
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_... | ...);
@@ -900,8 +900,8 @@
// Omitted: fill ec with key material
// (the public key will not be used and does not need to be set)
unsigned char buf[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
-size_t length = PSA_BITS_TO_BYTES(mbedtls_pk_bitlen(&pk));
-mbedtls_ecp_write_key(&ec, buf, length);
+size_t length;
+mbedtls_ecp_write_key_ext(&ec, &length, buf, sizeof(buf));
psa_ecc_curve_t curve = ...; // need to determine the curve family manually
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_attributes(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(curve));
@@ -1300,7 +1300,7 @@
The PSA API is a cryptography API, not an arithmetic API. As a consequence, there is no PSA equivalent for the ECC arithmetic functionality exposed by `ecp.h`:
* Manipulation of point objects and input-output: the type `mbedtls_ecp_point` and functions operating on it (`mbedtls_ecp_point_xxx`, `mbedtls_ecp_copy`, `mbedtls_ecp_{set,is}_zero`, `mbedtls_ecp_tls_{read,write}_point`). Note that the PSA export format for public keys corresponds to the uncompressed point format (`MBEDTLS_ECP_PF_UNCOMPRESSED`), so [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) and [`psa_export_public_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1gaf22ae73312217aaede2ea02cdebb6062) are equivalent to `mbedtls_ecp_point_read_binary` and `mbedtls_ecp_point_write_binary` for uncompressed points. The PSA API does not currently support compressed points, but it is likely that such support will be added in the future.
-* Manipulation of key pairs as such, with a bridge to bignum arithmetic (`mbedtls_ecp_keypair` type, `mbedtls_ecp_export`). However, the PSA export format for ECC private keys used by [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) is the same as the format used by `mbedtls_ecp_read_key` and `mbedtls_ecp_write_key`.
+* Manipulation of key pairs as such, with a bridge to bignum arithmetic (`mbedtls_ecp_keypair` type, `mbedtls_ecp_export`). However, the PSA export format for ECC private keys used by [`psa_import_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga0336ea76bf30587ab204a8296462327b), [`psa_export_key`](https://mbed-tls.readthedocs.io/projects/api/en/development/api/group/group__import__export/#group__import__export_1ga668e35be8d2852ad3feeef74ac6f75bf) is the same as the format used by `mbedtls_ecp_read_key` and `mbedtls_ecp_write_key_ext`.
* Elliptic curve arithmetic (`mbedtls_ecp_mul`, `mbedtls_ecp_muladd` and their restartable variants).
### Additional information about RSA
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 931e06d..71d7b97 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -51,15 +51,15 @@
#if !defined(MBEDTLS_MPI_WINDOW_SIZE)
/*
- * Maximum window size used for modular exponentiation. Default: 2
+ * Maximum window size used for modular exponentiation. Default: 3
* Minimum value: 1. Maximum value: 6.
*
* Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
- * for the sliding window calculation. (So 64 by default)
+ * for the sliding window calculation. (So 8 by default)
*
* Reduction in size, reduces speed.
*/
-#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */
+#define MBEDTLS_MPI_WINDOW_SIZE 3 /**< Maximum window size used. */
#endif /* !MBEDTLS_MPI_WINDOW_SIZE */
#if !defined(MBEDTLS_MPI_MAX_SIZE)
diff --git a/include/mbedtls/ecdh.h b/include/mbedtls/ecdh.h
index 792db79..a0909d6 100644
--- a/include/mbedtls/ecdh.h
+++ b/include/mbedtls/ecdh.h
@@ -142,6 +142,19 @@
mbedtls_ecdh_context;
/**
+ * \brief Return the ECP group for provided context.
+ *
+ * \note To access group specific fields, users should use
+ * `mbedtls_ecp_curve_info_from_grp_id` or
+ * `mbedtls_ecp_group_load` on the extracted `group_id`.
+ *
+ * \param ctx The ECDH context to parse. This must not be \c NULL.
+ *
+ * \return The \c mbedtls_ecp_group_id of the context.
+ */
+mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx);
+
+/**
* \brief Check whether a given group can be used for ECDH.
*
* \param gid The ECP group ID to check.
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 0201963..d8f73ae 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -24,6 +24,7 @@
#include "mbedtls/private_access.h"
#include "mbedtls/build_info.h"
+#include "mbedtls/platform_util.h"
#include "mbedtls/bignum.h"
@@ -1327,10 +1328,11 @@
int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
const unsigned char *buf, size_t buflen);
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
/**
* \brief This function exports an elliptic curve private key.
*
- * \note Note that although this function accepts an output
+ * \deprecated Note that although this function accepts an output
* buffer that is smaller or larger than the key, most key
* import interfaces require the output to have exactly
* key's nominal length. It is generally simplest to
@@ -1338,6 +1340,10 @@
* checking that the output buffer is large enough.
* See the description of the \p buflen parameter for
* how to calculate the nominal length.
+ * To avoid this difficulty, use mbedtls_ecp_write_key_ext()
+ * instead.
+ * mbedtls_ecp_write_key() is deprecated and will be
+ * removed in a future version of the library.
*
* \note If the private key was not set in \p key,
* the output is unspecified. Future versions
@@ -1367,8 +1373,31 @@
* representation is larger than the available space in \p buf.
* \return Another negative error code on different kinds of failure.
*/
-int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
- unsigned char *buf, size_t buflen);
+int MBEDTLS_DEPRECATED mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
+ unsigned char *buf, size_t buflen);
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief This function exports an elliptic curve private key.
+ *
+ * \param key The private key.
+ * \param olen On success, the length of the private key.
+ * This is always (`grp->nbits` + 7) / 8 bytes
+ * where `grp->nbits` is the private key size in bits.
+ * \param buf The output buffer for containing the binary representation
+ * of the key.
+ * \param buflen The total length of the buffer in bytes.
+ * #MBEDTLS_ECP_MAX_BYTES is always sufficient.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the \p key
+ * representation is larger than the available space in \p buf.
+ * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if no private key is
+ * set in \p key.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key,
+ size_t *olen, unsigned char *buf, size_t buflen);
/**
* \brief This function exports an elliptic curve public key.
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index 984f031..c78cc23 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -21,44 +21,24 @@
* otherwise error codes would be unknown in test_suite_psa_crypto_util.data.*/
#include <mbedtls/asn1write.h>
-#if defined(MBEDTLS_PSA_CRYPTO_C)
-
-/* Expose whatever RNG the PSA subsystem uses to applications using the
- * mbedtls_xxx API. The declarations and definitions here need to be
- * consistent with the implementation in library/psa_crypto_random_impl.h.
- * See that file for implementation documentation. */
-
-
-/* The type of a `f_rng` random generator function that many library functions
- * take.
- *
- * This type name is not part of the Mbed TLS stable API. It may be renamed
- * or moved without warning.
- */
-typedef int mbedtls_f_rng_t(void *p_rng, unsigned char *output, size_t output_size);
-
-#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
/** The random generator function for the PSA subsystem.
*
* This function is suitable as the `f_rng` random generator function
- * parameter of many `mbedtls_xxx` functions. Use #MBEDTLS_PSA_RANDOM_STATE
- * to obtain the \p p_rng parameter.
+ * parameter of many `mbedtls_xxx` functions.
*
* The implementation of this function depends on the configuration of the
* library.
*
- * \note Depending on the configuration, this may be a function or
- * a pointer to a function.
- *
* \note This function may only be used if the PSA crypto subsystem is active.
* This means that you must call psa_crypto_init() before any call to
* this function, and you must not call this function after calling
* mbedtls_psa_crypto_free().
*
- * \param p_rng The random generator context. This must be
- * #MBEDTLS_PSA_RANDOM_STATE. No other state is
- * supported.
+ * \param p_rng This parameter is only kept for backward compatibility
+ * reasons with legacy `f_rng` functions and it's ignored.
+ * Set to #MBEDTLS_PSA_RANDOM_STATE or NULL.
* \param output The buffer to fill. It must have room for
* \c output_size bytes.
* \param output_size The number of bytes to write to \p output.
@@ -80,32 +60,11 @@
/** The random generator state for the PSA subsystem.
*
- * This macro expands to an expression which is suitable as the `p_rng`
- * random generator state parameter of many `mbedtls_xxx` functions.
- * It must be used in combination with the random generator function
- * mbedtls_psa_get_random().
- *
- * The implementation of this macro depends on the configuration of the
- * library. Do not make any assumption on its nature.
+ * This macro always expands to NULL because the `p_rng` parameter is unused
+ * in mbedtls_psa_get_random(), but it's kept for interface's backward
+ * compatibility.
*/
-#define MBEDTLS_PSA_RANDOM_STATE NULL
-
-#else /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
-
-#if defined(MBEDTLS_CTR_DRBG_C)
-#include "mbedtls/ctr_drbg.h"
-typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
-static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_ctr_drbg_random;
-#elif defined(MBEDTLS_HMAC_DRBG_C)
-#include "mbedtls/hmac_drbg.h"
-typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
-static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_hmac_drbg_random;
-#endif
-extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
-
-#define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
-
-#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
+#define MBEDTLS_PSA_RANDOM_STATE NULL
/** \defgroup psa_tls_helpers TLS helper functions
* @{
@@ -180,7 +139,7 @@
{
return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK);
}
-#endif /* MBEDTLS_PSA_CRYPTO_C */
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 78395d2..9a66663 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1859,7 +1859,8 @@
* within a single datagram. */
#endif /* MBEDTLS_SSL_PROTO_DTLS */
-#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+#if defined(MBEDTLS_SSL_SRV_C)
/*
* One of:
* MBEDTLS_SSL_EARLY_DATA_NO_DISCARD
@@ -1868,6 +1869,8 @@
*/
uint8_t MBEDTLS_PRIVATE(discard_early_data_record);
#endif
+ uint32_t MBEDTLS_PRIVATE(total_early_data_size); /*!< Number of received/written early data bytes */
+#endif /* MBEDTLS_SSL_EARLY_DATA */
/*
* Record layer (outgoing data)
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 3f1a1e7..1ce0d23 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -916,6 +916,18 @@
return ctx->MBEDTLS_PRIVATE(ext_types) & ext_type;
}
+/**
+ * \brief Access the ca_istrue field
+ *
+ * \param[in] crt Certificate to be queried, must not be \c NULL
+ *
+ * \return \c 1 if this a CA certificate \c 0 otherwise.
+ * \return MBEDTLS_ERR_X509_INVALID_EXTENSIONS if the certificate does not contain
+ * the Optional Basic Constraint extension.
+ *
+ */
+int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt);
+
/** \} name Structures and functions for parsing and writing X.509 certificates */
#if defined(MBEDTLS_X509_CRT_WRITE_C)
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index ac21e3e..6ed1f6c 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -59,7 +59,7 @@
psa_key_attributes_t *attributes,
psa_algorithm_t alg2)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2) = alg2;
+ attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2) = alg2;
}
/** Retrieve the enrollment algorithm policy from key attributes.
@@ -71,7 +71,7 @@
static inline psa_algorithm_t psa_get_key_enrollment_algorithm(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2);
+ return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg2);
}
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
@@ -129,7 +129,7 @@
psa_key_attributes_t *attributes,
psa_key_slot_number_t slot_number)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(flags) |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
+ attributes->MBEDTLS_PRIVATE(has_slot_number) = 1;
attributes->MBEDTLS_PRIVATE(slot_number) = slot_number;
}
@@ -142,8 +142,7 @@
static inline void psa_clear_key_slot_number(
psa_key_attributes_t *attributes)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(flags) &=
- ~MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
+ attributes->MBEDTLS_PRIVATE(has_slot_number) = 0;
}
/** Register a key that is already present in a secure element.
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 683d841..3913551 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -266,35 +266,15 @@
* conditionals. */
#define PSA_MAX_KEY_BITS 0xfff8
-/** A mask of flags that can be stored in key attributes.
- *
- * This type is also used internally to store flags in slots. Internal
- * flags are defined in library/psa_crypto_core.h. Internal flags may have
- * the same value as external flags if they are properly handled during
- * key creation and in psa_get_key_attributes.
- */
-typedef uint16_t psa_key_attributes_flag_t;
-
-#define MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER \
- ((psa_key_attributes_flag_t) 0x0001)
-
-/* A mask of key attribute flags used externally only.
- * Only meant for internal checks inside the library. */
-#define MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ( \
- MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER | \
- 0)
-
-/* A mask of key attribute flags used both internally and externally.
- * Currently there aren't any. */
-#define MBEDTLS_PSA_KA_MASK_DUAL_USE ( \
- 0)
-
-typedef struct {
+struct psa_key_attributes_s {
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+ psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number);
+ int MBEDTLS_PRIVATE(has_slot_number);
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
psa_key_type_t MBEDTLS_PRIVATE(type);
psa_key_bits_t MBEDTLS_PRIVATE(bits);
psa_key_lifetime_t MBEDTLS_PRIVATE(lifetime);
psa_key_policy_t MBEDTLS_PRIVATE(policy);
- psa_key_attributes_flag_t MBEDTLS_PRIVATE(flags);
/* This type has a different layout in the client view wrt the
* service view of the key id, i.e. in service view usually is
* expected to have MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined
@@ -307,31 +287,18 @@
* struct
*/
mbedtls_svc_key_id_t MBEDTLS_PRIVATE(id);
-} psa_core_key_attributes_t;
-
-#define PSA_CORE_KEY_ATTRIBUTES_INIT { PSA_KEY_TYPE_NONE, 0, \
- PSA_KEY_LIFETIME_VOLATILE, \
- PSA_KEY_POLICY_INIT, 0, \
- MBEDTLS_SVC_KEY_ID_INIT }
-
-struct psa_key_attributes_s {
-#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
- psa_key_slot_number_t MBEDTLS_PRIVATE(slot_number);
-#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
- /* With client/service separation, struct psa_key_attributes_s is
- * marshalled through a transport channel between the client and
- * service side implementation of the PSA Crypto APIs, thus having
- * the mbedtls_svc_key_id_t id as the last field of this structure
- * allows for a more efficient marshalling/unmarshalling of parameters
- */
- psa_core_key_attributes_t MBEDTLS_PRIVATE(core);
};
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
-#define PSA_KEY_ATTRIBUTES_INIT { 0, PSA_CORE_KEY_ATTRIBUTES_INIT }
+#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER 0, 0,
#else
-#define PSA_KEY_ATTRIBUTES_INIT { PSA_CORE_KEY_ATTRIBUTES_INIT }
+#define PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER
#endif
+#define PSA_KEY_ATTRIBUTES_INIT { PSA_KEY_ATTRIBUTES_MAYBE_SLOT_NUMBER \
+ PSA_KEY_TYPE_NONE, 0, \
+ PSA_KEY_LIFETIME_VOLATILE, \
+ PSA_KEY_POLICY_INIT, \
+ MBEDTLS_SVC_KEY_ID_INIT }
static inline struct psa_key_attributes_s psa_key_attributes_init(void)
{
@@ -342,12 +309,12 @@
static inline void psa_set_key_id(psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t key)
{
- psa_key_lifetime_t lifetime = attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime);
+ psa_key_lifetime_t lifetime = attributes->MBEDTLS_PRIVATE(lifetime);
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id) = key;
+ attributes->MBEDTLS_PRIVATE(id) = key;
if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) =
+ attributes->MBEDTLS_PRIVATE(lifetime) =
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
PSA_KEY_LIFETIME_PERSISTENT,
PSA_KEY_LIFETIME_GET_LOCATION(lifetime));
@@ -357,26 +324,26 @@
static inline mbedtls_svc_key_id_t psa_get_key_id(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id);
+ return attributes->MBEDTLS_PRIVATE(id);
}
#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
static inline void mbedtls_set_key_owner_id(psa_key_attributes_t *attributes,
mbedtls_key_owner_id_t owner)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(owner) = owner;
+ attributes->MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(owner) = owner;
}
#endif
static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
psa_key_lifetime_t lifetime)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime) = lifetime;
+ attributes->MBEDTLS_PRIVATE(lifetime) = lifetime;
if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id) = 0;
+ attributes->MBEDTLS_PRIVATE(id).MBEDTLS_PRIVATE(key_id) = 0;
#else
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(id) = 0;
+ attributes->MBEDTLS_PRIVATE(id) = 0;
#endif
}
}
@@ -384,7 +351,7 @@
static inline psa_key_lifetime_t psa_get_key_lifetime(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(lifetime);
+ return attributes->MBEDTLS_PRIVATE(lifetime);
}
static inline void psa_extend_key_usage_flags(psa_key_usage_t *usage_flags)
@@ -402,53 +369,53 @@
psa_key_usage_t usage_flags)
{
psa_extend_key_usage_flags(&usage_flags);
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags;
+ attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage) = usage_flags;
}
static inline psa_key_usage_t psa_get_key_usage_flags(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage);
+ return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(usage);
}
static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes,
psa_algorithm_t alg)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = alg;
+ attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg) = alg;
}
static inline psa_algorithm_t psa_get_key_algorithm(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg);
+ return attributes->MBEDTLS_PRIVATE(policy).MBEDTLS_PRIVATE(alg);
}
static inline void psa_set_key_type(psa_key_attributes_t *attributes,
psa_key_type_t type)
{
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type) = type;
+ attributes->MBEDTLS_PRIVATE(type) = type;
}
static inline psa_key_type_t psa_get_key_type(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(type);
+ return attributes->MBEDTLS_PRIVATE(type);
}
static inline void psa_set_key_bits(psa_key_attributes_t *attributes,
size_t bits)
{
if (bits > PSA_MAX_KEY_BITS) {
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) = PSA_KEY_BITS_TOO_LARGE;
+ attributes->MBEDTLS_PRIVATE(bits) = PSA_KEY_BITS_TOO_LARGE;
} else {
- attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits) = (psa_key_bits_t) bits;
+ attributes->MBEDTLS_PRIVATE(bits) = (psa_key_bits_t) bits;
}
}
static inline size_t psa_get_key_bits(
const psa_key_attributes_t *attributes)
{
- return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits);
+ return attributes->MBEDTLS_PRIVATE(bits);
}
/**
diff --git a/library/bignum.c b/library/bignum.c
index d3d72ab..c45fd5b 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -37,6 +37,19 @@
#include "mbedtls/platform.h"
+
+
+/*
+ * Conditionally select an MPI sign in constant time.
+ * (MPI sign is the field s in mbedtls_mpi. It is unsigned short and only 1 and -1 are valid
+ * values.)
+ */
+static inline signed short mbedtls_ct_mpi_sign_if(mbedtls_ct_condition_t cond,
+ signed short sign1, signed short sign2)
+{
+ return (signed short) mbedtls_ct_uint_if(cond, sign1 + 1, sign2 + 1) - 1;
+}
+
/*
* Compare signed values in constant time
*/
@@ -112,7 +125,7 @@
{
mbedtls_ct_condition_t do_assign = mbedtls_ct_bool(assign);
- X->s = (int) mbedtls_ct_uint_if(do_assign, Y->s, X->s);
+ X->s = mbedtls_ct_mpi_sign_if(do_assign, Y->s, X->s);
mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, do_assign);
@@ -149,8 +162,8 @@
MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n));
s = X->s;
- X->s = (int) mbedtls_ct_uint_if(do_swap, Y->s, X->s);
- Y->s = (int) mbedtls_ct_uint_if(do_swap, s, Y->s);
+ X->s = mbedtls_ct_mpi_sign_if(do_swap, Y->s, X->s);
+ Y->s = mbedtls_ct_mpi_sign_if(do_swap, s, Y->s);
mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, do_swap);
@@ -288,8 +301,7 @@
* This function is not constant-time. Leading zeros in Y may be removed.
*
* Ensure that X does not shrink. This is not guaranteed by the public API,
- * but some code in the bignum module relies on this property, for example
- * in mbedtls_mpi_exp_mod().
+ * but some code in the bignum module might still rely on this property.
*/
int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y)
{
@@ -1598,98 +1610,11 @@
return 0;
}
-static void mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N)
-{
- *mm = mbedtls_mpi_core_montmul_init(N->p);
-}
-
-/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
- *
- * \param[in,out] A One of the numbers to multiply.
- * It must have at least as many limbs as N
- * (A->n >= N->n), and any limbs beyond n are ignored.
- * On successful completion, A contains the result of
- * the multiplication A * B * R^-1 mod N where
- * R = (2^ciL)^n.
- * \param[in] B One of the numbers to multiply.
- * It must be nonzero and must not have more limbs than N
- * (B->n <= N->n).
- * \param[in] N The modulus. \p N must be odd.
- * \param mm The value calculated by `mpi_montg_init(&mm, N)`.
- * This is -N^-1 mod 2^ciL.
- * \param[in,out] T A bignum for temporary storage.
- * It must be at least twice the limb size of N plus 1
- * (T->n >= 2 * N->n + 1).
- * Its initial content is unused and
- * its final content is indeterminate.
- * It does not get reallocated.
- */
-static void mpi_montmul(mbedtls_mpi *A, const mbedtls_mpi *B,
- const mbedtls_mpi *N, mbedtls_mpi_uint mm,
- mbedtls_mpi *T)
-{
- mbedtls_mpi_core_montmul(A->p, A->p, B->p, B->n, N->p, N->n, mm, T->p);
-}
-
-/*
- * Montgomery reduction: A = A * R^-1 mod N
- *
- * See mpi_montmul() regarding constraints and guarantees on the parameters.
- */
-static void mpi_montred(mbedtls_mpi *A, const mbedtls_mpi *N,
- mbedtls_mpi_uint mm, mbedtls_mpi *T)
-{
- mbedtls_mpi_uint z = 1;
- mbedtls_mpi U;
- U.n = 1;
- U.s = 1;
- U.p = &z;
-
- mpi_montmul(A, &U, N, mm, T);
-}
-
-/**
- * Select an MPI from a table without leaking the index.
- *
- * This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it
- * reads the entire table in order to avoid leaking the value of idx to an
- * attacker able to observe memory access patterns.
- *
- * \param[out] R Where to write the selected MPI.
- * \param[in] T The table to read from.
- * \param[in] T_size The number of elements in the table.
- * \param[in] idx The index of the element to select;
- * this must satisfy 0 <= idx < T_size.
- *
- * \return \c 0 on success, or a negative error code.
- */
-static int mpi_select(mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
- for (size_t i = 0; i < T_size; i++) {
- MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign(R, &T[i],
- (unsigned char) mbedtls_ct_uint_eq(i, idx)));
- }
-cleanup:
- return ret;
-}
-
-/*
- * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
- */
int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *E, const mbedtls_mpi *N,
mbedtls_mpi *prec_RR)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t window_bitsize;
- size_t i, j, nblimbs;
- size_t bufsize, nbits;
- size_t exponent_bits_in_window = 0;
- mbedtls_mpi_uint ei, mm, state;
- mbedtls_mpi RR, T, W[(size_t) 1 << MBEDTLS_MPI_WINDOW_SIZE], WW, Apos;
- int neg;
if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
@@ -1705,261 +1630,88 @@
}
/*
- * Init temps and window size
+ * Ensure that the exponent that we are passing to the core is not NULL.
*/
- mpi_montg_init(&mm, N);
- mbedtls_mpi_init(&RR); mbedtls_mpi_init(&T);
- mbedtls_mpi_init(&Apos);
- mbedtls_mpi_init(&WW);
- memset(W, 0, sizeof(W));
-
- i = mbedtls_mpi_bitlen(E);
-
- window_bitsize = (i > 671) ? 6 : (i > 239) ? 5 :
- (i > 79) ? 4 : (i > 23) ? 3 : 1;
-
-#if (MBEDTLS_MPI_WINDOW_SIZE < 6)
- if (window_bitsize > MBEDTLS_MPI_WINDOW_SIZE) {
- window_bitsize = MBEDTLS_MPI_WINDOW_SIZE;
+ if (E->n == 0) {
+ ret = mbedtls_mpi_lset(X, 1);
+ return ret;
}
-#endif
-
- const size_t w_table_used_size = (size_t) 1 << window_bitsize;
/*
- * This function is not constant-trace: its memory accesses depend on the
- * exponent value. To defend against timing attacks, callers (such as RSA
- * and DHM) should use exponent blinding. However this is not enough if the
- * adversary can find the exponent in a single trace, so this function
- * takes extra precautions against adversaries who can observe memory
- * access patterns.
- *
- * This function performs a series of multiplications by table elements and
- * squarings, and we want the prevent the adversary from finding out which
- * table element was used, and from distinguishing between multiplications
- * and squarings. Firstly, when multiplying by an element of the window
- * W[i], we do a constant-trace table lookup to obfuscate i. This leaves
- * squarings as having a different memory access patterns from other
- * multiplications. So secondly, we put the accumulator in the table as
- * well, and also do a constant-trace table lookup to multiply by the
- * accumulator which is W[x_index].
- *
- * This way, all multiplications take the form of a lookup-and-multiply.
- * The number of lookup-and-multiply operations inside each iteration of
- * the main loop still depends on the bits of the exponent, but since the
- * other operations in the loop don't have an easily recognizable memory
- * trace, an adversary is unlikely to be able to observe the exact
- * patterns.
- *
- * An adversary may still be able to recover the exponent if they can
- * observe both memory accesses and branches. However, branch prediction
- * exploitation typically requires many traces of execution over the same
- * data, which is defeated by randomized blinding.
+ * Allocate working memory for mbedtls_mpi_core_exp_mod()
*/
- const size_t x_index = 0;
- mbedtls_mpi_init(&W[x_index]);
-
- j = N->n + 1;
- /* All W[i] including the accumulator must have at least N->n limbs for
- * the mpi_montmul() and mpi_montred() calls later. Here we ensure that
- * W[1] and the accumulator W[x_index] are large enough. later we'll grow
- * other W[i] to the same length. They must not be shrunk midway through
- * this function!
- */
- MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[x_index], j));
- MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], j));
- MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T, j * 2));
-
- /*
- * Compensate for negative A (and correct at the end)
- */
- neg = (A->s == -1);
- if (neg) {
- MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Apos, A));
- Apos.s = 1;
- A = &Apos;
+ size_t T_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N->n, E->n);
+ mbedtls_mpi_uint *T = (mbedtls_mpi_uint *) mbedtls_calloc(T_limbs, sizeof(mbedtls_mpi_uint));
+ if (T == NULL) {
+ return MBEDTLS_ERR_MPI_ALLOC_FAILED;
}
+ mbedtls_mpi RR;
+ mbedtls_mpi_init(&RR);
+
/*
* If 1st call, pre-compute R^2 mod N
*/
if (prec_RR == NULL || prec_RR->p == NULL) {
- MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&RR, 1));
- MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&RR, N->n * 2 * biL));
- MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&RR, &RR, N));
+ MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));
if (prec_RR != NULL) {
- memcpy(prec_RR, &RR, sizeof(mbedtls_mpi));
+ *prec_RR = RR;
}
} else {
- memcpy(&RR, prec_RR, sizeof(mbedtls_mpi));
+ MBEDTLS_MPI_CHK(mbedtls_mpi_grow(prec_RR, N->n));
+ RR = *prec_RR;
}
/*
- * W[1] = A * R^2 * R^-1 mod N = A * R mod N
+ * To preserve constness we need to make a copy of A. Using X for this to
+ * save memory.
*/
- if (mbedtls_mpi_cmp_mpi(A, N) >= 0) {
- MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&W[1], A, N));
- /* This should be a no-op because W[1] is already that large before
- * mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow
- * in mpi_montmul() below, so let's make sure. */
- MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], N->n + 1));
- } else {
- MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[1], A));
- }
-
- /* Note that this is safe because W[1] always has at least N->n limbs
- * (it grew above and was preserved by mbedtls_mpi_copy()). */
- mpi_montmul(&W[1], &RR, N, mm, &T);
+ MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
/*
- * W[x_index] = R^2 * R^-1 mod N = R mod N
+ * Compensate for negative A (and correct at the end).
*/
- MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[x_index], &RR));
- mpi_montred(&W[x_index], N, mm, &T);
+ X->s = 1;
-
- if (window_bitsize > 1) {
- /*
- * W[i] = W[1] ^ i
- *
- * The first bit of the sliding window is always 1 and therefore we
- * only need to store the second half of the table.
- *
- * (There are two special elements in the table: W[0] for the
- * accumulator/result and W[1] for A in Montgomery form. Both of these
- * are already set at this point.)
- */
- j = w_table_used_size / 2;
-
- MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[j], N->n + 1));
- MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[j], &W[1]));
-
- for (i = 0; i < window_bitsize - 1; i++) {
- mpi_montmul(&W[j], &W[j], N, mm, &T);
- }
-
- /*
- * W[i] = W[i - 1] * W[1]
- */
- for (i = j + 1; i < w_table_used_size; i++) {
- MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[i], N->n + 1));
- MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[i], &W[i - 1]));
-
- mpi_montmul(&W[i], &W[1], N, mm, &T);
- }
+ /*
+ * Make sure that X is in a form that is safe for consumption by
+ * the core functions.
+ *
+ * - The core functions will not touch the limbs of X above N->n. The
+ * result will be correct if those limbs are 0, which the mod call
+ * ensures.
+ * - Also, X must have at least as many limbs as N for the calls to the
+ * core functions.
+ */
+ if (mbedtls_mpi_cmp_mpi(X, N) >= 0) {
+ MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N));
}
+ MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, N->n));
- nblimbs = E->n;
- bufsize = 0;
- nbits = 0;
- state = 0;
-
- while (1) {
- if (bufsize == 0) {
- if (nblimbs == 0) {
- break;
- }
-
- nblimbs--;
-
- bufsize = sizeof(mbedtls_mpi_uint) << 3;
- }
-
- bufsize--;
-
- ei = (E->p[nblimbs] >> bufsize) & 1;
-
- /*
- * skip leading 0s
- */
- if (ei == 0 && state == 0) {
- continue;
- }
-
- if (ei == 0 && state == 1) {
- /*
- * out of window, square W[x_index]
- */
- MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index));
- mpi_montmul(&W[x_index], &WW, N, mm, &T);
- continue;
- }
-
- /*
- * add ei to current window
- */
- state = 2;
-
- nbits++;
- exponent_bits_in_window |= (ei << (window_bitsize - nbits));
-
- if (nbits == window_bitsize) {
- /*
- * W[x_index] = W[x_index]^window_bitsize R^-1 mod N
- */
- for (i = 0; i < window_bitsize; i++) {
- MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size,
- x_index));
- mpi_montmul(&W[x_index], &WW, N, mm, &T);
- }
-
- /*
- * W[x_index] = W[x_index] * W[exponent_bits_in_window] R^-1 mod N
- */
- MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size,
- exponent_bits_in_window));
- mpi_montmul(&W[x_index], &WW, N, mm, &T);
-
- state--;
- nbits = 0;
- exponent_bits_in_window = 0;
- }
+ /*
+ * Convert to and from Montgomery around mbedtls_mpi_core_exp_mod().
+ */
+ {
+ mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
+ mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);
+ mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
+ mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);
}
/*
- * process the remaining bits
+ * Correct for negative A.
*/
- for (i = 0; i < nbits; i++) {
- MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index));
- mpi_montmul(&W[x_index], &WW, N, mm, &T);
+ if (A->s == -1 && (E->p[0] & 1) != 0) {
+ mbedtls_ct_condition_t is_x_non_zero = mbedtls_mpi_core_check_zero_ct(X->p, X->n);
+ X->s = mbedtls_ct_mpi_sign_if(is_x_non_zero, -1, 1);
- exponent_bits_in_window <<= 1;
-
- if ((exponent_bits_in_window & ((size_t) 1 << window_bitsize)) != 0) {
- MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, 1));
- mpi_montmul(&W[x_index], &WW, N, mm, &T);
- }
+ MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, N, X));
}
- /*
- * W[x_index] = A^E * R * R^-1 mod N = A^E mod N
- */
- mpi_montred(&W[x_index], N, mm, &T);
-
- if (neg && E->n != 0 && (E->p[0] & 1) != 0) {
- W[x_index].s = -1;
- MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&W[x_index], N, &W[x_index]));
- }
-
- /*
- * Load the result in the output variable.
- */
- MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &W[x_index]));
-
cleanup:
- /* The first bit of the sliding window is always 1 and therefore the first
- * half of the table was unused. */
- for (i = w_table_used_size/2; i < w_table_used_size; i++) {
- mbedtls_mpi_free(&W[i]);
- }
-
- mbedtls_mpi_free(&W[x_index]);
- mbedtls_mpi_free(&W[1]);
- mbedtls_mpi_free(&T);
- mbedtls_mpi_free(&Apos);
- mbedtls_mpi_free(&WW);
+ mbedtls_mpi_zeroize_and_free(T, T_limbs);
if (prec_RR == NULL || prec_RR->p == NULL) {
mbedtls_mpi_free(&RR);
diff --git a/library/bignum_core.c b/library/bignum_core.c
index dfed60d..1a3e0b9 100644
--- a/library/bignum_core.c
+++ b/library/bignum_core.c
@@ -856,16 +856,17 @@
return c;
}
-mbedtls_mpi_uint mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
- size_t limbs)
+mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
+ size_t limbs)
{
+ volatile const mbedtls_mpi_uint *force_read_A = A;
mbedtls_mpi_uint bits = 0;
for (size_t i = 0; i < limbs; i++) {
- bits |= A[i];
+ bits |= force_read_A[i];
}
- return bits;
+ return mbedtls_ct_bool(bits);
}
void mbedtls_mpi_core_to_mont_rep(mbedtls_mpi_uint *X,
diff --git a/library/bignum_core.h b/library/bignum_core.h
index b56be0a..92c8d47 100644
--- a/library/bignum_core.h
+++ b/library/bignum_core.h
@@ -662,11 +662,11 @@
* \param[in] A The MPI to test.
* \param limbs Number of limbs in \p A.
*
- * \return 0 if `A == 0`
- * non-0 (may be any value) if `A != 0`.
+ * \return MBEDTLS_CT_FALSE if `A == 0`
+ * MBEDTLS_CT_TRUE if `A != 0`.
*/
-mbedtls_mpi_uint mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
- size_t limbs);
+mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
+ size_t limbs);
/**
* \brief Returns the number of limbs of working memory required for
diff --git a/library/ecdh.c b/library/ecdh.c
index 52b1617..b276c6a 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -144,6 +144,15 @@
#endif
}
+mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx)
+{
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+ return ctx->MBEDTLS_PRIVATE(grp).id;
+#else
+ return ctx->MBEDTLS_PRIVATE(grp_id);
+#endif
+}
+
/*
* Initialize context
*/
diff --git a/library/ecp.c b/library/ecp.c
index 66b3dc1..427059b 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -3302,6 +3302,7 @@
/*
* Write a private key.
*/
+#if !defined MBEDTLS_DEPRECATED_REMOVED
int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key,
unsigned char *buf, size_t buflen)
{
@@ -3332,6 +3333,39 @@
return ret;
}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+int mbedtls_ecp_write_key_ext(const mbedtls_ecp_keypair *key,
+ size_t *olen, unsigned char *buf, size_t buflen)
+{
+ size_t len = (key->grp.nbits + 7) / 8;
+ if (len > buflen) {
+ /* For robustness, ensure *olen <= buflen even on error. */
+ *olen = 0;
+ return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
+ }
+ *olen = len;
+
+ /* Private key not set */
+ if (key->d.n == 0) {
+ return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+ }
+
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
+ return mbedtls_mpi_write_binary_le(&key->d, buf, len);
+ }
+#endif
+
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
+ return mbedtls_mpi_write_binary(&key->d, buf, len);
+ }
+#endif
+
+ /* Private key set but no recognized curve type? This shouldn't happen. */
+ return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+}
/*
* Write a public key.
diff --git a/library/pk.c b/library/pk.c
index 8a5124f..003ef4a 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -675,10 +675,7 @@
#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
psa_ecc_family_t from_family = pk->ec_family;
#else /* MBEDTLS_PK_USE_PSA_EC_DATA */
- /* We're only reading the key, but mbedtls_ecp_write_key()
- * is missing a const annotation on its key parameter, so
- * we need the non-const accessor here. */
- mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
+ const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
size_t from_bits = 0;
psa_ecc_family_t from_family = mbedtls_ecc_group_to_psa(ec->grp.id,
&from_bits);
@@ -704,12 +701,9 @@
return MBEDTLS_ERR_PK_TYPE_MISMATCH;
}
unsigned char key_buffer[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
- /* Make sure to pass the exact key length to
- * mbedtls_ecp_write_key(), because it writes Montgomery keys
- * at the start of the buffer but Weierstrass keys at the
- * end of the buffer. */
- size_t key_length = PSA_BITS_TO_BYTES(ec->grp.nbits);
- int ret = mbedtls_ecp_write_key(ec, key_buffer, key_length);
+ size_t key_length = 0;
+ int ret = mbedtls_ecp_write_key_ext(ec, &key_length,
+ key_buffer, sizeof(key_buffer));
if (ret < 0) {
return ret;
}
diff --git a/library/pkwrite.c b/library/pkwrite.c
index b9ddcf1..5e009c5 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -202,7 +202,7 @@
mbedtls_ecp_keypair *ec = mbedtls_pk_ec_rw(*pk);
byte_length = (ec->grp.pbits + 7) / 8;
- ret = mbedtls_ecp_write_key(ec, tmp, byte_length);
+ ret = mbedtls_ecp_write_key_ext(ec, &byte_length, tmp, sizeof(tmp));
if (ret != 0) {
goto exit;
}
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index ca01e76..ec9d115 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -101,11 +101,6 @@
static psa_global_data_t global_data;
-#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
-mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state =
- &global_data.rng.drbg;
-#endif
-
#define GUARD_MODULE_INITIALIZED \
if (global_data.initialized == 0) \
return PSA_ERROR_BAD_STATE;
@@ -568,7 +563,7 @@
size_t *key_buffer_length, size_t *bits)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
- psa_key_type_t type = attributes->core.type;
+ psa_key_type_t type = attributes->type;
/* zero-length keys are never supported. */
if (data_length == 0) {
@@ -578,7 +573,7 @@
if (key_type_is_raw_bytes(type)) {
*bits = PSA_BYTES_TO_BITS(data_length);
- status = psa_validate_unstructured_key_bit_size(attributes->core.type,
+ status = psa_validate_unstructured_key_bit_size(attributes->type,
*bits);
if (status != PSA_SUCCESS) {
return status;
@@ -1106,6 +1101,17 @@
* fully destroyed. */
PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(
&mbedtls_threading_key_slot_mutex));
+
+ if (slot->state == PSA_SLOT_PENDING_DELETION) {
+ /* Another thread has destroyed the key between us locking the slot
+ * and us gaining the mutex. Unregister from the slot,
+ * and report that the key does not exist. */
+ status = psa_unregister_read(slot);
+
+ PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
+ &mbedtls_threading_key_slot_mutex));
+ return (status == PSA_SUCCESS) ? PSA_ERROR_INVALID_HANDLE : status;
+ }
#endif
/* Set the key slot containing the key description's state to
* PENDING_DELETION. This stops new operations from registering
@@ -1115,10 +1121,10 @@
* 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. */
- status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL,
- PSA_SLOT_PENDING_DELETION);
+ overall_status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL,
+ PSA_SLOT_PENDING_DELETION);
- if (status != PSA_SUCCESS) {
+ if (overall_status != PSA_SUCCESS) {
goto exit;
}
@@ -1226,9 +1232,7 @@
return status;
}
- attributes->core = slot->attr;
- attributes->core.flags &= (MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
- MBEDTLS_PSA_KA_MASK_DUAL_USE);
+ *attributes = slot->attr;
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
if (psa_get_se_driver_entry(slot->attr.lifetime) != NULL) {
@@ -1245,7 +1249,7 @@
const psa_key_attributes_t *attributes,
psa_key_slot_number_t *slot_number)
{
- if (attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER) {
+ if (attributes->has_slot_number) {
*slot_number = attributes->slot_number;
return PSA_SUCCESS;
} else {
@@ -1275,7 +1279,7 @@
const uint8_t *key_buffer, size_t key_buffer_size,
uint8_t *data, size_t data_size, size_t *data_length)
{
- psa_key_type_t type = attributes->core.type;
+ psa_key_type_t type = attributes->type;
if (key_type_is_raw_bytes(type) ||
PSA_KEY_TYPE_IS_RSA(type) ||
@@ -1324,10 +1328,7 @@
return status;
}
- psa_key_attributes_t attributes = {
- .core = slot->attr
- };
- status = psa_driver_wrapper_export_key(&attributes,
+ status = psa_driver_wrapper_export_key(&slot->attr,
slot->key.data, slot->key.bytes,
data, data_size, data_length);
@@ -1344,7 +1345,7 @@
size_t data_size,
size_t *data_length)
{
- psa_key_type_t type = attributes->core.type;
+ psa_key_type_t type = attributes->type;
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) &&
(PSA_KEY_TYPE_IS_RSA(type) || PSA_KEY_TYPE_IS_ECC(type) ||
@@ -1411,7 +1412,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
- psa_key_attributes_t attributes;
/* Reject a zero-length output buffer now, since this can never be a
* valid key representation. This way we know that data must be a valid
@@ -1437,11 +1437,8 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
status = psa_driver_wrapper_export_public_key(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
data, data_size, data_length);
exit:
@@ -1450,16 +1447,6 @@
return (status == PSA_SUCCESS) ? unlock_status : status;
}
-MBEDTLS_STATIC_ASSERT(
- (MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0,
- "One or more key attribute flag is listed as both external-only and dual-use")
-MBEDTLS_STATIC_ASSERT(
- (PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE) == 0,
- "One or more key attribute flag is listed as both internal-only and dual-use")
-MBEDTLS_STATIC_ASSERT(
- (PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY) == 0,
- "One or more key attribute flag is listed as both internal-only and external-only")
-
/** Validate that a key policy is internally well-formed.
*
* This function only rejects invalid policies. It does not validate the
@@ -1525,7 +1512,7 @@
}
}
- status = psa_validate_key_policy(&attributes->core.policy);
+ status = psa_validate_key_policy(&attributes->policy);
if (status != PSA_SUCCESS) {
return status;
}
@@ -1538,12 +1525,6 @@
return PSA_ERROR_NOT_SUPPORTED;
}
- /* Reject invalid flags. These should not be reachable through the API. */
- if (attributes->core.flags & ~(MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
- MBEDTLS_PSA_KA_MASK_DUAL_USE)) {
- return PSA_ERROR_INVALID_ARGUMENT;
- }
-
return PSA_SUCCESS;
}
@@ -1617,7 +1598,7 @@
* volatile key identifier associated to the slot returned to contain its
* definition. */
- slot->attr = attributes->core;
+ slot->attr = *attributes;
if (PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) {
#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
slot->attr.id = volatile_key_id;
@@ -1626,13 +1607,6 @@
#endif
}
- /* 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_reserve_free_key_slot()
- * may have set. */
- slot->attr.flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
-
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* For a key in a secure element, we need to do three things
* when creating or registering a persistent key:
@@ -1659,7 +1633,7 @@
return status;
}
- if (!PSA_KEY_LIFETIME_IS_VOLATILE(attributes->core.lifetime)) {
+ if (!PSA_KEY_LIFETIME_IS_VOLATILE(attributes->lifetime)) {
psa_crypto_prepare_transaction(PSA_CRYPTO_TRANSACTION_CREATE_KEY);
psa_crypto_transaction.key.lifetime = slot->attr.lifetime;
psa_crypto_transaction.key.slot = slot_number;
@@ -1859,14 +1833,14 @@
const psa_key_slot_t *slot,
const psa_key_attributes_t *attributes)
{
- if (attributes->core.type != 0) {
- if (attributes->core.type != slot->attr.type) {
+ if (attributes->type != 0) {
+ if (attributes->type != slot->attr.type) {
return PSA_ERROR_INVALID_ARGUMENT;
}
}
- if (attributes->core.bits != 0) {
- if (attributes->core.bits != slot->attr.bits) {
+ if (attributes->bits != 0) {
+ if (attributes->bits != slot->attr.bits) {
return PSA_ERROR_INVALID_ARGUMENT;
}
}
@@ -1910,7 +1884,7 @@
* with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
* buffer to hold the imported key material. */
if (slot->key.data == NULL) {
- if (psa_key_lifetime_is_external(attributes->core.lifetime)) {
+ if (psa_key_lifetime_is_external(attributes->lifetime)) {
status = psa_driver_wrapper_get_key_buffer_size_from_key_data(
attributes, data, data_length, &storage_size);
if (status != PSA_SUCCESS) {
@@ -2030,12 +2004,12 @@
* equal to the ones of the source key. So it is safe to inherit
* them from the source key now."
* */
- actual_attributes.core.bits = source_slot->attr.bits;
- actual_attributes.core.type = source_slot->attr.type;
+ actual_attributes.bits = source_slot->attr.bits;
+ actual_attributes.type = source_slot->attr.type;
status = psa_restrict_key_policy(source_slot->attr.type,
- &actual_attributes.core.policy,
+ &actual_attributes.policy,
&source_slot->attr.policy);
if (status != PSA_SUCCESS) {
goto exit;
@@ -2064,7 +2038,7 @@
* - For opaque keys this translates to an invocation of the drivers'
* copy_key entry point through the dispatch layer.
* */
- if (psa_key_lifetime_is_external(actual_attributes.core.lifetime)) {
+ if (psa_key_lifetime_is_external(actual_attributes.lifetime)) {
status = psa_driver_wrapper_get_key_buffer_size(&actual_attributes,
&storage_size);
if (status != PSA_SUCCESS) {
@@ -2372,7 +2346,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot = NULL;
- psa_key_attributes_t attributes;
/* A context must be freshly initialized before it can be set up. */
if (operation->id != 0) {
@@ -2389,11 +2362,7 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
- status = psa_mac_finalize_alg_and_key_validation(alg, &attributes,
+ status = psa_mac_finalize_alg_and_key_validation(alg, &slot->attr,
&operation->mac_size);
if (status != PSA_SUCCESS) {
goto exit;
@@ -2403,13 +2372,13 @@
/* Dispatch the MAC setup call with validated input */
if (is_sign) {
status = psa_driver_wrapper_mac_sign_setup(operation,
- &attributes,
+ &slot->attr,
slot->key.data,
slot->key.bytes,
alg);
} else {
status = psa_driver_wrapper_mac_verify_setup(operation,
- &attributes,
+ &slot->attr,
slot->key.data,
slot->key.bytes,
alg);
@@ -2559,7 +2528,6 @@
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
uint8_t operation_mac_size = 0;
- psa_key_attributes_t attributes;
status = psa_get_and_lock_key_slot_with_policy(
key,
@@ -2570,11 +2538,7 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
- status = psa_mac_finalize_alg_and_key_validation(alg, &attributes,
+ status = psa_mac_finalize_alg_and_key_validation(alg, &slot->attr,
&operation_mac_size);
if (status != PSA_SUCCESS) {
goto exit;
@@ -2586,7 +2550,7 @@
}
status = psa_driver_wrapper_mac_compute(
- &attributes,
+ &slot->attr,
slot->key.data, slot->key.bytes,
alg,
input, input_length,
@@ -2696,7 +2660,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
- psa_key_attributes_t attributes;
*signature_length = 0;
@@ -2728,19 +2691,15 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
if (input_is_message) {
status = psa_driver_wrapper_sign_message(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length,
signature, signature_size, signature_length);
} else {
status = psa_driver_wrapper_sign_hash(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length,
signature, signature_size, signature_length);
}
@@ -2782,18 +2741,14 @@
return status;
}
- psa_key_attributes_t attributes = {
- .core = slot->attr
- };
-
if (input_is_message) {
status = psa_driver_wrapper_verify_message(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length,
signature, signature_length);
} else {
status = psa_driver_wrapper_verify_hash(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length,
signature, signature_length);
}
@@ -2904,7 +2859,7 @@
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
uint8_t *signature, size_t signature_size, size_t *signature_length)
{
- if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
+ if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
PSA_ALG_IS_RSA_PSS(alg)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
@@ -2919,7 +2874,7 @@
} else {
return PSA_ERROR_INVALID_ARGUMENT;
}
- } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
+ } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) {
if (PSA_ALG_IS_ECDSA(alg)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
@@ -2965,7 +2920,7 @@
psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
const uint8_t *signature, size_t signature_length)
{
- if (PSA_KEY_TYPE_IS_RSA(attributes->core.type)) {
+ if (PSA_KEY_TYPE_IS_RSA(attributes->type)) {
if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
PSA_ALG_IS_RSA_PSS(alg)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN) || \
@@ -2980,7 +2935,7 @@
} else {
return PSA_ERROR_INVALID_ARGUMENT;
}
- } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
+ } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) {
if (PSA_ALG_IS_ECDSA(alg)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
@@ -3031,7 +2986,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
- psa_key_attributes_t attributes;
(void) input;
(void) input_length;
@@ -3056,12 +3010,8 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
status = psa_driver_wrapper_asymmetric_encrypt(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length, salt, salt_length,
output, output_size, output_length);
exit:
@@ -3083,7 +3033,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
- psa_key_attributes_t attributes;
(void) input;
(void) input_length;
@@ -3107,12 +3056,8 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
status = psa_driver_wrapper_asymmetric_decrypt(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length, salt, salt_length,
output, output_size, output_length);
@@ -3181,7 +3126,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
- psa_key_attributes_t attributes;
/* Check that start has not been previously called, or operation has not
* previously errored. */
@@ -3208,14 +3152,10 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
/* Ensure ops count gets reset, in case of operation re-use. */
operation->num_ops = 0;
- status = psa_driver_wrapper_sign_hash_start(operation, &attributes,
+ status = psa_driver_wrapper_sign_hash_start(operation, &slot->attr,
slot->key.data,
slot->key.bytes, alg,
hash, hash_length);
@@ -3353,14 +3293,10 @@
return status;
}
- psa_key_attributes_t attributes = {
- .core = slot->attr
- };
-
/* Ensure ops count gets reset, in case of operation re-use. */
operation->num_ops = 0;
- status = psa_driver_wrapper_verify_hash_start(operation, &attributes,
+ status = psa_driver_wrapper_verify_hash_start(operation, &slot->attr,
slot->key.data,
slot->key.bytes,
alg, hash, hash_length,
@@ -3495,7 +3431,7 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t required_hash_length;
- if (!PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
+ if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) {
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -3512,8 +3448,8 @@
/* Ensure num_ops is zero'ed in case of context re-use. */
operation->num_ops = 0;
- status = mbedtls_psa_ecp_load_representation(attributes->core.type,
- attributes->core.bits,
+ status = mbedtls_psa_ecp_load_representation(attributes->type,
+ attributes->bits,
key_buffer,
key_buffer_size,
&operation->ctx);
@@ -3711,7 +3647,7 @@
size_t coordinate_bytes = 0;
size_t required_hash_length = 0;
- if (!PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
+ if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) {
return PSA_ERROR_NOT_SUPPORTED;
}
@@ -3730,8 +3666,8 @@
/* Ensure num_ops is zero'ed in case of context re-use. */
operation->num_ops = 0;
- status = mbedtls_psa_ecp_load_representation(attributes->core.type,
- attributes->core.bits,
+ status = mbedtls_psa_ecp_load_representation(attributes->type,
+ attributes->bits,
key_buffer,
key_buffer_size,
&operation->ctx);
@@ -3889,7 +3825,6 @@
psa_key_usage_t usage = (cipher_operation == MBEDTLS_ENCRYPT ?
PSA_KEY_USAGE_ENCRYPT :
PSA_KEY_USAGE_DECRYPT);
- psa_key_attributes_t attributes;
/* A context must be freshly initialized before it can be set up. */
if (operation->id != 0) {
@@ -3919,20 +3854,16 @@
}
operation->default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg);
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
/* Try doing the operation through a driver before using software fallback. */
if (cipher_operation == MBEDTLS_ENCRYPT) {
status = psa_driver_wrapper_cipher_encrypt_setup(operation,
- &attributes,
+ &slot->attr,
slot->key.data,
slot->key.bytes,
alg);
} else {
status = psa_driver_wrapper_cipher_decrypt_setup(operation,
- &attributes,
+ &slot->attr,
slot->key.data,
slot->key.bytes,
alg);
@@ -4145,7 +4076,6 @@
psa_key_slot_t *slot = NULL;
uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE];
size_t default_iv_length = 0;
- psa_key_attributes_t attributes;
if (!PSA_ALG_IS_CIPHER(alg)) {
status = PSA_ERROR_INVALID_ARGUMENT;
@@ -4159,10 +4089,6 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg);
if (default_iv_length > PSA_CIPHER_IV_MAX_SIZE) {
status = PSA_ERROR_GENERIC_ERROR;
@@ -4182,7 +4108,7 @@
}
status = psa_driver_wrapper_cipher_encrypt(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, local_iv, default_iv_length, input, input_length,
psa_crypto_buffer_offset(output, default_iv_length),
output_size - default_iv_length, output_length);
@@ -4216,7 +4142,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot = NULL;
- psa_key_attributes_t attributes;
if (!PSA_ALG_IS_CIPHER(alg)) {
status = PSA_ERROR_INVALID_ARGUMENT;
@@ -4230,10 +4155,6 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
if (alg == PSA_ALG_CCM_STAR_NO_TAG &&
input_length < PSA_BLOCK_CIPHER_BLOCK_LENGTH(slot->attr.type)) {
status = PSA_ERROR_INVALID_ARGUMENT;
@@ -4244,7 +4165,7 @@
}
status = psa_driver_wrapper_cipher_decrypt(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg, input, input_length,
output, output_size, output_length);
@@ -4353,17 +4274,13 @@
return status;
}
- psa_key_attributes_t attributes = {
- .core = slot->attr
- };
-
status = psa_aead_check_nonce_length(alg, nonce_length);
if (status != PSA_SUCCESS) {
goto exit;
}
status = psa_driver_wrapper_aead_encrypt(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg,
nonce, nonce_length,
additional_data, additional_data_length,
@@ -4408,17 +4325,13 @@
return status;
}
- psa_key_attributes_t attributes = {
- .core = slot->attr
- };
-
status = psa_aead_check_nonce_length(alg, nonce_length);
if (status != PSA_SUCCESS) {
goto exit;
}
status = psa_driver_wrapper_aead_decrypt(
- &attributes, slot->key.data, slot->key.bytes,
+ &slot->attr, slot->key.data, slot->key.bytes,
alg,
nonce, nonce_length,
additional_data, additional_data_length,
@@ -4484,7 +4397,6 @@
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot = NULL;
psa_key_usage_t key_usage = 0;
- psa_key_attributes_t attributes;
status = psa_aead_check_algorithm(alg);
if (status != PSA_SUCCESS) {
@@ -4514,23 +4426,19 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
if ((status = psa_validate_tag_length(alg)) != PSA_SUCCESS) {
goto exit;
}
if (is_encrypt) {
status = psa_driver_wrapper_aead_encrypt_setup(operation,
- &attributes,
+ &slot->attr,
slot->key.data,
slot->key.bytes,
alg);
} else {
status = psa_driver_wrapper_aead_decrypt_setup(operation,
- &attributes,
+ &slot->attr,
slot->key.data,
slot->key.bytes,
alg);
@@ -4539,7 +4447,7 @@
goto exit;
}
- operation->key_type = psa_get_key_type(&attributes);
+ operation->key_type = psa_get_key_type(&slot->attr);
exit:
unlock_status = psa_unregister_read_under_mutex(slot);
@@ -5842,7 +5750,6 @@
size_t bytes = PSA_BITS_TO_BYTES(bits);
size_t storage_size = bytes;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
- psa_key_attributes_t attributes;
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(slot->attr.type)) {
return PSA_ERROR_INVALID_ARGUMENT;
@@ -5891,12 +5798,9 @@
}
slot->attr.bits = (psa_key_bits_t) bits;
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
- if (psa_key_lifetime_is_external(attributes.core.lifetime)) {
- status = psa_driver_wrapper_get_key_buffer_size(&attributes,
+ if (psa_key_lifetime_is_external(slot->attr.lifetime)) {
+ status = psa_driver_wrapper_get_key_buffer_size(&slot->attr,
&storage_size);
if (status != PSA_SUCCESS) {
goto exit;
@@ -5907,7 +5811,7 @@
goto exit;
}
- status = psa_driver_wrapper_import_key(&attributes,
+ status = psa_driver_wrapper_import_key(&slot->attr,
data, bytes,
slot->key.data,
slot->key.bytes,
@@ -5978,7 +5882,7 @@
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
if (status == PSA_SUCCESS) {
status = psa_generate_derived_key_internal(slot,
- attributes->core.bits,
+ attributes->bits,
operation);
}
if (status == PSA_SUCCESS) {
@@ -7023,11 +6927,7 @@
return PSA_ERROR_NOT_SUPPORTED;
}
- psa_key_attributes_t attributes = {
- .core = private_key->attr
- };
-
- return psa_driver_wrapper_key_agreement(&attributes,
+ return psa_driver_wrapper_key_agreement(&private_key->attr,
private_key->key.data,
private_key->key.bytes, alg,
peer_key, peer_key_length,
@@ -7046,7 +6946,7 @@
size_t peer_key_length)
{
psa_status_t status;
- uint8_t shared_secret[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE];
+ uint8_t shared_secret[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE] = { 0 };
size_t shared_secret_length = 0;
psa_algorithm_t ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE(operation->alg);
@@ -7209,7 +7109,7 @@
MBEDTLS_ENTROPY_SOURCE_STRONG);
#endif
- mbedtls_psa_drbg_init(MBEDTLS_PSA_RANDOM_STATE);
+ mbedtls_psa_drbg_init(&rng->drbg);
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
}
@@ -7220,7 +7120,7 @@
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
memset(rng, 0, sizeof(*rng));
#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
- mbedtls_psa_drbg_free(MBEDTLS_PSA_RANDOM_STATE);
+ mbedtls_psa_drbg_free(&rng->drbg);
rng->entropy_free(&rng->entropy);
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
}
@@ -7235,7 +7135,7 @@
return PSA_SUCCESS;
#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
const unsigned char drbg_seed[] = "PSA";
- int ret = mbedtls_psa_drbg_seed(&rng->entropy,
+ int ret = mbedtls_psa_drbg_seed(&rng->drbg, &rng->entropy,
drbg_seed, sizeof(drbg_seed) - 1);
return mbedtls_to_psa_error(ret);
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
@@ -7265,12 +7165,16 @@
#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
while (output_size > 0) {
+ int ret = MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
size_t request_size =
(output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ?
MBEDTLS_PSA_RANDOM_MAX_REQUEST :
output_size);
- int ret = mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE,
- output, request_size);
+#if defined(MBEDTLS_CTR_DRBG_C)
+ ret = mbedtls_ctr_drbg_random(&global_data.rng.drbg, output, request_size);
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+ ret = mbedtls_hmac_drbg_random(&global_data.rng.drbg, output, request_size);
+#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
if (ret != 0) {
return mbedtls_to_psa_error(ret);
}
@@ -7281,39 +7185,6 @@
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
}
-/* Wrapper function allowing the classic API to use the PSA RNG.
- *
- * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
- * `psa_generate_random(...)`. The state parameter is ignored since the
- * PSA API doesn't support passing an explicit state.
- *
- * In the non-external case, psa_generate_random() calls an
- * `mbedtls_xxx_drbg_random` function which has exactly the same signature
- * and semantics as mbedtls_psa_get_random(). As an optimization,
- * instead of doing this back-and-forth between the PSA API and the
- * classic API, psa_crypto_random_impl.h defines `mbedtls_psa_get_random`
- * as a constant function pointer to `mbedtls_xxx_drbg_random`.
- */
-#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
-int mbedtls_psa_get_random(void *p_rng,
- unsigned char *output,
- size_t output_size)
-{
- /* This function takes a pointer to the RNG state because that's what
- * classic mbedtls functions using an RNG expect. The PSA RNG manages
- * its own state internally and doesn't let the caller access that state.
- * So we just ignore the state parameter, and in practice we'll pass
- * NULL. */
- (void) p_rng;
- psa_status_t status = psa_generate_random(output, output_size);
- if (status == PSA_SUCCESS) {
- return 0;
- } else {
- return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
- }
-}
-#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
-
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
size_t seed_size)
@@ -7400,7 +7271,7 @@
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
- psa_key_type_t type = attributes->core.type;
+ psa_key_type_t type = attributes->type;
/* Only used for RSA */
(void) params;
@@ -7473,12 +7344,12 @@
}
/* Reject any attempt to create a public key. */
- if (PSA_KEY_TYPE_IS_PUBLIC_KEY(attributes->core.type)) {
+ if (PSA_KEY_TYPE_IS_PUBLIC_KEY(attributes->type)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
- if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
+ if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
if (params->flags != 0) {
return PSA_ERROR_INVALID_ARGUMENT;
}
@@ -7499,17 +7370,17 @@
* with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
* buffer to hold the generated key material. */
if (slot->key.data == NULL) {
- if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->core.lifetime) ==
+ if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->lifetime) ==
PSA_KEY_LOCATION_LOCAL_STORAGE) {
status = psa_validate_key_type_and_size_for_key_generation(
- attributes->core.type, attributes->core.bits);
+ attributes->type, attributes->bits);
if (status != PSA_SUCCESS) {
goto exit;
}
key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
- attributes->core.type,
- attributes->core.bits);
+ attributes->type,
+ attributes->bits);
} else {
status = psa_driver_wrapper_get_key_buffer_size(
attributes, &key_buffer_size);
@@ -7823,7 +7694,6 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot = NULL;
- psa_key_attributes_t attributes;
psa_key_type_t type;
if (operation->stage != PSA_PAKE_OPERATION_STAGE_COLLECT_INPUTS) {
@@ -7838,11 +7708,7 @@
goto exit;
}
- attributes = (psa_key_attributes_t) {
- .core = slot->attr
- };
-
- type = psa_get_key_type(&attributes);
+ type = psa_get_key_type(&slot->attr);
if (type != PSA_KEY_TYPE_PASSWORD &&
type != PSA_KEY_TYPE_PASSWORD_HASH) {
@@ -7858,7 +7724,8 @@
memcpy(operation->data.inputs.password, slot->key.data, slot->key.bytes);
operation->data.inputs.password_len = slot->key.bytes;
- operation->data.inputs.attributes = attributes;
+ operation->data.inputs.attributes = slot->attr;
+
exit:
if (status != PSA_SUCCESS) {
psa_pake_abort(operation);
diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c
index 49aa961..a201985 100644
--- a/library/psa_crypto_aead.c
+++ b/library/psa_crypto_aead.c
@@ -33,10 +33,10 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
mbedtls_cipher_id_t cipher_id;
mbedtls_cipher_mode_t mode;
- size_t key_bits = attributes->core.bits;
+ size_t key_bits = attributes->bits;
(void) key_buffer_size;
- status = mbedtls_cipher_values_from_psa(alg, attributes->core.type,
+ status = mbedtls_cipher_values_from_psa(alg, attributes->type,
&key_bits, &mode, &cipher_id);
if (status != PSA_SUCCESS) {
return status;
@@ -49,7 +49,7 @@
/* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
* The call to mbedtls_ccm_encrypt_and_tag or
* mbedtls_ccm_auth_decrypt will validate the tag length. */
- if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) {
+ if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
return PSA_ERROR_INVALID_ARGUMENT;
}
@@ -69,7 +69,7 @@
/* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
* The call to mbedtls_gcm_crypt_and_tag or
* mbedtls_gcm_auth_decrypt will validate the tag length. */
- if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) {
+ if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
return PSA_ERROR_INVALID_ARGUMENT;
}
diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c
index 3132854..a45fb0f 100644
--- a/library/psa_crypto_cipher.c
+++ b/library/psa_crypto_cipher.c
@@ -289,14 +289,14 @@
int ret = 0;
size_t key_bits;
const mbedtls_cipher_info_t *cipher_info = NULL;
- psa_key_type_t key_type = attributes->core.type;
+ psa_key_type_t key_type = attributes->type;
(void) key_buffer_size;
mbedtls_cipher_init(&operation->ctx.cipher);
operation->alg = alg;
- key_bits = attributes->core.bits;
+ key_bits = attributes->bits;
cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
key_bits, NULL);
if (cipher_info == NULL) {
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index afa8659..d4bdf92 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -59,7 +59,7 @@
* and metadata for one key.
*/
typedef struct {
- psa_core_key_attributes_t attr;
+ psa_key_attributes_t attr;
/*
* The current state of the key slot, as described in
@@ -159,11 +159,6 @@
} while (0);
#endif
-/* A mask of key attribute flags used only internally.
- * Currently there aren't any. */
-#define PSA_KA_MASK_INTERNAL_ONLY ( \
- 0)
-
/** Test whether a key slot has any registered readers.
* If multi-threading is enabled, the caller must hold the
* global key slot mutex.
@@ -177,56 +172,6 @@
return slot->registered_readers > 0;
}
-/** Retrieve flags from psa_key_slot_t::attr::core::flags.
- *
- * \param[in] slot The key slot to query.
- * \param mask The mask of bits to extract.
- *
- * \return The key attribute flags in the given slot,
- * bitwise-anded with \p mask.
- */
-static inline uint16_t psa_key_slot_get_flags(const psa_key_slot_t *slot,
- uint16_t mask)
-{
- return slot->attr.flags & mask;
-}
-
-/** Set flags in psa_key_slot_t::attr::core::flags.
- *
- * \param[in,out] slot The key slot to modify.
- * \param mask The mask of bits to modify.
- * \param value The new value of the selected bits.
- */
-static inline void psa_key_slot_set_flags(psa_key_slot_t *slot,
- uint16_t mask,
- uint16_t value)
-{
- slot->attr.flags = ((~mask & slot->attr.flags) |
- (mask & value));
-}
-
-/** Turn on flags in psa_key_slot_t::attr::core::flags.
- *
- * \param[in,out] slot The key slot to modify.
- * \param mask The mask of bits to set.
- */
-static inline void psa_key_slot_set_bits_in_flags(psa_key_slot_t *slot,
- uint16_t mask)
-{
- slot->attr.flags |= mask;
-}
-
-/** Turn off flags in psa_key_slot_t::attr::core::flags.
- *
- * \param[in,out] slot The key slot to modify.
- * \param mask The mask of bits to clear.
- */
-static inline void psa_key_slot_clear_bits(psa_key_slot_t *slot,
- uint16_t mask)
-{
- slot->attr.flags &= ~mask;
-}
-
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/** Get the SE slot number of a key from the key slot storing its description.
*
diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c
index 7edea81..95baff6 100644
--- a/library/psa_crypto_ecp.c
+++ b/library/psa_crypto_ecp.c
@@ -216,8 +216,8 @@
mbedtls_ecp_keypair *ecp = NULL;
/* Parse input */
- status = mbedtls_psa_ecp_load_representation(attributes->core.type,
- attributes->core.bits,
+ status = mbedtls_psa_ecp_load_representation(attributes->type,
+ attributes->bits,
data,
data_length,
&ecp);
@@ -225,7 +225,7 @@
goto exit;
}
- if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) ==
+ if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type) ==
PSA_ECC_FAMILY_MONTGOMERY) {
*bits = ecp->grp.nbits + 1;
} else {
@@ -235,7 +235,7 @@
/* Re-export the data to PSA export format. There is currently no support
* for other input formats then the export format, so this is a 1-1
* copy operation. */
- status = mbedtls_psa_ecp_export_key(attributes->core.type,
+ status = mbedtls_psa_ecp_export_key(attributes->type,
ecp,
key_buffer,
key_buffer_size,
@@ -281,20 +281,8 @@
return status;
} else {
- if (data_size < PSA_BITS_TO_BYTES(ecp->grp.nbits)) {
- return PSA_ERROR_BUFFER_TOO_SMALL;
- }
-
status = mbedtls_to_psa_error(
- mbedtls_ecp_write_key(ecp,
- data,
- PSA_BITS_TO_BYTES(ecp->grp.nbits)));
- if (status == PSA_SUCCESS) {
- *data_length = PSA_BITS_TO_BYTES(ecp->grp.nbits);
- } else {
- memset(data, 0, data_size);
- }
-
+ mbedtls_ecp_write_key_ext(ecp, data_length, data, data_size));
return status;
}
}
@@ -308,7 +296,7 @@
mbedtls_ecp_keypair *ecp = NULL;
status = mbedtls_psa_ecp_load_representation(
- attributes->core.type, attributes->core.bits,
+ attributes->type, attributes->bits,
key_buffer, key_buffer_size, &ecp);
if (status != PSA_SUCCESS) {
return status;
@@ -316,7 +304,7 @@
status = mbedtls_psa_ecp_export_key(
PSA_KEY_TYPE_ECC_PUBLIC_KEY(
- PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type)),
+ PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->type)),
ecp, data, data_size, data_length);
mbedtls_ecp_keypair_free(ecp);
@@ -337,9 +325,9 @@
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
- attributes->core.type);
+ attributes->type);
mbedtls_ecp_group_id grp_id =
- mbedtls_ecc_group_from_psa(curve, attributes->core.bits);
+ mbedtls_ecc_group_from_psa(curve, attributes->bits);
const mbedtls_ecp_curve_info *curve_info =
mbedtls_ecp_curve_info_from_grp_id(grp_id);
@@ -359,14 +347,11 @@
}
status = mbedtls_to_psa_error(
- mbedtls_ecp_write_key(&ecp, key_buffer, key_buffer_size));
+ mbedtls_ecp_write_key_ext(&ecp, key_buffer_length,
+ key_buffer, key_buffer_size));
mbedtls_ecp_keypair_free(&ecp);
- if (status == PSA_SUCCESS) {
- *key_buffer_length = key_buffer_size;
- }
-
return status;
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE */
@@ -389,8 +374,8 @@
size_t curve_bytes;
mbedtls_mpi r, s;
- status = mbedtls_psa_ecp_load_representation(attributes->core.type,
- attributes->core.bits,
+ status = mbedtls_psa_ecp_load_representation(attributes->type,
+ attributes->bits,
key_buffer,
key_buffer_size,
&ecp);
@@ -476,8 +461,8 @@
(void) alg;
- status = mbedtls_psa_ecp_load_representation(attributes->core.type,
- attributes->core.bits,
+ status = mbedtls_psa_ecp_load_representation(attributes->type,
+ attributes->bits,
key_buffer,
key_buffer_size,
&ecp);
@@ -541,14 +526,14 @@
size_t *shared_secret_length)
{
psa_status_t status;
- if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->core.type) ||
+ if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type) ||
!PSA_ALG_IS_ECDH(alg)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
mbedtls_ecp_keypair *ecp = NULL;
status = mbedtls_psa_ecp_load_representation(
- attributes->core.type,
- attributes->core.bits,
+ attributes->type,
+ attributes->bits,
key_buffer,
key_buffer_size,
&ecp);
diff --git a/library/psa_crypto_ffdh.c b/library/psa_crypto_ffdh.c
index 0099d5f..ae38f6d 100644
--- a/library/psa_crypto_ffdh.c
+++ b/library/psa_crypto_ffdh.c
@@ -151,7 +151,7 @@
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi GX, G, X, P;
- psa_key_type_t type = attributes->core.type;
+ psa_key_type_t type = attributes->type;
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
if (key_buffer_size > data_size) {
@@ -167,7 +167,7 @@
mbedtls_mpi_init(&GX); mbedtls_mpi_init(&G);
mbedtls_mpi_init(&X); mbedtls_mpi_init(&P);
- size_t key_len = PSA_BITS_TO_BYTES(attributes->core.bits);
+ size_t key_len = PSA_BITS_TO_BYTES(attributes->bits);
status = mbedtls_psa_ffdh_set_prime_generator(key_len, &P, &G);
@@ -283,7 +283,7 @@
mbedtls_mpi_init(&K);
status = mbedtls_psa_ffdh_set_prime_generator(
- PSA_BITS_TO_BYTES(attributes->core.bits), &P, &G);
+ PSA_BITS_TO_BYTES(attributes->bits), &P, &G);
if (status != PSA_SUCCESS) {
goto cleanup;
diff --git a/library/psa_crypto_random_impl.h b/library/psa_crypto_random_impl.h
index 64b8949..533fb2e 100644
--- a/library/psa_crypto_random_impl.h
+++ b/library/psa_crypto_random_impl.h
@@ -1,14 +1,6 @@
/** \file psa_crypto_random_impl.h
*
* \brief PSA crypto random generator implementation abstraction.
- *
- * The definitions here need to be consistent with the declarations
- * in include/psa_util_internal.h. This file contains some redundant
- * declarations to increase the chance that a compiler will detect
- * inconsistencies if one file is changed without updating the other,
- * but not all potential inconsistencies can be enforced, so make sure
- * to check the public declarations and contracts in
- * include/psa_util_internal.h if you modify this file.
*/
/*
* Copyright The Mbed TLS Contributors
@@ -22,22 +14,12 @@
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
-#include <string.h>
-#include <mbedtls/entropy.h> // only for error codes
-#include <psa/crypto.h>
-
typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t;
-/* Trivial wrapper around psa_generate_random(). */
-int mbedtls_psa_get_random(void *p_rng,
- unsigned char *output,
- size_t output_size);
-
-/* The PSA RNG API doesn't need any externally maintained state. */
-#define MBEDTLS_PSA_RANDOM_STATE NULL
-
#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+#include "mbedtls/entropy.h"
+
/* Choose a DRBG based on configuration and availability */
#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
@@ -67,11 +49,37 @@
#error "No hash algorithm available for HMAC_DBRG."
#endif
-#else
+#else /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
+
#error "No DRBG module available for the psa_crypto module."
+
+#endif /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
+
+#if defined(MBEDTLS_CTR_DRBG_C)
+#include "mbedtls/ctr_drbg.h"
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+#include "mbedtls/hmac_drbg.h"
+#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
+
+/* The maximum number of bytes that mbedtls_psa_get_random() is expected to return. */
+#if defined(MBEDTLS_CTR_DRBG_C)
+#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
#endif
-#include "mbedtls/entropy.h"
+#if defined(MBEDTLS_CTR_DRBG_C)
+typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
+#elif defined(MBEDTLS_HMAC_DRBG_C)
+typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
+#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
+
+typedef struct {
+ void (* entropy_init)(mbedtls_entropy_context *ctx);
+ void (* entropy_free)(mbedtls_entropy_context *ctx);
+ mbedtls_entropy_context entropy;
+ mbedtls_psa_drbg_context_t drbg;
+} mbedtls_psa_random_context_t;
/** Initialize the PSA DRBG.
*
@@ -99,63 +107,6 @@
#endif
}
-/** The type of the PSA random generator context.
- *
- * The random generator context is composed of an entropy context and
- * a DRBG context.
- */
-typedef struct {
- void (* entropy_init)(mbedtls_entropy_context *ctx);
- void (* entropy_free)(mbedtls_entropy_context *ctx);
- mbedtls_entropy_context entropy;
- mbedtls_psa_drbg_context_t drbg;
-} mbedtls_psa_random_context_t;
-
-/* Defined in include/psa_util_internal.h so that it's visible to
- * application code. The declaration here is redundant, but included
- * as a safety net to make it more likely that a future change that
- * accidentally causes the implementation to diverge from the interface
- * will be noticed. */
-/* Do not include the declaration under MSVC because it doesn't accept it
- * ("error C2370: 'mbedtls_psa_get_random' : redefinition; different storage class").
- * Observed with Visual Studio 2013. A known bug apparently:
- * https://stackoverflow.com/questions/8146541/duplicate-external-static-declarations-not-allowed-in-visual-studio
- */
-#if !defined(_MSC_VER)
-static mbedtls_f_rng_t *const mbedtls_psa_get_random;
-#endif
-
-/** The maximum number of bytes that mbedtls_psa_get_random() is expected to
- * return.
- */
-#if defined(MBEDTLS_CTR_DRBG_C)
-#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
-#elif defined(MBEDTLS_HMAC_DRBG_C)
-#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
-#endif
-
-/** A pointer to the PSA DRBG state.
- *
- * This variable is only intended to be used through the macro
- * #MBEDTLS_PSA_RANDOM_STATE.
- */
-/* psa_crypto.c sets this variable to a pointer to the DRBG state in the
- * global PSA crypto state. */
-/* The type `mbedtls_psa_drbg_context_t` is defined in
- * include/psa_util_internal.h so that `mbedtls_psa_random_state` can be
- * declared there and be visible to application code. */
-extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
-
-/** A pointer to the PSA DRBG state.
- *
- * This macro expands to an expression that is suitable as the \c p_rng
- * parameter to pass to mbedtls_psa_get_random().
- *
- * This macro exists in all configurations where the psa_crypto module is
- * enabled. Its expansion depends on the configuration.
- */
-#define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
-
/** Seed the PSA DRBG.
*
* \param entropy An entropy context to read the seed from.
@@ -167,23 +118,15 @@
* \return \c 0 on success.
* \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure.
*/
-static inline int mbedtls_psa_drbg_seed(
- mbedtls_entropy_context *entropy,
- const unsigned char *custom, size_t len)
+static inline int mbedtls_psa_drbg_seed(mbedtls_psa_drbg_context_t *drbg_ctx,
+ mbedtls_entropy_context *entropy,
+ const unsigned char *custom, size_t len)
{
#if defined(MBEDTLS_CTR_DRBG_C)
- return mbedtls_ctr_drbg_seed(MBEDTLS_PSA_RANDOM_STATE,
- mbedtls_entropy_func,
- entropy,
- custom, len);
+ return mbedtls_ctr_drbg_seed(drbg_ctx, mbedtls_entropy_func, entropy, custom, len);
#elif defined(MBEDTLS_HMAC_DRBG_C)
- const mbedtls_md_info_t *md_info =
- mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE);
- return mbedtls_hmac_drbg_seed(MBEDTLS_PSA_RANDOM_STATE,
- md_info,
- mbedtls_entropy_func,
- entropy,
- custom, len);
+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE);
+ return mbedtls_hmac_drbg_seed(drbg_ctx, md_info, mbedtls_entropy_func, entropy, custom, len);
#endif
}
diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c
index 84a8667..2f613b3 100644
--- a/library/psa_crypto_rsa.c
+++ b/library/psa_crypto_rsa.c
@@ -116,7 +116,7 @@
mbedtls_rsa_context *rsa = NULL;
/* Parse input */
- status = mbedtls_psa_rsa_load_representation(attributes->core.type,
+ status = mbedtls_psa_rsa_load_representation(attributes->type,
data,
data_length,
&rsa);
@@ -130,7 +130,7 @@
* representation in the key slot. Export representation in case of RSA is
* the smallest representation that's allowed as input, so a straight-up
* allocation of the same size as the input buffer will be large enough. */
- status = mbedtls_psa_rsa_export_key(attributes->core.type,
+ status = mbedtls_psa_rsa_export_key(attributes->type,
rsa,
key_buffer,
key_buffer_size,
@@ -196,7 +196,7 @@
mbedtls_rsa_context *rsa = NULL;
status = mbedtls_psa_rsa_load_representation(
- attributes->core.type, key_buffer, key_buffer_size, &rsa);
+ attributes->type, key_buffer, key_buffer_size, &rsa);
if (status != PSA_SUCCESS) {
return status;
}
@@ -261,13 +261,13 @@
ret = mbedtls_rsa_gen_key(&rsa,
mbedtls_psa_get_random,
MBEDTLS_PSA_RANDOM_STATE,
- (unsigned int) attributes->core.bits,
+ (unsigned int) attributes->bits,
exponent);
if (ret != 0) {
return mbedtls_to_psa_error(ret);
}
- status = mbedtls_psa_rsa_export_key(attributes->core.type,
+ status = mbedtls_psa_rsa_export_key(attributes->type,
&rsa, key_buffer, key_buffer_size,
key_buffer_length);
mbedtls_rsa_free(&rsa);
@@ -325,7 +325,7 @@
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_type_t md_alg;
- status = mbedtls_psa_rsa_load_representation(attributes->core.type,
+ status = mbedtls_psa_rsa_load_representation(attributes->type,
key_buffer,
key_buffer_size,
&rsa);
@@ -424,7 +424,7 @@
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_type_t md_alg;
- status = mbedtls_psa_rsa_load_representation(attributes->core.type,
+ status = mbedtls_psa_rsa_load_representation(attributes->type,
key_buffer,
key_buffer_size,
&rsa);
@@ -536,11 +536,11 @@
(void) output_size;
(void) output_length;
- if (PSA_KEY_TYPE_IS_RSA(attributes->core.type)) {
+ if (PSA_KEY_TYPE_IS_RSA(attributes->type)) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
mbedtls_rsa_context *rsa = NULL;
- status = mbedtls_psa_rsa_load_representation(attributes->core.type,
+ status = mbedtls_psa_rsa_load_representation(attributes->type,
key_buffer,
key_buffer_size,
&rsa);
@@ -632,11 +632,11 @@
*output_length = 0;
- if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
+ if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
mbedtls_rsa_context *rsa = NULL;
- status = mbedtls_psa_rsa_load_representation(attributes->core.type,
+ status = mbedtls_psa_rsa_load_representation(attributes->type,
key_buffer,
key_buffer_size,
&rsa);
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index b2a3c7e..5dee32f 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -329,7 +329,7 @@
/* Copy actual key length and core attributes into the slot on success */
slot->key.bytes = key_buffer_length;
- slot->attr = attributes.core;
+ slot->attr = attributes;
exit:
if (status != PSA_SUCCESS) {
psa_remove_key_data_from_memory(slot);
diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c
index 13a3c8a..7d1317b 100644
--- a/library/psa_crypto_storage.c
+++ b/library/psa_crypto_storage.c
@@ -235,7 +235,7 @@
void psa_format_key_data_for_storage(const uint8_t *data,
const size_t data_length,
- const psa_core_key_attributes_t *attr,
+ const psa_key_attributes_t *attr,
uint8_t *storage_data)
{
psa_persistent_key_storage_format *storage_format =
@@ -267,7 +267,7 @@
size_t storage_data_length,
uint8_t **key_data,
size_t *key_data_length,
- psa_core_key_attributes_t *attr)
+ psa_key_attributes_t *attr)
{
psa_status_t status;
const psa_persistent_key_storage_format *storage_format =
@@ -314,7 +314,7 @@
return PSA_SUCCESS;
}
-psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
+psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr,
const uint8_t *data,
const size_t data_length)
{
@@ -352,7 +352,7 @@
mbedtls_zeroize_and_free(key_data, key_data_length);
}
-psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
+psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr,
uint8_t **data,
size_t *data_length)
{
diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h
index b6b5e15..f1ea265 100644
--- a/library/psa_crypto_storage.h
+++ b/library/psa_crypto_storage.h
@@ -93,7 +93,7 @@
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
*/
-psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
+psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr,
const uint8_t *data,
const size_t data_length);
@@ -123,7 +123,7 @@
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
*/
-psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
+psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr,
uint8_t **data,
size_t *data_length);
@@ -163,7 +163,7 @@
*/
void psa_format_key_data_for_storage(const uint8_t *data,
const size_t data_length,
- const psa_core_key_attributes_t *attr,
+ const psa_key_attributes_t *attr,
uint8_t *storage_data);
/**
@@ -186,7 +186,7 @@
size_t storage_data_length,
uint8_t **key_data,
size_t *key_data_length,
- psa_core_key_attributes_t *attr);
+ psa_key_attributes_t *attr);
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/** This symbol is defined if transaction support is required. */
diff --git a/library/psa_util.c b/library/psa_util.c
index 125b173..4ccc5b0 100644
--- a/library/psa_util.c
+++ b/library/psa_util.c
@@ -18,7 +18,7 @@
#include "psa_util_internal.h"
-#if defined(MBEDTLS_PSA_CRYPTO_C)
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
#include <psa/crypto.h>
@@ -46,6 +46,7 @@
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
#include <mbedtls/cipher.h>
#endif
+#include <mbedtls/entropy.h>
/* PSA_SUCCESS is kept at the top of each error table since
* it's the most common status when everything functions properly. */
@@ -338,7 +339,31 @@
}
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
-#endif /* MBEDTLS_PSA_CRYPTO_C */
+/* Wrapper function allowing the classic API to use the PSA RNG.
+ *
+ * `mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, ...)` calls
+ * `psa_generate_random(...)`. The state parameter is ignored since the
+ * PSA API doesn't support passing an explicit state.
+ */
+int mbedtls_psa_get_random(void *p_rng,
+ unsigned char *output,
+ size_t output_size)
+{
+ /* This function takes a pointer to the RNG state because that's what
+ * classic mbedtls functions using an RNG expect. The PSA RNG manages
+ * its own state internally and doesn't let the caller access that state.
+ * So we just ignore the state parameter, and in practice we'll pass
+ * NULL. */
+ (void) p_rng;
+ psa_status_t status = psa_generate_random(output, output_size);
+ if (status == PSA_SUCCESS) {
+ return 0;
+ } else {
+ return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+ }
+}
+
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
diff --git a/library/psa_util_internal.h b/library/psa_util_internal.h
index 3e62d5f..70a08a0 100644
--- a/library/psa_util_internal.h
+++ b/library/psa_util_internal.h
@@ -16,7 +16,7 @@
#include "psa/crypto.h"
-#if defined(MBEDTLS_PSA_CRYPTO_C)
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
/*************************************************************************
* FFDH
@@ -96,5 +96,5 @@
sizeof(error_list)/sizeof(error_list[0]), \
fallback_f)
-#endif /* MBEDTLS_PSA_CRYPTO_C */
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
#endif /* MBEDTLS_PSA_UTIL_INTERNAL_H */
diff --git a/library/ssl_client.c b/library/ssl_client.c
index 6d988a8..8892acf 100644
--- a/library/ssl_client.c
+++ b/library/ssl_client.c
@@ -765,11 +765,6 @@
MBEDTLS_SSL_SESSION_TICKETS &&
MBEDTLS_HAVE_TIME */
- if (ssl->conf->f_rng == NULL) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
- return MBEDTLS_ERR_SSL_NO_RNG;
- }
-
/* Bet on the highest configured version if we are not in a TLS 1.2
* renegotiation or session resumption.
*/
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index d8844fc..883b988 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -2150,6 +2150,9 @@
unsigned char *buf,
const unsigned char *end,
size_t *out_len);
+
+int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl,
+ size_t early_data_len);
#endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 2a6d434..0c71157 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -4005,7 +4005,11 @@
MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD)) {
MBEDTLS_SSL_DEBUG_MSG(
3, ("EarlyData: deprotect and discard app data records."));
- /* TODO: Add max_early_data_size check here, see issue 6347 */
+
+ ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
+ if (ret != 0) {
+ return ret;
+ }
ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
}
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
@@ -4129,9 +4133,15 @@
*/
if (ssl->discard_early_data_record == MBEDTLS_SSL_EARLY_DATA_DISCARD) {
if (rec->type == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
+
+ ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
+ if (ret != 0) {
+ return ret;
+ }
+
MBEDTLS_SSL_DEBUG_MSG(
3, ("EarlyData: Ignore application message before 2nd ClientHello"));
- /* TODO: Add max_early_data_size check here, see issue 6347 */
+
return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
} else if (rec->type == MBEDTLS_SSL_MSG_HANDSHAKE) {
ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 5b0a4b9..1bfd180 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -432,10 +432,6 @@
static int ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int);
#endif /* MBEDTLS_MD_CAN_SHA384*/
-static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session,
- unsigned char *buf,
- size_t buf_len);
-
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls12_session_load(mbedtls_ssl_session *session,
const unsigned char *buf,
@@ -1105,6 +1101,7 @@
#if defined(MBEDTLS_SSL_SRV_C)
ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
#endif
+ ssl->total_early_data_size = 0;
#endif /* MBEDTLS_SSL_EARLY_DATA */
/* Initialize structures */
@@ -1365,6 +1362,11 @@
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+ if (ssl->conf->f_rng == NULL) {
+ MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
+ return MBEDTLS_ERR_SSL_NO_RNG;
+ }
+
/* Space for further checks */
return 0;
@@ -2448,282 +2450,6 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
-#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-/* Serialization of TLS 1.3 sessions:
- *
- * struct {
- * opaque hostname<0..2^16-1>;
- * uint64 ticket_reception_time;
- * uint32 ticket_lifetime;
- * opaque ticket<1..2^16-1>;
- * } ClientOnlyData;
- *
- * struct {
- * uint32 ticket_age_add;
- * uint8 ticket_flags;
- * opaque resumption_key<0..255>;
- * uint32 max_early_data_size;
- * uint16 record_size_limit;
- * select ( endpoint ) {
- * case client: ClientOnlyData;
- * case server: uint64 ticket_creation_time;
- * };
- * } serialized_session_tls13;
- *
- */
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
- unsigned char *buf,
- size_t buf_len,
- size_t *olen)
-{
- unsigned char *p = buf;
-#if defined(MBEDTLS_SSL_CLI_C) && \
- defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- size_t hostname_len = (session->hostname == NULL) ?
- 0 : strlen(session->hostname) + 1;
-#endif
- size_t needed = 4 /* ticket_age_add */
- + 1 /* ticket_flags */
- + 1; /* resumption_key length */
- *olen = 0;
-
- if (session->resumption_key_len > MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- needed += session->resumption_key_len; /* resumption_key */
-
-#if defined(MBEDTLS_SSL_EARLY_DATA)
- needed += 4; /* max_early_data_size */
-#endif
-#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
- needed += 2; /* record_size_limit */
-#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
-
-#if defined(MBEDTLS_HAVE_TIME)
- needed += 8; /* ticket_creation_time or ticket_reception_time */
-#endif
-
-#if defined(MBEDTLS_SSL_CLI_C)
- if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- needed += 2 /* hostname_len */
- + hostname_len; /* hostname */
-#endif
-
- needed += 4 /* ticket_lifetime */
- + 2; /* ticket_len */
-
- /* Check size_t overflow */
- if (session->ticket_len > SIZE_MAX - needed) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- needed += session->ticket_len; /* ticket */
- }
-#endif /* MBEDTLS_SSL_CLI_C */
-
- *olen = needed;
- if (needed > buf_len) {
- return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
- }
-
- MBEDTLS_PUT_UINT32_BE(session->ticket_age_add, p, 0);
- p[4] = session->ticket_flags;
-
- /* save resumption_key */
- p[5] = session->resumption_key_len;
- p += 6;
- memcpy(p, session->resumption_key, session->resumption_key_len);
- p += session->resumption_key_len;
-
-#if defined(MBEDTLS_SSL_EARLY_DATA)
- MBEDTLS_PUT_UINT32_BE(session->max_early_data_size, p, 0);
- p += 4;
-#endif
-#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
- MBEDTLS_PUT_UINT16_BE(session->record_size_limit, p, 0);
- p += 2;
-#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
-
-#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
- if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
- MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0);
- p += 8;
- }
-#endif /* MBEDTLS_HAVE_TIME */
-
-#if defined(MBEDTLS_SSL_CLI_C)
- if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- MBEDTLS_PUT_UINT16_BE(hostname_len, p, 0);
- p += 2;
- if (hostname_len > 0) {
- /* save host name */
- memcpy(p, session->hostname, hostname_len);
- p += hostname_len;
- }
-#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
-
-#if defined(MBEDTLS_HAVE_TIME)
- MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_reception_time, p, 0);
- p += 8;
-#endif
- MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
- p += 4;
-
- MBEDTLS_PUT_UINT16_BE(session->ticket_len, p, 0);
- p += 2;
-
- if (session->ticket != NULL && session->ticket_len > 0) {
- memcpy(p, session->ticket, session->ticket_len);
- p += session->ticket_len;
- }
- }
-#endif /* MBEDTLS_SSL_CLI_C */
- return 0;
-}
-
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_session_load(mbedtls_ssl_session *session,
- const unsigned char *buf,
- size_t len)
-{
- const unsigned char *p = buf;
- const unsigned char *end = buf + len;
-
- if (end - p < 6) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 0);
- session->ticket_flags = p[4];
-
- /* load resumption_key */
- session->resumption_key_len = p[5];
- p += 6;
-
- if (end - p < session->resumption_key_len) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- if (sizeof(session->resumption_key) < session->resumption_key_len) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- memcpy(session->resumption_key, p, session->resumption_key_len);
- p += session->resumption_key_len;
-
-#if defined(MBEDTLS_SSL_EARLY_DATA)
- if (end - p < 4) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->max_early_data_size = MBEDTLS_GET_UINT32_BE(p, 0);
- p += 4;
-#endif
-#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
- if (end - p < 2) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->record_size_limit = MBEDTLS_GET_UINT16_BE(p, 0);
- p += 2;
-#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
-
-#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
- if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
- if (end - p < 8) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0);
- p += 8;
- }
-#endif /* MBEDTLS_HAVE_TIME */
-
-#if defined(MBEDTLS_SSL_CLI_C)
- if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- size_t hostname_len;
- /* load host name */
- if (end - p < 2) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- hostname_len = MBEDTLS_GET_UINT16_BE(p, 0);
- p += 2;
-
- if (end - p < (long int) hostname_len) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- if (hostname_len > 0) {
- session->hostname = mbedtls_calloc(1, hostname_len);
- if (session->hostname == NULL) {
- return MBEDTLS_ERR_SSL_ALLOC_FAILED;
- }
- memcpy(session->hostname, p, hostname_len);
- p += hostname_len;
- }
-#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
-
-#if defined(MBEDTLS_HAVE_TIME)
- if (end - p < 8) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->ticket_reception_time = MBEDTLS_GET_UINT64_BE(p, 0);
- p += 8;
-#endif
- if (end - p < 4) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
- p += 4;
-
- if (end - p < 2) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->ticket_len = MBEDTLS_GET_UINT16_BE(p, 0);
- p += 2;
-
- if (end - p < (long int) session->ticket_len) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- if (session->ticket_len > 0) {
- session->ticket = mbedtls_calloc(1, session->ticket_len);
- if (session->ticket == NULL) {
- return MBEDTLS_ERR_SSL_ALLOC_FAILED;
- }
- memcpy(session->ticket, p, session->ticket_len);
- p += session->ticket_len;
- }
- }
-#endif /* MBEDTLS_SSL_CLI_C */
-
- return 0;
-
-}
-#else /* MBEDTLS_SSL_SESSION_TICKETS */
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
- unsigned char *buf,
- size_t buf_len,
- size_t *olen)
-{
- ((void) session);
- ((void) buf);
- ((void) buf_len);
- *olen = 0;
- return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
-}
-
-static int ssl_tls13_session_load(const mbedtls_ssl_session *session,
- unsigned char *buf,
- size_t buf_len)
-{
- ((void) session);
- ((void) buf);
- ((void) buf_len);
- return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
-}
-#endif /* !MBEDTLS_SSL_SESSION_TICKETS */
-#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
-
psa_status_t mbedtls_ssl_cipher_to_psa(mbedtls_cipher_type_t mbedtls_cipher_type,
size_t taglen,
psa_algorithm_t *alg,
@@ -3640,6 +3366,630 @@
}
#endif /* MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+
+/* Serialization of TLS 1.2 sessions
+ *
+ * For more detail, see the description of ssl_session_save().
+ */
+static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session,
+ unsigned char *buf,
+ size_t buf_len)
+{
+ unsigned char *p = buf;
+ size_t used = 0;
+
+#if defined(MBEDTLS_HAVE_TIME)
+ uint64_t start;
+#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ size_t cert_len;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ /*
+ * Time
+ */
+#if defined(MBEDTLS_HAVE_TIME)
+ used += 8;
+
+ if (used <= buf_len) {
+ start = (uint64_t) session->start;
+
+ MBEDTLS_PUT_UINT64_BE(start, p, 0);
+ p += 8;
+ }
+#endif /* MBEDTLS_HAVE_TIME */
+
+ /*
+ * Basic mandatory fields
+ */
+ used += 1 /* id_len */
+ + sizeof(session->id)
+ + sizeof(session->master)
+ + 4; /* verify_result */
+
+ if (used <= buf_len) {
+ *p++ = MBEDTLS_BYTE_0(session->id_len);
+ memcpy(p, session->id, 32);
+ p += 32;
+
+ memcpy(p, session->master, 48);
+ p += 48;
+
+ MBEDTLS_PUT_UINT32_BE(session->verify_result, p, 0);
+ p += 4;
+ }
+
+ /*
+ * Peer's end-entity certificate
+ */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ if (session->peer_cert == NULL) {
+ cert_len = 0;
+ } else {
+ cert_len = session->peer_cert->raw.len;
+ }
+
+ used += 3 + cert_len;
+
+ if (used <= buf_len) {
+ *p++ = MBEDTLS_BYTE_2(cert_len);
+ *p++ = MBEDTLS_BYTE_1(cert_len);
+ *p++ = MBEDTLS_BYTE_0(cert_len);
+
+ if (session->peer_cert != NULL) {
+ memcpy(p, session->peer_cert->raw.p, cert_len);
+ p += cert_len;
+ }
+ }
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if (session->peer_cert_digest != NULL) {
+ used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
+ if (used <= buf_len) {
+ *p++ = (unsigned char) session->peer_cert_digest_type;
+ *p++ = (unsigned char) session->peer_cert_digest_len;
+ memcpy(p, session->peer_cert_digest,
+ session->peer_cert_digest_len);
+ p += session->peer_cert_digest_len;
+ }
+ } else {
+ used += 2;
+ if (used <= buf_len) {
+ *p++ = (unsigned char) MBEDTLS_MD_NONE;
+ *p++ = 0;
+ }
+ }
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ /*
+ * Session ticket if any, plus associated data
+ */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+#if defined(MBEDTLS_SSL_CLI_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
+ used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
+
+ if (used <= buf_len) {
+ *p++ = MBEDTLS_BYTE_2(session->ticket_len);
+ *p++ = MBEDTLS_BYTE_1(session->ticket_len);
+ *p++ = MBEDTLS_BYTE_0(session->ticket_len);
+
+ if (session->ticket != NULL) {
+ memcpy(p, session->ticket, session->ticket_len);
+ p += session->ticket_len;
+ }
+
+ MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
+ p += 4;
+ }
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+ used += 8;
+
+ if (used <= buf_len) {
+ MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0);
+ p += 8;
+ }
+ }
+#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+ /*
+ * Misc extension-related info
+ */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ used += 1;
+
+ if (used <= buf_len) {
+ *p++ = session->mfl_code;
+ }
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ used += 1;
+
+ if (used <= buf_len) {
+ *p++ = MBEDTLS_BYTE_0(session->encrypt_then_mac);
+ }
+#endif
+
+ return used;
+}
+
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls12_session_load(mbedtls_ssl_session *session,
+ const unsigned char *buf,
+ size_t len)
+{
+#if defined(MBEDTLS_HAVE_TIME)
+ uint64_t start;
+#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ size_t cert_len;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ const unsigned char *p = buf;
+ const unsigned char * const end = buf + len;
+
+ /*
+ * Time
+ */
+#if defined(MBEDTLS_HAVE_TIME)
+ if (8 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ start = MBEDTLS_GET_UINT64_BE(p, 0);
+ p += 8;
+
+ session->start = (time_t) start;
+#endif /* MBEDTLS_HAVE_TIME */
+
+ /*
+ * Basic mandatory fields
+ */
+ if (1 + 32 + 48 + 4 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->id_len = *p++;
+ memcpy(session->id, p, 32);
+ p += 32;
+
+ memcpy(session->master, p, 48);
+ p += 48;
+
+ session->verify_result = MBEDTLS_GET_UINT32_BE(p, 0);
+ p += 4;
+
+ /* Immediately clear invalid pointer values that have been read, in case
+ * we exit early before we replaced them with valid ones. */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ session->peer_cert = NULL;
+#else
+ session->peer_cert_digest = NULL;
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+ session->ticket = NULL;
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+ /*
+ * Peer certificate
+ */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* Deserialize CRT from the end of the ticket. */
+ if (3 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ cert_len = MBEDTLS_GET_UINT24_BE(p, 0);
+ p += 3;
+
+ if (cert_len != 0) {
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if (cert_len > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->peer_cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
+
+ if (session->peer_cert == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+
+ mbedtls_x509_crt_init(session->peer_cert);
+
+ if ((ret = mbedtls_x509_crt_parse_der(session->peer_cert,
+ p, cert_len)) != 0) {
+ mbedtls_x509_crt_free(session->peer_cert);
+ mbedtls_free(session->peer_cert);
+ session->peer_cert = NULL;
+ return ret;
+ }
+
+ p += cert_len;
+ }
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ /* Deserialize CRT digest from the end of the ticket. */
+ if (2 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
+ session->peer_cert_digest_len = (size_t) *p++;
+
+ if (session->peer_cert_digest_len != 0) {
+ const mbedtls_md_info_t *md_info =
+ mbedtls_md_info_from_type(session->peer_cert_digest_type);
+ if (md_info == NULL) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ if (session->peer_cert_digest_len != mbedtls_md_get_size(md_info)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ if (session->peer_cert_digest_len > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->peer_cert_digest =
+ mbedtls_calloc(1, session->peer_cert_digest_len);
+ if (session->peer_cert_digest == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+
+ memcpy(session->peer_cert_digest, p,
+ session->peer_cert_digest_len);
+ p += session->peer_cert_digest_len;
+ }
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ /*
+ * Session ticket and associated data
+ */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+#if defined(MBEDTLS_SSL_CLI_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
+ if (3 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->ticket_len = MBEDTLS_GET_UINT24_BE(p, 0);
+ p += 3;
+
+ if (session->ticket_len != 0) {
+ if (session->ticket_len > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->ticket = mbedtls_calloc(1, session->ticket_len);
+ if (session->ticket == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+
+ memcpy(session->ticket, p, session->ticket_len);
+ p += session->ticket_len;
+ }
+
+ if (4 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
+ p += 4;
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+ if (8 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0);
+ p += 8;
+ }
+#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+ /*
+ * Misc extension-related info
+ */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ if (1 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->mfl_code = *p++;
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ if (1 > (size_t) (end - p)) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ session->encrypt_then_mac = *p++;
+#endif
+
+ /* Done, should have consumed entire buffer */
+ if (p != end) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ return 0;
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+/* Serialization of TLS 1.3 sessions:
+ *
+ * For more detail, see the description of ssl_session_save().
+ */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
+ unsigned char *buf,
+ size_t buf_len,
+ size_t *olen)
+{
+ unsigned char *p = buf;
+#if defined(MBEDTLS_SSL_CLI_C) && \
+ defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ size_t hostname_len = (session->hostname == NULL) ?
+ 0 : strlen(session->hostname) + 1;
+#endif
+ size_t needed = 4 /* ticket_age_add */
+ + 1 /* ticket_flags */
+ + 1; /* resumption_key length */
+ *olen = 0;
+
+ if (session->resumption_key_len > MBEDTLS_SSL_TLS1_3_TICKET_RESUMPTION_KEY_LEN) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ needed += session->resumption_key_len; /* resumption_key */
+
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ needed += 4; /* max_early_data_size */
+#endif
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ needed += 2; /* record_size_limit */
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
+#if defined(MBEDTLS_HAVE_TIME)
+ needed += 8; /* ticket_creation_time or ticket_reception_time */
+#endif
+
+#if defined(MBEDTLS_SSL_CLI_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ needed += 2 /* hostname_len */
+ + hostname_len; /* hostname */
+#endif
+
+ needed += 4 /* ticket_lifetime */
+ + 2; /* ticket_len */
+
+ /* Check size_t overflow */
+ if (session->ticket_len > SIZE_MAX - needed) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ needed += session->ticket_len; /* ticket */
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+
+ *olen = needed;
+ if (needed > buf_len) {
+ return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
+ }
+
+ MBEDTLS_PUT_UINT32_BE(session->ticket_age_add, p, 0);
+ p[4] = session->ticket_flags;
+
+ /* save resumption_key */
+ p[5] = session->resumption_key_len;
+ p += 6;
+ memcpy(p, session->resumption_key, session->resumption_key_len);
+ p += session->resumption_key_len;
+
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ MBEDTLS_PUT_UINT32_BE(session->max_early_data_size, p, 0);
+ p += 4;
+#endif
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ MBEDTLS_PUT_UINT16_BE(session->record_size_limit, p, 0);
+ p += 2;
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
+#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+ MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0);
+ p += 8;
+ }
+#endif /* MBEDTLS_HAVE_TIME */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ MBEDTLS_PUT_UINT16_BE(hostname_len, p, 0);
+ p += 2;
+ if (hostname_len > 0) {
+ /* save host name */
+ memcpy(p, session->hostname, hostname_len);
+ p += hostname_len;
+ }
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_HAVE_TIME)
+ MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_reception_time, p, 0);
+ p += 8;
+#endif
+ MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
+ p += 4;
+
+ MBEDTLS_PUT_UINT16_BE(session->ticket_len, p, 0);
+ p += 2;
+
+ if (session->ticket != NULL && session->ticket_len > 0) {
+ memcpy(p, session->ticket, session->ticket_len);
+ p += session->ticket_len;
+ }
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+ return 0;
+}
+
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_session_load(mbedtls_ssl_session *session,
+ const unsigned char *buf,
+ size_t len)
+{
+ const unsigned char *p = buf;
+ const unsigned char *end = buf + len;
+
+ if (end - p < 6) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 0);
+ session->ticket_flags = p[4];
+
+ /* load resumption_key */
+ session->resumption_key_len = p[5];
+ p += 6;
+
+ if (end - p < session->resumption_key_len) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+
+ if (sizeof(session->resumption_key) < session->resumption_key_len) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ memcpy(session->resumption_key, p, session->resumption_key_len);
+ p += session->resumption_key_len;
+
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+ if (end - p < 4) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->max_early_data_size = MBEDTLS_GET_UINT32_BE(p, 0);
+ p += 4;
+#endif
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ if (end - p < 2) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->record_size_limit = MBEDTLS_GET_UINT16_BE(p, 0);
+ p += 2;
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
+#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
+ if (end - p < 8) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0);
+ p += 8;
+ }
+#endif /* MBEDTLS_HAVE_TIME */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+ if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ size_t hostname_len;
+ /* load host name */
+ if (end - p < 2) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ hostname_len = MBEDTLS_GET_UINT16_BE(p, 0);
+ p += 2;
+
+ if (end - p < (long int) hostname_len) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ if (hostname_len > 0) {
+ session->hostname = mbedtls_calloc(1, hostname_len);
+ if (session->hostname == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+ memcpy(session->hostname, p, hostname_len);
+ p += hostname_len;
+ }
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_HAVE_TIME)
+ if (end - p < 8) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->ticket_reception_time = MBEDTLS_GET_UINT64_BE(p, 0);
+ p += 8;
+#endif
+ if (end - p < 4) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
+ p += 4;
+
+ if (end - p < 2) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ session->ticket_len = MBEDTLS_GET_UINT16_BE(p, 0);
+ p += 2;
+
+ if (end - p < (long int) session->ticket_len) {
+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+ }
+ if (session->ticket_len > 0) {
+ session->ticket = mbedtls_calloc(1, session->ticket_len);
+ if (session->ticket == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+ memcpy(session->ticket, p, session->ticket_len);
+ p += session->ticket_len;
+ }
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+
+ return 0;
+
+}
+#else /* MBEDTLS_SSL_SESSION_TICKETS */
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_session_save(const mbedtls_ssl_session *session,
+ unsigned char *buf,
+ size_t buf_len,
+ size_t *olen)
+{
+ ((void) session);
+ ((void) buf);
+ ((void) buf_len);
+ *olen = 0;
+ return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+}
+
+static int ssl_tls13_session_load(const mbedtls_ssl_session *session,
+ unsigned char *buf,
+ size_t buf_len)
+{
+ ((void) session);
+ ((void) buf);
+ ((void) buf_len);
+ return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+}
+#endif /* !MBEDTLS_SSL_SESSION_TICKETS */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
+
/*
* Define ticket header determining Mbed TLS version
* and structure of the ticket.
@@ -3662,6 +4012,12 @@
#define SSL_SERIALIZED_SESSION_CONFIG_CRT 0
#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT 0
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SESSION_TICKETS)
#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 1
#else
@@ -3686,12 +4042,34 @@
#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 0
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+#define SSL_SERIALIZED_SESSION_CONFIG_SNI 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_SNI 0
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_SSL_EARLY_DATA)
+#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA 0
+#endif /* MBEDTLS_SSL_EARLY_DATA */
+
+#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE 0
+#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
+
#define SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT 0
#define SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT 1
#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT 2
#define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT 3
#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 4
#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 5
+#define SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT 6
+#define SSL_SERIALIZED_SESSION_CONFIG_SNI_BIT 7
+#define SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT 8
+#define SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE_BIT 9
#define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG \
((uint16_t) ( \
@@ -3701,7 +4079,14 @@
SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT) | \
(SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT) | \
(SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT) | \
- (SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT)))
+ (SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT) | \
+ (SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT << \
+ SSL_SERIALIZED_SESSION_CONFIG_KEEP_PEER_CRT_BIT) | \
+ (SSL_SERIALIZED_SESSION_CONFIG_SNI << SSL_SERIALIZED_SESSION_CONFIG_SNI_BIT) | \
+ (SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA << \
+ SSL_SERIALIZED_SESSION_CONFIG_EARLY_DATA_BIT) | \
+ (SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE << \
+ SSL_SERIALIZED_SESSION_CONFIG_RECORD_SIZE_BIT)))
static const unsigned char ssl_serialized_session_header[] = {
MBEDTLS_VERSION_MAJOR,
@@ -3715,7 +4100,77 @@
* Serialize a session in the following format:
* (in the presentation language of TLS, RFC 8446 section 3)
*
- * struct {
+ * TLS 1.2 session:
+ *
+ * struct {
+ * #if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ * opaque ticket<0..2^24-1>; // length 0 means no ticket
+ * uint32 ticket_lifetime;
+ * #endif
+ * } ClientOnlyData;
+ *
+ * struct {
+ * #if defined(MBEDTLS_HAVE_TIME)
+ * uint64 start_time;
+ * #endif
+ * uint8 session_id_len; // at most 32
+ * opaque session_id[32];
+ * opaque master[48]; // fixed length in the standard
+ * uint32 verify_result;
+ * #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
+ * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
+ * #else
+ * uint8 peer_cert_digest_type;
+ * opaque peer_cert_digest<0..2^8-1>
+ * #endif
+ * select (endpoint) {
+ * case client: ClientOnlyData;
+ * case server: uint64 ticket_creation_time;
+ * };
+ * #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ * uint8 mfl_code; // up to 255 according to standard
+ * #endif
+ * #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ * uint8 encrypt_then_mac; // 0 or 1
+ * #endif
+ * } serialized_session_tls12;
+ *
+ *
+ * TLS 1.3 Session:
+ *
+ * struct {
+ * #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ * opaque hostname<0..2^16-1>;
+ * #endif
+ * #if defined(MBEDTLS_HAVE_TIME)
+ * uint64 ticket_reception_time;
+ * #endif
+ * uint32 ticket_lifetime;
+ * opaque ticket<1..2^16-1>;
+ * } ClientOnlyData;
+ *
+ * struct {
+ * uint32 ticket_age_add;
+ * uint8 ticket_flags;
+ * opaque resumption_key<0..255>;
+ * #if defined(MBEDTLS_SSL_EARLY_DATA)
+ * uint32 max_early_data_size;
+ * #endif
+ * #if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
+ * uint16 record_size_limit;
+ * #endif
+ * select ( endpoint ) {
+ * case client: ClientOnlyData;
+ * #if defined(MBEDTLS_HAVE_TIME)
+ * case server: uint64 ticket_creation_time;
+ * #endif
+ * };
+ * } serialized_session_tls13;
+ *
+ *
+ * SSL session:
+ *
+ * struct {
*
* opaque mbedtls_version[3]; // library version: major, minor, patch
* opaque session_format[2]; // library-version specific 16-bit field
@@ -3733,6 +4188,8 @@
* uint8_t minor_ver; // Protocol minor version. Possible values:
* // - TLS 1.2 (0x0303)
* // - TLS 1.3 (0x0304)
+ * uint8_t endpoint;
+ * uint16_t ciphersuite;
*
* select (serialized_session.tls_version) {
*
@@ -8948,385 +9405,6 @@
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
-/* Serialization of TLS 1.2 sessions:
- *
- * struct {
- * opaque ticket<0..2^24-1>; // length 0 means no ticket
- * uint32 ticket_lifetime;
- * } ClientOnlyData;
- *
- * struct {
- * uint64 start_time;
- * uint8 session_id_len; // at most 32
- * opaque session_id[32];
- * opaque master[48]; // fixed length in the standard
- * uint32 verify_result;
- * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
- * select (endpoint) {
- * case client: ClientOnlyData;
- * case server: uint64 ticket_creation_time;
- * };
- * uint8 mfl_code; // up to 255 according to standard
- * uint8 encrypt_then_mac; // 0 or 1
- * } serialized_session_tls12;
- */
-static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session,
- unsigned char *buf,
- size_t buf_len)
-{
- unsigned char *p = buf;
- size_t used = 0;
-
-#if defined(MBEDTLS_HAVE_TIME)
- uint64_t start;
-#endif
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
- size_t cert_len;
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- /*
- * Time
- */
-#if defined(MBEDTLS_HAVE_TIME)
- used += 8;
-
- if (used <= buf_len) {
- start = (uint64_t) session->start;
-
- MBEDTLS_PUT_UINT64_BE(start, p, 0);
- p += 8;
- }
-#endif /* MBEDTLS_HAVE_TIME */
-
- /*
- * Basic mandatory fields
- */
- used += 1 /* id_len */
- + sizeof(session->id)
- + sizeof(session->master)
- + 4; /* verify_result */
-
- if (used <= buf_len) {
- *p++ = MBEDTLS_BYTE_0(session->id_len);
- memcpy(p, session->id, 32);
- p += 32;
-
- memcpy(p, session->master, 48);
- p += 48;
-
- MBEDTLS_PUT_UINT32_BE(session->verify_result, p, 0);
- p += 4;
- }
-
- /*
- * Peer's end-entity certificate
- */
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
- if (session->peer_cert == NULL) {
- cert_len = 0;
- } else {
- cert_len = session->peer_cert->raw.len;
- }
-
- used += 3 + cert_len;
-
- if (used <= buf_len) {
- *p++ = MBEDTLS_BYTE_2(cert_len);
- *p++ = MBEDTLS_BYTE_1(cert_len);
- *p++ = MBEDTLS_BYTE_0(cert_len);
-
- if (session->peer_cert != NULL) {
- memcpy(p, session->peer_cert->raw.p, cert_len);
- p += cert_len;
- }
- }
-#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
- if (session->peer_cert_digest != NULL) {
- used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
- if (used <= buf_len) {
- *p++ = (unsigned char) session->peer_cert_digest_type;
- *p++ = (unsigned char) session->peer_cert_digest_len;
- memcpy(p, session->peer_cert_digest,
- session->peer_cert_digest_len);
- p += session->peer_cert_digest_len;
- }
- } else {
- used += 2;
- if (used <= buf_len) {
- *p++ = (unsigned char) MBEDTLS_MD_NONE;
- *p++ = 0;
- }
- }
-#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- /*
- * Session ticket if any, plus associated data
- */
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-#if defined(MBEDTLS_SSL_CLI_C)
- if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
- used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
-
- if (used <= buf_len) {
- *p++ = MBEDTLS_BYTE_2(session->ticket_len);
- *p++ = MBEDTLS_BYTE_1(session->ticket_len);
- *p++ = MBEDTLS_BYTE_0(session->ticket_len);
-
- if (session->ticket != NULL) {
- memcpy(p, session->ticket, session->ticket_len);
- p += session->ticket_len;
- }
-
- MBEDTLS_PUT_UINT32_BE(session->ticket_lifetime, p, 0);
- p += 4;
- }
- }
-#endif /* MBEDTLS_SSL_CLI_C */
-#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
- if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
- used += 8;
-
- if (used <= buf_len) {
- MBEDTLS_PUT_UINT64_BE((uint64_t) session->ticket_creation_time, p, 0);
- p += 8;
- }
- }
-#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */
-#endif /* MBEDTLS_SSL_SESSION_TICKETS */
-
- /*
- * Misc extension-related info
- */
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- used += 1;
-
- if (used <= buf_len) {
- *p++ = session->mfl_code;
- }
-#endif
-
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- used += 1;
-
- if (used <= buf_len) {
- *p++ = MBEDTLS_BYTE_0(session->encrypt_then_mac);
- }
-#endif
-
- return used;
-}
-
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls12_session_load(mbedtls_ssl_session *session,
- const unsigned char *buf,
- size_t len)
-{
-#if defined(MBEDTLS_HAVE_TIME)
- uint64_t start;
-#endif
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
- size_t cert_len;
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- const unsigned char *p = buf;
- const unsigned char * const end = buf + len;
-
- /*
- * Time
- */
-#if defined(MBEDTLS_HAVE_TIME)
- if (8 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- start = MBEDTLS_GET_UINT64_BE(p, 0);
- p += 8;
-
- session->start = (time_t) start;
-#endif /* MBEDTLS_HAVE_TIME */
-
- /*
- * Basic mandatory fields
- */
- if (1 + 32 + 48 + 4 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->id_len = *p++;
- memcpy(session->id, p, 32);
- p += 32;
-
- memcpy(session->master, p, 48);
- p += 48;
-
- session->verify_result = MBEDTLS_GET_UINT32_BE(p, 0);
- p += 4;
-
- /* Immediately clear invalid pointer values that have been read, in case
- * we exit early before we replaced them with valid ones. */
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
- session->peer_cert = NULL;
-#else
- session->peer_cert_digest = NULL;
-#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
- session->ticket = NULL;
-#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
-
- /*
- * Peer certificate
- */
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
- /* Deserialize CRT from the end of the ticket. */
- if (3 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- cert_len = MBEDTLS_GET_UINT24_BE(p, 0);
- p += 3;
-
- if (cert_len != 0) {
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-
- if (cert_len > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->peer_cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
-
- if (session->peer_cert == NULL) {
- return MBEDTLS_ERR_SSL_ALLOC_FAILED;
- }
-
- mbedtls_x509_crt_init(session->peer_cert);
-
- if ((ret = mbedtls_x509_crt_parse_der(session->peer_cert,
- p, cert_len)) != 0) {
- mbedtls_x509_crt_free(session->peer_cert);
- mbedtls_free(session->peer_cert);
- session->peer_cert = NULL;
- return ret;
- }
-
- p += cert_len;
- }
-#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
- /* Deserialize CRT digest from the end of the ticket. */
- if (2 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
- session->peer_cert_digest_len = (size_t) *p++;
-
- if (session->peer_cert_digest_len != 0) {
- const mbedtls_md_info_t *md_info =
- mbedtls_md_info_from_type(session->peer_cert_digest_type);
- if (md_info == NULL) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- if (session->peer_cert_digest_len != mbedtls_md_get_size(md_info)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- if (session->peer_cert_digest_len > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->peer_cert_digest =
- mbedtls_calloc(1, session->peer_cert_digest_len);
- if (session->peer_cert_digest == NULL) {
- return MBEDTLS_ERR_SSL_ALLOC_FAILED;
- }
-
- memcpy(session->peer_cert_digest, p,
- session->peer_cert_digest_len);
- p += session->peer_cert_digest_len;
- }
-#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- /*
- * Session ticket and associated data
- */
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-#if defined(MBEDTLS_SSL_CLI_C)
- if (session->endpoint == MBEDTLS_SSL_IS_CLIENT) {
- if (3 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->ticket_len = MBEDTLS_GET_UINT24_BE(p, 0);
- p += 3;
-
- if (session->ticket_len != 0) {
- if (session->ticket_len > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->ticket = mbedtls_calloc(1, session->ticket_len);
- if (session->ticket == NULL) {
- return MBEDTLS_ERR_SSL_ALLOC_FAILED;
- }
-
- memcpy(session->ticket, p, session->ticket_len);
- p += session->ticket_len;
- }
-
- if (4 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
- p += 4;
- }
-#endif /* MBEDTLS_SSL_CLI_C */
-#if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_SRV_C)
- if (session->endpoint == MBEDTLS_SSL_IS_SERVER) {
- if (8 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
- session->ticket_creation_time = MBEDTLS_GET_UINT64_BE(p, 0);
- p += 8;
- }
-#endif /* MBEDTLS_HAVE_TIME && MBEDTLS_SSL_SRV_C */
-#endif /* MBEDTLS_SSL_SESSION_TICKETS */
-
- /*
- * Misc extension-related info
- */
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- if (1 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->mfl_code = *p++;
-#endif
-
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- if (1 > (size_t) (end - p)) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- session->encrypt_then_mac = *p++;
-#endif
-
- /* Done, should have consumed entire buffer */
- if (p != end) {
- return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
- }
-
- return 0;
-}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
int mbedtls_ssl_validate_ciphersuite(
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index 53a9ce2..b49a8ae 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -2178,11 +2178,6 @@
}
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
- if (ssl->conf->f_rng == NULL) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
- return MBEDTLS_ERR_SSL_NO_RNG;
- }
-
/*
* 0 . 0 handshake type
* 1 . 3 handshake length
@@ -2703,8 +2698,7 @@
PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type));
psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits);
- key_len = PSA_BITS_TO_BYTES(key->grp.pbits);
- ret = mbedtls_ecp_write_key(key, buf, key_len);
+ ret = mbedtls_ecp_write_key_ext(key, &key_len, buf, sizeof(buf));
if (ret != 0) {
mbedtls_platform_zeroize(buf, sizeof(buf));
break;
diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c
index bc73704..d448a05 100644
--- a/library/ssl_tls13_generic.c
+++ b/library/ssl_tls13_generic.c
@@ -1454,6 +1454,54 @@
return 0;
}
+
+#if defined(MBEDTLS_SSL_SRV_C)
+int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl,
+ size_t early_data_len)
+{
+ /*
+ * This function should be called only while an handshake is in progress
+ * and thus a session under negotiation. Add a sanity check to detect a
+ * misuse.
+ */
+ if (ssl->session_negotiate == NULL) {
+ return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ }
+
+ /* 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.
+ * Note that if it is still possible to send early_data_len bytes of early
+ * data, it means that early_data_len is smaller than max_early_data_size
+ * (type uint32_t) and can fit in an uint32_t. We use this further
+ * down.
+ */
+ if (early_data_len >
+ (ssl->session_negotiate->max_early_data_size -
+ ssl->total_early_data_size)) {
+
+ MBEDTLS_SSL_DEBUG_MSG(
+ 2, ("EarlyData: Too much early data received, %u + %" MBEDTLS_PRINTF_SIZET " > %u",
+ ssl->total_early_data_size, early_data_len,
+ ssl->session_negotiate->max_early_data_size));
+
+ MBEDTLS_SSL_PEND_FATAL_ALERT(
+ MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
+ MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
+ return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
+ }
+
+ /*
+ * early_data_len has been checked to be less than max_early_data_size
+ * that is uint32_t. Its cast to an uint32_t below is thus safe. We need
+ * the cast to appease some compilers.
+ */
+ ssl->total_early_data_size += (uint32_t) early_data_len;
+
+ return 0;
+}
+#endif /* MBEDTLS_SSL_SRV_C */
#endif /* MBEDTLS_SSL_EARLY_DATA */
/* Reset SSL context and update hash for handling HRR.
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 3a968aa..887c5c6 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -39,6 +39,63 @@
return ciphersuite_info;
}
+static void ssl_tls13_select_ciphersuite(
+ mbedtls_ssl_context *ssl,
+ const unsigned char *cipher_suites,
+ const unsigned char *cipher_suites_end,
+ int psk_ciphersuite_id,
+ psa_algorithm_t psk_hash_alg,
+ const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info)
+{
+ *selected_ciphersuite_info = NULL;
+
+ /*
+ * In a compliant ClientHello the byte-length of the list of ciphersuites
+ * is even and this function relies on this fact. This should have been
+ * checked in the main ClientHello parsing function. Double check here.
+ */
+ if ((cipher_suites_end - cipher_suites) & 1) {
+ return;
+ }
+
+ for (const unsigned char *p = cipher_suites;
+ p < cipher_suites_end; p += 2) {
+ /*
+ * "cipher_suites_end - p is even" is an invariant of the loop. As
+ * cipher_suites_end - p > 0, we have cipher_suites_end - p >= 2 and it
+ * is thus safe to read two bytes.
+ */
+ uint16_t id = MBEDTLS_GET_UINT16_BE(p, 0);
+
+ const mbedtls_ssl_ciphersuite_t *info =
+ ssl_tls13_validate_peer_ciphersuite(ssl, id);
+ if (info == NULL) {
+ continue;
+ }
+
+ /*
+ * If a valid PSK ciphersuite identifier has been passed in, we want
+ * an exact match.
+ */
+ if (psk_ciphersuite_id != 0) {
+ if (id != psk_ciphersuite_id) {
+ continue;
+ }
+ } else if (psk_hash_alg != PSA_ALG_NONE) {
+ if (mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) info->mac) !=
+ psk_hash_alg) {
+ continue;
+ }
+ }
+
+ *selected_ciphersuite_info = info;
+ return;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite, psk_ciphersuite_id=%x, psk_hash_alg=%x",
+ (unsigned) psk_ciphersuite_id, psk_hash_alg));
+}
+
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
/* From RFC 8446:
*
@@ -90,8 +147,30 @@
return 0;
}
-#define SSL_TLS1_3_OFFERED_PSK_NOT_MATCH 1
-#define SSL_TLS1_3_OFFERED_PSK_MATCH 0
+/*
+ * Non-error return values of
+ * ssl_tls13_offered_psks_check_identity_match_ticket() and
+ * ssl_tls13_offered_psks_check_identity_match(). They are positive to
+ * not collide with error codes that are negative. Zero
+ * (SSL_TLS1_3_PSK_IDENTITY_MATCH) in case of success as it may be propagated
+ * up by the callers of this function as a generic success condition.
+ *
+ * The return value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE means
+ * that the pre-shared-key identity matches that of a ticket or an externally-
+ * provisioned pre-shared-key. We have thus been able to retrieve the
+ * attributes of the pre-shared-key but at least one of them does not meet
+ * some criteria and the pre-shared-key cannot be used. For example, a ticket
+ * is expired or its version is not TLS 1.3. Note eventually that the return
+ * value SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE does not have
+ * anything to do with binder check. A binder check is done only when a
+ * suitable pre-shared-key has been selected and only for that selected
+ * pre-shared-key: if the binder check fails, we fail the handshake and we do
+ * not try to find another pre-shared-key for which the binder check would
+ * succeed as recommended by the specification.
+ */
+#define SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH 2
+#define SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE 1
+#define SSL_TLS1_3_PSK_IDENTITY_MATCH 0
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
@@ -109,7 +188,6 @@
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *ticket_buffer;
- unsigned int key_exchanges;
#if defined(MBEDTLS_HAVE_TIME)
mbedtls_ms_time_t now;
mbedtls_ms_time_t server_age;
@@ -123,7 +201,7 @@
/* Ticket parser is not configured, Skip */
if (ssl->conf->f_ticket_parse == NULL || identity_len == 0) {
- return 0;
+ return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
}
/* We create a copy of the encrypted ticket since the ticket parsing
@@ -133,63 +211,51 @@
*/
ticket_buffer = mbedtls_calloc(1, identity_len);
if (ticket_buffer == NULL) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}
memcpy(ticket_buffer, identity, identity_len);
- if ((ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket,
- session,
- ticket_buffer, identity_len)) != 0) {
- if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
- MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic"));
- } else if (ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) {
+ ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket,
+ session,
+ ticket_buffer, identity_len);
+ switch (ret) {
+ case 0:
+ ret = SSL_TLS1_3_PSK_IDENTITY_MATCH;
+ break;
+
+ case MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED:
MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is expired"));
- } else {
+ ret = SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE;
+ break;
+
+ case MBEDTLS_ERR_SSL_INVALID_MAC:
+ MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic"));
+ ret = SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
+ break;
+
+ default:
MBEDTLS_SSL_DEBUG_RET(1, "ticket_parse", ret);
- }
+ ret = SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
}
/* We delete the temporary buffer */
mbedtls_free(ticket_buffer);
- if (ret == 0 && session->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
- MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket TLS version is not 1.3."));
- /* TODO: Define new return value for this case. */
- ret = MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
- }
-
- if (ret != 0) {
+ if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) {
goto exit;
}
- /* RFC 8446 section 4.2.9
- *
- * Servers SHOULD NOT send NewSessionTicket with tickets that are not
- * compatible with the advertised modes; however, if a server does so,
- * the impact will just be that the client's attempts at resumption fail.
- *
- * We regard the ticket with incompatible key exchange modes as not match.
+ /*
+ * The identity matches that of a ticket. Now check that it has suitable
+ * attributes and bet it will not be the case.
*/
- ret = MBEDTLS_ERR_ERROR_GENERIC_ERROR;
- MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
+ ret = SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE;
- key_exchanges = 0;
- if (mbedtls_ssl_tls13_session_ticket_allow_psk_ephemeral(session) &&
- ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
- key_exchanges |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
- }
- if (mbedtls_ssl_tls13_session_ticket_allow_psk(session) &&
- ssl_tls13_key_exchange_is_psk_available(ssl)) {
- key_exchanges |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
- }
-
- if (key_exchanges == 0) {
- MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable key exchange mode"));
+ if (session->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
+ MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket TLS version is not 1.3."));
goto exit;
}
- ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
#if defined(MBEDTLS_HAVE_TIME)
now = mbedtls_ms_time();
@@ -242,13 +308,15 @@
age_diff));
goto exit;
}
-
- ret = 0;
-
#endif /* MBEDTLS_HAVE_TIME */
+ /*
+ * All good, we have found a suitable ticket.
+ */
+ ret = SSL_TLS1_3_PSK_IDENTITY_MATCH;
+
exit:
- if (ret != 0) {
+ if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) {
mbedtls_ssl_session_free(session);
}
@@ -273,13 +341,11 @@
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL;
MBEDTLS_SSL_DEBUG_BUF(4, "identity", identity, identity_len);
- ssl->handshake->resume = 0;
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- if (ssl_tls13_offered_psks_check_identity_match_ticket(
- ssl, identity, identity_len, obfuscated_ticket_age,
- session) == SSL_TLS1_3_OFFERED_PSK_MATCH) {
- ssl->handshake->resume = 1;
+ ret = ssl_tls13_offered_psks_check_identity_match_ticket(
+ ssl, identity, identity_len, obfuscated_ticket_age, session);
+ if (ret == SSL_TLS1_3_PSK_IDENTITY_MATCH) {
*psk_type = MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION;
ret = mbedtls_ssl_set_hs_psk(ssl,
session->resumption_key,
@@ -294,7 +360,9 @@
session->resumption_key_len);
MBEDTLS_SSL_DEBUG_MSG(4, ("ticket: obfuscated_ticket_age: %u",
(unsigned) obfuscated_ticket_age));
- return SSL_TLS1_3_OFFERED_PSK_MATCH;
+ return SSL_TLS1_3_PSK_IDENTITY_MATCH;
+ } else if (ret == SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE) {
+ return SSL_TLS1_3_PSK_IDENTITY_MATCH_BUT_PSK_NOT_USABLE;
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
@@ -302,9 +370,9 @@
if (ssl->conf->f_psk != NULL) {
if (ssl->conf->f_psk(
ssl->conf->p_psk, ssl, identity, identity_len) == 0) {
- return SSL_TLS1_3_OFFERED_PSK_MATCH;
+ return SSL_TLS1_3_PSK_IDENTITY_MATCH;
}
- return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH;
+ return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
}
MBEDTLS_SSL_DEBUG_BUF(5, "identity", identity, identity_len);
@@ -318,12 +386,20 @@
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret);
return ret;
}
- return SSL_TLS1_3_OFFERED_PSK_MATCH;
+ return SSL_TLS1_3_PSK_IDENTITY_MATCH;
}
- return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH;
+ return SSL_TLS1_3_PSK_IDENTITY_DOES_NOT_MATCH;
}
+/*
+ * Non-error return values of ssl_tls13_offered_psks_check_binder_match().
+ * They are positive to not collide with error codes that are negative. Zero
+ * (SSL_TLS1_3_BINDER_MATCH) in case of success as it may be propagated up
+ * by the callers of this function as a generic success condition.
+ */
+#define SSL_TLS1_3_BINDER_DOES_NOT_MATCH 1
+#define SSL_TLS1_3_BINDER_MATCH 0
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_offered_psks_check_binder_match(
mbedtls_ssl_context *ssl,
@@ -368,100 +444,16 @@
MBEDTLS_SSL_DEBUG_BUF(3, "psk binder ( received ): ", binder, binder_len);
if (mbedtls_ct_memcmp(server_computed_binder, binder, binder_len) == 0) {
- return SSL_TLS1_3_OFFERED_PSK_MATCH;
+ return SSL_TLS1_3_BINDER_MATCH;
}
mbedtls_platform_zeroize(server_computed_binder,
sizeof(server_computed_binder));
- return SSL_TLS1_3_OFFERED_PSK_NOT_MATCH;
-}
-
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_select_ciphersuite_for_psk(
- mbedtls_ssl_context *ssl,
- const unsigned char *cipher_suites,
- const unsigned char *cipher_suites_end,
- uint16_t *selected_ciphersuite,
- const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info)
-{
- psa_algorithm_t psk_hash_alg = PSA_ALG_SHA_256;
-
- *selected_ciphersuite = 0;
- *selected_ciphersuite_info = NULL;
-
- /* RFC 8446, page 55.
- *
- * For externally established PSKs, the Hash algorithm MUST be set when the
- * PSK is established or default to SHA-256 if no such algorithm is defined.
- *
- */
-
- /*
- * Search for a matching ciphersuite
- */
- for (const unsigned char *p = cipher_suites;
- p < cipher_suites_end; p += 2) {
- uint16_t cipher_suite;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
-
- cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0);
- ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(ssl,
- cipher_suite);
- if (ciphersuite_info == NULL) {
- continue;
- }
-
- /* MAC of selected ciphersuite MUST be same with PSK binder if exist.
- * Otherwise, client should reject.
- */
- if (psk_hash_alg ==
- mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac)) {
- *selected_ciphersuite = cipher_suite;
- *selected_ciphersuite_info = ciphersuite_info;
- return 0;
- }
- }
- MBEDTLS_SSL_DEBUG_MSG(2, ("No matched ciphersuite"));
- return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
+ return SSL_TLS1_3_BINDER_DOES_NOT_MATCH;
}
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_select_ciphersuite_for_resumption(
- mbedtls_ssl_context *ssl,
- const unsigned char *cipher_suites,
- const unsigned char *cipher_suites_end,
- mbedtls_ssl_session *session,
- uint16_t *selected_ciphersuite,
- const mbedtls_ssl_ciphersuite_t **selected_ciphersuite_info)
-{
-
- *selected_ciphersuite = 0;
- *selected_ciphersuite_info = NULL;
- for (const unsigned char *p = cipher_suites; p < cipher_suites_end; p += 2) {
- uint16_t cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0);
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
-
- if (cipher_suite != session->ciphersuite) {
- continue;
- }
-
- ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(ssl,
- cipher_suite);
- if (ciphersuite_info == NULL) {
- continue;
- }
-
- *selected_ciphersuite = cipher_suite;
- *selected_ciphersuite_info = ciphersuite_info;
-
- return 0;
- }
-
- return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
-}
-
-MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_session_copy_ticket(mbedtls_ssl_session *dst,
const mbedtls_ssl_session *src)
{
@@ -481,6 +473,13 @@
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+struct psk_attributes {
+ int type;
+ int key_exchange_mode;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+};
+#define PSK_ATTRIBUTES_INIT { 0, 0, NULL }
+
/* Parser for pre_shared_key extension in client hello
* struct {
* opaque identity<1..2^16-1>;
@@ -507,7 +506,8 @@
const unsigned char *pre_shared_key_ext,
const unsigned char *pre_shared_key_ext_end,
const unsigned char *ciphersuites,
- const unsigned char *ciphersuites_end)
+ const unsigned char *ciphersuites_end,
+ struct psk_attributes *psk)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *identities = pre_shared_key_ext;
@@ -558,9 +558,10 @@
uint32_t obfuscated_ticket_age;
const unsigned char *binder;
size_t binder_len;
- int psk_type;
- uint16_t cipher_suite;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+ int psk_ciphersuite_id;
+ psa_algorithm_t psk_hash_alg;
+ int allowed_key_exchange_modes;
+
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
mbedtls_ssl_session session;
mbedtls_ssl_session_init(&session);
@@ -586,47 +587,74 @@
ret = ssl_tls13_offered_psks_check_identity_match(
ssl, identity, identity_len, obfuscated_ticket_age,
- &psk_type, &session);
- if (ret != SSL_TLS1_3_OFFERED_PSK_MATCH) {
+ &psk->type, &session);
+ if (ret != SSL_TLS1_3_PSK_IDENTITY_MATCH) {
continue;
}
MBEDTLS_SSL_DEBUG_MSG(4, ("found matched identity"));
- switch (psk_type) {
+
+ switch (psk->type) {
case MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL:
- ret = ssl_tls13_select_ciphersuite_for_psk(
- ssl, ciphersuites, ciphersuites_end,
- &cipher_suite, &ciphersuite_info);
+ psk_ciphersuite_id = 0;
+ psk_hash_alg = PSA_ALG_SHA_256;
+ allowed_key_exchange_modes =
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
break;
- case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION:
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- ret = ssl_tls13_select_ciphersuite_for_resumption(
- ssl, ciphersuites, ciphersuites_end, &session,
- &cipher_suite, &ciphersuite_info);
- if (ret != 0) {
- mbedtls_ssl_session_free(&session);
- }
-#else
- ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
-#endif
+ case MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION:
+ psk_ciphersuite_id = session.ciphersuite;
+ psk_hash_alg = PSA_ALG_NONE;
+ ssl->session_negotiate->ticket_flags = session.ticket_flags;
+ allowed_key_exchange_modes =
+ session.ticket_flags &
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
break;
+#endif
default:
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
- if (ret != 0) {
- /* See below, no cipher_suite available, abort handshake */
+
+ psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
+
+ if ((allowed_key_exchange_modes &
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) &&
+ ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
+ psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
+ } else if ((allowed_key_exchange_modes &
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) &&
+ ssl_tls13_key_exchange_is_psk_available(ssl)) {
+ psk->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
+ }
+
+ if (psk->key_exchange_mode == MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE) {
+ MBEDTLS_SSL_DEBUG_MSG(3, ("No suitable PSK key exchange mode"));
+ continue;
+ }
+
+ ssl_tls13_select_ciphersuite(ssl, ciphersuites, ciphersuites_end,
+ psk_ciphersuite_id, psk_hash_alg,
+ &psk->ciphersuite_info);
+
+ if (psk->ciphersuite_info == NULL) {
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ mbedtls_ssl_session_free(&session);
+#endif
+ /*
+ * We consider finding a ciphersuite suitable for the PSK as part
+ * of the validation of its binder. Thus if we do not find one, we
+ * abort the handshake with a decrypt_error alert.
+ */
MBEDTLS_SSL_PEND_FATAL_ALERT(
MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR,
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
- MBEDTLS_SSL_DEBUG_RET(
- 2, "ssl_tls13_select_ciphersuite", ret);
- return ret;
+ return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
ret = ssl_tls13_offered_psks_check_binder_match(
- ssl, binder, binder_len, psk_type,
- mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac));
- if (ret != SSL_TLS1_3_OFFERED_PSK_MATCH) {
+ ssl, binder, binder_len, psk->type,
+ mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) psk->ciphersuite_info->mac));
+ if (ret != SSL_TLS1_3_BINDER_MATCH) {
/* For security reasons, the handshake should be aborted when we
* fail to validate a binder value. See RFC 8446 section 4.2.11.2
* and appendix E.6. */
@@ -644,13 +672,8 @@
matched_identity = identity_id;
- /* Update handshake parameters */
- ssl->handshake->ciphersuite_info = ciphersuite_info;
- ssl->session_negotiate->ciphersuite = cipher_suite;
- MBEDTLS_SSL_DEBUG_MSG(2, ("overwrite ciphersuite: %04x - %s",
- cipher_suite, ciphersuite_info->name));
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- if (psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) {
+ if (psk->type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) {
ret = ssl_tls13_session_copy_ticket(ssl->session_negotiate,
&session);
mbedtls_ssl_session_free(&session);
@@ -676,7 +699,7 @@
return ret;
}
if (matched_identity == -1) {
- MBEDTLS_SSL_DEBUG_MSG(3, ("No matched PSK or ticket."));
+ MBEDTLS_SSL_DEBUG_MSG(3, ("No usable PSK or ticket."));
return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
}
@@ -1003,21 +1026,29 @@
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_ticket_is_kex_mode_permitted(mbedtls_ssl_context *ssl,
- unsigned int kex_mode)
+static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl)
{
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- if (ssl->handshake->resume) {
- if (!mbedtls_ssl_tls13_session_ticket_has_flags(
- ssl->session_negotiate, kex_mode)) {
- return 0;
- }
- }
+#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
+ return mbedtls_ssl_conf_tls13_is_psk_enabled(ssl) &&
+ mbedtls_ssl_tls13_is_psk_supported(ssl) &&
+ ssl_tls13_client_hello_has_exts_for_psk_key_exchange(ssl);
#else
((void) ssl);
- ((void) kex_mode);
+ return 0;
#endif
- return 1;
+}
+
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl)
+{
+#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
+ return mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(ssl) &&
+ mbedtls_ssl_tls13_is_psk_ephemeral_supported(ssl) &&
+ ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(ssl);
+#else
+ ((void) ssl);
+ return 0;
+#endif
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
@@ -1033,83 +1064,6 @@
#endif
}
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_key_exchange_is_psk_available(mbedtls_ssl_context *ssl)
-{
-#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED)
- return ssl_tls13_ticket_is_kex_mode_permitted(
- ssl, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) &&
- mbedtls_ssl_conf_tls13_is_psk_enabled(ssl) &&
- mbedtls_ssl_tls13_is_psk_supported(ssl) &&
- ssl_tls13_client_hello_has_exts_for_psk_key_exchange(ssl);
-#else
- ((void) ssl);
- return 0;
-#endif
-}
-
-MBEDTLS_CHECK_RETURN_CRITICAL
-static int ssl_tls13_key_exchange_is_psk_ephemeral_available(mbedtls_ssl_context *ssl)
-{
-#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED)
- return ssl_tls13_ticket_is_kex_mode_permitted(
- ssl, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL) &&
- mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(ssl) &&
- mbedtls_ssl_tls13_is_psk_ephemeral_supported(ssl) &&
- ssl_tls13_client_hello_has_exts_for_psk_ephemeral_key_exchange(ssl);
-#else
- ((void) ssl);
- return 0;
-#endif
-}
-
-static int ssl_tls13_determine_key_exchange_mode(mbedtls_ssl_context *ssl)
-{
- /*
- * Determine the key exchange algorithm to use.
- * There are three types of key exchanges supported in TLS 1.3:
- * - (EC)DH with ECDSA,
- * - (EC)DH with PSK,
- * - plain PSK.
- *
- * The PSK-based key exchanges may additionally be used with 0-RTT.
- *
- * Our built-in order of preference is
- * 1 ) (EC)DHE-PSK Mode ( psk_ephemeral )
- * 2 ) Certificate Mode ( ephemeral )
- * 3 ) Plain PSK Mode ( psk )
- */
-
- ssl->handshake->key_exchange_mode =
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
-
- if (ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
- ssl->handshake->key_exchange_mode =
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
- MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk_ephemeral"));
- } else
- if (ssl_tls13_key_exchange_is_ephemeral_available(ssl)) {
- ssl->handshake->key_exchange_mode =
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
- MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: ephemeral"));
- } else
- if (ssl_tls13_key_exchange_is_psk_available(ssl)) {
- ssl->handshake->key_exchange_mode =
- MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
- MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk"));
- } else {
- MBEDTLS_SSL_DEBUG_MSG(
- 1,
- ("ClientHello message misses mandatory extensions."));
- MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_MISSING_EXTENSION,
- MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
- return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
- }
-
- return 0;
-
-}
-
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
@@ -1301,6 +1255,8 @@
int no_usable_share_for_key_agreement = 0;
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+ int got_psk = 0;
+ struct psk_attributes psk = PSK_ATTRIBUTES_INIT;
const unsigned char *pre_shared_key_ext = NULL;
const unsigned char *pre_shared_key_ext_end = NULL;
#endif
@@ -1464,37 +1420,20 @@
*/
MBEDTLS_SSL_DEBUG_BUF(3, "client hello, list of cipher suites",
cipher_suites, cipher_suites_len);
- for (const unsigned char *cipher_suites_p = cipher_suites;
- cipher_suites_p < cipher_suites_end; cipher_suites_p += 2) {
- uint16_t cipher_suite;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
- /*
- * "cipher_suites_end - cipher_suites_p is even" is an invariant of the
- * loop. As cipher_suites_end - cipher_suites_p > 0, we have
- * cipher_suites_end - cipher_suites_p >= 2 and it is thus safe to read
- * two bytes.
- */
- cipher_suite = MBEDTLS_GET_UINT16_BE(cipher_suites_p, 0);
- ciphersuite_info = ssl_tls13_validate_peer_ciphersuite(
- ssl, cipher_suite);
- if (ciphersuite_info == NULL) {
- continue;
- }
-
- ssl->session_negotiate->ciphersuite = cipher_suite;
- handshake->ciphersuite_info = ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %04x - %s",
- cipher_suite,
- ciphersuite_info->name));
- break;
- }
+ ssl_tls13_select_ciphersuite(ssl, cipher_suites, cipher_suites_end,
+ 0, PSA_ALG_NONE, &handshake->ciphersuite_info);
if (handshake->ciphersuite_info == NULL) {
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
+ ssl->session_negotiate->ciphersuite = handshake->ciphersuite_info->id;
+
+ MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %04x - %s",
+ ((unsigned) handshake->ciphersuite_info->id),
+ handshake->ciphersuite_info->name));
/* ...
* opaque legacy_compression_methods<1..2^8-1>;
@@ -1734,10 +1673,11 @@
/* Update checksum with either
* - The entire content of the CH message, if no PSK extension is present
* - The content up to but excluding the PSK extension, if present.
+ * Always parse the pre-shared-key extension when present in the
+ * ClientHello even if some pre-requisites for PSK key exchange modes are
+ * not met. That way we always validate the syntax of the extension.
*/
- /* If we've settled on a PSK-based exchange, parse PSK identity ext */
- if (ssl_tls13_key_exchange_is_psk_available(ssl) ||
- ssl_tls13_key_exchange_is_psk_ephemeral_available(ssl)) {
+ if (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY)) {
ret = handshake->update_checksum(ssl, buf,
pre_shared_key_ext - buf);
if (0 != ret) {
@@ -1748,10 +1688,11 @@
pre_shared_key_ext,
pre_shared_key_ext_end,
cipher_suites,
- cipher_suites_end);
- if (ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) {
- handshake->received_extensions &= ~MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY);
- } else if (ret != 0) {
+ cipher_suites_end,
+ &psk);
+ if (ret == 0) {
+ got_psk = 1;
+ } else if (ret != MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) {
MBEDTLS_SSL_DEBUG_RET(
1, "ssl_tls13_parse_pre_shared_key_ext", ret);
return ret;
@@ -1766,12 +1707,68 @@
}
}
- ret = ssl_tls13_determine_key_exchange_mode(ssl);
- if (ret < 0) {
- return ret;
+ /*
+ * Determine the key exchange algorithm to use.
+ * There are three types of key exchanges supported in TLS 1.3:
+ * - (EC)DH with ECDSA,
+ * - (EC)DH with PSK,
+ * - plain PSK.
+ *
+ * The PSK-based key exchanges may additionally be used with 0-RTT.
+ *
+ * Our built-in order of preference is
+ * 1 ) (EC)DHE-PSK Mode ( psk_ephemeral )
+ * 2 ) Certificate Mode ( ephemeral )
+ * 3 ) Plain PSK Mode ( psk )
+ */
+#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+ if (got_psk && (psk.key_exchange_mode ==
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL)) {
+ handshake->key_exchange_mode =
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
+ MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk_ephemeral"));
+
+ } else
+#endif
+ if (ssl_tls13_key_exchange_is_ephemeral_available(ssl)) {
+ handshake->key_exchange_mode =
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
+ MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: ephemeral"));
+
+ }
+#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+ else if (got_psk && (psk.key_exchange_mode ==
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK)) {
+ handshake->key_exchange_mode = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
+ MBEDTLS_SSL_DEBUG_MSG(2, ("key exchange mode: psk"));
+ }
+#endif
+ else {
+ MBEDTLS_SSL_DEBUG_MSG(
+ 1,
+ ("ClientHello message misses mandatory extensions."));
+ MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_MISSING_EXTENSION,
+ MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
+ return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
- if (ssl->handshake->key_exchange_mode !=
+#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
+ if (handshake->key_exchange_mode &
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL) {
+ handshake->ciphersuite_info = psk.ciphersuite_info;
+ ssl->session_negotiate->ciphersuite = psk.ciphersuite_info->id;
+
+ MBEDTLS_SSL_DEBUG_MSG(2, ("Select PSK ciphersuite: %04x - %s",
+ ((unsigned) psk.ciphersuite_info->id),
+ psk.ciphersuite_info->name));
+
+ if (psk.type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) {
+ handshake->resume = 1;
+ }
+ }
+#endif
+
+ if (handshake->key_exchange_mode !=
MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) {
hrr_required = (no_usable_share_for_key_agreement != 0);
}
@@ -1973,10 +1970,6 @@
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *server_randbytes =
ssl->handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN;
- if (ssl->conf->f_rng == NULL) {
- MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
- return MBEDTLS_ERR_SSL_NO_RNG;
- }
if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, server_randbytes,
MBEDTLS_SERVER_HELLO_RANDOM_LEN)) != 0) {
@@ -2913,17 +2906,14 @@
}
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.
- */
if (ssl->in_offt == NULL) {
+ MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
/* Set the reading pointer */
ssl->in_offt = ssl->in_msg;
+ ret = mbedtls_ssl_tls13_check_early_data_len(ssl, ssl->in_msglen);
+ if (ret != 0) {
+ return ret;
+ }
}
return SSL_GOT_EARLY_DATA;
}
@@ -3141,6 +3131,7 @@
ssl->conf->max_early_data_size > 0) {
mbedtls_ssl_tls13_session_set_ticket_flags(
session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA);
+ session->max_early_data_size = ssl->conf->max_early_data_size;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 7f0160a..2fd56fb 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -3290,4 +3290,12 @@
}
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt)
+{
+ if ((crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS) != 0) {
+ return crt->MBEDTLS_PRIVATE(ca_istrue);
+ }
+ return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
+}
+
#endif /* MBEDTLS_X509_CRT_PARSE_C */
diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja
index 4f9764d..8b91f0b 100644
--- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja
+++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja
@@ -122,7 +122,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -196,7 +196,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -266,7 +266,7 @@
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
if( drv->asymmetric == NULL ||
drv->asymmetric->p_sign == NULL )
@@ -283,7 +283,7 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -306,11 +306,11 @@
return( status );
#endif /* PSA_CRYPTO_DRIVER_TEST */
#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED)
- if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
+ if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
PSA_ALG_IS_ECDSA(alg) &&
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
- PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 &&
- attributes->core.bits == 256 )
+ PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
+ psa_get_key_bits(attributes) == 256 )
{
status = p256_transparent_sign_hash( attributes,
key_buffer,
@@ -370,7 +370,7 @@
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
if( drv->asymmetric == NULL ||
drv->asymmetric->p_verify == NULL )
@@ -387,7 +387,7 @@
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -410,11 +410,11 @@
return( status );
#endif /* PSA_CRYPTO_DRIVER_TEST */
#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED)
- if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
+ if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
PSA_ALG_IS_ECDSA(alg) &&
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
- PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 &&
- attributes->core.bits == 256 )
+ PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
+ psa_get_key_bits(attributes) == 256 )
{
status = p256_transparent_verify_hash( attributes,
key_buffer,
@@ -517,7 +517,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(
- attributes->core.lifetime );
+ psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -609,7 +609,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(
- attributes->core.lifetime );
+ psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -707,8 +707,8 @@
size_t *key_buffer_size )
{
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
- psa_key_type_t key_type = attributes->core.type;
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
+ psa_key_type_t key_type = psa_get_key_type(attributes);
*key_buffer_size = 0;
switch( location )
@@ -736,7 +736,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION(attributes->core.lifetime);
+ PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes));
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
int is_default_production =
@@ -757,7 +757,7 @@
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
size_t pubkey_length = 0; /* We don't support this feature yet */
if( drv->key_management == NULL ||
@@ -780,7 +780,7 @@
/* Transparent drivers are limited to generating asymmetric keys. */
/* We don't support passing custom production parameters
* to drivers yet. */
- if( PSA_KEY_TYPE_IS_ASYMMETRIC( attributes->core.type ) &&
+ if( PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type(attributes) ) &&
is_default_production )
{
/* Cycle through all known transparent accelerators */
@@ -793,9 +793,9 @@
break;
#endif /* PSA_CRYPTO_DRIVER_TEST */
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
- if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
- attributes->core.type == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1) &&
- attributes->core.bits == 256 )
+ if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
+ psa_get_key_type(attributes) == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1) &&
+ psa_get_key_bits(attributes) == 256 )
{
status = p256_transparent_generate_key( attributes,
key_buffer,
@@ -862,7 +862,7 @@
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
if( drv->key_management == NULL ||
drv->key_management->p_import == NULL )
@@ -939,7 +939,7 @@
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
if( ( drv->key_management == NULL ) ||
( drv->key_management->p_export == NULL ) )
@@ -994,13 +994,13 @@
{% endmacro %}
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
/* Copying to a secure element is not implemented yet. */
return( PSA_ERROR_NOT_SUPPORTED );
@@ -1044,7 +1044,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1134,7 +1134,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1211,7 +1211,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1284,7 +1284,7 @@
{
psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1684,7 +1684,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1736,7 +1736,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1785,7 +1785,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -1833,7 +1833,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2169,7 +2169,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2233,7 +2233,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2305,7 +2305,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2505,7 +2505,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2563,7 +2563,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2627,7 +2627,7 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_location_t location =
- PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
@@ -2645,10 +2645,10 @@
return( status );
#endif /* PSA_CRYPTO_DRIVER_TEST */
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
- if( PSA_KEY_TYPE_IS_ECC( attributes->core.type ) &&
+ if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
PSA_ALG_IS_ECDH(alg) &&
- PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) == PSA_ECC_FAMILY_SECP_R1 &&
- attributes->core.bits == 256 )
+ PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
+ psa_get_key_bits(attributes) == 256 )
{
status = p256_transparent_key_agreement( attributes,
key_buffer,
diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja
index 2aae628..261cd2a 100644
--- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja
+++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja
@@ -88,9 +88,9 @@
const psa_key_attributes_t *attributes,
size_t *key_buffer_size )
{
- psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
- psa_key_type_t key_type = attributes->core.type;
- size_t key_bits = attributes->core.bits;
+ psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
+ psa_key_type_t key_type = psa_get_key_type(attributes);
+ size_t key_bits = psa_get_key_bits(attributes);
*key_buffer_size = 0;
switch( location )
@@ -144,7 +144,7 @@
const psa_drv_se_t *drv;
psa_drv_se_context_t *drv_context;
- if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
+ if( psa_get_se_driver( psa_get_key_lifetime(attributes), &drv, &drv_context ) )
{
if( ( drv->key_management == NULL ) ||
( drv->key_management->p_export_public == NULL ) )
@@ -203,7 +203,7 @@
key_buffer_size,
key_buffer_length
{% endmacro %}
- psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
+ psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( psa_get_key_lifetime(attributes) );
switch( location )
{
#if defined(PSA_CRYPTO_DRIVER_TEST)
diff --git a/tests/include/test/drivers/config_test_driver.h b/tests/include/test/drivers/config_test_driver.h
index 4eb27f0..ec8bcb6 100644
--- a/tests/include/test/drivers/config_test_driver.h
+++ b/tests/include/test/drivers/config_test_driver.h
@@ -40,5 +40,7 @@
//#define MBEDTLS_MD_C
//#define MBEDTLS_PEM_PARSE_C
//#define MBEDTLS_BASE64_C
+//#define MBEDTLS_THREADING_C
+//#define MBEDTLS_THREADING_PTHREAD
#endif /* MBEDTLS_CONFIG_H */
diff --git a/tests/include/test/ssl_helpers.h b/tests/include/test/ssl_helpers.h
index 5b071f7..335386b 100644
--- a/tests/include/test/ssl_helpers.h
+++ b/tests/include/test/ssl_helpers.h
@@ -114,6 +114,7 @@
void (*cli_log_fun)(void *, int, const char *, int, const char *);
int resize_buffers;
int early_data;
+ int max_early_data_size;
#if defined(MBEDTLS_SSL_CACHE_C)
mbedtls_ssl_cache_context *cache;
#endif
@@ -196,6 +197,13 @@
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
/*
+ * Random number generator aimed for TLS unitary tests. Its main purpose is to
+ * simplify the set-up of a random number generator for TLS
+ * unitary tests: no need to set up a good entropy source for example.
+ */
+int mbedtls_test_random(void *p_rng, unsigned char *output, size_t output_len);
+
+/*
* This function can be passed to mbedtls to receive output logs from it. In
* this case, it will count the instances of a mbedtls_test_ssl_log_pattern
* in the received logged messages.
diff --git a/tests/opt-testcases/tls13-kex-modes.sh b/tests/opt-testcases/tls13-kex-modes.sh
index 4581bc5..49f06e0 100755
--- a/tests/opt-testcases/tls13-kex-modes.sh
+++ b/tests/opt-testcases/tls13-kex-modes.sh
@@ -23,7 +23,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-s "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -41,7 +41,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -78,7 +78,7 @@
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-s "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -96,7 +96,7 @@
-s "found pre_shared_key extension" \
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -133,7 +133,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -151,7 +151,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -188,7 +188,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -206,7 +206,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -261,7 +261,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -280,7 +280,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -319,7 +319,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -338,7 +338,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -377,7 +377,7 @@
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-s "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -396,7 +396,7 @@
-s "found pre_shared_key extension" \
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -435,7 +435,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -454,7 +454,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -493,7 +493,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -512,7 +512,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -550,8 +550,9 @@
-s "found pre_shared_key extension" \
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
+ -s "No suitable PSK key exchange mode" \
-S "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -572,7 +573,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -592,7 +593,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -633,7 +634,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -653,7 +654,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -694,7 +695,7 @@
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -733,8 +734,9 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
+ -s "No suitable PSK key exchange mode" \
-S "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -754,7 +756,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -793,7 +795,7 @@
-S "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -921,7 +923,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-s "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -938,7 +940,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -973,7 +975,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -990,7 +992,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1025,7 +1027,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1042,7 +1044,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1078,7 +1080,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1096,7 +1098,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1133,7 +1135,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1151,7 +1153,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1188,7 +1190,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1206,7 +1208,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -1243,7 +1245,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1261,7 +1263,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -1299,7 +1301,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1318,7 +1320,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -1357,7 +1359,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-s "key exchange mode: psk_ephemeral" \
-S "key exchange mode: ephemeral"
@@ -1376,7 +1378,7 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -1413,8 +1415,9 @@
-s "found pre_shared_key extension" \
-s "Found PSK_EPHEMERAL KEX MODE" \
-S "Found PSK KEX MODE" \
+ -s "No suitable PSK key exchange mode" \
-S "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -1433,7 +1436,7 @@
-s "Found PSK_EPHEMERAL KEX MODE" \
-s "Found PSK KEX MODE" \
-s "Pre shared key found" \
- -S "No matched PSK or ticket" \
+ -S "No usable PSK or ticket" \
-S "key exchange mode: psk$" \
-S "key exchange mode: psk_ephemeral" \
-s "key exchange mode: ephemeral"
@@ -1580,7 +1583,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket"
+ -s "No usable PSK or ticket"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -1665,7 +1668,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -1711,7 +1714,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -1769,7 +1772,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -1827,7 +1830,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket"
+ -s "No usable PSK or ticket"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -1870,7 +1873,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -1916,7 +1919,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -2047,7 +2050,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket"
+ -s "No usable PSK or ticket"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -2106,7 +2109,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "key exchange mode: ephemeral"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2152,7 +2155,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2199,7 +2202,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "key exchange mode: ephemeral"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2288,7 +2291,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2348,7 +2351,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket"
+ -s "No usable PSK or ticket"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -2392,7 +2395,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2438,7 +2441,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket"
+ -s "No usable PSK or ticket"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
requires_config_enabled MBEDTLS_SSL_SRV_C
@@ -2485,7 +2488,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2532,7 +2535,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2595,7 +2598,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-c "Selected key exchange mode: ephemeral" \
-c "HTTP/1.0 200 OK"
@@ -2643,7 +2646,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "ClientHello message misses mandatory extensions."
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
@@ -2690,7 +2693,7 @@
-c "client hello, adding pre_shared_key extension, omitting PSK binder list" \
-c "client hello, adding psk_key_exchange_modes extension" \
-c "client hello, adding PSK binder list" \
- -s "No matched PSK or ticket" \
+ -s "No usable PSK or ticket" \
-s "key exchange mode: ephemeral"
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
diff --git a/tests/opt-testcases/tls13-misc.sh b/tests/opt-testcases/tls13-misc.sh
index ad062dc..066fa3f 100755
--- a/tests/opt-testcases/tls13-misc.sh
+++ b/tests/opt-testcases/tls13-misc.sh
@@ -353,8 +353,8 @@
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
- -s "No suitable key exchange mode" \
- -s "No matched PSK or ticket"
+ -s "No suitable PSK key exchange mode" \
+ -s "No usable PSK or ticket"
requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
@@ -365,7 +365,7 @@
"$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
+ -S "No suitable PSK key exchange mode" \
-s "found matched identity"
requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
@@ -381,8 +381,8 @@
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
- -s "No suitable key exchange mode" \
- -s "No matched PSK or ticket"
+ -s "No suitable PSK key exchange mode" \
+ -s "No usable PSK or ticket"
requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
@@ -393,7 +393,7 @@
"$P_CLI debug_level=4 tls13_kex_modes=psk_or_ephemeral reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
+ -S "No suitable PSK key exchange mode" \
-s "found matched identity"
requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
@@ -409,8 +409,8 @@
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
- -s "No suitable key exchange mode" \
- -s "No matched PSK or ticket"
+ -s "No suitable PSK key exchange mode" \
+ -s "No usable PSK or ticket"
requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
@@ -425,8 +425,8 @@
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
- -s "No suitable key exchange mode" \
- -s "No matched PSK or ticket"
+ -s "No suitable PSK key exchange mode" \
+ -s "No usable PSK or ticket"
requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
@@ -437,7 +437,7 @@
"$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
+ -S "No suitable PSK key exchange mode" \
-s "found matched identity" \
-s "key exchange mode: psk_ephemeral"
@@ -450,7 +450,7 @@
"$P_CLI debug_level=4 tls13_kex_modes=ephemeral_all reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
+ -S "No suitable PSK key exchange mode" \
-s "found matched identity" \
-s "key exchange mode: psk_ephemeral"
@@ -468,8 +468,8 @@
-s "key exchange mode: ephemeral" \
-S "key exchange mode: psk_ephemeral" \
-S "key exchange mode: psk$" \
- -s "No suitable key exchange mode" \
- -s "No matched PSK or ticket"
+ -s "No suitable PSK key exchange mode" \
+ -s "No usable PSK or ticket"
requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
MBEDTLS_SSL_SRV_C MBEDTLS_SSL_CLI_C MBEDTLS_DEBUG_C \
@@ -481,7 +481,7 @@
"$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
+ -S "No suitable PSK key exchange mode" \
-s "found matched identity"
requires_all_configs_enabled MBEDTLS_SSL_SESSION_TICKETS \
@@ -494,7 +494,7 @@
"$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
+ -S "No suitable PSK key exchange mode" \
-s "found matched identity" \
-s "key exchange mode: psk_ephemeral"
@@ -508,7 +508,7 @@
"$P_CLI debug_level=4 tls13_kex_modes=all reconnect=1" \
0 \
-c "Pre-configured PSK number = 1" \
- -S "No suitable key exchange mode" \
+ -S "No suitable PSK key exchange mode" \
-s "found matched identity" \
-s "key exchange mode: psk_ephemeral"
@@ -535,3 +535,18 @@
-s "$( tail -1 $EARLY_DATA_INPUT )" \
-s "200 early data bytes read" \
-s "106 early data bytes read"
+
+requires_all_configs_enabled MBEDTLS_SSL_EARLY_DATA MBEDTLS_SSL_SESSION_TICKETS \
+ MBEDTLS_SSL_CLI_C MBEDTLS_SSL_SRV_C \
+ MBEDTLS_DEBUG_C MBEDTLS_HAVE_TIME \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED \
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "TLS 1.3 m->m: Ephemeral over PSK kex with early data enabled" \
+ "$P_SRV force_version=tls13 debug_level=4 max_early_data_size=1024" \
+ "$P_CLI debug_level=4 early_data=1 tls13_kex_modes=psk_or_ephemeral reco_mode=1 reconnect=1" \
+ 0 \
+ -s "key exchange mode: ephemeral" \
+ -S "key exchange mode: psk" \
+ -s "found matched identity" \
+ -s "EarlyData: rejected, not a session resumption" \
+ -C "EncryptedExtensions: early_data(42) extension exists."
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index c25f044..9191f65 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -212,10 +212,21 @@
# defined in this script whose name starts with "component_".
ALL_COMPONENTS=$(compgen -A function component_ | sed 's/component_//')
- # Delay determinig SUPPORTED_COMPONENTS until the command line options have a chance to override
+ # Delay determining SUPPORTED_COMPONENTS until the command line options have a chance to override
# the commands set by the environment
}
+setup_quiet_wrappers()
+{
+ # Pick up "quiet" wrappers for make and cmake, which don't output very much
+ # unless there is an error. This reduces logging overhead in the CI.
+ #
+ # Note that the cmake wrapper breaks unless we use an absolute path here.
+ if [[ -e ${PWD}/tests/scripts/quiet ]]; then
+ export PATH=${PWD}/tests/scripts/quiet:$PATH
+ fi
+}
+
# Test whether the component $1 is included in the command line patterns.
is_component_included()
{
@@ -889,6 +900,16 @@
# Dynamic secure element support is a deprecated feature and needs to be disabled here.
# This is done to have the same form of psa_key_attributes_s for libdriver and library.
scripts/config.py unset MBEDTLS_PSA_CRYPTO_SE_C
+
+ # If threading is enabled on the normal build, then we need to enable it in the drivers as well,
+ # otherwise we will end up running multithreaded tests without mutexes to protect them.
+ if scripts/config.py get MBEDTLS_THREADING_C; then
+ scripts/config.py -f "$CONFIG_TEST_DRIVER_H" set MBEDTLS_THREADING_C
+ fi
+
+ if scripts/config.py get MBEDTLS_THREADING_PTHREAD; then
+ scripts/config.py -f "$CONFIG_TEST_DRIVER_H" set MBEDTLS_THREADING_PTHREAD
+ fi
}
# When called with no parameter this function disables all builtin curves.
@@ -1089,6 +1110,8 @@
echo "MBEDTLS_ECP_RESTARTABLE" >> $expected
# No PSA equivalent - needed by some init tests
echo "MBEDTLS_ENTROPY_NV_SEED" >> $expected
+ # No PSA equivalent - required to run threaded tests.
+ echo "MBEDTLS_THREADING_PTHREAD" >> $expected
# Compare reality with expectation.
# We want an exact match, to ensure the above list remains up-to-date.
@@ -2177,6 +2200,8 @@
scripts/config.py full
scripts/config.py set MBEDTLS_THREADING_C
scripts/config.py set MBEDTLS_THREADING_PTHREAD
+ # Self-tests do not currently use multiple threads.
+ scripts/config.py unset MBEDTLS_SELF_TEST
CC=clang cmake -D CMAKE_BUILD_TYPE:String=TSan .
make
@@ -6353,6 +6378,7 @@
pre_initialize_variables
pre_parse_command_line "$@"
+setup_quiet_wrappers
pre_check_git
pre_restore_files
pre_back_up
diff --git a/tests/scripts/check_files.py b/tests/scripts/check_files.py
index 65fbc9f..4483f55 100755
--- a/tests/scripts/check_files.py
+++ b/tests/scripts/check_files.py
@@ -173,6 +173,8 @@
b'sh': 'sh',
}
+ path_exemptions = re.compile(r'tests/scripts/quiet/.*')
+
def is_valid_shebang(self, first_line, filepath):
m = re.match(self._shebang_re, first_line)
if not m:
diff --git a/tests/scripts/quiet/cmake b/tests/scripts/quiet/cmake
new file mode 100755
index 0000000..930931d
--- /dev/null
+++ b/tests/scripts/quiet/cmake
@@ -0,0 +1,19 @@
+#! /usr/bin/env bash
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# This swallows the output of the wrapped tool, unless there is an error.
+# This helps reduce excess logging in the CI.
+
+# If you are debugging a build / CI issue, you can get complete unsilenced logs
+# by un-commenting the following line (or setting VERBOSE_LOGS in your environment):
+
+# export VERBOSE_LOGS=1
+
+# don't silence invocations containing these arguments
+export NO_SILENCE=" --version "
+
+export TOOL="cmake"
+
+exec "$(dirname "$0")/quiet.sh" "$@"
diff --git a/tests/scripts/quiet/make b/tests/scripts/quiet/make
new file mode 100755
index 0000000..d022551
--- /dev/null
+++ b/tests/scripts/quiet/make
@@ -0,0 +1,19 @@
+#! /usr/bin/env bash
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# This swallows the output of the wrapped tool, unless there is an error.
+# This helps reduce excess logging in the CI.
+
+# If you are debugging a build / CI issue, you can get complete unsilenced logs
+# by un-commenting the following line (or setting VERBOSE_LOGS in your environment):
+
+# export VERBOSE_LOGS=1
+
+# don't silence invocations containing these arguments
+export NO_SILENCE=" --version | test "
+
+export TOOL="make"
+
+exec "$(dirname "$0")/quiet.sh" "$@"
diff --git a/tests/scripts/quiet/quiet.sh b/tests/scripts/quiet/quiet.sh
new file mode 100755
index 0000000..30ee569
--- /dev/null
+++ b/tests/scripts/quiet/quiet.sh
@@ -0,0 +1,75 @@
+# -*-mode: sh; sh-shell: bash -*-
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+#
+# This swallows the output of the wrapped tool, unless there is an error.
+# This helps reduce excess logging in the CI.
+
+# If you are debugging a build / CI issue, you can get complete unsilenced logs
+# by un-commenting the following line (or setting VERBOSE_LOGS in your environment):
+#
+# VERBOSE_LOGS=1
+#
+# This script provides most of the functionality for the adjacent make and cmake
+# wrappers.
+#
+# It requires two variables to be set:
+#
+# TOOL - the name of the tool that is being wrapped (with no path), e.g. "make"
+#
+# NO_SILENCE - a regex that describes the commandline arguments for which output will not
+# be silenced, e.g. " --version | test ". In this example, "make lib test" will
+# not be silent, but "make lib" will be.
+
+# Locate original tool
+TOOL_WITH_PATH=$(dirname "$0")/$TOOL
+ORIGINAL_TOOL=$(type -ap "${TOOL}" | grep -v -Fx "$TOOL_WITH_PATH" | head -n1)
+
+print_quoted_args() {
+ # similar to printf '%q' "$@"
+ # but produce more human-readable results for common/simple cases like "a b"
+ for a in "$@"; do
+ # Get bash to quote the string
+ printf -v q '%q' "$a"
+ simple_pattern="^([-[:alnum:]_+./:@]+=)?([^']*)$"
+ if [[ "$a" != "$q" && $a =~ $simple_pattern ]]; then
+ # a requires some quoting (a != q), but has no single quotes, so we can
+ # simplify the quoted form - e.g.:
+ # a b -> 'a b'
+ # CFLAGS=a b -> CFLAGS='a b'
+ q="${BASH_REMATCH[1]}'${BASH_REMATCH[2]}'"
+ fi
+ printf " %s" "$q"
+ done
+}
+
+if [[ ! " $* " =~ " --version " ]]; then
+ # Display the command being invoked - if it succeeds, this is all that will
+ # be displayed. Don't do this for invocations with --version, because
+ # this output is often parsed by scripts, so we don't want to modify it.
+ printf %s "${TOOL}" 1>&2
+ print_quoted_args "$@" 1>&2
+ echo 1>&2
+fi
+
+if [[ " $@ " =~ $NO_SILENCE || -n "${VERBOSE_LOGS}" ]]; then
+ # Run original command with no output supression
+ exec "${ORIGINAL_TOOL}" "$@"
+else
+ # Run original command and capture output & exit status
+ TMPFILE=$(mktemp "quiet-${TOOL}.XXXXXX")
+ "${ORIGINAL_TOOL}" "$@" > "${TMPFILE}" 2>&1
+ EXIT_STATUS=$?
+
+ if [[ $EXIT_STATUS -ne 0 ]]; then
+ # On error, display the full output
+ cat "${TMPFILE}"
+ fi
+
+ # Remove tmpfile
+ rm "${TMPFILE}"
+
+ # Propagate the exit status
+ exit $EXIT_STATUS
+fi
diff --git a/tests/src/drivers/test_driver_signature.c b/tests/src/drivers/test_driver_signature.c
index 00dd3e2..4fca5d1 100644
--- a/tests/src/drivers/test_driver_signature.c
+++ b/tests/src/drivers/test_driver_signature.c
@@ -49,7 +49,7 @@
size_t signature_size,
size_t *signature_length)
{
- if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
+ if (attributes->type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
PSA_ALG_IS_RSA_PSS(alg)) {
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
@@ -71,7 +71,7 @@
} else {
return PSA_ERROR_INVALID_ARGUMENT;
}
- } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
+ } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) {
if (PSA_ALG_IS_ECDSA(alg)) {
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
(defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
@@ -116,7 +116,7 @@
const uint8_t *signature,
size_t signature_length)
{
- if (PSA_KEY_TYPE_IS_RSA(attributes->core.type)) {
+ if (PSA_KEY_TYPE_IS_RSA(attributes->type)) {
if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
PSA_ALG_IS_RSA_PSS(alg)) {
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
@@ -138,7 +138,7 @@
} else {
return PSA_ERROR_INVALID_ARGUMENT;
}
- } else if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) {
+ } else if (PSA_KEY_TYPE_IS_ECC(attributes->type)) {
if (PSA_ALG_IS_ECDSA(alg)) {
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
(defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
diff --git a/tests/src/psa_crypto_stubs.c b/tests/src/psa_crypto_stubs.c
new file mode 100644
index 0000000..f3ca850
--- /dev/null
+++ b/tests/src/psa_crypto_stubs.c
@@ -0,0 +1,25 @@
+/** \file psa_crypto_stubs.c
+ *
+ * \brief Stub functions when MBEDTLS_PSA_CRYPTO_CLIENT is enabled but
+ * MBEDTLS_PSA_CRYPTO_C is disabled.
+ */
+
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#include <psa/crypto.h>
+
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
+
+psa_status_t psa_generate_random(uint8_t *output,
+ size_t output_size)
+{
+ (void) output;
+ (void) output_size;
+
+ return PSA_ERROR_COMMUNICATION_FAILURE;
+}
+
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT && !MBEDTLS_PSA_CRYPTO_C */
diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c
index 5d4cb1c..56e03f1 100644
--- a/tests/src/test_helpers/ssl_helpers.c
+++ b/tests/src/test_helpers/ssl_helpers.c
@@ -12,9 +12,7 @@
#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_SSL_TLS_C)
-#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
-static int rng_seed = 0xBEEF;
-static int rng_get(void *p_rng, unsigned char *output, size_t output_len)
+int mbedtls_test_random(void *p_rng, unsigned char *output, size_t output_len)
{
(void) p_rng;
for (size_t i = 0; i < output_len; i++) {
@@ -23,7 +21,6 @@
return 0;
}
-#endif
void mbedtls_test_ssl_log_analyzer(void *ctx, int level,
const char *file, int line,
@@ -46,6 +43,8 @@
mbedtls_test_handshake_test_options *opts)
{
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
+ static int rng_seed = 0xBEEF;
+
srand(rng_seed);
rng_seed += 0xD0;
#endif
@@ -68,6 +67,7 @@
opts->legacy_renegotiation = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION;
opts->resize_buffers = 1;
opts->early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
+ opts->max_early_data_size = -1;
#if defined(MBEDTLS_SSL_CACHE_C)
TEST_CALLOC(opts->cache, 1);
mbedtls_ssl_cache_init(opts->cache);
@@ -755,7 +755,7 @@
mbedtls_ssl_init(&(ep->ssl));
mbedtls_ssl_config_init(&(ep->conf));
- mbedtls_ssl_conf_rng(&(ep->conf), rng_get, NULL);
+ mbedtls_ssl_conf_rng(&(ep->conf), mbedtls_test_random, NULL);
TEST_ASSERT(mbedtls_ssl_conf_get_user_data_p(&ep->conf) == NULL);
TEST_EQUAL(mbedtls_ssl_conf_get_user_data_n(&ep->conf), 0);
@@ -826,6 +826,13 @@
#if defined(MBEDTLS_SSL_EARLY_DATA)
mbedtls_ssl_conf_early_data(&(ep->conf), options->early_data);
+#if defined(MBEDTLS_SSL_SRV_C)
+ if (endpoint_type == MBEDTLS_SSL_IS_SERVER &&
+ (options->max_early_data_size >= 0)) {
+ mbedtls_ssl_conf_max_early_data_size(&(ep->conf),
+ options->max_early_data_size);
+ }
+#endif
#endif
#if defined(MBEDTLS_SSL_CACHE_C) && defined(MBEDTLS_SSL_SRV_C)
diff --git a/tests/suites/test_suite_bignum.function b/tests/suites/test_suite_bignum.function
index 50be2d2..f3a64e1 100644
--- a/tests/suites/test_suite_bignum.function
+++ b/tests/suites/test_suite_bignum.function
@@ -966,6 +966,45 @@
/* END_CASE */
/* BEGIN_CASE */
+void mpi_exp_mod_min_RR(char *input_A, char *input_E,
+ char *input_N, char *input_X,
+ int exp_result)
+{
+ mbedtls_mpi A, E, N, RR, Z, X;
+ int res;
+ mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
+ mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
+
+ TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
+ TEST_EQUAL(mbedtls_test_read_mpi(&E, input_E), 0);
+ TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
+ TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
+
+ TEST_EQUAL(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N), 0);
+ TEST_EQUAL(mbedtls_mpi_shrink(&RR, 0), 0);
+ /* The objective of this test is to check that exp_mod defends
+ * against a smaller RR. */
+ TEST_LE_U(RR.n, N.n - 1);
+
+ res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
+ /* We know that exp_mod internally needs RR to be as large as N.
+ * Validate that it is the case now, otherwise there was probably
+ * a buffer overread. */
+ TEST_EQUAL(RR.n, N.n);
+
+ TEST_EQUAL(res, exp_result);
+ if (res == 0) {
+ TEST_EQUAL(sign_is_valid(&Z), 1);
+ TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &X), 0);
+ }
+
+exit:
+ mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
+ mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
void mpi_exp_mod(char *input_A, char *input_E,
char *input_N, char *input_X,
int exp_result)
diff --git a/tests/suites/test_suite_bignum.misc.data b/tests/suites/test_suite_bignum.misc.data
index c53e42a..eb55dbe 100644
--- a/tests/suites/test_suite_bignum.misc.data
+++ b/tests/suites/test_suite_bignum.misc.data
@@ -1362,6 +1362,9 @@
Test mbedtls_mpi_exp_mod: 10 ^ 0 (1 limb) mod 9
mpi_exp_mod:"0a":"00":"09":"1":0
+Test mbedtls_mpi_exp_mod: -3 ^ 3 mod 27
+mpi_exp_mod:"-3":"3":"1b":"1b":0
+
Test mbedtls_mpi_exp_mod: MAX_SIZE exponent
mpi_exp_mod_size:2:MBEDTLS_MPI_MAX_SIZE:10:"":0
@@ -1391,6 +1394,14 @@
depends_on:MPI_MAX_BITS_LARGER_THAN_792
mpi_exp_mod:"-9f13012cd92aa72fb86ac8879d2fde4f7fd661aaae43a00971f081cc60ca277059d5c37e89652e2af2585d281d66ef6a9d38a117e9608e9e7574cd142dc55278838a2161dd56db9470d4c1da2d5df15a908ee2eb886aaa890f23be16de59386663a12f1afbb325431a3e835e3fd89b98b96a6f77382f458ef9a37e1f84a03045c8676ab55291a94c2228ea15448ee96b626b998":"40a54d1b9e86789f06d9607fb158672d64867665c73ee9abb545fc7a785634b354c7bae5b962ce8040cf45f2c1f3d3659b2ee5ede17534c8fc2ec85c815e8df1fe7048d12c90ee31b88a68a081f17f0d8ce5f4030521e9400083bcea73a429031d4ca7949c2000d597088e0c39a6014d8bf962b73bb2e8083bd0390a4e00b9b3":"eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3":"21acc7199e1b90f9b4844ffe12c19f00ec548c5d32b21c647d48b6015d8eb9ec9db05b4f3d44db4227a2b5659c1a7cceb9d5fa8fa60376047953ce7397d90aaeb7465e14e820734f84aa52ad0fc66701bcbb991d57715806a11531268e1e83dd48288c72b424a6287e9ce4e5cc4db0dd67614aecc23b0124a5776d36e5c89483":0
+Test mbedtls_mpi_exp_mod (N.n=3, RR.n=1 on 32 bit)
+depends_on:MBEDTLS_HAVE_INT32
+mpi_exp_mod_min_RR:"10":"2":"10000000100000001":"100":0
+
+Test mbedtls_mpi_exp_mod (N.n=3, RR.n=1 on 64 bit)
+depends_on:MBEDTLS_HAVE_INT64
+mpi_exp_mod_min_RR:"10":"2":"100000000000000010000000000000001":"100":0
+
Base test GCD #1
mpi_gcd:"2b5":"261":"15"
diff --git a/tests/suites/test_suite_debug.function b/tests/suites/test_suite_debug.function
index eeefc95..70e7bad 100644
--- a/tests/suites/test_suite_debug.function
+++ b/tests/suites/test_suite_debug.function
@@ -2,6 +2,7 @@
#include "debug_internal.h"
#include "string.h"
#include "mbedtls/pk.h"
+#include <test/ssl_helpers.h>
struct buffer_data {
char buf[2000];
@@ -65,11 +66,12 @@
memset(buffer.buf, 0, 2000);
buffer.ptr = buffer.buf;
- mbedtls_ssl_config_defaults(&conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT);
-
+ TEST_EQUAL(mbedtls_ssl_config_defaults(&conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT),
+ 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
@@ -103,11 +105,12 @@
memset(buffer.buf, 0, 2000);
buffer.ptr = buffer.buf;
- mbedtls_ssl_config_defaults(&conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT);
-
+ TEST_EQUAL(mbedtls_ssl_config_defaults(&conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT),
+ 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
@@ -138,11 +141,12 @@
memset(buffer.buf, 0, 2000);
buffer.ptr = buffer.buf;
- mbedtls_ssl_config_defaults(&conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT);
-
+ TEST_EQUAL(mbedtls_ssl_config_defaults(&conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT),
+ 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
@@ -175,11 +179,12 @@
memset(buffer.buf, 0, 2000);
buffer.ptr = buffer.buf;
- mbedtls_ssl_config_defaults(&conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT);
-
+ TEST_EQUAL(mbedtls_ssl_config_defaults(&conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT),
+ 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
@@ -214,11 +219,12 @@
memset(buffer.buf, 0, 2000);
buffer.ptr = buffer.buf;
- mbedtls_ssl_config_defaults(&conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT);
-
+ TEST_EQUAL(mbedtls_ssl_config_defaults(&conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT),
+ 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
mbedtls_ssl_conf_dbg(&conf, string_debug, &buffer);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
diff --git a/tests/suites/test_suite_ecdh.data b/tests/suites/test_suite_ecdh.data
index cc58432..8d06067 100644
--- a/tests/suites/test_suite_ecdh.data
+++ b/tests/suites/test_suite_ecdh.data
@@ -100,3 +100,19 @@
ECDH get_params with mismatched groups: their SECP256R1, our BP256R1
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_BP256R1_ENABLED
ecdh_exchange_get_params_fail:MBEDTLS_ECP_DP_BP256R1:"1234567812345678123456781234567812345678123456781234567812345678":MBEDTLS_ECP_DP_SECP256R1:"04dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":1:MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+
+Context get ECP Group #1
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecdh_context_grp:MBEDTLS_ECP_DP_SECP256R1
+
+Context get ECP Group #2
+depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+ecdh_primitive_random:MBEDTLS_ECP_DP_SECP384R1
+
+Context get ECP Group #3
+depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED
+ecdh_primitive_random:MBEDTLS_ECP_DP_SECP521R1
+
+Context get ECP Group #4
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecdh_primitive_random:MBEDTLS_ECP_DP_CURVE448
diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function
index cc193da..300916f 100644
--- a/tests/suites/test_suite_ecdh.function
+++ b/tests/suites/test_suite_ecdh.function
@@ -464,3 +464,20 @@
mbedtls_ecp_keypair_free(&their_key);
}
/* END_CASE */
+
+/* BEGIN_CASE */
+void ecdh_context_grp(int id)
+{
+ mbedtls_ecdh_context srv;
+
+ mbedtls_ecdh_init(&srv);
+ TEST_ASSERT(mbedtls_ecdh_setup(&srv, id) == 0);
+
+ /* Test the retrieved group id matches/*/
+ TEST_ASSERT((int) mbedtls_ecdh_get_grp_id(&srv) == id);
+
+exit:
+ mbedtls_ecdh_free(&srv);
+
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data
index 1dd963a..fd63657 100644
--- a/tests/suites/test_suite_ecp.data
+++ b/tests/suites/test_suite_ecp.data
@@ -888,6 +888,109 @@
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
ecp_write_key:MBEDTLS_ECP_DP_CURVE448:"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080":55:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+ECP write key ext: secp256r1, nominal
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":32:0
+
+ECP write key ext: secp256r1, output longer by 1
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":33:0
+
+ECP write key ext: secp256r1, output short by 1
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: secp256r1, output_size=0
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"f12a1320760270a83cbffd53f6031ef76a5d86c8a204f2c30ca9ebf51f0f0ea7":0:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: secp256r1, top byte = 0, output_size=32
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":32:0
+
+ECP write key ext: secp256r1, top byte = 0, output_size=31
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: secp256r1, top byte = 0, output_size=30
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":30:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: secp256r1, mostly-0 key, output_size=32
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"0000000000000000000000000000000000000000000000000000000000000001":32:0
+
+ECP write key ext: secp256r1, mostly-0 key, output_size=1
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"0000000000000000000000000000000000000000000000000000000000000001":1:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: secp256r1, private key not set
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP256R1:"":32:MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+
+ECP write key ext: secp384r1, nominal
+depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP384R1:"d27335ea71664af244dd14e9fd1260715dfd8a7965571c48d709ee7a7962a156d706a90cbcb5df2986f05feadb9376f1":48:0
+
+ECP write key ext: secp384r1, output longer by 1
+depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP384R1:"d27335ea71664af244dd14e9fd1260715dfd8a7965571c48d709ee7a7962a156d706a90cbcb5df2986f05feadb9376f1":49:0
+
+ECP write key ext: secp384r1, output short by 1
+depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_SECP384R1:"d27335ea71664af244dd14e9fd1260715dfd8a7965571c48d709ee7a7962a156d706a90cbcb5df2986f05feadb9376f1":47:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: Curve25519, nominal
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":32:0
+
+ECP write key ext: Curve25519, output longer by 1
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":33:0
+
+ECP write key ext: Curve25519, output short by 1
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: Curve25519, output_size=0
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44":0:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: Curve25519, mostly-0 key, output_size=32
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"0000000000000000000000000000000000000000000000000000000000000040":32:0
+
+ECP write key ext: Curve25519, mostly-0 key, output_size=31
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"0000000000000000000000000000000000000000000000000000000000000040":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: Curve25519, private key not set
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE25519:"":32:MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+
+ECP write key ext: Curve448, nominal
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"3c262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3":56:0
+
+ECP write key ext: Curve448, output longer by 1
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"3c262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3":57:0
+
+ECP write key ext: Curve448, output short by 1
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"3c262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3":55:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: Curve448, mostly-0 key, output_size=56
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080":56:0
+
+ECP write key ext: Curve448, mostly-0 key, output_size=55
+depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
+ecp_write_key_ext:MBEDTLS_ECP_DP_CURVE448:"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080":55:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
+ECP write key ext: group not set
+ecp_write_key_ext:MBEDTLS_ECP_DP_NONE:"":32:MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+
ECP mod p192 small (more than 192 bits, less limbs than 2 * 192 bits)
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_ECP_NIST_OPTIM
ecp_fast_mod:MBEDTLS_ECP_DP_SECP192R1:"0100000000000103010000000000010201000000000001010100000000000100"
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 9cf0ce1..9b5c86f 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -1204,29 +1204,46 @@
TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.Y, 2), 0);
TEST_EQUAL(mbedtls_mpi_cmp_int(&key.Q.Z, 3), 0);
- if (canonical) {
+ if (canonical && in_key->len == (key.grp.nbits + 7) / 8) {
unsigned char buf[MBEDTLS_ECP_MAX_BYTES];
+ size_t length = 0xdeadbeef;
- ret = mbedtls_ecp_write_key(&key, buf, in_key->len);
- TEST_ASSERT(ret == 0);
+ TEST_EQUAL(mbedtls_ecp_write_key_ext(&key,
+ &length, buf, in_key->len), 0);
+ TEST_MEMORY_COMPARE(in_key->x, in_key->len,
+ buf, length);
+#if defined(MBEDTLS_TEST_DEPRECATED)
+ memset(buf, 0, sizeof(buf));
+ TEST_EQUAL(mbedtls_ecp_write_key(&key, buf, in_key->len), 0);
TEST_MEMORY_COMPARE(in_key->x, in_key->len,
buf, in_key->len);
+#endif /* MBEDTLS_TEST_DEPRECATED */
} else {
unsigned char export1[MBEDTLS_ECP_MAX_BYTES];
unsigned char export2[MBEDTLS_ECP_MAX_BYTES];
- ret = mbedtls_ecp_write_key(&key, export1, in_key->len);
- TEST_ASSERT(ret == 0);
+ size_t length1 = 0xdeadbeef;
+ TEST_EQUAL(mbedtls_ecp_write_key_ext(&key, &length1,
+ export1, sizeof(export1)), 0);
+ TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key2, export1, length1),
+ expected);
+ size_t length2 = 0xdeadbeef;
+ TEST_EQUAL(mbedtls_ecp_write_key_ext(&key2, &length2,
+ export2, sizeof(export2)), 0);
+ TEST_MEMORY_COMPARE(export1, length1,
+ export2, length2);
- ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len);
- TEST_ASSERT(ret == expected);
-
- ret = mbedtls_ecp_write_key(&key2, export2, in_key->len);
- TEST_ASSERT(ret == 0);
-
+#if defined(MBEDTLS_TEST_DEPRECATED)
+ memset(export1, 0, sizeof(export1));
+ memset(export2, 0, sizeof(export2));
+ TEST_EQUAL(mbedtls_ecp_write_key(&key, export1, in_key->len), 0);
+ TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len),
+ expected);
+ TEST_EQUAL(mbedtls_ecp_write_key(&key2, export2, in_key->len), 0);
TEST_MEMORY_COMPARE(export1, in_key->len,
export2, in_key->len);
+#endif /* MBEDTLS_TEST_DEPRECATED */
}
}
@@ -1236,7 +1253,7 @@
}
/* END_CASE */
-/* BEGIN_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_TEST_DEPRECATED */
void ecp_write_key(int grp_id, data_t *in_key,
int exported_size, int expected_ret)
{
@@ -1296,6 +1313,42 @@
}
/* END_CASE */
+/* BEGIN_CASE */
+void ecp_write_key_ext(int grp_id, data_t *in_key,
+ int exported_size, int expected_ret)
+{
+ mbedtls_ecp_keypair key;
+ mbedtls_ecp_keypair_init(&key);
+ unsigned char *exported = NULL;
+
+ if (in_key->len != 0) {
+ TEST_EQUAL(mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len), 0);
+ } else if (grp_id != MBEDTLS_ECP_DP_NONE) {
+ TEST_EQUAL(mbedtls_ecp_group_load(&key.grp, grp_id), 0);
+ }
+
+ TEST_CALLOC(exported, exported_size);
+ size_t olen = 0xdeadbeef;
+ TEST_EQUAL(mbedtls_ecp_write_key_ext(&key, &olen, exported, exported_size),
+ expected_ret);
+
+ if (expected_ret == 0) {
+ TEST_EQUAL(olen, (key.grp.nbits + 7) / 8);
+ TEST_LE_U(olen, MBEDTLS_ECP_MAX_BYTES);
+ TEST_MEMORY_COMPARE(in_key->x, in_key->len,
+ exported, olen);
+ } else {
+ /* Robustness check: even in the error case, insist that olen is less
+ * than the buffer size. */
+ TEST_LE_U(olen, exported_size);
+ }
+
+exit:
+ mbedtls_ecp_keypair_free(&key);
+ mbedtls_free(exported);
+}
+/* END_CASE */
+
/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED:MBEDTLS_ECP_LIGHT */
void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected)
{
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index c55af03..b633c6f 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -7532,6 +7532,150 @@
depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH
generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:0:"2a":PSA_ERROR_INVALID_ARGUMENT
+PSA concurrent key generation: bad type (RSA public key)
+depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: raw data, 0 bits: invalid argument
+depends_on:MBEDTLS_THREADING_PTHREAD
+# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:0:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: raw data, 7 bits: invalid argument
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:7:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: raw data, 8 bits
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation- raw data, 9 bits: invalid argument
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:9:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: raw data, (MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:(MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: raw data, (2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:(2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: raw data, 65528 bits (large key, ok if it fits)
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:65528:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS:1:8:5
+
+PSA concurrent key generation: raw data, 65536 bits (not supported)
+depends_on:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RAW_DATA:65536:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: AES, 128 bits, CTR
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: AES, 128 bits, GCM
+depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_GCM:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: DES, 64 bits, CBC-nopad
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: DES, 128 bits, CBC-nopad
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: DES, 192 bits, CBC-nopad
+depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_DES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DES:192:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_NO_PADDING:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: invalid key size: AES, 64 bits
+depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_AES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: RSA, minimum allowed key size, good, sign (PKCS#1 v1.5)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS > 128:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 1032 bits, good, sign (PKCS#1 v1.5)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1032:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:1032:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 1024 bits, good, sign (PSS SHA-256)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1024:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 1024 bits, good, sign (PSS-any-salt SHA-256)
+depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1024:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PSS_ANY_SALT(PSA_ALG_SHA_256):PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, minimum allowed key size, good, encrypt (PKCS#1 v1.5)
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS >= 256:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 2048:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 1024 bits, good, encrypt (OAEP SHA-256)
+depends_on:PSA_WANT_ALG_RSA_OAEP:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS <= 1024:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: RSA, 0 bits: invalid
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+# The spec allows either INVALID_ARGUMENT or NOT_SUPPORTED
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_INVALID_ARGUMENT:0:8:5
+
+PSA concurrent key generation: RSA, size not multiple of 8: not supported
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS + 62:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: RSA, size not multiple of 2: not supported
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS + 63:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: RSA, maximum size exceeded
+depends_on:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_MAX_KEY_BITS+8:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: ECC, SECP256R1, good
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: ECC, SECP256R1, incorrect bit size
+depends_on:PSA_WANT_ALG_ECDSA: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:MBEDTLS_THREADING_PTHREAD
+# INVALID_ARGUMENT would make more sense, but our code as currently structured
+# doesn't fully relate the curve with its size.
+concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
+PSA concurrent key generation: ECC, Curve25519, good
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_MONTGOMERY_255:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):255:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: ECC, Curve448, good
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_MONTGOMERY_448:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):448:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 2048 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_2048:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):2048:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 3072 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_3072:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):3072:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 4096 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_4096:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):4096:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 6144 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_6144:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):6144:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 8192 bits, good
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:PSA_WANT_DH_RFC7919_8192:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):8192:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_SUCCESS:0:8:5
+
+PSA concurrent key generation: FFDH, 1024 bits, invalid bits
+depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE:MBEDTLS_THREADING_PTHREAD
+concurrently_generate_keys:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_ERROR_NOT_SUPPORTED:0:8:5
+
Key production parameters initializers
key_production_parameters_init:
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 09874a1..1141597 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -28,6 +28,10 @@
#define TEST_DRIVER_LOCATION 0x7fffff
#endif
+#if defined(MBEDTLS_THREADING_PTHREAD)
+#include "mbedtls/threading.h"
+#endif
+
/* If this comes up, it's a bug in the test code or in the test data. */
#define UNUSED 0xdeadbeef
@@ -1333,6 +1337,66 @@
return 0;
}
+#if defined(MBEDTLS_THREADING_PTHREAD)
+typedef struct generate_key_context {
+ psa_key_type_t type;
+ psa_key_usage_t usage;
+ size_t bits;
+ psa_algorithm_t alg;
+ psa_status_t expected_status;
+ psa_key_attributes_t *attributes;
+ int is_large_key;
+ int reps;
+}
+generate_key_context;
+void *thread_generate_key(void *ctx)
+{
+ mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT;
+ generate_key_context *gkc = (struct generate_key_context *) ctx;
+
+ /* If there are race conditions, it is likely the case that they do not
+ * arise every time the code runs. We repeat the code to increase the
+ * chance that any race conditions will be hit. */
+ for (int n = 0; n < gkc->reps; n++) {
+ /* Generate a key */
+ psa_status_t status = psa_generate_key(gkc->attributes, &key);
+
+ if (gkc->is_large_key > 0) {
+ TEST_ASSUME(status != PSA_ERROR_INSUFFICIENT_MEMORY);
+ }
+
+ TEST_EQUAL(status, gkc->expected_status);
+ if (gkc->expected_status != PSA_SUCCESS) {
+ PSA_ASSERT(psa_destroy_key(key));
+ goto exit;
+ }
+
+ /* Test the key information */
+ PSA_ASSERT(psa_get_key_attributes(key, &got_attributes));
+ TEST_EQUAL(psa_get_key_type(&got_attributes), gkc->type);
+ TEST_EQUAL(psa_get_key_bits(&got_attributes), gkc->bits);
+
+ /* Do something with the key according
+ * to its type and permitted usage. */
+ if (!mbedtls_test_psa_exercise_key(key, gkc->usage, gkc->alg)) {
+ psa_destroy_key(key);
+ goto exit;
+ }
+ psa_reset_key_attributes(&got_attributes);
+
+ PSA_ASSERT(psa_destroy_key(key));
+ }
+exit:
+ /*
+ * Key attributes may have been returned by psa_get_key_attributes()
+ * thus reset them as required.
+ */
+ psa_reset_key_attributes(&got_attributes);
+ return NULL;
+}
+#endif /* MBEDTLS_THREADING_PTHREAD */
+
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -9783,6 +9847,59 @@
}
/* END_CASE */
+#if defined MBEDTLS_THREADING_PTHREAD
+
+/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD */
+void concurrently_generate_keys(int type_arg,
+ int bits_arg,
+ int usage_arg,
+ int alg_arg,
+ int expected_status_arg,
+ int is_large_key_arg,
+ int arg_thread_count,
+ int reps_arg)
+{
+ size_t thread_count = (size_t) arg_thread_count;
+ mbedtls_test_thread_t *threads = NULL;
+ generate_key_context gkc;
+ gkc.type = type_arg;
+ gkc.usage = usage_arg;
+ gkc.bits = bits_arg;
+ gkc.alg = alg_arg;
+ gkc.expected_status = expected_status_arg;
+ gkc.is_large_key = is_large_key_arg;
+ gkc.reps = reps_arg;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ PSA_ASSERT(psa_crypto_init());
+
+ psa_set_key_usage_flags(&attributes, usage_arg);
+ psa_set_key_algorithm(&attributes, alg_arg);
+ psa_set_key_type(&attributes, type_arg);
+ psa_set_key_bits(&attributes, bits_arg);
+ gkc.attributes = &attributes;
+
+ TEST_CALLOC(threads, sizeof(mbedtls_test_thread_t) * thread_count);
+
+ /* Split threads to generate key then destroy key. */
+ for (size_t i = 0; i < thread_count; i++) {
+ TEST_EQUAL(
+ mbedtls_test_thread_create(&threads[i], thread_generate_key,
+ (void *) &gkc), 0);
+ }
+
+ /* Join threads. */
+ for (size_t i = 0; i < thread_count; i++) {
+ TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0);
+ }
+
+exit:
+ mbedtls_free(threads);
+ PSA_DONE();
+}
+/* END_CASE */
+#endif
+
/* BEGIN_CASE */
void generate_key(int type_arg,
int bits_arg,
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function
index c4e4c7d..ea8cb6b 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.function
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.function
@@ -61,7 +61,7 @@
TEST_CALLOC(file_data, file_data_length);
psa_format_key_data_for_storage(key_data->x, key_data->len,
- &attributes.core,
+ &attributes,
file_data);
TEST_MEMORY_COMPARE(expected_file_data->x, expected_file_data->len,
@@ -90,7 +90,7 @@
status = psa_parse_key_data_from_storage(file_data->x, file_data->len,
&key_data, &key_data_length,
- &attributes.core);
+ &attributes);
TEST_EQUAL(status, expected_status);
if (status != PSA_SUCCESS) {
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.function b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
index 8e96984..e3681ba 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
@@ -952,7 +952,7 @@
psa_set_key_slot_number(&attributes, min_slot);
if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
- attributes.core.id = returned_id;
+ attributes.id = returned_id;
} else {
psa_set_key_id(&attributes, returned_id);
}
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
index 6f28f93..b6d3a34 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function
@@ -359,19 +359,19 @@
if (mock_alloc_return_value == PSA_SUCCESS) {
TEST_ASSERT(mbedtls_svc_key_id_equal(
- mock_import_data.attributes.core.id, id));
+ mock_import_data.attributes.id, id));
} else {
TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_KEY_ID(
- mock_import_data.attributes.core.id) == 0);
+ mock_import_data.attributes.id) == 0);
TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(
- mock_import_data.attributes.core.id) == 0);
+ mock_import_data.attributes.id) == 0);
}
- TEST_ASSERT(mock_import_data.attributes.core.lifetime ==
+ TEST_ASSERT(mock_import_data.attributes.lifetime ==
(mock_alloc_return_value == PSA_SUCCESS ? lifetime : 0));
- TEST_ASSERT(mock_import_data.attributes.core.policy.usage ==
+ TEST_ASSERT(mock_import_data.attributes.policy.usage ==
(mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_USAGE_EXPORT : 0));
- TEST_ASSERT(mock_import_data.attributes.core.type ==
+ TEST_ASSERT(mock_import_data.attributes.type ==
(mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_TYPE_RAW_DATA : 0));
if (expected_result == PSA_SUCCESS) {
@@ -474,19 +474,19 @@
if (mock_alloc_return_value == PSA_SUCCESS) {
TEST_ASSERT(mbedtls_svc_key_id_equal(
- mock_generate_data.attributes.core.id, id));
+ mock_generate_data.attributes.id, id));
} else {
TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_KEY_ID(
- mock_generate_data.attributes.core.id) == 0);
+ mock_generate_data.attributes.id) == 0);
TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(
- mock_generate_data.attributes.core.id) == 0);
+ mock_generate_data.attributes.id) == 0);
}
- TEST_ASSERT(mock_generate_data.attributes.core.lifetime ==
+ TEST_ASSERT(mock_generate_data.attributes.lifetime ==
(mock_alloc_return_value == PSA_SUCCESS ? lifetime : 0));
- TEST_ASSERT(mock_generate_data.attributes.core.policy.usage ==
+ TEST_ASSERT(mock_generate_data.attributes.policy.usage ==
(mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_USAGE_EXPORT : 0));
- TEST_ASSERT(mock_generate_data.attributes.core.type ==
+ TEST_ASSERT(mock_generate_data.attributes.type ==
(mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_TYPE_RAW_DATA : 0));
if (expected_result == PSA_SUCCESS) {
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function
index 8564d35..94f26f6 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.function
+++ b/tests/suites/test_suite_psa_crypto_slot_management.function
@@ -458,7 +458,7 @@
* PSA key attributes APIs thus accessing to the attributes
* directly.
*/
- attributes.core.id = id;
+ attributes.id = id;
} else {
psa_set_key_id(&attributes, id);
}
@@ -992,7 +992,7 @@
* Check that we can now access the persistent key again.
*/
PSA_ASSERT(psa_get_key_attributes(persistent_key, &attributes));
- TEST_ASSERT(mbedtls_svc_key_id_equal(attributes.core.id,
+ TEST_ASSERT(mbedtls_svc_key_id_equal(attributes.id,
persistent_key));
/*
diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data
index 385682a..c0c816c 100644
--- a/tests/suites/test_suite_ssl.data
+++ b/tests/suites/test_suite_ssl.data
@@ -3309,3 +3309,39 @@
TLS 1.3 write early data, hello retry request
tls13_write_early_data:TEST_EARLY_DATA_HRR
+
+TLS 1.3 srv, max early data size, dflt, wsz=96
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1:96
+
+TLS 1.3 srv, max early data size, dflt, wsz=128
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1:128
+
+TLS 1.3 srv, max early data size, 3, wsz=2
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3:2
+
+TLS 1.3 srv, max early data size, 3, wsz=3
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3:3
+
+TLS 1.3 srv, max early data size, 98, wsz=23
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:98:23
+
+TLS 1.3 srv, max early data size, 98, wsz=49
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:98:49
+
+TLS 1.3 srv, max early data size, server rejects, dflt, wsz=128
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:-1:128
+
+TLS 1.3 srv, max early data size, server rejects, 3, wsz=3
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:3:3
+
+TLS 1.3 srv, max early data size, server rejects, 98, wsz=49
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:98:49
+
+TLS 1.3 srv, max early data size, HRR, dflt, wsz=128
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:-1:128
+
+TLS 1.3 srv, max early data size, HRR, 3, wsz=3
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:3:3
+
+TLS 1.3 srv, max early data size, HRR, 98, wsz=49
+tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:97:0
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index d327828..6e95817 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -18,6 +18,47 @@
#define TEST_EARLY_DATA_SERVER_REJECTS 2
#define TEST_EARLY_DATA_HRR 3
+#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) && \
+ 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)
+/*
+ * Test function to write early data for negative tests where
+ * mbedtls_ssl_write_early_data() cannot be used.
+ */
+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_LE_U(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
@@ -1131,6 +1172,8 @@
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_DATAGRAM,
MBEDTLS_SSL_PRESET_DEFAULT) == 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
+
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
/* Read previous record numbers */
@@ -2879,6 +2922,7 @@
mbedtls_ssl_conf_transport(&conf, transport);
mbedtls_ssl_conf_min_tls_version(&conf, min_tls_version);
mbedtls_ssl_conf_max_tls_version(&conf, max_tls_version);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == expected_ssl_setup_result);
TEST_EQUAL(mbedtls_ssl_conf_get_endpoint(
@@ -2920,6 +2964,8 @@
mbedtls_ssl_init(&ssl);
MD_OR_USE_PSA_INIT();
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
+
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
TEST_ASSERT(ssl.handshake != NULL && ssl.handshake->group_list != NULL);
@@ -2951,6 +2997,7 @@
mbedtls_ssl_config conf;
mbedtls_ssl_config_init(&conf);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
mbedtls_ssl_conf_max_tls_version(&conf, MBEDTLS_SSL_VERSION_TLS1_2);
mbedtls_ssl_conf_min_tls_version(&conf, MBEDTLS_SSL_VERSION_TLS1_2);
@@ -3059,6 +3106,7 @@
MBEDTLS_SSL_TRANSPORT_DATAGRAM,
MBEDTLS_SSL_PRESET_DEFAULT),
0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
TEST_EQUAL(mbedtls_ssl_setup(&ssl, &conf), 0);
TEST_EQUAL(mbedtls_ssl_check_dtls_clihlo_cookie(&ssl, ssl.cli_id,
@@ -3113,6 +3161,7 @@
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)
== 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
TEST_ASSERT(mbedtls_ssl_setup(&ssl, &conf) == 0);
@@ -3371,6 +3420,7 @@
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT), 0);
+ mbedtls_ssl_conf_rng(&conf, mbedtls_test_random, NULL);
TEST_EQUAL(mbedtls_ssl_setup(&ssl, &conf), 0);
@@ -4159,6 +4209,10 @@
break;
case TEST_EARLY_DATA_HRR:
+ /*
+ * Remove server support for the group negotiated in
+ * mbedtls_test_get_tls13_ticket() forcing a HelloRetryRequest.
+ */
server_options.group_list = group_list + 1;
break;
@@ -4448,3 +4502,259 @@
PSA_DONE();
}
/* 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_srv_max_early_data_size(int scenario, int max_early_data_size_arg, int write_size_arg)
+{
+ int ret = -1;
+ 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 };
+ uint16_t group_list[3] = {
+ MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1,
+ MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1,
+ MBEDTLS_SSL_IANA_TLS_GROUP_NONE
+ };
+ char pattern[128];
+ unsigned char *buf_write = NULL;
+ uint32_t write_size = (uint32_t) write_size_arg;
+ unsigned char *buf_read = NULL;
+ uint32_t read_size;
+ uint32_t expanded_early_data_chunk_size = 0;
+ uint32_t written_early_data_size = 0;
+ uint32_t max_early_data_size;
+
+ 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);
+ PSA_INIT();
+
+ TEST_CALLOC(buf_write, write_size);
+
+ /*
+ * Allocate a smaller buffer for early data reading to exercise the reading
+ * of data in one record in multiple calls.
+ */
+ read_size = (write_size / 2) + 1;
+ TEST_CALLOC(buf_read, read_size);
+
+ /*
+ * Run first handshake to get a ticket from the server.
+ */
+
+ client_options.pk_alg = MBEDTLS_PK_ECDSA;
+ client_options.group_list = group_list;
+ client_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
+ server_options.pk_alg = MBEDTLS_PK_ECDSA;
+ server_options.group_list = group_list;
+ server_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
+ server_options.max_early_data_size = max_early_data_size_arg;
+
+ ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options,
+ &saved_session);
+ TEST_EQUAL(ret, 0);
+
+ /*
+ * Prepare for handshake with the ticket.
+ */
+ server_options.srv_log_fun = mbedtls_test_ssl_log_analyzer;
+ server_options.srv_log_obj = &server_pattern;
+ server_pattern.pattern = pattern;
+
+ switch (scenario) {
+ case TEST_EARLY_DATA_ACCEPTED:
+ break;
+
+ case TEST_EARLY_DATA_SERVER_REJECTS:
+ server_options.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
+ ret = mbedtls_snprintf(pattern, sizeof(pattern),
+ "EarlyData: deprotect and discard app data records.");
+ TEST_ASSERT(ret < (int) sizeof(pattern));
+ mbedtls_debug_set_threshold(3);
+ break;
+
+ case TEST_EARLY_DATA_HRR:
+ /*
+ * Remove server support for the group negotiated in
+ * mbedtls_test_get_tls13_ticket() forcing an HelloRetryRequest.
+ */
+ server_options.group_list = group_list + 1;
+ ret = mbedtls_snprintf(
+ pattern, sizeof(pattern),
+ "EarlyData: Ignore application message before 2nd ClientHello");
+ TEST_ASSERT(ret < (int) sizeof(pattern));
+ mbedtls_debug_set_threshold(3);
+ break;
+
+ default:
+ TEST_FAIL("Unknown scenario.");
+ }
+
+ ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT,
+ &client_options, NULL, NULL, NULL);
+ TEST_EQUAL(ret, 0);
+
+ ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER,
+ &server_options, 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);
+
+ ret = mbedtls_test_mock_socket_connect(&(client_ep.socket),
+ &(server_ep.socket), 1024);
+ TEST_EQUAL(ret, 0);
+
+ max_early_data_size = saved_session.max_early_data_size;
+
+ ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session);
+ TEST_EQUAL(ret, 0);
+
+ /*
+ * Start an handshake based on the ticket up to the point where early data
+ * can be sent from client side. Then send in a loop as much early data as
+ * possible without going over the maximum permitted size for the ticket.
+ * Finally, do a last writting to go past that maximum permitted size and
+ * check that we detect it.
+ */
+ 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);
+
+ ret = mbedtls_ssl_handshake(&(server_ep.ssl));
+ TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ);
+
+ /*
+ * Write and if possible read as much as possible chunks of write_size
+ * bytes data without getting over the max_early_data_size limit.
+ */
+ do {
+ uint32_t read_early_data_size = 0;
+
+ /*
+ * The contents of the early data are not very important, write a
+ * pattern that varies byte-by-byte and is different for every chunk of
+ * early data.
+ */
+ if ((written_early_data_size + write_size) > max_early_data_size) {
+ break;
+ }
+
+ /*
+ * If the server rejected early data, base the determination of when
+ * to stop the loop on the expanded size (padding and encryption
+ * expansion) of early data on server side and the number of early data
+ * received so far by the server (multiple of the expanded size).
+ */
+ if ((expanded_early_data_chunk_size != 0) &&
+ ((server_ep.ssl.total_early_data_size +
+ expanded_early_data_chunk_size) > max_early_data_size)) {
+ break;
+ }
+
+ for (size_t i = 0; i < write_size; i++) {
+ buf_write[i] = (unsigned char) (written_early_data_size + i);
+ }
+
+ ret = write_early_data(&(client_ep.ssl), buf_write, write_size);
+ TEST_EQUAL(ret, write_size);
+ written_early_data_size += write_size;
+
+ switch (scenario) {
+ case TEST_EARLY_DATA_ACCEPTED:
+ while (read_early_data_size < write_size) {
+ ret = mbedtls_ssl_handshake(&(server_ep.ssl));
+ TEST_EQUAL(ret, MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA);
+
+ ret = mbedtls_ssl_read_early_data(&(server_ep.ssl),
+ buf_read, read_size);
+ TEST_ASSERT(ret > 0);
+
+ TEST_MEMORY_COMPARE(buf_read, ret,
+ buf_write + read_early_data_size, ret);
+ read_early_data_size += ret;
+
+ TEST_EQUAL(server_ep.ssl.total_early_data_size,
+ written_early_data_size);
+ }
+ break;
+
+ case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
+ case TEST_EARLY_DATA_HRR:
+ ret = mbedtls_ssl_handshake(&(server_ep.ssl));
+ /*
+ * In this write loop we try to always stay below the
+ * max_early_data_size limit but if max_early_data_size is very
+ * small we may exceed the max_early_data_size limit on the
+ * first write. In TEST_EARLY_DATA_SERVER_REJECTS/
+ * TEST_EARLY_DATA_HRR scenario, this is for sure the case if
+ * max_early_data_size is smaller than the smallest possible
+ * inner content/protected record. Take into account this
+ * possibility here but only for max_early_data_size values
+ * that are close to write_size. Below, '1' is for the inner
+ * type byte and '16' is to take into account some AEAD
+ * expansion (tag, ...).
+ */
+ if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) {
+ if (scenario == TEST_EARLY_DATA_SERVER_REJECTS) {
+ TEST_LE_U(max_early_data_size,
+ write_size + 1 +
+ MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
+ } else {
+ TEST_LE_U(max_early_data_size,
+ write_size + 1 + 16 +
+ MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
+ }
+ goto exit;
+ }
+
+ TEST_ASSERT(ret == MBEDTLS_ERR_SSL_WANT_READ);
+
+ TEST_EQUAL(server_pattern.counter, 1);
+ server_pattern.counter = 0;
+ if (expanded_early_data_chunk_size == 0) {
+ expanded_early_data_chunk_size = server_ep.ssl.total_early_data_size;
+ }
+ break;
+ }
+ TEST_LE_U(server_ep.ssl.total_early_data_size, max_early_data_size);
+ } while (1);
+
+ mbedtls_debug_set_threshold(3);
+ ret = write_early_data(&(client_ep.ssl), buf_write, write_size);
+ TEST_EQUAL(ret, write_size);
+
+ ret = mbedtls_snprintf(pattern, sizeof(pattern),
+ "EarlyData: Too much early data received");
+ TEST_ASSERT(ret < (int) sizeof(pattern));
+
+ ret = mbedtls_ssl_handshake(&(server_ep.ssl));
+ TEST_EQUAL(ret, MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
+ 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_free(buf_write);
+ mbedtls_free(buf_read);
+ mbedtls_debug_set_threshold(0);
+ PSA_DONE();
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 2b0920d..754660c 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -3155,6 +3155,18 @@
depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
x509parse_crt_file:"data_files/parse_input/server5.crt":0
+X509 File parse & read the ca_istrue field (Not Set)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAVE_TIME_DATE:MBEDTLS_MD_CAN_SHA1
+mbedtls_x509_get_ca_istrue:"data_files/parse_input/server1.crt":0
+
+X509 File parse & read the ca_istrue field (Set)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAVE_TIME_DATE:MBEDTLS_MD_CAN_SHA1
+mbedtls_x509_get_ca_istrue:"data_files/test-ca.crt":1
+
+X509 File parse & read the ca_istrue field (Legacy Certificate)
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAVE_TIME_DATE:MBEDTLS_MD_CAN_SHA1:MBEDTLS_MD_CAN_SHA256
+mbedtls_x509_get_ca_istrue:"data_files/server1-v1.crt":MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+
X509 Get time (UTC no issues)
depends_on:MBEDTLS_X509_USE_C
x509_get_time:MBEDTLS_ASN1_UTC_TIME:"500101000000Z":0:1950:1:1:0:0:0
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 66477e0..f3ae0f4 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -1083,6 +1083,21 @@
}
/* END_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_FS_IO */
+void mbedtls_x509_get_ca_istrue(char *crt_file, int result)
+{
+ mbedtls_x509_crt crt;
+ mbedtls_x509_crt_init(&crt);
+ USE_PSA_INIT();
+
+ TEST_EQUAL(mbedtls_x509_crt_parse_file(&crt, crt_file), 0);
+ TEST_EQUAL(mbedtls_x509_crt_get_ca_istrue(&crt), result);
+exit:
+ mbedtls_x509_crt_free(&crt);
+ USE_PSA_DONE();
+}
+/* END_CASE */
+
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
void x509parse_crt(data_t *buf, char *result_str, int result)
{