| Index: nss/lib/softoken/pkcs11c.c
|
| ===================================================================
|
| --- nss/lib/softoken/pkcs11c.c (revision 228205)
|
| +++ nss/lib/softoken/pkcs11c.c (working copy)
|
| @@ -475,6 +475,97 @@
|
| maxLen, input, inputLen);
|
| }
|
|
|
| +static SFTKChaCha20Poly1305Info *
|
| +sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key,
|
| + unsigned int keyLen,
|
| + const CK_NSS_AEAD_PARAMS* params)
|
| +{
|
| + SFTKChaCha20Poly1305Info *ctx;
|
| +
|
| + if (params->ulIvLen != sizeof(ctx->nonce)) {
|
| + PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| + return NULL;
|
| + }
|
| +
|
| + ctx = PORT_New(SFTKChaCha20Poly1305Info);
|
| + if (ctx == NULL) {
|
| + return NULL;
|
| + }
|
| +
|
| + if (ChaCha20Poly1305_InitContext(&ctx->freeblCtx, key, keyLen,
|
| + params->ulTagLen) != SECSuccess) {
|
| + PORT_Free(ctx);
|
| + return NULL;
|
| + }
|
| +
|
| + memcpy(ctx->nonce, params->pIv, sizeof(ctx->nonce));
|
| +
|
| + if (params->ulAADLen > sizeof(ctx->ad)) {
|
| + /* Need to allocate an overflow buffer for the additional data. */
|
| + ctx->adOverflow = (unsigned char *)PORT_Alloc(params->ulAADLen);
|
| + if (!ctx->adOverflow) {
|
| + PORT_Free(ctx);
|
| + return NULL;
|
| + }
|
| + memcpy(ctx->adOverflow, params->pAAD, params->ulAADLen);
|
| + } else {
|
| + ctx->adOverflow = NULL;
|
| + memcpy(ctx->ad, params->pAAD, params->ulAADLen);
|
| + }
|
| + ctx->adLen = params->ulAADLen;
|
| +
|
| + return ctx;
|
| +}
|
| +
|
| +static void
|
| +sftk_ChaCha20Poly1305_DestroyContext(SFTKChaCha20Poly1305Info *ctx,
|
| + PRBool freeit)
|
| +{
|
| + ChaCha20Poly1305_DestroyContext(&ctx->freeblCtx, PR_FALSE);
|
| + if (ctx->adOverflow != NULL) {
|
| + PORT_Free(ctx->adOverflow);
|
| + ctx->adOverflow = NULL;
|
| + }
|
| + ctx->adLen = 0;
|
| + if (freeit) {
|
| + PORT_Free(ctx);
|
| + }
|
| +}
|
| +
|
| +static SECStatus
|
| +sftk_ChaCha20Poly1305_Encrypt(const SFTKChaCha20Poly1305Info *ctx,
|
| + unsigned char *output, unsigned int *outputLen,
|
| + unsigned int maxOutputLen,
|
| + const unsigned char *input, unsigned int inputLen)
|
| +{
|
| + const unsigned char *ad = ctx->adOverflow;
|
| +
|
| + if (ad == NULL) {
|
| + ad = ctx->ad;
|
| + }
|
| +
|
| + return ChaCha20Poly1305_Seal(&ctx->freeblCtx, output, outputLen,
|
| + maxOutputLen, input, inputLen, ctx->nonce,
|
| + sizeof(ctx->nonce), ad, ctx->adLen);
|
| +}
|
| +
|
| +static SECStatus
|
| +sftk_ChaCha20Poly1305_Decrypt(const SFTKChaCha20Poly1305Info *ctx,
|
| + unsigned char *output, unsigned int *outputLen,
|
| + unsigned int maxOutputLen,
|
| + const unsigned char *input, unsigned int inputLen)
|
| +{
|
| + const unsigned char *ad = ctx->adOverflow;
|
| +
|
| + if (ad == NULL) {
|
| + ad = ctx->ad;
|
| + }
|
| +
|
| + return ChaCha20Poly1305_Open(&ctx->freeblCtx, output, outputLen,
|
| + maxOutputLen, input, inputLen, ctx->nonce,
|
| + sizeof(ctx->nonce), ad, ctx->adLen);
|
| +}
|
| +
|
| /** NSC_CryptInit initializes an encryption/Decryption operation.
|
| *
|
| * Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey.
|
| @@ -870,6 +961,35 @@
|
| context->destroy = (SFTKDestroy) AES_DestroyContext;
|
| break;
|
|
|
| + case CKM_NSS_CHACHA20_POLY1305:
|
| + if (pMechanism->ulParameterLen != sizeof(CK_NSS_AEAD_PARAMS)) {
|
| + crv = CKR_MECHANISM_PARAM_INVALID;
|
| + break;
|
| + }
|
| + context->multi = PR_FALSE;
|
| + if (key_type != CKK_NSS_CHACHA20) {
|
| + crv = CKR_KEY_TYPE_INCONSISTENT;
|
| + break;
|
| + }
|
| + att = sftk_FindAttribute(key,CKA_VALUE);
|
| + if (att == NULL) {
|
| + crv = CKR_KEY_HANDLE_INVALID;
|
| + break;
|
| + }
|
| + context->cipherInfo = sftk_ChaCha20Poly1305_CreateContext(
|
| + (unsigned char*) att->attrib.pValue, att->attrib.ulValueLen,
|
| + (CK_NSS_AEAD_PARAMS*) pMechanism->pParameter);
|
| + sftk_FreeAttribute(att);
|
| + if (context->cipherInfo == NULL) {
|
| + crv = sftk_MapCryptError(PORT_GetError());
|
| + break;
|
| + }
|
| + context->update = (SFTKCipher) (isEncrypt ?
|
| + sftk_ChaCha20Poly1305_Encrypt :
|
| + sftk_ChaCha20Poly1305_Decrypt);
|
| + context->destroy = (SFTKDestroy) sftk_ChaCha20Poly1305_DestroyContext;
|
| + break;
|
| +
|
| case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
|
| context->doPad = PR_TRUE;
|
| /* fall thru */
|
| @@ -3272,6 +3392,10 @@
|
| *key_type = CKK_AES;
|
| if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
|
| break;
|
| + case CKM_NSS_CHACHA20_KEY_GEN:
|
| + *key_type = CKK_NSS_CHACHA20;
|
| + if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
|
| + break;
|
| default:
|
| PORT_Assert(0);
|
| crv = CKR_MECHANISM_INVALID;
|
| @@ -3516,6 +3640,7 @@
|
| case CKM_SEED_KEY_GEN:
|
| case CKM_CAMELLIA_KEY_GEN:
|
| case CKM_AES_KEY_GEN:
|
| + case CKM_NSS_CHACHA20_KEY_GEN:
|
| #if NSS_SOFTOKEN_DOES_RC5
|
| case CKM_RC5_KEY_GEN:
|
| #endif
|
|
|