Implement use of internal DRBG for ecp_mul()
The case of MBEDTLS_ECP_RESTARTABLE isn't handled correctly yet: in that case the DRBG instance should persist when resuming the operation. This will be addressed in the next commit. When both CTR_DRBG and HMAC_DRBG are available, CTR_DRBG is preferred since both are suitable but CTR_DRBG tends to be faster and I needed a tie-breaker. There are currently three possible cases to test: - NO_INTERNAL_RNG is set -> tested in test_ecp_no_internal_rng - it's unset and CTR_DRBG is available -> tested in the default config - it's unset and CTR_DRBG is disabled -> tested in test_ecp_internal_rng_no_ctr_drbg Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This commit is contained in:
parent
1a3f9edc08
commit
c52a43c2bd
@ -104,6 +104,8 @@ typedef struct mbedtls_md_context_t
|
||||
* \brief This function returns the list of digests supported by the
|
||||
* generic digest module.
|
||||
*
|
||||
* \note The list starts with the strongest available hashes.
|
||||
*
|
||||
* \return A statically allocated array of digests. Each element
|
||||
* in the returned list is an integer belonging to the
|
||||
* message-digest enumeration #mbedtls_md_type_t.
|
||||
|
137
library/ecp.c
137
library/ecp.c
@ -105,6 +105,16 @@
|
||||
|
||||
#include "mbedtls/ecp_internal.h"
|
||||
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
#include "mbedtls/hmac_drbg.h"
|
||||
#else
|
||||
#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid."
|
||||
#endif
|
||||
#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */
|
||||
|
||||
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
|
||||
!defined(inline) && !defined(__cplusplus)
|
||||
#define inline __inline
|
||||
@ -118,6 +128,113 @@
|
||||
static unsigned long add_count, dbl_count, mul_count;
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
/*
|
||||
* Currently ecp_mul() takes a RNG function as an argument, used for
|
||||
* side-channel protection, but it can be NULL. The initial reasonning was
|
||||
* that people will pass non-NULL RNG when they care about side-channels, but
|
||||
* unfortunately we have some APIs that call ecp_mul() with a NULL RNG, with
|
||||
* no opportunity for the user to do anything about it.
|
||||
*
|
||||
* The obvious strategies for addressing that include:
|
||||
* - change those APIs so that they take RNG arguments;
|
||||
* - require a global RNG to be available to all crypto modules.
|
||||
*
|
||||
* Unfortunately those would break compatibility. So what we do instead is
|
||||
* have our own internal DRBG instance, seeded from the secret scalar.
|
||||
*
|
||||
* The following is a light-weight abstraction layer for doing that with
|
||||
* CTR_DRBG or HMAC_DRBG.
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
/* DRBG context type */
|
||||
typedef mbedtls_ctr_drbg_context ecp_drbg_context;
|
||||
|
||||
/* DRBG context init */
|
||||
static inline void ecp_drbg_init( ecp_drbg_context *ctx )
|
||||
{
|
||||
mbedtls_ctr_drbg_init( ctx );
|
||||
}
|
||||
|
||||
/* DRBG context free */
|
||||
static inline void ecp_drbg_free( ecp_drbg_context *ctx )
|
||||
{
|
||||
mbedtls_ctr_drbg_free( ctx );
|
||||
}
|
||||
|
||||
/* DRBG function */
|
||||
static inline int ecp_drbg_random( void *p_rng,
|
||||
unsigned char *output, size_t output_len )
|
||||
{
|
||||
return( mbedtls_ctr_drbg_random( p_rng, output, output_len ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Since CTR_DRBG doesn't have a seed_buf() function the way HMAC_DRBG does,
|
||||
* we need to pass an entropy function when seeding. So we use a dummy
|
||||
* function for that, and pass the actual entropy as customisation string.
|
||||
* (During seeding of CTR_DRBG the entropy input and customisation string are
|
||||
* concatenated before being used to update the secret state.)
|
||||
*/
|
||||
static int ecp_ctr_drbg_null_entropy(void *ctx, unsigned char *out, size_t len)
|
||||
{
|
||||
(void) ctx;
|
||||
memset( out, 0, len );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* DRBG context seeding */
|
||||
static int ecp_drbg_seed( ecp_drbg_context *ctx, const mbedtls_mpi *secret )
|
||||
{
|
||||
const unsigned char *secret_p = (const unsigned char *) secret->p;
|
||||
const size_t secret_size = secret->n * sizeof( mbedtls_mpi_uint );
|
||||
|
||||
return( mbedtls_ctr_drbg_seed( ctx, ecp_ctr_drbg_null_entropy, NULL,
|
||||
secret_p, secret_size ) );
|
||||
}
|
||||
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
/* DRBG context type */
|
||||
typedef mbedtls_hmac_drbg_context ecp_drbg_context;
|
||||
|
||||
/* DRBG context init */
|
||||
static inline void ecp_drbg_init( ecp_drbg_context *ctx )
|
||||
{
|
||||
mbedtls_hmac_drbg_init( ctx );
|
||||
}
|
||||
|
||||
/* DRBG context free */
|
||||
static inline void ecp_drbg_free( ecp_drbg_context *ctx )
|
||||
{
|
||||
mbedtls_hmac_drbg_free( ctx );
|
||||
}
|
||||
|
||||
/* DRBG function */
|
||||
static inline int ecp_drbg_random( void *p_rng,
|
||||
unsigned char *output, size_t output_len )
|
||||
{
|
||||
return( mbedtls_hmac_drbg_random( p_rng, output, output_len ) );
|
||||
}
|
||||
|
||||
/* DRBG context seeding */
|
||||
static int ecp_drbg_seed( ecp_drbg_context *ctx, const mbedtls_mpi *secret )
|
||||
{
|
||||
const unsigned char *secret_p = (const unsigned char *) secret->p;
|
||||
const size_t secret_size = secret->n * sizeof( mbedtls_mpi_uint );
|
||||
|
||||
/* The list starts with strong hashes */
|
||||
const mbedtls_md_type_t md_type = mbedtls_md_list()[0];
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_type );
|
||||
|
||||
return( mbedtls_hmac_drbg_seed_buf( ctx, md_info, secret_p, secret_size ) );
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid."
|
||||
#endif /* DRBG modules */
|
||||
#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/*
|
||||
* Maximum number of "basic operations" to be done in a row.
|
||||
@ -2443,12 +2560,19 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
||||
int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
|
||||
char is_grp_capable = 0;
|
||||
#endif
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
ecp_drbg_context drbg_ctx;
|
||||
#endif
|
||||
ECP_VALIDATE_RET( grp != NULL );
|
||||
ECP_VALIDATE_RET( R != NULL );
|
||||
ECP_VALIDATE_RET( m != NULL );
|
||||
ECP_VALIDATE_RET( P != NULL );
|
||||
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
ecp_drbg_init( &drbg_ctx );
|
||||
#endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/* reset ops count for this call if top-level */
|
||||
if( rs_ctx != NULL && rs_ctx->depth++ == 0 )
|
||||
@ -2460,6 +2584,15 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
||||
MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
|
||||
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
|
||||
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
if( f_rng == NULL )
|
||||
{
|
||||
MBEDTLS_MPI_CHK( ecp_drbg_seed( &drbg_ctx, m ) );
|
||||
f_rng = &ecp_drbg_random;
|
||||
p_rng = &drbg_ctx;
|
||||
}
|
||||
#endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/* skip argument check when restarting */
|
||||
if( rs_ctx == NULL || rs_ctx->rsm == NULL )
|
||||
@ -2490,6 +2623,10 @@ cleanup:
|
||||
mbedtls_internal_ecp_free( grp );
|
||||
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
|
||||
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
ecp_drbg_free( &drbg_ctx );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if( rs_ctx != NULL )
|
||||
rs_ctx->depth--;
|
||||
|
Loading…
Reference in New Issue
Block a user