[crypto/asn1] Fix multiple SCA vulnerabilities during RSA key validation.

This commit addresses multiple side-channel vulnerabilities present
during RSA key validation.
Private key parameters are re-computed using variable-time functions.

This issue was discovered and reported by the NISEC group at TAU Finland.

Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9779)
This commit is contained in:
Cesar Pereida Garcia 2019-09-05 12:13:11 +03:00 committed by Matt Caswell
parent c7bfb138ac
commit 311e903d84
2 changed files with 20 additions and 3 deletions

View file

@ -130,9 +130,20 @@ static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it) int utype, char *free_cont, const ASN1_ITEM *it)
{ {
if (!*pval) int ret;
bn_secure_new(pval, it); BIGNUM *bn;
return bn_c2i(pval, cont, len, utype, free_cont, it);
if (!*pval && !bn_secure_new(pval, it))
return 0;
ret = bn_c2i(pval, cont, len, utype, free_cont, it);
if (!ret)
return 0;
/* Set constant-time flag for all secure BIGNUMS */
bn = (BIGNUM *)*pval;
BN_set_flags(bn, BN_FLG_CONSTTIME);
return ret;
} }
static int bn_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, static int bn_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it,

View file

@ -325,6 +325,7 @@ int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
if (d != NULL) { if (d != NULL) {
BN_clear_free(r->d); BN_clear_free(r->d);
r->d = d; r->d = d;
BN_set_flags(r->d, BN_FLG_CONSTTIME);
} }
return 1; return 1;
@ -342,10 +343,12 @@ int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
if (p != NULL) { if (p != NULL) {
BN_clear_free(r->p); BN_clear_free(r->p);
r->p = p; r->p = p;
BN_set_flags(r->p, BN_FLG_CONSTTIME);
} }
if (q != NULL) { if (q != NULL) {
BN_clear_free(r->q); BN_clear_free(r->q);
r->q = q; r->q = q;
BN_set_flags(r->q, BN_FLG_CONSTTIME);
} }
return 1; return 1;
@ -364,14 +367,17 @@ int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
if (dmp1 != NULL) { if (dmp1 != NULL) {
BN_clear_free(r->dmp1); BN_clear_free(r->dmp1);
r->dmp1 = dmp1; r->dmp1 = dmp1;
BN_set_flags(r->dmp1, BN_FLG_CONSTTIME);
} }
if (dmq1 != NULL) { if (dmq1 != NULL) {
BN_clear_free(r->dmq1); BN_clear_free(r->dmq1);
r->dmq1 = dmq1; r->dmq1 = dmq1;
BN_set_flags(r->dmq1, BN_FLG_CONSTTIME);
} }
if (iqmp != NULL) { if (iqmp != NULL) {
BN_clear_free(r->iqmp); BN_clear_free(r->iqmp);
r->iqmp = iqmp; r->iqmp = iqmp;
BN_set_flags(r->iqmp, BN_FLG_CONSTTIME);
} }
return 1; return 1;