Skip to content

Commit

Permalink
CHANGE: updated Mbed-TLS sources to version 3.6.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Oldes committed Oct 16, 2024
1 parent 672662f commit e91639c
Show file tree
Hide file tree
Showing 31 changed files with 782 additions and 4,060 deletions.
24 changes: 10 additions & 14 deletions make/rebol3.nest
Original file line number Diff line number Diff line change
Expand Up @@ -676,20 +676,16 @@ include-cryptography: [
library: %Bcrypt ;; used by mbedtls_platform_entropy_poll
]

define: MBEDTLS_ASN1_PARSE_C ; The generic ASN1 parser.
define: MBEDTLS_ASN1_WRITE_C ; The generic ASN1 writer.

define: MBEDTLS_CTR_DRBG_C ; The CTR_DRBG AES-based random generator.

define: MBEDTLS_AES_C ; The AES block cipher.
define: MBEDTLS_DHM_C ; The Diffie-Hellman-Merkle module.
define: MBEDTLS_ECDSA_C ; The elliptic curve DSA library.
define: MBEDTLS_ECP_C ; The elliptic curve over GF(p) library.
define: MBEDTLS_ECDH_C ; The elliptic curve Diffie-Hellman library.
define: MBEDTLS_BIGNUM_C ; The multi-precision integer library. Required for: RSA, ECDSA, ECP, DHM
define: MBEDTLS_ENTROPY_C ; The platform-specific entropy code.
define: MBEDTLS_OID_C ; Required for RSA
define: MBEDTLS_PKCS1_V15
config: MBEDTLS_CTR_DRBG_C ; The CTR_DRBG AES-based random generator.
config: MBEDTLS_AES_C ; The AES block cipher.
config: MBEDTLS_DHM_C ; The Diffie-Hellman-Merkle module.
config: MBEDTLS_ECDSA_C ; The elliptic curve DSA library.
config: MBEDTLS_ECP_C ; The elliptic curve over GF(p) library.
config: MBEDTLS_ECDH_C ; The elliptic curve Diffie-Hellman library.
config: MBEDTLS_BIGNUM_C ; The multi-precision integer library. Required for: RSA, ECDSA, ECP, DHM
config: MBEDTLS_ENTROPY_C ; The platform-specific entropy code.
config: MBEDTLS_OID_C ; Required for RSA
config: MBEDTLS_PKCS1_V15

core-files: [
%core/n-crypt.c
Expand Down
31 changes: 27 additions & 4 deletions src/core/mbedtls/bignum.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "mbedtls/bignum.h"
#include "bignum_core.h"
#include "bignum_internal.h"
#include "bn_mul.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
Expand Down Expand Up @@ -1610,9 +1611,13 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_s
return 0;
}

int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *E, const mbedtls_mpi *N,
mbedtls_mpi *prec_RR)
/*
* Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
* this function is not constant time with respect to the exponent (parameter E).
*/
static int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *E, int E_public,
const mbedtls_mpi *N, mbedtls_mpi *prec_RR)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

Expand Down Expand Up @@ -1695,7 +1700,11 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
{
mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);
mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
mbedtls_mpi_core_exp_mod_unsafe(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
} else {
mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
}
mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);
}

Expand All @@ -1720,6 +1729,20 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
return ret;
}

int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *E, const mbedtls_mpi *N,
mbedtls_mpi *prec_RR)
{
return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_SECRET, N, prec_RR);
}

int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *E, const mbedtls_mpi *N,
mbedtls_mpi *prec_RR)
{
return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR);
}

/*
* Greatest common divisor: G = gcd(A, B) (HAC 14.54)
*/
Expand Down
163 changes: 144 additions & 19 deletions src/core/mbedtls/bignum_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,93 @@ static void exp_mod_precompute_window(const mbedtls_mpi_uint *A,
}
}

#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
// Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
int mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1;
#endif

/*
* This function calculates the indices of the exponent where the exponentiation algorithm should
* start processing.
*
* Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
* this function is not constant time with respect to the exponent (parameter E).
*/
static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint *E,
size_t E_limbs,
int E_public,
size_t *E_limb_index,
size_t *E_bit_index)
{
if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
/*
* Skip leading zero bits.
*/
size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs);
if (E_bits == 0) {
/*
* If E is 0 mbedtls_mpi_core_bitlen() returns 0. Even if that is the case, we will want
* to represent it as a single 0 bit and as such the bitlength will be 1.
*/
E_bits = 1;
}

*E_limb_index = E_bits / biL;
*E_bit_index = E_bits % biL;

#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC;
#endif
} else {
/*
* Here we need to be constant time with respect to E and can't do anything better than
* start at the first allocated bit.
*/
*E_limb_index = E_limbs;
*E_bit_index = 0;
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
// Only mark the codepath safe if there wasn't an unsafe codepath before
if (mbedtls_mpi_optionally_safe_codepath != MBEDTLS_MPI_IS_PUBLIC) {
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_SECRET;
}
#endif
}
}

/*
* Warning! If the parameter window_public has MBEDTLS_MPI_IS_PUBLIC as its value, this function is
* not constant time with respect to the window parameter and consequently the exponent of the
* exponentiation (parameter E of mbedtls_mpi_core_exp_mod_optionally_safe).
*/
static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselect,
mbedtls_mpi_uint *Wtable,
size_t AN_limbs, size_t welem,
mbedtls_mpi_uint window,
int window_public)
{
if (window_public == MBEDTLS_MPI_IS_PUBLIC) {
memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL);
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC;
#endif
} else {
/* Select Wtable[window] without leaking window through
* memory access patterns. */
mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,
AN_limbs, welem, window);
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
// Only mark the codepath safe if there wasn't an unsafe codepath before
if (mbedtls_mpi_optionally_safe_codepath != MBEDTLS_MPI_IS_PUBLIC) {
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_SECRET;
}
#endif
}
}

/* Exponentiation: X := A^E mod N.
*
* Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
* this function is not constant time with respect to the exponent (parameter E).
*
* A must already be in Montgomery form.
*
Expand All @@ -758,16 +844,25 @@ static void exp_mod_precompute_window(const mbedtls_mpi_uint *A,
* (The difference is that the body in our loop processes a single bit instead
* of a full window.)
*/
void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *N,
size_t AN_limbs,
const mbedtls_mpi_uint *E,
size_t E_limbs,
const mbedtls_mpi_uint *RR,
mbedtls_mpi_uint *T)
static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *N,
size_t AN_limbs,
const mbedtls_mpi_uint *E,
size_t E_limbs,
int E_public,
const mbedtls_mpi_uint *RR,
mbedtls_mpi_uint *T)
{
const size_t wsize = exp_mod_get_window_size(E_limbs * biL);
/* We'll process the bits of E from most significant
* (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant
* (limb_index=0, E_bit_index=0). */
size_t E_limb_index;
size_t E_bit_index;
exp_mod_calc_first_bit_optionally_safe(E, E_limbs, E_public,
&E_limb_index, &E_bit_index);

const size_t wsize = exp_mod_get_window_size(E_limb_index * biL);
const size_t welem = ((size_t) 1) << wsize;

/* This is how we will use the temporary storage T, which must have space
Expand All @@ -786,7 +881,7 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,

const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N);

/* Set Wtable[i] = A^(2^i) (in Montgomery representation) */
/* Set Wtable[i] = A^i (in Montgomery representation) */
exp_mod_precompute_window(A, N, AN_limbs,
mm, RR,
welem, Wtable, temp);
Expand All @@ -798,11 +893,6 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
/* X = 1 (in Montgomery presentation) initially */
memcpy(X, Wtable, AN_limbs * ciL);

/* We'll process the bits of E from most significant
* (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant
* (limb_index=0, E_bit_index=0). */
size_t E_limb_index = E_limbs;
size_t E_bit_index = 0;
/* At any given time, window contains window_bits bits from E.
* window_bits can go up to wsize. */
size_t window_bits = 0;
Expand All @@ -828,10 +918,9 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
* when we've finished processing the exponent. */
if (window_bits == wsize ||
(E_bit_index == 0 && E_limb_index == 0)) {
/* Select Wtable[window] without leaking window through
* memory access patterns. */
mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,
AN_limbs, welem, window);

exp_mod_table_lookup_optionally_safe(Wselect, Wtable, AN_limbs, welem,
window, E_public);
/* Multiply X by the selected element. */
mbedtls_mpi_core_montmul(X, X, Wselect, AN_limbs, N, AN_limbs, mm,
temp);
Expand All @@ -841,6 +930,42 @@ void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
} while (!(E_bit_index == 0 && E_limb_index == 0));
}

void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *N, size_t AN_limbs,
const mbedtls_mpi_uint *E, size_t E_limbs,
const mbedtls_mpi_uint *RR,
mbedtls_mpi_uint *T)
{
mbedtls_mpi_core_exp_mod_optionally_safe(X,
A,
N,
AN_limbs,
E,
E_limbs,
MBEDTLS_MPI_IS_SECRET,
RR,
T);
}

void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *N, size_t AN_limbs,
const mbedtls_mpi_uint *E, size_t E_limbs,
const mbedtls_mpi_uint *RR,
mbedtls_mpi_uint *T)
{
mbedtls_mpi_core_exp_mod_optionally_safe(X,
A,
N,
AN_limbs,
E,
E_limbs,
MBEDTLS_MPI_IS_PUBLIC,
RR,
T);
}

mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
mbedtls_mpi_uint c, /* doubles as carry */
Expand Down
70 changes: 70 additions & 0 deletions src/core/mbedtls/bignum_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,27 @@
#define GET_BYTE(X, i) \
(((X)[(i) / ciL] >> (((i) % ciL) * 8)) & 0xff)

/* Constants to identify whether a value is public or secret. If a parameter is marked as secret by
* this constant, the function must be constant time with respect to the parameter.
*
* This is only needed for functions with the _optionally_safe postfix. All other functions have
* fixed behavior that can't be changed at runtime and are constant time with respect to their
* parameters as prescribed by their documentation or by conventions in their module's documentation.
*
* Parameters should be named X_public where X is the name of the
* corresponding input parameter.
*
* Implementation should always check using
* if (X_public == MBEDTLS_MPI_IS_PUBLIC) {
* // unsafe path
* } else {
* // safe path
* }
* not the other way round, in order to prevent misuse. (This is, if a value
* other than the two below is passed, default to the safe path.) */
#define MBEDTLS_MPI_IS_PUBLIC 0x2a2a2a2a
#define MBEDTLS_MPI_IS_SECRET 0

/** Count leading zero bits in a given integer.
*
* \warning The result is undefined if \p a == 0
Expand Down Expand Up @@ -604,6 +625,42 @@ int mbedtls_mpi_core_random(mbedtls_mpi_uint *X,
*/
size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs);

/**
* \brief Perform a modular exponentiation with public or secret exponent:
* X = A^E mod N, where \p A is already in Montgomery form.
*
* \warning This function is not constant time with respect to \p E (the exponent).
*
* \p X may be aliased to \p A, but not to \p RR or \p E, even if \p E_limbs ==
* \p AN_limbs.
*
* \param[out] X The destination MPI, as a little endian array of length
* \p AN_limbs.
* \param[in] A The base MPI, as a little endian array of length \p AN_limbs.
* Must be in Montgomery form.
* \param[in] N The modulus, as a little endian array of length \p AN_limbs.
* \param AN_limbs The number of limbs in \p X, \p A, \p N, \p RR.
* \param[in] E The exponent, as a little endian array of length \p E_limbs.
* \param E_limbs The number of limbs in \p E.
* \param[in] RR The precomputed residue of 2^{2*biL} modulo N, as a little
* endian array of length \p AN_limbs.
* \param[in,out] T Temporary storage of at least the number of limbs returned
* by `mbedtls_mpi_core_exp_mod_working_limbs()`.
* Its initial content is unused and its final content is
* indeterminate.
* It must not alias or otherwise overlap any of the other
* parameters.
* It is up to the caller to zeroize \p T when it is no
* longer needed, and before freeing it if it was dynamically
* allocated.
*/
void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X,
const mbedtls_mpi_uint *A,
const mbedtls_mpi_uint *N, size_t AN_limbs,
const mbedtls_mpi_uint *E, size_t E_limbs,
const mbedtls_mpi_uint *RR,
mbedtls_mpi_uint *T);

/**
* \brief Perform a modular exponentiation with secret exponent:
* X = A^E mod N, where \p A is already in Montgomery form.
Expand Down Expand Up @@ -760,4 +817,17 @@ void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X,
mbedtls_mpi_uint mm,
mbedtls_mpi_uint *T);

/*
* Can't define thread local variables with our abstraction layer: do nothing if threading is on.
*/
#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
extern int mbedtls_mpi_optionally_safe_codepath;

static inline void mbedtls_mpi_optionally_safe_codepath_reset(void)
{
// Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1;
}
#endif

#endif /* MBEDTLS_BIGNUM_CORE_H */
Loading

0 comments on commit e91639c

Please sign in to comment.