Merge remote-tracking branch 'restricted/development-restricted' into mbedtls-3.0.0rc0-pr
This commit is contained in:
commit
34d8cd2892
7
ChangeLog.d/ecdsa-random-leading-zeros.txt
Normal file
7
ChangeLog.d/ecdsa-random-leading-zeros.txt
Normal file
@ -0,0 +1,7 @@
|
||||
Security
|
||||
* Fix a potential side channel vulnerability in ECDSA ephemeral key generation.
|
||||
An adversary who is capable of very precise timing measurements could
|
||||
learn partial information about the leading bits of the nonce used for the
|
||||
signature, allowing the recovery of the private key after observing a
|
||||
large number of signature operations. This completes a partial fix in
|
||||
Mbed TLS 2.20.0.
|
6
ChangeLog.d/fix-rsa-leak.txt
Normal file
6
ChangeLog.d/fix-rsa-leak.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Security
|
||||
* An adversary with access to precise enough information about memory
|
||||
accesses (typically, an untrusted operating system attacking a secure
|
||||
enclave) could recover an RSA private key after observing the victim
|
||||
performing a single private-key operation. Found and reported by
|
||||
Zili KOU, Wenjian HE, Sharad Sinha, and Wei ZHANG.
|
6
ChangeLog.d/reject-low-order-points-early.txt
Normal file
6
ChangeLog.d/reject-low-order-points-early.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Security
|
||||
* An adversary with access to precise enough timing information (typically, a
|
||||
co-located process) could recover a Curve25519 or Curve448 static ECDH key
|
||||
after inputting a chosen public key and observing the victim performing the
|
||||
corresponding private-key operation. Found and reported by Leila Batina,
|
||||
Lukas Chmielewski, Björn Haase, Niels Samwel and Peter Schwabe.
|
176
library/bignum.c
176
library/bignum.c
@ -268,6 +268,36 @@ void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
|
||||
memcpy( Y, &T, sizeof( mbedtls_mpi ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Select between two sign values in constant-time.
|
||||
*
|
||||
* This is functionally equivalent to second ? a : b but uses only bit
|
||||
* operations in order to avoid branches.
|
||||
*
|
||||
* \param[in] a The first sign; must be either +1 or -1.
|
||||
* \param[in] b The second sign; must be either +1 or -1.
|
||||
* \param[in] second Must be either 1 (return b) or 0 (return a).
|
||||
*
|
||||
* \return The selected sign value.
|
||||
*/
|
||||
static int mpi_safe_cond_select_sign( int a, int b, unsigned char second )
|
||||
{
|
||||
/* In order to avoid questions about what we can reasonnably assume about
|
||||
* the representations of signed integers, move everything to unsigned
|
||||
* by taking advantage of the fact that a and b are either +1 or -1. */
|
||||
unsigned ua = a + 1;
|
||||
unsigned ub = b + 1;
|
||||
|
||||
/* second was 0 or 1, mask is 0 or 2 as are ua and ub */
|
||||
const unsigned mask = second << 1;
|
||||
|
||||
/* select ua or ub */
|
||||
unsigned ur = ( ua & ~mask ) | ( ub & mask );
|
||||
|
||||
/* ur is now 0 or 2, convert back to -1 or +1 */
|
||||
return( (int) ur - 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Conditionally assign dest = src, without leaking information
|
||||
* about whether the assignment was made or not.
|
||||
@ -280,8 +310,23 @@ static void mpi_safe_cond_assign( size_t n,
|
||||
unsigned char assign )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/* MSVC has a warning about unary minus on unsigned integer types,
|
||||
* but this is well-defined and precisely what we want to do here. */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4146 )
|
||||
#endif
|
||||
|
||||
/* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
|
||||
const mbedtls_mpi_uint mask = -assign;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
dest[i] = dest[i] * ( 1 - assign ) + src[i] * assign;
|
||||
dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -293,20 +338,34 @@ int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned
|
||||
{
|
||||
int ret = 0;
|
||||
size_t i;
|
||||
mbedtls_mpi_uint limb_mask;
|
||||
MPI_VALIDATE_RET( X != NULL );
|
||||
MPI_VALIDATE_RET( Y != NULL );
|
||||
|
||||
/* MSVC has a warning about unary minus on unsigned integer types,
|
||||
* but this is well-defined and precisely what we want to do here. */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4146 )
|
||||
#endif
|
||||
|
||||
/* make sure assign is 0 or 1 in a time-constant manner */
|
||||
assign = (assign | (unsigned char)-assign) >> 7;
|
||||
assign = (assign | (unsigned char)-assign) >> (sizeof( assign ) * 8 - 1);
|
||||
/* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
|
||||
limb_mask = -assign;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
|
||||
|
||||
X->s = X->s * ( 1 - assign ) + Y->s * assign;
|
||||
X->s = mpi_safe_cond_select_sign( X->s, Y->s, assign );
|
||||
|
||||
mpi_safe_cond_assign( Y->n, X->p, Y->p, assign );
|
||||
|
||||
for( i = Y->n; i < X->n; i++ )
|
||||
X->p[i] *= ( 1 - assign );
|
||||
X->p[i] &= ~limb_mask;
|
||||
|
||||
cleanup:
|
||||
return( ret );
|
||||
@ -322,6 +381,7 @@ int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char sw
|
||||
{
|
||||
int ret, s;
|
||||
size_t i;
|
||||
mbedtls_mpi_uint limb_mask;
|
||||
mbedtls_mpi_uint tmp;
|
||||
MPI_VALIDATE_RET( X != NULL );
|
||||
MPI_VALIDATE_RET( Y != NULL );
|
||||
@ -329,22 +389,35 @@ int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char sw
|
||||
if( X == Y )
|
||||
return( 0 );
|
||||
|
||||
/* MSVC has a warning about unary minus on unsigned integer types,
|
||||
* but this is well-defined and precisely what we want to do here. */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4146 )
|
||||
#endif
|
||||
|
||||
/* make sure swap is 0 or 1 in a time-constant manner */
|
||||
swap = (swap | (unsigned char)-swap) >> 7;
|
||||
swap = (swap | (unsigned char)-swap) >> (sizeof( swap ) * 8 - 1);
|
||||
/* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
|
||||
limb_mask = -swap;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
|
||||
|
||||
s = X->s;
|
||||
X->s = X->s * ( 1 - swap ) + Y->s * swap;
|
||||
Y->s = Y->s * ( 1 - swap ) + s * swap;
|
||||
X->s = mpi_safe_cond_select_sign( X->s, Y->s, swap );
|
||||
Y->s = mpi_safe_cond_select_sign( Y->s, s, swap );
|
||||
|
||||
|
||||
for( i = 0; i < X->n; i++ )
|
||||
{
|
||||
tmp = X->p[i];
|
||||
X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
|
||||
Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap;
|
||||
X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
|
||||
Y->p[i] = ( Y->p[i] & ~limb_mask ) | ( tmp & limb_mask );
|
||||
}
|
||||
|
||||
cleanup:
|
||||
@ -2154,6 +2227,71 @@ static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
|
||||
mpi_montmul( A, &U, N, mm, T );
|
||||
}
|
||||
|
||||
/*
|
||||
* Constant-flow boolean "equal" comparison:
|
||||
* return x == y
|
||||
*
|
||||
* This function can be used to write constant-time code by replacing branches
|
||||
* with bit operations - it can be used in conjunction with
|
||||
* mbedtls_ssl_cf_mask_from_bit().
|
||||
*
|
||||
* This function is implemented without using comparison operators, as those
|
||||
* might be translated to branches by some compilers on some platforms.
|
||||
*/
|
||||
static size_t mbedtls_mpi_cf_bool_eq( size_t x, size_t y )
|
||||
{
|
||||
/* diff = 0 if x == y, non-zero otherwise */
|
||||
const size_t diff = x ^ y;
|
||||
|
||||
/* MSVC has a warning about unary minus on unsigned integer types,
|
||||
* but this is well-defined and precisely what we want to do here. */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4146 )
|
||||
#endif
|
||||
|
||||
/* diff_msb's most significant bit is equal to x != y */
|
||||
const size_t diff_msb = ( diff | (size_t) -diff );
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
/* diff1 = (x != y) ? 1 : 0 */
|
||||
const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
|
||||
|
||||
return( 1 ^ diff1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Select an MPI from a table without leaking the index.
|
||||
*
|
||||
* This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it
|
||||
* reads the entire table in order to avoid leaking the value of idx to an
|
||||
* attacker able to observe memory access patterns.
|
||||
*
|
||||
* \param[out] R Where to write the selected MPI.
|
||||
* \param[in] T The table to read from.
|
||||
* \param[in] T_size The number of elements in the table.
|
||||
* \param[in] idx The index of the element to select;
|
||||
* this must satisfy 0 <= idx < T_size.
|
||||
*
|
||||
* \return \c 0 on success, or a negative error code.
|
||||
*/
|
||||
static int mpi_select( mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
for( size_t i = 0; i < T_size; i++ )
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( R, &T[i],
|
||||
(unsigned char) mbedtls_mpi_cf_bool_eq( i, idx ) ) );
|
||||
}
|
||||
|
||||
cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
|
||||
*/
|
||||
@ -2166,7 +2304,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
|
||||
size_t i, j, nblimbs;
|
||||
size_t bufsize, nbits;
|
||||
mbedtls_mpi_uint ei, mm, state;
|
||||
mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
|
||||
mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], WW, Apos;
|
||||
int neg;
|
||||
|
||||
MPI_VALIDATE_RET( X != NULL );
|
||||
@ -2190,6 +2328,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
|
||||
mpi_montg_init( &mm, N );
|
||||
mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
|
||||
mbedtls_mpi_init( &Apos );
|
||||
mbedtls_mpi_init( &WW );
|
||||
memset( W, 0, sizeof( W ) );
|
||||
|
||||
i = mbedtls_mpi_bitlen( E );
|
||||
@ -2343,7 +2482,8 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
|
||||
/*
|
||||
* X = X * W[wbits] R^-1 mod N
|
||||
*/
|
||||
mpi_montmul( X, &W[wbits], N, mm, &T );
|
||||
MBEDTLS_MPI_CHK( mpi_select( &WW, W, (size_t) 1 << wsize, wbits ) );
|
||||
mpi_montmul( X, &WW, N, mm, &T );
|
||||
|
||||
state--;
|
||||
nbits = 0;
|
||||
@ -2381,6 +2521,7 @@ cleanup:
|
||||
mbedtls_mpi_free( &W[i] );
|
||||
|
||||
mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
|
||||
mbedtls_mpi_free( &WW );
|
||||
|
||||
if( _RR == NULL || _RR->p == NULL )
|
||||
mbedtls_mpi_free( &RR );
|
||||
@ -2565,9 +2706,10 @@ int mbedtls_mpi_random( mbedtls_mpi *X,
|
||||
{
|
||||
int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
||||
int count;
|
||||
unsigned cmp = 0;
|
||||
unsigned lt_lower = 1, lt_upper = 0;
|
||||
size_t n_bits = mbedtls_mpi_bitlen( N );
|
||||
size_t n_bytes = ( n_bits + 7 ) / 8;
|
||||
mbedtls_mpi lower_bound;
|
||||
|
||||
if( min < 0 )
|
||||
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
|
||||
@ -2593,10 +2735,14 @@ int mbedtls_mpi_random( mbedtls_mpi *X,
|
||||
*/
|
||||
count = ( n_bytes > 4 ? 30 : 250 );
|
||||
|
||||
mbedtls_mpi_init( &lower_bound );
|
||||
|
||||
/* Ensure that target MPI has exactly the same number of limbs
|
||||
* as the upper bound, even if the upper bound has leading zeros.
|
||||
* This is necessary for the mbedtls_mpi_lt_mpi_ct() check. */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, N->n ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &lower_bound, N->n ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &lower_bound, min ) );
|
||||
|
||||
/*
|
||||
* Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)
|
||||
@ -2617,11 +2763,13 @@ int mbedtls_mpi_random( mbedtls_mpi *X,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, &cmp ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, &lower_bound, <_lower ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, <_upper ) );
|
||||
}
|
||||
while( mbedtls_mpi_cmp_int( X, min ) < 0 || cmp != 1 );
|
||||
while( lt_lower != 0 || lt_upper == 0 );
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free( &lower_bound );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,46 @@
|
||||
|
||||
#include "mbedtls/bignum.h"
|
||||
|
||||
|
||||
/*
|
||||
* Conversion macros for embedded constants:
|
||||
* build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2
|
||||
*/
|
||||
#if defined(MBEDTLS_HAVE_INT32)
|
||||
|
||||
#define MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d ) \
|
||||
( (mbedtls_mpi_uint) (a) << 0 ) | \
|
||||
( (mbedtls_mpi_uint) (b) << 8 ) | \
|
||||
( (mbedtls_mpi_uint) (c) << 16 ) | \
|
||||
( (mbedtls_mpi_uint) (d) << 24 )
|
||||
|
||||
#define MBEDTLS_BYTES_TO_T_UINT_2( a, b ) \
|
||||
MBEDTLS_BYTES_TO_T_UINT_4( a, b, 0, 0 )
|
||||
|
||||
#define MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
|
||||
MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d ), \
|
||||
MBEDTLS_BYTES_TO_T_UINT_4( e, f, g, h )
|
||||
|
||||
#else /* 64-bits */
|
||||
|
||||
#define MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
|
||||
( (mbedtls_mpi_uint) (a) << 0 ) | \
|
||||
( (mbedtls_mpi_uint) (b) << 8 ) | \
|
||||
( (mbedtls_mpi_uint) (c) << 16 ) | \
|
||||
( (mbedtls_mpi_uint) (d) << 24 ) | \
|
||||
( (mbedtls_mpi_uint) (e) << 32 ) | \
|
||||
( (mbedtls_mpi_uint) (f) << 40 ) | \
|
||||
( (mbedtls_mpi_uint) (g) << 48 ) | \
|
||||
( (mbedtls_mpi_uint) (h) << 56 )
|
||||
|
||||
#define MBEDTLS_BYTES_TO_T_UINT_4( a, b, c, d ) \
|
||||
MBEDTLS_BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )
|
||||
|
||||
#define MBEDTLS_BYTES_TO_T_UINT_2( a, b ) \
|
||||
MBEDTLS_BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )
|
||||
|
||||
#endif /* bits in mbedtls_mpi_uint */
|
||||
|
||||
#if defined(MBEDTLS_HAVE_ASM)
|
||||
|
||||
#ifndef asm
|
||||
|
100
library/ecp.c
100
library/ecp.c
@ -77,6 +77,7 @@
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
#include "bn_mul.h"
|
||||
#include "ecp_invasive.h"
|
||||
|
||||
#include <string.h>
|
||||
@ -2746,6 +2747,97 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
||||
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
|
||||
#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
|
||||
#define ECP_MPI_INIT_ARRAY(x) \
|
||||
ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
|
||||
/*
|
||||
* Constants for the two points other than 0, 1, -1 (mod p) in
|
||||
* https://cr.yp.to/ecdh.html#validate
|
||||
* See ecp_check_pubkey_x25519().
|
||||
*/
|
||||
static const mbedtls_mpi_uint x25519_bad_point_1[] = {
|
||||
MBEDTLS_BYTES_TO_T_UINT_8( 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae ),
|
||||
MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a ),
|
||||
MBEDTLS_BYTES_TO_T_UINT_8( 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd ),
|
||||
MBEDTLS_BYTES_TO_T_UINT_8( 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 ),
|
||||
};
|
||||
static const mbedtls_mpi_uint x25519_bad_point_2[] = {
|
||||
MBEDTLS_BYTES_TO_T_UINT_8( 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24 ),
|
||||
MBEDTLS_BYTES_TO_T_UINT_8( 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b ),
|
||||
MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86 ),
|
||||
MBEDTLS_BYTES_TO_T_UINT_8( 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 ),
|
||||
};
|
||||
static const mbedtls_mpi ecp_x25519_bad_point_1 = ECP_MPI_INIT_ARRAY(
|
||||
x25519_bad_point_1 );
|
||||
static const mbedtls_mpi ecp_x25519_bad_point_2 = ECP_MPI_INIT_ARRAY(
|
||||
x25519_bad_point_2 );
|
||||
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
|
||||
|
||||
/*
|
||||
* Check that the input point is not one of the low-order points.
|
||||
* This is recommended by the "May the Fourth" paper:
|
||||
* https://eprint.iacr.org/2017/806.pdf
|
||||
* Those points are never sent by an honest peer.
|
||||
*/
|
||||
static int ecp_check_bad_points_mx( const mbedtls_mpi *X, const mbedtls_mpi *P,
|
||||
const mbedtls_ecp_group_id grp_id )
|
||||
{
|
||||
int ret;
|
||||
mbedtls_mpi XmP;
|
||||
|
||||
mbedtls_mpi_init( &XmP );
|
||||
|
||||
/* Reduce X mod P so that we only need to check values less than P.
|
||||
* We know X < 2^256 so we can proceed by subtraction. */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &XmP, X ) );
|
||||
while( mbedtls_mpi_cmp_mpi( &XmP, P ) >= 0 )
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &XmP, &XmP, P ) );
|
||||
|
||||
/* Check against the known bad values that are less than P. For Curve448
|
||||
* these are 0, 1 and -1. For Curve25519 we check the values less than P
|
||||
* from the following list: https://cr.yp.to/ecdh.html#validate */
|
||||
if( mbedtls_mpi_cmp_int( &XmP, 1 ) <= 0 ) /* takes care of 0 and 1 */
|
||||
{
|
||||
ret = MBEDTLS_ERR_ECP_INVALID_KEY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
|
||||
if( grp_id == MBEDTLS_ECP_DP_CURVE25519 )
|
||||
{
|
||||
if( mbedtls_mpi_cmp_mpi( &XmP, &ecp_x25519_bad_point_1 ) == 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_ECP_INVALID_KEY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if( mbedtls_mpi_cmp_mpi( &XmP, &ecp_x25519_bad_point_2 ) == 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_ECP_INVALID_KEY;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) grp_id;
|
||||
#endif
|
||||
|
||||
/* Final check: check if XmP + 1 is P (final because it changes XmP!) */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &XmP, &XmP, 1 ) );
|
||||
if( mbedtls_mpi_cmp_mpi( &XmP, P ) == 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_ECP_INVALID_KEY;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free( &XmP );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Check validity of a public key for Montgomery curves with x-only schemes
|
||||
*/
|
||||
@ -2757,7 +2849,13 @@ static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_
|
||||
if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 )
|
||||
return( MBEDTLS_ERR_ECP_INVALID_KEY );
|
||||
|
||||
return( 0 );
|
||||
/* Implicit in all standards (as they don't consider negative numbers):
|
||||
* X must be non-negative. This is normally ensured by the way it's
|
||||
* encoded for transmission, but let's be extra sure. */
|
||||
if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 )
|
||||
return( MBEDTLS_ERR_ECP_INVALID_KEY );
|
||||
|
||||
return( ecp_check_bad_points_mx( &pt->X, &grp->P, grp->id ) );
|
||||
}
|
||||
#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
|
||||
|
||||
|
6049
library/ecp_curves.c
6049
library/ecp_curves.c
File diff suppressed because it is too large
Load Diff
@ -33,13 +33,133 @@ ECP curve info #8
|
||||
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
||||
mbedtls_ecp_curve_info:MBEDTLS_ECP_DP_SECP192R1:19:192:"secp192r1"
|
||||
|
||||
ECP check pubkey Montgomery #1 (too big)
|
||||
ECP check pubkey Curve25519 #1 (biggest)
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":0
|
||||
|
||||
ECP check pubkey Curve25519 #2 (too big)
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"010000000000000000000000000000000000000000000000000000000000000000":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Montgomery #2 (biggest)
|
||||
ECP check pubkey Curve25519 #3 (DoS big)
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":0
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"0100000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Curve25519 y ignored
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"2":"-1":"1":0
|
||||
|
||||
ECP check pubkey Curve25519 z is not 1
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"2":"0":"2":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Curve25519 x negative
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"-2":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
# see https://cr.yp.to/ecdh.html#validate
|
||||
ECP check pubkey Curve25519 low-order point #1
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"0":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
# see https://cr.yp.to/ecdh.html#validate
|
||||
ECP check pubkey Curve25519 low-order point #2
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"1":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
# see https://cr.yp.to/ecdh.html#validate
|
||||
ECP check pubkey Curve25519 low-order point #3 (let's call this u)
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"b8495f16056286fdb1329ceb8d09da6ac49ff1fae35616aeb8413b7c7aebe0":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
# see https://cr.yp.to/ecdh.html#validate
|
||||
ECP check pubkey Curve25519 low-order point #4 (let's call this v)
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"57119fd0dd4e22d8868e1c58c45c44045bef839c55b1d0b1248c50a3bc959c5f":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
# see https://cr.yp.to/ecdh.html#validate
|
||||
ECP check pubkey Curve25519 low-order point #5 p-1
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
# see https://cr.yp.to/ecdh.html#validate
|
||||
ECP check pubkey Curve25519 low-order point #6 p
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
# see https://cr.yp.to/ecdh.html#validate
|
||||
ECP check pubkey Curve25519 low-order point #7 p+1
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
# see https://cr.yp.to/ecdh.html#validate
|
||||
ECP check pubkey Curve25519 low-order point #8 p+u
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"80b8495f16056286fdb1329ceb8d09da6ac49ff1fae35616aeb8413b7c7aebcd":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
# see https://cr.yp.to/ecdh.html#validate
|
||||
ECP check pubkey Curve25519 low-order point #9 p+v
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"d7119fd0dd4e22d8868e1c58c45c44045bef839c55b1d0b1248c50a3bc959c4c":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
# see https://cr.yp.to/ecdh.html#validate
|
||||
ECP check pubkey Curve25519 low-order point #10 2p-1
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd9":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
# see https://cr.yp.to/ecdh.html#validate
|
||||
ECP check pubkey Curve25519 low-order point #11 2p
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffda":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
# see https://cr.yp.to/ecdh.html#validate
|
||||
ECP check pubkey Curve25519 low-order point #12 2p+1
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE25519:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdb":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Curve448 #1 (biggest)
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":0
|
||||
|
||||
ECP check pubkey Curve448 #2 (too big)
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Curve448 #3 (DoS big)
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"0100000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Curve448 y ignored
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"2":"-1":"1":0
|
||||
|
||||
ECP check pubkey Curve448 z is not 1
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"2":"0":"2":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Curve448 x negative
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"-2":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Curve448 low-order point #1
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"0":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Curve448 low-order point #2
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"1":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Curve448 low-order point #3 p-1
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Curve448 low-order point #4 p
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Curve448 low-order point #5 p+1
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
ecp_check_pub:MBEDTLS_ECP_DP_CURVE448:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000000000000":"0":"1":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP check pubkey Koblitz #1 (point not on curve)
|
||||
depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED
|
||||
@ -473,15 +593,15 @@ ecp_test_mul:MBEDTLS_ECP_DP_CURVE25519:"5AC99F33632E5A768DE7E81BF854C27C46E3FBF2
|
||||
|
||||
ECP point multiplication Curve25519 (element of order 2: origin) #3
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_test_mul:MBEDTLS_ECP_DP_CURVE25519:"5AC99F33632E5A768DE7E81BF854C27C46E3FBF2ABBACD29EC4AFF517369C660":"00":"00":"01":"00":"01":"00":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
|
||||
ecp_test_mul:MBEDTLS_ECP_DP_CURVE25519:"5AC99F33632E5A768DE7E81BF854C27C46E3FBF2ABBACD29EC4AFF517369C660":"00":"00":"01":"00":"01":"00":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP point multiplication Curve25519 (element of order 4: 1) #4
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_test_mul:MBEDTLS_ECP_DP_CURVE25519:"5AC99F33632E5A768DE7E81BF854C27C46E3FBF2ABBACD29EC4AFF517369C660":"01":"00":"01":"00":"01":"00":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
|
||||
ecp_test_mul:MBEDTLS_ECP_DP_CURVE25519:"5AC99F33632E5A768DE7E81BF854C27C46E3FBF2ABBACD29EC4AFF517369C660":"01":"00":"01":"00":"01":"00":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP point multiplication Curve25519 (element of order 8) #5
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
ecp_test_mul:MBEDTLS_ECP_DP_CURVE25519:"5AC99F33632E5A768DE7E81BF854C27C46E3FBF2ABBACD29EC4AFF517369C660":"B8495F16056286FDB1329CEB8D09DA6AC49FF1FAE35616AEB8413B7C7AEBE0":"00":"01":"00":"01":"00":MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
|
||||
ecp_test_mul:MBEDTLS_ECP_DP_CURVE25519:"5AC99F33632E5A768DE7E81BF854C27C46E3FBF2ABBACD29EC4AFF517369C660":"B8495F16056286FDB1329CEB8D09DA6AC49FF1FAE35616AEB8413B7C7AEBE0":"00":"01":"00":"01":"00":MBEDTLS_ERR_ECP_INVALID_KEY
|
||||
|
||||
ECP point multiplication rng fail secp256r1
|
||||
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
|
Loading…
Reference in New Issue
Block a user