diff options
Diffstat (limited to 'security/nss/lib/freebl/dsa.c')
-rw-r--r-- | security/nss/lib/freebl/dsa.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/security/nss/lib/freebl/dsa.c b/security/nss/lib/freebl/dsa.c index 9324d306b1..aef353967d 100644 --- a/security/nss/lib/freebl/dsa.c +++ b/security/nss/lib/freebl/dsa.c @@ -16,14 +16,11 @@ #include "blapi.h" #include "nssilock.h" #include "secitem.h" -#include "blapi.h" +#include "blapit.h" #include "mpi.h" #include "secmpi.h" #include "pqg.h" -/* XXX to be replaced by define in blapit.h */ -#define NSS_FREEBL_DSA_DEFAULT_CHUNKSIZE 2048 - /* * FIPS 186-2 requires result from random output to be reduced mod q when * generating random numbers for DSA. @@ -168,7 +165,7 @@ dsa_NewKeyExtended(const PQGParams *params, const SECItem *seed, return SECFailure; } /* Initialize an arena for the DSA key. */ - arena = PORT_NewArena(NSS_FREEBL_DSA_DEFAULT_CHUNKSIZE); + arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE); if (!arena) { PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; @@ -213,8 +210,9 @@ cleanup: mp_clear(&g); mp_clear(&x); mp_clear(&y); - if (key) + if (key) { PORT_FreeArena(key->params.arena, PR_TRUE); + } if (err) { translate_mpi_error(err); return SECFailure; @@ -321,6 +319,7 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest, 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_err err = MP_OKAY; SECStatus rv = SECSuccess; unsigned int dsa_subprime_len, dsa_signature_len, offset; @@ -364,6 +363,7 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest, MP_DIGITS(&r) = 0; MP_DIGITS(&s) = 0; MP_DIGITS(&t) = 0; + MP_DIGITS(&ar) = 0; CHECK_MPI_OK(mp_init(&p)); CHECK_MPI_OK(mp_init(&q)); CHECK_MPI_OK(mp_init(&g)); @@ -372,6 +372,7 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest, 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. */ @@ -397,14 +398,28 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest, rv = SECFailure; goto cleanup; } - SECITEM_TO_MPINT(t2, &t); /* t <-$ Zq */ + SECITEM_TO_MPINT(t2, &t); /* t <-$ Zq */ + SECITEM_FreeItem(&t2, PR_FALSE); + if (DSA_NewRandom(NULL, &key->params.subPrime, &t2) != SECSuccess) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); + rv = SECFailure; + 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 */ CHECK_MPI_OK(mp_mulmod(&k, &t, &q, &k)); /* k = k * t mod q */ SECITEM_TO_MPINT(localDigest, &s); /* s = HASH(M) */ - CHECK_MPI_OK(mp_mulmod(&x, &r, &q, &x)); /* x = x * r mod q */ - CHECK_MPI_OK(mp_addmod(&s, &x, &q, &s)); /* s = s + x mod q */ - CHECK_MPI_OK(mp_mulmod(&s, &k, &q, &s)); /* s = s * k mod q */ + /* 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_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 */ /* ** verify r != 0 and s != 0 ** mentioned as optional in FIPS 186-1. @@ -438,7 +453,7 @@ cleanup: mp_clear(&r); mp_clear(&s); mp_clear(&t); - SECITEM_FreeItem(&t2, PR_FALSE); + mp_clear(&ar); if (err) { translate_mpi_error(err); rv = SECFailure; |