mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-07-29 11:41:15 +03:00
Merge remote-tracking branch 'tls/development' into development
Resolve conflicts actions: - Reject path changes to config.h - Reject submodule-related changes in build scripts (Makefile, CMakeLists.txt) - Add oid test suite to list of tests in tests/CMakeLists.txt, rejecting any test filtering related changes (which TLS uses to avoid duplicating crypto tests) - Add legacy ECDH test to all.sh without including all.sh tests that depend on SSL
This commit is contained in:
@ -178,7 +178,7 @@ endif(USE_STATIC_MBEDTLS_LIBRARY)
|
||||
|
||||
if(USE_SHARED_MBEDTLS_LIBRARY)
|
||||
add_library(mbedcrypto SHARED ${src_crypto})
|
||||
set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.0 SOVERSION 3)
|
||||
set_target_properties(mbedcrypto PROPERTIES VERSION 2.17.0 SOVERSION 3)
|
||||
target_link_libraries(mbedcrypto ${libs})
|
||||
target_include_directories(mbedcrypto
|
||||
PUBLIC ${CMAKE_SOURCE_DIR}/include/
|
||||
|
@ -813,6 +813,39 @@ static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Import X from unsigned binary data, little endian
|
||||
*/
|
||||
int mbedtls_mpi_read_binary_le( mbedtls_mpi *X,
|
||||
const unsigned char *buf, size_t buflen )
|
||||
{
|
||||
int ret;
|
||||
size_t i;
|
||||
size_t const limbs = CHARS_TO_LIMBS( buflen );
|
||||
|
||||
/* Ensure that target MPI has exactly the necessary number of limbs */
|
||||
if( X->n != limbs )
|
||||
{
|
||||
mbedtls_mpi_free( X );
|
||||
mbedtls_mpi_init( X );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
|
||||
|
||||
for( i = 0; i < buflen; i++ )
|
||||
X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3);
|
||||
|
||||
cleanup:
|
||||
|
||||
/*
|
||||
* This function is also used to import keys. However, wiping the buffers
|
||||
* upon failure is not necessary because failure only can happen before any
|
||||
* input is copied.
|
||||
*/
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Import X from unsigned binary data, big endian
|
||||
*/
|
||||
@ -847,9 +880,53 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t bu
|
||||
|
||||
cleanup:
|
||||
|
||||
/*
|
||||
* This function is also used to import keys. However, wiping the buffers
|
||||
* upon failure is not necessary because failure only can happen before any
|
||||
* input is copied.
|
||||
*/
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Export X into unsigned binary data, little endian
|
||||
*/
|
||||
int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X,
|
||||
unsigned char *buf, size_t buflen )
|
||||
{
|
||||
size_t stored_bytes = X->n * ciL;
|
||||
size_t bytes_to_copy;
|
||||
size_t i;
|
||||
|
||||
if( stored_bytes < buflen )
|
||||
{
|
||||
bytes_to_copy = stored_bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_to_copy = buflen;
|
||||
|
||||
/* The output buffer is smaller than the allocated size of X.
|
||||
* However X may fit if its leading bytes are zero. */
|
||||
for( i = bytes_to_copy; i < stored_bytes; i++ )
|
||||
{
|
||||
if( GET_BYTE( X, i ) != 0 )
|
||||
return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < bytes_to_copy; i++ )
|
||||
buf[i] = GET_BYTE( X, i );
|
||||
|
||||
if( stored_bytes < buflen )
|
||||
{
|
||||
/* Write trailing 0 bytes */
|
||||
memset( buf + stored_bytes, 0, buflen - stored_bytes );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Export X into unsigned binary data, big endian
|
||||
*/
|
||||
|
@ -49,6 +49,16 @@
|
||||
typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed;
|
||||
#endif
|
||||
|
||||
static mbedtls_ecp_group_id mbedtls_ecdh_grp_id(
|
||||
const mbedtls_ecdh_context *ctx )
|
||||
{
|
||||
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||
return( ctx->grp.id );
|
||||
#else
|
||||
return( ctx->grp_id );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
|
||||
/*
|
||||
* Generate public key (restartable version)
|
||||
@ -442,8 +452,21 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
|
||||
ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS ||
|
||||
side == MBEDTLS_ECDH_THEIRS );
|
||||
|
||||
if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 )
|
||||
return( ret );
|
||||
if( mbedtls_ecdh_grp_id( ctx ) == MBEDTLS_ECP_DP_NONE )
|
||||
{
|
||||
/* This is the first call to get_params(). Set up the context
|
||||
* for use with the group. */
|
||||
if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 )
|
||||
return( ret );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is not the first call to get_params(). Check that the
|
||||
* current key's group is the same as the context's, which was set
|
||||
* from the first key's group. */
|
||||
if( mbedtls_ecdh_grp_id( ctx ) != key->grp.id )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||
return( ecdh_get_params_internal( ctx, key, side ) );
|
||||
@ -614,6 +637,10 @@ static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx,
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
*olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
|
||||
|
||||
if( mbedtls_ecp_get_type( &ctx->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
|
||||
return mbedtls_mpi_write_binary_le( &ctx->z, buf, *olen );
|
||||
|
||||
return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
|
||||
}
|
||||
|
||||
|
232
library/ecp.c
232
library/ecp.c
@ -363,16 +363,6 @@ int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp,
|
||||
#define ECP_MONTGOMERY
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curve types: internal for now, might be exposed later
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECP_TYPE_NONE = 0,
|
||||
ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
|
||||
ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
|
||||
} ecp_curve_type;
|
||||
|
||||
/*
|
||||
* List of supported curves:
|
||||
* - internal ID
|
||||
@ -522,15 +512,15 @@ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name
|
||||
/*
|
||||
* Get the type of a curve
|
||||
*/
|
||||
static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp )
|
||||
mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp )
|
||||
{
|
||||
if( grp->G.X.p == NULL )
|
||||
return( ECP_TYPE_NONE );
|
||||
return( MBEDTLS_ECP_TYPE_NONE );
|
||||
|
||||
if( grp->G.Y.p == NULL )
|
||||
return( ECP_TYPE_MONTGOMERY );
|
||||
return( MBEDTLS_ECP_TYPE_MONTGOMERY );
|
||||
else
|
||||
return( ECP_TYPE_SHORT_WEIERSTRASS );
|
||||
return( MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -729,14 +719,14 @@ cleanup:
|
||||
}
|
||||
|
||||
/*
|
||||
* Export a point into unsigned binary data (SEC1 2.3.3)
|
||||
* Export a point into unsigned binary data (SEC1 2.3.3 and RFC7748)
|
||||
*/
|
||||
int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
|
||||
const mbedtls_ecp_point *P,
|
||||
int format, size_t *olen,
|
||||
unsigned char *buf, size_t buflen )
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
|
||||
size_t plen;
|
||||
ECP_VALIDATE_RET( grp != NULL );
|
||||
ECP_VALIDATE_RET( P != NULL );
|
||||
@ -745,56 +735,71 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
|
||||
ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED ||
|
||||
format == MBEDTLS_ECP_PF_COMPRESSED );
|
||||
|
||||
/*
|
||||
* Common case: P == 0
|
||||
*/
|
||||
if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
|
||||
{
|
||||
if( buflen < 1 )
|
||||
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
|
||||
|
||||
buf[0] = 0x00;
|
||||
*olen = 1;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
plen = mbedtls_mpi_size( &grp->P );
|
||||
|
||||
if( format == MBEDTLS_ECP_PF_UNCOMPRESSED )
|
||||
#if defined(ECP_MONTGOMERY)
|
||||
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
|
||||
{
|
||||
*olen = 2 * plen + 1;
|
||||
|
||||
*olen = plen;
|
||||
if( buflen < *olen )
|
||||
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
|
||||
|
||||
buf[0] = 0x04;
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &P->X, buf, plen ) );
|
||||
}
|
||||
else if( format == MBEDTLS_ECP_PF_COMPRESSED )
|
||||
#endif
|
||||
#if defined(ECP_SHORTWEIERSTRASS)
|
||||
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
{
|
||||
*olen = plen + 1;
|
||||
/*
|
||||
* Common case: P == 0
|
||||
*/
|
||||
if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
|
||||
{
|
||||
if( buflen < 1 )
|
||||
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
|
||||
|
||||
if( buflen < *olen )
|
||||
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
|
||||
buf[0] = 0x00;
|
||||
*olen = 1;
|
||||
|
||||
buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
if( format == MBEDTLS_ECP_PF_UNCOMPRESSED )
|
||||
{
|
||||
*olen = 2 * plen + 1;
|
||||
|
||||
if( buflen < *olen )
|
||||
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
|
||||
|
||||
buf[0] = 0x04;
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
|
||||
}
|
||||
else if( format == MBEDTLS_ECP_PF_COMPRESSED )
|
||||
{
|
||||
*olen = plen + 1;
|
||||
|
||||
if( buflen < *olen )
|
||||
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
|
||||
|
||||
buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Import a point from unsigned binary data (SEC1 2.3.4)
|
||||
* Import a point from unsigned binary data (SEC1 2.3.4 and RFC7748)
|
||||
*/
|
||||
int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
|
||||
mbedtls_ecp_point *pt,
|
||||
const unsigned char *buf, size_t ilen )
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
|
||||
size_t plen;
|
||||
ECP_VALIDATE_RET( grp != NULL );
|
||||
ECP_VALIDATE_RET( pt != NULL );
|
||||
@ -803,25 +808,47 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
|
||||
if( ilen < 1 )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
if( buf[0] == 0x00 )
|
||||
{
|
||||
if( ilen == 1 )
|
||||
return( mbedtls_ecp_set_zero( pt ) );
|
||||
else
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
plen = mbedtls_mpi_size( &grp->P );
|
||||
|
||||
if( buf[0] != 0x04 )
|
||||
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
|
||||
#if defined(ECP_MONTGOMERY)
|
||||
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
|
||||
{
|
||||
if( plen != ilen )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
if( ilen != 2 * plen + 1 )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &pt->X, buf, plen ) );
|
||||
mbedtls_mpi_free( &pt->Y );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
|
||||
if( grp->id == MBEDTLS_ECP_DP_CURVE25519 )
|
||||
/* Set most significant bit to 0 as prescribed in RFC7748 §5 */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &pt->X, plen * 8 - 1, 0 ) );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
|
||||
}
|
||||
#endif
|
||||
#if defined(ECP_SHORTWEIERSTRASS)
|
||||
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
{
|
||||
if( buf[0] == 0x00 )
|
||||
{
|
||||
if( ilen == 1 )
|
||||
return( mbedtls_ecp_set_zero( pt ) );
|
||||
else
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( buf[0] != 0x04 )
|
||||
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
|
||||
|
||||
if( ilen != 2 * plen + 1 )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y,
|
||||
buf + 1 + plen, plen ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
return( ret );
|
||||
@ -2357,11 +2384,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( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
|
||||
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( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
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
|
||||
|
||||
@ -2500,7 +2527,7 @@ int mbedtls_ecp_muladd_restartable(
|
||||
ECP_VALIDATE_RET( n != NULL );
|
||||
ECP_VALIDATE_RET( Q != NULL );
|
||||
|
||||
if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
if( mbedtls_ecp_get_type( grp ) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
|
||||
|
||||
mbedtls_ecp_point_init( &mP );
|
||||
@ -2620,11 +2647,11 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
|
||||
return( MBEDTLS_ERR_ECP_INVALID_KEY );
|
||||
|
||||
#if defined(ECP_MONTGOMERY)
|
||||
if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
|
||||
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
|
||||
return( ecp_check_pubkey_mx( grp, pt ) );
|
||||
#endif
|
||||
#if defined(ECP_SHORTWEIERSTRASS)
|
||||
if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
return( ecp_check_pubkey_sw( grp, pt ) );
|
||||
#endif
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
@ -2640,7 +2667,7 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
|
||||
ECP_VALIDATE_RET( d != NULL );
|
||||
|
||||
#if defined(ECP_MONTGOMERY)
|
||||
if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
|
||||
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
|
||||
{
|
||||
/* see RFC 7748 sec. 5 para. 5 */
|
||||
if( mbedtls_mpi_get_bit( d, 0 ) != 0 ||
|
||||
@ -2656,7 +2683,7 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
|
||||
}
|
||||
#endif /* ECP_MONTGOMERY */
|
||||
#if defined(ECP_SHORTWEIERSTRASS)
|
||||
if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
{
|
||||
/* see SEC1 3.2 */
|
||||
if( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
|
||||
@ -2688,7 +2715,7 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
|
||||
n_size = ( grp->nbits + 7 ) / 8;
|
||||
|
||||
#if defined(ECP_MONTGOMERY)
|
||||
if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
|
||||
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
|
||||
{
|
||||
/* [M225] page 5 */
|
||||
size_t b;
|
||||
@ -2716,7 +2743,7 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
|
||||
#endif /* ECP_MONTGOMERY */
|
||||
|
||||
#if defined(ECP_SHORTWEIERSTRASS)
|
||||
if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
{
|
||||
/* SEC1 3.2.1: Generate d such that 1 <= n < N */
|
||||
int count = 0;
|
||||
@ -2809,6 +2836,75 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
|
||||
return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) );
|
||||
}
|
||||
|
||||
#define ECP_CURVE25519_KEY_SIZE 32
|
||||
/*
|
||||
* Read a private key.
|
||||
*/
|
||||
int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
|
||||
const unsigned char *buf, size_t buflen )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ECP_VALIDATE_RET( key != NULL );
|
||||
ECP_VALIDATE_RET( buf != NULL );
|
||||
|
||||
if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
|
||||
|
||||
#if defined(ECP_MONTGOMERY)
|
||||
if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
|
||||
{
|
||||
/*
|
||||
* If it is Curve25519 curve then mask the key as mandated by RFC7748
|
||||
*/
|
||||
if( grp_id == MBEDTLS_ECP_DP_CURVE25519 )
|
||||
{
|
||||
if( buflen != ECP_CURVE25519_KEY_SIZE )
|
||||
return MBEDTLS_ERR_ECP_INVALID_KEY;
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &key->d, buf, buflen ) );
|
||||
|
||||
/* Set the three least significant bits to 0 */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 0, 0 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 1, 0 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 2, 0 ) );
|
||||
|
||||
/* Set the most significant bit to 0 */
|
||||
MBEDTLS_MPI_CHK(
|
||||
mbedtls_mpi_set_bit( &key->d,
|
||||
ECP_CURVE25519_KEY_SIZE * 8 - 1, 0 )
|
||||
);
|
||||
|
||||
/* Set the second most significant bit to 1 */
|
||||
MBEDTLS_MPI_CHK(
|
||||
mbedtls_mpi_set_bit( &key->d,
|
||||
ECP_CURVE25519_KEY_SIZE * 8 - 2, 1 )
|
||||
);
|
||||
}
|
||||
else
|
||||
ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
#endif
|
||||
#if defined(ECP_SHORTWEIERSTRASS)
|
||||
if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &key->d, buf, buflen ) );
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( &key->grp, &key->d ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
cleanup:
|
||||
|
||||
if( ret != 0 )
|
||||
mbedtls_mpi_free( &key->d );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Check a public-private key pair
|
||||
*/
|
||||
|
@ -296,6 +296,15 @@ static const mbedtls_oid_descriptor_t oid_ext_key_usage[] =
|
||||
FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage)
|
||||
FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description)
|
||||
|
||||
static const mbedtls_oid_descriptor_t oid_certificate_policies[] =
|
||||
{
|
||||
{ ADD_LEN( MBEDTLS_OID_ANY_POLICY ), "anyPolicy", "Any Policy" },
|
||||
{ NULL, 0, NULL, NULL },
|
||||
};
|
||||
|
||||
FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, certificate_policies, oid_certificate_policies)
|
||||
FN_OID_GET_ATTR1(mbedtls_oid_get_certificate_policies, mbedtls_oid_descriptor_t, certificate_policies, const char *, description)
|
||||
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
/*
|
||||
* For SignatureAlgorithmIdentifier
|
||||
|
@ -351,6 +351,9 @@ static const char *features[] = {
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
"MBEDTLS_ECP_RESTARTABLE",
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||
"MBEDTLS_ECDH_LEGACY_CONTEXT",
|
||||
#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
"MBEDTLS_ECDSA_DETERMINISTIC",
|
||||
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
||||
|
Reference in New Issue
Block a user