Resolves: RHEL-182305

- rebase to upstream NSS 3.124
- backport ml-dsa support that is not upstream yet.
- pick up in process patches upstream including eddsa
This commit is contained in:
Robert Relyea 2026-06-04 14:34:43 -07:00
parent 4d06d7623d
commit 0b59ee7dde
38 changed files with 101634 additions and 126484 deletions

1
.gitignore vendored
View File

@ -92,3 +92,4 @@ TestUser51.cert
/nss-3.101-with-nspr-4.35.tar.gz
/nss-3.112-with-nspr-4.36.tar.gz
/nss_compat_test_pkcs12.tar
/nss-3.124-with-nspr-4.39.tar.gz

View File

@ -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 },

View File

@ -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) {

View File

@ -1,17 +0,0 @@
--- ./lib/softoken/pkcs11c.c.unused 2024-08-05 17:56:10.705414972 +0200
+++ ./lib/softoken/pkcs11c.c 2024-08-05 18:09:04.681015706 +0200
@@ -165,10 +165,14 @@ SFTKCipherWrap(AESKeyWrapContext, AESKey
mmm##_DestroyContext(ctx, freeit); \
}
+#ifndef NSS_DISABLE_DEPRECATED_RC2
SFTKCipherWrap2(RC2Context, RC2);
+#endif
SFTKCipherWrap2(RC4Context, RC4);
SFTKCipherWrap2(DESContext, DES);
+#ifndef NSS_DISABLE_DEPRECATED_SEED
SFTKCipherWrap2(SEEDContext, SEED);
+#endif
SFTKCipherWrap2(CamelliaContext, Camellia);
SFTKCipherWrap2(AESContext, AES);
SFTKCipherWrap2(AESKeyWrapContext, AESKeyWrap);

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

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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=&params->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
*
*/

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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 = &params;
+ 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,
&paramSet);
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.

File diff suppressed because it is too large Load Diff

642
nss-3.118-ml-dsa-tls.patch Normal file
View 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

View 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);

View 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

View File

@ -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;

View 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(

104
nss-3.124-enable-crmf.patch Normal file
View File

@ -0,0 +1,104 @@
# HG changeset patch
# User Robert Relyea <rrelyea@redhat.com>
# Date 1780437848 25200
# Tue Jun 02 15:04:08 2026 -0700
# Branch NSS_3_124_BRANCH
# Node ID b32abfeba0dab71016b45b33d32b8bea717da75f
# Parent 19e655733f3af71e3d517ada0d31ad0697d40f3f
nss-3.124-enable-crmf.patch
diff --git a/cmd/manifest.mn b/cmd/manifest.mn
--- a/cmd/manifest.mn
+++ b/cmd/manifest.mn
@@ -4,16 +4,22 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = ..
# MODULE = seccmd
SOFTOKEN_SRCDIRS=
NSS_SRCDIRS=
LIB_SRCDIRS=
+CRMF_SRCDIR=
+
+ifdef NSS_ENABLE_CRMF
+CRMF_SRCDIR=crmftest
+endif
+
ifdef NSS_BUILD_UTIL_ONLY
REQUIRES = nspr
else
REQUIRES = nss nspr libdbm
LIB_SRCDIRS = \
lib \
$(NULL)
@@ -35,16 +41,17 @@ ifndef NSS_BUILD_SOFTOKEN_ONLY
ifndef NSS_BUILD_UTIL_ONLY
NSS_SRCDIRS = \
addbuiltin \
atob \
btoa \
certutil \
chktest \
crlutil \
+ $(CRMF_SRCDIR) \
dbtest \
derdump \
digest \
httpserv \
listsuites \
makepqg \
multinit \
nss-policy-check \
diff --git a/lib/Makefile b/lib/Makefile
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -51,16 +51,20 @@ endif # MOZILLA_CLIENT
ifndef NSS_DISABLE_DBM
DBM_SRCDIR = dbm
endif
ifndef NSS_DISABLE_LIBPKIX
LIBPKIX_SRCDIR = libpkix
endif
+ifdef NSS_ENABLE_CRMF
+CRMF_SRCDIR=crmf
+endif
+
ifeq ($(NSS_BUILD_UTIL_ONLY),1)
UTIL_SRCDIR = util
else
ifeq ($(NSS_BUILD_SOFTOKEN_ONLY),1)
FREEBL_SRCDIR = freebl
SOFTOKEN_SRCDIR = softoken
else
@@ -83,24 +87,24 @@ else
endif
ifneq (,$(SOFTOKEN_SRCDIR))
$(SOFTOKEN_SRCDIR): $(DBM_SRCDIR) $(FREEBL_SRCDIR) $(SQLITE_SRCDIR) $(UTIL_SRCDIR)
endif
ifndef NSS_BUILD_SOFTOKEN_ONLY
NSS_SRCDIRS = \
- base certdb certhigh ckfw cryptohi dev jar $(LIBPKIX_SRCDIR) \
+ base certdb certhigh ckfw $(CRMF_SRCDIR) cryptohi dev jar $(LIBPKIX_SRCDIR) \
nss pk11wrap pkcs12 pkcs7 pki smime ssl $(SYSINIT_SRCDIR) $(ZLIB_SRCDIR)
ifneq (,$(SYSINIT_SRCDIR))
$(SYSINIT_SRCDIR): $(UTIL_SRCDIR)
endif
- nss: base certdb certhigh cryptohi dev $(LIBPKIX_SRCDIR) pk11wrap pki $(UTIL_SRCDIR)
+ nss: base certdb certhigh cryptohi $(CRMF_SRCDIR) dev $(LIBPKIX_SRCDIR) pk11wrap pki $(UTIL_SRCDIR)
smime: nss pkcs7 pkcs12
ssl: nss
ckfw: nss
endif # !NSS_BUILD_SOFTOKEN_ONLY
endif # !NSS_BUILD_UTIL_ONLY
DIRS = \

View 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 = &params;
+ 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)

View 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,
&paramSet);
if (crv != CKR_OK) {
crv = sftk_GetULongAttribute(object, CKA_NSS_PARAMETER_SET,
&paramSet);
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

View 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

View 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 = &paramSet;
+ 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, &paramSet, &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 ##############################

View 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

View 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

View 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;
}
}

View 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

View File

@ -1,375 +0,0 @@
# HG changeset patch
# User John M. Schanck <jschanck@mozilla.com>
# Date 1648094761 0
# Thu Mar 24 04:06:01 2022 +0000
# Node ID b722e523d66297fe4bc1fac0ebb06203138eccbb
# Parent 853b64626b19a46f41f4ba9c684490dc15923c94
Bug 1751305 - Remove expired explicitly distrusted certificates from certdata.txt. r=KathleenWilson
Differential Revision: https://phabricator.services.mozilla.com/D141919
diff --git a/lib/ckfw/builtins/certdata.txt b/lib/ckfw/builtins/certdata.txt
--- a/lib/ckfw/builtins/certdata.txt
+++ b/lib/ckfw/builtins/certdata.txt
@@ -7663,197 +7663,16 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
\377\377
END
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
-# Certificate "Explicitly Distrusted DigiNotar PKIoverheid G2"
-#
-# Issuer: CN=DigiNotar PKIoverheid CA Organisatie - G2,O=DigiNotar B.V.,C=NL
-# Serial Number: 268435455 (0xfffffff)
-# Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2,O=DigiNotar B.V.,C=NL
-# Not Valid Before: Wed May 12 08:51:39 2010
-# Not Valid After : Mon Mar 23 09:50:05 2020
-# Fingerprint (MD5): 2E:61:A2:D1:78:CE:EE:BF:59:33:B0:23:14:0F:94:1C
-# Fingerprint (SHA1): D5:F2:57:A9:BF:2D:D0:3F:8B:46:57:F9:2B:C9:A4:C6:92:E1:42:42
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrusted DigiNotar PKIoverheid G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\027\060\025\006\003\125\004\012\014\016\104\151\147\151\116\157
-\164\141\162\040\102\056\126\056\061\062\060\060\006\003\125\004
-\003\014\051\104\151\147\151\116\157\164\141\162\040\120\113\111
-\157\166\145\162\150\145\151\144\040\103\101\040\117\162\147\141
-\156\151\163\141\164\151\145\040\055\040\107\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\027\060\025\006\003\125\004\012\014\016\104\151\147\151\116\157
-\164\141\162\040\102\056\126\056\061\062\060\060\006\003\125\004
-\003\014\051\104\151\147\151\116\157\164\141\162\040\120\113\111
-\157\166\145\162\150\145\151\144\040\103\101\040\117\162\147\141
-\156\151\163\141\164\151\145\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\017\377\377\377
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\006\225\060\202\004\175\240\003\002\001\002\002\004\017
-\377\377\377\060\015\006\011\052\206\110\206\367\015\001\001\013
-\005\000\060\132\061\013\060\011\006\003\125\004\006\023\002\116
-\114\061\027\060\025\006\003\125\004\012\014\016\104\151\147\151
-\116\157\164\141\162\040\102\056\126\056\061\062\060\060\006\003
-\125\004\003\014\051\104\151\147\151\116\157\164\141\162\040\120
-\113\111\157\166\145\162\150\145\151\144\040\103\101\040\117\162
-\147\141\156\151\163\141\164\151\145\040\055\040\107\062\060\036
-\027\015\061\060\060\065\061\062\060\070\065\061\063\071\132\027
-\015\062\060\060\063\062\063\060\071\065\060\060\065\132\060\132
-\061\013\060\011\006\003\125\004\006\023\002\116\114\061\027\060
-\025\006\003\125\004\012\014\016\104\151\147\151\116\157\164\141
-\162\040\102\056\126\056\061\062\060\060\006\003\125\004\003\014
-\051\104\151\147\151\116\157\164\141\162\040\120\113\111\157\166
-\145\162\150\145\151\144\040\103\101\040\117\162\147\141\156\151
-\163\141\164\151\145\040\055\040\107\062\060\202\002\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002
-\017\000\060\202\002\012\002\202\002\001\000\261\023\031\017\047
-\346\154\324\125\206\113\320\354\211\212\105\221\170\254\107\275
-\107\053\344\374\105\353\117\264\046\163\133\067\323\303\177\366
-\343\336\327\243\370\055\150\305\010\076\113\224\326\344\207\045
-\066\153\204\265\030\164\363\050\130\163\057\233\152\317\274\004
-\036\366\336\335\257\374\113\252\365\333\146\142\045\001\045\202
-\336\362\227\132\020\156\335\135\251\042\261\004\251\043\163\072
-\370\161\255\035\317\204\104\353\107\321\257\155\310\174\050\253
-\307\362\067\172\164\137\137\305\002\024\212\243\132\343\033\154
-\001\343\135\216\331\150\326\364\011\033\062\334\221\265\054\365
-\040\353\214\003\155\046\111\270\223\304\205\135\330\322\233\257
-\126\152\314\005\063\314\240\102\236\064\125\104\234\153\240\324
-\022\320\053\124\315\267\211\015\345\366\353\350\373\205\001\063
-\117\172\153\361\235\162\063\226\016\367\262\204\245\245\047\304
-\047\361\121\163\051\167\272\147\156\376\114\334\264\342\241\241
-\201\057\071\111\215\103\070\023\316\320\245\134\302\207\072\000
-\147\145\102\043\361\066\131\012\035\243\121\310\274\243\224\052
-\061\337\343\074\362\235\032\074\004\260\357\261\012\060\023\163
-\266\327\363\243\114\001\165\024\205\170\300\327\212\071\130\205
-\120\372\056\346\305\276\317\213\077\257\217\066\324\045\011\055
-\322\017\254\162\223\362\277\213\324\120\263\371\025\120\233\231
-\365\024\331\373\213\221\243\062\046\046\240\370\337\073\140\201
-\206\203\171\133\053\353\023\075\051\072\301\155\335\275\236\216
-\207\326\112\256\064\227\005\356\024\246\366\334\070\176\112\351
-\044\124\007\075\227\150\067\106\153\015\307\250\041\257\023\124
-\344\011\152\361\115\106\012\311\135\373\233\117\275\336\373\267
-\124\313\270\070\234\247\071\373\152\055\300\173\215\253\245\247
-\127\354\112\222\212\063\305\341\040\134\163\330\220\222\053\200
-\325\017\206\030\151\174\071\117\204\206\274\367\114\133\363\325
-\264\312\240\302\360\067\042\312\171\122\037\123\346\252\363\220
-\260\073\335\362\050\375\254\353\305\006\044\240\311\324\057\017
-\130\375\265\236\354\017\317\262\131\320\242\004\172\070\152\256
-\162\373\275\360\045\142\224\011\247\005\013\002\003\001\000\001
-\243\202\001\141\060\202\001\135\060\110\006\003\125\035\040\004
-\101\060\077\060\075\006\004\125\035\040\000\060\065\060\063\006
-\010\053\006\001\005\005\007\002\001\026\047\150\164\164\160\072
-\057\057\167\167\167\056\144\151\147\151\156\157\164\141\162\056
-\156\154\057\143\160\163\057\160\153\151\157\166\145\162\150\145
-\151\144\060\017\006\003\125\035\023\001\001\377\004\005\060\003
-\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004\003
-\002\001\006\060\201\205\006\003\125\035\043\004\176\060\174\200
-\024\071\020\213\111\222\134\333\141\022\040\315\111\235\032\216
-\332\234\147\100\271\241\136\244\134\060\132\061\013\060\011\006
-\003\125\004\006\023\002\116\114\061\036\060\034\006\003\125\004
-\012\014\025\123\164\141\141\164\040\144\145\162\040\116\145\144
-\145\162\154\141\156\144\145\156\061\053\060\051\006\003\125\004
-\003\014\042\123\164\141\141\164\040\144\145\162\040\116\145\144
-\145\162\154\141\156\144\145\156\040\122\157\157\164\040\103\101
-\040\055\040\107\062\202\004\000\230\226\364\060\111\006\003\125
-\035\037\004\102\060\100\060\076\240\074\240\072\206\070\150\164
-\164\160\072\057\057\143\162\154\056\160\153\151\157\166\145\162
-\150\145\151\144\056\156\154\057\104\157\155\117\162\147\141\156
-\151\163\141\164\151\145\114\141\164\145\163\164\103\122\114\055
-\107\062\056\143\162\154\060\035\006\003\125\035\016\004\026\004
-\024\274\135\224\073\331\253\173\003\045\163\141\302\333\055\356
-\374\253\217\145\241\060\015\006\011\052\206\110\206\367\015\001
-\001\013\005\000\003\202\002\001\000\217\374\055\114\267\331\055
-\325\037\275\357\313\364\267\150\027\165\235\116\325\367\335\234
-\361\052\046\355\237\242\266\034\003\325\123\263\354\010\317\064
-\342\343\303\364\265\026\057\310\303\276\327\323\163\253\000\066
-\371\032\112\176\326\143\351\136\106\272\245\266\216\025\267\243
-\052\330\103\035\357\135\310\037\201\205\263\213\367\377\074\364
-\331\364\106\010\077\234\274\035\240\331\250\114\315\045\122\116
-\012\261\040\367\037\351\103\331\124\106\201\023\232\300\136\164
-\154\052\230\062\352\374\167\273\015\245\242\061\230\042\176\174
-\174\347\332\244\255\354\267\056\032\031\161\370\110\120\332\103
-\217\054\204\335\301\100\047\343\265\360\025\116\226\324\370\134
-\343\206\051\106\053\327\073\007\353\070\177\310\206\127\227\323
-\357\052\063\304\027\120\325\144\151\153\053\153\105\136\135\057
-\027\312\132\116\317\303\327\071\074\365\073\237\106\271\233\347
-\016\111\227\235\326\325\343\033\017\352\217\001\116\232\023\224
-\131\012\002\007\110\113\032\140\253\177\117\355\013\330\125\015
-\150\157\125\234\151\145\025\102\354\300\334\335\154\254\303\026
-\316\013\035\126\233\244\304\304\322\056\340\017\342\104\047\053
-\120\151\244\334\142\350\212\041\051\102\154\314\000\072\226\166
-\233\357\100\300\244\136\167\204\062\154\046\052\071\146\256\135
-\343\271\271\262\054\150\037\036\232\220\003\071\360\252\263\244
-\314\111\213\030\064\351\067\311\173\051\307\204\174\157\104\025
-\057\354\141\131\004\311\105\313\242\326\122\242\174\177\051\222
-\326\112\305\213\102\250\324\376\352\330\307\207\043\030\344\235
-\172\175\163\100\122\230\240\256\156\343\005\077\005\017\340\245
-\306\155\115\355\203\067\210\234\307\363\334\102\232\152\266\327
-\041\111\066\167\362\357\030\117\305\160\331\236\351\336\267\053
-\213\364\274\176\050\337\015\100\311\205\134\256\235\305\061\377
-\320\134\016\265\250\176\360\351\057\272\257\210\256\345\265\321
-\130\245\257\234\161\247\051\001\220\203\151\067\202\005\272\374
-\011\301\010\156\214\170\073\303\063\002\200\077\104\205\010\035
-\337\125\126\010\255\054\205\055\135\261\003\341\256\252\164\305
-\244\363\116\272\067\230\173\202\271
-END
-
-# Trust for Certificate "Explicitly Distrusted DigiNotar PKIoverheid G2"
-# Issuer: CN=DigiNotar PKIoverheid CA Organisatie - G2,O=DigiNotar B.V.,C=NL
-# Serial Number: 268435455 (0xfffffff)
-# Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2,O=DigiNotar B.V.,C=NL
-# Not Valid Before: Wed May 12 08:51:39 2010
-# Not Valid After : Mon Mar 23 09:50:05 2020
-# Fingerprint (MD5): 2E:61:A2:D1:78:CE:EE:BF:59:33:B0:23:14:0F:94:1C
-# Fingerprint (SHA1): D5:F2:57:A9:BF:2D:D0:3F:8B:46:57:F9:2B:C9:A4:C6:92:E1:42:42
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrusted DigiNotar PKIoverheid G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\325\362\127\251\277\055\320\077\213\106\127\371\053\311\244\306
-\222\341\102\102
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\056\141\242\321\170\316\356\277\131\063\260\043\024\017\224\034
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\027\060\025\006\003\125\004\012\014\016\104\151\147\151\116\157
-\164\141\162\040\102\056\126\056\061\062\060\060\006\003\125\004
-\003\014\051\104\151\147\151\116\157\164\141\162\040\120\113\111
-\157\166\145\162\150\145\151\144\040\103\101\040\117\162\147\141
-\156\151\163\141\164\151\145\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\017\377\377\377
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
# Certificate "Security Communication RootCA2"
#
# Issuer: OU=Security Communication RootCA2,O="SECOM Trust Systems CO.,LTD.",C=JP
# Serial Number: 0 (0x0)
# Subject: OU=Security Communication RootCA2,O="SECOM Trust Systems CO.,LTD.",C=JP
# Not Valid Before: Fri May 29 05:00:39 2009
# Not Valid After : Tue May 29 05:00:39 2029
# Fingerprint (SHA-256): 51:3B:2C:EC:B8:10:D4:CD:E5:DD:85:39:1A:DF:C6:C2:DD:60:D8:7B:B7:36:D2:B5:21:48:4A:A4:7A:0E:BE:F6
@@ -8337,78 +8156,16 @@ END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\001\000
END
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-# Explicitly Distrust "MITM subCA 1 issued by Trustwave", Bug 724929
-# Issuer: E=ca@trustwave.com,CN="Trustwave Organization Issuing CA, Level 2",O="Trustwave Holdings, Inc.",L=Chicago,ST=Illinois,C=US
-# Serial Number: 1800000005 (0x6b49d205)
-# Not Before: Apr 7 15:37:15 2011 GMT
-# Not After : Apr 4 15:37:15 2021 GMT
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "MITM subCA 1 issued by Trustwave"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\253\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\021\060\017\006\003\125\004\010\023\010\111\154\154\151\156
-\157\151\163\061\020\060\016\006\003\125\004\007\023\007\103\150
-\151\143\141\147\157\061\041\060\037\006\003\125\004\012\023\030
-\124\162\165\163\164\167\141\166\145\040\110\157\154\144\151\156
-\147\163\054\040\111\156\143\056\061\063\060\061\006\003\125\004
-\003\023\052\124\162\165\163\164\167\141\166\145\040\117\162\147
-\141\156\151\172\141\164\151\157\156\040\111\163\163\165\151\156
-\147\040\103\101\054\040\114\145\166\145\154\040\062\061\037\060
-\035\006\011\052\206\110\206\367\015\001\011\001\026\020\143\141
-\100\164\162\165\163\164\167\141\166\145\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\153\111\322\005
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-# Explicitly Distrust "MITM subCA 2 issued by Trustwave", Bug 724929
-# Issuer: E=ca@trustwave.com,CN="Trustwave Organization Issuing CA, Level 2",O="Trustwave Holdings, Inc.",L=Chicago,ST=Illinois,C=US
-# Serial Number: 1800000006 (0x6b49d206)
-# Not Before: Apr 18 21:09:30 2011 GMT
-# Not After : Apr 15 21:09:30 2021 GMT
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "MITM subCA 2 issued by Trustwave"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\253\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\021\060\017\006\003\125\004\010\023\010\111\154\154\151\156
-\157\151\163\061\020\060\016\006\003\125\004\007\023\007\103\150
-\151\143\141\147\157\061\041\060\037\006\003\125\004\012\023\030
-\124\162\165\163\164\167\141\166\145\040\110\157\154\144\151\156
-\147\163\054\040\111\156\143\056\061\063\060\061\006\003\125\004
-\003\023\052\124\162\165\163\164\167\141\166\145\040\117\162\147
-\141\156\151\172\141\164\151\157\156\040\111\163\163\165\151\156
-\147\040\103\101\054\040\114\145\166\145\154\040\062\061\037\060
-\035\006\011\052\206\110\206\367\015\001\011\001\026\020\143\141
-\100\164\162\165\163\164\167\141\166\145\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\153\111\322\006
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
#
# Certificate "Actalis Authentication Root CA"
#
# Issuer: CN=Actalis Authentication Root CA,O=Actalis S.p.A./03358520967,L=Milan,C=IT
# Serial Number:57:0a:11:97:42:c4:e3:cc
# Subject: CN=Actalis Authentication Root CA,O=Actalis S.p.A./03358520967,L=Milan,C=IT
# Not Valid Before: Thu Sep 22 11:22:02 2011
# Not Valid After : Sun Sep 22 11:22:02 2030
@@ -9042,84 +8799,16 @@ END
CKA_SERIAL_NUMBER MULTILINE_OCTAL
\002\001\001
END
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-# Explicitly Distrust "TURKTRUST Mis-issued Intermediate CA 1", Bug 825022
-# Issuer: O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A...,C=TR,CN=T..RKTRUST Elektronik Sunucu Sertifikas.. Hizmetleri
-# Serial Number: 2087 (0x827)
-# Subject: CN=*.EGO.GOV.TR,OU=EGO BILGI ISLEM,O=EGO,L=ANKARA,ST=ANKARA,C=TR
-# Not Valid Before: Mon Aug 08 07:07:51 2011
-# Not Valid After : Tue Jul 06 07:07:51 2021
-# Fingerprint (MD5): F8:F5:25:FF:0C:31:CF:85:E1:0C:86:17:C1:CE:1F:8E
-# Fingerprint (SHA1): C6:9F:28:C8:25:13:9E:65:A6:46:C4:34:AC:A5:A1:D2:00:29:5D:B1
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TURKTRUST Mis-issued Intermediate CA 1"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\254\061\075\060\073\006\003\125\004\003\014\064\124\303
-\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157
-\156\151\153\040\123\165\156\165\143\165\040\123\145\162\164\151
-\146\151\153\141\163\304\261\040\110\151\172\155\145\164\154\145
-\162\151\061\013\060\011\006\003\125\004\006\023\002\124\122\061
-\136\060\134\006\003\125\004\012\014\125\124\303\234\122\113\124
-\122\125\123\124\040\102\151\154\147\151\040\304\260\154\145\164
-\151\305\237\151\155\040\166\145\040\102\151\154\151\305\237\151
-\155\040\107\303\274\166\145\156\154\151\304\237\151\040\110\151
-\172\155\145\164\154\145\162\151\040\101\056\305\236\056\040\050
-\143\051\040\113\141\163\304\261\155\040\040\062\060\060\065
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\010\047
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-# Explicitly Distrust "TURKTRUST Mis-issued Intermediate CA 2", Bug 825022
-# Issuer: O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A...,C=TR,CN=T..RKTRUST Elektronik Sunucu Sertifikas.. Hizmetleri
-# Serial Number: 2148 (0x864)
-# Subject: E=ileti@kktcmerkezbankasi.org,CN=e-islem.kktcmerkezbankasi.org,O=KKTC Merkez Bankasi,L=Lefkosa,ST=Lefkosa,C=TR
-# Not Valid Before: Mon Aug 08 07:07:51 2011
-# Not Valid After : Thu Aug 05 07:07:51 2021
-# Fingerprint (MD5): BF:C3:EC:AD:0F:42:4F:B4:B5:38:DB:35:BF:AD:84:A2
-# Fingerprint (SHA1): F9:2B:E5:26:6C:C0:5D:B2:DC:0D:C3:F2:DC:74:E0:2D:EF:D9:49:CB
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TURKTRUST Mis-issued Intermediate CA 2"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\254\061\075\060\073\006\003\125\004\003\014\064\124\303
-\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157
-\156\151\153\040\123\165\156\165\143\165\040\123\145\162\164\151
-\146\151\153\141\163\304\261\040\110\151\172\155\145\164\154\145
-\162\151\061\013\060\011\006\003\125\004\006\023\002\124\122\061
-\136\060\134\006\003\125\004\012\014\125\124\303\234\122\113\124
-\122\125\123\124\040\102\151\154\147\151\040\304\260\154\145\164
-\151\305\237\151\155\040\166\145\040\102\151\154\151\305\237\151
-\155\040\107\303\274\166\145\156\154\151\304\237\151\040\110\151
-\172\155\145\164\154\145\162\151\040\101\056\305\236\056\040\050
-\143\051\040\113\141\163\304\261\155\040\040\062\060\060\065
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\010\144
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
#
# Certificate "D-TRUST Root Class 3 CA 2 2009"
#
# Issuer: CN=D-TRUST Root Class 3 CA 2 2009,O=D-Trust GmbH,C=DE
# Serial Number: 623603 (0x983f3)
# Subject: CN=D-TRUST Root Class 3 CA 2 2009,O=D-Trust GmbH,C=DE
# Not Valid Before: Thu Nov 05 08:35:58 2009
# Not Valid After : Mon Nov 05 08:35:58 2029

View File

@ -1,36 +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
#######################################################################

View File

@ -1,12 +1,13 @@
%global nss_version 3.112.0
%global nspr_version 4.36.0
%global nss_version 3.124.0
%global nspr_version 4.39.0
# NOTE: To avoid NVR clashes of nspr* packages:
# - reset %%{nspr_release} to 1, when updating %%{nspr_version}
# - increment %%{nspr_version}, when updating the NSS part only
%global baserelease 8
%global baserelease 1
%global nss_release %baserelease
# use "%%global nspr_release %%[%%baserelease+n]" to handle offsets when
# release number between nss and nspr are different.
# release number between nss and nspr are different. This typically
# happens with a new version of nss was release, but nspr was not updated
#%%global nspr_release %%[%%baserelease+21]
%global nspr_release %baserelease
# only need to update this as we added new
@ -130,7 +131,8 @@ Source27: secmod.db.xml
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
Source30: prwin.h
Source90: fips_algorithms.h
Source101: nspr-config.xml
@ -154,40 +156,43 @@ Patch31: nss-dso-ldflags.patch
Patch32: nss-3.112-disable-md5.patch
# rhel10 disabled dbm by default
Patch33: nss-no-dbm-man-page.patch
# not upstreamable patch...
Patch34: nss-3.71-fix-lto-gtests.patch
# disable ech
Patch36: nss-3.112-disable-ech.patch
Patch35: nss-3.124-disable-ech.patch
# don't fail if our build machine can't access the internet
Patch36: nss-3.101-skip-ocsp-if-not-connected.patch
# build crmf for now
Patch37: nss-3.124-enable-crmf.patch
# patches that expect to be upstreamed
Patch42: nss-3.103-unused-cipherwrap2.patch
# https://bugzilla.mozilla.org/show_bug.cgi?id=1767883
Patch50: nss-3.112-fips.patch
Patch53: nss-3.101-skip-ocsp-if-not-connected.patch
Patch74: nss-3.90-dh-test-update.patch
Patch75: nss-3.90-ppc_no_init.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
Patch78: nss-3.101-fix-cms-abi-break.patch
Patch79: nss-3.101-fix-shlibsign-fips.patch
Patch42: nss-3.101-fix-cms-abi-break.patch
Patch43: nss-3.124-tools-test-fix.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
# Post Quantum specific
Patch80: nss-3.112-disable-dsa.patch
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.patch
Patch84: nss-3.112-add-ml-dsa-gtests.patch
Patch85: nss-3.112-add-ml-dsa-ssl-support.patch
Patch86: nss-3.112-fips-and-fixes-el10.patch
Patch87: nss-3.112-big-endian-compression-fix.patch
Patch88: nss-3.112-fix-get-interface.patch
Patch89: nss-3.112-mlkem-fips-update.patch
Patch90: nss-3.112-update-fixes.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
# NSS reverse patches
Patch300: nss-3.79-distrusted-certs.patch
# no longer need this patch because all the builtins are
# handled by p11kit and ca-certifiates.
#Patch300: nss-3.79-distrusted-certs.patch
Patch100: nspr-config-pc.patch
Patch101: nspr-gcc-atomics.patch
@ -357,20 +362,16 @@ tar xvf %{SOURCE29}
pushd nss
%autopatch -p1 -M 99
# sigh it would be nice if autopatch supported -R
%patch -P 300 -R -p 1
#%%patch -P 400 -p 1 -b .cert_compression
popd
# 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/
# https://bugzilla.redhat.com/show_bug.cgi?id=1247353
find nss/lib/libpkix -perm /u+x -type f -exec chmod -x {} \;
%build
# Build, check, and install NSPR for building NSS in the later phase
#
@ -433,6 +434,7 @@ export NSS_DISABLE_DEPRECATED_SEED=1
export NSS_DISABLE_DSA=1
export NSS_DISABLE_KYBER=1
export NSS_ENABLE_ML_DSA=1
export NSS_ENABLE_CRMF=1
# FIPS related defines
export NSS_FORCE_FIPS=1
@ -635,6 +637,7 @@ export NSS_DISABLE_DEPRECATED_SEED=1
export NSS_DISABLE_DSA=1
export NSS_DISABLE_KYBER=1
export NSS_ENABLE_ML_DSA=1
export NSS_ENABLE_CRMF=1
%ifnarch noarch
%if 0%{__isa_bits} == 64
@ -733,6 +736,7 @@ rm -rf \
$RPM_BUILD_ROOT/%{_includedir}/nspr4/md
#cp win.h to old name for compatibility
cp %{SOURCE30} $RPM_BUILD_ROOT/%{_includedir}/nspr4/prwin.h
cp $RPM_BUILD_ROOT/%{_includedir}/nspr4/prwin.h \
$RPM_BUILD_ROOT/%{_includedir}/nspr4/prwin16.h
@ -1172,6 +1176,11 @@ fi
%changelog
* Tue Jun 2 2026 Bob Relyea <rrelyea@redhat.com> - 3.124.0-1
- rebase to upstream NSS 3.124
- backport ml-dsa support that is not upstream yet.
- pick up in process patches upstream including eddsa
* Fri Jan 23 2026 Bob Relyea <rrelyea@redhat.com> - 3.112.0-8
- fix incomplete ml-kem pct patch.

20
prwin.h Normal file
View File

@ -0,0 +1,20 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*/
/* 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/. */
/* This file is deprecated upstream. it's maintained here for source
* code compatibility do not expect it in future versions of RHEL */
#ifndef prwin_h___
#define prwin_h___
/*
** For platforms other than Win16, define
** PR_STDIO_INIT() as a No-Op.
*/
#define PR_STDIO_INIT()
#endif /* prwin_h___ */

View File

@ -1,4 +1,4 @@
SHA512 (blank-cert9.db) = 2f8eab4c0612210ee47db8a3a80c1b58a0b43849551af78c7da403fda3e3d4e7757838061ae56ccf5aac335cb54f254f0a9e6e9c0dd5920b4155a39264525b06
SHA512 (blank-key4.db) = 8fedae93af7163da23fe9492ea8e785a44c291604fa98e58438448efb69c85d3253fc22b926d5c3209c62e58a86038fd4d78a1c4c068bc00600a7f3e5382ebe7
SHA512 (nss_compat_test_pkcs12.tar) = 766af618ef02be5d54aff94651751ec68109a293c0b2782b0d7f6f2c844e41f4414eee5a9f46df2b1c22e0f24c4d85be00217cbcbc2632ac2f51bfa644abc2e6
SHA512 (nss-3.112-with-nspr-4.36.tar.gz) = a3da1f5cc5a05e7d3d7082312ef6000266ca3a33a9cc61c81d9d54743522d752e7634cd11ff6b6721bde7ee0c3ca92b93c964b34cb1d377462379de075fa3fe1
SHA512 (nss_compat_test_pkcs12.tar) = 58eef24a2f5f4df0e230fc775ba26d8bb43689597553460735593dd8655dac5e42e8dfea120c187f5af623910d80f34490ce426e22a42a7498a787d2cc9fadf5
SHA512 (nss-3.124-with-nspr-4.39.tar.gz) = a8af03f4f1ca1148e7ec847b8a5a2d6adcb7656c58243b1473bdd7ee0cbc23ad5d36c5bf62be24b7c9d6ce2b472de72013e58c246f5dca8645590093728759e9