nss-fips-aes-keywrap-post.patch nss-fips-approved-crypto-non-ec.patch nss-fips-cavs-dsa-fixes.patch nss-fips-cavs-general.patch nss-fips-cavs-kas-ecc.patch nss-fips-cavs-kas-ffc.patch nss-fips-cavs-keywrap.patch nss-fips-cavs-rsa-fixes.patch nss-fips-combined-hash-sign-dsa-ecdsa.patch nss-fips-constructor-self-tests.patch nss-fips-detect-fips-mode-fixes.patch nss-fips-dsa-kat.patch nss-fips-gcm-ctr.patch nss-fips-pairwise-consistency-check.patch nss-fips-rsa-keygen-strictness.patch nss-fips-tls-allow-md5-prf.patch nss-fips-use-getrandom.patch nss-fips-use-strong-random-pool.patch nss-fips-zeroization.patch nss-fix-dh-pkcs-derive-inverted-logic.patch - update to NSS 3.53.1 * required for Firefox 78 * CVE-2020-12402 - Use constant-time GCD and modular inversion in MPI. (bmo#1631597, bsc#1173032) - update to NSS 3.53 Notable changes * SEED is now moved into a new freebl directory freebl/deprecated OBS-URL: https://build.opensuse.org/package/show/mozilla:Factory/mozilla-nss?expand=0&rev=326
396 lines
14 KiB
Diff
396 lines
14 KiB
Diff
From 7f3606a84f6c62b002246ee73121279e59f83437 Mon Sep 17 00:00:00 2001
|
|
From: Hans Petter Jansson <hpj@cl.no>
|
|
Date: Thu, 28 May 2020 22:44:22 +0200
|
|
Subject: [PATCH] CKM_(EC)DSA_SHAxxx mechs: Add some missing pieces.
|
|
|
|
This includes pairwise consistency checks and entry points for
|
|
power-on self tests.
|
|
---
|
|
cmd/lib/pk11table.c | 8 ++
|
|
lib/pk11wrap/pk11mech.c | 8 ++
|
|
lib/softoken/pkcs11c.c | 213 +++++++++++++++++++++++++++-------------
|
|
lib/softoken/softoken.h | 10 ++
|
|
4 files changed, 169 insertions(+), 70 deletions(-)
|
|
|
|
diff --git a/cmd/lib/pk11table.c b/cmd/lib/pk11table.c
|
|
index f7a45fa..d302436 100644
|
|
--- a/cmd/lib/pk11table.c
|
|
+++ b/cmd/lib/pk11table.c
|
|
@@ -273,6 +273,10 @@ const Constant _consts[] = {
|
|
mkEntry(CKM_DSA_KEY_PAIR_GEN, Mechanism),
|
|
mkEntry(CKM_DSA, Mechanism),
|
|
mkEntry(CKM_DSA_SHA1, Mechanism),
|
|
+ mkEntry(CKM_DSA_SHA224, Mechanism),
|
|
+ mkEntry(CKM_DSA_SHA256, Mechanism),
|
|
+ mkEntry(CKM_DSA_SHA384, Mechanism),
|
|
+ mkEntry(CKM_DSA_SHA512, Mechanism),
|
|
mkEntry(CKM_DH_PKCS_KEY_PAIR_GEN, Mechanism),
|
|
mkEntry(CKM_DH_PKCS_DERIVE, Mechanism),
|
|
mkEntry(CKM_X9_42_DH_DERIVE, Mechanism),
|
|
@@ -438,6 +442,10 @@ const Constant _consts[] = {
|
|
mkEntry(CKM_EC_KEY_PAIR_GEN, Mechanism),
|
|
mkEntry(CKM_ECDSA, Mechanism),
|
|
mkEntry(CKM_ECDSA_SHA1, Mechanism),
|
|
+ mkEntry(CKM_ECDSA_SHA224, Mechanism),
|
|
+ mkEntry(CKM_ECDSA_SHA256, Mechanism),
|
|
+ mkEntry(CKM_ECDSA_SHA384, Mechanism),
|
|
+ mkEntry(CKM_ECDSA_SHA512, Mechanism),
|
|
mkEntry(CKM_ECDH1_DERIVE, Mechanism),
|
|
mkEntry(CKM_ECDH1_COFACTOR_DERIVE, Mechanism),
|
|
mkEntry(CKM_ECMQV_DERIVE, Mechanism),
|
|
diff --git a/lib/pk11wrap/pk11mech.c b/lib/pk11wrap/pk11mech.c
|
|
index d94d59a..ac280f0 100644
|
|
--- a/lib/pk11wrap/pk11mech.c
|
|
+++ b/lib/pk11wrap/pk11mech.c
|
|
@@ -376,6 +376,10 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
|
|
return CKK_RSA;
|
|
case CKM_DSA:
|
|
case CKM_DSA_SHA1:
|
|
+ case CKM_DSA_SHA224:
|
|
+ case CKM_DSA_SHA256:
|
|
+ case CKM_DSA_SHA384:
|
|
+ case CKM_DSA_SHA512:
|
|
case CKM_DSA_KEY_PAIR_GEN:
|
|
return CKK_DSA;
|
|
case CKM_DH_PKCS_DERIVE:
|
|
@@ -386,6 +390,10 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
|
|
return CKK_KEA;
|
|
case CKM_ECDSA:
|
|
case CKM_ECDSA_SHA1:
|
|
+ case CKM_ECDSA_SHA224:
|
|
+ case CKM_ECDSA_SHA256:
|
|
+ case CKM_ECDSA_SHA384:
|
|
+ case CKM_ECDSA_SHA512:
|
|
case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
|
|
case CKM_ECDH1_DERIVE:
|
|
return CKK_EC; /* CKK_ECDSA is deprecated */
|
|
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
|
|
index 08f94bc..ec6b205 100644
|
|
--- a/lib/softoken/pkcs11c.c
|
|
+++ b/lib/softoken/pkcs11c.c
|
|
@@ -2606,7 +2606,7 @@ nsc_DSA_Verify_Stub(void *ctx, void *sigBuf, unsigned int sigLen,
|
|
static SECStatus
|
|
nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
|
|
unsigned int *sigLen, unsigned int maxSigLen,
|
|
- void *dataBuf, unsigned int dataLen)
|
|
+ const void *dataBuf, unsigned int dataLen)
|
|
{
|
|
SECItem signature, digest;
|
|
SECStatus rv;
|
|
@@ -2624,6 +2624,22 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
|
|
return rv;
|
|
}
|
|
|
|
+SECStatus
|
|
+DSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
|
|
+ unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
|
|
+ const unsigned char *hash, unsigned int hashLen)
|
|
+{
|
|
+ SECStatus rv;
|
|
+
|
|
+ rv = nsc_DSA_Sign_Stub(key, sig, sigLen, maxLen, hash, hashLen);
|
|
+
|
|
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
|
|
+ sftk_fatalError = PR_TRUE;
|
|
+ }
|
|
+
|
|
+ return rv;
|
|
+}
|
|
+
|
|
static SECStatus
|
|
nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen,
|
|
void *dataBuf, unsigned int dataLen)
|
|
@@ -2641,7 +2657,7 @@ nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen,
|
|
static SECStatus
|
|
nsc_ECDSASignStub(void *ctx, void *sigBuf,
|
|
unsigned int *sigLen, unsigned int maxSigLen,
|
|
- void *dataBuf, unsigned int dataLen)
|
|
+ const void *dataBuf, unsigned int dataLen)
|
|
{
|
|
SECItem signature, digest;
|
|
SECStatus rv;
|
|
@@ -2659,6 +2675,22 @@ nsc_ECDSASignStub(void *ctx, void *sigBuf,
|
|
return rv;
|
|
}
|
|
|
|
+SECStatus
|
|
+ECDSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
|
|
+ unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
|
|
+ const unsigned char *hash, unsigned int hashLen)
|
|
+{
|
|
+ SECStatus rv;
|
|
+
|
|
+ rv = nsc_ECDSASignStub(key, sig, sigLen, maxLen, hash, hashLen);
|
|
+
|
|
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
|
|
+ sftk_fatalError = PR_TRUE;
|
|
+ }
|
|
+
|
|
+ return rv;
|
|
+}
|
|
+
|
|
/* NSC_SignInit setups up the signing operations. There are three basic
|
|
* types of signing:
|
|
* (1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied
|
|
@@ -3511,6 +3543,22 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession,
|
|
info->hashOid = SEC_OID_##mmm; \
|
|
goto finish_rsa;
|
|
|
|
+#define INIT_DSA_VFY_MECH(mmm) \
|
|
+ case CKM_DSA_##mmm: \
|
|
+ context->multi = PR_TRUE; \
|
|
+ crv = sftk_doSub##mmm(context); \
|
|
+ if (crv != CKR_OK) \
|
|
+ break; \
|
|
+ goto finish_dsa;
|
|
+
|
|
+#define INIT_ECDSA_VFY_MECH(mmm) \
|
|
+ case CKM_ECDSA_##mmm: \
|
|
+ context->multi = PR_TRUE; \
|
|
+ crv = sftk_doSub##mmm(context); \
|
|
+ if (crv != CKR_OK) \
|
|
+ break; \
|
|
+ goto finish_ecdsa;
|
|
+
|
|
switch (pMechanism->mechanism) {
|
|
INIT_RSA_VFY_MECH(MD5)
|
|
INIT_RSA_VFY_MECH(MD2)
|
|
@@ -3575,13 +3623,15 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession,
|
|
context->destroy = (SFTKDestroy)sftk_Space;
|
|
context->verify = (SFTKVerify)sftk_RSACheckSignPSS;
|
|
break;
|
|
- case CKM_DSA_SHA1:
|
|
- context->multi = PR_TRUE;
|
|
- crv = sftk_doSubSHA1(context);
|
|
- if (crv != CKR_OK)
|
|
- break;
|
|
- /* fall through */
|
|
+
|
|
+ INIT_DSA_VFY_MECH(SHA1)
|
|
+ INIT_DSA_VFY_MECH(SHA224)
|
|
+ INIT_DSA_VFY_MECH(SHA256)
|
|
+ INIT_DSA_VFY_MECH(SHA384)
|
|
+ INIT_DSA_VFY_MECH(SHA512)
|
|
+
|
|
case CKM_DSA:
|
|
+ finish_dsa:
|
|
if (key_type != CKK_DSA) {
|
|
crv = CKR_KEY_TYPE_INCONSISTENT;
|
|
break;
|
|
@@ -3594,13 +3644,15 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession,
|
|
context->verify = (SFTKVerify)nsc_DSA_Verify_Stub;
|
|
context->destroy = sftk_Null;
|
|
break;
|
|
- case CKM_ECDSA_SHA1:
|
|
- context->multi = PR_TRUE;
|
|
- crv = sftk_doSubSHA1(context);
|
|
- if (crv != CKR_OK)
|
|
- break;
|
|
- /* fall through */
|
|
+
|
|
+ INIT_ECDSA_VFY_MECH(SHA1)
|
|
+ INIT_ECDSA_VFY_MECH(SHA224)
|
|
+ INIT_ECDSA_VFY_MECH(SHA256)
|
|
+ INIT_ECDSA_VFY_MECH(SHA384)
|
|
+ INIT_ECDSA_VFY_MECH(SHA512)
|
|
+
|
|
case CKM_ECDSA:
|
|
+ finish_ecdsa:
|
|
if (key_type != CKK_EC) {
|
|
crv = CKR_KEY_TYPE_INCONSISTENT;
|
|
break;
|
|
@@ -4733,6 +4785,73 @@ loser:
|
|
#define PAIRWISE_DIGEST_LENGTH SHA224_LENGTH /* 224-bits */
|
|
#define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */
|
|
|
|
+static CK_RV
|
|
+pairwise_signverify_mech (CK_SESSION_HANDLE hSession,
|
|
+ SFTKObject *publicKey, SFTKObject *privateKey,
|
|
+ CK_MECHANISM mech,
|
|
+ CK_ULONG signature_length,
|
|
+ CK_ULONG pairwise_digest_length)
|
|
+{
|
|
+ /* Variables used for Signature/Verification functions. */
|
|
+ /* 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_RV crv;
|
|
+
|
|
+ /* Allocate space for signature data. */
|
|
+ signature = (unsigned char *)PORT_ZAlloc(signature_length);
|
|
+ if (signature == NULL) {
|
|
+ return CKR_HOST_MEMORY;
|
|
+ }
|
|
+
|
|
+ /* Sign the known hash using the private key. */
|
|
+ crv = NSC_SignInit(hSession, &mech, privateKey->handle);
|
|
+ if (crv != CKR_OK) {
|
|
+ PORT_Free(signature);
|
|
+ return crv;
|
|
+ }
|
|
+
|
|
+ crv = NSC_Sign(hSession,
|
|
+ known_digest,
|
|
+ pairwise_digest_length,
|
|
+ signature,
|
|
+ &signature_length);
|
|
+ if (crv != CKR_OK) {
|
|
+ PORT_Free(signature);
|
|
+ return crv;
|
|
+ }
|
|
+
|
|
+ /* detect trivial signing transforms */
|
|
+ if ((signature_length >= pairwise_digest_length) &&
|
|
+ (PORT_Memcmp(known_digest, signature + (signature_length - pairwise_digest_length), pairwise_digest_length) == 0)) {
|
|
+ PORT_Free(signature);
|
|
+ return CKR_DEVICE_ERROR;
|
|
+ }
|
|
+
|
|
+ /* Verify the known hash using the public key. */
|
|
+ crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
|
|
+ if (crv != CKR_OK) {
|
|
+ PORT_Free(signature);
|
|
+ return crv;
|
|
+ }
|
|
+
|
|
+ crv = NSC_Verify(hSession,
|
|
+ known_digest,
|
|
+ pairwise_digest_length,
|
|
+ signature,
|
|
+ signature_length);
|
|
+
|
|
+ /* Free signature data. */
|
|
+ PORT_Free(signature);
|
|
+
|
|
+ if ((crv == CKR_SIGNATURE_LEN_RANGE) ||
|
|
+ (crv == CKR_SIGNATURE_INVALID)) {
|
|
+ return CKR_GENERAL_ERROR;
|
|
+ }
|
|
+
|
|
+ return crv;
|
|
+}
|
|
+
|
|
/*
|
|
* FIPS 140-2 pairwise consistency check utilized to validate key pair.
|
|
*
|
|
@@ -4780,8 +4899,6 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
|
|
|
|
/* Variables used for Signature/Verification functions. */
|
|
/* 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;
|
|
|
|
if (keyType == CKK_RSA) {
|
|
@@ -4935,76 +5052,32 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
|
|
}
|
|
}
|
|
|
|
+#define SIGNVERIFY_CHECK_MECH(vfymech) \
|
|
+ mech.mechanism = vfymech; \
|
|
+ crv = pairwise_signverify_mech (hSession, publicKey, privateKey, \
|
|
+ mech, signature_length, pairwise_digest_length); \
|
|
+ if (crv != CKR_OK) \
|
|
+ return crv;
|
|
+
|
|
if (canSignVerify) {
|
|
- /* Determine length of signature. */
|
|
switch (keyType) {
|
|
case CKK_RSA:
|
|
signature_length = modulusLen;
|
|
- mech.mechanism = CKM_RSA_PKCS;
|
|
+ SIGNVERIFY_CHECK_MECH(CKM_SHA224_RSA_PKCS)
|
|
break;
|
|
case CKK_DSA:
|
|
signature_length = DSA_MAX_SIGNATURE_LEN;
|
|
pairwise_digest_length = subPrimeLen;
|
|
- mech.mechanism = CKM_DSA;
|
|
+ SIGNVERIFY_CHECK_MECH(CKM_DSA_SHA224)
|
|
break;
|
|
case CKK_EC:
|
|
signature_length = MAX_ECKEY_LEN * 2;
|
|
- mech.mechanism = CKM_ECDSA;
|
|
+ SIGNVERIFY_CHECK_MECH(CKM_ECDSA_SHA224)
|
|
break;
|
|
default:
|
|
return CKR_DEVICE_ERROR;
|
|
}
|
|
|
|
- /* Allocate space for signature data. */
|
|
- signature = (unsigned char *)PORT_ZAlloc(signature_length);
|
|
- if (signature == NULL) {
|
|
- return CKR_HOST_MEMORY;
|
|
- }
|
|
-
|
|
- /* Sign the known hash using the private key. */
|
|
- crv = NSC_SignInit(hSession, &mech, privateKey->handle);
|
|
- if (crv != CKR_OK) {
|
|
- PORT_Free(signature);
|
|
- return crv;
|
|
- }
|
|
-
|
|
- crv = NSC_Sign(hSession,
|
|
- known_digest,
|
|
- pairwise_digest_length,
|
|
- signature,
|
|
- &signature_length);
|
|
- if (crv != CKR_OK) {
|
|
- PORT_Free(signature);
|
|
- return crv;
|
|
- }
|
|
-
|
|
- /* detect trivial signing transforms */
|
|
- if ((signature_length >= pairwise_digest_length) &&
|
|
- (PORT_Memcmp(known_digest, signature + (signature_length - pairwise_digest_length), pairwise_digest_length) == 0)) {
|
|
- PORT_Free(signature);
|
|
- return CKR_DEVICE_ERROR;
|
|
- }
|
|
-
|
|
- /* Verify the known hash using the public key. */
|
|
- crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
|
|
- if (crv != CKR_OK) {
|
|
- PORT_Free(signature);
|
|
- return crv;
|
|
- }
|
|
-
|
|
- crv = NSC_Verify(hSession,
|
|
- known_digest,
|
|
- pairwise_digest_length,
|
|
- signature,
|
|
- signature_length);
|
|
-
|
|
- /* Free signature data. */
|
|
- PORT_Free(signature);
|
|
-
|
|
- if ((crv == CKR_SIGNATURE_LEN_RANGE) ||
|
|
- (crv == CKR_SIGNATURE_INVALID)) {
|
|
- return CKR_GENERAL_ERROR;
|
|
- }
|
|
if (crv != CKR_OK) {
|
|
return crv;
|
|
}
|
|
diff --git a/lib/softoken/softoken.h b/lib/softoken/softoken.h
|
|
index 30586fc..d5aaffa 100644
|
|
--- a/lib/softoken/softoken.h
|
|
+++ b/lib/softoken/softoken.h
|
|
@@ -35,6 +35,16 @@ RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key,
|
|
const unsigned char *sig, unsigned int sigLen,
|
|
const unsigned char *hash, unsigned int hashLen);
|
|
|
|
+extern SECStatus
|
|
+DSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
|
|
+ unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
|
|
+ const unsigned char *hash, unsigned int hashLen);
|
|
+
|
|
+extern SECStatus
|
|
+ECDSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
|
|
+ unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
|
|
+ const unsigned char *hash, unsigned int hashLen);
|
|
+
|
|
/*
|
|
** Prepare a buffer for padded CBC encryption, growing to the appropriate
|
|
** boundary, filling with the appropriate padding.
|
|
--
|
|
2.26.2
|
|
|