Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Unified Diff: mozilla/security/nss/lib/freebl/dsa.c

Issue 10961060: Update NSS to NSS 3.14 Beta 1. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Add the NSS snapshot timestamp to README.chromium and nss-checkout.sh Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mozilla/security/nss/lib/freebl/drbg.c ('k') | mozilla/security/nss/lib/freebl/hasht.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mozilla/security/nss/lib/freebl/dsa.c
===================================================================
--- mozilla/security/nss/lib/freebl/dsa.c (revision 158129)
+++ mozilla/security/nss/lib/freebl/dsa.c (working copy)
@@ -20,6 +20,7 @@
#include "blapi.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
@@ -79,7 +80,7 @@
FIPS186Change_ReduceModQForDSA(const unsigned char *w,
const unsigned char *q,
unsigned char *xj) {
- return fips186Change_ReduceModQForDSA(w, q, DSA_SUBPRIME_LEN, xj);
+ return fips186Change_ReduceModQForDSA(w, q, DSA1_SUBPRIME_LEN, xj);
}
/*
@@ -127,7 +128,7 @@
}
if (maxDestLen < qLen) {
/* This condition can occur when DSA_SignDigest is passed a group
- with a subprime that is larger than DSA_SUBPRIME_LEN. */
+ with a subprime that is larger than DSA_MAX_SUBPRIME_LEN. */
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -279,11 +280,15 @@
SECItem seed;
SECStatus rv;
+ rv = PQG_Check(params);
+ if (rv != SECSuccess) {
+ return rv;
+ }
seed.data = NULL;
rv = DSA_NewRandom(NULL, &params->subPrime, &seed);
if (rv == SECSuccess) {
- if (seed.len != DSA_SUBPRIME_LEN) {
+ if (seed.len != PQG_GetLength(&params->subPrime)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
} else {
@@ -294,16 +299,15 @@
return rv;
}
-/* For FIPS compliance testing. Seed must be exactly 20 bytes long */
+/* For FIPS compliance testing. Seed must be exactly the size of subPrime */
SECStatus
DSA_NewKeyFromSeed(const PQGParams *params,
const unsigned char *seed,
DSAPrivateKey **privKey)
{
- /* TODO: check Q size */
SECItem seedItem;
seedItem.data = (unsigned char*) seed;
- seedItem.len = DSA_SUBPRIME_LEN;
+ seedItem.len = PQG_GetLength(&params->subPrime);
return dsa_NewKeyExtended(params, &seedItem, privKey);
}
@@ -316,16 +320,39 @@
mp_int r, s; /* tuple (r, s) is signature) */
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];
+
- /* FIPS-compliance dictates that digest is a SHA1 hash. */
+ /* FIPS-compliance dictates that digest is a SHA hash. */
/* Check args. */
- if (!key || !signature || !digest ||
- (signature->len < DSA_SIGNATURE_LEN) ||
- (digest->len != SHA1_LENGTH)) {
+ if (!key || !signature || !digest) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
+ dsa_subprime_len = PQG_GetLength(&key->params.subPrime);
+ dsa_signature_len = dsa_subprime_len*2;
+ if ((signature->len < dsa_signature_len) ||
+ (digest->len > HASH_LENGTH_MAX) ||
+ (digest->len < SHA1_LENGTH)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ /* DSA accepts digests not equal to dsa_subprime_len, if the
+ * digests are greater, then they are truncated to the size of
+ * dsa_subprime_len, using the left most bits. If they are less
+ * then they are padded on the left.*/
+ PORT_Memset(localDigestData, 0, dsa_subprime_len);
+ offset = (digest->len < dsa_subprime_len) ?
+ (dsa_subprime_len - digest->len) : 0;
+ PORT_Memcpy(localDigestData+offset, digest->data,
+ dsa_subprime_len - offset);
+ localDigest.data = localDigestData;
+ localDigest.len = dsa_subprime_len;
+
/* Initialize MPI integers. */
MP_DIGITS(&p) = 0;
MP_DIGITS(&q) = 0;
@@ -348,7 +375,7 @@
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(kb, &k, dsa_subprime_len);
/*
** FIPS 186-1, Section 5, Step 1
**
@@ -359,9 +386,9 @@
/*
** FIPS 186-1, Section 5, Step 2
**
- ** s = (k**-1 * (SHA1(M) + x*r)) mod q
+ ** s = (k**-1 * (HASH(M) + x*r)) mod q
*/
- SECITEM_TO_MPINT(*digest, &s); /* s = SHA1(M) */
+ SECITEM_TO_MPINT(localDigest, &s); /* s = HASH(M) */
CHECK_MPI_OK( mp_invmod(&k, &q, &k) ); /* k = k**-1 mod q */
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 */
@@ -380,14 +407,15 @@
**
** Signature is tuple (r, s)
*/
- err = mp_to_fixlen_octets(&r, signature->data, DSA_SUBPRIME_LEN);
+ err = mp_to_fixlen_octets(&r, signature->data, dsa_subprime_len);
if (err < 0) goto cleanup;
- err = mp_to_fixlen_octets(&s, signature->data + DSA_SUBPRIME_LEN,
- DSA_SUBPRIME_LEN);
+ err = mp_to_fixlen_octets(&s, signature->data + dsa_subprime_len,
+ dsa_subprime_len);
if (err < 0) goto cleanup;
err = MP_OKAY;
- signature->len = DSA_SIGNATURE_LEN;
+ signature->len = dsa_signature_len;
cleanup:
+ PORT_Memset(localDigestData, 0, DSA_MAX_SUBPRIME_LEN);
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);
@@ -413,9 +441,10 @@
{
SECStatus rv;
int retries = 10;
- unsigned char kSeed[DSA_SUBPRIME_LEN];
+ unsigned char kSeed[DSA_MAX_SUBPRIME_LEN];
unsigned int kSeedLen = 0;
unsigned int i;
+ unsigned int dsa_subprime_len = PQG_GetLength(&key->params.subPrime);
PRBool good;
PORT_SetError(0);
@@ -424,7 +453,7 @@
kSeed, &kSeedLen, sizeof kSeed);
if (rv != SECSuccess)
break;
- if (kSeedLen != DSA_SUBPRIME_LEN) {
+ if (kSeedLen != dsa_subprime_len) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
break;
@@ -468,21 +497,44 @@
DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
const SECItem *digest)
{
- /* FIPS-compliance dictates that digest is a SHA1 hash. */
+ /* FIPS-compliance dictates that digest is a SHA hash. */
mp_int p, q, g; /* PQG parameters */
mp_int r_, s_; /* tuple (r', s') is received signature) */
mp_int u1, u2, v, w; /* intermediate values used in verification */
mp_int y; /* public key */
mp_err err;
+ int dsa_subprime_len, dsa_signature_len, offset;
+ SECItem localDigest;
+ unsigned char localDigestData[DSA_MAX_SUBPRIME_LEN];
SECStatus verified = SECFailure;
/* Check args. */
- if (!key || !signature || !digest ||
- (signature->len != DSA_SIGNATURE_LEN) ||
- (digest->len != SHA1_LENGTH)) {
+ if (!key || !signature || !digest ) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
+
+ dsa_subprime_len = PQG_GetLength(&key->params.subPrime);
+ dsa_signature_len = dsa_subprime_len*2;
+ if ((signature->len != dsa_signature_len) ||
+ (digest->len > HASH_LENGTH_MAX) ||
+ (digest->len < SHA1_LENGTH)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ /* DSA accepts digests not equal to dsa_subprime_len, if the
+ * digests are greater, than they are truncated to the size of
+ * dsa_subprime_len, using the left most bits. If they are less
+ * then they are padded on the left.*/
+ PORT_Memset(localDigestData, 0, dsa_subprime_len);
+ offset = (digest->len < dsa_subprime_len) ?
+ (dsa_subprime_len - digest->len) : 0;
+ PORT_Memcpy(localDigestData+offset, digest->data,
+ dsa_subprime_len - offset);
+ localDigest.data = localDigestData;
+ localDigest.len = dsa_subprime_len;
+
/* Initialize MPI integers. */
MP_DIGITS(&p) = 0;
MP_DIGITS(&q) = 0;
@@ -514,8 +566,8 @@
/*
** Convert received signature (r', s') into MPI integers.
*/
- OCTETS_TO_MPINT(signature->data, &r_, DSA_SUBPRIME_LEN);
- OCTETS_TO_MPINT(signature->data + DSA_SUBPRIME_LEN, &s_, DSA_SUBPRIME_LEN);
+ OCTETS_TO_MPINT(signature->data, &r_, dsa_subprime_len);
+ OCTETS_TO_MPINT(signature->data + dsa_subprime_len, &s_, dsa_subprime_len);
/*
** Verify that 0 < r' < q and 0 < s' < q
*/
@@ -534,9 +586,9 @@
/*
** FIPS 186-1, Section 6, Step 2
**
- ** u1 = ((SHA1(M')) * w) mod q
+ ** u1 = ((Hash(M')) * w) mod q
*/
- SECITEM_TO_MPINT(*digest, &u1); /* u1 = SHA1(M') */
+ SECITEM_TO_MPINT(localDigest, &u1); /* u1 = HASH(M') */
CHECK_MPI_OK( mp_mulmod(&u1, &w, &q, &u1) ); /* u1 = u1 * w mod q */
/*
** FIPS 186-1, Section 6, Step 3
« no previous file with comments | « mozilla/security/nss/lib/freebl/drbg.c ('k') | mozilla/security/nss/lib/freebl/hasht.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698