Little HMAC_DRBG refactoring
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 03068aa..0bd0e97 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -49,52 +49,48 @@
} hmac_drbg_context;
/*
+ * Simplified HMAC_DRBG update, using optional additional data
+ */
+static void hmac_drbg_update( hmac_drbg_context *ctx,
+ const unsigned char *data, size_t data_len )
+{
+ size_t md_len = ctx->md_ctx.md_info->size;
+ unsigned char rounds = ( data != NULL && data_len != 0 ) ? 2 : 1;
+ unsigned char sep[1];
+
+ for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
+ {
+ md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
+ md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
+ md_hmac_update( &ctx->md_ctx, sep, 1 );
+ if( rounds == 2 )
+ md_hmac_update( &ctx->md_ctx, data, data_len );
+ md_hmac_finish( &ctx->md_ctx, ctx->K );
+
+ md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
+ md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
+ md_hmac_finish( &ctx->md_ctx, ctx->V );
+ }
+}
+
+/*
* Simplified HMAC_DRBG initialisation.
*
* Uses an entropy buffer rather than callback,
- * assumes personalisation is not null,
+ * assume personalisation string is included in entropy buffer,
* assumes md_info is not NULL and valid.
*/
static void hmac_drbg_init( hmac_drbg_context *ctx,
const md_info_t * md_info,
- const unsigned char *entropy, size_t entropy_len,
- const unsigned char *pers, size_t pers_len )
+ const unsigned char *data, size_t data_len )
{
- unsigned char sep[1];
- size_t md_len = md_info->size;
-
memset( ctx, 0, sizeof( hmac_drbg_context ) );
md_init_ctx( &ctx->md_ctx, md_info );
- memset( ctx->V, 0x01, md_len );
+ memset( ctx->V, 0x01, md_info->size );
/* ctx->K is already 0 */
- sep[0] = 0x00;
- md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
- md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- md_hmac_update( &ctx->md_ctx, sep, 1 );
- md_hmac_update( &ctx->md_ctx, entropy, entropy_len );
- md_hmac_update( &ctx->md_ctx, pers, pers_len );
- md_hmac_finish( &ctx->md_ctx, ctx->K );
-
- /* Step e */
- md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
- md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- md_hmac_finish( &ctx->md_ctx, ctx->V );
-
- /* Step f */
- sep[0] = 0x01;
- md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
- md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- md_hmac_update( &ctx->md_ctx, sep, 1 );
- md_hmac_update( &ctx->md_ctx, entropy, entropy_len );
- md_hmac_update( &ctx->md_ctx, pers, pers_len );
- md_hmac_finish( &ctx->md_ctx, ctx->K );
-
- /* Step g */
- md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
- md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- md_hmac_finish( &ctx->md_ctx, ctx->V );
+ hmac_drbg_update( ctx, data, data_len );
}
/*
@@ -104,7 +100,6 @@
unsigned char *output, size_t out_len )
{
hmac_drbg_context *ctx = (hmac_drbg_context *) state;
- unsigned char sep[1] = { 0 };
size_t md_len = ctx->md_ctx.md_info->size;
size_t left = out_len;
unsigned char *out = output;
@@ -122,14 +117,7 @@
left -= use_len;
}
- md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
- md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- md_hmac_update( &ctx->md_ctx, sep, 1 );
- md_hmac_finish( &ctx->md_ctx, ctx->K );
-
- md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
- md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
- md_hmac_finish( &ctx->md_ctx, ctx->V );
+ hmac_drbg_update( ctx, NULL, 0 );
return( 0 );
}
@@ -249,8 +237,7 @@
{
int ret;
hmac_drbg_context rng_ctx;
- unsigned char key[POLARSSL_ECP_MAX_BYTES];
- unsigned char hash[POLARSSL_ECP_MAX_BYTES];
+ unsigned char data[2 * POLARSSL_ECP_MAX_BYTES];
size_t grp_len = ( grp->nbits + 7 ) / 8;
const md_info_t *md_info;
mpi h;
@@ -261,15 +248,12 @@
mpi_init( &h );
memset( &rng_ctx, 0, sizeof( hmac_drbg_context ) );
- /* Export private key as entropy source */
- MPI_CHK( mpi_write_binary( d, key, grp_len ) );
-
- /* Export message hash as additional data; need to reduce it first */
+ /* Use private key and message hash (reduced) to initialize HMAC_DRBG */
+ MPI_CHK( mpi_write_binary( d, data, grp_len ) );
MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
- MPI_CHK( mpi_write_binary( &h, hash, grp_len ) );
+ MPI_CHK( mpi_write_binary( &h, data + grp_len, grp_len ) );
+ hmac_drbg_init( &rng_ctx, md_info, data, 2 * grp_len );
- /* Initialize HMAC_DRBG and use it for signature */
- hmac_drbg_init( &rng_ctx, md_info, key, grp_len, hash, grp_len );
ret = ecdsa_sign( grp, r, s, d, buf, blen,
hmac_drbg_random, &rng_ctx );