Merge pull request #1616 from mpg/restricted-ecp-modp-fix-3.6

Restricted ecp modp fix 3.6
This commit is contained in:
Ronald Cron
2026-05-19 08:43:25 +02:00
committed by GitHub
11 changed files with 1050 additions and 6498 deletions
+5
View File
@@ -0,0 +1,5 @@
Security
* Fix a side channel in ECC computations that allows a powerful local
attacker (typically, untrusted OS attacking a secure enclave) to fully
recover long-term secret keys. Found and reported by Alejandro Cabrera
Aldaya from Tampere University.
+6 -6
View File
@@ -213,11 +213,11 @@ mbedtls_ecp_point;
*
* If \p modp is NULL, reduction modulo \p P is done using a generic algorithm.
* Otherwise, \p modp must point to a function that takes an \p mbedtls_mpi in the
* range of <code>0..2^(2*pbits)-1</code>, and transforms it in-place to an integer
* which is congruent mod \p P to the given MPI, and is close enough to \p pbits
* in size, so that it may be efficiently brought in the 0..P-1 range by a few
* additions or subtractions. Therefore, it is only an approximate modular
* reduction. It must return 0 on success and non-zero on failure.
* range of [0, 2^(2*pbits)), and transforms it in-place to an integer which is
* congruent mod \p P to the given MPI, is in the range [0, 2P), and has no more
* non-zero limbs than P, so that it may be efficiently brought into the range
* [0, P) by a single constant-time conditional subtraction.
* It must return 0 on success and non-zero on failure.
*
* \note Alternative implementations of the ECP module must obey the
* following constraints.
@@ -248,7 +248,7 @@ typedef struct mbedtls_ecp_group {
private keys. */
/* End of public fields */
unsigned int MBEDTLS_PRIVATE(h); /*!< \internal 1 if the constants are static. */
unsigned int MBEDTLS_PRIVATE(h); /*!< \internal 1 if all the constants are static, 2 if only N and P are static */
int(*MBEDTLS_PRIVATE(modp))(mbedtls_mpi *); /*!< The function for fast pseudo-reduction
mod \p P (see above).*/
int(*MBEDTLS_PRIVATE(t_pre))(mbedtls_ecp_point *, void *); /*!< Unused. */
-1
View File
@@ -39,7 +39,6 @@ set(src_crypto
ecjpake.c
ecp.c
ecp_curves.c
ecp_curves_new.c
entropy.c
entropy_poll.c
error.c
-1
View File
@@ -131,7 +131,6 @@ OBJS_CRYPTO= \
ecjpake.o \
ecp.o \
ecp_curves.o \
ecp_curves_new.o \
entropy.o \
entropy_poll.o \
error.o \
+7 -1
View File
@@ -4,7 +4,13 @@
* This interface should only be used by the legacy bignum module (bignum.h)
* and the modular bignum modules (bignum_mod.c, bignum_mod_raw.c). All other
* modules should use the high-level modular bignum interface (bignum_mod.h)
* or the legacy bignum interface (bignum.h).
* or the legacy bignum interface (bignum.h). The only exceptions are:
* 1. In ecp_curves.c, some mbedtls_ecp_mod_pXXX_raw() functions are using
* bignum_core functions. That's because those functions are implementing a
* part of bignum_mod: the optimized reduction in mbedtls_mpi_mod_modulus.
* 2. In ecp.c, ecp_modp() is currently using bignum_core, while the rest of
* the module is using legacy bignum. That's transitional; eventually ecp.c is
* going to use bignum_mod_raw.
*
* This module is about processing non-negative integers with a fixed upper
* bound that's of the form 2^n-1 where n is a multiple of #biL.
+10 -13
View File
@@ -69,6 +69,7 @@
#include "bn_mul.h"
#include "bignum_internal.h"
#include "bignum_core.h"
#include "ecp_invasive.h"
#include <string.h>
@@ -582,10 +583,10 @@ void mbedtls_ecp_group_free(mbedtls_ecp_group *grp)
mbedtls_mpi_free(&grp->B);
mbedtls_ecp_point_free(&grp->G);
#if !defined(MBEDTLS_ECP_WITH_MPI_UINT)
mbedtls_mpi_free(&grp->N);
mbedtls_mpi_free(&grp->P);
#endif
if (grp->h != 2) {
mbedtls_mpi_free(&grp->N);
mbedtls_mpi_free(&grp->P);
}
}
if (!ecp_group_is_static_comb_table(grp) && grp->T != NULL) {
@@ -1013,15 +1014,11 @@ static int ecp_modp(mbedtls_mpi *N, const mbedtls_ecp_group *grp)
MBEDTLS_MPI_CHK(grp->modp(N));
/* N->s < 0 is a much faster test, which fails only if N is 0 */
while (N->s < 0 && mbedtls_mpi_cmp_int(N, 0) != 0) {
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &grp->P));
}
while (mbedtls_mpi_cmp_mpi(N, &grp->P) >= 0) {
/* we known P, N and the result are positive */
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(N, N, &grp->P));
}
/* The previous call left N in the range [0, 2P) with no more limbs than P
* (see documentation of mbedtls_ecp_mod_pXXX_raw() in ecp_invasive.h),
* so we can bring it into the range [0, P) in constant time. */
mbedtls_mpi_uint c = mbedtls_mpi_core_sub(N->p, N->p, grp->P.p, grp->P.n);
(void) mbedtls_mpi_core_add_if(N->p, grp->P.p, grp->P.n, (unsigned) c);
cleanup:
return ret;
+1005 -414
View File
File diff suppressed because it is too large Load Diff
+3 -6030
View File
File diff suppressed because it is too large Load Diff
-13
View File
@@ -28,21 +28,8 @@ typedef enum {
MBEDTLS_ECP_MOD_SCALAR
} mbedtls_ecp_modulus_type;
typedef enum {
MBEDTLS_ECP_VARIANT_NONE = 0,
MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT,
MBEDTLS_ECP_VARIANT_WITH_MPI_UINT
} mbedtls_ecp_variant;
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_LIGHT)
/** Queries the ecp variant.
*
* \return The id of the ecp variant.
*/
MBEDTLS_STATIC_TESTABLE
mbedtls_ecp_variant mbedtls_ecp_get_variant(void);
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
/** Generate a private key on a Montgomery curve (Curve25519 or Curve448).
*
-3
View File
@@ -2268,6 +2268,3 @@ ecp_mod_random:MBEDTLS_ECP_DP_SECP256K1:MBEDTLS_ECP_MOD_SCALAR
ecp_random #25 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE448)
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
ecp_mod_random:MBEDTLS_ECP_DP_CURVE448:MBEDTLS_ECP_MOD_COORDINATE
ecp variant check
check_variant:
+14 -16
View File
@@ -1551,7 +1551,7 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
void ecp_mod_p_generic_raw(int curve_id,
char *input_N,
char *input_X,
@@ -1569,8 +1569,10 @@ void ecp_mod_p_generic_raw(int curve_id,
size_t curve_bits;
int (*curve_func)(mbedtls_mpi_uint *X, size_t X_limbs);
#if defined(MBEDTLS_ECP_WITH_MPI_UINT)
mbedtls_mpi_mod_modulus m;
mbedtls_mpi_mod_modulus_init(&m);
#endif
TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
@@ -1656,12 +1658,19 @@ void ecp_mod_p_generic_raw(int curve_id,
TEST_EQUAL(limbs_X, limbs);
TEST_EQUAL(limbs_res, limbs_N);
TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
&m, N, limbs_N), 0);
TEST_EQUAL((*curve_func)(X, limbs_X), 0);
#if defined(MBEDTLS_ECP_WITH_MPI_UINT)
/* This is what we'll do in the future, based on bignum_mod_raw */
TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(&m, N, limbs_N), 0);
mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
#else
/* This is what we're doing now, based on bignum_core,
* see ecp_modp() in ecp.c */
mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, X, N, limbs_N);
(void) mbedtls_mpi_core_add_if(X, N, limbs_N, (unsigned) c);
#endif
TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), curve_bits);
TEST_MEMORY_COMPARE(X, bytes, res, bytes);
@@ -1669,7 +1678,9 @@ exit:
mbedtls_free(X);
mbedtls_free(res);
#if defined(MBEDTLS_ECP_WITH_MPI_UINT)
mbedtls_mpi_mod_modulus_free(&m);
#endif
mbedtls_free(N);
}
/* END_CASE */
@@ -1914,16 +1925,3 @@ exit:
mbedtls_free(rX_raw);
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_LIGHT */
void check_variant()
{
mbedtls_ecp_variant variant = mbedtls_ecp_get_variant();
#if defined(MBEDTLS_ECP_WITH_MPI_UINT)
TEST_EQUAL(variant, MBEDTLS_ECP_VARIANT_WITH_MPI_UINT);
#else
TEST_EQUAL(variant, MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT);
#endif
}
/* END_CASE */