diff options
author | Moonchild <moonchild@palemoon.org> | 2020-06-03 10:15:17 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2020-06-03 10:15:17 +0000 |
commit | 760c45dbe1756d715b43167113a6a0d5d323027e (patch) | |
tree | 8d0556e1019a510cdd6fc615365a94a6cb3ed15a | |
parent | 11718bf88e2f5fa00cf69da9709b4a5923e42546 (diff) | |
download | uxp-760c45dbe1756d715b43167113a6a0d5d323027e.tar.gz |
[NSS] Force a fixed length for DSA exponentiation
-rw-r--r-- | security/nss/lib/freebl/dsa.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/security/nss/lib/freebl/dsa.c b/security/nss/lib/freebl/dsa.c index aef353967d..389c9de24f 100644 --- a/security/nss/lib/freebl/dsa.c +++ b/security/nss/lib/freebl/dsa.c @@ -313,13 +313,14 @@ DSA_NewKeyFromSeed(const PQGParams *params, static SECStatus dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest, - const unsigned char *kb) + const unsigned char *kbytes) { mp_int p, q, g; /* PQG parameters */ mp_int x, k; /* private key & pseudo-random integer */ mp_int r, s; /* tuple (r, s) is signature) */ mp_int t; /* holding tmp values */ mp_int ar; /* holding blinding values */ + mp_digit fuzz; /* blinding multiplier for q */ mp_err err = MP_OKAY; SECStatus rv = SECSuccess; unsigned int dsa_subprime_len, dsa_signature_len, offset; @@ -373,6 +374,7 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest, CHECK_MPI_OK(mp_init(&s)); CHECK_MPI_OK(mp_init(&t)); CHECK_MPI_OK(mp_init(&ar)); + /* ** Convert stored PQG and private key into MPI integers. */ @@ -380,14 +382,28 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest, SECITEM_TO_MPINT(key->params.subPrime, &q); SECITEM_TO_MPINT(key->params.base, &g); SECITEM_TO_MPINT(key->privateValue, &x); - OCTETS_TO_MPINT(kb, &k, dsa_subprime_len); + OCTETS_TO_MPINT(kbytes, &k, dsa_subprime_len); + + /* k blinding create a single value that has the high bit set in + * the mp_digit*/ + if (RNG_GenerateGlobalRandomBytes(&fuzz, sizeof(mp_digit)) != SECSuccess) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); + rv = SECFailure; + goto cleanup; + } + fuzz |= 1ULL << ((sizeof(mp_digit) * PR_BITS_PER_BYTE - 1)); /* ** FIPS 186-1, Section 5, Step 1 ** ** r = (g**k mod p) mod q */ - CHECK_MPI_OK(mp_exptmod(&g, &k, &p, &r)); /* r = g**k mod p */ - CHECK_MPI_OK(mp_mod(&r, &q, &r)); /* r = r mod q */ + CHECK_MPI_OK(mp_mul_d(&q, fuzz, &t)); /* t = q*fuzz */ + CHECK_MPI_OK(mp_add(&k, &t, &t)); /* t = k+q*fuzz */ + /* length of t is now fixed, bits in k have been blinded */ + CHECK_MPI_OK(mp_exptmod(&g, &t, &p, &r)); /* r = g**t mod p */ + /* r is now g**(k+q*fuzz) == g**k mod p */ + CHECK_MPI_OK(mp_mod(&r, &q, &r)); /* r = r mod q */ + /* ** FIPS 186-1, Section 5, Step 2 ** @@ -411,15 +427,24 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest, /* Using mp_invmod on k directly would leak bits from k. */ CHECK_MPI_OK(mp_mul(&k, &ar, &k)); /* k = k * ar */ CHECK_MPI_OK(mp_mulmod(&k, &t, &q, &k)); /* k = k * t mod q */ - CHECK_MPI_OK(mp_invmod(&k, &q, &k)); /* k = k**-1 mod q */ + /* k is now k*t*ar */ + CHECK_MPI_OK(mp_invmod(&k, &q, &k)); /* k = k**-1 mod q */ + /* k is now (k*t*ar)**-1 */ CHECK_MPI_OK(mp_mulmod(&k, &t, &q, &k)); /* k = k * t mod q */ - SECITEM_TO_MPINT(localDigest, &s); /* s = HASH(M) */ + /* k is now (k*ar)**-1 */ + SECITEM_TO_MPINT(localDigest, &s); /* s = HASH(M) */ /* To avoid leaking secret bits here the addition is blinded. */ - CHECK_MPI_OK(mp_mul(&x, &ar, &x)); /* x = x * ar */ - CHECK_MPI_OK(mp_mulmod(&x, &r, &q, &x)); /* x = x * r mod q */ + CHECK_MPI_OK(mp_mul(&x, &ar, &x)); /* x = x * ar */ + /* x is now x*ar */ + CHECK_MPI_OK(mp_mulmod(&x, &r, &q, &x)); /* x = x * r mod q */ + /* x is now x*r*ar */ CHECK_MPI_OK(mp_mulmod(&s, &ar, &q, &t)); /* t = s * ar mod q */ - CHECK_MPI_OK(mp_add(&t, &x, &s)); /* s = t + x */ - CHECK_MPI_OK(mp_mulmod(&s, &k, &q, &s)); /* s = s * k mod q */ + /* t is now hash(M)*ar */ + CHECK_MPI_OK(mp_add(&t, &x, &s)); /* s = t + x */ + /* s is now (HASH(M)+x*r)*ar */ + CHECK_MPI_OK(mp_mulmod(&s, &k, &q, &s)); /* s = s * k mod q */ + /* s is now (HASH(M)+x*r)*ar*(k*ar)**-1 = (k**-1)*(HASH(M)+x*r) */ + /* ** verify r != 0 and s != 0 ** mentioned as optional in FIPS 186-1. |