mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-08-25 04:29:55 +00:00
Merge pull request #1616 from mpg/restricted-ecp-modp-fix-3.6
Restricted ecp modp fix 3.6
This commit is contained in:
@@ -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.
|
||||
@@ -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. */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -131,7 +131,6 @@ OBJS_CRYPTO= \
|
||||
ecjpake.o \
|
||||
ecp.o \
|
||||
ecp_curves.o \
|
||||
ecp_curves_new.o \
|
||||
entropy.o \
|
||||
entropy_poll.o \
|
||||
error.o \
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+3
-6030
File diff suppressed because it is too large
Load Diff
@@ -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).
|
||||
*
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user