| Index: patches/nss-chacha20-poly1305.patch
|
| ===================================================================
|
| --- patches/nss-chacha20-poly1305.patch (revision 239365)
|
| +++ patches/nss-chacha20-poly1305.patch (working copy)
|
| @@ -1,279 +1,682 @@
|
| -Index: nss/lib/softoken/pkcs11.c
|
| -===================================================================
|
| ---- nss/lib/softoken/pkcs11.c (revision 228205)
|
| -+++ nss/lib/softoken/pkcs11.c (working copy)
|
| -@@ -368,6 +368,9 @@
|
| - {CKM_SEED_MAC, {16, 16, CKF_SN_VR}, PR_TRUE},
|
| - {CKM_SEED_MAC_GENERAL, {16, 16, CKF_SN_VR}, PR_TRUE},
|
| - {CKM_SEED_CBC_PAD, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
|
| -+ /* ------------------------- ChaCha20 Operations ---------------------- */
|
| -+ {CKM_NSS_CHACHA20_KEY_GEN, {32, 32, CKF_GENERATE}, PR_TRUE},
|
| -+ {CKM_NSS_CHACHA20_POLY1305,{32, 32, CKF_EN_DE}, PR_TRUE},
|
| - /* ------------------------- Hashing Operations ----------------------- */
|
| - {CKM_MD2, {0, 0, CKF_DIGEST}, PR_FALSE},
|
| - {CKM_MD2_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE},
|
| -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);
|
| - }
|
| +diff -r c3565a90b8c4 lib/freebl/blapi.h
|
| +--- a/lib/freebl/blapi.h Fri Jan 03 20:59:10 2014 +0100
|
| ++++ b/lib/freebl/blapi.h Tue Jan 07 12:11:36 2014 -0800
|
| +@@ -986,6 +986,38 @@
|
| + unsigned int *outputLen, unsigned int maxOutputLen,
|
| + const unsigned char *input, unsigned int inputLen);
|
|
|
| -+static SFTKChaCha20Poly1305Info *
|
| -+sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key,
|
| -+ unsigned int keyLen,
|
| -+ const CK_NSS_AEAD_PARAMS* params)
|
| -+{
|
| -+ SFTKChaCha20Poly1305Info *ctx;
|
| ++/******************************************/
|
| ++/*
|
| ++** ChaCha20+Poly1305 AEAD
|
| ++*/
|
| +
|
| -+ if (params->ulIvLen != sizeof(ctx->nonce)) {
|
| -+ PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| -+ return NULL;
|
| -+ }
|
| ++extern SECStatus
|
| ++ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
|
| ++ const unsigned char *key, unsigned int keyLen,
|
| ++ unsigned int tagLen);
|
| +
|
| -+ ctx = PORT_New(SFTKChaCha20Poly1305Info);
|
| -+ if (ctx == NULL) {
|
| -+ return NULL;
|
| ++extern ChaCha20Poly1305Context *
|
| ++ChaCha20Poly1305_CreateContext(const unsigned char *key, unsigned int keyLen,
|
| ++ unsigned int tagLen);
|
| ++
|
| ++extern void
|
| ++ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit);
|
| ++
|
| ++extern SECStatus
|
| ++ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx,
|
| ++ unsigned char *output, unsigned int *outputLen,
|
| ++ unsigned int maxOutputLen,
|
| ++ const unsigned char *input, unsigned int inputLen,
|
| ++ const unsigned char *nonce, unsigned int nonceLen,
|
| ++ const unsigned char *ad, unsigned int adLen);
|
| ++
|
| ++extern SECStatus
|
| ++ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx,
|
| ++ unsigned char *output, unsigned int *outputLen,
|
| ++ unsigned int maxOutputLen,
|
| ++ const unsigned char *input, unsigned int inputLen,
|
| ++ const unsigned char *nonce, unsigned int nonceLen,
|
| ++ const unsigned char *ad, unsigned int adLen);
|
| +
|
| + /******************************************/
|
| + /*
|
| +diff -r c3565a90b8c4 lib/freebl/blapit.h
|
| +--- a/lib/freebl/blapit.h Fri Jan 03 20:59:10 2014 +0100
|
| ++++ b/lib/freebl/blapit.h Tue Jan 07 12:11:36 2014 -0800
|
| +@@ -222,6 +222,7 @@
|
| + struct SHA512ContextStr ;
|
| + struct AESKeyWrapContextStr ;
|
| + struct SEEDContextStr ;
|
| ++struct ChaCha20Poly1305ContextStr;
|
| +
|
| + typedef struct DESContextStr DESContext;
|
| + typedef struct RC2ContextStr RC2Context;
|
| +@@ -240,6 +241,7 @@
|
| + typedef struct SHA512ContextStr SHA384Context;
|
| + typedef struct AESKeyWrapContextStr AESKeyWrapContext;
|
| + typedef struct SEEDContextStr SEEDContext;
|
| ++typedef struct ChaCha20Poly1305ContextStr ChaCha20Poly1305Context;
|
| +
|
| + /***************************************************************************
|
| + ** RSA Public and Private Key structures
|
| +diff -r c3565a90b8c4 lib/freebl/chacha20/chacha20.c
|
| +--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
| ++++ b/lib/freebl/chacha20/chacha20.c Tue Jan 07 12:11:36 2014 -0800
|
| +@@ -0,0 +1,108 @@
|
| ++/* This Source Code Form is subject to the terms of the Mozilla Public
|
| ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| ++
|
| ++/* Adopted from the public domain code in NaCl by djb. */
|
| ++
|
| ++#include <string.h>
|
| ++#include <stdio.h>
|
| ++
|
| ++#include "prtypes.h"
|
| ++#include "chacha20.h"
|
| ++
|
| ++#define ROTL32(v, n) (((v) << (n)) | ((v) >> (32 - (n))))
|
| ++#define ROTATE(v, c) ROTL32((v), (c))
|
| ++#define XOR(v, w) ((v) ^ (w))
|
| ++#define PLUS(x, y) ((x) + (y))
|
| ++
|
| ++#define U32TO8_LITTLE(p, v) \
|
| ++ { (p)[0] = ((v) ) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \
|
| ++ (p)[2] = ((v) >> 16) & 0xff; (p)[3] = ((v) >> 24) & 0xff; }
|
| ++#define U8TO32_LITTLE(p) \
|
| ++ (((PRUint32)((p)[0]) ) | ((PRUint32)((p)[1]) << 8) | \
|
| ++ ((PRUint32)((p)[2]) << 16) | ((PRUint32)((p)[3]) << 24) )
|
| ++
|
| ++#define QUARTERROUND(a,b,c,d) \
|
| ++ x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \
|
| ++ x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]),12); \
|
| ++ x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \
|
| ++ x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7);
|
| ++
|
| ++static void ChaChaCore(unsigned char output[64], const PRUint32 input[16],
|
| ++ int num_rounds) {
|
| ++ PRUint32 x[16];
|
| ++ int i;
|
| ++
|
| ++ memcpy(x, input, sizeof(PRUint32) * 16);
|
| ++ for (i = num_rounds; i > 0; i -= 2) {
|
| ++ QUARTERROUND( 0, 4, 8,12)
|
| ++ QUARTERROUND( 1, 5, 9,13)
|
| ++ QUARTERROUND( 2, 6,10,14)
|
| ++ QUARTERROUND( 3, 7,11,15)
|
| ++ QUARTERROUND( 0, 5,10,15)
|
| ++ QUARTERROUND( 1, 6,11,12)
|
| ++ QUARTERROUND( 2, 7, 8,13)
|
| ++ QUARTERROUND( 3, 4, 9,14)
|
| + }
|
| +
|
| -+ if (ChaCha20Poly1305_InitContext(&ctx->freeblCtx, key, keyLen,
|
| -+ params->ulTagLen) != SECSuccess) {
|
| -+ PORT_Free(ctx);
|
| -+ return NULL;
|
| ++ for (i = 0; i < 16; ++i) {
|
| ++ x[i] = PLUS(x[i], input[i]);
|
| + }
|
| ++ for (i = 0; i < 16; ++i) {
|
| ++ U32TO8_LITTLE(output + 4 * i, x[i]);
|
| ++ }
|
| ++}
|
| +
|
| -+ memcpy(ctx->nonce, params->pIv, sizeof(ctx->nonce));
|
| ++static const unsigned char sigma[16] = "expand 32-byte k";
|
| +
|
| -+ 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;
|
| ++void ChaCha20XOR(unsigned char *out, const unsigned char *in, unsigned int inLen,
|
| ++ const unsigned char key[32], const unsigned char nonce[8],
|
| ++ uint64_t counter) {
|
| ++ unsigned char block[64];
|
| ++ PRUint32 input[16];
|
| ++ unsigned int u;
|
| ++ unsigned int i;
|
| ++
|
| ++ input[4] = U8TO32_LITTLE(key + 0);
|
| ++ input[5] = U8TO32_LITTLE(key + 4);
|
| ++ input[6] = U8TO32_LITTLE(key + 8);
|
| ++ input[7] = U8TO32_LITTLE(key + 12);
|
| ++
|
| ++ input[8] = U8TO32_LITTLE(key + 16);
|
| ++ input[9] = U8TO32_LITTLE(key + 20);
|
| ++ input[10] = U8TO32_LITTLE(key + 24);
|
| ++ input[11] = U8TO32_LITTLE(key + 28);
|
| ++
|
| ++ input[0] = U8TO32_LITTLE(sigma + 0);
|
| ++ input[1] = U8TO32_LITTLE(sigma + 4);
|
| ++ input[2] = U8TO32_LITTLE(sigma + 8);
|
| ++ input[3] = U8TO32_LITTLE(sigma + 12);
|
| ++
|
| ++ input[12] = counter;
|
| ++ input[13] = counter >> 32;
|
| ++ input[14] = U8TO32_LITTLE(nonce + 0);
|
| ++ input[15] = U8TO32_LITTLE(nonce + 4);
|
| ++
|
| ++ while (inLen >= 64) {
|
| ++ ChaChaCore(block, input, 20);
|
| ++ for (i = 0; i < 64; i++) {
|
| ++ out[i] = in[i] ^ block[i];
|
| + }
|
| -+ memcpy(ctx->adOverflow, params->pAAD, params->ulAADLen);
|
| -+ } else {
|
| -+ ctx->adOverflow = NULL;
|
| -+ memcpy(ctx->ad, params->pAAD, params->ulAADLen);
|
| -+ }
|
| -+ ctx->adLen = params->ulAADLen;
|
| +
|
| -+ return ctx;
|
| -+}
|
| ++ input[12]++;
|
| ++ if (input[12] == 0) {
|
| ++ input[13]++;
|
| ++ }
|
| +
|
| -+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;
|
| ++ inLen -= 64;
|
| ++ in += 64;
|
| ++ out += 64;
|
| + }
|
| -+ ctx->adLen = 0;
|
| -+ if (freeit) {
|
| -+ PORT_Free(ctx);
|
| ++
|
| ++ if (inLen > 0) {
|
| ++ ChaChaCore(block, input, 20);
|
| ++ for (i = 0; i < inLen; i++) {
|
| ++ out[i] = in[i] ^ block[i];
|
| ++ }
|
| + }
|
| +}
|
| +diff -r c3565a90b8c4 lib/freebl/chacha20/chacha20.h
|
| +--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
| ++++ b/lib/freebl/chacha20/chacha20.h Tue Jan 07 12:11:36 2014 -0800
|
| +@@ -0,0 +1,22 @@
|
| ++/*
|
| ++ * chacha20.h - header file for ChaCha20 implementation.
|
| ++ *
|
| ++ * This Source Code Form is subject to the terms of the Mozilla Public
|
| ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| +
|
| -+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;
|
| ++#ifndef FREEBL_CHACHA20_H_
|
| ++#define FREEBL_CHACHA20_H_
|
| +
|
| -+ if (ad == NULL) {
|
| -+ ad = ctx->ad;
|
| -+ }
|
| ++#include <stdint.h>
|
| +
|
| -+ return ChaCha20Poly1305_Seal(&ctx->freeblCtx, output, outputLen,
|
| -+ maxOutputLen, input, inputLen, ctx->nonce,
|
| -+ sizeof(ctx->nonce), ad, ctx->adLen);
|
| -+}
|
| ++/* ChaCha20XOR encrypts |inLen| bytes from |in| with the given key and
|
| ++ * nonce and writes the result to |out|, which may be equal to |in|. The
|
| ++ * initial block counter is specified by |counter|. */
|
| ++extern void ChaCha20XOR(unsigned char *out,
|
| ++ const unsigned char *in, unsigned int inLen,
|
| ++ const unsigned char key[32],
|
| ++ const unsigned char nonce[8],
|
| ++ uint64_t counter);
|
| +
|
| -+static SECStatus
|
| -+sftk_ChaCha20Poly1305_Decrypt(const SFTKChaCha20Poly1305Info *ctx,
|
| -+ unsigned char *output, unsigned int *outputLen,
|
| -+ unsigned int maxOutputLen,
|
| -+ const unsigned char *input, unsigned int inputLen)
|
| ++#endif /* FREEBL_CHACHA20_H_ */
|
| +diff -r c3565a90b8c4 lib/freebl/chacha20/chacha20_vec.c
|
| +--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
| ++++ b/lib/freebl/chacha20/chacha20_vec.c Tue Jan 07 12:11:36 2014 -0800
|
| +@@ -0,0 +1,281 @@
|
| ++/* This Source Code Form is subject to the terms of the Mozilla Public
|
| ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| ++
|
| ++/* This implementation is by Ted Krovetz and was submitted to SUPERCOP and
|
| ++ * marked as public domain. It was been altered to allow for non-aligned inputs
|
| ++ * and to allow the block counter to be passed in specifically. */
|
| ++
|
| ++#include <string.h>
|
| ++
|
| ++#include "chacha20.h"
|
| ++
|
| ++#ifndef CHACHA_RNDS
|
| ++#define CHACHA_RNDS 20 /* 8 (high speed), 20 (conservative), 12 (middle) */
|
| ++#endif
|
| ++
|
| ++/* Architecture-neutral way to specify 16-byte vector of ints */
|
| ++typedef unsigned vec __attribute__ ((vector_size (16)));
|
| ++
|
| ++/* This implementation is designed for Neon, SSE and AltiVec machines. The
|
| ++ * following specify how to do certain vector operations efficiently on
|
| ++ * each architecture, using intrinsics.
|
| ++ * This implementation supports parallel processing of multiple blocks,
|
| ++ * including potentially using general-purpose registers.
|
| ++ */
|
| ++#if __ARM_NEON__
|
| ++#include <arm_neon.h>
|
| ++#define GPR_TOO 1
|
| ++#define VBPI 2
|
| ++#define ONE (vec)vsetq_lane_u32(1,vdupq_n_u32(0),0)
|
| ++#define LOAD(m) (vec)(*((vec*)(m)))
|
| ++#define STORE(m,r) (*((vec*)(m))) = (r)
|
| ++#define ROTV1(x) (vec)vextq_u32((uint32x4_t)x,(uint32x4_t)x,1)
|
| ++#define ROTV2(x) (vec)vextq_u32((uint32x4_t)x,(uint32x4_t)x,2)
|
| ++#define ROTV3(x) (vec)vextq_u32((uint32x4_t)x,(uint32x4_t)x,3)
|
| ++#define ROTW16(x) (vec)vrev32q_u16((uint16x8_t)x)
|
| ++#if __clang__
|
| ++#define ROTW7(x) (x << ((vec){ 7, 7, 7, 7})) ^ (x >> ((vec){25,25,25,25}))
|
| ++#define ROTW8(x) (x << ((vec){ 8, 8, 8, 8})) ^ (x >> ((vec){24,24,24,24}))
|
| ++#define ROTW12(x) (x << ((vec){12,12,12,12})) ^ (x >> ((vec){20,20,20,20}))
|
| ++#else
|
| ++#define ROTW7(x) (vec)vsriq_n_u32(vshlq_n_u32((uint32x4_t)x,7),(uint32x4_t)x,25)
|
| ++#define ROTW8(x) (vec)vsriq_n_u32(vshlq_n_u32((uint32x4_t)x,8),(uint32x4_t)x,24)
|
| ++#define ROTW12(x) (vec)vsriq_n_u32(vshlq_n_u32((uint32x4_t)x,12),(uint32x4_t)x,20)
|
| ++#endif
|
| ++#elif __SSE2__
|
| ++#include <emmintrin.h>
|
| ++#define GPR_TOO 0
|
| ++#if __clang__
|
| ++#define VBPI 4
|
| ++#else
|
| ++#define VBPI 3
|
| ++#endif
|
| ++#define ONE (vec)_mm_set_epi32(0,0,0,1)
|
| ++#define LOAD(m) (vec)_mm_loadu_si128((__m128i*)(m))
|
| ++#define STORE(m,r) _mm_storeu_si128((__m128i*)(m), (__m128i) (r))
|
| ++#define ROTV1(x) (vec)_mm_shuffle_epi32((__m128i)x,_MM_SHUFFLE(0,3,2,1))
|
| ++#define ROTV2(x) (vec)_mm_shuffle_epi32((__m128i)x,_MM_SHUFFLE(1,0,3,2))
|
| ++#define ROTV3(x) (vec)_mm_shuffle_epi32((__m128i)x,_MM_SHUFFLE(2,1,0,3))
|
| ++#define ROTW7(x) (vec)(_mm_slli_epi32((__m128i)x, 7) ^ _mm_srli_epi32((__m128i)x,25))
|
| ++#define ROTW12(x) (vec)(_mm_slli_epi32((__m128i)x,12) ^ _mm_srli_epi32((__m128i)x,20))
|
| ++#if __SSSE3__
|
| ++#include <tmmintrin.h>
|
| ++#define ROTW8(x) (vec)_mm_shuffle_epi8((__m128i)x,_mm_set_epi8(14,13,12,15,10,9,8,11,6,5,4,7,2,1,0,3))
|
| ++#define ROTW16(x) (vec)_mm_shuffle_epi8((__m128i)x,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2))
|
| ++#else
|
| ++#define ROTW8(x) (vec)(_mm_slli_epi32((__m128i)x, 8) ^ _mm_srli_epi32((__m128i)x,24))
|
| ++#define ROTW16(x) (vec)(_mm_slli_epi32((__m128i)x,16) ^ _mm_srli_epi32((__m128i)x,16))
|
| ++#endif
|
| ++#else
|
| ++#error -- Implementation supports only machines with neon or SSE2
|
| ++#endif
|
| ++
|
| ++#ifndef REVV_BE
|
| ++#define REVV_BE(x) (x)
|
| ++#endif
|
| ++
|
| ++#ifndef REVW_BE
|
| ++#define REVW_BE(x) (x)
|
| ++#endif
|
| ++
|
| ++#define BPI (VBPI + GPR_TOO) /* Blocks computed per loop iteration */
|
| ++
|
| ++#define DQROUND_VECTORS(a,b,c,d) \
|
| ++ a += b; d ^= a; d = ROTW16(d); \
|
| ++ c += d; b ^= c; b = ROTW12(b); \
|
| ++ a += b; d ^= a; d = ROTW8(d); \
|
| ++ c += d; b ^= c; b = ROTW7(b); \
|
| ++ b = ROTV1(b); c = ROTV2(c); d = ROTV3(d); \
|
| ++ a += b; d ^= a; d = ROTW16(d); \
|
| ++ c += d; b ^= c; b = ROTW12(b); \
|
| ++ a += b; d ^= a; d = ROTW8(d); \
|
| ++ c += d; b ^= c; b = ROTW7(b); \
|
| ++ b = ROTV3(b); c = ROTV2(c); d = ROTV1(d);
|
| ++
|
| ++#define QROUND_WORDS(a,b,c,d) \
|
| ++ a = a+b; d ^= a; d = d<<16 | d>>16; \
|
| ++ c = c+d; b ^= c; b = b<<12 | b>>20; \
|
| ++ a = a+b; d ^= a; d = d<< 8 | d>>24; \
|
| ++ c = c+d; b ^= c; b = b<< 7 | b>>25;
|
| ++
|
| ++#define WRITE_XOR(in, op, d, v0, v1, v2, v3) \
|
| ++ STORE(op + d + 0, LOAD(in + d + 0) ^ REVV_BE(v0)); \
|
| ++ STORE(op + d + 4, LOAD(in + d + 4) ^ REVV_BE(v1)); \
|
| ++ STORE(op + d + 8, LOAD(in + d + 8) ^ REVV_BE(v2)); \
|
| ++ STORE(op + d +12, LOAD(in + d +12) ^ REVV_BE(v3));
|
| ++
|
| ++void ChaCha20XOR(
|
| ++ unsigned char *out,
|
| ++ const unsigned char *in,
|
| ++ unsigned int inlen,
|
| ++ const unsigned char key[32],
|
| ++ const unsigned char nonce[8],
|
| ++ uint64_t counter)
|
| +{
|
| -+ const unsigned char *ad = ctx->adOverflow;
|
| ++ unsigned iters, i, *op=(unsigned *)out, *ip=(unsigned *)in, *kp;
|
| ++#if defined(__ARM_NEON__)
|
| ++ unsigned *np;
|
| ++#endif
|
| ++ vec s0, s1, s2, s3;
|
| ++#if !defined(__ARM_NEON__) && !defined(__SSE2__)
|
| ++ __attribute__ ((aligned (16))) unsigned key[8], nonce[4];
|
| ++#endif
|
| ++ __attribute__ ((aligned (16))) unsigned chacha_const[] =
|
| ++ {0x61707865,0x3320646E,0x79622D32,0x6B206574};
|
| ++#if defined(__ARM_NEON__) || defined(__SSE2__)
|
| ++ kp = (unsigned *)key;
|
| ++#else
|
| ++ ((vec *)key)[0] = REVV_BE(((vec *)key)[0]);
|
| ++ ((vec *)key)[1] = REVV_BE(((vec *)key)[1]);
|
| ++ nonce[0] = REVW_BE(((unsigned *)nonce)[0]);
|
| ++ nonce[1] = REVW_BE(((unsigned *)nonce)[1]);
|
| ++ nonce[2] = REVW_BE(((unsigned *)nonce)[2]);
|
| ++ nonce[3] = REVW_BE(((unsigned *)nonce)[3]);
|
| ++ kp = (unsigned *)key;
|
| ++ np = (unsigned *)nonce;
|
| ++#endif
|
| ++#if defined(__ARM_NEON__)
|
| ++ np = (unsigned*) nonce;
|
| ++#endif
|
| ++ s0 = LOAD(chacha_const);
|
| ++ s1 = LOAD(&((vec*)kp)[0]);
|
| ++ s2 = LOAD(&((vec*)kp)[1]);
|
| ++ s3 = (vec) {
|
| ++ counter & 0xffffffff,
|
| ++ counter >> 32,
|
| ++ ((uint32_t*)nonce)[0],
|
| ++ ((uint32_t*)nonce)[1]
|
| ++ };
|
| +
|
| -+ if (ad == NULL) {
|
| -+ ad = ctx->ad;
|
| ++ for (iters = 0; iters < inlen/(BPI*64); iters++) {
|
| ++#if GPR_TOO
|
| ++ register unsigned x0, x1, x2, x3, x4, x5, x6, x7, x8,
|
| ++ x9, x10, x11, x12, x13, x14, x15;
|
| ++#endif
|
| ++#if VBPI > 2
|
| ++ vec v8,v9,v10,v11;
|
| ++#endif
|
| ++#if VBPI > 3
|
| ++ vec v12,v13,v14,v15;
|
| ++#endif
|
| ++
|
| ++ vec v0,v1,v2,v3,v4,v5,v6,v7;
|
| ++ v4 = v0 = s0; v5 = v1 = s1; v6 = v2 = s2; v3 = s3;
|
| ++ v7 = v3 + ONE;
|
| ++#if VBPI > 2
|
| ++ v8 = v4; v9 = v5; v10 = v6;
|
| ++ v11 = v7 + ONE;
|
| ++#endif
|
| ++#if VBPI > 3
|
| ++ v12 = v8; v13 = v9; v14 = v10;
|
| ++ v15 = v11 + ONE;
|
| ++#endif
|
| ++#if GPR_TOO
|
| ++ x0 = chacha_const[0]; x1 = chacha_const[1];
|
| ++ x2 = chacha_const[2]; x3 = chacha_const[3];
|
| ++ x4 = kp[0]; x5 = kp[1]; x6 = kp[2]; x7 = kp[3];
|
| ++ x8 = kp[4]; x9 = kp[5]; x10 = kp[6]; x11 = kp[7];
|
| ++ x12 = (counter & 0xffffffff)+BPI*iters+(BPI-1); x13 = counter >> 32;
|
| ++ x14 = np[0]; x15 = np[1];
|
| ++#endif
|
| ++ for (i = CHACHA_RNDS/2; i; i--) {
|
| ++ DQROUND_VECTORS(v0,v1,v2,v3)
|
| ++ DQROUND_VECTORS(v4,v5,v6,v7)
|
| ++#if VBPI > 2
|
| ++ DQROUND_VECTORS(v8,v9,v10,v11)
|
| ++#endif
|
| ++#if VBPI > 3
|
| ++ DQROUND_VECTORS(v12,v13,v14,v15)
|
| ++#endif
|
| ++#if GPR_TOO
|
| ++ QROUND_WORDS( x0, x4, x8,x12)
|
| ++ QROUND_WORDS( x1, x5, x9,x13)
|
| ++ QROUND_WORDS( x2, x6,x10,x14)
|
| ++ QROUND_WORDS( x3, x7,x11,x15)
|
| ++ QROUND_WORDS( x0, x5,x10,x15)
|
| ++ QROUND_WORDS( x1, x6,x11,x12)
|
| ++ QROUND_WORDS( x2, x7, x8,x13)
|
| ++ QROUND_WORDS( x3, x4, x9,x14)
|
| ++#endif
|
| ++ }
|
| ++
|
| ++ WRITE_XOR(ip, op, 0, v0+s0, v1+s1, v2+s2, v3+s3)
|
| ++ s3 += ONE;
|
| ++ WRITE_XOR(ip, op, 16, v4+s0, v5+s1, v6+s2, v7+s3)
|
| ++ s3 += ONE;
|
| ++#if VBPI > 2
|
| ++ WRITE_XOR(ip, op, 32, v8+s0, v9+s1, v10+s2, v11+s3)
|
| ++ s3 += ONE;
|
| ++#endif
|
| ++#if VBPI > 3
|
| ++ WRITE_XOR(ip, op, 48, v12+s0, v13+s1, v14+s2, v15+s3)
|
| ++ s3 += ONE;
|
| ++#endif
|
| ++ ip += VBPI*16;
|
| ++ op += VBPI*16;
|
| ++#if GPR_TOO
|
| ++ op[0] = REVW_BE(REVW_BE(ip[0]) ^ (x0 + chacha_const[0]));
|
| ++ op[1] = REVW_BE(REVW_BE(ip[1]) ^ (x1 + chacha_const[1]));
|
| ++ op[2] = REVW_BE(REVW_BE(ip[2]) ^ (x2 + chacha_const[2]));
|
| ++ op[3] = REVW_BE(REVW_BE(ip[3]) ^ (x3 + chacha_const[3]));
|
| ++ op[4] = REVW_BE(REVW_BE(ip[4]) ^ (x4 + kp[0]));
|
| ++ op[5] = REVW_BE(REVW_BE(ip[5]) ^ (x5 + kp[1]));
|
| ++ op[6] = REVW_BE(REVW_BE(ip[6]) ^ (x6 + kp[2]));
|
| ++ op[7] = REVW_BE(REVW_BE(ip[7]) ^ (x7 + kp[3]));
|
| ++ op[8] = REVW_BE(REVW_BE(ip[8]) ^ (x8 + kp[4]));
|
| ++ op[9] = REVW_BE(REVW_BE(ip[9]) ^ (x9 + kp[5]));
|
| ++ op[10] = REVW_BE(REVW_BE(ip[10]) ^ (x10 + kp[6]));
|
| ++ op[11] = REVW_BE(REVW_BE(ip[11]) ^ (x11 + kp[7]));
|
| ++ op[12] = REVW_BE(REVW_BE(ip[12]) ^ (x12 + (counter & 0xffffffff)+BPI*iters+(BPI-1)));
|
| ++ op[13] = REVW_BE(REVW_BE(ip[13]) ^ (x13 + (counter >> 32)));
|
| ++ op[14] = REVW_BE(REVW_BE(ip[14]) ^ (x14 + np[0]));
|
| ++ op[15] = REVW_BE(REVW_BE(ip[15]) ^ (x15 + np[1]));
|
| ++ s3 += ONE;
|
| ++ ip += 16;
|
| ++ op += 16;
|
| ++#endif
|
| + }
|
| +
|
| -+ return ChaCha20Poly1305_Open(&ctx->freeblCtx, output, outputLen,
|
| -+ maxOutputLen, input, inputLen, ctx->nonce,
|
| -+ sizeof(ctx->nonce), ad, ctx->adLen);
|
| -+}
|
| ++ for (iters = inlen%(BPI*64)/64; iters != 0; iters--) {
|
| ++ vec v0 = s0, v1 = s1, v2 = s2, v3 = s3;
|
| ++ for (i = CHACHA_RNDS/2; i; i--) {
|
| ++ DQROUND_VECTORS(v0,v1,v2,v3);
|
| ++ }
|
| ++ WRITE_XOR(ip, op, 0, v0+s0, v1+s1, v2+s2, v3+s3)
|
| ++ s3 += ONE;
|
| ++ ip += 16;
|
| ++ op += 16;
|
| ++ }
|
| +
|
| - /** 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;
|
| ++ inlen = inlen % 64;
|
| ++ if (inlen) {
|
| ++ __attribute__ ((aligned (16))) vec buf[4];
|
| ++ vec v0,v1,v2,v3;
|
| ++ v0 = s0; v1 = s1; v2 = s2; v3 = s3;
|
| ++ for (i = CHACHA_RNDS/2; i; i--) {
|
| ++ DQROUND_VECTORS(v0,v1,v2,v3);
|
| + }
|
| -+ context->multi = PR_FALSE;
|
| -+ if (key_type != CKK_NSS_CHACHA20) {
|
| -+ crv = CKR_KEY_TYPE_INCONSISTENT;
|
| -+ break;
|
| ++
|
| ++ if (inlen >= 16) {
|
| ++ STORE(op + 0, LOAD(ip + 0) ^ REVV_BE(v0 + s0));
|
| ++ if (inlen >= 32) {
|
| ++ STORE(op + 4, LOAD(ip + 4) ^ REVV_BE(v1 + s1));
|
| ++ if (inlen >= 48) {
|
| ++ STORE(op + 8, LOAD(ip + 8) ^ REVV_BE(v2 + s2));
|
| ++ buf[3] = REVV_BE(v3 + s3);
|
| ++ } else {
|
| ++ buf[2] = REVV_BE(v2 + s2);
|
| ++ }
|
| ++ } else {
|
| ++ buf[1] = REVV_BE(v1 + s1);
|
| ++ }
|
| ++ } else {
|
| ++ buf[0] = REVV_BE(v0 + s0);
|
| + }
|
| -+ att = sftk_FindAttribute(key,CKA_VALUE);
|
| -+ if (att == NULL) {
|
| -+ crv = CKR_KEY_HANDLE_INVALID;
|
| -+ break;
|
| ++
|
| ++ for (i=inlen & ~15; i<inlen; i++) {
|
| ++ ((char *)op)[i] = ((char *)ip)[i] ^ ((char *)buf)[i];
|
| + }
|
| -+ 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;
|
| ++ }
|
| ++}
|
| +diff -r c3565a90b8c4 lib/freebl/chacha20poly1305.c
|
| +--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
| ++++ b/lib/freebl/chacha20poly1305.c Tue Jan 07 12:11:36 2014 -0800
|
| +@@ -0,0 +1,169 @@
|
| ++/* This Source Code Form is subject to the terms of the Mozilla Public
|
| ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| +
|
| - 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
|
| -Index: nss/lib/softoken/pkcs11i.h
|
| -===================================================================
|
| ---- nss/lib/softoken/pkcs11i.h (revision 228205)
|
| -+++ nss/lib/softoken/pkcs11i.h (working copy)
|
| -@@ -14,6 +14,7 @@
|
| - #include "pkcs11t.h"
|
| -
|
| - #include "sftkdbt.h"
|
| ++#ifdef FREEBL_NO_DEPEND
|
| ++#include "stubs.h"
|
| ++#endif
|
| ++
|
| ++#include <string.h>
|
| ++#include <stdio.h>
|
| ++
|
| ++#include "seccomon.h"
|
| ++#include "secerr.h"
|
| ++#include "blapit.h"
|
| ++#include "poly1305/poly1305.h"
|
| ++#include "chacha20/chacha20.h"
|
| +#include "chacha20poly1305.h"
|
| - #include "hasht.h"
|
| -
|
| - /*
|
| -@@ -104,6 +105,7 @@
|
| - typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo;
|
| - typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo;
|
| - typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo;
|
| -+typedef struct SFTKChaCha20Poly1305InfoStr SFTKChaCha20Poly1305Info;
|
| - typedef struct SFTKItemTemplateStr SFTKItemTemplate;
|
| -
|
| - /* define function pointer typdefs for pointer tables */
|
| -@@ -399,6 +401,16 @@
|
| - unsigned int keySize;
|
| - };
|
| -
|
| -+/* SFTKChaCha20Poly1305Info saves the key, tag length, nonce, and additional
|
| -+ * data for a ChaCha20+Poly1305 AEAD operation. */
|
| -+struct SFTKChaCha20Poly1305InfoStr {
|
| -+ ChaCha20Poly1305Context freeblCtx;
|
| -+ unsigned char nonce[8];
|
| -+ unsigned char ad[16];
|
| -+ unsigned char *adOverflow;
|
| -+ unsigned int adLen;
|
| -+};
|
| +
|
| - /*
|
| - * Template based on SECItems, suitable for passing as arrays
|
| - */
|
| -Index: nss/lib/freebl/blapit.h
|
| -===================================================================
|
| ---- nss/lib/freebl/blapit.h (revision 228205)
|
| -+++ nss/lib/freebl/blapit.h (working copy)
|
| -@@ -222,6 +222,7 @@
|
| - struct SHA512ContextStr ;
|
| - struct AESKeyWrapContextStr ;
|
| - struct SEEDContextStr ;
|
| -+struct ChaCha20Poly1305ContextStr;
|
| -
|
| - typedef struct DESContextStr DESContext;
|
| - typedef struct RC2ContextStr RC2Context;
|
| -@@ -240,6 +241,7 @@
|
| - typedef struct SHA512ContextStr SHA384Context;
|
| - typedef struct AESKeyWrapContextStr AESKeyWrapContext;
|
| - typedef struct SEEDContextStr SEEDContext;
|
| -+typedef struct ChaCha20Poly1305ContextStr ChaCha20Poly1305Context;
|
| -
|
| - /***************************************************************************
|
| - ** RSA Public and Private Key structures
|
| -Index: nss/lib/freebl/blapi.h
|
| -===================================================================
|
| ---- nss/lib/freebl/blapi.h (revision 228205)
|
| -+++ nss/lib/freebl/blapi.h (working copy)
|
| -@@ -818,7 +818,39 @@
|
| - unsigned int *outputLen, unsigned int maxOutputLen,
|
| - const unsigned char *input, unsigned int inputLen);
|
| -
|
| -+/******************************************/
|
| -+/*
|
| -+** ChaCha20+Poly1305 AEAD
|
| -+*/
|
| -
|
| -+extern SECStatus
|
| ++/* Poly1305Do writes the Poly1305 authenticator of the given additional data
|
| ++ * and ciphertext to |out|. */
|
| ++static void
|
| ++Poly1305Do(unsigned char *out,
|
| ++ const unsigned char *ad, unsigned int adLen,
|
| ++ const unsigned char *ciphertext, unsigned int ciphertextLen,
|
| ++ const unsigned char key[32])
|
| ++{
|
| ++ poly1305_state state;
|
| ++ unsigned int j;
|
| ++ unsigned char lengthBytes[8];
|
| ++ unsigned int i;
|
| ++
|
| ++ Poly1305Init(&state, key);
|
| ++ j = adLen;
|
| ++ for (i = 0; i < sizeof(lengthBytes); i++) {
|
| ++ lengthBytes[i] = j;
|
| ++ j >>= 8;
|
| ++ }
|
| ++ Poly1305Update(&state, ad, adLen);
|
| ++ Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
|
| ++ j = ciphertextLen;
|
| ++ for (i = 0; i < sizeof(lengthBytes); i++) {
|
| ++ lengthBytes[i] = j;
|
| ++ j >>= 8;
|
| ++ }
|
| ++ Poly1305Update(&state, ciphertext, ciphertextLen);
|
| ++ Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
|
| ++ Poly1305Finish(&state, out);
|
| ++}
|
| ++
|
| ++SECStatus
|
| +ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
|
| + const unsigned char *key, unsigned int keyLen,
|
| -+ unsigned int tagLen);
|
| ++ unsigned int tagLen)
|
| ++{
|
| ++ if (keyLen != 32) {
|
| ++ PORT_SetError(SEC_ERROR_BAD_KEY);
|
| ++ return SECFailure;
|
| ++ }
|
| ++ if (tagLen == 0 || tagLen > 16) {
|
| ++ PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| ++ return SECFailure;
|
| ++ }
|
| +
|
| -+extern ChaCha20Poly1305Context *
|
| ++ memcpy(ctx->key, key, sizeof(ctx->key));
|
| ++ ctx->tagLen = tagLen;
|
| ++
|
| ++ return SECSuccess;
|
| ++}
|
| ++
|
| ++ChaCha20Poly1305Context *
|
| +ChaCha20Poly1305_CreateContext(const unsigned char *key, unsigned int keyLen,
|
| -+ unsigned int tagLen);
|
| ++ unsigned int tagLen)
|
| ++{
|
| ++ ChaCha20Poly1305Context *ctx;
|
| +
|
| -+extern void
|
| -+ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit);
|
| ++ ctx = PORT_New(ChaCha20Poly1305Context);
|
| ++ if (ctx == NULL) {
|
| ++ return NULL;
|
| ++ }
|
| +
|
| -+extern SECStatus
|
| ++ if (ChaCha20Poly1305_InitContext(ctx, key, keyLen, tagLen) != SECSuccess) {
|
| ++ PORT_Free(ctx);
|
| ++ ctx = NULL;
|
| ++ }
|
| ++
|
| ++ return ctx;
|
| ++}
|
| ++
|
| ++void
|
| ++ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit)
|
| ++{
|
| ++ memset(ctx, 0, sizeof(*ctx));
|
| ++ if (freeit) {
|
| ++ PORT_Free(ctx);
|
| ++ }
|
| ++}
|
| ++
|
| ++SECStatus
|
| +ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx,
|
| + unsigned char *output, unsigned int *outputLen,
|
| + unsigned int maxOutputLen,
|
| + const unsigned char *input, unsigned int inputLen,
|
| + const unsigned char *nonce, unsigned int nonceLen,
|
| -+ const unsigned char *ad, unsigned int adLen);
|
| ++ const unsigned char *ad, unsigned int adLen)
|
| ++{
|
| ++ unsigned char block[64];
|
| ++ unsigned char tag[16];
|
| +
|
| -+extern SECStatus
|
| ++ if (nonceLen != 8) {
|
| ++ PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| ++ return SECFailure;
|
| ++ }
|
| ++ *outputLen = inputLen + ctx->tagLen;
|
| ++ if (maxOutputLen < *outputLen) {
|
| ++ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
| ++ return SECFailure;
|
| ++ }
|
| ++
|
| ++ memset(block, 0, sizeof(block));
|
| ++ // Generate a block of keystream. The first 32 bytes will be the poly1305
|
| ++ // key. The remainder of the block is discarded.
|
| ++ ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0);
|
| ++ ChaCha20XOR(output, input, inputLen, ctx->key, nonce, 1);
|
| ++
|
| ++ Poly1305Do(tag, ad, adLen, output, inputLen, block);
|
| ++ memcpy(output + inputLen, tag, ctx->tagLen);
|
| ++
|
| ++ return SECSuccess;
|
| ++}
|
| ++
|
| ++SECStatus
|
| +ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx,
|
| + unsigned char *output, unsigned int *outputLen,
|
| + unsigned int maxOutputLen,
|
| + const unsigned char *input, unsigned int inputLen,
|
| + const unsigned char *nonce, unsigned int nonceLen,
|
| -+ const unsigned char *ad, unsigned int adLen);
|
| ++ const unsigned char *ad, unsigned int adLen)
|
| ++{
|
| ++ unsigned char block[64];
|
| ++ unsigned char tag[16];
|
| +
|
| - /******************************************/
|
| - /*
|
| - ** MD5 secure hash function
|
| -Index: nss/lib/freebl/poly1305/poly1305-donna-x64-sse2-incremental-source.c
|
| -===================================================================
|
| ---- nss/lib/freebl/poly1305/poly1305-donna-x64-sse2-incremental-source.c (revision 0)
|
| -+++ nss/lib/freebl/poly1305/poly1305-donna-x64-sse2-incremental-source.c (revision 0)
|
| ++ if (nonceLen != 8) {
|
| ++ PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| ++ return SECFailure;
|
| ++ }
|
| ++ 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;
|
| ++ }
|
| ++
|
| ++ memset(block, 0, sizeof(block));
|
| ++ // Generate a block of keystream. The first 32 bytes will be the poly1305
|
| ++ // key. The remainder of the block is discarded.
|
| ++ ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0);
|
| ++ Poly1305Do(tag, ad, adLen, input, inputLen - ctx->tagLen, block);
|
| ++ if (NSS_SecureMemcmp(tag, &input[inputLen - ctx->tagLen], ctx->tagLen) != 0) {
|
| ++ PORT_SetError(SEC_ERROR_BAD_DATA);
|
| ++ return SECFailure;
|
| ++ }
|
| ++
|
| ++ ChaCha20XOR(output, input, inputLen - ctx->tagLen, ctx->key, nonce, 1);
|
| ++
|
| ++ return SECSuccess;
|
| ++}
|
| +diff -r c3565a90b8c4 lib/freebl/chacha20poly1305.h
|
| +--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
| ++++ b/lib/freebl/chacha20poly1305.h Tue Jan 07 12:11:36 2014 -0800
|
| +@@ -0,0 +1,15 @@
|
| ++/* This Source Code Form is subject to the terms of the Mozilla Public
|
| ++ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| ++
|
| ++#ifndef _CHACHA20_POLY1305_H_
|
| ++#define _CHACHA20_POLY1305_H_ 1
|
| ++
|
| ++/* ChaCha20Poly1305ContextStr saves the key and tag length for a
|
| ++ * ChaCha20+Poly1305 AEAD operation. */
|
| ++struct ChaCha20Poly1305ContextStr {
|
| ++ unsigned char key[32];
|
| ++ unsigned char tagLen;
|
| ++};
|
| ++
|
| ++#endif /* _CHACHA20_POLY1305_H_ */
|
| +diff -r c3565a90b8c4 lib/freebl/poly1305/poly1305-donna-x64-sse2-incremental-source.c
|
| +--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
| ++++ b/lib/freebl/poly1305/poly1305-donna-x64-sse2-incremental-source.c Tue Jan 07 12:11:36 2014 -0800
|
| @@ -0,0 +1,623 @@
|
| +/* This Source Code Form is subject to the terms of the Mozilla Public
|
| + * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| @@ -898,58 +1301,9 @@
|
| + U64TO8_LE(mac + 0, ((h0 ) | (h1 << 44)));
|
| + U64TO8_LE(mac + 8, ((h1 >> 20) | (h2 << 24)));
|
| +}
|
| -
|
| -Property changes on: nss/lib/freebl/poly1305/poly1305-donna-x64-sse2-incremental-source.c
|
| -___________________________________________________________________
|
| -Added: svn:eol-style
|
| - + LF
|
| -
|
| -Index: nss/lib/freebl/poly1305/poly1305.h
|
| -===================================================================
|
| ---- nss/lib/freebl/poly1305/poly1305.h (revision 0)
|
| -+++ nss/lib/freebl/poly1305/poly1305.h (revision 0)
|
| -@@ -0,0 +1,31 @@
|
| -+/*
|
| -+ * poly1305.h - header file for Poly1305 implementation.
|
| -+ *
|
| -+ * This Source Code Form is subject to the terms of the Mozilla Public
|
| -+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| -+
|
| -+#ifndef FREEBL_POLY1305_H_
|
| -+#define FREEBL_POLY1305_H_
|
| -+
|
| -+typedef unsigned char poly1305_state[512];
|
| -+
|
| -+/* Poly1305Init sets up |state| so that it can be used to calculate an
|
| -+ * authentication tag with the one-time key |key|. Note that |key| is a
|
| -+ * one-time key and therefore there is no `reset' method because that would
|
| -+ * enable several messages to be authenticated with the same key. */
|
| -+extern void Poly1305Init(poly1305_state* state,
|
| -+ const unsigned char key[32]);
|
| -+
|
| -+/* Poly1305Update processes |in_len| bytes from |in|. It can be called zero or
|
| -+ * more times after poly1305_init. */
|
| -+extern void Poly1305Update(poly1305_state* state,
|
| -+ const unsigned char *in,
|
| -+ size_t inLen);
|
| -+
|
| -+/* Poly1305Finish completes the poly1305 calculation and writes a 16 byte
|
| -+ * authentication tag to |mac|. */
|
| -+extern void Poly1305Finish(poly1305_state* state,
|
| -+ unsigned char mac[16]);
|
| -+
|
| -+#endif /* FREEBL_POLY1305_H_ */
|
| -
|
| -Property changes on: nss/lib/freebl/poly1305/poly1305.h
|
| -___________________________________________________________________
|
| -Added: svn:eol-style
|
| - + LF
|
| -
|
| -Index: nss/lib/freebl/poly1305/poly1305.c
|
| -===================================================================
|
| ---- nss/lib/freebl/poly1305/poly1305.c (revision 0)
|
| -+++ nss/lib/freebl/poly1305/poly1305.c (revision 0)
|
| +diff -r c3565a90b8c4 lib/freebl/poly1305/poly1305.c
|
| +--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
| ++++ b/lib/freebl/poly1305/poly1305.c Tue Jan 07 12:11:36 2014 -0800
|
| @@ -0,0 +1,254 @@
|
| +/* This Source Code Form is subject to the terms of the Mozilla Public
|
| + * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| @@ -1205,697 +1559,279 @@
|
| + U32TO8_LE(&mac[ 8], f2); f3 += (f2 >> 32);
|
| + U32TO8_LE(&mac[12], f3);
|
| +}
|
| -
|
| -Property changes on: nss/lib/freebl/poly1305/poly1305.c
|
| -___________________________________________________________________
|
| -Added: svn:eol-style
|
| - + LF
|
| -
|
| -Index: nss/lib/freebl/chacha20poly1305.c
|
| -===================================================================
|
| ---- nss/lib/freebl/chacha20poly1305.c (revision 0)
|
| -+++ nss/lib/freebl/chacha20poly1305.c (revision 0)
|
| -@@ -0,0 +1,169 @@
|
| -+/* This Source Code Form is subject to the terms of the Mozilla Public
|
| +diff -r c3565a90b8c4 lib/freebl/poly1305/poly1305.h
|
| +--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
| ++++ b/lib/freebl/poly1305/poly1305.h Tue Jan 07 12:11:36 2014 -0800
|
| +@@ -0,0 +1,31 @@
|
| ++/*
|
| ++ * poly1305.h - header file for Poly1305 implementation.
|
| ++ *
|
| ++ * This Source Code Form is subject to the terms of the Mozilla Public
|
| + * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| +
|
| -+#ifdef FREEBL_NO_DEPEND
|
| -+#include "stubs.h"
|
| -+#endif
|
| ++#ifndef FREEBL_POLY1305_H_
|
| ++#define FREEBL_POLY1305_H_
|
| +
|
| -+#include <string.h>
|
| -+#include <stdio.h>
|
| ++typedef unsigned char poly1305_state[512];
|
| +
|
| -+#include "seccomon.h"
|
| -+#include "secerr.h"
|
| -+#include "blapit.h"
|
| -+#include "poly1305/poly1305.h"
|
| -+#include "chacha20/chacha20.h"
|
| -+#include "chacha20poly1305.h"
|
| ++/* Poly1305Init sets up |state| so that it can be used to calculate an
|
| ++ * authentication tag with the one-time key |key|. Note that |key| is a
|
| ++ * one-time key and therefore there is no `reset' method because that would
|
| ++ * enable several messages to be authenticated with the same key. */
|
| ++extern void Poly1305Init(poly1305_state* state,
|
| ++ const unsigned char key[32]);
|
| +
|
| -+/* Poly1305Do writes the Poly1305 authenticator of the given additional data
|
| -+ * and ciphertext to |out|. */
|
| -+static void
|
| -+Poly1305Do(unsigned char *out,
|
| -+ const unsigned char *ad, unsigned int adLen,
|
| -+ const unsigned char *ciphertext, unsigned int ciphertextLen,
|
| -+ const unsigned char key[32])
|
| -+{
|
| -+ poly1305_state state;
|
| -+ unsigned int j;
|
| -+ unsigned char lengthBytes[8];
|
| -+ unsigned int i;
|
| ++/* Poly1305Update processes |in_len| bytes from |in|. It can be called zero or
|
| ++ * more times after poly1305_init. */
|
| ++extern void Poly1305Update(poly1305_state* state,
|
| ++ const unsigned char *in,
|
| ++ size_t inLen);
|
| +
|
| -+ Poly1305Init(&state, key);
|
| -+ j = adLen;
|
| -+ for (i = 0; i < sizeof(lengthBytes); i++) {
|
| -+ lengthBytes[i] = j;
|
| -+ j >>= 8;
|
| -+ }
|
| -+ Poly1305Update(&state, ad, adLen);
|
| -+ Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
|
| -+ j = ciphertextLen;
|
| -+ for (i = 0; i < sizeof(lengthBytes); i++) {
|
| -+ lengthBytes[i] = j;
|
| -+ j >>= 8;
|
| -+ }
|
| -+ Poly1305Update(&state, ciphertext, ciphertextLen);
|
| -+ Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
|
| -+ Poly1305Finish(&state, out);
|
| -+}
|
| ++/* Poly1305Finish completes the poly1305 calculation and writes a 16 byte
|
| ++ * authentication tag to |mac|. */
|
| ++extern void Poly1305Finish(poly1305_state* state,
|
| ++ unsigned char mac[16]);
|
| +
|
| -+SECStatus
|
| -+ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
|
| -+ const unsigned char *key, unsigned int keyLen,
|
| -+ unsigned int tagLen)
|
| ++#endif /* FREEBL_POLY1305_H_ */
|
| +diff -r c3565a90b8c4 lib/pk11wrap/pk11mech.c
|
| +--- a/lib/pk11wrap/pk11mech.c Fri Jan 03 20:59:10 2014 +0100
|
| ++++ b/lib/pk11wrap/pk11mech.c Tue Jan 07 12:11:36 2014 -0800
|
| +@@ -152,6 +152,8 @@
|
| + return CKM_SEED_CBC;
|
| + case CKK_CAMELLIA:
|
| + return CKM_CAMELLIA_CBC;
|
| ++ case CKK_NSS_CHACHA20:
|
| ++ return CKM_NSS_CHACHA20_POLY1305;
|
| + case CKK_AES:
|
| + return CKM_AES_CBC;
|
| + case CKK_DES:
|
| +@@ -219,6 +221,8 @@
|
| + case CKM_CAMELLIA_CBC_PAD:
|
| + case CKM_CAMELLIA_KEY_GEN:
|
| + return CKK_CAMELLIA;
|
| ++ case CKM_NSS_CHACHA20_POLY1305:
|
| ++ return CKK_NSS_CHACHA20;
|
| + case CKM_AES_ECB:
|
| + case CKM_AES_CBC:
|
| + case CKM_AES_CCM:
|
| +@@ -429,6 +433,8 @@
|
| + case CKM_CAMELLIA_CBC_PAD:
|
| + case CKM_CAMELLIA_KEY_GEN:
|
| + return CKM_CAMELLIA_KEY_GEN;
|
| ++ case CKM_NSS_CHACHA20_POLY1305:
|
| ++ return CKM_NSS_CHACHA20_KEY_GEN;
|
| + case CKM_AES_ECB:
|
| + case CKM_AES_CBC:
|
| + case CKM_AES_CCM:
|
| +diff -r c3565a90b8c4 lib/softoken/pkcs11.c
|
| +--- a/lib/softoken/pkcs11.c Fri Jan 03 20:59:10 2014 +0100
|
| ++++ b/lib/softoken/pkcs11.c Tue Jan 07 12:11:36 2014 -0800
|
| +@@ -368,6 +368,9 @@
|
| + {CKM_SEED_MAC, {16, 16, CKF_SN_VR}, PR_TRUE},
|
| + {CKM_SEED_MAC_GENERAL, {16, 16, CKF_SN_VR}, PR_TRUE},
|
| + {CKM_SEED_CBC_PAD, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
|
| ++ /* ------------------------- ChaCha20 Operations ---------------------- */
|
| ++ {CKM_NSS_CHACHA20_KEY_GEN, {32, 32, CKF_GENERATE}, PR_TRUE},
|
| ++ {CKM_NSS_CHACHA20_POLY1305,{32, 32, CKF_EN_DE}, PR_TRUE},
|
| + /* ------------------------- Hashing Operations ----------------------- */
|
| + {CKM_MD2, {0, 0, CKF_DIGEST}, PR_FALSE},
|
| + {CKM_MD2_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE},
|
| +diff -r c3565a90b8c4 lib/softoken/pkcs11c.c
|
| +--- a/lib/softoken/pkcs11c.c Fri Jan 03 20:59:10 2014 +0100
|
| ++++ b/lib/softoken/pkcs11c.c Tue Jan 07 12:11:36 2014 -0800
|
| +@@ -632,6 +632,97 @@
|
| + return rv;
|
| + }
|
| +
|
| ++static SFTKChaCha20Poly1305Info *
|
| ++sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key,
|
| ++ unsigned int keyLen,
|
| ++ const CK_NSS_AEAD_PARAMS* params)
|
| +{
|
| -+ if (keyLen != 32) {
|
| -+ PORT_SetError(SEC_ERROR_BAD_KEY);
|
| -+ return SECFailure;
|
| -+ }
|
| -+ if (tagLen == 0 || tagLen > 16) {
|
| ++ SFTKChaCha20Poly1305Info *ctx;
|
| ++
|
| ++ if (params->ulIvLen != sizeof(ctx->nonce)) {
|
| + PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| -+ return SECFailure;
|
| ++ return NULL;
|
| + }
|
| +
|
| -+ memcpy(ctx->key, key, sizeof(ctx->key));
|
| -+ ctx->tagLen = tagLen;
|
| -+
|
| -+ return SECSuccess;
|
| -+}
|
| -+
|
| -+ChaCha20Poly1305Context *
|
| -+ChaCha20Poly1305_CreateContext(const unsigned char *key, unsigned int keyLen,
|
| -+ unsigned int tagLen)
|
| -+{
|
| -+ ChaCha20Poly1305Context *ctx;
|
| -+
|
| -+ ctx = PORT_New(ChaCha20Poly1305Context);
|
| ++ ctx = PORT_New(SFTKChaCha20Poly1305Info);
|
| + if (ctx == NULL) {
|
| + return NULL;
|
| + }
|
| +
|
| -+ if (ChaCha20Poly1305_InitContext(ctx, key, keyLen, tagLen) != SECSuccess) {
|
| ++ if (ChaCha20Poly1305_InitContext(&ctx->freeblCtx, key, keyLen,
|
| ++ params->ulTagLen) != SECSuccess) {
|
| + PORT_Free(ctx);
|
| -+ ctx = NULL;
|
| ++ 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;
|
| +}
|
| +
|
| -+void
|
| -+ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit)
|
| ++static void
|
| ++sftk_ChaCha20Poly1305_DestroyContext(SFTKChaCha20Poly1305Info *ctx,
|
| ++ PRBool freeit)
|
| +{
|
| -+ memset(ctx, 0, sizeof(*ctx));
|
| ++ 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);
|
| + }
|
| +}
|
| +
|
| -+SECStatus
|
| -+ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx,
|
| -+ unsigned char *output, unsigned int *outputLen,
|
| -+ unsigned int maxOutputLen,
|
| -+ const unsigned char *input, unsigned int inputLen,
|
| -+ const unsigned char *nonce, unsigned int nonceLen,
|
| -+ const unsigned char *ad, unsigned int adLen)
|
| ++static SECStatus
|
| ++sftk_ChaCha20Poly1305_Encrypt(const SFTKChaCha20Poly1305Info *ctx,
|
| ++ unsigned char *output, unsigned int *outputLen,
|
| ++ unsigned int maxOutputLen,
|
| ++ const unsigned char *input, unsigned int inputLen)
|
| +{
|
| -+ unsigned char block[64];
|
| -+ unsigned char tag[16];
|
| ++ const unsigned char *ad = ctx->adOverflow;
|
| +
|
| -+ if (nonceLen != 8) {
|
| -+ PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| -+ return SECFailure;
|
| ++ if (ad == NULL) {
|
| ++ ad = ctx->ad;
|
| + }
|
| -+ *outputLen = inputLen + ctx->tagLen;
|
| -+ if (maxOutputLen < *outputLen) {
|
| -+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
| -+ return SECFailure;
|
| -+ }
|
| +
|
| -+ memset(block, 0, sizeof(block));
|
| -+ // Generate a block of keystream. The first 32 bytes will be the poly1305
|
| -+ // key. The remainder of the block is discarded.
|
| -+ ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0);
|
| -+ ChaCha20XOR(output, input, inputLen, ctx->key, nonce, 1);
|
| -+
|
| -+ Poly1305Do(tag, ad, adLen, output, inputLen, block);
|
| -+ memcpy(output + inputLen, tag, ctx->tagLen);
|
| -+
|
| -+ return SECSuccess;
|
| ++ return ChaCha20Poly1305_Seal(&ctx->freeblCtx, output, outputLen,
|
| ++ maxOutputLen, input, inputLen, ctx->nonce,
|
| ++ sizeof(ctx->nonce), ad, ctx->adLen);
|
| +}
|
| +
|
| -+SECStatus
|
| -+ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx,
|
| -+ unsigned char *output, unsigned int *outputLen,
|
| -+ unsigned int maxOutputLen,
|
| -+ const unsigned char *input, unsigned int inputLen,
|
| -+ const unsigned char *nonce, unsigned int nonceLen,
|
| -+ const unsigned char *ad, unsigned int 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)
|
| +{
|
| -+ unsigned char block[64];
|
| -+ unsigned char tag[16];
|
| ++ const unsigned char *ad = ctx->adOverflow;
|
| +
|
| -+ if (nonceLen != 8) {
|
| -+ PORT_SetError(SEC_ERROR_INPUT_LEN);
|
| -+ return SECFailure;
|
| ++ if (ad == NULL) {
|
| ++ ad = ctx->ad;
|
| + }
|
| -+ 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;
|
| -+ }
|
| +
|
| -+ memset(block, 0, sizeof(block));
|
| -+ // Generate a block of keystream. The first 32 bytes will be the poly1305
|
| -+ // key. The remainder of the block is discarded.
|
| -+ ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0);
|
| -+ Poly1305Do(tag, ad, adLen, input, inputLen - ctx->tagLen, block);
|
| -+ if (NSS_SecureMemcmp(tag, &input[inputLen - ctx->tagLen], ctx->tagLen) != 0) {
|
| -+ PORT_SetError(SEC_ERROR_BAD_DATA);
|
| -+ return SECFailure;
|
| -+ }
|
| -+
|
| -+ ChaCha20XOR(output, input, inputLen - ctx->tagLen, ctx->key, nonce, 1);
|
| -+
|
| -+ return SECSuccess;
|
| ++ return ChaCha20Poly1305_Open(&ctx->freeblCtx, output, outputLen,
|
| ++ maxOutputLen, input, inputLen, ctx->nonce,
|
| ++ sizeof(ctx->nonce), ad, ctx->adLen);
|
| +}
|
| -
|
| -Property changes on: nss/lib/freebl/chacha20poly1305.c
|
| -___________________________________________________________________
|
| -Added: svn:eol-style
|
| - + LF
|
| -
|
| -Index: nss/lib/freebl/chacha20/chacha20.h
|
| -===================================================================
|
| ---- nss/lib/freebl/chacha20/chacha20.h (revision 0)
|
| -+++ nss/lib/freebl/chacha20/chacha20.h (revision 0)
|
| -@@ -0,0 +1,22 @@
|
| -+/*
|
| -+ * chacha20.h - header file for ChaCha20 implementation.
|
| -+ *
|
| -+ * This Source Code Form is subject to the terms of the Mozilla Public
|
| -+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| +
|
| -+#ifndef FREEBL_CHACHA20_H_
|
| -+#define FREEBL_CHACHA20_H_
|
| -+
|
| -+#include <stdint.h>
|
| -+
|
| -+/* ChaCha20XOR encrypts |inLen| bytes from |in| with the given key and
|
| -+ * nonce and writes the result to |out|, which may be equal to |in|. The
|
| -+ * initial block counter is specified by |counter|. */
|
| -+extern void ChaCha20XOR(unsigned char *out,
|
| -+ const unsigned char *in, unsigned int inLen,
|
| -+ const unsigned char key[32],
|
| -+ const unsigned char nonce[8],
|
| -+ uint64_t counter);
|
| -+
|
| -+#endif /* FREEBL_CHACHA20_H_ */
|
| -
|
| -Property changes on: nss/lib/freebl/chacha20/chacha20.h
|
| -___________________________________________________________________
|
| -Added: svn:eol-style
|
| - + LF
|
| -
|
| -Index: nss/lib/freebl/chacha20/chacha20_vec.c
|
| -===================================================================
|
| ---- nss/lib/freebl/chacha20/chacha20_vec.c (revision 0)
|
| -+++ nss/lib/freebl/chacha20/chacha20_vec.c (revision 0)
|
| -@@ -0,0 +1,281 @@
|
| -+/* This Source Code Form is subject to the terms of the Mozilla Public
|
| -+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| -+
|
| -+/* This implementation is by Ted Krovetz and was submitted to SUPERCOP and
|
| -+ * marked as public domain. It was been altered to allow for non-aligned inputs
|
| -+ * and to allow the block counter to be passed in specifically. */
|
| -+
|
| -+#include <string.h>
|
| -+
|
| -+#include "chacha20.h"
|
| -+
|
| -+#ifndef CHACHA_RNDS
|
| -+#define CHACHA_RNDS 20 /* 8 (high speed), 20 (conservative), 12 (middle) */
|
| -+#endif
|
| -+
|
| -+/* Architecture-neutral way to specify 16-byte vector of ints */
|
| -+typedef unsigned vec __attribute__ ((vector_size (16)));
|
| -+
|
| -+/* This implementation is designed for Neon, SSE and AltiVec machines. The
|
| -+ * following specify how to do certain vector operations efficiently on
|
| -+ * each architecture, using intrinsics.
|
| -+ * This implementation supports parallel processing of multiple blocks,
|
| -+ * including potentially using general-purpose registers.
|
| -+ */
|
| -+#if __ARM_NEON__
|
| -+#include <arm_neon.h>
|
| -+#define GPR_TOO 1
|
| -+#define VBPI 2
|
| -+#define ONE (vec)vsetq_lane_u32(1,vdupq_n_u32(0),0)
|
| -+#define LOAD(m) (vec)(*((vec*)(m)))
|
| -+#define STORE(m,r) (*((vec*)(m))) = (r)
|
| -+#define ROTV1(x) (vec)vextq_u32((uint32x4_t)x,(uint32x4_t)x,1)
|
| -+#define ROTV2(x) (vec)vextq_u32((uint32x4_t)x,(uint32x4_t)x,2)
|
| -+#define ROTV3(x) (vec)vextq_u32((uint32x4_t)x,(uint32x4_t)x,3)
|
| -+#define ROTW16(x) (vec)vrev32q_u16((uint16x8_t)x)
|
| -+#if __clang__
|
| -+#define ROTW7(x) (x << ((vec){ 7, 7, 7, 7})) ^ (x >> ((vec){25,25,25,25}))
|
| -+#define ROTW8(x) (x << ((vec){ 8, 8, 8, 8})) ^ (x >> ((vec){24,24,24,24}))
|
| -+#define ROTW12(x) (x << ((vec){12,12,12,12})) ^ (x >> ((vec){20,20,20,20}))
|
| -+#else
|
| -+#define ROTW7(x) (vec)vsriq_n_u32(vshlq_n_u32((uint32x4_t)x,7),(uint32x4_t)x,25)
|
| -+#define ROTW8(x) (vec)vsriq_n_u32(vshlq_n_u32((uint32x4_t)x,8),(uint32x4_t)x,24)
|
| -+#define ROTW12(x) (vec)vsriq_n_u32(vshlq_n_u32((uint32x4_t)x,12),(uint32x4_t)x,20)
|
| -+#endif
|
| -+#elif __SSE2__
|
| -+#include <emmintrin.h>
|
| -+#define GPR_TOO 0
|
| -+#if __clang__
|
| -+#define VBPI 4
|
| -+#else
|
| -+#define VBPI 3
|
| -+#endif
|
| -+#define ONE (vec)_mm_set_epi32(0,0,0,1)
|
| -+#define LOAD(m) (vec)_mm_loadu_si128((__m128i*)(m))
|
| -+#define STORE(m,r) _mm_storeu_si128((__m128i*)(m), (__m128i) (r))
|
| -+#define ROTV1(x) (vec)_mm_shuffle_epi32((__m128i)x,_MM_SHUFFLE(0,3,2,1))
|
| -+#define ROTV2(x) (vec)_mm_shuffle_epi32((__m128i)x,_MM_SHUFFLE(1,0,3,2))
|
| -+#define ROTV3(x) (vec)_mm_shuffle_epi32((__m128i)x,_MM_SHUFFLE(2,1,0,3))
|
| -+#define ROTW7(x) (vec)(_mm_slli_epi32((__m128i)x, 7) ^ _mm_srli_epi32((__m128i)x,25))
|
| -+#define ROTW12(x) (vec)(_mm_slli_epi32((__m128i)x,12) ^ _mm_srli_epi32((__m128i)x,20))
|
| -+#if __SSSE3__
|
| -+#include <tmmintrin.h>
|
| -+#define ROTW8(x) (vec)_mm_shuffle_epi8((__m128i)x,_mm_set_epi8(14,13,12,15,10,9,8,11,6,5,4,7,2,1,0,3))
|
| -+#define ROTW16(x) (vec)_mm_shuffle_epi8((__m128i)x,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2))
|
| -+#else
|
| -+#define ROTW8(x) (vec)(_mm_slli_epi32((__m128i)x, 8) ^ _mm_srli_epi32((__m128i)x,24))
|
| -+#define ROTW16(x) (vec)(_mm_slli_epi32((__m128i)x,16) ^ _mm_srli_epi32((__m128i)x,16))
|
| -+#endif
|
| -+#else
|
| -+#error -- Implementation supports only machines with neon or SSE2
|
| -+#endif
|
| -+
|
| -+#ifndef REVV_BE
|
| -+#define REVV_BE(x) (x)
|
| -+#endif
|
| -+
|
| -+#ifndef REVW_BE
|
| -+#define REVW_BE(x) (x)
|
| -+#endif
|
| -+
|
| -+#define BPI (VBPI + GPR_TOO) /* Blocks computed per loop iteration */
|
| -+
|
| -+#define DQROUND_VECTORS(a,b,c,d) \
|
| -+ a += b; d ^= a; d = ROTW16(d); \
|
| -+ c += d; b ^= c; b = ROTW12(b); \
|
| -+ a += b; d ^= a; d = ROTW8(d); \
|
| -+ c += d; b ^= c; b = ROTW7(b); \
|
| -+ b = ROTV1(b); c = ROTV2(c); d = ROTV3(d); \
|
| -+ a += b; d ^= a; d = ROTW16(d); \
|
| -+ c += d; b ^= c; b = ROTW12(b); \
|
| -+ a += b; d ^= a; d = ROTW8(d); \
|
| -+ c += d; b ^= c; b = ROTW7(b); \
|
| -+ b = ROTV3(b); c = ROTV2(c); d = ROTV1(d);
|
| -+
|
| -+#define QROUND_WORDS(a,b,c,d) \
|
| -+ a = a+b; d ^= a; d = d<<16 | d>>16; \
|
| -+ c = c+d; b ^= c; b = b<<12 | b>>20; \
|
| -+ a = a+b; d ^= a; d = d<< 8 | d>>24; \
|
| -+ c = c+d; b ^= c; b = b<< 7 | b>>25;
|
| -+
|
| -+#define WRITE_XOR(in, op, d, v0, v1, v2, v3) \
|
| -+ STORE(op + d + 0, LOAD(in + d + 0) ^ REVV_BE(v0)); \
|
| -+ STORE(op + d + 4, LOAD(in + d + 4) ^ REVV_BE(v1)); \
|
| -+ STORE(op + d + 8, LOAD(in + d + 8) ^ REVV_BE(v2)); \
|
| -+ STORE(op + d +12, LOAD(in + d +12) ^ REVV_BE(v3));
|
| -+
|
| -+void ChaCha20XOR(
|
| -+ unsigned char *out,
|
| -+ const unsigned char *in,
|
| -+ unsigned int inlen,
|
| -+ const unsigned char key[32],
|
| -+ const unsigned char nonce[8],
|
| -+ uint64_t counter)
|
| -+{
|
| -+ unsigned iters, i, *op=(unsigned *)out, *ip=(unsigned *)in, *kp;
|
| -+#if defined(__ARM_NEON__)
|
| -+ unsigned *np;
|
| -+#endif
|
| -+ vec s0, s1, s2, s3;
|
| -+#if !defined(__ARM_NEON__) && !defined(__SSE2__)
|
| -+ __attribute__ ((aligned (16))) unsigned key[8], nonce[4];
|
| -+#endif
|
| -+ __attribute__ ((aligned (16))) unsigned chacha_const[] =
|
| -+ {0x61707865,0x3320646E,0x79622D32,0x6B206574};
|
| -+#if defined(__ARM_NEON__) || defined(__SSE2__)
|
| -+ kp = (unsigned *)key;
|
| -+#else
|
| -+ ((vec *)key)[0] = REVV_BE(((vec *)key)[0]);
|
| -+ ((vec *)key)[1] = REVV_BE(((vec *)key)[1]);
|
| -+ nonce[0] = REVW_BE(((unsigned *)nonce)[0]);
|
| -+ nonce[1] = REVW_BE(((unsigned *)nonce)[1]);
|
| -+ nonce[2] = REVW_BE(((unsigned *)nonce)[2]);
|
| -+ nonce[3] = REVW_BE(((unsigned *)nonce)[3]);
|
| -+ kp = (unsigned *)key;
|
| -+ np = (unsigned *)nonce;
|
| -+#endif
|
| -+#if defined(__ARM_NEON__)
|
| -+ np = (unsigned*) nonce;
|
| -+#endif
|
| -+ s0 = LOAD(chacha_const);
|
| -+ s1 = LOAD(&((vec*)kp)[0]);
|
| -+ s2 = LOAD(&((vec*)kp)[1]);
|
| -+ s3 = (vec) {
|
| -+ counter & 0xffffffff,
|
| -+ counter >> 32,
|
| -+ ((uint32_t*)nonce)[0],
|
| -+ ((uint32_t*)nonce)[1]
|
| -+ };
|
| -+
|
| -+ for (iters = 0; iters < inlen/(BPI*64); iters++) {
|
| -+#if GPR_TOO
|
| -+ register unsigned x0, x1, x2, x3, x4, x5, x6, x7, x8,
|
| -+ x9, x10, x11, x12, x13, x14, x15;
|
| -+#endif
|
| -+#if VBPI > 2
|
| -+ vec v8,v9,v10,v11;
|
| -+#endif
|
| -+#if VBPI > 3
|
| -+ vec v12,v13,v14,v15;
|
| -+#endif
|
| -+
|
| -+ vec v0,v1,v2,v3,v4,v5,v6,v7;
|
| -+ v4 = v0 = s0; v5 = v1 = s1; v6 = v2 = s2; v3 = s3;
|
| -+ v7 = v3 + ONE;
|
| -+#if VBPI > 2
|
| -+ v8 = v4; v9 = v5; v10 = v6;
|
| -+ v11 = v7 + ONE;
|
| -+#endif
|
| -+#if VBPI > 3
|
| -+ v12 = v8; v13 = v9; v14 = v10;
|
| -+ v15 = v11 + ONE;
|
| -+#endif
|
| -+#if GPR_TOO
|
| -+ x0 = chacha_const[0]; x1 = chacha_const[1];
|
| -+ x2 = chacha_const[2]; x3 = chacha_const[3];
|
| -+ x4 = kp[0]; x5 = kp[1]; x6 = kp[2]; x7 = kp[3];
|
| -+ x8 = kp[4]; x9 = kp[5]; x10 = kp[6]; x11 = kp[7];
|
| -+ x12 = (counter & 0xffffffff)+BPI*iters+(BPI-1); x13 = counter >> 32;
|
| -+ x14 = np[0]; x15 = np[1];
|
| -+#endif
|
| -+ for (i = CHACHA_RNDS/2; i; i--) {
|
| -+ DQROUND_VECTORS(v0,v1,v2,v3)
|
| -+ DQROUND_VECTORS(v4,v5,v6,v7)
|
| -+#if VBPI > 2
|
| -+ DQROUND_VECTORS(v8,v9,v10,v11)
|
| -+#endif
|
| -+#if VBPI > 3
|
| -+ DQROUND_VECTORS(v12,v13,v14,v15)
|
| -+#endif
|
| -+#if GPR_TOO
|
| -+ QROUND_WORDS( x0, x4, x8,x12)
|
| -+ QROUND_WORDS( x1, x5, x9,x13)
|
| -+ QROUND_WORDS( x2, x6,x10,x14)
|
| -+ QROUND_WORDS( x3, x7,x11,x15)
|
| -+ QROUND_WORDS( x0, x5,x10,x15)
|
| -+ QROUND_WORDS( x1, x6,x11,x12)
|
| -+ QROUND_WORDS( x2, x7, x8,x13)
|
| -+ QROUND_WORDS( x3, x4, x9,x14)
|
| -+#endif
|
| + /** NSC_CryptInit initializes an encryption/Decryption operation.
|
| + *
|
| + * Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey.
|
| +@@ -1027,6 +1118,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;
|
| + }
|
| -+
|
| -+ WRITE_XOR(ip, op, 0, v0+s0, v1+s1, v2+s2, v3+s3)
|
| -+ s3 += ONE;
|
| -+ WRITE_XOR(ip, op, 16, v4+s0, v5+s1, v6+s2, v7+s3)
|
| -+ s3 += ONE;
|
| -+#if VBPI > 2
|
| -+ WRITE_XOR(ip, op, 32, v8+s0, v9+s1, v10+s2, v11+s3)
|
| -+ s3 += ONE;
|
| -+#endif
|
| -+#if VBPI > 3
|
| -+ WRITE_XOR(ip, op, 48, v12+s0, v13+s1, v14+s2, v15+s3)
|
| -+ s3 += ONE;
|
| -+#endif
|
| -+ ip += VBPI*16;
|
| -+ op += VBPI*16;
|
| -+#if GPR_TOO
|
| -+ op[0] = REVW_BE(REVW_BE(ip[0]) ^ (x0 + chacha_const[0]));
|
| -+ op[1] = REVW_BE(REVW_BE(ip[1]) ^ (x1 + chacha_const[1]));
|
| -+ op[2] = REVW_BE(REVW_BE(ip[2]) ^ (x2 + chacha_const[2]));
|
| -+ op[3] = REVW_BE(REVW_BE(ip[3]) ^ (x3 + chacha_const[3]));
|
| -+ op[4] = REVW_BE(REVW_BE(ip[4]) ^ (x4 + kp[0]));
|
| -+ op[5] = REVW_BE(REVW_BE(ip[5]) ^ (x5 + kp[1]));
|
| -+ op[6] = REVW_BE(REVW_BE(ip[6]) ^ (x6 + kp[2]));
|
| -+ op[7] = REVW_BE(REVW_BE(ip[7]) ^ (x7 + kp[3]));
|
| -+ op[8] = REVW_BE(REVW_BE(ip[8]) ^ (x8 + kp[4]));
|
| -+ op[9] = REVW_BE(REVW_BE(ip[9]) ^ (x9 + kp[5]));
|
| -+ op[10] = REVW_BE(REVW_BE(ip[10]) ^ (x10 + kp[6]));
|
| -+ op[11] = REVW_BE(REVW_BE(ip[11]) ^ (x11 + kp[7]));
|
| -+ op[12] = REVW_BE(REVW_BE(ip[12]) ^ (x12 + (counter & 0xffffffff)+BPI*iters+(BPI-1)));
|
| -+ op[13] = REVW_BE(REVW_BE(ip[13]) ^ (x13 + (counter >> 32)));
|
| -+ op[14] = REVW_BE(REVW_BE(ip[14]) ^ (x14 + np[0]));
|
| -+ op[15] = REVW_BE(REVW_BE(ip[15]) ^ (x15 + np[1]));
|
| -+ s3 += ONE;
|
| -+ ip += 16;
|
| -+ op += 16;
|
| -+#endif
|
| -+ }
|
| -+
|
| -+ for (iters = inlen%(BPI*64)/64; iters != 0; iters--) {
|
| -+ vec v0 = s0, v1 = s1, v2 = s2, v3 = s3;
|
| -+ for (i = CHACHA_RNDS/2; i; i--) {
|
| -+ DQROUND_VECTORS(v0,v1,v2,v3);
|
| ++ context->multi = PR_FALSE;
|
| ++ if (key_type != CKK_NSS_CHACHA20) {
|
| ++ crv = CKR_KEY_TYPE_INCONSISTENT;
|
| ++ break;
|
| + }
|
| -+ WRITE_XOR(ip, op, 0, v0+s0, v1+s1, v2+s2, v3+s3)
|
| -+ s3 += ONE;
|
| -+ ip += 16;
|
| -+ op += 16;
|
| -+ }
|
| -+
|
| -+ inlen = inlen % 64;
|
| -+ if (inlen) {
|
| -+ __attribute__ ((aligned (16))) vec buf[4];
|
| -+ vec v0,v1,v2,v3;
|
| -+ v0 = s0; v1 = s1; v2 = s2; v3 = s3;
|
| -+ for (i = CHACHA_RNDS/2; i; i--) {
|
| -+ DQROUND_VECTORS(v0,v1,v2,v3);
|
| ++ att = sftk_FindAttribute(key,CKA_VALUE);
|
| ++ if (att == NULL) {
|
| ++ crv = CKR_KEY_HANDLE_INVALID;
|
| ++ break;
|
| + }
|
| -+
|
| -+ if (inlen >= 16) {
|
| -+ STORE(op + 0, LOAD(ip + 0) ^ REVV_BE(v0 + s0));
|
| -+ if (inlen >= 32) {
|
| -+ STORE(op + 4, LOAD(ip + 4) ^ REVV_BE(v1 + s1));
|
| -+ if (inlen >= 48) {
|
| -+ STORE(op + 8, LOAD(ip + 8) ^ REVV_BE(v2 + s2));
|
| -+ buf[3] = REVV_BE(v3 + s3);
|
| -+ } else {
|
| -+ buf[2] = REVV_BE(v2 + s2);
|
| -+ }
|
| -+ } else {
|
| -+ buf[1] = REVV_BE(v1 + s1);
|
| -+ }
|
| -+ } else {
|
| -+ buf[0] = REVV_BE(v0 + s0);
|
| ++ 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;
|
| +
|
| -+ for (i=inlen & ~15; i<inlen; i++) {
|
| -+ ((char *)op)[i] = ((char *)ip)[i] ^ ((char *)buf)[i];
|
| -+ }
|
| -+ }
|
| -+}
|
| -
|
| -Property changes on: nss/lib/freebl/chacha20/chacha20_vec.c
|
| -___________________________________________________________________
|
| -Added: svn:eol-style
|
| - + LF
|
| -
|
| -Index: nss/lib/freebl/chacha20/chacha20.c
|
| -===================================================================
|
| ---- nss/lib/freebl/chacha20/chacha20.c (revision 0)
|
| -+++ nss/lib/freebl/chacha20/chacha20.c (revision 0)
|
| -@@ -0,0 +1,108 @@
|
| -+/* This Source Code Form is subject to the terms of the Mozilla Public
|
| -+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| -+
|
| -+/* Adopted from the public domain code in NaCl by djb. */
|
| -+
|
| -+#include <string.h>
|
| -+#include <stdio.h>
|
| -+
|
| -+#include "prtypes.h"
|
| -+#include "chacha20.h"
|
| -+
|
| -+#define ROTL32(v, n) (((v) << (n)) | ((v) >> (32 - (n))))
|
| -+#define ROTATE(v, c) ROTL32((v), (c))
|
| -+#define XOR(v, w) ((v) ^ (w))
|
| -+#define PLUS(x, y) ((x) + (y))
|
| -+
|
| -+#define U32TO8_LITTLE(p, v) \
|
| -+ { (p)[0] = ((v) ) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \
|
| -+ (p)[2] = ((v) >> 16) & 0xff; (p)[3] = ((v) >> 24) & 0xff; }
|
| -+#define U8TO32_LITTLE(p) \
|
| -+ (((PRUint32)((p)[0]) ) | ((PRUint32)((p)[1]) << 8) | \
|
| -+ ((PRUint32)((p)[2]) << 16) | ((PRUint32)((p)[3]) << 24) )
|
| -+
|
| -+#define QUARTERROUND(a,b,c,d) \
|
| -+ x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \
|
| -+ x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]),12); \
|
| -+ x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \
|
| -+ x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7);
|
| -+
|
| -+static void ChaChaCore(unsigned char output[64], const PRUint32 input[16],
|
| -+ int num_rounds) {
|
| -+ PRUint32 x[16];
|
| -+ int i;
|
| -+
|
| -+ memcpy(x, input, sizeof(PRUint32) * 16);
|
| -+ for (i = num_rounds; i > 0; i -= 2) {
|
| -+ QUARTERROUND( 0, 4, 8,12)
|
| -+ QUARTERROUND( 1, 5, 9,13)
|
| -+ QUARTERROUND( 2, 6,10,14)
|
| -+ QUARTERROUND( 3, 7,11,15)
|
| -+ QUARTERROUND( 0, 5,10,15)
|
| -+ QUARTERROUND( 1, 6,11,12)
|
| -+ QUARTERROUND( 2, 7, 8,13)
|
| -+ QUARTERROUND( 3, 4, 9,14)
|
| -+ }
|
| -+
|
| -+ for (i = 0; i < 16; ++i) {
|
| -+ x[i] = PLUS(x[i], input[i]);
|
| -+ }
|
| -+ for (i = 0; i < 16; ++i) {
|
| -+ U32TO8_LITTLE(output + 4 * i, x[i]);
|
| -+ }
|
| -+}
|
| -+
|
| -+static const unsigned char sigma[16] = "expand 32-byte k";
|
| -+
|
| -+void ChaCha20XOR(unsigned char *out, const unsigned char *in, unsigned int inLen,
|
| -+ const unsigned char key[32], const unsigned char nonce[8],
|
| -+ uint64_t counter) {
|
| -+ unsigned char block[64];
|
| -+ PRUint32 input[16];
|
| -+ unsigned int u;
|
| -+ unsigned int i;
|
| -+
|
| -+ input[4] = U8TO32_LITTLE(key + 0);
|
| -+ input[5] = U8TO32_LITTLE(key + 4);
|
| -+ input[6] = U8TO32_LITTLE(key + 8);
|
| -+ input[7] = U8TO32_LITTLE(key + 12);
|
| -+
|
| -+ input[8] = U8TO32_LITTLE(key + 16);
|
| -+ input[9] = U8TO32_LITTLE(key + 20);
|
| -+ input[10] = U8TO32_LITTLE(key + 24);
|
| -+ input[11] = U8TO32_LITTLE(key + 28);
|
| -+
|
| -+ input[0] = U8TO32_LITTLE(sigma + 0);
|
| -+ input[1] = U8TO32_LITTLE(sigma + 4);
|
| -+ input[2] = U8TO32_LITTLE(sigma + 8);
|
| -+ input[3] = U8TO32_LITTLE(sigma + 12);
|
| -+
|
| -+ input[12] = counter;
|
| -+ input[13] = counter >> 32;
|
| -+ input[14] = U8TO32_LITTLE(nonce + 0);
|
| -+ input[15] = U8TO32_LITTLE(nonce + 4);
|
| -+
|
| -+ while (inLen >= 64) {
|
| -+ ChaChaCore(block, input, 20);
|
| -+ for (i = 0; i < 64; i++) {
|
| -+ out[i] = in[i] ^ block[i];
|
| -+ }
|
| -+
|
| -+ input[12]++;
|
| -+ if (input[12] == 0) {
|
| -+ input[13]++;
|
| -+ }
|
| -+
|
| -+ inLen -= 64;
|
| -+ in += 64;
|
| -+ out += 64;
|
| -+ }
|
| -+
|
| -+ if (inLen > 0) {
|
| -+ ChaChaCore(block, input, 20);
|
| -+ for (i = 0; i < inLen; i++) {
|
| -+ out[i] = in[i] ^ block[i];
|
| -+ }
|
| -+ }
|
| -+}
|
| -
|
| -Property changes on: nss/lib/freebl/chacha20/chacha20.c
|
| -___________________________________________________________________
|
| -Added: svn:eol-style
|
| - + LF
|
| -
|
| -Index: nss/lib/freebl/chacha20poly1305.h
|
| -===================================================================
|
| ---- nss/lib/freebl/chacha20poly1305.h (revision 0)
|
| -+++ nss/lib/freebl/chacha20poly1305.h (revision 0)
|
| -@@ -0,0 +1,15 @@
|
| -+/* This Source Code Form is subject to the terms of the Mozilla Public
|
| -+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| -+
|
| -+#ifndef _CHACHA20_POLY1305_H_
|
| -+#define _CHACHA20_POLY1305_H_ 1
|
| -+
|
| -+/* ChaCha20Poly1305ContextStr saves the key and tag length for a
|
| -+ * ChaCha20+Poly1305 AEAD operation. */
|
| -+struct ChaCha20Poly1305ContextStr {
|
| -+ unsigned char key[32];
|
| -+ unsigned char tagLen;
|
| + case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
|
| + context->doPad = PR_TRUE;
|
| + /* fall thru */
|
| +@@ -3601,6 +3721,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;
|
| +@@ -3846,6 +3970,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
|
| +diff -r c3565a90b8c4 lib/softoken/pkcs11i.h
|
| +--- a/lib/softoken/pkcs11i.h Fri Jan 03 20:59:10 2014 +0100
|
| ++++ b/lib/softoken/pkcs11i.h Tue Jan 07 12:11:36 2014 -0800
|
| +@@ -14,6 +14,7 @@
|
| + #include "pkcs11t.h"
|
| +
|
| + #include "sftkdbt.h"
|
| ++#include "chacha20poly1305.h"
|
| + #include "hasht.h"
|
| +
|
| + /*
|
| +@@ -104,6 +105,7 @@
|
| + typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo;
|
| + typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo;
|
| + typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo;
|
| ++typedef struct SFTKChaCha20Poly1305InfoStr SFTKChaCha20Poly1305Info;
|
| + typedef struct SFTKItemTemplateStr SFTKItemTemplate;
|
| +
|
| + /* define function pointer typdefs for pointer tables */
|
| +@@ -399,6 +401,16 @@
|
| + unsigned int keySize;
|
| + };
|
| +
|
| ++/* SFTKChaCha20Poly1305Info saves the key, tag length, nonce, and additional
|
| ++ * data for a ChaCha20+Poly1305 AEAD operation. */
|
| ++struct SFTKChaCha20Poly1305InfoStr {
|
| ++ ChaCha20Poly1305Context freeblCtx;
|
| ++ unsigned char nonce[8];
|
| ++ unsigned char ad[16];
|
| ++ unsigned char *adOverflow;
|
| ++ unsigned int adLen;
|
| +};
|
| +
|
| -+#endif /* _CHACHA20_POLY1305_H_ */
|
| -
|
| -Property changes on: nss/lib/freebl/chacha20poly1305.h
|
| -___________________________________________________________________
|
| -Added: svn:eol-style
|
| - + LF
|
| -
|
| -Index: nss/lib/pk11wrap/pk11mech.c
|
| -===================================================================
|
| ---- nss/lib/pk11wrap/pk11mech.c (revision 228205)
|
| -+++ nss/lib/pk11wrap/pk11mech.c (working copy)
|
| -@@ -152,6 +152,8 @@
|
| - return CKM_SEED_CBC;
|
| - case CKK_CAMELLIA:
|
| - return CKM_CAMELLIA_CBC;
|
| -+ case CKK_NSS_CHACHA20:
|
| -+ return CKM_NSS_CHACHA20_POLY1305;
|
| - case CKK_AES:
|
| - return CKM_AES_CBC;
|
| - case CKK_DES:
|
| -@@ -219,6 +221,8 @@
|
| - case CKM_CAMELLIA_CBC_PAD:
|
| - case CKM_CAMELLIA_KEY_GEN:
|
| - return CKK_CAMELLIA;
|
| -+ case CKM_NSS_CHACHA20_POLY1305:
|
| -+ return CKK_NSS_CHACHA20;
|
| - case CKM_AES_ECB:
|
| - case CKM_AES_CBC:
|
| - case CKM_AES_CCM:
|
| -@@ -429,6 +433,8 @@
|
| - case CKM_CAMELLIA_CBC_PAD:
|
| - case CKM_CAMELLIA_KEY_GEN:
|
| - return CKM_CAMELLIA_KEY_GEN;
|
| -+ case CKM_NSS_CHACHA20_POLY1305:
|
| -+ return CKM_NSS_CHACHA20_KEY_GEN;
|
| - case CKM_AES_ECB:
|
| - case CKM_AES_CBC:
|
| - case CKM_AES_CCM:
|
| -Index: nss/lib/util/pkcs11n.h
|
| -===================================================================
|
| ---- nss/lib/util/pkcs11n.h (revision 228205)
|
| -+++ nss/lib/util/pkcs11n.h (working copy)
|
| + /*
|
| + * Template based on SECItems, suitable for passing as arrays
|
| + */
|
| +diff -r c3565a90b8c4 lib/util/pkcs11n.h
|
| +--- a/lib/util/pkcs11n.h Fri Jan 03 20:59:10 2014 +0100
|
| ++++ b/lib/util/pkcs11n.h Tue Jan 07 12:11:36 2014 -0800
|
| @@ -51,6 +51,8 @@
|
| #define CKK_NSS_JPAKE_ROUND1 (CKK_NSS + 2)
|
| #define CKK_NSS_JPAKE_ROUND2 (CKK_NSS + 3)
|
|
|