summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/pk11wrap
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/pk11wrap')
-rw-r--r--security/nss/lib/pk11wrap/pk11akey.c61
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c4
-rw-r--r--security/nss/lib/pk11wrap/pk11mech.c9
-rw-r--r--security/nss/lib/pk11wrap/pk11obj.c2
-rw-r--r--security/nss/lib/pk11wrap/pk11pars.c2
-rw-r--r--security/nss/lib/pk11wrap/pk11pk12.c80
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c5
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c3
8 files changed, 153 insertions, 13 deletions
diff --git a/security/nss/lib/pk11wrap/pk11akey.c b/security/nss/lib/pk11wrap/pk11akey.c
index 343a5bdef5..b797b54aef 100644
--- a/security/nss/lib/pk11wrap/pk11akey.c
+++ b/security/nss/lib/pk11wrap/pk11akey.c
@@ -41,6 +41,7 @@ pk11_MakeIDFromPublicKey(SECKEYPublicKey *pubKey)
case dhKey:
pubKeyIndex = &pubKey->u.dh.publicValue;
break;
+ case edKey:
case ecKey:
pubKeyIndex = &pubKey->u.ec.publicValue;
break;
@@ -190,6 +191,19 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
pubKey->u.dh.publicValue.len);
attrs++;
break;
+ case edKey:
+ keyType = CKK_EC_EDWARDS;
+ PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));
+ attrs++;
+ PK11_SETATTRS(attrs, CKA_EC_PARAMS,
+ pubKey->u.ec.DEREncodedParams.data,
+ pubKey->u.ec.DEREncodedParams.len);
+ attrs++;
+ PK11_SETATTRS(attrs, CKA_EC_POINT,
+ pubKey->u.ec.publicValue.data,
+ pubKey->u.ec.publicValue.len);
+ attrs++;
+ break;
case ecKey:
keyType = CKK_EC;
PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));
@@ -248,7 +262,7 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
}
templateCount = attrs - theTemplate;
PORT_Assert(templateCount <= (sizeof(theTemplate) / sizeof(CK_ATTRIBUTE)));
- if (pubKey->keyType != ecKey && pubKey->keyType != kyberKey) {
+ if (pubKey->keyType != ecKey && pubKey->keyType != kyberKey && pubKey->keyType != edKey) {
PORT_Assert(signedattr);
signedcount = attrs - signedattr;
for (attrs = signedattr; signedcount; attrs++, signedcount--) {
@@ -407,6 +421,7 @@ pk11_get_EC_PointLenInBytes(PLArenaPool *arena, const SECItem *ecParams,
case SEC_OID_SECG_EC_SECT571R1:
return 145; /*curve len in bytes = 72 bytes */
case SEC_OID_CURVE25519:
+ case SEC_OID_ED25519_PUBLIC_KEY:
*plain = PR_TRUE;
return 32; /* curve len in bytes = 32 bytes (only X) */
/* unknown or unrecognized OIDs. return unknown length */
@@ -642,6 +657,9 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType, CK_OBJECT_HANDLE id)
case CKK_EC:
keyType = ecKey;
break;
+ case CKK_EC_EDWARDS:
+ keyType = edKey;
+ break;
case CKK_NSS_KYBER:
keyType = kyberKey;
break;
@@ -771,6 +789,7 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType, CK_OBJECT_HANDLE id)
if (crv != CKR_OK)
break;
break;
+ case edKey:
case ecKey:
pubKey->u.ec.size = 0;
ecparams = attrs;
@@ -785,7 +804,7 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType, CK_OBJECT_HANDLE id)
if (crv != CKR_OK)
break;
- if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_EC)) {
+ if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_EC && pk11KeyType != CKK_EC_EDWARDS)) {
crv = CKR_OBJECT_HANDLE_INVALID;
break;
}
@@ -886,6 +905,9 @@ PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
case CKK_EC:
keyType = ecKey;
break;
+ case CKK_EC_EDWARDS:
+ keyType = edKey;
+ break;
case CKK_NSS_KYBER:
keyType = kyberKey;
break;
@@ -1093,6 +1115,7 @@ pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot, SECKEYPrivateKey *privKey,
extra_count++;
break;
case ecKey:
+ case edKey:
ap->type = CKA_EC_PARAMS;
ap++;
count++;
@@ -1101,10 +1124,13 @@ pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot, SECKEYPrivateKey *privKey,
ap++;
count++;
extra_count++;
- ap->type = CKA_DERIVE;
- ap++;
- count++;
- extra_count++;
+ if (privKey->keyType == ecKey) {
+ ap->type = CKA_DERIVE;
+ ap++;
+ count++;
+ extra_count++;
+ }
+
ap->type = CKA_SIGN;
ap++;
count++;
@@ -1143,7 +1169,7 @@ pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot, SECKEYPrivateKey *privKey,
* them the raw data as unsigned. The exception is EC,
* where the values are encoded or zero-preserving
* per-RFC5915 */
- if (privKey->keyType != ecKey) {
+ if (privKey->keyType != ecKey && privKey->keyType != edKey) {
for (ap = attrs; extra_count; ap++, extra_count--) {
pk11_SignedToUnsigned(ap);
}
@@ -1499,6 +1525,16 @@ PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
keyType = kyberKey;
test_mech.mechanism = CKM_NSS_KYBER;
break;
+ case CKM_EC_EDWARDS_KEY_PAIR_GEN:
+ ecParams = (SECKEYECParams *)param;
+ attrs = ecPubTemplate;
+ PK11_SETATTRS(attrs, CKA_EC_PARAMS, ecParams->data,
+ ecParams->len);
+ attrs++;
+ pubTemplate = ecPubTemplate;
+ keyType = edKey;
+ test_mech.mechanism = CKM_EDDSA;
+ break;
default:
PORT_SetError(SEC_ERROR_BAD_KEY);
return NULL;
@@ -1555,6 +1591,10 @@ PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
case CKM_ECDSA:
mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
break;
+ case CKM_EDDSA:
+ mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
+ break;
+
default:
break;
}
@@ -1835,6 +1875,7 @@ SECKEY_SetPublicValue(SECKEYPrivateKey *privKey, SECItem *publicValue)
rv = PK11_ReadAttribute(slot, privKeyID, CKA_BASE,
arena, &pubKey.u.dh.base);
break;
+ case edKey:
case ecKey:
pubKey.u.ec.publicValue = *publicValue;
pubKey.u.ec.encoding = ECPoint_Undefined;
@@ -1905,6 +1946,7 @@ PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
CK_ATTRIBUTE_TYPE dsaUsage[] = { CKA_SIGN };
CK_ATTRIBUTE_TYPE dhUsage[] = { CKA_DERIVE };
CK_ATTRIBUTE_TYPE ecUsage[] = { CKA_SIGN, CKA_DERIVE };
+ CK_ATTRIBUTE_TYPE edUsage[] = { CKA_SIGN };
if ((epki == NULL) || (pwitem == NULL))
return SECFailure;
@@ -1959,6 +2001,11 @@ PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
break;
}
break;
+ case edKey:
+ key_type = CKK_EC_EDWARDS;
+ usage = edUsage;
+ usageCount = 1;
+ break;
}
try_faulty_3des:
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c
index 580d02b613..fb37b713ed 100644
--- a/security/nss/lib/pk11wrap/pk11cert.c
+++ b/security/nss/lib/pk11wrap/pk11cert.c
@@ -171,6 +171,7 @@ PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
pubKey->u.dh.publicValue.len);
break;
case ecKey:
+ case edKey:
PK11_SETATTRS(&theTemplate, CKA_EC_POINT,
pubKey->u.ec.publicValue.data,
pubKey->u.ec.publicValue.len);
@@ -187,7 +188,7 @@ PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
SECKEY_DestroyPublicKey(pubKey);
return PR_FALSE;
}
- if (pubKey->keyType != ecKey) {
+ if (pubKey->keyType != ecKey && pubKey->keyType != edKey) {
pk11_SignedToUnsigned(&theTemplate);
}
if (pk11_FindObjectByTemplate(slot, &theTemplate, 1) != CK_INVALID_HANDLE) {
@@ -1113,6 +1114,7 @@ PK11_GetPubIndexKeyID(CERTCertificate *cert)
newItem = SECITEM_DupItem(&pubk->u.dh.publicValue);
break;
case ecKey:
+ case edKey:
newItem = SECITEM_DupItem(&pubk->u.ec.publicValue);
break;
case fortezzaKey:
diff --git a/security/nss/lib/pk11wrap/pk11mech.c b/security/nss/lib/pk11wrap/pk11mech.c
index 54e55c6da2..df7e3455bc 100644
--- a/security/nss/lib/pk11wrap/pk11mech.c
+++ b/security/nss/lib/pk11wrap/pk11mech.c
@@ -198,6 +198,8 @@ PK11_GetKeyMechanism(CK_KEY_TYPE type)
return CKM_KEA_KEY_DERIVE;
case CKK_EC: /* CKK_ECDSA is deprecated */
return CKM_ECDSA;
+ case CKK_EC_EDWARDS:
+ return CKM_EDDSA;
case CKK_HKDF:
return CKM_HKDF_DERIVE;
case CKK_GENERIC_SECRET:
@@ -388,6 +390,9 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
case CKM_ECDH1_DERIVE:
return CKK_EC; /* CKK_ECDSA is deprecated */
+ case CKM_EC_EDWARDS_KEY_PAIR_GEN:
+ case CKM_EDDSA:
+ return CKK_EC_EDWARDS;
case CKM_HKDF_KEY_GEN:
case CKM_HKDF_DERIVE:
case CKM_HKDF_DATA:
@@ -603,6 +608,8 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
case CKM_ECDH1_DERIVE:
return CKM_EC_KEY_PAIR_GEN;
+ case CKM_EDDSA:
+ return CKM_EC_EDWARDS_KEY_PAIR_GEN;
case CKM_SSL3_PRE_MASTER_KEY_GEN:
case CKM_SSL3_MASTER_KEY_DERIVE:
case CKM_SSL3_KEY_AND_MAC_DERIVE:
@@ -1917,6 +1924,8 @@ PK11_MapSignKeyType(KeyType keyType)
return CKM_DSA;
case ecKey:
return CKM_ECDSA;
+ case edKey:
+ return CKM_EDDSA;
case dhKey:
default:
break;
diff --git a/security/nss/lib/pk11wrap/pk11obj.c b/security/nss/lib/pk11wrap/pk11obj.c
index 1661bcb2b4..5759408a27 100644
--- a/security/nss/lib/pk11wrap/pk11obj.c
+++ b/security/nss/lib/pk11wrap/pk11obj.c
@@ -575,7 +575,7 @@ PK11_SignatureLen(SECKEYPrivateKey *key)
return length * 2;
}
return pk11_backupGetSignLength(key);
-
+ case edKey:
case ecKey:
rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, CKA_EC_PARAMS,
NULL, &attributeItem);
diff --git a/security/nss/lib/pk11wrap/pk11pars.c b/security/nss/lib/pk11wrap/pk11pars.c
index bda4ab688a..45b4a5934a 100644
--- a/security/nss/lib/pk11wrap/pk11pars.c
+++ b/security/nss/lib/pk11wrap/pk11pars.c
@@ -402,6 +402,8 @@ static const oidValDef signOptList[] = {
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
{ CIPHER_NAME("ECDSA"), SEC_OID_ANSIX962_EC_PUBLIC_KEY,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
+ { CIPHER_NAME("ED25519"), SEC_OID_ED25519_PUBLIC_KEY,
+ NSS_USE_ALG_IN_SIGNATURE },
};
typedef struct {
diff --git a/security/nss/lib/pk11wrap/pk11pk12.c b/security/nss/lib/pk11wrap/pk11pk12.c
index 917b7f0f67..5d8b00d3d0 100644
--- a/security/nss/lib/pk11wrap/pk11pk12.c
+++ b/security/nss/lib/pk11wrap/pk11pk12.c
@@ -180,6 +180,13 @@ const SEC_ASN1Template SECKEY_ECPrivateKeyExportTemplate[] = {
{ 0 }
};
+/* The template operates a private key consisting only of private key. */
+const SEC_ASN1Template SECKEY_EDPrivateKeyExportTemplate[] = {
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(SECKEYRawPrivateKey, u.ec.privateValue) },
+ { 0 }
+};
+
const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) },
@@ -270,8 +277,10 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
SECStatus rv = SECFailure;
temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!temparena)
+ if (!temparena) {
return rv;
+ }
+
pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo);
if (!pki) {
PORT_FreeArena(temparena, PR_FALSE);
@@ -523,13 +532,31 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
lpk->u.ec.publicValue.len);
attrs++;
break;
+ case edKey:
+ keyType = CKK_EC_EDWARDS;
+ PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL));
+ attrs++;
+ if (nickname) {
+ PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
+ attrs++;
+ }
+
+ /* No signed attrs for EC */
+ /* curveOID always is a copy of AlgorithmID.parameters. */
+ PK11_SETATTRS(attrs, CKA_EC_PARAMS, lpk->u.ec.curveOID.data,
+ lpk->u.ec.curveOID.len);
+ attrs++;
+ PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.ec.privateValue.data,
+ lpk->u.ec.privateValue.len);
+ attrs++;
+ break;
default:
PORT_SetError(SEC_ERROR_BAD_KEY);
goto loser;
}
templateCount = attrs - theTemplate;
PORT_Assert(templateCount <= sizeof(theTemplate) / sizeof(CK_ATTRIBUTE));
- if (lpk->keyType != ecKey) {
+ if (lpk->keyType != ecKey && lpk->keyType != edKey) {
PORT_Assert(signedattr);
signedcount = attrs - signedattr;
for (ap = signedattr; signedcount; ap++, signedcount--) {
@@ -604,6 +631,12 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
paramDest = NULL;
lpk->keyType = dhKey;
break;
+ case SEC_OID_ED25519_PUBLIC_KEY:
+ keyTemplate = SECKEY_EDPrivateKeyExportTemplate;
+ paramTemplate = NULL;
+ paramDest = NULL;
+ lpk->keyType = edKey;
+ break;
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
prepare_ec_priv_key_export_for_asn1(lpk);
keyTemplate = SECKEY_ECPrivateKeyExportTemplate;
@@ -641,6 +674,26 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
}
}
+ if (lpk->keyType == edKey) {
+ /* Convert length in bits to length in bytes. */
+ lpk->u.ec.publicValue.len >>= 3;
+
+ if (pki->algorithm.parameters.len != 0) {
+ /* Currently supporting only (Pure)Ed25519 .*/
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
+ goto loser;
+ }
+
+ SECOidData *oidEd25519 = SECOID_FindOIDByTag(SEC_OID_ED25519_PUBLIC_KEY);
+
+ if (!SECITEM_AllocItem(arena, &lpk->u.ec.curveOID, oidEd25519->oid.len + 2)) {
+ goto loser;
+ }
+ lpk->u.ec.curveOID.data[0] = SEC_ASN1_OBJECT_ID;
+ lpk->u.ec.curveOID.data[1] = oidEd25519->oid.len;
+ PORT_Memcpy(lpk->u.ec.curveOID.data + 2, oidEd25519->oid.data, oidEd25519->oid.len);
+ }
+
if (paramDest && paramTemplate) {
rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate,
&(pki->algorithm.parameters));
@@ -651,7 +704,6 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
rv = PK11_ImportAndReturnPrivateKey(slot, lpk, nickname, publicValue, isPerm,
isPrivate, keyUsage, privk, wincx);
-
loser:
if (arena != NULL) {
PORT_FreeArena(arena, PR_TRUE);
@@ -800,6 +852,28 @@ PK11_ExportPrivKeyInfo(SECKEYPrivateKey *pk, void *wincx)
}
} break;
+ case edKey: {
+ rawKey.u.ec.version.type = siUnsignedInteger;
+ rawKey.u.ec.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
+ if (!rawKey.u.ec.version.data) {
+ goto loser;
+ }
+ rawKey.u.ec.version.data[0] = ecVersion;
+ rawKey.u.ec.version.len = 1;
+
+ if (!ReadAttribute(pk, CKA_VALUE, arena,
+ &rawKey.u.ec.privateValue)) {
+ goto loser;
+ }
+
+ keyTemplate = SECKEY_EDPrivateKeyExportTemplate;
+ /* Currently, ED25519 does not support any parameter. */
+ rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, SEC_OID_ED25519_PUBLIC_KEY, NULL);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ } break;
default: {
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
goto loser;
diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c
index f09519ee27..02db85b6bf 100644
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ b/security/nss/lib/pk11wrap/pk11skey.c
@@ -2097,7 +2097,7 @@ PK11_DerivePubKeyFromPrivKey(SECKEYPrivateKey *privKey)
/*
* This Generates a wrapping key based on a privateKey, publicKey, and two
* random numbers. For Mail usage RandomB should be NULL. In the Sender's
- * case RandomA is generate, outherwize it is passed.
+ * case RandomA is generate, otherwise it is passed.
*/
PK11SymKey *
PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
@@ -2218,6 +2218,9 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
return symKey;
PORT_SetError(PK11_MapError(crv));
} break;
+ case edKey:
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ break;
case ecKey: {
CK_BBOOL cktrue = CK_TRUE;
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index d61d0f750d..90a429d952 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -36,6 +36,7 @@ const PK11DefaultArrayEntry PK11_DefaultArray[] = {
{ "RSA", SECMOD_RSA_FLAG, CKM_RSA_PKCS },
{ "DSA", SECMOD_DSA_FLAG, CKM_DSA },
{ "ECC", SECMOD_ECC_FLAG, CKM_ECDSA },
+ { "EDDSA", SECMOD_ECC_FLAG, CKM_EDDSA },
{ "DH", SECMOD_DH_FLAG, CKM_DH_PKCS_DERIVE },
{ "RC2", SECMOD_RC2_FLAG, CKM_RC2_CBC },
{ "RC4", SECMOD_RC4_FLAG, CKM_RC4 },
@@ -940,6 +941,8 @@ PK11_GetSlotList(CK_MECHANISM_TYPE type)
case CKM_DH_PKCS_KEY_PAIR_GEN:
case CKM_DH_PKCS_DERIVE:
return &pk11_dhSlotList;
+ case CKM_EDDSA:
+ case CKM_EC_EDWARDS_KEY_PAIR_GEN:
case CKM_ECDSA:
case CKM_ECDSA_SHA1:
case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */