diff options
Diffstat (limited to 'security/nss/lib/pk11wrap')
-rw-r--r-- | security/nss/lib/pk11wrap/pk11akey.c | 61 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11cert.c | 4 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11mech.c | 9 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11obj.c | 2 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11pars.c | 2 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11pk12.c | 80 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11skey.c | 5 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11slot.c | 3 |
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 */ |