ECDSA alternative support

Support for alternative implementation of ECDSA, at the higher layer
This commit is contained in:
Ron Eldor 2017-06-18 16:03:14 +03:00
parent 45d269555b
commit b68733bf62
4 changed files with 61 additions and 50 deletions

View File

@ -36,6 +36,10 @@ Changes
* Clarify ECDSA documentation and improve the sample code to avoid * Clarify ECDSA documentation and improve the sample code to avoid
misunderstandings and potentially dangerous use of the API. Pointed out misunderstandings and potentially dangerous use of the API. Pointed out
by Jean-Philippe Aumasson. by Jean-Philippe Aumasson.
* Add support for alternative implementation for ECDSA, controlled by new
configuration flag MBEDTLS_ECDSA_ALT in config.h.
Alternative Ecdsa is supported for implementation of `mbedtls_ecdsa_sign`
and `mbedtls_ecdsa_verify`.
= mbed TLS 2.5.0 branch released 2017-05-17 = mbed TLS 2.5.0 branch released 2017-05-17

View File

@ -238,6 +238,7 @@
//#define MBEDTLS_BLOWFISH_ALT //#define MBEDTLS_BLOWFISH_ALT
//#define MBEDTLS_CAMELLIA_ALT //#define MBEDTLS_CAMELLIA_ALT
//#define MBEDTLS_DES_ALT //#define MBEDTLS_DES_ALT
//#define MBEDTLS_ECDSA_ALT
//#define MBEDTLS_XTEA_ALT //#define MBEDTLS_XTEA_ALT
//#define MBEDTLS_MD2_ALT //#define MBEDTLS_MD2_ALT
//#define MBEDTLS_MD4_ALT //#define MBEDTLS_MD4_ALT

View File

@ -37,11 +37,10 @@
#include "mbedtls/asn1write.h" #include "mbedtls/asn1write.h"
#include <string.h> #include <string.h>
#include "mbedtls/platform.h"
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) #if defined(MBEDTLS_ECDSA_DETERMINISTIC)
#include "mbedtls/hmac_drbg.h" #include "mbedtls/hmac_drbg.h"
#endif #endif
/* /*
* Derive a suitable integer for group grp from a buffer of length len * Derive a suitable integer for group grp from a buffer of length len
* SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3 * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
@ -65,6 +64,8 @@ cleanup:
return( ret ); return( ret );
} }
#if !defined(MBEDTLS_ECDSA_ALT)
/* /*
* Compute ECDSA signature of a hashed message (SEC1 4.1.3) * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
* Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
@ -154,43 +155,6 @@ cleanup:
return( ret ); return( ret );
} }
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/*
* Deterministic signature wrapper
*/
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg )
{
int ret;
mbedtls_hmac_drbg_context rng_ctx;
unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
size_t grp_len = ( grp->nbits + 7 ) / 8;
const mbedtls_md_info_t *md_info;
mbedtls_mpi h;
if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
mbedtls_mpi_init( &h );
mbedtls_hmac_drbg_init( &rng_ctx );
/* Use private key and message hash (reduced) to initialize HMAC_DRBG */
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) );
MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) );
mbedtls_hmac_drbg_seed_buf( &rng_ctx, md_info, data, 2 * grp_len );
ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
mbedtls_hmac_drbg_random, &rng_ctx );
cleanup:
mbedtls_hmac_drbg_free( &rng_ctx );
mbedtls_mpi_free( &h );
return( ret );
}
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/* /*
* Verify ECDSA signature of hashed message (SEC1 4.1.4) * Verify ECDSA signature of hashed message (SEC1 4.1.4)
@ -278,6 +242,56 @@ cleanup:
return( ret ); return( ret );
} }
/*
* Generate key pair
*/
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
return( mbedtls_ecp_group_load( &ctx->grp, gid ) ||
mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
}
#endif /* MBEDTLS_ECDSA_ALT */
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
/*
* Deterministic signature wrapper
*/
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg )
{
int ret;
mbedtls_hmac_drbg_context rng_ctx;
unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
size_t grp_len = ( grp->nbits + 7 ) / 8;
const mbedtls_md_info_t *md_info;
mbedtls_mpi h;
if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
mbedtls_mpi_init( &h );
mbedtls_hmac_drbg_init( &rng_ctx );
/* Use private key and message hash (reduced) to initialize HMAC_DRBG */
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) );
MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) );
mbedtls_hmac_drbg_seed_buf( &rng_ctx, md_info, data, 2 * grp_len );
ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
mbedtls_hmac_drbg_random, &rng_ctx );
cleanup:
mbedtls_hmac_drbg_free( &rng_ctx );
mbedtls_mpi_free( &h );
return( ret );
}
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/* /*
* Convert a signature (given by context) to ASN.1 * Convert a signature (given by context) to ASN.1
*/ */
@ -301,7 +315,6 @@ static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
return( 0 ); return( 0 );
} }
/* /*
* Compute and write signature * Compute and write signature
*/ */
@ -402,16 +415,6 @@ cleanup:
return( ret ); return( ret );
} }
/*
* Generate key pair
*/
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
return( mbedtls_ecp_group_load( &ctx->grp, gid ) ||
mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
}
/* /*
* Set context from an mbedtls_ecp_keypair * Set context from an mbedtls_ecp_keypair
*/ */

View File

@ -93,6 +93,9 @@ static const char *features[] = {
#if defined(MBEDTLS_DES_ALT) #if defined(MBEDTLS_DES_ALT)
"MBEDTLS_DES_ALT", "MBEDTLS_DES_ALT",
#endif /* MBEDTLS_DES_ALT */ #endif /* MBEDTLS_DES_ALT */
#if defined(MBEDTLS_ECDSA_ALT)
"MBEDTLS_ECDSA_ALT",
#endif /* MBEDTLS_ECDSA_ALT */
#if defined(MBEDTLS_XTEA_ALT) #if defined(MBEDTLS_XTEA_ALT)
"MBEDTLS_XTEA_ALT", "MBEDTLS_XTEA_ALT",
#endif /* MBEDTLS_XTEA_ALT */ #endif /* MBEDTLS_XTEA_ALT */