Bug 475578 - Implement Extended DSA as defined in FIPS 186-3 (DSS)
r wtc Patches 1 and 4 in the original bug (lib/softoken lib/freebl, and lib/ssl) git-svn-id: svn://10.0.0.236/trunk@263930 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
59a2cacd1c
commit
528d2c4c19
@ -4,7 +4,7 @@
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* $Id: blapi.h,v 1.46 2012-04-25 14:49:43 gerv%gerv.net Exp $ */
|
||||
/* $Id: blapi.h,v 1.47 2012-06-12 16:39:00 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#ifndef _BLAPI_H_
|
||||
#define _BLAPI_H_
|
||||
@ -1232,6 +1232,8 @@ PRNGTEST_Uninstantiate(void);
|
||||
/* Generate PQGParams and PQGVerify structs.
|
||||
* Length of seed and length of h both equal length of P.
|
||||
* All lengths are specified by "j", according to the table above.
|
||||
*
|
||||
* The verify parameters will conform to FIPS186-1.
|
||||
*/
|
||||
extern SECStatus
|
||||
PQG_ParamGen(unsigned int j, /* input : determines length of P. */
|
||||
@ -1242,6 +1244,8 @@ PQG_ParamGen(unsigned int j, /* input : determines length of P. */
|
||||
* Length of P specified by j. Length of h will match length of P.
|
||||
* Length of SEED in bytes specified in seedBytes.
|
||||
* seedBbytes must be in the range [20..255] or an error will result.
|
||||
*
|
||||
* The verify parameters will conform to FIPS186-1.
|
||||
*/
|
||||
extern SECStatus
|
||||
PQG_ParamGenSeedLen(
|
||||
@ -1250,6 +1254,32 @@ PQG_ParamGenSeedLen(
|
||||
PQGParams **pParams, /* output: P Q and G returned here */
|
||||
PQGVerify **pVfy); /* output: counter and seed. */
|
||||
|
||||
/* Generate PQGParams and PQGVerify structs.
|
||||
* Length of P specified by L in bits.
|
||||
* Length of Q specified by N in bits.
|
||||
* Length of SEED in bytes specified in seedBytes.
|
||||
* seedBbytes must be in the range [N..L*2] or an error will result.
|
||||
*
|
||||
* Not that J uses the above table, L is the length exact. L and N must
|
||||
* match the table below or an error will result:
|
||||
*
|
||||
* L N
|
||||
* 1024 160
|
||||
* 2048 224
|
||||
* 2048 256
|
||||
* 3072 256
|
||||
*
|
||||
* The verify parameters will conform to FIPS186-3 using the smallest
|
||||
* permissible hash for the key strength.
|
||||
*/
|
||||
extern SECStatus
|
||||
PQG_ParamGenV2(
|
||||
unsigned int L, /* input : determines length of P. */
|
||||
unsigned int N, /* input : determines length of Q. */
|
||||
unsigned int seedBytes, /* input : length of seed in bytes.*/
|
||||
PQGParams **pParams, /* output: P Q and G returned here */
|
||||
PQGVerify **pVfy); /* output: counter and seed. */
|
||||
|
||||
|
||||
/* Test PQGParams for validity as DSS PQG values.
|
||||
* If vfy is non-NULL, test PQGParams to make sure they were generated
|
||||
@ -1261,20 +1291,9 @@ PQG_ParamGenSeedLen(
|
||||
* SECSuccess: PQGParams are valid.
|
||||
* SECFailure: PQGParams are invalid.
|
||||
*
|
||||
* Verify the following 12 facts about PQG counter SEED g and h
|
||||
* 1. Q is 160 bits long.
|
||||
* 2. P is one of the 9 valid lengths.
|
||||
* 3. G < P
|
||||
* 4. P % Q == 1
|
||||
* 5. Q is prime
|
||||
* 6. P is prime
|
||||
* Steps 7-12 are done only if the optional PQGVerify is supplied.
|
||||
* 7. counter < 4096
|
||||
* 8. g >= 160 and g < 2048 (g is length of seed in bits)
|
||||
* 9. Q generated from SEED matches Q in PQGParams.
|
||||
* 10. P generated from (L, counter, g, SEED, Q) matches P in PQGParams.
|
||||
* 11. 1 < h < P-1
|
||||
* 12. G generated from h matches G in PQGParams.
|
||||
* Verify the PQG againts the counter, SEED and h.
|
||||
* These tests are specified in FIPS 186-3 Appendix A.1.1.1, A.1.1.3, and A.2.2
|
||||
* PQG_VerifyParams will automatically choose the appropriate test.
|
||||
*/
|
||||
|
||||
extern SECStatus PQG_VerifyParams(const PQGParams *params,
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* $Id: blapit.h,v 1.27 2012-04-25 14:49:43 gerv%gerv.net Exp $ */
|
||||
/* $Id: blapit.h,v 1.28 2012-06-12 16:39:00 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#ifndef _BLAPIT_H_
|
||||
#define _BLAPIT_H_
|
||||
@ -43,8 +43,32 @@
|
||||
#define NSS_SEED 0
|
||||
#define NSS_SEED_CBC 1
|
||||
|
||||
#define DSA_SIGNATURE_LEN 40 /* Bytes */
|
||||
#define DSA_SUBPRIME_LEN 20 /* Bytes */
|
||||
#define DSA1_SUBPRIME_LEN 20 /* Bytes */
|
||||
#define DSA1_SIGNATURE_LEN (DSA1_SUBPRIME_LEN*2) /* Bytes */
|
||||
#define DSA_MAX_SUBPRIME_LEN 32 /* Bytes */
|
||||
#define DSA_MAX_SIGNATURE_LEN (DSA_MAX_SUBPRIME_LEN*2)/* Bytes */
|
||||
|
||||
/*
|
||||
* Mark the old defines as deprecated. This will warn code that expected
|
||||
* DSA1 only that they need to change if the are to support DSA2.
|
||||
*/
|
||||
#if defined(__GNUC__) && (__GNUC__ > 3)
|
||||
/* make GCC warn when we use these #defines */
|
||||
typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
|
||||
#define DSA_SUBPRIME_LEN ((__BLAPI_DEPRECATED)DSA1_SUBPRIME_LEN)
|
||||
#define DSA_SIGNATURE_LEN ((__BLAPI_DEPRECATED)DSA1_SIGNATURE_LEN)
|
||||
#define DSA_Q_BITS ((__BLAPI_DEPRECATED)(DSA1_SUBPRIME_LEN*8))
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
/* This magic gets the windows compiler to give us a deprecation
|
||||
* warning */
|
||||
#pragma deprecated(DSA_SUBPRIME_LEN, DSA_SIGNATURE_LEN, DSA_QBITS)
|
||||
#endif
|
||||
#define DSA_SUBPRIME_LEN DSA1_SUBPRIME_LEN
|
||||
#define DSA_SIGNATURE_LEN DSA1_SIGNATURE_LEN
|
||||
#define DSA_Q_BITS (DSA1_SUBPRIME_LEN*8)
|
||||
#endif
|
||||
|
||||
|
||||
/* XXX We shouldn't have to hard code this limit. For
|
||||
* now, this is the quickest way to support ECDSA signature
|
||||
@ -111,7 +135,7 @@
|
||||
#define DH_MAX_P_BITS 3072
|
||||
|
||||
/*
|
||||
* The FIPS 186 algorithm for generating primes P and Q allows only 9
|
||||
* The FIPS 186-1 algorithm for generating primes P and Q allows only 9
|
||||
* distinct values for the length of P, and only one value for the
|
||||
* length of Q.
|
||||
* The algorithm uses a variable j to indicate which of the 9 lengths
|
||||
@ -130,12 +154,31 @@
|
||||
* 7 960 160
|
||||
* 8 1024 160
|
||||
*
|
||||
* The FIPS-186 compliant PQG generator takes j as an input parameter.
|
||||
* The FIPS-186-1 compliant PQG generator takes j as an input parameter.
|
||||
*
|
||||
* FIPS 186-3 algorithm specifies 4 distinct P and Q sizes:
|
||||
*
|
||||
* bits in P bits in Q
|
||||
* _________ _________
|
||||
* 1024 160
|
||||
* 2048 224
|
||||
* 2048 256
|
||||
* 3072 256
|
||||
*
|
||||
* The FIPS-186-3 complaiant PQG generator (PQG V2) takes arbitrary p and q
|
||||
* lengths as input and returns an error if they aren't in this list.
|
||||
*/
|
||||
|
||||
#define DSA_Q_BITS 160
|
||||
#define DSA_MAX_P_BITS 1024
|
||||
#define DSA1_Q_BITS 160
|
||||
#define DSA_MAX_P_BITS 3072
|
||||
#define DSA_MIN_P_BITS 512
|
||||
#define DSA_MAX_Q_BITS 256
|
||||
#define DSA_MIN_Q_BITS 160
|
||||
|
||||
#if DSA_MAX_Q_BITS != DSA_MAX_SUBPRIME_LEN*8
|
||||
#error "Inconsistent declaration of DSA SUBPRIME/Q parameters in blapit.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* function takes desired number of bits in P,
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* $Id: dsa.c,v 1.22 2012-04-25 14:49:43 gerv%gerv.net Exp $ */
|
||||
/* $Id: dsa.c,v 1.23 2012-06-12 16:39:00 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
@ -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 @@ SECStatus
|
||||
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 @@ dsa_GenerateGlobalRandomBytes(const SECItem * qItem, PRUint8 * dest,
|
||||
}
|
||||
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 @@ DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
|
||||
SECItem seed;
|
||||
SECStatus rv;
|
||||
|
||||
rv = PQG_Check(params);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
seed.data = NULL;
|
||||
|
||||
rv = DSA_NewRandom(NULL, ¶ms->subPrime, &seed);
|
||||
if (rv == SECSuccess) {
|
||||
if (seed.len != DSA_SUBPRIME_LEN) {
|
||||
if (seed.len != PQG_GetLength(¶ms->subPrime)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
@ -294,16 +299,15 @@ DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
|
||||
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(¶ms->subPrime);
|
||||
return dsa_NewKeyExtended(params, &seedItem, privKey);
|
||||
}
|
||||
|
||||
@ -316,16 +320,39 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
|
||||
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 @@ 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(kb, &k, dsa_subprime_len);
|
||||
/*
|
||||
** FIPS 186-1, Section 5, Step 1
|
||||
**
|
||||
@ -359,9 +386,9 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
|
||||
/*
|
||||
** 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 @@ 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);
|
||||
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 @@ DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
|
||||
{
|
||||
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 @@ DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
|
||||
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 @@ SECStatus
|
||||
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 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
|
||||
/*
|
||||
** 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 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
|
||||
/*
|
||||
** 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
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* $Id: ldvector.c,v 1.30 2012-04-25 14:49:43 gerv%gerv.net Exp $ */
|
||||
/* $Id: ldvector.c,v 1.31 2012-06-12 16:39:00 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
extern int FREEBL_InitStubs(void);
|
||||
@ -253,9 +253,13 @@ static const struct FREEBLVectorStr vector =
|
||||
SHA224_Flatten,
|
||||
SHA224_Resurrect,
|
||||
SHA224_Clone,
|
||||
BLAPI_SHVerifyFile
|
||||
BLAPI_SHVerifyFile,
|
||||
|
||||
/* End of Version 3.013 */
|
||||
|
||||
PQG_ParamGenV2
|
||||
|
||||
/* End of Version 3.014 */
|
||||
};
|
||||
|
||||
const FREEBLVector *
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* $Id: loader.c,v 1.55 2012-04-25 14:49:43 gerv%gerv.net Exp $ */
|
||||
/* $Id: loader.c,v 1.56 2012-06-12 16:39:00 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#include "loader.h"
|
||||
#include "prmem.h"
|
||||
@ -850,6 +850,7 @@ PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes,
|
||||
return (vector->p_PQG_ParamGenSeedLen)(j, seedBytes, pParams, pVfy);
|
||||
}
|
||||
|
||||
|
||||
SECStatus
|
||||
PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy,
|
||||
SECStatus *result)
|
||||
@ -1839,3 +1840,13 @@ BLAPI_SHVerifyFile(const char *name)
|
||||
return PR_FALSE;
|
||||
return vector->p_BLAPI_SHVerifyFile(name);
|
||||
}
|
||||
|
||||
/* === new for DSA-2 === */
|
||||
SECStatus
|
||||
PQG_ParamGenV2( unsigned int L, unsigned int N, unsigned int seedBytes,
|
||||
PQGParams **pParams, PQGVerify **pVfy)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_PQG_ParamGenV2)(L, N, seedBytes, pParams, pVfy);
|
||||
}
|
||||
|
||||
@ -4,14 +4,14 @@
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* $Id: loader.h,v 1.36 2012-04-25 14:49:43 gerv%gerv.net Exp $ */
|
||||
/* $Id: loader.h,v 1.37 2012-06-12 16:39:00 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#ifndef _LOADER_H_
|
||||
#define _LOADER_H_ 1
|
||||
|
||||
#include "blapi.h"
|
||||
|
||||
#define FREEBL_VERSION 0x030D
|
||||
#define FREEBL_VERSION 0x030E
|
||||
|
||||
struct FREEBLVectorStr {
|
||||
|
||||
@ -563,6 +563,12 @@ struct FREEBLVectorStr {
|
||||
|
||||
/* Version 3.013 came to here */
|
||||
|
||||
SECStatus (* p_PQG_ParamGenV2)( unsigned int L, unsigned int N,
|
||||
unsigned int seedBytes,
|
||||
PQGParams **pParams, PQGVerify **pVfy);
|
||||
|
||||
/* Version 3.014 came to here */
|
||||
|
||||
};
|
||||
|
||||
typedef struct FREEBLVectorStr FREEBLVector;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
25
mozilla/security/nss/lib/freebl/pqg.h
Normal file
25
mozilla/security/nss/lib/freebl/pqg.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* pqg.h
|
||||
*
|
||||
* header file for pqg functions exported just to freebl
|
||||
*/
|
||||
|
||||
#ifndef _PQG_H_
|
||||
#define _PQG_H_ 1
|
||||
|
||||
/* PQG_GetLength returns the significant bytes in the SECItem object (that is
|
||||
* the length of the object minus any leading zeros. Any SECItem may be used,
|
||||
* though this function is usually used for P, Q, or G values */
|
||||
unsigned int PQG_GetLength(const SECItem *obj);
|
||||
/* Check to see the PQG parameters patch a NIST defined DSA size,
|
||||
* returns SECFaillure and sets SEC_ERROR_INVALID_ARGS if it doesn't.
|
||||
* See blapi.h for legal DSA PQG sizes. */
|
||||
SECStatus PQG_Check(const PQGParams *params);
|
||||
/* Return the prefered hash algorithm for the given PQGParameters. */
|
||||
HASH_HashType PQG_GetHashType(const PQGParams *params);
|
||||
|
||||
#endif
|
||||
@ -145,3 +145,37 @@ HASH_GetRawHashObject(HASH_HashType hashType)
|
||||
}
|
||||
return &SECRawHashObjects[hashType];
|
||||
}
|
||||
|
||||
unsigned int
|
||||
HASH_ResultLen(HASH_HashType type)
|
||||
{
|
||||
const SECHashObject *hash_obj = HASH_GetRawHashObject(type);
|
||||
if (hash_obj == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return hash_obj->length;
|
||||
}
|
||||
|
||||
|
||||
SECStatus
|
||||
HASH_HashBuf(HASH_HashType type, unsigned char *dest, unsigned char *src,
|
||||
PRUint32 src_len)
|
||||
{
|
||||
const SECHashObject *hash_obj = HASH_GetRawHashObject(type);
|
||||
void *hashcx = NULL;
|
||||
unsigned int dummy;
|
||||
|
||||
if (hash_obj == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
hashcx = hash_obj->create();
|
||||
if (hashcx == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
hash_obj->begin(hashcx);
|
||||
hash_obj->update(hashcx,src,src_len);
|
||||
hash_obj->end(hashcx,dest, &dummy, hash_obj->length);
|
||||
hash_obj->destroy(hashcx, PR_TRUE);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* $Id: shvfy.c,v 1.16 2012-04-25 14:49:43 gerv%gerv.net Exp $ */
|
||||
/* $Id: shvfy.c,v 1.17 2012-06-12 16:39:00 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
@ -15,6 +15,8 @@
|
||||
#include "seccomon.h"
|
||||
#include "stdio.h"
|
||||
#include "prmem.h"
|
||||
#include "hasht.h"
|
||||
#include "pqg.h"
|
||||
|
||||
/*
|
||||
* Most modern version of Linux support a speed optimization scheme where an
|
||||
@ -298,7 +300,8 @@ BLAPI_SHVerifyFile(const char *shName)
|
||||
char *checkName = NULL;
|
||||
PRFileDesc *checkFD = NULL;
|
||||
PRFileDesc *shFD = NULL;
|
||||
SHA1Context *hashcx = NULL;
|
||||
void *hashcx = NULL;
|
||||
SECHashObject *hashObj = NULL;
|
||||
SECItem signature = { 0, NULL, 0 };
|
||||
SECItem hash;
|
||||
int bytesRead, offset;
|
||||
@ -312,7 +315,7 @@ BLAPI_SHVerifyFile(const char *shName)
|
||||
PRBool result = PR_FALSE; /* if anything goes wrong,
|
||||
* the signature does not verify */
|
||||
unsigned char buf[4096];
|
||||
unsigned char hashBuf[SHA1_LENGTH];
|
||||
unsigned char hashBuf[HASH_LENGTH_MAX];
|
||||
|
||||
PORT_Memset(&key,0,sizeof(key));
|
||||
hash.data = hashBuf;
|
||||
@ -387,6 +390,11 @@ BLAPI_SHVerifyFile(const char *shName)
|
||||
PR_Close(checkFD);
|
||||
checkFD = NULL;
|
||||
|
||||
hashObj = HASH_GetRawHashObject(PQG_GetHashType(&key.params));
|
||||
if (hashObj == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* open our library file */
|
||||
#ifdef FREEBL_USE_PRELINK
|
||||
shFD = bl_OpenUnPrelink(shName,&pid);
|
||||
@ -402,15 +410,15 @@ BLAPI_SHVerifyFile(const char *shName)
|
||||
}
|
||||
|
||||
/* hash our library file with SHA1 */
|
||||
hashcx = SHA1_NewContext();
|
||||
hashcx = hashObj->create();
|
||||
if (hashcx == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
SHA1_Begin(hashcx);
|
||||
hashObj->begin(hashcx);
|
||||
|
||||
count = 0;
|
||||
while ((bytesRead = PR_Read(shFD, buf, sizeof(buf))) > 0) {
|
||||
SHA1_Update(hashcx, buf, bytesRead);
|
||||
hashObj->update(hashcx, buf, bytesRead);
|
||||
count += bytesRead;
|
||||
}
|
||||
#ifdef FREEBL_USE_PRELINK
|
||||
@ -420,7 +428,7 @@ BLAPI_SHVerifyFile(const char *shName)
|
||||
#endif
|
||||
shFD = NULL;
|
||||
|
||||
SHA1_End(hashcx, hash.data, &hash.len, hash.len);
|
||||
hashObj->end(hashcx, hash.data, &hash.len, hash.len);
|
||||
|
||||
|
||||
/* verify the hash against the check file */
|
||||
@ -464,7 +472,9 @@ loser:
|
||||
PR_Close(shFD);
|
||||
}
|
||||
if (hashcx != NULL) {
|
||||
SHA1_DestroyContext(hashcx,PR_TRUE);
|
||||
if (hashObj) {
|
||||
hashObj->destroy(hashcx,PR_TRUE);
|
||||
}
|
||||
}
|
||||
if (signature.data != NULL) {
|
||||
PORT_Free(signature.data);
|
||||
|
||||
@ -290,6 +290,8 @@ static const struct mechanismList mechanisms[] = {
|
||||
CKF_GENERATE_KEY_PAIR}, PR_TRUE},
|
||||
{CKM_DSA, {DSA_MIN_P_BITS, DSA_MAX_P_BITS,
|
||||
CKF_SN_VR}, PR_TRUE},
|
||||
{CKM_DSA_PARAMETER_GEN, {DSA_MIN_P_BITS, DSA_MAX_P_BITS,
|
||||
CKF_GENERATE}, PR_TRUE},
|
||||
{CKM_DSA_SHA1, {DSA_MIN_P_BITS, DSA_MAX_P_BITS,
|
||||
CKF_SN_VR}, PR_TRUE},
|
||||
/* -------------------- Diffie Hellman Operations --------------------- */
|
||||
@ -860,7 +862,7 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
|
||||
break;
|
||||
case CKK_DSA:
|
||||
crv = sftk_ConstrainAttribute(object, CKA_SUBPRIME,
|
||||
DSA_Q_BITS, DSA_Q_BITS, 0);
|
||||
DSA_MIN_Q_BITS, DSA_MAX_Q_BITS, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
@ -869,11 +871,11 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
crv = sftk_ConstrainAttribute(object, CKA_BASE, 1, DSA_MAX_P_BITS, 0);
|
||||
crv = sftk_ConstrainAttribute(object, CKA_BASE, 2, DSA_MAX_P_BITS, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
crv = sftk_ConstrainAttribute(object, CKA_VALUE, 1, DSA_MAX_P_BITS, 0);
|
||||
crv = sftk_ConstrainAttribute(object, CKA_VALUE, 2, DSA_MAX_P_BITS, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
@ -887,11 +889,11 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
crv = sftk_ConstrainAttribute(object, CKA_BASE, 1, DH_MAX_P_BITS, 0);
|
||||
crv = sftk_ConstrainAttribute(object, CKA_BASE, 2, DH_MAX_P_BITS, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
crv = sftk_ConstrainAttribute(object, CKA_VALUE, 1, DH_MAX_P_BITS, 0);
|
||||
crv = sftk_ConstrainAttribute(object, CKA_VALUE, 2, DH_MAX_P_BITS, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
@ -1349,6 +1351,23 @@ sftk_handleDSAParameterObject(SFTKSession *session, SFTKObject *object)
|
||||
PQGParams params;
|
||||
PQGVerify vfy, *verify = NULL;
|
||||
SECStatus result,rv;
|
||||
/* This bool keeps track of whether or not we need verify parameters.
|
||||
* If a P, Q and G or supplied, we dont' need verify parameters, as we
|
||||
* have PQ and G.
|
||||
* - If G is not supplied, the presumption is that we want to
|
||||
* verify P and Q only.
|
||||
* - If counter is supplied, it is presumed we want to verify PQ because
|
||||
* the counter is only used in verification.
|
||||
* - If H is supplied, is is presumed we want to verify G because H is
|
||||
* only used to verify G.
|
||||
* - Any verification step must have the SEED (counter or H could be
|
||||
* missing depending on exactly what we want to verify). If SEED is supplied,
|
||||
* the code just goes ahead and runs verify (other errors are parameter
|
||||
* errors are detected by the PQG_VerifyParams function). If SEED is not
|
||||
* supplied, but we determined that we are trying to verify (because needVfy
|
||||
* is set, go ahead and return CKR_TEMPLATE_INCOMPLETE.
|
||||
*/
|
||||
PRBool needVfy = PR_FALSE;
|
||||
|
||||
primeAttr = sftk_FindAttribute(object,CKA_PRIME);
|
||||
if (primeAttr == NULL) goto loser;
|
||||
@ -1361,26 +1380,43 @@ sftk_handleDSAParameterObject(SFTKSession *session, SFTKObject *object)
|
||||
params.subPrime.len = subPrimeAttr->attrib.ulValueLen;
|
||||
|
||||
baseAttr = sftk_FindAttribute(object,CKA_BASE);
|
||||
if (baseAttr == NULL) goto loser;
|
||||
params.base.data = baseAttr->attrib.pValue;
|
||||
params.base.len = baseAttr->attrib.ulValueLen;
|
||||
if (baseAttr != NULL) {
|
||||
params.base.data = baseAttr->attrib.pValue;
|
||||
params.base.len = baseAttr->attrib.ulValueLen;
|
||||
} else {
|
||||
params.base.data = NULL;
|
||||
params.base.len = 0;
|
||||
needVfy = PR_TRUE; /* presumably only including PQ so we can verify
|
||||
* them. */
|
||||
}
|
||||
|
||||
attribute = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_COUNTER);
|
||||
if (attribute != NULL) {
|
||||
vfy.counter = *(CK_ULONG *) attribute->attrib.pValue;
|
||||
sftk_FreeAttribute(attribute);
|
||||
needVfy = PR_TRUE; /* included a count so we can verify PQ */
|
||||
} else {
|
||||
vfy.counter = -1;
|
||||
}
|
||||
|
||||
seedAttr = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_SEED);
|
||||
if (seedAttr == NULL) goto loser;
|
||||
hAttr = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_H);
|
||||
if (hAttr != NULL) {
|
||||
vfy.h.data = hAttr->attrib.pValue;
|
||||
vfy.h.len = hAttr->attrib.ulValueLen;
|
||||
needVfy = PR_TRUE; /* included H so we can verify G */
|
||||
} else {
|
||||
vfy.h.data = NULL;
|
||||
vfy.h.len = 0;
|
||||
}
|
||||
seedAttr = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_SEED);
|
||||
if (seedAttr != NULL) {
|
||||
vfy.seed.data = seedAttr->attrib.pValue;
|
||||
vfy.seed.len = seedAttr->attrib.ulValueLen;
|
||||
|
||||
hAttr = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_H);
|
||||
if (hAttr == NULL) goto loser;
|
||||
vfy.h.data = hAttr->attrib.pValue;
|
||||
vfy.h.len = hAttr->attrib.ulValueLen;
|
||||
|
||||
verify = &vfy;
|
||||
} else if (needVfy) {
|
||||
goto loser; /* Verify always needs seed, if we need verify and not seed
|
||||
* then fail */
|
||||
}
|
||||
|
||||
crv = CKR_FUNCTION_FAILED;
|
||||
|
||||
@ -2057,7 +2057,7 @@ finish_rsa:
|
||||
context->update = (SFTKCipher) nsc_DSA_Sign_Stub;
|
||||
context->destroy = (privKey == key->objectInfo) ?
|
||||
(SFTKDestroy) sftk_Null:(SFTKDestroy)sftk_FreePrivKey;
|
||||
context->maxLen = DSA_SIGNATURE_LEN;
|
||||
context->maxLen = DSA_MAX_SIGNATURE_LEN;
|
||||
|
||||
break;
|
||||
|
||||
@ -2905,14 +2905,36 @@ nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism,
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* this is coded for "full" support. These selections will be limitted to
|
||||
* the official subset by freebl.
|
||||
*/
|
||||
static unsigned int
|
||||
sftk_GetSubPrimeFromPrime(unsigned int primeBits)
|
||||
{
|
||||
if (primeBits <= 1024) {
|
||||
return 160;
|
||||
} else if (primeBits <= 2048) {
|
||||
return 224;
|
||||
} else if (primeBits <= 3072) {
|
||||
return 256;
|
||||
} else if (primeBits <= 7680) {
|
||||
return 384;
|
||||
} else {
|
||||
return 512;
|
||||
}
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
|
||||
{
|
||||
SFTKAttribute *attribute;
|
||||
CK_ULONG counter;
|
||||
unsigned int seedBits = 0;
|
||||
unsigned int subprimeBits = 0;
|
||||
unsigned int primeBits;
|
||||
unsigned int j;
|
||||
unsigned int j = 8; /* default to 1024 bits */
|
||||
CK_RV crv = CKR_OK;
|
||||
PQGParams *params = NULL;
|
||||
PQGVerify *vfy = NULL;
|
||||
@ -2924,9 +2946,11 @@ nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
|
||||
}
|
||||
primeBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue;
|
||||
sftk_FreeAttribute(attribute);
|
||||
j = PQG_PBITS_TO_INDEX(primeBits);
|
||||
if (j == (unsigned int)-1) {
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
if (primeBits < 1024) {
|
||||
j = PQG_PBITS_TO_INDEX(primeBits);
|
||||
if (j == (unsigned int)-1) {
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
attribute = sftk_FindAttribute(key, CKA_NETSCAPE_PQG_SEED_BITS);
|
||||
@ -2935,14 +2959,34 @@ nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
|
||||
sftk_FreeAttribute(attribute);
|
||||
}
|
||||
|
||||
attribute = sftk_FindAttribute(key, CKA_SUBPRIME_BITS);
|
||||
if (attribute != NULL) {
|
||||
subprimeBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue;
|
||||
sftk_FreeAttribute(attribute);
|
||||
}
|
||||
|
||||
sftk_DeleteAttributeType(key,CKA_PRIME_BITS);
|
||||
sftk_DeleteAttributeType(key,CKA_SUBPRIME_BITS);
|
||||
sftk_DeleteAttributeType(key,CKA_NETSCAPE_PQG_SEED_BITS);
|
||||
|
||||
if (seedBits == 0) {
|
||||
rv = PQG_ParamGen(j, ¶ms, &vfy);
|
||||
/* use the old PQG interface if we have old input data */
|
||||
if ((primeBits < 1024) || ((primeBits == 1024) && (subprimeBits == 0))) {
|
||||
if (seedBits == 0) {
|
||||
rv = PQG_ParamGen(j, ¶ms, &vfy);
|
||||
} else {
|
||||
rv = PQG_ParamGenSeedLen(j,seedBits/8, ¶ms, &vfy);
|
||||
}
|
||||
} else {
|
||||
rv = PQG_ParamGenSeedLen(j,seedBits/8, ¶ms, &vfy);
|
||||
if (subprimeBits == 0) {
|
||||
subprimeBits = sftk_GetSubPrimeFromPrime(primeBits);
|
||||
}
|
||||
if (seedBits == 0) {
|
||||
seedBits = primeBits;
|
||||
}
|
||||
rv = PQG_ParamGenV2(primeBits, subprimeBits, seedBits/8, ¶ms, &vfy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
|
||||
@ -3459,6 +3503,7 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
|
||||
CK_MECHANISM mech = {0, NULL, 0};
|
||||
|
||||
CK_ULONG modulusLen;
|
||||
CK_ULONG subPrimeLen;
|
||||
PRBool isEncryptable = PR_FALSE;
|
||||
PRBool canSignVerify = PR_FALSE;
|
||||
PRBool isDerivable = PR_FALSE;
|
||||
@ -3472,10 +3517,12 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
|
||||
unsigned char *text_compared;
|
||||
CK_ULONG bytes_encrypted;
|
||||
CK_ULONG bytes_compared;
|
||||
CK_ULONG pairwise_digest_length = PAIRWISE_DIGEST_LENGTH;
|
||||
|
||||
/* Variables used for Signature/Verification functions. */
|
||||
/* always uses SHA-1 digest */
|
||||
unsigned char *known_digest = (unsigned char *)"Mozilla Rules World!";
|
||||
/* Must be at least 256 bits for DSA2 digest */
|
||||
unsigned char *known_digest = (unsigned char *)
|
||||
"Mozilla Rules the World through NSS!";
|
||||
unsigned char *signature;
|
||||
CK_ULONG signature_length;
|
||||
|
||||
@ -3492,6 +3539,19 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
|
||||
modulusLen--;
|
||||
}
|
||||
sftk_FreeAttribute(attribute);
|
||||
} else if (keyType == CKK_DSA) {
|
||||
SFTKAttribute *attribute;
|
||||
|
||||
/* Get subprime length of private key. */
|
||||
attribute = sftk_FindAttribute(privateKey, CKA_SUBPRIME);
|
||||
if (attribute == NULL) {
|
||||
return CKR_DEVICE_ERROR;
|
||||
}
|
||||
subPrimeLen = attribute->attrib.ulValueLen;
|
||||
if (subPrimeLen > 1 && *(unsigned char *)attribute->attrib.pValue == 0) {
|
||||
subPrimeLen--;
|
||||
}
|
||||
sftk_FreeAttribute(attribute);
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
@ -3617,7 +3677,8 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
|
||||
mech.mechanism = CKM_RSA_PKCS;
|
||||
break;
|
||||
case CKK_DSA:
|
||||
signature_length = DSA_SIGNATURE_LEN;
|
||||
signature_length = DSA_MAX_SIGNATURE_LEN;
|
||||
pairwise_digest_length = subPrimeLen;
|
||||
mech.mechanism = CKM_DSA;
|
||||
break;
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
@ -3645,7 +3706,7 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
|
||||
|
||||
crv = NSC_Sign(hSession,
|
||||
known_digest,
|
||||
PAIRWISE_DIGEST_LENGTH,
|
||||
pairwise_digest_length,
|
||||
signature,
|
||||
&signature_length);
|
||||
if (crv != CKR_OK) {
|
||||
@ -3662,7 +3723,7 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
|
||||
|
||||
crv = NSC_Verify(hSession,
|
||||
known_digest,
|
||||
PAIRWISE_DIGEST_LENGTH,
|
||||
pairwise_digest_length,
|
||||
signature,
|
||||
signature_length);
|
||||
|
||||
@ -3945,9 +4006,12 @@ kpg_done:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* these are checked by DSA_NewKey
|
||||
*/
|
||||
bitSize = sftk_GetLengthInBits(pqgParam.subPrime.data,
|
||||
pqgParam.subPrime.len);
|
||||
if (bitSize != DSA_Q_BITS) {
|
||||
if ((bitSize < DSA_MIN_Q_BITS) || (bitSize > DSA_MAX_Q_BITS)) {
|
||||
crv = CKR_TEMPLATE_INCOMPLETE;
|
||||
PORT_Free(pqgParam.prime.data);
|
||||
PORT_Free(pqgParam.subPrime.data);
|
||||
@ -3963,7 +4027,7 @@ kpg_done:
|
||||
break;
|
||||
}
|
||||
bitSize = sftk_GetLengthInBits(pqgParam.base.data,pqgParam.base.len);
|
||||
if ((bitSize < 1) || (bitSize > DSA_MAX_P_BITS)) {
|
||||
if ((bitSize < 2) || (bitSize > DSA_MAX_P_BITS)) {
|
||||
crv = CKR_TEMPLATE_INCOMPLETE;
|
||||
PORT_Free(pqgParam.prime.data);
|
||||
PORT_Free(pqgParam.subPrime.data);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* $Id: ssl3con.c,v 1.183 2012-06-11 02:38:30 emaldona%redhat.com Exp $ */
|
||||
/* $Id: ssl3con.c,v 1.184 2012-06-12 16:39:03 rrelyea%redhat.com Exp $ */
|
||||
|
||||
/* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
|
||||
|
||||
@ -901,7 +901,7 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,
|
||||
hashItem.data = hash->sha;
|
||||
hashItem.len = sizeof(hash->sha);
|
||||
/* Allow DER encoded DSA signatures in SSL 3.0 */
|
||||
if (isTLS || buf->len != DSA_SIGNATURE_LEN) {
|
||||
if (isTLS || buf->len != SECKEY_SignatureLen(key)) {
|
||||
signature = DSAU_DecodeDerSig(buf);
|
||||
if (!signature) {
|
||||
PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user