summaryrefslogtreecommitdiff
path: root/nss/lib/freebl/dsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'nss/lib/freebl/dsa.c')
-rw-r--r--nss/lib/freebl/dsa.c398
1 files changed, 207 insertions, 191 deletions
diff --git a/nss/lib/freebl/dsa.c b/nss/lib/freebl/dsa.c
index 0da63ed..9324d30 100644
--- a/nss/lib/freebl/dsa.c
+++ b/nss/lib/freebl/dsa.c
@@ -21,12 +21,12 @@
#include "secmpi.h"
#include "pqg.h"
- /* XXX to be replaced by define in blapit.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.
+ * FIPS 186-2 requires result from random output to be reduced mod q when
+ * generating random numbers for DSA.
*
* Input: w, 2*qLen bytes
* q, qLen bytes
@@ -34,7 +34,7 @@
*/
static SECStatus
fips186Change_ReduceModQForDSA(const PRUint8 *w, const PRUint8 *q,
- unsigned int qLen, PRUint8 * xj)
+ unsigned int qLen, PRUint8 *xj)
{
mp_int W, Q, Xj;
mp_err err;
@@ -44,41 +44,42 @@ fips186Change_ReduceModQForDSA(const PRUint8 *w, const PRUint8 *q,
MP_DIGITS(&W) = 0;
MP_DIGITS(&Q) = 0;
MP_DIGITS(&Xj) = 0;
- CHECK_MPI_OK( mp_init(&W) );
- CHECK_MPI_OK( mp_init(&Q) );
- CHECK_MPI_OK( mp_init(&Xj) );
+ CHECK_MPI_OK(mp_init(&W));
+ CHECK_MPI_OK(mp_init(&Q));
+ CHECK_MPI_OK(mp_init(&Xj));
/*
* Convert input arguments into MPI integers.
*/
- CHECK_MPI_OK( mp_read_unsigned_octets(&W, w, 2*qLen) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&Q, q, qLen) );
+ CHECK_MPI_OK(mp_read_unsigned_octets(&W, w, 2 * qLen));
+ CHECK_MPI_OK(mp_read_unsigned_octets(&Q, q, qLen));
/*
* Algorithm 1 of FIPS 186-2 Change Notice 1, Step 3.3
*
* xj = (w0 || w1) mod q
*/
- CHECK_MPI_OK( mp_mod(&W, &Q, &Xj) );
- CHECK_MPI_OK( mp_to_fixlen_octets(&Xj, xj, qLen) );
+ CHECK_MPI_OK(mp_mod(&W, &Q, &Xj));
+ CHECK_MPI_OK(mp_to_fixlen_octets(&Xj, xj, qLen));
cleanup:
mp_clear(&W);
mp_clear(&Q);
mp_clear(&Xj);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
/*
- * FIPS 186-2 requires result from random output to be reduced mod q when
- * generating random numbers for DSA.
+ * FIPS 186-2 requires result from random output to be reduced mod q when
+ * generating random numbers for DSA.
*/
SECStatus
FIPS186Change_ReduceModQForDSA(const unsigned char *w,
const unsigned char *q,
- unsigned char *xj) {
+ unsigned char *xj)
+{
return fips186Change_ReduceModQForDSA(w, q, DSA1_SUBPRIME_LEN, xj);
}
@@ -112,13 +113,13 @@ FIPS186Change_GenerateX(PRUint8 *XKEY, const PRUint8 *XSEEDj,
** Generate some random bytes, using the global random number generator
** object. In DSA mode, so there is a q.
*/
-static SECStatus
-dsa_GenerateGlobalRandomBytes(const SECItem * qItem, PRUint8 * dest,
- unsigned int * destLen, unsigned int maxDestLen)
+static SECStatus
+dsa_GenerateGlobalRandomBytes(const SECItem *qItem, PRUint8 *dest,
+ unsigned int *destLen, unsigned int maxDestLen)
{
SECStatus rv;
SECItem w;
- const PRUint8 * q = qItem->data;
+ const PRUint8 *q = qItem->data;
unsigned int qLen = qItem->len;
if (*q == 0) {
@@ -132,7 +133,7 @@ dsa_GenerateGlobalRandomBytes(const SECItem * qItem, PRUint8 * dest,
return SECFailure;
}
w.data = NULL; /* otherwise SECITEM_AllocItem asserts */
- if (!SECITEM_AllocItem(NULL, &w, 2*qLen)) {
+ if (!SECITEM_AllocItem(NULL, &w, 2 * qLen)) {
return SECFailure;
}
*destLen = qLen;
@@ -146,13 +147,14 @@ dsa_GenerateGlobalRandomBytes(const SECItem * qItem, PRUint8 * dest,
return rv;
}
-static void translate_mpi_error(mp_err err)
+static void
+translate_mpi_error(mp_err err)
{
MP_TO_SEC_ERROR(err);
}
-static SECStatus
-dsa_NewKeyExtended(const PQGParams *params, const SECItem * seed,
+static SECStatus
+dsa_NewKeyExtended(const PQGParams *params, const SECItem *seed,
DSAPrivateKey **privKey)
{
mp_int p, g;
@@ -162,20 +164,20 @@ dsa_NewKeyExtended(const PQGParams *params, const SECItem * seed,
DSAPrivateKey *key;
/* Check args. */
if (!params || !privKey || !seed || !seed->data) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
/* Initialize an arena for the DSA key. */
arena = PORT_NewArena(NSS_FREEBL_DSA_DEFAULT_CHUNKSIZE);
if (!arena) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
}
key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey));
if (!key) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_FreeArena(arena, PR_TRUE);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_FreeArena(arena, PR_TRUE);
+ return SECFailure;
}
key->params.arena = arena;
/* Initialize MPI integers. */
@@ -183,25 +185,25 @@ dsa_NewKeyExtended(const PQGParams *params, const SECItem * seed,
MP_DIGITS(&g) = 0;
MP_DIGITS(&x) = 0;
MP_DIGITS(&y) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&g) );
- CHECK_MPI_OK( mp_init(&x) );
- CHECK_MPI_OK( mp_init(&y) );
+ CHECK_MPI_OK(mp_init(&p));
+ CHECK_MPI_OK(mp_init(&g));
+ CHECK_MPI_OK(mp_init(&x));
+ CHECK_MPI_OK(mp_init(&y));
/* Copy over the PQG params */
- CHECK_MPI_OK( SECITEM_CopyItem(arena, &key->params.prime,
- &params->prime) );
- CHECK_MPI_OK( SECITEM_CopyItem(arena, &key->params.subPrime,
- &params->subPrime) );
- CHECK_MPI_OK( SECITEM_CopyItem(arena, &key->params.base, &params->base) );
+ CHECK_MPI_OK(SECITEM_CopyItem(arena, &key->params.prime,
+ &params->prime));
+ CHECK_MPI_OK(SECITEM_CopyItem(arena, &key->params.subPrime,
+ &params->subPrime));
+ CHECK_MPI_OK(SECITEM_CopyItem(arena, &key->params.base, &params->base));
/* Convert stored p, g, and received x into MPI integers. */
SECITEM_TO_MPINT(params->prime, &p);
- SECITEM_TO_MPINT(params->base, &g);
+ SECITEM_TO_MPINT(params->base, &g);
OCTETS_TO_MPINT(seed->data, &x, seed->len);
/* Store x in private key */
SECITEM_AllocItem(arena, &key->privateValue, seed->len);
PORT_Memcpy(key->privateValue.data, seed->data, seed->len);
/* Compute public key y = g**x mod p */
- CHECK_MPI_OK( mp_exptmod(&g, &x, &p, &y) );
+ CHECK_MPI_OK(mp_exptmod(&g, &x, &p, &y));
/* Store y in public key */
MPINT_TO_SECITEM(&y, &key->publicValue, arena);
*privKey = key;
@@ -212,16 +214,16 @@ cleanup:
mp_clear(&x);
mp_clear(&y);
if (key)
- PORT_FreeArena(key->params.arena, PR_TRUE);
+ PORT_FreeArena(key->params.arena, PR_TRUE);
if (err) {
- translate_mpi_error(err);
- return SECFailure;
+ translate_mpi_error(err);
+ return SECFailure;
}
return SECSuccess;
}
SECStatus
-DSA_NewRandom(PLArenaPool * arena, const SECItem * q, SECItem * seed)
+DSA_NewRandom(PLArenaPool *arena, const SECItem *q, SECItem *seed)
{
int retries = 10;
unsigned int i;
@@ -238,30 +240,31 @@ DSA_NewRandom(PLArenaPool * arena, const SECItem * q, SECItem * seed)
}
do {
- /* Generate seed bytes for x according to FIPS 186-1 appendix 3 */
+ /* Generate seed bytes for x according to FIPS 186-1 appendix 3 */
if (dsa_GenerateGlobalRandomBytes(q, seed->data, &seed->len,
seed->len)) {
goto loser;
}
- /* Disallow values of 0 and 1 for x. */
- good = PR_FALSE;
- for (i = 0; i < seed->len-1; i++) {
- if (seed->data[i] != 0) {
- good = PR_TRUE;
- break;
- }
- }
- if (!good && seed->data[i] > 1) {
- good = PR_TRUE;
- }
+ /* Disallow values of 0 and 1 for x. */
+ good = PR_FALSE;
+ for (i = 0; i < seed->len - 1; i++) {
+ if (seed->data[i] != 0) {
+ good = PR_TRUE;
+ break;
+ }
+ }
+ if (!good && seed->data[i] > 1) {
+ good = PR_TRUE;
+ }
} while (!good && --retries > 0);
if (!good) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
-loser: if (arena != NULL) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ loser:
+ if (arena != NULL) {
SECITEM_FreeItem(seed, PR_FALSE);
}
- return SECFailure;
+ return SECFailure;
}
return SECSuccess;
@@ -269,11 +272,11 @@ loser: if (arena != NULL) {
/*
** Generate and return a new DSA public and private key pair,
-** both of which are encoded into a single DSAPrivateKey struct.
-** "params" is a pointer to the PQG parameters for the domain
-** Uses a random seed.
+** both of which are encoded into a single DSAPrivateKey struct.
+** "params" is a pointer to the PQG parameters for the domain
+** Uses a random seed.
*/
-SECStatus
+SECStatus
DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
{
SECItem seed;
@@ -281,7 +284,7 @@ DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
rv = PQG_Check(params);
if (rv != SECSuccess) {
- return rv;
+ return rv;
}
seed.data = NULL;
@@ -299,56 +302,56 @@ DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
}
/* For FIPS compliance testing. Seed must be exactly the size of subPrime */
-SECStatus
-DSA_NewKeyFromSeed(const PQGParams *params,
+SECStatus
+DSA_NewKeyFromSeed(const PQGParams *params,
const unsigned char *seed,
DSAPrivateKey **privKey)
{
SECItem seedItem;
- seedItem.data = (unsigned char*) seed;
+ seedItem.data = (unsigned char *)seed;
seedItem.len = PQG_GetLength(&params->subPrime);
return dsa_NewKeyExtended(params, &seedItem, privKey);
}
-static SECStatus
+static SECStatus
dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
const unsigned char *kb)
{
- 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_err err = MP_OKAY;
+ 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_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. */
/* Check args. */
if (!key || !signature || !digest) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
dsa_subprime_len = PQG_GetLength(&key->params.subPrime);
- dsa_signature_len = dsa_subprime_len*2;
+ 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;
+ (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 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);
+ 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;
@@ -360,46 +363,56 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
MP_DIGITS(&k) = 0;
MP_DIGITS(&r) = 0;
MP_DIGITS(&s) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- 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) );
+ MP_DIGITS(&t) = 0;
+ CHECK_MPI_OK(mp_init(&p));
+ 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));
/*
** Convert stored PQG and private key into MPI integers.
*/
- SECITEM_TO_MPINT(key->params.prime, &p);
+ 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);
+ SECITEM_TO_MPINT(key->params.base, &g);
+ SECITEM_TO_MPINT(key->privateValue, &x);
OCTETS_TO_MPINT(kb, &k, dsa_subprime_len);
/*
** 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_exptmod(&g, &k, &p, &r)); /* r = 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
*/
- 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 */
- CHECK_MPI_OK( mp_mulmod(&s, &k, &q, &s) ); /* s = s * k mod q */
+ if (DSA_NewRandom(NULL, &key->params.subPrime, &t2) != SECSuccess) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ rv = SECFailure;
+ goto cleanup;
+ }
+ SECITEM_TO_MPINT(t2, &t); /* t <-$ Zq */
+ 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 */
/*
** 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;
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ rv = SECFailure;
+ goto cleanup;
}
/*
** Step 4
@@ -407,10 +420,12 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
** Signature is tuple (r, s)
*/
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);
- if (err < 0) goto cleanup;
+ if (err < 0)
+ goto cleanup;
+ 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;
cleanup:
@@ -422,9 +437,11 @@ cleanup:
mp_clear(&k);
mp_clear(&r);
mp_clear(&s);
+ mp_clear(&t);
+ SECITEM_FreeItem(&t2, PR_FALSE);
if (err) {
- translate_mpi_error(err);
- rv = SECFailure;
+ translate_mpi_error(err);
+ rv = SECFailure;
}
return rv;
}
@@ -435,53 +452,53 @@ cleanup:
** On output, signature->len == size of signature in buffer.
** Uses a random seed.
*/
-SECStatus
+SECStatus
DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
{
SECStatus rv;
- int retries = 10;
+ int retries = 10;
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;
+ PRBool good;
PORT_SetError(0);
do {
- rv = dsa_GenerateGlobalRandomBytes(&key->params.subPrime,
+ rv = dsa_GenerateGlobalRandomBytes(&key->params.subPrime,
kSeed, &kSeedLen, sizeof kSeed);
- if (rv != SECSuccess)
- break;
+ if (rv != SECSuccess)
+ break;
if (kSeedLen != dsa_subprime_len) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
break;
}
- /* Disallow a value of 0 for k. */
- good = PR_FALSE;
- for (i = 0; i < kSeedLen; i++) {
- if (kSeed[i] != 0) {
- good = PR_TRUE;
- break;
- }
- }
- if (!good) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- rv = SECFailure;
- continue;
- }
- rv = dsa_SignDigest(key, signature, digest, kSeed);
+ /* Disallow a value of 0 for k. */
+ good = PR_FALSE;
+ for (i = 0; i < kSeedLen; i++) {
+ if (kSeed[i] != 0) {
+ good = PR_TRUE;
+ break;
+ }
+ }
+ if (!good) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ rv = SECFailure;
+ continue;
+ }
+ rv = dsa_SignDigest(key, signature, digest, kSeed);
} while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
- --retries > 0);
+ --retries > 0);
return rv;
}
/* For FIPS compliance testing. Seed must be exactly 20 bytes. */
-SECStatus
-DSA_SignDigestWithSeed(DSAPrivateKey * key,
- SECItem * signature,
- const SECItem * digest,
- const unsigned char * seed)
+SECStatus
+DSA_SignDigestWithSeed(DSAPrivateKey *key,
+ SECItem *signature,
+ const SECItem *digest,
+ const unsigned char *seed)
{
SECStatus rv;
rv = dsa_SignDigest(key, signature, digest, seed);
@@ -492,8 +509,8 @@ DSA_SignDigestWithSeed(DSAPrivateKey * key,
** On input, signature->len == size of buffer to hold signature.
** digest->len == size of digest.
*/
-SECStatus
-DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
+SECStatus
+DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
const SECItem *digest)
{
/* FIPS-compliance dictates that digest is a SHA hash. */
@@ -508,60 +525,59 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
SECStatus verified = SECFailure;
/* Check args. */
- if (!key || !signature || !digest ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ 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;
+ (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 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);
+ 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;
- MP_DIGITS(&g) = 0;
- MP_DIGITS(&y) = 0;
+ MP_DIGITS(&p) = 0;
+ MP_DIGITS(&q) = 0;
+ MP_DIGITS(&g) = 0;
+ MP_DIGITS(&y) = 0;
MP_DIGITS(&r_) = 0;
MP_DIGITS(&s_) = 0;
MP_DIGITS(&u1) = 0;
MP_DIGITS(&u2) = 0;
- MP_DIGITS(&v) = 0;
- MP_DIGITS(&w) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&q) );
- CHECK_MPI_OK( mp_init(&g) );
- CHECK_MPI_OK( mp_init(&y) );
- CHECK_MPI_OK( mp_init(&r_) );
- CHECK_MPI_OK( mp_init(&s_) );
- CHECK_MPI_OK( mp_init(&u1) );
- CHECK_MPI_OK( mp_init(&u2) );
- CHECK_MPI_OK( mp_init(&v) );
- CHECK_MPI_OK( mp_init(&w) );
+ MP_DIGITS(&v) = 0;
+ MP_DIGITS(&w) = 0;
+ CHECK_MPI_OK(mp_init(&p));
+ CHECK_MPI_OK(mp_init(&q));
+ CHECK_MPI_OK(mp_init(&g));
+ CHECK_MPI_OK(mp_init(&y));
+ CHECK_MPI_OK(mp_init(&r_));
+ CHECK_MPI_OK(mp_init(&s_));
+ CHECK_MPI_OK(mp_init(&u1));
+ CHECK_MPI_OK(mp_init(&u2));
+ CHECK_MPI_OK(mp_init(&v));
+ CHECK_MPI_OK(mp_init(&w));
/*
** Convert stored PQG and public key into MPI integers.
*/
- SECITEM_TO_MPINT(key->params.prime, &p);
+ 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->publicValue, &y);
+ SECITEM_TO_MPINT(key->params.base, &g);
+ SECITEM_TO_MPINT(key->publicValue, &y);
/*
** Convert received signature (r', s') into MPI integers.
*/
@@ -572,46 +588,46 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
*/
if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
mp_cmp(&r_, &q) >= 0 || mp_cmp(&s_, &q) >= 0) {
- /* err is zero here. */
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- goto cleanup; /* will return verified == SECFailure */
+ /* err is zero here. */
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ goto cleanup; /* will return verified == SECFailure */
}
/*
** FIPS 186-1, Section 6, Step 1
**
** w = (s')**-1 mod q
*/
- CHECK_MPI_OK( mp_invmod(&s_, &q, &w) ); /* w = (s')**-1 mod q */
+ CHECK_MPI_OK(mp_invmod(&s_, &q, &w)); /* w = (s')**-1 mod q */
/*
** FIPS 186-1, Section 6, Step 2
**
** u1 = ((Hash(M')) * w) mod q
*/
- SECITEM_TO_MPINT(localDigest, &u1); /* u1 = HASH(M') */
- CHECK_MPI_OK( mp_mulmod(&u1, &w, &q, &u1) ); /* u1 = u1 * w mod q */
+ 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
**
** u2 = ((r') * w) mod q
*/
- CHECK_MPI_OK( mp_mulmod(&r_, &w, &q, &u2) );
+ CHECK_MPI_OK(mp_mulmod(&r_, &w, &q, &u2));
/*
** FIPS 186-1, Section 6, Step 4
**
** v = ((g**u1 * y**u2) mod p) mod q
*/
- CHECK_MPI_OK( mp_exptmod(&g, &u1, &p, &g) ); /* g = g**u1 mod p */
- CHECK_MPI_OK( mp_exptmod(&y, &u2, &p, &y) ); /* y = y**u2 mod p */
- CHECK_MPI_OK( mp_mulmod(&g, &y, &p, &v) ); /* v = g * y mod p */
- CHECK_MPI_OK( mp_mod(&v, &q, &v) ); /* v = v mod q */
+ CHECK_MPI_OK(mp_exptmod(&g, &u1, &p, &g)); /* g = g**u1 mod p */
+ CHECK_MPI_OK(mp_exptmod(&y, &u2, &p, &y)); /* y = y**u2 mod p */
+ CHECK_MPI_OK(mp_mulmod(&g, &y, &p, &v)); /* v = g * y mod p */
+ CHECK_MPI_OK(mp_mod(&v, &q, &v)); /* v = v mod q */
/*
** Verification: v == r'
*/
if (mp_cmp(&v, &r_)) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- verified = SECFailure; /* Signature failed to verify. */
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ verified = SECFailure; /* Signature failed to verify. */
} else {
- verified = SECSuccess; /* Signature verified. */
+ verified = SECSuccess; /* Signature verified. */
}
cleanup:
mp_clear(&p);
@@ -625,7 +641,7 @@ cleanup:
mp_clear(&v);
mp_clear(&w);
if (err) {
- translate_mpi_error(err);
+ translate_mpi_error(err);
}
return verified;
}