Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(121)

Unified Diff: nss/lib/softoken/pkcs11c.c

Issue 27510015: Support ChaCha20+Poly1305 cipher suites. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Fix compilation error, fix typos in function arguments Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: nss/lib/softoken/pkcs11c.c
===================================================================
--- nss/lib/softoken/pkcs11c.c (revision 228205)
+++ nss/lib/softoken/pkcs11c.c (working copy)
@@ -475,6 +475,110 @@
maxLen, input, inputLen);
}
+/* sftk_ChaCha20Poly1305_Context saves the key and additional data for a
+ * ChaCha20+Poly1305 AEAD operation. */
+struct sftk_ChaCha20Poly1305_Context {
+ unsigned char key[32];
+ unsigned char nonce[8];
+ unsigned char ad[16];
+ unsigned char *adOverflow;
+ unsigned int adLen;
+ unsigned char tagLen;
+};
+
+static struct sftk_ChaCha20Poly1305_Context* sftk_ChaCha20Poly1305_New(
+ const unsigned char *key,
+ const CK_AEAD_PARAMS* params) {
+ struct sftk_ChaCha20Poly1305_Context* ctx;
+
+ if (params->ulIvLen != sizeof(ctx->nonce))
+ return NULL;
+
+ if (params->ulTagBits == 0 ||
+ params->ulTagBits > 128 ||
+ (params->ulTagBits & 3) != 0) {
+ return NULL;
+ }
+
+ ctx = PORT_Alloc(sizeof(struct sftk_ChaCha20Poly1305_Context));
+ if (ctx == NULL)
+ return NULL;
+
+ memcpy(ctx->nonce, params->pIv, sizeof(ctx->nonce));
+ memcpy(ctx->key, key, sizeof(ctx->key));
+ ctx->tagLen = params->ulTagBits >> 3;
+
+ if (params->ulAADLen > sizeof(ctx->ad)) {
+ /* Need to allocate an overflow buffer for the additional data. */
+ ctx->adOverflow = 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(
+ struct sftk_ChaCha20Poly1305_Context *ctx) {
+ if (ctx->adOverflow != NULL) {
+ PORT_Free(ctx->adOverflow);
+ }
+ PORT_Free(ctx);
+}
+
+static SECStatus sftk_ChaCha20Poly1305_Seal(
+ const struct sftk_ChaCha20Poly1305_Context *ctx,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen) {
+ const unsigned char* ad = ctx->adOverflow;
+
+ if (maxOutputLen < inputLen + 16) {
+ return SECFailure;
+ }
+
+ if (ad == NULL) {
+ ad = ctx->ad;
+ }
+
+ *outputLen = inputLen + 16;
+
+ return ChaCha20Poly1305_Seal(output, ad, ctx->adLen, input, inputLen,
+ ctx->tagLen, ctx->key, ctx->nonce);
+}
+
+static SECStatus sftk_ChaCha20Poly1305_Open(
+ const struct sftk_ChaCha20Poly1305_Context *ctx,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen) {
+ const unsigned char* ad = ctx->adOverflow;
+
+ if (maxOutputLen < inputLen || inputLen < 16) {
+ return SECFailure;
+ }
+
+ if (ad == NULL) {
+ ad = ctx->ad;
+ }
+
+ *outputLen = inputLen - 16;
+
+ 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 +974,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_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 +3400,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 +3648,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

Powered by Google App Engine
This is Rietveld 408576698