Resolves: RHEL-182558
- rebase to upstream NSS 3.124 - backport ml-dsa support that is not upstream yet. - pick up in process patches upstream including eddsa - fix pss issues
This commit is contained in:
parent
a599dd307d
commit
e0164ae30e
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,3 +14,4 @@ SOURCES/nss-3.79.tar.gz
|
||||
/nss-3.90.tar.gz
|
||||
/nss-3.101.tar.gz
|
||||
/nss-3.112.tar.gz
|
||||
/nss-3.124.tar.gz
|
||||
|
||||
@ -7,43 +7,9 @@
|
||||
* algorithms which have NIST algorithm Certificates.
|
||||
*/
|
||||
|
||||
/* handle special cases. Classes require existing code to already be
|
||||
* in place for that class */
|
||||
typedef enum {
|
||||
SFTKFIPSNone = 0,
|
||||
SFTKFIPSDH, /* allow only specific primes */
|
||||
SFTKFIPSECC, /* not just keys but specific curves */
|
||||
SFTKFIPSAEAD, /* single shot AEAD functions not allowed in FIPS mode */
|
||||
SFTKFIPSRSAPSS, /* make sure salt isn't too big */
|
||||
SFTKFIPSPBKDF2, /* handle pbkdf2 FIPS restrictions */
|
||||
SFTKFIPSTlsKeyCheck, /* check the output of TLS prf functions */
|
||||
SFTKFIPSChkHash, /* make sure the base hash of KDF functions is FIPS */
|
||||
SFTKFIPSChkHashTls, /* make sure the base hash of TLS KDF functions is FIPS */
|
||||
SFTKFIPSChkHashSp800, /* make sure the base hash of SP-800-108 KDF functions is FIPS */
|
||||
SFTKFIPSRSAOAEP, /* make sure that both hashes use the same FIPS compliant algorithm */
|
||||
#ifndef NSS_DISABLE_KYBER
|
||||
SFKFIPSMLKEM, /* make sure the keys are only mlkem and not kyber */
|
||||
#endif
|
||||
} SFTKFIPSSpecialClass;
|
||||
|
||||
#ifdef NSS_DISABLE_KYBER
|
||||
/* if kyber is disable, we don't need to check that we are using
|
||||
* a kyber key in the ML_KEM code */
|
||||
#define SFTKFIPSMLKEM SFTKFIPSNone
|
||||
#endif
|
||||
|
||||
/* set according to your security policy */
|
||||
#define SFTKFIPS_PBKDF2_MIN_PW_LEN 8
|
||||
|
||||
typedef struct SFTKFIPSAlgorithmListStr SFTKFIPSAlgorithmList;
|
||||
struct SFTKFIPSAlgorithmListStr {
|
||||
CK_MECHANISM_TYPE type;
|
||||
CK_MECHANISM_INFO info;
|
||||
CK_ULONG step;
|
||||
SFTKFIPSSpecialClass special;
|
||||
size_t offset;
|
||||
};
|
||||
|
||||
SFTKFIPSAlgorithmList sftk_fips_mechs[] = {
|
||||
/* A sample set of algorithms to allow basic testing in our continous
|
||||
* testing infrastructure. The vendor version should replace this with
|
||||
@ -120,9 +86,9 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] = {
|
||||
{ CKM_ML_DSA_KEY_PAIR_GEN, { CK_ALL_KEY, CKF_KPG }, CK_ALL_STEP, SFTKFIPSNone },
|
||||
{ CKM_ML_DSA, { CK_ALL_KEY, CKF_SGN }, CK_ALL_STEP, SFTKFIPSNone },
|
||||
/* only allowed keys are implented for ML_KEM */
|
||||
{ CKM_ML_KEM_KEY_PAIR_GEN, { CK_ALL_KEY, CKF_KPG }, CK_ALL_STEP, SFTKFIPSMLKEM },
|
||||
{ CKM_ML_KEM_KEY_PAIR_GEN, { CK_ALL_KEY, CKF_KPG }, CK_ALL_STEP, SFTKFIPSNone },
|
||||
|
||||
{ CKM_ML_KEM, { CK_ALL_KEY, CKF_KEM }, CK_ALL_STEP, SFTKFIPSMLKEM },
|
||||
{ CKM_ML_KEM, { CK_ALL_KEY, CKF_KEM }, CK_ALL_STEP, SFTKFIPSNone },
|
||||
/* ------------------------- RC2 Operations --------------------------- */
|
||||
/* ------------------------- AES Operations --------------------------- */
|
||||
{ CKM_AES_KEY_GEN, { AES_FB_KEY, CKF_GEN }, AES_FB_STEP, SFTKFIPSNone },
|
||||
@ -187,7 +153,7 @@ SFTKFIPSAlgorithmList sftk_fips_mechs[] = {
|
||||
* to set the FIPS indicators on these (sigh) */
|
||||
/* NOTE: CKM_NSS_ML_KEM_KEY_GEN and the KYBER equivalent does not do
|
||||
* pairwise consistency checks on key gen, so are not FIPS */
|
||||
{ CKM_NSS_ML_KEM, { CK_ALL_KEY, CKF_KEM }, CK_ALL_STEP, SFTKFIPSMLKEM },
|
||||
{ CKM_NSS_ML_KEM, { CK_ALL_KEY, CKF_KEM }, CK_ALL_STEP, SFTKFIPSNone },
|
||||
{ CKM_NSS_AES_KEY_WRAP, { AES_FB_KEY, CKF_ECW }, AES_FB_STEP, SFTKFIPSNone },
|
||||
{ CKM_NSS_AES_KEY_WRAP_PAD, { AES_FB_KEY, CKF_ECW }, AES_FB_STEP, SFTKFIPSNone },
|
||||
{ CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256, { 384, 384, CKF_DERIVE }, 1, SFTKFIPSTlsKeyCheck },
|
||||
|
||||
@ -1,490 +0,0 @@
|
||||
diff -up ./lib/freebl/dh.c.fips-review ./lib/freebl/dh.c
|
||||
--- ./lib/freebl/dh.c.fips-review 2024-06-07 09:26:03.000000000 -0700
|
||||
+++ ./lib/freebl/dh.c 2024-06-12 12:04:10.639360404 -0700
|
||||
@@ -445,7 +445,7 @@ cleanup:
|
||||
PRBool
|
||||
KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime)
|
||||
{
|
||||
- mp_int p, q, y, r;
|
||||
+ mp_int p, q, y, r, psub1;
|
||||
mp_err err;
|
||||
int cmp = 1; /* default is false */
|
||||
if (!Y || !prime || !subPrime) {
|
||||
@@ -456,13 +456,30 @@ KEA_Verify(SECItem *Y, SECItem *prime, S
|
||||
MP_DIGITS(&q) = 0;
|
||||
MP_DIGITS(&y) = 0;
|
||||
MP_DIGITS(&r) = 0;
|
||||
+ MP_DIGITS(&psub1) = 0;
|
||||
CHECK_MPI_OK(mp_init(&p));
|
||||
CHECK_MPI_OK(mp_init(&q));
|
||||
CHECK_MPI_OK(mp_init(&y));
|
||||
CHECK_MPI_OK(mp_init(&r));
|
||||
+ CHECK_MPI_OK(mp_init(&psub1));
|
||||
SECITEM_TO_MPINT(*prime, &p);
|
||||
SECITEM_TO_MPINT(*subPrime, &q);
|
||||
SECITEM_TO_MPINT(*Y, &y);
|
||||
+ CHECK_MPI_OK(mp_sub_d(&p, 1, &psub1));
|
||||
+ /*
|
||||
+ * We check that the public value isn't zero (which isn't in the
|
||||
+ * group), one (subgroup of order one) or p-1 (subgroup of order 2). We
|
||||
+ * also check that the public value is less than p, to avoid being fooled
|
||||
+ * by values like p+1 or 2*p-1.
|
||||
+ * This check is required by SP-800-56Ar3. It's also done in derive,
|
||||
+ * but this is only called in various FIPS cases, so put it here to help
|
||||
+ * reviewers find it.
|
||||
+ */
|
||||
+ if (mp_cmp_d(&y, 1) <= 0 ||
|
||||
+ mp_cmp(&y, &psub1) >= 0) {
|
||||
+ err = MP_BADARG;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
/* compute r = y**q mod p */
|
||||
CHECK_MPI_OK(mp_exptmod(&y, &q, &p, &r));
|
||||
/* compare to 1 */
|
||||
@@ -472,6 +489,7 @@ cleanup:
|
||||
mp_clear(&q);
|
||||
mp_clear(&y);
|
||||
mp_clear(&r);
|
||||
+ mp_clear(&psub1);
|
||||
if (err) {
|
||||
MP_TO_SEC_ERROR(err);
|
||||
return PR_FALSE;
|
||||
diff -up ./lib/softoken/pkcs11c.c.fips-review ./lib/softoken/pkcs11c.c
|
||||
--- ./lib/softoken/pkcs11c.c.fips-review 2024-06-12 12:04:10.638360392 -0700
|
||||
+++ ./lib/softoken/pkcs11c.c 2024-06-12 13:06:35.410551333 -0700
|
||||
@@ -43,6 +43,7 @@
|
||||
|
||||
#include "prprf.h"
|
||||
#include "prenv.h"
|
||||
+#include "prerror.h"
|
||||
|
||||
#define __PASTE(x, y) x##y
|
||||
#define BAD_PARAM_CAST(pMech, typeSize) (!pMech->pParameter || pMech->ulParameterLen < typeSize)
|
||||
@@ -4882,6 +4883,10 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
|
||||
* handle the base object stuff
|
||||
*/
|
||||
crv = sftk_handleObject(key, session);
|
||||
+ /* we need to do this check at the end, so we can check the generated
|
||||
+ * key length against fips requirements */
|
||||
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE, key);
|
||||
+ session->lastOpWasFIPS = key->isFIPS;
|
||||
sftk_FreeSession(session);
|
||||
if (crv == CKR_OK && sftk_isTrue(key, CKA_SENSITIVE)) {
|
||||
crv = sftk_forceAttribute(key, CKA_ALWAYS_SENSITIVE, &cktrue, sizeof(CK_BBOOL));
|
||||
@@ -4889,9 +4894,6 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
|
||||
if (crv == CKR_OK && !sftk_isTrue(key, CKA_EXTRACTABLE)) {
|
||||
crv = sftk_forceAttribute(key, CKA_NEVER_EXTRACTABLE, &cktrue, sizeof(CK_BBOOL));
|
||||
}
|
||||
- /* we need to do this check at the end, so we can check the generated key length against
|
||||
- * fips requirements */
|
||||
- key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE, key);
|
||||
if (crv == CKR_OK) {
|
||||
*phKey = key->handle;
|
||||
}
|
||||
@@ -5199,60 +5201,68 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
|
||||
|
||||
if (isDerivable) {
|
||||
SFTKAttribute *pubAttribute = NULL;
|
||||
- CK_OBJECT_HANDLE newKey;
|
||||
PRBool isFIPS = sftk_isFIPS(slot->slotID);
|
||||
- CK_RV crv2;
|
||||
- CK_OBJECT_CLASS secret = CKO_SECRET_KEY;
|
||||
- CK_KEY_TYPE generic = CKK_GENERIC_SECRET;
|
||||
- CK_ULONG keyLen = 128;
|
||||
- CK_BBOOL ckTrue = CK_TRUE;
|
||||
- CK_ATTRIBUTE template[] = {
|
||||
- { CKA_CLASS, &secret, sizeof(secret) },
|
||||
- { CKA_KEY_TYPE, &generic, sizeof(generic) },
|
||||
- { CKA_VALUE_LEN, &keyLen, sizeof(keyLen) },
|
||||
- { CKA_DERIVE, &ckTrue, sizeof(ckTrue) }
|
||||
- };
|
||||
- CK_ULONG templateCount = PR_ARRAY_SIZE(template);
|
||||
- CK_ECDH1_DERIVE_PARAMS ecParams;
|
||||
+ NSSLOWKEYPrivateKey *lowPrivKey = NULL;
|
||||
+ ECPrivateKey *ecPriv;
|
||||
+ SECItem *lowPubValue = NULL;
|
||||
+ SECItem item;
|
||||
+ SECStatus rv;
|
||||
|
||||
crv = CKR_OK; /*paranoia, already get's set before we drop to the end */
|
||||
- /* FIPS 140-2 requires we verify that the resulting key is a valid key.
|
||||
- * The easiest way to do this is to do a derive operation, which checks
|
||||
- * the validity of the key */
|
||||
-
|
||||
+ /* FIPS 140-3 requires we verify that the resulting key is a valid key
|
||||
+ * by recalculating the public can an compare it to our own public
|
||||
+ * key. */
|
||||
+ lowPrivKey = sftk_GetPrivKey(privateKey, keyType, &crv);
|
||||
+ if (lowPrivKey == NULL) {
|
||||
+ return sftk_MapCryptError(PORT_GetError());
|
||||
+ }
|
||||
+ /* recalculate the public key from the private key */
|
||||
switch (keyType) {
|
||||
- case CKK_DH:
|
||||
- mech.mechanism = CKM_DH_PKCS_DERIVE;
|
||||
- pubAttribute = sftk_FindAttribute(publicKey, CKA_VALUE);
|
||||
- if (pubAttribute == NULL) {
|
||||
- return CKR_DEVICE_ERROR;
|
||||
- }
|
||||
- mech.pParameter = pubAttribute->attrib.pValue;
|
||||
- mech.ulParameterLen = pubAttribute->attrib.ulValueLen;
|
||||
- break;
|
||||
- case CKK_EC:
|
||||
- mech.mechanism = CKM_ECDH1_DERIVE;
|
||||
- pubAttribute = sftk_FindAttribute(publicKey, CKA_EC_POINT);
|
||||
- if (pubAttribute == NULL) {
|
||||
- return CKR_DEVICE_ERROR;
|
||||
- }
|
||||
- ecParams.kdf = CKD_NULL;
|
||||
- ecParams.ulSharedDataLen = 0;
|
||||
- ecParams.pSharedData = NULL;
|
||||
- ecParams.ulPublicDataLen = pubAttribute->attrib.ulValueLen;
|
||||
- ecParams.pPublicData = pubAttribute->attrib.pValue;
|
||||
- mech.pParameter = &ecParams;
|
||||
- mech.ulParameterLen = sizeof(ecParams);
|
||||
- break;
|
||||
- default:
|
||||
- return CKR_DEVICE_ERROR;
|
||||
+ case CKK_DH:
|
||||
+ rv = DH_Derive(&lowPrivKey->u.dh.base, &lowPrivKey->u.dh.prime,
|
||||
+ &lowPrivKey->u.dh.privateValue, &item, 0);
|
||||
+ if (rv != SECSuccess) {
|
||||
+ return CKR_GENERAL_ERROR;
|
||||
+ }
|
||||
+ lowPubValue = SECITEM_DupItem(&item);
|
||||
+ SECITEM_ZfreeItem(&item, PR_FALSE);
|
||||
+ pubAttribute = sftk_FindAttribute(publicKey, CKA_VALUE);
|
||||
+ break;
|
||||
+ case CKK_EC:
|
||||
+ rv = EC_NewKeyFromSeed(&lowPrivKey->u.ec.ecParams, &ecPriv,
|
||||
+ lowPrivKey->u.ec.privateValue.data,
|
||||
+ lowPrivKey->u.ec.privateValue.len);
|
||||
+ if (rv != SECSuccess) {
|
||||
+ return CKR_GENERAL_ERROR;
|
||||
+ }
|
||||
+ /* make sure it has the same encoding */
|
||||
+ if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT") ||
|
||||
+ lowPrivKey->u.ec.ecParams.type != ec_params_named) {
|
||||
+ lowPubValue = SECITEM_DupItem(&ecPriv->publicValue);
|
||||
+ } else {
|
||||
+ lowPubValue = SEC_ASN1EncodeItem(NULL, NULL, &ecPriv->publicValue,
|
||||
+ SEC_ASN1_GET(SEC_OctetStringTemplate));;
|
||||
+ }
|
||||
+ pubAttribute = sftk_FindAttribute(publicKey, CKA_EC_POINT);
|
||||
+ /* clear out our generated private key */
|
||||
+ PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return CKR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
- crv = NSC_DeriveKey(hSession, &mech, privateKey->handle, template, templateCount, &newKey);
|
||||
- if (crv != CKR_OK) {
|
||||
- sftk_FreeAttribute(pubAttribute);
|
||||
- return crv;
|
||||
+ /* now compare new public key with our already generated key */
|
||||
+ if ((pubAttribute == NULL) || (lowPubValue == NULL) ||
|
||||
+ (pubAttribute->attrib.ulValueLen != lowPubValue->len) ||
|
||||
+ (PORT_Memcmp(pubAttribute->attrib.pValue, lowPubValue->data,
|
||||
+ lowPubValue->len) != 0)) {
|
||||
+ if (pubAttribute) sftk_FreeAttribute(pubAttribute);
|
||||
+ if (lowPubValue) SECITEM_ZfreeItem(lowPubValue, PR_TRUE);
|
||||
+ PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
+ return CKR_GENERAL_ERROR;
|
||||
}
|
||||
+ SECITEM_ZfreeItem(lowPubValue, PR_TRUE);
|
||||
+
|
||||
/* FIPS requires full validation, but in fipx mode NSC_Derive
|
||||
* only does partial validation with approved primes, now handle
|
||||
* full validation */
|
||||
@@ -5260,44 +5270,78 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
|
||||
SECItem pubKey;
|
||||
SECItem prime;
|
||||
SECItem subPrime;
|
||||
+ SECItem base;
|
||||
+ SECItem generator;
|
||||
const SECItem *subPrimePtr = &subPrime;
|
||||
|
||||
pubKey.data = pubAttribute->attrib.pValue;
|
||||
pubKey.len = pubAttribute->attrib.ulValueLen;
|
||||
- prime.data = subPrime.data = NULL;
|
||||
- prime.len = subPrime.len = 0;
|
||||
+ base.data = prime.data = subPrime.data = NULL;
|
||||
+ base.len = prime.len = subPrime.len = 0;
|
||||
crv = sftk_Attribute2SecItem(NULL, &prime, privateKey, CKA_PRIME);
|
||||
if (crv != CKR_OK) {
|
||||
goto done;
|
||||
}
|
||||
- crv = sftk_Attribute2SecItem(NULL, &prime, privateKey, CKA_PRIME);
|
||||
+ crv = sftk_Attribute2SecItem(NULL, &base, privateKey, CKA_BASE);
|
||||
+ if (crv != CKR_OK) {
|
||||
+ goto done;
|
||||
+ }
|
||||
/* we ignore the return code an only look at the length */
|
||||
- if (subPrime.len == 0) {
|
||||
- /* subprime not supplied, In this case look it up.
|
||||
- * This only works with approved primes, but in FIPS mode
|
||||
- * that's the only kine of prime that will get here */
|
||||
- subPrimePtr = sftk_VerifyDH_Prime(&prime, isFIPS);
|
||||
- if (subPrimePtr == NULL) {
|
||||
- crv = CKR_GENERAL_ERROR;
|
||||
+ /* do we have a known prime ? */
|
||||
+ subPrimePtr = sftk_VerifyDH_Prime(&prime, &generator, isFIPS);
|
||||
+ if (subPrimePtr == NULL) {
|
||||
+ if (subPrime.len == 0) {
|
||||
+ /* if not a known prime, subprime must be supplied */
|
||||
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
+ goto done;
|
||||
+ } else {
|
||||
+ /* not a known prime, check for primality of prime
|
||||
+ * and subPrime */
|
||||
+ if (!KEA_PrimeCheck(&prime)) {
|
||||
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ if (!KEA_PrimeCheck(&subPrime)) {
|
||||
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ /* if we aren't using a defined group, make sure base is in the
|
||||
+ * subgroup. If it's not, then our key could fail or succeed sometimes.
|
||||
+ * This makes the failure reliable */
|
||||
+ if (!KEA_Verify(&base, &prime, (SECItem *)subPrimePtr)) {
|
||||
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
+ }
|
||||
+ }
|
||||
+ subPrimePtr = &subPrime;
|
||||
+ } else {
|
||||
+ /* we're using a known group, make sure we are using the known generator for that group */
|
||||
+ if (SECITEM_CompareItem(&generator, &base) != 0) {
|
||||
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
goto done;
|
||||
}
|
||||
+ if (subPrime.len != 0) {
|
||||
+ /* we have a known prime and a supplied subPrime,
|
||||
+ * make sure the subPrime matches the subPrime for
|
||||
+ * the known Prime */
|
||||
+ if (SECITEM_CompareItem(subPrimePtr, &subPrime) != 0) {
|
||||
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
if (!KEA_Verify(&pubKey, &prime, (SECItem *)subPrimePtr)) {
|
||||
- crv = CKR_GENERAL_ERROR;
|
||||
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
}
|
||||
done:
|
||||
+ SECITEM_ZfreeItem(&base, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&subPrime, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&prime, PR_FALSE);
|
||||
}
|
||||
/* clean up before we return */
|
||||
sftk_FreeAttribute(pubAttribute);
|
||||
- crv2 = NSC_DestroyObject(hSession, newKey);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
- if (crv2 != CKR_OK) {
|
||||
- return crv2;
|
||||
- }
|
||||
}
|
||||
|
||||
return CKR_OK;
|
||||
@@ -5925,8 +5969,8 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
|
||||
* created and linked.
|
||||
*/
|
||||
crv = sftk_handleObject(publicKey, session);
|
||||
- sftk_FreeSession(session);
|
||||
if (crv != CKR_OK) {
|
||||
+ sftk_FreeSession(session);
|
||||
sftk_FreeObject(publicKey);
|
||||
NSC_DestroyObject(hSession, privateKey->handle);
|
||||
sftk_FreeObject(privateKey);
|
||||
@@ -5968,6 +6012,7 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
|
||||
}
|
||||
|
||||
if (crv != CKR_OK) {
|
||||
+ sftk_FreeSession(session);
|
||||
NSC_DestroyObject(hSession, publicKey->handle);
|
||||
sftk_FreeObject(publicKey);
|
||||
NSC_DestroyObject(hSession, privateKey->handle);
|
||||
@@ -5977,6 +6022,8 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
|
||||
/* we need to do this check at the end to make sure the generated key meets the key length requirements */
|
||||
privateKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE_KEY_PAIR, privateKey);
|
||||
publicKey->isFIPS = privateKey->isFIPS;
|
||||
+ session->lastOpWasFIPS = privateKey->isFIPS;
|
||||
+ sftk_FreeSession(session);
|
||||
|
||||
*phPrivateKey = privateKey->handle;
|
||||
*phPublicKey = publicKey->handle;
|
||||
@@ -8610,7 +8657,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
||||
|
||||
/* if the prime is an approved prime, we can skip all the other
|
||||
* checks. */
|
||||
- subPrime = sftk_VerifyDH_Prime(&dhPrime, isFIPS);
|
||||
+ subPrime = sftk_VerifyDH_Prime(&dhPrime, NULL, isFIPS);
|
||||
if (subPrime == NULL) {
|
||||
SECItem dhSubPrime;
|
||||
/* If the caller set the subprime value, it means that
|
||||
@@ -8792,6 +8839,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
||||
secretlen = tmp.len;
|
||||
} else {
|
||||
secretlen = keySize;
|
||||
+ key->isFIPS = PR_FALSE;
|
||||
crv = sftk_ANSI_X9_63_kdf(&secret, keySize,
|
||||
&tmp, mechParams->pSharedData,
|
||||
mechParams->ulSharedDataLen, mechParams->kdf);
|
||||
diff -up ./lib/softoken/pkcs11i.h.fips-review ./lib/softoken/pkcs11i.h
|
||||
--- ./lib/softoken/pkcs11i.h.fips-review 2024-06-12 12:04:10.638360392 -0700
|
||||
+++ ./lib/softoken/pkcs11i.h 2024-06-12 12:04:10.640360416 -0700
|
||||
@@ -971,7 +971,7 @@ char **NSC_ModuleDBFunc(unsigned long fu
|
||||
/* dh verify functions */
|
||||
/* verify that dhPrime matches one of our known primes, and if so return
|
||||
* it's subprime value */
|
||||
-const SECItem *sftk_VerifyDH_Prime(SECItem *dhPrime, PRBool isFIPS);
|
||||
+const SECItem *sftk_VerifyDH_Prime(SECItem *dhPrime, SECItem *generator, PRBool isFIPS);
|
||||
/* check if dhSubPrime claims dhPrime is a safe prime. */
|
||||
SECStatus sftk_IsSafePrime(SECItem *dhPrime, SECItem *dhSubPrime, PRBool *isSafe);
|
||||
/* map an operation Attribute to a Mechanism flag */
|
||||
diff -up ./lib/softoken/pkcs11u.c.fips-review ./lib/softoken/pkcs11u.c
|
||||
--- ./lib/softoken/pkcs11u.c.fips-review 2024-06-12 12:04:10.638360392 -0700
|
||||
+++ ./lib/softoken/pkcs11u.c 2024-06-12 12:04:10.640360416 -0700
|
||||
@@ -2409,15 +2409,27 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
|
||||
switch (mechInfo->special) {
|
||||
case SFTKFIPSDH: {
|
||||
SECItem dhPrime;
|
||||
+ SECItem dhBase;
|
||||
+ SECItem dhGenerator;
|
||||
+ PRBool val = PR_FALSE;
|
||||
const SECItem *dhSubPrime;
|
||||
CK_RV crv = sftk_Attribute2SecItem(NULL, &dhPrime,
|
||||
source, CKA_PRIME);
|
||||
if (crv != CKR_OK) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
- dhSubPrime = sftk_VerifyDH_Prime(&dhPrime, PR_TRUE);
|
||||
+ crv = sftk_Attribute2SecItem(NULL, &dhBase, source, CKA_BASE);
|
||||
+ if (crv != CKR_OK) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ dhSubPrime = sftk_VerifyDH_Prime(&dhPrime, &dhGenerator, PR_TRUE);
|
||||
+ val = (dhSubPrime) ? PR_TRUE : PR_FALSE;
|
||||
+ if (val && (SECITEM_CompareItem(&dhBase, &dhGenerator) != 0)) {
|
||||
+ val = PR_FALSE;
|
||||
+ }
|
||||
SECITEM_ZfreeItem(&dhPrime, PR_FALSE);
|
||||
- return (dhSubPrime) ? PR_TRUE : PR_FALSE;
|
||||
+ SECITEM_ZfreeItem(&dhBase, PR_FALSE);
|
||||
+ return val;
|
||||
}
|
||||
case SFTKFIPSNone:
|
||||
return PR_FALSE;
|
||||
diff -up ./lib/softoken/sftkdhverify.c.fips-review ./lib/softoken/sftkdhverify.c
|
||||
--- ./lib/softoken/sftkdhverify.c.fips-review 2024-06-07 09:26:03.000000000 -0700
|
||||
+++ ./lib/softoken/sftkdhverify.c 2024-06-12 12:04:10.641360427 -0700
|
||||
@@ -6726,11 +6726,20 @@ static const SECItem subprime_tls_8192 =
|
||||
(unsigned char *)subprime_tls_8192_data,
|
||||
sizeof(subprime_tls_8192_data) };
|
||||
|
||||
+/* generator for all the groups is 2 */
|
||||
+static const unsigned char generator_2_data[] = { 2 };
|
||||
+
|
||||
+
|
||||
+static const SECItem generator_2 =
|
||||
+ { siBuffer,
|
||||
+ (unsigned char *)generator_2_data,
|
||||
+ sizeof(generator_2_data) };
|
||||
+
|
||||
/*
|
||||
* verify that dhPrime matches one of our known primes
|
||||
*/
|
||||
const SECItem *
|
||||
-sftk_VerifyDH_Prime(SECItem *dhPrime, PRBool isFIPS)
|
||||
+sftk_VerifyDH_Prime(SECItem *dhPrime, SECItem *g, PRBool isFIPS)
|
||||
{
|
||||
/* use the length to decide which primes to check */
|
||||
switch (dhPrime->len) {
|
||||
@@ -6741,56 +6750,67 @@ sftk_VerifyDH_Prime(SECItem *dhPrime, PR
|
||||
}
|
||||
if (PORT_Memcmp(dhPrime->data, prime_ike_1536,
|
||||
sizeof(prime_ike_1536)) == 0) {
|
||||
+ if (g) *g = generator_2;
|
||||
return &subprime_ike_1536;
|
||||
}
|
||||
break;
|
||||
case 2048 / PR_BITS_PER_BYTE:
|
||||
if (PORT_Memcmp(dhPrime->data, prime_tls_2048,
|
||||
sizeof(prime_tls_2048)) == 0) {
|
||||
+ if (g) *g = generator_2;
|
||||
return &subprime_tls_2048;
|
||||
}
|
||||
if (PORT_Memcmp(dhPrime->data, prime_ike_2048,
|
||||
sizeof(prime_ike_2048)) == 0) {
|
||||
+ if (g) *g = generator_2;
|
||||
return &subprime_ike_2048;
|
||||
}
|
||||
break;
|
||||
case 3072 / PR_BITS_PER_BYTE:
|
||||
if (PORT_Memcmp(dhPrime->data, prime_tls_3072,
|
||||
sizeof(prime_tls_3072)) == 0) {
|
||||
+ if (g) *g = generator_2;
|
||||
return &subprime_tls_3072;
|
||||
}
|
||||
if (PORT_Memcmp(dhPrime->data, prime_ike_3072,
|
||||
sizeof(prime_ike_3072)) == 0) {
|
||||
+ if (g) *g = generator_2;
|
||||
return &subprime_ike_3072;
|
||||
}
|
||||
break;
|
||||
case 4096 / PR_BITS_PER_BYTE:
|
||||
if (PORT_Memcmp(dhPrime->data, prime_tls_4096,
|
||||
sizeof(prime_tls_4096)) == 0) {
|
||||
+ if (g) *g = generator_2;
|
||||
return &subprime_tls_4096;
|
||||
}
|
||||
if (PORT_Memcmp(dhPrime->data, prime_ike_4096,
|
||||
sizeof(prime_ike_4096)) == 0) {
|
||||
+ if (g) *g = generator_2;
|
||||
return &subprime_ike_4096;
|
||||
}
|
||||
break;
|
||||
case 6144 / PR_BITS_PER_BYTE:
|
||||
if (PORT_Memcmp(dhPrime->data, prime_tls_6144,
|
||||
sizeof(prime_tls_6144)) == 0) {
|
||||
+ if (g) *g = generator_2;
|
||||
return &subprime_tls_6144;
|
||||
}
|
||||
if (PORT_Memcmp(dhPrime->data, prime_ike_6144,
|
||||
sizeof(prime_ike_6144)) == 0) {
|
||||
+ if (g) *g = generator_2;
|
||||
return &subprime_ike_6144;
|
||||
}
|
||||
break;
|
||||
case 8192 / PR_BITS_PER_BYTE:
|
||||
if (PORT_Memcmp(dhPrime->data, prime_tls_8192,
|
||||
sizeof(prime_tls_8192)) == 0) {
|
||||
+ if (g) *g = generator_2;
|
||||
return &subprime_tls_8192;
|
||||
}
|
||||
if (PORT_Memcmp(dhPrime->data, prime_ike_8192,
|
||||
sizeof(prime_ike_8192)) == 0) {
|
||||
+ if (g) *g = generator_2;
|
||||
return &subprime_ike_8192;
|
||||
}
|
||||
break;
|
||||
diff -up ./lib/softoken/sftkike.c.fips-review ./lib/softoken/sftkike.c
|
||||
--- ./lib/softoken/sftkike.c.fips-review 2024-06-07 09:26:03.000000000 -0700
|
||||
+++ ./lib/softoken/sftkike.c 2024-06-12 12:04:10.641360427 -0700
|
||||
@@ -516,6 +516,11 @@ sftk_ike_prf(CK_SESSION_HANDLE hSession,
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
+ /* ikev1 isn't validated, if we use this function in ikev1 mode,
|
||||
+ * mark the resulting key as not FIPS */
|
||||
+ if (!params->bRekey) {
|
||||
+ outKey->isFIPS = PR_FALSE;
|
||||
+ }
|
||||
crv = prf_init(&context, inKey->attrib.pValue,
|
||||
inKey->attrib.ulValueLen);
|
||||
if (crv != CKR_OK) {
|
||||
@ -1,12 +0,0 @@
|
||||
diff -up ./cmd/shlibsign/shlibsign.c.shlibsign ./cmd/shlibsign/shlibsign.c
|
||||
--- ./cmd/shlibsign/shlibsign.c.shlibsign 2024-06-07 09:26:03.000000000 -0700
|
||||
+++ ./cmd/shlibsign/shlibsign.c 2024-10-31 10:49:28.637449054 -0700
|
||||
@@ -1426,7 +1426,7 @@ main(int argc, char **argv)
|
||||
} else {
|
||||
/* NON FIPS mode == C_GetFunctionList */
|
||||
pC_GetFunctionList = (CK_C_GetFunctionList)
|
||||
- PR_FindFunctionSymbol(lib, "C_GetFunctionList");
|
||||
+ PR_FindFunctionSymbol(lib, "NSC_GetFunctionList");
|
||||
}
|
||||
assert(pC_GetFunctionList != NULL);
|
||||
if (!pC_GetFunctionList) {
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,71 +0,0 @@
|
||||
diff --git a/cmd/selfserv/selfserv.c b/cmd/selfserv/selfserv.c
|
||||
--- a/cmd/selfserv/selfserv.c
|
||||
+++ b/cmd/selfserv/selfserv.c
|
||||
@@ -2078,13 +2078,13 @@
|
||||
if (!input || !input->data || input->len == 0 || !output || outputLen == 0) {
|
||||
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
- *usedLen = outputLen;
|
||||
-
|
||||
- int ret = uncompress(output, (unsigned long *)usedLen, input->data, input->len);
|
||||
+ unsigned long outputLenUL = outputLen;
|
||||
+ int ret = uncompress(output, &outputLenUL, input->data, input->len);
|
||||
+ *usedLen = outputLenUL;
|
||||
if (ret != Z_OK) {
|
||||
PR_SetError(SEC_ERROR_BAD_DATA, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
@@ -2100,11 +2100,13 @@
|
||||
}
|
||||
|
||||
unsigned long maxCompressedLen = compressBound(input->len);
|
||||
SECITEM_AllocItem(NULL, output, maxCompressedLen);
|
||||
|
||||
- int ret = compress(output->data, (unsigned long *)&output->len, input->data, input->len);
|
||||
+ unsigned long outputLenUL = output->len;
|
||||
+ int ret = compress(output->data, &outputLenUL, input->data, input->len);
|
||||
+ output->len = outputLenUL;
|
||||
if (ret != Z_OK) {
|
||||
PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
diff --git a/cmd/tstclnt/tstclnt.c b/cmd/tstclnt/tstclnt.c
|
||||
--- a/cmd/tstclnt/tstclnt.c
|
||||
+++ b/cmd/tstclnt/tstclnt.c
|
||||
@@ -1375,11 +1375,13 @@
|
||||
}
|
||||
|
||||
unsigned long maxCompressedLen = compressBound(input->len);
|
||||
SECITEM_AllocItem(NULL, output, maxCompressedLen);
|
||||
|
||||
- int ret = compress(output->data, (unsigned long *)&output->len, input->data, input->len);
|
||||
+ unsigned long outputLenUL = output->len;
|
||||
+ int ret = compress(output->data, &outputLenUL, input->data, input->len);
|
||||
+ output->len = outputLenUL;
|
||||
if (ret != Z_OK) {
|
||||
PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
@@ -1394,13 +1396,13 @@
|
||||
if (!input || !input->data || input->len == 0 || !output || outputLen == 0) {
|
||||
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
- *usedLen = outputLen;
|
||||
-
|
||||
- int ret = uncompress(output, (unsigned long *)usedLen, input->data, input->len);
|
||||
+ unsigned long outputLenUL = outputLen;
|
||||
+ int ret = uncompress(output, &outputLenUL, input->data, input->len);
|
||||
+ *usedLen = outputLenUL;
|
||||
if (ret != Z_OK) {
|
||||
PR_SetError(SEC_ERROR_BAD_DATA, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
||||
@ -1,160 +0,0 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1752603323 25200
|
||||
# Tue Jul 15 11:15:23 2025 -0700
|
||||
# Branch RHEL_8
|
||||
# Node ID 66485f8ab28943977de80c0e22c800bea996e3c9
|
||||
# Parent c36fc2df3a13b0672f9a11b500e6e3ddc7115490
|
||||
nss-3.112-el8-no-p12-smime-policy.patch
|
||||
|
||||
diff --git a/lib/pkcs12/p12plcy.c b/lib/pkcs12/p12plcy.c
|
||||
--- a/lib/pkcs12/p12plcy.c
|
||||
+++ b/lib/pkcs12/p12plcy.c
|
||||
@@ -32,27 +32,31 @@ static pkcs12SuiteMap pkcs12SuiteMaps[]
|
||||
{ SEC_OID_UNKNOWN, 0, PKCS12_NULL, PR_FALSE, PR_FALSE },
|
||||
{ SEC_OID_UNKNOWN, 0, 0L, PR_FALSE, PR_FALSE }
|
||||
};
|
||||
|
||||
/* determine if algid is an algorithm which is allowed */
|
||||
static PRBool
|
||||
sec_PKCS12Allowed(SECOidTag alg, PRUint32 needed)
|
||||
{
|
||||
+#ifdef notdef
|
||||
PRUint32 policy;
|
||||
SECStatus rv;
|
||||
|
||||
rv = NSS_GetAlgorithmPolicy(alg, &policy);
|
||||
if (rv != SECSuccess) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if ((policy & needed) == needed) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
+#else
|
||||
+ return PR_TRUE;
|
||||
+#endif
|
||||
}
|
||||
|
||||
PRBool
|
||||
SEC_PKCS12CipherAllowed(SECOidTag pbeAlg, SECOidTag hmacAlg)
|
||||
{
|
||||
SECOidTag cipherAlg = SEC_PKCS5GetCryptoFromAlgTag(pbeAlg);
|
||||
SECOidTag hashAlg = SEC_PKCS5GetHashFromAlgTag(pbeAlg);
|
||||
if (cipherAlg == SEC_OID_UNKNOWN) {
|
||||
diff --git a/lib/smime/smimeutil.c b/lib/smime/smimeutil.c
|
||||
--- a/lib/smime/smimeutil.c
|
||||
+++ b/lib/smime/smimeutil.c
|
||||
@@ -197,16 +197,17 @@ smime_get_policy_tag_from_key_length(SEC
|
||||
return SEC_OID_UNKNOWN;
|
||||
}
|
||||
return algtag;
|
||||
}
|
||||
|
||||
PRBool
|
||||
smime_allowed_by_policy(SECOidTag algtag, PRUint32 neededPolicy)
|
||||
{
|
||||
+#ifdef notdef
|
||||
PRUint32 policyFlags;
|
||||
|
||||
/* some S/MIME algs map to the same underlying KEA mechanism,
|
||||
* collaps them here */
|
||||
if ((neededPolicy & (NSS_USE_ALG_IN_SMIME_KX | NSS_USE_ALG_IN_SMIME_KX_LEGACY)) != 0) {
|
||||
CK_MECHANISM_TYPE mechType = PK11_AlgtagToMechanism(algtag);
|
||||
switch (mechType) {
|
||||
case CKM_ECDH1_DERIVE:
|
||||
@@ -216,16 +217,17 @@ smime_allowed_by_policy(SECOidTag algtag
|
||||
}
|
||||
}
|
||||
|
||||
if ((NSS_GetAlgorithmPolicy(algtag, &policyFlags) == SECFailure) ||
|
||||
((policyFlags & neededPolicy) != neededPolicy)) {
|
||||
PORT_SetError(SEC_ERROR_BAD_EXPORT_ALGORITHM);
|
||||
return PR_FALSE;
|
||||
}
|
||||
+#endif
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* We'll need this for the fake policy oids for RC2, but the
|
||||
* rest of these should be moved to pk11wrap for generic
|
||||
* algtag to key size values. We already need this for
|
||||
* sec_pkcs5v2_key_length_by oid.
|
||||
@@ -480,28 +482,34 @@ smime_init_once(void *arg)
|
||||
return PR_FAILURE;
|
||||
}
|
||||
algorithm_list_lock = PZ_NewLock(nssILockCache);
|
||||
if (algorithm_list_lock == NULL) {
|
||||
*error = PORT_GetError();
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
+#ifdef notdef
|
||||
/* At initialization time, we need to set up the defaults. We first
|
||||
* look to see if the system or application has set up certain algorithms
|
||||
* by policy. If they have set up values by policy we'll only allow those
|
||||
* algorithms. We'll then look to see if any algorithms are enabled by
|
||||
* the application. */
|
||||
rv = NSS_GetAlgorithmPolicyAll(NSS_USE_ALG_IN_SMIME_LEGACY,
|
||||
NSS_USE_ALG_IN_SMIME_LEGACY,
|
||||
&tags, &tagCount);
|
||||
if (tags) {
|
||||
PORT_Free(tags);
|
||||
tags = NULL;
|
||||
}
|
||||
+#else
|
||||
+ /* just initialize the old maps */
|
||||
+ rv = SECSuccess;
|
||||
+ tagCount = 0;
|
||||
+#endif
|
||||
if ((rv != SECSuccess) || (tagCount == 0)) {
|
||||
/* No algorithms have been enabled by policy (either by the system
|
||||
* or by the application, we then will use the traditional default
|
||||
* algorithms from the policy map */
|
||||
for (i = smime_legacy_map_count - 1; i >= 0; i--) {
|
||||
SECOidTag policytag = smime_legacy_map[i].policytag;
|
||||
/* this enables the algorithm by policy. We need this or
|
||||
* the policy code will reject attempts to use it */
|
||||
diff --git a/tests/smime/smime.sh b/tests/smime/smime.sh
|
||||
--- a/tests/smime/smime.sh
|
||||
+++ b/tests/smime/smime.sh
|
||||
@@ -867,13 +867,13 @@ smime_cleanup()
|
||||
}
|
||||
|
||||
################## main #################################################
|
||||
|
||||
smime_init
|
||||
smime_main
|
||||
smime_data_tb
|
||||
smime_p7
|
||||
-if using_sql ; then
|
||||
- smime_policy
|
||||
-fi
|
||||
+#if using_sql ; then
|
||||
+# smime_policy
|
||||
+#fi
|
||||
smime_cleanup
|
||||
|
||||
diff --git a/tests/tools/tools.sh b/tests/tools/tools.sh
|
||||
--- a/tests/tools/tools.sh
|
||||
+++ b/tests/tools/tools.sh
|
||||
@@ -590,17 +590,17 @@ tools_p12()
|
||||
tools_p12_export_list_import_most_ciphers
|
||||
fi
|
||||
tools_p12_export_with_none_ciphers
|
||||
tools_p12_export_with_invalid_ciphers
|
||||
tools_p12_import_old_files
|
||||
tools_p12_import_pbmac1_samples
|
||||
if using_sql; then
|
||||
tools_p12_import_rsa_pss_private_key
|
||||
- tools_p12_policy
|
||||
+#tools_p12_policy
|
||||
fi
|
||||
}
|
||||
|
||||
############################## tools_sign ##############################
|
||||
# local shell function pk12util uses a hardcoded tmp file, if this exists
|
||||
# and is owned by another user we don't get reasonable errormessages
|
||||
########################################################################
|
||||
check_tmpfile()
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,888 +0,0 @@
|
||||
diff --git a/lib/freebl/stubs.c b/lib/freebl/stubs.c
|
||||
--- a/lib/freebl/stubs.c
|
||||
+++ b/lib/freebl/stubs.c
|
||||
@@ -485,17 +485,17 @@ PR_GetLibraryFilePathname_stub(const cha
|
||||
extern int
|
||||
PORT_GetError_stub(void)
|
||||
{
|
||||
STUB_SAFE_CALL0(PORT_GetError_Util);
|
||||
return errno;
|
||||
}
|
||||
|
||||
extern void
|
||||
-PORT_SafeZero(void *p, size_t n)
|
||||
+PORT_SafeZero_stub(void *p, size_t n)
|
||||
{
|
||||
STUB_SAFE_CALL2(PORT_SafeZero, p, n);
|
||||
/* just use a generic call in the case where we are running
|
||||
* standalone freebl */
|
||||
if (p != NULL) {
|
||||
volatile unsigned char *__vl = (unsigned char *)p;
|
||||
size_t __nl = n;
|
||||
while (__nl--)
|
||||
diff --git a/lib/freebl/stubs.h b/lib/freebl/stubs.h
|
||||
--- a/lib/freebl/stubs.h
|
||||
+++ b/lib/freebl/stubs.h
|
||||
@@ -22,17 +22,17 @@
|
||||
|
||||
#define PORT_Alloc PORT_Alloc_stub
|
||||
#define PORT_ArenaAlloc PORT_ArenaAlloc_stub
|
||||
#define PORT_ArenaZAlloc PORT_ArenaZAlloc_stub
|
||||
#define PORT_Free PORT_Free_stub
|
||||
#define PORT_FreeArena PORT_FreeArena_stub
|
||||
#define PORT_GetError PORT_GetError_stub
|
||||
#define PORT_NewArena PORT_NewArena_stub
|
||||
-#define PORT_SaveZero PORT_SaveZero_stub
|
||||
+#define PORT_SafeZero PORT_SafeZero_stub
|
||||
#define PORT_SetError PORT_SetError_stub
|
||||
#define PORT_ZAlloc PORT_ZAlloc_stub
|
||||
#define PORT_ZFree PORT_ZFree_stub
|
||||
#define PORT_ZAllocAligned PORT_ZAllocAligned_stub
|
||||
#define PORT_ZAllocAlignedOffset PORT_ZAllocAlignedOffset_stub
|
||||
|
||||
#define SECITEM_AllocItem SECITEM_AllocItem_stub
|
||||
#define SECITEM_CompareItem SECITEM_CompareItem_stub
|
||||
diff --git a/lib/freebl/unix_fips140_3.c b/lib/freebl/unix_fips140_3.c
|
||||
--- a/lib/freebl/unix_fips140_3.c
|
||||
+++ b/lib/freebl/unix_fips140_3.c
|
||||
@@ -25,17 +25,17 @@ RNG_SystemInfoForRNG(void)
|
||||
{
|
||||
PRUint8 bytes[SYSTEM_RNG_SEED_COUNT];
|
||||
size_t numBytes = RNG_SystemRNG(bytes, SYSTEM_RNG_SEED_COUNT);
|
||||
if (!numBytes) {
|
||||
/* error is set */
|
||||
return;
|
||||
}
|
||||
RNG_RandomUpdate(bytes, numBytes);
|
||||
- PORT_SaveZero(bytes, sizeof(bytes));
|
||||
+ PORT_SafeZero(bytes, sizeof(bytes));
|
||||
}
|
||||
|
||||
static unsigned int rng_grndFlags = 0;
|
||||
static PRCallOnceType rng_KernelFips;
|
||||
|
||||
static PRStatus
|
||||
rng_getKernelFips()
|
||||
{
|
||||
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
|
||||
--- a/lib/softoken/pkcs11c.c
|
||||
+++ b/lib/softoken/pkcs11c.c
|
||||
@@ -535,17 +535,17 @@ sftk_InitGeneric(SFTKSession *session, C
|
||||
context->cipherInfo = NULL;
|
||||
context->hashInfo = NULL;
|
||||
context->doPad = PR_FALSE;
|
||||
context->padDataLength = 0;
|
||||
context->key = key;
|
||||
context->blockSize = 0;
|
||||
context->maxLen = 0;
|
||||
context->isFIPS = sftk_operationIsFIPS(session->slot, pMechanism,
|
||||
- operation, key);
|
||||
+ operation, key, 0);
|
||||
*contextPtr = context;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
sftk_aes_mode(CK_MECHANISM_TYPE mechanism)
|
||||
{
|
||||
switch (mechanism) {
|
||||
@@ -4794,16 +4794,17 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* make sure we don't have any class, key_type, or value fields */
|
||||
sftk_DeleteAttributeType(key, CKA_CLASS);
|
||||
sftk_DeleteAttributeType(key, CKA_KEY_TYPE);
|
||||
sftk_DeleteAttributeType(key, CKA_VALUE);
|
||||
|
||||
+
|
||||
/* Now Set up the parameters to generate the key (based on mechanism) */
|
||||
key_gen_type = nsc_bulk; /* bulk key by default */
|
||||
switch (pMechanism->mechanism) {
|
||||
case CKM_CDMF_KEY_GEN:
|
||||
case CKM_DES_KEY_GEN:
|
||||
case CKM_DES2_KEY_GEN:
|
||||
case CKM_DES3_KEY_GEN:
|
||||
checkWeak = PR_TRUE;
|
||||
@@ -4990,16 +4991,20 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
|
||||
crv = CKR_SESSION_HANDLE_INVALID;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle the base object stuff
|
||||
*/
|
||||
crv = sftk_handleObject(key, session);
|
||||
+ /* we need to do this check at the end, so we can check the generated key length against
|
||||
+ * fips requirements */
|
||||
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE, key, 0);
|
||||
+ session->lastOpWasFIPS = key->isFIPS;
|
||||
sftk_FreeSession(session);
|
||||
if (crv == CKR_OK && sftk_isTrue(key, CKA_SENSITIVE)) {
|
||||
crv = sftk_forceAttribute(key, CKA_ALWAYS_SENSITIVE, &cktrue, sizeof(CK_BBOOL));
|
||||
}
|
||||
if (crv == CKR_OK && !sftk_isTrue(key, CKA_EXTRACTABLE)) {
|
||||
crv = sftk_forceAttribute(key, CKA_NEVER_EXTRACTABLE, &cktrue, sizeof(CK_BBOOL));
|
||||
}
|
||||
if (crv == CKR_OK) {
|
||||
@@ -6077,18 +6082,18 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
|
||||
}
|
||||
|
||||
/*
|
||||
* handle the base object cleanup for the private Key
|
||||
* If we have any problems, we destroy the public Key we've
|
||||
* created and linked.
|
||||
*/
|
||||
crv = sftk_handleObject(publicKey, session);
|
||||
- sftk_FreeSession(session);
|
||||
if (crv != CKR_OK) {
|
||||
+ sftk_FreeSession(session);
|
||||
sftk_FreeObject(publicKey);
|
||||
NSC_DestroyObject(hSession, privateKey->handle);
|
||||
sftk_FreeObject(privateKey);
|
||||
return crv;
|
||||
}
|
||||
if (sftk_isTrue(privateKey, CKA_SENSITIVE)) {
|
||||
crv = sftk_forceAttribute(privateKey, CKA_ALWAYS_SENSITIVE,
|
||||
&cktrue, sizeof(CK_BBOOL));
|
||||
@@ -6120,22 +6125,29 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
|
||||
(PRUint32)hSession, (PRUint32)pMechanism->mechanism,
|
||||
(PRUint32)crv);
|
||||
sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (crv != CKR_OK) {
|
||||
+ sftk_FreeSession(session);
|
||||
NSC_DestroyObject(hSession, publicKey->handle);
|
||||
sftk_FreeObject(publicKey);
|
||||
NSC_DestroyObject(hSession, privateKey->handle);
|
||||
sftk_FreeObject(privateKey);
|
||||
return crv;
|
||||
}
|
||||
+ /* we need to do this check at the end to make sure the generated key meets the key length requirements */
|
||||
+ privateKey->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE_KEY_PAIR, privateKey, 0);
|
||||
+ publicKey->isFIPS = privateKey->isFIPS;
|
||||
+ session->lastOpWasFIPS = privateKey->isFIPS;
|
||||
+
|
||||
+ sftk_FreeSession(session);
|
||||
*phPrivateKey = privateKey->handle;
|
||||
*phPublicKey = publicKey->handle;
|
||||
sftk_FreeObject(publicKey);
|
||||
sftk_FreeObject(privateKey);
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
@@ -7321,30 +7333,35 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
|
||||
return CKR_MECHANISM_PARAM_INVALID;
|
||||
}
|
||||
if ((params->bExpand && keySize == 0) ||
|
||||
(!params->bExpand && keySize > hashLen) ||
|
||||
(params->bExpand && keySize > 255 * hashLen)) {
|
||||
return CKR_TEMPLATE_INCONSISTENT;
|
||||
}
|
||||
|
||||
+ if (!params->bExpand) {
|
||||
+ keySize = hashLen;
|
||||
+ }
|
||||
+
|
||||
/* sourceKey is NULL if we are called from the POST, skip the
|
||||
* sensitiveCheck */
|
||||
if (sourceKey != NULL) {
|
||||
crv = sftk_DeriveSensitiveCheck(sourceKey, key, canBeData);
|
||||
if (crv != CKR_OK)
|
||||
return crv;
|
||||
}
|
||||
|
||||
/* HKDF-Extract(salt, base key value) */
|
||||
if (params->bExtract) {
|
||||
CK_BYTE *salt;
|
||||
CK_ULONG saltLen;
|
||||
HMACContext *hmac;
|
||||
unsigned int bufLen;
|
||||
+ SFTKSource saltKeySource = SFTK_SOURCE_DEFAULT;
|
||||
|
||||
switch (params->ulSaltType) {
|
||||
case CKF_HKDF_SALT_NULL:
|
||||
saltLen = hashLen;
|
||||
salt = hashbuf;
|
||||
memset(salt, 0, saltLen);
|
||||
break;
|
||||
case CKF_HKDF_SALT_DATA:
|
||||
@@ -7369,31 +7386,57 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
|
||||
/* if the base key is not fips, but the salt key is, the
|
||||
* resulting key can be fips */
|
||||
if (isFIPS && (key->isFIPS == 0) && (saltKey->isFIPS == 1)) {
|
||||
CK_MECHANISM mech;
|
||||
mech.mechanism = CKM_HKDF_DERIVE;
|
||||
mech.pParameter = params;
|
||||
mech.ulParameterLen = sizeof(*params);
|
||||
key->isFIPS = sftk_operationIsFIPS(saltKey->slot, &mech,
|
||||
- CKA_DERIVE, saltKey);
|
||||
+ CKA_DERIVE, saltKey,
|
||||
+ keySize*PR_BITS_PER_BYTE);
|
||||
}
|
||||
+ saltKeySource = saltKey->source;
|
||||
saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE);
|
||||
if (saltKey_att == NULL) {
|
||||
sftk_FreeObject(saltKey);
|
||||
return CKR_KEY_HANDLE_INVALID;
|
||||
}
|
||||
/* save the resulting salt */
|
||||
salt = saltKey_att->attrib.pValue;
|
||||
saltLen = saltKey_att->attrib.ulValueLen;
|
||||
break;
|
||||
default:
|
||||
return CKR_MECHANISM_PARAM_INVALID;
|
||||
break;
|
||||
}
|
||||
+ /* only TLS style usage is FIPS approved,
|
||||
+ * turn off the FIPS indicator for other usages */
|
||||
+ if (isFIPS && key && sourceKey) {
|
||||
+ PRBool fipsOK = PR_FALSE;
|
||||
+ /* case one: mix the kea with a previous or default
|
||||
+ * salt */
|
||||
+ if ((sourceKey->source == SFTK_SOURCE_KEA) &&
|
||||
+ (saltKeySource == SFTK_SOURCE_HKDF_EXPAND) &&
|
||||
+ (saltLen == rawHash->length)) {
|
||||
+ fipsOK = PR_TRUE;
|
||||
+ }
|
||||
+ /* case two: restart, remix the previous secret as a salt */
|
||||
+ if ((sourceKey->objclass == CKO_DATA) &&
|
||||
+ (NSS_SecureMemcmpZero(sourceKeyBytes, sourceKeyLen) == 0) &&
|
||||
+ (sourceKeyLen == rawHash->length) &&
|
||||
+ (saltKeySource == SFTK_SOURCE_HKDF_EXPAND) &&
|
||||
+ (saltLen == rawHash->length)) {
|
||||
+ fipsOK = PR_TRUE;
|
||||
+ }
|
||||
+ if (!fipsOK) {
|
||||
+ key->isFIPS = PR_FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+ if (key) key->source = SFTK_SOURCE_HKDF_EXTRACT;
|
||||
|
||||
hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS);
|
||||
if (saltKey_att) {
|
||||
sftk_FreeAttribute(saltKey_att);
|
||||
}
|
||||
if (saltKey) {
|
||||
sftk_FreeObject(saltKey);
|
||||
}
|
||||
@@ -7411,26 +7454,50 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
|
||||
/* PRK = base key value */
|
||||
prk = sourceKeyBytes;
|
||||
prkLen = sourceKeyLen;
|
||||
}
|
||||
|
||||
/* HKDF-Expand */
|
||||
if (!params->bExpand) {
|
||||
okm = prk;
|
||||
- keySize = genLen = hashLen;
|
||||
+ genLen = hashLen;
|
||||
} else {
|
||||
/* T(1) = HMAC-Hash(prk, "" | info | 0x01)
|
||||
* T(n) = HMAC-Hash(prk, T(n-1) | info | n
|
||||
* key material = T(1) | ... | T(n)
|
||||
*/
|
||||
HMACContext *hmac;
|
||||
CK_BYTE bi;
|
||||
unsigned iterations;
|
||||
|
||||
+ /* only TLS style usage is FIPS approved,
|
||||
+ * turn off the FIPS indicator for other usages */
|
||||
+ if (isFIPS && key && key->isFIPS && sourceKey) {
|
||||
+ unsigned char *info=¶ms->pInfo[3];
|
||||
+ /* only one case,
|
||||
+ * 1) Expand only
|
||||
+ * 2) with a key whose source was
|
||||
+ * SFTK_SOURCE_HKDF_EXPAND or SFTK_SOURCE_HKDF_EXTRACT
|
||||
+ * 3) source key length == rawHash->length
|
||||
+ * 4) Info has tls or dtls
|
||||
+ * If any of those conditions aren't met, then we turn
|
||||
+ * off the fips indicator */
|
||||
+ if (params->bExtract ||
|
||||
+ ((sourceKey->source != SFTK_SOURCE_HKDF_EXTRACT) &&
|
||||
+ (sourceKey->source != SFTK_SOURCE_HKDF_EXPAND)) ||
|
||||
+ (sourceKeyLen != rawHash->length) ||
|
||||
+ (params->ulInfoLen < 7) ||
|
||||
+ ((PORT_Memcmp(info,"tls",3) != 0) &&
|
||||
+ (PORT_Memcmp(info,"dtls",4) != 0))) {
|
||||
+ key->isFIPS = PR_FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+ if (key) key->source = SFTK_SOURCE_HKDF_EXPAND;
|
||||
+
|
||||
genLen = PR_ROUNDUP(keySize, hashLen);
|
||||
iterations = genLen / hashLen;
|
||||
|
||||
if (genLen > sizeof(keyBlock)) {
|
||||
keyBlockAlloc = PORT_Alloc(genLen);
|
||||
if (keyBlockAlloc == NULL) {
|
||||
return CKR_HOST_MEMORY;
|
||||
}
|
||||
@@ -7635,17 +7702,18 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
||||
/* get the value of the base key */
|
||||
att = sftk_FindAttribute(sourceKey, CKA_VALUE);
|
||||
if (att == NULL) {
|
||||
sftk_FreeObject(key);
|
||||
sftk_FreeObject(sourceKey);
|
||||
return CKR_KEY_HANDLE_INVALID;
|
||||
}
|
||||
}
|
||||
- key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DERIVE, sourceKey);
|
||||
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DERIVE, sourceKey,
|
||||
+ keySize*PR_BITS_PER_BYTE);
|
||||
|
||||
switch (mechanism) {
|
||||
/* get a public key from a private key. nsslowkey_ConvertToPublickey()
|
||||
* will generate the public portion if it doesn't already exist. */
|
||||
case CKM_NSS_PUB_FROM_PRIV: {
|
||||
NSSLOWKEYPrivateKey *privKey;
|
||||
NSSLOWKEYPublicKey *pubKey;
|
||||
int error;
|
||||
@@ -8797,16 +8865,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
||||
|
||||
/* calculate private value - oct */
|
||||
rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize);
|
||||
|
||||
SECITEM_ZfreeItem(&dhPrime, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&dhValue, PR_FALSE);
|
||||
|
||||
if (rv == SECSuccess) {
|
||||
+ key->source = SFTK_SOURCE_KEA;
|
||||
sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len);
|
||||
SECITEM_ZfreeItem(&derived, PR_FALSE);
|
||||
crv = CKR_OK;
|
||||
} else
|
||||
crv = CKR_HOST_MEMORY;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -8894,16 +8963,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
||||
* tmp is the raw data created by ECDH_Derive,
|
||||
* secret and secretlen are the values we will
|
||||
* eventually pass as our generated key.
|
||||
*/
|
||||
secret = tmp.data;
|
||||
secretlen = tmp.len;
|
||||
} else {
|
||||
secretlen = keySize;
|
||||
+ key->isFIPS = PR_FALSE;
|
||||
crv = sftk_ANSI_X9_63_kdf(&secret, keySize,
|
||||
&tmp, mechParams->pSharedData,
|
||||
mechParams->ulSharedDataLen, mechParams->kdf);
|
||||
PORT_ZFree(tmp.data, tmp.len);
|
||||
if (crv != CKR_OK) {
|
||||
break;
|
||||
}
|
||||
tmp.data = secret;
|
||||
@@ -8927,16 +8997,17 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
||||
}
|
||||
PORT_Memcpy(&keyData[keySize - secretlen], secret, secretlen);
|
||||
secret = keyData;
|
||||
} else {
|
||||
secret += (secretlen - keySize);
|
||||
}
|
||||
secretlen = keySize;
|
||||
}
|
||||
+ key->source = SFTK_SOURCE_KEA;
|
||||
|
||||
sftk_forceAttribute(key, CKA_VALUE, secret, secretlen);
|
||||
PORT_ZFree(tmp.data, tmp.len);
|
||||
if (keyData) {
|
||||
PORT_ZFree(keyData, keySize);
|
||||
}
|
||||
break;
|
||||
|
||||
diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h
|
||||
--- a/lib/softoken/pkcs11i.h
|
||||
+++ b/lib/softoken/pkcs11i.h
|
||||
@@ -147,16 +147,26 @@ typedef enum {
|
||||
*/
|
||||
typedef enum {
|
||||
SFTK_DestroyFailure,
|
||||
SFTK_Destroyed,
|
||||
SFTK_Busy
|
||||
} SFTKFreeStatus;
|
||||
|
||||
/*
|
||||
+ * Source of various objects
|
||||
+ */
|
||||
+typedef enum {
|
||||
+ SFTK_SOURCE_DEFAULT=0,
|
||||
+ SFTK_SOURCE_KEA,
|
||||
+ SFTK_SOURCE_HKDF_EXPAND,
|
||||
+ SFTK_SOURCE_HKDF_EXTRACT
|
||||
+} SFTKSource;
|
||||
+
|
||||
+/*
|
||||
* attribute values of an object.
|
||||
*/
|
||||
struct SFTKAttributeStr {
|
||||
SFTKAttribute *next;
|
||||
SFTKAttribute *prev;
|
||||
PRBool freeAttr;
|
||||
PRBool freeData;
|
||||
/*must be called handle to make sftkqueue_find work */
|
||||
@@ -189,16 +199,17 @@ struct SFTKObjectStr {
|
||||
CK_OBJECT_CLASS objclass;
|
||||
CK_OBJECT_HANDLE handle;
|
||||
int refCount;
|
||||
PZLock *refLock;
|
||||
SFTKSlot *slot;
|
||||
void *objectInfo;
|
||||
SFTKFree infoFree;
|
||||
PRBool isFIPS;
|
||||
+ SFTKSource source;
|
||||
};
|
||||
|
||||
struct SFTKTokenObjectStr {
|
||||
SFTKObject obj;
|
||||
SECItem dbKey;
|
||||
};
|
||||
|
||||
struct SFTKSessionObjectStr {
|
||||
@@ -963,15 +974,16 @@ char **NSC_ModuleDBFunc(unsigned long fu
|
||||
const SECItem *sftk_VerifyDH_Prime(SECItem *dhPrime, SECItem *generator, PRBool isFIPS);
|
||||
/* check if dhSubPrime claims dhPrime is a safe prime. */
|
||||
SECStatus sftk_IsSafePrime(SECItem *dhPrime, SECItem *dhSubPrime, PRBool *isSafe);
|
||||
/* map an operation Attribute to a Mechanism flag */
|
||||
CK_FLAGS sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE op);
|
||||
/* check the FIPS table to determine if this current operation is allowed by
|
||||
* FIPS security policy */
|
||||
PRBool sftk_operationIsFIPS(SFTKSlot *slot, CK_MECHANISM *mech,
|
||||
- CK_ATTRIBUTE_TYPE op, SFTKObject *source);
|
||||
+ CK_ATTRIBUTE_TYPE op, SFTKObject *source,
|
||||
+ CK_ULONG targetKeySize);
|
||||
/* add validation objects to the slot */
|
||||
CK_RV sftk_CreateValidationObjects(SFTKSlot *slot);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _PKCS11I_H_ */
|
||||
diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c
|
||||
--- a/lib/softoken/pkcs11u.c
|
||||
+++ b/lib/softoken/pkcs11u.c
|
||||
@@ -1098,16 +1098,17 @@ sftk_NewObject(SFTKSlot *slot)
|
||||
sessObject->attrList[i].freeData = PR_FALSE;
|
||||
}
|
||||
sessObject->optimizeSpace = slot->optimizeSpace;
|
||||
|
||||
object->handle = 0;
|
||||
object->next = object->prev = NULL;
|
||||
object->slot = slot;
|
||||
object->isFIPS = sftk_isFIPS(slot->slotID);
|
||||
+ object->source = SFTK_SOURCE_DEFAULT;
|
||||
|
||||
object->refCount = 1;
|
||||
sessObject->sessionList.next = NULL;
|
||||
sessObject->sessionList.prev = NULL;
|
||||
sessObject->sessionList.parent = object;
|
||||
sessObject->session = NULL;
|
||||
sessObject->wasDerived = PR_FALSE;
|
||||
if (!hasLocks)
|
||||
@@ -1683,16 +1684,17 @@ fail:
|
||||
CK_RV
|
||||
sftk_CopyObject(SFTKObject *destObject, SFTKObject *srcObject)
|
||||
{
|
||||
SFTKAttribute *attribute;
|
||||
SFTKSessionObject *src_so = sftk_narrowToSessionObject(srcObject);
|
||||
unsigned int i;
|
||||
|
||||
destObject->isFIPS = srcObject->isFIPS;
|
||||
+ destObject->source = srcObject->source;
|
||||
if (src_so == NULL) {
|
||||
return sftk_CopyTokenObject(destObject, srcObject);
|
||||
}
|
||||
|
||||
PZ_Lock(src_so->attributeLock);
|
||||
for (i = 0; i < src_so->hashSize; i++) {
|
||||
attribute = src_so->head[i];
|
||||
do {
|
||||
@@ -2068,16 +2070,17 @@ sftk_NewTokenObject(SFTKSlot *slot, SECI
|
||||
/* every object must have a class, if we can't get it, the object
|
||||
* doesn't exist */
|
||||
crv = handleToClass(slot, handle, &object->objclass);
|
||||
if (crv != CKR_OK) {
|
||||
goto loser;
|
||||
}
|
||||
object->slot = slot;
|
||||
object->isFIPS = sftk_isFIPS(slot->slotID);
|
||||
+ object->source = SFTK_SOURCE_DEFAULT;
|
||||
object->objectInfo = NULL;
|
||||
object->infoFree = NULL;
|
||||
if (!hasLocks) {
|
||||
object->refLock = PZ_NewLock(nssILockRefLock);
|
||||
}
|
||||
if (object->refLock == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
@@ -2234,16 +2237,25 @@ sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE
|
||||
break;
|
||||
case CKA_DERIVE:
|
||||
flags = CKF_DERIVE;
|
||||
break;
|
||||
/* fake attribute to select digesting */
|
||||
case CKA_DIGEST:
|
||||
flags = CKF_DIGEST;
|
||||
break;
|
||||
+ /* fake attribute to select key gen */
|
||||
+ case CKA_NSS_GENERATE:
|
||||
+ flags = CKF_GENERATE;
|
||||
+ break;
|
||||
+ /* fake attribute to select key pair gen */
|
||||
+ case CKA_NSS_GENERATE_KEY_PAIR:
|
||||
+ flags = CKF_GENERATE_KEY_PAIR;
|
||||
+ break;
|
||||
+ /* fake attributes to to handle MESSAGE* flags */
|
||||
case CKA_NSS_MESSAGE | CKA_ENCRYPT:
|
||||
flags = CKF_MESSAGE_ENCRYPT;
|
||||
break;
|
||||
case CKA_NSS_MESSAGE | CKA_DECRYPT:
|
||||
flags = CKF_MESSAGE_DECRYPT;
|
||||
break;
|
||||
case CKA_NSS_MESSAGE | CKA_SIGN:
|
||||
flags = CKF_MESSAGE_SIGN;
|
||||
@@ -2319,20 +2331,20 @@ sftk_quickGetECCCurveOid(SFTKObject *sou
|
||||
}
|
||||
|
||||
/* This function currently only returns valid lengths for
|
||||
* FIPS approved ECC curves. If we want to make this generic
|
||||
* in the future, that Curve determination can be done in
|
||||
* the sftk_handleSpecial. Since it's currently only used
|
||||
* in FIPS indicators, it's currently only compiled with
|
||||
* the FIPS indicator code */
|
||||
-static int
|
||||
+static CK_ULONG
|
||||
sftk_getKeyLength(SFTKObject *source)
|
||||
{
|
||||
- CK_KEY_TYPE keyType = CK_INVALID_HANDLE;
|
||||
+ CK_KEY_TYPE keyType = CKK_INVALID_KEY_TYPE;
|
||||
CK_ATTRIBUTE_TYPE keyAttribute;
|
||||
CK_ULONG keyLength = 0;
|
||||
SFTKAttribute *attribute;
|
||||
CK_RV crv;
|
||||
|
||||
/* If we don't have a key, then it doesn't have a length.
|
||||
* this may be OK (say we are hashing). The mech info will
|
||||
* sort this out because algorithms which expect no keys
|
||||
@@ -2342,17 +2354,17 @@ sftk_getKeyLength(SFTKObject *source)
|
||||
}
|
||||
|
||||
crv = sftk_GetULongAttribute(source, CKA_KEY_TYPE, &keyType);
|
||||
if (crv != CKR_OK) {
|
||||
/* sometimes we're passed a data object, in that case the
|
||||
* key length is CKA_VALUE, which is the default */
|
||||
keyType = CKK_INVALID_KEY_TYPE;
|
||||
}
|
||||
- if (keyType == CKK_EC) {
|
||||
+ if (keyType == CKK_EC || keyType == CKK_EC_EDWARDS || keyType == CKK_EC_MONTGOMERY) {
|
||||
SECOidTag curve = sftk_quickGetECCCurveOid(source);
|
||||
switch (curve) {
|
||||
case SEC_OID_CURVE25519:
|
||||
/* change when we start algorithm testing on curve25519 */
|
||||
return 0;
|
||||
case SEC_OID_SECG_EC_SECP256R1:
|
||||
return 256;
|
||||
case SEC_OID_SECG_EC_SECP384R1:
|
||||
@@ -2384,24 +2396,65 @@ sftk_getKeyLength(SFTKObject *source)
|
||||
attribute = sftk_FindAttribute(source, keyAttribute);
|
||||
if (attribute) {
|
||||
keyLength = attribute->attrib.ulValueLen * 8;
|
||||
sftk_FreeAttribute(attribute);
|
||||
}
|
||||
return keyLength;
|
||||
}
|
||||
|
||||
+PRBool
|
||||
+sftk_checkFIPSHash(CK_MECHANISM_TYPE hash, PRBool allowSmall, PRBool allowCMAC)
|
||||
+{
|
||||
+ switch (hash) {
|
||||
+ case CKM_AES_CMAC:
|
||||
+ return allowCMAC;
|
||||
+ case CKM_SHA_1:
|
||||
+ case CKM_SHA_1_HMAC:
|
||||
+ case CKM_SHA224:
|
||||
+ case CKM_SHA224_HMAC:
|
||||
+ return allowSmall;
|
||||
+ case CKM_SHA256:
|
||||
+ case CKM_SHA256_HMAC:
|
||||
+ case CKM_SHA384:
|
||||
+ case CKM_SHA384_HMAC:
|
||||
+ case CKM_SHA512:
|
||||
+ case CKM_SHA512_HMAC:
|
||||
+ return PR_TRUE;
|
||||
+ }
|
||||
+ return PR_FALSE;
|
||||
+}
|
||||
+
|
||||
+PRBool
|
||||
+sftk_checkKeyLength(CK_ULONG keyLength, CK_ULONG min,
|
||||
+ CK_ULONG max, CK_ULONG step)
|
||||
+{
|
||||
+ if (keyLength > max) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ if (keyLength < min ) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ if (((keyLength - min) % step) != 0) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ return PR_TRUE;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* handle specialized FIPS semantics that are too complicated to
|
||||
* handle with just a table. NOTE: this means any additional semantics
|
||||
* would have to be coded here before they can be added to the table */
|
||||
static PRBool
|
||||
sftk_handleSpecial(SFTKSlot *slot, CK_MECHANISM *mech,
|
||||
- SFTKFIPSAlgorithmList *mechInfo, SFTKObject *source)
|
||||
+ SFTKFIPSAlgorithmList *mechInfo, SFTKObject *source,
|
||||
+ CK_ULONG keyLength, CK_ULONG targetKeyLength)
|
||||
{
|
||||
+ PRBool allowSmall = PR_FALSE;
|
||||
+ PRBool allowCMAC = PR_FALSE;
|
||||
switch (mechInfo->special) {
|
||||
case SFTKFIPSDH: {
|
||||
SECItem dhPrime;
|
||||
SECItem dhBase;
|
||||
SECItem dhGenerator;
|
||||
PRBool fipsOk = PR_FALSE;
|
||||
const SECItem *dhSubPrime;
|
||||
CK_RV crv = sftk_Attribute2SecItem(NULL, &dhPrime,
|
||||
@@ -2451,32 +2504,97 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
|
||||
}
|
||||
/* we use the existing hash utilities to find the length of
|
||||
* the hash */
|
||||
hashObj = HASH_GetRawHashObject(sftk_GetHashTypeFromMechanism(
|
||||
pss->hashAlg));
|
||||
if (hashObj == NULL) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
+ /* cap the salt for legacy keys */
|
||||
+ if ((keyLength <= 1024) && (pss->sLen > 63)) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ /* cap the salt for based on the hash */
|
||||
if (pss->sLen > hashObj->length) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
+ /* Our code makes sure pss->hashAlg matches the explicit
|
||||
+ * hash in the mechanism, and only mechanisms with approved
|
||||
+ * hashes are included, so no need to check pss->hashAlg
|
||||
+ * here */
|
||||
+ return PR_TRUE;
|
||||
+ }
|
||||
+ case SFTKFIPSPBKDF2: {
|
||||
+ /* PBKDF2 must have the following addition restrictions
|
||||
+ * (independent of keysize).
|
||||
+ * 1. iteration count must be at least 1000.
|
||||
+ * 2. salt must be at least 128 bits (16 bytes).
|
||||
+ * 3. password must match the length specified in the SP
|
||||
+ */
|
||||
+ CK_PKCS5_PBKD2_PARAMS *pbkdf2 = (CK_PKCS5_PBKD2_PARAMS *)
|
||||
+ mech->pParameter;
|
||||
+ if (mech->ulParameterLen != sizeof(*pbkdf2)) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ if (pbkdf2->iterations < 1000) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ if (pbkdf2->ulSaltSourceDataLen < 16) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ if (*(pbkdf2->ulPasswordLen) < SFTKFIPS_PBKDF2_MIN_PW_LEN) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
return PR_TRUE;
|
||||
}
|
||||
+ /* check the hash mechanisms to make sure they themselves are FIPS */
|
||||
+ case SFTKFIPSChkHashSp800:
|
||||
+ allowCMAC = PR_TRUE;
|
||||
+ case SFTKFIPSChkHash:
|
||||
+ allowSmall = PR_TRUE;
|
||||
+ case SFTKFIPSChkHashTls:
|
||||
+ if (mech->ulParameterLen < mechInfo->offset +sizeof(CK_ULONG)) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ return sftk_checkFIPSHash(*(CK_ULONG *)(((char *)mech->pParameter)
|
||||
+ + mechInfo->offset), allowSmall, allowCMAC);
|
||||
+ case SFTKFIPSTlsKeyCheck:
|
||||
+ if (mech->mechanism != CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256) {
|
||||
+ /* unless the mechnism has a built-in hash, check the hash */
|
||||
+ if (mech->ulParameterLen < mechInfo->offset +sizeof(CK_ULONG)) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ if (!sftk_checkFIPSHash(*(CK_ULONG *)(((char *)mech->pParameter)
|
||||
+ + mechInfo->offset), PR_FALSE, PR_FALSE)) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+ return sftk_checkKeyLength(targetKeyLength, 112, 512, 1);
|
||||
+ case SFTKFIPSRSAOAEP:;
|
||||
+ CK_RSA_PKCS_OAEP_PARAMS *rsaoaep = (CK_RSA_PKCS_OAEP_PARAMS *)
|
||||
+ mech->pParameter;
|
||||
+
|
||||
+ HASH_HashType hash_msg = sftk_GetHashTypeFromMechanism(rsaoaep->hashAlg);
|
||||
+ HASH_HashType hash_pad = sftk_GetHashTypeFromMechanism(rsaoaep->mgf);
|
||||
+ /* message hash and mask generation function must be the same */
|
||||
+ if (hash_pad != hash_msg) return PR_FALSE;
|
||||
+
|
||||
+ return sftk_checkFIPSHash(rsaoaep->hashAlg, PR_FALSE, PR_FALSE);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* if we didn't understand the special processing, mark it non-fips */
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
PRBool
|
||||
sftk_operationIsFIPS(SFTKSlot *slot, CK_MECHANISM *mech, CK_ATTRIBUTE_TYPE op,
|
||||
- SFTKObject *source)
|
||||
+ SFTKObject *source, CK_ULONG targetKeyLength)
|
||||
{
|
||||
#ifndef NSS_HAS_FIPS_INDICATORS
|
||||
return PR_FALSE;
|
||||
#else
|
||||
int i;
|
||||
CK_FLAGS opFlags;
|
||||
CK_ULONG keyLength;
|
||||
|
||||
@@ -2498,23 +2616,25 @@ sftk_operationIsFIPS(SFTKSlot *slot, CK_
|
||||
}
|
||||
keyLength = sftk_getKeyLength(source);
|
||||
|
||||
/* check against our algorithm array */
|
||||
for (i = 0; i < SFTK_NUMBER_FIPS_ALGORITHMS; i++) {
|
||||
SFTKFIPSAlgorithmList *mechs = &sftk_fips_mechs[i];
|
||||
/* if we match the number of records exactly, then we are an
|
||||
* approved algorithm in the approved mode with an approved key */
|
||||
- if (((mech->mechanism == mechs->type) &&
|
||||
- (opFlags == (mechs->info.flags & opFlags)) &&
|
||||
- (keyLength <= mechs->info.ulMaxKeySize) &&
|
||||
- (keyLength >= mechs->info.ulMinKeySize) &&
|
||||
- ((keyLength - mechs->info.ulMinKeySize) % mechs->step) == 0) &&
|
||||
- ((mechs->special == SFTKFIPSNone) ||
|
||||
- sftk_handleSpecial(slot, mech, mechs, source))) {
|
||||
+ if ((mech->mechanism == mechs->type) &&
|
||||
+ (opFlags == (mechs->info.flags & opFlags)) &&
|
||||
+ sftk_checkKeyLength(keyLength, mechs->info.ulMinKeySize,
|
||||
+ mechs->info.ulMaxKeySize, mechs->step) &&
|
||||
+ ((targetKeyLength == 0) || (mechs->special == SFTKFIPSTlsKeyCheck)
|
||||
+ || sftk_checkKeyLength(targetKeyLength, mechs->info.ulMinKeySize,
|
||||
+ mechs->info.ulMaxKeySize, mechs->step)) &&
|
||||
+ ((mechs->special == SFTKFIPSNone) ||
|
||||
+ sftk_handleSpecial(slot, mech, mechs, source, keyLength, targetKeyLength))) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/lib/softoken/sftkike.c b/lib/softoken/sftkike.c
|
||||
--- a/lib/softoken/sftkike.c
|
||||
+++ b/lib/softoken/sftkike.c
|
||||
@@ -511,16 +511,22 @@ sftk_ike_prf(CK_SESSION_HANDLE hSession,
|
||||
}
|
||||
/* key as the data */
|
||||
crv = prf_update(&context, inKey->attrib.pValue,
|
||||
inKey->attrib.ulValueLen);
|
||||
if (crv != CKR_OK) {
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
+ /* ikev1 isn't validated, if we use this function in ikev1 mode,
|
||||
+ * mark the resulting key as not FIPS */
|
||||
+ if (!params->bRekey) {
|
||||
+ outKey->isFIPS = PR_FALSE;
|
||||
+ }
|
||||
+
|
||||
crv = prf_init(&context, inKey->attrib.pValue,
|
||||
inKey->attrib.ulValueLen);
|
||||
if (crv != CKR_OK) {
|
||||
goto fail;
|
||||
}
|
||||
if (newKeyValue) {
|
||||
crv = prf_update(&context, newKeyValue->attrib.pValue,
|
||||
newKeyValue->attrib.ulValueLen);
|
||||
diff --git a/lib/softoken/sftkmessage.c b/lib/softoken/sftkmessage.c
|
||||
--- a/lib/softoken/sftkmessage.c
|
||||
+++ b/lib/softoken/sftkmessage.c
|
||||
@@ -178,16 +178,48 @@ sftk_CryptMessage(CK_SESSION_HANDLE hSes
|
||||
|
||||
CHECK_FORK();
|
||||
|
||||
/* make sure we're legal */
|
||||
crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE, NULL);
|
||||
if (crv != CKR_OK)
|
||||
return crv;
|
||||
|
||||
+ if (context->isFIPS && (contextType == SFTK_MESSAGE_ENCRYPT)) {
|
||||
+ if ((pParameter == NULL) || (ulParameterLen != sizeof(CK_GCM_MESSAGE_PARAMS))) {
|
||||
+ context->isFIPS = PR_FALSE;
|
||||
+ } else {
|
||||
+ CK_GCM_MESSAGE_PARAMS *p = (CK_GCM_MESSAGE_PARAMS *)pParameter;
|
||||
+ switch (p->ivGenerator) {
|
||||
+ default:
|
||||
+ case CKG_NO_GENERATE:
|
||||
+ context->isFIPS = PR_FALSE;
|
||||
+ break;
|
||||
+ case CKG_GENERATE_RANDOM:
|
||||
+ if ((p->ulIvLen < 96/PR_BITS_PER_BYTE) ||
|
||||
+ (p->ulIvFixedBits != 0)) {
|
||||
+ context->isFIPS = PR_FALSE;
|
||||
+ }
|
||||
+ break;
|
||||
+ case CKG_GENERATE_COUNTER_XOR:
|
||||
+ if ((p->ulIvLen != 96/PR_BITS_PER_BYTE) ||
|
||||
+ (p->ulIvFixedBits != 32)) {
|
||||
+ context->isFIPS = PR_FALSE;
|
||||
+ }
|
||||
+ break;
|
||||
+ case CKG_GENERATE_COUNTER:
|
||||
+ if ((p->ulIvFixedBits < 32) ||
|
||||
+ ((p->ulIvLen*PR_BITS_PER_BYTE - p->ulIvFixedBits) < 32)) {
|
||||
+ context->isFIPS = PR_FALSE;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (!pOuttext) {
|
||||
*pulOuttextLen = ulIntextLen;
|
||||
return CKR_OK;
|
||||
}
|
||||
rv = (*context->aeadUpdate)(context->cipherInfo, pOuttext, &outlen,
|
||||
maxout, pIntext, ulIntextLen,
|
||||
pParameter, ulParameterLen,
|
||||
pAssociatedData, ulAssociatedDataLen);
|
||||
diff --git a/lib/util/pkcs11n.h b/lib/util/pkcs11n.h
|
||||
--- a/lib/util/pkcs11n.h
|
||||
+++ b/lib/util/pkcs11n.h
|
||||
@@ -148,16 +148,18 @@
|
||||
/*
|
||||
* NSS-defined certificate types
|
||||
*
|
||||
*/
|
||||
#define CKC_NSS (CKC_VENDOR_DEFINED | NSSCK_VENDOR_NSS)
|
||||
|
||||
/* FAKE PKCS #11 defines */
|
||||
#define CKA_DIGEST 0x81000000L
|
||||
+#define CKA_NSS_GENERATE 0x81000001L
|
||||
+#define CKA_NSS_GENERATE_KEY_PAIR 0x81000002L
|
||||
#define CKA_NSS_MESSAGE 0x82000000L
|
||||
#define CKA_NSS_MESSAGE_MASK 0xff000000L
|
||||
#define CKA_FLAGS_ONLY 0 /* CKA_CLASS */
|
||||
|
||||
/*
|
||||
* NSS-defined object attributes
|
||||
*
|
||||
*/
|
||||
@ -1,44 +0,0 @@
|
||||
diff --git a/lib/softoken/fipstokn.c b/lib/softoken/fipstokn.c
|
||||
--- a/lib/softoken/fipstokn.c
|
||||
+++ b/lib/softoken/fipstokn.c
|
||||
@@ -244,17 +244,17 @@ fc_getAttribute(CK_ATTRIBUTE_PTR pTempla
|
||||
|
||||
#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F, name)
|
||||
#define CK_NEED_ARG_LIST 1
|
||||
|
||||
#include "pkcs11f.h"
|
||||
|
||||
/* ------------- build the CK_CRYPTO_TABLE ------------------------- */
|
||||
static CK_FUNCTION_LIST_3_0 sftk_fipsTable = {
|
||||
- { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
|
||||
+ { 3, 0 },
|
||||
|
||||
#undef CK_NEED_ARG_LIST
|
||||
#undef CK_PKCS11_FUNCTION_INFO
|
||||
|
||||
#define CK_PKCS11_FUNCTION_INFO(name) \
|
||||
__PASTE(F, name) \
|
||||
,
|
||||
|
||||
diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c
|
||||
--- a/lib/softoken/pkcs11.c
|
||||
+++ b/lib/softoken/pkcs11.c
|
||||
@@ -107,17 +107,17 @@ static PRIntervalTime loginWaitTime;
|
||||
#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F, name)
|
||||
#define CK_NEED_ARG_LIST 1
|
||||
|
||||
#include "pkcs11f.h"
|
||||
#endif
|
||||
|
||||
/* build the crypto module table */
|
||||
static CK_FUNCTION_LIST_3_0 sftk_funcList = {
|
||||
- { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
|
||||
+ { 3, 0 },
|
||||
|
||||
#undef CK_PKCS11_FUNCTION_INFO
|
||||
#undef CK_NEED_ARG_LIST
|
||||
|
||||
#define CK_PKCS11_FUNCTION_INFO(func) \
|
||||
__PASTE(NS, func) \
|
||||
,
|
||||
#include "pkcs11f.h"
|
||||
@ -1,704 +0,0 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1761684967 25200
|
||||
# Tue Oct 28 13:56:07 2025 -0700
|
||||
# Branch RHEL10
|
||||
# Node ID 41c115659ed4c65119d97e4be6bdc3030c9a4586
|
||||
# Parent a2ec761c754f728b669dc32ea94e260362b43b5b
|
||||
nss-3.112-mlkem-fips-update.patch
|
||||
|
||||
diff --git a/lib/freebl/fipsfreebl.c b/lib/freebl/fipsfreebl.c
|
||||
--- a/lib/freebl/fipsfreebl.c
|
||||
+++ b/lib/freebl/fipsfreebl.c
|
||||
@@ -1797,29 +1797,34 @@ loser:
|
||||
|
||||
static SECStatus
|
||||
freebl_ML_KEM_Test(KyberParams param_set,
|
||||
const unsigned char *seed, size_t seed_len,
|
||||
const unsigned char *enc_seed, size_t enc_seed_len,
|
||||
const unsigned char *pub_key, size_t pub_key_len,
|
||||
const unsigned char *priv_key, size_t priv_key_len,
|
||||
const unsigned char *cipher_text, size_t cipher_text_len,
|
||||
- const unsigned char *key, size_t key_len)
|
||||
+ const unsigned char *key, size_t key_len,
|
||||
+ const unsigned char *rej_key, size_t rej_key_len)
|
||||
{
|
||||
SECStatus rv;
|
||||
unsigned char cipher_text_buf[MAX_ML_KEM_CIPHER_LENGTH];
|
||||
+ unsigned char zero_text_buf[MAX_ML_KEM_CIPHER_LENGTH] = { 0 };
|
||||
unsigned char priv_key_buf[MAX_ML_KEM_PRIVATE_KEY_LENGTH];
|
||||
unsigned char pub_key_buf[MAX_ML_KEM_PUBLIC_KEY_LENGTH];
|
||||
unsigned char key_buf[KYBER_SHARED_SECRET_BYTES];
|
||||
unsigned char key2_buf[KYBER_SHARED_SECRET_BYTES];
|
||||
+ unsigned char key3_buf[KYBER_SHARED_SECRET_BYTES];
|
||||
SECItem ct_item = { siBuffer, cipher_text_buf, cipher_text_len };
|
||||
+ SECItem zt_item = { siBuffer, zero_text_buf, cipher_text_len };
|
||||
SECItem priv_key_item = { siBuffer, priv_key_buf, priv_key_len };
|
||||
SECItem pub_key_item = { siBuffer, pub_key_buf, pub_key_len };
|
||||
SECItem key_item = { siBuffer, key_buf, sizeof(key_buf) };
|
||||
SECItem key2_item = { siBuffer, key2_buf, sizeof(key2_buf) };
|
||||
+ SECItem key3_item = { siBuffer, key3_buf, sizeof(key3_buf) };
|
||||
SECItem seed_item = { siBuffer, (unsigned char *)seed, seed_len };
|
||||
SECItem eseed_item = { siBuffer, (unsigned char *)enc_seed, enc_seed_len };
|
||||
|
||||
PORT_Assert(pub_key_len <= sizeof(pub_key_buf));
|
||||
PORT_Assert(priv_key_len <= sizeof(priv_key_buf));
|
||||
PORT_Assert(cipher_text_len <= sizeof(cipher_text_buf));
|
||||
|
||||
rv = Kyber_NewKey(param_set, &seed_item, &priv_key_item, &pub_key_item);
|
||||
@@ -1828,43 +1833,53 @@ freebl_ML_KEM_Test(KyberParams param_set
|
||||
return rv;
|
||||
}
|
||||
|
||||
if ((priv_key_item.len != priv_key_len) ||
|
||||
(pub_key_item.len != pub_key_len) ||
|
||||
(PORT_Memcmp(priv_key_item.data, priv_key, priv_key_len) != 0) ||
|
||||
(PORT_Memcmp(pub_key_item.data, pub_key, pub_key_len) != 0)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
- return rv;
|
||||
+ return SECFailure;
|
||||
}
|
||||
|
||||
rv = Kyber_Encapsulate(param_set, &eseed_item, &pub_key_item,
|
||||
&ct_item, &key_item);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
if ((ct_item.len != cipher_text_len) ||
|
||||
(key_item.len != key_len) ||
|
||||
(PORT_Memcmp(ct_item.data, cipher_text, cipher_text_len) != 0) ||
|
||||
(PORT_Memcmp(key_item.data, key, key_len) != 0)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
- return rv;
|
||||
+ return SECFailure;
|
||||
}
|
||||
|
||||
rv = Kyber_Decapsulate(param_set, &priv_key_item, &ct_item, &key2_item);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return rv;
|
||||
}
|
||||
if (SECITEM_CompareItem(&key2_item, &key_item) != 0) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
+ return SECFailure;
|
||||
+ }
|
||||
+ rv = Kyber_Decapsulate(param_set, &priv_key_item, &zt_item, &key3_item);
|
||||
+ if (rv != SECSuccess) {
|
||||
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return rv;
|
||||
}
|
||||
+ if ((key3_item.len != rej_key_len) ||
|
||||
+ (PORT_Memcmp(key3_item.data, rej_key, rej_key_len) != 0)) {
|
||||
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
+ return SECFailure;
|
||||
+ }
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
freebl_fips_ML_KEM_PowerUpSelfTest()
|
||||
{
|
||||
SECStatus rv;
|
||||
|
||||
@@ -1881,27 +1896,29 @@ freebl_fips_ML_KEM_PowerUpSelfTest()
|
||||
PORT_Assert(sizeof (ml_kem1024_key) == KYBER_SHARED_SECRET_BYTES);
|
||||
|
||||
rv = freebl_ML_KEM_Test(params_ml_kem768_test_mode,
|
||||
ml_kem_key_seed, KYBER_KEYPAIR_COIN_BYTES,
|
||||
ml_kem_enc_seed, KYBER_SHARED_SECRET_BYTES,
|
||||
ml_kem768_pub_key, KYBER768_PUBLIC_KEY_BYTES,
|
||||
ml_kem768_priv_key, KYBER768_PRIVATE_KEY_BYTES,
|
||||
ml_kem768_cipher_text, KYBER768_CIPHERTEXT_BYTES,
|
||||
- ml_kem768_key, KYBER_SHARED_SECRET_BYTES);
|
||||
+ ml_kem768_key, KYBER_SHARED_SECRET_BYTES,
|
||||
+ ml_kem768_rej_key, KYBER_SHARED_SECRET_BYTES);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
rv = freebl_ML_KEM_Test(params_ml_kem1024_test_mode,
|
||||
ml_kem_key_seed, KYBER_KEYPAIR_COIN_BYTES,
|
||||
ml_kem_enc_seed, KYBER_SHARED_SECRET_BYTES,
|
||||
ml_kem1024_pub_key, MLKEM1024_PUBLIC_KEY_BYTES,
|
||||
ml_kem1024_priv_key, MLKEM1024_PRIVATE_KEY_BYTES,
|
||||
ml_kem1024_cipher_text, MLKEM1024_CIPHERTEXT_BYTES,
|
||||
- ml_kem1024_key, KYBER_SHARED_SECRET_BYTES);
|
||||
+ ml_kem1024_key, KYBER_SHARED_SECRET_BYTES,
|
||||
+ ml_kem1024_rej_key, KYBER_SHARED_SECRET_BYTES);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
#ifdef NSS_ENABLE_ML_DSA
|
||||
diff --git a/lib/freebl/kyber.c b/lib/freebl/kyber.c
|
||||
--- a/lib/freebl/kyber.c
|
||||
+++ b/lib/freebl/kyber.c
|
||||
@@ -4,16 +4,17 @@
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "blapi.h"
|
||||
+#include "blapii.h"
|
||||
#include "secerr.h"
|
||||
#include "secitem.h"
|
||||
|
||||
#include "kyber-pqcrystals-ref.h"
|
||||
#include "kyber.h"
|
||||
#include "verified/internal/libcrux_core.h"
|
||||
#include "verified/libcrux_mlkem768_portable.h"
|
||||
#include "verified/libcrux_mlkem768.h"
|
||||
@@ -198,29 +199,39 @@ Kyber_NewKey(KyberParams params, const S
|
||||
}
|
||||
coins = randbuf;
|
||||
}
|
||||
NSS_CLASSIFY(coins, KYBER_KEYPAIR_COIN_BYTES);
|
||||
if (params == params_ml_kem768 || params == params_ml_kem768_test_mode) {
|
||||
libcrux_ml_kem_mlkem768_MlKem768KeyPair keys = libcrux_ml_kem_mlkem768_portable_generate_key_pair(coins);
|
||||
memcpy(pubkey->data, keys.pk.value, KYBER768_PUBLIC_KEY_BYTES);
|
||||
memcpy(privkey->data, keys.sk.value, KYBER768_PRIVATE_KEY_BYTES);
|
||||
+ PORT_SafeZero(&keys, sizeof(keys));
|
||||
} else if (params == params_ml_kem1024 || params == params_ml_kem1024_test_mode) {
|
||||
libcrux_ml_kem_mlkem1024_MlKem1024KeyPair keys = libcrux_ml_kem_mlkem1024_portable_generate_key_pair(coins);
|
||||
memcpy(pubkey->data, keys.pk.value, MLKEM1024_PUBLIC_KEY_BYTES);
|
||||
memcpy(privkey->data, keys.sk.value, MLKEM1024_PRIVATE_KEY_BYTES);
|
||||
+ PORT_SafeZero(&keys, sizeof(keys));
|
||||
#ifndef NSS_DISABLE_KYBER
|
||||
} else if (params == params_kyber768_round3 || params == params_kyber768_round3_test_mode) {
|
||||
pqcrystals_kyber768_ref_keypair_derand(pubkey->data, privkey->data, coins);
|
||||
#endif
|
||||
} else {
|
||||
/* unreachable */
|
||||
+ if (coins == randbuf) {
|
||||
+ PORT_SafeZero(randbuf, sizeof(randbuf));
|
||||
+ }
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
+ /* manual max stack count 68000 */
|
||||
+ BLAPI_CLEAR_STACK(70000);
|
||||
+ if (coins == randbuf) {
|
||||
+ PORT_SafeZero(randbuf, sizeof(randbuf));
|
||||
+ }
|
||||
NSS_DECLASSIFY(pubkey->data, pubkey->len);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
Kyber_Encapsulate(KyberParams params, const SECItem *enc_seed, const SECItem *pubkey, SECItem *ciphertext, SECItem *secret)
|
||||
{
|
||||
if (!valid_params(params)) {
|
||||
@@ -239,103 +250,133 @@ Kyber_Encapsulate(KyberParams params, co
|
||||
coins = enc_seed->data;
|
||||
} else {
|
||||
if (RNG_GenerateGlobalRandomBytes(randbuf, sizeof randbuf) != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_NEED_RANDOM);
|
||||
return SECFailure;
|
||||
}
|
||||
coins = randbuf;
|
||||
}
|
||||
+ SECStatus rv = SECSuccess;
|
||||
NSS_CLASSIFY(coins, KYBER_ENC_COIN_BYTES);
|
||||
if (params == params_ml_kem768 || params == params_ml_kem768_test_mode) {
|
||||
/* shouldn't this just use the typedef im libcrux_mlkem768.h? */
|
||||
libcrux_ml_kem_types_MlKemPublicKey_15 pk_value;
|
||||
memcpy(pk_value.value, pubkey->data, KYBER768_PUBLIC_KEY_BYTES);
|
||||
|
||||
bool valid_pk = libcrux_ml_kem_mlkem768_portable_validate_public_key(&pk_value);
|
||||
if (!valid_pk) {
|
||||
+ PORT_SafeZero(&pk_value, sizeof(pk_value));
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
- return SECFailure;
|
||||
+ rv = SECFailure;
|
||||
+ goto loser;
|
||||
}
|
||||
|
||||
tuple_3c encap = libcrux_ml_kem_mlkem768_portable_encapsulate(&pk_value, coins);
|
||||
memcpy(ciphertext->data, encap.fst.value, KYBER768_CIPHERTEXT_BYTES);
|
||||
memcpy(secret->data, encap.snd, KYBER_SHARED_SECRET_BYTES);
|
||||
+ PORT_SafeZero(&pk_value, sizeof(pk_value));
|
||||
+ PORT_SafeZero(&encap, sizeof(encap));
|
||||
} else if (params == params_ml_kem1024 || params == params_ml_kem1024_test_mode) {
|
||||
/* shouldn't this just use the typedef im libcrux_mlkem1024.h? */
|
||||
libcrux_ml_kem_types_MlKemPublicKey_1f pk_value;
|
||||
memcpy(pk_value.value, pubkey->data, MLKEM1024_PUBLIC_KEY_BYTES);
|
||||
|
||||
bool valid_pk = libcrux_ml_kem_mlkem1024_portable_validate_public_key(&pk_value);
|
||||
if (!valid_pk) {
|
||||
+ PORT_SafeZero(&pk_value, sizeof(pk_value));
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
- return SECFailure;
|
||||
+ rv = SECFailure;
|
||||
+ goto loser;
|
||||
}
|
||||
|
||||
tuple_21 encap = libcrux_ml_kem_mlkem1024_portable_encapsulate(&pk_value, coins);
|
||||
memcpy(ciphertext->data, encap.fst.value, MLKEM1024_CIPHERTEXT_BYTES);
|
||||
memcpy(secret->data, encap.snd, KYBER_SHARED_SECRET_BYTES);
|
||||
+ PORT_SafeZero(&pk_value, sizeof(pk_value));
|
||||
+ PORT_SafeZero(&encap, sizeof(encap));
|
||||
#ifndef NSS_DISABLE_KYBER
|
||||
} else if (params == params_kyber768_round3 || params == params_kyber768_round3_test_mode) {
|
||||
pqcrystals_kyber768_ref_enc_derand(ciphertext->data, secret->data, pubkey->data, coins);
|
||||
#endif
|
||||
} else {
|
||||
/* unreachable */
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
- return SECFailure;
|
||||
+ rv = SECFailure;
|
||||
+ goto loser;
|
||||
}
|
||||
+loser:
|
||||
+ if (coins == randbuf) {
|
||||
+ PORT_SafeZero(randbuf, sizeof(randbuf));
|
||||
+ }
|
||||
+ /* manual max stack count 6700 */
|
||||
+ BLAPI_CLEAR_STACK(10000);
|
||||
|
||||
- return SECSuccess;
|
||||
+ return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
Kyber_Decapsulate(KyberParams params, const SECItem *privkey, const SECItem *ciphertext, SECItem *secret)
|
||||
{
|
||||
if (!valid_params(params)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (!(valid_privkey(params, privkey) && valid_ciphertext(params, ciphertext) && valid_secret(params, secret))) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
+ SECStatus rv = SECSuccess;
|
||||
if (params == params_ml_kem768 || params == params_ml_kem768_test_mode) {
|
||||
libcrux_ml_kem_types_MlKemPrivateKey_55 private_key;
|
||||
memcpy(private_key.value, privkey->data, KYBER768_PRIVATE_KEY_BYTES);
|
||||
|
||||
libcrux_ml_kem_mlkem768_MlKem768Ciphertext cipher_text;
|
||||
memcpy(cipher_text.value, ciphertext->data, KYBER768_CIPHERTEXT_BYTES);
|
||||
|
||||
bool valid = libcrux_ml_kem_mlkem768_portable_validate_private_key(&private_key, &cipher_text);
|
||||
if (!valid) {
|
||||
+ PORT_SafeZero(&private_key, sizeof(private_key));
|
||||
+ PORT_SafeZero(&cipher_text, sizeof(cipher_text));
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
- return SECFailure;
|
||||
+ rv = SECFailure;
|
||||
+ goto loser;
|
||||
}
|
||||
|
||||
libcrux_ml_kem_mlkem768_portable_decapsulate(&private_key, &cipher_text, secret->data);
|
||||
+ PORT_SafeZero(&private_key, sizeof(private_key));
|
||||
+ PORT_SafeZero(&cipher_text, sizeof(cipher_text));
|
||||
} else if (params == params_ml_kem1024 || params == params_ml_kem1024_test_mode) {
|
||||
libcrux_ml_kem_types_MlKemPrivateKey_95 private_key;
|
||||
memcpy(private_key.value, privkey->data, MLKEM1024_PRIVATE_KEY_BYTES);
|
||||
|
||||
libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext cipher_text;
|
||||
memcpy(cipher_text.value, ciphertext->data, MLKEM1024_CIPHERTEXT_BYTES);
|
||||
|
||||
bool valid = libcrux_ml_kem_mlkem1024_portable_validate_private_key(&private_key, &cipher_text);
|
||||
if (!valid) {
|
||||
+ PORT_SafeZero(&private_key, sizeof(private_key));
|
||||
+ PORT_SafeZero(&cipher_text, sizeof(cipher_text));
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
- return SECFailure;
|
||||
+ rv = SECFailure;
|
||||
+ goto loser;
|
||||
}
|
||||
|
||||
libcrux_ml_kem_mlkem1024_portable_decapsulate(&private_key, &cipher_text, secret->data);
|
||||
+ PORT_SafeZero(&private_key, sizeof(private_key));
|
||||
+ PORT_SafeZero(&cipher_text, sizeof(cipher_text));
|
||||
#ifndef NSS_DISABLE_KYBER
|
||||
} else if (params == params_kyber768_round3 || params == params_kyber768_round3_test_mode) {
|
||||
pqcrystals_kyber768_ref_dec(secret->data, ciphertext->data, privkey->data);
|
||||
#endif
|
||||
} else {
|
||||
// unreachable
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
+loser:
|
||||
+ /* manual max stack count 8200 */
|
||||
+ BLAPI_CLEAR_STACK(10000);
|
||||
|
||||
- return SECSuccess;
|
||||
+ return rv;
|
||||
}
|
||||
diff --git a/lib/freebl/ml_kem_fips_vectors.h b/lib/freebl/ml_kem_fips_vectors.h
|
||||
--- a/lib/freebl/ml_kem_fips_vectors.h
|
||||
+++ b/lib/freebl/ml_kem_fips_vectors.h
|
||||
@@ -415,16 +415,21 @@
|
||||
0xd6, 0x18, 0xf6, 0x5a, 0x70, 0x0b, 0x41, 0xf0, 0x17, 0x08, 0x67, 0x98,
|
||||
0x2f, 0x5a, 0x68, 0xc7, 0x5c, 0x65, 0x15, 0x0e,
|
||||
};
|
||||
static const unsigned char ml_kem768_key[] = {
|
||||
0x42, 0xf5, 0x58, 0xb0, 0xbc, 0x5d, 0x70, 0x0a, 0x91, 0x1b, 0x0f, 0xc6,
|
||||
0x7f, 0x62, 0x37, 0x6f, 0x7a, 0xee, 0x46, 0x67, 0xf1, 0x96, 0x9e, 0x03,
|
||||
0xf1, 0x8b, 0xdf, 0xdf, 0x3c, 0x59, 0xfb, 0xdc,
|
||||
};
|
||||
+ static const unsigned char ml_kem768_rej_key[] = {
|
||||
+ 0x6b, 0x24, 0x6e, 0xb1, 0x8b, 0x55, 0x3a, 0xb4, 0xcc, 0x4a, 0x57, 0x04,
|
||||
+ 0x4d, 0x8d, 0x15, 0x34, 0xa8, 0x85, 0xd1, 0xd3, 0x42, 0x14, 0xc9, 0x87,
|
||||
+ 0x78, 0x96, 0x19, 0xcb, 0x73, 0xe6, 0x12, 0x9a,
|
||||
+ };
|
||||
static const unsigned char ml_kem1024_pub_key[] = {
|
||||
0x4b, 0x94, 0xc2, 0x94, 0x50, 0x11, 0x11, 0x91, 0x82, 0x3b, 0x35, 0x14,
|
||||
0xc9, 0xac, 0x1e, 0xa3, 0xd9, 0x82, 0x5c, 0xcb, 0x86, 0x39, 0x3a, 0x2d,
|
||||
0xfb, 0x04, 0x65, 0x4f, 0xa2, 0x19, 0x2d, 0x37, 0xbf, 0xad, 0x1c, 0x49,
|
||||
0x7c, 0x65, 0x02, 0xee, 0xe5, 0xca, 0x80, 0xa7, 0x3b, 0xfc, 0xe0, 0xba,
|
||||
0xf5, 0xa5, 0x4a, 0x88, 0x58, 0x5a, 0x40, 0x13, 0x97, 0xa3, 0xd2, 0x32,
|
||||
0xf4, 0x26, 0xa7, 0xaf, 0xb0, 0x82, 0xbc, 0x21, 0xa4, 0x43, 0x17, 0x09,
|
||||
0x0e, 0xaa, 0xc7, 0x59, 0x2c, 0x2e, 0xa8, 0x8a, 0x65, 0x3c, 0x44, 0x91,
|
||||
@@ -952,8 +957,13 @@
|
||||
0x3b, 0xaf, 0x03, 0xad, 0xf1, 0xab, 0x8f, 0x86, 0xea, 0x46, 0x28, 0xf8,
|
||||
0x53, 0x80, 0xee, 0x89, 0x53, 0xd4, 0xa1, 0xad,
|
||||
};
|
||||
static const unsigned char ml_kem1024_key[] = {
|
||||
0x73, 0x8a, 0x88, 0xcd, 0x9a, 0x25, 0x86, 0x1e, 0x9a, 0x37, 0xc6, 0x5a,
|
||||
0x67, 0xec, 0x1b, 0x39, 0xf0, 0x69, 0xae, 0xd9, 0x64, 0x6e, 0xde, 0x89,
|
||||
0x41, 0x0a, 0xce, 0x47, 0xa9, 0x6a, 0x9b, 0x57,
|
||||
};
|
||||
+ static const unsigned char ml_kem1024_rej_key[] = {
|
||||
+ 0x6a, 0x58, 0xe1, 0xc5, 0x96, 0x86, 0xc9, 0xfc, 0x32, 0x2e, 0xc2, 0x6b,
|
||||
+ 0x6e, 0xa0, 0xd5, 0x27, 0x22, 0x67, 0x29, 0x2c, 0xe9, 0xa4, 0x0f, 0x12,
|
||||
+ 0x75, 0x13, 0x96, 0xbc, 0x53, 0x22, 0x72, 0x46,
|
||||
+ };
|
||||
diff --git a/lib/softoken/kem.c b/lib/softoken/kem.c
|
||||
--- a/lib/softoken/kem.c
|
||||
+++ b/lib/softoken/kem.c
|
||||
@@ -198,16 +198,18 @@ NSC_EncapsulateKey(CK_SESSION_HANDLE hSe
|
||||
SFTKAttribute *encapsulationKey = NULL;
|
||||
|
||||
CK_RV crv;
|
||||
SFTKFreeStatus status;
|
||||
CK_ULONG paramSet = 0; /* use a generic U_LONG so we can handle
|
||||
* different param set types based on the
|
||||
* Mechanism value */
|
||||
KyberParams kyberParams;
|
||||
+ CK_OBJECT_CLASS ckclass = CKO_SECRET_KEY;
|
||||
+ CK_KEY_TYPE ckkeyType = CKK_GENERIC_SECRET;
|
||||
|
||||
CHECK_FORK();
|
||||
|
||||
if (!pMechanism || !phKey || !pulCiphertextLen) {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
if (!sftk_kem_ValidateMechanism(pMechanism)) {
|
||||
@@ -232,16 +234,25 @@ NSC_EncapsulateKey(CK_SESSION_HANDLE hSe
|
||||
}
|
||||
for (unsigned long int i = 0; i < ulAttributeCount; i++) {
|
||||
crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i]));
|
||||
if (crv != CKR_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
+ crv = sftk_defaultAttribute(key, CKA_CLASS, &ckclass, sizeof(ckclass));
|
||||
+ if (crv != CKR_OK) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ crv = sftk_defaultAttribute(key, CKA_KEY_TYPE, &ckkeyType, sizeof(ckkeyType));
|
||||
+ if (crv != CKR_OK) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
encapsulationKeyObject = sftk_ObjectFromHandle(hPublicKey, session);
|
||||
if (encapsulationKeyObject == NULL) {
|
||||
crv = CKR_KEY_HANDLE_INVALID;
|
||||
goto cleanup;
|
||||
}
|
||||
encapsulationKey = sftk_FindAttribute(encapsulationKeyObject, CKA_VALUE);
|
||||
if (encapsulationKey == NULL) {
|
||||
crv = CKR_KEY_HANDLE_INVALID;
|
||||
@@ -264,17 +275,17 @@ NSC_EncapsulateKey(CK_SESSION_HANDLE hSe
|
||||
SECItem pubKey = { siBuffer, encapsulationKey->attrib.pValue, encapsulationKey->attrib.ulValueLen };
|
||||
|
||||
/* The length of secretBuf can be increased if we ever support other KEMs
|
||||
* by changing the define at the top of this file */
|
||||
uint8_t secretBuf[MAX_KEM_SHARED_SECRET_BYTES] = { 0 };
|
||||
SECItem secret = { siBuffer, secretBuf, sizeof secretBuf };
|
||||
|
||||
key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_ENCAPSULATE,
|
||||
- key, 0);
|
||||
+ encapsulationKeyObject, 0);
|
||||
key->source = SFTK_SOURCE_KEA;
|
||||
switch (pMechanism->mechanism) {
|
||||
#ifndef NSS_DISABLE_KYBER
|
||||
case CKM_NSS_KYBER:
|
||||
#endif
|
||||
case CKM_NSS_ML_KEM:
|
||||
case CKM_ML_KEM:
|
||||
PORT_Assert(secret.len >= KYBER_SHARED_SECRET_BYTES);
|
||||
@@ -347,16 +358,18 @@ NSC_DecapsulateKey(CK_SESSION_HANDLE hSe
|
||||
SFTKAttribute *decapsulationKey = NULL;
|
||||
CK_ULONG paramSet = 0; /* use a generic U_LONG so we can handle
|
||||
* different param set types based on the
|
||||
* Mechanism value */
|
||||
|
||||
CK_RV crv;
|
||||
SFTKFreeStatus status;
|
||||
KyberParams kyberParams;
|
||||
+ CK_OBJECT_CLASS ckclass = CKO_SECRET_KEY;
|
||||
+ CK_KEY_TYPE ckkeyType = CKK_GENERIC_SECRET;
|
||||
|
||||
CHECK_FORK();
|
||||
|
||||
if (!pMechanism || !pCiphertext || !pTemplate || !phKey) {
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
if (!sftk_kem_ValidateMechanism(pMechanism)) {
|
||||
@@ -381,16 +394,25 @@ NSC_DecapsulateKey(CK_SESSION_HANDLE hSe
|
||||
}
|
||||
for (unsigned long int i = 0; i < ulAttributeCount; i++) {
|
||||
crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i]));
|
||||
if (crv != CKR_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
+ crv = sftk_defaultAttribute(key, CKA_CLASS, &ckclass, sizeof(ckclass));
|
||||
+ if (crv != CKR_OK) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ crv = sftk_defaultAttribute(key, CKA_KEY_TYPE, &ckkeyType, sizeof(ckkeyType));
|
||||
+ if (crv != CKR_OK) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
decapsulationKeyObject = sftk_ObjectFromHandle(hPrivateKey, session);
|
||||
if (decapsulationKeyObject == NULL) {
|
||||
crv = CKR_KEY_HANDLE_INVALID;
|
||||
goto cleanup;
|
||||
}
|
||||
decapsulationKey = sftk_FindAttribute(decapsulationKeyObject, CKA_VALUE);
|
||||
if (decapsulationKey == NULL) {
|
||||
crv = CKR_KEY_HANDLE_INVALID;
|
||||
@@ -412,17 +434,17 @@ NSC_DecapsulateKey(CK_SESSION_HANDLE hSe
|
||||
decapsulationKey->attrib.ulValueLen };
|
||||
SECItem ciphertext = { siBuffer, pCiphertext, ulCiphertextLen };
|
||||
|
||||
/* The length of secretBuf can be increased if we ever support other KEMs
|
||||
* by changing the define at the top of this file */
|
||||
uint8_t secretBuf[MAX_KEM_SHARED_SECRET_BYTES] = { 0 };
|
||||
SECItem secret = { siBuffer, secretBuf, sizeof secretBuf };
|
||||
key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DECAPSULATE,
|
||||
- key, 0);
|
||||
+ decapsulationKeyObject, 0);
|
||||
key->source = SFTK_SOURCE_KEA;
|
||||
|
||||
switch (pMechanism->mechanism) {
|
||||
#ifndef NSS_DISABLE_KYBER
|
||||
case CKM_NSS_KYBER:
|
||||
#endif
|
||||
case CKM_NSS_ML_KEM:
|
||||
case CKM_ML_KEM:
|
||||
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
|
||||
--- a/lib/softoken/pkcs11c.c
|
||||
+++ b/lib/softoken/pkcs11c.c
|
||||
@@ -5236,17 +5236,17 @@ sftk_compareKeysEqual(CK_SESSION_HANDLE
|
||||
SFTKObject *key1obj = NULL;
|
||||
SFTKObject *key2obj = NULL;
|
||||
SFTKAttribute *att1 = NULL;
|
||||
SFTKAttribute *att2 = NULL;
|
||||
|
||||
/* fetch the pkcs11 objects from the handles */
|
||||
session = sftk_SessionFromHandle(hSession);
|
||||
if (session == NULL) {
|
||||
- return CKR_SESSION_HANDLE_INVALID;
|
||||
+ return PR_FALSE;
|
||||
}
|
||||
|
||||
key1obj = sftk_ObjectFromHandle(key1, session);
|
||||
key2obj = sftk_ObjectFromHandle(key2, session);
|
||||
sftk_FreeSession(session);
|
||||
if ((key1obj == NULL) || (key2obj == NULL)) {
|
||||
goto loser;
|
||||
}
|
||||
@@ -5268,17 +5268,17 @@ sftk_compareKeysEqual(CK_SESSION_HANDLE
|
||||
goto loser;
|
||||
}
|
||||
result = PR_TRUE;
|
||||
loser:
|
||||
if (key1obj) {
|
||||
sftk_FreeObject(key1obj);
|
||||
}
|
||||
if (key2obj) {
|
||||
- sftk_FreeObject(key1obj);
|
||||
+ sftk_FreeObject(key2obj);
|
||||
}
|
||||
if (att1) {
|
||||
sftk_FreeAttribute(att1);
|
||||
}
|
||||
if (att2) {
|
||||
sftk_FreeAttribute(att2);
|
||||
}
|
||||
return result;
|
||||
@@ -5758,24 +5758,24 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
|
||||
SECITEM_ZfreeItem(&prime, PR_FALSE);
|
||||
}
|
||||
/* clean up before we return */
|
||||
sftk_FreeAttribute(pubAttribute);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
}
|
||||
- isKEM = sftk_isTrue(privateKey, CKA_ENCAPSULATE);
|
||||
+ isKEM = sftk_isTrue(privateKey, CKA_DECAPSULATE);
|
||||
if (isKEM) {
|
||||
unsigned char *cipher_text = NULL;
|
||||
CK_ULONG cipher_text_length = 0;
|
||||
CK_OBJECT_HANDLE key1 = CK_INVALID_HANDLE;
|
||||
CK_OBJECT_HANDLE key2 = CK_INVALID_HANDLE;
|
||||
CK_KEY_TYPE genType = CKO_SECRET_KEY;
|
||||
- CK_ATTRIBUTE template = { CKA_KEY_TYPE, NULL, 0 };
|
||||
+ CK_ATTRIBUTE template = { CKA_CLASS, NULL, 0 };
|
||||
|
||||
template.pValue = &genType;
|
||||
template.ulValueLen = sizeof(genType);
|
||||
crv = CKR_OK;
|
||||
switch (keyType) {
|
||||
case CKK_ML_KEM:
|
||||
cipher_text_length = MAX_ML_KEM_CIPHER_LENGTH;
|
||||
mech.mechanism = CKM_ML_KEM;
|
||||
@@ -5828,17 +5828,17 @@ kem_done:
|
||||
PORT_Free(cipher_text);
|
||||
if (key1 != CK_INVALID_HANDLE) {
|
||||
NSC_DestroyObject(hSession, key1);
|
||||
}
|
||||
if (key2 != CK_INVALID_HANDLE) {
|
||||
NSC_DestroyObject(hSession, key2);
|
||||
}
|
||||
if (crv != CKR_OK) {
|
||||
- return CKR_DEVICE_ERROR;
|
||||
+ return crv;
|
||||
}
|
||||
}
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
/* NSC_GenerateKeyPair generates a public-key/private-key pair,
|
||||
* creating new key objects. */
|
||||
@@ -7905,16 +7905,17 @@ sftk_DeriveEncrypt(SFTKCipher encrypt, v
|
||||
return crv;
|
||||
}
|
||||
|
||||
crv = sftk_forceAttribute(key, CKA_VALUE, tmpdata, keySize);
|
||||
PORT_Memset(tmpdata, 0, sizeof tmpdata);
|
||||
return crv;
|
||||
}
|
||||
|
||||
+
|
||||
CK_RV
|
||||
sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_SESSION_HANDLE hSession,
|
||||
SFTKObject *sourceKey, const unsigned char *sourceKeyBytes,
|
||||
int sourceKeyLen, SFTKObject *key, unsigned char *outKeyBytes,
|
||||
int keySize, PRBool canBeData, PRBool isFIPS)
|
||||
{
|
||||
SFTKSession *session;
|
||||
SFTKAttribute *saltKey_att = NULL;
|
||||
@@ -7958,16 +7959,21 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
|
||||
}
|
||||
|
||||
/* sourceKey is NULL if we are called from the POST, skip the
|
||||
* sensitiveCheck */
|
||||
if (sourceKey != NULL) {
|
||||
crv = sftk_DeriveSensitiveCheck(sourceKey, key, canBeData);
|
||||
if (crv != CKR_OK)
|
||||
return crv;
|
||||
+ /* if the source key is data, clear the FIPS flag
|
||||
+ * and only get the FIPS state from the salt */
|
||||
+ if (sourceKey->objclass == CKO_DATA) {
|
||||
+ key->isFIPS = PR_FALSE;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* HKDF-Extract(salt, base key value) */
|
||||
if (params->bExtract) {
|
||||
CK_BYTE *salt;
|
||||
CK_ULONG saltLen;
|
||||
HMACContext *hmac;
|
||||
unsigned int bufLen;
|
||||
@@ -7988,16 +7994,17 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
|
||||
break;
|
||||
case CKF_HKDF_SALT_KEY:
|
||||
/* lookup key */
|
||||
session = sftk_SessionFromHandle(hSession);
|
||||
if (session == NULL) {
|
||||
return CKR_SESSION_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
+
|
||||
saltKey = sftk_ObjectFromHandle(params->hSaltKey, session);
|
||||
sftk_FreeSession(session);
|
||||
if (saltKey == NULL) {
|
||||
return CKR_KEY_HANDLE_INVALID;
|
||||
}
|
||||
/* if the base key is not fips, but the salt key is, the
|
||||
* resulting key can be fips */
|
||||
if (isFIPS && (key->isFIPS == 0) && (saltKey->isFIPS == 1)) {
|
||||
@@ -9190,17 +9197,23 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
|
||||
|
||||
PORT_Memcpy(buf, att->attrib.pValue, att->attrib.ulValueLen);
|
||||
PORT_Memcpy(buf + att->attrib.ulValueLen,
|
||||
att2->attrib.pValue, att2->attrib.ulValueLen);
|
||||
|
||||
crv = sftk_forceAttribute(key, CKA_VALUE, buf, keySize);
|
||||
PORT_ZFree(buf, tmpKeySize);
|
||||
/* preserve the source of the original base key */
|
||||
- /* key->source = sourceKey->source; */
|
||||
+ key->source = sourceKey->source;
|
||||
+
|
||||
+ /* make sure this is fully fips approved, and mark it
|
||||
+ * unapproved if not */
|
||||
+ if (key->isFIPS) {
|
||||
+ key->isFIPS = paramKey->isFIPS;
|
||||
+ }
|
||||
sftk_FreeAttribute(att2);
|
||||
sftk_FreeObject(paramKey);
|
||||
break;
|
||||
}
|
||||
|
||||
case CKM_CONCATENATE_BASE_AND_DATA:
|
||||
crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE);
|
||||
if (crv != CKR_OK)
|
||||
diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c
|
||||
--- a/lib/softoken/pkcs11u.c
|
||||
+++ b/lib/softoken/pkcs11u.c
|
||||
@@ -2285,16 +2285,22 @@ sftk_AttributeToFlags(CK_ATTRIBUTE_TYPE
|
||||
flags = CKF_VERIFY;
|
||||
break;
|
||||
case CKA_VERIFY_RECOVER:
|
||||
flags = CKF_VERIFY_RECOVER;
|
||||
break;
|
||||
case CKA_DERIVE:
|
||||
flags = CKF_DERIVE;
|
||||
break;
|
||||
+ case CKA_ENCAPSULATE:
|
||||
+ flags = CKF_ENCAPSULATE;
|
||||
+ break;
|
||||
+ case CKA_DECAPSULATE:
|
||||
+ flags = CKF_DECAPSULATE;
|
||||
+ break;
|
||||
/* fake attribute to select digesting */
|
||||
case CKA_DIGEST:
|
||||
flags = CKF_DIGEST;
|
||||
break;
|
||||
/* fake attribute to select key gen */
|
||||
case CKA_NSS_GENERATE:
|
||||
flags = CKF_GENERATE;
|
||||
break;
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,202 +0,0 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1767992040 28800
|
||||
# Fri Jan 09 12:54:00 2026 -0800
|
||||
# Branch RHEL10
|
||||
# Node ID 15f1129c29c037cce7913eb62c0eca06b5aa51d1
|
||||
# Parent 4bfb87c6e863957fc933e6dd5af8eae8a5cd0469
|
||||
nss-3.112-pkcs12-ml-dsa-crash-fix.patch
|
||||
|
||||
diff --git a/gtests/pk11_gtest/pk11_der_private_key_import_unittest.cc b/gtests/pk11_gtest/pk11_der_private_key_import_unittest.cc
|
||||
--- a/gtests/pk11_gtest/pk11_der_private_key_import_unittest.cc
|
||||
+++ b/gtests/pk11_gtest/pk11_der_private_key_import_unittest.cc
|
||||
@@ -7,16 +7,17 @@
|
||||
#include <climits>
|
||||
#include <memory>
|
||||
#include "nss.h"
|
||||
#include "pk11pub.h"
|
||||
#include "secutil.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
+#define SEC_OID_ML_DSA_44 SEC_OID_PRIVATE_3
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
const std::vector<uint8_t> kValidP256Key = {
|
||||
0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
|
||||
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
|
||||
0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
|
||||
0xc9, 0xaf, 0xa9, 0xd8, 0x45, 0xba, 0x75, 0x16, 0x6b, 0x5c, 0x21, 0x57,
|
||||
@@ -133,16 +134,69 @@ class DERPrivateKeyImportTest : public :
|
||||
// no cert. This is expected, so clear it.
|
||||
if (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) {
|
||||
PORT_SetError(0);
|
||||
}
|
||||
}
|
||||
|
||||
return rv == SECSuccess;
|
||||
}
|
||||
+
|
||||
+ SECStatus BuildPrivateKeyInfoAndImportIt(SECOidTag algTag) {
|
||||
+ ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
+ EXPECT_TRUE(slot);
|
||||
+ if (!slot) {
|
||||
+ return SECFailure;
|
||||
+ }
|
||||
+
|
||||
+ ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
+ EXPECT_TRUE(arena);
|
||||
+ if (!arena) {
|
||||
+ return SECFailure;
|
||||
+ }
|
||||
+
|
||||
+ SECKEYPrivateKeyInfo* pki = (SECKEYPrivateKeyInfo*)PORT_ArenaZAlloc(
|
||||
+ arena.get(), sizeof(SECKEYPrivateKeyInfo));
|
||||
+ EXPECT_TRUE(pki);
|
||||
+ if (!pki) {
|
||||
+ return SECFailure;
|
||||
+ }
|
||||
+
|
||||
+ pki->version.data = (unsigned char*)PORT_ArenaAlloc(arena.get(), 1);
|
||||
+ EXPECT_TRUE(pki->version.data);
|
||||
+ if (!pki->version.data) {
|
||||
+ return SECFailure;
|
||||
+ }
|
||||
+
|
||||
+ pki->version.data[0] = 0x00;
|
||||
+ pki->version.len = 1;
|
||||
+
|
||||
+ EXPECT_EQ(
|
||||
+ SECOID_SetAlgorithmID(arena.get(), &pki->algorithm, algTag, nullptr),
|
||||
+ SECSuccess);
|
||||
+
|
||||
+ // Empty private key
|
||||
+ pki->privateKey.data = (unsigned char*)PORT_ArenaAlloc(arena.get(), 1);
|
||||
+ EXPECT_TRUE(pki->privateKey.data);
|
||||
+ if (!pki->privateKey.data) {
|
||||
+ return SECFailure;
|
||||
+ }
|
||||
+ pki->privateKey.len = 0;
|
||||
+
|
||||
+ SECKEYPrivateKey* privk = nullptr;
|
||||
+ PORT_SetError(0);
|
||||
+ SECStatus rv = PK11_ImportPrivateKeyInfoAndReturnKey(
|
||||
+ slot.get(), pki, nullptr, nullptr, PR_FALSE, PR_FALSE, KU_ALL, &privk,
|
||||
+ nullptr);
|
||||
+
|
||||
+ if (privk) {
|
||||
+ SECKEY_DestroyPrivateKey(privk);
|
||||
+ }
|
||||
+ return rv;
|
||||
+ }
|
||||
};
|
||||
|
||||
TEST_F(DERPrivateKeyImportTest, ImportPrivateRSAKey) {
|
||||
EXPECT_TRUE(ParsePrivateKey(kValidRSAKey, true));
|
||||
EXPECT_FALSE(PORT_GetError()) << PORT_GetError();
|
||||
}
|
||||
|
||||
TEST_F(DERPrivateKeyImportTest, ImportEcdsaKey) {
|
||||
@@ -155,9 +209,15 @@ TEST_F(DERPrivateKeyImportTest, ImportIn
|
||||
EXPECT_EQ(PORT_GetError(), SEC_ERROR_BAD_DER) << PORT_GetError();
|
||||
}
|
||||
|
||||
TEST_F(DERPrivateKeyImportTest, ImportZeroLengthPrivateKey) {
|
||||
EXPECT_FALSE(ParsePrivateKey(kInvalidZeroLengthKey, false));
|
||||
EXPECT_EQ(PORT_GetError(), SEC_ERROR_BAD_KEY) << PORT_GetError();
|
||||
}
|
||||
|
||||
+TEST_F(DERPrivateKeyImportTest,
|
||||
+ ImportZeroLengthMLDSAPrivateKey) {
|
||||
+ EXPECT_EQ(BuildPrivateKeyInfoAndImportIt(SEC_OID_ML_DSA_44), SECFailure);
|
||||
+ EXPECT_EQ(PORT_GetError(), SEC_ERROR_BAD_KEY);
|
||||
+}
|
||||
+
|
||||
} // namespace nss_test
|
||||
diff --git a/lib/pk11wrap/pk11pk12.c b/lib/pk11wrap/pk11pk12.c
|
||||
--- a/lib/pk11wrap/pk11pk12.c
|
||||
+++ b/lib/pk11wrap/pk11pk12.c
|
||||
@@ -323,17 +323,17 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey
|
||||
derPKI);
|
||||
if (rv != SECSuccess) {
|
||||
/* If SEC_ASN1DecodeItem fails, we cannot assume anything about the
|
||||
* validity of the data in pki. The best we can do is free the arena
|
||||
* and return. */
|
||||
PORT_FreeArena(temparena, PR_TRUE);
|
||||
return rv;
|
||||
}
|
||||
- if (pki->privateKey.data == NULL) {
|
||||
+ if (pki->privateKey.data == NULL || pki->privateKey.len == 0) {
|
||||
/* If SEC_ASN1DecodeItems succeeds but SECKEYPrivateKeyInfo.privateKey
|
||||
* is a zero-length octet string, free the arena and return a failure
|
||||
* to avoid trying to zero the corresponding SECItem in
|
||||
* SECKEY_DestroyPrivateKeyInfo(). */
|
||||
PORT_FreeArena(temparena, PR_TRUE);
|
||||
PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
return SECFailure;
|
||||
}
|
||||
@@ -753,16 +753,20 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK
|
||||
keyTemplate = SECKEY_ECPrivateKeyExportTemplate;
|
||||
paramTemplate = NULL;
|
||||
paramDest = NULL;
|
||||
lpk->keyType = ecKey;
|
||||
break;
|
||||
case SEC_OID_ML_DSA_44:
|
||||
case SEC_OID_ML_DSA_65:
|
||||
case SEC_OID_ML_DSA_87:
|
||||
+ if (pki->privateKey.data == NULL || pki->privateKey.len == 0) {
|
||||
+ PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
+ goto loser;
|
||||
+ }
|
||||
/* choice */
|
||||
switch (pki->privateKey.data[0]) {
|
||||
case SEC_ASN1_CONTEXT_SPECIFIC|0:
|
||||
keyTemplate = SECKEY_MLDSAPrivateKeySeedExportTemplate;
|
||||
break;
|
||||
case SEC_ASN1_OCTET_STRING:
|
||||
keyTemplate = SECKEY_MLDSAPrivateKeyKeyExportTemplate;
|
||||
break;
|
||||
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
|
||||
--- a/lib/softoken/pkcs11c.c
|
||||
+++ b/lib/softoken/pkcs11c.c
|
||||
@@ -5815,17 +5815,17 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
|
||||
}
|
||||
crv = NSC_Decapsulate(hSession, &mech, privateKey->handle,
|
||||
cipher_text, cipher_text_length, &template, 1,
|
||||
&key2);
|
||||
if (crv != CKR_OK) {
|
||||
goto kem_done;
|
||||
}
|
||||
if (!sftk_compareKeysEqual(hSession, key1, key2)) {
|
||||
- crv = CKR_DEVICE_ERROR;
|
||||
+ crv = CKR_GENERAL_ERROR;
|
||||
goto kem_done;
|
||||
}
|
||||
kem_done:
|
||||
/* PORT_Free already checks for NULL */
|
||||
PORT_Free(cipher_text);
|
||||
if (key1 != CK_INVALID_HANDLE) {
|
||||
NSC_DestroyObject(hSession, key1);
|
||||
}
|
||||
@@ -7105,16 +7105,20 @@ sftk_unwrapPrivateKey(SFTKObject *key, S
|
||||
paramSet = CKP_ML_DSA_44;
|
||||
goto mldsa_next;
|
||||
case SEC_OID_ML_DSA_65:
|
||||
paramSet = CKP_ML_DSA_65;
|
||||
goto mldsa_next;
|
||||
case SEC_OID_ML_DSA_87:
|
||||
paramSet = CKP_ML_DSA_87;
|
||||
mldsa_next:
|
||||
+ if (pki->privateKey.data == NULL || pki->privateKey.len == 0) {
|
||||
+ PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
+ goto loser;
|
||||
+ }
|
||||
switch (pki->privateKey.data[0]) {
|
||||
case SEC_ASN1_CONTEXT_SPECIFIC|0:
|
||||
keyTemplate = nsslowkey_PQSeedTemplate;
|
||||
break;
|
||||
case SEC_ASN1_OCTET_STRING:
|
||||
keyTemplate = nsslowkey_PQPrivateKeyTemplate;
|
||||
break;
|
||||
case SEC_ASN1_CONSTRUCTED|SEC_ASN1_SEQUENCE:
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,928 +0,0 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1762542092 28800
|
||||
# Fri Nov 07 11:01:32 2025 -0800
|
||||
# Branch RHEL_8
|
||||
# Node ID 5b6833262609c6a2567d234a645be532bde27ef7
|
||||
# Parent 04ad729ed140ac94ab37d012dd2fec6c575bba2b
|
||||
nss-3.112-update-fixes.patch
|
||||
|
||||
diff --git a/lib/cryptohi/keythi.h b/lib/cryptohi/keythi.h
|
||||
--- a/lib/cryptohi/keythi.h
|
||||
+++ b/lib/cryptohi/keythi.h
|
||||
@@ -243,16 +243,27 @@ struct SECKEYPrivateKeyStr {
|
||||
PK11SlotInfo *pkcs11Slot; /* pkcs11 slot this key lives in */
|
||||
CK_OBJECT_HANDLE pkcs11ID; /* ID of pkcs11 object */
|
||||
PRBool pkcs11IsTemp; /* temp pkcs11 object, delete it when done */
|
||||
void *wincx; /* context for errors and pw prompts */
|
||||
PRUint32 staticflags; /* bit flag of cached PKCS#11 attributes */
|
||||
};
|
||||
typedef struct SECKEYPrivateKeyStr SECKEYPrivateKey;
|
||||
|
||||
+#define SECKEYPRIVATEKEY_IS_TEMP_FLAG 0x01
|
||||
+#define SECKEYPRIVATEKEY_IS_OWNED_FLAG 0x02
|
||||
+#define SECKEYPRIVATEKEY_IS_TEMP(key) \
|
||||
+ ((PRBool)((key)->pkcs11IsTemp&SECKEYPRIVATEKEY_IS_TEMP_FLAG)==SECKEYPRIVATEKEY_IS_TEMP_FLAG)
|
||||
+#define SECKEYPRIVATEKEY_IS_OWNED(key) \
|
||||
+ ((PRBool)((key)->pkcs11IsTemp&SECKEYPRIVATEKEY_IS_OWNED_FLAG)==SECKEYPRIVATEKEY_IS_OWNED_FLAG)
|
||||
+#define SECKEYPRIVATEKEY_SET_TEMP(key,isTemp) (key)->pkcs11IsTemp = ((key)->pkcs11IsTemp & ~SECKEYPRIVATEKEY_IS_TEMP_FLAG) | \
|
||||
+ ((isTemp) ? SECKEYPRIVATEKEY_IS_TEMP_FLAG : 0)
|
||||
+#define SECKEYPRIVATEKEY_SET_OWNED(key,isOwned) (key)->pkcs11IsTemp = ((key)->pkcs11IsTemp & ~SECKEYPRIVATEKEY_IS_OWNED_FLAG) | \
|
||||
+ ((isOwned) ? SECKEYPRIVATEKEY_IS_OWNED_FLAG : 0)
|
||||
+
|
||||
typedef struct {
|
||||
PRCList links;
|
||||
SECKEYPrivateKey *key;
|
||||
} SECKEYPrivateKeyListNode;
|
||||
|
||||
typedef struct {
|
||||
PRCList list;
|
||||
PLArenaPool *arena;
|
||||
diff --git a/lib/cryptohi/seckey.c b/lib/cryptohi/seckey.c
|
||||
--- a/lib/cryptohi/seckey.c
|
||||
+++ b/lib/cryptohi/seckey.c
|
||||
@@ -416,17 +416,17 @@ SECKEY_CreateEDPrivateKey(SECKEYECParams
|
||||
return (privk);
|
||||
}
|
||||
|
||||
void
|
||||
SECKEY_DestroyPrivateKey(SECKEYPrivateKey *privk)
|
||||
{
|
||||
if (privk) {
|
||||
if (privk->pkcs11Slot) {
|
||||
- if (privk->pkcs11IsTemp) {
|
||||
+ if (SECKEYPRIVATEKEY_IS_OWNED(privk)) {
|
||||
PK11_DestroyObject(privk->pkcs11Slot, privk->pkcs11ID);
|
||||
}
|
||||
PK11_FreeSlot(privk->pkcs11Slot);
|
||||
}
|
||||
if (privk->arena) {
|
||||
PORT_FreeArena(privk->arena, PR_TRUE);
|
||||
}
|
||||
}
|
||||
@@ -1418,27 +1418,31 @@ SECKEY_CopyPrivateKey(const SECKEYPrivat
|
||||
copyk = (SECKEYPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey));
|
||||
if (copyk) {
|
||||
copyk->arena = arena;
|
||||
copyk->keyType = privk->keyType;
|
||||
|
||||
/* copy the PKCS #11 parameters */
|
||||
copyk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot);
|
||||
/* if the key we're referencing was a temparary key we have just
|
||||
- * created, that we want to go away when we're through, we need
|
||||
+ * it may go away when we're through, we need
|
||||
* to make a copy of it */
|
||||
- if (privk->pkcs11IsTemp) {
|
||||
+ copyk->pkcs11IsTemp = privk->pkcs11IsTemp;
|
||||
+ if (SECKEYPRIVATEKEY_IS_TEMP(privk)) {
|
||||
copyk->pkcs11ID =
|
||||
PK11_CopyKey(privk->pkcs11Slot, privk->pkcs11ID);
|
||||
if (copyk->pkcs11ID == CK_INVALID_HANDLE)
|
||||
goto fail;
|
||||
+ /* since we made a copy, we own that copy (even if we
|
||||
+ * didn't own the original */
|
||||
+ SECKEYPRIVATEKEY_SET_OWNED(copyk, PR_TRUE);
|
||||
} else {
|
||||
copyk->pkcs11ID = privk->pkcs11ID;
|
||||
+ SECKEYPRIVATEKEY_SET_OWNED(copyk, PR_FALSE);
|
||||
}
|
||||
- copyk->pkcs11IsTemp = privk->pkcs11IsTemp;
|
||||
copyk->wincx = privk->wincx;
|
||||
copyk->staticflags = privk->staticflags;
|
||||
return copyk;
|
||||
} else {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
}
|
||||
|
||||
fail:
|
||||
diff --git a/lib/cryptohi/secvfy.c b/lib/cryptohi/secvfy.c
|
||||
--- a/lib/cryptohi/secvfy.c
|
||||
+++ b/lib/cryptohi/secvfy.c
|
||||
@@ -436,17 +436,17 @@ sec_DecodeSigAlg(const SECKEYPublicKey *
|
||||
const SECItem *param, SECOidTag *encalgp, SECOidTag *hashalg,
|
||||
CK_MECHANISM_TYPE *mechp, SECItem *mechparamsp)
|
||||
{
|
||||
unsigned int len;
|
||||
PLArenaPool *arena;
|
||||
SECStatus rv;
|
||||
SECItem oid;
|
||||
SECOidTag encalg;
|
||||
- PRBool comboRequired = PR_TRUE;
|
||||
+ PRBool comboRequired = PR_FALSE;
|
||||
char *evp;
|
||||
|
||||
PR_ASSERT(hashalg != NULL);
|
||||
PR_ASSERT(encalgp != NULL);
|
||||
PR_ASSERT(mechp != NULL);
|
||||
/* Get the expected combined mechanism from the signature OID
|
||||
* We'll override it in the table below if necessary */
|
||||
*mechp = PK11_AlgtagToMechanism(sigAlg);
|
||||
diff --git a/lib/freebl/leancrypto/lc_sha3.h b/lib/freebl/leancrypto/lc_sha3.h
|
||||
--- a/lib/freebl/leancrypto/lc_sha3.h
|
||||
+++ b/lib/freebl/leancrypto/lc_sha3.h
|
||||
@@ -20,17 +20,20 @@
|
||||
struct lc_hash_ctx _##name ; \
|
||||
_##name.hash= type_; \
|
||||
_##name.buf= NULL; \
|
||||
_##name.stream = false; \
|
||||
_##name.u.ctx_ptr = NULL; \
|
||||
struct lc_hash_ctx *name= &_##name;
|
||||
|
||||
#define LC_HASH_SET_CTX(name, type_) \
|
||||
- name->hash= type_;
|
||||
+ name->hash= type_; \
|
||||
+ name->stream = true; \
|
||||
+ name->u.ctx_ptr = NULL; \
|
||||
+ name->buf = NULL;
|
||||
|
||||
#define LC_SHAKE_256_CTX(name) \
|
||||
LC_HASH_SET_CTX(name, lc_shake256);
|
||||
|
||||
typedef enum {
|
||||
lc_shake128,
|
||||
lc_shake256,
|
||||
} sha3Type;
|
||||
diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c
|
||||
--- a/lib/pk11wrap/pk11akey.c
|
||||
+++ b/lib/pk11wrap/pk11akey.c
|
||||
@@ -1002,34 +1002,39 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot
|
||||
return pubKey;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build a Private Key structure from raw PKCS #11 information.
|
||||
*/
|
||||
SECKEYPrivateKey *
|
||||
PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
|
||||
- PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx)
|
||||
+ PRBool isOwner, CK_OBJECT_HANDLE privID, void *wincx)
|
||||
{
|
||||
PLArenaPool *arena;
|
||||
SECKEYPrivateKey *privKey;
|
||||
PRBool isPrivate;
|
||||
SECStatus rv;
|
||||
+ PRBool isTemp = isOwner;
|
||||
|
||||
/* don't know? look it up */
|
||||
if (keyType == nullKey) {
|
||||
CK_KEY_TYPE pk11Type = CKK_RSA;
|
||||
|
||||
pk11Type = PK11_ReadULongAttribute(slot, privID, CKA_KEY_TYPE);
|
||||
isTemp = (PRBool)!PK11_HasAttributeSet(slot, privID, CKA_TOKEN, PR_FALSE);
|
||||
keyType = pk11_GetKeyTypeFromPKCS11KeyType(pk11Type);
|
||||
if (keyType == nullKey) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
+ /* we can never own a perm key, make sure we don't set owner */
|
||||
+ if (!isTemp) {
|
||||
+ isOwner = PR_FALSE;
|
||||
+ }
|
||||
|
||||
/* if the key is private, make sure we are authenticated to the
|
||||
* token before we try to use it */
|
||||
isPrivate = (PRBool)PK11_HasAttributeSet(slot, privID, CKA_PRIVATE, PR_FALSE);
|
||||
if (isPrivate) {
|
||||
rv = PK11_Authenticate(slot, PR_TRUE, wincx);
|
||||
if (rv != SECSuccess) {
|
||||
return NULL;
|
||||
@@ -1047,17 +1052,19 @@ PK11_MakePrivKey(PK11SlotInfo *slot, Key
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
privKey->arena = arena;
|
||||
privKey->keyType = keyType;
|
||||
privKey->pkcs11Slot = PK11_ReferenceSlot(slot);
|
||||
privKey->pkcs11ID = privID;
|
||||
- privKey->pkcs11IsTemp = isTemp;
|
||||
+ privKey->pkcs11IsTemp = 0;
|
||||
+ SECKEYPRIVATEKEY_SET_TEMP(privKey, isTemp);
|
||||
+ SECKEYPRIVATEKEY_SET_OWNED(privKey, isOwner);
|
||||
privKey->wincx = wincx;
|
||||
|
||||
return privKey;
|
||||
}
|
||||
|
||||
PK11SlotInfo *
|
||||
PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key)
|
||||
{
|
||||
@@ -2635,17 +2642,17 @@ PK11_CopyTokenPrivKeyToSessionPrivKey(PK
|
||||
1, &newKeyID);
|
||||
PK11_ExitSlotMonitor(destSlot);
|
||||
|
||||
if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- return PK11_MakePrivKey(destSlot, privKey->keyType, PR_TRUE /*isTemp*/,
|
||||
+ return PK11_MakePrivKey(destSlot, privKey->keyType, PR_TRUE /*isOwner*/,
|
||||
newKeyID, privKey->wincx);
|
||||
}
|
||||
|
||||
SECKEYPrivateKey *
|
||||
PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void *wincx)
|
||||
{
|
||||
PK11SlotInfo *slot = privk->pkcs11Slot;
|
||||
CK_ATTRIBUTE template[1];
|
||||
@@ -2668,17 +2675,17 @@ PK11_ConvertSessionPrivKeyToTokenPrivKey
|
||||
template, 1, &newKeyID);
|
||||
PK11_RestoreROSession(slot, rwsession);
|
||||
|
||||
if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- return PK11_MakePrivKey(slot, nullKey /*KeyType*/, PR_FALSE /*isTemp*/,
|
||||
+ return PK11_MakePrivKey(slot, nullKey /*KeyType*/, PR_FALSE /*isOwner*/,
|
||||
newKeyID, NULL /*wincx*/);
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy a private key if there are no matching certs.
|
||||
* this function also frees the privKey structure.
|
||||
*/
|
||||
SECStatus
|
||||
@@ -2731,17 +2738,17 @@ pk11_DoKeys(PK11SlotInfo *slot, CK_OBJEC
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
SECKEYPrivateKey *privKey;
|
||||
pk11KeyCallback *keycb = (pk11KeyCallback *)arg;
|
||||
if (!arg) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
- privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, keycb->wincx);
|
||||
+ privKey = PK11_MakePrivKey(slot, nullKey, PR_FALSE, keyHandle, keycb->wincx);
|
||||
|
||||
if (privKey == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (keycb->callback) {
|
||||
rv = (*keycb->callback)(privKey, keycb->callbackArg);
|
||||
}
|
||||
@@ -2823,17 +2830,17 @@ PK11_FindKeyByKeyID(PK11SlotInfo *slot,
|
||||
{
|
||||
CK_OBJECT_HANDLE keyHandle;
|
||||
SECKEYPrivateKey *privKey;
|
||||
|
||||
keyHandle = pk11_FindPrivateKeyFromCertID(slot, keyID);
|
||||
if (keyHandle == CK_INVALID_HANDLE) {
|
||||
return NULL;
|
||||
}
|
||||
- privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
|
||||
+ privKey = PK11_MakePrivKey(slot, nullKey, PR_FALSE, keyHandle, wincx);
|
||||
return privKey;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a CKA_ID from the relevant public key data. The CKA_ID is generated
|
||||
* from the pubKeyData by SHA1_Hashing it to produce a smaller CKA_ID (to make
|
||||
* smart cards happy.
|
||||
*/
|
||||
@@ -3011,15 +3018,15 @@ PK11_ListPrivKeysInSlot(PK11SlotInfo *sl
|
||||
keys = SECKEY_NewPrivateKeyList();
|
||||
if (keys == NULL) {
|
||||
PORT_Free(key_ids);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < objCount; i++) {
|
||||
SECKEYPrivateKey *privKey =
|
||||
- PK11_MakePrivKey(slot, nullKey, PR_TRUE, key_ids[i], wincx);
|
||||
+ PK11_MakePrivKey(slot, nullKey, PR_FALSE, key_ids[i], wincx);
|
||||
SECKEY_AddPrivateKeyToListTail(keys, privKey);
|
||||
}
|
||||
|
||||
PORT_Free(key_ids);
|
||||
return keys;
|
||||
}
|
||||
diff --git a/lib/pk11wrap/pk11cert.c b/lib/pk11wrap/pk11cert.c
|
||||
--- a/lib/pk11wrap/pk11cert.c
|
||||
+++ b/lib/pk11wrap/pk11cert.c
|
||||
@@ -1313,17 +1313,18 @@ PK11_FindPrivateKeyFromCert(PK11SlotInfo
|
||||
if (rv != SECSuccess) {
|
||||
return NULL;
|
||||
}
|
||||
keyh = PK11_MatchItem(slot, certh, CKO_PRIVATE_KEY);
|
||||
}
|
||||
if (keyh == CK_INVALID_HANDLE) {
|
||||
return NULL;
|
||||
}
|
||||
- return PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyh, wincx);
|
||||
+
|
||||
+ return PK11_MakePrivKey(slot, nullKey, PR_FALSE, keyh, wincx);
|
||||
}
|
||||
|
||||
/*
|
||||
* import a cert for a private key we have already generated. Set the label
|
||||
* on both to be the nickname. This is for the Key Gen, orphaned key case.
|
||||
*/
|
||||
PK11SlotInfo *
|
||||
PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr,
|
||||
@@ -2085,17 +2086,17 @@ PK11_FindKeyByAnyCert(CERTCertificate *c
|
||||
SEC_ERROR_TOKEN_NOT_LOGGED_IN == err)) {
|
||||
/* authenticate and try again */
|
||||
rv = PK11_Authenticate(slot, PR_TRUE, wincx);
|
||||
if (rv == SECSuccess) {
|
||||
keyHandle = PK11_MatchItem(slot, certHandle, CKO_PRIVATE_KEY);
|
||||
}
|
||||
}
|
||||
if (keyHandle != CK_INVALID_HANDLE) {
|
||||
- privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
|
||||
+ privKey = PK11_MakePrivKey(slot, nullKey, PR_FALSE, keyHandle, wincx);
|
||||
}
|
||||
if (slot) {
|
||||
PK11_FreeSlot(slot);
|
||||
}
|
||||
return privKey;
|
||||
}
|
||||
|
||||
CK_OBJECT_HANDLE
|
||||
@@ -2492,17 +2493,17 @@ PK11_FindKeyByDERCert(PK11SlotInfo *slot
|
||||
return NULL;
|
||||
}
|
||||
|
||||
keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx);
|
||||
if (keyHandle == CK_INVALID_HANDLE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- return PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
|
||||
+ return PK11_MakePrivKey(slot, nullKey, PR_FALSE, keyHandle, wincx);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert,
|
||||
char *nickname,
|
||||
PRBool addCertUsage, void *wincx)
|
||||
{
|
||||
CK_OBJECT_HANDLE keyHandle;
|
||||
diff --git a/lib/pk11wrap/pk11kea.c b/lib/pk11wrap/pk11kea.c
|
||||
--- a/lib/pk11wrap/pk11kea.c
|
||||
+++ b/lib/pk11wrap/pk11kea.c
|
||||
@@ -86,17 +86,17 @@ pk11_KeyExchange(PK11SlotInfo *slot, CK_
|
||||
goto rsa_failed;
|
||||
}
|
||||
rsaParams.keySizeInBits = 1024;
|
||||
rsaParams.pe = 0x10001;
|
||||
privKey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN,
|
||||
&rsaParams, &pubKey, PR_FALSE, PR_TRUE, symKey->cx);
|
||||
} else {
|
||||
/* if keys exist, build SECKEY data structures for them */
|
||||
- privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, privKeyHandle,
|
||||
+ privKey = PK11_MakePrivKey(slot, nullKey, PR_FALSE, privKeyHandle,
|
||||
symKey->cx);
|
||||
if (privKey != NULL) {
|
||||
pubKey = PK11_ExtractPublicKey(slot, rsaKey, pubKeyHandle);
|
||||
if (pubKey && pubKey->pkcs11Slot) {
|
||||
PK11_FreeSlot(pubKey->pkcs11Slot);
|
||||
pubKey->pkcs11Slot = NULL;
|
||||
pubKey->pkcs11ID = CK_INVALID_HANDLE;
|
||||
}
|
||||
diff --git a/lib/pk11wrap/pk11skey.c b/lib/pk11wrap/pk11skey.c
|
||||
--- a/lib/pk11wrap/pk11skey.c
|
||||
+++ b/lib/pk11wrap/pk11skey.c
|
||||
@@ -433,17 +433,17 @@ PK11_VerifyKeyOK(PK11SymKey *key)
|
||||
return PR_FALSE;
|
||||
}
|
||||
return (PRBool)(key->series == key->slot->series);
|
||||
}
|
||||
|
||||
static PK11SymKey *
|
||||
pk11_ImportSymKeyWithTempl(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
||||
PK11Origin origin, PRBool isToken, CK_ATTRIBUTE *keyTemplate,
|
||||
- unsigned int templateCount, SECItem *key, void *wincx)
|
||||
+ unsigned int templateCount, SECItem *key, PRBool force, void *wincx)
|
||||
{
|
||||
PK11SymKey *symKey;
|
||||
SECStatus rv;
|
||||
|
||||
symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx);
|
||||
if (symKey == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -458,22 +458,71 @@ pk11_ImportSymKeyWithTempl(PK11SlotInfo
|
||||
return NULL;
|
||||
}
|
||||
|
||||
symKey->origin = origin;
|
||||
|
||||
/* import the keys */
|
||||
rv = PK11_CreateNewObject(slot, symKey->session, keyTemplate,
|
||||
templateCount, isToken, &symKey->objectID);
|
||||
- if (rv != SECSuccess) {
|
||||
+ if (rv == SECSuccess) {
|
||||
+ return symKey;
|
||||
+ }
|
||||
+ /* we failed to create the key, if force isn't set, we just fail now */
|
||||
+ if (!force) {
|
||||
+ PK11_FreeSymKey(symKey);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ /* if force is set, we are simulating an unwrap, probably from another token, we
|
||||
+ * are probably here because we are trying to import into a FIPS token. Normally
|
||||
+ * we would want this to fail, but the application got here because they are using
|
||||
+ * unwrap, which is the correct way to do this, so try to import the key into
|
||||
+ * the FIPS token my hand */
|
||||
+ /* first generate a seed key */
|
||||
+ PK11SymKey *seedKey = PK11_KeyGen(slot, CKM_SHA256_HMAC, NULL, 256, wincx);
|
||||
+
|
||||
+ if (seedKey == NULL) {
|
||||
PK11_FreeSymKey(symKey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- return symKey;
|
||||
+ /* now append our key data to the seed key and truncate the seed key */
|
||||
+ CK_KEY_DERIVATION_STRING_DATA params = { 0 };
|
||||
+ CK_MECHANISM mechanism = { 0, NULL, 0 };
|
||||
+ params.pData = key->data;
|
||||
+ params.ulLen = key->len;
|
||||
+ mechanism.mechanism = CKM_CONCATENATE_DATA_AND_BASE;
|
||||
+ mechanism.pParameter = ¶ms;
|
||||
+ mechanism.ulParameterLen = sizeof(params);
|
||||
+
|
||||
+ /* derive removed the CKA_VALUE_LEN before it called us, but now we need
|
||||
+ * it back. We know there is space in the template because derive leaves
|
||||
+ * space for the CKA_VALUE_LEN attribute. Any other callers that set force
|
||||
+ * should also make sure there is space for the CKA_VALUE_LEN */
|
||||
+ CK_ULONG valueLen; /* Don't define this in the 'if' statement, because it
|
||||
+ * would go out of scope before we use it */
|
||||
+ if (!pk11_FindAttrInTemplate(keyTemplate, templateCount, CKA_VALUE_LEN)) {
|
||||
+ valueLen = (CK_ULONG)key->len;
|
||||
+ keyTemplate[templateCount].type = CKA_VALUE_LEN;
|
||||
+ keyTemplate[templateCount].pValue = (void *)&valueLen;
|
||||
+ keyTemplate[templateCount].ulValueLen = sizeof(valueLen);
|
||||
+ templateCount++;
|
||||
+ }
|
||||
+
|
||||
+ CK_RV crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism,
|
||||
+ seedKey->objectID, keyTemplate,
|
||||
+ templateCount,
|
||||
+ &symKey->objectID);
|
||||
+ PK11_FreeSymKey(seedKey);
|
||||
+ if (crv == CKR_OK) {
|
||||
+ return symKey;
|
||||
+ }
|
||||
+
|
||||
+ PK11_FreeSymKey(symKey);
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* turn key bits into an appropriate key object
|
||||
*/
|
||||
PK11SymKey *
|
||||
PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
||||
PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, void *wincx)
|
||||
@@ -501,17 +550,17 @@ PK11_ImportSymKey(PK11SlotInfo *slot, CK
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, operation, &cktrue, 1);
|
||||
attrs++;
|
||||
templateCount = attrs - keyTemplate;
|
||||
PR_ASSERT(templateCount + 1 <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE));
|
||||
|
||||
keyType = PK11_GetKeyType(type, key->len);
|
||||
symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, PR_FALSE,
|
||||
- keyTemplate, templateCount, key, wincx);
|
||||
+ keyTemplate, templateCount, key, PR_FALSE, wincx);
|
||||
return symKey;
|
||||
}
|
||||
/* Import a PKCS #11 data object and return it as a key. This key is
|
||||
* only useful in a limited number of mechanisms, such as HKDF. */
|
||||
PK11SymKey *
|
||||
PK11_ImportDataKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PK11Origin origin,
|
||||
CK_ATTRIBUTE_TYPE operation, SECItem *key, void *wincx)
|
||||
{
|
||||
@@ -580,17 +629,17 @@ PK11_ImportSymKeyWithFlags(PK11SlotInfo
|
||||
PK11_SETATTRS(attrs, operation, &cktrue, sizeof(cktrue));
|
||||
attrs++;
|
||||
}
|
||||
templateCount = attrs - keyTemplate;
|
||||
PR_ASSERT(templateCount + 1 <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE));
|
||||
|
||||
keyType = PK11_GetKeyType(type, key->len);
|
||||
symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, isPerm,
|
||||
- keyTemplate, templateCount, key, wincx);
|
||||
+ keyTemplate, templateCount, key, PR_FALSE, wincx);
|
||||
if (symKey && isPerm) {
|
||||
symKey->owner = PR_FALSE;
|
||||
}
|
||||
return symKey;
|
||||
}
|
||||
|
||||
PK11SymKey *
|
||||
PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID,
|
||||
@@ -2670,29 +2719,29 @@ pk11_HandUnwrap(PK11SlotInfo *slot, CK_O
|
||||
}
|
||||
|
||||
outKey.len = (key_size == 0) ? len : key_size;
|
||||
outKey.type = siBuffer;
|
||||
|
||||
if (PK11_DoesMechanism(slot, target)) {
|
||||
symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap,
|
||||
isPerm, keyTemplate,
|
||||
- templateCount, &outKey, wincx);
|
||||
+ templateCount, &outKey, PR_TRUE, wincx);
|
||||
} else {
|
||||
slot = PK11_GetBestSlot(target, wincx);
|
||||
if (slot == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MODULE);
|
||||
PORT_Free(outKey.data);
|
||||
if (crvp)
|
||||
*crvp = CKR_DEVICE_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap,
|
||||
isPerm, keyTemplate,
|
||||
- templateCount, &outKey, wincx);
|
||||
+ templateCount, &outKey, PR_TRUE, wincx);
|
||||
PK11_FreeSlot(slot);
|
||||
}
|
||||
PORT_Free(outKey.data);
|
||||
|
||||
if (crvp)
|
||||
*crvp = symKey ? CKR_OK : CKR_DEVICE_ERROR;
|
||||
return symKey;
|
||||
}
|
||||
diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c
|
||||
--- a/lib/softoken/pkcs11.c
|
||||
+++ b/lib/softoken/pkcs11.c
|
||||
@@ -1031,36 +1031,40 @@ sftk_handleCrlObject(SFTKSession *sessio
|
||||
|
||||
/*
|
||||
* check the consistancy and initialize a Public Key Object
|
||||
*/
|
||||
static CK_RV
|
||||
sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
|
||||
CK_KEY_TYPE key_type)
|
||||
{
|
||||
- CK_BBOOL encrypt = CK_TRUE;
|
||||
- CK_BBOOL recover = CK_TRUE;
|
||||
- CK_BBOOL wrap = CK_TRUE;
|
||||
+ CK_BBOOL encrypt = CK_FALSE;
|
||||
+ CK_BBOOL recover = CK_FALSE;
|
||||
+ CK_BBOOL wrap = CK_FALSE;
|
||||
CK_BBOOL derive = CK_FALSE;
|
||||
- CK_BBOOL verify = CK_TRUE;
|
||||
+ CK_BBOOL verify = CK_FALSE;
|
||||
CK_BBOOL encapsulate = CK_FALSE;
|
||||
CK_ULONG paramSet = 0;
|
||||
CK_RV crv;
|
||||
|
||||
switch (key_type) {
|
||||
case CKK_RSA:
|
||||
crv = sftk_ConstrainAttribute(object, CKA_MODULUS,
|
||||
RSA_MIN_MODULUS_BITS, 0, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
crv = sftk_ConstrainAttribute(object, CKA_PUBLIC_EXPONENT, 2, 0, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
+ encrypt = CK_TRUE;
|
||||
+ recover = CK_TRUE;
|
||||
+ wrap = CK_TRUE;
|
||||
+ verify = CK_TRUE;
|
||||
break;
|
||||
case CKK_DSA:
|
||||
crv = sftk_ConstrainAttribute(object, CKA_SUBPRIME,
|
||||
DSA_MIN_Q_BITS, DSA_MAX_Q_BITS, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
crv = sftk_ConstrainAttribute(object, CKA_PRIME,
|
||||
@@ -1071,92 +1075,73 @@ sftk_handlePublicKeyObject(SFTKSession *
|
||||
crv = sftk_ConstrainAttribute(object, CKA_BASE, 2, DSA_MAX_P_BITS, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
crv = sftk_ConstrainAttribute(object, CKA_VALUE, 2, DSA_MAX_P_BITS, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
- encrypt = CK_FALSE;
|
||||
- recover = CK_FALSE;
|
||||
- wrap = CK_FALSE;
|
||||
+ verify = CK_TRUE;
|
||||
break;
|
||||
case CKK_DH:
|
||||
crv = sftk_ConstrainAttribute(object, CKA_PRIME,
|
||||
DH_MIN_P_BITS, DH_MAX_P_BITS, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
crv = sftk_ConstrainAttribute(object, CKA_BASE, 2, DH_MAX_P_BITS, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
crv = sftk_ConstrainAttribute(object, CKA_VALUE, 2, DH_MAX_P_BITS, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
- verify = CK_FALSE;
|
||||
derive = CK_TRUE;
|
||||
- encrypt = CK_FALSE;
|
||||
- recover = CK_FALSE;
|
||||
- wrap = CK_FALSE;
|
||||
break;
|
||||
case CKK_EC_MONTGOMERY:
|
||||
case CKK_EC_EDWARDS:
|
||||
case CKK_EC:
|
||||
if (!sftk_hasAttribute(object, CKA_EC_PARAMS)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
if (!sftk_hasAttribute(object, CKA_EC_POINT)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
/* for ECDSA and EDDSA. Change if the structure of any of them is modified. */
|
||||
derive = (key_type == CKK_EC_EDWARDS) ? CK_FALSE : CK_TRUE; /* CK_TRUE for ECDH */
|
||||
verify = (key_type == CKK_EC_MONTGOMERY) ? CK_FALSE : CK_TRUE; /* for ECDSA and EDDSA */
|
||||
- encrypt = CK_FALSE;
|
||||
- recover = CK_FALSE;
|
||||
- wrap = CK_FALSE;
|
||||
break;
|
||||
#ifndef NSS_DISABLE_KYBER
|
||||
case CKK_NSS_KYBER:
|
||||
#endif
|
||||
case CKK_NSS_ML_KEM:
|
||||
case CKK_ML_KEM:
|
||||
if (!sftk_hasAttribute(object, CKA_PARAMETER_SET)) {
|
||||
if (!sftk_hasAttribute(object, CKA_NSS_PARAMETER_SET)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
}
|
||||
- derive = CK_FALSE;
|
||||
- verify = CK_FALSE;
|
||||
- encrypt = CK_FALSE;
|
||||
- recover = CK_FALSE;
|
||||
- wrap = CK_FALSE;
|
||||
encapsulate = CK_TRUE;
|
||||
break;
|
||||
#ifdef NSS_ENABLE_ML_DSA
|
||||
case CKK_ML_DSA:
|
||||
if (!sftk_hasAttribute(object, CKA_PARAMETER_SET)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
crv = sftk_GetULongAttribute (object, CKA_PARAMETER_SET,
|
||||
¶mSet);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
if (sftk_MLDSAGetSigLen(paramSet) == 0) {
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
}
|
||||
- derive = CK_FALSE;
|
||||
verify = CK_TRUE;
|
||||
- encrypt = CK_FALSE;
|
||||
- recover = CK_FALSE;
|
||||
- wrap = CK_FALSE;
|
||||
- encapsulate = CK_FALSE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
}
|
||||
|
||||
/* make sure the required fields exist */
|
||||
crv = sftk_defaultAttribute(object, CKA_SUBJECT, NULL, 0);
|
||||
@@ -1224,21 +1209,21 @@ sftk_verifyRSAPrivateKey(SFTKObject *obj
|
||||
|
||||
/*
|
||||
* check the consistancy and initialize a Private Key Object
|
||||
*/
|
||||
static CK_RV
|
||||
sftk_handlePrivateKeyObject(SFTKSession *session, SFTKObject *object, CK_KEY_TYPE key_type)
|
||||
{
|
||||
CK_BBOOL cktrue = CK_TRUE;
|
||||
- CK_BBOOL encrypt = CK_TRUE;
|
||||
+ CK_BBOOL encrypt = CK_FALSE;
|
||||
CK_BBOOL sign = CK_FALSE;
|
||||
- CK_BBOOL recover = CK_TRUE;
|
||||
- CK_BBOOL wrap = CK_TRUE;
|
||||
- CK_BBOOL derive = CK_TRUE;
|
||||
+ CK_BBOOL recover = CK_FALSE;
|
||||
+ CK_BBOOL wrap = CK_FALSE;
|
||||
+ CK_BBOOL derive = CK_FALSE;
|
||||
CK_BBOOL decapsulate = CK_FALSE;
|
||||
CK_BBOOL ckfalse = CK_FALSE;
|
||||
PRBool createObjectInfo = PR_TRUE;
|
||||
PRBool fillPrivateKey = PR_FALSE;
|
||||
CK_ULONG paramSet = 0;
|
||||
int missing_rsa_mod_component = 0;
|
||||
int missing_rsa_exp_component = 0;
|
||||
int missing_rsa_crt_component = 0;
|
||||
@@ -1300,71 +1285,74 @@ sftk_handlePrivateKeyObject(SFTKSession
|
||||
crv = sftk_forceAttribute(object, CKA_NSS_DB,
|
||||
sftk_item_expand(&mod));
|
||||
if (mod.data)
|
||||
SECITEM_ZfreeItem(&mod, PR_FALSE);
|
||||
if (crv != CKR_OK)
|
||||
return crv;
|
||||
|
||||
sign = CK_TRUE;
|
||||
- derive = CK_FALSE;
|
||||
+ wrap = CK_TRUE;
|
||||
+ encrypt = CK_TRUE;
|
||||
break;
|
||||
case CKK_DSA:
|
||||
if (!sftk_hasAttribute(object, CKA_SUBPRIME)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
+ if (!sftk_hasAttribute(object, CKA_PRIME)) {
|
||||
+ return CKR_TEMPLATE_INCOMPLETE;
|
||||
+ }
|
||||
+ if (!sftk_hasAttribute(object, CKA_BASE)) {
|
||||
+ return CKR_TEMPLATE_INCOMPLETE;
|
||||
+ }
|
||||
+ if (!sftk_hasAttribute(object, CKA_VALUE)) {
|
||||
+ return CKR_TEMPLATE_INCOMPLETE;
|
||||
+ }
|
||||
sign = CK_TRUE;
|
||||
- derive = CK_FALSE;
|
||||
- /* fall through */
|
||||
+ break;
|
||||
case CKK_DH:
|
||||
if (!sftk_hasAttribute(object, CKA_PRIME)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
if (!sftk_hasAttribute(object, CKA_BASE)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
if (!sftk_hasAttribute(object, CKA_VALUE)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
/* allow subprime to be set after the fact */
|
||||
crv = sftk_defaultAttribute(object, CKA_SUBPRIME, NULL, 0);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
- encrypt = CK_FALSE;
|
||||
- recover = CK_FALSE;
|
||||
- wrap = CK_FALSE;
|
||||
+ derive = CK_TRUE;
|
||||
break;
|
||||
case CKK_EC:
|
||||
case CKK_EC_EDWARDS:
|
||||
case CKK_EC_MONTGOMERY:
|
||||
if (!sftk_hasAttribute(object, CKA_EC_PARAMS)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
if (!sftk_hasAttribute(object, CKA_VALUE)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
/* for ECDSA and EDDSA. Change if the structure of any of them is modified. */
|
||||
derive = (key_type == CKK_EC_EDWARDS) ? CK_FALSE : CK_TRUE; /* CK_TRUE for ECDH */
|
||||
sign = (key_type == CKK_EC_MONTGOMERY) ? CK_FALSE : CK_TRUE; /* for ECDSA and EDDSA */
|
||||
- encrypt = CK_FALSE;
|
||||
- recover = CK_FALSE;
|
||||
- wrap = CK_FALSE;
|
||||
break;
|
||||
case CKK_NSS_JPAKE_ROUND1:
|
||||
if (!sftk_hasAttribute(object, CKA_PRIME) ||
|
||||
!sftk_hasAttribute(object, CKA_SUBPRIME) ||
|
||||
!sftk_hasAttribute(object, CKA_BASE)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
/* fall through */
|
||||
case CKK_NSS_JPAKE_ROUND2:
|
||||
/* CKA_NSS_JPAKE_SIGNERID and CKA_NSS_JPAKE_PEERID are checked in
|
||||
the J-PAKE code. */
|
||||
- encrypt = sign = recover = wrap = CK_FALSE;
|
||||
derive = CK_TRUE;
|
||||
createObjectInfo = PR_FALSE;
|
||||
break;
|
||||
#ifndef NSS_DISABLE_KYBER
|
||||
case CKK_NSS_KYBER:
|
||||
#endif
|
||||
case CKK_NSS_ML_KEM:
|
||||
case CKK_ML_KEM:
|
||||
@@ -1374,17 +1362,16 @@ sftk_handlePrivateKeyObject(SFTKSession
|
||||
if (!sftk_hasAttribute(object, CKA_VALUE)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
if (!sftk_hasAttribute(object, CKA_PARAMETER_SET)) {
|
||||
if (!sftk_hasAttribute(object, CKA_NSS_PARAMETER_SET)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
}
|
||||
- encrypt = sign = recover = wrap = CK_FALSE;
|
||||
decapsulate = CK_TRUE;
|
||||
break;
|
||||
#ifdef NSS_ENABLE_ML_DSA
|
||||
case CKK_ML_DSA:
|
||||
if (!sftk_hasAttribute(object, CKA_KEY_TYPE)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
/* make sure we have a CKA_PARAMETER_SET */
|
||||
@@ -1452,17 +1439,16 @@ sftk_handlePrivateKeyObject(SFTKSession
|
||||
}
|
||||
}
|
||||
sftk_DeleteAttributeType(object, CKA_NSS_SEED_OK);
|
||||
/* if we got this far, we should have a CKA_VALUE, either but
|
||||
* one given to us, or by it being generated above */
|
||||
if (!sftk_hasAttribute(object, CKA_VALUE)) {
|
||||
return CKR_TEMPLATE_INCOMPLETE;
|
||||
}
|
||||
- encrypt = decapsulate = recover = wrap = CK_FALSE;
|
||||
sign = CK_TRUE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
}
|
||||
crv = sftk_defaultAttribute(object, CKA_SUBJECT, NULL, 0);
|
||||
if (crv != CKR_OK)
|
||||
diff --git a/lib/softoken/sftkdb.c b/lib/softoken/sftkdb.c
|
||||
--- a/lib/softoken/sftkdb.c
|
||||
+++ b/lib/softoken/sftkdb.c
|
||||
@@ -54,16 +54,17 @@ sftkdb_isULONGAttribute(CK_ATTRIBUTE_TYP
|
||||
case CKA_KEY_GEN_MECHANISM:
|
||||
case CKA_KEY_TYPE:
|
||||
case CKA_MECHANISM_TYPE:
|
||||
case CKA_MODULUS_BITS:
|
||||
case CKA_PRIME_BITS:
|
||||
case CKA_SUBPRIME_BITS:
|
||||
case CKA_VALUE_BITS:
|
||||
case CKA_VALUE_LEN:
|
||||
+ case CKA_PARAMETER_SET:
|
||||
|
||||
case CKA_TRUST_DIGITAL_SIGNATURE:
|
||||
case CKA_TRUST_NON_REPUDIATION:
|
||||
case CKA_TRUST_KEY_ENCIPHERMENT:
|
||||
case CKA_TRUST_DATA_ENCIPHERMENT:
|
||||
case CKA_TRUST_KEY_AGREEMENT:
|
||||
case CKA_TRUST_KEY_CERT_SIGN:
|
||||
case CKA_TRUST_CRL_SIGN:
|
||||
@@ -386,17 +387,25 @@ sftkdb_fixupTemplateOut(CK_ATTRIBUTE *te
|
||||
CK_ULONG value;
|
||||
|
||||
value = sftk_SDBULong2ULong(ntemplate[i].pValue);
|
||||
if (length < sizeof(CK_ULONG)) {
|
||||
template[i].ulValueLen = -1;
|
||||
crv = CKR_BUFFER_TOO_SMALL;
|
||||
continue;
|
||||
}
|
||||
- PORT_Memcpy(template[i].pValue, &value, sizeof(CK_ULONG));
|
||||
+ /* handle the case where the CKA_PARAMETER_SET was
|
||||
+ * incorrectly encoded */
|
||||
+ if ((value > 0xff) &&
|
||||
+ (template[i].type == CKA_PARAMETER_SET)) {
|
||||
+ PORT_Memcpy(template[i].pValue, ntemplate[i].pValue,
|
||||
+ ntemplate[i].ulValueLen);
|
||||
+ } else {
|
||||
+ PORT_Memcpy(template[i].pValue, &value, sizeof(CK_ULONG));
|
||||
+ }
|
||||
}
|
||||
template[i].ulValueLen = sizeof(CK_ULONG);
|
||||
}
|
||||
}
|
||||
|
||||
/* if no data was retrieved, no need to process encrypted or signed
|
||||
* attributes */
|
||||
if ((template[i].pValue == NULL) || (template[i].ulValueLen == -1)) {
|
||||
@@ -1580,16 +1589,18 @@ sftkdb_DestroyObject(SFTKDBHandle *handl
|
||||
(void)sftkdb_DestroyAttributeSignature(handle, keydb, objectID,
|
||||
CKA_PRIME_2);
|
||||
(void)sftkdb_DestroyAttributeSignature(handle, keydb, objectID,
|
||||
CKA_EXPONENT_1);
|
||||
(void)sftkdb_DestroyAttributeSignature(handle, keydb, objectID,
|
||||
CKA_EXPONENT_2);
|
||||
(void)sftkdb_DestroyAttributeSignature(handle, keydb, objectID,
|
||||
CKA_COEFFICIENT);
|
||||
+ (void)sftkdb_DestroyAttributeSignature(handle, keydb, objectID,
|
||||
+ CKA_SEED);
|
||||
} else {
|
||||
keydb = SFTK_GET_SDB(handle->peerDB);
|
||||
}
|
||||
/* now destroy any authenticated attributes that may exist */
|
||||
(void)sftkdb_DestroyAttributeSignature(handle, keydb, objectID,
|
||||
CKA_MODULUS);
|
||||
(void)sftkdb_DestroyAttributeSignature(handle, keydb, objectID,
|
||||
CKA_PUBLIC_EXPONENT);
|
||||
diff --git a/lib/softoken/sftkpwd.c b/lib/softoken/sftkpwd.c
|
||||
--- a/lib/softoken/sftkpwd.c
|
||||
+++ b/lib/softoken/sftkpwd.c
|
||||
@@ -1205,16 +1205,17 @@ sftk_updateEncrypted(PLArenaPool *arena,
|
||||
CK_ATTRIBUTE_TYPE privAttrTypes[] = {
|
||||
CKA_VALUE,
|
||||
CKA_PRIVATE_EXPONENT,
|
||||
CKA_PRIME_1,
|
||||
CKA_PRIME_2,
|
||||
CKA_EXPONENT_1,
|
||||
CKA_EXPONENT_2,
|
||||
CKA_COEFFICIENT,
|
||||
+ CKA_SEED,
|
||||
};
|
||||
const CK_ULONG privAttrCount = sizeof(privAttrTypes) / sizeof(privAttrTypes[0]);
|
||||
|
||||
// We don't know what attributes this object has, so we update them one at a
|
||||
// time.
|
||||
unsigned int i;
|
||||
for (i = 0; i < privAttrCount; i++) {
|
||||
// Read the old attribute in the clear.
|
||||
21025
nss-3.118-ml-dsa-leancrypto.patch
Normal file
21025
nss-3.118-ml-dsa-leancrypto.patch
Normal file
File diff suppressed because it is too large
Load Diff
642
nss-3.118-ml-dsa-tls.patch
Normal file
642
nss-3.118-ml-dsa-tls.patch
Normal file
@ -0,0 +1,642 @@
|
||||
diff --git a/automation/abi-check/expected-report-libssl3.so.txt b/automation/abi-check/expected-report-libssl3.so.txt
|
||||
--- a/automation/abi-check/expected-report-libssl3.so.txt
|
||||
+++ b/automation/abi-check/expected-report-libssl3.so.txt
|
||||
@@ -0,0 +1,24 @@
|
||||
+
|
||||
+1 function with some indirect sub-type change:
|
||||
+
|
||||
+ [C]'function SECStatus SSL_ConfigServerCert(PRFileDesc*, CERTCertificate*, SECKEYPrivateKey*, const SSLExtraServerCertData*, unsigned int)' at sslcert.c:662:1 has some indirect sub-type changes:
|
||||
+ parameter 4 of type 'const SSLExtraServerCertData*' has sub-type changes:
|
||||
+ in pointed to type 'const SSLExtraServerCertData':
|
||||
+ in unqualified underlying type 'typedef SSLExtraServerCertData' at sslt.h:310:1:
|
||||
+ underlying type 'struct SSLExtraServerCertDataStr' at sslt.h:269:1 changed:
|
||||
+ type size hasn't changed
|
||||
+ 1 data member change:
|
||||
+ type of 'SSLAuthType SSLExtraServerCertDataStr::authType' changed:
|
||||
+ underlying type 'enum __anonymous_enum__' at sslt.h:176:1 changed:
|
||||
+ type size hasn't changed
|
||||
+ 3 enumerator insertions:
|
||||
+ '__anonymous_enum__::ssl_auth_mldsa44' value '11'
|
||||
+ '__anonymous_enum__::ssl_auth_mldsa65' value '12'
|
||||
+ '__anonymous_enum__::ssl_auth_mldsa87' value '13'
|
||||
+
|
||||
+ 1 enumerator change:
|
||||
+ '__anonymous_enum__::ssl_auth_size' from value '11' to '14' at sslt.h:180:1
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
|
||||
--- a/lib/ssl/ssl3con.c
|
||||
+++ b/lib/ssl/ssl3con.c
|
||||
@@ -69,10 +69,11 @@
|
||||
static CK_MECHANISM_TYPE ssl3_GetMgfMechanismByHashType(SSLHashType hash);
|
||||
PRBool ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme);
|
||||
PRBool ssl_IsRsaeSignatureScheme(SSLSignatureScheme scheme);
|
||||
PRBool ssl_IsRsaPkcs1SignatureScheme(SSLSignatureScheme scheme);
|
||||
PRBool ssl_IsDsaSignatureScheme(SSLSignatureScheme scheme);
|
||||
+PRBool ssl_IsMldsaSignatureScheme(SSLSignatureScheme scheme);
|
||||
static SECStatus ssl3_UpdateDefaultHandshakeHashes(sslSocket *ss,
|
||||
const unsigned char *b,
|
||||
unsigned int l);
|
||||
const PRUint32 kSSLSigSchemePolicy =
|
||||
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_ANY_SIGNATURE;
|
||||
@@ -203,11 +204,14 @@
|
||||
ssl_sig_rsa_pkcs1_sha512,
|
||||
ssl_sig_rsa_pkcs1_sha1,
|
||||
ssl_sig_dsa_sha256,
|
||||
ssl_sig_dsa_sha384,
|
||||
ssl_sig_dsa_sha512,
|
||||
- ssl_sig_dsa_sha1
|
||||
+ ssl_sig_dsa_sha1,
|
||||
+ ssl_sig_mldsa44,
|
||||
+ ssl_sig_mldsa65,
|
||||
+ ssl_sig_mldsa87,
|
||||
};
|
||||
PR_STATIC_ASSERT(PR_ARRAY_SIZE(defaultSignatureSchemes) <=
|
||||
MAX_SIGNATURE_SCHEMES);
|
||||
|
||||
/* Verify that SSL_ImplementedCiphers and cipherSuites are in consistent order.
|
||||
@@ -361,11 +365,14 @@
|
||||
CKM_ECDH1_DERIVE, /* ssl_auth_ecdh_rsa */
|
||||
CKM_ECDH1_DERIVE, /* ssl_auth_ecdh_ecdsa */
|
||||
CKM_RSA_PKCS, /* ssl_auth_rsa_sign */
|
||||
CKM_RSA_PKCS_PSS, /* ssl_auth_rsa_pss */
|
||||
CKM_HKDF_DATA, /* ssl_auth_psk (just check for HKDF) */
|
||||
- CKM_INVALID_MECHANISM /* ssl_auth_tls13_any */
|
||||
+ CKM_INVALID_MECHANISM, /* ssl_auth_tls13_any */
|
||||
+ CKM_ML_DSA, /* ssl_auth_mldsa44 */
|
||||
+ CKM_ML_DSA, /* ssl_auth_mldsa65 */
|
||||
+ CKM_ML_DSA, /* ssl_auth_mldsa87 */
|
||||
};
|
||||
PR_STATIC_ASSERT(PR_ARRAY_SIZE(auth_alg_defs) == ssl_auth_size);
|
||||
|
||||
static const CK_MECHANISM_TYPE kea_alg_defs[] = {
|
||||
CKM_INVALID_MECHANISM, /* ssl_kea_null */
|
||||
@@ -917,10 +924,18 @@
|
||||
{
|
||||
PRCList *cursor;
|
||||
if (authType == ssl_auth_null || authType == ssl_auth_psk || authType == ssl_auth_tls13_any) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
+ /* mldsa is only supported in TLS 1.3 or greater */
|
||||
+ if (maxVersion < SSL_LIBRARY_VERSION_TLS_1_3 &&
|
||||
+ (authType == ssl_auth_mldsa44 ||
|
||||
+ authType == ssl_auth_mldsa65 ||
|
||||
+ authType == ssl_auth_mldsa87)) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+
|
||||
for (cursor = PR_NEXT_LINK(&ss->serverCerts);
|
||||
cursor != &ss->serverCerts;
|
||||
cursor = PR_NEXT_LINK(cursor)) {
|
||||
sslServerCert *cert = (sslServerCert *)cursor;
|
||||
if (!cert->serverKeyPair ||
|
||||
@@ -989,19 +1004,28 @@
|
||||
}
|
||||
|
||||
/* Check that a signature scheme is accepted.
|
||||
* Both by policy and by having a token that supports it. */
|
||||
static PRBool
|
||||
-ssl_SignatureSchemeAccepted(PRUint16 minVersion,
|
||||
+ssl_SignatureSchemeAccepted(PRUint16 maxVersion,
|
||||
+ PRUint16 minVersion,
|
||||
SSLSignatureScheme scheme,
|
||||
PRBool forCert)
|
||||
{
|
||||
/* Disable RSA-PSS schemes if there are no tokens to verify them. */
|
||||
if (ssl_IsRsaPssSignatureScheme(scheme)) {
|
||||
if (!PK11_TokenExists(auth_alg_defs[ssl_auth_rsa_pss])) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
+ } else if (ssl_IsMldsaSignatureScheme(scheme)) {
|
||||
+ /* ML-DSA: only in TLS 1.3 and later. */
|
||||
+ if (maxVersion < SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ if (!PK11_TokenExists(auth_alg_defs[ssl_auth_mldsa44])) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
} else if (!forCert && ssl_IsRsaPkcs1SignatureScheme(scheme)) {
|
||||
/* Disable PKCS#1 signatures if we are limited to TLS 1.3.
|
||||
* We still need to advertise PKCS#1 signatures in CH and CR
|
||||
* for certificate signatures.
|
||||
*/
|
||||
@@ -1046,11 +1070,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure that there is a signature scheme that can be accepted.*/
|
||||
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
|
||||
- if (ssl_SignatureSchemeAccepted(ss->vrange.min,
|
||||
+ if (ssl_SignatureSchemeAccepted(ss->vrange.max, ss->vrange.min,
|
||||
ss->ssl3.signatureSchemes[i],
|
||||
PR_FALSE /* forCert */)) {
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
@@ -1077,11 +1101,12 @@
|
||||
SSLSignatureScheme scheme = ss->ssl3.signatureSchemes[i];
|
||||
SSLAuthType schemeAuthType = ssl_SignatureSchemeToAuthType(scheme);
|
||||
PRBool acceptable = authType == schemeAuthType ||
|
||||
(schemeAuthType == ssl_auth_rsa_pss &&
|
||||
authType == ssl_auth_rsa_sign);
|
||||
- if (acceptable && ssl_SignatureSchemeAccepted(ss->version, scheme, PR_FALSE /* forCert */)) {
|
||||
+ if (acceptable && ssl_SignatureSchemeAccepted(ss->version, ss->version,
|
||||
+ scheme, PR_FALSE /* forCert */)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
@@ -3569,10 +3594,11 @@
|
||||
case ssl_hash_none:
|
||||
/* ssl_hash_none is for pre-1.2 suites, which use SHA-256. */
|
||||
return CKM_SHA256;
|
||||
case ssl_hash_sha1:
|
||||
return CKM_SHA_1;
|
||||
+ /* don't return a mechansim for ml_dsa hashes */
|
||||
default:
|
||||
PORT_Assert(0);
|
||||
}
|
||||
return CKM_SHA256;
|
||||
}
|
||||
@@ -4525,10 +4551,16 @@
|
||||
return SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
|
||||
case ssl_auth_ecdsa:
|
||||
return SEC_OID_ANSIX962_EC_PUBLIC_KEY;
|
||||
case ssl_auth_dsa:
|
||||
return SEC_OID_ANSIX9_DSA_SIGNATURE;
|
||||
+ case ssl_auth_mldsa44:
|
||||
+ return SEC_OID_ML_DSA_44;
|
||||
+ case ssl_auth_mldsa65:
|
||||
+ return SEC_OID_ML_DSA_65;
|
||||
+ case ssl_auth_mldsa87:
|
||||
+ return SEC_OID_ML_DSA_87;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* shouldn't ever get there */
|
||||
PORT_Assert(0);
|
||||
@@ -4561,10 +4593,14 @@
|
||||
case ssl_sig_rsa_pss_pss_sha512:
|
||||
case ssl_sig_dsa_sha512:
|
||||
return ssl_hash_sha512;
|
||||
case ssl_sig_rsa_pkcs1_sha1md5:
|
||||
return ssl_hash_none; /* Special for TLS 1.0/1.1. */
|
||||
+ case ssl_sig_mldsa44:
|
||||
+ case ssl_sig_mldsa65:
|
||||
+ case ssl_sig_mldsa87:
|
||||
+ return ssl_hash_none; /* ml_dsa does no hashing */
|
||||
case ssl_sig_none:
|
||||
case ssl_sig_ed25519:
|
||||
case ssl_sig_ed448:
|
||||
break;
|
||||
}
|
||||
@@ -4613,14 +4649,38 @@
|
||||
return PR_FALSE;
|
||||
}
|
||||
/* With TLS 1.3, EC keys should have been selected based on calling
|
||||
* ssl_SignatureSchemeFromSpki(), reject them otherwise. */
|
||||
return spkiOid != SEC_OID_ANSIX962_EC_PUBLIC_KEY;
|
||||
+ } else {
|
||||
+ if (ssl_IsMldsaSignatureScheme(scheme)) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
+/* some schmemes match 1 for 1 to oids, for those schemes, we
|
||||
+ * can return the oid directly. If this function return ssl_sig_none,
|
||||
+ * it means the oid doesn't match a scheme or matches more than one
|
||||
+ * scheme */
|
||||
+SSLSignatureScheme
|
||||
+ssl_SignatureSchemeFromPublicKeyOid(SECOidTag tag)
|
||||
+{
|
||||
+ switch (tag) {
|
||||
+ case SEC_OID_ML_DSA_44:
|
||||
+ return ssl_sig_mldsa44;
|
||||
+ case SEC_OID_ML_DSA_65:
|
||||
+ return ssl_sig_mldsa65;
|
||||
+ case SEC_OID_ML_DSA_87:
|
||||
+ return ssl_sig_mldsa87;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ return ssl_sig_none;
|
||||
+}
|
||||
+
|
||||
static SECStatus
|
||||
ssl_SignatureSchemeFromPssSpki(const CERTSubjectPublicKeyInfo *spki,
|
||||
SSLSignatureScheme *scheme)
|
||||
{
|
||||
SECKEYRSAPSSParams pssParam = { 0 };
|
||||
@@ -4709,22 +4769,27 @@
|
||||
ssl_SignatureSchemeFromSpki(const CERTSubjectPublicKeyInfo *spki,
|
||||
PRBool isTls13, SSLSignatureScheme *scheme)
|
||||
{
|
||||
SECOidTag spkiOid = SECOID_GetAlgorithmTag(&spki->algorithm);
|
||||
|
||||
- if (spkiOid == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
|
||||
- return ssl_SignatureSchemeFromPssSpki(spki, scheme);
|
||||
- }
|
||||
-
|
||||
- /* Only do this lookup for TLS 1.3, where the scheme can be determined from
|
||||
- * the SPKI alone because the ECDSA key size determines the hash. Earlier
|
||||
- * TLS versions allow the same EC key to be used with different hashes. */
|
||||
- if (isTls13 && spkiOid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) {
|
||||
- return ssl_SignatureSchemeFromEcSpki(spki, scheme);
|
||||
- }
|
||||
-
|
||||
*scheme = ssl_sig_none;
|
||||
+ switch (spkiOid) {
|
||||
+ case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
|
||||
+ return ssl_SignatureSchemeFromPssSpki(spki, scheme);
|
||||
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
|
||||
+ /* Only do this lookup for TLS 1.3, where the scheme can be
|
||||
+ * determined from the SPKI alone because the ECDSA key size
|
||||
+ * determines the hash. Earlier TLS versions allow the same
|
||||
+ * EC key to be used with different hashes. */
|
||||
+ if (isTls13) {
|
||||
+ return ssl_SignatureSchemeFromEcSpki(spki, scheme);
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ *scheme = ssl_SignatureSchemeFromPublicKeyOid(spkiOid);
|
||||
+ break;
|
||||
+ }
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* Check that a signature scheme is enabled by configuration. */
|
||||
PRBool
|
||||
@@ -4826,10 +4891,13 @@
|
||||
case ssl_sig_rsa_pss_pss_sha384:
|
||||
case ssl_sig_rsa_pss_pss_sha512:
|
||||
case ssl_sig_ecdsa_secp256r1_sha256:
|
||||
case ssl_sig_ecdsa_secp384r1_sha384:
|
||||
case ssl_sig_ecdsa_secp521r1_sha512:
|
||||
+ case ssl_sig_mldsa44:
|
||||
+ case ssl_sig_mldsa65:
|
||||
+ case ssl_sig_mldsa87:
|
||||
case ssl_sig_dsa_sha1:
|
||||
case ssl_sig_dsa_sha256:
|
||||
case ssl_sig_dsa_sha384:
|
||||
case ssl_sig_dsa_sha512:
|
||||
case ssl_sig_ecdsa_sha1:
|
||||
@@ -4908,10 +4976,25 @@
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
+PRBool
|
||||
+ssl_IsMldsaSignatureScheme(SSLSignatureScheme scheme)
|
||||
+{
|
||||
+ switch (scheme) {
|
||||
+ case ssl_sig_mldsa44:
|
||||
+ case ssl_sig_mldsa65:
|
||||
+ case ssl_sig_mldsa87:
|
||||
+ return PR_TRUE;
|
||||
+
|
||||
+ default:
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ return PR_FALSE;
|
||||
+}
|
||||
+
|
||||
SSLAuthType
|
||||
ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme)
|
||||
{
|
||||
switch (scheme) {
|
||||
case ssl_sig_rsa_pkcs1_sha1:
|
||||
@@ -4936,10 +5019,21 @@
|
||||
case ssl_sig_dsa_sha1:
|
||||
case ssl_sig_dsa_sha256:
|
||||
case ssl_sig_dsa_sha384:
|
||||
case ssl_sig_dsa_sha512:
|
||||
return ssl_auth_dsa;
|
||||
+ /* while there is one mechanism for ML-DSA,
|
||||
+ * server cert selection depends on which
|
||||
+ * flavor (paramset) is being used, so
|
||||
+ * we need one auth foreach param set.
|
||||
+ */
|
||||
+ case ssl_sig_mldsa44:
|
||||
+ return ssl_auth_mldsa44;
|
||||
+ case ssl_sig_mldsa65:
|
||||
+ return ssl_auth_mldsa65;
|
||||
+ case ssl_sig_mldsa87:
|
||||
+ return ssl_auth_mldsa87;
|
||||
|
||||
default:
|
||||
PORT_Assert(0);
|
||||
}
|
||||
return ssl_auth_null;
|
||||
@@ -10490,17 +10584,18 @@
|
||||
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
-ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool forCert,
|
||||
- PRBool grease, sslBuffer *buf)
|
||||
+ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 maxVersion, PRUint16 minVersion,
|
||||
+ PRBool forCert, PRBool grease, sslBuffer *buf)
|
||||
{
|
||||
SSLSignatureScheme filtered[MAX_SIGNATURE_SCHEMES] = { 0 };
|
||||
unsigned int filteredCount = 0;
|
||||
|
||||
- SECStatus rv = ssl3_FilterSigAlgs(ss, minVersion, PR_FALSE, forCert,
|
||||
+ SECStatus rv = ssl3_FilterSigAlgs(ss, maxVersion, minVersion,
|
||||
+ PR_FALSE, forCert,
|
||||
PR_ARRAY_SIZE(filtered),
|
||||
filtered, &filteredCount);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
@@ -10573,12 +10668,12 @@
|
||||
* requires that PKCS#1 schemes are placed last in the list if they
|
||||
* are present. This sorting can be removed once we support
|
||||
* signature_algorithms_cert.
|
||||
*/
|
||||
SECStatus
|
||||
-ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool disableRsae,
|
||||
- PRBool forCert,
|
||||
+ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 maxVersion, PRUint16 minVersion,
|
||||
+ PRBool disableRsae, PRBool forCert,
|
||||
unsigned int maxSchemes, SSLSignatureScheme *filteredSchemes,
|
||||
unsigned int *numFilteredSchemes)
|
||||
{
|
||||
PORT_Assert(filteredSchemes);
|
||||
PORT_Assert(numFilteredSchemes);
|
||||
@@ -10591,25 +10686,25 @@
|
||||
PRBool allowUnsortedPkcs1 = forCert && minVersion < SSL_LIBRARY_VERSION_TLS_1_3;
|
||||
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
|
||||
if (disableRsae && ssl_IsRsaeSignatureScheme(ss->ssl3.signatureSchemes[i])) {
|
||||
continue;
|
||||
}
|
||||
- if (ssl_SignatureSchemeAccepted(minVersion,
|
||||
+ if (ssl_SignatureSchemeAccepted(maxVersion, minVersion,
|
||||
ss->ssl3.signatureSchemes[i],
|
||||
allowUnsortedPkcs1)) {
|
||||
filteredSchemes[(*numFilteredSchemes)++] = ss->ssl3.signatureSchemes[i];
|
||||
}
|
||||
}
|
||||
if (forCert && !allowUnsortedPkcs1) {
|
||||
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
|
||||
if (disableRsae && ssl_IsRsaeSignatureScheme(ss->ssl3.signatureSchemes[i])) {
|
||||
continue;
|
||||
}
|
||||
- if (!ssl_SignatureSchemeAccepted(minVersion,
|
||||
+ if (!ssl_SignatureSchemeAccepted(maxVersion, minVersion,
|
||||
ss->ssl3.signatureSchemes[i],
|
||||
PR_FALSE) &&
|
||||
- ssl_SignatureSchemeAccepted(minVersion,
|
||||
+ ssl_SignatureSchemeAccepted(maxVersion, minVersion,
|
||||
ss->ssl3.signatureSchemes[i],
|
||||
PR_TRUE)) {
|
||||
filteredSchemes[(*numFilteredSchemes)++] = ss->ssl3.signatureSchemes[i];
|
||||
}
|
||||
}
|
||||
@@ -10648,11 +10743,11 @@
|
||||
certTypes = certificate_types;
|
||||
certTypesLength = sizeof certificate_types;
|
||||
|
||||
length = 1 + certTypesLength + 2 + calen;
|
||||
if (isTLS12) {
|
||||
- rv = ssl3_EncodeSigAlgs(ss, ss->version, PR_TRUE /* forCert */,
|
||||
+ rv = ssl3_EncodeSigAlgs(ss, ss->version, ss->version, PR_TRUE /* forCert */,
|
||||
PR_FALSE /* GREASE */, &sigAlgsBuf);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
length += SSL_BUFFER_LEN(&sigAlgsBuf);
|
||||
@@ -11854,10 +11949,15 @@
|
||||
/* Don't check EC strength here on the understanding that we
|
||||
* only support curves we like. */
|
||||
minKey = ss->sec.authKeyBits;
|
||||
}
|
||||
break;
|
||||
+ case mldsaKey:
|
||||
+ /* ML DSA has fixed sizes per param set and are handled by
|
||||
+ * separate policy oids for each param set */
|
||||
+ minKey = ss->sec.authKeyBits;
|
||||
+ break;
|
||||
|
||||
default:
|
||||
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
|
||||
return SECFailure;
|
||||
}
|
||||
diff --git a/lib/ssl/ssl3exthandle.c b/lib/ssl/ssl3exthandle.c
|
||||
--- a/lib/ssl/ssl3exthandle.c
|
||||
+++ b/lib/ssl/ssl3exthandle.c
|
||||
@@ -1653,17 +1653,21 @@
|
||||
if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_2) {
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
PRUint16 minVersion;
|
||||
+ PRUint16 maxVersion;
|
||||
if (ss->sec.isServer) {
|
||||
+ maxVersion = ss->version; /* CertificateRequest */
|
||||
minVersion = ss->version; /* CertificateRequest */
|
||||
} else {
|
||||
+ maxVersion = ss->vrange.max; /* ClientHello */
|
||||
minVersion = ss->vrange.min; /* ClientHello */
|
||||
}
|
||||
|
||||
- SECStatus rv = ssl3_EncodeSigAlgs(ss, minVersion, PR_TRUE /* forCert */,
|
||||
+ SECStatus rv = ssl3_EncodeSigAlgs(ss, maxVersion, minVersion,
|
||||
+ PR_TRUE /* forCert */,
|
||||
ss->opt.enableGrease, buf);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
diff --git a/lib/ssl/sslcert.c b/lib/ssl/sslcert.c
|
||||
--- a/lib/ssl/sslcert.c
|
||||
+++ b/lib/ssl/sslcert.c
|
||||
@@ -568,10 +568,27 @@
|
||||
if (cert->keyUsage & KU_KEY_ENCIPHERMENT) {
|
||||
authTypes |= 1 << ssl_GetEcdhAuthType(cert);
|
||||
}
|
||||
break;
|
||||
|
||||
+ case SEC_OID_ML_DSA_44:
|
||||
+ if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
|
||||
+ authTypes |= 1 << ssl_auth_mldsa44;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case SEC_OID_ML_DSA_65:
|
||||
+ if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
|
||||
+ authTypes |= 1 << ssl_auth_mldsa65;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case SEC_OID_ML_DSA_87:
|
||||
+ if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
|
||||
+ authTypes |= 1 << ssl_auth_mldsa87;
|
||||
+ }
|
||||
+
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check that we successfully picked an authType */
|
||||
@@ -729,10 +746,19 @@
|
||||
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
|
||||
mask |= 1 << ssl_auth_ecdsa;
|
||||
mask |= 1 << ssl_auth_ecdh_rsa;
|
||||
mask |= 1 << ssl_auth_ecdh_ecdsa;
|
||||
break;
|
||||
+ case SEC_OID_ML_DSA_44:
|
||||
+ mask |= 1 << ssl_auth_mldsa44;
|
||||
+ break;
|
||||
+ case SEC_OID_ML_DSA_65:
|
||||
+ mask |= 1 << ssl_auth_mldsa65;
|
||||
+ break;
|
||||
+ case SEC_OID_ML_DSA_87:
|
||||
+ mask |= 1 << ssl_auth_mldsa87;
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
PORT_Assert(authTypes);
|
||||
/* Simply test that no inappropriate auth types are set. */
|
||||
diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
|
||||
--- a/lib/ssl/sslimpl.h
|
||||
+++ b/lib/ssl/sslimpl.h
|
||||
@@ -1746,16 +1746,18 @@
|
||||
SECStatus ssl_SetAuthKeyBits(sslSocket *ss, const SECKEYPublicKey *pubKey);
|
||||
SECStatus ssl3_HandleServerSpki(sslSocket *ss);
|
||||
SECStatus ssl3_AuthCertificate(sslSocket *ss);
|
||||
SECStatus ssl_ReadCertificateStatus(sslSocket *ss, PRUint8 *b,
|
||||
PRUint32 length);
|
||||
-SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool forCert,
|
||||
+SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 maxVersion,
|
||||
+ PRUint16 minVersion, PRBool forCert,
|
||||
PRBool grease, sslBuffer *buf);
|
||||
SECStatus ssl3_EncodeFilteredSigAlgs(const sslSocket *ss,
|
||||
const SSLSignatureScheme *schemes,
|
||||
PRUint32 numSchemes, PRBool grease, sslBuffer *buf);
|
||||
-SECStatus ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool disableRsae, PRBool forCert,
|
||||
+SECStatus ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 maxVersion, PRUint16 minVersion,
|
||||
+ PRBool disableRsae, PRBool forCert,
|
||||
unsigned int maxSchemes, SSLSignatureScheme *filteredSchemes,
|
||||
unsigned int *numFilteredSchemes);
|
||||
SECStatus ssl_GetCertificateRequestCAs(const sslSocket *ss,
|
||||
unsigned int *calenp,
|
||||
const SECItem **namesp,
|
||||
@@ -1821,10 +1823,11 @@
|
||||
SECStatus ssl_InsertRecordHeader(const sslSocket *ss, ssl3CipherSpec *cwSpec,
|
||||
SSLContentType contentType, sslBuffer *wrBuf,
|
||||
PRBool *needsLength);
|
||||
PRBool ssl_SignatureSchemeValid(SSLSignatureScheme scheme, SECOidTag spkiOid,
|
||||
PRBool isTls13);
|
||||
+SSLSignatureScheme ssl_SignatureSchemeFromPublicKeyOid(SECOidTag tag);
|
||||
|
||||
/* Pull in DTLS functions */
|
||||
#include "dtlscon.h"
|
||||
|
||||
/* Pull in TLS 1.3 functions */
|
||||
diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h
|
||||
--- a/lib/ssl/sslt.h
|
||||
+++ b/lib/ssl/sslt.h
|
||||
@@ -154,10 +154,14 @@
|
||||
ssl_sig_dsa_sha256 = 0x0402,
|
||||
ssl_sig_dsa_sha384 = 0x0502,
|
||||
ssl_sig_dsa_sha512 = 0x0602,
|
||||
ssl_sig_ecdsa_sha1 = 0x0203,
|
||||
|
||||
+ ssl_sig_mldsa44 = 0x0904,
|
||||
+ ssl_sig_mldsa65 = 0x0905,
|
||||
+ ssl_sig_mldsa87 = 0x0906,
|
||||
+
|
||||
/* The following value (which can't be used in the protocol), represents
|
||||
* the RSA signature using SHA-1 and MD5 that is used in TLS 1.0 and 1.1.
|
||||
* This is reported as a signature scheme when TLS 1.0 or 1.1 is used.
|
||||
* This should not be passed to SSL_SignatureSchemePrefSet(); this
|
||||
* signature scheme is always used and cannot be disabled. */
|
||||
@@ -183,10 +187,13 @@
|
||||
ssl_auth_ecdh_ecdsa = 6, /* ECDH cert with an ECDSA signature. */
|
||||
ssl_auth_rsa_sign = 7, /* RSA signing with an rsaEncryption key. */
|
||||
ssl_auth_rsa_pss = 8, /* RSA signing with a PSS key. */
|
||||
ssl_auth_psk = 9,
|
||||
ssl_auth_tls13_any = 10,
|
||||
+ ssl_auth_mldsa44 = 11, /* use separate auth for each paramset */
|
||||
+ ssl_auth_mldsa65 = 12, /* so we can properly identify the certs */
|
||||
+ ssl_auth_mldsa87 = 13,
|
||||
ssl_auth_size /* number of authentication types */
|
||||
} SSLAuthType;
|
||||
|
||||
typedef enum {
|
||||
ssl_psk_none = 0,
|
||||
diff --git a/lib/ssl/tls13exthandle.c b/lib/ssl/tls13exthandle.c
|
||||
--- a/lib/ssl/tls13exthandle.c
|
||||
+++ b/lib/ssl/tls13exthandle.c
|
||||
@@ -1450,11 +1450,11 @@
|
||||
* the "advertised" list, then encode them to be sent. If we receive
|
||||
* a DC in response, validate that it matches one of the advertised
|
||||
* schemes. */
|
||||
SSLSignatureScheme filtered[MAX_SIGNATURE_SCHEMES] = { 0 };
|
||||
unsigned int filteredCount = 0;
|
||||
- SECStatus rv = ssl3_FilterSigAlgs(ss, ss->vrange.max,
|
||||
+ SECStatus rv = ssl3_FilterSigAlgs(ss, ss->vrange.max, ss->vrange.max,
|
||||
PR_TRUE /* disableRsae */,
|
||||
PR_FALSE /* forCert */,
|
||||
MAX_SIGNATURE_SCHEMES,
|
||||
filtered,
|
||||
&filteredCount);
|
||||
diff --git a/lib/ssl/tls13signature.c b/lib/ssl/tls13signature.c
|
||||
--- a/lib/ssl/tls13signature.c
|
||||
+++ b/lib/ssl/tls13signature.c
|
||||
@@ -55,10 +55,24 @@
|
||||
break;
|
||||
case ssl_sig_ecdsa_secp521r1_sha512:
|
||||
algTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE;
|
||||
hashAlgTag = SEC_OID_SHA512;
|
||||
break;
|
||||
+ /* ML-DSA fully defines the hash and sign algorithm,
|
||||
+ * we set the hash alg to the same as the sign alg. */
|
||||
+ case ssl_sig_mldsa44:
|
||||
+ algTag = SEC_OID_ML_DSA_44;
|
||||
+ hashAlgTag = SEC_OID_ML_DSA_44;
|
||||
+ break;
|
||||
+ case ssl_sig_mldsa65:
|
||||
+ algTag = SEC_OID_ML_DSA_65;
|
||||
+ hashAlgTag = SEC_OID_ML_DSA_65;
|
||||
+ break;
|
||||
+ case ssl_sig_mldsa87:
|
||||
+ algTag = SEC_OID_ML_DSA_87;
|
||||
+ hashAlgTag = SEC_OID_ML_DSA_87;
|
||||
+ break;
|
||||
|
||||
/* the following is unsupported in tls 1.3 and greater, just break.
|
||||
* We include them here explicitly so we get the compiler warning about
|
||||
* missing enums in the switch statement. default would be a break anyway.
|
||||
* That way we'll know to update this table when new algorithms are
|
||||
diff --git a/lib/ssl/tls13subcerts.c b/lib/ssl/tls13subcerts.c
|
||||
--- a/lib/ssl/tls13subcerts.c
|
||||
+++ b/lib/ssl/tls13subcerts.c
|
||||
@@ -649,11 +649,17 @@
|
||||
PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
|
||||
return NULL;
|
||||
}
|
||||
return SECKEY_CreateSubjectPublicKeyInfo(dcPub);
|
||||
}
|
||||
-
|
||||
+ case mldsaKey:
|
||||
+ if (ssl_SignatureSchemeFromPublicKeyOid(dcPub->u.mldsa.paramSet)
|
||||
+ != dcCertVerifyAlg) {
|
||||
+ PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ return SECKEY_CreateSubjectPublicKeyInfo(dcPub);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
PORT_SetError(SEC_ERROR_INVALID_KEY);
|
||||
|
||||
File diff suppressed because one or more lines are too long
29
nss-3.123-fix-mldsa-import-regeneration.patch
Normal file
29
nss-3.123-fix-mldsa-import-regeneration.patch
Normal file
@ -0,0 +1,29 @@
|
||||
--- a/lib/pk11wrap/pk11akey.c
|
||||
+++ b/lib/pk11wrap/pk11akey.c
|
||||
@@ -2145,7 +2145,7 @@
|
||||
PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
break;
|
||||
}
|
||||
- pubKey.u.mldsa.paramSet = SECKEY_GetMLDSAPkcs11ParamSetByOidTag(paramSet);
|
||||
+ pubKey.u.mldsa.paramSet = SECKEY_GetMLDSAOidTagByPkcs11ParamSet(paramSet);
|
||||
if (pubKey.u.mldsa.paramSet == SEC_OID_UNKNOWN) {
|
||||
PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
break;
|
||||
--- a/lib/softoken/pkcs11.c
|
||||
+++ b/lib/softoken/pkcs11.c
|
||||
@@ -1565,10 +1565,15 @@
|
||||
(PORT_Memcmp(valueAttribute->attrib.pValue,
|
||||
privKey.keyVal, valueLen) != 0)) {
|
||||
crv = CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
}
|
||||
}
|
||||
+ if (crv == CKR_OK && !sftk_hasAttribute(object, CKA_NSS_DB)) {
|
||||
+ crv = sftk_forceAttribute(object, CKA_NSS_DB,
|
||||
+ pubKey.keyVal,
|
||||
+ pubKey.keyValLen);
|
||||
+ }
|
||||
PORT_SafeZero(&privKey, sizeof(privKey));
|
||||
PORT_SafeZero(&pubKey, sizeof(pubKey));
|
||||
}
|
||||
if (valueAttribute)
|
||||
sftk_FreeAttribute(valueAttribute);
|
||||
489
nss-3.124-allow-hash-override-pss.patch
Normal file
489
nss-3.124-allow-hash-override-pss.patch
Normal file
@ -0,0 +1,489 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1781635239 25200
|
||||
# Tue Jun 16 11:40:39 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID c85110e0f7ba48ef44c9b535a9c3bccf78f8416d
|
||||
# Parent 4b0e3f33a2e76a77e36b435eb3cc1eb06f14249d
|
||||
nss-3.124-allow-hash-override-pss.patch
|
||||
|
||||
diff --git a/cmd/certutil/certutil.c b/cmd/certutil/certutil.c
|
||||
--- a/cmd/certutil/certutil.c
|
||||
+++ b/cmd/certutil/certutil.c
|
||||
@@ -228,16 +228,20 @@ CertReq(SECKEYPrivateKey *privk, SECKEYP
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Change cert type to RSA-PSS, if desired. */
|
||||
if (pssCertificate) {
|
||||
/* force a PSS signature. We can do a PSS signature with an
|
||||
* RSA key, this will force us to generate a PSS signature */
|
||||
signAlgTag = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
|
||||
+ /* we are reusing an algorithm id, prevent the assert when we try
|
||||
+ * to set the parameters of that algorithm id */
|
||||
+ spki->algorithm.parameters.data = NULL;
|
||||
+ spki->algorithm.parameters.len = 0;
|
||||
/* override the SPKI algorithm id. */
|
||||
rv = SEC_CreateSignatureAlgorithmID(arena, &spki->algorithm,
|
||||
signAlgTag, hashAlgTag,
|
||||
NULL, NULL, pubk);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
SECKEY_DestroySubjectPublicKeyInfo(spki);
|
||||
SECU_PrintError(progName, "unable to set algorithm ID");
|
||||
diff --git a/gtests/cryptohi_gtest/cryptohi_unittest.cc b/gtests/cryptohi_gtest/cryptohi_unittest.cc
|
||||
--- a/gtests/cryptohi_gtest/cryptohi_unittest.cc
|
||||
+++ b/gtests/cryptohi_gtest/cryptohi_unittest.cc
|
||||
@@ -105,17 +105,17 @@ class SignParamsTestF : public ::testing
|
||||
SECItem *saltLengthItem =
|
||||
SEC_ASN1EncodeInteger(arena_.get(), ¶ms->saltLength, saltLength);
|
||||
ASSERT_EQ(¶ms->saltLength, saltLengthItem);
|
||||
}
|
||||
|
||||
void CheckHashAlg(SECKEYRSAPSSParams *params, SECOidTag hashAlgTag) {
|
||||
// If hash algorithm is SHA-1, it must be omitted in the parameters
|
||||
if (hashAlgTag == SEC_OID_SHA1) {
|
||||
- EXPECT_EQ(nullptr, params->hashAlg);
|
||||
+ EXPECT_EQ(nullptr, params->hashAlg) << "oid==" << SECOID_FindOIDTagDescription(SECOID_GetAlgorithmTag(params->hashAlg));
|
||||
} else {
|
||||
EXPECT_NE(nullptr, params->hashAlg);
|
||||
EXPECT_EQ(hashAlgTag, SECOID_GetAlgorithmTag(params->hashAlg));
|
||||
}
|
||||
}
|
||||
|
||||
void CheckMaskAlg(SECKEYRSAPSSParams *params, SECOidTag hashAlgTag) {
|
||||
SECStatus rv;
|
||||
@@ -225,22 +225,16 @@ TEST_P(SignParamsTest, CreateRsaPss) {
|
||||
} else {
|
||||
srcParams = NULL;
|
||||
}
|
||||
|
||||
SECItem *params = SEC_CreateSignatureAlgorithmParameters(
|
||||
arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg,
|
||||
srcParams, privk_.get());
|
||||
|
||||
- if (hashAlg != SEC_OID_UNKNOWN && srcHashAlg != SEC_OID_UNKNOWN &&
|
||||
- hashAlg != srcHashAlg) {
|
||||
- EXPECT_EQ(nullptr, params);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
EXPECT_NE(nullptr, params);
|
||||
|
||||
SECKEYRSAPSSParams pssParams;
|
||||
PORT_Memset(&pssParams, 0, sizeof(pssParams));
|
||||
SECStatus rv =
|
||||
SEC_QuickDERDecodeItem(arena_.get(), &pssParams,
|
||||
SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate), params);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
@@ -294,83 +288,100 @@ TEST_P(SignParamsTest, CreateRsaPssWithE
|
||||
|
||||
TEST_P(SignParamsTest, CreateRsaPssWithInvalidHashAlg) {
|
||||
SECOidTag srcHashAlg = std::get<1>(GetParam());
|
||||
|
||||
SECItem *srcParams;
|
||||
if (srcHashAlg != SEC_OID_UNKNOWN) {
|
||||
SECKEYRSAPSSParams pssParams;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
- CreatePssParams(&pssParams, srcHashAlg, srcHashAlg));
|
||||
+ CreatePssParams(&pssParams, SEC_OID_MD5, SEC_OID_MD5));
|
||||
srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams,
|
||||
SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate));
|
||||
ASSERT_NE(nullptr, srcParams);
|
||||
} else {
|
||||
srcParams = NULL;
|
||||
}
|
||||
|
||||
SECItem *params = SEC_CreateSignatureAlgorithmParameters(
|
||||
- arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, SEC_OID_MD5,
|
||||
+ arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, srcHashAlg,
|
||||
srcParams, privk_.get());
|
||||
|
||||
- EXPECT_EQ(nullptr, params);
|
||||
+ /* override invalid hash with valid hash */
|
||||
+ EXPECT_NE(nullptr, params);
|
||||
+ /* assert params ->hashAlg != SEC_OID_MD5 */
|
||||
}
|
||||
|
||||
TEST_P(SignParamsSourceTest, CreateRsaPssWithInvalidHashAlg) {
|
||||
SECOidTag hashAlg = GetParam();
|
||||
|
||||
SECItem *srcParams;
|
||||
SECKEYRSAPSSParams pssParams;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
- CreatePssParams(&pssParams, SEC_OID_MD5, SEC_OID_MD5));
|
||||
+ CreatePssParams(&pssParams, hashAlg, hashAlg));
|
||||
srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams,
|
||||
SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate));
|
||||
ASSERT_NE(nullptr, srcParams);
|
||||
|
||||
SECItem *params = SEC_CreateSignatureAlgorithmParameters(
|
||||
- arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg,
|
||||
+ arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, SEC_OID_MD4,
|
||||
srcParams, privk_.get());
|
||||
|
||||
EXPECT_EQ(nullptr, params);
|
||||
}
|
||||
|
||||
TEST_P(SignParamsSourceTest, CreateRsaPssWithInvalidSaltLength) {
|
||||
SECOidTag hashAlg = GetParam();
|
||||
|
||||
SECItem *srcParams;
|
||||
SECKEYRSAPSSParams pssParams;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
- CreatePssParams(&pssParams, SEC_OID_SHA512, SEC_OID_SHA512, 100));
|
||||
+ CreatePssParams(&pssParams, SEC_OID_SHA512, SEC_OID_SHA512, 110));
|
||||
srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams,
|
||||
SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate));
|
||||
ASSERT_NE(nullptr, srcParams);
|
||||
|
||||
SECItem *params = SEC_CreateSignatureAlgorithmParameters(
|
||||
arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg,
|
||||
srcParams, privk_.get());
|
||||
|
||||
EXPECT_EQ(nullptr, params);
|
||||
}
|
||||
|
||||
TEST_P(SignParamsSourceTest, CreateRsaPssWithHashMismatch) {
|
||||
SECOidTag hashAlg = GetParam();
|
||||
|
||||
SECItem *srcParams;
|
||||
SECKEYRSAPSSParams pssParams;
|
||||
+ if ((hashAlg == SEC_OID_UNKNOWN) || (hashAlg == SEC_OID_SHA512)) {
|
||||
+ hashAlg = SEC_OID_SHA1;
|
||||
+ }
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
- CreatePssParams(&pssParams, SEC_OID_SHA256, SEC_OID_SHA512));
|
||||
+ CreatePssParams(&pssParams, hashAlg, SEC_OID_SHA512));
|
||||
srcParams = SEC_ASN1EncodeItem(arena_.get(), nullptr, &pssParams,
|
||||
SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate));
|
||||
ASSERT_NE(nullptr, srcParams);
|
||||
|
||||
SECItem *params = SEC_CreateSignatureAlgorithmParameters(
|
||||
- arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg,
|
||||
+ arena_.get(), nullptr, SEC_OID_PKCS1_RSA_PSS_SIGNATURE, SEC_OID_UNKNOWN,
|
||||
srcParams, privk_.get());
|
||||
|
||||
- EXPECT_EQ(nullptr, params);
|
||||
+ EXPECT_NE(nullptr, params);
|
||||
+
|
||||
+ PORT_Memset(&pssParams, 0, sizeof(pssParams));
|
||||
+ SECStatus rv =
|
||||
+ SEC_QuickDERDecodeItem(arena_.get(), &pssParams,
|
||||
+ SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate), params);
|
||||
+ ASSERT_EQ(SECSuccess, rv);
|
||||
+ ASSERT_NO_FATAL_FAILURE(CheckHashAlg(&pssParams, hashAlg));
|
||||
+ ASSERT_NO_FATAL_FAILURE(CheckMaskAlg(&pssParams, hashAlg));
|
||||
+ ASSERT_NO_FATAL_FAILURE(CheckSaltLength(&pssParams, hashAlg));
|
||||
+
|
||||
+ // The default trailer field (1) must be omitted
|
||||
+ EXPECT_EQ(nullptr, pssParams.trailerField.data);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SignParamsTestCases, SignParamsTest,
|
||||
::testing::Combine(::testing::Values(SEC_OID_UNKNOWN, SEC_OID_SHA1,
|
||||
SEC_OID_SHA224, SEC_OID_SHA256,
|
||||
SEC_OID_SHA384, SEC_OID_SHA512),
|
||||
::testing::Values(SEC_OID_UNKNOWN, SEC_OID_SHA1,
|
||||
diff --git a/lib/cryptohi/seckey.c b/lib/cryptohi/seckey.c
|
||||
--- a/lib/cryptohi/seckey.c
|
||||
+++ b/lib/cryptohi/seckey.c
|
||||
@@ -2876,21 +2876,23 @@ sec_DecodeRSAPSSParams(PLArenaPool *aren
|
||||
SECKEYRSAPSSParams pssParams;
|
||||
SECOidTag hashAlg;
|
||||
SECOidTag maskHashAlg;
|
||||
unsigned long saltLength;
|
||||
unsigned long trailerField;
|
||||
SECStatus rv;
|
||||
|
||||
PORT_Memset(&pssParams, 0, sizeof(pssParams));
|
||||
- rv = SEC_QuickDERDecodeItem(arena, &pssParams,
|
||||
- SECKEY_RSAPSSParamsTemplate,
|
||||
- params);
|
||||
- if (rv != SECSuccess) {
|
||||
- return rv;
|
||||
+ if (params && (params->len != 0)) {
|
||||
+ rv = SEC_QuickDERDecodeItem(arena, &pssParams,
|
||||
+ SECKEY_RSAPSSParamsTemplate,
|
||||
+ params);
|
||||
+ if (rv != SECSuccess) {
|
||||
+ return rv;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (pssParams.hashAlg) {
|
||||
hashAlg = SECOID_GetAlgorithmTag(pssParams.hashAlg);
|
||||
} else {
|
||||
hashAlg = SEC_OID_SHA1; /* default, SHA-1 */
|
||||
}
|
||||
|
||||
diff --git a/lib/cryptohi/secsign.c b/lib/cryptohi/secsign.c
|
||||
--- a/lib/cryptohi/secsign.c
|
||||
+++ b/lib/cryptohi/secsign.c
|
||||
@@ -814,16 +814,18 @@ sec_CreateRSAPSSParameters(PLArenaPool *
|
||||
SECOidTag hashAlgTag,
|
||||
const SECItem *params,
|
||||
int modBytes)
|
||||
{
|
||||
SECKEYRSAPSSParams pssParams;
|
||||
int hashLength;
|
||||
unsigned long saltLength;
|
||||
PRBool defaultSHA1 = PR_FALSE;
|
||||
+ PRBool overWriteHash = PR_TRUE;
|
||||
+ PRBool overWriteMask = PR_TRUE;
|
||||
SECStatus rv;
|
||||
|
||||
PORT_Memset(&pssParams, 0, sizeof(pssParams));
|
||||
|
||||
if (params && params->data) {
|
||||
/* The parameters field should either be empty or contain
|
||||
* valid RSA-PSS parameters */
|
||||
PORT_Assert(!(params->len == 2 &&
|
||||
@@ -831,16 +833,18 @@ sec_CreateRSAPSSParameters(PLArenaPool *
|
||||
params->data[1] == 0));
|
||||
rv = SEC_QuickDERDecodeItem(arena, &pssParams,
|
||||
SECKEY_RSAPSSParamsTemplate,
|
||||
params);
|
||||
if (rv != SECSuccess) {
|
||||
return NULL;
|
||||
}
|
||||
defaultSHA1 = PR_TRUE;
|
||||
+ overWriteHash = PR_FALSE;
|
||||
+ overWriteMask = PR_FALSE;
|
||||
}
|
||||
|
||||
if (pssParams.trailerField.data) {
|
||||
unsigned long trailerField;
|
||||
|
||||
rv = SEC_ASN1DecodeInteger((SECItem *)&pssParams.trailerField,
|
||||
&trailerField);
|
||||
if (rv != SECSuccess) {
|
||||
@@ -851,19 +855,21 @@ sec_CreateRSAPSSParameters(PLArenaPool *
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine the hash algorithm to use, based on hashAlgTag and
|
||||
* pssParams.hashAlg; there are 6 cases.
|
||||
* case:
|
||||
* 1) We have params and params.hashAlg and we have a specified hashAlgTag,
|
||||
- * make sure that hashAlgTag specified by the appication matches.
|
||||
+ * make sure that hashAlgTag specified by the appication matches, othersize we
|
||||
+ * overwrite params.hashAlg with hashAlgTag.
|
||||
* 2) We have params, but no params.hashAlg and we have a specified
|
||||
- * hashAlg, make sure the hashAlgTag matches SEC_OID_SHA1.
|
||||
+ * hashAlg, make sure the hashAlgTag matches SEC_OID_SHA1, otherwise we
|
||||
+ * overwrite params.hashAlg with hashAlgTag..
|
||||
* 3) we did not specify any parameters but we did specified
|
||||
* a hashAlgTag. Use the specified hash algtag.
|
||||
* 4) We have params and params.hashAlg and we did not specify a
|
||||
* hashAlgTag, use the hashAlg from the parameter.
|
||||
* 5) We have params, but no params.hashAlg and we did not specify a
|
||||
* hashAlgTag, use the SEC_OID_SHA1
|
||||
* 6) We did not specify any parameters, nor did we specify a
|
||||
* hashAlgTag, use the key size to select an appropriate hashAlg.
|
||||
@@ -873,36 +879,42 @@ sec_CreateRSAPSSParameters(PLArenaPool *
|
||||
|
||||
if (pssParams.hashAlg) {
|
||||
tag = SECOID_GetAlgorithmTag(pssParams.hashAlg);
|
||||
} else if (defaultSHA1) {
|
||||
tag = SEC_OID_SHA1;
|
||||
}
|
||||
|
||||
if (tag != SEC_OID_UNKNOWN && tag != hashAlgTag) {
|
||||
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
- return NULL;
|
||||
+ overWriteHash = PR_TRUE;
|
||||
}
|
||||
} else if (hashAlgTag == SEC_OID_UNKNOWN) {
|
||||
if (pssParams.hashAlg) {
|
||||
hashAlgTag = SECOID_GetAlgorithmTag(pssParams.hashAlg);
|
||||
} else if (defaultSHA1) {
|
||||
hashAlgTag = SEC_OID_SHA1;
|
||||
} else {
|
||||
/* Find a suitable hash algorithm based on the NIST recommendation */
|
||||
if (modBytes <= 384) { /* 128, in NIST 800-57, Part 1 */
|
||||
hashAlgTag = SEC_OID_SHA256;
|
||||
} else if (modBytes <= 960) { /* 192, NIST 800-57, Part 1 */
|
||||
hashAlgTag = SEC_OID_SHA384;
|
||||
} else {
|
||||
hashAlgTag = SEC_OID_SHA512;
|
||||
}
|
||||
+ overWriteHash = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
+ /* handle the case where the params invalidly encoded SEC_OID_SHA1. This
|
||||
+ * will force the correct encoding */
|
||||
+ if ((hashAlgTag == SEC_OID_SHA1) && pssParams.hashAlg) {
|
||||
+ overWriteHash = PR_TRUE;
|
||||
+ }
|
||||
+
|
||||
/* explicitly restrict hashAlg to SHA2 variants */
|
||||
if (hashAlgTag != SEC_OID_SHA1 && hashAlgTag != SEC_OID_SHA224 &&
|
||||
hashAlgTag != SEC_OID_SHA256 && hashAlgTag != SEC_OID_SHA384 &&
|
||||
hashAlgTag != SEC_OID_SHA512) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -927,23 +939,24 @@ sec_CreateRSAPSSParameters(PLArenaPool *
|
||||
&pssParams.maskAlg->parameters);
|
||||
if (rv != SECSuccess) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Following the recommendation in RFC 4055, assume the hash
|
||||
* algorithm identical to pssParam.hashAlg */
|
||||
if (SECOID_GetAlgorithmTag(&maskHashAlg) != hashAlgTag) {
|
||||
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
- return NULL;
|
||||
+ overWriteMask = PR_TRUE;
|
||||
+ }
|
||||
+ if (hashAlgTag == SEC_OID_SHA1) {
|
||||
+ overWriteMask = PR_TRUE;
|
||||
}
|
||||
} else if (defaultSHA1) {
|
||||
if (hashAlgTag != SEC_OID_SHA1) {
|
||||
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
- return NULL;
|
||||
+ overWriteMask = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
hashLength = HASH_ResultLenByOidTag(hashAlgTag);
|
||||
|
||||
if (modBytes < hashLength + 2) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
@@ -961,42 +974,38 @@ sec_CreateRSAPSSParameters(PLArenaPool *
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
} else if (defaultSHA1) {
|
||||
saltLength = 20;
|
||||
}
|
||||
|
||||
/* Fill in the parameters */
|
||||
- if (pssParams.hashAlg) {
|
||||
+ if (overWriteHash) {
|
||||
if (hashAlgTag == SEC_OID_SHA1) {
|
||||
/* Omit hashAlg if the the algorithm is SHA-1 (default) */
|
||||
pssParams.hashAlg = NULL;
|
||||
- }
|
||||
- } else {
|
||||
- if (hashAlgTag != SEC_OID_SHA1) {
|
||||
+ } else {
|
||||
pssParams.hashAlg = PORT_ArenaZAlloc(arena, sizeof(SECAlgorithmID));
|
||||
if (!pssParams.hashAlg) {
|
||||
return NULL;
|
||||
}
|
||||
rv = SECOID_SetAlgorithmID(arena, pssParams.hashAlg, hashAlgTag,
|
||||
NULL);
|
||||
if (rv != SECSuccess) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- if (pssParams.maskAlg) {
|
||||
+ if (overWriteMask) {
|
||||
if (hashAlgTag == SEC_OID_SHA1) {
|
||||
/* Omit maskAlg if the the algorithm is SHA-1 (default) */
|
||||
pssParams.maskAlg = NULL;
|
||||
- }
|
||||
- } else {
|
||||
- if (hashAlgTag != SEC_OID_SHA1) {
|
||||
+ } else {
|
||||
SECItem *hashAlgItem;
|
||||
|
||||
PORT_Assert(pssParams.hashAlg != NULL);
|
||||
|
||||
hashAlgItem = SEC_ASN1EncodeItem(arena, NULL, pssParams.hashAlg,
|
||||
SEC_ASN1_GET(SECOID_AlgorithmIDTemplate));
|
||||
if (!hashAlgItem) {
|
||||
return NULL;
|
||||
@@ -1086,17 +1095,16 @@ SEC_CreateSignatureAlgorithmParameters(P
|
||||
const SECItem *params,
|
||||
const SECKEYPrivateKey *key)
|
||||
{
|
||||
PORT_SetError(0);
|
||||
switch (signAlgTag) {
|
||||
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
|
||||
return SEC_CreateRSAPSSParameters(arena, result,
|
||||
hashAlgTag, params, key, NULL);
|
||||
-
|
||||
default:
|
||||
if (params == NULL)
|
||||
return NULL;
|
||||
if (result == NULL)
|
||||
result = SECITEM_AllocItem(arena, NULL, 0);
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -1112,16 +1120,19 @@ SEC_CreateVerifyAlgorithmParameters(PLAr
|
||||
SECOidTag signAlgTag,
|
||||
SECOidTag hashAlgTag,
|
||||
const SECItem *params,
|
||||
const SECKEYPublicKey *key)
|
||||
{
|
||||
PORT_SetError(0);
|
||||
switch (signAlgTag) {
|
||||
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
|
||||
+ if ((hashAlgTag == SEC_OID_UNKNOWN) && ((params == NULL) || (params->len == 0))){
|
||||
+ return NULL;
|
||||
+ }
|
||||
return SEC_CreateRSAPSSParameters(arena, result,
|
||||
hashAlgTag, params, NULL, key);
|
||||
|
||||
default:
|
||||
if (params == NULL)
|
||||
return NULL;
|
||||
if (result == NULL)
|
||||
result = SECITEM_AllocItem(arena, NULL, 0);
|
||||
diff --git a/tests/cert/cert.sh b/tests/cert/cert.sh
|
||||
--- a/tests/cert/cert.sh
|
||||
+++ b/tests/cert/cert.sh
|
||||
@@ -2234,20 +2234,18 @@ EOF
|
||||
# Signature: RSA-PSS (with conflicting hash algorithm)
|
||||
CERTNAME="TestUser-rsa-pss7"
|
||||
|
||||
CU_ACTION="Generate Cert Request for $CERTNAME"
|
||||
CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@example.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
||||
certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" --pss -o req 2>&1
|
||||
|
||||
CU_ACTION="Sign ${CERTNAME}'s Request"
|
||||
- RETEXPECTED=255
|
||||
certu -C -c "TestCA-rsa-pss" --pss-sign -Z SHA512 -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \
|
||||
-i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1
|
||||
- RETEXPECTED=0
|
||||
|
||||
CERTSERIAL=`expr $CERTSERIAL + 1`
|
||||
|
||||
# Subject certificate: RSA-PSS
|
||||
# Issuer certificate: RSA-PSS
|
||||
# Signature: RSA-PSS (with compatible hash algorithm)
|
||||
CERTNAME="TestUser-rsa-pss8"
|
||||
|
||||
@@ -2345,20 +2343,18 @@ EOF
|
||||
# Signature: RSA-PSS (with conflicting hash algorithm, default parameters)
|
||||
CERTNAME="TestUser-rsa-pss11"
|
||||
|
||||
CU_ACTION="Generate Cert Request for $CERTNAME"
|
||||
CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@example.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
|
||||
certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" --pss -o req 2>&1
|
||||
|
||||
CU_ACTION="Sign ${CERTNAME}'s Request"
|
||||
- RETEXPECTED=255
|
||||
certu -C -c "TestCA-rsa-pss-sha1" --pss-sign -Z SHA256 -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \
|
||||
-i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1
|
||||
- RETEXPECTED=0
|
||||
}
|
||||
|
||||
cert_test_orphan_key_delete()
|
||||
{
|
||||
CU_ACTION="Create orphan key in serverdir"
|
||||
certu -G -k ec -q nistp256 -f "${R_PWFILE}" -z ${R_NOISE_FILE} -d ${PROFILEDIR}
|
||||
# Let's get the key ID of the first orphan key.
|
||||
# The output of certutil -K (list keys) isn't well formatted.
|
||||
170
nss-3.124-annocheck.fix.patch
Normal file
170
nss-3.124-annocheck.fix.patch
Normal file
@ -0,0 +1,170 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1780440795 25200
|
||||
# Tue Jun 02 15:53:15 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID b1208e88ea45bdc57d04ae64e6614eec7072bd7f
|
||||
# Parent 7b631ae5c0693bdb28e9ee9a4171eee2d3d62d0a
|
||||
nss-3.124-annocheck.fix.patch
|
||||
|
||||
diff --git a/lib/freebl/arcfour-amd64-gas.s b/lib/freebl/arcfour-amd64-gas.s
|
||||
--- a/lib/freebl/arcfour-amd64-gas.s
|
||||
+++ b/lib/freebl/arcfour-amd64-gas.s
|
||||
@@ -1,11 +1,35 @@
|
||||
# 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/.
|
||||
+#
|
||||
+# none of the functions are used as a target of an indirect call, so
|
||||
+# it's safe to set IBT. If we ever need to put these at the end of a
|
||||
+# function table pointer, then we should and ENDBR64 instructions as the
|
||||
+# first instruction of each function. */
|
||||
+# reference names are in /usr/include/elf.h
|
||||
+ .section .note.gnu.property,"a"
|
||||
+ .align 8
|
||||
+ .long 1f - 0f # note_gnu_name_end - note_gnu_name
|
||||
+ .long 4f - 1f # note_gnu_descriptor_end -note_gnu_descriptor
|
||||
+ .long 5 # GNU_PROPERTY_TYPE_0
|
||||
+0: #note_gnu_name
|
||||
+ .string "GNU"
|
||||
+1: #note_gnu_end
|
||||
+ #note_gnu_descriptor
|
||||
+ .align 8
|
||||
+ .long 0xc0000002 # GNU_PROPERTY_X86_FEATURE_1_AND
|
||||
+ .long 3f - 2f #note_gnu_flags_end - note_gnu_flags
|
||||
+2: #note_gnu_flags
|
||||
+ .long 0x3 # GNU_PROPERTY_X86_FEATURE_1_IBT = 1 |
|
||||
+ # GNU_PROPERTY_X86_FEATURE_1_SHSTK = 2
|
||||
+3: #note_gnu_flags_end
|
||||
+ .align 8
|
||||
+4: #note_gnu_descriptor_end
|
||||
|
||||
# ** ARCFOUR implementation optimized for AMD64.
|
||||
# **
|
||||
# ** The throughput achieved by this code is about 320 MBytes/sec, on
|
||||
# ** a 1.8 GHz AMD Opteron (rev C0) processor.
|
||||
|
||||
.text
|
||||
.align 16
|
||||
diff --git a/lib/freebl/intel-aes.S b/lib/freebl/intel-aes.S
|
||||
--- a/lib/freebl/intel-aes.S
|
||||
+++ b/lib/freebl/intel-aes.S
|
||||
@@ -1,12 +1,34 @@
|
||||
/* 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/. */
|
||||
-
|
||||
+/* none of the functions are used as a target of an indirect call, so
|
||||
+ * it's safe to set IBT. If we ever need to put these at the end of a
|
||||
+ * function table pointer, then we should and ENDBR64 instructions as the
|
||||
+ * first instruction of each function. */
|
||||
+# reference names are in /usr/include/elf.h
|
||||
+ .section .note.gnu.property,"a"
|
||||
+ .align 8
|
||||
+ .long 1f - 0f # note_gnu_name_end - note_gnu_name
|
||||
+ .long 4f - 1f # note_gnu_descriptor_end -note_gnu_descriptor
|
||||
+ .long 5 # GNU_PROPERTY_TYPE_0
|
||||
+0: #note_gnu_name
|
||||
+ .string "GNU"
|
||||
+1: #note_gnu_end
|
||||
+ #note_gnu_descriptor
|
||||
+ .align 8
|
||||
+ .long 0xc0000002 # GNU_PROPERTY_X86_FEATURE_1_AND
|
||||
+ .long 3f - 2f #note_gnu_flags_end - note_gnu_flags
|
||||
+2: #note_gnu_flags
|
||||
+ .long 0x3 # GNU_PROPERTY_X86_FEATURE_1_IBT = 1 |
|
||||
+ # GNU_PROPERTY_X86_FEATURE_1_SHSTK = 2
|
||||
+3: #note_gnu_flags_end
|
||||
+ .align 8
|
||||
+4: #note_gnu_descriptor_end
|
||||
.text
|
||||
|
||||
#define IV_OFFSET 256
|
||||
|
||||
/*
|
||||
* Warning: the length values used in this module are "unsigned int"
|
||||
* in C, which is 32-bit. When they're passed in registers, use only
|
||||
* the low 32 bits, because the top half is unspecified.
|
||||
diff --git a/lib/freebl/intel-gcm.S b/lib/freebl/intel-gcm.S
|
||||
--- a/lib/freebl/intel-gcm.S
|
||||
+++ b/lib/freebl/intel-gcm.S
|
||||
@@ -1,14 +1,38 @@
|
||||
# LICENSE:
|
||||
# This submission to NSS is to be made available under the terms of the
|
||||
# Mozilla Public License, v. 2.0. You can obtain one at http:
|
||||
# //mozilla.org/MPL/2.0/.
|
||||
################################################################################
|
||||
# Copyright(c) 2012, Intel Corp.
|
||||
+/* none of the functions are used as a target of an indirect call, so
|
||||
+ * it's safe to set IBT. If we ever need to put these at the end of a
|
||||
+ * function table pointer, then we should and ENDBR64 instructions as the
|
||||
+ * first instruction of each function. */
|
||||
+# reference names are in /usr/include/elf.h
|
||||
+ .section .note.gnu.property,"a"
|
||||
+ .align 8
|
||||
+ .long 1f - 0f # note_gnu_name_end - note_gnu_name
|
||||
+ .long 4f - 1f # note_gnu_descriptor_end -note_gnu_descriptor
|
||||
+ .long 5 # GNU_PROPERTY_TYPE_0
|
||||
+0: #note_gnu_name
|
||||
+ .string "GNU"
|
||||
+1: #note_gnu_end
|
||||
+ #note_gnu_descriptor
|
||||
+ .align 8
|
||||
+ .long 0xc0000002 # GNU_PROPERTY_X86_FEATURE_1_AND
|
||||
+ .long 3f - 2f #note_gnu_flags_end - note_gnu_flags
|
||||
+2: #note_gnu_flags
|
||||
+ .long 0x3 # GNU_PROPERTY_X86_FEATURE_1_IBT = 1 |
|
||||
+ # GNU_PROPERTY_X86_FEATURE_1_SHSTK = 2
|
||||
+3: #note_gnu_flags_end
|
||||
+ .align 8
|
||||
+4: #note_gnu_descriptor_end
|
||||
+ .text
|
||||
|
||||
#if defined(DARWIN)
|
||||
# define cdecl(s) _##s
|
||||
#else
|
||||
# define cdecl(s) s
|
||||
#endif
|
||||
|
||||
#ifndef DARWIN
|
||||
diff --git a/lib/freebl/mpi/mpi_amd64_common.S b/lib/freebl/mpi/mpi_amd64_common.S
|
||||
--- a/lib/freebl/mpi/mpi_amd64_common.S
|
||||
+++ b/lib/freebl/mpi/mpi_amd64_common.S
|
||||
@@ -398,12 +398,37 @@ s_mpv_mul_add_vec64:
|
||||
|
||||
.L27:
|
||||
movq %r9, %rax
|
||||
ret
|
||||
|
||||
#ifndef DARWIN
|
||||
.size s_mpv_mul_add_vec64, .-s_mpv_mul_add_vec64
|
||||
|
||||
+# Magic indicating IBT is allowed.
|
||||
+# none of the functions are used as a target of an indirect call, so
|
||||
+# it's safe to set IBT. If we ever need to put these at the end of a
|
||||
+# function table pointer, then we should and ENDBR64 instructions as the
|
||||
+# first instruction of each function.
|
||||
+# reference names are in /usr/include/elf.h
|
||||
+ .section .note.gnu.property,"a"
|
||||
+ .align 8
|
||||
+ .long 1f - 0f # note_gnu_name_end - note_gnu_name
|
||||
+ .long 4f - 1f # note_gnu_descriptor_end -note_gnu_descriptor
|
||||
+ .long 5 # GNU_PROPERTY_TYPE_0
|
||||
+0: #note_gnu_name
|
||||
+ .string "GNU"
|
||||
+1: #note_gnu_end
|
||||
+ #note_gnu_descriptor
|
||||
+ .align 8
|
||||
+ .long 0xc0000002 # GNU_PROPERTY_X86_FEATURE_1_AND
|
||||
+ .long 3f - 2f #note_gnu_flags_end - note_gnu_flags
|
||||
+2: #note_gnu_flags
|
||||
+ .long 0x3 # GNU_PROPERTY_X86_FEATURE_1_IBT = 1 |
|
||||
+ # GNU_PROPERTY_X86_FEATURE_1_SHSTK = 2
|
||||
+3: #note_gnu_flags_end
|
||||
+ .align 8
|
||||
+4: #note_gnu_descriptor_end
|
||||
+
|
||||
# Magic indicating no need for an executable stack
|
||||
.section .note.GNU-stack, "", @progbits
|
||||
.previous
|
||||
#endif
|
||||
@ -1,8 +1,17 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1780431402 25200
|
||||
# Tue Jun 02 13:16:42 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID b9532ef80e57a3656a1cf077e751b5e1988c52b7
|
||||
# Parent adcfeed46df897fe20ab59d2a40d8150915707fe
|
||||
nss-3.112-disable-ech.patch
|
||||
|
||||
diff --git a/gtests/ssl_gtest/manifest.mn b/gtests/ssl_gtest/manifest.mn
|
||||
--- a/gtests/ssl_gtest/manifest.mn
|
||||
+++ b/gtests/ssl_gtest/manifest.mn
|
||||
@@ -50,17 +50,16 @@ CPPSRCS = \
|
||||
ssl_staticrsa_unittest.cc \
|
||||
@@ -51,17 +51,16 @@ CPPSRCS = \
|
||||
ssl_timers_unittest.cc \
|
||||
ssl_tls13compat_unittest.cc \
|
||||
ssl_v2_client_hello_unittest.cc \
|
||||
ssl_version_unittest.cc \
|
||||
@ -17,12 +26,17 @@ diff --git a/gtests/ssl_gtest/manifest.mn b/gtests/ssl_gtest/manifest.mn
|
||||
tls_protect.cc \
|
||||
tls_psk_unittest.cc \
|
||||
tls_subcerts_unittest.cc \
|
||||
tls_xyber_unittest.cc \
|
||||
$(XYBER_FILES) \
|
||||
$(SSLKEYLOGFILE_FILES) \
|
||||
diff -up ./lib/ssl/sslsock.c.disable_ech ./lib/ssl/sslsock.c
|
||||
--- ./lib/ssl/sslsock.c.disable_ech 2024-06-07 09:26:03.000000000 -0700
|
||||
+++ ./lib/ssl/sslsock.c 2024-06-12 13:29:17.162207862 -0700
|
||||
@@ -4415,17 +4415,23 @@ ssl_ClearPRCList(PRCList *list, void (*f
|
||||
diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
|
||||
--- a/lib/ssl/sslsock.c
|
||||
+++ b/lib/ssl/sslsock.c
|
||||
@@ -4466,62 +4466,82 @@ ssl_ClearPRCList(PRCList *list, void (*f
|
||||
}
|
||||
PORT_Free(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SSLExp_EnableTls13GreaseEch(PRFileDesc *fd, PRBool enabled)
|
||||
{
|
||||
@ -46,7 +60,13 @@ diff -up ./lib/ssl/sslsock.c.disable_ech ./lib/ssl/sslsock.c
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
if (!ss || size == 0) {
|
||||
return SECFailure;
|
||||
@@ -4439,28 +4445,42 @@ SSLExp_SetTls13GreaseEchSize(PRFileDesc
|
||||
}
|
||||
ssl_Get1stHandshakeLock(ss);
|
||||
ssl_GetSSL3HandshakeLock(ss);
|
||||
|
||||
ss->ssl3.hs.greaseEchSize = size;
|
||||
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
ssl_Release1stHandshakeLock(ss);
|
||||
|
||||
return SECSuccess;
|
||||
@ -89,3 +109,8 @@ diff -up ./lib/ssl/sslsock.c.disable_ech ./lib/ssl/sslsock.c
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SSLExp_SetDtls13VersionWorkaround(PRFileDesc *fd, PRBool enabled)
|
||||
{
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
return SECFailure;
|
||||
19
nss-3.124-disable-kyber-test.patch
Normal file
19
nss-3.124-disable-kyber-test.patch
Normal file
@ -0,0 +1,19 @@
|
||||
diff -up ./gtests/freebl_gtest/kyber_unittest.cc.disable_kyber ./gtests/freebl_gtest/kyber_unittest.cc
|
||||
--- ./gtests/freebl_gtest/kyber_unittest.cc.disable_kyber 2026-06-03 10:11:43.287411934 -0700
|
||||
+++ ./gtests/freebl_gtest/kyber_unittest.cc 2026-06-03 10:11:47.246465604 -0700
|
||||
@@ -394,6 +394,7 @@ INSTANTIATE_TEST_SUITE_P(SelfTests, Kybe
|
||||
params_kyber768_round3));
|
||||
#endif
|
||||
|
||||
+#ifndef NSS_DISABLE_KYBER
|
||||
TEST(Kyber768Test, KnownAnswersTest) {
|
||||
ScopedSECItem privateKey(
|
||||
SECITEM_AllocItem(nullptr, nullptr, MAX_ML_KEM_PRIVATE_KEY_LENGTH));
|
||||
@@ -446,6 +447,7 @@ TEST(Kyber768Test, KnownAnswersTest) {
|
||||
EXPECT_EQ(0, memcmp(secret->data, secret2->data, secret2->len));
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
TEST(MlKemKeyGen, KnownAnswersTest) {
|
||||
ScopedSECItem privateKey(
|
||||
@ -1,16 +1,16 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1752601818 25200
|
||||
# Tue Jul 15 10:50:18 2025 -0700
|
||||
# Branch RHEL_8
|
||||
# Node ID ef820c54bad5f034231f51df2b14f88863170cfb
|
||||
# Parent 5c09db329be3e1e2b19c92f9e6224cdad04d65ba
|
||||
nss-3.101-disable-signature-policies.patch
|
||||
# Date 1780948869 25200
|
||||
# Mon Jun 08 13:01:09 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID 298a64e7d25ef5b11e2ba991709348399de31392
|
||||
# Parent 2d476ee9cdb748ab0ef24601f4ac039f35ee3ddc
|
||||
nss-3.124-disable-signature-policies.patch
|
||||
|
||||
diff --git a/lib/pk11wrap/pk11pars.c b/lib/pk11wrap/pk11pars.c
|
||||
--- a/lib/pk11wrap/pk11pars.c
|
||||
+++ b/lib/pk11wrap/pk11pars.c
|
||||
@@ -448,22 +448,19 @@ static const oidValDef smimeKxOptList[]
|
||||
@@ -461,22 +461,19 @@ static const oidValDef smimeKxOptList[]
|
||||
{ CIPHER_NAME("ECDH"), SEC_OID_ECDH_KEA, NSS_USE_ALG_IN_SMIME_KX },
|
||||
{ CIPHER_NAME("DH"), SEC_OID_X942_DIFFIE_HELMAN_KEY, NSS_USE_ALG_IN_SMIME_KX },
|
||||
};
|
||||
@ -27,15 +27,15 @@ diff --git a/lib/pk11wrap/pk11pars.c b/lib/pk11wrap/pk11pars.c
|
||||
- NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
|
||||
+ { CIPHER_NAME("RSA-PKCS"), SEC_OID_PKCS1_RSA_ENCRYPTION, 0},
|
||||
+ { CIPHER_NAME("RSA-PSS"), SEC_OID_PKCS1_RSA_PSS_SIGNATURE, 0},
|
||||
+ { CIPHER_NAME("ECDSA"), SEC_OID_ANSIX962_EC_PUBLIC_KEY, 0},
|
||||
+ { CIPHER_NAME("ECDSA"), SEC_OID_ANSIX962_EC_PUBLIC_KEY, 0},
|
||||
{ CIPHER_NAME("ED25519"), SEC_OID_ED25519_PUBLIC_KEY,
|
||||
NSS_USE_ALG_IN_SIGNATURE },
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const oidValDef *list;
|
||||
PRUint32 entries;
|
||||
const char *description;
|
||||
{ CIPHER_NAME("ML-DSA-44"), SEC_OID_ML_DSA_44,
|
||||
NSS_USE_ALG_IN_SIGNATURE },
|
||||
{ CIPHER_NAME("ML-DSA-65"), SEC_OID_ML_DSA_65,
|
||||
NSS_USE_ALG_IN_SIGNATURE },
|
||||
{ CIPHER_NAME("ML-DSA-87"), SEC_OID_ML_DSA_87,
|
||||
NSS_USE_ALG_IN_SIGNATURE },
|
||||
diff --git a/tests/ssl/sslpolicy.txt b/tests/ssl/sslpolicy.txt
|
||||
--- a/tests/ssl/sslpolicy.txt
|
||||
+++ b/tests/ssl/sslpolicy.txt
|
||||
@ -1,11 +1,11 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1752603075 25200
|
||||
# Tue Jul 15 11:11:15 2025 -0700
|
||||
# Branch RHEL_8
|
||||
# Node ID 688a6b5db483a4168d15e09d5b243fca79b5b01d
|
||||
# Parent a87aba54de420d418961245be6e55d354bebd77b
|
||||
nss-3.101-revert-libpkix-default.patch
|
||||
# Date 1780949364 25200
|
||||
# Mon Jun 08 13:09:24 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID bc6ea7dc13c8873dffae84fbe02939250e448c6d
|
||||
# Parent 20048d1ef425e744445edb521dd5871210f65558
|
||||
nss-3.124-el8-revert-libpkix-default.patch
|
||||
|
||||
diff --git a/lib/certhigh/certvfypkix.c b/lib/certhigh/certvfypkix.c
|
||||
--- a/lib/certhigh/certvfypkix.c
|
||||
@ -57,7 +57,7 @@ diff --git a/lib/nss/nssinit.c b/lib/nss/nssinit.c
|
||||
diff --git a/tests/all.sh b/tests/all.sh
|
||||
--- a/tests/all.sh
|
||||
+++ b/tests/all.sh
|
||||
@@ -138,28 +138,23 @@ run_tests()
|
||||
@@ -244,28 +244,23 @@ run_tests()
|
||||
|
||||
########################## run_cycle_standard ##########################
|
||||
# run test suites with sql database (no PKIX)
|
||||
@ -86,7 +86,7 @@ diff --git a/tests/all.sh b/tests/all.sh
|
||||
run_cycle_pkix()
|
||||
{
|
||||
TEST_MODE=PKIX
|
||||
@@ -167,16 +162,19 @@ run_cycle_pkix()
|
||||
@@ -273,16 +268,19 @@ run_cycle_pkix()
|
||||
TABLE_ARGS="bgcolor=cyan"
|
||||
html_head "Testing with PKIX"
|
||||
html "</TABLE><BR>"
|
||||
@ -99,7 +99,7 @@ diff --git a/tests/all.sh b/tests/all.sh
|
||||
+ export NSS_ENABLE_PKIX_VERIFY
|
||||
+
|
||||
TESTS="${ALL_TESTS}"
|
||||
TESTS_SKIP="cipher dbtests sdr crmf smime merge multinit"
|
||||
TESTS_SKIP="cipher cipher-noaes cipher-noavx cipher-nopclmul cipher-nosha cipher-nosse41 cipher-nossse3 dbtests sdr smime merge multinit"
|
||||
|
||||
export -n NSS_SSL_RUN
|
||||
|
||||
@ -133,8 +133,7 @@ diff --git a/tests/common/init.sh b/tests/common/init.sh
|
||||
diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh
|
||||
--- a/tests/ssl/ssl.sh
|
||||
+++ b/tests/ssl/ssl.sh
|
||||
@@ -957,18 +957,19 @@ ssl_policy_listsuites()
|
||||
html "</TABLE><BR>"
|
||||
@@ -973,17 +973,18 @@ ssl_policy_listsuites()
|
||||
}
|
||||
|
||||
ssl_policy_pkix_ocsp()
|
||||
@ -142,9 +141,8 @@ diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh
|
||||
#verbose="-v"
|
||||
html_head "Check that OCSP doesn't break if we disable sha1 $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE"
|
||||
|
||||
- PKIX_SAVE=${NSS_DISABLE_LIBPKIX_VERIFY-"unset"}
|
||||
PKIX_SAVE=${NSS_DISABLE_LIBPKIX_VERIFY-"unset"}
|
||||
- unset NSS_DISABLE_LIBPKIX_VERIFY
|
||||
+ PKIX_SAVE=${NSS_ENABLE_PKIX_VERIFY-"unset"}
|
||||
+ NSS_ENABLE_PKIX_VERIFY="1"
|
||||
+ export NSS_ENABLE_PKIX_VERIFY
|
||||
|
||||
@ -155,7 +153,7 @@ diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh
|
||||
return 1;
|
||||
fi
|
||||
|
||||
@@ -983,20 +984,22 @@ ssl_policy_pkix_ocsp()
|
||||
@@ -998,20 +999,22 @@ ssl_policy_pkix_ocsp()
|
||||
vfyserv -o wrong.host.badssl.com -d ${P_R_SERVERDIR} 2>&1 | tee ${P_R_SERVERDIR}/vfy.out
|
||||
# make sure we have the domain mismatch, not bad signature error
|
||||
echo "grep -E '12276|5961' ${P_R_SERVERDIR}/vfy.out"
|
||||
137
nss-3.124-fips-key-import-fix.patch
Normal file
137
nss-3.124-fips-key-import-fix.patch
Normal file
@ -0,0 +1,137 @@
|
||||
diff --git a/lib/pk11wrap/pk11skey.c b/lib/pk11wrap/pk11skey.c
|
||||
--- a/lib/pk11wrap/pk11skey.c
|
||||
+++ b/lib/pk11wrap/pk11skey.c
|
||||
@@ -436,11 +436,11 @@
|
||||
}
|
||||
|
||||
static PK11SymKey *
|
||||
pk11_ImportSymKeyWithTempl(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
||||
PK11Origin origin, PRBool isToken, CK_ATTRIBUTE *keyTemplate,
|
||||
- unsigned int templateCount, SECItem *key, void *wincx)
|
||||
+ unsigned int templateCount, SECItem *key, PRBool force, void *wincx)
|
||||
{
|
||||
PK11SymKey *symKey;
|
||||
SECStatus rv;
|
||||
|
||||
symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx);
|
||||
@@ -461,16 +461,65 @@
|
||||
symKey->origin = origin;
|
||||
|
||||
/* import the keys */
|
||||
rv = PK11_CreateNewObject(slot, symKey->session, keyTemplate,
|
||||
templateCount, isToken, &symKey->objectID);
|
||||
- if (rv != SECSuccess) {
|
||||
+ if (rv == SECSuccess) {
|
||||
+ return symKey;
|
||||
+ }
|
||||
+ /* we failed to create the key, if force isn't set, we just fail now */
|
||||
+ if (!force) {
|
||||
+ PK11_FreeSymKey(symKey);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ /* if force is set, we are simulating an unwrap, probably from another token, we
|
||||
+ * are probably here because we are trying to import into a FIPS token. Normally
|
||||
+ * we would want this to fail, but the application got here because they are using
|
||||
+ * unwrap, which is the correct way to do this, so try to import the key into
|
||||
+ * the FIPS token my hand */
|
||||
+ /* first generate a seed key */
|
||||
+ PK11SymKey *seedKey = PK11_KeyGen(slot, CKM_SHA256_HMAC, NULL, 256, wincx);
|
||||
+
|
||||
+ if (seedKey == NULL) {
|
||||
PK11_FreeSymKey(symKey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- return symKey;
|
||||
+ /* now append our key data to the seed key and truncate the seed key */
|
||||
+ CK_KEY_DERIVATION_STRING_DATA params = { 0 };
|
||||
+ CK_MECHANISM mechanism = { 0, NULL, 0 };
|
||||
+ params.pData = key->data;
|
||||
+ params.ulLen = key->len;
|
||||
+ mechanism.mechanism = CKM_CONCATENATE_DATA_AND_BASE;
|
||||
+ mechanism.pParameter = ¶ms;
|
||||
+ mechanism.ulParameterLen = sizeof(params);
|
||||
+
|
||||
+ /* derive removed the CKA_VALUE_LEN before it called us, but now we need
|
||||
+ * it back. We know there is space in the template because derive leaves
|
||||
+ * space for the CKA_VALUE_LEN attribute. Any other callers that set force
|
||||
+ * should also make sure there is space for the CKA_VALUE_LEN */
|
||||
+ CK_ULONG valueLen; /* Don't define this in the 'if' statement, because it
|
||||
+ * would go out of scope before we use it */
|
||||
+ if (!pk11_FindAttrInTemplate(keyTemplate, templateCount, CKA_VALUE_LEN)) {
|
||||
+ valueLen = (CK_ULONG)key->len;
|
||||
+ keyTemplate[templateCount].type = CKA_VALUE_LEN;
|
||||
+ keyTemplate[templateCount].pValue = (void *)&valueLen;
|
||||
+ keyTemplate[templateCount].ulValueLen = sizeof(valueLen);
|
||||
+ templateCount++;
|
||||
+ }
|
||||
+
|
||||
+ CK_RV crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism,
|
||||
+ seedKey->objectID, keyTemplate,
|
||||
+ templateCount,
|
||||
+ &symKey->objectID);
|
||||
+ PK11_FreeSymKey(seedKey);
|
||||
+ if (crv == CKR_OK) {
|
||||
+ return symKey;
|
||||
+ }
|
||||
+
|
||||
+ PK11_FreeSymKey(symKey);
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* turn key bits into an appropriate key object
|
||||
*/
|
||||
@@ -504,11 +553,11 @@
|
||||
templateCount = attrs - keyTemplate;
|
||||
PR_ASSERT(templateCount + 1 <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE));
|
||||
|
||||
keyType = PK11_GetKeyType(type, key->len);
|
||||
symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, PR_FALSE,
|
||||
- keyTemplate, templateCount, key, wincx);
|
||||
+ keyTemplate, templateCount, key, PR_FALSE, wincx);
|
||||
return symKey;
|
||||
}
|
||||
/* Import a PKCS #11 data object and return it as a key. This key is
|
||||
* only useful in a limited number of mechanisms, such as HKDF. */
|
||||
PK11SymKey *
|
||||
@@ -583,11 +632,11 @@
|
||||
templateCount = attrs - keyTemplate;
|
||||
PR_ASSERT(templateCount + 1 <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE));
|
||||
|
||||
keyType = PK11_GetKeyType(type, key->len);
|
||||
symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, isPerm,
|
||||
- keyTemplate, templateCount, key, wincx);
|
||||
+ keyTemplate, templateCount, key, PR_FALSE, wincx);
|
||||
if (symKey && isPerm) {
|
||||
symKey->owner = PR_FALSE;
|
||||
}
|
||||
return symKey;
|
||||
}
|
||||
@@ -2667,11 +2716,11 @@
|
||||
outKey.type = siBuffer;
|
||||
|
||||
if (PK11_DoesMechanism(slot, target)) {
|
||||
symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap,
|
||||
isPerm, keyTemplate,
|
||||
- templateCount, &outKey, wincx);
|
||||
+ templateCount, &outKey, PR_TRUE, wincx);
|
||||
} else {
|
||||
slot = PK11_GetBestSlot(target, wincx);
|
||||
if (slot == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MODULE);
|
||||
PORT_Free(outKey.data);
|
||||
@@ -2679,11 +2728,11 @@
|
||||
*crvp = CKR_DEVICE_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap,
|
||||
isPerm, keyTemplate,
|
||||
- templateCount, &outKey, wincx);
|
||||
+ templateCount, &outKey, PR_TRUE, wincx);
|
||||
PK11_FreeSlot(slot);
|
||||
}
|
||||
PORT_Free(outKey.data);
|
||||
|
||||
if (crvp)
|
||||
|
||||
627
nss-3.124-fix-ed-key-storage.patch
Normal file
627
nss-3.124-fix-ed-key-storage.patch
Normal file
@ -0,0 +1,627 @@
|
||||
diff --git a/cmd/lib/secutil.c b/cmd/lib/secutil.c
|
||||
--- a/cmd/lib/secutil.c
|
||||
+++ b/cmd/lib/secutil.c
|
||||
@@ -1603,10 +1603,18 @@
|
||||
|
||||
case ecKey:
|
||||
secu_PrintECPublicKey(out, pk, "EC Public Key", level + 1);
|
||||
break;
|
||||
|
||||
+ case ecMontKey:
|
||||
+ secu_PrintECPublicKey(out, pk, "EC Montgomery Public Key", level + 1);
|
||||
+ break;
|
||||
+
|
||||
+ case edKey:
|
||||
+ secu_PrintECPublicKey(out, pk, "EC Edwards Public Key", level + 1);
|
||||
+ break;
|
||||
+
|
||||
case mldsaKey:
|
||||
SECU_PrintMLDSAPublicKey(out, pk, "ML-DSA Public Key", level + 1);
|
||||
break;
|
||||
|
||||
case kyberKey:
|
||||
diff --git a/cmd/pk11importtest/pk11importtest.c b/cmd/pk11importtest/pk11importtest.c
|
||||
--- a/cmd/pk11importtest/pk11importtest.c
|
||||
+++ b/cmd/pk11importtest/pk11importtest.c
|
||||
@@ -191,10 +191,12 @@
|
||||
" -r skip rsa test",
|
||||
" -D skip dsa test",
|
||||
" -h skip dh test",
|
||||
" -e skip ec test",
|
||||
" -K skip mk-kem test",
|
||||
+ " -w skip ed test",
|
||||
+ " -g skip ec montgomery test",
|
||||
};
|
||||
static int nUsageInfo = sizeof(usageInfo) / sizeof(char *);
|
||||
|
||||
static void
|
||||
Usage(char *progName, FILE *outFile)
|
||||
@@ -216,10 +218,12 @@
|
||||
opt_NoRSA,
|
||||
opt_NoDSA,
|
||||
opt_NoDH,
|
||||
opt_NoEC,
|
||||
opt_NoMLKEM,
|
||||
+ opt_NoED,
|
||||
+ opt_NoECMont,
|
||||
};
|
||||
|
||||
static secuCommandFlag options[] = {
|
||||
{ /* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_KeySize */ 'k', PR_TRUE, 0, PR_FALSE },
|
||||
@@ -230,10 +234,12 @@
|
||||
{ /* opt_NoRSA */ 'r', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_NoDSA */ 'D', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_NoDH */ 'h', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_NoEC */ 'e', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_NoMLKEM */ 'K', PR_FALSE, 0, PR_FALSE },
|
||||
+ { /* opt_NoED */ 'w', PR_FALSE, 0, PR_FALSE },
|
||||
+ { /* opt_NoECMont */ 'g', PR_FALSE, 0, PR_FALSE },
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@@ -246,10 +252,12 @@
|
||||
PRBool doRSA = PR_TRUE;
|
||||
PRBool doDSA = PR_TRUE;
|
||||
PRBool doDH = PR_FALSE; /* NSS currently can't export wrapped DH keys */
|
||||
PRBool doEC = PR_TRUE;
|
||||
PRBool doMLKEM = PR_TRUE;
|
||||
+ PRBool doED = PR_TRUE;
|
||||
+ PRBool doECMont = PR_TRUE;
|
||||
PRBool noPub = PR_FALSE;
|
||||
PQGParams *pqgParams = NULL;
|
||||
int keySize;
|
||||
|
||||
args.numCommands = 0;
|
||||
@@ -410,10 +418,55 @@
|
||||
fprintf(stderr, "MLKEM Import Failed!\n");
|
||||
failed = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
+ if (doED) {
|
||||
+ SECKEYECParams ecParams;
|
||||
+ SECOidData *curve = SECOID_FindOIDByTag(SEC_OID_ED25519);
|
||||
+ ecParams.data = PORT_Alloc(curve->oid.len + 2);
|
||||
+ if (ecParams.data == NULL) {
|
||||
+ rv = SECFailure;
|
||||
+ goto ed_failed;
|
||||
+ }
|
||||
+ ecParams.data[0] = SEC_ASN1_OBJECT_ID;
|
||||
+ ecParams.data[1] = (unsigned char)curve->oid.len;
|
||||
+ PORT_Memcpy(&ecParams.data[2], curve->oid.data, curve->oid.len);
|
||||
+ ecParams.len = curve->oid.len + 2;
|
||||
+ rv = handleEncryptedPrivateImportTest(progName, slot, "EDDSA",
|
||||
+ CKM_EC_EDWARDS_KEY_PAIR_GEN,
|
||||
+ noPub, &ecParams, &pwArgs);
|
||||
+ PORT_Free(ecParams.data);
|
||||
+ ed_failed:
|
||||
+ if (rv != SECSuccess) {
|
||||
+ fprintf(stderr, "EDDSA Import Failed!\n");
|
||||
+ failed = PR_TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+ if (doECMont) {
|
||||
+ SECKEYECParams ecParams;
|
||||
+ SECOidData *curve = SECOID_FindOIDByTag(SEC_OID_X25519);
|
||||
+ ecParams.data = PORT_Alloc(curve->oid.len + 2);
|
||||
+ if (ecParams.data == NULL) {
|
||||
+ rv = SECFailure;
|
||||
+ goto ecmont_failed;
|
||||
+ }
|
||||
+ ecParams.data[0] = SEC_ASN1_OBJECT_ID;
|
||||
+ ecParams.data[1] = (unsigned char)curve->oid.len;
|
||||
+ PORT_Memcpy(&ecParams.data[2], curve->oid.data, curve->oid.len);
|
||||
+ ecParams.len = curve->oid.len + 2;
|
||||
+ rv = handleEncryptedPrivateImportTest(progName, slot, "EC Mont",
|
||||
+ CKM_EC_MONTGOMERY_KEY_PAIR_GEN,
|
||||
+ noPub, &ecParams, &pwArgs);
|
||||
+ PORT_Free(ecParams.data);
|
||||
+ ecmont_failed:
|
||||
+ if (rv != SECSuccess) {
|
||||
+ fprintf(stderr, "EC Montgomery Import Failed!\n");
|
||||
+ failed = PR_TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (pqgParams) {
|
||||
PK11_PQG_DestroyParams(pqgParams);
|
||||
}
|
||||
|
||||
if (slot) {
|
||||
diff --git a/lib/softoken/lowkey.c b/lib/softoken/lowkey.c
|
||||
--- a/lib/softoken/lowkey.c
|
||||
+++ b/lib/softoken/lowkey.c
|
||||
@@ -43,10 +43,15 @@
|
||||
{ SEC_ASN1_OCTET_STRING,
|
||||
offsetof(NSSLOWKEYPrivateKeyInfo, privateKey) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
offsetof(NSSLOWKEYPrivateKeyInfo, attributes),
|
||||
nsslowkey_SetOfAttributeTemplate },
|
||||
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
|
||||
+ SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
|
||||
+ SEC_ASN1_XTRN | 1,
|
||||
+ offsetof(NSSLOWKEYPrivateKeyInfo, publicKey),
|
||||
+ SEC_ASN1_SUB(SEC_BitStringTemplate) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template nsslowkey_SubjectPublicKeyInfoTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYSubjectPublicKeyInfo) },
|
||||
@@ -399,10 +404,12 @@
|
||||
if (rv == SECSuccess)
|
||||
return pubk;
|
||||
}
|
||||
break;
|
||||
case NSSLOWKEYECKey:
|
||||
+ case NSSLOWKEYECEdwardsKey:
|
||||
+ case NSSLOWKEYECMontgomeryKey:
|
||||
pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
|
||||
sizeof(NSSLOWKEYPublicKey));
|
||||
if (pubk != NULL) {
|
||||
SECStatus rv;
|
||||
|
||||
@@ -631,10 +638,12 @@
|
||||
&(privKey->u.dh.base));
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
break;
|
||||
case NSSLOWKEYECKey:
|
||||
+ case NSSLOWKEYECEdwardsKey:
|
||||
+ case NSSLOWKEYECMontgomeryKey:
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.version),
|
||||
&(privKey->u.ec.version));
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.publicValue),
|
||||
diff --git a/lib/softoken/lowkeyti.h b/lib/softoken/lowkeyti.h
|
||||
--- a/lib/softoken/lowkeyti.h
|
||||
+++ b/lib/softoken/lowkeyti.h
|
||||
@@ -48,10 +48,11 @@
|
||||
PLArenaPool *arena;
|
||||
SECItem version;
|
||||
SECAlgorithmID algorithm;
|
||||
SECItem privateKey;
|
||||
NSSLOWKEYAttribute **attributes;
|
||||
+ SECItem publicKey;
|
||||
};
|
||||
typedef struct NSSLOWKEYPrivateKeyInfoStr NSSLOWKEYPrivateKeyInfo;
|
||||
#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
|
||||
|
||||
struct NSSLOWKEYSubjectPublicKeyInfoStr {
|
||||
@@ -65,12 +66,14 @@
|
||||
NSSLOWKEYNullKey = 0,
|
||||
NSSLOWKEYRSAKey = 1,
|
||||
NSSLOWKEYDSAKey = 2,
|
||||
NSSLOWKEYDHKey = 4,
|
||||
NSSLOWKEYECKey = 5,
|
||||
- NSSLOWKEYMLDSAKey = 6,
|
||||
- NSSLOWKEYMLKEMKey = 7,
|
||||
+ NSSLOWKEYECEdwardsKey = 6,
|
||||
+ NSSLOWKEYECMontgomeryKey = 7,
|
||||
+ NSSLOWKEYMLDSAKey = 8,
|
||||
+ NSSLOWKEYMLKEMKey = 9,
|
||||
} NSSLOWKEYType;
|
||||
|
||||
/* ML KEM low structures packages a key with it's parameters.
|
||||
* The ML KEM freebl didn't define these because all the functions
|
||||
* take raw keys and param separately */
|
||||
diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c
|
||||
--- a/lib/softoken/pkcs11.c
|
||||
+++ b/lib/softoken/pkcs11.c
|
||||
@@ -2223,13 +2223,18 @@
|
||||
break;
|
||||
crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dh.publicValue,
|
||||
object, CKA_VALUE);
|
||||
break;
|
||||
case CKK_EC_EDWARDS:
|
||||
+ pubKey->keyType = NSSLOWKEYECEdwardsKey;
|
||||
+ goto ec_continue;
|
||||
case CKK_EC_MONTGOMERY:
|
||||
+ pubKey->keyType = NSSLOWKEYECMontgomeryKey;
|
||||
+ goto ec_continue;
|
||||
case CKK_EC:
|
||||
pubKey->keyType = NSSLOWKEYECKey;
|
||||
+ ec_continue:
|
||||
crv = sftk_Attribute2SSecItem(arena,
|
||||
&pubKey->u.ec.ecParams.DEREncoding,
|
||||
object, CKA_EC_PARAMS);
|
||||
if (crv != CKR_OK)
|
||||
break;
|
||||
@@ -2451,13 +2456,18 @@
|
||||
itemTemplateCount++;
|
||||
/* privKey was zero'd so public value is already set to NULL, 0
|
||||
* if we don't set it explicitly */
|
||||
break;
|
||||
case CKK_EC_EDWARDS:
|
||||
+ privKey->keyType = NSSLOWKEYECEdwardsKey;
|
||||
+ goto ec_continue;
|
||||
case CKK_EC_MONTGOMERY:
|
||||
+ privKey->keyType = NSSLOWKEYECMontgomeryKey;
|
||||
+ goto ec_continue;
|
||||
case CKK_EC:
|
||||
privKey->keyType = NSSLOWKEYECKey;
|
||||
+ ec_continue:
|
||||
crv = sftk_Attribute2SSecItem(arena,
|
||||
&privKey->u.ec.ecParams.DEREncoding,
|
||||
object, CKA_EC_PARAMS);
|
||||
if (crv != CKR_OK)
|
||||
break;
|
||||
@@ -2514,10 +2524,11 @@
|
||||
case CKK_NSS_KYBER:
|
||||
#endif
|
||||
case CKK_NSS_ML_KEM:
|
||||
case CKK_ML_KEM:
|
||||
privKey->keyType = NSSLOWKEYMLKEMKey;
|
||||
+
|
||||
crv = sftk_GetULongAttribute(object, CKA_PARAMETER_SET,
|
||||
¶mSet);
|
||||
if (crv != CKR_OK) {
|
||||
crv = sftk_GetULongAttribute(object, CKA_NSS_PARAMETER_SET,
|
||||
¶mSet);
|
||||
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
|
||||
--- a/lib/softoken/pkcs11c.c
|
||||
+++ b/lib/softoken/pkcs11c.c
|
||||
@@ -6465,12 +6465,10 @@
|
||||
* the private key */
|
||||
seed.data = seedData;
|
||||
seed.len = sizeof(seedData);
|
||||
rv = RNG_GenerateGlobalRandomBytes(seed.data, seed.len);
|
||||
if (rv != SECSuccess) {
|
||||
- fprintf(stderr, "Generate bytes failed nbytes=%d err=%d\n",
|
||||
- seed.len, PORT_GetError());
|
||||
crv = sftk_MapCryptError(PORT_GetError());
|
||||
goto kyber_done;
|
||||
}
|
||||
|
||||
KyberParams kyberParams = sftk_kyber_PK11ParamToInternal(genParamSet);
|
||||
@@ -6482,12 +6480,10 @@
|
||||
crv = CKR_HOST_MEMORY;
|
||||
goto kyber_done;
|
||||
}
|
||||
rv = Kyber_NewKey(kyberParams, &seed, &privKey, &pubKey);
|
||||
if (rv != SECSuccess) {
|
||||
- fprintf(stderr, "Generate Kyber_NewKey failed nbytes=%d err=%d\n",
|
||||
- seed.len, PORT_GetError());
|
||||
crv = sftk_MapCryptError(PORT_GetError());
|
||||
goto kyber_done;
|
||||
}
|
||||
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_VALUE, sftk_item_expand(&pubKey));
|
||||
@@ -6902,10 +6898,11 @@
|
||||
param = SEC_ASN1EncodeItem(NULL, NULL, &(lk->u.dsa.params),
|
||||
nsslowkey_PQGParamsTemplate);
|
||||
algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE;
|
||||
break;
|
||||
case NSSLOWKEYECKey:
|
||||
+ algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
|
||||
prepare_low_ec_priv_key_for_asn1(lk);
|
||||
/* Public value is encoded as a bit string so adjust length
|
||||
* to be in bits before ASN encoding and readjust
|
||||
* immediately after.
|
||||
*
|
||||
@@ -6926,12 +6923,30 @@
|
||||
SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType,
|
||||
fordebug);
|
||||
#endif
|
||||
|
||||
param = SECITEM_DupItem(&lk->u.ec.ecParams.DEREncoding);
|
||||
-
|
||||
- algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
|
||||
+ break;
|
||||
+ /* X25519, ED25519, X448, and ED448 encode the private key
|
||||
+ * as just and int. The public key and Curve come from the
|
||||
+ * generaly key structure */
|
||||
+ case NSSLOWKEYECEdwardsKey:
|
||||
+ algorithm = SEC_OID_ED25519;
|
||||
+ goto ec_continue;
|
||||
+ case NSSLOWKEYECMontgomeryKey:
|
||||
+ algorithm = SEC_OID_X25519;
|
||||
+ ec_continue:
|
||||
+ prepare_low_ec_priv_key_for_asn1(lk);
|
||||
+ /* if we have a public key, copy it to pki public key */
|
||||
+ if (lk->u.ec.publicValue.len) {
|
||||
+ pki->publicKey = lk->u.ec.publicValue;
|
||||
+ pki->publicKey.len <<= 3;
|
||||
+ }
|
||||
+ dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey,
|
||||
+ &lk->u.ec.privateValue,
|
||||
+ SEC_ASN1_GET(SEC_OctetStringTemplate));
|
||||
+ param = NULL;
|
||||
break;
|
||||
case NSSLOWKEYMLKEMKey: {
|
||||
SECItem seed = { siBuffer, NULL, 0 };
|
||||
SECItem rawKey = { siBuffer, NULL, 0 };
|
||||
dummy = NULL;
|
||||
@@ -7258,10 +7273,12 @@
|
||||
PLArenaPool *arena;
|
||||
NSSLOWKEYPrivateKey *lpk = NULL;
|
||||
NSSLOWKEYPrivateKeyInfo *pki = NULL;
|
||||
CK_RV crv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
CK_ULONG paramSet = 0;
|
||||
+ const SECOidData *oidData = NULL;
|
||||
+ SECOidTag pkiAlg = SEC_OID_UNKNOWN;
|
||||
|
||||
arena = PORT_NewArena(2048);
|
||||
if (!arena) {
|
||||
return SECFailure;
|
||||
}
|
||||
@@ -7283,11 +7300,12 @@
|
||||
if (lpk == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lpk->arena = arena;
|
||||
|
||||
- switch (SECOID_GetAlgorithmTag(&pki->algorithm)) {
|
||||
+ pkiAlg = SECOID_GetAlgorithmTag(&pki->algorithm);
|
||||
+ switch (pkiAlg) {
|
||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
|
||||
keyTemplate = nsslowkey_RSAPrivateKeyTemplate;
|
||||
paramTemplate = NULL;
|
||||
paramDest = NULL;
|
||||
@@ -7309,10 +7327,46 @@
|
||||
paramDest = &(lpk->u.ec.ecParams.DEREncoding);
|
||||
lpk->keyType = NSSLOWKEYECKey;
|
||||
prepare_low_ec_priv_key_for_asn1(lpk);
|
||||
prepare_low_ecparams_for_asn1(&lpk->u.ec.ecParams);
|
||||
break;
|
||||
+ case SEC_OID_X25519:
|
||||
+ lpk->keyType = NSSLOWKEYECMontgomeryKey;
|
||||
+ goto ecx_continue;
|
||||
+ case SEC_OID_ED25519:
|
||||
+ lpk->keyType = NSSLOWKEYECEdwardsKey;
|
||||
+ ecx_continue:
|
||||
+ /* we decode the whole key here rather than do the normal
|
||||
+ * later decode step */
|
||||
+ keyTemplate = NULL;
|
||||
+ paramTemplate = NULL;
|
||||
+ paramDest = NULL;
|
||||
+ oidData = SECOID_FindOIDByTag(pkiAlg);
|
||||
+ if (oidData == NULL) {
|
||||
+ goto loser;
|
||||
+ }
|
||||
+ /* CURVE is provided by the tag, not encoded in the parameters
|
||||
+ * for the x25519, x448, ed25519 and ed448 keys */
|
||||
+ if (SEC_ASN1EncodeItem(arena, &(lpk->u.ec.ecParams.DEREncoding),
|
||||
+ &oidData->oid,
|
||||
+ SEC_ASN1_GET(SEC_ObjectIDTemplate)) == NULL) {
|
||||
+ goto loser;
|
||||
+ }
|
||||
+ prepare_low_ec_priv_key_for_asn1(lpk);
|
||||
+ /* private key is a simple octet string, just decode it now */
|
||||
+ rv = SEC_QuickDERDecodeItem(arena, &(lpk->u.ec.privateValue),
|
||||
+ SEC_ASN1_GET(SEC_OctetStringTemplate),
|
||||
+ &(pki->privateKey));
|
||||
+ if (rv != SECSuccess) {
|
||||
+ goto loser;
|
||||
+ }
|
||||
+ if (pki->publicKey.len) {
|
||||
+ lpk->u.ec.publicValue = pki->publicKey;
|
||||
+ /* convert length in bits to length in bytes */
|
||||
+ lpk->u.ec.publicValue.len >>= 3;
|
||||
+ }
|
||||
+ break;
|
||||
case SEC_OID_ML_KEM_768:
|
||||
paramSet = CKP_ML_KEM_768;
|
||||
goto mlkem_next;
|
||||
case SEC_OID_ML_KEM_1024:
|
||||
paramSet = CKP_ML_KEM_1024;
|
||||
@@ -7344,30 +7398,31 @@
|
||||
case SEC_ASN1_CONSTRUCTED | SEC_ASN1_SEQUENCE:
|
||||
keyTemplate = nsslowkey_PQBothSeedAndPrivateKeyTemplate;
|
||||
break;
|
||||
default:
|
||||
keyTemplate = NULL;
|
||||
- break;
|
||||
+ PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
+ goto loser;
|
||||
}
|
||||
|
||||
paramTemplate = NULL;
|
||||
paramDest = NULL;
|
||||
/* genpq encodes ocect, not integer, so no need to prep it */
|
||||
break;
|
||||
default:
|
||||
keyTemplate = NULL;
|
||||
paramTemplate = NULL;
|
||||
paramDest = NULL;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if (!keyTemplate) {
|
||||
- goto loser;
|
||||
+ PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
+ goto loser;
|
||||
}
|
||||
|
||||
/* decode the private key and any algorithm parameters */
|
||||
- rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
|
||||
+ rv = SECSuccess;
|
||||
+ if (keyTemplate) {
|
||||
+ rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
|
||||
+ }
|
||||
|
||||
if (lpk->keyType == NSSLOWKEYECKey) {
|
||||
/* convert length in bits to length in bytes */
|
||||
lpk->u.ec.publicValue.len >>= 3;
|
||||
rv = SECITEM_CopyItem(arena,
|
||||
@@ -7560,13 +7615,19 @@
|
||||
template = dhTemplate;
|
||||
templateCount = sizeof(dhTemplate) / sizeof(CK_ATTRIBUTE);
|
||||
keyType = CKK_DH;
|
||||
break;
|
||||
#endif
|
||||
- /* what about fortezza??? */
|
||||
+ case NSSLOWKEYECEdwardsKey:
|
||||
+ keyType = CKK_EC_EDWARDS;
|
||||
+ goto ec_import_continue;
|
||||
+ case NSSLOWKEYECMontgomeryKey:
|
||||
+ keyType = CKK_EC_MONTGOMERY;
|
||||
+ goto ec_import_continue;
|
||||
case NSSLOWKEYECKey:
|
||||
keyType = CKK_EC;
|
||||
+ ec_import_continue:
|
||||
/* if we weren't passed the CKA_NSS_DB, get it
|
||||
* from the public key */
|
||||
if (!sftk_hasAttribute(key, CKA_NSS_DB)) {
|
||||
if (lpk->u.ec.publicValue.len == 0) {
|
||||
crv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c
|
||||
--- a/lib/softoken/pkcs11u.c
|
||||
+++ b/lib/softoken/pkcs11u.c
|
||||
@@ -1642,10 +1642,12 @@
|
||||
case CKK_DH:
|
||||
crv = stfk_CopyTokenAttributes(destObject, src_to, dhPrivKeyAttrs,
|
||||
dhPrivKeyAttrsCount);
|
||||
break;
|
||||
case CKK_EC:
|
||||
+ case CKK_EC_EDWARDS:
|
||||
+ case CKK_EC_MONTGOMERY:
|
||||
crv = stfk_CopyTokenAttributes(destObject, src_to, ecPrivKeyAttrs,
|
||||
ecPrivKeyAttrsCount);
|
||||
break;
|
||||
default:
|
||||
crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
|
||||
@@ -1706,10 +1708,12 @@
|
||||
case CKK_DH:
|
||||
crv = stfk_CopyTokenAttributes(destObject, src_to, dhPubKeyAttrs,
|
||||
dhPubKeyAttrsCount);
|
||||
break;
|
||||
case CKK_EC:
|
||||
+ case CKK_EC_EDWARDS:
|
||||
+ case CKK_EC_MONTGOMERY:
|
||||
crv = stfk_CopyTokenAttributes(destObject, src_to, ecPubKeyAttrs,
|
||||
ecPubKeyAttrsCount);
|
||||
break;
|
||||
default:
|
||||
crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
|
||||
diff --git a/lib/util/secoid.c b/lib/util/secoid.c
|
||||
--- a/lib/util/secoid.c
|
||||
+++ b/lib/util/secoid.c
|
||||
@@ -640,14 +640,14 @@
|
||||
a private key, and a signature (for the two EdDSA related OIDs).
|
||||
Additional encoding information is provided below for each of these
|
||||
locations.
|
||||
*/
|
||||
|
||||
-CONST_OID ed25519PublicKey[] = { 0x2B, 0x65, 0x70 };
|
||||
-CONST_OID ed25519Signature[] = { 0x2B, 0x65, 0x70 };
|
||||
-
|
||||
/*https://www.rfc-editor.org/rfc/rfc8410#section-3*/
|
||||
+/* 1.3.101.112 */
|
||||
+CONST_OID ed25519[] = { 0x2B, 0x65, 0x70 };
|
||||
+/* 1.3.101.110 */
|
||||
CONST_OID x25519PublicKey[] = { 0x2b, 0x65, 0x6e };
|
||||
|
||||
/*
|
||||
* ML-DSA OIDs
|
||||
* https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration
|
||||
@@ -1869,15 +1869,18 @@
|
||||
OD(hmac_sha3_512, SEC_OID_HMAC_SHA3_512, "HMAC SHA3-512", CKM_SHA3_512_HMAC, INVALID_CERT_EXTENSION),
|
||||
|
||||
ODE(SEC_OID_XYBER768D00,
|
||||
"X25519+Kyber768 key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
|
||||
|
||||
- OD(ed25519Signature, SEC_OID_ED25519_SIGNATURE, "X9.62 EDDSA signature", CKM_EDDSA,
|
||||
- INVALID_CERT_EXTENSION),
|
||||
+ /* SEC_OID_ED25519_PUBLIC_KEY and SEC_OID_ED25519_SIGNATURE have the same
|
||||
+ * values, so we should only have one entry in the table, We can't
|
||||
+ * shift the values of the other entries, so just leav a dead spot here */
|
||||
+ ODE(SEC_OID_RESERVED_OLD_EDSIG, "Reserved", CKM_INVALID_MECHANISM,
|
||||
+ INVALID_CERT_EXTENSION),
|
||||
|
||||
- OD(ed25519PublicKey, SEC_OID_ED25519_PUBLIC_KEY,
|
||||
- "X9.62 elliptic edwards curve public key", CKM_EC_EDWARDS_KEY_PAIR_GEN, INVALID_CERT_EXTENSION),
|
||||
+ OD(ed25519, SEC_OID_ED25519,
|
||||
+ "X9.62 Elliptic Edwards Curve 25519", CKM_EDDSA, INVALID_CERT_EXTENSION),
|
||||
|
||||
OD(dhSinglePassstdDHsha1kdfscheme, SEC_OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME,
|
||||
"Eliptic Curve Diffie-Hellman Single Pass Standard with SHA1 KDF", CKM_ECDH1_DERIVE,
|
||||
INVALID_CERT_EXTENSION),
|
||||
OD(dhSinglePassstdDHsha224kdfscheme, SEC_OID_DHSINGLEPASS_STDDH_SHA224KDF_SCHEME,
|
||||
diff --git a/lib/util/secoidt.h b/lib/util/secoidt.h
|
||||
--- a/lib/util/secoidt.h
|
||||
+++ b/lib/util/secoidt.h
|
||||
@@ -512,12 +512,12 @@
|
||||
SEC_OID_HMAC_SHA3_384 = 370,
|
||||
SEC_OID_HMAC_SHA3_512 = 371,
|
||||
|
||||
SEC_OID_XYBER768D00 = 372,
|
||||
|
||||
- SEC_OID_ED25519_SIGNATURE = 373,
|
||||
- SEC_OID_ED25519_PUBLIC_KEY = 374,
|
||||
+ SEC_OID_RESERVED_OLD_EDSIG = 373,
|
||||
+ SEC_OID_ED25519 = 374,
|
||||
|
||||
SEC_OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME = 375,
|
||||
SEC_OID_DHSINGLEPASS_STDDH_SHA224KDF_SCHEME = 376,
|
||||
SEC_OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME = 377,
|
||||
SEC_OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME = 378,
|
||||
@@ -561,10 +561,14 @@
|
||||
#define SEC_OID_ML_DSA_65_SIGNATURE SEC_OID_ML_DSA_65
|
||||
#define SEC_OID_ML_DSA_65_PUBLIC_KEY SEC_OID_ML_DSA_65
|
||||
#define SEC_OID_ML_DSA_87_SIGNATURE SEC_OID_ML_DSA_87
|
||||
#define SEC_OID_ML_DSA_87_PUBLIC_KEY SEC_OID_ML_DSA_87
|
||||
|
||||
+/* EDDSA have the same identifiers for public keys and signatures */
|
||||
+#define SEC_OID_ED25519_SIGNATURE SEC_OID_ED25519
|
||||
+#define SEC_OID_ED25519_PUBLIC_KEY SEC_OID_ED25519
|
||||
+
|
||||
typedef enum {
|
||||
INVALID_CERT_EXTENSION = 0,
|
||||
UNSUPPORTED_CERT_EXTENSION = 1,
|
||||
SUPPORTED_CERT_EXTENSION = 2
|
||||
} SECSupportExtenTag;
|
||||
diff --git a/tests/tools/tools.sh b/tests/tools/tools.sh
|
||||
--- a/tests/tools/tools.sh
|
||||
+++ b/tests/tools/tools.sh
|
||||
@@ -126,10 +126,11 @@
|
||||
cp ${QADIR}/tools/pbmac1-valid-sha512.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/pbmac1-invalid-bad-iter.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/pbmac1-invalid-bad-salt.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/pbmac1-invalid-no-length.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/corrupted_cert_bag.p12 ${TOOLSDIR}/data
|
||||
+ cp ${QADIR}/tools/openssl-ed25519.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/openssl-ml-kem-768-seed.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/openssl-ml-kem-768-priv.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/openssl-ml-kem-768-both.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/openssl-ml-kem-1024-seed.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/openssl-ml-kem-1024-priv.p12 ${TOOLSDIR}/data
|
||||
@@ -534,10 +535,21 @@
|
||||
check_tmpfile
|
||||
|
||||
return $ret
|
||||
}
|
||||
|
||||
+tools_p12_import_ed25519_private_key()
|
||||
+{
|
||||
+ echo "$SCRIPTNAME: Importing ED25519 private key from PKCS#12 file --------------"
|
||||
+ ${BINDIR}/pk12util -i ${TOOLSDIR}/data/openssl-ed25519.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W 'test' 2>&1
|
||||
+ ret=$?
|
||||
+ html_msg $ret 0 "Importing ED25519 private key from PKCS#12 file"
|
||||
+ check_tmpfile
|
||||
+
|
||||
+ return $ret
|
||||
+}
|
||||
+
|
||||
tools_p12_ml_kem_import()
|
||||
{
|
||||
echo "$SCRIPTNAME: Testing ml-kem compatibility with pkcs12 --------------"
|
||||
for i in 768 1024
|
||||
do
|
||||
@@ -614,10 +626,11 @@
|
||||
fi
|
||||
tools_p12_export_with_none_ciphers
|
||||
tools_p12_export_with_invalid_ciphers
|
||||
tools_p12_import_old_files
|
||||
tools_p12_import_pbmac1_samples
|
||||
+ tools_p12_import_ed25519_private_key
|
||||
tools_p12_ml_kem_import
|
||||
if using_sql; then
|
||||
tools_p12_import_rsa_pss_private_key
|
||||
tools_p12_policy
|
||||
fi
|
||||
|
||||
42
nss-3.124-fix-old-compiler-issue.patch
Normal file
42
nss-3.124-fix-old-compiler-issue.patch
Normal file
@ -0,0 +1,42 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1782250609 25200
|
||||
# Tue Jun 23 14:36:49 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID d7217ccba81e478980f5540140f2d2a690e2a2a9
|
||||
# Parent 9fc4546f66e227fd073fd908984f6a729c04f662
|
||||
nss-3.124-fix-old-compiler-issue.patch
|
||||
|
||||
diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c
|
||||
--- a/lib/softoken/pkcs11u.c
|
||||
+++ b/lib/softoken/pkcs11u.c
|
||||
@@ -2723,27 +2723,28 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
|
||||
if (mech->ulParameterLen < mechInfo->offset + sizeof(CK_ULONG)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (!sftk_checkFIPSHash(*(CK_MECHANISM_TYPE *)(((char *)mech->pParameter) + mechInfo->offset), PR_FALSE, PR_FALSE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
- case SFTKFIPSRSAOAEP:
|
||||
+ case SFTKFIPSRSAOAEP: {
|
||||
CK_RSA_PKCS_OAEP_PARAMS *rsaoaep = (CK_RSA_PKCS_OAEP_PARAMS *)
|
||||
mech->pParameter;
|
||||
|
||||
HASH_HashType hash_msg = sftk_GetHashTypeFromMechanism(rsaoaep->hashAlg);
|
||||
HASH_HashType hash_pad = sftk_GetHashTypeFromMechanism(rsaoaep->mgf);
|
||||
/* message hash and mask generation function must be the same */
|
||||
if (hash_pad != hash_msg)
|
||||
return PR_FALSE;
|
||||
|
||||
return sftk_checkFIPSHash(rsaoaep->hashAlg, PR_FALSE, PR_FALSE);
|
||||
+ }
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* if we didn't understand the special processing, mark it non-fips */
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
189
nss-3.124-indicators-prf.patch
Normal file
189
nss-3.124-indicators-prf.patch
Normal file
@ -0,0 +1,189 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1780434653 25200
|
||||
# Tue Jun 02 14:10:53 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID 19e655733f3af71e3d517ada0d31ad0697d40f3f
|
||||
# Parent 567ea70a139936a15e80b0c88104ea44936dfc30
|
||||
nss-3.124-indicators-prf.patch
|
||||
|
||||
diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c
|
||||
--- a/lib/softoken/pkcs11u.c
|
||||
+++ b/lib/softoken/pkcs11u.c
|
||||
@@ -16,37 +16,47 @@
|
||||
#include "secoid.h"
|
||||
#include "softkver.h"
|
||||
|
||||
#if !defined(NSS_FIPS_DISABLED) && defined(NSS_ENABLE_FIPS_INDICATORS)
|
||||
/* handle special cases. Classes require existing code to already be
|
||||
* in place for that class */
|
||||
typedef enum {
|
||||
SFTKFIPSNone = 0,
|
||||
- SFTKFIPSDH, /* allow only specific primes */
|
||||
- SFTKFIPSECC, /* not just keys but specific curves */
|
||||
- SFTKFIPSAEAD, /* single shot AEAD functions not allowed in FIPS mode */
|
||||
- SFTKFIPSRSAPSS,
|
||||
- SFTKFIPSTlsKeyCheck
|
||||
+ SFTKFIPSDH, /* allow only specific primes */
|
||||
+ SFTKFIPSECC, /* not just keys but specific curves */
|
||||
+ SFTKFIPSAEAD, /* single shot AEAD functions not allowed in FIPS mode */
|
||||
+ SFTKFIPSRSAPSS, /* make sure salt isn't too big */
|
||||
+ SFTKFIPSPBKDF2, /* handle pbkdf2 FIPS restrictions */
|
||||
+ SFTKFIPSTlsKeyCheck, /* check the output of TLS prf functions */
|
||||
+ SFTKFIPSChkHash, /* make sure the base hash of KDF functions is FIPS */
|
||||
+ SFTKFIPSChkHashTls, /* make sure the base hash of TLS KDF functions is FIPS */
|
||||
+ SFTKFIPSChkHashSp800, /* make sure the base hash of SP-800-108 KDF functions is FIPS */
|
||||
+ SFTKFIPSRSAOAEP, /* make sure that both hashes use the same FIPS compliant algorithm */
|
||||
} SFTKFIPSSpecialClass;
|
||||
|
||||
typedef struct SFTKFIPSAlgorithmListStr SFTKFIPSAlgorithmList;
|
||||
struct SFTKFIPSAlgorithmListStr {
|
||||
CK_MECHANISM_TYPE type;
|
||||
CK_MECHANISM_INFO info;
|
||||
CK_ULONG step;
|
||||
SFTKFIPSSpecialClass special;
|
||||
+ size_t offset;
|
||||
};
|
||||
/* this file should be supplied by the vendor and include all the
|
||||
* algorithms which have Algorithm certs and have been reviewed by
|
||||
* the lab. A blank file is included for the base so that FIPS mode
|
||||
* will still be compiled and run, but FIPS indicators will always
|
||||
* return PR_FALSE
|
||||
*/
|
||||
#include "fips_algorithms.h"
|
||||
+
|
||||
+#ifndef SFTKFIPS_PBKDF2_MIN_PW_LEN /* allow fips_algorithms.h to override */
|
||||
+#define SFTKFIPS_PBKDF2_MIN_PW_LEN 8
|
||||
+#endif
|
||||
#define NSS_HAS_FIPS_INDICATORS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ******************** Error mapping *******************************
|
||||
*/
|
||||
/*
|
||||
* map all the SEC_ERROR_xxx error codes that may be returned by freebl
|
||||
@@ -2566,25 +2576,49 @@ sftk_checkKeyLength(CK_ULONG keyLength,
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (((keyLength - min) % step) != 0) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
+PRBool
|
||||
+sftk_checkFIPSHash(CK_MECHANISM_TYPE hash, PRBool allowSmall, PRBool allowCMAC)
|
||||
+{
|
||||
+ switch (hash) {
|
||||
+ case CKM_AES_CMAC:
|
||||
+ return allowCMAC;
|
||||
+ case CKM_SHA_1:
|
||||
+ case CKM_SHA_1_HMAC:
|
||||
+ case CKM_SHA224:
|
||||
+ case CKM_SHA224_HMAC:
|
||||
+ return allowSmall;
|
||||
+ case CKM_SHA256:
|
||||
+ case CKM_SHA256_HMAC:
|
||||
+ case CKM_SHA384:
|
||||
+ case CKM_SHA384_HMAC:
|
||||
+ case CKM_SHA512:
|
||||
+ case CKM_SHA512_HMAC:
|
||||
+ return PR_TRUE;
|
||||
+ }
|
||||
+ return PR_FALSE;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* handle specialized FIPS semantics that are too complicated to
|
||||
* handle with just a table. NOTE: this means any additional semantics
|
||||
* would have to be coded here before they can be added to the table */
|
||||
static PRBool
|
||||
sftk_handleSpecial(SFTKSlot *slot, CK_MECHANISM *mech,
|
||||
SFTKFIPSAlgorithmList *mechInfo, SFTKObject *source,
|
||||
CK_ULONG keyLength, CK_ULONG targetKeyLength)
|
||||
{
|
||||
+ PRBool allowSmall = PR_FALSE;
|
||||
+ PRBool allowCMAC = PR_FALSE;
|
||||
switch (mechInfo->special) {
|
||||
case SFTKFIPSDH: {
|
||||
SECItem dhPrime;
|
||||
SECItem dhBase;
|
||||
SECItem dhGenerator;
|
||||
PRBool fipsOk = PR_FALSE;
|
||||
const SECItem *dhSubPrime;
|
||||
CK_RV crv = sftk_Attribute2SecItem(NULL, &dhPrime,
|
||||
@@ -2644,18 +2678,72 @@ sftk_handleSpecial(SFTKSlot *slot, CK_ME
|
||||
return PR_FALSE;
|
||||
}
|
||||
/* cap the salt based on the hash */
|
||||
if (pss->sLen > hashObj->length) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
+ case SFTKFIPSPBKDF2: {
|
||||
+ /* from NIST SP 800-132
|
||||
+ * PBKDF2 must have the following addition restrictions
|
||||
+ * (independent of keysize).
|
||||
+ * 1. iteration count must be at least 1000.
|
||||
+ * 2. salt must be at least 128 bits (16 bytes).
|
||||
+ * 3. password must match the length specified in the SP
|
||||
+ */
|
||||
+ CK_PKCS5_PBKD2_PARAMS2 *pbkdf2 = (CK_PKCS5_PBKD2_PARAMS2 *)
|
||||
+ mech->pParameter;
|
||||
+ if (mech->ulParameterLen != sizeof(*pbkdf2)) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ if (pbkdf2->iterations < 1000) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ if (pbkdf2->ulSaltSourceDataLen < 16) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ if (pbkdf2->ulPasswordLen < SFTKFIPS_PBKDF2_MIN_PW_LEN) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ return PR_TRUE;
|
||||
+ }
|
||||
+ /* check the hash mechanisms to make sure they themselves are FIPS */
|
||||
+ case SFTKFIPSChkHashSp800:
|
||||
+ allowCMAC = PR_TRUE;
|
||||
+ case SFTKFIPSChkHash:
|
||||
+ allowSmall = PR_TRUE;
|
||||
+ case SFTKFIPSChkHashTls:
|
||||
+ if (mech->ulParameterLen < mechInfo->offset + sizeof(CK_ULONG)) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ return sftk_checkFIPSHash(*(CK_MECHANISM_TYPE *)(((char *)mech->pParameter) + mechInfo->offset), allowSmall, allowCMAC);
|
||||
case SFTKFIPSTlsKeyCheck:
|
||||
- return sftk_checkKeyLength(targetKeyLength, 112, 512, 1);
|
||||
+ if (mech->mechanism != CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256) {
|
||||
+ /* unless the mechnism has a built-in hash, check the hash */
|
||||
+ if (mech->ulParameterLen < mechInfo->offset + sizeof(CK_ULONG)) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ if (!sftk_checkFIPSHash(*(CK_MECHANISM_TYPE *)(((char *)mech->pParameter) + mechInfo->offset), PR_FALSE, PR_FALSE)) {
|
||||
+ return PR_FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+ return PR_TRUE;
|
||||
+ case SFTKFIPSRSAOAEP:
|
||||
+ CK_RSA_PKCS_OAEP_PARAMS *rsaoaep = (CK_RSA_PKCS_OAEP_PARAMS *)
|
||||
+ mech->pParameter;
|
||||
+
|
||||
+ HASH_HashType hash_msg = sftk_GetHashTypeFromMechanism(rsaoaep->hashAlg);
|
||||
+ HASH_HashType hash_pad = sftk_GetHashTypeFromMechanism(rsaoaep->mgf);
|
||||
+ /* message hash and mask generation function must be the same */
|
||||
+ if (hash_pad != hash_msg)
|
||||
+ return PR_FALSE;
|
||||
+
|
||||
+ return sftk_checkFIPSHash(rsaoaep->hashAlg, PR_FALSE, PR_FALSE);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* if we didn't understand the special processing, mark it non-fips */
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
654
nss-3.124-ml-dsa-test-for-sign-verify-pkcs12.patch
Normal file
654
nss-3.124-ml-dsa-test-for-sign-verify-pkcs12.patch
Normal file
@ -0,0 +1,654 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1780515403 25200
|
||||
# Wed Jun 03 12:36:43 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID eaa726433f362aed5f4cdc40fe0b6aa813d99ed7
|
||||
# Parent 8136ca511f641717eb0b88becf947767a0335eab
|
||||
nss-3.124-ml-dsa-test-for-sign-verify-pkcs12.patch
|
||||
|
||||
diff --git a/cmd/certutil/certutil.c b/cmd/certutil/certutil.c
|
||||
--- a/cmd/certutil/certutil.c
|
||||
+++ b/cmd/certutil/certutil.c
|
||||
@@ -1155,18 +1155,20 @@ PrintSyntax()
|
||||
FPS "\t%s -F -k key-id [-d certdir] [-P dbprefix]\n",
|
||||
progName);
|
||||
FPS "\t%s -G -n key-name [-h token-name] [-k rsa] [-g key-size] [-y exp]\n"
|
||||
"\t\t [-f pwfile] [-z noisefile] [-d certdir] [-P dbprefix]\n", progName);
|
||||
FPS "\t%s -G [-h token-name] -k dsa [-q pqgfile -g key-size] [-f pwfile]\n"
|
||||
"\t\t [-z noisefile] [-d certdir] [-P dbprefix]\n", progName);
|
||||
FPS "\t%s -G [-h token-name] -k ec -q curve [-f pwfile]\n"
|
||||
"\t\t [-z noisefile] [-d certdir] [-P dbprefix]\n", progName);
|
||||
- FPS "\t%s -K [-n key-name] [-h token-name] [-k dsa|ec|rsa|all]\n",
|
||||
- progName);
|
||||
+ FPS "\t%s -G [-h token-name] -k mldsa -q paramset [-f pwfile]\n"
|
||||
+ "\t\t [-z noisefile] [-d certdir] [-P dbprefix]\n", progName);
|
||||
+ FPS "\t%s -K [-n key-name] [-h token-name] [-k dsa|ec|rsa|mldsa|all]\n",
|
||||
+ progName);
|
||||
FPS "\t\t [-f pwfile] [-X] [-d certdir] [-P dbprefix]\n");
|
||||
FPS "\t%s --upgrade-merge --source-dir upgradeDir --upgrade-id uniqueID\n",
|
||||
progName);
|
||||
FPS "\t\t [--upgrade-token-name tokenName] [-d targetDBDir]\n");
|
||||
FPS "\t\t [-P targetDBPrefix] [--source-prefix upgradeDBPrefix]\n");
|
||||
FPS "\t\t [-f targetPWfile] [-@ upgradePWFile]\n");
|
||||
FPS "\t%s --merge --source-dir sourceDBDir [-d targetDBdir]\n",
|
||||
progName);
|
||||
@@ -1389,16 +1391,19 @@ luG(enum usage_level ul, const char *com
|
||||
FPS "%-20s prime239v1, prime239v2, prime239v3, c2pnb163v1, \n", "");
|
||||
FPS "%-20s c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1, \n", "");
|
||||
FPS "%-20s c2tnb191v2, c2tnb191v3, \n", "");
|
||||
FPS "%-20s c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3, \n", "");
|
||||
FPS "%-20s c2pnb272w1, c2pnb304w1, \n", "");
|
||||
FPS "%-20s c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1, \n", "");
|
||||
FPS "%-20s secp112r2, secp128r1, secp128r2, sect113r1, sect113r2\n", "");
|
||||
FPS "%-20s sect131r1, sect131r2\n", "");
|
||||
+ FPS "%-20s ML-DSA parameter set (mldsa only)\n",
|
||||
+ " -q paramset");
|
||||
+ FPS "%-20s valid values are ml-dsa-44, ml-dsa-65, ml-dsa-87:\n", "");
|
||||
FPS "%-20s Key database directory (default is ~/.netscape)\n",
|
||||
" -d keydir");
|
||||
FPS "%-20s Cert & Key database prefix\n",
|
||||
" -P dbprefix");
|
||||
FPS "%-20s\n"
|
||||
"%-20s PKCS #11 key Attributes.\n",
|
||||
" --keyAttrFlags attrflags", "");
|
||||
FPS "%-20s Comma separated list of key attribute attribute flags,\n", "");
|
||||
@@ -1481,16 +1486,17 @@ luK(enum usage_level ul, const char *com
|
||||
"-K");
|
||||
if (ul == usage_selected && !is_my_command)
|
||||
return;
|
||||
FPS "%-20s Name of token to search (\"all\" for all tokens)\n",
|
||||
" -h token-name ");
|
||||
|
||||
FPS "%-20s Key type (\"all\" (default), \"dsa\","
|
||||
" \"ec\","
|
||||
+ " \"mldsa\","
|
||||
" \"rsa\")\n",
|
||||
" -k key-type");
|
||||
FPS "%-20s The nickname of the key or associated certificate\n",
|
||||
" -n name");
|
||||
FPS "%-20s Specify the password file\n",
|
||||
" -f password-file");
|
||||
FPS "%-20s Key database directory (default is ~/.netscape)\n",
|
||||
" -d keydir");
|
||||
@@ -1641,16 +1647,20 @@ luR(enum usage_level ul, const char *com
|
||||
FPS "%-20s Create a certificate request restricted to RSA-PSS (rsa only)\n",
|
||||
" --pss");
|
||||
FPS "%-20s Name of file containing PQG parameters (dsa only)\n",
|
||||
" -q pqgfile");
|
||||
FPS "%-20s Elliptic curve name (ec only)\n",
|
||||
" -q curve-name");
|
||||
FPS "%-20s See the \"-G\" option for a full list of supported names.\n",
|
||||
"");
|
||||
+ FPS "%-20s ML-DSA parameter set (mldsa only)\n",
|
||||
+ " -q paramset");
|
||||
+ FPS "%-20s See the \"-G\" option for a full list of supported names.\n",
|
||||
+ "");
|
||||
FPS "%-20s Specify the password file\n",
|
||||
" -f pwfile");
|
||||
FPS "%-20s Key database directory (default is ~/.netscape)\n",
|
||||
" -d keydir");
|
||||
FPS "%-20s Cert & Key database prefix\n",
|
||||
" -P dbprefix");
|
||||
FPS "%-20s Specify the contact phone number (\"123-456-7890\")\n",
|
||||
" -p phone");
|
||||
@@ -1821,16 +1831,20 @@ luS(enum usage_level ul, const char *com
|
||||
FPS "%-20s Create a certificate restricted to RSA-PSS (rsa only)\n",
|
||||
" --pss");
|
||||
FPS "%-20s Name of file containing PQG parameters (dsa only)\n",
|
||||
" -q pqgfile");
|
||||
FPS "%-20s Elliptic curve name (ec only)\n",
|
||||
" -q curve-name");
|
||||
FPS "%-20s See the \"-G\" option for a full list of supported names.\n",
|
||||
"");
|
||||
+ FPS "%-20s ML-DSA parameter set (mldsa only)\n",
|
||||
+ " -q paramset");
|
||||
+ FPS "%-20s See the \"-G\" option for a full list of supported names.\n",
|
||||
+ "");
|
||||
FPS "%-20s Self sign\n",
|
||||
" -x");
|
||||
FPS "%-20s Sign the certificate with RSA-PSS (the issuer key must be rsa)\n",
|
||||
" --pss-sign");
|
||||
FPS "%-20s Cert serial number\n",
|
||||
" -m serial-number");
|
||||
FPS "%-20s Time Warp\n",
|
||||
" -w warp-months");
|
||||
@@ -2773,19 +2787,44 @@ certutil_main(int argc, char **argv, PRB
|
||||
sourceDir = certutil.options[opt_SourceDir].arg;
|
||||
|
||||
if (certutil.options[opt_UpgradeID].activated)
|
||||
upgradeID = certutil.options[opt_UpgradeID].arg;
|
||||
|
||||
if (certutil.options[opt_UpgradeTokenName].activated)
|
||||
upgradeTokenName = certutil.options[opt_UpgradeTokenName].arg;
|
||||
|
||||
+ /* must be before opt_KeySize! */
|
||||
+ /* -k key type */
|
||||
+ if (certutil.options[opt_KeyType].activated) {
|
||||
+ char *arg = certutil.options[opt_KeyType].arg;
|
||||
+ if (PL_strcmp(arg, "rsa") == 0) {
|
||||
+ keytype = rsaKey;
|
||||
+ } else if (PL_strcmp(arg, "dsa") == 0) {
|
||||
+ keytype = dsaKey;
|
||||
+ } else if (PL_strcmp(arg, "ec") == 0) {
|
||||
+ keytype = ecKey;
|
||||
+ } else if (PL_strcmp(arg, "mldsa") == 0) {
|
||||
+ keytype = mldsaKey;
|
||||
+ } else if (PL_strcmp(arg, "all") == 0) {
|
||||
+ keytype = nullKey;
|
||||
+ } else {
|
||||
+ /* use an existing private/public key pair */
|
||||
+ keysource = arg;
|
||||
+ }
|
||||
+ } else if (certutil.commands[cmd_ListKeys].activated) {
|
||||
+ keytype = nullKey;
|
||||
+ }
|
||||
+
|
||||
if (certutil.options[opt_KeySize].activated) {
|
||||
keysize = PORT_Atoi(certutil.options[opt_KeySize].arg);
|
||||
- if ((keysize < MIN_KEY_BITS) || (keysize > MAX_KEY_BITS)) {
|
||||
+ /* mldsa limits are much different that rsa and dsa, don't
|
||||
+ * do the check here */
|
||||
+ if ((keytype != mldsaKey) &&
|
||||
+ ((keysize < MIN_KEY_BITS) || (keysize > MAX_KEY_BITS))) {
|
||||
PR_fprintf(PR_STDERR,
|
||||
"%s -g: Keysize must be between %d and %d.\n",
|
||||
progName, MIN_KEY_BITS, MAX_KEY_BITS);
|
||||
return 255;
|
||||
}
|
||||
if (keytype == ecKey) {
|
||||
PR_fprintf(PR_STDERR, "%s -g: Not for ec keys.\n", progName);
|
||||
return 255;
|
||||
@@ -2806,35 +2845,16 @@ certutil_main(int argc, char **argv, PRB
|
||||
hashAlgTag = SECU_StringToSignatureAlgTag(arg);
|
||||
if (hashAlgTag == SEC_OID_UNKNOWN) {
|
||||
PR_fprintf(PR_STDERR, "%s -Z: %s is not a recognized type.\n",
|
||||
progName, arg);
|
||||
return 255;
|
||||
}
|
||||
}
|
||||
|
||||
- /* -k key type */
|
||||
- if (certutil.options[opt_KeyType].activated) {
|
||||
- char *arg = certutil.options[opt_KeyType].arg;
|
||||
- if (PL_strcmp(arg, "rsa") == 0) {
|
||||
- keytype = rsaKey;
|
||||
- } else if (PL_strcmp(arg, "dsa") == 0) {
|
||||
- keytype = dsaKey;
|
||||
- } else if (PL_strcmp(arg, "ec") == 0) {
|
||||
- keytype = ecKey;
|
||||
- } else if (PL_strcmp(arg, "all") == 0) {
|
||||
- keytype = nullKey;
|
||||
- } else {
|
||||
- /* use an existing private/public key pair */
|
||||
- keysource = arg;
|
||||
- }
|
||||
- } else if (certutil.commands[cmd_ListKeys].activated) {
|
||||
- keytype = nullKey;
|
||||
- }
|
||||
-
|
||||
if (certutil.options[opt_KeyOpFlagsOn].activated) {
|
||||
keyOpFlagsOn = GetOpFlags(certutil.options[opt_KeyOpFlagsOn].arg);
|
||||
}
|
||||
if (certutil.options[opt_KeyOpFlagsOff].activated) {
|
||||
keyOpFlagsOff = GetOpFlags(certutil.options[opt_KeyOpFlagsOff].arg);
|
||||
keyOpFlagsOn &= ~keyOpFlagsOff; /* make off override on */
|
||||
}
|
||||
if (certutil.options[opt_KeyAttrFlags].activated) {
|
||||
@@ -2867,19 +2887,22 @@ certutil_main(int argc, char **argv, PRB
|
||||
srcCertPrefix = certutil.options[opt_SourcePrefix].arg;
|
||||
} else {
|
||||
Usage();
|
||||
}
|
||||
}
|
||||
|
||||
/* -q PQG file or curve name */
|
||||
if (certutil.options[opt_PQGFile].activated) {
|
||||
- if ((keytype != dsaKey) && (keytype != ecKey)) {
|
||||
+ if ((keytype != dsaKey) && (keytype != ecKey) &&
|
||||
+ (keytype != mldsaKey)) {
|
||||
PR_fprintf(PR_STDERR, "%s -q: specifies a PQG file for DSA keys"
|
||||
- " (-k dsa) or a named curve for EC keys (-k ec)\n)",
|
||||
+ " (-k dsa)\n"
|
||||
+ " or a named curve for EC keys (-k ec)\n"
|
||||
+ " or a parameter set for ML-DSA keys (-k mldsa)\n",
|
||||
progName);
|
||||
return 255;
|
||||
}
|
||||
}
|
||||
|
||||
/* -s subject name */
|
||||
if (certutil.options[opt_Subject].activated) {
|
||||
subject = CERT_AsciiToName(certutil.options[opt_Subject].arg);
|
||||
diff --git a/cmd/certutil/keystuff.c b/cmd/certutil/keystuff.c
|
||||
--- a/cmd/certutil/keystuff.c
|
||||
+++ b/cmd/certutil/keystuff.c
|
||||
@@ -512,16 +512,17 @@ CERTUTIL_GeneratePrivateKey(KeyType keyt
|
||||
int publicExponent, const char *noise,
|
||||
SECKEYPublicKey **pubkeyp, const char *pqgFile,
|
||||
PK11AttrFlags attrFlags, CK_FLAGS opFlagsOn,
|
||||
CK_FLAGS opFlagsOff, secuPWData *pwdata)
|
||||
{
|
||||
CK_MECHANISM_TYPE mechanism;
|
||||
PK11RSAGenParams rsaparams;
|
||||
SECKEYPQGParams *dsaparams = NULL;
|
||||
+ CK_ULONG paramSet;
|
||||
void *params;
|
||||
SECKEYPrivateKey *privKey = NULL;
|
||||
|
||||
if (slot == NULL)
|
||||
return NULL;
|
||||
|
||||
if (PK11_Authenticate(slot, PR_TRUE, pwdata) != SECSuccess)
|
||||
return NULL;
|
||||
@@ -564,16 +565,60 @@ CERTUTIL_GeneratePrivateKey(KeyType keyt
|
||||
}
|
||||
break;
|
||||
case ecKey:
|
||||
mechanism = CKM_EC_KEY_PAIR_GEN;
|
||||
/* For EC keys, PQGFile determines EC parameters */
|
||||
if ((params = (void *)getECParams(pqgFile)) == NULL)
|
||||
return NULL;
|
||||
break;
|
||||
+ case mldsaKey:
|
||||
+ mechanism = CKM_ML_DSA_KEY_PAIR_GEN;
|
||||
+ /* set paramset */
|
||||
+ paramSet = 0;
|
||||
+ if (pqgFile) {
|
||||
+ if (PORT_Strcasecmp(pqgFile, "ML-DSA-44") == 0) {
|
||||
+ paramSet = CKP_ML_DSA_44;
|
||||
+ } else if (PORT_Strcasecmp(pqgFile, "ML-DSA-65") == 0) {
|
||||
+ paramSet = CKP_ML_DSA_65;
|
||||
+ } else if (PORT_Strcasecmp(pqgFile, "ML-DSA-87") == 0) {
|
||||
+ paramSet = CKP_ML_DSA_87;
|
||||
+ } else {
|
||||
+ /* if we set pqgfile, it had better be right, don't
|
||||
+ * fall back to key size */
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ } else
|
||||
+ switch (size) {
|
||||
+ /* optionally use the size, either the actual size in bytes
|
||||
+ * or the short hand ('44', '65', '87') */
|
||||
+ case 44:
|
||||
+ case 2560:
|
||||
+ paramSet = CKP_ML_DSA_44;
|
||||
+ break;
|
||||
+ case 65:
|
||||
+ case 4032:
|
||||
+ paramSet = CKP_ML_DSA_65;
|
||||
+ break;
|
||||
+ case 87:
|
||||
+ case 4896:
|
||||
+ paramSet = CKP_ML_DSA_87;
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* force a size to be specified somewhere */
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ /* paranoia, shouldn't be able to happen logically. Code
|
||||
+ * scanners will scream, but I like belt and suspenders */
|
||||
+ if (paramSet == 0) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ params = ¶mSet;
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n\n");
|
||||
fprintf(stderr, "Generating key. This may take a few moments...\n\n");
|
||||
|
||||
privKey = PK11_GenerateKeyPairWithOpFlags(slot, mechanism, params, pubkeyp,
|
||||
diff --git a/cmd/pk11importtest/pk11importtest.c b/cmd/pk11importtest/pk11importtest.c
|
||||
--- a/cmd/pk11importtest/pk11importtest.c
|
||||
+++ b/cmd/pk11importtest/pk11importtest.c
|
||||
@@ -214,32 +214,34 @@ enum {
|
||||
opt_ECCurve,
|
||||
opt_PWFile,
|
||||
opt_PWString,
|
||||
opt_NoPub,
|
||||
opt_NoRSA,
|
||||
opt_NoDSA,
|
||||
opt_NoDH,
|
||||
opt_NoEC,
|
||||
+ opt_NoMLDSA,
|
||||
opt_NoMLKEM,
|
||||
opt_NoED,
|
||||
opt_NoECMont,
|
||||
};
|
||||
|
||||
static secuCommandFlag options[] = {
|
||||
{ /* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_KeySize */ 'k', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_ECCurve */ 'C', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_PWFile */ 'f', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_PWString */ 'p', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_NoPub */ 'n', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_NoRSA */ 'r', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_NoDSA */ 'D', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_NoDH */ 'h', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_NoEC */ 'e', PR_FALSE, 0, PR_FALSE },
|
||||
+ { /* opt_NoMLDSA */ 'm', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_NoMLKEM */ 'K', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_NoED */ 'w', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_NoECMont */ 'g', PR_FALSE, 0, PR_FALSE },
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@@ -248,16 +250,18 @@ main(int argc, char **argv)
|
||||
secuCommand args;
|
||||
PK11SlotInfo *slot = NULL;
|
||||
PRBool failed = PR_FALSE;
|
||||
secuPWData pwArgs = { PW_NONE, 0 };
|
||||
PRBool doRSA = PR_TRUE;
|
||||
PRBool doDSA = PR_TRUE;
|
||||
PRBool doDH = PR_FALSE; /* NSS currently can't export wrapped DH keys */
|
||||
PRBool doEC = PR_TRUE;
|
||||
+ PRBool doMLDSA = PR_FALSE;
|
||||
+ CK_ML_DSA_PARAMETER_SET_TYPE mldsaParamSet = CKP_ML_DSA_44;
|
||||
PRBool doMLKEM = PR_TRUE;
|
||||
PRBool doED = PR_TRUE;
|
||||
PRBool doECMont = PR_TRUE;
|
||||
PRBool noPub = PR_FALSE;
|
||||
PQGParams *pqgParams = NULL;
|
||||
int keySize;
|
||||
|
||||
args.numCommands = 0;
|
||||
@@ -308,16 +312,19 @@ main(int argc, char **argv)
|
||||
doDSA = PR_FALSE;
|
||||
}
|
||||
if (args.options[opt_NoDH].activated) {
|
||||
doDH = PR_FALSE;
|
||||
}
|
||||
if (args.options[opt_NoEC].activated) {
|
||||
doEC = PR_FALSE;
|
||||
}
|
||||
+ if (args.options[opt_NoMLDSA].activated) {
|
||||
+ doMLDSA = PR_FALSE;
|
||||
+ }
|
||||
if (args.options[opt_NoMLKEM].activated) {
|
||||
doMLKEM = PR_FALSE;
|
||||
}
|
||||
|
||||
slot = PK11_GetInternalKeySlot();
|
||||
if (slot == NULL) {
|
||||
SECU_PrintError(progName, "Couldn't find the internal key slot\n");
|
||||
return 255;
|
||||
@@ -403,16 +410,26 @@ main(int argc, char **argv)
|
||||
PORT_Free(ecParams.data);
|
||||
ec_failed:
|
||||
if (rv != SECSuccess) {
|
||||
fprintf(stderr, "ECC Import Failed!\n");
|
||||
failed = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
+ if (doMLDSA) {
|
||||
+ rv = handleEncryptedPrivateImportTest(progName, slot, "MLDSA",
|
||||
+ CKM_ML_DSA_KEY_PAIR_GEN,
|
||||
+ noPub, &mldsaParamSet, &pwArgs);
|
||||
+ if (rv != SECSuccess) {
|
||||
+ fprintf(stderr, "MLDSA Import Failed!\n");
|
||||
+ failed = PR_TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (doMLKEM) {
|
||||
CK_ML_KEM_PARAMETER_SET_TYPE paramSet = CKP_ML_KEM_768;
|
||||
|
||||
rv = handleEncryptedPrivateImportTest(progName, slot, "MLKEM",
|
||||
CKM_ML_KEM_KEY_PAIR_GEN,
|
||||
noPub, ¶mSet, &pwArgs);
|
||||
if (rv != SECSuccess) {
|
||||
fprintf(stderr, "MLKEM Import Failed!\n");
|
||||
diff --git a/tests/cert/cert.sh b/tests/cert/cert.sh
|
||||
--- a/tests/cert/cert.sh
|
||||
+++ b/tests/cert/cert.sh
|
||||
@@ -101,16 +101,19 @@ cert_init()
|
||||
fi
|
||||
|
||||
cert_add_algorithm "RSA" "" "" "false" 0
|
||||
if [ -z ${NSS_DISABLE_DSA} ]; then
|
||||
cert_add_algorithm "DSA" "-dsa" "-k dsa" "true" 20000
|
||||
fi
|
||||
# NOTE: curve is added later, so the full command would be '-k ec -q curve'
|
||||
cert_add_algorithm "ECC" "-ec" "-k ec -q" "true" 10000
|
||||
+ cert_add_algorithm "ML-DSA-44" "-ml-dsa-44" "-k mldsa -q ml-dsa-44" "false" 30000
|
||||
+ cert_add_algorithm "ML-DSA-65" "-ml-dsa-65" "-k mldsa -q ml-dsa-65" "false" 40000
|
||||
+ cert_add_algorithm "ML-DSA-87" "-ml-dsa-87" "-k mldsa -q ml-dsa-87" "false" 50000
|
||||
# currently rsa-pss is only enabled for a subset of tests
|
||||
# this will enable a full suite of RSA-PSS certs, and we would
|
||||
# then remove the explicit ones
|
||||
# ulike the other tests, we would need to change ssl tests as this
|
||||
# will rename some of the RSA-PSS certificates.
|
||||
#cert_add_algorithm "RSA-PSS" "-rsa-pss" "-k rsa -pss -Z sha256" "true"
|
||||
#cert_add_algorithm "RSA-PSS-SHA1" "-rsa-pss-sha1" "-k rsa -pss -Z sha1" "true"
|
||||
|
||||
@@ -519,16 +522,25 @@ cert_CA()
|
||||
cert_dsa_CA "${CUR_CADIR}" "${NICKNAME}" "${SIGNER}" "${TRUSTARG}" "${DOMAIN}" "${CERTSERIAL}"
|
||||
;;
|
||||
ECC)
|
||||
cert_ec_CA "${CUR_CADIR}" "${NICKNAME}" "${SIGNER}" "${TRUSTARG}" "${DOMAIN}" "${CERTSERIAL}" "${ALG}"
|
||||
;;
|
||||
RSA-PSS)
|
||||
cert_rsa_pss_CA "${CUR_CADIR}" "${NICKNAME}" "${SIGNER}" "${TRUSTARG}" "${DOMAIN}" "${CERTSERIAL}" "${ALG}"
|
||||
;;
|
||||
+ ML-DSA-44)
|
||||
+ cert_ml_dsa_CA ml-dsa-44 "${CUR_CADIR}" "${NICKNAME}" "${SIGNER}" "${TRUSTARG}" "${DOMAIN}" "${CERTSERIAL}"
|
||||
+ ;;
|
||||
+ ML-DSA-65)
|
||||
+ cert_ml_dsa_CA ml-dsa-65 "${CUR_CADIR}" "${NICKNAME}" "${SIGNER}" "${TRUSTARG}" "${DOMAIN}" "${CERTSERIAL}"
|
||||
+ ;;
|
||||
+ ML-DSA-87)
|
||||
+ cert_ml_dsa_CA ml-dsa-65 "${CUR_CADIR}" "${NICKNAME}" "${SIGNER}" "${TRUSTARG}" "${DOMAIN}" "${CERTSERIAL}"
|
||||
+ ;;
|
||||
*)
|
||||
Exit 9 "Fatal - unknown key type ${KEY_TYPE}, failed to create CA cert"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -672,19 +684,78 @@ CERTSCRIPT
|
||||
CU_ACTION="Exporting DSA Root Cert"
|
||||
certu -L -n $NICKNAME -r -d ${LPROFILE} -o root-dsa.cert
|
||||
if [ "$RET" -ne 0 ]; then
|
||||
Exit 7 "Fatal - failed to export dsa root cert"
|
||||
fi
|
||||
cp root-dsa.cert ${NICKNAME}.ca.cert
|
||||
}
|
||||
|
||||
++################################ cert_ml_dsa_CA #############################
|
||||
+# local shell function to build the Temp. Certificate Authority (CA)
|
||||
+# used for testing purposes, creating a CA Certificate and a root cert
|
||||
+# This is the ML-DSA version of cert_CA.
|
||||
+##########################################################################
|
||||
+cert_ml_dsa_CA()
|
||||
+{
|
||||
+ PARAM_SET=$1
|
||||
+ CUR_CADIR=$2
|
||||
+ NICKNAME=$3
|
||||
+ SIGNER=$4
|
||||
+ TRUSTARG=$5
|
||||
+ DOMAIN=$6
|
||||
+ CERTSERIAL=$7
|
||||
|
||||
+ echo "$SCRIPTNAME: Creating a ML-DSA ($PARAM_SET) CA Certificate $NICKNAME =========================="
|
||||
+
|
||||
+ if [ ! -d "${CUR_CADIR}" ]; then
|
||||
+ mkdir -p "${CUR_CADIR}"
|
||||
+ fi
|
||||
+ cd ${CUR_CADIR}
|
||||
+ pwd
|
||||
+
|
||||
+ LPROFILE=.
|
||||
+ if [ -n "${MULTIACCESS_DBM}" ]; then
|
||||
+ LPROFILE="multiaccess:${DOMAIN}"
|
||||
+ fi
|
||||
|
||||
+ ################# Creating a ML-DSA CA Cert ###############################
|
||||
+ #
|
||||
+ CU_ACTION="Creating ML-DSA ($PARAM_SET) CA Cert $NICKNAME "
|
||||
+ CU_SUBJECT=$ALL_CU_SUBJECT
|
||||
+ certu -S -n $NICKNAME -k mldsa -q $PARAM_SET -t $TRUSTARG -v 600 $SIGNER \
|
||||
+ -d ${LPROFILE} -1 -2 -5 -f ${R_PWFILE} -z ${R_NOISE_FILE} \
|
||||
+ -m $CERTSERIAL 2>&1 <<CERTSCRIPT
|
||||
+5
|
||||
+6
|
||||
+9
|
||||
+n
|
||||
+y
|
||||
+-1
|
||||
+n
|
||||
+5
|
||||
+6
|
||||
+7
|
||||
+9
|
||||
+n
|
||||
+CERTSCRIPT
|
||||
|
||||
+ if [ "$RET" -ne 0 ]; then
|
||||
+ echo "return value is $RET"
|
||||
+ Exit 6 "Fatal - failed to create ML-DSA ($PARAM_SET) CA cert"
|
||||
+ fi
|
||||
+
|
||||
+ ################# Exporting ML-DSA Root Cert ###############################
|
||||
+ #
|
||||
+ CU_ACTION="Exporting ML-DSA ($PARAM_SET) Root Cert"
|
||||
+ certu -L -n $NICKNAME -r -d ${LPROFILE} -o ${NICKNAME}.ca.cert
|
||||
+ if [ "$RET" -ne 0 ]; then
|
||||
+ Exit 7 "Fatal - failed to export $PARAM_SET root cert"
|
||||
+ fi
|
||||
+}
|
||||
|
||||
################################ cert_rsa_pss_CA #############################
|
||||
# local shell function to build the Temp. Certificate Authority (CA)
|
||||
# used for testing purposes, creating a CA Certificate and a root cert
|
||||
# This is the RSA-PSS version of cert_CA.
|
||||
##########################################################################
|
||||
cert_rsa_pss_CA()
|
||||
{
|
||||
@@ -1194,17 +1265,17 @@ cert_stresscerts()
|
||||
}
|
||||
|
||||
############################## cert_fips #####################################
|
||||
# local shell function to create certificates for FIPS tests
|
||||
##############################################################################
|
||||
cert_fips()
|
||||
{
|
||||
CERTFAILED=0
|
||||
- echo "$SCRIPTNAME: Creating FIPS 140 DSA Certificates =============="
|
||||
+ echo "$SCRIPTNAME: Creating FIPS 140 Certificates =============="
|
||||
cert_init_cert "${FIPSDIR}" "FIPS PUB 140 Test Certificate" 1000 "${D_FIPS}"
|
||||
|
||||
CU_ACTION="Initializing ${CERTNAME}'s Cert DB"
|
||||
certu -N -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" 2>&1
|
||||
|
||||
CU_ACTION="Loading root cert module to ${CERTNAME}'s Cert DB (ext.)"
|
||||
modu -add "RootCerts" -libfile "${ROOTCERTSFILE}" -dbdir "${PROFILEDIR}" 2>&1
|
||||
|
||||
diff --git a/tests/tools/tools.sh b/tests/tools/tools.sh
|
||||
--- a/tests/tools/tools.sh
|
||||
+++ b/tests/tools/tools.sh
|
||||
@@ -124,24 +124,32 @@ tools_init()
|
||||
cp ${QADIR}/tools/pbmac1-valid-sha256.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/pbmac1-valid-sha256-sha512.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/pbmac1-valid-sha512.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/pbmac1-invalid-bad-iter.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/pbmac1-invalid-bad-salt.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/pbmac1-invalid-no-length.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/corrupted_cert_bag.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/openssl-ed25519.p12 ${TOOLSDIR}/data
|
||||
+ cp ${QADIR}/tools/ietf-ml-dsa-44-both.p12 ${TOOLSDIR}/data
|
||||
+ cp ${QADIR}/tools/ietf-ml-dsa-44-key.p12 ${TOOLSDIR}/data
|
||||
+ cp ${QADIR}/tools/ietf-ml-dsa-65-both.p12 ${TOOLSDIR}/data
|
||||
+ cp ${QADIR}/tools/ietf-ml-dsa-65-key.p12 ${TOOLSDIR}/data
|
||||
+ cp ${QADIR}/tools/ietf-ml-dsa-87-both.p12 ${TOOLSDIR}/data
|
||||
+ cp ${QADIR}/tools/ietf-ml-dsa-87-key.p12 ${TOOLSDIR}/data
|
||||
+ cp ${QADIR}/tools/openssl-ml-dsa-44.p12 ${TOOLSDIR}/data
|
||||
+ cp ${QADIR}/tools/openssl-ml-dsa-65.p12 ${TOOLSDIR}/data
|
||||
+ cp ${QADIR}/tools/openssl-ml-dsa-87.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/openssl-ml-kem-768-seed.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/openssl-ml-kem-768-priv.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/openssl-ml-kem-768-both.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/openssl-ml-kem-1024-seed.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/openssl-ml-kem-1024-priv.p12 ${TOOLSDIR}/data
|
||||
cp ${QADIR}/tools/openssl-ml-kem-1024-both.p12 ${TOOLSDIR}/data
|
||||
|
||||
-
|
||||
cd ${TOOLSDIR}
|
||||
}
|
||||
|
||||
########################## list_p12_file ###############################
|
||||
# List the key and cert in the specified p12 file
|
||||
########################################################################
|
||||
list_p12_file()
|
||||
{
|
||||
@@ -543,16 +551,43 @@ tools_p12_import_ed25519_private_key()
|
||||
${BINDIR}/pk12util -i ${TOOLSDIR}/data/openssl-ed25519.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W 'test' 2>&1
|
||||
ret=$?
|
||||
html_msg $ret 0 "Importing ED25519 private key from PKCS#12 file"
|
||||
check_tmpfile
|
||||
|
||||
return $ret
|
||||
}
|
||||
|
||||
+tools_p12_ml_dsa_import()
|
||||
+{
|
||||
+ echo "$SCRIPTNAME: Testing ml-dsa compatibility with pkcs12 --------------"
|
||||
+ for i in 44 65 87
|
||||
+ do
|
||||
+ echo "${BINDIR}/pk12util -i ${TOOLSDIR}/data/openssl-ml-dsa-$i.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W 'test' 2>&1"
|
||||
+ ${BINDIR}/pk12util -i ${TOOLSDIR}/data/openssl-ml-dsa-$i.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W 'test' 2>&1
|
||||
+ ret=$?
|
||||
+ html_msg $ret 0 "Importing openssl encoded ml-dsa-$i private key from PKCS#12 file"
|
||||
+ check_tmpfile
|
||||
+ for j in 'key' 'both'
|
||||
+ do
|
||||
+ echo "${BINDIR}/pk12util -i ${TOOLSDIR}/data/ietf-ml-dsa-$i-$j.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W 'test' 2>&1"
|
||||
+ ${BINDIR}/pk12util -i ${TOOLSDIR}/data/ietf-ml-dsa-$i-$j.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W 'test' 2>&1
|
||||
+ ret=$?
|
||||
+ html_msg $ret 0 "Importing openssl encoded ml-dsa-$i private key from PKCS#12 file"
|
||||
+ check_tmpfile
|
||||
+ html_msg $ret 0 "Importing ietf sample ml-dsa-$i-$j private key from PKCS#12 file"
|
||||
+
|
||||
+ # each cert has the same issuer/sn, so we can't hold more than one in
|
||||
+ # the data base
|
||||
+ echo "${BINDIR}/certutil -F -n \"ietf ml-dsa-$i-$j sample\" -d ${P_R_COPYDIR} -f ${R_PWFILE}"
|
||||
+ ${BINDIR}/certutil -F -n "ietf ml-dsa-$i-$j sample" -d ${P_R_COPYDIR} -f ${R_PWFILE}
|
||||
+ done
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
tools_p12_ml_kem_import()
|
||||
{
|
||||
echo "$SCRIPTNAME: Testing ml-kem compatibility with pkcs12 --------------"
|
||||
for i in 768 1024
|
||||
do
|
||||
for j in 'seed' 'priv' 'both'
|
||||
do
|
||||
echo "${BINDIR}/pk12util -i ${TOOLSDIR}/data/openssl-ml-kem-$i-$j.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W 'test' 2>&1"
|
||||
@@ -624,16 +659,17 @@ tools_p12()
|
||||
else
|
||||
tools_p12_export_list_import_most_ciphers
|
||||
fi
|
||||
tools_p12_export_with_none_ciphers
|
||||
tools_p12_export_with_invalid_ciphers
|
||||
tools_p12_import_old_files
|
||||
tools_p12_import_pbmac1_samples
|
||||
tools_p12_import_ed25519_private_key
|
||||
+ tools_p12_ml_dsa_import
|
||||
tools_p12_ml_kem_import
|
||||
if using_sql; then
|
||||
tools_p12_import_rsa_pss_private_key
|
||||
tools_p12_policy
|
||||
fi
|
||||
}
|
||||
|
||||
############################## tools_sign ##############################
|
||||
496
nss-3.124-ml-dsa-tls-test.patch
Normal file
496
nss-3.124-ml-dsa-tls-test.patch
Normal file
@ -0,0 +1,496 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1780515790 25200
|
||||
# Wed Jun 03 12:43:10 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID 2d30979ddc35d6c5bde652f8692081f39aec78a0
|
||||
# Parent eaa726433f362aed5f4cdc40fe0b6aa813d99ed7
|
||||
nss-3.124-ml-dsa-tls-test.patch
|
||||
|
||||
diff --git a/cmd/lib/secutil.c b/cmd/lib/secutil.c
|
||||
--- a/cmd/lib/secutil.c
|
||||
+++ b/cmd/lib/secutil.c
|
||||
@@ -4446,16 +4446,19 @@ static const struct SSLSignatureSchemeSt
|
||||
MAKE_SCHEME(ed448),
|
||||
MAKE_SCHEME(rsa_pss_pss_sha256),
|
||||
MAKE_SCHEME(rsa_pss_pss_sha384),
|
||||
MAKE_SCHEME(rsa_pss_pss_sha512),
|
||||
MAKE_SCHEME(dsa_sha1),
|
||||
MAKE_SCHEME(dsa_sha256),
|
||||
MAKE_SCHEME(dsa_sha384),
|
||||
MAKE_SCHEME(dsa_sha512),
|
||||
+ MAKE_SCHEME(mldsa44),
|
||||
+ MAKE_SCHEME(mldsa65),
|
||||
+ MAKE_SCHEME(mldsa87),
|
||||
};
|
||||
|
||||
static const size_t sslSignatureSchemeStringLen =
|
||||
PR_ARRAY_SIZE(sslSignatureSchemeStringArray);
|
||||
|
||||
const char *
|
||||
SECU_SignatureSchemeGetNextScheme(size_t i)
|
||||
{
|
||||
diff --git a/gtests/ssl_gtest/ssl_auth_unittest.cc b/gtests/ssl_gtest/ssl_auth_unittest.cc
|
||||
--- a/gtests/ssl_gtest/ssl_auth_unittest.cc
|
||||
+++ b/gtests/ssl_gtest/ssl_auth_unittest.cc
|
||||
@@ -2476,10 +2476,32 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SignatureSchemeEcdsaSha1, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
||||
TlsConnectTestBase::kTlsV12,
|
||||
::testing::Values(TlsAgent::kServerEcdsa256,
|
||||
TlsAgent::kServerEcdsa384),
|
||||
::testing::Values(ssl_auth_ecdsa),
|
||||
::testing::Values(ssl_sig_ecdsa_sha1)));
|
||||
+// ML-DSA is only allowed to be used in TLS 1.3 or greater
|
||||
+INSTANTIATE_TEST_SUITE_P(
|
||||
+ SignatureSchemeMlDsa44Tls13, TlsSignatureSchemeConfiguration,
|
||||
+ ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
||||
+ TlsConnectTestBase::kTlsV13,
|
||||
+ ::testing::Values(TlsAgent::kServerMlDsa44),
|
||||
+ ::testing::Values(ssl_auth_mldsa44),
|
||||
+ ::testing::Values(ssl_sig_mldsa44)));
|
||||
+INSTANTIATE_TEST_SUITE_P(
|
||||
+ SignatureSchemeMlDsa65Tls13, TlsSignatureSchemeConfiguration,
|
||||
+ ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
||||
+ TlsConnectTestBase::kTlsV13,
|
||||
+ ::testing::Values(TlsAgent::kServerMlDsa65),
|
||||
+ ::testing::Values(ssl_auth_mldsa65),
|
||||
+ ::testing::Values(ssl_sig_mldsa65)));
|
||||
+INSTANTIATE_TEST_SUITE_P(
|
||||
+ SignatureSchemeMlDsa87Tls13, TlsSignatureSchemeConfiguration,
|
||||
+ ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
||||
+ TlsConnectTestBase::kTlsV13,
|
||||
+ ::testing::Values(TlsAgent::kServerMlDsa87),
|
||||
+ ::testing::Values(ssl_auth_mldsa87),
|
||||
+ ::testing::Values(ssl_sig_mldsa87)));
|
||||
|
||||
} // namespace nss_test
|
||||
diff --git a/gtests/ssl_gtest/tls_agent.cc b/gtests/ssl_gtest/tls_agent.cc
|
||||
--- a/gtests/ssl_gtest/tls_agent.cc
|
||||
+++ b/gtests/ssl_gtest/tls_agent.cc
|
||||
@@ -39,19 +39,25 @@ const std::string TlsAgent::kServerRsaSi
|
||||
const std::string TlsAgent::kServerRsaPss = "rsa_pss";
|
||||
const std::string TlsAgent::kServerRsaDecrypt = "rsa_decrypt";
|
||||
const std::string TlsAgent::kServerEcdsa256 = "ecdsa256";
|
||||
const std::string TlsAgent::kServerEcdsa384 = "ecdsa384";
|
||||
const std::string TlsAgent::kServerEcdsa521 = "ecdsa521";
|
||||
const std::string TlsAgent::kServerEcdhRsa = "ecdh_rsa";
|
||||
const std::string TlsAgent::kServerEcdhEcdsa = "ecdh_ecdsa";
|
||||
const std::string TlsAgent::kServerDsa = "dsa";
|
||||
+const std::string TlsAgent::kServerMlDsa44 = "mldsa44";
|
||||
+const std::string TlsAgent::kServerMlDsa65 = "mldsa65";
|
||||
+const std::string TlsAgent::kServerMlDsa87 = "mldsa87";
|
||||
const std::string TlsAgent::kDelegatorEcdsa256 = "delegator_ecdsa256";
|
||||
const std::string TlsAgent::kDelegatorRsae2048 = "delegator_rsae2048";
|
||||
const std::string TlsAgent::kDelegatorRsaPss2048 = "delegator_rsa_pss2048";
|
||||
+const std::string TlsAgent::kDelegatorMlDsa44 = "delegator_mldsa44";
|
||||
+const std::string TlsAgent::kDelegatorMlDsa65 = "delegator_mldsa65";
|
||||
+const std::string TlsAgent::kDelegatorMlDsa87 = "delegator_mldsa87";
|
||||
|
||||
static const uint8_t kCannedTls13ServerHello[] = {
|
||||
0x03, 0x03, 0x9c, 0xbc, 0x14, 0x9b, 0x0e, 0x2e, 0xfa, 0x0d, 0xf3,
|
||||
0xf0, 0x5c, 0x70, 0x7a, 0xe0, 0xd1, 0x9b, 0x3e, 0x5a, 0x44, 0x6b,
|
||||
0xdf, 0xe5, 0xc2, 0x28, 0x64, 0xf7, 0x00, 0xc1, 0x9c, 0x08, 0x76,
|
||||
0x08, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33, 0x00, 0x24,
|
||||
0x00, 0x1d, 0x00, 0x20, 0xc2, 0xcf, 0x23, 0x17, 0x64, 0x23, 0x03,
|
||||
0xf0, 0xfb, 0x45, 0x98, 0x26, 0xd1, 0x65, 0x24, 0xa1, 0x6c, 0xa9,
|
||||
diff --git a/gtests/ssl_gtest/tls_agent.h b/gtests/ssl_gtest/tls_agent.h
|
||||
--- a/gtests/ssl_gtest/tls_agent.h
|
||||
+++ b/gtests/ssl_gtest/tls_agent.h
|
||||
@@ -82,19 +82,25 @@ class TlsAgent : public PollTarget {
|
||||
static const std::string kServerRsaPss;
|
||||
static const std::string kServerRsaDecrypt;
|
||||
static const std::string kServerEcdsa256;
|
||||
static const std::string kServerEcdsa384;
|
||||
static const std::string kServerEcdsa521;
|
||||
static const std::string kServerEcdhEcdsa;
|
||||
static const std::string kServerEcdhRsa;
|
||||
static const std::string kServerDsa;
|
||||
+ static const std::string kServerMlDsa44;
|
||||
+ static const std::string kServerMlDsa65;
|
||||
+ static const std::string kServerMlDsa87;
|
||||
static const std::string kDelegatorEcdsa256; // draft-ietf-tls-subcerts
|
||||
static const std::string kDelegatorRsae2048; // draft-ietf-tls-subcerts
|
||||
static const std::string kDelegatorRsaPss2048; // draft-ietf-tls-subcerts
|
||||
+ static const std::string kDelegatorMlDsa44; // draft-ietf-tls-subcerts
|
||||
+ static const std::string kDelegatorMlDsa65; // draft-ietf-tls-subcerts
|
||||
+ static const std::string kDelegatorMlDsa87; // draft-ietf-tls-subcerts
|
||||
|
||||
TlsAgent(const std::string& name, Role role, SSLProtocolVariant variant);
|
||||
virtual ~TlsAgent();
|
||||
|
||||
void SetPeer(std::shared_ptr<TlsAgent>& peer) {
|
||||
adapter_->SetPeer(peer->adapter_);
|
||||
}
|
||||
|
||||
diff --git a/gtests/ssl_gtest/tls_subcerts_unittest.cc b/gtests/ssl_gtest/tls_subcerts_unittest.cc
|
||||
--- a/gtests/ssl_gtest/tls_subcerts_unittest.cc
|
||||
+++ b/gtests/ssl_gtest/tls_subcerts_unittest.cc
|
||||
@@ -19,21 +19,23 @@
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
#ifndef LTO
|
||||
// sigh this construction breaks LTO
|
||||
const std::string kEcdsaDelegatorId = TlsAgent::kDelegatorEcdsa256;
|
||||
const std::string kRsaeDelegatorId = TlsAgent::kDelegatorRsae2048;
|
||||
const std::string kPssDelegatorId = TlsAgent::kDelegatorRsaPss2048;
|
||||
+const std::string kMlDsa65DelegatorId = TlsAgent::kDelegatorMlDsa65;
|
||||
const std::string kDCId = TlsAgent::kServerEcdsa256;
|
||||
#else
|
||||
#define kEcdsaDelegatorId TlsAgent::kDelegatorEcdsa256
|
||||
#define kRsaeDelegatorId TlsAgent::kDelegatorRsae2048
|
||||
#define kPssDelegatorId TlsAgent::kDelegatorRsaPss2048
|
||||
+#define kMlDsa65DelegatorId TlsAgent::kDelegatorMlDsa65
|
||||
#define kDCId TlsAgent::kServerEcdsa256
|
||||
#endif
|
||||
const SSLSignatureScheme kDCScheme = ssl_sig_ecdsa_secp256r1_sha256;
|
||||
const PRUint32 kDCValidFor = 60 * 60 * 24 * 7 /* 1 week (seconds) */;
|
||||
|
||||
static void CheckPreliminaryPeerDelegCred(
|
||||
const std::shared_ptr<TlsAgent>& client, bool expected,
|
||||
PRUint32 key_bits = 0, SSLSignatureScheme sig_scheme = ssl_sig_none) {
|
||||
@@ -234,16 +236,62 @@ TEST_P(TlsConnectTls13, DCConnectEcdsaP2
|
||||
client_, ssl_delegated_credentials_xtn);
|
||||
Connect();
|
||||
|
||||
EXPECT_TRUE(cfilter->captured());
|
||||
CheckPeerDelegCred(client_, true, 256);
|
||||
EXPECT_EQ(ssl_sig_ecdsa_secp256r1_sha256, client_->info().signatureScheme);
|
||||
}
|
||||
|
||||
+// Connected with ML-DSA-65, using an ML-DSA-65 SKI and ML-DSA-65 delegation
|
||||
+// cert.
|
||||
+TEST_P(TlsConnectTls13, DCConnectMlDsa65MlDsa65) {
|
||||
+ Reset(kMlDsa65DelegatorId);
|
||||
+
|
||||
+ static const SSLSignatureScheme kSchemes[] = {ssl_sig_ecdsa_secp256r1_sha256,
|
||||
+ ssl_sig_mldsa65};
|
||||
+ client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
|
||||
+ server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
|
||||
+
|
||||
+ client_->EnableDelegatedCredentials();
|
||||
+ server_->AddDelegatedCredential(TlsAgent::kServerMlDsa65, ssl_sig_mldsa65,
|
||||
+ kDCValidFor, now());
|
||||
+
|
||||
+ auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
|
||||
+ client_, ssl_delegated_credentials_xtn);
|
||||
+ Connect();
|
||||
+
|
||||
+ EXPECT_TRUE(cfilter->captured());
|
||||
+ CheckPeerDelegCred(client_, true, ML_DSA_65_PUBLICKEY_LEN * 8);
|
||||
+ EXPECT_EQ(ssl_sig_mldsa65, client_->info().signatureScheme);
|
||||
+}
|
||||
+
|
||||
+// Connected with ECDSA-P256 using a ML-DSA-65 delegation cert.
|
||||
+TEST_P(TlsConnectTls13, DCConnectEcdsaP256MlDsa65) {
|
||||
+ Reset(kMlDsa65DelegatorId);
|
||||
+
|
||||
+ static const SSLSignatureScheme kSchemes[] = {ssl_sig_ecdsa_secp256r1_sha256,
|
||||
+ ssl_sig_mldsa65};
|
||||
+ client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
|
||||
+ server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
|
||||
+
|
||||
+ client_->EnableDelegatedCredentials();
|
||||
+ server_->AddDelegatedCredential(TlsAgent::kServerEcdsa256,
|
||||
+ ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
|
||||
+ now());
|
||||
+
|
||||
+ auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
|
||||
+ client_, ssl_delegated_credentials_xtn);
|
||||
+ Connect();
|
||||
+
|
||||
+ EXPECT_TRUE(cfilter->captured());
|
||||
+ CheckPeerDelegCred(client_, true, 256);
|
||||
+ EXPECT_EQ(ssl_sig_ecdsa_secp256r1_sha256, client_->info().signatureScheme);
|
||||
+}
|
||||
+
|
||||
// Simulate the client receiving a DC containing algorithms not advertised.
|
||||
// Do this by tweaking the client's supported sigSchemes after the CH.
|
||||
TEST_P(TlsConnectTls13, DCReceiveUnadvertisedScheme) {
|
||||
Reset(kEcdsaDelegatorId);
|
||||
static const SSLSignatureScheme kClientSchemes[] = {
|
||||
ssl_sig_ecdsa_secp256r1_sha256, ssl_sig_ecdsa_secp384r1_sha384};
|
||||
static const SSLSignatureScheme kServerSchemes[] = {
|
||||
ssl_sig_ecdsa_secp384r1_sha384, ssl_sig_ecdsa_secp256r1_sha256};
|
||||
@@ -729,11 +777,28 @@ TEST_F(DCDelegation, DCDelegations) {
|
||||
cert.get(), priv.get(), pub_ecdsa.get(),
|
||||
ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now, &dc));
|
||||
EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
|
||||
EXPECT_EQ(SECFailure,
|
||||
SSL_DelegateCredential(cert.get(), priv.get(), pub_ecdsa.get(),
|
||||
ssl_sig_ecdsa_secp384r1_sha384, kDCValidFor,
|
||||
now, &dc));
|
||||
EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
|
||||
+ ScopedSECKEYPublicKey pub_mldsa;
|
||||
+ ScopedSECKEYPrivateKey priv_mldsa;
|
||||
+ ASSERT_TRUE(TlsAgent::LoadKeyPairFromCert(TlsAgent::kServerMlDsa65,
|
||||
+ &pub_mldsa, &priv_mldsa));
|
||||
+ EXPECT_EQ(SECFailure,
|
||||
+ SSL_DelegateCredential(cert.get(), priv.get(), pub_mldsa.get(),
|
||||
+ ssl_sig_rsa_pss_rsae_sha256, kDCValidFor,
|
||||
+ now, &dc));
|
||||
+ EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
|
||||
+ EXPECT_EQ(SECFailure,
|
||||
+ SSL_DelegateCredential(cert.get(), priv.get(), pub_mldsa.get(),
|
||||
+ ssl_sig_mldsa44, kDCValidFor, now, &dc));
|
||||
+ EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
|
||||
+ EXPECT_EQ(SECSuccess,
|
||||
+ SSL_DelegateCredential(cert.get(), priv.get(), pub_mldsa.get(),
|
||||
+ ssl_sig_mldsa65, kDCValidFor, now, &dc));
|
||||
+ dc.Reset();
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
||||
diff --git a/tests/common/certsetup.sh b/tests/common/certsetup.sh
|
||||
--- a/tests/common/certsetup.sh
|
||||
+++ b/tests/common/certsetup.sh
|
||||
@@ -32,25 +32,49 @@ make_cert() {
|
||||
dsa) type_args=(-g 1024) ;;
|
||||
rsa) type_args=(-g 1024) ;;
|
||||
rsa2048) type_args=(-g 2048);type=rsa ;;
|
||||
rsa8192) type_args=(-g 8192);type=rsa ;;
|
||||
rsapss) type_args=(-g 1024 --pss);type=rsa ;;
|
||||
rsapss384) type_args=(-g 1024 --pss);type=rsa;sighash=(-Z SHA384) ;;
|
||||
rsapss512) type_args=(-g 2048 --pss);type=rsa;sighash=(-Z SHA512) ;;
|
||||
rsapss_noparam) type_args=(-g 2048 --pss);type=rsa;sighash=() ;;
|
||||
+ mldsa44) type_args=(-q ml-dsa-44);type=mldsa;sighash=() ;;
|
||||
+ mldsa65) type_args=(-q ml-dsa-65);type=mldsa;sighash=() ;;
|
||||
+ mldsa87) type_args=(-q ml-dsa-87);type=mldsa;sighash=() ;;
|
||||
p256) type_args=(-q nistp256);type=ec ;;
|
||||
p384) type_args=(-q secp384r1);type=ec ;;
|
||||
p521) type_args=(-q secp521r1);type=ec ;;
|
||||
rsa_ca) type_args=(-g 1024);trust='CT,CT,CT';type=rsa ;;
|
||||
rsa_chain) type_args=(-g 1024);sign=(-c rsa_ca);type=rsa;;
|
||||
rsapss_ca) type_args=(-g 1024 --pss);trust='CT,CT,CT';type=rsa ;;
|
||||
rsapss_chain) type_args=(-g 1024);sign=(-c rsa_pss_ca);type=rsa;;
|
||||
rsa_ca_rsapss_chain) type_args=(-g 1024 --pss-sign);sign=(-c rsa_ca);type=rsa;;
|
||||
+ mldsa44_ca) type_args=(-q ml-dsa-44);trust='CT,CT,CT';type=mldsa ;;
|
||||
+ mldsa65_ca) type_args=(-q ml-dsa-65);trust='CT,CT,CT';type=mldsa ;;
|
||||
+ mldsa87_ca) type_args=(-q ml-dsa-87);trust='CT,CT,CT';type=mldsa ;;
|
||||
+ mldsa44_chain) type_args=(-q ml-dsa-44);sign=(-c mldsa44_ca);type=mldsa;;
|
||||
+ mldsa65_chain) type_args=(-q ml-dsa-65);sign=(-c mldsa65_ca);type=mldsa;;
|
||||
+ mldsa87_chain) type_args=(-q ml-dsa-87);sign=(-c mldsa87_ca);type=mldsa;;
|
||||
ecdh_rsa) type_args=(-q nistp256);sign=(-c rsa_ca);type=ec ;;
|
||||
+ delegator_mldsa44)
|
||||
+ touch empty.txt
|
||||
+ type_args=(-q ml-dsa-44 --extGeneric 1.3.6.1.4.1.44363.44:not-critical:empty.txt)
|
||||
+ type=mldsa
|
||||
+ ;;
|
||||
+ delegator_mldsa65)
|
||||
+ touch empty.txt
|
||||
+ type_args=(-q ml-dsa-65 --extGeneric 1.3.6.1.4.1.44363.44:not-critical:empty.txt)
|
||||
+ type=mldsa
|
||||
+ ;;
|
||||
+ delegator_mldsa87)
|
||||
+ touch empty.txt
|
||||
+ type_args=(-q ml-dsa-87 --extGeneric 1.3.6.1.4.1.87363.87:not-critical:empty.txt)
|
||||
+ type=mldsa
|
||||
+ ;;
|
||||
delegator_p256)
|
||||
touch empty.txt
|
||||
type_args=(-q nistp256 --extGeneric 1.3.6.1.4.1.44363.44:not-critical:empty.txt)
|
||||
type=ec
|
||||
;;
|
||||
delegator_rsae2048)
|
||||
touch empty.txt
|
||||
type_args=(-g 2048 --extGeneric 1.3.6.1.4.1.44363.44:not-critical:empty.txt)
|
||||
diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh
|
||||
--- a/tests/ssl/ssl.sh
|
||||
+++ b/tests/ssl/ssl.sh
|
||||
@@ -241,40 +241,45 @@ kill_selfserv()
|
||||
# also: wait until the server is up and running
|
||||
########################################################################
|
||||
start_selfserv()
|
||||
{
|
||||
if [ -n "$testname" ] ; then
|
||||
echo "$SCRIPTNAME: $testname ----"
|
||||
fi
|
||||
if [ -z "$NO_ECC_CERTS" -o "$NO_ECC_CERTS" != "1" ] ; then
|
||||
- ECC_OPTIONS="-e ${HOSTADDR}-ecmixed -e ${HOSTADDR}-ec"
|
||||
+ ECC_OPTIONS="-e ${HOSTADDR}-ecmixed -e ${HOSTADDR}-ec "
|
||||
else
|
||||
ECC_OPTIONS=""
|
||||
fi
|
||||
+ if [ -z "$NO_ML_DSA_CERTS" -o "$NO_ML_DSA_CERTS" != "1" ] ; then
|
||||
+ ML_DSA_OPTIONS="-e ${HOSTADDR}-ml-dsa-44 -e ${HOSTADDR}-ml-dsa-65 -e ${HOSTADDR}-ml-dsa-87 "
|
||||
+ else
|
||||
+ ML_DSA_OPTIONS=""
|
||||
+ fi
|
||||
if [ -z "$RSA_PSS_CERT" -o "$RSA_PSS_CERT" != "1" ] ; then
|
||||
RSA_OPTIONS="-n ${HOSTADDR}"
|
||||
else
|
||||
RSA_OPTIONS="-n ${HOSTADDR}-rsa-pss"
|
||||
fi
|
||||
if [ -z "$NSS_DISABLE_DSA" ]; then
|
||||
- DSA_OPTIONS="-S ${HOSTADDR}-dsa"
|
||||
+ DSA_OPTIONS="-S ${HOSTADDR}-dsa "
|
||||
else
|
||||
DSA_OPTIONS=""
|
||||
fi
|
||||
|
||||
SERVER_VMIN=${SERVER_VMIN-ssl3}
|
||||
SERVER_VMAX=${SERVER_VMAX-tls1.2}
|
||||
echo "selfserv starting at `date`"
|
||||
echo "selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} ${RSA_OPTIONS} ${SERVER_OPTIONS} \\"
|
||||
- echo " ${ECC_OPTIONS} ${DSA_OPTIONS} -w nss "$@" -i ${R_SERVERPID}\\"
|
||||
+ echo " ${ECC_OPTIONS}${DSA_OPTIONS}${ML_DSA_OPTONS}-w nss "$@" -i ${R_SERVERPID}\\"
|
||||
echo " -V ${SERVER_VMIN}:${SERVER_VMAX} $verbose -H 1 &"
|
||||
if [ ${fileout} -eq 1 ]; then
|
||||
${PROFTOOL} ${BINDIR}/selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} ${RSA_OPTIONS} ${SERVER_OPTIONS} \
|
||||
- ${ECC_OPTIONS} ${DSA_OPTIONS} -w nss "$@" -i ${R_SERVERPID} -V ${SERVER_VMIN}:${SERVER_VMAX} $verbose -H 1 \
|
||||
+ ${ECC_OPTIONS}${DSA_OPTIONS}${ML_DSA_OPTIONS}-w nss "$@" -i ${R_SERVERPID} -V ${SERVER_VMIN}:${SERVER_VMAX} $verbose -H 1 \
|
||||
> ${SERVEROUTFILE} 2>&1 &
|
||||
RET=$?
|
||||
else
|
||||
${PROFTOOL} ${BINDIR}/selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} ${RSA_OPTIONS} ${SERVER_OPTIONS} \
|
||||
${ECC_OPTIONS} ${DSA_OPTIONS} -w nss "$@" -i ${R_SERVERPID} -V ${SERVER_VMIN}:${SERVER_VMAX} $verbose -H 1 &
|
||||
RET=$?
|
||||
fi
|
||||
|
||||
@@ -324,21 +329,30 @@ ssl_cov()
|
||||
VMAX="tls1.1"
|
||||
# can't use a pipe here, because we may have to restart selfserv, and
|
||||
# doing so hides the server pid environment variable in the subshell in
|
||||
# cygwin, which means we can't kill selfserv at the end here.
|
||||
SSL_COV_TMP=$(mktemp /tmp/ssl_cov.XXXXXX)
|
||||
ignore_blank_lines ${SSLCOV} > ${SSL_COV_TMP}
|
||||
while read ectype testmax param sig testname
|
||||
do
|
||||
- # RSA-PSS tests are handled in a separate function
|
||||
+ # Select the TLS SIG SCHEME if necessary
|
||||
+ TLS_SIG_SCHEMES=""
|
||||
if [ "$sig" = "RSA-PSS" ]; then
|
||||
+ # RSA-PSS tests are currently handled in a separate function
|
||||
continue
|
||||
+ elif [ "$sig" = "ML-DSA-44" ]; then
|
||||
+ TLS_SIG_SCHEMES="-J mldsa44 "
|
||||
+ elif [ "$sig" = "ML-DSA-65" ]; then
|
||||
+ TLS_SIG_SCHEMES="-J mldsa65 "
|
||||
+ elif [ "$sig" = "ML-DSA-87" ]; then
|
||||
+ TLS_SIG_SCHEMES="-J mldsa87 "
|
||||
fi
|
||||
|
||||
+
|
||||
# skip DSA tests if they are disabled
|
||||
if [ -n "$NSS_DISABLE_DSA" -a "$sig" = "DSA" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "$SCRIPTNAME: running $testname ----------------------------"
|
||||
VMAX="ssl3"
|
||||
if [ "$testmax" = "TLS10" ]; then
|
||||
@@ -380,21 +394,21 @@ ssl_cov()
|
||||
elif [ "$ectype" = "MLKEM219" ]; then
|
||||
TLS_GROUPS="x25519mlkem768"
|
||||
elif [ "$ectype" = "MLKEM256" ]; then
|
||||
TLS_GROUPS="secp256r1mlkem768"
|
||||
elif [ "$ectype" = "MLKEM384" ]; then
|
||||
TLS_GROUPS="secp384r1mlkem1024"
|
||||
fi
|
||||
|
||||
- echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -I \"${TLS_GROUPS}\" -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\"
|
||||
+ echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -I \"${TLS_GROUPS}\" ${TLS_SIG_SCHEMES}-V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\"
|
||||
echo " -f -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE}"
|
||||
|
||||
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
|
||||
- ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -I "${TLS_GROUPS}" -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \
|
||||
+ ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -I "${TLS_GROUPS}" ${TLS_SIG_SCHEMES}-V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \
|
||||
-d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE} \
|
||||
>${TMP}/$HOST.tmp.$$ 2>&1
|
||||
ret=$?
|
||||
cat ${TMP}/$HOST.tmp.$$
|
||||
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
|
||||
html_msg $ret 0 "${testname}" \
|
||||
"produced a returncode of $ret, expected is 0"
|
||||
done < ${SSL_COV_TMP}
|
||||
diff --git a/tests/ssl/sslauth.txt b/tests/ssl/sslauth.txt
|
||||
--- a/tests/ssl/sslauth.txt
|
||||
+++ b/tests/ssl/sslauth.txt
|
||||
@@ -77,8 +77,26 @@
|
||||
SNI 1 -r_-a_Host-sni.Dom -V_ssl3:tls1.2_-c_v_-w_nss_-n_TestUser_-a_Host-sni1.Dom TLS Server response with alert
|
||||
SNI 0 -r_-a_Host-sni.Dom -V_ssl3:ssl3_-w_nss_-n_TestUser SSL3 Server hello response without SNI
|
||||
SNI 1 -r_-a_Host-sni.Dom -V_ssl3:ssl3_-c_v_-w_nss_-n_TestUser_-a_Host-sni.Dom SSL3 Server hello response with SNI: SSL don't have SH extensions
|
||||
SNI 0 -r_-r_-r_-a_Host-sni.Dom -V_ssl3:tls1.2_-w_nss_-n_TestUser TLS Server hello response without SNI
|
||||
SNI 0 -r_-r_-r_-a_Host-sni.Dom -V_ssl3:tls1.2_-c_v_-w_nss_-n_TestUser_-a_Host-sni.Dom TLS Server hello response with SNI
|
||||
SNI 1 -r_-r_-r_-a_Host-sni.Dom -V_ssl3:tls1.2_-w_nss_-n_TestUser_-a_Host-sni.Dom_-a_Host.Dom TLS Server hello response with SNI: Change name on 2d HS
|
||||
SNI 1 -r_-r_-r_-a_Host-sni.Dom -V_ssl3:tls1.2_-c_v_-w_nss_-n_TestUser_-a_Host-sni.Dom_-a_Host-sni1.Dom TLS Server hello response with SNI: Change name to invalid 2d HS
|
||||
SNI 1 -r_-r_-r_-a_Host-sni.Dom -V_ssl3:tls1.2_-c_v_-w_nss_-n_TestUser_-a_Host-sni1.Dom TLS Server response with alert
|
||||
+#
|
||||
+# ML-DSA Tests
|
||||
+#
|
||||
+MLDSA 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-44_-w_nss TLS 1.3 ML-DSA-44 Request don't require client auth on post hs (client auth)
|
||||
+MLDSA 0 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-44_-w_nss TLS 1.3 ML-DSA-44 Require client auth on post hs (client auth)
|
||||
+MLDSA 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 ML-DSA-44 Request don't require client auth on post hs (client does not provide auth)
|
||||
+MLDSA 1 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 ML-DSA-44 Require client auth on post hs (client does not provide auth)
|
||||
+MLDSA 0 -r_-r_-r_-E_-u -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-44_-w_nss TLS 1.3 ML-DSA-44 Request don't require client auth on post hs with session ticket (client auth)
|
||||
+MLDSA 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-65_-w_nss TLS 1.3 ML-DSA-65 Request don't require client auth on post hs (client auth)
|
||||
+MLDSA 0 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-65_-w_nss TLS 1.3 ML-DSA-65 Require client auth on post hs (client auth)
|
||||
+MLDSA 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 ML-DSA-65 Request don't require client auth on post hs (client does not provide auth)
|
||||
+MLDSA 1 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 ML-DSA-65 Require client auth on post hs (client does not provide auth)
|
||||
+MLDSA 0 -r_-r_-r_-E_-u -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-65_-w_nss TLS 1.3 ML-DSA-65 Request don't require client auth on post hs with session ticket (client auth)
|
||||
+MLDSA 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-87_-w_nss TLS 1.3 ML-DSA-87 Request don't require client auth on post hs (client auth)
|
||||
+MLDSA 0 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-87_-w_nss TLS 1.3 ML-DSA-87 Require client auth on post hs (client auth)
|
||||
+MLDSA 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 ML-DSA-87 Request don't require client auth on post hs (client does not provide auth)
|
||||
+MLDSA 1 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 ML-DSA-87 Require client auth on post hs (client does not provide auth)
|
||||
+MLDSA 0 -r_-r_-r_-E_-u -V_tls1.3:tls1.3_-E_-n_TestUser-ml-dsa-87_-w_nss TLS 1.3 ML-DSA-87 Request don't require client auth on post hs with session ticket (client auth)
|
||||
diff --git a/tests/ssl/sslcov.txt b/tests/ssl/sslcov.txt
|
||||
--- a/tests/ssl/sslcov.txt
|
||||
+++ b/tests/ssl/sslcov.txt
|
||||
@@ -157,12 +157,18 @@ MLKEM219 TLS13 :1301 ECC TLS13_X25519ML
|
||||
MLKEM219 TLS13 :1302 ECC TLS13_X25519MLKEM768_WITH_AES_256_GCM_SHA384
|
||||
MLKEM219 TLS13 :1303 ECC TLS13_X25519MLKEM768_WITH_CHACHA20_POLY1305_SHA256
|
||||
MLKEM256 TLS13 :1301 ECC TLS13_SECP256R1MLKEM768_WITH_AES_128_GCM_SHA256
|
||||
MLKEM256 TLS13 :1302 ECC TLS13_SECP256R1MLKEM768_WITH_AES_256_GCM_SHA384
|
||||
MLKEM256 TLS13 :1303 ECC TLS13_SECP256R1MLKEM768_WITH_CHACHA20_POLY1305_SHA256
|
||||
MLKEM384 TLS13 :1301 ECC TLS13_SECP384R1MLKEM1024_WITH_AES_128_GCM_SHA256
|
||||
MLKEM384 TLS13 :1302 ECC TLS13_SECP384R1MLKEM1024_WITH_AES_256_GCM_SHA384
|
||||
MLKEM384 TLS13 :1303 ECC TLS13_SECP384R1MLKEM1024_WITH_CHACHA20_POLY1305_SHA256
|
||||
+ ECC TLS13 :1301 ML_DSA_44 TLS13_ECDHE_WITH_AES_128_GCM_SHA256 (ML_DSA_44)
|
||||
+ ECC TLS13 :1302 ML_DSA_65 TLS13_ECDHE_WITH_AES_256_GCM_SHA384 (ML_DSA_65)
|
||||
+ ECC TLS13 :1303 ML_DSA_87 TLS13_ECDHE_WITH_CHACHA20_POLY1305_SHA256 (ML_DSA_87)
|
||||
+MLKEM219 TLS13 :1301 ML_DSA_65 TLS13_MLKEM768X25519_WITH_AES_128_GCM_SHA256 (ML_DSA_65)
|
||||
+MLKEM219 TLS13 :1302 ML_DSA_87 TLS13_MLKEM768X25519_WITH_AES_256_GCM_SHA384 (ML_DSA_87)
|
||||
+MLKEM219 TLS13 :1303 ML_DSA_44 TLS13_MLKEM768X25519_WITH_CHACHA20_POLY1305_SHA256 (ML_DSA_44)
|
||||
# need to turn on policy in selfserv/tstclnt to make these work
|
||||
#XYBER TLS13 :1301 ECC TLS13_XYBER768D00_WITH_AES_128_GCM_SHA256
|
||||
#XYBER TLS13 :1302 ECC TLS13_XYBER768D00_WITH_AES_256_GCM_SHA384
|
||||
#XYBER TLS13 :1303 ECC TLS13_XYBER768D00_WITH_CHACHA20_POLY1305_SHA256
|
||||
diff --git a/tests/ssl_gtests/ssl_gtest_db.sh b/tests/ssl_gtests/ssl_gtest_db.sh
|
||||
--- a/tests/ssl_gtests/ssl_gtest_db.sh
|
||||
+++ b/tests/ssl_gtests/ssl_gtest_db.sh
|
||||
@@ -54,21 +54,33 @@ make_cert rsa_sign rsa sign
|
||||
make_cert rsa_pss rsapss sign
|
||||
make_cert rsa_pss384 rsapss384 sign
|
||||
make_cert rsa_pss512 rsapss512 sign
|
||||
make_cert rsa_pss_noparam rsapss_noparam sign
|
||||
make_cert rsa_decrypt rsa kex
|
||||
make_cert ecdsa256 p256 sign
|
||||
make_cert ecdsa384 p384 sign
|
||||
make_cert ecdsa521 p521 sign
|
||||
+make_cert mldsa44 mldsa44 sign
|
||||
+make_cert mldsa65 mldsa65 sign
|
||||
+make_cert mldsa87 mldsa87 sign
|
||||
make_cert ecdh_ecdsa p256 kex
|
||||
make_cert rsa_ca rsa_ca ca
|
||||
make_cert rsa_chain rsa_chain sign
|
||||
make_cert rsa_pss_ca rsapss_ca ca
|
||||
make_cert rsa_pss_chain rsapss_chain sign
|
||||
make_cert rsa_ca_rsa_pss_chain rsa_ca_rsapss_chain sign
|
||||
+make_cert mldsa44_ca mldsa44_ca ca
|
||||
+make_cert mldsa44_chain mldsa44_chain sign
|
||||
+make_cert mldsa65_ca mldsa65_ca ca
|
||||
+make_cert mldsa65_chain mldsa65_chain sign
|
||||
+make_cert mldsa87_ca mldsa87_ca ca
|
||||
+make_cert mldsa87_chain mldsa87_chain sign
|
||||
make_cert ecdh_rsa ecdh_rsa kex
|
||||
if [ -z "${NSS_DISABLE_DSA}" ]; then
|
||||
make_cert dsa dsa sign
|
||||
fi
|
||||
make_cert delegator_ecdsa256 delegator_p256 sign
|
||||
make_cert delegator_rsae2048 delegator_rsae2048 sign
|
||||
make_cert delegator_rsa_pss2048 delegator_rsa_pss2048 sign
|
||||
+make_cert delegator_mldsa44 delegator_mldsa44 sign
|
||||
+make_cert delegator_mldsa65 delegator_mldsa65 sign
|
||||
+make_cert delegator_mldsa87 delegator_mldsa87 sign
|
||||
65
nss-3.124-ppc_no_init.patch
Normal file
65
nss-3.124-ppc_no_init.patch
Normal file
@ -0,0 +1,65 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1780431689 25200
|
||||
# Tue Jun 02 13:21:29 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID c3324d6ea02d9496ced68a4c59f81af9525d89ea
|
||||
# Parent ba35abba131fe9379c69e63c9206d6a2143a3762
|
||||
nss-3.90-ppc_no_init.patch
|
||||
|
||||
diff --git a/lib/freebl/Makefile b/lib/freebl/Makefile
|
||||
--- a/lib/freebl/Makefile
|
||||
+++ b/lib/freebl/Makefile
|
||||
@@ -288,17 +288,17 @@ ifeq ($(CPU_ARCH),arm)
|
||||
DEFINES += -DMP_USE_UINT_DIGIT
|
||||
DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
|
||||
MPI_SRCS += mpi_arm.c
|
||||
endif
|
||||
ifeq ($(CPU_ARCH),ppc)
|
||||
DEFINES += -DHAVE_PLATFORM_GHASH
|
||||
EXTRA_SRCS += ghash-ppc.c
|
||||
ifdef USE_64
|
||||
- DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
+# DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
PPC_ABI := $(shell $(CC) -dM -E - < /dev/null | awk '$$2 == "_CALL_ELF" {print $$3}')
|
||||
ifeq ($(PPC_ABI),2)
|
||||
ASFILES += sha512-p8.s
|
||||
ifeq ($(OS_TEST),ppc64le)
|
||||
EXTRA_SRCS += chacha20poly1305-ppc.c ppc-gcm-wrap.c
|
||||
ASFILES += chacha20-ppc64le.s ppc-gcm.s
|
||||
DEFINES += -DHAVE_PLATFORM_GCM
|
||||
endif # ppc64le
|
||||
diff --git a/lib/softoken/Makefile b/lib/softoken/Makefile
|
||||
--- a/lib/softoken/Makefile
|
||||
+++ b/lib/softoken/Makefile
|
||||
@@ -18,23 +18,23 @@ include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
ifdef NSS_NO_INIT_SUPPORT
|
||||
DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
endif
|
||||
-ifeq ($(OS_TARGET),Linux)
|
||||
-ifeq ($(CPU_ARCH),ppc)
|
||||
-ifdef USE_64
|
||||
- DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
-endif # USE_64
|
||||
-endif # ppc
|
||||
-endif # Linux
|
||||
+#ifeq ($(OS_TARGET),Linux)
|
||||
+#ifeq ($(CPU_ARCH),ppc)
|
||||
+#ifdef USE_64
|
||||
+# DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
+#endif # USE_64
|
||||
+#endif # ppc
|
||||
+#endif # Linux
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
include config.mk
|
||||
|
||||
92
nss-3.124-prefer-all-hybrid.patch
Normal file
92
nss-3.124-prefer-all-hybrid.patch
Normal file
@ -0,0 +1,92 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1780514963 25200
|
||||
# Wed Jun 03 12:29:23 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID 6e7722343bbb64c097f476afff27db4bc0b103c2
|
||||
# Parent c821cfd68f40883d94215accb63869deeeb1d4e6
|
||||
nss-3.124-prefer-all-hybrid.patch
|
||||
|
||||
diff --git a/gtests/ssl_gtest/ssl_dhe_unittest.cc b/gtests/ssl_gtest/ssl_dhe_unittest.cc
|
||||
--- a/gtests/ssl_gtest/ssl_dhe_unittest.cc
|
||||
+++ b/gtests/ssl_gtest/ssl_dhe_unittest.cc
|
||||
@@ -36,17 +36,17 @@ TEST_P(TlsConnectTls13, SharesForBothEcd
|
||||
auto shares_capture =
|
||||
std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn);
|
||||
std::vector<std::shared_ptr<PacketFilter>> captures = {groups_capture,
|
||||
shares_capture};
|
||||
client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures));
|
||||
|
||||
Connect();
|
||||
|
||||
- CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
|
||||
+ CheckKeys(GetDefaultKEA(), ssl_auth_rsa_sign);
|
||||
|
||||
bool ec, dh;
|
||||
auto track_group_type = [&ec, &dh](SSLNamedGroup group) {
|
||||
if ((group & 0xff00U) == 0x100U) {
|
||||
dh = true;
|
||||
} else {
|
||||
ec = true;
|
||||
}
|
||||
diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
|
||||
--- a/lib/ssl/sslsock.c
|
||||
+++ b/lib/ssl/sslsock.c
|
||||
@@ -163,22 +163,22 @@ static const PRUint16 srtpCiphers[] = {
|
||||
ssl_grp_kem_##first##second, size, ssl_kea_ecdh_hybrid, \
|
||||
SEC_OID_##first_oid##second_oid, assumeSupported \
|
||||
}
|
||||
|
||||
const sslNamedGroupDef ssl_named_groups[] = {
|
||||
/* Note that 256 for 25519 and x25519mlkem786 is a lie, but we only use it
|
||||
* for checking bit security and expect 256 bits there (not 255). */
|
||||
HYGROUP(mlkem768, x25519, 256, MLKEM768, X25519, PR_TRUE),
|
||||
+ HYGROUP(secp256r1, mlkem768, 256, SECP256R1, MLKEM768, PR_TRUE),
|
||||
+ HYGROUP(secp384r1, mlkem1024, 256, SECP384R1, MLKEM1024, PR_TRUE),
|
||||
{ ssl_grp_ec_curve25519, 256, ssl_kea_ecdh, SEC_OID_CURVE25519, PR_TRUE },
|
||||
ECGROUP(secp256r1, 256, SECP256R1, PR_TRUE),
|
||||
ECGROUP(secp384r1, 384, SECP384R1, PR_TRUE),
|
||||
ECGROUP(secp521r1, 521, SECP521R1, PR_TRUE),
|
||||
- HYGROUP(secp256r1, mlkem768, 256, SECP256R1, MLKEM768, PR_TRUE),
|
||||
- HYGROUP(secp384r1, mlkem1024, 256, SECP384R1, MLKEM1024, PR_TRUE),
|
||||
{ ssl_grp_kem_xyber768d00, 256, ssl_kea_ecdh_hybrid, SEC_OID_XYBER768D00, PR_FALSE },
|
||||
FFGROUP(2048),
|
||||
FFGROUP(3072),
|
||||
FFGROUP(4096),
|
||||
FFGROUP(6144),
|
||||
FFGROUP(8192),
|
||||
ECGROUP(secp192r1, 192, SECP192R1, PR_FALSE),
|
||||
ECGROUP(secp160r2, 160, SECP160R2, PR_FALSE),
|
||||
diff --git a/lib/ssl/tls13con.c b/lib/ssl/tls13con.c
|
||||
--- a/lib/ssl/tls13con.c
|
||||
+++ b/lib/ssl/tls13con.c
|
||||
@@ -666,20 +666,29 @@ tls13_SetupClientHello(sslSocket *ss, ss
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Select the first enabled group.
|
||||
* TODO(ekr@rtfm.com): be smarter about offering the group
|
||||
* that the other side negotiated if we are resuming. */
|
||||
PORT_Assert(PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs));
|
||||
+ PRBool has_hybrid = PR_FALSE;
|
||||
for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
|
||||
if (!ss->namedGroupPreferences[i]) {
|
||||
continue;
|
||||
}
|
||||
+ /* only send one hybrid key share no matter how many key
|
||||
+ * shares we send */
|
||||
+ if (ss->namedGroupPreferences[i]->keaType == ssl_kea_ecdh_hybrid) {
|
||||
+ if (has_hybrid) {
|
||||
+ continue; /* already have one skip*/
|
||||
+ }
|
||||
+ has_hybrid = PR_TRUE;
|
||||
+ }
|
||||
rv = tls13_AddKeyShare(ss, ss->namedGroupPreferences[i]);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
if (++numShares > ss->additionalShares) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
36
nss-3.124-revert-hmac-pkcs12-fips-default.patch
Normal file
36
nss-3.124-revert-hmac-pkcs12-fips-default.patch
Normal file
@ -0,0 +1,36 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1781629595 25200
|
||||
# Tue Jun 16 10:06:35 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID b38b82d220e288befed5176cd2ebb04df5fc3317
|
||||
# Parent 07371c5f55e422e28311ef00131462bcf2058882
|
||||
nss-3.124-revert-hmac-pkcs12-fips-default.patch
|
||||
|
||||
diff --git a/cmd/pk12util/pk12util.c b/cmd/pk12util/pk12util.c
|
||||
--- a/cmd/pk12util/pk12util.c
|
||||
+++ b/cmd/pk12util/pk12util.c
|
||||
@@ -1159,20 +1159,23 @@ main(int argc, char **argv)
|
||||
if (certCipher == SEC_OID_UNKNOWN) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
SECU_PrintError(progName, "Algorithm: \"%s\"", cipherString);
|
||||
pk12uErrno = PK12UERR_INVALIDALGORITHM;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
+#ifdef nodef
|
||||
+ /* default to old encodings on rhel-8 and rhel-9 */
|
||||
/* in FIPS mode default to encoding with pkcs5v2 for the MAC */
|
||||
if (PK11_IsFIPS()) {
|
||||
hash = SEC_OID_HMAC_SHA256;
|
||||
}
|
||||
+#endif
|
||||
if (pk12util.options[opt_Mac].activated) {
|
||||
char *hashString = pk12util.options[opt_Mac].arg;
|
||||
|
||||
hash = PKCS12U_MapHashFromString(hashString);
|
||||
/* We don't support creating Mac-less pkcs 12 files */
|
||||
if (hash == SEC_OID_UNKNOWN) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
SECU_PrintError(progName, "Algorithm: \"%s\"", hashString);
|
||||
31
nss-3.124-tools-test-fix.patch
Normal file
31
nss-3.124-tools-test-fix.patch
Normal file
@ -0,0 +1,31 @@
|
||||
# HG changeset patch
|
||||
# User Robert Relyea <rrelyea@redhat.com>
|
||||
# Date 1780589779 25200
|
||||
# Thu Jun 04 09:16:19 2026 -0700
|
||||
# Branch NSS_3_124_BRANCH
|
||||
# Node ID 5f6c91f6171020eea4ce9eb5bc353370d30c8df0
|
||||
# Parent 709702f4bfbee0bed65f6abcd85bc8fc2d14ff55
|
||||
nss-3.124-tools-test-fix.patch
|
||||
|
||||
diff --git a/tests/tools/tools.sh b/tests/tools/tools.sh
|
||||
--- a/tests/tools/tools.sh
|
||||
+++ b/tests/tools/tools.sh
|
||||
@@ -518,17 +518,17 @@ tools_p12_import_old_files()
|
||||
${BINDIR}/pk12util -i ${TOOLSDIR}/data/PKCS5WithImplicitKDF.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W password 2>&1
|
||||
ret=$?
|
||||
html_msg $ret 0 "Importing PKCS#12 file with and implicit KDF value"
|
||||
check_tmpfile
|
||||
|
||||
echo "pk12util -I -l corrupted_cert_bag.p12 -W start"
|
||||
${BINDIR}/pk12util -I -l ${TOOLSDIR}/data/corrupted_cert_bag.p12 -W start 2>&1
|
||||
ret=$?
|
||||
- html_msg $ret 17 "Listing a PKCS#12 file with corrupted certificate bag"
|
||||
+ html_msg $ret 19 "Listing a PKCS#12 file with corrupted certificate bag"
|
||||
check_tmpfile
|
||||
|
||||
}
|
||||
|
||||
tools_p12_import_rsa_pss_private_key()
|
||||
{
|
||||
echo "$SCRIPTNAME: Importing RSA-PSS private key from PKCS#12 file --------------"
|
||||
${BINDIR}/pk12util -i ${TOOLSDIR}/data/TestRSAPSS.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '' 2>&1
|
||||
885
nss-3.124-turn_off_non_dbm_tests.patch
Normal file
885
nss-3.124-turn_off_non_dbm_tests.patch
Normal file
@ -0,0 +1,885 @@
|
||||
diff --git a/cmd/pk11importtest/pk11importtest.c b/cmd/pk11importtest/pk11importtest.c
|
||||
--- a/cmd/pk11importtest/pk11importtest.c
|
||||
+++ b/cmd/pk11importtest/pk11importtest.c
|
||||
@@ -318,16 +318,22 @@ main(int argc, char **argv)
|
||||
doEC = PR_FALSE;
|
||||
}
|
||||
if (args.options[opt_NoMLDSA].activated) {
|
||||
doMLDSA = PR_FALSE;
|
||||
}
|
||||
if (args.options[opt_NoMLKEM].activated) {
|
||||
doMLKEM = PR_FALSE;
|
||||
}
|
||||
+ if (args.options[opt_NoED].activated) {
|
||||
+ doED = PR_FALSE;
|
||||
+ }
|
||||
+ if (args.options[opt_NoECMont].activated) {
|
||||
+ doECMont = PR_FALSE;
|
||||
+ }
|
||||
|
||||
slot = PK11_GetInternalKeySlot();
|
||||
if (slot == NULL) {
|
||||
SECU_PrintError(progName, "Couldn't find the internal key slot\n");
|
||||
return 255;
|
||||
}
|
||||
rv = PK11_Authenticate(slot, PR_TRUE, &pwArgs);
|
||||
if (rv != SECSuccess) {
|
||||
diff --git a/gtests/ssl_gtest/ssl_auth_unittest.cc b/gtests/ssl_gtest/ssl_auth_unittest.cc
|
||||
--- a/gtests/ssl_gtest/ssl_auth_unittest.cc
|
||||
+++ b/gtests/ssl_gtest/ssl_auth_unittest.cc
|
||||
@@ -2477,16 +2477,17 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
SignatureSchemeEcdsaSha1, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
||||
TlsConnectTestBase::kTlsV12,
|
||||
::testing::Values(TlsAgent::kServerEcdsa256,
|
||||
TlsAgent::kServerEcdsa384),
|
||||
::testing::Values(ssl_auth_ecdsa),
|
||||
::testing::Values(ssl_sig_ecdsa_sha1)));
|
||||
// ML-DSA is only allowed to be used in TLS 1.3 or greater
|
||||
+#ifdef notdef
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SignatureSchemeMlDsa44Tls13, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
||||
TlsConnectTestBase::kTlsV13,
|
||||
::testing::Values(TlsAgent::kServerMlDsa44),
|
||||
::testing::Values(ssl_auth_mldsa44),
|
||||
::testing::Values(ssl_sig_mldsa44)));
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
@@ -2498,10 +2499,11 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
::testing::Values(ssl_sig_mldsa65)));
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
SignatureSchemeMlDsa87Tls13, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
||||
TlsConnectTestBase::kTlsV13,
|
||||
::testing::Values(TlsAgent::kServerMlDsa87),
|
||||
::testing::Values(ssl_auth_mldsa87),
|
||||
::testing::Values(ssl_sig_mldsa87)));
|
||||
+#endif
|
||||
|
||||
} // namespace nss_test
|
||||
diff --git a/gtests/ssl_gtest/tls_subcerts_unittest.cc b/gtests/ssl_gtest/tls_subcerts_unittest.cc
|
||||
--- a/gtests/ssl_gtest/tls_subcerts_unittest.cc
|
||||
+++ b/gtests/ssl_gtest/tls_subcerts_unittest.cc
|
||||
@@ -236,16 +236,17 @@ TEST_P(TlsConnectTls13, DCConnectEcdsaP2
|
||||
client_, ssl_delegated_credentials_xtn);
|
||||
Connect();
|
||||
|
||||
EXPECT_TRUE(cfilter->captured());
|
||||
CheckPeerDelegCred(client_, true, 256);
|
||||
EXPECT_EQ(ssl_sig_ecdsa_secp256r1_sha256, client_->info().signatureScheme);
|
||||
}
|
||||
|
||||
+#ifdef notdef
|
||||
// Connected with ML-DSA-65, using an ML-DSA-65 SKI and ML-DSA-65 delegation
|
||||
// cert.
|
||||
TEST_P(TlsConnectTls13, DCConnectMlDsa65MlDsa65) {
|
||||
Reset(kMlDsa65DelegatorId);
|
||||
|
||||
static const SSLSignatureScheme kSchemes[] = {ssl_sig_ecdsa_secp256r1_sha256,
|
||||
ssl_sig_mldsa65};
|
||||
client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
|
||||
@@ -281,16 +282,17 @@ TEST_P(TlsConnectTls13, DCConnectEcdsaP2
|
||||
auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
|
||||
client_, ssl_delegated_credentials_xtn);
|
||||
Connect();
|
||||
|
||||
EXPECT_TRUE(cfilter->captured());
|
||||
CheckPeerDelegCred(client_, true, 256);
|
||||
EXPECT_EQ(ssl_sig_ecdsa_secp256r1_sha256, client_->info().signatureScheme);
|
||||
}
|
||||
+#endif
|
||||
|
||||
// Simulate the client receiving a DC containing algorithms not advertised.
|
||||
// Do this by tweaking the client's supported sigSchemes after the CH.
|
||||
TEST_P(TlsConnectTls13, DCReceiveUnadvertisedScheme) {
|
||||
Reset(kEcdsaDelegatorId);
|
||||
static const SSLSignatureScheme kClientSchemes[] = {
|
||||
ssl_sig_ecdsa_secp256r1_sha256, ssl_sig_ecdsa_secp384r1_sha384};
|
||||
static const SSLSignatureScheme kServerSchemes[] = {
|
||||
@@ -725,16 +727,17 @@ TEST_P(TlsConnectTls13, DCRejectModified
|
||||
now());
|
||||
ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
|
||||
server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
|
||||
client_->CheckErrorCode(SSL_ERROR_DC_CERT_VERIFY_ALG_MISMATCH);
|
||||
}
|
||||
|
||||
class DCDelegation : public ::testing::Test {};
|
||||
|
||||
+#ifdef notdef
|
||||
TEST_F(DCDelegation, DCDelegations) {
|
||||
PRTime now = PR_Now();
|
||||
ScopedCERTCertificate cert;
|
||||
ScopedSECKEYPrivateKey priv;
|
||||
ASSERT_TRUE(TlsAgent::LoadCertificate(kEcdsaDelegatorId, &cert, &priv));
|
||||
|
||||
ScopedSECKEYPublicKey pub_rsa;
|
||||
ScopedSECKEYPrivateKey priv_rsa;
|
||||
@@ -795,10 +798,11 @@ TEST_F(DCDelegation, DCDelegations) {
|
||||
SSL_DelegateCredential(cert.get(), priv.get(), pub_mldsa.get(),
|
||||
ssl_sig_mldsa44, kDCValidFor, now, &dc));
|
||||
EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_DelegateCredential(cert.get(), priv.get(), pub_mldsa.get(),
|
||||
ssl_sig_mldsa65, kDCValidFor, now, &dc));
|
||||
dc.Reset();
|
||||
}
|
||||
+#endif
|
||||
|
||||
} // namespace nss_test
|
||||
diff --git a/lib/softoken/legacydb/lgattr.c b/lib/softoken/legacydb/lgattr.c
|
||||
--- a/lib/softoken/legacydb/lgattr.c
|
||||
+++ b/lib/softoken/legacydb/lgattr.c
|
||||
@@ -646,28 +646,103 @@ lg_FindPublicKeyAttribute(LGObjectCache
|
||||
return lg_FindECPublicKeyAttribute(key, type, attribute);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return lg_invalidAttribute(attribute);
|
||||
}
|
||||
|
||||
+CK_KEY_TYPE
|
||||
+lg_FetchSecretKeyType(NSSLOWKEYPrivateKey *key)
|
||||
+{
|
||||
+ unsigned char *keyString;
|
||||
+ int keyTypeLen;
|
||||
+ CK_KEY_TYPE keyType;
|
||||
+ PRUint32 keyTypeStorage;
|
||||
+
|
||||
+ /* handle legacy databases. In legacy databases key_type was stored
|
||||
+ * in host order, with any leading zeros stripped off. Only key types
|
||||
+ * under 0x1f (AES) were stored. We assume that any values which are
|
||||
+ * either 1 byte long (big endian), or have byte[0] between 0 and
|
||||
+ * 0x7f and bytes[1]-bytes[3] equal to '0' (little endian). All other
|
||||
+ * values are assumed to be from the new database, which is always 4
|
||||
+ * bytes in network order */
|
||||
+ keyType = 0;
|
||||
+ keyString = key->u.rsa.coefficient.data;
|
||||
+ keyTypeLen = key->u.rsa.coefficient.len;
|
||||
+
|
||||
+ /*
|
||||
+ * Because of various endian and word lengths The database may have
|
||||
+ * stored the keyType value in one of the following formats:
|
||||
+ * (kt) <= 0x1f
|
||||
+ * length data
|
||||
+ * Big Endian, pre-3.9, all lengths: 1 (kt)
|
||||
+ * Little Endian, pre-3.9, 32 bits: 4 (kt) 0 0 0
|
||||
+ * Little Endian, pre-3.9, 64 bits: 8 (kt) 0 0 0 0 0 0 0
|
||||
+ * All platforms, 3.9, 32 bits: 4 0 0 0 (kt)
|
||||
+ * Big Endian, 3.9, 64 bits: 8 0 0 0 (kt) 0 0 0 0
|
||||
+ * Little Endian, 3.9, 64 bits: 8 0 0 0 0 0 0 0 (kt)
|
||||
+ * All platforms, >= 3.9.1, all lengths: 4 (a) k1 k2 k3
|
||||
+ * where (a) is 0 or >= 0x80. currently (a) can only be 0.
|
||||
+ */
|
||||
+ /*
|
||||
+ * this key was written on a 64 bit platform with a using NSS 3.9
|
||||
+ * or earlier. Reduce the 64 bit possibilities above. When we are
|
||||
+ * through, we will only have:
|
||||
+ *
|
||||
+ * Big Endian, pre-3.9, all lengths: 1 (kt)
|
||||
+ * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0
|
||||
+ * All platforms, 3.9, all lengths: 4 0 0 0 (kt)
|
||||
+ * All platforms, => 3.9.1, all lengths: 4 (a) k1 k2 k3
|
||||
+ */
|
||||
+ if (keyTypeLen == 8) {
|
||||
+ keyTypeStorage = *(PRUint32 *)keyString;
|
||||
+ if (keyTypeStorage == 0) {
|
||||
+ keyString += sizeof(PRUint32);
|
||||
+ }
|
||||
+ keyTypeLen = 4;
|
||||
+ }
|
||||
+ /*
|
||||
+ * Now Handle:
|
||||
+ *
|
||||
+ * All platforms, 3.9, all lengths: 4 0 0 0 (kt)
|
||||
+ * All platforms, => 3.9.1, all lengths: 4 (a) k1 k2 k3
|
||||
+ *
|
||||
+ * NOTE: if kt == 0 or ak1k2k3 == 0, the test fails and
|
||||
+ * we handle it as:
|
||||
+ *
|
||||
+ * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0
|
||||
+ */
|
||||
+ if (keyTypeLen == sizeof(keyTypeStorage) &&
|
||||
+ (((keyString[0] & 0x80) == 0x80) ||
|
||||
+ !((keyString[1] == 0) && (keyString[2] == 0) && (keyString[3] == 0)))) {
|
||||
+ PORT_Memcpy(&keyTypeStorage, keyString, sizeof(keyTypeStorage));
|
||||
+ keyType = (CK_KEY_TYPE)PR_ntohl(keyTypeStorage);
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Now Handle:
|
||||
+ *
|
||||
+ * Big Endian, pre-3.9, all lengths: 1 (kt)
|
||||
+ * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0
|
||||
+ * -- KeyType == 0 all other cases ---: 4 0 0 0 0
|
||||
+ */
|
||||
+ keyType = (CK_KEY_TYPE)keyString[0];
|
||||
+ }
|
||||
+ return keyType;
|
||||
+}
|
||||
static CK_RV
|
||||
lg_FindSecretKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
|
||||
CK_ATTRIBUTE *attribute)
|
||||
{
|
||||
NSSLOWKEYPrivateKey *key;
|
||||
char *label;
|
||||
- unsigned char *keyString;
|
||||
CK_RV crv;
|
||||
- int keyTypeLen;
|
||||
+ CK_KEY_TYPE keyType;
|
||||
CK_ULONG keyLen;
|
||||
- CK_KEY_TYPE keyType;
|
||||
- PRUint32 keyTypeStorage;
|
||||
|
||||
switch (type) {
|
||||
case CKA_PRIVATE:
|
||||
case CKA_SENSITIVE:
|
||||
case CKA_ALWAYS_SENSITIVE:
|
||||
case CKA_EXTRACTABLE:
|
||||
case CKA_DERIVE:
|
||||
case CKA_ENCRYPT:
|
||||
@@ -704,84 +779,17 @@ lg_FindSecretKeyAttribute(LGObjectCache
|
||||
}
|
||||
|
||||
key = lg_GetPrivateKey(obj);
|
||||
if (key == NULL) {
|
||||
return CKR_OBJECT_HANDLE_INVALID;
|
||||
}
|
||||
switch (type) {
|
||||
case CKA_KEY_TYPE:
|
||||
- /* handle legacy databases. In legacy databases key_type was stored
|
||||
- * in host order, with any leading zeros stripped off. Only key types
|
||||
- * under 0x1f (AES) were stored. We assume that any values which are
|
||||
- * either 1 byte long (big endian), or have byte[0] between 0 and
|
||||
- * 0x7f and bytes[1]-bytes[3] equal to '0' (little endian). All other
|
||||
- * values are assumed to be from the new database, which is always 4
|
||||
- * bytes in network order */
|
||||
- keyType = 0;
|
||||
- keyString = key->u.rsa.coefficient.data;
|
||||
- keyTypeLen = key->u.rsa.coefficient.len;
|
||||
-
|
||||
- /*
|
||||
- * Because of various endian and word lengths The database may have
|
||||
- * stored the keyType value in one of the following formats:
|
||||
- * (kt) <= 0x1f
|
||||
- * length data
|
||||
- * Big Endian, pre-3.9, all lengths: 1 (kt)
|
||||
- * Little Endian, pre-3.9, 32 bits: 4 (kt) 0 0 0
|
||||
- * Little Endian, pre-3.9, 64 bits: 8 (kt) 0 0 0 0 0 0 0
|
||||
- * All platforms, 3.9, 32 bits: 4 0 0 0 (kt)
|
||||
- * Big Endian, 3.9, 64 bits: 8 0 0 0 (kt) 0 0 0 0
|
||||
- * Little Endian, 3.9, 64 bits: 8 0 0 0 0 0 0 0 (kt)
|
||||
- * All platforms, >= 3.9.1, all lengths: 4 (a) k1 k2 k3
|
||||
- * where (a) is 0 or >= 0x80. currently (a) can only be 0.
|
||||
- */
|
||||
- /*
|
||||
- * this key was written on a 64 bit platform with a using NSS 3.9
|
||||
- * or earlier. Reduce the 64 bit possibilities above. When we are
|
||||
- * through, we will only have:
|
||||
- *
|
||||
- * Big Endian, pre-3.9, all lengths: 1 (kt)
|
||||
- * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0
|
||||
- * All platforms, 3.9, all lengths: 4 0 0 0 (kt)
|
||||
- * All platforms, => 3.9.1, all lengths: 4 (a) k1 k2 k3
|
||||
- */
|
||||
- if (keyTypeLen == 8) {
|
||||
- keyTypeStorage = *(PRUint32 *)keyString;
|
||||
- if (keyTypeStorage == 0) {
|
||||
- keyString += sizeof(PRUint32);
|
||||
- }
|
||||
- keyTypeLen = 4;
|
||||
- }
|
||||
- /*
|
||||
- * Now Handle:
|
||||
- *
|
||||
- * All platforms, 3.9, all lengths: 4 0 0 0 (kt)
|
||||
- * All platforms, => 3.9.1, all lengths: 4 (a) k1 k2 k3
|
||||
- *
|
||||
- * NOTE: if kt == 0 or ak1k2k3 == 0, the test fails and
|
||||
- * we handle it as:
|
||||
- *
|
||||
- * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0
|
||||
- */
|
||||
- if (keyTypeLen == sizeof(keyTypeStorage) &&
|
||||
- (((keyString[0] & 0x80) == 0x80) ||
|
||||
- !((keyString[1] == 0) && (keyString[2] == 0) && (keyString[3] == 0)))) {
|
||||
- PORT_Memcpy(&keyTypeStorage, keyString, sizeof(keyTypeStorage));
|
||||
- keyType = (CK_KEY_TYPE)PR_ntohl(keyTypeStorage);
|
||||
- } else {
|
||||
- /*
|
||||
- * Now Handle:
|
||||
- *
|
||||
- * Big Endian, pre-3.9, all lengths: 1 (kt)
|
||||
- * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0
|
||||
- * -- KeyType == 0 all other cases ---: 4 0 0 0 0
|
||||
- */
|
||||
- keyType = (CK_KEY_TYPE)keyString[0];
|
||||
- }
|
||||
+ keyType = lg_FetchSecretKeyType(key);
|
||||
return lg_ULongAttribute(attribute, type, keyType);
|
||||
case CKA_VALUE:
|
||||
return lg_CopyPrivAttribute(attribute, type, key->u.rsa.privateExponent.data,
|
||||
key->u.rsa.privateExponent.len, obj->sdb);
|
||||
case CKA_VALUE_LEN:
|
||||
keyLen = key->u.rsa.privateExponent.len;
|
||||
return lg_ULongAttribute(attribute, type, keyLen);
|
||||
}
|
||||
@@ -1063,17 +1071,17 @@ lg_FindSMIMEAttribute(LGObjectCache *obj
|
||||
|
||||
static CK_RV
|
||||
lg_FindTrustAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
|
||||
CK_ATTRIBUTE *attribute)
|
||||
{
|
||||
NSSLOWCERTTrust *trust;
|
||||
NSSLOWCERTCertDBHandle *certHandle;
|
||||
NSSLOWCERTCertificate *cert;
|
||||
- unsigned char hash[SHA1_LENGTH];
|
||||
+ unsigned char hash[SHA256_LENGTH];
|
||||
unsigned int trustFlags;
|
||||
CK_RV crv = CKR_CANCEL;
|
||||
PRBool isPKCS;
|
||||
|
||||
switch (type) {
|
||||
case CKA_PRIVATE:
|
||||
return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
|
||||
case CKA_MODIFIABLE:
|
||||
@@ -1103,21 +1111,23 @@ lg_FindTrustAttribute(LGObjectCache *obj
|
||||
}
|
||||
trust = lg_getTrust(obj, certHandle);
|
||||
if (trust == NULL) {
|
||||
return CKR_OBJECT_HANDLE_INVALID;
|
||||
}
|
||||
isPKCS = PR_TRUE;
|
||||
switch (type) {
|
||||
case CKA_NAME_HASH_ALGORITHM:
|
||||
- return lg_ULongAttribute(attribute, type, CKM_SHA_1);
|
||||
+ return lg_ULongAttribute(attribute, type, CKM_SHA256);
|
||||
case CKA_NSS_CERT_SHA1_HASH:
|
||||
- case CKA_HASH_OF_CERTIFICATE:
|
||||
SHA1_HashBuf(hash, trust->derCert->data, trust->derCert->len);
|
||||
return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
|
||||
+ case CKA_HASH_OF_CERTIFICATE:
|
||||
+ SHA256_HashBuf(hash, trust->derCert->data, trust->derCert->len);
|
||||
+ return lg_CopyAttribute(attribute, type, hash, SHA256_LENGTH);
|
||||
case CKA_NSS_CERT_MD5_HASH:
|
||||
MD5_HashBuf(hash, trust->derCert->data, trust->derCert->len);
|
||||
return lg_CopyAttribute(attribute, type, hash, MD5_LENGTH);
|
||||
case CKA_NSS_TRUST_CLIENT_AUTH:
|
||||
isPKCS = PR_FALSE;
|
||||
case CKA_PKCS_TRUST_CLIENT_AUTH:
|
||||
trustFlags = trust->trust->sslFlags &
|
||||
CERTDB_TRUSTED_CLIENT_CA
|
||||
diff --git a/lib/softoken/legacydb/lgcreate.c b/lib/softoken/legacydb/lgcreate.c
|
||||
--- a/lib/softoken/legacydb/lgcreate.c
|
||||
+++ b/lib/softoken/legacydb/lgcreate.c
|
||||
@@ -905,16 +905,28 @@ lg_createSecretKeyObject(SDB *sdb, CK_KE
|
||||
if (pubKey.len == 0) {
|
||||
if (pubKey.data) {
|
||||
PORT_Free(pubKey.data);
|
||||
pubKey.data = NULL;
|
||||
}
|
||||
crv = lg_GenerateSecretCKA_ID(keyHandle, &pubKey, label);
|
||||
if (crv != CKR_OK)
|
||||
goto loser;
|
||||
+ } else if (nsslowkey_KeyForIDExists(keyHandle, &pubKey)) {
|
||||
+ /* if the item already exists, create a version with a different key type */
|
||||
+ SECItem *newPubKey = lg_makeSecretKeyId(&pubKey, key_type);
|
||||
+ PORT_Free(pubKey.data);
|
||||
+ pubKey.data = NULL;
|
||||
+ if (newPubKey == NULL) {
|
||||
+ goto loser;
|
||||
+ }
|
||||
+ /* swap in the new id length into pubkey */
|
||||
+ pubKey.data = newPubKey->data;
|
||||
+ pubKey.len = newPubKey->len;
|
||||
+ PORT_Free(newPubKey);
|
||||
}
|
||||
|
||||
privKey = lg_mkSecretKeyRep(templ, count, key_type, &pubKey, sdb);
|
||||
if (privKey == NULL) {
|
||||
crv = CKR_HOST_MEMORY;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
diff --git a/lib/softoken/legacydb/lgfind.c b/lib/softoken/legacydb/lgfind.c
|
||||
--- a/lib/softoken/legacydb/lgfind.c
|
||||
+++ b/lib/softoken/legacydb/lgfind.c
|
||||
@@ -252,50 +252,81 @@ lg_key_collect(DBT *key, DBT *data, void
|
||||
|
||||
loser:
|
||||
if (privKey) {
|
||||
lg_nsslowkey_DestroyPrivateKey(privKey);
|
||||
}
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
+SECItem *lg_makeSecretKeyId(SECItem *key_id, CK_KEY_TYPE keyType)
|
||||
+{
|
||||
+ SECItem *newItem=SECITEM_AllocItem(NULL, NULL, key_id->len+sizeof(PRUint32));
|
||||
+ if (newItem == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ PRUint32 nkeyType=PR_htonl(keyType);
|
||||
+ PORT_Memcpy(newItem->data, key_id->data, key_id->len);
|
||||
+ PORT_Memcpy(newItem->data+key_id->len, &nkeyType, sizeof(PRUint32));
|
||||
+ return newItem;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
lg_searchKeys(SDB *sdb, SECItem *key_id,
|
||||
- unsigned long classFlags, SDBFind *search, PRBool mustStrict,
|
||||
+ unsigned long classFlags, CK_KEY_TYPE keyType, SDBFind *search, PRBool mustStrict,
|
||||
const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
|
||||
{
|
||||
NSSLOWKEYDBHandle *keyHandle = NULL;
|
||||
NSSLOWKEYPrivateKey *privKey;
|
||||
lgKeyData keyData;
|
||||
PRBool found = PR_FALSE;
|
||||
|
||||
keyHandle = lg_getKeyDB(sdb);
|
||||
if (keyHandle == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (key_id->data) {
|
||||
privKey = nsslowkey_FindKeyByPublicKey(keyHandle, key_id, sdb);
|
||||
if (privKey) {
|
||||
- if ((classFlags & LG_KEY) && isSecretKey(privKey)) {
|
||||
+ if ((classFlags & LG_KEY) && isSecretKey(privKey) && (keyType == lg_FetchSecretKeyType(privKey))) {
|
||||
lg_addHandle(search,
|
||||
lg_mkHandle(sdb, key_id, LG_TOKEN_TYPE_KEY));
|
||||
found = PR_TRUE;
|
||||
}
|
||||
if ((classFlags & LG_PRIVATE) && !isSecretKey(privKey)) {
|
||||
lg_addHandle(search,
|
||||
lg_mkHandle(sdb, key_id, LG_TOKEN_TYPE_PRIV));
|
||||
found = PR_TRUE;
|
||||
}
|
||||
if ((classFlags & LG_PUBLIC) && !isSecretKey(privKey)) {
|
||||
lg_addHandle(search,
|
||||
lg_mkHandle(sdb, key_id, LG_TOKEN_TYPE_PUB));
|
||||
found = PR_TRUE;
|
||||
}
|
||||
lg_nsslowkey_DestroyPrivateKey(privKey);
|
||||
+ privKey = NULL;
|
||||
+ }
|
||||
+ if (!found && (classFlags & LG_KEY)) {
|
||||
+ /* sigh we allow more than one key of different key types to have the same id,
|
||||
+ * so we store those other ids under key_id/keytype */
|
||||
+ SECItem *new_key_id = lg_makeSecretKeyId(key_id, keyType);
|
||||
+ if (new_key_id) {
|
||||
+ privKey = nsslowkey_FindKeyByPublicKey(keyHandle, new_key_id, sdb);
|
||||
+ if (privKey) {
|
||||
+ if (isSecretKey(privKey) && (keyType == lg_FetchSecretKeyType(privKey))) {
|
||||
+ lg_addHandle(search,
|
||||
+ lg_mkHandle(sdb, new_key_id, LG_TOKEN_TYPE_KEY));
|
||||
+ found = PR_TRUE;
|
||||
+ }
|
||||
+ lg_nsslowkey_DestroyPrivateKey(privKey);
|
||||
+ privKey = NULL;
|
||||
+ }
|
||||
+ SECITEM_FreeItem(new_key_id, PR_TRUE);
|
||||
+ }
|
||||
}
|
||||
/* don't do the traversal if we have an up to date db */
|
||||
if (keyHandle->version != 3) {
|
||||
goto loser;
|
||||
}
|
||||
/* don't do the traversal if it can't possibly be the correct id */
|
||||
/* all soft token id's are SHA1_HASH_LEN's */
|
||||
if (key_id->len != SHA1_LENGTH) {
|
||||
@@ -642,16 +673,17 @@ lg_searchTokenList(SDB *sdb, SDBFind *se
|
||||
SECItem cert_md5_hash = { siBuffer, NULL, 0 };
|
||||
NSSLOWCERTIssuerAndSN issuerSN = {
|
||||
{ siBuffer, NULL, 0 },
|
||||
{ siBuffer, NULL, 0 }
|
||||
};
|
||||
SECItem *copy = NULL;
|
||||
CK_CERTIFICATE_TYPE certType;
|
||||
CK_OBJECT_CLASS objectClass;
|
||||
+ CK_KEY_TYPE keyType = CK_INVALID_HANDLE;
|
||||
CK_RV crv;
|
||||
unsigned long classFlags;
|
||||
|
||||
if (lg_getCertDB(sdb) == NULL) {
|
||||
classFlags = LG_PRIVATE | LG_KEY;
|
||||
} else {
|
||||
classFlags = LG_CERT | LG_TRUST | LG_NSS_TRUST | LG_PUBLIC | LG_SMIME | LG_CRL;
|
||||
}
|
||||
@@ -793,16 +825,21 @@ lg_searchTokenList(SDB *sdb, SDBFind *se
|
||||
break;
|
||||
}
|
||||
classFlags &= LG_CRL;
|
||||
isKrl = (PRBool)(*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE);
|
||||
break;
|
||||
case CKA_MODIFIABLE:
|
||||
break;
|
||||
case CKA_KEY_TYPE:
|
||||
+ crv = lg_GetULongAttribute(CKA_KEY_TYPE, &pTemplate[i], 1, &keyType);
|
||||
+ if (crv != CKR_OK) {
|
||||
+ classFlags = 0;
|
||||
+ break;
|
||||
+ }
|
||||
case CKA_DERIVE:
|
||||
classFlags &= LG_PUBLIC | LG_PRIVATE | LG_KEY;
|
||||
break;
|
||||
case CKA_VERIFY_RECOVER:
|
||||
classFlags &= LG_PUBLIC;
|
||||
break;
|
||||
case CKA_SIGN_RECOVER:
|
||||
classFlags &= LG_PRIVATE;
|
||||
@@ -838,17 +875,17 @@ lg_searchTokenList(SDB *sdb, SDBFind *se
|
||||
lg_searchCertsAndTrust(sdb, &derCert, &name, &derSubject,
|
||||
&issuerSN, &email, classFlags, search,
|
||||
pTemplate, ulCount);
|
||||
}
|
||||
|
||||
/* keys */
|
||||
if (classFlags & (LG_PRIVATE | LG_PUBLIC | LG_KEY)) {
|
||||
PRBool mustStrict = (name.len != 0);
|
||||
- lg_searchKeys(sdb, &key_id, classFlags, search,
|
||||
+ lg_searchKeys(sdb, &key_id, classFlags, keyType, search,
|
||||
mustStrict, pTemplate, ulCount);
|
||||
}
|
||||
|
||||
/* crl's */
|
||||
if (classFlags & LG_CRL) {
|
||||
lg_searchCrls(sdb, &derSubject, isKrl, classFlags, search,
|
||||
pTemplate, ulCount);
|
||||
}
|
||||
diff --git a/lib/softoken/legacydb/lowkeyi.h b/lib/softoken/legacydb/lowkeyi.h
|
||||
--- a/lib/softoken/legacydb/lowkeyi.h
|
||||
+++ b/lib/softoken/legacydb/lowkeyi.h
|
||||
@@ -138,11 +138,17 @@ nsslowkey_FindKeyNicknameByPublicKey(NSS
|
||||
*/
|
||||
SECStatus LGEC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
|
||||
ECParams *params);
|
||||
|
||||
/* Copy all of the fields from srcParams into dstParams */
|
||||
SECStatus LGEC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
|
||||
const ECParams *srcParams);
|
||||
|
||||
+/* fetch the key type from a secret key */
|
||||
+CK_KEY_TYPE lg_FetchSecretKeyType(NSSLOWKEYPrivateKey *key);
|
||||
+
|
||||
+/* create a new key id with a distinguishing key type */
|
||||
+SECItem *lg_makeSecretKeyId(SECItem *key_id, CK_KEY_TYPE keyType);
|
||||
+
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _LOWKEYI_H_ */
|
||||
diff --git a/tests/cert/cert.sh b/tests/cert/cert.sh
|
||||
--- a/tests/cert/cert.sh
|
||||
+++ b/tests/cert/cert.sh
|
||||
@@ -101,19 +101,21 @@ cert_init()
|
||||
fi
|
||||
|
||||
cert_add_algorithm "RSA" "" "" "false" 0
|
||||
if [ -z ${NSS_DISABLE_DSA} ]; then
|
||||
cert_add_algorithm "DSA" "-dsa" "-k dsa" "true" 20000
|
||||
fi
|
||||
# NOTE: curve is added later, so the full command would be '-k ec -q curve'
|
||||
cert_add_algorithm "ECC" "-ec" "-k ec -q" "true" 10000
|
||||
- cert_add_algorithm "ML-DSA-44" "-ml-dsa-44" "-k mldsa -q ml-dsa-44" "false" 30000
|
||||
- cert_add_algorithm "ML-DSA-65" "-ml-dsa-65" "-k mldsa -q ml-dsa-65" "false" 40000
|
||||
- cert_add_algorithm "ML-DSA-87" "-ml-dsa-87" "-k mldsa -q ml-dsa-87" "false" 50000
|
||||
+ if using_sql; then
|
||||
+ cert_add_algorithm "ML-DSA-44" "-ml-dsa-44" "-k mldsa -q ml-dsa-44" "false" 30000
|
||||
+ cert_add_algorithm "ML-DSA-65" "-ml-dsa-65" "-k mldsa -q ml-dsa-65" "false" 40000
|
||||
+ cert_add_algorithm "ML-DSA-87" "-ml-dsa-87" "-k mldsa -q ml-dsa-87" "false" 50000
|
||||
+ fi
|
||||
# currently rsa-pss is only enabled for a subset of tests
|
||||
# this will enable a full suite of RSA-PSS certs, and we would
|
||||
# then remove the explicit ones
|
||||
# ulike the other tests, we would need to change ssl tests as this
|
||||
# will rename some of the RSA-PSS certificates.
|
||||
#cert_add_algorithm "RSA-PSS" "-rsa-pss" "-k rsa -pss -Z sha256" "true"
|
||||
#cert_add_algorithm "RSA-PSS-SHA1" "-rsa-pss-sha1" "-k rsa -pss -Z sha1" "true"
|
||||
|
||||
diff --git a/tests/dbtests/dbtests.sh b/tests/dbtests/dbtests.sh
|
||||
--- a/tests/dbtests/dbtests.sh
|
||||
+++ b/tests/dbtests/dbtests.sh
|
||||
@@ -456,18 +456,22 @@ dbtest_main()
|
||||
if [ $ret -ne 0 ]; then
|
||||
html_failed "Nickname conflict test-setting nickname conflict incorrectly worked"
|
||||
else
|
||||
html_passed "Nickname conflict test-setting nickname conflict was correctly rejected"
|
||||
fi
|
||||
# import a token private key and make sure the corresponding public key is
|
||||
# created
|
||||
IMPORT_OPTIONS=""
|
||||
+ if ! using_sql ; then
|
||||
+ # can't store mlkem, mldsa, eddsa, or ecMont keys in the old database
|
||||
+ IMPORT_OPTIONS="$IMPORT_OPTIONS -m -K -w -g"
|
||||
+ fi
|
||||
if [ -n "$NSS_DISABLE_DSA" ]; then
|
||||
- IMPORT_OPTIONS="-D noDSA"
|
||||
+ IMPORT_OPTIONS="$IMPORT_OPTION -D noDSA"
|
||||
fi
|
||||
Echo "Importing Token Private Key"
|
||||
echo "pk11importtest ${IMPORT_OPTIONS} -d ${CONFLICT_DIR} -f ${R_PWFILE}"
|
||||
${BINDIR}/pk11importtest ${IMPORT_OPTIONS} -d ${CONFLICT_DIR} -f ${R_PWFILE}
|
||||
ret=$?
|
||||
if [ $ret -ne 0 ]; then
|
||||
html_failed "Importing Token Private Key does not create the corrresponding Public Key"
|
||||
else
|
||||
diff --git a/tests/sdr/sdr.sh b/tests/sdr/sdr.sh
|
||||
--- a/tests/sdr/sdr.sh
|
||||
+++ b/tests/sdr/sdr.sh
|
||||
@@ -89,17 +89,17 @@ sdr_main()
|
||||
html_msg $? 0 "Encrypt - Value 2"
|
||||
|
||||
echo "$SCRIPTNAME: SDR Encrypt - Value 3"
|
||||
echo "sdrtest -d ${PROFILE} -o ${VALUE3} -t \"${T3}\" -f ${R_PWFILE}"
|
||||
${BINDIR}/sdrtest -d ${PROFILE} -o ${VALUE3} -t "${T3}" -f ${R_PWFILE}
|
||||
html_msg $? 0 "Encrypt - Value 3"
|
||||
|
||||
echo "$SCRIPTNAME: Creating an DES3 SDR key/SDR Encrypt - Value 4"
|
||||
- echo "sdrtest -d ${PROFILE} -o ${VALUE4} -t \"${T4}\" -f ${R_PWFILE}"
|
||||
+ echo "sdrtest -d ${PROFILE} -o ${VALUE4} -t \"${T4}\" -f ${R_PWFILE} -m des3"
|
||||
${BINDIR}/sdrtest -d ${PROFILE} -o ${VALUE4} -t "${T4}" -f ${R_PWFILE} -m des3
|
||||
html_msg $? 0 "Creating an DES3 SDR key/Encrypt - Value 4"
|
||||
|
||||
echo "$SCRIPTNAME: SDR Decrypt - Value 1"
|
||||
echo "sdrtest -d ${PROFILE} -i ${VALUE1} -t \"${T1}\" -f ${R_PWFILE}"
|
||||
${BINDIR}/sdrtest -d ${PROFILE} -i ${VALUE1} -t "${T1}" -f ${R_PWFILE}
|
||||
html_msg $? 0 "Decrypt - Value 1"
|
||||
|
||||
@@ -118,16 +118,17 @@ sdr_main()
|
||||
${BINDIR}/sdrtest -d ${PROFILE} -i ${VALUE4} -t "${T4}" -f ${R_PWFILE}
|
||||
html_msg $? 0 "DES3 Decrypt - Value 4"
|
||||
|
||||
echo "$SCRIPTNAME: pwdecrypt - 300 Entries"
|
||||
# get base64 encoded encrypted versions of our tests
|
||||
sdrtest -d ${PROFILE} -o ${ASCII_VALUE1} -a -t "${T1}" -f ${R_PWFILE}
|
||||
sdrtest -d ${PROFILE} -o ${ASCII_VALUE2} -a -t "${T2}" -f ${R_PWFILE}
|
||||
sdrtest -d ${PROFILE} -o ${ASCII_VALUE3} -a -t "${T3}" -f ${R_PWFILE}
|
||||
+ echo "sdrtest -d ${PROFILE} -o ${ASCII_VALUE4} -a -t \"${T4}\" -f ${R_PWFILE} -m des3"
|
||||
sdrtest -d ${PROFILE} -o ${ASCII_VALUE4} -a -t "${T4}" -f ${R_PWFILE} -m des3
|
||||
# make each encoded span exactly one line
|
||||
touch ${ASCII_COMBINED}
|
||||
cat ${ASCII_VALUE1} | tr -d '\n' >> ${ASCII_COMBINED}
|
||||
echo >> ${ASCII_COMBINED}
|
||||
cat ${ASCII_VALUE2} | tr -d '\n' >> ${ASCII_COMBINED}
|
||||
echo >> ${ASCII_COMBINED}
|
||||
cat ${ASCII_VALUE3} | tr -d '\n' >> ${ASCII_COMBINED}
|
||||
diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh
|
||||
--- a/tests/ssl/ssl.sh
|
||||
+++ b/tests/ssl/ssl.sh
|
||||
@@ -134,16 +134,24 @@ ssl_init()
|
||||
# in fips mode, turn off curve25519 until it's NIST approved
|
||||
FIPS_OPTIONS=""
|
||||
# in fips mode, turn off curve25519 until it's NIST approved
|
||||
ALL_GROUPS="P256,P384,P521,x25519,FF2048,FF3072,FF4096,FF6144,FF8192,xyber768d00,x25519mlkem768,secp256r1mlkem768,secp384r1mlkem1024"
|
||||
NON_PQ_GROUPS="P256,P384,P521,x25519,FF2048,FF3072,FF4096,FF6144,FF8192"
|
||||
FIPS_GROUPS="P256,P384,P521,FF2048,FF3072,FF4096,FF6144,FF8192,x25519mlkem768,secp256r1mlkem768,secp384r1mlkem1024"
|
||||
FIPS_NON_PQ_GROUPS="P256,P384,P521,FF2048,FF3072,FF4096,FF6144,FF8192"
|
||||
|
||||
+ # dbm can't store ML_DSA certs
|
||||
+ if ! using_sql ; then
|
||||
+ NO_ML_DSA_CERTS=1
|
||||
+ fi
|
||||
+ # upgrade DB's are created from dbm, so they have no ML_DSA certs
|
||||
+ if [ "$TEST_MODE" = "UPGRADE_DB" ]; then
|
||||
+ NO_ML_DSA_CERTS=1
|
||||
+ fi
|
||||
|
||||
# in non-fips mode, tstclnt may run without the db password in some
|
||||
# cases, but in fips mode it's always needed
|
||||
CLIENT_PW=""
|
||||
CLIENT_PW_FIPS="-w nss"
|
||||
CLIENT_PW_NORMAL=""
|
||||
|
||||
if [ "${OS_ARCH}" != "WINNT" ]; then
|
||||
@@ -331,32 +339,40 @@ ssl_cov()
|
||||
# doing so hides the server pid environment variable in the subshell in
|
||||
# cygwin, which means we can't kill selfserv at the end here.
|
||||
SSL_COV_TMP=$(mktemp /tmp/ssl_cov.XXXXXX)
|
||||
ignore_blank_lines ${SSLCOV} > ${SSL_COV_TMP}
|
||||
while read ectype testmax param sig testname
|
||||
do
|
||||
# Select the TLS SIG SCHEME if necessary
|
||||
TLS_SIG_SCHEMES=""
|
||||
+ TLS_IS_ML_DSA=0
|
||||
if [ "$sig" = "RSA-PSS" ]; then
|
||||
# RSA-PSS tests are currently handled in a separate function
|
||||
continue
|
||||
elif [ "$sig" = "ML-DSA-44" ]; then
|
||||
TLS_SIG_SCHEMES="-J mldsa44 "
|
||||
+ TLS_IS_ML_DSA=1
|
||||
elif [ "$sig" = "ML-DSA-65" ]; then
|
||||
TLS_SIG_SCHEMES="-J mldsa65 "
|
||||
+ TLS_IS_ML_DSA=1
|
||||
elif [ "$sig" = "ML-DSA-87" ]; then
|
||||
TLS_SIG_SCHEMES="-J mldsa87 "
|
||||
+ TLS_IS_ML_DSA=1
|
||||
fi
|
||||
|
||||
|
||||
# skip DSA tests if they are disabled
|
||||
if [ -n "$NSS_DISABLE_DSA" -a "$sig" = "DSA" ]; then
|
||||
continue
|
||||
fi
|
||||
+ # skip ML-DSA tests if they are disabled
|
||||
+ if [ -n "$NO_ML_DSA_CERTS" -a -n "$NO_ML_DSA_CERTS" -a "$TLS_IS_ML_DSA" = 1 ]; then
|
||||
+ continue
|
||||
+ fi
|
||||
|
||||
echo "$SCRIPTNAME: running $testname ----------------------------"
|
||||
VMAX="ssl3"
|
||||
if [ "$testmax" = "TLS10" ]; then
|
||||
VMAX="tls1.0"
|
||||
fi
|
||||
if [ "$testmax" = "TLS11" ]; then
|
||||
VMAX="tls1.1"
|
||||
@@ -485,16 +501,18 @@ ssl_auth()
|
||||
CAUTH=$?
|
||||
echo "${testname}" | grep "TLS 1.3" > /dev/null
|
||||
TLS13=$?
|
||||
|
||||
if [ "${CLIENT_MODE}" = "fips" -a "${CAUTH}" -eq 0 ] ; then
|
||||
echo "$SCRIPTNAME: skipping $testname (non-FIPS only)"
|
||||
elif [ "$ectype" = "SNI" -a "$NORM_EXT" = "Extended Test" ] ; then
|
||||
echo "$SCRIPTNAME: skipping $testname for $NORM_EXT"
|
||||
+ elif [ "$ectype" = "MLDSA" -a -n "$NO_ML_DSA_CERTS" -a "$NO_ML_DSA_CERTS" = "1" ] ; then
|
||||
+ echo "$SCRIPTNAME: skipping $testname old dbm does not support mldsa"
|
||||
else
|
||||
cparam=`echo $cparam | sed -e 's;\([^\\]\)_;\1 ;g' -e 's;\\\\_;_;g' -e "s/TestUser/$USER_NICKNAME/g" `
|
||||
if [ "$ectype" = "SNI" ]; then
|
||||
cparam=`echo $cparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" `
|
||||
sparam=`echo $sparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" `
|
||||
fi
|
||||
# SSL3 cannot be used with TLS 1.3
|
||||
unset SERVER_VMIN
|
||||
@@ -763,16 +781,18 @@ ssl_crl_ssl()
|
||||
|
||||
ignore_blank_lines ${SSLAUTH} | \
|
||||
while read ectype value sparam cparam testname
|
||||
do
|
||||
echo "${testname}" | grep "TLS 1.3" > /dev/null
|
||||
TLS13=$?
|
||||
if [ "$ectype" = "SNI" ]; then
|
||||
continue
|
||||
+ elif [ "$ectype" = "MLDSA" -a -n "$NO_ML_DSA_CERTS" -a "$NO_ML_DSA_CERTS" = "1" ] ; then
|
||||
+ continue
|
||||
else
|
||||
# SSL3 cannot be used with TLS 1.3
|
||||
unset SERVER_VMIN
|
||||
unset SERVER_VMAX
|
||||
if [ $TLS13 -eq 0 ] ; then
|
||||
SERVER_VMIN=tls1.0
|
||||
SERVER_VMAX=tls1.3
|
||||
fi
|
||||
diff --git a/tests/ssl_gtests/ssl_gtest_db.sh b/tests/ssl_gtests/ssl_gtest_db.sh
|
||||
--- a/tests/ssl_gtests/ssl_gtest_db.sh
|
||||
+++ b/tests/ssl_gtests/ssl_gtest_db.sh
|
||||
@@ -54,33 +54,39 @@ make_cert rsa_sign rsa sign
|
||||
make_cert rsa_pss rsapss sign
|
||||
make_cert rsa_pss384 rsapss384 sign
|
||||
make_cert rsa_pss512 rsapss512 sign
|
||||
make_cert rsa_pss_noparam rsapss_noparam sign
|
||||
make_cert rsa_decrypt rsa kex
|
||||
make_cert ecdsa256 p256 sign
|
||||
make_cert ecdsa384 p384 sign
|
||||
make_cert ecdsa521 p521 sign
|
||||
-make_cert mldsa44 mldsa44 sign
|
||||
-make_cert mldsa65 mldsa65 sign
|
||||
-make_cert mldsa87 mldsa87 sign
|
||||
+if using_sql; then
|
||||
+ make_cert mldsa44 mldsa44 sign
|
||||
+ make_cert mldsa65 mldsa65 sign
|
||||
+ make_cert mldsa87 mldsa87 sign
|
||||
+fi
|
||||
make_cert ecdh_ecdsa p256 kex
|
||||
make_cert rsa_ca rsa_ca ca
|
||||
make_cert rsa_chain rsa_chain sign
|
||||
make_cert rsa_pss_ca rsapss_ca ca
|
||||
make_cert rsa_pss_chain rsapss_chain sign
|
||||
make_cert rsa_ca_rsa_pss_chain rsa_ca_rsapss_chain sign
|
||||
-make_cert mldsa44_ca mldsa44_ca ca
|
||||
-make_cert mldsa44_chain mldsa44_chain sign
|
||||
-make_cert mldsa65_ca mldsa65_ca ca
|
||||
-make_cert mldsa65_chain mldsa65_chain sign
|
||||
-make_cert mldsa87_ca mldsa87_ca ca
|
||||
-make_cert mldsa87_chain mldsa87_chain sign
|
||||
+if using_sql; then
|
||||
+ make_cert mldsa44_ca mldsa44_ca ca
|
||||
+ make_cert mldsa44_chain mldsa44_chain sign
|
||||
+ make_cert mldsa65_ca mldsa65_ca ca
|
||||
+ make_cert mldsa65_chain mldsa65_chain sign
|
||||
+ make_cert mldsa87_ca mldsa87_ca ca
|
||||
+ make_cert mldsa87_chain mldsa87_chain sign
|
||||
+fi
|
||||
make_cert ecdh_rsa ecdh_rsa kex
|
||||
if [ -z "${NSS_DISABLE_DSA}" ]; then
|
||||
make_cert dsa dsa sign
|
||||
fi
|
||||
make_cert delegator_ecdsa256 delegator_p256 sign
|
||||
make_cert delegator_rsae2048 delegator_rsae2048 sign
|
||||
make_cert delegator_rsa_pss2048 delegator_rsa_pss2048 sign
|
||||
-make_cert delegator_mldsa44 delegator_mldsa44 sign
|
||||
-make_cert delegator_mldsa65 delegator_mldsa65 sign
|
||||
-make_cert delegator_mldsa87 delegator_mldsa87 sign
|
||||
+if using_sql; then
|
||||
+ make_cert delegator_mldsa44 delegator_mldsa44 sign
|
||||
+ make_cert delegator_mldsa65 delegator_mldsa65 sign
|
||||
+ make_cert delegator_mldsa87 delegator_mldsa87 sign
|
||||
+fi
|
||||
diff --git a/tests/ssl_gtests/ssl_gtests.sh b/tests/ssl_gtests/ssl_gtests.sh
|
||||
--- a/tests/ssl_gtests/ssl_gtests.sh
|
||||
+++ b/tests/ssl_gtests/ssl_gtests.sh
|
||||
@@ -30,23 +30,27 @@ ssl_gtest_certs() {
|
||||
ssl_gtest_init()
|
||||
{
|
||||
SCRIPTNAME=ssl_gtest.sh # sourced - $0 would point to all.sh
|
||||
|
||||
if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for
|
||||
CLEANUP="${SCRIPTNAME}" # cleaning this script will do it
|
||||
fi
|
||||
if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
|
||||
- cd ../common
|
||||
+ pushd ../common
|
||||
. ./init.sh
|
||||
+ popd
|
||||
fi
|
||||
|
||||
SCRIPTNAME=ssl_gtest.sh
|
||||
html_head SSL Gtests
|
||||
|
||||
+ echo "SSLGTESTDIR=${SSLGTESTDIR}"
|
||||
+ pwd
|
||||
+
|
||||
if [ ! -d "${SSLGTESTDIR}" ]; then
|
||||
ssl_gtest_certs
|
||||
fi
|
||||
|
||||
cd "${SSLGTESTDIR}"
|
||||
}
|
||||
|
||||
########################## ssl_gtest_start #########################
|
||||
diff --git a/tests/tools/tools.sh b/tests/tools/tools.sh
|
||||
--- a/tests/tools/tools.sh
|
||||
+++ b/tests/tools/tools.sh
|
||||
@@ -658,20 +658,20 @@ tools_p12()
|
||||
tools_p12_export_list_import_all_pkcs12v2pbe_ciphers
|
||||
else
|
||||
tools_p12_export_list_import_most_ciphers
|
||||
fi
|
||||
tools_p12_export_with_none_ciphers
|
||||
tools_p12_export_with_invalid_ciphers
|
||||
tools_p12_import_old_files
|
||||
tools_p12_import_pbmac1_samples
|
||||
- tools_p12_import_ed25519_private_key
|
||||
- tools_p12_ml_dsa_import
|
||||
- tools_p12_ml_kem_import
|
||||
if using_sql; then
|
||||
+ tools_p12_import_ed25519_private_key
|
||||
+ tools_p12_ml_dsa_import
|
||||
+ tools_p12_ml_kem_import
|
||||
tools_p12_import_rsa_pss_private_key
|
||||
tools_p12_policy
|
||||
fi
|
||||
}
|
||||
|
||||
############################## tools_sign ##############################
|
||||
# local shell function pk12util uses a hardcoded tmp file, if this exists
|
||||
# and is owned by another user we don't get reasonable errormessages
|
||||
@ -1,65 +0,0 @@
|
||||
diff -up ./lib/freebl/Makefile.ppc_no_init ./lib/freebl/Makefile
|
||||
--- ./lib/freebl/Makefile.ppc_no_init 2024-06-03 14:12:24.216755903 -0700
|
||||
+++ ./lib/freebl/Makefile 2024-06-03 14:11:36.464234903 -0700
|
||||
@@ -303,7 +303,7 @@ endif
|
||||
ifeq ($(CPU_ARCH),ppc)
|
||||
EXTRA_SRCS += gcm-ppc.c
|
||||
ifdef USE_64
|
||||
- DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
+# DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
PPC_ABI := $(shell $(CC) -dM -E - < /dev/null | awk '$$2 == "_CALL_ELF" {print $$3}')
|
||||
ifeq ($(PPC_ABI),2)
|
||||
ASFILES += sha512-p8.s
|
||||
diff -up ./lib/softoken/Makefile.ppc_no_init ./lib/softoken/Makefile
|
||||
--- ./lib/softoken/Makefile.ppc_no_init 2024-06-03 14:12:44.664979003 -0700
|
||||
+++ ./lib/softoken/Makefile 2024-06-03 14:10:26.703473806 -0700
|
||||
@@ -23,13 +23,13 @@ include $(CORE_DEPTH)/coreconf/config.mk
|
||||
ifdef NSS_NO_INIT_SUPPORT
|
||||
DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
endif
|
||||
-ifeq ($(OS_TARGET),Linux)
|
||||
-ifeq ($(CPU_ARCH),ppc)
|
||||
-ifdef USE_64
|
||||
- DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
-endif # USE_64
|
||||
-endif # ppc
|
||||
-endif # Linux
|
||||
+#ifeq ($(OS_TARGET),Linux)
|
||||
+#ifeq ($(CPU_ARCH),ppc)
|
||||
+#ifdef USE_64
|
||||
+# DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
+#endif # USE_64
|
||||
+#endif # ppc
|
||||
+#endif # Linux
|
||||
|
||||
|
||||
#######################################################################
|
||||
diff -up ./lib/softoken/legacydb/Makefile.ppc_no_init ./lib/softoken/legacydb/Makefile
|
||||
--- ./lib/softoken/legacydb/Makefile.ppc_no_init 2024-11-12 11:51:16.535343581 +0100
|
||||
+++ ./lib/softoken/legacydb/Makefile 2024-11-12 12:09:58.968187800 +0100
|
||||
@@ -23,16 +23,17 @@ include $(CORE_DEPTH)/coreconf/config.mk
|
||||
ifdef NSS_NO_INIT_SUPPORT
|
||||
DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
endif
|
||||
-ifeq ($(OS_TARGET),Linux)
|
||||
-ifeq ($(CPU_ARCH),ppc)
|
||||
-ifdef USE_64
|
||||
- DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
-endif # USE_64
|
||||
-endif # ppc
|
||||
-else # !Linux
|
||||
+#ifeq ($(OS_TARGET),Linux)
|
||||
+#ifeq ($(CPU_ARCH),ppc)
|
||||
+#ifdef USE_64
|
||||
+# DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
+#endif # USE_64
|
||||
+#endif # ppc
|
||||
+#else # !Linux
|
||||
+ifneq ($(OS_TARGET),Linux)
|
||||
# turn off no init support everywhere for now
|
||||
DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
-endif # Linux
|
||||
+endif # !Linux
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
87
nss.spec
87
nss.spec
@ -1,7 +1,7 @@
|
||||
%global nspr_build_version 4.36.0-2
|
||||
%global nspr_release -2
|
||||
%global nspr_version 4.35.0
|
||||
%global nss_version 3.112.0
|
||||
%global nspr_build_version 4.39.0-1
|
||||
%global nspr_release -1
|
||||
%global nspr_version 4.39.0
|
||||
%global nss_version 3.124.0
|
||||
%global unsupported_tools_directory %{_libdir}/nss/unsupported-tools
|
||||
%global saved_files_dir %{_libdir}/nss/saved
|
||||
%global dracutlibdir %{_prefix}/lib/dracut
|
||||
@ -63,7 +63,7 @@ print(string.sub(hash, 0, 16))
|
||||
Summary: Network Security Services
|
||||
Name: nss
|
||||
Version: %{nss_version}
|
||||
Release: 8%{?dist}
|
||||
Release: 5%{?dist}
|
||||
License: MPLv2.0
|
||||
URL: http://www.mozilla.org/projects/security/pki/nss/
|
||||
Requires: nspr >= %{nspr_version}%{nspr_release}
|
||||
@ -112,7 +112,7 @@ Source28: nss-p11-kit.config
|
||||
Source29: nss_compat_test_pkcs12.tar
|
||||
# fips algorithms are tied to the red hat validation, others
|
||||
# will have their own validation
|
||||
Source30: fips_algorithms.h
|
||||
Source90: fips_algorithms.h
|
||||
|
||||
#Source50: NameConstraints_Certs.tar
|
||||
|
||||
@ -150,7 +150,7 @@ Patch12: nss-gcm-param-default-pkcs11v2.patch
|
||||
Patch13: rhbz1185708-enable-ecc-3des-ciphers-by-default.patch
|
||||
# Local patch: ignore rsa, rsa-pss, ecdsa policies until crypto-policies
|
||||
# is updated.
|
||||
Patch14: nss-3.112-disable-signature-policies.patch
|
||||
Patch14: nss-3.124-disable-signature-policies.patch
|
||||
# Local patch: disable tests that require external reference so brew completes
|
||||
Patch16: nss-3.112-disable-external-host-test.patch
|
||||
# Local patch: restore old pkcs 12 defaults on old version of rhel
|
||||
@ -166,39 +166,39 @@ Patch20: nss-3.101-ec-dbm-test.patch
|
||||
# end of RHEL-8 specific patches
|
||||
|
||||
# RHEL-specific shared with RHEL-9
|
||||
Patch30: nss-3.101-extend-db-dump-time.patch
|
||||
Patch21: nss-3.101-extend-db-dump-time.patch
|
||||
# Local patch: disable MD5 (also MD2 and MD4) completely
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1849938
|
||||
Patch32: nss-3.112-disable-md5.patch
|
||||
Patch34: nss-3.71-fix-lto-gtests.patch
|
||||
Patch36: nss-3.112-disable-ech.patch
|
||||
Patch37: nss-3.112-revert-libpkix-default.patch
|
||||
Patch22: nss-3.112-disable-md5.patch
|
||||
Patch24: nss-3.71-fix-lto-gtests.patch
|
||||
Patch26: nss-3.124-disable-ech.patch
|
||||
Patch27: nss-3.124-el8-revert-libpkix-default.patch
|
||||
Patch37: nss-3.124-allow-hash-override-pss.patch
|
||||
|
||||
|
||||
# patches that expect to be upstreamed
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1767883
|
||||
Patch50: nss-3.112-fips.patch
|
||||
Patch40: nss-3.90-dh-test-update.patch
|
||||
Patch41: nss-3.124-ppc_no_init.patch
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=676100
|
||||
Patch42: nss-3.101-fix-cms-abi-break.patch
|
||||
Patch43: nss-3.124-tools-test-fix.patch
|
||||
|
||||
# ems policy. needs to upstream
|
||||
Patch74: nss-3.90-dh-test-update.patch
|
||||
Patch75: nss-3.90-ppc_no_init.patch
|
||||
Patch76: nss-3.112-el8-no-p12-smime-policy.patch
|
||||
Patch78: nss-3.101-fix-cms-abi-break.patch
|
||||
Patch79: nss-3.101-fix-shlibsign-fips.patch
|
||||
#in process upstream
|
||||
Patch50: nss-3.124-fips-key-import-fix.patch
|
||||
Patch51: nss-3.124-fix-ed-key-storage.patch
|
||||
Patch52: nss-3.124-indicators-prf.patch
|
||||
Patch53: nss-3.124-annocheck.fix.patch
|
||||
Patch54: nss-3.124-disable-kyber-test.patch
|
||||
Patch55: nss-3.124-fix-old-compiler-issue.patch
|
||||
|
||||
# Post Quantum specific
|
||||
Patch81: nss-3.112-replace-xyber-with-mlkem-256.patch
|
||||
Patch82: nss-3.112-add-sec384r1-mlkem-1024.patch
|
||||
Patch83: nss-3.112-add-ml-dsa-base-el8.patch
|
||||
Patch84: nss-3.112-add-ml-dsa-gtests-el8.patch
|
||||
Patch85: nss-3.112-add-ml-dsa-ssl-support-el8.patch
|
||||
Patch86: nss-3.112-fips-and-fixes-el8.patch
|
||||
Patch87: nss-3.112-big-endian-compression-fix.patch
|
||||
Patch88: nss-3.112-fix-get-interface.patch
|
||||
Patch89: nss-3.112-update-fixes.patch
|
||||
Patch90: nss-3.112-mlkem-fips-update.patch
|
||||
Patch91: nss-3.112-partial-pub-key-validate.patch
|
||||
Patch92: nss-3.112-pkcs12-ml-dsa-crash-fix.patch
|
||||
Patch60: nss-3.118-ml-dsa-leancrypto.patch
|
||||
Patch61: nss-3.118-ml-dsa-tls.patch
|
||||
Patch62: nss-3.124-prefer-all-hybrid.patch
|
||||
Patch65: nss-3.124-ml-dsa-test-for-sign-verify-pkcs12.patch
|
||||
Patch66: nss-3.124-ml-dsa-tls-test.patch
|
||||
Patch67: nss-3.118-ml-dsa-unittests.patch
|
||||
Patch68: nss-3.123-fix-mldsa-import-regeneration.patch
|
||||
|
||||
Patch88: nss-3.124-turn_off_non_dbm_tests.patch
|
||||
|
||||
%description
|
||||
Network Security Services (NSS) is a set of libraries designed to
|
||||
@ -337,7 +337,7 @@ tar xvf %{SOURCE29}
|
||||
# copy the fips_algorithms.h for this release
|
||||
# this file is release specific and matches what
|
||||
# each vendors claim in their own FIPS certification
|
||||
cp %{SOURCE30} nss/lib/softoken/
|
||||
cp %{SOURCE90} nss/lib/softoken/
|
||||
|
||||
#update expired test certs
|
||||
#pushd nss
|
||||
@ -371,6 +371,7 @@ export NSS_FIPS_140_3=1
|
||||
export NSS_ENABLE_FIPS_INDICATORS=1
|
||||
export NSS_DISABLE_KYBER=1
|
||||
export NSS_ENABLE_ML_DSA=1
|
||||
export NSS_ENABLE_CRMF=1
|
||||
|
||||
# Enable compiler optimizations and disable debugging code
|
||||
export BUILD_OPT=1
|
||||
@ -596,7 +597,7 @@ export NSS_DEFAULT_DB_TYPE=dbm #in RHEL 8, the default db is sql, but we want
|
||||
%define nss_cycles "standard pkix upgradedb sharedb threadunsafe"
|
||||
# the full list from all.sh is:
|
||||
# "cipher lowhash libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge pkits chains ec gtests ssl_gtests"
|
||||
%define nss_tests "libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge pkits chains ec gtests ssl_gtests"
|
||||
%define nss_tests "libpkix cert dbtests tools fips sdr smime ssl ocsp merge pkits chains ec gtests ssl_gtests"
|
||||
# nss_ssl_tests: crl bypass_normal normal_bypass normal_fips fips_normal iopr policy
|
||||
# nss_ssl_run: cov auth stapling stress
|
||||
#
|
||||
@ -655,7 +656,7 @@ install -p -m 644 %{SOURCE14} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/key4.db
|
||||
install -p -m 644 %{SOURCE15} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/pkcs11.txt
|
||||
|
||||
# Copy the development libraries we want
|
||||
for file in libcrmf.a libnssb.a libnssckfw.a
|
||||
for file in libnssb.a libnssckfw.a
|
||||
do
|
||||
install -p -m 644 dist/*.OBJ/lib/$file $RPM_BUILD_ROOT/%{_libdir}
|
||||
done
|
||||
@ -818,7 +819,6 @@ update-crypto-policies --no-reload &> /dev/null || :
|
||||
%doc %{_mandir}/man1/vfyserv.1*
|
||||
|
||||
%files devel
|
||||
%{_libdir}/libcrmf.a
|
||||
%{_libdir}/pkgconfig/nss.pc
|
||||
%{_bindir}/nss-config
|
||||
%doc %{_mandir}/man1/nss-config.1*
|
||||
@ -827,13 +827,9 @@ update-crypto-policies --no-reload &> /dev/null || :
|
||||
%{_includedir}/nss3/cert.h
|
||||
%{_includedir}/nss3/certdb.h
|
||||
%{_includedir}/nss3/certt.h
|
||||
%{_includedir}/nss3/cmmf.h
|
||||
%{_includedir}/nss3/cmmft.h
|
||||
%{_includedir}/nss3/cms.h
|
||||
%{_includedir}/nss3/cmsreclist.h
|
||||
%{_includedir}/nss3/cmst.h
|
||||
%{_includedir}/nss3/crmf.h
|
||||
%{_includedir}/nss3/crmft.h
|
||||
%{_includedir}/nss3/cryptohi.h
|
||||
%{_includedir}/nss3/cryptoht.h
|
||||
%{_includedir}/nss3/sechash.h
|
||||
@ -999,8 +995,13 @@ update-crypto-policies --no-reload &> /dev/null || :
|
||||
%{_includedir}/nss3/nsslowhash.h
|
||||
%{_includedir}/nss3/shsign.h
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Jun 8 2026 Bob Relyea <rrelyea@redhat.com> - 3.124.0-5
|
||||
- rebase to upstream NSS 3.124
|
||||
- backport ml-dsa support that is not upstream yet.
|
||||
- pick up in process patches upstream including eddsa
|
||||
- fix pss issues
|
||||
|
||||
* Fri Jan 23 2026 Bob Relyea <rrelyea@redhat.com> - 3.112.0-8
|
||||
- fix incomplete ml-kem pct patch.
|
||||
|
||||
|
||||
5
sources
5
sources
@ -3,6 +3,5 @@ SHA512 (blank-cert9.db) = 2f8eab4c0612210ee47db8a3a80c1b58a0b43849551af78c7da403
|
||||
SHA512 (blank-key3.db) = 01f7314e9fc8a7c9aa997652624cfcde213d18a6b3bb31840c1a60bbd662e56b5bc3221d13874abb42ce78163b225a6dfce2e1326cf6dd29366ad9c28ba5a71c
|
||||
SHA512 (blank-key4.db) = 8fedae93af7163da23fe9492ea8e785a44c291604fa98e58438448efb69c85d3253fc22b926d5c3209c62e58a86038fd4d78a1c4c068bc00600a7f3e5382ebe7
|
||||
SHA512 (blank-secmod.db) = 06a2dbd861839ef6315093459328b500d3832333a34b30e6fac4a2503af337f014a4d319f0f93322409e719142904ce8bc08252ae9a4f37f30d4c3312e900310
|
||||
SHA512 (nss_compat_test_pkcs12.tar) = 766af618ef02be5d54aff94651751ec68109a293c0b2782b0d7f6f2c844e41f4414eee5a9f46df2b1c22e0f24c4d85be00217cbcbc2632ac2f51bfa644abc2e6
|
||||
SHA512 (nss-3.112.tar.gz) = 564ae4ded323d7213f224673b0ddc584dcfae71bbdd139310854e547d9ba2877ba45462da49f71ea2fae72caea1cf10fa51d9dfef656a21957256cadc5fa4b35
|
||||
|
||||
SHA512 (nss-3.124.tar.gz) = 9959977b3cbcb0306c8aeba2c059d4f3646b3144c6401fbc73c14aea364caa92331875354afa79c095b6482b29ae743228d35c1bd510c5124cad5e7c37c5daa2
|
||||
SHA512 (nss_compat_test_pkcs12.tar) = 58eef24a2f5f4df0e230fc775ba26d8bb43689597553460735593dd8655dac5e42e8dfea120c187f5af623910d80f34490ce426e22a42a7498a787d2cc9fadf5
|
||||
|
||||
Loading…
Reference in New Issue
Block a user