summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/softoken
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:13:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:13:27 +0000
commit40a355a42d4a9444dc753c04c6608dade2f06a23 (patch)
tree871fc667d2de662f171103ce5ec067014ef85e61 /security/nss/lib/softoken
parentAdding upstream version 124.0.1. (diff)
downloadfirefox-adbda400be353e676059e335c3c0aaf99e719475.tar.xz
firefox-adbda400be353e676059e335c3c0aaf99e719475.zip
Adding upstream version 125.0.1.upstream/125.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'security/nss/lib/softoken')
-rw-r--r--security/nss/lib/softoken/lowkey.c19
-rw-r--r--security/nss/lib/softoken/lowpbe.c17
-rw-r--r--security/nss/lib/softoken/pkcs11.c21
-rw-r--r--security/nss/lib/softoken/pkcs11c.c167
-rw-r--r--security/nss/lib/softoken/softkver.h4
5 files changed, 186 insertions, 42 deletions
diff --git a/security/nss/lib/softoken/lowkey.c b/security/nss/lib/softoken/lowkey.c
index f47bda231d..5adae04263 100644
--- a/security/nss/lib/softoken/lowkey.c
+++ b/security/nss/lib/softoken/lowkey.c
@@ -9,6 +9,7 @@
#include "secasn1.h"
#include "secerr.h"
#include "softoken.h"
+#include "ec.h"
SEC_ASN1_MKSUB(SEC_AnyTemplate)
SEC_ASN1_MKSUB(SEC_BitStringTemplate)
@@ -381,6 +382,24 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
pubk->arena = arena;
pubk->keyType = privk->keyType;
+
+ /* if the public key value doesn't exist, calculate it */
+ if (privk->u.ec.publicValue.len == 0) {
+ /* Checking if it's an ed25519 key. */
+ SECOidTag privKeyOIDTag = SECOID_FindOIDTag(&privk->u.ec.ecParams.curveOID);
+ if (privKeyOIDTag == SEC_OID_ED25519_PUBLIC_KEY) {
+ PORT_Memset(&privk->u.ec.publicValue, 0, sizeof(privk->u.ec.publicValue));
+ if (SECITEM_AllocItem(privk->arena, &privk->u.ec.publicValue, Ed25519_PUBLIC_KEYLEN) == NULL) {
+ break;
+ }
+
+ rv = ED_DerivePublicKey(&privk->u.ec.privateValue, &privk->u.ec.publicValue);
+ if (rv != CKR_OK) {
+ break;
+ }
+ }
+ }
+
rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue,
&privk->u.ec.publicValue);
if (rv != SECSuccess)
diff --git a/security/nss/lib/softoken/lowpbe.c b/security/nss/lib/softoken/lowpbe.c
index ff80f573ff..68c19aaaf4 100644
--- a/security/nss/lib/softoken/lowpbe.c
+++ b/security/nss/lib/softoken/lowpbe.c
@@ -803,13 +803,7 @@ nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
goto loser;
}
- if (pbe_param->is2KeyDES) {
- PORT_Memcpy(key->data, hash->data, (key->len * 2) / 3);
- PORT_Memcpy(&(key->data[(key->len * 2) / 3]), key->data,
- key->len / 3);
- } else {
- PORT_Memcpy(key->data, hash->data, key->len);
- }
+ PORT_Memcpy(key->data, hash->data, key->len);
SECITEM_ZfreeItem(hash, PR_TRUE);
return key;
@@ -878,10 +872,15 @@ nsspkcs5_FillInParam(SECOidTag algorithm, HASH_HashType hashType,
/* DES3 Algorithms */
case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
pbe_param->is2KeyDES = PR_TRUE;
- /* fall through */
+ pbe_param->pbeType = NSSPKCS5_PKCS12_V2;
+ pbe_param->keyLen = 16;
+ pbe_param->encAlg = SEC_OID_DES_EDE3_CBC;
+ break;
case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
pbe_param->pbeType = NSSPKCS5_PKCS12_V2;
- /* fall through */
+ pbe_param->keyLen = 24;
+ pbe_param->encAlg = SEC_OID_DES_EDE3_CBC;
+ break;
case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
pbe_param->keyLen = 24;
pbe_param->encAlg = SEC_OID_DES_EDE3_CBC;
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index 9c0d93e317..768c7c2669 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -310,6 +310,7 @@ struct mechanismList {
#define CKF_EC_PNU CKF_EC_F_P | CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS
#define CKF_EC_BPNU CKF_EC_F_2M | CKF_EC_PNU
+#define CKF_EC_POC CKF_EC_F_P | CKF_EC_OID | CKF_EC_COMPRESS
#define CK_MAX 0xffffffff
@@ -379,6 +380,8 @@ static const struct mechanismList mechanisms[] = {
{ CKM_ECDSA_SHA256, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE },
{ CKM_ECDSA_SHA384, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE },
{ CKM_ECDSA_SHA512, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE },
+ { CKM_EC_EDWARDS_KEY_PAIR_GEN, { ECD_MIN_KEY_BITS, ECD_MAX_KEY_BITS, CKF_GENERATE_KEY_PAIR }, PR_TRUE },
+ { CKM_EDDSA, { ECD_MIN_KEY_BITS, ECD_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_POC }, PR_TRUE },
/* ------------------------- RC2 Operations --------------------------- */
{ CKM_RC2_KEY_GEN, { 1, 128, CKF_GENERATE }, PR_TRUE },
{ CKM_RC2_ECB, { 1, 128, CKF_EN_DE_WR_UN }, PR_TRUE },
@@ -1074,6 +1077,8 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
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;
@@ -1081,8 +1086,9 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
if (!sftk_hasAttribute(object, CKA_EC_POINT)) {
return CKR_TEMPLATE_INCOMPLETE;
}
- derive = CK_TRUE; /* for ECDH */
- verify = CK_TRUE; /* for ECDSA */
+ /* 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 = CK_TRUE; /* for ECDSA */
encrypt = CK_FALSE;
recover = CK_FALSE;
wrap = CK_FALSE;
@@ -1129,7 +1135,7 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
object->infoFree = (SFTKFree)nsslowkey_DestroyPublicKey;
/* Check that an imported EC key is valid */
- if (key_type == CKK_EC) {
+ if (key_type == CKK_EC || key_type == CKK_EC_EDWARDS || key_type == CKK_EC_MONTGOMERY) {
NSSLOWKEYPublicKey *pubKey = (NSSLOWKEYPublicKey *)object->objectInfo;
SECStatus rv = EC_ValidatePublicKey(&pubKey->u.ec.ecParams,
&pubKey->u.ec.publicValue);
@@ -1271,6 +1277,8 @@ sftk_handlePrivateKeyObject(SFTKSession *session, SFTKObject *object, CK_KEY_TYP
wrap = CK_FALSE;
break;
case CKK_EC:
+ case CKK_EC_EDWARDS:
+ case CKK_EC_MONTGOMERY:
if (!sftk_hasAttribute(object, CKA_EC_PARAMS)) {
return CKR_TEMPLATE_INCOMPLETE;
}
@@ -1926,6 +1934,8 @@ sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type,
crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dh.publicValue,
object, CKA_VALUE);
break;
+ case CKK_EC_EDWARDS:
+ case CKK_EC_MONTGOMERY:
case CKK_EC:
pubKey->keyType = NSSLOWKEYECKey;
crv = sftk_Attribute2SSecItem(arena,
@@ -2098,7 +2108,8 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
/* 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:
+ case CKK_EC_MONTGOMERY:
case CKK_EC:
privKey->keyType = NSSLOWKEYECKey;
crv = sftk_Attribute2SSecItem(arena,
@@ -2414,6 +2425,8 @@ sftk_PutPubKey(SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyTyp
sftk_item_expand(&pubKey->u.dh.publicValue));
break;
case CKK_EC:
+ case CKK_EC_MONTGOMERY:
+ case CKK_EC_EDWARDS:
sftk_DeleteAttributeType(publicKey, CKA_EC_PARAMS);
sftk_DeleteAttributeType(publicKey, CKA_EC_POINT);
crv = sftk_AddAttributeType(publicKey, CKA_EC_PARAMS,
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index 856c98e7cf..758a7eba45 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -2668,13 +2668,9 @@ static SECStatus
nsc_DSA_Verify_Stub(void *ctx, void *sigBuf, unsigned int sigLen,
void *dataBuf, unsigned int dataLen)
{
- SECItem signature, digest;
+ SECItem signature = { siBuffer, (unsigned char *)sigBuf, sigLen };
+ SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen };
NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;
-
- signature.data = (unsigned char *)sigBuf;
- signature.len = sigLen;
- digest.data = (unsigned char *)dataBuf;
- digest.len = dataLen;
return DSA_VerifyDigest(&(key->u.dsa), &signature, &digest);
}
@@ -2683,15 +2679,10 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
unsigned int *sigLen, unsigned int maxSigLen,
void *dataBuf, unsigned int dataLen)
{
- SECItem signature, digest;
- SECStatus rv;
NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
-
- signature.data = (unsigned char *)sigBuf;
- signature.len = maxSigLen;
- digest.data = (unsigned char *)dataBuf;
- digest.len = dataLen;
- rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest);
+ SECItem signature = { siBuffer, (unsigned char *)sigBuf, maxSigLen };
+ SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen };
+ SECStatus rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest);
if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
sftk_fatalError = PR_TRUE;
}
@@ -2703,13 +2694,9 @@ static SECStatus
nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen,
void *dataBuf, unsigned int dataLen)
{
- SECItem signature, digest;
+ SECItem signature = { siBuffer, (unsigned char *)sigBuf, sigLen };
+ SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen };
NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;
-
- signature.data = (unsigned char *)sigBuf;
- signature.len = sigLen;
- digest.data = (unsigned char *)dataBuf;
- digest.len = dataLen;
return ECDSA_VerifyDigest(&(key->u.ec), &signature, &digest);
}
@@ -2718,15 +2705,38 @@ nsc_ECDSASignStub(void *ctx, void *sigBuf,
unsigned int *sigLen, unsigned int maxSigLen,
void *dataBuf, unsigned int dataLen)
{
- SECItem signature, digest;
- SECStatus rv;
NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
+ SECItem signature = { siBuffer, (unsigned char *)sigBuf, maxSigLen };
+ SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen };
- signature.data = (unsigned char *)sigBuf;
- signature.len = maxSigLen;
- digest.data = (unsigned char *)dataBuf;
- digest.len = dataLen;
- rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest);
+ SECStatus rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest);
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
+ *sigLen = signature.len;
+ return rv;
+}
+
+static SECStatus
+nsc_EDDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen,
+ void *dataBuf, unsigned int dataLen)
+{
+ SECItem signature = { siBuffer, (unsigned char *)sigBuf, sigLen };
+ SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen };
+ NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;
+ return ED_VerifyMessage(&(key->u.ec), &signature, &digest);
+}
+
+static SECStatus
+nsc_EDDSASignStub(void *ctx, void *sigBuf,
+ unsigned int *sigLen, unsigned int maxSigLen,
+ void *dataBuf, unsigned int dataLen)
+{
+ NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
+ SECItem signature = { siBuffer, (unsigned char *)sigBuf, maxSigLen };
+ SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen };
+
+ SECStatus rv = ED_SignMessage(&(key->u.ec), &signature, &digest);
if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
sftk_fatalError = PR_TRUE;
}
@@ -2953,6 +2963,29 @@ NSC_SignInit(CK_SESSION_HANDLE hSession,
break;
+ case CKM_EDDSA:
+ if (key_type != CKK_EC_EDWARDS) {
+ crv = CKR_KEY_TYPE_INCONSISTENT;
+ break;
+ }
+
+ if (pMechanism->pParameter) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
+
+ privKey = sftk_GetPrivKey(key, CKK_EC_EDWARDS, &crv);
+ if (privKey == NULL) {
+ crv = CKR_HOST_MEMORY;
+ break;
+ }
+ context->cipherInfo = privKey;
+ context->update = (SFTKCipher)nsc_EDDSASignStub;
+ context->destroy = (privKey == key->objectInfo) ? (SFTKDestroy)sftk_Null : (SFTKDestroy)sftk_FreePrivKey;
+ context->maxLen = MAX_ECKEY_LEN * 2;
+
+ break;
+
#define INIT_HMAC_MECH(mmm) \
case CKM_##mmm##_HMAC_GENERAL: \
PORT_Assert(pMechanism->pParameter); \
@@ -3736,6 +3769,27 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession,
INIT_HMAC_MECH(SHA3_384)
INIT_HMAC_MECH(SHA3_512)
+ case CKM_EDDSA:
+ if (key_type != CKK_EC_EDWARDS) {
+ crv = CKR_KEY_TYPE_INCONSISTENT;
+ break;
+ }
+ pubKey = sftk_GetPubKey(key, CKK_EC_EDWARDS, &crv);
+ if (pubKey == NULL) {
+ crv = CKR_HOST_MEMORY;
+ break;
+ }
+
+ if (pMechanism->pParameter) {
+ crv = CKR_FUNCTION_NOT_SUPPORTED;
+ break;
+ }
+
+ context->cipherInfo = pubKey;
+ context->verify = (SFTKVerify)nsc_EDDSAVerifyStub;
+ context->destroy = sftk_Null;
+ break;
+
case CKM_SSL3_MD5_MAC:
PORT_Assert(pMechanism->pParameter);
if (!pMechanism->pParameter) {
@@ -5070,6 +5124,10 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession, SFTKSlot *slot,
signature_length = MAX_ECKEY_LEN * 2;
mech.mechanism = CKM_ECDSA;
break;
+ case CKK_EC_EDWARDS:
+ signature_length = ED25519_SIGN_LEN;
+ mech.mechanism = CKM_EDDSA;
+ break;
default:
return CKR_DEVICE_ERROR;
}
@@ -5749,6 +5807,61 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession,
SECITEM_FreeItem(&pubKey, PR_FALSE);
break;
+ case CKM_EC_EDWARDS_KEY_PAIR_GEN:
+ sftk_DeleteAttributeType(privateKey, CKA_EC_PARAMS);
+ sftk_DeleteAttributeType(privateKey, CKA_VALUE);
+ sftk_DeleteAttributeType(privateKey, CKA_NSS_DB);
+ key_type = CKK_EC_EDWARDS;
+
+ /* extract the necessary parameters and copy them to private keys */
+ crv = sftk_Attribute2SSecItem(NULL, &ecEncodedParams, publicKey,
+ CKA_EC_PARAMS);
+ if (crv != CKR_OK) {
+ break;
+ }
+
+ crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS,
+ sftk_item_expand(&ecEncodedParams));
+ if (crv != CKR_OK) {
+ SECITEM_ZfreeItem(&ecEncodedParams, PR_FALSE);
+ break;
+ }
+
+ /* Decode ec params before calling EC_NewKey */
+ rv = EC_DecodeParams(&ecEncodedParams, &ecParams);
+ SECITEM_ZfreeItem(&ecEncodedParams, PR_FALSE);
+ if (rv != SECSuccess) {
+ crv = sftk_MapCryptError(PORT_GetError());
+ break;
+ }
+
+ rv = EC_NewKey(ecParams, &ecPriv);
+ if (rv != SECSuccess) {
+ if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
+ PORT_FreeArena(ecParams->arena, PR_TRUE);
+ crv = sftk_MapCryptError(PORT_GetError());
+ break;
+ }
+ PORT_FreeArena(ecParams->arena, PR_TRUE);
+ crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
+ sftk_item_expand(&ecPriv->publicValue));
+ if (crv != CKR_OK)
+ goto edgn_done;
+
+ crv = sftk_AddAttributeType(privateKey, CKA_VALUE,
+ sftk_item_expand(&ecPriv->privateValue));
+ if (crv != CKR_OK)
+ goto edgn_done;
+
+ crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB,
+ sftk_item_expand(&ecPriv->publicValue));
+ edgn_done:
+ /* should zeroize, since this function doesn't. */
+ PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE);
+ break;
+
default:
crv = CKR_MECHANISM_INVALID;
}
diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h
index 1a203f56f2..ae4ebbe017 100644
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -17,9 +17,9 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
-#define SOFTOKEN_VERSION "3.98" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION "3.99" SOFTOKEN_ECC_STRING
#define SOFTOKEN_VMAJOR 3
-#define SOFTOKEN_VMINOR 98
+#define SOFTOKEN_VMINOR 99
#define SOFTOKEN_VPATCH 0
#define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_FALSE