mbedTLS: Update to version 3.6.4, fixes GCC 15 compatibility

- Security fixes: https://github.com/Mbed-TLS/mbedtls/releases/tag/mbedtls-3.6.4
- Fixes #107754.
- Fixes #108048.
This commit is contained in:
Rémi Verschelde 2025-07-07 10:17:14 +02:00
parent 53be3b78d1
commit f2eb6b5fed
No known key found for this signature in database
GPG key ID: C3336907360768E1
45 changed files with 960 additions and 440 deletions

View file

@ -654,14 +654,13 @@ File extracted from upstream source:
## mbedtls
- Upstream: https://github.com/Mbed-TLS/mbedtls
- Version: 3.6.3 (22098d41c6620ce07cf8a0134d37302355e1e5ef, 2025)
- Version: 3.6.4 (c765c831e5c2a0971410692f92f7a81d6ec65ec2, 2025)
- License: Apache 2.0
File extracted from upstream release tarball:
- All `.h` from `include/mbedtls/` to `thirdparty/mbedtls/include/mbedtls/`
and all `.h` from `include/psa/` to `thirdparty/mbedtls/include/psa/`
- All `.c` and `.h` from `library/` to `thirdparty/mbedtls/library/`
- From `library/` to `thirdparty/mbedtls/library/`:
- All `.c` and `.h` files
- Except `bignum_mod.c`, `block_cipher.c`, `ecp_curves_new.c`, `lmots.c`,

View file

@ -12,6 +12,7 @@
#include "mbedtls/private_access.h"
#include "mbedtls/build_info.h"
#include "mbedtls/platform_util.h"
#include <stddef.h>
#include <stdint.h>
@ -928,7 +929,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
* be relevant in applications like deterministic ECDSA.
*/
int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/** Generate a random number uniformly in a range.
@ -966,7 +967,7 @@ int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size,
int mbedtls_mpi_random(mbedtls_mpi *X,
mbedtls_mpi_sint min,
const mbedtls_mpi *N,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -1030,7 +1031,7 @@ int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
* \brief Flags for mbedtls_mpi_gen_prime()
@ -1063,7 +1064,7 @@ typedef enum {
* \c 3 and #MBEDTLS_MPI_MAX_BITS.
*/
int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
#if defined(MBEDTLS_SELF_TEST)

View file

@ -26,16 +26,16 @@
*/
#define MBEDTLS_VERSION_MAJOR 3
#define MBEDTLS_VERSION_MINOR 6
#define MBEDTLS_VERSION_PATCH 3
#define MBEDTLS_VERSION_PATCH 4
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
#define MBEDTLS_VERSION_NUMBER 0x03060300
#define MBEDTLS_VERSION_STRING "3.6.3"
#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.3"
#define MBEDTLS_VERSION_NUMBER 0x03060400
#define MBEDTLS_VERSION_STRING "3.6.4"
#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.6.4"
/* Macros for build-time platform detection */

View file

@ -183,7 +183,7 @@ int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx,
*/
int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size,
unsigned char *output, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -250,7 +250,7 @@ int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx,
*/
int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size,
unsigned char *output, size_t olen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -281,7 +281,7 @@ int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size,
*/
int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx,
unsigned char *output, size_t output_size, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**

View file

@ -189,7 +189,7 @@ int mbedtls_ecdh_can_do(mbedtls_ecp_group_id gid);
* \c MBEDTLS_MPI_XXX error code on failure.
*/
int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -225,7 +225,7 @@ int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_
*/
int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z,
const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -290,7 +290,7 @@ void mbedtls_ecdh_free(mbedtls_ecdh_context *ctx);
*/
int mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -372,7 +372,7 @@ int mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx,
*/
int mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -428,7 +428,7 @@ int mbedtls_ecdh_read_public(mbedtls_ecdh_context *ctx,
*/
int mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
#if defined(MBEDTLS_ECP_RESTARTABLE)

View file

@ -150,7 +150,8 @@ int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid);
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param f_rng The RNG function. This must not be \c NULL.
* \param f_rng The RNG function, used both to generate the ECDSA nonce
* and for blinding. This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
*
@ -160,7 +161,7 @@ int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid);
*/
int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
mbedtls_f_rng_t *f_rng, void *p_rng);
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/**
@ -207,7 +208,7 @@ int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r,
mbedtls_mpi *s, const mbedtls_mpi *d,
const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg,
int (*f_rng_blind)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng_blind,
void *p_rng_blind);
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
@ -247,7 +248,8 @@ int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r,
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param f_rng The RNG function. This must not be \c NULL.
* \param f_rng The RNG function used to generate the ECDSA nonce.
* This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng doesn't need a context parameter.
* \param f_rng_blind The RNG function used for blinding. This must not be
@ -271,9 +273,9 @@ int mbedtls_ecdsa_sign_restartable(
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d,
const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
int (*f_rng_blind)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng_blind,
void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx);
@ -334,7 +336,7 @@ int mbedtls_ecdsa_sign_det_restartable(
mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg,
int (*f_rng_blind)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng_blind,
void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx);
@ -458,10 +460,10 @@ int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp,
* \param sig_size The size of the \p sig buffer in bytes.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param f_rng The RNG function. This must not be \c NULL if
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
* it is used only for blinding and may be set to \c NULL, but
* doing so is DEPRECATED.
* \param f_rng The RNG function. This is used for blinding.
* If #MBEDTLS_ECDSA_DETERMINISTIC is unset, this is also
* used to generate the ECDSA nonce.
* This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
*
@ -473,7 +475,7 @@ int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t sig_size, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -501,9 +503,10 @@ int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
* \param sig_size The size of the \p sig buffer in bytes.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param f_rng The RNG function. This must not be \c NULL if
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
* it is unused and may be set to \c NULL.
* \param f_rng The RNG function. This is used for blinding.
* If #MBEDTLS_ECDSA_DETERMINISTIC is unset, this is also
* used to generate the ECDSA nonce.
* This must not be \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
* \param rs_ctx The restart context to use. This may be \c NULL to disable
@ -520,7 +523,7 @@ int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t sig_size, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
mbedtls_ecdsa_restart_ctx *rs_ctx);
@ -608,7 +611,7 @@ int mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx,
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
*/
int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
mbedtls_f_rng_t *f_rng, void *p_rng);
/**
* \brief This function sets up an ECDSA context from an EC key pair.

View file

@ -162,7 +162,7 @@ int mbedtls_ecjpake_check(const mbedtls_ecjpake_context *ctx);
*/
int mbedtls_ecjpake_write_round_one(mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -203,7 +203,7 @@ int mbedtls_ecjpake_read_round_one(mbedtls_ecjpake_context *ctx,
*/
int mbedtls_ecjpake_write_round_two(mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -243,7 +243,7 @@ int mbedtls_ecjpake_read_round_two(mbedtls_ecjpake_context *ctx,
*/
int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -266,7 +266,7 @@ int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx,
*/
int mbedtls_ecjpake_write_shared_key(mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**

View file

@ -966,7 +966,7 @@ int mbedtls_ecp_tls_write_group(const mbedtls_ecp_group *grp,
*/
int mbedtls_ecp_mul(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
mbedtls_f_rng_t *f_rng, void *p_rng);
/**
* \brief This function performs multiplication of a point by
@ -1000,7 +1000,7 @@ int mbedtls_ecp_mul(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
*/
int mbedtls_ecp_mul_restartable(mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_f_rng_t *f_rng, void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx);
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
@ -1179,7 +1179,7 @@ int mbedtls_ecp_check_privkey(const mbedtls_ecp_group *grp,
*/
int mbedtls_ecp_gen_privkey(const mbedtls_ecp_group *grp,
mbedtls_mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -1212,7 +1212,7 @@ int mbedtls_ecp_gen_privkey(const mbedtls_ecp_group *grp,
int mbedtls_ecp_gen_keypair_base(mbedtls_ecp_group *grp,
const mbedtls_ecp_point *G,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -1240,7 +1240,7 @@ int mbedtls_ecp_gen_keypair_base(mbedtls_ecp_group *grp,
*/
int mbedtls_ecp_gen_keypair(mbedtls_ecp_group *grp, mbedtls_mpi *d,
mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -1257,7 +1257,7 @@ int mbedtls_ecp_gen_keypair(mbedtls_ecp_group *grp, mbedtls_mpi *d,
* on failure.
*/
int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/** \brief Set the public key in a key pair object.
@ -1451,7 +1451,7 @@ int mbedtls_ecp_write_public_key(const mbedtls_ecp_keypair *key,
*/
int mbedtls_ecp_check_pub_priv(
const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
mbedtls_f_rng_t *f_rng, void *p_rng);
/** \brief Calculate the public key from a private key in a key pair.
*
@ -1468,7 +1468,7 @@ int mbedtls_ecp_check_pub_priv(
*/
int mbedtls_ecp_keypair_calc_public(
mbedtls_ecp_keypair *key,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
mbedtls_f_rng_t *f_rng, void *p_rng);
/** \brief Query the group that a key pair belongs to.
*

View file

@ -364,7 +364,7 @@ void mbedtls_lms_private_free(mbedtls_lms_private_t *ctx);
int mbedtls_lms_generate_private_key(mbedtls_lms_private_t *ctx,
mbedtls_lms_algorithm_type_t type,
mbedtls_lmots_algorithm_type_t otstype,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng, const unsigned char *seed,
size_t seed_size);
@ -427,7 +427,7 @@ int mbedtls_lms_calculate_public_key(mbedtls_lms_public_t *ctx,
* \return A non-zero error code on failure.
*/
int mbedtls_lms_sign(mbedtls_lms_private_t *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng, const unsigned char *msg,
unsigned int msg_size, unsigned char *sig, size_t sig_size,
size_t *sig_len);

View file

@ -1763,6 +1763,20 @@
*/
#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
/**
* \def MBEDTLS_SSL_KEYING_MATERIAL_EXPORT
*
* When this option is enabled, the client and server can extract additional
* shared symmetric keys after an SSL handshake using the function
* mbedtls_ssl_export_keying_material().
*
* The process for deriving the keys is specified in RFC 5705 for TLS 1.2 and
* in RFC 8446, Section 7.5, for TLS 1.3.
*
* Comment this macro to disable mbedtls_ssl_export_keying_material().
*/
#define MBEDTLS_SSL_KEYING_MATERIAL_EXPORT
/**
* \def MBEDTLS_SSL_RENEGOTIATION
*

View file

@ -285,7 +285,7 @@ typedef int (*mbedtls_pk_rsa_alt_decrypt_func)(void *ctx, size_t *olen,
const unsigned char *input, unsigned char *output,
size_t output_max_len);
typedef int (*mbedtls_pk_rsa_alt_sign_func)(void *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
mbedtls_md_type_t md_alg, unsigned int hashlen,
const unsigned char *hash, unsigned char *sig);
@ -849,7 +849,7 @@ int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options,
int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t sig_size, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
mbedtls_f_rng_t *f_rng, void *p_rng);
/**
* \brief Make signature given a signature type.
@ -885,7 +885,7 @@ int mbedtls_pk_sign_ext(mbedtls_pk_type_t pk_type,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t sig_size, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -921,7 +921,7 @@ int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t sig_size, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_f_rng_t *f_rng, void *p_rng,
mbedtls_pk_restart_ctx *rs_ctx);
/**
@ -947,7 +947,7 @@ int mbedtls_pk_sign_restartable(mbedtls_pk_context *ctx,
int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
mbedtls_f_rng_t *f_rng, void *p_rng);
/**
* \brief Encrypt message (including padding if relevant).
@ -973,7 +973,7 @@ int mbedtls_pk_decrypt(mbedtls_pk_context *ctx,
int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
mbedtls_f_rng_t *f_rng, void *p_rng);
/**
* \brief Check if a public-private pair of keys matches.
@ -991,7 +991,7 @@ int mbedtls_pk_encrypt(mbedtls_pk_context *ctx,
*/
int mbedtls_pk_check_pair(const mbedtls_pk_context *pub,
const mbedtls_pk_context *prv,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -1109,7 +1109,7 @@ static inline mbedtls_ecp_keypair *mbedtls_pk_ec(const mbedtls_pk_context pk)
int mbedtls_pk_parse_key(mbedtls_pk_context *ctx,
const unsigned char *key, size_t keylen,
const unsigned char *pwd, size_t pwdlen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
mbedtls_f_rng_t *f_rng, void *p_rng);
/** \ingroup pk_module */
/**
@ -1173,7 +1173,7 @@ int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx,
*/
int mbedtls_pk_parse_keyfile(mbedtls_pk_context *ctx,
const char *path, const char *password,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
mbedtls_f_rng_t *f_rng, void *p_rng);
/** \ingroup pk_module */
/**

View file

@ -159,6 +159,56 @@ MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t;
void mbedtls_platform_zeroize(void *buf, size_t len);
#endif
/** \brief The type of custom random generator (RNG) callbacks.
*
* Many Mbed TLS functions take two parameters
* `mbedtls_f_rng_t *f_rng, void *p_rng`. The
* library will call \c f_rng to generate
* random values.
*
* \note This is typically one of the following:
* - mbedtls_ctr_drbg_random() with \c p_rng
* pointing to a #mbedtls_ctr_drbg_context;
* - mbedtls_hmac_drbg_random() with \c p_rng
* pointing to a #mbedtls_hmac_drbg_context;
* - mbedtls_psa_get_random() with
* `prng = MBEDTLS_PSA_RANDOM_STATE`.
*
* \note Generally, given a call
* `mbedtls_foo(f_rng, p_rng, ....)`, the RNG callback
* and the context only need to remain valid until
* the call to `mbedtls_foo` returns. However, there
* are a few exceptions where the callback is stored
* in for future use. Check the documentation of
* the calling function.
*
* \warning In a multithreaded environment, calling the
* function should be thread-safe. The standard
* functions provided by the library are thread-safe
* when #MBEDTLS_THREADING_C is enabled.
*
* \warning This function must either provide as many
* bytes as requested of **cryptographic quality**
* random data, or return a negative error code.
*
* \param p_rng The \c p_rng argument that was passed along \c f_rng.
* The library always passes \c p_rng unchanged.
* This is typically a pointer to the random generator
* state, or \c NULL if the custom random generator
* doesn't need a context-specific state.
* \param[out] output On success, this must be filled with \p output_size
* bytes of cryptographic-quality random data.
* \param output_size The number of bytes to output.
*
* \return \c 0 on success, or a negative error code on failure.
* Library functions will generally propagate this
* error code, so \c MBEDTLS_ERR_xxx values are
* recommended. #MBEDTLS_ERR_ENTROPY_SOURCE_FAILED is
* typically sensible for RNG failures.
*/
typedef int mbedtls_f_rng_t(void *p_rng,
unsigned char *output, size_t output_size);
#if defined(MBEDTLS_HAVE_TIME_DATE)
/**
* \brief Platform-specific implementation of gmtime_r()

View file

@ -465,7 +465,7 @@ size_t mbedtls_rsa_get_len(const mbedtls_rsa_context *ctx);
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
*/
int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
unsigned int nbits, int exponent);
@ -590,7 +590,7 @@ int mbedtls_rsa_public(mbedtls_rsa_context *ctx,
*
*/
int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
const unsigned char *input,
unsigned char *output);
@ -619,7 +619,7 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
*/
int mbedtls_rsa_pkcs1_encrypt(mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
size_t ilen,
const unsigned char *input,
@ -646,7 +646,7 @@ int mbedtls_rsa_pkcs1_encrypt(mbedtls_rsa_context *ctx,
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
*/
int mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
size_t ilen,
const unsigned char *input,
@ -680,7 +680,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_rsa_context *ctx,
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
*/
int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
const unsigned char *label, size_t label_len,
size_t ilen,
@ -723,7 +723,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx,
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
*/
int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
size_t *olen,
const unsigned char *input,
@ -765,7 +765,7 @@ int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx,
*
*/
int mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
size_t *olen,
const unsigned char *input,
@ -806,7 +806,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_rsa_context *ctx,
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
*/
int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
const unsigned char *label, size_t label_len,
size_t *olen,
@ -849,7 +849,7 @@ int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx,
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
*/
int mbedtls_rsa_pkcs1_sign(mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
mbedtls_md_type_t md_alg,
unsigned int hashlen,
@ -881,7 +881,7 @@ int mbedtls_rsa_pkcs1_sign(mbedtls_rsa_context *ctx,
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
*/
int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
mbedtls_md_type_t md_alg,
unsigned int hashlen,
@ -933,7 +933,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx,
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
*/
int mbedtls_rsa_rsassa_pss_sign_ext(mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
mbedtls_md_type_t md_alg,
unsigned int hashlen,
@ -983,7 +983,7 @@ int mbedtls_rsa_rsassa_pss_sign_ext(mbedtls_rsa_context *ctx,
* \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
*/
int mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng,
mbedtls_md_type_t md_alg,
unsigned int hashlen,

View file

@ -729,6 +729,14 @@ union mbedtls_ssl_premaster_secret {
/* Length in number of bytes of the TLS sequence number */
#define MBEDTLS_SSL_SEQUENCE_NUMBER_LEN 8
/* Helper to state that client_random and server_random need to be stored
* after the handshake is complete. This is required for context serialization
* and for the keying material exporter in TLS 1.2. */
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) || \
(defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) && defined(MBEDTLS_SSL_PROTO_TLS1_2))
#define MBEDTLS_SSL_KEEP_RANDBYTES
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -2247,12 +2255,16 @@ void mbedtls_ssl_conf_verify(mbedtls_ssl_config *conf,
/**
* \brief Set the random number generator callback
*
* \note The callback with its parameter must remain valid as
* long as there is an SSL context that uses the
* SSL configuration.
*
* \param conf SSL configuration
* \param f_rng RNG function (mandatory)
* \param p_rng RNG parameter
*/
void mbedtls_ssl_conf_rng(mbedtls_ssl_config *conf,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**
@ -5767,6 +5779,41 @@ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf,
const unsigned char *random, size_t rlen,
unsigned char *dstbuf, size_t dlen);
#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT)
/* Maximum value for key_len in mbedtls_ssl_export_keying material. Depending on the TLS
* version and the negotiated ciphersuite, larger keys could in principle be exported,
* but for simplicity, we define one limit that works in all cases. TLS 1.3 with SHA256
* has the strictest limit: 255 blocks of SHA256 output, or 8160 bytes. */
#define MBEDTLS_SSL_EXPORT_MAX_KEY_LEN 8160
/**
* \brief TLS-Exporter to derive shared symmetric keys between server and client.
*
* \param ssl SSL context from which to export keys. Must have finished the handshake.
* \param out Output buffer of length at least key_len bytes.
* \param key_len Length of the key to generate in bytes, must be at most
* MBEDTLS_SSL_EXPORT_MAX_KEY_LEN (8160).
* \param label Label for which to generate the key of length label_len.
* \param label_len Length of label in bytes. Must be at most 249 in TLS 1.3.
* \param context Context of the key. Can be NULL if context_len or use_context is 0.
* \param context_len Length of context. Must be < 2^16 in TLS 1.2.
* \param use_context Indicates if a context should be used in deriving the key.
*
* \note TLS 1.2 makes a distinction between a 0-length context and no context.
* This is why the use_context argument exists. TLS 1.3 does not make
* this distinction. If use_context is 0 and TLS 1.3 is used, context and
* context_len are ignored and a 0-length context is used.
*
* \return 0 on success.
* \return MBEDTLS_ERR_SSL_BAD_INPUT_DATA if the handshake is not yet completed.
* \return An SSL-specific error on failure.
*/
int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl,
uint8_t *out, const size_t key_len,
const char *label, const size_t label_len,
const unsigned char *context, const size_t context_len,
const int use_context);
#endif
#ifdef __cplusplus
}
#endif

View file

@ -70,7 +70,7 @@ void mbedtls_ssl_cookie_init(mbedtls_ssl_cookie_ctx *ctx);
* \brief Setup cookie context (generate keys)
*/
int mbedtls_ssl_cookie_setup(mbedtls_ssl_cookie_ctx *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
/**

View file

@ -98,7 +98,9 @@ void mbedtls_ssl_ticket_init(mbedtls_ssl_ticket_context *ctx);
*
* \param ctx Context to be set up
* \param f_rng RNG callback function (mandatory)
* \param p_rng RNG callback context
* \param p_rng RNG callback context.
* Note that the RNG callback must remain valid
* until the ticket context is freed.
* \param cipher AEAD cipher to use for ticket protection.
* Recommended value: MBEDTLS_CIPHER_AES_256_GCM.
* \param lifetime Tickets lifetime in seconds
@ -122,7 +124,7 @@ void mbedtls_ssl_ticket_init(mbedtls_ssl_ticket_context *ctx);
* or a specific MBEDTLS_ERR_XXX error code
*/
int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_f_rng_t *f_rng, void *p_rng,
mbedtls_cipher_type_t cipher,
uint32_t lifetime);

View file

@ -332,7 +332,8 @@ int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn);
* call to mbedtls_asn1_free_named_data_list().
*
* \param[out] head Address in which to store the pointer to the head of the
* allocated list of mbedtls_x509_name
* allocated list of mbedtls_x509_name. Must point to NULL on
* entry.
* \param[in] name The string representation of a DN to convert
*
* \return 0 on success, or a negative error code.

View file

@ -1176,7 +1176,7 @@ void mbedtls_x509write_crt_free(mbedtls_x509write_cert *ctx);
* \note \p f_rng is used for the signature operation.
*/
int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
#if defined(MBEDTLS_PEM_WRITE_C)
@ -1194,7 +1194,7 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, unsigned char *buf, s
* \note \p f_rng is used for the signature operation.
*/
int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
#endif /* MBEDTLS_PEM_WRITE_C */
#endif /* MBEDTLS_X509_CRT_WRITE_C */

View file

@ -349,7 +349,7 @@ void mbedtls_x509write_csr_free(mbedtls_x509write_csr *ctx);
* \note \p f_rng is used for the signature operation.
*/
int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
#if defined(MBEDTLS_PEM_WRITE_C)
@ -368,7 +368,7 @@ int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf, si
* \note \p f_rng is used for the signature operation.
*/
int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
mbedtls_f_rng_t *f_rng,
void *p_rng);
#endif /* MBEDTLS_PEM_WRITE_C */
#endif /* MBEDTLS_X509_CSR_WRITE_C */

View file

@ -59,6 +59,18 @@ extern "C" {
* of integral types defined in "crypto_types.h". */
#include "crypto_values.h"
/* The file "crypto_sizes.h" contains definitions for size calculation
* macros whose definitions are implementation-specific. */
#include "crypto_sizes.h"
/* The file "crypto_struct.h" contains definitions for
* implementation-specific structs that are declared above. */
#if defined(MBEDTLS_PSA_CRYPTO_STRUCT_FILE)
#include MBEDTLS_PSA_CRYPTO_STRUCT_FILE
#else
#include "crypto_struct.h"
#endif
/** \defgroup initialization Library initialization
* @{
*/
@ -4972,18 +4984,6 @@ psa_status_t psa_verify_hash_abort(
}
#endif
/* The file "crypto_sizes.h" contains definitions for size calculation
* macros whose definitions are implementation-specific. */
#include "crypto_sizes.h"
/* The file "crypto_struct.h" contains definitions for
* implementation-specific structs that are declared above. */
#if defined(MBEDTLS_PSA_CRYPTO_STRUCT_FILE)
#include MBEDTLS_PSA_CRYPTO_STRUCT_FILE
#else
#include "crypto_struct.h"
#endif
/* The file "crypto_extra.h" contains vendor-specific definitions. This
* can include vendor-defined algorithms, extra functions, etc. */
#include "crypto_extra.h"

View file

@ -952,6 +952,208 @@ typedef uint32_t psa_pake_primitive_t;
*/
#define PSA_PAKE_STEP_ZK_PROOF ((psa_pake_step_t) 0x03)
/**@}*/
/** A sufficient output buffer size for psa_pake_output().
*
* If the size of the output buffer is at least this large, it is guaranteed
* that psa_pake_output() will not fail due to an insufficient output buffer
* size. The actual size of the output might be smaller in any given call.
*
* See also #PSA_PAKE_OUTPUT_MAX_SIZE
*
* \param alg A PAKE algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_PAKE(\p alg) is true).
* \param primitive A primitive of type ::psa_pake_primitive_t that is
* compatible with algorithm \p alg.
* \param output_step A value of type ::psa_pake_step_t that is valid for the
* algorithm \p alg.
* \return A sufficient output buffer size for the specified
* PAKE algorithm, primitive, and output step. If the
* PAKE algorithm, primitive, or output step is not
* recognized, or the parameters are incompatible,
* return 0.
*/
#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) \
(alg == PSA_ALG_JPAKE && \
primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, \
PSA_ECC_FAMILY_SECP_R1, 256) ? \
( \
output_step == PSA_PAKE_STEP_KEY_SHARE ? 65 : \
output_step == PSA_PAKE_STEP_ZK_PUBLIC ? 65 : \
32 \
) : \
0)
/** A sufficient input buffer size for psa_pake_input().
*
* The value returned by this macro is guaranteed to be large enough for any
* valid input to psa_pake_input() in an operation with the specified
* parameters.
*
* See also #PSA_PAKE_INPUT_MAX_SIZE
*
* \param alg A PAKE algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_PAKE(\p alg) is true).
* \param primitive A primitive of type ::psa_pake_primitive_t that is
* compatible with algorithm \p alg.
* \param input_step A value of type ::psa_pake_step_t that is valid for the
* algorithm \p alg.
* \return A sufficient input buffer size for the specified
* input, cipher suite and algorithm. If the cipher suite,
* the input type or PAKE algorithm is not recognized, or
* the parameters are incompatible, return 0.
*/
#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) \
(alg == PSA_ALG_JPAKE && \
primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, \
PSA_ECC_FAMILY_SECP_R1, 256) ? \
( \
input_step == PSA_PAKE_STEP_KEY_SHARE ? 65 : \
input_step == PSA_PAKE_STEP_ZK_PUBLIC ? 65 : \
32 \
) : \
0)
/** Output buffer size for psa_pake_output() for any of the supported PAKE
* algorithm and primitive suites and output step.
*
* This macro must expand to a compile-time constant integer.
*
* The value of this macro must be at least as large as the largest value
* returned by PSA_PAKE_OUTPUT_SIZE()
*
* See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p output_step).
*/
#define PSA_PAKE_OUTPUT_MAX_SIZE 65
/** Input buffer size for psa_pake_input() for any of the supported PAKE
* algorithm and primitive suites and input step.
*
* This macro must expand to a compile-time constant integer.
*
* The value of this macro must be at least as large as the largest value
* returned by PSA_PAKE_INPUT_SIZE()
*
* See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p output_step).
*/
#define PSA_PAKE_INPUT_MAX_SIZE 65
/** Returns a suitable initializer for a PAKE cipher suite object of type
* psa_pake_cipher_suite_t.
*/
#define PSA_PAKE_CIPHER_SUITE_INIT { PSA_ALG_NONE, 0, 0, 0, PSA_ALG_NONE }
/** Returns a suitable initializer for a PAKE operation object of type
* psa_pake_operation_t.
*/
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
#define PSA_PAKE_OPERATION_INIT { 0 }
#else
#define PSA_PAKE_OPERATION_INIT { 0, PSA_ALG_NONE, 0, PSA_PAKE_OPERATION_STAGE_SETUP, \
{ 0 }, { { 0 } } }
#endif
struct psa_pake_cipher_suite_s {
psa_algorithm_t algorithm;
psa_pake_primitive_type_t type;
psa_pake_family_t family;
uint16_t bits;
psa_algorithm_t hash;
};
struct psa_crypto_driver_pake_inputs_s {
uint8_t *MBEDTLS_PRIVATE(password);
size_t MBEDTLS_PRIVATE(password_len);
uint8_t *MBEDTLS_PRIVATE(user);
size_t MBEDTLS_PRIVATE(user_len);
uint8_t *MBEDTLS_PRIVATE(peer);
size_t MBEDTLS_PRIVATE(peer_len);
psa_key_attributes_t MBEDTLS_PRIVATE(attributes);
struct psa_pake_cipher_suite_s MBEDTLS_PRIVATE(cipher_suite);
};
typedef enum psa_crypto_driver_pake_step {
PSA_JPAKE_STEP_INVALID = 0, /* Invalid step */
PSA_JPAKE_X1_STEP_KEY_SHARE = 1, /* Round 1: input/output key share (for ephemeral private key X1).*/
PSA_JPAKE_X1_STEP_ZK_PUBLIC = 2, /* Round 1: input/output Schnorr NIZKP public key for the X1 key */
PSA_JPAKE_X1_STEP_ZK_PROOF = 3, /* Round 1: input/output Schnorr NIZKP proof for the X1 key */
PSA_JPAKE_X2_STEP_KEY_SHARE = 4, /* Round 1: input/output key share (for ephemeral private key X2).*/
PSA_JPAKE_X2_STEP_ZK_PUBLIC = 5, /* Round 1: input/output Schnorr NIZKP public key for the X2 key */
PSA_JPAKE_X2_STEP_ZK_PROOF = 6, /* Round 1: input/output Schnorr NIZKP proof for the X2 key */
PSA_JPAKE_X2S_STEP_KEY_SHARE = 7, /* Round 2: output X2S key (our key) */
PSA_JPAKE_X2S_STEP_ZK_PUBLIC = 8, /* Round 2: output Schnorr NIZKP public key for the X2S key (our key) */
PSA_JPAKE_X2S_STEP_ZK_PROOF = 9, /* Round 2: output Schnorr NIZKP proof for the X2S key (our key) */
PSA_JPAKE_X4S_STEP_KEY_SHARE = 10, /* Round 2: input X4S key (from peer) */
PSA_JPAKE_X4S_STEP_ZK_PUBLIC = 11, /* Round 2: input Schnorr NIZKP public key for the X4S key (from peer) */
PSA_JPAKE_X4S_STEP_ZK_PROOF = 12 /* Round 2: input Schnorr NIZKP proof for the X4S key (from peer) */
} psa_crypto_driver_pake_step_t;
typedef enum psa_jpake_round {
PSA_JPAKE_FIRST = 0,
PSA_JPAKE_SECOND = 1,
PSA_JPAKE_FINISHED = 2
} psa_jpake_round_t;
typedef enum psa_jpake_io_mode {
PSA_JPAKE_INPUT = 0,
PSA_JPAKE_OUTPUT = 1
} psa_jpake_io_mode_t;
struct psa_jpake_computation_stage_s {
/* The J-PAKE round we are currently on */
psa_jpake_round_t MBEDTLS_PRIVATE(round);
/* The 'mode' we are currently in (inputting or outputting) */
psa_jpake_io_mode_t MBEDTLS_PRIVATE(io_mode);
/* The number of completed inputs so far this round */
uint8_t MBEDTLS_PRIVATE(inputs);
/* The number of completed outputs so far this round */
uint8_t MBEDTLS_PRIVATE(outputs);
/* The next expected step (KEY_SHARE, ZK_PUBLIC or ZK_PROOF) */
psa_pake_step_t MBEDTLS_PRIVATE(step);
};
#define PSA_JPAKE_EXPECTED_INPUTS(round) ((round) == PSA_JPAKE_FINISHED ? 0 : \
((round) == PSA_JPAKE_FIRST ? 2 : 1))
#define PSA_JPAKE_EXPECTED_OUTPUTS(round) ((round) == PSA_JPAKE_FINISHED ? 0 : \
((round) == PSA_JPAKE_FIRST ? 2 : 1))
struct psa_pake_operation_s {
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_psa_client_handle_t handle;
#else
/** Unique ID indicating which driver got assigned to do the
* operation. Since driver contexts are driver-specific, swapping
* drivers halfway through the operation is not supported.
* ID values are auto-generated in psa_crypto_driver_wrappers.h
* ID value zero means the context is not valid or not assigned to
* any driver (i.e. none of the driver contexts are active). */
unsigned int MBEDTLS_PRIVATE(id);
/* Algorithm of the PAKE operation */
psa_algorithm_t MBEDTLS_PRIVATE(alg);
/* A primitive of type compatible with algorithm */
psa_pake_primitive_t MBEDTLS_PRIVATE(primitive);
/* Stage of the PAKE operation: waiting for the setup, collecting inputs
* or computing. */
uint8_t MBEDTLS_PRIVATE(stage);
/* Holds computation stage of the PAKE algorithms. */
union {
uint8_t MBEDTLS_PRIVATE(dummy);
#if defined(PSA_WANT_ALG_JPAKE)
struct psa_jpake_computation_stage_s MBEDTLS_PRIVATE(jpake);
#endif
} MBEDTLS_PRIVATE(computation_stage);
union {
psa_driver_pake_context_t MBEDTLS_PRIVATE(ctx);
struct psa_crypto_driver_pake_inputs_s MBEDTLS_PRIVATE(inputs);
} MBEDTLS_PRIVATE(data);
#endif
};
/** \addtogroup pake
* @{
*/
/** The type of the data structure for PAKE cipher suites.
*
* This is an implementation-defined \c struct. Applications should not
@ -1658,114 +1860,6 @@ psa_status_t psa_pake_abort(psa_pake_operation_t *operation);
/**@}*/
/** A sufficient output buffer size for psa_pake_output().
*
* If the size of the output buffer is at least this large, it is guaranteed
* that psa_pake_output() will not fail due to an insufficient output buffer
* size. The actual size of the output might be smaller in any given call.
*
* See also #PSA_PAKE_OUTPUT_MAX_SIZE
*
* \param alg A PAKE algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_PAKE(\p alg) is true).
* \param primitive A primitive of type ::psa_pake_primitive_t that is
* compatible with algorithm \p alg.
* \param output_step A value of type ::psa_pake_step_t that is valid for the
* algorithm \p alg.
* \return A sufficient output buffer size for the specified
* PAKE algorithm, primitive, and output step. If the
* PAKE algorithm, primitive, or output step is not
* recognized, or the parameters are incompatible,
* return 0.
*/
#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) \
(alg == PSA_ALG_JPAKE && \
primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, \
PSA_ECC_FAMILY_SECP_R1, 256) ? \
( \
output_step == PSA_PAKE_STEP_KEY_SHARE ? 65 : \
output_step == PSA_PAKE_STEP_ZK_PUBLIC ? 65 : \
32 \
) : \
0)
/** A sufficient input buffer size for psa_pake_input().
*
* The value returned by this macro is guaranteed to be large enough for any
* valid input to psa_pake_input() in an operation with the specified
* parameters.
*
* See also #PSA_PAKE_INPUT_MAX_SIZE
*
* \param alg A PAKE algorithm (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_PAKE(\p alg) is true).
* \param primitive A primitive of type ::psa_pake_primitive_t that is
* compatible with algorithm \p alg.
* \param input_step A value of type ::psa_pake_step_t that is valid for the
* algorithm \p alg.
* \return A sufficient input buffer size for the specified
* input, cipher suite and algorithm. If the cipher suite,
* the input type or PAKE algorithm is not recognized, or
* the parameters are incompatible, return 0.
*/
#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) \
(alg == PSA_ALG_JPAKE && \
primitive == PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, \
PSA_ECC_FAMILY_SECP_R1, 256) ? \
( \
input_step == PSA_PAKE_STEP_KEY_SHARE ? 65 : \
input_step == PSA_PAKE_STEP_ZK_PUBLIC ? 65 : \
32 \
) : \
0)
/** Output buffer size for psa_pake_output() for any of the supported PAKE
* algorithm and primitive suites and output step.
*
* This macro must expand to a compile-time constant integer.
*
* The value of this macro must be at least as large as the largest value
* returned by PSA_PAKE_OUTPUT_SIZE()
*
* See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p output_step).
*/
#define PSA_PAKE_OUTPUT_MAX_SIZE 65
/** Input buffer size for psa_pake_input() for any of the supported PAKE
* algorithm and primitive suites and input step.
*
* This macro must expand to a compile-time constant integer.
*
* The value of this macro must be at least as large as the largest value
* returned by PSA_PAKE_INPUT_SIZE()
*
* See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p output_step).
*/
#define PSA_PAKE_INPUT_MAX_SIZE 65
/** Returns a suitable initializer for a PAKE cipher suite object of type
* psa_pake_cipher_suite_t.
*/
#define PSA_PAKE_CIPHER_SUITE_INIT { PSA_ALG_NONE, 0, 0, 0, PSA_ALG_NONE }
/** Returns a suitable initializer for a PAKE operation object of type
* psa_pake_operation_t.
*/
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
#define PSA_PAKE_OPERATION_INIT { 0 }
#else
#define PSA_PAKE_OPERATION_INIT { 0, PSA_ALG_NONE, 0, PSA_PAKE_OPERATION_STAGE_SETUP, \
{ 0 }, { { 0 } } }
#endif
struct psa_pake_cipher_suite_s {
psa_algorithm_t algorithm;
psa_pake_primitive_type_t type;
psa_pake_family_t family;
uint16_t bits;
psa_algorithm_t hash;
};
static inline psa_algorithm_t psa_pake_cs_get_algorithm(
const psa_pake_cipher_suite_t *cipher_suite)
{
@ -1827,94 +1921,6 @@ static inline void psa_pake_cs_set_hash(psa_pake_cipher_suite_t *cipher_suite,
}
}
struct psa_crypto_driver_pake_inputs_s {
uint8_t *MBEDTLS_PRIVATE(password);
size_t MBEDTLS_PRIVATE(password_len);
uint8_t *MBEDTLS_PRIVATE(user);
size_t MBEDTLS_PRIVATE(user_len);
uint8_t *MBEDTLS_PRIVATE(peer);
size_t MBEDTLS_PRIVATE(peer_len);
psa_key_attributes_t MBEDTLS_PRIVATE(attributes);
psa_pake_cipher_suite_t MBEDTLS_PRIVATE(cipher_suite);
};
typedef enum psa_crypto_driver_pake_step {
PSA_JPAKE_STEP_INVALID = 0, /* Invalid step */
PSA_JPAKE_X1_STEP_KEY_SHARE = 1, /* Round 1: input/output key share (for ephemeral private key X1).*/
PSA_JPAKE_X1_STEP_ZK_PUBLIC = 2, /* Round 1: input/output Schnorr NIZKP public key for the X1 key */
PSA_JPAKE_X1_STEP_ZK_PROOF = 3, /* Round 1: input/output Schnorr NIZKP proof for the X1 key */
PSA_JPAKE_X2_STEP_KEY_SHARE = 4, /* Round 1: input/output key share (for ephemeral private key X2).*/
PSA_JPAKE_X2_STEP_ZK_PUBLIC = 5, /* Round 1: input/output Schnorr NIZKP public key for the X2 key */
PSA_JPAKE_X2_STEP_ZK_PROOF = 6, /* Round 1: input/output Schnorr NIZKP proof for the X2 key */
PSA_JPAKE_X2S_STEP_KEY_SHARE = 7, /* Round 2: output X2S key (our key) */
PSA_JPAKE_X2S_STEP_ZK_PUBLIC = 8, /* Round 2: output Schnorr NIZKP public key for the X2S key (our key) */
PSA_JPAKE_X2S_STEP_ZK_PROOF = 9, /* Round 2: output Schnorr NIZKP proof for the X2S key (our key) */
PSA_JPAKE_X4S_STEP_KEY_SHARE = 10, /* Round 2: input X4S key (from peer) */
PSA_JPAKE_X4S_STEP_ZK_PUBLIC = 11, /* Round 2: input Schnorr NIZKP public key for the X4S key (from peer) */
PSA_JPAKE_X4S_STEP_ZK_PROOF = 12 /* Round 2: input Schnorr NIZKP proof for the X4S key (from peer) */
} psa_crypto_driver_pake_step_t;
typedef enum psa_jpake_round {
PSA_JPAKE_FIRST = 0,
PSA_JPAKE_SECOND = 1,
PSA_JPAKE_FINISHED = 2
} psa_jpake_round_t;
typedef enum psa_jpake_io_mode {
PSA_JPAKE_INPUT = 0,
PSA_JPAKE_OUTPUT = 1
} psa_jpake_io_mode_t;
struct psa_jpake_computation_stage_s {
/* The J-PAKE round we are currently on */
psa_jpake_round_t MBEDTLS_PRIVATE(round);
/* The 'mode' we are currently in (inputting or outputting) */
psa_jpake_io_mode_t MBEDTLS_PRIVATE(io_mode);
/* The number of completed inputs so far this round */
uint8_t MBEDTLS_PRIVATE(inputs);
/* The number of completed outputs so far this round */
uint8_t MBEDTLS_PRIVATE(outputs);
/* The next expected step (KEY_SHARE, ZK_PUBLIC or ZK_PROOF) */
psa_pake_step_t MBEDTLS_PRIVATE(step);
};
#define PSA_JPAKE_EXPECTED_INPUTS(round) ((round) == PSA_JPAKE_FINISHED ? 0 : \
((round) == PSA_JPAKE_FIRST ? 2 : 1))
#define PSA_JPAKE_EXPECTED_OUTPUTS(round) ((round) == PSA_JPAKE_FINISHED ? 0 : \
((round) == PSA_JPAKE_FIRST ? 2 : 1))
struct psa_pake_operation_s {
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C)
mbedtls_psa_client_handle_t handle;
#else
/** Unique ID indicating which driver got assigned to do the
* operation. Since driver contexts are driver-specific, swapping
* drivers halfway through the operation is not supported.
* ID values are auto-generated in psa_crypto_driver_wrappers.h
* ID value zero means the context is not valid or not assigned to
* any driver (i.e. none of the driver contexts are active). */
unsigned int MBEDTLS_PRIVATE(id);
/* Algorithm of the PAKE operation */
psa_algorithm_t MBEDTLS_PRIVATE(alg);
/* A primitive of type compatible with algorithm */
psa_pake_primitive_t MBEDTLS_PRIVATE(primitive);
/* Stage of the PAKE operation: waiting for the setup, collecting inputs
* or computing. */
uint8_t MBEDTLS_PRIVATE(stage);
/* Holds computation stage of the PAKE algorithms. */
union {
uint8_t MBEDTLS_PRIVATE(dummy);
#if defined(PSA_WANT_ALG_JPAKE)
psa_jpake_computation_stage_t MBEDTLS_PRIVATE(jpake);
#endif
} MBEDTLS_PRIVATE(computation_stage);
union {
psa_driver_pake_context_t MBEDTLS_PRIVATE(ctx);
psa_crypto_driver_pake_inputs_t MBEDTLS_PRIVATE(inputs);
} MBEDTLS_PRIVATE(data);
#endif
};
static inline struct psa_pake_cipher_suite_s psa_pake_cipher_suite_init(void)
{
const struct psa_pake_cipher_suite_s v = PSA_PAKE_CIPHER_SUITE_INIT;

View file

@ -48,8 +48,19 @@
*/
int mbedtls_aesni_has_support(unsigned int what)
{
static int done = 0;
static unsigned int c = 0;
/* To avoid a race condition, tell the compiler that the assignment
* `done = 1` and the assignment to `c` may not be reordered.
* https://github.com/Mbed-TLS/mbedtls/issues/9840
*
* Note that we may also be worried about memory access reordering,
* but fortunately the x86 memory model is not too wild: stores
* from the same thread are observed consistently by other threads.
* (See example 8-1 in Sewell et al., "x86-TSO: A Rigorous and Usable
* Programmers Model for x86 Multiprocessors", CACM, 2010,
* https://www.cl.cam.ac.uk/~pes20/weakmemory/cacm.pdf)
*/
static volatile int done = 0;
static volatile unsigned int c = 0;
if (!done) {
#if MBEDTLS_AESNI_HAVE_CODE == 2

View file

@ -90,7 +90,9 @@ int mbedtls_asn1_write_raw_buffer(unsigned char **p, const unsigned char *start,
len = size;
(*p) -= len;
if (len != 0) {
memcpy(*p, buf, len);
}
return (int) len;
}
@ -412,6 +414,7 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
} else if (val_len == 0) {
mbedtls_free(cur->val.p);
cur->val.p = NULL;
cur->val.len = 0;
} else if (cur->val.len != val_len) {
/*
* Enlarge existing value buffer if needed

View file

@ -14,6 +14,7 @@
#include "mbedtls/base64.h"
#include "base64_internal.h"
#include "constant_time_internal.h"
#include "mbedtls/error.h"
#include <stdint.h>
@ -183,49 +184,72 @@ int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen,
n++;
}
if (n == 0) {
*olen = 0;
return 0;
/* In valid base64, the number of digits (n-equals) is always of the form
* 4*k, 4*k+2 or *4k+3. Also, the number n of digits plus the number of
* equal signs at the end is always a multiple of 4. */
if ((n - equals) % 4 == 1) {
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
}
if (n % 4 != 0) {
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
}
/* The following expression is to calculate the following formula without
* risk of integer overflow in n:
* n = ( ( n * 6 ) + 7 ) >> 3;
/* We've determined that the input is valid, and that it contains
* exactly k blocks of digits-or-equals, with n = 4 * k,
* and equals only present at the end of the last block if at all.
* Now we can calculate the length of the output.
*
* Each block of 4 digits in the input map to 3 bytes of output.
* For the last block:
* - abcd (where abcd are digits) is a full 3-byte block;
* - abc= means 1 byte less than a full 3-byte block of output;
* - ab== means 2 bytes less than a full 3-byte block of output;
* - a==== and ==== is rejected above.
*/
n = (6 * (n >> 3)) + ((6 * (n & 0x7) + 7) >> 3);
n -= equals;
*olen = (n / 4) * 3 - equals;
if (dst == NULL || dlen < n) {
*olen = n;
/* If the output buffer is too small, signal this and stop here.
* Also, as documented, stop here if `dst` is null, independently of
* `dlen`.
*
* There is an edge case when the output is empty: in this case,
* `dlen == 0` with `dst == NULL` is valid (on some platforms,
* `malloc(0)` returns `NULL`). Since the call is valid, we return
* 0 in this case.
*/
if ((*olen != 0 && dst == NULL) || dlen < *olen) {
return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
}
equals = 0;
for (x = 0, p = dst; i > 0; i--, src++) {
if (*src == '\r' || *src == '\n' || *src == ' ') {
continue;
}
x = x << 6;
if (*src == '=') {
++equals;
} else {
x |= mbedtls_ct_base64_dec_value(*src);
/* We already know from the first loop that equal signs are
* only at the end. */
break;
}
x = x << 6;
x |= mbedtls_ct_base64_dec_value(*src);
if (++accumulated_digits == 4) {
accumulated_digits = 0;
*p++ = MBEDTLS_BYTE_2(x);
if (equals <= 1) {
*p++ = MBEDTLS_BYTE_1(x);
}
if (equals <= 0) {
*p++ = MBEDTLS_BYTE_0(x);
}
}
if (accumulated_digits == 3) {
*p++ = MBEDTLS_BYTE_2(x << 6);
*p++ = MBEDTLS_BYTE_1(x << 6);
} else if (accumulated_digits == 2) {
*p++ = MBEDTLS_BYTE_2(x << 12);
}
*olen = (size_t) (p - dst);
if (*olen != (size_t) (p - dst)) {
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
}
return 0;
}

View file

@ -14,6 +14,7 @@
#if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher.h"
#include "cipher_invasive.h"
#include "cipher_wrap.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
@ -838,7 +839,13 @@ static void add_pkcs_padding(unsigned char *output, size_t output_len,
}
}
static int get_pkcs_padding(unsigned char *input, size_t input_len,
/*
* Get the length of the PKCS7 padding.
*
* Note: input_len must be the block size of the cipher.
*/
MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input,
size_t input_len,
size_t *data_len)
{
size_t i, pad_idx;
@ -849,10 +856,6 @@ static int get_pkcs_padding(unsigned char *input, size_t input_len,
}
padding_len = input[input_len - 1];
if (padding_len == 0 || padding_len > input_len) {
return MBEDTLS_ERR_CIPHER_INVALID_PADDING;
}
*data_len = input_len - padding_len;
mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len);
bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
@ -866,6 +869,9 @@ static int get_pkcs_padding(unsigned char *input, size_t input_len,
bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different));
}
/* If the padding is invalid, set the output length to 0 */
*data_len = mbedtls_ct_if(bad, 0, input_len - padding_len);
return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING);
}
#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
@ -1144,7 +1150,7 @@ int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx,
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
case MBEDTLS_PADDING_PKCS7:
ctx->add_padding = add_pkcs_padding;
ctx->get_padding = get_pkcs_padding;
ctx->get_padding = mbedtls_get_pkcs_padding;
break;
#endif
#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)

View file

@ -0,0 +1,27 @@
/**
* \file cipher_invasive.h
*
* \brief Cipher module: interfaces for invasive testing only.
*
* The interfaces in this file are intended for testing purposes only.
* They SHOULD NOT be made available in library integrations except when
* building the library for testing.
*/
/*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_CIPHER_INVASIVE_H
#define MBEDTLS_CIPHER_INVASIVE_H
#include "common.h"
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_CIPHER_C)
MBEDTLS_STATIC_TESTABLE int mbedtls_get_pkcs_padding(unsigned char *input,
size_t input_len,
size_t *data_len);
#endif
#endif /* MBEDTLS_CIPHER_INVASIVE_H */

View file

@ -2425,7 +2425,7 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
sizeof(mbedtls_cipher_definitions[0]))
int mbedtls_cipher_supported[NUM_CIPHERS];
const mbedtls_cipher_base_t *mbedtls_cipher_base_lookup_table[] = {
const mbedtls_cipher_base_t * const mbedtls_cipher_base_lookup_table[] = {
#if defined(MBEDTLS_AES_C)
[MBEDTLS_CIPHER_BASE_INDEX_AES] = &aes_info,
#endif

View file

@ -169,7 +169,7 @@ extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
extern int mbedtls_cipher_supported[];
extern const mbedtls_cipher_base_t *mbedtls_cipher_base_lookup_table[];
extern const mbedtls_cipher_base_t * const mbedtls_cipher_base_lookup_table[];
#ifdef __cplusplus
}

View file

@ -434,4 +434,20 @@ static inline void mbedtls_xor_no_simd(unsigned char *r,
# define MBEDTLS_MAYBE_UNUSED
#endif
/* GCC >= 15 has a warning 'unterminated-string-initialization' which complains if you initialize
* a string into an array without space for a terminating NULL character. In some places in the
* codebase this behaviour is intended, so we add the macro MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING
* to suppress the warning in these places.
*/
#if defined(__has_attribute)
#if __has_attribute(nonstring)
#define MBEDTLS_HAS_ATTRIBUTE_NONSTRING
#endif /* __has_attribute(nonstring) */
#endif /* __has_attribute */
#if defined(MBEDTLS_HAS_ATTRIBUTE_NONSTRING)
#define MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING __attribute__((nonstring))
#else
#define MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING
#endif /* MBEDTLS_HAS_ATTRIBUTE_NONSTRING */
#endif /* MBEDTLS_LIBRARY_COMMON_H */

View file

@ -243,7 +243,10 @@ exit:
#if defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C)
static int pem_check_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len)
{
/* input_len > 0 is guaranteed by mbedtls_pem_read_buffer(). */
/* input_len > 0 is not guaranteed by mbedtls_pem_read_buffer(). */
if (input_len < 1) {
return MBEDTLS_ERR_PEM_INVALID_DATA;
}
size_t pad_len = input[input_len - 1];
size_t i;

View file

@ -2400,8 +2400,11 @@ psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
goto exit;
}
/* Ensure all of the context is zeroized, since PSA_HASH_OPERATION_INIT only
* directly zeroes the int-sized dummy member of the context union. */
/* Make sure the driver-dependent part of the operation is zeroed.
* This is a guarantee we make to drivers. Initializing the operation
* does not necessarily take care of it, since the context is a
* union and initializing a union does not necessarily initialize
* all of its members. */
memset(&operation->ctx, 0, sizeof(operation->ctx));
status = psa_driver_wrapper_hash_setup(operation, alg);
@ -2596,6 +2599,13 @@ psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
return PSA_ERROR_BAD_STATE;
}
/* Make sure the driver-dependent part of the operation is zeroed.
* This is a guarantee we make to drivers. Initializing the operation
* does not necessarily take care of it, since the context is a
* union and initializing a union does not necessarily initialize
* all of its members. */
memset(&target_operation->ctx, 0, sizeof(target_operation->ctx));
psa_status_t status = psa_driver_wrapper_hash_clone(source_operation,
target_operation);
if (status != PSA_SUCCESS) {
@ -2693,6 +2703,13 @@ static psa_status_t psa_mac_setup(psa_mac_operation_t *operation,
goto exit;
}
/* Make sure the driver-dependent part of the operation is zeroed.
* This is a guarantee we make to drivers. Initializing the operation
* does not necessarily take care of it, since the context is a
* union and initializing a union does not necessarily initialize
* all of its members. */
memset(&operation->ctx, 0, sizeof(operation->ctx));
status = psa_get_and_lock_key_slot_with_policy(
key,
&slot,
@ -3619,6 +3636,13 @@ psa_status_t psa_sign_hash_start(
return PSA_ERROR_BAD_STATE;
}
/* Make sure the driver-dependent part of the operation is zeroed.
* This is a guarantee we make to drivers. Initializing the operation
* does not necessarily take care of it, since the context is a
* union and initializing a union does not necessarily initialize
* all of its members. */
memset(&operation->ctx, 0, sizeof(operation->ctx));
status = psa_sign_verify_check_alg(0, alg);
if (status != PSA_SUCCESS) {
operation->error_occurred = 1;
@ -3779,6 +3803,13 @@ psa_status_t psa_verify_hash_start(
return PSA_ERROR_BAD_STATE;
}
/* Make sure the driver-dependent part of the operation is zeroed.
* This is a guarantee we make to drivers. Initializing the operation
* does not necessarily take care of it, since the context is a
* union and initializing a union does not necessarily initialize
* all of its members. */
memset(&operation->ctx, 0, sizeof(operation->ctx));
status = psa_sign_verify_check_alg(0, alg);
if (status != PSA_SUCCESS) {
operation->error_occurred = 1;
@ -4446,6 +4477,14 @@ static psa_status_t psa_cipher_setup(psa_cipher_operation_t *operation,
}
operation->default_iv_length = PSA_CIPHER_IV_LENGTH(slot->attr.type, alg);
/* Make sure the driver-dependent part of the operation is zeroed.
* This is a guarantee we make to drivers. Initializing the operation
* does not necessarily take care of it, since the context is a
* union and initializing a union does not necessarily initialize
* all of its members. */
memset(&operation->ctx, 0, sizeof(operation->ctx));
/* Try doing the operation through a driver before using software fallback. */
if (cipher_operation == MBEDTLS_ENCRYPT) {
status = psa_driver_wrapper_cipher_encrypt_setup(operation,
@ -5079,6 +5118,13 @@ static psa_status_t psa_aead_setup(psa_aead_operation_t *operation,
goto exit;
}
/* Make sure the driver-dependent part of the operation is zeroed.
* This is a guarantee we make to drivers. Initializing the operation
* does not necessarily take care of it, since the context is a
* union and initializing a union does not necessarily initialize
* all of its members. */
memset(&operation->ctx, 0, sizeof(operation->ctx));
if (is_encrypt) {
key_usage = PSA_KEY_USAGE_ENCRYPT;
} else {
@ -5585,7 +5631,7 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
}
/****************************************************************/
/* Generators */
/* Key derivation: output generation */
/****************************************************************/
#if defined(BUILTIN_ALG_ANY_HKDF) || \
@ -5599,6 +5645,17 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
#if defined(BUILTIN_ALG_ANY_HKDF) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
/** Internal helper to set up an HMAC operation with a key passed directly.
*
* \param[in,out] operation A MAC operation object. It does not need to
* be initialized.
* \param hash_alg The hash algorithm used for HMAC.
* \param hmac_key The HMAC key.
* \param hmac_key_length Length of \p hmac_key in bytes.
*
* \return A PSA status code.
*/
static psa_status_t psa_key_derivation_start_hmac(
psa_mac_operation_t *operation,
psa_algorithm_t hash_alg,
@ -5611,6 +5668,14 @@ static psa_status_t psa_key_derivation_start_hmac(
psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(hmac_key_length));
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
/* Make sure the whole the operation is zeroed.
* It isn't enough to require the caller to initialize operation to
* PSA_MAC_OPERATION_INIT, since one field is a union and initializing
* a union does not necessarily initialize all of its members.
* psa_mac_setup() would handle PSA_MAC_OPERATION_INIT, but here we
* bypass it and call lower-level functions directly. */
memset(operation, 0, sizeof(*operation));
operation->is_sign = 1;
operation->mac_size = PSA_HASH_LENGTH(hash_alg);
@ -5835,7 +5900,7 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
{
psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(alg);
uint8_t hash_length = PSA_HASH_LENGTH(hash_alg);
psa_mac_operation_t hmac = PSA_MAC_OPERATION_INIT;
psa_mac_operation_t hmac;
size_t hmac_output_length;
psa_status_t status, cleanup_status;
@ -6036,7 +6101,14 @@ static psa_status_t psa_key_derivation_pbkdf2_generate_block(
psa_key_attributes_t *attributes)
{
psa_status_t status;
psa_mac_operation_t mac_operation = PSA_MAC_OPERATION_INIT;
psa_mac_operation_t mac_operation;
/* Make sure the whole the operation is zeroed.
* PSA_MAC_OPERATION_INIT does not necessarily do it fully,
* since one field is a union and initializing a union does not
* necessarily initialize all of its members.
* psa_mac_setup() would do it, but here we bypass it and call
* lower-level functions directly. */
memset(&mac_operation, 0, sizeof(mac_operation));
size_t mac_output_length;
uint8_t U_i[PSA_MAC_MAX_SIZE];
uint8_t *U_accumulator = pbkdf2->output_block;
@ -6667,7 +6739,7 @@ psa_status_t psa_key_derivation_output_key(
/****************************************************************/
/* Key derivation */
/* Key derivation: operation management */
/****************************************************************/
#if defined(AT_LEAST_ONE_BUILTIN_KDF)
@ -8222,6 +8294,8 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
key);
}
/****************************************************************/
/* Module setup */
/****************************************************************/
@ -8497,6 +8571,12 @@ exit:
return status;
}
/****************************************************************/
/* PAKE */
/****************************************************************/
#if defined(PSA_WANT_ALG_SOME_PAKE)
psa_status_t psa_crypto_driver_pake_get_password_len(
const psa_crypto_driver_pake_inputs_t *inputs,
@ -8621,7 +8701,11 @@ psa_status_t psa_pake_setup(
goto exit;
}
memset(&operation->data.inputs, 0, sizeof(operation->data.inputs));
/* Make sure the variable-purpose part of the operation is zeroed.
* Initializing the operation does not necessarily take care of it,
* since the context is a union and initializing a union does not
* necessarily initialize all of its members. */
memset(&operation->data, 0, sizeof(operation->data));
operation->alg = cipher_suite->algorithm;
operation->primitive = PSA_PAKE_PRIMITIVE(cipher_suite->type,

View file

@ -465,6 +465,15 @@ psa_status_t mbedtls_psa_mac_compute(
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
mbedtls_psa_mac_operation_t operation = MBEDTLS_PSA_MAC_OPERATION_INIT;
/* Make sure the whole operation is zeroed.
* PSA_MAC_OPERATION_INIT does not necessarily do it fully,
* since one field is a union and initializing a union does not
* necessarily initialize all of its members.
* In multipart operations, this is done in the API functions,
* before driver dispatch, since it needs to be done before calling
* the driver entry point. Here, we bypass the multipart API,
* so it's our job. */
memset(&operation, 0, sizeof(operation));
status = psa_mac_setup(&operation,
attributes, key_buffer, key_buffer_size,

View file

@ -663,7 +663,7 @@ psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
/* Refresh slot_idx, for when the slot is not the original
* selected_slot but rather unused_persistent_key_slot. */
slot_idx = selected_slot - global_data.key_slots;
*volatile_key_id = PSA_KEY_ID_VOLATILE_MIN + slot_idx;
*volatile_key_id = PSA_KEY_ID_VOLATILE_MIN + (psa_key_id_t) slot_idx;
}
#endif
*p_slot = selected_slot;

View file

@ -16,6 +16,9 @@
#include "mbedtls/error.h"
#include "mbedtls/ssl.h"
#include "mbedtls/debug.h"
#include "debug_internal.h"
#include "mbedtls/cipher.h"
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
@ -1163,14 +1166,15 @@ struct mbedtls_ssl_transform {
unsigned char out_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX];
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
#if defined(MBEDTLS_SSL_KEEP_RANDBYTES)
/* We need the Hello random bytes in order to re-derive keys from the
* Master Secret and other session info,
* see ssl_tls12_populate_transform() */
* Master Secret and other session info and for the keying material
* exporter in TLS 1.2.
* See ssl_tls12_populate_transform() */
unsigned char randbytes[MBEDTLS_SERVER_HELLO_RANDOM_LEN +
MBEDTLS_CLIENT_HELLO_RANDOM_LEN];
/*!< ServerHello.random+ClientHello.random */
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
#endif /* defined(MBEDTLS_SSL_KEEP_RANDBYTES) */
};
/*
@ -1333,12 +1337,30 @@ int mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl);
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl);
void mbedtls_ssl_handshake_wrapup(mbedtls_ssl_context *ssl);
#if defined(MBEDTLS_DEBUG_C)
/* Declared in "ssl_debug_helpers.h". We can't include this file from
* "ssl_misc.h" because it includes "ssl_misc.h" because it needs some
* type definitions. TODO: split the type definitions and the helper
* functions into different headers.
*/
const char *mbedtls_ssl_states_str(mbedtls_ssl_states state);
#endif
static inline void mbedtls_ssl_handshake_set_state(mbedtls_ssl_context *ssl,
mbedtls_ssl_states state)
{
MBEDTLS_SSL_DEBUG_MSG(3, ("handshake state: %d (%s) -> %d (%s)",
ssl->state, mbedtls_ssl_states_str(ssl->state),
(int) state, mbedtls_ssl_states_str(state)));
ssl->state = (int) state;
}
static inline void mbedtls_ssl_handshake_increment_state(mbedtls_ssl_context *ssl)
{
mbedtls_ssl_handshake_set_state(ssl, ssl->state + 1);
}
MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context *ssl);

View file

@ -3971,6 +3971,7 @@ static int ssl_parse_record_header(mbedtls_ssl_context const *ssl,
rec->buf_len = rec->data_offset + rec->data_len;
if (rec->data_len == 0) {
MBEDTLS_SSL_DEBUG_MSG(1, ("rejecting empty record"));
return MBEDTLS_ERR_SSL_INVALID_RECORD;
}
@ -5318,7 +5319,7 @@ int mbedtls_ssl_write_change_cipher_spec(mbedtls_ssl_context *ssl)
ssl->out_msglen = 1;
ssl->out_msg[0] = 1;
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
@ -5380,7 +5381,7 @@ int mbedtls_ssl_parse_change_cipher_spec(mbedtls_ssl_context *ssl)
mbedtls_ssl_update_in_pointers(ssl);
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse change cipher spec"));

View file

@ -19,6 +19,7 @@
#include "ssl_client.h"
#include "ssl_debug_helpers.h"
#include "ssl_misc.h"
#include "ssl_tls13_keys.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
@ -1554,7 +1555,7 @@ int mbedtls_ssl_session_reset_int(mbedtls_ssl_context *ssl, int partial)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HELLO_REQUEST);
ssl->tls_version = ssl->conf->max_tls_version;
mbedtls_ssl_session_reset_msg_layer(ssl, partial);
@ -4587,7 +4588,7 @@ int mbedtls_ssl_handshake_step(mbedtls_ssl_context *ssl)
switch (ssl->state) {
case MBEDTLS_SSL_HELLO_REQUEST:
ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
ret = 0;
break;
@ -4738,7 +4739,7 @@ int mbedtls_ssl_start_renegotiation(mbedtls_ssl_context *ssl)
}
#endif
ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HELLO_REQUEST);
ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS;
if ((ret = mbedtls_ssl_handshake(ssl)) != 0) {
@ -5521,7 +5522,7 @@ static int ssl_context_load(mbedtls_ssl_context *ssl,
* Most of them already set to the correct value by mbedtls_ssl_init() and
* mbedtls_ssl_reset(), so we only need to set the remaining ones.
*/
ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER);
ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
/* Adjust pointers for header fields of outgoing records to
@ -5761,7 +5762,7 @@ static const uint16_t ssl_preset_default_sig_algs[] = {
/* NOTICE: see above */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
static uint16_t ssl_tls12_preset_default_sig_algs[] = {
static const uint16_t ssl_tls12_preset_default_sig_algs[] = {
#if defined(MBEDTLS_MD_CAN_SHA512)
#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
@ -5825,7 +5826,7 @@ static const uint16_t ssl_preset_suiteb_sig_algs[] = {
/* NOTICE: see above */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
static uint16_t ssl_tls12_preset_suiteb_sig_algs[] = {
static const uint16_t ssl_tls12_preset_suiteb_sig_algs[] = {
#if defined(MBEDTLS_MD_CAN_SHA256)
#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
@ -6768,7 +6769,7 @@ static psa_status_t setup_psa_key_derivation(psa_key_derivation_operation_t *der
MBEDTLS_CHECK_RETURN_CRITICAL
static int tls_prf_generic(mbedtls_md_type_t md_type,
const unsigned char *secret, size_t slen,
const char *label,
const char *label, size_t label_len,
const unsigned char *random, size_t rlen,
unsigned char *dstbuf, size_t dlen)
{
@ -6808,7 +6809,7 @@ static int tls_prf_generic(mbedtls_md_type_t md_type,
NULL, 0,
random, rlen,
(unsigned char const *) label,
(size_t) strlen(label),
label_len,
NULL, 0,
dlen);
if (status != PSA_SUCCESS) {
@ -6848,7 +6849,7 @@ static int tls_prf_generic(mbedtls_md_type_t md_type,
MBEDTLS_CHECK_RETURN_CRITICAL
static int tls_prf_generic(mbedtls_md_type_t md_type,
const unsigned char *secret, size_t slen,
const char *label,
const char *label, size_t label_len,
const unsigned char *random, size_t rlen,
unsigned char *dstbuf, size_t dlen)
{
@ -6869,14 +6870,14 @@ static int tls_prf_generic(mbedtls_md_type_t md_type,
md_len = mbedtls_md_get_size(md_info);
tmp_len = md_len + strlen(label) + rlen;
tmp_len = md_len + label_len + rlen;
tmp = mbedtls_calloc(1, tmp_len);
if (tmp == NULL) {
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto exit;
}
nb = strlen(label);
nb = label_len;
memcpy(tmp + md_len, label, nb);
memcpy(tmp + md_len + nb, random, rlen);
nb += rlen;
@ -6959,7 +6960,7 @@ static int tls_prf_sha256(const unsigned char *secret, size_t slen,
unsigned char *dstbuf, size_t dlen)
{
return tls_prf_generic(MBEDTLS_MD_SHA256, secret, slen,
label, random, rlen, dstbuf, dlen);
label, strlen(label), random, rlen, dstbuf, dlen);
}
#endif /* MBEDTLS_MD_CAN_SHA256*/
@ -6971,7 +6972,7 @@ static int tls_prf_sha384(const unsigned char *secret, size_t slen,
unsigned char *dstbuf, size_t dlen)
{
return tls_prf_generic(MBEDTLS_MD_SHA384, secret, slen,
label, random, rlen, dstbuf, dlen);
label, strlen(label), random, rlen, dstbuf, dlen);
}
#endif /* MBEDTLS_MD_CAN_SHA384*/
@ -7576,7 +7577,7 @@ int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl)
if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
@ -7593,7 +7594,7 @@ int mbedtls_ssl_parse_certificate(mbedtls_ssl_context *ssl)
if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
@ -7616,7 +7617,7 @@ int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl)
if (!mbedtls_ssl_ciphersuite_uses_srv_cert(ciphersuite_info)) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
@ -7624,7 +7625,7 @@ int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl)
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
if (ssl->handshake->client_auth == 0) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
}
@ -7678,7 +7679,7 @@ int mbedtls_ssl_write_certificate(mbedtls_ssl_context *ssl)
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE;
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
@ -8136,7 +8137,7 @@ crt_verify:
exit:
if (ret == 0) {
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
}
#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
@ -8352,7 +8353,7 @@ void mbedtls_ssl_handshake_wrapup(mbedtls_ssl_context *ssl)
#endif
mbedtls_ssl_handshake_wrapup_free_hs_transform(ssl);
ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER);
MBEDTLS_SSL_DEBUG_MSG(3, ("<= handshake wrapup"));
}
@ -8396,16 +8397,16 @@ int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl)
if (ssl->handshake->resume != 0) {
#if defined(MBEDTLS_SSL_CLI_C)
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP);
}
#endif
#if defined(MBEDTLS_SSL_SRV_C)
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC);
}
#endif
} else {
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
}
/*
@ -8531,16 +8532,16 @@ int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl)
if (ssl->handshake->resume != 0) {
#if defined(MBEDTLS_SSL_CLI_C)
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC);
}
#endif
#if defined(MBEDTLS_SSL_SRV_C)
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER) {
ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP);
}
#endif
} else {
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
@ -8668,7 +8669,7 @@ static int ssl_tls12_populate_transform(mbedtls_ssl_transform *transform,
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */
transform->tls_version = tls_version;
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
#if defined(MBEDTLS_SSL_KEEP_RANDBYTES)
memcpy(transform->randbytes, randbytes, sizeof(transform->randbytes));
#endif
@ -10053,4 +10054,134 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT)
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
static int mbedtls_ssl_tls12_export_keying_material(const mbedtls_ssl_context *ssl,
const mbedtls_md_type_t hash_alg,
uint8_t *out,
const size_t key_len,
const char *label,
const size_t label_len,
const unsigned char *context,
const size_t context_len,
const int use_context)
{
int ret = 0;
unsigned char *prf_input = NULL;
/* The input to the PRF is client_random, then server_random.
* If a context is provided, this is then followed by the context length
* as a 16-bit big-endian integer, and then the context itself. */
const size_t randbytes_len = MBEDTLS_CLIENT_HELLO_RANDOM_LEN + MBEDTLS_SERVER_HELLO_RANDOM_LEN;
size_t prf_input_len = randbytes_len;
if (use_context) {
if (context_len > UINT16_MAX) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
/* This does not overflow a 32-bit size_t because the current value of
* prf_input_len is 64 (length of client_random + server_random) and
* context_len fits into two bytes (checked above). */
prf_input_len += sizeof(uint16_t) + context_len;
}
prf_input = mbedtls_calloc(prf_input_len, sizeof(unsigned char));
if (prf_input == NULL) {
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}
memcpy(prf_input,
ssl->transform->randbytes + MBEDTLS_SERVER_HELLO_RANDOM_LEN,
MBEDTLS_CLIENT_HELLO_RANDOM_LEN);
memcpy(prf_input + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
ssl->transform->randbytes,
MBEDTLS_SERVER_HELLO_RANDOM_LEN);
if (use_context) {
MBEDTLS_PUT_UINT16_BE(context_len, prf_input, randbytes_len);
memcpy(prf_input + randbytes_len + sizeof(uint16_t), context, context_len);
}
ret = tls_prf_generic(hash_alg, ssl->session->master, sizeof(ssl->session->master),
label, label_len,
prf_input, prf_input_len,
out, key_len);
mbedtls_free(prf_input);
return ret;
}
#endif /* defined(MBEDTLS_SSL_PROTO_TLS1_2) */
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
static int mbedtls_ssl_tls13_export_keying_material(mbedtls_ssl_context *ssl,
const mbedtls_md_type_t hash_alg,
uint8_t *out,
const size_t key_len,
const char *label,
const size_t label_len,
const unsigned char *context,
const size_t context_len)
{
const psa_algorithm_t psa_hash_alg = mbedtls_md_psa_alg_from_type(hash_alg);
const size_t hash_len = PSA_HASH_LENGTH(hash_alg);
const unsigned char *secret = ssl->session->app_secrets.exporter_master_secret;
/* The length of the label must be at most 249 bytes to fit into the HkdfLabel
* struct as defined in RFC 8446, Section 7.1.
*
* The length of the context is unlimited even though the context field in the
* struct can only hold up to 255 bytes. This is because we place a *hash* of
* the context in the field. */
if (label_len > 249) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
return mbedtls_ssl_tls13_exporter(psa_hash_alg, secret, hash_len,
(const unsigned char *) label, label_len,
context, context_len, out, key_len);
}
#endif /* defined(MBEDTLS_SSL_PROTO_TLS1_3) */
int mbedtls_ssl_export_keying_material(mbedtls_ssl_context *ssl,
uint8_t *out, const size_t key_len,
const char *label, const size_t label_len,
const unsigned char *context, const size_t context_len,
const int use_context)
{
if (!mbedtls_ssl_is_handshake_over(ssl)) {
/* TODO: Change this to a more appropriate error code when one is available. */
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
if (key_len > MBEDTLS_SSL_EXPORT_MAX_KEY_LEN) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
int ciphersuite_id = mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl);
const mbedtls_ssl_ciphersuite_t *ciphersuite = mbedtls_ssl_ciphersuite_from_id(ciphersuite_id);
const mbedtls_md_type_t hash_alg = ciphersuite->mac;
switch (mbedtls_ssl_get_version_number(ssl)) {
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
case MBEDTLS_SSL_VERSION_TLS1_2:
return mbedtls_ssl_tls12_export_keying_material(ssl, hash_alg, out, key_len,
label, label_len,
context, context_len, use_context);
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
case MBEDTLS_SSL_VERSION_TLS1_3:
return mbedtls_ssl_tls13_export_keying_material(ssl,
hash_alg,
out,
key_len,
label,
label_len,
use_context ? context : NULL,
use_context ? context_len : 0);
#endif
default:
return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
}
}
#endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */
#endif /* MBEDTLS_SSL_TLS_C */

View file

@ -1163,7 +1163,7 @@ static int ssl_parse_hello_verify_request(mbedtls_ssl_context *ssl)
ssl->handshake->cookie_len = cookie_len;
/* Start over at ClientHello */
ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
ret = mbedtls_ssl_reset_checksum(ssl);
if (0 != ret) {
MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_reset_checksum"), ret);
@ -1372,7 +1372,7 @@ static int ssl_parse_server_hello(mbedtls_ssl_context *ssl)
ssl->session_negotiate->ciphersuite != i ||
ssl->session_negotiate->id_len != n ||
memcmp(ssl->session_negotiate->id, buf + 35, n) != 0) {
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
ssl->handshake->resume = 0;
#if defined(MBEDTLS_HAVE_TIME)
ssl->session_negotiate->start = mbedtls_time(NULL);
@ -1381,7 +1381,7 @@ static int ssl_parse_server_hello(mbedtls_ssl_context *ssl)
ssl->session_negotiate->id_len = n;
memcpy(ssl->session_negotiate->id, buf + 35, n);
} else {
ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC);
}
MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed",
@ -2091,7 +2091,7 @@ static int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
((void) p);
@ -2112,7 +2112,7 @@ static int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl)
}
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
((void) p);
@ -2454,7 +2454,7 @@ start_processing:
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
exit:
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server key exchange"));
@ -2472,7 +2472,7 @@ static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl)
if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
@ -2499,7 +2499,7 @@ static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl)
if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
@ -2517,7 +2517,7 @@ static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
}
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
ssl->handshake->client_auth =
(ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST);
@ -2688,7 +2688,7 @@ static int ssl_parse_server_hello_done(mbedtls_ssl_context *ssl)
return MBEDTLS_ERR_SSL_DECODE_ERROR;
}
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
@ -3199,7 +3199,7 @@ ecdh_calc_secret:
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
@ -3228,7 +3228,7 @@ static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl)
if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
@ -3270,14 +3270,14 @@ static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl)
if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
if (ssl->handshake->client_auth == 0 ||
mbedtls_ssl_own_cert(ssl) == NULL) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
@ -3359,7 +3359,7 @@ sign:
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY;
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
@ -3433,7 +3433,7 @@ static int ssl_parse_new_session_ticket(mbedtls_ssl_context *ssl)
/* We're not waiting for a NewSessionTicket message any more */
ssl->handshake->new_session_ticket = 0;
ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC);
/*
* Zero-length ticket means the server changed his mind and doesn't want
@ -3494,13 +3494,13 @@ int mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
if (ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC &&
ssl->handshake->new_session_ticket != 0) {
ssl->state = MBEDTLS_SSL_NEW_SESSION_TICKET;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_NEW_SESSION_TICKET);
}
#endif
switch (ssl->state) {
case MBEDTLS_SSL_HELLO_REQUEST:
ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
break;
/*
@ -3585,7 +3585,7 @@ int mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl)
case MBEDTLS_SSL_FLUSH_BUFFERS:
MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done"));
ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP);
break;
case MBEDTLS_SSL_HANDSHAKE_WRAPUP:

View file

@ -1636,7 +1636,7 @@ have_ciphersuite:
ssl->session_negotiate->ciphersuite = ciphersuites[i];
ssl->handshake->ciphersuite_info = ciphersuite_info;
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
@ -2064,7 +2064,7 @@ static int ssl_write_hello_verify_request(mbedtls_ssl_context *ssl)
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT);
if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
@ -2232,7 +2232,7 @@ static int ssl_write_server_hello(mbedtls_ssl_context *ssl)
* New session, create a new session id,
* unless we're about to issue a session ticket
*/
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
#if defined(MBEDTLS_HAVE_TIME)
ssl->session_negotiate->start = mbedtls_time(NULL);
@ -2256,7 +2256,7 @@ static int ssl_write_server_hello(mbedtls_ssl_context *ssl)
* Resuming a session
*/
n = ssl->session_negotiate->id_len;
ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC);
if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
@ -2382,7 +2382,7 @@ static int ssl_write_certificate_request(mbedtls_ssl_context *ssl)
if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
@ -2405,7 +2405,7 @@ static int ssl_write_certificate_request(mbedtls_ssl_context *ssl)
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
if (ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET) {
@ -3252,7 +3252,7 @@ static int ssl_write_server_key_exchange(mbedtls_ssl_context *ssl)
/* Key exchanges not involving ephemeral keys don't use
* ServerKeyExchange, so end here. */
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write server key exchange"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
@ -3306,7 +3306,7 @@ static int ssl_write_server_key_exchange(mbedtls_ssl_context *ssl)
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
@ -3328,7 +3328,7 @@ static int ssl_write_server_hello_done(mbedtls_ssl_context *ssl)
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO_DONE;
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
@ -4052,7 +4052,7 @@ static int ssl_parse_client_key_exchange(mbedtls_ssl_context *ssl)
return ret;
}
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client key exchange"));
@ -4070,7 +4070,7 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
@ -4096,20 +4096,20 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
if (ssl->session_negotiate->peer_cert == NULL) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if (ssl->session_negotiate->peer_cert_digest == NULL) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
return 0;
}
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
@ -4121,7 +4121,7 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
return ret;
}
ssl->state++;
mbedtls_ssl_handshake_increment_state(ssl);
/* Process the message contents */
if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
@ -4305,7 +4305,7 @@ int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl)
switch (ssl->state) {
case MBEDTLS_SSL_HELLO_REQUEST:
ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
break;
/*
@ -4394,7 +4394,7 @@ int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl)
case MBEDTLS_SSL_FLUSH_BUFFERS:
MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done"));
ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP);
break;
case MBEDTLS_SSL_HANDSHAKE_WRAPUP:

View file

@ -58,15 +58,16 @@ struct mbedtls_ssl_tls13_labels_struct const mbedtls_ssl_tls13_labels =
* };
*
* Parameters:
* - desired_length: Length of expanded key material
* Even though the standard allows expansion to up to
* 2**16 Bytes, TLS 1.3 never uses expansion to more than
* 255 Bytes, so we require `desired_length` to be at most
* 255. This allows us to save a few Bytes of code by
* hardcoding the writing of the high bytes.
* - desired_length: Length of expanded key material.
* The length field can hold numbers up to 2**16, but HKDF
* can only generate outputs of up to 255 * HASH_LEN bytes.
* It is the caller's responsibility to ensure that this
* limit is not exceeded. In TLS 1.3, SHA256 is the hash
* function with the smallest block size, so a length
* <= 255 * 32 = 8160 is always safe.
* - (label, label_len): label + label length, without "tls13 " prefix
* The label length MUST be less than or equal to
* MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN
* MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN.
* It is the caller's responsibility to ensure this.
* All (label, label length) pairs used in TLS 1.3
* can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN().
@ -81,7 +82,8 @@ struct mbedtls_ssl_tls13_labels_struct const mbedtls_ssl_tls13_labels =
* the HkdfLabel structure on success.
*/
static const char tls13_label_prefix[6] = "tls13 ";
/* We need to tell the compiler that we meant to leave out the null character. */
static const char tls13_label_prefix[6] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING = "tls13 ";
#define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(label_len, context_len) \
(2 /* expansion length */ \
@ -93,7 +95,7 @@ static const char tls13_label_prefix[6] = "tls13 ";
#define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN \
SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( \
sizeof(tls13_label_prefix) + \
MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN, \
MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN, \
MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN)
static void ssl_tls13_hkdf_encode_label(
@ -109,15 +111,13 @@ static void ssl_tls13_hkdf_encode_label(
unsigned char *p = dst;
/* Add the size of the expanded key material.
* We're hardcoding the high byte to 0 here assuming that we never use
* TLS 1.3 HKDF key expansion to more than 255 Bytes. */
#if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > 255
#error "The implementation of ssl_tls13_hkdf_encode_label() is not fit for the \
value of MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN"
/* Add the size of the expanded key material. */
#if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > UINT16_MAX
#error "The desired key length must fit into an uint16 but \
MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN is greater than UINT16_MAX"
#endif
*p++ = 0;
*p++ = MBEDTLS_BYTE_1(desired_length);
*p++ = MBEDTLS_BYTE_0(desired_length);
/* Add label incl. prefix */
@ -151,7 +151,7 @@ int mbedtls_ssl_tls13_hkdf_expand_label(
psa_key_derivation_operation_t operation =
PSA_KEY_DERIVATION_OPERATION_INIT;
if (label_len > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN) {
if (label_len > MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN) {
/* Should never happen since this is an internal
* function, and we know statically which labels
* are allowed. */
@ -1882,4 +1882,37 @@ int mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT)
int mbedtls_ssl_tls13_exporter(const psa_algorithm_t hash_alg,
const unsigned char *secret, const size_t secret_len,
const unsigned char *label, const size_t label_len,
const unsigned char *context_value, const size_t context_len,
unsigned char *out, const size_t out_len)
{
size_t hash_len = PSA_HASH_LENGTH(hash_alg);
unsigned char hkdf_secret[MBEDTLS_TLS1_3_MD_MAX_SIZE];
int ret = 0;
ret = mbedtls_ssl_tls13_derive_secret(hash_alg, secret, secret_len, label, label_len, NULL, 0,
MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, hkdf_secret,
hash_len);
if (ret != 0) {
goto exit;
}
ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
hkdf_secret,
hash_len,
MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exporter),
context_value,
context_len,
MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
out,
out_len);
exit:
mbedtls_platform_zeroize(hkdf_secret, sizeof(hkdf_secret));
return ret;
}
#endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */

View file

@ -40,8 +40,9 @@
#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
/* We need to tell the compiler that we meant to leave out the null character. */
#define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \
const unsigned char name [sizeof(string) - 1];
const unsigned char name [sizeof(string) - 1] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING;
union mbedtls_ssl_tls13_labels_union {
MBEDTLS_SSL_TLS1_3_LABEL_LIST
@ -60,8 +61,9 @@ extern const struct mbedtls_ssl_tls13_labels_struct mbedtls_ssl_tls13_labels;
mbedtls_ssl_tls13_labels.LABEL, \
MBEDTLS_SSL_TLS1_3_LBL_LEN(LABEL)
#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN \
sizeof(union mbedtls_ssl_tls13_labels_union)
/* Maximum length of the label field in the HkdfLabel struct defined in
* RFC 8446, Section 7.1, excluding the "tls13 " prefix. */
#define MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN 249
/* The maximum length of HKDF contexts used in the TLS 1.3 standard.
* Since contexts are always hashes of message transcripts, this can
@ -70,13 +72,11 @@ extern const struct mbedtls_ssl_tls13_labels_struct mbedtls_ssl_tls13_labels;
PSA_HASH_MAX_SIZE
/* Maximum desired length for expanded key material generated
* by HKDF-Expand-Label.
*
* Warning: If this ever needs to be increased, the implementation
* ssl_tls13_hkdf_encode_label() in ssl_tls13_keys.c needs to be
* adjusted since it currently assumes that HKDF key expansion
* is never used with more than 255 Bytes of output. */
#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN 255
* by HKDF-Expand-Label. This algorithm can output up to 255 * hash_size
* bytes of key material where hash_size is the output size of the
* underlying hash function. */
#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN \
(255 * MBEDTLS_TLS1_3_MD_MAX_SIZE)
/**
* \brief The \c HKDF-Expand-Label function from
@ -646,6 +646,23 @@ int mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl,
size_t *psk_len);
#endif
/**
* \brief Calculate TLS-Exporter function as defined in RFC 8446, Section 7.5.
*
* \param[in] hash_alg The hash algorithm.
* \param[in] secret The secret to use. (Should be the exporter master secret.)
* \param[in] secret_len Length of secret.
* \param[in] label The label of the exported key.
* \param[in] label_len The length of label.
* \param[out] out The output buffer for the exported key. Must have room for at least out_len bytes.
* \param[in] out_len Length of the key to generate.
*/
int mbedtls_ssl_tls13_exporter(const psa_algorithm_t hash_alg,
const unsigned char *secret, const size_t secret_len,
const unsigned char *label, const size_t label_len,
const unsigned char *context_value, const size_t context_len,
uint8_t *out, const size_t out_len);
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
#endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */

View file

@ -477,6 +477,9 @@ static const char * const features[] = {
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
"SSL_KEEP_PEER_CERTIFICATE", //no-check-names
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT)
"SSL_KEYING_MATERIAL_EXPORT", //no-check-names
#endif /* MBEDTLS_SSL_KEYING_MATERIAL_EXPORT */
#if defined(MBEDTLS_SSL_RENEGOTIATION)
"SSL_RENEGOTIATION", //no-check-names
#endif /* MBEDTLS_SSL_RENEGOTIATION */

View file

@ -292,8 +292,12 @@ int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *nam
unsigned char data[MBEDTLS_X509_MAX_DN_NAME_SIZE];
size_t data_len = 0;
/* Clear existing chain if present */
mbedtls_asn1_free_named_data_list(head);
/* Ensure the output parameter is not already populated.
* (If it were, overwriting it would likely cause a memory leak.)
*/
if (*head != NULL) {
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
}
while (c <= end) {
if (in_attr_type && *c == '=') {

View file

@ -84,12 +84,14 @@ void mbedtls_x509write_crt_set_issuer_key(mbedtls_x509write_cert *ctx,
int mbedtls_x509write_crt_set_subject_name(mbedtls_x509write_cert *ctx,
const char *subject_name)
{
mbedtls_asn1_free_named_data_list(&ctx->subject);
return mbedtls_x509_string_to_names(&ctx->subject, subject_name);
}
int mbedtls_x509write_crt_set_issuer_name(mbedtls_x509write_cert *ctx,
const char *issuer_name)
{
mbedtls_asn1_free_named_data_list(&ctx->issuer);
return mbedtls_x509_string_to_names(&ctx->issuer, issuer_name);
}

View file

@ -66,6 +66,7 @@ void mbedtls_x509write_csr_set_key(mbedtls_x509write_csr *ctx, mbedtls_pk_contex
int mbedtls_x509write_csr_set_subject_name(mbedtls_x509write_csr *ctx,
const char *subject_name)
{
mbedtls_asn1_free_named_data_list(&ctx->subject);
return mbedtls_x509_string_to_names(&ctx->subject, subject_name);
}

View file

@ -1,8 +1,8 @@
diff --git a/thirdparty/mbedtls/include/psa/crypto.h b/thirdparty/mbedtls/include/psa/crypto.h
index 2bbcea3ee0..96baf8f3ed 100644
index 2fe9f35ec3..ed7da26276 100644
--- a/thirdparty/mbedtls/include/psa/crypto.h
+++ b/thirdparty/mbedtls/include/psa/crypto.h
@@ -107,7 +107,9 @@ psa_status_t psa_crypto_init(void);
@@ -119,7 +119,9 @@ psa_status_t psa_crypto_init(void);
/** Return an initial value for a key attributes structure.
*/
@ -12,7 +12,7 @@ index 2bbcea3ee0..96baf8f3ed 100644
/** Declare a key as persistent and set its key identifier.
*
@@ -336,7 +338,9 @@ static void psa_set_key_bits(psa_key_attributes_t *attributes,
@@ -348,7 +350,9 @@ static void psa_set_key_bits(psa_key_attributes_t *attributes,
*
* \return The key type stored in the attribute structure.
*/
@ -22,7 +22,7 @@ index 2bbcea3ee0..96baf8f3ed 100644
/** Retrieve the key size from key attributes.
*
@@ -939,7 +943,9 @@ typedef struct psa_hash_operation_s psa_hash_operation_t;
@@ -951,7 +955,9 @@ typedef struct psa_hash_operation_s psa_hash_operation_t;
/** Return an initial value for a hash operation object.
*/
@ -32,7 +32,7 @@ index 2bbcea3ee0..96baf8f3ed 100644
/** Set up a multipart hash operation.
*
@@ -1298,7 +1304,9 @@ typedef struct psa_mac_operation_s psa_mac_operation_t;
@@ -1310,7 +1316,9 @@ typedef struct psa_mac_operation_s psa_mac_operation_t;
/** Return an initial value for a MAC operation object.
*/
@ -42,7 +42,7 @@ index 2bbcea3ee0..96baf8f3ed 100644
/** Set up a multipart MAC calculation operation.
*
@@ -1711,7 +1719,9 @@ typedef struct psa_cipher_operation_s psa_cipher_operation_t;
@@ -1723,7 +1731,9 @@ typedef struct psa_cipher_operation_s psa_cipher_operation_t;
/** Return an initial value for a cipher operation object.
*/
@ -52,7 +52,7 @@ index 2bbcea3ee0..96baf8f3ed 100644
/** Set the key for a multipart symmetric encryption operation.
*
@@ -2229,7 +2239,9 @@ typedef struct psa_aead_operation_s psa_aead_operation_t;
@@ -2241,7 +2251,9 @@ typedef struct psa_aead_operation_s psa_aead_operation_t;
/** Return an initial value for an AEAD operation object.
*/
@ -62,7 +62,7 @@ index 2bbcea3ee0..96baf8f3ed 100644
/** Set the key for a multipart authenticated encryption operation.
*
@@ -3216,7 +3228,9 @@ typedef struct psa_key_derivation_s psa_key_derivation_operation_t;
@@ -3228,7 +3240,9 @@ typedef struct psa_key_derivation_s psa_key_derivation_operation_t;
/** Return an initial value for a key derivation operation object.
*/
@ -73,10 +73,10 @@ index 2bbcea3ee0..96baf8f3ed 100644
/** Set up a key derivation operation.
*
diff --git a/thirdparty/mbedtls/include/psa/crypto_extra.h b/thirdparty/mbedtls/include/psa/crypto_extra.h
index 0cf42c6055..d276cd4c7f 100644
index 70740901e1..e503c9e3ca 100644
--- a/thirdparty/mbedtls/include/psa/crypto_extra.h
+++ b/thirdparty/mbedtls/include/psa/crypto_extra.h
@@ -923,7 +923,9 @@ typedef struct psa_pake_cipher_suite_s psa_pake_cipher_suite_t;
@@ -1164,7 +1164,9 @@ typedef struct psa_pake_cipher_suite_s psa_pake_cipher_suite_t;
/** Return an initial value for a PAKE cipher suite object.
*/
@ -86,7 +86,7 @@ index 0cf42c6055..d276cd4c7f 100644
/** Retrieve the PAKE algorithm from a PAKE cipher suite.
*
@@ -1056,7 +1058,9 @@ typedef struct psa_jpake_computation_stage_s psa_jpake_computation_stage_t;
@@ -1297,7 +1299,9 @@ typedef struct psa_jpake_computation_stage_s psa_jpake_computation_stage_t;
/** Return an initial value for a PAKE operation object.
*/