mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-22 17:35:38 +01:00
Make ECDSA sign actually restartable
This commit is contained in:
parent
50b63ba2f5
commit
af081f5460
@ -91,8 +91,14 @@ static void ecdsa_restart_ver_free( mbedtls_ecdsa_restart_ver_ctx *ctx )
|
|||||||
*/
|
*/
|
||||||
struct mbedtls_ecdsa_restart_sig
|
struct mbedtls_ecdsa_restart_sig
|
||||||
{
|
{
|
||||||
|
int sign_tries;
|
||||||
|
int key_tries;
|
||||||
|
mbedtls_mpi k; /* per-signature random */
|
||||||
|
mbedtls_mpi r; /* r value */
|
||||||
enum { /* what to do next? */
|
enum { /* what to do next? */
|
||||||
ecdsa_sig_init = 0, /* getting started */
|
ecdsa_sig_init = 0, /* getting started */
|
||||||
|
ecdsa_sig_mul, /* doing ecp_mul() */
|
||||||
|
ecdsa_sig_modn, /* mod N computations */
|
||||||
} state;
|
} state;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,6 +108,9 @@ struct mbedtls_ecdsa_restart_sig
|
|||||||
static void ecdsa_restart_sig_init( mbedtls_ecdsa_restart_sig_ctx *ctx )
|
static void ecdsa_restart_sig_init( mbedtls_ecdsa_restart_sig_ctx *ctx )
|
||||||
{
|
{
|
||||||
memset( ctx, 0, sizeof( *ctx ) );
|
memset( ctx, 0, sizeof( *ctx ) );
|
||||||
|
|
||||||
|
mbedtls_mpi_init( &ctx->k );
|
||||||
|
mbedtls_mpi_init( &ctx->r );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -112,6 +121,9 @@ static void ecdsa_restart_sig_free( mbedtls_ecdsa_restart_sig_ctx *ctx )
|
|||||||
if( ctx == NULL )
|
if( ctx == NULL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mbedtls_mpi_free( &ctx->k );
|
||||||
|
mbedtls_mpi_free( &ctx->r );
|
||||||
|
|
||||||
memset( ctx, 0, sizeof( *ctx ) );
|
memset( ctx, 0, sizeof( *ctx ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,8 +133,10 @@ static void ecdsa_restart_sig_free( mbedtls_ecdsa_restart_sig_ctx *ctx )
|
|||||||
*/
|
*/
|
||||||
struct mbedtls_ecdsa_restart_det
|
struct mbedtls_ecdsa_restart_det
|
||||||
{
|
{
|
||||||
|
mbedtls_hmac_drbg_context rng_ctx; /* DRBG state */
|
||||||
enum { /* what to do next? */
|
enum { /* what to do next? */
|
||||||
ecdsa_det_init = 0, /* getting started */
|
ecdsa_det_init = 0, /* getting started */
|
||||||
|
ecdsa_det_sign, /* make signature */
|
||||||
} state;
|
} state;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -132,6 +146,8 @@ struct mbedtls_ecdsa_restart_det
|
|||||||
static void ecdsa_restart_det_init( mbedtls_ecdsa_restart_det_ctx *ctx )
|
static void ecdsa_restart_det_init( mbedtls_ecdsa_restart_det_ctx *ctx )
|
||||||
{
|
{
|
||||||
memset( ctx, 0, sizeof( *ctx ) );
|
memset( ctx, 0, sizeof( *ctx ) );
|
||||||
|
|
||||||
|
mbedtls_hmac_drbg_init( &ctx->rng_ctx );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -142,6 +158,8 @@ static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx )
|
|||||||
if( ctx == NULL )
|
if( ctx == NULL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mbedtls_hmac_drbg_free( &ctx->rng_ctx );
|
||||||
|
|
||||||
memset( ctx, 0, sizeof( *ctx ) );
|
memset( ctx, 0, sizeof( *ctx ) );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
||||||
@ -226,8 +244,10 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
|
|||||||
mbedtls_ecdsa_restart_ctx *rs_ctx )
|
mbedtls_ecdsa_restart_ctx *rs_ctx )
|
||||||
{
|
{
|
||||||
int ret, key_tries, sign_tries;
|
int ret, key_tries, sign_tries;
|
||||||
|
int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries;
|
||||||
mbedtls_ecp_point R;
|
mbedtls_ecp_point R;
|
||||||
mbedtls_mpi k, e, t;
|
mbedtls_mpi k, e, t;
|
||||||
|
mbedtls_mpi *pk = &k, *pr = r;
|
||||||
|
|
||||||
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
|
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
|
||||||
if( grp->N.p == NULL )
|
if( grp->N.p == NULL )
|
||||||
@ -242,17 +262,24 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
|
|||||||
if( rs_ctx != NULL && rs_ctx->sig != NULL )
|
if( rs_ctx != NULL && rs_ctx->sig != NULL )
|
||||||
{
|
{
|
||||||
/* redirect to our context */
|
/* redirect to our context */
|
||||||
// TODO
|
p_sign_tries = &rs_ctx->sig->sign_tries;
|
||||||
|
p_key_tries = &rs_ctx->sig->key_tries;
|
||||||
|
pk = &rs_ctx->sig->k;
|
||||||
|
pr = &rs_ctx->sig->r;
|
||||||
|
|
||||||
|
|
||||||
/* jump to current step */
|
/* jump to current step */
|
||||||
// TODO
|
if( rs_ctx->sig->state == ecdsa_sig_mul )
|
||||||
|
goto mul;
|
||||||
|
if( rs_ctx->sig->state == ecdsa_sig_modn )
|
||||||
|
goto modn;
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||||
|
|
||||||
sign_tries = 0;
|
*p_sign_tries = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if( sign_tries++ > 10 )
|
if( *p_sign_tries++ > 10 )
|
||||||
{
|
{
|
||||||
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -262,22 +289,43 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
|
|||||||
* Steps 1-3: generate a suitable ephemeral keypair
|
* Steps 1-3: generate a suitable ephemeral keypair
|
||||||
* and set r = xR mod n
|
* and set r = xR mod n
|
||||||
*/
|
*/
|
||||||
key_tries = 0;
|
*p_key_tries = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if( key_tries++ > 10 )
|
if( *p_key_tries++ > 10 )
|
||||||
{
|
{
|
||||||
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, &k, f_rng, p_rng ) );
|
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, pk, f_rng, p_rng ) );
|
||||||
|
|
||||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &R, &k, &grp->G,
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
f_rng, p_rng ) );
|
if( rs_ctx != NULL && rs_ctx->sig != NULL )
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( r, &R.X, &grp->N ) );
|
{
|
||||||
|
rs_ctx->sig->state++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mul:
|
||||||
|
#endif
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &R, pk, &grp->G,
|
||||||
|
f_rng, p_rng, ECDSA_RS_ECP ) );
|
||||||
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pr, &R.X, &grp->N ) );
|
||||||
}
|
}
|
||||||
while( mbedtls_mpi_cmp_int( r, 0 ) == 0 );
|
while( mbedtls_mpi_cmp_int( pr, 0 ) == 0 );
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
if( rs_ctx != NULL && rs_ctx->sig != NULL )
|
||||||
|
rs_ctx->sig->state++;
|
||||||
|
|
||||||
|
modn:
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Accounting for everything up to the end of the loop
|
||||||
|
* (step 6, but checking now avoids saving e and t)
|
||||||
|
*/
|
||||||
|
ECDSA_BUDGET( MBEDTLS_ECP_OPS_INV + 4 );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Step 5: derive MPI from hashed message
|
* Step 5: derive MPI from hashed message
|
||||||
@ -293,16 +341,20 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
|
|||||||
/*
|
/*
|
||||||
* Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
|
* Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
|
||||||
*/
|
*/
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, r, d ) );
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, pr, d ) );
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) );
|
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) );
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) );
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) );
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &k, &k, &t ) );
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pk, pk, &t ) );
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, &k, &grp->N ) );
|
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, pk, &grp->N ) );
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) );
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) );
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) );
|
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) );
|
||||||
}
|
}
|
||||||
while( mbedtls_mpi_cmp_int( s, 0 ) == 0 );
|
while( mbedtls_mpi_cmp_int( s, 0 ) == 0 );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
mbedtls_mpi_copy( r, pr );
|
||||||
|
#endif
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
mbedtls_ecp_point_free( &R );
|
mbedtls_ecp_point_free( &R );
|
||||||
mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t );
|
mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t );
|
||||||
@ -335,6 +387,7 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
mbedtls_hmac_drbg_context rng_ctx;
|
mbedtls_hmac_drbg_context rng_ctx;
|
||||||
|
mbedtls_hmac_drbg_context *p_rng = &rng_ctx;
|
||||||
unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
|
unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
|
||||||
size_t grp_len = ( grp->nbits + 7 ) / 8;
|
size_t grp_len = ( grp->nbits + 7 ) / 8;
|
||||||
const mbedtls_md_info_t *md_info;
|
const mbedtls_md_info_t *md_info;
|
||||||
@ -352,10 +405,11 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
|
|||||||
if( rs_ctx != NULL && rs_ctx->det != NULL )
|
if( rs_ctx != NULL && rs_ctx->det != NULL )
|
||||||
{
|
{
|
||||||
/* redirect to our context */
|
/* redirect to our context */
|
||||||
// TODO
|
p_rng = &rs_ctx->det->rng_ctx;
|
||||||
|
|
||||||
/* jump to current step */
|
/* jump to current step */
|
||||||
// TODO
|
if( rs_ctx->det->state == ecdsa_det_sign )
|
||||||
|
goto sign;
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||||
|
|
||||||
@ -363,10 +417,16 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
|
|||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) );
|
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) );
|
||||||
MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
|
MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
|
||||||
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) );
|
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 );
|
mbedtls_hmac_drbg_seed_buf( p_rng, md_info, data, 2 * grp_len );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
|
if( rs_ctx != NULL && rs_ctx->det != NULL )
|
||||||
|
rs_ctx->det->state++;
|
||||||
|
|
||||||
|
sign:
|
||||||
|
#endif
|
||||||
ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
|
ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
|
||||||
mbedtls_hmac_drbg_random, &rng_ctx, rs_ctx );
|
mbedtls_hmac_drbg_random, p_rng, rs_ctx );
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
mbedtls_hmac_drbg_free( &rng_ctx );
|
mbedtls_hmac_drbg_free( &rng_ctx );
|
||||||
|
@ -269,3 +269,15 @@ ecdsa_read_restart:MBEDTLS_ECP_DP_SECP256R1:"04e8f573412a810c5f81ecd2d251bb94387
|
|||||||
ECDSA restartable sign-write: secp256r1 restart disabled
|
ECDSA restartable sign-write: secp256r1 restart disabled
|
||||||
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C
|
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C
|
||||||
ecdsa_write_restart:MBEDTLS_ECP_DP_SECP256R1:"C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721":MBEDTLS_MD_SHA256:"test":"3045022100f1abb023518351cd71d881567b1ea663ed3efcf6c5132b354f28d3b0b7d383670220019f4113742a2b14bd25926b49c649155f267e60d3814b4c0cc84250e46f0083":0:0:0
|
ecdsa_write_restart:MBEDTLS_ECP_DP_SECP256R1:"C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721":MBEDTLS_MD_SHA256:"test":"3045022100f1abb023518351cd71d881567b1ea663ed3efcf6c5132b354f28d3b0b7d383670220019f4113742a2b14bd25926b49c649155f267e60d3814b4c0cc84250e46f0083":0:0:0
|
||||||
|
|
||||||
|
ECDSA restartable sign-write: secp256r1 restart max_ops=1
|
||||||
|
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C
|
||||||
|
ecdsa_write_restart:MBEDTLS_ECP_DP_SECP256R1:"C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721":MBEDTLS_MD_SHA256:"test":"3045022100f1abb023518351cd71d881567b1ea663ed3efcf6c5132b354f28d3b0b7d383670220019f4113742a2b14bd25926b49c649155f267e60d3814b4c0cc84250e46f0083":1:1:10000
|
||||||
|
|
||||||
|
ECDSA restartable sign-write: secp256r1 restart max_ops=10000
|
||||||
|
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C
|
||||||
|
ecdsa_write_restart:MBEDTLS_ECP_DP_SECP256R1:"C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721":MBEDTLS_MD_SHA256:"test":"3045022100f1abb023518351cd71d881567b1ea663ed3efcf6c5132b354f28d3b0b7d383670220019f4113742a2b14bd25926b49c649155f267e60d3814b4c0cc84250e46f0083":10000:0:0
|
||||||
|
|
||||||
|
ECDSA restartable sign-write: secp256r1 restart max_ops=250
|
||||||
|
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C
|
||||||
|
ecdsa_write_restart:MBEDTLS_ECP_DP_SECP256R1:"C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721":MBEDTLS_MD_SHA256:"test":"3045022100f1abb023518351cd71d881567b1ea663ed3efcf6c5132b354f28d3b0b7d383670220019f4113742a2b14bd25926b49c649155f267e60d3814b4c0cc84250e46f0083":250:2:32
|
||||||
|
Loading…
Reference in New Issue
Block a user