Chromium Code Reviews| Index: nss/lib/softoken/pkcs11c.c |
| =================================================================== |
| --- nss/lib/softoken/pkcs11c.c (revision 228205) |
| +++ nss/lib/softoken/pkcs11c.c (working copy) |
| @@ -475,6 +475,95 @@ |
| maxLen, input, inputLen); |
| } |
| +static SFTKChaCha20Poly1305Info * |
| +sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key, unsigned int keyLen, |
|
agl
2013/10/23 14:24:28
(not about about local style, but this spills over
wtc
2013/10/23 20:04:20
Done.
|
| + 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 +959,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) { |
| + /* XXX map error code */ |
| + crv = CKR_HOST_MEMORY; |
| + 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 +3390,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 +3638,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 |