| Index: nss/lib/softoken/pkcs11c.c
|
| ===================================================================
|
| --- nss/lib/softoken/pkcs11c.c (revision 228205)
|
| +++ nss/lib/softoken/pkcs11c.c (working copy)
|
| @@ -475,6 +475,107 @@
|
| maxLen, input, inputLen);
|
| }
|
|
|
| +static SFTKChaCha20Poly1305Info *
|
| +sftk_ChaCha20Poly1305_New(const unsigned char *key,
|
| + const CK_NSS_AEAD_PARAMS* params)
|
| +{
|
| + SFTKChaCha20Poly1305Info *ctx;
|
| +
|
| + if (params->ulIvLen != sizeof(ctx->nonce)) {
|
| + PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| + return NULL;
|
| + }
|
| +
|
| + if (params->ulTagBits == 0 ||
|
| + params->ulTagBits > 128 ||
|
| + (params->ulTagBits & 7) != 0) {
|
| + PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| + return NULL;
|
| + }
|
| +
|
| + ctx = PORT_New(SFTKChaCha20Poly1305Info);
|
| + if (ctx == NULL) {
|
| + return NULL;
|
| + }
|
| +
|
| + memcpy(ctx->key, key, sizeof(ctx->key));
|
| + memcpy(ctx->nonce, params->pIv, sizeof(ctx->nonce));
|
| + ctx->tagLen = params->ulTagBits >> 3;
|
| +
|
| + 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_Free(SFTKChaCha20Poly1305Info *ctx)
|
| +{
|
| + if (ctx->adOverflow != NULL) {
|
| + PORT_Free(ctx->adOverflow);
|
| + }
|
| + PORT_Free(ctx);
|
| +}
|
| +
|
| +static SECStatus
|
| +sftk_ChaCha20Poly1305_Seal(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;
|
| +
|
| + *outputLen = inputLen + ctx->tagLen;
|
| + if (maxOutputLen < *outputLen) {
|
| + PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
| + return SECFailure;
|
| + }
|
| +
|
| + if (ad == NULL) {
|
| + ad = ctx->ad;
|
| + }
|
| +
|
| + return ChaCha20Poly1305_Seal(output, ad, ctx->adLen, input, inputLen,
|
| + ctx->tagLen, ctx->key, ctx->nonce);
|
| +}
|
| +
|
| +static SECStatus
|
| +sftk_ChaCha20Poly1305_Open(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 (inputLen < ctx->tagLen) {
|
| + PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| + return SECFailure;
|
| + }
|
| + *outputLen = inputLen - ctx->tagLen;
|
| + if (maxOutputLen < *outputLen) {
|
| + PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
| + return SECFailure;
|
| + }
|
| +
|
| + if (ad == NULL) {
|
| + ad = ctx->ad;
|
| + }
|
| +
|
| + return ChaCha20Poly1305_Open(output, ad, ctx->adLen, input, inputLen,
|
| + ctx->tagLen, ctx->key, ctx->nonce);
|
| +}
|
| +
|
| /** NSC_CryptInit initializes an encryption/Decryption operation.
|
| *
|
| * Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey.
|
| @@ -870,6 +971,30 @@
|
| context->destroy = (SFTKDestroy) AES_DestroyContext;
|
| break;
|
|
|
| + case CKM_NSS_CHACHA20_POLY1305:
|
| + 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_New(
|
| + (unsigned char*) att->attrib.pValue,
|
| + (CK_NSS_AEAD_PARAMS*) pMechanism->pParameter);
|
| + sftk_FreeAttribute(att);
|
| + if (context->cipherInfo == NULL) {
|
| + crv = CKR_HOST_MEMORY;
|
| + break;
|
| + }
|
| + context->update = (SFTKCipher) (isEncrypt ? sftk_ChaCha20Poly1305_Seal :
|
| + sftk_ChaCha20Poly1305_Open);
|
| + context->destroy = (SFTKDestroy) sftk_ChaCha20Poly1305_Free;
|
| + break;
|
| +
|
| case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
|
| context->doPad = PR_TRUE;
|
| /* fall thru */
|
| @@ -3272,6 +3397,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 +3645,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
|
|
|