Merge pull request #2019 from gilles-peskine-arm/build_with_only_montgomery_curves-conditional_mul_add

Build with only Montgomery curves (conditional mul_add)
This commit is contained in:
Manuel Pégourié-Gonnard 2020-07-22 13:13:36 +02:00 committed by GitHub
commit ee7e85f5b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 377 additions and 142 deletions

View file

@ -0,0 +1,6 @@
Bugfix
* Fix build errors when the only enabled elliptic curves are Montgomery
curves. Raised by signpainter in #941 and by Taiki-San in #1412. This
also fixes missing declarations reported by Steven Cooreman in #1147.
* Fix self-test failure when the only enabled short Weierstrass elliptic
curve is secp192k1. Fixes #2017.

View file

@ -103,6 +103,17 @@
#if defined(MBEDTLS_ECDSA_C) && \
( !defined(MBEDTLS_ECP_C) || \
!( defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) ) || \
!defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_ASN1_WRITE_C) )
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
@ -246,12 +257,14 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
#endif

View file

@ -756,6 +756,7 @@
*
* Comment macros to disable the curve and functions for it
*/
/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
@ -767,6 +768,7 @@
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
#define MBEDTLS_ECP_DP_BP512R1_ENABLED
/* Montgomery curves (supporting ECP) */
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
#define MBEDTLS_ECP_DP_CURVE448_ENABLED
@ -1083,7 +1085,7 @@
*
* Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS.
*
* Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
* Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C
*
* This enables the following ciphersuites (if other requisites are
* enabled as well):
@ -1107,7 +1109,7 @@
*
* Enable the ECDH-RSA based ciphersuite modes in SSL / TLS.
*
* Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
* Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_X509_CRT_PARSE_C
*
* This enables the following ciphersuites (if other requisites are
* enabled as well):
@ -2571,7 +2573,9 @@
* This module is used by the following key exchanges:
* ECDHE-ECDSA
*
* Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C
* Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C,
* and at least one MBEDTLS_ECP_DP_XXX_ENABLED for a
* short Weierstrass curve.
*/
#define MBEDTLS_ECDSA_C

View file

@ -61,6 +61,26 @@
#define MBEDTLS_ERR_ECP_IN_PROGRESS -0x4B00 /**< Operation in progress, call again with the same parameters to continue. */
/* Flags indicating whether to include code that is specific to certain
* types of curves. These flags are for internal library use only. */
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
#define MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
#endif
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
#define MBEDTLS_ECP_MONTGOMERY_ENABLED
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -74,6 +94,20 @@ extern "C" {
* parameters. Therefore, only standardized domain parameters from trusted
* sources should be used. See mbedtls_ecp_group_load().
*/
/* Note: when adding a new curve:
* - Add it at the end of this enum, otherwise you'll break the ABI by
* changing the numerical value for existing curves.
* - Increment MBEDTLS_ECP_DP_MAX below if needed.
* - Add the corresponding MBEDTLS_ECP_DP_xxx_ENABLED macro definition to
* config.h.
* - List the curve as a dependency of MBEDTLS_ECP_C and
* MBEDTLS_ECDSA_C if supported in check_config.h.
* - Add the curve to the appropriate curve type macro
* MBEDTLS_ECP_yyy_ENABLED above.
* - Add the necessary definitions to ecp_curves.c.
* - Add the curve to the ecp_supported_curves array in ecp.c.
* - Add the curve to applicable profiles in x509_crt.c if applicable.
*/
typedef enum
{
MBEDTLS_ECP_DP_NONE = 0, /*!< Curve not defined. */
@ -906,6 +940,7 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx );
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/**
* \brief This function performs multiplication and addition of two
* points by integers: \p R = \p m * \p P + \p n * \p Q
@ -915,6 +950,10 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
* \note In contrast to mbedtls_ecp_mul(), this function does not
* guarantee a constant execution flow and timing.
*
* \note This function is only defined for short Weierstrass curves.
* It may not be included in builds without any short
* Weierstrass curve.
*
* \param grp The ECP group to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
@ -933,6 +972,8 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
* valid private keys, or \p P or \p Q are not valid public
* keys.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not
* designate a short Weierstrass curve.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
@ -950,6 +991,10 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
* but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
* \note This function is only defined for short Weierstrass curves.
* It may not be included in builds without any short
* Weierstrass curve.
*
* \param grp The ECP group to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
@ -969,6 +1014,8 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
* valid private keys, or \p P or \p Q are not valid public
* keys.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not
* designate a short Weierstrass curve.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another negative error code on other kinds of failure.
@ -978,6 +1025,7 @@ int mbedtls_ecp_muladd_restartable(
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
const mbedtls_mpi *n, const mbedtls_ecp_point *Q,
mbedtls_ecp_restart_ctx *rs_ctx );
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
/**
* \brief This function checks that a point is a valid public key

View file

@ -105,7 +105,7 @@ int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp );
*/
void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp );
#if defined(ECP_SHORTWEIERSTRASS)
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
/**
@ -245,9 +245,9 @@ int mbedtls_internal_ecp_normalize_jac( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *pt );
#endif
#endif /* ECP_SHORTWEIERSTRASS */
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
int mbedtls_internal_ecp_double_add_mxz( const mbedtls_ecp_group *grp,
@ -291,7 +291,7 @@ int mbedtls_internal_ecp_normalize_mxz( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *P );
#endif
#endif /* ECP_MONTGOMERY */
#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
#endif /* MBEDTLS_ECP_INTERNAL_ALT */

View file

@ -501,25 +501,6 @@ int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp,
#endif /* MBEDTLS_ECP_RESTARTABLE */
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
#define ECP_SHORTWEIERSTRASS
#endif
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
#define ECP_MONTGOMERY
#endif
/*
* List of supported curves:
* - internal ID
@ -897,7 +878,8 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
plen = mbedtls_mpi_size( &grp->P );
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
(void) format; /* Montgomery curves always use the same point format */
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
*olen = plen;
@ -907,7 +889,7 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &P->X, buf, plen ) );
}
#endif
#if defined(ECP_SHORTWEIERSTRASS)
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
/*
@ -970,7 +952,7 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
plen = mbedtls_mpi_size( &grp->P );
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
if( plen != ilen )
@ -986,7 +968,7 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
}
#endif
#if defined(ECP_SHORTWEIERSTRASS)
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
if( buf[0] == 0x00 )
@ -1304,7 +1286,7 @@ cleanup:
return( ret );
}
#if defined(ECP_SHORTWEIERSTRASS)
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/*
* For curves in short Weierstrass form, we do all the internal operations in
* Jacobian coordinates.
@ -2413,9 +2395,9 @@ cleanup:
return( ret );
}
#endif /* ECP_SHORTWEIERSTRASS */
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
/*
* For Montgomery curves, we do all the internal arithmetic in projective
* coordinates. Import/export of points uses only the x coordinates, which is
@ -2649,7 +2631,7 @@ cleanup:
return( ret );
}
#endif /* ECP_MONTGOMERY */
#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
/*
* Restartable multiplication R = m * P
@ -2672,6 +2654,8 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
/* reset ops count for this call if top-level */
if( rs_ctx != NULL && rs_ctx->depth++ == 0 )
rs_ctx->ops_done = 0;
#else
(void) rs_ctx;
#endif
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
@ -2693,11 +2677,11 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
}
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
MBEDTLS_MPI_CHK( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) );
#endif
#if defined(ECP_SHORTWEIERSTRASS)
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
MBEDTLS_MPI_CHK( ecp_mul_comb( grp, R, m, P, f_rng, p_rng, rs_ctx ) );
#endif
@ -2731,7 +2715,7 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
return( mbedtls_ecp_mul_restartable( grp, R, m, P, f_rng, p_rng, NULL ) );
}
#if defined(ECP_SHORTWEIERSTRASS)
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/*
* Check that an affine point is valid as a public key,
* short weierstrass curves (SEC1 3.2.3.1)
@ -2779,8 +2763,9 @@ cleanup:
return( ret );
}
#endif /* ECP_SHORTWEIERSTRASS */
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/*
* R = m * P with shortcuts for m == 1 and m == -1
* NOT constant-time - ONLY for short Weierstrass!
@ -2926,8 +2911,9 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
ECP_VALIDATE_RET( Q != NULL );
return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) );
}
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
/*
* Check validity of a public key for Montgomery curves with x-only schemes
*/
@ -2941,7 +2927,7 @@ static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_
return( 0 );
}
#endif /* ECP_MONTGOMERY */
#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
/*
* Check that a point is valid as a public key
@ -2956,11 +2942,11 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 )
return( MBEDTLS_ERR_ECP_INVALID_KEY );
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
return( ecp_check_pubkey_mx( grp, pt ) );
#endif
#if defined(ECP_SHORTWEIERSTRASS)
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
return( ecp_check_pubkey_sw( grp, pt ) );
#endif
@ -2976,7 +2962,7 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( d != NULL );
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
/* see RFC 7748 sec. 5 para. 5 */
@ -2991,8 +2977,8 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
return( 0 );
}
#endif /* ECP_MONTGOMERY */
#if defined(ECP_SHORTWEIERSTRASS)
#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
/* see SEC1 3.2 */
@ -3002,7 +2988,7 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
else
return( 0 );
}
#endif /* ECP_SHORTWEIERSTRASS */
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
}
@ -3024,7 +3010,7 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
n_size = ( grp->nbits + 7 ) / 8;
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
/* [M225] page 5 */
@ -3050,9 +3036,9 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
}
}
#endif /* ECP_MONTGOMERY */
#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
#if defined(ECP_SHORTWEIERSTRASS)
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
/* SEC1 3.2.1: Generate d such that 1 <= n < N */
@ -3094,7 +3080,7 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
}
while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || cmp != 1 );
}
#endif /* ECP_SHORTWEIERSTRASS */
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
cleanup:
return( ret );
@ -3172,7 +3158,7 @@ int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
/*
@ -3207,7 +3193,7 @@ int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
}
#endif
#if defined(ECP_SHORTWEIERSTRASS)
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &key->d, buf, buflen ) );
@ -3235,7 +3221,7 @@ int mbedtls_ecp_write_key( mbedtls_ecp_keypair *key,
ECP_VALIDATE_RET( key != NULL );
ECP_VALIDATE_RET( buf != NULL );
#if defined(ECP_MONTGOMERY)
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
if( key->grp.id == MBEDTLS_ECP_DP_CURVE25519 )
@ -3250,7 +3236,7 @@ int mbedtls_ecp_write_key( mbedtls_ecp_keypair *key,
}
#endif
#if defined(ECP_SHORTWEIERSTRASS)
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &key->d, buf, buflen ) );
@ -3309,33 +3295,141 @@ cleanup:
#if defined(MBEDTLS_SELF_TEST)
/* Adjust the exponent to be a valid private point for the specified curve.
* This is sometimes necessary because we use a single set of exponents
* for all curves but the validity of values depends on the curve. */
static int self_test_adjust_exponent( const mbedtls_ecp_group *grp,
mbedtls_mpi *m )
{
int ret = 0;
switch( grp->id )
{
/* If Curve25519 is available, then that's what we use for the
* Montgomery test, so we don't need the adjustment code. */
#if ! defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
case MBEDTLS_ECP_DP_CURVE448:
/* Move highest bit from 254 to N-1. Setting bit N-1 is
* necessary to enforce the highest-bit-set constraint. */
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( m, 254, 0 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( m, grp->nbits, 1 ) );
/* Copy second-highest bit from 253 to N-2. This is not
* necessary but improves the test variety a bit. */
MBEDTLS_MPI_CHK(
mbedtls_mpi_set_bit( m, grp->nbits - 1,
mbedtls_mpi_get_bit( m, 253 ) ) );
break;
#endif
#endif /* ! defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) */
default:
/* Non-Montgomery curves and Curve25519 need no adjustment. */
(void) grp;
(void) m;
goto cleanup;
}
cleanup:
return( ret );
}
/* Calculate R = m.P for each m in exponents. Check that the number of
* basic operations doesn't depend on the value of m. */
static int self_test_point( int verbose,
mbedtls_ecp_group *grp,
mbedtls_ecp_point *R,
mbedtls_mpi *m,
const mbedtls_ecp_point *P,
const char *const *exponents,
size_t n_exponents )
{
int ret = 0;
size_t i = 0;
unsigned long add_c_prev, dbl_c_prev, mul_c_prev;
add_count = 0;
dbl_count = 0;
mul_count = 0;
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[0] ) );
MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
for( i = 1; i < n_exponents; i++ )
{
add_c_prev = add_count;
dbl_c_prev = dbl_count;
mul_c_prev = mul_count;
add_count = 0;
dbl_count = 0;
mul_count = 0;
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[i] ) );
MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
if( add_count != add_c_prev ||
dbl_count != dbl_c_prev ||
mul_count != mul_c_prev )
{
ret = 1;
break;
}
}
cleanup:
if( verbose != 0 )
{
if( ret != 0 )
mbedtls_printf( "failed (%u)\n", (unsigned int) i );
else
mbedtls_printf( "passed\n" );
}
return( ret );
}
/*
* Checkup routine
*/
int mbedtls_ecp_self_test( int verbose )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_ecp_group grp;
mbedtls_ecp_point R, P;
mbedtls_mpi m;
unsigned long add_c_prev, dbl_c_prev, mul_c_prev;
/* exponents especially adapted for secp192r1 */
const char *exponents[] =
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/* Exponents especially adapted for secp192k1, which has the lowest
* order n of all supported curves (secp192r1 is in a slightly larger
* field but the order of its base point is slightly smaller). */
const char *sw_exponents[] =
{
"000000000000000000000000000000000000000000000001", /* one */
"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */
"FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8C", /* n - 1 */
"5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */
"400000000000000000000000000000000000000000000000", /* one and zeros */
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */
"555555555555555555555555555555555555555555555555", /* 101010... */
};
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
const char *m_exponents[] =
{
/* Valid private values for Curve25519. In a build with Curve448
* but not Curve25519, they will be adjusted in
* self_test_adjust_exponent(). */
"4000000000000000000000000000000000000000000000000000000000000000",
"5C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C30",
"5715ECCE24583F7A7023C24164390586842E816D7280A49EF6DF4EAE6B280BF8",
"41A2B017516F6D254E1F002BCCBADD54BE30F8CEC737A0E912B4963B6BA74460",
"5555555555555555555555555555555555555555555555555555555555555550",
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8",
};
#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
mbedtls_ecp_group_init( &grp );
mbedtls_ecp_point_init( &R );
mbedtls_ecp_point_init( &P );
mbedtls_mpi_init( &m );
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/* Use secp192r1 if available, or any available curve */
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP192R1 ) );
@ -3344,81 +3438,48 @@ int mbedtls_ecp_self_test( int verbose )
#endif
if( verbose != 0 )
mbedtls_printf( " ECP test #1 (constant op_count, base point G): " );
mbedtls_printf( " ECP SW test #1 (constant op_count, base point G): " );
/* Do a dummy multiplication first to trigger precomputation */
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) );
add_count = 0;
dbl_count = 0;
mul_count = 0;
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
{
add_c_prev = add_count;
dbl_c_prev = dbl_count;
mul_c_prev = mul_count;
add_count = 0;
dbl_count = 0;
mul_count = 0;
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
if( add_count != add_c_prev ||
dbl_count != dbl_c_prev ||
mul_count != mul_c_prev )
{
if( verbose != 0 )
mbedtls_printf( "failed (%u)\n", (unsigned int) i );
ret = 1;
goto cleanup;
}
}
ret = self_test_point( verbose,
&grp, &R, &m, &grp.G,
sw_exponents,
sizeof( sw_exponents ) / sizeof( sw_exponents[0] ));
if( ret != 0 )
goto cleanup;
if( verbose != 0 )
mbedtls_printf( "passed\n" );
if( verbose != 0 )
mbedtls_printf( " ECP test #2 (constant op_count, other point): " );
mbedtls_printf( " ECP SW test #2 (constant op_count, other point): " );
/* We computed P = 2G last time, use it */
ret = self_test_point( verbose,
&grp, &R, &m, &P,
sw_exponents,
sizeof( sw_exponents ) / sizeof( sw_exponents[0] ));
if( ret != 0 )
goto cleanup;
add_count = 0;
dbl_count = 0;
mul_count = 0;
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
{
add_c_prev = add_count;
dbl_c_prev = dbl_count;
mul_c_prev = mul_count;
add_count = 0;
dbl_count = 0;
mul_count = 0;
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
if( add_count != add_c_prev ||
dbl_count != dbl_c_prev ||
mul_count != mul_c_prev )
{
if( verbose != 0 )
mbedtls_printf( "failed (%u)\n", (unsigned int) i );
ret = 1;
goto cleanup;
}
}
mbedtls_ecp_group_free( &grp );
mbedtls_ecp_point_free( &R );
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
if( verbose != 0 )
mbedtls_printf( "passed\n" );
mbedtls_printf( " ECP Montgomery test (constant op_count): " );
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_CURVE25519 ) );
#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_CURVE448 ) );
#else
#error "MBEDTLS_ECP_MONTGOMERY_ENABLED is defined, but no curve is supported for self-test"
#endif
ret = self_test_point( verbose,
&grp, &R, &m, &grp.G,
m_exponents,
sizeof( m_exponents ) / sizeof( m_exponents[0] ));
if( ret != 0 )
goto cleanup;
#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
cleanup:

View file

@ -553,6 +553,22 @@ static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
};
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
/* For these curves, we build the group parameters dynamically. */
#define ECP_LOAD_GROUP
#endif
#if defined(ECP_LOAD_GROUP)
/*
* Create an MPI from embedded constants
* (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
@ -603,6 +619,7 @@ static int ecp_group_load( mbedtls_ecp_group *grp,
return( 0 );
}
#endif /* ECP_LOAD_GROUP */
#if defined(MBEDTLS_ECP_NIST_OPTIM)
/* Forward declarations */
@ -644,6 +661,7 @@ static int ecp_mod_p224k1( mbedtls_mpi * );
static int ecp_mod_p256k1( mbedtls_mpi * );
#endif
#if defined(ECP_LOAD_GROUP)
#define LOAD_GROUP_A( G ) ecp_group_load( grp, \
G ## _p, sizeof( G ## _p ), \
G ## _a, sizeof( G ## _a ), \
@ -659,6 +677,7 @@ static int ecp_mod_p256k1( mbedtls_mpi * );
G ## _gx, sizeof( G ## _gx ), \
G ## _gy, sizeof( G ## _gy ), \
G ## _n, sizeof( G ## _n ) )
#endif /* ECP_LOAD_GROUP */
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
/*

View file

@ -1001,6 +1001,25 @@ component_test_everest () {
if_build_succeeded tests/compat.sh -f ECDH -V NO -e 'ARCFOUR\|ARIA\|CAMELLIA\|CHACHA\|DES\|RC4'
}
component_test_everest_curve25519_only () {
msg "build: Everest ECDH context, only Curve25519" # ~ 6 min
scripts/config.py unset MBEDTLS_ECDH_LEGACY_CONTEXT
scripts/config.py set MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
scripts/config.py unset MBEDTLS_ECDSA_C
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
# Disable all curves
for c in $(sed -n 's/#define \(MBEDTLS_ECP_DP_[0-9A-Z_a-z]*_ENABLED\).*/\1/p' <"$CONFIG_H"); do
scripts/config.py unset "$c"
done
scripts/config.py set MBEDTLS_ECP_DP_CURVE25519_ENABLED
make CFLAGS="$ASAN_CFLAGS -O2" LDFLAGS="$ASAN_CFLAGS"
msg "test: Everest ECDH context, only Curve25519" # ~ 50s
make test
}
component_test_small_ssl_out_content_len () {
msg "build: small SSL_OUT_CONTENT_LEN (ASan build)"
scripts/config.py set MBEDTLS_SSL_IN_CONTENT_LEN 16384

View file

@ -2,7 +2,7 @@
# curves.pl
#
# Copyright (c) 2014-2016, ARM Limited, All Rights Reserved
# Copyright (c) 2014-2020, ARM Limited, All Rights Reserved
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -21,21 +21,25 @@
#
# Purpose
#
# To test the code dependencies on individual curves in each test suite. This
# is a verification step to ensure we don't ship test suites that do not work
# for some build options.
# The purpose of this test script is to validate that the library works
# with any combination of elliptic curves. To this effect, build the library
# and run the test suite with each tested combination of elliptic curves.
#
# The process is:
# for each possible curve
# build the library and test suites with the curve disabled
# execute the test suites
#
# And any test suite with the wrong dependencies will fail.
# Testing all 2^n combinations would be too much, so we only test 2*n:
#
# 1. Test with a single curve, for each curve. This validates that the
# library works with any curve, and in particular that curve-specific
# code is guarded by the proper preprocessor conditionals.
# 2. Test with all curves except one, for each curve. This validates that
# the test cases have correct dependencies. Testing with a single curve
# doesn't validate this for tests that require more than one curve.
# Usage: tests/scripts/curves.pl
#
# This script should be executed from the root of the project directory.
#
# Only curves that are enabled in config.h will be tested.
#
# For best effect, run either with cmake disabled, or cmake enabled in a mode
# that includes -Werror.
@ -48,6 +52,25 @@ my $sed_cmd = 's/^#define \(MBEDTLS_ECP_DP.*_ENABLED\)/\1/p';
my $config_h = 'include/mbedtls/config.h';
my @curves = split( /\s+/, `sed -n -e '$sed_cmd' $config_h` );
# Determine which curves support ECDSA by checking the dependencies of
# ECDSA in check_config.h.
my %curve_supports_ecdsa = ();
{
local $/ = "";
local *CHECK_CONFIG;
open(CHECK_CONFIG, '<', 'include/mbedtls/check_config.h')
or die "open include/mbedtls/check_config.h: $!";
while (my $stanza = <CHECK_CONFIG>) {
if ($stanza =~ /\A#if defined\(MBEDTLS_ECDSA_C\)/) {
for my $curve ($stanza =~ /(?<=\()MBEDTLS_ECP_DP_\w+_ENABLED(?=\))/g) {
$curve_supports_ecdsa{$curve} = 1;
}
last;
}
}
close(CHECK_CONFIG);
}
system( "cp $config_h $config_h.bak" ) and die;
sub abort {
system( "mv $config_h.bak $config_h" ) and warn "$config_h not restored\n";
@ -56,6 +79,46 @@ sub abort {
exit 1;
}
# Disable all the curves. We'll then re-enable them one by one.
for my $curve (@curves) {
system( "scripts/config.pl unset $curve" )
and abort "Failed to disable $curve\n";
}
# Depends on a specific curve. Also, ignore error if it wasn't enabled.
system( "scripts/config.pl unset MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED" );
# Test with only $curve enabled, for each $curve.
for my $curve (@curves) {
system( "make clean" ) and die;
print "\n******************************************\n";
print "* Testing with only curve: $curve\n";
print "******************************************\n";
$ENV{MBEDTLS_TEST_CONFIGURATION} = "$curve";
system( "scripts/config.pl set $curve" )
and abort "Failed to enable $curve\n";
my $ecdsa = $curve_supports_ecdsa{$curve} ? "set" : "unset";
for my $dep (qw(MBEDTLS_ECDSA_C
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)) {
system( "scripts/config.pl $ecdsa $dep" )
and abort "Failed to $ecdsa $dep\n";
}
system( "CFLAGS='-Werror -Wall -Wextra' make" )
and abort "Failed to build: only $curve\n";
system( "make test" )
and abort "Failed test suite: only $curve\n";
system( "scripts/config.pl unset $curve" )
and abort "Failed to disable $curve\n";
}
system( "cp $config_h.bak $config_h" ) and die "$config_h not restored\n";
# Test with $curve disabled but the others enabled, for each $curve.
for my $curve (@curves) {
system( "cp $config_h.bak $config_h" ) and die "$config_h not restored\n";
system( "make clean" ) and die;
@ -71,10 +134,10 @@ for my $curve (@curves) {
system( "scripts/config.py unset $curve" )
and abort "Failed to disable $curve\n";
system( "CFLAGS='-Werror -Wall -Wextra' make lib" )
and abort "Failed to build lib: $curve\n";
system( "make" ) and abort "Failed to build tests: $curve\n";
system( "make test" ) and abort "Failed test suite: $curve\n";
system( "CFLAGS='-Werror -Wall -Wextra' make" )
and abort "Failed to build: all but $curve\n";
system( "make test" )
and abort "Failed test suite: all but $curve\n";
}

View file

@ -50,7 +50,8 @@ my $config_h = 'include/mbedtls/config.h';
# Some algorithms can't be disabled on their own as others depend on them, so
# we list those reverse-dependencies here to keep check_config.h happy.
my %algs = (
'MBEDTLS_ECDSA_C' => ['MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED'],
'MBEDTLS_ECDSA_C' => ['MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED'],
'MBEDTLS_ECP_C' => ['MBEDTLS_ECDSA_C',
'MBEDTLS_ECDH_C',
'MBEDTLS_ECJPAKE_C',
@ -68,6 +69,7 @@ my %algs = (
'MBEDTLS_RSA_C' => ['MBEDTLS_X509_RSASSA_PSS_SUPPORT',
'MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED',
'MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED',
'MBEDTLS_KEY_EXCHANGE_RSA_ENABLED'],
);