Merge branch 'master' into ti
This commit is contained in:
commit
a73a160aaf
32
configure.ac
32
configure.ac
@ -401,6 +401,21 @@ fi
|
||||
AM_CONDITIONAL([BUILD_AESNI], [test "x$ENABLED_AESNI" = "xyes"])
|
||||
|
||||
|
||||
# POLY1305
|
||||
AC_ARG_ENABLE([poly1305],
|
||||
[ --enable-poly1305 Enable CyaSSL POLY1305 support (default: disabled)],
|
||||
[ ENABLED_POLY1305=$enableval ],
|
||||
[ ENABLED_POLY1305=no ]
|
||||
)
|
||||
|
||||
if test "$ENABLED_POLY1305" = "yes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_POLY1305"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([BUILD_POLY1305], [test "x$ENABLED_POLY1305" = "xyes"])
|
||||
|
||||
|
||||
# Camellia
|
||||
AC_ARG_ENABLE([camellia],
|
||||
[ --enable-camellia Enable CyaSSL Camellia support (default: disabled)],
|
||||
@ -1062,6 +1077,21 @@ fi
|
||||
AM_CONDITIONAL([BUILD_RABBIT], [test "x$ENABLED_RABBIT" = "xyes"])
|
||||
|
||||
|
||||
# CHACHA
|
||||
AC_ARG_ENABLE([chacha],
|
||||
[ --enable-chacha Enable CHACHA (default: disabled)],
|
||||
[ ENABLED_CHACHA=$enableval ],
|
||||
[ ENABLED_CHACHA=no ]
|
||||
)
|
||||
|
||||
if test "$ENABLED_CHACHA" = "yes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_CHACHA"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([BUILD_CHACHA], [test "x$ENABLED_CHACHA" = "xyes"])
|
||||
|
||||
|
||||
# FIPS
|
||||
AC_ARG_ENABLE([fips],
|
||||
[ --enable-fips Enable FIPS 140-2 (default: disabled)],
|
||||
@ -1797,11 +1827,13 @@ echo " * certgen: $ENABLED_CERTGEN"
|
||||
echo " * certreq: $ENABLED_CERTREQ"
|
||||
echo " * HC-128: $ENABLED_HC128"
|
||||
echo " * RABBIT: $ENABLED_RABBIT"
|
||||
echo " * CHACHA: $ENABLED_CHACHA"
|
||||
echo " * Hash DRBG: $ENABLED_HASHDRBG"
|
||||
echo " * PWDBASED: $ENABLED_PWDBASED"
|
||||
echo " * HKDF: $ENABLED_HKDF"
|
||||
echo " * MD4: $ENABLED_MD4"
|
||||
echo " * PSK: $ENABLED_PSK"
|
||||
echo " * Poly1305: $ENABLED_POLY1305"
|
||||
echo " * LEANPSK: $ENABLED_LEANPSK"
|
||||
echo " * RSA: $ENABLED_RSA"
|
||||
echo " * DSA: $ENABLED_DSA"
|
||||
|
@ -34,7 +34,9 @@
|
||||
#include <cyassl/ctaocrypt/arc4.h>
|
||||
#include <cyassl/ctaocrypt/hc128.h>
|
||||
#include <cyassl/ctaocrypt/rabbit.h>
|
||||
#include <cyassl/ctaocrypt/chacha.h>
|
||||
#include <cyassl/ctaocrypt/aes.h>
|
||||
#include <cyassl/ctaocrypt/poly1305.h>
|
||||
#include <cyassl/ctaocrypt/camellia.h>
|
||||
#include <cyassl/ctaocrypt/md5.h>
|
||||
#include <cyassl/ctaocrypt/sha.h>
|
||||
@ -85,10 +87,12 @@ void bench_des(void);
|
||||
void bench_arc4(void);
|
||||
void bench_hc128(void);
|
||||
void bench_rabbit(void);
|
||||
void bench_chacha(void);
|
||||
void bench_aes(int);
|
||||
void bench_aesgcm(void);
|
||||
void bench_aesccm(void);
|
||||
void bench_aesctr(void);
|
||||
void bench_poly1305(void);
|
||||
void bench_camellia(void);
|
||||
|
||||
void bench_md5(void);
|
||||
@ -189,6 +193,9 @@ int benchmark_test(void *args)
|
||||
#ifndef NO_RABBIT
|
||||
bench_rabbit();
|
||||
#endif
|
||||
#ifdef HAVE_CHACHA
|
||||
bench_chacha();
|
||||
#endif
|
||||
#ifndef NO_DES3
|
||||
bench_des();
|
||||
#endif
|
||||
@ -198,6 +205,9 @@ int benchmark_test(void *args)
|
||||
#ifndef NO_MD5
|
||||
bench_md5();
|
||||
#endif
|
||||
#ifdef HAVE_POLY1305
|
||||
bench_poly1305();
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
bench_sha();
|
||||
#endif
|
||||
@ -425,6 +435,41 @@ void bench_aesccm(void)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
void bench_poly1305()
|
||||
{
|
||||
Poly1305 enc;
|
||||
byte mac[16];
|
||||
double start, total, persec;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = Poly1305SetKey(&enc, key, 32);
|
||||
if (ret != 0) {
|
||||
printf("Poly1305SetKey failed, ret = %d\n", ret);
|
||||
return;
|
||||
}
|
||||
start = current_time(1);
|
||||
|
||||
for(i = 0; i < numBlocks; i++)
|
||||
Poly1305Update(&enc, plain, sizeof(plain));
|
||||
|
||||
Poly1305Final(&enc, mac);
|
||||
total = current_time(0) - start;
|
||||
|
||||
persec = 1 / total * numBlocks;
|
||||
#ifdef BENCH_EMBEDDED
|
||||
/* since using kB, convert to MB/s */
|
||||
persec = persec / 1024;
|
||||
#endif
|
||||
|
||||
printf("POLY1305 %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
|
||||
blockType, total, persec);
|
||||
}
|
||||
#endif /* HAVE_POLY1305 */
|
||||
|
||||
|
||||
#ifdef HAVE_CAMELLIA
|
||||
void bench_camellia(void)
|
||||
{
|
||||
@ -580,6 +625,33 @@ void bench_rabbit(void)
|
||||
#endif /* NO_RABBIT */
|
||||
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
void bench_chacha(void)
|
||||
{
|
||||
ChaCha enc;
|
||||
double start, total, persec;
|
||||
int i;
|
||||
|
||||
Chacha_SetKey(&enc, key, 16);
|
||||
start = current_time(1);
|
||||
|
||||
for (i = 0; i < numBlocks; i++) {
|
||||
Chacha_SetIV(&enc, iv, 0);
|
||||
Chacha_Process(&enc, cipher, plain, sizeof(plain));
|
||||
}
|
||||
total = current_time(0) - start;
|
||||
persec = 1 / total * numBlocks;
|
||||
#ifdef BENCH_EMBEDDED
|
||||
/* since using kB, convert to MB/s */
|
||||
persec = persec / 1024;
|
||||
#endif
|
||||
|
||||
printf("CHACHA %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks, blockType, total, persec);
|
||||
|
||||
}
|
||||
#endif /* HAVE_CHACHA*/
|
||||
|
||||
|
||||
#ifndef NO_MD5
|
||||
void bench_md5(void)
|
||||
{
|
||||
|
@ -216,6 +216,10 @@
|
||||
RelativePath=".\include\rabbit.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\chacha.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\random.h"
|
||||
>
|
||||
@ -304,6 +308,10 @@
|
||||
RelativePath=".\src\rabbit.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\chacha.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\random.c"
|
||||
>
|
||||
|
250
ctaocrypt/src/chacha.c
Normal file
250
ctaocrypt/src/chacha.c
Normal file
@ -0,0 +1,250 @@
|
||||
/* chacha.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of CyaSSL.
|
||||
*
|
||||
* CyaSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CyaSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* based from
|
||||
* chacha-ref.c version 20080118
|
||||
* D. J. Bernstein
|
||||
* Public domain.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
|
||||
#include <cyassl/ctaocrypt/chacha.h>
|
||||
#include <cyassl/ctaocrypt/error-crypt.h>
|
||||
#include <cyassl/ctaocrypt/logging.h>
|
||||
#ifdef NO_INLINE
|
||||
#include <cyassl/ctaocrypt/misc.h>
|
||||
#else
|
||||
#include <ctaocrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef BIG_ENDIAN_ORDER
|
||||
#define LITTLE32(x) ByteReverseWord32(x)
|
||||
#else
|
||||
#define LITTLE32(x) (x)
|
||||
#endif
|
||||
|
||||
/* Number of rounds */
|
||||
#define ROUNDS 20
|
||||
|
||||
#define U32C(v) (v##U)
|
||||
#define U32V(v) ((word32)(v) & U32C(0xFFFFFFFF))
|
||||
#define U8TO32_LITTLE(p) LITTLE32(((word32*)(p))[0])
|
||||
|
||||
#define ROTATE(v,c) rotlFixed(v, c)
|
||||
#define XOR(v,w) ((v) ^ (w))
|
||||
#define PLUS(v,w) (U32V((v) + (w)))
|
||||
#define PLUSONE(v) (PLUS((v),1))
|
||||
|
||||
#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);
|
||||
|
||||
|
||||
/**
|
||||
* Set up iv(nonce). Earlier versions used 64 bits instead of 96, this version
|
||||
* uses the typical AEAD 96 bit nonce and can do record sizes of 256 GB.
|
||||
*/
|
||||
int Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter)
|
||||
{
|
||||
word32 temp[3]; /* used for alignment of memory */
|
||||
XMEMSET(temp, 0, 12);
|
||||
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
word32 i;
|
||||
printf("NONCE : ");
|
||||
for (i = 0; i < 12; i++) {
|
||||
printf("%02x", inIv[i]);
|
||||
}
|
||||
printf("\n\n");
|
||||
#endif
|
||||
|
||||
XMEMCPY(temp, inIv, 12);
|
||||
|
||||
ctx->X[12] = counter; /* block counter */
|
||||
ctx->X[13] = temp[0]; /* fixed variable from nonce */
|
||||
ctx->X[14] = temp[1]; /* counter from nonce */
|
||||
ctx->X[15] = temp[2]; /* counter from nonce */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* "expand 32-byte k" as unsigned 32 byte */
|
||||
static const word32 sigma[4] = {0x61707865, 0x3320646e, 0x79622d32, 0x6b206574};
|
||||
/* "expand 16-byte k" as unsigned 16 byte */
|
||||
static const word32 tau[4] = {0x61707865, 0x3120646e, 0x79622d36, 0x6b206574};
|
||||
|
||||
/**
|
||||
* Key setup. 8 word iv (nonce)
|
||||
*/
|
||||
int Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz)
|
||||
{
|
||||
const word32* constants;
|
||||
const byte* k;
|
||||
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef XSTREAM_ALIGN
|
||||
word32 alignKey[keySz / 4];
|
||||
if ((word)key % 4) {
|
||||
CYASSL_MSG("ChachaSetKey unaligned key");
|
||||
XMEMCPY(alignKey, key, sizeof(alignKey));
|
||||
k = (byte*)alignKey;
|
||||
}
|
||||
else {
|
||||
k = key;
|
||||
}
|
||||
#else
|
||||
k = key;
|
||||
#endif /* XSTREAM_ALIGN */
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
word32 i;
|
||||
printf("ChaCha key used :\n");
|
||||
for (i = 0; i < keySz; i++) {
|
||||
printf("%02x", key[i]);
|
||||
if ((i + 1) % 8 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n\n");
|
||||
#endif
|
||||
|
||||
ctx->X[4] = U8TO32_LITTLE(k + 0);
|
||||
ctx->X[5] = U8TO32_LITTLE(k + 4);
|
||||
ctx->X[6] = U8TO32_LITTLE(k + 8);
|
||||
ctx->X[7] = U8TO32_LITTLE(k + 12);
|
||||
if (keySz == 32) {
|
||||
k += 16;
|
||||
constants = sigma;
|
||||
}
|
||||
else {
|
||||
/* key size of 128 */
|
||||
if (keySz != 16)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
constants = tau;
|
||||
}
|
||||
ctx->X[ 8] = U8TO32_LITTLE(k + 0);
|
||||
ctx->X[ 9] = U8TO32_LITTLE(k + 4);
|
||||
ctx->X[10] = U8TO32_LITTLE(k + 8);
|
||||
ctx->X[11] = U8TO32_LITTLE(k + 12);
|
||||
ctx->X[ 0] = U8TO32_LITTLE(constants + 0);
|
||||
ctx->X[ 1] = U8TO32_LITTLE(constants + 1);
|
||||
ctx->X[ 2] = U8TO32_LITTLE(constants + 2);
|
||||
ctx->X[ 3] = U8TO32_LITTLE(constants + 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts word into bytes with rotations having been done.
|
||||
*/
|
||||
static INLINE void Chacha_wordtobyte(word32 output[16], const word32 input[16])
|
||||
{
|
||||
word32 x[16];
|
||||
word32 i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
x[i] = input[i];
|
||||
}
|
||||
|
||||
for (i = (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++) {
|
||||
output[i] = LITTLE32(x[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt a stream of bytes
|
||||
*/
|
||||
static void Chacha_encrypt_bytes(ChaCha* ctx, const byte* m, byte* c,
|
||||
word32 bytes)
|
||||
{
|
||||
byte* output;
|
||||
word32 temp[16]; /* used to make sure aligned */
|
||||
word32 i;
|
||||
|
||||
output = (byte*)temp;
|
||||
|
||||
if (!bytes) return;
|
||||
for (;;) {
|
||||
Chacha_wordtobyte(temp, ctx->X);
|
||||
ctx->X[12] = PLUSONE(ctx->X[12]);
|
||||
if (bytes <= 64) {
|
||||
for (i = 0; i < bytes; ++i) {
|
||||
c[i] = m[i] ^ output[i];
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < 64; ++i) {
|
||||
c[i] = m[i] ^ output[i];
|
||||
}
|
||||
bytes -= 64;
|
||||
c += 64;
|
||||
m += 64;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* API to encrypt/decrypt a message of any size.
|
||||
*/
|
||||
int Chacha_Process(ChaCha* ctx, byte* output, const byte* input, word32 msglen)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
Chacha_encrypt_bytes(ctx, input, output, msglen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_CHACHA*/
|
||||
|
538
ctaocrypt/src/poly1305.c
Normal file
538
ctaocrypt/src/poly1305.c
Normal file
@ -0,0 +1,538 @@
|
||||
/* poly1305.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of CyaSSL.
|
||||
*
|
||||
* CyaSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CyaSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* Based off the public domain implementations by Andrew Moon
|
||||
* and Daniel J. Bernstein
|
||||
*/
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
#include <cyassl/ctaocrypt/poly1305.h>
|
||||
#include <cyassl/ctaocrypt/error-crypt.h>
|
||||
#include <cyassl/ctaocrypt/logging.h>
|
||||
#ifdef NO_INLINE
|
||||
#include <cyassl/ctaocrypt/misc.h>
|
||||
#else
|
||||
#include <ctaocrypt/src/misc.c>
|
||||
#endif
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* 4127 warning constant while(1) */
|
||||
#pragma warning(disable: 4127)
|
||||
#endif
|
||||
|
||||
#if defined(POLY130564)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define POLY1305_NOINLINE __declspec(noinline)
|
||||
#elif defined(__GNUC__)
|
||||
#define POLY1305_NOINLINE __attribute__((noinline))
|
||||
#else
|
||||
#define POLY1305_NOINLINE
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
|
||||
typedef struct word128 {
|
||||
word64 lo;
|
||||
word64 hi;
|
||||
} word128;
|
||||
|
||||
#define MUL(out, x, y) out.lo = _umul128((x), (y), &out.hi)
|
||||
#define ADD(out, in) { word64 t = out.lo; out.lo += in.lo;
|
||||
out.hi += (out.lo < t) + in.hi; }
|
||||
#define ADDLO(out, in) { word64 t = out.lo; out.lo += in;
|
||||
out.hi += (out.lo < t); }
|
||||
#define SHR(in, shift) (__shiftright128(in.lo, in.hi, (shift)))
|
||||
#define LO(in) (in.lo)
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#if defined(__SIZEOF_INT128__)
|
||||
typedef unsigned __int128 word128;
|
||||
#else
|
||||
typedef unsigned word128 __attribute__((mode(TI)));
|
||||
#endif
|
||||
|
||||
#define MUL(out, x, y) out = ((word128)x * y)
|
||||
#define ADD(out, in) out += in
|
||||
#define ADDLO(out, in) out += in
|
||||
#define SHR(in, shift) (word64)(in >> (shift))
|
||||
#define LO(in) (word64)(in)
|
||||
#endif
|
||||
|
||||
static word64 U8TO64(const byte* p) {
|
||||
return
|
||||
(((word64)(p[0] & 0xff) ) |
|
||||
((word64)(p[1] & 0xff) << 8) |
|
||||
((word64)(p[2] & 0xff) << 16) |
|
||||
((word64)(p[3] & 0xff) << 24) |
|
||||
((word64)(p[4] & 0xff) << 32) |
|
||||
((word64)(p[5] & 0xff) << 40) |
|
||||
((word64)(p[6] & 0xff) << 48) |
|
||||
((word64)(p[7] & 0xff) << 56));
|
||||
}
|
||||
|
||||
static void U64TO8(byte* p, word64 v) {
|
||||
p[0] = (v ) & 0xff;
|
||||
p[1] = (v >> 8) & 0xff;
|
||||
p[2] = (v >> 16) & 0xff;
|
||||
p[3] = (v >> 24) & 0xff;
|
||||
p[4] = (v >> 32) & 0xff;
|
||||
p[5] = (v >> 40) & 0xff;
|
||||
p[6] = (v >> 48) & 0xff;
|
||||
p[7] = (v >> 56) & 0xff;
|
||||
}
|
||||
|
||||
#else /* if not 64 bit then use 32 bit */
|
||||
|
||||
static word32 U8TO32(const byte *p) {
|
||||
return
|
||||
(((word32)(p[0] & 0xff) ) |
|
||||
((word32)(p[1] & 0xff) << 8) |
|
||||
((word32)(p[2] & 0xff) << 16) |
|
||||
((word32)(p[3] & 0xff) << 24));
|
||||
}
|
||||
|
||||
static void U32TO8(byte *p, word32 v) {
|
||||
p[0] = (v ) & 0xff;
|
||||
p[1] = (v >> 8) & 0xff;
|
||||
p[2] = (v >> 16) & 0xff;
|
||||
p[3] = (v >> 24) & 0xff;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void poly1305_blocks(Poly1305* ctx, const unsigned char *m,
|
||||
size_t bytes) {
|
||||
#ifdef POLY130564
|
||||
|
||||
const word64 hibit = (ctx->final) ? 0 : ((word64)1 << 40); /* 1 << 128 */
|
||||
word64 r0,r1,r2;
|
||||
word64 s1,s2;
|
||||
word64 h0,h1,h2;
|
||||
word64 c;
|
||||
word128 d0,d1,d2,d;
|
||||
|
||||
r0 = ctx->r[0];
|
||||
r1 = ctx->r[1];
|
||||
r2 = ctx->r[2];
|
||||
|
||||
h0 = ctx->h[0];
|
||||
h1 = ctx->h[1];
|
||||
h2 = ctx->h[2];
|
||||
|
||||
s1 = r1 * (5 << 2);
|
||||
s2 = r2 * (5 << 2);
|
||||
|
||||
while (bytes >= POLY1305_BLOCK_SIZE) {
|
||||
word64 t0,t1;
|
||||
|
||||
/* h += m[i] */
|
||||
t0 = U8TO64(&m[0]);
|
||||
t1 = U8TO64(&m[8]);
|
||||
|
||||
h0 += (( t0 ) & 0xfffffffffff);
|
||||
h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff);
|
||||
h2 += (((t1 >> 24) ) & 0x3ffffffffff) | hibit;
|
||||
|
||||
/* h *= r */
|
||||
MUL(d0, h0, r0); MUL(d, h1, s2); ADD(d0, d); MUL(d, h2, s1); ADD(d0, d);
|
||||
MUL(d1, h0, r1); MUL(d, h1, r0); ADD(d1, d); MUL(d, h2, s2); ADD(d1, d);
|
||||
MUL(d2, h0, r2); MUL(d, h1, r1); ADD(d2, d); MUL(d, h2, r0); ADD(d2, d);
|
||||
|
||||
/* (partial) h %= p */
|
||||
c = SHR(d0, 44); h0 = LO(d0) & 0xfffffffffff;
|
||||
ADDLO(d1, c); c = SHR(d1, 44); h1 = LO(d1) & 0xfffffffffff;
|
||||
ADDLO(d2, c); c = SHR(d2, 42); h2 = LO(d2) & 0x3ffffffffff;
|
||||
h0 += c * 5; c = (h0 >> 44); h0 = h0 & 0xfffffffffff;
|
||||
h1 += c;
|
||||
|
||||
m += POLY1305_BLOCK_SIZE;
|
||||
bytes -= POLY1305_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
ctx->h[0] = h0;
|
||||
ctx->h[1] = h1;
|
||||
ctx->h[2] = h2;
|
||||
|
||||
#else /* if not 64 bit then use 32 bit */
|
||||
|
||||
const word32 hibit = (ctx->final) ? 0 : (1 << 24); /* 1 << 128 */
|
||||
word32 r0,r1,r2,r3,r4;
|
||||
word32 s1,s2,s3,s4;
|
||||
word32 h0,h1,h2,h3,h4;
|
||||
word64 d0,d1,d2,d3,d4;
|
||||
word32 c;
|
||||
|
||||
r0 = ctx->r[0];
|
||||
r1 = ctx->r[1];
|
||||
r2 = ctx->r[2];
|
||||
r3 = ctx->r[3];
|
||||
r4 = ctx->r[4];
|
||||
|
||||
s1 = r1 * 5;
|
||||
s2 = r2 * 5;
|
||||
s3 = r3 * 5;
|
||||
s4 = r4 * 5;
|
||||
|
||||
h0 = ctx->h[0];
|
||||
h1 = ctx->h[1];
|
||||
h2 = ctx->h[2];
|
||||
h3 = ctx->h[3];
|
||||
h4 = ctx->h[4];
|
||||
|
||||
while (bytes >= POLY1305_BLOCK_SIZE) {
|
||||
/* h += m[i] */
|
||||
h0 += (U8TO32(m+ 0) ) & 0x3ffffff;
|
||||
h1 += (U8TO32(m+ 3) >> 2) & 0x3ffffff;
|
||||
h2 += (U8TO32(m+ 6) >> 4) & 0x3ffffff;
|
||||
h3 += (U8TO32(m+ 9) >> 6) & 0x3ffffff;
|
||||
h4 += (U8TO32(m+12) >> 8) | hibit;
|
||||
|
||||
/* h *= r */
|
||||
d0 = ((word64)h0 * r0) + ((word64)h1 * s4) + ((word64)h2 * s3) +
|
||||
((word64)h3 * s2) + ((word64)h4 * s1);
|
||||
d1 = ((word64)h0 * r1) + ((word64)h1 * r0) + ((word64)h2 * s4) +
|
||||
((word64)h3 * s3) + ((word64)h4 * s2);
|
||||
d2 = ((word64)h0 * r2) + ((word64)h1 * r1) + ((word64)h2 * r0) +
|
||||
((word64)h3 * s4) + ((word64)h4 * s3);
|
||||
d3 = ((word64)h0 * r3) + ((word64)h1 * r2) + ((word64)h2 * r1) +
|
||||
((word64)h3 * r0) + ((word64)h4 * s4);
|
||||
d4 = ((word64)h0 * r4) + ((word64)h1 * r3) + ((word64)h2 * r2) +
|
||||
((word64)h3 * r1) + ((word64)h4 * r0);
|
||||
|
||||
/* (partial) h %= p */
|
||||
c = (word32)(d0 >> 26); h0 = (word32)d0 & 0x3ffffff;
|
||||
d1 += c; c = (word32)(d1 >> 26); h1 = (word32)d1 & 0x3ffffff;
|
||||
d2 += c; c = (word32)(d2 >> 26); h2 = (word32)d2 & 0x3ffffff;
|
||||
d3 += c; c = (word32)(d3 >> 26); h3 = (word32)d3 & 0x3ffffff;
|
||||
d4 += c; c = (word32)(d4 >> 26); h4 = (word32)d4 & 0x3ffffff;
|
||||
h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff;
|
||||
h1 += c;
|
||||
|
||||
m += POLY1305_BLOCK_SIZE;
|
||||
bytes -= POLY1305_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
ctx->h[0] = h0;
|
||||
ctx->h[1] = h1;
|
||||
ctx->h[2] = h2;
|
||||
ctx->h[3] = h3;
|
||||
ctx->h[4] = h4;
|
||||
|
||||
#endif /* end of 64 bit cpu blocks or 32 bit cpu */
|
||||
}
|
||||
|
||||
|
||||
int Poly1305SetKey(Poly1305* ctx, const byte* key, word32 keySz) {
|
||||
|
||||
if (keySz != 32 || ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
word32 k;
|
||||
printf("Poly key used:\n");
|
||||
for (k = 0; k < keySz; k++) {
|
||||
printf("%02x", key[k]);
|
||||
if ((k+1) % 8 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
#if defined(POLY130564)
|
||||
|
||||
word64 t0,t1;
|
||||
|
||||
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
|
||||
t0 = U8TO64(key + 0);
|
||||
t1 = U8TO64(key + 8);
|
||||
|
||||
ctx->r[0] = ( t0 ) & 0xffc0fffffff;
|
||||
ctx->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff;
|
||||
ctx->r[2] = ((t1 >> 24) ) & 0x00ffffffc0f;
|
||||
|
||||
/* h (accumulator) = 0 */
|
||||
ctx->h[0] = 0;
|
||||
ctx->h[1] = 0;
|
||||
ctx->h[2] = 0;
|
||||
|
||||
/* save pad for later */
|
||||
ctx->pad[0] = U8TO64(key + 16);
|
||||
ctx->pad[1] = U8TO64(key + 24);
|
||||
|
||||
#else /* if not 64 bit then use 32 bit */
|
||||
|
||||
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
|
||||
ctx->r[0] = (U8TO32(key + 0) ) & 0x3ffffff;
|
||||
ctx->r[1] = (U8TO32(key + 3) >> 2) & 0x3ffff03;
|
||||
ctx->r[2] = (U8TO32(key + 6) >> 4) & 0x3ffc0ff;
|
||||
ctx->r[3] = (U8TO32(key + 9) >> 6) & 0x3f03fff;
|
||||
ctx->r[4] = (U8TO32(key + 12) >> 8) & 0x00fffff;
|
||||
|
||||
/* h = 0 */
|
||||
ctx->h[0] = 0;
|
||||
ctx->h[1] = 0;
|
||||
ctx->h[2] = 0;
|
||||
ctx->h[3] = 0;
|
||||
ctx->h[4] = 0;
|
||||
|
||||
/* save pad for later */
|
||||
ctx->pad[0] = U8TO32(key + 16);
|
||||
ctx->pad[1] = U8TO32(key + 20);
|
||||
ctx->pad[2] = U8TO32(key + 24);
|
||||
ctx->pad[3] = U8TO32(key + 28);
|
||||
|
||||
#endif
|
||||
|
||||
ctx->leftover = 0;
|
||||
ctx->final = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Poly1305Final(Poly1305* ctx, byte* mac) {
|
||||
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#if defined(POLY130564)
|
||||
|
||||
word64 h0,h1,h2,c;
|
||||
word64 g0,g1,g2;
|
||||
word64 t0,t1;
|
||||
|
||||
/* process the remaining block */
|
||||
if (ctx->leftover) {
|
||||
size_t i = ctx->leftover;
|
||||
ctx->buffer[i] = 1;
|
||||
for (i = i + 1; i < POLY1305_BLOCK_SIZE; i++)
|
||||
ctx->buffer[i] = 0;
|
||||
ctx->final = 1;
|
||||
poly1305_blocks(ctx, ctx->buffer, POLY1305_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
/* fully carry h */
|
||||
h0 = ctx->h[0];
|
||||
h1 = ctx->h[1];
|
||||
h2 = ctx->h[2];
|
||||
|
||||
c = (h1 >> 44); h1 &= 0xfffffffffff;
|
||||
h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff;
|
||||
h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff;
|
||||
h1 += c; c = (h1 >> 44); h1 &= 0xfffffffffff;
|
||||
h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff;
|
||||
h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff;
|
||||
h1 += c;
|
||||
|
||||
/* compute h + -p */
|
||||
g0 = h0 + 5; c = (g0 >> 44); g0 &= 0xfffffffffff;
|
||||
g1 = h1 + c; c = (g1 >> 44); g1 &= 0xfffffffffff;
|
||||
g2 = h2 + c - ((word64)1 << 42);
|
||||
|
||||
/* select h if h < p, or h + -p if h >= p */
|
||||
c = (g2 >> ((sizeof(word64) * 8) - 1)) - 1;
|
||||
g0 &= c;
|
||||
g1 &= c;
|
||||
g2 &= c;
|
||||
c = ~c;
|
||||
h0 = (h0 & c) | g0;
|
||||
h1 = (h1 & c) | g1;
|
||||
h2 = (h2 & c) | g2;
|
||||
|
||||
/* h = (h + pad) */
|
||||
t0 = ctx->pad[0];
|
||||
t1 = ctx->pad[1];
|
||||
|
||||
h0 += (( t0 ) & 0xfffffffffff) ;
|
||||
c = (h0 >> 44); h0 &= 0xfffffffffff;
|
||||
h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c;
|
||||
c = (h1 >> 44); h1 &= 0xfffffffffff;
|
||||
h2 += (((t1 >> 24) ) & 0x3ffffffffff) + c;
|
||||
h2 &= 0x3ffffffffff;
|
||||
|
||||
/* mac = h % (2^128) */
|
||||
h0 = ((h0 ) | (h1 << 44));
|
||||
h1 = ((h1 >> 20) | (h2 << 24));
|
||||
|
||||
U64TO8(mac + 0, h0);
|
||||
U64TO8(mac + 8, h1);
|
||||
|
||||
/* zero out the state */
|
||||
ctx->h[0] = 0;
|
||||
ctx->h[1] = 0;
|
||||
ctx->h[2] = 0;
|
||||
ctx->r[0] = 0;
|
||||
ctx->r[1] = 0;
|
||||
ctx->r[2] = 0;
|
||||
ctx->pad[0] = 0;
|
||||
ctx->pad[1] = 0;
|
||||
|
||||
#else /* if not 64 bit then use 32 bit */
|
||||
|
||||
word32 h0,h1,h2,h3,h4,c;
|
||||
word32 g0,g1,g2,g3,g4;
|
||||
word64 f;
|
||||
word32 mask;
|
||||
|
||||
/* process the remaining block */
|
||||
if (ctx->leftover) {
|
||||
size_t i = ctx->leftover;
|
||||
ctx->buffer[i++] = 1;
|
||||
for (; i < POLY1305_BLOCK_SIZE; i++)
|
||||
ctx->buffer[i] = 0;
|
||||
ctx->final = 1;
|
||||
poly1305_blocks(ctx, ctx->buffer, POLY1305_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
/* fully carry h */
|
||||
h0 = ctx->h[0];
|
||||
h1 = ctx->h[1];
|
||||
h2 = ctx->h[2];
|
||||
h3 = ctx->h[3];
|
||||
h4 = ctx->h[4];
|
||||
|
||||
c = h1 >> 26; h1 = h1 & 0x3ffffff;
|
||||
h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff;
|
||||
h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff;
|
||||
h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff;
|
||||
h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff;
|
||||
h1 += c;
|
||||
|
||||
/* compute h + -p */
|
||||
g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff;
|
||||
g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff;
|
||||
g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff;
|
||||
g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff;
|
||||
g4 = h4 + c - (1 << 26);
|
||||
|
||||
/* select h if h < p, or h + -p if h >= p */
|
||||
mask = (g4 >> ((sizeof(word32) * 8) - 1)) - 1;
|
||||
g0 &= mask;
|
||||
g1 &= mask;
|
||||
g2 &= mask;
|
||||
g3 &= mask;
|
||||
g4 &= mask;
|
||||
mask = ~mask;
|
||||
h0 = (h0 & mask) | g0;
|
||||
h1 = (h1 & mask) | g1;
|
||||
h2 = (h2 & mask) | g2;
|
||||
h3 = (h3 & mask) | g3;
|
||||
h4 = (h4 & mask) | g4;
|
||||
|
||||
/* h = h % (2^128) */
|
||||
h0 = ((h0 ) | (h1 << 26)) & 0xffffffff;
|
||||
h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff;
|
||||
h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
|
||||
h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
|
||||
|
||||
/* mac = (h + pad) % (2^128) */
|
||||
f = (word64)h0 + ctx->pad[0] ; h0 = (word32)f;
|
||||
f = (word64)h1 + ctx->pad[1] + (f >> 32); h1 = (word32)f;
|
||||
f = (word64)h2 + ctx->pad[2] + (f >> 32); h2 = (word32)f;
|
||||
f = (word64)h3 + ctx->pad[3] + (f >> 32); h3 = (word32)f;
|
||||
|
||||
U32TO8(mac + 0, h0);
|
||||
U32TO8(mac + 4, h1);
|
||||
U32TO8(mac + 8, h2);
|
||||
U32TO8(mac + 12, h3);
|
||||
|
||||
/* zero out the state */
|
||||
ctx->h[0] = 0;
|
||||
ctx->h[1] = 0;
|
||||
ctx->h[2] = 0;
|
||||
ctx->h[3] = 0;
|
||||
ctx->h[4] = 0;
|
||||
ctx->r[0] = 0;
|
||||
ctx->r[1] = 0;
|
||||
ctx->r[2] = 0;
|
||||
ctx->r[3] = 0;
|
||||
ctx->r[4] = 0;
|
||||
ctx->pad[0] = 0;
|
||||
ctx->pad[1] = 0;
|
||||
ctx->pad[2] = 0;
|
||||
ctx->pad[3] = 0;
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes) {
|
||||
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
word32 k;
|
||||
printf("Raw input to poly:\n");
|
||||
for (k = 0; k < bytes; k++) {
|
||||
printf("%02x", m[k]);
|
||||
if ((k+1) % 16 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
size_t i;
|
||||
|
||||
/* handle leftover */
|
||||
if (ctx->leftover) {
|
||||
size_t want = (POLY1305_BLOCK_SIZE - ctx->leftover);
|
||||
if (want > bytes)
|
||||
want = bytes;
|
||||
for (i = 0; i < want; i++)
|
||||
ctx->buffer[ctx->leftover + i] = m[i];
|
||||
bytes -= want;
|
||||
m += want;
|
||||
ctx->leftover += want;
|
||||
if (ctx->leftover < POLY1305_BLOCK_SIZE)
|
||||
return 0;
|
||||
poly1305_blocks(ctx, ctx->buffer, POLY1305_BLOCK_SIZE);
|
||||
ctx->leftover = 0;
|
||||
}
|
||||
|
||||
/* process full blocks */
|
||||
if (bytes >= POLY1305_BLOCK_SIZE) {
|
||||
size_t want = (bytes & ~(POLY1305_BLOCK_SIZE - 1));
|
||||
poly1305_blocks(ctx, m, want);
|
||||
m += want;
|
||||
bytes -= want;
|
||||
}
|
||||
|
||||
/* store leftover */
|
||||
if (bytes) {
|
||||
for (i = 0; i < bytes; i++)
|
||||
ctx->buffer[ctx->leftover + i] = m[i];
|
||||
ctx->leftover += bytes;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_POLY1305 */
|
||||
|
@ -48,12 +48,14 @@
|
||||
#include <cyassl/ctaocrypt/rsa.h>
|
||||
#include <cyassl/ctaocrypt/des3.h>
|
||||
#include <cyassl/ctaocrypt/aes.h>
|
||||
#include <cyassl/ctaocrypt/poly1305.h>
|
||||
#include <cyassl/ctaocrypt/camellia.h>
|
||||
#include <cyassl/ctaocrypt/hmac.h>
|
||||
#include <cyassl/ctaocrypt/dh.h>
|
||||
#include <cyassl/ctaocrypt/dsa.h>
|
||||
#include <cyassl/ctaocrypt/hc128.h>
|
||||
#include <cyassl/ctaocrypt/rabbit.h>
|
||||
#include <cyassl/ctaocrypt/chacha.h>
|
||||
#include <cyassl/ctaocrypt/pwdbased.h>
|
||||
#include <cyassl/ctaocrypt/ripemd.h>
|
||||
#ifdef HAVE_ECC
|
||||
@ -152,9 +154,11 @@ int hkdf_test(void);
|
||||
int arc4_test(void);
|
||||
int hc128_test(void);
|
||||
int rabbit_test(void);
|
||||
int chacha_test(void);
|
||||
int des_test(void);
|
||||
int des3_test(void);
|
||||
int aes_test(void);
|
||||
int poly1305_test(void);
|
||||
int aesgcm_test(void);
|
||||
int gmac_test(void);
|
||||
int aesccm_test(void);
|
||||
@ -367,6 +371,13 @@ void ctaocrypt_test(void* args)
|
||||
printf( "Rabbit test passed!\n");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
if ( (ret = chacha_test()) != 0)
|
||||
err_sys("Chacha test failed!\n", ret);
|
||||
else
|
||||
printf( "Chacha test passed!\n");
|
||||
#endif
|
||||
|
||||
#ifndef NO_DES3
|
||||
if ( (ret = des_test()) != 0)
|
||||
err_sys("DES test failed!\n", ret);
|
||||
@ -387,6 +398,13 @@ void ctaocrypt_test(void* args)
|
||||
else
|
||||
printf( "AES test passed!\n");
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
if ( (ret = poly1305_test()) != 0)
|
||||
err_sys("POLY1305 test failed!\n", ret);
|
||||
else
|
||||
printf( "POLY1305 test passed!\n");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
if ( (ret = aesgcm_test()) != 0)
|
||||
err_sys("AES-GCM test failed!\n", ret);
|
||||
@ -1816,6 +1834,107 @@ int rabbit_test(void)
|
||||
#endif /* NO_RABBIT */
|
||||
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
int chacha_test(void)
|
||||
{
|
||||
byte cipher[32];
|
||||
byte plain[32];
|
||||
byte input[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
word32 keySz;
|
||||
int i;
|
||||
int times = 4;
|
||||
|
||||
const byte key1[] =
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
|
||||
const byte key2[] =
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01
|
||||
};
|
||||
|
||||
const byte key3[] =
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
|
||||
/* 128 bit key */
|
||||
const byte key4[] =
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
|
||||
|
||||
const byte* keys[] = {key1, key2, key3, key4};
|
||||
|
||||
const byte ivs1[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
const byte ivs2[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
const byte ivs3[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01};
|
||||
const byte ivs4[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
|
||||
|
||||
const byte* ivs[] = {ivs1, ivs2, ivs3, ivs4};
|
||||
|
||||
|
||||
byte a[] = {0x76,0xb8,0xe0,0xad,0xa0,0xf1,0x3d,0x90};
|
||||
byte b[] = {0x45,0x40,0xf0,0x5a,0x9f,0x1f,0xb2,0x96};
|
||||
byte c[] = {0xde,0x9c,0xba,0x7b,0xf3,0xd6,0x9e,0xf5};
|
||||
byte d[] = {0x89,0x67,0x09,0x52,0x60,0x83,0x64,0xfd};
|
||||
|
||||
byte* test_chacha[4];
|
||||
|
||||
test_chacha[0] = a;
|
||||
test_chacha[1] = b;
|
||||
test_chacha[2] = c;
|
||||
test_chacha[3] = d;
|
||||
|
||||
for (i = 0; i < times; ++i) {
|
||||
if (i < 3) {
|
||||
keySz = 32;
|
||||
}
|
||||
else {
|
||||
keySz = 16;
|
||||
}
|
||||
ChaCha enc;
|
||||
ChaCha dec;
|
||||
|
||||
XMEMCPY(plain, keys[i], keySz);
|
||||
XMEMSET(cipher, 0, 32);
|
||||
XMEMCPY(cipher + 4, ivs[i], 8);
|
||||
|
||||
Chacha_SetKey(&enc, keys[i], keySz);
|
||||
Chacha_SetKey(&dec, keys[i], keySz);
|
||||
|
||||
Chacha_SetIV(&enc, cipher,0);
|
||||
Chacha_SetIV(&dec, cipher,0);
|
||||
XMEMCPY(plain, input, 8);
|
||||
|
||||
Chacha_Process(&enc, cipher, plain, (word32)8);
|
||||
Chacha_Process(&dec, plain, cipher, (word32)8);
|
||||
|
||||
if (memcmp(test_chacha[i], cipher, 8))
|
||||
return -130 - 5 - i;
|
||||
|
||||
if (memcmp(plain, input, 8))
|
||||
return -130 - i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_CHACHA */
|
||||
|
||||
|
||||
#ifndef NO_DES3
|
||||
int des_test(void)
|
||||
{
|
||||
@ -2126,6 +2245,96 @@ int aes_test(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
int poly1305_test(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int i;
|
||||
byte tag[16];
|
||||
Poly1305 enc;
|
||||
|
||||
const byte msg[] =
|
||||
{
|
||||
0x43,0x72,0x79,0x70,0x74,0x6f,0x67,0x72,
|
||||
0x61,0x70,0x68,0x69,0x63,0x20,0x46,0x6f,
|
||||
0x72,0x75,0x6d,0x20,0x52,0x65,0x73,0x65,
|
||||
0x61,0x72,0x63,0x68,0x20,0x47,0x72,0x6f,
|
||||
0x75,0x70
|
||||
};
|
||||
|
||||
const byte msg2[] =
|
||||
{
|
||||
0x48,0x65,0x6c,0x6c,0x6f,0x20,0x77,0x6f,0x72,
|
||||
0x6c,0x64,0x21
|
||||
};
|
||||
|
||||
const byte msg3[] =
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
|
||||
const byte correct[] =
|
||||
{
|
||||
0xa8,0x06,0x1d,0xc1,0x30,0x51,0x36,0xc6,
|
||||
0xc2,0x2b,0x8b,0xaf,0x0c,0x01,0x27,0xa9
|
||||
|
||||
};
|
||||
|
||||
const byte correct2[] =
|
||||
{
|
||||
0xa6,0xf7,0x45,0x00,0x8f,0x81,0xc9,0x16,
|
||||
0xa2,0x0d,0xcc,0x74,0xee,0xf2,0xb2,0xf0
|
||||
};
|
||||
|
||||
const byte correct3[] =
|
||||
{
|
||||
0x49,0xec,0x78,0x09,0x0e,0x48,0x1e,0xc6,
|
||||
0xc2,0x6b,0x33,0xb9,0x1c,0xcc,0x03,0x07
|
||||
};
|
||||
|
||||
const byte key[] = {
|
||||
0x85,0xd6,0xbe,0x78,0x57,0x55,0x6d,0x33,
|
||||
0x7f,0x44,0x52,0xfe,0x42,0xd5,0x06,0xa8,
|
||||
0x01,0x03,0x80,0x8a,0xfb,0x0d,0xb2,0xfd,
|
||||
0x4a,0xbf,0xf6,0xaf,0x41,0x49,0xf5,0x1b
|
||||
};
|
||||
|
||||
const byte key2[] = {
|
||||
0x74,0x68,0x69,0x73,0x20,0x69,0x73,0x20,
|
||||
0x33,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,
|
||||
0x6b,0x65,0x79,0x20,0x66,0x6f,0x72,0x20,
|
||||
0x50,0x6f,0x6c,0x79,0x31,0x33,0x30,0x35
|
||||
};
|
||||
|
||||
const byte* msgs[] = {msg, msg2, msg3};
|
||||
word32 szm[] = {sizeof(msg),sizeof(msg2),sizeof(msg3)};
|
||||
const byte* keys[] = {key, key2, key2};
|
||||
const byte* tests[] = {correct, correct2, correct3};
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
ret = Poly1305SetKey(&enc, keys[i], 32);
|
||||
if (ret != 0)
|
||||
return -1001;
|
||||
|
||||
ret = Poly1305Update(&enc, msgs[i], szm[i]);
|
||||
if (ret != 0)
|
||||
return -1005;
|
||||
|
||||
ret = Poly1305Final(&enc, tag);
|
||||
if (ret != 0)
|
||||
return -60;
|
||||
|
||||
if (memcmp(tag, tests[i], sizeof(tag)))
|
||||
return -61;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_POLY1305 */
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
int aesgcm_test(void)
|
||||
{
|
||||
|
55
cyassl/ctaocrypt/chacha.h
Normal file
55
cyassl/ctaocrypt/chacha.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* chacha.h
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of CyaSSL.
|
||||
*
|
||||
* CyaSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CyaSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef CHACHA_H
|
||||
#define CHACHA_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
CHACHA_ENC_TYPE = 7 /* cipher unique type */
|
||||
};
|
||||
|
||||
typedef struct ChaCha {
|
||||
word32 X[16]; /* state of cipher */
|
||||
} ChaCha;
|
||||
|
||||
CYASSL_API int Chacha_Process(ChaCha* ctx, byte* cipher, const byte* plain,
|
||||
word32 msglen);
|
||||
CYASSL_API int Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz);
|
||||
|
||||
/**
|
||||
* IV(nonce) changes with each record
|
||||
* counter is for what value the block counter should start ... usually 0
|
||||
*/
|
||||
CYASSL_API int Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -6,6 +6,7 @@ nobase_include_HEADERS+= \
|
||||
cyassl/ctaocrypt/arc4.h \
|
||||
cyassl/ctaocrypt/asn.h \
|
||||
cyassl/ctaocrypt/asn_public.h \
|
||||
cyassl/ctaocrypt/poly1305.h \
|
||||
cyassl/ctaocrypt/camellia.h \
|
||||
cyassl/ctaocrypt/coding.h \
|
||||
cyassl/ctaocrypt/compress.h \
|
||||
@ -26,6 +27,7 @@ nobase_include_HEADERS+= \
|
||||
cyassl/ctaocrypt/wc_port.h \
|
||||
cyassl/ctaocrypt/pwdbased.h \
|
||||
cyassl/ctaocrypt/rabbit.h \
|
||||
cyassl/ctaocrypt/chacha.h \
|
||||
cyassl/ctaocrypt/random.h \
|
||||
cyassl/ctaocrypt/ripemd.h \
|
||||
cyassl/ctaocrypt/rsa.h \
|
||||
|
82
cyassl/ctaocrypt/poly1305.h
Normal file
82
cyassl/ctaocrypt/poly1305.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* poly1305.h
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of CyaSSL.
|
||||
*
|
||||
* CyaSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CyaSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
|
||||
#ifndef CTAO_CRYPT_POLY1305_H
|
||||
#define CTAO_CRYPT_POLY1305_H
|
||||
|
||||
#include <cyassl/ctaocrypt/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* auto detect between 32bit / 64bit */
|
||||
#define HAS_SIZEOF_INT128_64BIT (defined(__SIZEOF_INT128__) && defined(__LP64__))
|
||||
#define HAS_MSVC_64BIT (defined(_MSC_VER) && defined(_M_X64))
|
||||
#define HAS_GCC_4_4_64BIT (defined(__GNUC__) && defined(__LP64__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4))))
|
||||
|
||||
#if (HAS_SIZEOF_INT128_64BIT || HAS_MSVC_64BIT || HAS_GCC_4_4_64BIT)
|
||||
#define POLY130564
|
||||
#else
|
||||
#define POLY130532
|
||||
#endif
|
||||
|
||||
enum {
|
||||
POLY1305 = 7,
|
||||
POLY1305_BLOCK_SIZE = 16,
|
||||
POLY1305_DIGEST_SIZE = 16,
|
||||
POLY1305_PAD_SIZE = 56
|
||||
};
|
||||
|
||||
/* Poly1305 state */
|
||||
typedef struct Poly1305 {
|
||||
#if defined(POLY130564)
|
||||
word64 r[3];
|
||||
word64 h[3];
|
||||
word64 pad[2];
|
||||
#else
|
||||
word32 r[5];
|
||||
word32 h[5];
|
||||
word32 pad[4];
|
||||
#endif
|
||||
size_t leftover;
|
||||
unsigned char buffer[POLY1305_BLOCK_SIZE];
|
||||
unsigned char final;
|
||||
} Poly1305;
|
||||
|
||||
|
||||
/* does init */
|
||||
|
||||
CYASSL_API int Poly1305SetKey(Poly1305* poly1305, const byte* key, word32 kySz);
|
||||
CYASSL_API int Poly1305Update(Poly1305* poly1305, const byte*, word32);
|
||||
CYASSL_API int Poly1305Final(Poly1305* poly1305, byte* tag);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* CTAO_CRYPT_POLY1305_H */
|
||||
|
||||
#endif /* HAVE_POLY1305 */
|
||||
|
@ -31,10 +31,12 @@
|
||||
#include <cyassl/ctaocrypt/des3.h>
|
||||
#include <cyassl/ctaocrypt/hc128.h>
|
||||
#include <cyassl/ctaocrypt/rabbit.h>
|
||||
#include <cyassl/ctaocrypt/chacha.h>
|
||||
#include <cyassl/ctaocrypt/asn.h>
|
||||
#include <cyassl/ctaocrypt/md5.h>
|
||||
#include <cyassl/ctaocrypt/sha.h>
|
||||
#include <cyassl/ctaocrypt/aes.h>
|
||||
#include <cyassl/ctaocrypt/poly1305.h>
|
||||
#include <cyassl/ctaocrypt/camellia.h>
|
||||
#include <cyassl/ctaocrypt/logging.h>
|
||||
#include <cyassl/ctaocrypt/hmac.h>
|
||||
@ -465,9 +467,23 @@ void c32to24(word32 in, word24 out);
|
||||
#define BUILD_ARC4
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
#define CHACHA20_BLOCK_SIZE 16
|
||||
/* ChaCha - Poly AEAD suites */
|
||||
#if defined(HAVE_POLY1305) && !defined(NO_SHA256)
|
||||
#if defined(HAVE_ECC)
|
||||
#if !defined(NO_RSA)
|
||||
#define BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
#endif
|
||||
#define BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
#endif
|
||||
#if !defined(NO_DH) && !defined(NO_RSA)
|
||||
#define BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
#endif
|
||||
#endif /* end of ChaCha - Poly AEAD suites */
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
|
||||
#if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) || defined(HAVE_CHACHA)
|
||||
#define HAVE_AEAD
|
||||
#endif
|
||||
|
||||
@ -592,13 +608,18 @@ enum {
|
||||
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xbe,
|
||||
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0xc4,
|
||||
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0x13,
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0x14,
|
||||
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0x15,
|
||||
|
||||
/* Renegotiation Indication Extension Special Suite */
|
||||
TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0xff
|
||||
};
|
||||
|
||||
|
||||
enum Misc {
|
||||
ECC_BYTE = 0xC0, /* ECC first cipher suite byte */
|
||||
ECC_BYTE = 0xC0, /* ECC first cipher suite byte */
|
||||
CHACHA_BYTE = 0xCC, /* ChaCha first cipher suite */
|
||||
|
||||
SEND_CERT = 1,
|
||||
SEND_BLANK_CERT = 2,
|
||||
@ -721,6 +742,12 @@ enum Misc {
|
||||
CAMELLIA_256_KEY_SIZE = 32, /* for 256 bit */
|
||||
CAMELLIA_IV_SIZE = 16, /* always block size */
|
||||
|
||||
CHACHA20_256_KEY_SIZE = 32, /* for 256 bit */
|
||||
CHACHA20_128_KEY_SIZE = 16, /* for 128 bit */
|
||||
CHACHA20_IV_SIZE = 8, /* 64 bits for iv */
|
||||
|
||||
POLY1305_AUTH_SZ = 16, /* 128 bits */
|
||||
|
||||
HC_128_KEY_SIZE = 16, /* 128 bits */
|
||||
HC_128_IV_SIZE = 16, /* also 128 bits */
|
||||
|
||||
@ -1495,6 +1522,12 @@ typedef struct Ciphers {
|
||||
#ifdef HAVE_CAMELLIA
|
||||
Camellia* cam;
|
||||
#endif
|
||||
#ifdef HAVE_CHACHA
|
||||
ChaCha* chacha;
|
||||
#endif
|
||||
#ifdef HAVE_POLY1305
|
||||
Poly1305* poly1305;
|
||||
#endif
|
||||
#ifdef HAVE_HC128
|
||||
HC128* hc128;
|
||||
#endif
|
||||
@ -1681,6 +1714,10 @@ typedef struct Options {
|
||||
byte usingNonblock; /* set when using nonblocking socket */
|
||||
byte saveArrays; /* save array Memory for user get keys
|
||||
or psk */
|
||||
#ifdef HAVE_POLY1305
|
||||
byte oldPoly; /* set when to use old rfc way of poly*/
|
||||
#endif
|
||||
|
||||
#ifndef NO_PSK
|
||||
byte havePSK; /* psk key set by user */
|
||||
psk_client_callback client_psk_cb;
|
||||
|
@ -217,6 +217,10 @@ CYASSL_API int CyaSSL_use_RSAPrivateKey_file(CYASSL*, const char*, int);
|
||||
const char*, int);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
CYASSL_API int CyaSSL_use_old_poly(CYASSL*, int);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NTRU
|
||||
CYASSL_API int CyaSSL_CTX_use_NTRUPrivateKey_file(CYASSL_CTX*, const char*);
|
||||
/* load NTRU private key blob */
|
||||
@ -1064,6 +1068,7 @@ enum BulkCipherAlgorithm {
|
||||
cyassl_aes,
|
||||
cyassl_aes_gcm,
|
||||
cyassl_aes_ccm,
|
||||
cyassl_chacha,
|
||||
cyassl_camellia,
|
||||
cyassl_hc128, /* CyaSSL extensions */
|
||||
cyassl_rabbit
|
||||
|
@ -622,6 +622,15 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
|
||||
else {
|
||||
tcp_connect(&sockfd, host, port, 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
/* use old poly to connect with google server */
|
||||
if (!XSTRNCMP(domain, "www.google.com", 14)) {
|
||||
if (CyaSSL_use_old_poly(ssl, 1) != 0)
|
||||
err_sys("unable to set to old poly");
|
||||
}
|
||||
#endif
|
||||
|
||||
CyaSSL_set_fd(ssl, sockfd);
|
||||
#ifdef HAVE_CRL
|
||||
if (CyaSSL_EnableCRL(ssl, CYASSL_CRL_CHECKALL) != SSL_SUCCESS)
|
||||
|
@ -55,6 +55,10 @@ if BUILD_AES
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/aes.c
|
||||
endif
|
||||
|
||||
if BUILD_POLY1305
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/poly1305.c
|
||||
endif
|
||||
|
||||
if BUILD_DES3
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/des3.c
|
||||
endif
|
||||
@ -119,6 +123,10 @@ if BUILD_RABBIT
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/rabbit.c
|
||||
endif
|
||||
|
||||
if BUILD_CHACHA
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/chacha.c
|
||||
endif
|
||||
|
||||
if !BUILD_INLINE
|
||||
src_libcyassl_la_SOURCES += ctaocrypt/src/misc.c
|
||||
endif
|
||||
|
461
src/internal.c
461
src/internal.c
@ -38,7 +38,7 @@
|
||||
#include "ntru_crypto.h"
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_CYASSL) || defined(SHOW_SECRETS)
|
||||
#if defined(DEBUG_CYASSL) || defined(SHOW_SECRETS) || defined(CHACHA_AEAD_TEST)
|
||||
#ifdef FREESCALE_MQX
|
||||
#include <fio.h>
|
||||
#else
|
||||
@ -203,7 +203,8 @@ static INLINE void c16toa(word16 u16, byte* c)
|
||||
}
|
||||
|
||||
|
||||
#if !defined(NO_OLD_TLS) || defined(HAVE_AESCCM) || defined(HAVE_AESGCM)
|
||||
#if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
|
||||
|| defined(HAVE_AESGCM)
|
||||
/* convert 32 bit integer to opaque */
|
||||
static INLINE void c32toa(word32 u32, byte* c)
|
||||
{
|
||||
@ -527,6 +528,14 @@ void InitCiphers(CYASSL* ssl)
|
||||
#ifdef BUILD_RABBIT
|
||||
ssl->encrypt.rabbit = NULL;
|
||||
ssl->decrypt.rabbit = NULL;
|
||||
#endif
|
||||
#ifdef HAVE_CHACHA
|
||||
ssl->encrypt.chacha = NULL;
|
||||
ssl->decrypt.chacha = NULL;
|
||||
#endif
|
||||
#ifdef HAVE_POLY1305
|
||||
ssl->encrypt.poly1305 = NULL;
|
||||
ssl->decrypt.poly1305 = NULL;
|
||||
#endif
|
||||
ssl->encrypt.setup = 0;
|
||||
ssl->decrypt.setup = 0;
|
||||
@ -579,6 +588,14 @@ void FreeCiphers(CYASSL* ssl)
|
||||
XFREE(ssl->encrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
XFREE(ssl->decrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
#endif
|
||||
#ifdef HAVE_CHACHA
|
||||
XFREE(ssl->encrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
XFREE(ssl->decrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
#endif
|
||||
#ifdef HAVE_POLY1305
|
||||
XFREE(ssl->encrypt.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
XFREE(ssl->decrypt.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -891,6 +908,27 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
if (tls && haveRSA) {
|
||||
suites->suites[idx++] = CHACHA_BYTE;
|
||||
suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
if (tls1_2 && haveECDSAsig) {
|
||||
suites->suites[idx++] = CHACHA_BYTE;
|
||||
suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
if (tls && haveRSA) {
|
||||
suites->suites[idx++] = CHACHA_BYTE;
|
||||
suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
|
||||
if (tls && haveRSAsig && haveStaticECC) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
@ -1634,6 +1672,9 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
||||
ssl->options.groupMessages = ctx->groupMessages;
|
||||
ssl->options.usingNonblock = 0;
|
||||
ssl->options.saveArrays = 0;
|
||||
#ifdef HAVE_POLY1305
|
||||
ssl->options.oldPoly = 0;
|
||||
#endif
|
||||
|
||||
#ifndef NO_CERTS
|
||||
/* ctx still owns certificate, certChain, key, dh, and cm */
|
||||
@ -3151,6 +3192,30 @@ static int BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
|
||||
the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
|
||||
static int CipherRequires(byte first, byte second, int requirement)
|
||||
{
|
||||
|
||||
if (first == CHACHA_BYTE) {
|
||||
|
||||
switch (second) {
|
||||
|
||||
case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
|
||||
if (requirement == REQUIRES_RSA)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
|
||||
if (requirement == REQUIRES_ECC_DSA)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
|
||||
if (requirement == REQUIRES_RSA)
|
||||
return 1;
|
||||
if (requirement == REQUIRES_DHE)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ECC extensions */
|
||||
if (first == ECC_BYTE) {
|
||||
|
||||
@ -4677,7 +4742,8 @@ static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(NO_OLD_TLS) || defined(HAVE_AESCCM) || defined(HAVE_AESGCM)
|
||||
#if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
|
||||
|| defined(HAVE_AESGCM)
|
||||
static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
|
||||
{
|
||||
if (verify)
|
||||
@ -4696,6 +4762,333 @@ static INLINE void AeadIncrementExpIV(CYASSL* ssl)
|
||||
if (++ssl->keys.aead_exp_IV[i]) return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
/*more recent rfc's concatonate input for poly1305 differently*/
|
||||
static int Poly1305Tag(CYASSL* ssl, byte* additional, const byte* out,
|
||||
byte* cipher, word16 sz, byte* tag)
|
||||
{
|
||||
int ret = 0;
|
||||
int paddingSz = 0;
|
||||
int msglen = (sz - ssl->specs.aead_mac_size);
|
||||
word32 keySz = 32;
|
||||
byte padding[16];
|
||||
|
||||
if (msglen < 0)
|
||||
return INPUT_CASE_ERROR;
|
||||
|
||||
XMEMSET(padding, 0, sizeof(padding));
|
||||
|
||||
if ((ret = Poly1305SetKey(ssl->encrypt.poly1305, cipher, keySz)) != 0)
|
||||
return ret;
|
||||
|
||||
/* additional input to poly1305 */
|
||||
if ((ret = Poly1305Update(ssl->encrypt.poly1305, additional,
|
||||
CHACHA20_BLOCK_SIZE)) != 0)
|
||||
return ret;
|
||||
|
||||
/* cipher input */
|
||||
if ((ret = Poly1305Update(ssl->encrypt.poly1305, out, msglen)) != 0)
|
||||
return ret;
|
||||
|
||||
/* handle padding for cipher input to make it 16 bytes long */
|
||||
if (msglen % 16 != 0) {
|
||||
paddingSz = (16 - (sz - ssl->specs.aead_mac_size) % 16);
|
||||
if (paddingSz < 0)
|
||||
return INPUT_CASE_ERROR;
|
||||
|
||||
if ((ret = Poly1305Update(ssl->encrypt.poly1305, padding, paddingSz))
|
||||
!= 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* add size of AD and size of cipher to poly input */
|
||||
XMEMSET(padding, 0, sizeof(padding));
|
||||
padding[0] = CHACHA20_BLOCK_SIZE;
|
||||
|
||||
/* 32 bit size of cipher to 64 bit endian */
|
||||
padding[8] = msglen & 0xff;
|
||||
padding[9] = (msglen >> 8) & 0xff;
|
||||
padding[10] = (msglen >>16) & 0xff;
|
||||
padding[11] = (msglen >>24) & 0xff;
|
||||
if ((ret = Poly1305Update(ssl->encrypt.poly1305, padding, sizeof(padding)))
|
||||
!= 0)
|
||||
return ret;
|
||||
|
||||
/* generate tag */
|
||||
if ((ret = Poly1305Final(ssl->encrypt.poly1305, tag)) != 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Used for the older version of creating AEAD tags with Poly1305 */
|
||||
static int Poly1305TagOld(CYASSL* ssl, byte* additional, const byte* out,
|
||||
byte* cipher, word16 sz, byte* tag)
|
||||
{
|
||||
int ret = 0;
|
||||
int msglen = (sz - ssl->specs.aead_mac_size);
|
||||
word32 keySz = 32;
|
||||
byte padding[8]; /* used to temporarly store lengths */
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
printf("Using old version of poly1305 input.\n");
|
||||
#endif
|
||||
|
||||
if (msglen < 0)
|
||||
return INPUT_CASE_ERROR;
|
||||
|
||||
if ((ret = Poly1305SetKey(ssl->encrypt.poly1305, cipher, keySz)) != 0)
|
||||
return ret;
|
||||
|
||||
/* add TLS compressed length and additional input to poly1305 */
|
||||
additional[AEAD_AUTH_DATA_SZ - 2] = (msglen >> 8) & 0xff;
|
||||
additional[AEAD_AUTH_DATA_SZ - 1] = msglen & 0xff;
|
||||
if ((ret = Poly1305Update(ssl->encrypt.poly1305, additional,
|
||||
AEAD_AUTH_DATA_SZ)) != 0)
|
||||
return ret;
|
||||
|
||||
/* length of additional input plus padding */
|
||||
XMEMSET(padding, 0, sizeof(padding));
|
||||
padding[0] = AEAD_AUTH_DATA_SZ;
|
||||
if ((ret = Poly1305Update(ssl->encrypt.poly1305, padding,
|
||||
sizeof(padding))) != 0)
|
||||
return ret;
|
||||
|
||||
|
||||
/* add cipher info and then its length */
|
||||
XMEMSET(padding, 0, sizeof(padding));
|
||||
if ((ret = Poly1305Update(ssl->encrypt.poly1305, out, msglen)) != 0)
|
||||
return ret;
|
||||
|
||||
/* 32 bit size of cipher to 64 bit endian */
|
||||
padding[0] = msglen & 0xff;
|
||||
padding[1] = (msglen >> 8) & 0xff;
|
||||
padding[2] = (msglen >> 16) & 0xff;
|
||||
padding[3] = (msglen >> 24) & 0xff;
|
||||
if ((ret = Poly1305Update(ssl->encrypt.poly1305, padding, sizeof(padding)))
|
||||
!= 0)
|
||||
return ret;
|
||||
|
||||
/* generate tag */
|
||||
if ((ret = Poly1305Final(ssl->encrypt.poly1305, tag)) != 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /*HAVE_POLY1305*/
|
||||
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
static int ChachaAEADEncrypt(CYASSL* ssl, byte* out, const byte* input,
|
||||
word16 sz)
|
||||
{
|
||||
const byte* additionalSrc = input - RECORD_HEADER_SZ;
|
||||
int ret = 0;
|
||||
byte tag[POLY1305_AUTH_SZ];
|
||||
byte additional[CHACHA20_BLOCK_SIZE];
|
||||
byte nonce[AEAD_NONCE_SZ];
|
||||
byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for poly1305 */
|
||||
|
||||
XMEMSET(tag, 0, sizeof(tag));
|
||||
XMEMSET(nonce, 0, AEAD_NONCE_SZ);
|
||||
XMEMSET(cipher, 0, sizeof(cipher));
|
||||
XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
|
||||
|
||||
/* get nonce */
|
||||
c32toa(ssl->keys.sequence_number, nonce + AEAD_IMP_IV_SZ
|
||||
+ AEAD_SEQ_OFFSET);
|
||||
|
||||
/* opaque SEQ number stored for AD */
|
||||
c32toa(GetSEQIncrement(ssl, 0), additional + AEAD_SEQ_OFFSET);
|
||||
|
||||
/* Store the type, version. Unfortunately, they are in
|
||||
* the input buffer ahead of the plaintext. */
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
c16toa(ssl->keys.dtls_epoch, additional);
|
||||
additionalSrc -= DTLS_HANDSHAKE_EXTRA;
|
||||
}
|
||||
#endif
|
||||
|
||||
XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
int i;
|
||||
printf("Encrypt Additional : ");
|
||||
for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
|
||||
printf("%02x", additional[i]);
|
||||
}
|
||||
printf("\n\n");
|
||||
printf("input before encryption :\n");
|
||||
for (i = 0; i < sz; i++) {
|
||||
printf("%02x", input[i]);
|
||||
if ((i + 1) % 16 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/* set the nonce for chacha and get poly1305 key */
|
||||
if ((ret = Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = Chacha_Process(ssl->encrypt.chacha, cipher,
|
||||
cipher, sizeof(cipher))) != 0)
|
||||
return ret;
|
||||
|
||||
/* encrypt the plain text */
|
||||
if ((ret = Chacha_Process(ssl->encrypt.chacha, out, input,
|
||||
sz - ssl->specs.aead_mac_size)) != 0)
|
||||
return ret;
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
/* get the tag : future use of hmac could go here*/
|
||||
if (ssl->options.oldPoly == 1) {
|
||||
if ((ret = Poly1305TagOld(ssl, additional, (const byte* )out,
|
||||
cipher, sz, tag)) != 0)
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
if ((ret = Poly1305Tag(ssl, additional, (const byte* )out,
|
||||
cipher, sz, tag)) != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* append tag to ciphertext */
|
||||
XMEMCPY(out + sz - ssl->specs.aead_mac_size, tag, sizeof(tag));
|
||||
|
||||
AeadIncrementExpIV(ssl);
|
||||
XMEMSET(nonce, 0, AEAD_NONCE_SZ);
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
printf("mac tag :\n");
|
||||
for (i = 0; i < 16; i++) {
|
||||
printf("%02x", tag[i]);
|
||||
if ((i + 1) % 16 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n\noutput after encrypt :\n");
|
||||
for (i = 0; i < sz; i++) {
|
||||
printf("%02x", out[i]);
|
||||
if ((i + 1) % 16 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int ChachaAEADDecrypt(CYASSL* ssl, byte* plain, const byte* input,
|
||||
word16 sz)
|
||||
{
|
||||
byte additional[CHACHA20_BLOCK_SIZE];
|
||||
byte nonce[AEAD_NONCE_SZ];
|
||||
byte tag[POLY1305_AUTH_SZ];
|
||||
byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
XMEMSET(tag, 0, sizeof(tag));
|
||||
XMEMSET(cipher, 0, sizeof(cipher));
|
||||
XMEMSET(nonce, 0, AEAD_NONCE_SZ);
|
||||
XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
printf("input before decrypt :\n");
|
||||
for (i = 0; i < sz; i++) {
|
||||
printf("%02x", input[i]);
|
||||
if ((i + 1) % 16 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/* get nonce */
|
||||
c32toa(ssl->keys.peer_sequence_number, nonce + AEAD_IMP_IV_SZ
|
||||
+ AEAD_SEQ_OFFSET);
|
||||
|
||||
/* sequence number field is 64-bits, we only use 32-bits */
|
||||
c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
|
||||
|
||||
/* get AD info */
|
||||
additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
|
||||
additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
|
||||
additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
|
||||
|
||||
/* Store the type, version. */
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls)
|
||||
c16toa(ssl->keys.dtls_state.curEpoch, additional);
|
||||
#endif
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
printf("Decrypt Additional : ");
|
||||
for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
|
||||
printf("%02x", additional[i]);
|
||||
}
|
||||
printf("\n\n");
|
||||
#endif
|
||||
|
||||
/* set nonce and get poly1305 key */
|
||||
if ((ret = Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = Chacha_Process(ssl->decrypt.chacha, cipher,
|
||||
cipher, sizeof(cipher))) != 0)
|
||||
return ret;
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
/* get the tag : future use of hmac could go here*/
|
||||
if (ssl->options.oldPoly == 1) {
|
||||
if ((ret = Poly1305TagOld(ssl, additional, input, cipher,
|
||||
sz, tag)) != 0)
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
if ((ret = Poly1305Tag(ssl, additional, input, cipher,
|
||||
sz, tag)) != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check mac sent along with packet */
|
||||
ret = 0;
|
||||
for (i = 0; i < ssl->specs.aead_mac_size; i++) {
|
||||
if ((input + sz - ssl->specs.aead_mac_size)[i] != tag[i])
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (ret == 1) {
|
||||
CYASSL_MSG("Mac did not match");
|
||||
SendAlert(ssl, alert_fatal, bad_record_mac);
|
||||
XMEMSET(nonce, 0, AEAD_NONCE_SZ);
|
||||
return VERIFY_MAC_ERROR;
|
||||
}
|
||||
|
||||
/* if mac was good decrypt message */
|
||||
if ((ret = Chacha_Process(ssl->decrypt.chacha, plain, input,
|
||||
sz - ssl->specs.aead_mac_size)) != 0)
|
||||
return ret;
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
printf("plain after decrypt :\n");
|
||||
for (i = 0; i < sz; i++) {
|
||||
printf("%02x", plain[i]);
|
||||
if ((i + 1) % 16 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_CHACHA */
|
||||
#endif
|
||||
|
||||
|
||||
@ -4831,6 +5224,11 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word16 sz)
|
||||
return RabbitProcess(ssl->encrypt.rabbit, out, input, sz);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
case cyassl_chacha:
|
||||
return ChachaAEADEncrypt(ssl, out, input, sz);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NULL_CIPHER
|
||||
case cyassl_cipher_null:
|
||||
if (input != out) {
|
||||
@ -4976,6 +5374,11 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input,
|
||||
return RabbitProcess(ssl->decrypt.rabbit, plain, input, sz);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
case cyassl_chacha:
|
||||
return ChachaAEADDecrypt(ssl, plain, input, sz);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NULL_CIPHER
|
||||
case cyassl_cipher_null:
|
||||
if (input != plain) {
|
||||
@ -5017,8 +5420,9 @@ static int SanityCheckCipherText(CYASSL* ssl, word32 encryptSz)
|
||||
minLength += ssl->specs.block_size; /* explicit IV */
|
||||
}
|
||||
else if (ssl->specs.cipher_type == aead) {
|
||||
minLength = ssl->specs.aead_mac_size + AEAD_EXP_IV_SZ;
|
||||
/* explicit IV + authTag size */
|
||||
minLength = ssl->specs.aead_mac_size; /* authTag size */
|
||||
if (ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
|
||||
minLength += AEAD_EXP_IV_SZ; /* explicit IV */
|
||||
}
|
||||
|
||||
if (encryptSz < minLength) {
|
||||
@ -5326,7 +5730,8 @@ int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
|
||||
ivExtra = ssl->specs.block_size;
|
||||
}
|
||||
else if (ssl->specs.cipher_type == aead) {
|
||||
ivExtra = AEAD_EXP_IV_SZ;
|
||||
if (ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
|
||||
ivExtra = AEAD_EXP_IV_SZ;
|
||||
}
|
||||
|
||||
dataSz = msgSz - ivExtra - ssl->keys.padSz;
|
||||
@ -5717,7 +6122,8 @@ int ProcessReply(CYASSL* ssl)
|
||||
if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
|
||||
ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
|
||||
/* go past TLSv1.1 IV */
|
||||
if (ssl->specs.cipher_type == aead)
|
||||
if (ssl->specs.cipher_type == aead &&
|
||||
ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
|
||||
ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ;
|
||||
#endif /* ATOMIC_USER */
|
||||
}
|
||||
@ -5734,7 +6140,8 @@ int ProcessReply(CYASSL* ssl)
|
||||
if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
|
||||
ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
|
||||
/* go past TLSv1.1 IV */
|
||||
if (ssl->specs.cipher_type == aead)
|
||||
if (ssl->specs.cipher_type == aead &&
|
||||
ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
|
||||
ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ;
|
||||
|
||||
ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer +
|
||||
@ -6166,7 +6573,9 @@ static int BuildMessage(CYASSL* ssl, byte* output, int outSz,
|
||||
|
||||
#ifdef HAVE_AEAD
|
||||
if (ssl->specs.cipher_type == aead) {
|
||||
ivSz = AEAD_EXP_IV_SZ;
|
||||
if (ssl->specs.bulk_cipher_algorithm != cyassl_chacha)
|
||||
ivSz = AEAD_EXP_IV_SZ;
|
||||
|
||||
sz += (ivSz + ssl->specs.aead_mac_size - digestSz);
|
||||
XMEMCPY(iv, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
|
||||
}
|
||||
@ -7434,6 +7843,18 @@ static const char* const cipher_names[] =
|
||||
"ECDH-ECDSA-AES256-SHA384",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
"ECDHE-RSA-CHACHA20-POLY1305",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
"ECDHE-ECDSA-CHACHA20-POLY1305",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
"DHE-RSA-CHACHA20-POLY1305",
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -7807,7 +8228,19 @@ static int cipher_name_idx[] =
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
|
||||
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
|
||||
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -7854,8 +8287,12 @@ int SetCipherList(Suites* s, const char* list)
|
||||
|
||||
for (i = 0; i < suiteSz; i++)
|
||||
if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
|
||||
if (XSTRSTR(name, "EC") || XSTRSTR(name, "CCM"))
|
||||
s->suites[idx++] = ECC_BYTE; /* ECC suite */
|
||||
if (XSTRSTR(name, "CHACHA"))
|
||||
s->suites[idx++] = CHACHA_BYTE;
|
||||
else if (XSTRSTR(name, "EC") || XSTRSTR(name, "CCM")) {
|
||||
|
||||
s->suites[idx++] = ECC_BYTE; /* ECC suite */
|
||||
}
|
||||
else
|
||||
s->suites[idx++] = 0x00; /* normal */
|
||||
s->suites[idx++] = (byte)cipher_name_idx[i];
|
||||
|
123
src/keys.c
123
src/keys.c
@ -28,7 +28,7 @@
|
||||
|
||||
#include <cyassl/internal.h>
|
||||
#include <cyassl/error-ssl.h>
|
||||
#ifdef SHOW_SECRETS
|
||||
#if defined(SHOW_SECRETS) || defined(CHACHA_AEAD_TEST)
|
||||
#ifdef FREESCALE_MQX
|
||||
#include <fio.h>
|
||||
#else
|
||||
@ -49,6 +49,69 @@ int SetCipherSpecs(CYASSL* ssl)
|
||||
}
|
||||
#endif /* NO_CYASSL_CLIENT */
|
||||
|
||||
/* Chacha extensions, 0xcc */
|
||||
if (ssl->options.cipherSuite0 == CHACHA_BYTE) {
|
||||
|
||||
switch (ssl->options.cipherSuite) {
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
|
||||
ssl->specs.bulk_cipher_algorithm = cyassl_chacha;
|
||||
ssl->specs.cipher_type = aead;
|
||||
ssl->specs.mac_algorithm = sha256_mac;
|
||||
ssl->specs.kea = ecc_diffie_hellman_kea;
|
||||
ssl->specs.sig_algo = rsa_sa_algo;
|
||||
ssl->specs.hash_size = SHA256_DIGEST_SIZE;
|
||||
ssl->specs.pad_size = PAD_SHA;
|
||||
ssl->specs.static_ecdh = 0;
|
||||
ssl->specs.key_size = CHACHA20_256_KEY_SIZE;
|
||||
ssl->specs.block_size = CHACHA20_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = CHACHA20_IV_SIZE;
|
||||
ssl->specs.aead_mac_size = POLY1305_AUTH_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
|
||||
ssl->specs.bulk_cipher_algorithm = cyassl_chacha;
|
||||
ssl->specs.cipher_type = aead;
|
||||
ssl->specs.mac_algorithm = sha256_mac;
|
||||
ssl->specs.kea = ecc_diffie_hellman_kea;
|
||||
ssl->specs.sig_algo = ecc_dsa_sa_algo;
|
||||
ssl->specs.hash_size = SHA256_DIGEST_SIZE;
|
||||
ssl->specs.pad_size = PAD_SHA;
|
||||
ssl->specs.static_ecdh = 0;
|
||||
ssl->specs.key_size = CHACHA20_256_KEY_SIZE;
|
||||
ssl->specs.block_size = CHACHA20_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = CHACHA20_IV_SIZE;
|
||||
ssl->specs.aead_mac_size = POLY1305_AUTH_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
|
||||
ssl->specs.bulk_cipher_algorithm = cyassl_chacha;
|
||||
ssl->specs.cipher_type = aead;
|
||||
ssl->specs.mac_algorithm = sha256_mac;
|
||||
ssl->specs.kea = diffie_hellman_kea;
|
||||
ssl->specs.sig_algo = rsa_sa_algo;
|
||||
ssl->specs.hash_size = SHA256_DIGEST_SIZE;
|
||||
ssl->specs.pad_size = PAD_SHA;
|
||||
ssl->specs.static_ecdh = 0;
|
||||
ssl->specs.key_size = CHACHA20_256_KEY_SIZE;
|
||||
ssl->specs.block_size = CHACHA20_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = CHACHA20_IV_SIZE;
|
||||
ssl->specs.aead_mac_size = POLY1305_AUTH_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
CYASSL_MSG("Unsupported cipher suite, SetCipherSpecs ChaCha");
|
||||
return UNSUPPORTED_SUITE;
|
||||
}
|
||||
}
|
||||
|
||||
/* ECC extensions, or AES-CCM */
|
||||
if (ssl->options.cipherSuite0 == ECC_BYTE) {
|
||||
|
||||
@ -792,7 +855,8 @@ int SetCipherSpecs(CYASSL* ssl)
|
||||
return UNSUPPORTED_SUITE;
|
||||
} /* switch */
|
||||
} /* if */
|
||||
if (ssl->options.cipherSuite0 != ECC_BYTE) { /* normal suites */
|
||||
if (ssl->options.cipherSuite0 != ECC_BYTE &&
|
||||
ssl->options.cipherSuite0 != CHACHA_BYTE) { /* normal suites */
|
||||
switch (ssl->options.cipherSuite) {
|
||||
|
||||
#ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
|
||||
@ -1774,7 +1838,62 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
|
||||
dec->setup = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
/* set up memory space for poly1305 */
|
||||
if (enc->poly1305 == NULL)
|
||||
enc->poly1305 = (Poly1305*)malloc(sizeof(Poly1305));
|
||||
if (enc->poly1305 == NULL)
|
||||
return MEMORY_E;
|
||||
if (dec->poly1305 == NULL)
|
||||
dec->poly1305 =
|
||||
(Poly1305*)XMALLOC(sizeof(Poly1305), heap, DYNAMIC_TYPE_CIPHER);
|
||||
if (dec->poly1305 == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
if (specs->bulk_cipher_algorithm == cyassl_chacha) {
|
||||
int chachaRet;
|
||||
if (enc->chacha == NULL)
|
||||
enc->chacha = (ChaCha*)malloc(sizeof(ChaCha));
|
||||
if (enc->chacha == NULL)
|
||||
return MEMORY_E;
|
||||
if (dec->chacha == NULL)
|
||||
dec->chacha =
|
||||
(ChaCha*)XMALLOC(sizeof(ChaCha), heap, DYNAMIC_TYPE_CIPHER);
|
||||
if (dec->chacha == NULL)
|
||||
return MEMORY_E;
|
||||
if (side == CYASSL_CLIENT_END) {
|
||||
chachaRet = Chacha_SetKey(enc->chacha, keys->client_write_key,
|
||||
specs->key_size);
|
||||
XMEMCPY(keys->aead_enc_imp_IV,
|
||||
keys->client_write_IV, AEAD_IMP_IV_SZ);
|
||||
if (chachaRet != 0) return chachaRet;
|
||||
chachaRet = Chacha_SetKey(dec->chacha, keys->server_write_key,
|
||||
specs->key_size);
|
||||
XMEMCPY(keys->aead_dec_imp_IV,
|
||||
keys->server_write_IV, AEAD_IMP_IV_SZ);
|
||||
if (chachaRet != 0) return chachaRet;
|
||||
}
|
||||
else {
|
||||
chachaRet = Chacha_SetKey(enc->chacha, keys->server_write_key,
|
||||
specs->key_size);
|
||||
XMEMCPY(keys->aead_enc_imp_IV,
|
||||
keys->server_write_IV, AEAD_IMP_IV_SZ);
|
||||
if (chachaRet != 0) return chachaRet;
|
||||
chachaRet = Chacha_SetKey(dec->chacha, keys->client_write_key,
|
||||
specs->key_size);
|
||||
XMEMCPY(keys->aead_dec_imp_IV,
|
||||
keys->client_write_IV, AEAD_IMP_IV_SZ);
|
||||
if (chachaRet != 0) return chachaRet;
|
||||
}
|
||||
|
||||
enc->setup = 1;
|
||||
dec->setup = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HC128
|
||||
if (specs->bulk_cipher_algorithm == cyassl_hc128) {
|
||||
int hcRet;
|
||||
|
38
src/ssl.c
38
src/ssl.c
@ -194,6 +194,16 @@ void CyaSSL_free(CYASSL* ssl)
|
||||
CYASSL_LEAVE("SSL_free", 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
/* set if to use old poly 1 for yes 0 to use new poly */
|
||||
int CyaSSL_use_old_poly(CYASSL* ssl, int value)
|
||||
{
|
||||
CYASSL_ENTER("SSL_use_old_poly");
|
||||
ssl->options.oldPoly = value;
|
||||
CYASSL_LEAVE("SSL_use_old_poly", 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int CyaSSL_set_fd(CYASSL* ssl, int fd)
|
||||
{
|
||||
@ -324,6 +334,9 @@ int CyaSSL_GetObjectSize(void)
|
||||
#endif
|
||||
#ifndef NO_RABBIT
|
||||
printf(" sizeof rabbit = %lu\n", sizeof(Rabbit));
|
||||
#endif
|
||||
#ifdef HAVE_CHACHA
|
||||
printf(" sizeof chacha = %lu\n", sizeof(Chacha));
|
||||
#endif
|
||||
printf("sizeof cipher specs = %lu\n", sizeof(CipherSpecs));
|
||||
printf("sizeof keys = %lu\n", sizeof(Keys));
|
||||
@ -8362,6 +8375,25 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format)
|
||||
CYASSL_ENTER("SSL_CIPHER_get_name");
|
||||
#ifndef NO_ERROR_STRINGS
|
||||
if (cipher) {
|
||||
#if defined(HAVE_CHACHA)
|
||||
if (cipher->ssl->options.cipherSuite0 == CHACHA_BYTE) {
|
||||
/* ChaCha suites */
|
||||
switch (cipher->ssl->options.cipherSuite) {
|
||||
#ifdef HAVE_CHACHA
|
||||
#ifndef NO_RSA
|
||||
case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
|
||||
return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
|
||||
|
||||
case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
|
||||
return "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
|
||||
#endif
|
||||
case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
|
||||
return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ECC) || defined(HAVE_AESCCM)
|
||||
/* Awkwardly, the ECC cipher suites use the ECC_BYTE as expected,
|
||||
* but the AES-CCM cipher suites also use it, even the ones that
|
||||
@ -8508,8 +8540,10 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format)
|
||||
}
|
||||
}
|
||||
#endif /* ECC */
|
||||
if (cipher->ssl->options.cipherSuite0 != ECC_BYTE) {
|
||||
/* normal suites */
|
||||
if (cipher->ssl->options.cipherSuite0 != ECC_BYTE &&
|
||||
cipher->ssl->options.cipherSuite0 != CHACHA_BYTE) {
|
||||
|
||||
/* normal suites */
|
||||
switch (cipher->ssl->options.cipherSuite) {
|
||||
#ifndef NO_RSA
|
||||
#ifndef NO_RC4
|
||||
|
@ -1,3 +1,69 @@
|
||||
# server DTLSv1 DHE-RSA-CHACHA20-POLY1305
|
||||
-u
|
||||
-v 2
|
||||
-l DHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# client DTLSv1 DHE-RSA-CHACHA20-POLY1305
|
||||
-u
|
||||
-v 2
|
||||
-l DHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# server DTLSv1 ECDHE-RSA-CHACHA20-POLY1305
|
||||
-u
|
||||
-v 2
|
||||
-l ECDHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# client DTLSv1 ECDHE-RSA-CHACHA20-POLY1305
|
||||
-u
|
||||
-v 2
|
||||
-l ECDHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# server DTLSv1 ECDHE-EDCSA-CHACHA20-POLY1305
|
||||
-u
|
||||
-v 2
|
||||
-l ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-c ./certs/server-ecc.pem
|
||||
-k ./certs/ecc-key.pem
|
||||
|
||||
# client DTLSv1 ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-u
|
||||
-v 2
|
||||
-l ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-A ./certs/server-ecc.pem
|
||||
|
||||
# server DTLSv1.2 DHE-RSA-CHACHA20-POLY1305
|
||||
-u
|
||||
-v 3
|
||||
-l DHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# client DTLSv1.2 DHE-RSA-CHACHA20-POLY1305
|
||||
-u
|
||||
-v 3
|
||||
-l DHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# server DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305
|
||||
-u
|
||||
-v 3
|
||||
-l ECDHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# client DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305
|
||||
-u
|
||||
-v 3
|
||||
-l ECDHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# server DTLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305
|
||||
-u
|
||||
-v 3
|
||||
-l ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-c ./certs/server-ecc.pem
|
||||
-k ./certs/ecc-key.pem
|
||||
|
||||
# client DTLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-u
|
||||
-v 3
|
||||
-l ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-A ./certs/server-ecc.pem
|
||||
|
||||
# server DTLSv1 RC4-SHA
|
||||
-u
|
||||
-v 2
|
||||
|
@ -1,3 +1,84 @@
|
||||
# server TLSv1 DHE-RSA-CHACHA20-POLY1305
|
||||
-v 1
|
||||
-l DHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# client TLSv1 DHE-RSA-CHACHA20-POLY1305
|
||||
-v 1
|
||||
-l DHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# server TLSv1 ECDHE-EDCSA-CHACHA20-POLY1305
|
||||
-v 1
|
||||
-l ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-c ./certs/server-ecc.pem
|
||||
-k ./certs/ecc-key.pem
|
||||
|
||||
# client TLSv1 ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-v 1
|
||||
-l ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-A ./certs/server-ecc.pem
|
||||
|
||||
# server TLSv1 ECDHE-RSA-CHACHA20-POLY1305
|
||||
-v 1
|
||||
-l ECDHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# client TLSv1 ECDHE-RSA-CHACHA20-POLY1305
|
||||
-v 1
|
||||
-l ECDHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# server TLSv1.1 DHE-RSA-CHACHA20-POLY1305
|
||||
-v 2
|
||||
-l DHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# client TLSv1.1 DHE-RSA-CHACHA20-POLY1305
|
||||
-v 2
|
||||
-l DHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# server TLSv1.1 ECDHE-RSA-CHACHA20-POLY1305
|
||||
-v 2
|
||||
-l ECDHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# client TLSv1.1 ECDHE-RSA-CHACHA20-POLY1305
|
||||
-v 2
|
||||
-l ECDHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# server TLSv1.1 ECDHE-EDCSA-CHACHA20-POLY1305
|
||||
-v 2
|
||||
-l ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-c ./certs/server-ecc.pem
|
||||
-k ./certs/ecc-key.pem
|
||||
|
||||
# client TLSv1.1 ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-v 2
|
||||
-l ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-A ./certs/server-ecc.pem
|
||||
|
||||
# server TLSv1.2 DHE-RSA-CHACHA20-POLY1305
|
||||
-v 3
|
||||
-l DHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# client TLSv1.2 DHE-RSA-CHACHA20-POLY1305
|
||||
-v 3
|
||||
-l DHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# server TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305
|
||||
-v 3
|
||||
-l ECDHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# client TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305
|
||||
-v 3
|
||||
-l ECDHE-RSA-CHACHA20-POLY1305
|
||||
|
||||
# server TLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305
|
||||
-v 3
|
||||
-l ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-c ./certs/server-ecc.pem
|
||||
-k ./certs/ecc-key.pem
|
||||
|
||||
# client TLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-v 3
|
||||
-l ECDHE-ECDSA-CHACHA20-POLY1305
|
||||
-A ./certs/server-ecc.pem
|
||||
|
||||
# server SSLv3 RC4-SHA
|
||||
-v 0
|
||||
-l RC4-SHA
|
||||
|
Loading…
Reference in New Issue
Block a user