diff options
Diffstat (limited to '')
-rw-r--r-- | security/nss/lib/softoken/lowkey.c | 19 | ||||
-rw-r--r-- | security/nss/lib/softoken/lowpbe.c | 17 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11.c | 21 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11c.c | 167 | ||||
-rw-r--r-- | security/nss/lib/softoken/softkver.h | 4 |
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 |