diff options
Diffstat (limited to 'gnu/packages/patches/nss-CVE-2020-12399.patch')
-rw-r--r-- | gnu/packages/patches/nss-CVE-2020-12399.patch | 138 |
1 files changed, 0 insertions, 138 deletions
diff --git a/gnu/packages/patches/nss-CVE-2020-12399.patch b/gnu/packages/patches/nss-CVE-2020-12399.patch deleted file mode 100644 index 0d91b655e2..0000000000 --- a/gnu/packages/patches/nss-CVE-2020-12399.patch +++ /dev/null @@ -1,138 +0,0 @@ -Fix CVE-2020-12399 (Timing attack on DSA signature generation: NSS has -shown timing differences when performing DSA signatures, which was -exploitable and could eventually leak private keys.) - -Copied from upstream: -<https://hg.mozilla.org/projects/nss/rev/daa823a4a29bcef0fec33a379ec83857429aea2e> -but with "nss/" inserted into the file name to patch. - -# HG changeset patch -# User Robert Relyea <rrelyea@redhat.com> -# Date 1589907685 0 -# Node ID daa823a4a29bcef0fec33a379ec83857429aea2e -# Parent d2cfb4ccdf167e5ea06d2bb5bc39c50f789929c8 -Bug 1631576 - Force a fixed length for DSA exponentiation r=pereida,bbrumley - -Differential Revision: https://phabricator.services.mozilla.com/D72011 - -diff --git a/nss/lib/freebl/dsa.c b/nss/lib/freebl/dsa.c ---- a/nss/lib/freebl/dsa.c -+++ b/nss/lib/freebl/dsa.c -@@ -308,23 +308,24 @@ DSA_NewKeyFromSeed(const PQGParams *para - SECItem seedItem; - seedItem.data = (unsigned char *)seed; - seedItem.len = PQG_GetLength(¶ms->subPrime); - return dsa_NewKeyExtended(params, &seedItem, privKey); - } - - 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; - SECItem localDigest; - unsigned char localDigestData[DSA_MAX_SUBPRIME_LEN]; - SECItem t2 = { siBuffer, NULL, 0 }; - - /* FIPS-compliance dictates that digest is a SHA hash. */ -@@ -368,31 +369,46 @@ dsa_SignDigest(DSAPrivateKey *key, SECIt - CHECK_MPI_OK(mp_init(&q)); - CHECK_MPI_OK(mp_init(&g)); - CHECK_MPI_OK(mp_init(&x)); - CHECK_MPI_OK(mp_init(&k)); - CHECK_MPI_OK(mp_init(&r)); - 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. - */ - SECITEM_TO_MPINT(key->params.prime, &p); - 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 - ** - ** s = (k**-1 * (HASH(M) + x*r)) mod q - */ - if (DSA_NewRandom(NULL, &key->params.subPrime, &t2) != SECSuccess) { - PORT_SetError(SEC_ERROR_NEED_RANDOM); - rv = SECFailure; -@@ -406,25 +422,34 @@ dsa_SignDigest(DSAPrivateKey *key, SECIt - goto cleanup; - } - SECITEM_TO_MPINT(t2, &ar); /* ar <-$ Zq */ - SECITEM_FreeItem(&t2, PR_FALSE); - - /* 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. - */ - if (mp_cmp_z(&r) == 0 || mp_cmp_z(&s) == 0) { - PORT_SetError(SEC_ERROR_NEED_RANDOM); - rv = SECFailure; - goto cleanup; - |