Commit f390b0d4 authored by ROOL's avatar ROOL 🤖
Browse files

Library update

Detail:
  This is release 2.16.11 direct from ARM, with customisations to ro_config.h/timing.c/entropy_poll.c/net_sockets.[c|h] to port to RISC OS.

Version 2.24. Tagged as 'mbedTLS-2_24'
parent dde769da
/* (2.23) /* (2.24)
* *
* This file is automatically maintained by srccommit, do not edit manually. * This file is automatically maintained by srccommit, do not edit manually.
* *
*/ */
#define Module_MajorVersion_CMHG 2.23 #define Module_MajorVersion_CMHG 2.24
#define Module_MinorVersion_CMHG #define Module_MinorVersion_CMHG
#define Module_Date_CMHG 15 Mar 2021 #define Module_Date_CMHG 10 Jul 2021
#define Module_MajorVersion "2.23" #define Module_MajorVersion "2.24"
#define Module_Version 223 #define Module_Version 224
#define Module_MinorVersion "" #define Module_MinorVersion ""
#define Module_Date "15 Mar 2021" #define Module_Date "10 Jul 2021"
#define Module_ApplicationDate "15-Mar-21" #define Module_ApplicationDate "10-Jul-21"
#define Module_ComponentName "mbedTLS" #define Module_ComponentName "mbedTLS"
#define Module_FullVersion "2.23" #define Module_FullVersion "2.24"
#define Module_HelpVersion "2.23 (15 Mar 2021)" #define Module_HelpVersion "2.24 (10 Jul 2021)"
#define Module_LibraryVersionInfo "2:23" #define Module_LibraryVersionInfo "2:24"
...@@ -952,7 +952,7 @@ static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertext ...@@ -952,7 +952,7 @@ static const uint8_t aria_test2_ctr_ct[3][48] = // CTR ciphertext
{ \ { \
if( verbose ) \ if( verbose ) \
mbedtls_printf( "failed\n" ); \ mbedtls_printf( "failed\n" ); \
return( 1 ); \ goto exit; \
} else { \ } else { \
if( verbose ) \ if( verbose ) \
mbedtls_printf( "passed\n" ); \ mbedtls_printf( "passed\n" ); \
...@@ -966,6 +966,7 @@ int mbedtls_aria_self_test( int verbose ) ...@@ -966,6 +966,7 @@ int mbedtls_aria_self_test( int verbose )
int i; int i;
uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE]; uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE];
mbedtls_aria_context ctx; mbedtls_aria_context ctx;
int ret = 1;
#if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR)) #if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR))
size_t j; size_t j;
...@@ -977,6 +978,8 @@ int mbedtls_aria_self_test( int verbose ) ...@@ -977,6 +978,8 @@ int mbedtls_aria_self_test( int verbose )
uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE]; uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE];
#endif #endif
mbedtls_aria_init( &ctx );
/* /*
* Test set 1 * Test set 1
*/ */
...@@ -1096,7 +1099,11 @@ int mbedtls_aria_self_test( int verbose ) ...@@ -1096,7 +1099,11 @@ int mbedtls_aria_self_test( int verbose )
mbedtls_printf( "\n" ); mbedtls_printf( "\n" );
#endif /* MBEDTLS_CIPHER_MODE_CTR */ #endif /* MBEDTLS_CIPHER_MODE_CTR */
return( 0 ); ret = 0;
exit:
mbedtls_aria_free( &ctx );
return( ret );
} }
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */
......
...@@ -267,6 +267,36 @@ void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ) ...@@ -267,6 +267,36 @@ void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
memcpy( Y, &T, sizeof( mbedtls_mpi ) ); 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 * Conditionally assign dest = src, without leaking information
* about whether the assignment was made or not. * about whether the assignment was made or not.
...@@ -279,8 +309,23 @@ static void mpi_safe_cond_assign( size_t n, ...@@ -279,8 +309,23 @@ static void mpi_safe_cond_assign( size_t n,
unsigned char assign ) unsigned char assign )
{ {
size_t i; 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++ ) for( i = 0; i < n; i++ )
dest[i] = dest[i] * ( 1 - assign ) + src[i] * assign; dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
} }
/* /*
...@@ -292,20 +337,34 @@ int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned ...@@ -292,20 +337,34 @@ int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned
{ {
int ret = 0; int ret = 0;
size_t i; size_t i;
mbedtls_mpi_uint limb_mask;
MPI_VALIDATE_RET( X != NULL ); MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( Y != 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 */ /* 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 ) ); 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 ); mpi_safe_cond_assign( Y->n, X->p, Y->p, assign );
for( i = Y->n; i < X->n; i++ ) for( i = Y->n; i < X->n; i++ )
X->p[i] *= ( 1 - assign ); X->p[i] &= ~limb_mask;
cleanup: cleanup:
return( ret ); return( ret );
...@@ -321,6 +380,7 @@ int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char sw ...@@ -321,6 +380,7 @@ int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char sw
{ {
int ret, s; int ret, s;
size_t i; size_t i;
mbedtls_mpi_uint limb_mask;
mbedtls_mpi_uint tmp; mbedtls_mpi_uint tmp;
MPI_VALIDATE_RET( X != NULL ); MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( Y != NULL ); MPI_VALIDATE_RET( Y != NULL );
...@@ -328,22 +388,35 @@ int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char sw ...@@ -328,22 +388,35 @@ int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char sw
if( X == Y ) if( X == Y )
return( 0 ); 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 */ /* 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( X, Y->n ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
s = X->s; s = X->s;
X->s = X->s * ( 1 - swap ) + Y->s * swap; X->s = mpi_safe_cond_select_sign( X->s, Y->s, swap );
Y->s = Y->s * ( 1 - swap ) + s * swap; Y->s = mpi_safe_cond_select_sign( Y->s, s, swap );
for( i = 0; i < X->n; i++ ) for( i = 0; i < X->n; i++ )
{ {
tmp = X->p[i]; tmp = X->p[i];
X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap; X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap; Y->p[i] = ( Y->p[i] & ~limb_mask ) | ( tmp & limb_mask );
} }
cleanup: cleanup:
...@@ -500,6 +573,7 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ) ...@@ -500,6 +573,7 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
{ {
int ret; int ret;
size_t i, j, slen, n; size_t i, j, slen, n;
int sign = 1;
mbedtls_mpi_uint d; mbedtls_mpi_uint d;
mbedtls_mpi T; mbedtls_mpi T;
MPI_VALIDATE_RET( X != NULL ); MPI_VALIDATE_RET( X != NULL );
...@@ -510,6 +584,12 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ) ...@@ -510,6 +584,12 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T );
if( s[0] == '-' )
{
++s;
sign = -1;
}
slen = strlen( s ); slen = strlen( s );
if( radix == 16 ) if( radix == 16 )
...@@ -524,12 +604,6 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ) ...@@ -524,12 +604,6 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
for( i = slen, j = 0; i > 0; i--, j++ ) for( i = slen, j = 0; i > 0; i--, j++ )
{ {
if( i == 1 && s[i - 1] == '-' )
{
X->s = -1;
break;
}
MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) ); MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 ); X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
} }
...@@ -540,26 +614,15 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ) ...@@ -540,26 +614,15 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
for( i = 0; i < slen; i++ ) for( i = 0; i < slen; i++ )
{ {
if( i == 0 && s[i] == '-' )
{
X->s = -1;
continue;
}
MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) );
if( X->s == 1 )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) );
}
else
{
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( X, &T, d ) );
}
} }
} }
if( sign < 0 && mbedtls_mpi_bitlen( X ) != 0 )
X->s = -1;
cleanup: cleanup:
mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T );
...@@ -1570,6 +1633,7 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi ...@@ -1570,6 +1633,7 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
int ret; int ret;
size_t i, j; size_t i, j;
mbedtls_mpi TA, TB; mbedtls_mpi TA, TB;
int result_is_zero = 0;
MPI_VALIDATE_RET( X != NULL ); MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL ); MPI_VALIDATE_RET( A != NULL );
MPI_VALIDATE_RET( B != NULL ); MPI_VALIDATE_RET( B != NULL );
...@@ -1582,10 +1646,14 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi ...@@ -1582,10 +1646,14 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
for( i = A->n; i > 0; i-- ) for( i = A->n; i > 0; i-- )
if( A->p[i - 1] != 0 ) if( A->p[i - 1] != 0 )
break; break;
if( i == 0 )
result_is_zero = 1;
for( j = B->n; j > 0; j-- ) for( j = B->n; j > 0; j-- )
if( B->p[j - 1] != 0 ) if( B->p[j - 1] != 0 )
break; break;
if( j == 0 )
result_is_zero = 1;
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
...@@ -1593,7 +1661,14 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi ...@@ -1593,7 +1661,14 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
for( ; j > 0; j-- ) for( ; j > 0; j-- )
mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] ); mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] );
X->s = A->s * B->s; /* If the result is 0, we don't shortcut the operation, which reduces
* but does not eliminate side channels leaking the zero-ness. We do
* need to take care to set the sign bit properly since the library does
* not fully support an MPI object with a value of 0 and s == -1. */
if( result_is_zero )
X->s = 1;
else
X->s = A->s * B->s;
cleanup: cleanup:
...@@ -2041,6 +2116,72 @@ static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, ...@@ -2041,6 +2116,72 @@ static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
mpi_montmul( A, &U, N, mm, T ); 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_MPI_BAD_INPUT_DATA;
size_t i;
for( 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) * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
*/ */
...@@ -2053,7 +2194,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, ...@@ -2053,7 +2194,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
size_t i, j, nblimbs; size_t i, j, nblimbs;
size_t bufsize, nbits; size_t bufsize, nbits;
mbedtls_mpi_uint ei, mm, state; 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; int neg;
MPI_VALIDATE_RET( X != NULL ); MPI_VALIDATE_RET( X != NULL );
...@@ -2077,6 +2218,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, ...@@ -2077,6 +2218,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
mpi_montg_init( &mm, N ); mpi_montg_init( &mm, N );
mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
mbedtls_mpi_init( &Apos ); mbedtls_mpi_init( &Apos );
mbedtls_mpi_init( &WW );
memset( W, 0, sizeof( W ) ); memset( W, 0, sizeof( W ) );
i = mbedtls_mpi_bitlen( E ); i = mbedtls_mpi_bitlen( E );
...@@ -2090,6 +2232,11 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, ...@@ -2090,6 +2232,11 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
#endif #endif
j = N->n + 1; j = N->n + 1;
/* All W[i] and X must have at least N->n limbs for the mpi_montmul()
* and mpi_montred() calls later. Here we ensure that W[1] and X are
* large enough, and later we'll grow other W[i] to the same length.
* They must not be shrunk midway through this function!
*/
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
...@@ -2127,6 +2274,10 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, ...@@ -2127,6 +2274,10 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
else else
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
/* Re-grow W[1] if necessary. This should be only necessary in one corner
* case: when A == 0 represented with A.n == 0, mbedtls_mpi_copy shrinks
* W[1] to 0 limbs. */
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], N->n +1 ) );
mpi_montmul( &W[1], &RR, N, mm, &T ); mpi_montmul( &W[1], &RR, N, mm, &T );
...@@ -2217,7 +2368,8 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, ...@@ -2217,7 +2368,8 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
/* /*
* X = X * W[wbits] R^-1 mod N * 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--; state--;
nbits = 0; nbits = 0;
...@@ -2255,6 +2407,7 @@ cleanup: ...@@ -2255,6 +2407,7 @@ cleanup:
mbedtls_mpi_free( &W[i] ); mbedtls_mpi_free( &W[i] );
mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos ); mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
mbedtls_mpi_free( &WW );
if( _RR == NULL || _RR->p == NULL ) if( _RR == NULL || _RR->p == NULL )
mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &RR );
...@@ -2283,6 +2436,16 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B ...@@ -2283,6 +2436,16 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
lz = mbedtls_mpi_lsb( &TA ); lz = mbedtls_mpi_lsb( &TA );
lzt = mbedtls_mpi_lsb( &TB ); lzt = mbedtls_mpi_lsb( &TB );
/* The loop below gives the correct result when A==0 but not when B==0.
* So have a special case for B==0. Leverage the fact that we just
* calculated the lsb and lsb(B)==0 iff B is odd or 0 to make the test
* slightly more efficient than cmp_int(). */
if( lzt == 0 && mbedtls_mpi_get_bit( &TB, 0 ) == 0 )
{
ret = mbedtls_mpi_copy( G, A );
goto cleanup;
}
if( lzt < lz ) if( lzt < lz )
lz = lzt; lz = lzt;
...@@ -2291,11 +2454,52 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B ...@@ -2291,11 +2454,52 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
TA.s = TB.s = 1; TA.s = TB.s = 1;
/* We mostly follow the procedure described in HAC 14.54, but with some
* minor differences:
* - Sequences of multiplications or divisions by 2 are grouped into a
* single shift operation.
* - The procedure in HAC assumes that 0 < TB <= TA.
* - The condition TB <= TA is not actually necessary for correctness.
* TA and TB have symmetric roles except for the loop termination
* condition, and the shifts at the beginning of the loop body
* remove any significance from the ordering of TA vs TB before
* the shifts.
* - If TA = 0, the loop goes through 0 iterations and the result is
* correctly TB.
* - The case TB = 0 was short-circuited above.
*