Skip to content

Commit

Permalink
Parse RSA parameters DP, DQ and QP from PKCS1 private keys
Browse files Browse the repository at this point in the history
Otherwise these values are recomputed in mbedtls_rsa_deduce_crt, which
currently suffers from side channel issues in the computation of QP
(see https://eprint.iacr.org/2020/055). By loading the pre-computed
values not only is the side channel avoided, but runtime overhead of
loading RSA keys is reduced.

Discussion in ARMmbed/mbed-crypto#347

Backport of ARMmbed/mbed-crypto#352
  • Loading branch information
jack-fortanix committed Jan 29, 2020
1 parent a67508e commit 100e147
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
34 changes: 30 additions & 4 deletions library/pkparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -754,14 +754,40 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
goto cleanup;
p += len;

/* Complete the RSA private key */
if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 )
goto cleanup;
#if !defined(MBEDTLS_RSA_NO_CRT)
/*
* The RSA CRT parameters DP, DQ and QP are nominally redundant, in
* that they can be easily recomputed from D, P and Q. However by
* parsing them from the PKCS1 structure it is possible to avoid
* recalculating them which both reduces the overhead of loading
* RSA private keys into memory and also avoids side channels which
* can arise when computing those values, since all of D, P, and Q
* are secret. See https://eprint.iacr.org/2020/055 for a
* description of one such attack.
*/

/* Import DP */
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DP ) ) != 0)
goto cleanup;

/* Import DQ */
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0)
goto cleanup;

/* Import QP */
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->QP ) ) != 0)
goto cleanup;

/* Check optional parameters */
#else
/* Verify existance of the CRT params */
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 )
goto cleanup;
#endif

/* Complete the RSA private key */
if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 )
goto cleanup;

if( p != end )
Expand Down
8 changes: 7 additions & 1 deletion library/rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );

#if !defined(MBEDTLS_RSA_NO_CRT)
const int have_DP = ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) != 0 );
const int have_DQ = ( mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) != 0 );
const int have_QP = ( mbedtls_mpi_cmp_int( &ctx->QP, 0 ) != 0 );
#endif

/*
* Check whether provided parameters are enough
* to deduce all others. The following incomplete
Expand Down Expand Up @@ -316,7 +322,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
*/

#if !defined(MBEDTLS_RSA_NO_CRT)
if( is_priv )
if( is_priv && ! ( have_DP && have_DQ && have_QP ) )
{
ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
&ctx->DP, &ctx->DQ, &ctx->QP );
Expand Down

0 comments on commit 100e147

Please sign in to comment.