diff options
Diffstat (limited to 'security/nss/lib/softoken/pkcs11c.c')
-rw-r--r-- | security/nss/lib/softoken/pkcs11c.c | 167 |
1 files changed, 140 insertions, 27 deletions
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; } |