Merge branch 'master' of github.com:cyassl/cyassl
This commit is contained in:
commit
e2eb1b78cc
25
configure.ac
25
configure.ac
@ -296,9 +296,27 @@ AC_ARG_ENABLE(aesgcm,
|
||||
[ ENABLED_AESGCM=no ]
|
||||
)
|
||||
|
||||
if test "$ENABLED_AESGCM" = "word32"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DGCM_WORD32"
|
||||
ENABLED_AESGCM=yes
|
||||
fi
|
||||
|
||||
if test "$ENABLED_AESGCM" = "small"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DGCM_SMALL"
|
||||
ENABLED_AESGCM=yes
|
||||
fi
|
||||
|
||||
if test "$ENABLED_AESGCM" = "table"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DGCM_TABLE"
|
||||
ENABLED_AESGCM=yes
|
||||
fi
|
||||
|
||||
if test "$ENABLED_AESGCM" = "yes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_AESGCM"
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_AESGCM -DCYASSL_SHA384 -DCYASSL_SHA512"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([BUILD_AESGCM], [test "x$ENABLED_AESGCM" = "xyes"])
|
||||
@ -355,6 +373,11 @@ then
|
||||
ENABLED_SHA512="yes"
|
||||
fi
|
||||
|
||||
if test "$ENABLED_AESGCM" = "yes"
|
||||
then
|
||||
ENABLED_SHA512="yes"
|
||||
fi
|
||||
|
||||
|
||||
AM_CONDITIONAL([BUILD_SHA512], [test "x$ENABLED_SHA512" = "xyes"])
|
||||
|
||||
|
@ -54,6 +54,7 @@ void bench_arc4();
|
||||
void bench_hc128();
|
||||
void bench_rabbit();
|
||||
void bench_aes(int);
|
||||
void bench_aesgcm();
|
||||
|
||||
void bench_md5();
|
||||
void bench_sha();
|
||||
@ -78,6 +79,9 @@ int main(int argc, char** argv)
|
||||
#ifndef NO_AES
|
||||
bench_aes(0);
|
||||
bench_aes(1);
|
||||
#endif
|
||||
#ifdef HAVE_AESGCM
|
||||
bench_aesgcm();
|
||||
#endif
|
||||
bench_arc4();
|
||||
#ifdef HAVE_HC128
|
||||
@ -171,6 +175,34 @@ void bench_aes(int show)
|
||||
#endif
|
||||
|
||||
|
||||
byte additional[13];
|
||||
byte tag[16];
|
||||
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
void bench_aesgcm()
|
||||
{
|
||||
Aes enc;
|
||||
double start, total, persec;
|
||||
int i;
|
||||
|
||||
AesGcmSetKey(&enc, key, 16);
|
||||
AesSetIV(&enc, iv);
|
||||
start = current_time();
|
||||
|
||||
for(i = 0; i < megs; i++)
|
||||
AesGcmEncrypt(&enc, cipher, plain, sizeof(plain),
|
||||
tag, 16, additional, 13);
|
||||
|
||||
total = current_time() - start;
|
||||
|
||||
persec = 1 / total * megs;
|
||||
printf("AES-GCM %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
|
||||
persec);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NO_DES3
|
||||
void bench_des()
|
||||
{
|
||||
|
@ -1428,29 +1428,92 @@ static INLINE void IncrementGcmCounter(byte* inOutCtr)
|
||||
}
|
||||
|
||||
|
||||
static void RIGHTSHIFT(byte* x)
|
||||
#if defined(GCM_SMALL) || defined(GCM_TABLE)
|
||||
|
||||
static INLINE void FlattenSzInBits(byte* buf, word32 sz)
|
||||
{
|
||||
/* Multiply the sz by 8 */
|
||||
word32 szHi = (sz >> (8*sizeof(sz) - 3));
|
||||
sz <<= 3;
|
||||
|
||||
/* copy over the words of the sz into the destination buffer */
|
||||
buf[0] = (szHi >> 24) & 0xff;
|
||||
buf[1] = (szHi >> 16) & 0xff;
|
||||
buf[2] = (szHi >> 8) & 0xff;
|
||||
buf[3] = szHi & 0xff;
|
||||
buf[4] = (sz >> 24) & 0xff;
|
||||
buf[5] = (sz >> 16) & 0xff;
|
||||
buf[6] = (sz >> 8) & 0xff;
|
||||
buf[7] = sz & 0xff;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void RIGHTSHIFTX(byte* x)
|
||||
{
|
||||
int i;
|
||||
int carryOut = 0;
|
||||
int carryIn = 0;
|
||||
int borrow = x[15] & 0x01;
|
||||
|
||||
for (i = 0; i < AES_BLOCK_SIZE; i++) {
|
||||
carryOut = x[i] & 0x01;
|
||||
x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);
|
||||
carryIn = carryOut;
|
||||
}
|
||||
if (borrow) x[0] ^= 0xE1;
|
||||
}
|
||||
|
||||
#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) */
|
||||
|
||||
|
||||
#ifdef GCM_TABLE
|
||||
|
||||
static void GenerateM0(Aes* aes)
|
||||
{
|
||||
int i, j;
|
||||
byte (*m)[AES_BLOCK_SIZE] = aes->M0;
|
||||
|
||||
XMEMCPY(m[128], aes->H, AES_BLOCK_SIZE);
|
||||
|
||||
for (i = 64; i > 0; i /= 2) {
|
||||
XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE);
|
||||
RIGHTSHIFTX(m[i]);
|
||||
}
|
||||
|
||||
for (i = 2; i < 256; i *= 2) {
|
||||
for (j = 1; j < i; j++) {
|
||||
XMEMCPY(m[i+j], m[i], AES_BLOCK_SIZE);
|
||||
xorbuf(m[i+j], m[j], AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
XMEMSET(m[0], 0, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
#endif /* GCM_TABLE */
|
||||
|
||||
|
||||
void AesGcmSetKey(Aes* aes, const byte* key, word32 len)
|
||||
{
|
||||
byte iv[AES_BLOCK_SIZE];
|
||||
|
||||
XMEMSET(iv, 0, AES_BLOCK_SIZE);
|
||||
AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
|
||||
AesEncrypt(aes, iv, aes->H);
|
||||
#ifdef GCM_TABLE
|
||||
GenerateM0(aes);
|
||||
#endif /* GCM_TABLE */
|
||||
}
|
||||
|
||||
|
||||
#if defined(GCM_SMALL)
|
||||
|
||||
static void GMULT(byte* X, byte* Y)
|
||||
{
|
||||
byte R[AES_BLOCK_SIZE];
|
||||
byte Z[AES_BLOCK_SIZE];
|
||||
byte V[AES_BLOCK_SIZE];
|
||||
int i, j;
|
||||
|
||||
XMEMSET(R, 0, AES_BLOCK_SIZE);
|
||||
R[0] = 0xE1;
|
||||
XMEMSET(Z, 0, AES_BLOCK_SIZE);
|
||||
XMEMCPY(V, X, AES_BLOCK_SIZE);
|
||||
for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||
@ -1462,12 +1525,7 @@ static void GMULT(byte* X, byte* Y)
|
||||
xorbuf(Z, V, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if (V[15] & 0x01) {
|
||||
RIGHTSHIFT(V);
|
||||
xorbuf(V, R, AES_BLOCK_SIZE);
|
||||
} else {
|
||||
RIGHTSHIFT(V);
|
||||
}
|
||||
RIGHTSHIFTX(V);
|
||||
y = y << 1;
|
||||
}
|
||||
}
|
||||
@ -1475,11 +1533,13 @@ static void GMULT(byte* X, byte* Y)
|
||||
}
|
||||
|
||||
|
||||
static void GHASH(byte* h, const byte* a, word32 aSz,
|
||||
static void GHASH(Aes* aes, const byte* a, word32 aSz,
|
||||
const byte* c, word32 cSz, byte* s, word32 sSz)
|
||||
{
|
||||
byte x[AES_BLOCK_SIZE];
|
||||
byte scratch[AES_BLOCK_SIZE];
|
||||
word32 blocks, partial;
|
||||
byte* h = aes->H;
|
||||
|
||||
XMEMSET(x, 0, AES_BLOCK_SIZE);
|
||||
|
||||
@ -1493,7 +1553,6 @@ static void GHASH(byte* h, const byte* a, word32 aSz,
|
||||
a += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (partial != 0) {
|
||||
byte scratch[AES_BLOCK_SIZE];
|
||||
XMEMSET(scratch, 0, AES_BLOCK_SIZE);
|
||||
XMEMCPY(scratch, a, partial);
|
||||
xorbuf(x, scratch, AES_BLOCK_SIZE);
|
||||
@ -1511,7 +1570,6 @@ static void GHASH(byte* h, const byte* a, word32 aSz,
|
||||
c += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (partial != 0) {
|
||||
byte scratch[AES_BLOCK_SIZE];
|
||||
XMEMSET(scratch, 0, AES_BLOCK_SIZE);
|
||||
XMEMCPY(scratch, c, partial);
|
||||
xorbuf(x, scratch, AES_BLOCK_SIZE);
|
||||
@ -1519,27 +1577,433 @@ static void GHASH(byte* h, const byte* a, word32 aSz,
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash in the lengths in bits of A and C */
|
||||
{
|
||||
byte len[AES_BLOCK_SIZE];
|
||||
XMEMSET(len, 0, AES_BLOCK_SIZE);
|
||||
len[3] = aSz >> 29;
|
||||
len[4] = aSz >> 21;
|
||||
len[5] = aSz >> 13;
|
||||
len[6] = aSz >> 5;
|
||||
len[7] = aSz << 3;
|
||||
/* Hash in the lengths of A and C in bits */
|
||||
FlattenSzInBits(&scratch[0], aSz);
|
||||
FlattenSzInBits(&scratch[8], cSz);
|
||||
xorbuf(x, scratch, AES_BLOCK_SIZE);
|
||||
GMULT(x, h);
|
||||
|
||||
len[11] = cSz >> 29;
|
||||
len[12] = cSz >> 21;
|
||||
len[13] = cSz >> 13;
|
||||
len[14] = cSz >> 5;
|
||||
len[15] = cSz << 3;
|
||||
xorbuf(x, len, AES_BLOCK_SIZE);
|
||||
GMULT(x, h);
|
||||
}
|
||||
/* Copy the result into s. */
|
||||
XMEMCPY(s, x, sSz);
|
||||
}
|
||||
|
||||
/* end GCM_SMALL */
|
||||
#elif defined(GCM_TABLE)
|
||||
|
||||
static const byte R[256][2] = {
|
||||
{0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
|
||||
{0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
|
||||
{0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
|
||||
{0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
|
||||
{0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
|
||||
{0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
|
||||
{0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
|
||||
{0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
|
||||
{0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
|
||||
{0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
|
||||
{0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
|
||||
{0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
|
||||
{0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
|
||||
{0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
|
||||
{0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
|
||||
{0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
|
||||
{0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
|
||||
{0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
|
||||
{0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
|
||||
{0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
|
||||
{0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
|
||||
{0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
|
||||
{0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
|
||||
{0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
|
||||
{0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
|
||||
{0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
|
||||
{0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
|
||||
{0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
|
||||
{0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
|
||||
{0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
|
||||
{0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
|
||||
{0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
|
||||
{0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
|
||||
{0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
|
||||
{0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
|
||||
{0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
|
||||
{0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
|
||||
{0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
|
||||
{0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
|
||||
{0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
|
||||
{0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
|
||||
{0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
|
||||
{0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
|
||||
{0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
|
||||
{0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
|
||||
{0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
|
||||
{0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
|
||||
{0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
|
||||
{0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
|
||||
{0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
|
||||
{0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
|
||||
{0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
|
||||
{0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
|
||||
{0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
|
||||
{0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
|
||||
{0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
|
||||
{0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
|
||||
{0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
|
||||
{0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
|
||||
{0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
|
||||
{0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
|
||||
{0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
|
||||
{0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
|
||||
{0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
|
||||
|
||||
|
||||
static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE])
|
||||
{
|
||||
int i, j;
|
||||
byte Z[AES_BLOCK_SIZE];
|
||||
byte a;
|
||||
|
||||
XMEMSET(Z, 0, sizeof(Z));
|
||||
|
||||
for (i = 15; i > 0; i--) {
|
||||
xorbuf(Z, m[x[i]], AES_BLOCK_SIZE);
|
||||
a = Z[15];
|
||||
|
||||
for (j = 15; j > 0; j--) {
|
||||
Z[j] = Z[j-1];
|
||||
}
|
||||
|
||||
Z[0] = R[a][0];
|
||||
Z[1] ^= R[a][1];
|
||||
}
|
||||
xorbuf(Z, m[x[0]], AES_BLOCK_SIZE);
|
||||
|
||||
XMEMCPY(x, Z, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
|
||||
static void GHASH(Aes* aes, const byte* a, word32 aSz,
|
||||
const byte* c, word32 cSz, byte* s, word32 sSz)
|
||||
{
|
||||
byte x[AES_BLOCK_SIZE];
|
||||
byte scratch[AES_BLOCK_SIZE];
|
||||
word32 blocks, partial;
|
||||
|
||||
XMEMSET(x, 0, AES_BLOCK_SIZE);
|
||||
|
||||
/* Hash in A, the Additional Authentication Data */
|
||||
if (aSz != 0 && a != NULL) {
|
||||
blocks = aSz / AES_BLOCK_SIZE;
|
||||
partial = aSz % AES_BLOCK_SIZE;
|
||||
while (blocks--) {
|
||||
xorbuf(x, a, AES_BLOCK_SIZE);
|
||||
GMULT(x, aes->M0);
|
||||
a += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (partial != 0) {
|
||||
XMEMSET(scratch, 0, AES_BLOCK_SIZE);
|
||||
XMEMCPY(scratch, a, partial);
|
||||
xorbuf(x, scratch, AES_BLOCK_SIZE);
|
||||
GMULT(x, aes->M0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash in C, the Ciphertext */
|
||||
if (cSz != 0 && c != NULL) {
|
||||
blocks = cSz / AES_BLOCK_SIZE;
|
||||
partial = cSz % AES_BLOCK_SIZE;
|
||||
while (blocks--) {
|
||||
xorbuf(x, c, AES_BLOCK_SIZE);
|
||||
GMULT(x, aes->M0);
|
||||
c += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (partial != 0) {
|
||||
XMEMSET(scratch, 0, AES_BLOCK_SIZE);
|
||||
XMEMCPY(scratch, c, partial);
|
||||
xorbuf(x, scratch, AES_BLOCK_SIZE);
|
||||
GMULT(x, aes->M0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash in the lengths of A and C in bits */
|
||||
FlattenSzInBits(&scratch[0], aSz);
|
||||
FlattenSzInBits(&scratch[8], cSz);
|
||||
xorbuf(x, scratch, AES_BLOCK_SIZE);
|
||||
GMULT(x, aes->M0);
|
||||
|
||||
/* Copy the result into s. */
|
||||
XMEMCPY(s, x, sSz);
|
||||
}
|
||||
|
||||
/* end GCM_TABLE */
|
||||
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
|
||||
|
||||
static void GMULT(word64* X, word64* Y)
|
||||
{
|
||||
word64 Z[2] = {0,0};
|
||||
word64 V[2] = {X[0], X[1]};
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
word64 y = Y[i];
|
||||
for (j = 0; j < 64; j++)
|
||||
{
|
||||
if (y & 0x8000000000000000) {
|
||||
Z[0] ^= V[0];
|
||||
Z[1] ^= V[1];
|
||||
}
|
||||
|
||||
if (V[1] & 0x0000000000000001) {
|
||||
V[1] >>= 1;
|
||||
V[1] |= ((V[0] & 0x0000000000000001) ? 0x8000000000000000 : 0);
|
||||
V[0] >>= 1;
|
||||
V[0] ^= 0xE100000000000000;
|
||||
}
|
||||
else {
|
||||
V[1] >>= 1;
|
||||
V[1] |= ((V[0] & 0x0000000000000001) ? 0x8000000000000000 : 0);
|
||||
V[0] >>= 1;
|
||||
}
|
||||
y <<= 1;
|
||||
}
|
||||
}
|
||||
X[0] = Z[0];
|
||||
X[1] = Z[1];
|
||||
}
|
||||
|
||||
|
||||
static void GHASH(Aes* aes, const byte* a, word32 aSz,
|
||||
const byte* c, word32 cSz, byte* s, word32 sSz)
|
||||
{
|
||||
word64 x[2] = {0,0};
|
||||
word32 blocks, partial;
|
||||
word64 bigH[2];
|
||||
|
||||
XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(bigH, bigH, AES_BLOCK_SIZE);
|
||||
#endif
|
||||
|
||||
/* Hash in A, the Additional Authentication Data */
|
||||
if (aSz != 0 && a != NULL) {
|
||||
word64 bigA[2];
|
||||
blocks = aSz / AES_BLOCK_SIZE;
|
||||
partial = aSz % AES_BLOCK_SIZE;
|
||||
while (blocks--) {
|
||||
XMEMCPY(bigA, a, AES_BLOCK_SIZE);
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
|
||||
#endif
|
||||
x[0] ^= bigA[0];
|
||||
x[1] ^= bigA[1];
|
||||
GMULT(x, bigH);
|
||||
a += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (partial != 0) {
|
||||
XMEMSET(bigA, 0, AES_BLOCK_SIZE);
|
||||
XMEMCPY(bigA, a, partial);
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
|
||||
#endif
|
||||
x[0] ^= bigA[0];
|
||||
x[1] ^= bigA[1];
|
||||
GMULT(x, bigH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash in C, the Ciphertext */
|
||||
if (cSz != 0 && c != NULL) {
|
||||
word64 bigC[2];
|
||||
blocks = cSz / AES_BLOCK_SIZE;
|
||||
partial = cSz % AES_BLOCK_SIZE;
|
||||
while (blocks--) {
|
||||
XMEMCPY(bigC, c, AES_BLOCK_SIZE);
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
|
||||
#endif
|
||||
x[0] ^= bigC[0];
|
||||
x[1] ^= bigC[1];
|
||||
GMULT(x, bigH);
|
||||
c += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (partial != 0) {
|
||||
XMEMSET(bigC, 0, AES_BLOCK_SIZE);
|
||||
XMEMCPY(bigC, c, partial);
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
|
||||
#endif
|
||||
x[0] ^= bigC[0];
|
||||
x[1] ^= bigC[1];
|
||||
GMULT(x, bigH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash in the lengths in bits of A and C */
|
||||
{
|
||||
word64 len[2] = {aSz, cSz};
|
||||
|
||||
/* Lengths are in bytes. Convert to bits. */
|
||||
len[0] *= 8;
|
||||
len[1] *= 8;
|
||||
|
||||
x[0] ^= len[0];
|
||||
x[1] ^= len[1];
|
||||
GMULT(x, bigH);
|
||||
}
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords64(x, x, AES_BLOCK_SIZE);
|
||||
#endif
|
||||
XMEMCPY(s, x, sSz);
|
||||
}
|
||||
|
||||
/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
|
||||
#else /* GCM_WORD32 */
|
||||
|
||||
static void GMULT(word32* X, word32* Y)
|
||||
{
|
||||
word32 Z[4] = {0,0,0,0};
|
||||
word32 V[4] = {X[0], X[1], X[2], X[3]};
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
word32 y = Y[i];
|
||||
for (j = 0; j < 32; j++)
|
||||
{
|
||||
if (y & 0x80000000) {
|
||||
Z[0] ^= V[0];
|
||||
Z[1] ^= V[1];
|
||||
Z[2] ^= V[2];
|
||||
Z[3] ^= V[3];
|
||||
}
|
||||
|
||||
if (V[3] & 0x00000001) {
|
||||
V[3] >>= 1;
|
||||
V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
|
||||
V[2] >>= 1;
|
||||
V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
|
||||
V[1] >>= 1;
|
||||
V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
|
||||
V[0] >>= 1;
|
||||
V[0] ^= 0xE1000000;
|
||||
} else {
|
||||
V[3] >>= 1;
|
||||
V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
|
||||
V[2] >>= 1;
|
||||
V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
|
||||
V[1] >>= 1;
|
||||
V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
|
||||
V[0] >>= 1;
|
||||
}
|
||||
y <<= 1;
|
||||
}
|
||||
}
|
||||
X[0] = Z[0];
|
||||
X[1] = Z[1];
|
||||
X[2] = Z[2];
|
||||
X[3] = Z[3];
|
||||
}
|
||||
|
||||
|
||||
static void GHASH(Aes* aes, const byte* a, word32 aSz,
|
||||
const byte* c, word32 cSz, byte* s, word32 sSz)
|
||||
{
|
||||
word32 x[4] = {0,0,0,0};
|
||||
word32 blocks, partial;
|
||||
word32 bigH[4];
|
||||
|
||||
XMEMCPY(bigH, aes->H, AES_BLOCK_SIZE);
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords(bigH, bigH, AES_BLOCK_SIZE);
|
||||
#endif
|
||||
|
||||
/* Hash in A, the Additional Authentication Data */
|
||||
if (aSz != 0 && a != NULL) {
|
||||
word32 bigA[4];
|
||||
blocks = aSz / AES_BLOCK_SIZE;
|
||||
partial = aSz % AES_BLOCK_SIZE;
|
||||
while (blocks--) {
|
||||
XMEMCPY(bigA, a, AES_BLOCK_SIZE);
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
|
||||
#endif
|
||||
x[0] ^= bigA[0];
|
||||
x[1] ^= bigA[1];
|
||||
x[2] ^= bigA[2];
|
||||
x[3] ^= bigA[3];
|
||||
GMULT(x, bigH);
|
||||
a += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (partial != 0) {
|
||||
XMEMSET(bigA, 0, AES_BLOCK_SIZE);
|
||||
XMEMCPY(bigA, a, partial);
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
|
||||
#endif
|
||||
x[0] ^= bigA[0];
|
||||
x[1] ^= bigA[1];
|
||||
x[2] ^= bigA[2];
|
||||
x[3] ^= bigA[3];
|
||||
GMULT(x, bigH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash in C, the Ciphertext */
|
||||
if (cSz != 0 && c != NULL) {
|
||||
word32 bigC[4];
|
||||
blocks = cSz / AES_BLOCK_SIZE;
|
||||
partial = cSz % AES_BLOCK_SIZE;
|
||||
while (blocks--) {
|
||||
XMEMCPY(bigC, c, AES_BLOCK_SIZE);
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
|
||||
#endif
|
||||
x[0] ^= bigC[0];
|
||||
x[1] ^= bigC[1];
|
||||
x[2] ^= bigC[2];
|
||||
x[3] ^= bigC[3];
|
||||
GMULT(x, bigH);
|
||||
c += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (partial != 0) {
|
||||
XMEMSET(bigC, 0, AES_BLOCK_SIZE);
|
||||
XMEMCPY(bigC, c, partial);
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
|
||||
#endif
|
||||
x[0] ^= bigC[0];
|
||||
x[1] ^= bigC[1];
|
||||
x[2] ^= bigC[2];
|
||||
x[3] ^= bigC[3];
|
||||
GMULT(x, bigH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash in the lengths in bits of A and C */
|
||||
{
|
||||
word32 len[4];
|
||||
|
||||
/* Lengths are in bytes. Convert to bits. */
|
||||
len[0] = (aSz >> (8*sizeof(aSz) - 3));
|
||||
len[1] = aSz << 3;
|
||||
len[2] = (cSz >> (8*sizeof(cSz) - 3));
|
||||
len[3] = cSz << 3;
|
||||
|
||||
x[0] ^= len[0];
|
||||
x[1] ^= len[1];
|
||||
x[2] ^= len[2];
|
||||
x[3] ^= len[3];
|
||||
GMULT(x, bigH);
|
||||
}
|
||||
#ifdef LITTLE_ENDIAN_ORDER
|
||||
ByteReverseWords(x, x, AES_BLOCK_SIZE);
|
||||
#endif
|
||||
XMEMCPY(s, x, sSz);
|
||||
}
|
||||
|
||||
#endif /* end GCM_WORD32 */
|
||||
|
||||
|
||||
void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
byte* authTag, word32 authTagSz,
|
||||
@ -1549,40 +2013,35 @@ void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
word32 partial = sz % AES_BLOCK_SIZE;
|
||||
const byte* p = in;
|
||||
byte* c = out;
|
||||
byte h[AES_BLOCK_SIZE];
|
||||
byte ctr[AES_BLOCK_SIZE];
|
||||
byte scratch[AES_BLOCK_SIZE];
|
||||
|
||||
CYASSL_ENTER("AesGcmEncrypt");
|
||||
|
||||
/* Set up the H block by encrypting an array of zeroes with the key. */
|
||||
XMEMSET(ctr, 0, AES_BLOCK_SIZE);
|
||||
AesEncrypt(aes, ctr, h);
|
||||
|
||||
/* Initialize the counter with the MS 96 bits of IV, and the counter
|
||||
* portion set to "1". */
|
||||
XMEMCPY(ctr, aes->reg, AES_BLOCK_SIZE - 4);
|
||||
XMEMCPY(ctr, aes->reg, AES_BLOCK_SIZE);
|
||||
InitGcmCounter(ctr);
|
||||
|
||||
while (blocks--) {
|
||||
IncrementGcmCounter(ctr);
|
||||
AesEncrypt(aes, ctr, c);
|
||||
xorbuf(c, p, AES_BLOCK_SIZE);
|
||||
AesEncrypt(aes, ctr, scratch);
|
||||
xorbuf(scratch, p, AES_BLOCK_SIZE);
|
||||
XMEMCPY(c, scratch, AES_BLOCK_SIZE);
|
||||
|
||||
p += AES_BLOCK_SIZE;
|
||||
c += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (partial != 0) {
|
||||
byte cPartial[AES_BLOCK_SIZE];
|
||||
|
||||
IncrementGcmCounter(ctr);
|
||||
AesEncrypt(aes, ctr, cPartial);
|
||||
XMEMCPY(c, cPartial, partial);
|
||||
xorbuf(c, p, partial);
|
||||
AesEncrypt(aes, ctr, scratch);
|
||||
xorbuf(scratch, p, partial);
|
||||
XMEMCPY(c, scratch, partial);
|
||||
}
|
||||
GHASH(h, authIn, authInSz, out, sz, authTag, authTagSz);
|
||||
GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
|
||||
InitGcmCounter(ctr);
|
||||
AesEncrypt(aes, ctr, h);
|
||||
xorbuf(authTag, h, authTagSz);
|
||||
AesEncrypt(aes, ctr, scratch);
|
||||
xorbuf(authTag, scratch, authTagSz);
|
||||
}
|
||||
|
||||
|
||||
@ -1594,18 +2053,14 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
word32 partial = sz % AES_BLOCK_SIZE;
|
||||
const byte* c = in;
|
||||
byte* p = out;
|
||||
byte h[AES_BLOCK_SIZE];
|
||||
byte ctr[AES_BLOCK_SIZE];
|
||||
byte scratch[AES_BLOCK_SIZE];
|
||||
|
||||
CYASSL_ENTER("AesGcmDecrypt");
|
||||
|
||||
/* Set up the H block by encrypting an array of zeroes with the key. */
|
||||
XMEMSET(ctr, 0, AES_BLOCK_SIZE);
|
||||
AesEncrypt(aes, ctr, h);
|
||||
|
||||
/* Initialize the counter with the MS 96 bits of IV, and the counter
|
||||
* portion set to "1". */
|
||||
XMEMCPY(ctr, aes->reg, AES_BLOCK_SIZE - 4);
|
||||
XMEMCPY(ctr, aes->reg, AES_BLOCK_SIZE);
|
||||
InitGcmCounter(ctr);
|
||||
|
||||
/* Calculate the authTag again using the received auth data and the
|
||||
@ -1614,7 +2069,7 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
byte Tprime[AES_BLOCK_SIZE];
|
||||
byte EKY0[AES_BLOCK_SIZE];
|
||||
|
||||
GHASH(h, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
|
||||
GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
|
||||
AesEncrypt(aes, ctr, EKY0);
|
||||
xorbuf(Tprime, EKY0, sizeof(Tprime));
|
||||
if (XMEMCMP(authTag, Tprime, authTagSz) != 0) {
|
||||
@ -1624,19 +2079,18 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
|
||||
while (blocks--) {
|
||||
IncrementGcmCounter(ctr);
|
||||
AesEncrypt(aes, ctr, p);
|
||||
xorbuf(p, c, AES_BLOCK_SIZE);
|
||||
AesEncrypt(aes, ctr, scratch);
|
||||
xorbuf(scratch, c, AES_BLOCK_SIZE);
|
||||
XMEMCPY(p, scratch, AES_BLOCK_SIZE);
|
||||
|
||||
p += AES_BLOCK_SIZE;
|
||||
c += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (partial != 0) {
|
||||
byte pPartial[AES_BLOCK_SIZE];
|
||||
|
||||
IncrementGcmCounter(ctr);
|
||||
AesEncrypt(aes, ctr, pPartial);
|
||||
XMEMCPY(p, pPartial, partial);
|
||||
xorbuf(p, c, partial);
|
||||
AesEncrypt(aes, ctr, scratch);
|
||||
xorbuf(scratch, c, partial);
|
||||
XMEMCPY(p, scratch, partial);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -34,7 +34,7 @@ static int InitHmac(Hmac* hmac, int type)
|
||||
hmac->innerHashKeyed = 0;
|
||||
hmac->macType = (byte)type;
|
||||
|
||||
if (!(type == MD5 || type == SHA || type == SHA256))
|
||||
if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (type == MD5)
|
||||
@ -45,6 +45,10 @@ static int InitHmac(Hmac* hmac, int type)
|
||||
else if (type == SHA256)
|
||||
InitSha256(&hmac->hash.sha256);
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
else if (type == SHA384)
|
||||
InitSha384(&hmac->hash.sha384);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -54,34 +58,60 @@ void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
|
||||
{
|
||||
byte* ip = (byte*) hmac->ipad;
|
||||
byte* op = (byte*) hmac->opad;
|
||||
word32 i;
|
||||
word32 i, hmac_block_size = MD5_BLOCK_SIZE;
|
||||
|
||||
InitHmac(hmac, type);
|
||||
|
||||
if (length <= HMAC_BLOCK_SIZE)
|
||||
XMEMCPY(ip, key, length);
|
||||
else {
|
||||
if (hmac->macType == MD5) {
|
||||
if (hmac->macType == MD5) {
|
||||
if (length <= MD5_BLOCK_SIZE) {
|
||||
XMEMCPY(ip, key, length);
|
||||
}
|
||||
else {
|
||||
Md5Update(&hmac->hash.md5, key, length);
|
||||
Md5Final(&hmac->hash.md5, ip);
|
||||
length = MD5_DIGEST_SIZE;
|
||||
}
|
||||
else if (hmac->macType == SHA) {
|
||||
}
|
||||
else if (hmac->macType == SHA) {
|
||||
hmac_block_size = SHA_BLOCK_SIZE;
|
||||
if (length <= SHA_BLOCK_SIZE) {
|
||||
XMEMCPY(ip, key, length);
|
||||
}
|
||||
else {
|
||||
ShaUpdate(&hmac->hash.sha, key, length);
|
||||
ShaFinal(&hmac->hash.sha, ip);
|
||||
length = SHA_DIGEST_SIZE;
|
||||
}
|
||||
}
|
||||
#ifndef NO_SHA256
|
||||
else if (hmac->macType == SHA256) {
|
||||
else if (hmac->macType == SHA256) {
|
||||
hmac_block_size = SHA256_BLOCK_SIZE;
|
||||
if (length <= SHA256_BLOCK_SIZE) {
|
||||
XMEMCPY(ip, key, length);
|
||||
}
|
||||
else {
|
||||
Sha256Update(&hmac->hash.sha256, key, length);
|
||||
Sha256Final(&hmac->hash.sha256, ip);
|
||||
length = SHA256_DIGEST_SIZE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
XMEMSET(ip + length, 0, HMAC_BLOCK_SIZE - length);
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
else if (hmac->macType == SHA384) {
|
||||
hmac_block_size = SHA384_BLOCK_SIZE;
|
||||
if (length <= SHA384_BLOCK_SIZE) {
|
||||
XMEMCPY(ip, key, length);
|
||||
}
|
||||
else {
|
||||
Sha384Update(&hmac->hash.sha384, key, length);
|
||||
Sha384Final(&hmac->hash.sha384, ip);
|
||||
length = SHA384_DIGEST_SIZE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
XMEMSET(ip + length, 0, hmac_block_size - length);
|
||||
|
||||
for(i = 0; i < HMAC_BLOCK_SIZE; i++) {
|
||||
for(i = 0; i < hmac_block_size; i++) {
|
||||
op[i] = ip[i] ^ OPAD;
|
||||
ip[i] ^= IPAD;
|
||||
}
|
||||
@ -91,12 +121,16 @@ void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
|
||||
static void HmacKeyInnerHash(Hmac* hmac)
|
||||
{
|
||||
if (hmac->macType == MD5)
|
||||
Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, HMAC_BLOCK_SIZE);
|
||||
Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE);
|
||||
else if (hmac->macType == SHA)
|
||||
ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, HMAC_BLOCK_SIZE);
|
||||
ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE);
|
||||
#ifndef NO_SHA256
|
||||
else if (hmac->macType == SHA256)
|
||||
Sha256Update(&hmac->hash.sha256, (byte*) hmac->ipad, HMAC_BLOCK_SIZE);
|
||||
Sha256Update(&hmac->hash.sha256, (byte*) hmac->ipad, SHA256_BLOCK_SIZE);
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
else if (hmac->macType == SHA384)
|
||||
Sha384Update(&hmac->hash.sha384, (byte*) hmac->ipad, SHA384_BLOCK_SIZE);
|
||||
#endif
|
||||
|
||||
hmac->innerHashKeyed = 1;
|
||||
@ -116,6 +150,10 @@ void HmacUpdate(Hmac* hmac, const byte* msg, word32 length)
|
||||
else if (hmac->macType == SHA256)
|
||||
Sha256Update(&hmac->hash.sha256, msg, length);
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
else if (hmac->macType == SHA384)
|
||||
Sha384Update(&hmac->hash.sha384, msg, length);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@ -128,30 +166,41 @@ void HmacFinal(Hmac* hmac, byte* hash)
|
||||
if (hmac->macType == MD5) {
|
||||
Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash);
|
||||
|
||||
Md5Update(&hmac->hash.md5, (byte*) hmac->opad, HMAC_BLOCK_SIZE);
|
||||
Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE);
|
||||
Md5Update(&hmac->hash.md5, (byte*) hmac->innerHash, MD5_DIGEST_SIZE);
|
||||
|
||||
Md5Final(&hmac->hash.md5, hash);
|
||||
}
|
||||
else if (hmac->macType ==SHA) {
|
||||
else if (hmac->macType == SHA) {
|
||||
ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash);
|
||||
|
||||
ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, HMAC_BLOCK_SIZE);
|
||||
ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE);
|
||||
ShaUpdate(&hmac->hash.sha, (byte*) hmac->innerHash, SHA_DIGEST_SIZE);
|
||||
|
||||
ShaFinal(&hmac->hash.sha, hash);
|
||||
}
|
||||
#ifndef NO_SHA256
|
||||
else if (hmac->macType ==SHA256) {
|
||||
else if (hmac->macType == SHA256) {
|
||||
Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash);
|
||||
|
||||
Sha256Update(&hmac->hash.sha256, (byte*) hmac->opad, HMAC_BLOCK_SIZE);
|
||||
Sha256Update(&hmac->hash.sha256, (byte*) hmac->opad, SHA256_BLOCK_SIZE);
|
||||
Sha256Update(&hmac->hash.sha256, (byte*) hmac->innerHash,
|
||||
SHA256_DIGEST_SIZE);
|
||||
|
||||
Sha256Final(&hmac->hash.sha256, hash);
|
||||
}
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
else if (hmac->macType == SHA384) {
|
||||
Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash);
|
||||
|
||||
Sha384Update(&hmac->hash.sha384, (byte*) hmac->opad, SHA384_BLOCK_SIZE);
|
||||
Sha384Update(&hmac->hash.sha384, (byte*) hmac->innerHash,
|
||||
SHA384_DIGEST_SIZE);
|
||||
|
||||
Sha384Final(&hmac->hash.sha384, hash);
|
||||
}
|
||||
#endif
|
||||
|
||||
hmac->innerHashKeyed = 0;
|
||||
}
|
||||
|
@ -99,6 +99,7 @@ int rabbit_test();
|
||||
int des_test();
|
||||
int des3_test();
|
||||
int aes_test();
|
||||
int aesgcm_test();
|
||||
int rsa_test();
|
||||
int dh_test();
|
||||
int dsa_test();
|
||||
@ -233,6 +234,13 @@ void ctaocrypt_test(void* args)
|
||||
err_sys("AES test failed!\n", ret);
|
||||
else
|
||||
printf( "AES test passed!\n");
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
if ( (ret = aesgcm_test()) )
|
||||
err_sys("AES-GCM test failed!\n", ret);
|
||||
else
|
||||
printf( "AES-GCM test passed!\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ( (ret = random_test()) )
|
||||
@ -1144,93 +1152,101 @@ int aes_test()
|
||||
}
|
||||
#endif /* CYASSL_AES_COUNTER */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
int aesgcm_test()
|
||||
{
|
||||
Aes enc;
|
||||
|
||||
/*
|
||||
* This is Test Case 16 from the document Galois/
|
||||
* Counter Mode of Operation (GCM) by McGrew and
|
||||
* Viega.
|
||||
*/
|
||||
const byte k[] =
|
||||
{
|
||||
/*
|
||||
* This is Test Case 16 from the document Galois/
|
||||
* Counter Mode of Operation (GCM) by McGrew and
|
||||
* Viega.
|
||||
*/
|
||||
const byte k[] =
|
||||
{
|
||||
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
|
||||
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
|
||||
};
|
||||
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
|
||||
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
|
||||
};
|
||||
|
||||
const byte iv[] =
|
||||
{
|
||||
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
|
||||
0xde, 0xca, 0xf8, 0x88, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const byte p[] =
|
||||
{
|
||||
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
|
||||
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
|
||||
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
|
||||
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
|
||||
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
|
||||
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
|
||||
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
|
||||
0xba, 0x63, 0x7b, 0x39
|
||||
};
|
||||
|
||||
const byte a[] =
|
||||
{
|
||||
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xab, 0xad, 0xda, 0xd2
|
||||
};
|
||||
|
||||
const byte c[] =
|
||||
{
|
||||
0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
|
||||
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
|
||||
0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
|
||||
0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
|
||||
0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
|
||||
0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
|
||||
0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
|
||||
0xbc, 0xc9, 0xf6, 0x62
|
||||
};
|
||||
const byte iv[] =
|
||||
{
|
||||
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
|
||||
0xde, 0xca, 0xf8, 0x88, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const byte p[] =
|
||||
{
|
||||
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
|
||||
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
|
||||
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
|
||||
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
|
||||
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
|
||||
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
|
||||
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
|
||||
0xba, 0x63, 0x7b, 0x39
|
||||
};
|
||||
|
||||
const byte a[] =
|
||||
{
|
||||
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xab, 0xad, 0xda, 0xd2
|
||||
};
|
||||
|
||||
const byte c[] =
|
||||
{
|
||||
0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
|
||||
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
|
||||
0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
|
||||
0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
|
||||
0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
|
||||
0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
|
||||
0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
|
||||
0xbc, 0xc9, 0xf6, 0x62
|
||||
};
|
||||
|
||||
const byte t[] =
|
||||
{
|
||||
0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
|
||||
0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b
|
||||
};
|
||||
const byte t[] =
|
||||
{
|
||||
0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
|
||||
0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b
|
||||
};
|
||||
|
||||
byte t2[16];
|
||||
byte p2[60];
|
||||
byte c2[60];
|
||||
byte t2[16];
|
||||
byte p2[60];
|
||||
byte c2[60];
|
||||
|
||||
int result;
|
||||
int result;
|
||||
|
||||
memset(t2, 0, 16);
|
||||
memset(c2, 0, 60);
|
||||
memset(p2, 0, 60);
|
||||
memset(t2, 0, 16);
|
||||
memset(c2, 0, 60);
|
||||
memset(p2, 0, 60);
|
||||
|
||||
AesSetKey(&enc, k, sizeof(k), iv, AES_ENCRYPTION);
|
||||
/* AES-GCM encrypt and decrypt both use AES encrypt internally */
|
||||
AesGcmEncrypt(&enc, c2, p, sizeof(c2), t2, sizeof(t2), a, sizeof(a));
|
||||
if (memcmp(c, c2, sizeof(c2)))
|
||||
return -68;
|
||||
if (memcmp(t, t2, sizeof(t2)))
|
||||
return -69;
|
||||
AesGcmSetKey(&enc, k, sizeof(k));
|
||||
AesSetIV(&enc, iv);
|
||||
/* AES-GCM encrypt and decrypt both use AES encrypt internally */
|
||||
AesGcmEncrypt(&enc, c2, p, sizeof(c2), t2, sizeof(t2), a, sizeof(a));
|
||||
if (memcmp(c, c2, sizeof(c2)))
|
||||
return -68;
|
||||
if (memcmp(t, t2, sizeof(t2)))
|
||||
return -69;
|
||||
|
||||
result = AesGcmDecrypt(&enc,
|
||||
p2, c2, sizeof(p2), t2, sizeof(t2), a, sizeof(a));
|
||||
if (result != 0)
|
||||
return -70;
|
||||
if (memcmp(p, p2, sizeof(p2)))
|
||||
return -71;
|
||||
}
|
||||
#endif /* HAVE_AESGCM */
|
||||
result = AesGcmDecrypt(&enc,
|
||||
p2, c2, sizeof(p2), t2, sizeof(t2), a, sizeof(a));
|
||||
if (result != 0)
|
||||
return -70;
|
||||
if (memcmp(p, p2, sizeof(p2)))
|
||||
return -71;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_AESGCM */
|
||||
|
||||
|
||||
#endif /* NO_AES */
|
||||
|
||||
|
||||
|
@ -68,6 +68,14 @@ typedef struct Aes {
|
||||
|
||||
ALIGN16 word32 reg[AES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
|
||||
ALIGN16 word32 tmp[AES_BLOCK_SIZE / sizeof(word32)]; /* same */
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
ALIGN16 byte H[AES_BLOCK_SIZE];
|
||||
#ifdef GCM_TABLE
|
||||
/* key-based fast multiplication table. */
|
||||
ALIGN16 byte M0[256][AES_BLOCK_SIZE];
|
||||
#endif /* GCM_TABLE */
|
||||
#endif /* HAVE_AESGCM */
|
||||
} Aes;
|
||||
|
||||
|
||||
@ -81,6 +89,7 @@ CYASSL_API void AesEncryptDirect(Aes* aes, byte* out, const byte* in);
|
||||
CYASSL_API void AesDecryptDirect(Aes* aes, byte* out, const byte* in);
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
CYASSL_API void AesGcmSetKey(Aes* aes, const byte* key, word32 len);
|
||||
CYASSL_API void AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz);
|
||||
|
@ -32,6 +32,10 @@
|
||||
#include <cyassl/ctaocrypt/sha256.h>
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_SHA384
|
||||
#include <cyassl/ctaocrypt/sha512.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -40,13 +44,19 @@
|
||||
enum {
|
||||
IPAD = 0x36,
|
||||
OPAD = 0x5C,
|
||||
#ifndef NO_SHA256
|
||||
#if defined(CYASSL_SHA384)
|
||||
INNER_HASH_SIZE = SHA384_DIGEST_SIZE,
|
||||
HMAC_BLOCK_SIZE = SHA384_BLOCK_SIZE
|
||||
#elif !defined(NO_SHA256)
|
||||
INNER_HASH_SIZE = SHA256_DIGEST_SIZE,
|
||||
HMAC_BLOCK_SIZE = SHA256_BLOCK_SIZE,
|
||||
SHA384 = 5
|
||||
#else
|
||||
INNER_HASH_SIZE = SHA_DIGEST_SIZE,
|
||||
HMAC_BLOCK_SIZE = SHA_BLOCK_SIZE,
|
||||
SHA256 = 2, /* hash type unique */
|
||||
SHA384 = 5
|
||||
#endif
|
||||
HMAC_BLOCK_SIZE = MD5_BLOCK_SIZE
|
||||
};
|
||||
|
||||
|
||||
@ -57,6 +67,9 @@ typedef union {
|
||||
#ifndef NO_SHA256
|
||||
Sha256 sha256;
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
Sha384 sha384;
|
||||
#endif
|
||||
} Hash;
|
||||
|
||||
/* Hmac digest */
|
||||
|
@ -44,6 +44,9 @@
|
||||
#ifdef HAVE_OCSP
|
||||
#include <cyassl/ocsp.h>
|
||||
#endif
|
||||
#ifdef CYASSL_SHA512
|
||||
#include <cyassl/ctaocrypt/sha512.h>
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_CALLBACKS
|
||||
#include <cyassl/openssl/cyassl_callbacks.h>
|
||||
@ -147,6 +150,10 @@ void c32to24(word32 in, word24 out);
|
||||
#define BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
|
||||
#define BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
|
||||
#endif
|
||||
#if defined (HAVE_AESGCM)
|
||||
#define BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||
#define BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(NO_HC128) && !defined(NO_TLS)
|
||||
@ -164,6 +171,10 @@ void c32to24(word32 in, word24 out);
|
||||
#if !defined (NO_SHA256)
|
||||
#define BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
|
||||
#define BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
|
||||
#if defined (HAVE_AESGCM)
|
||||
#define BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
#define BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -178,6 +189,18 @@ void c32to24(word32 in, word24 out);
|
||||
#define BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
|
||||
#define BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
|
||||
#define BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
|
||||
|
||||
#if defined (HAVE_AESGCM)
|
||||
#define BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
#define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
#define BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
|
||||
#define BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
|
||||
#define BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
#define BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
#define BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
|
||||
#define BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(NO_RC4)
|
||||
#define BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
|
||||
@ -210,6 +233,11 @@ void c32to24(word32 in, word24 out);
|
||||
#define BUILD_AES
|
||||
#endif
|
||||
|
||||
#if defined(BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256) || \
|
||||
defined(BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
|
||||
#define BUILD_AESGCM
|
||||
#endif
|
||||
|
||||
#if defined(BUILD_TLS_RSA_WITH_HC_128_CBC_SHA) || \
|
||||
defined(BUILD_TLS_RSA_WITH_HC_128_CBC_MD5)
|
||||
#define BUILD_HC128
|
||||
@ -275,7 +303,23 @@ enum {
|
||||
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x6b,
|
||||
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x67,
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x3d,
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x3c
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x3c,
|
||||
|
||||
/* AES-GCM */
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x9c,
|
||||
TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x9d,
|
||||
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x9e,
|
||||
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x9f,
|
||||
|
||||
/* ECC AES-GCM, first byte is 0xC0 (ECC_BYTE) */
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0x2b,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0x2c,
|
||||
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0x2d,
|
||||
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0x2e,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0x2f,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0x30,
|
||||
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0x31,
|
||||
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0x32
|
||||
};
|
||||
|
||||
|
||||
@ -297,6 +341,7 @@ enum Misc {
|
||||
TLSv1_2_MINOR = 3, /* TLSv1_2 minor version number */
|
||||
NO_COMPRESSION = 0,
|
||||
ZLIB_COMPRESSION = 221, /* CyaSSL zlib compression */
|
||||
HELLO_EXT_SIG_ALGO = 13, /* ID for the sig_algo hello extension */
|
||||
SECRET_LEN = 48, /* pre RSA and all master */
|
||||
ENCRYPT_LEN = 512, /* allow 4096 bit static buffer */
|
||||
SIZEOF_SENDER = 4, /* clnt or srvr */
|
||||
@ -338,6 +383,10 @@ enum Misc {
|
||||
CERT_HEADER_SZ = 3, /* always 3 bytes */
|
||||
REQ_HEADER_SZ = 2, /* cert request header sz */
|
||||
HINT_LEN_SZ = 2, /* length of hint size field */
|
||||
HELLO_EXT_SZ = 14, /* total length of the lazy hello extensions */
|
||||
HELLO_EXT_LEN = 12, /* length of the lazy hello extensions */
|
||||
HELLO_EXT_SIGALGO_SZ = 8, /* length of signature algo extension */
|
||||
HELLO_EXT_SIGALGO_LEN = 6, /* number of items in the signature algo list */
|
||||
|
||||
DTLS_HANDSHAKE_HEADER_SZ = 12, /* normal + seq(2) + offset(3) + length(3) */
|
||||
DTLS_RECORD_HEADER_SZ = 13, /* normal + epoch(2) + seq_num(6) */
|
||||
@ -361,8 +410,19 @@ enum Misc {
|
||||
AES_256_KEY_SIZE = 32, /* for 256 bit */
|
||||
AES_192_KEY_SIZE = 24, /* for 192 bit */
|
||||
AES_IV_SIZE = 16, /* always block size */
|
||||
AES_GCM_IMP_IV_SZ = 4, /* Implicit part of IV */
|
||||
AES_GCM_EXP_IV_SZ = 8, /* Explicit part of IV */
|
||||
AES_GCM_CTR_IV_SZ = 4, /* Counter part of IV */
|
||||
AES_128_KEY_SIZE = 16, /* for 128 bit */
|
||||
|
||||
AEAD_SEQ_OFFSET = 4, /* Auth Data: Sequence number */
|
||||
AEAD_TYPE_OFFSET = 8, /* Auth Data: Type */
|
||||
AEAD_VMAJ_OFFSET = 9, /* Auth Data: Major Version */
|
||||
AEAD_VMIN_OFFSET = 10, /* Auth Data: Minor Version */
|
||||
AEAD_LEN_OFFSET = 11, /* Auth Data: Length */
|
||||
AEAD_AUTH_TAG_SZ = 16, /* Size of the authentication tag */
|
||||
AEAD_AUTH_DATA_SZ = 13, /* Size of the data to authenticate */
|
||||
|
||||
HC_128_KEY_SIZE = 16, /* 128 bits */
|
||||
HC_128_IV_SIZE = 16, /* also 128 bits */
|
||||
|
||||
@ -765,7 +825,7 @@ int AlreadySigner(CYASSL_CERT_MANAGER* cm, byte* hash);
|
||||
/* All cipher suite related info */
|
||||
typedef struct CipherSpecs {
|
||||
byte bulk_cipher_algorithm;
|
||||
byte cipher_type; /* block or stream */
|
||||
byte cipher_type; /* block, stream, or aead */
|
||||
byte mac_algorithm;
|
||||
byte kea; /* key exchange algo */
|
||||
byte sig_algo;
|
||||
@ -789,6 +849,7 @@ enum BulkCipherAlgorithm {
|
||||
des40,
|
||||
idea,
|
||||
aes,
|
||||
aes_gcm,
|
||||
hc128, /* CyaSSL extensions */
|
||||
rabbit
|
||||
};
|
||||
@ -859,7 +920,7 @@ enum ClientCertificateType {
|
||||
};
|
||||
|
||||
|
||||
enum CipherType { stream, block };
|
||||
enum CipherType { stream, block, aead };
|
||||
|
||||
|
||||
/* keys and secrets */
|
||||
@ -1129,6 +1190,9 @@ struct CYASSL {
|
||||
Sha hashSha; /* sha hash of handshake msgs */
|
||||
#ifndef NO_SHA256
|
||||
Sha256 hashSha256; /* sha256 hash of handshake msgs */
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
Sha384 hashSha384; /* sha384 hash of handshake msgs */
|
||||
#endif
|
||||
Hashes verifyHashes;
|
||||
Hashes certHashes; /* for cert verify */
|
||||
|
@ -69,7 +69,7 @@ void echoclient_test(void* args)
|
||||
#if defined(CYASSL_DTLS)
|
||||
method = DTLSv1_client_method();
|
||||
#elif !defined(NO_TLS)
|
||||
method = TLSv1_client_method();
|
||||
method = CyaSSLv23_client_method();
|
||||
#else
|
||||
method = SSLv3_client_method();
|
||||
#endif
|
||||
@ -105,7 +105,7 @@ void echoclient_test(void* args)
|
||||
|
||||
while (fgets(send, sizeof(send), fin)) {
|
||||
|
||||
sendSz = (int)strlen(send) + 1;
|
||||
sendSz = (int)strlen(send);
|
||||
|
||||
if (SSL_write(ssl, send, sendSz) != sendSz)
|
||||
err_sys("SSL_write failed");
|
||||
@ -115,7 +115,7 @@ void echoclient_test(void* args)
|
||||
break;
|
||||
}
|
||||
|
||||
if (strncmp(send, "break", 4) == 0) {
|
||||
if (strncmp(send, "break", 5) == 0) {
|
||||
fputs("sending server session close: break!\n", fout);
|
||||
break;
|
||||
}
|
||||
@ -123,6 +123,7 @@ void echoclient_test(void* args)
|
||||
while (sendSz) {
|
||||
int got;
|
||||
if ( (got = SSL_read(ssl, reply, sizeof(reply))) > 0) {
|
||||
reply[got] = 0;
|
||||
fputs(reply, fout);
|
||||
sendSz -= got;
|
||||
}
|
||||
@ -165,6 +166,9 @@ void echoclient_test(void* args)
|
||||
args.argv = argv;
|
||||
|
||||
CyaSSL_Init();
|
||||
#ifdef DEBUG_CYASSL
|
||||
CyaSSL_Debugging_ON();
|
||||
#endif
|
||||
if (CurrentDir("echoclient") || CurrentDir("build"))
|
||||
ChangeDirBack(2);
|
||||
echoclient_test(&args);
|
||||
|
548
src/internal.c
548
src/internal.c
@ -55,7 +55,7 @@
|
||||
|
||||
#ifndef NO_CYASSL_CLIENT
|
||||
static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input, word32*);
|
||||
static int DoServerHello(CYASSL* ssl, const byte* input, word32*);
|
||||
static int DoServerHello(CYASSL* ssl, const byte* input, word32*, word32);
|
||||
static int DoCertificateRequest(CYASSL* ssl, const byte* input, word32*);
|
||||
static int DoServerKeyExchange(CYASSL* ssl, const byte* input, word32*);
|
||||
#endif
|
||||
@ -239,7 +239,8 @@ static INLINE void ato32(const byte* c, word32* u32)
|
||||
ssl->c_stream.zfree = (free_func)myFree;
|
||||
ssl->c_stream.opaque = (voidpf)ssl->heap;
|
||||
|
||||
if (deflateInit(&ssl->c_stream, 8) != Z_OK) return ZLIB_INIT_ERROR;
|
||||
if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
|
||||
return ZLIB_INIT_ERROR;
|
||||
|
||||
ssl->didStreamInit = 1;
|
||||
|
||||
@ -268,11 +269,6 @@ static INLINE void ato32(const byte* c, word32* u32)
|
||||
int err;
|
||||
int currTotal = ssl->c_stream.total_out;
|
||||
|
||||
/* put size in front of compression */
|
||||
c16toa((word16)inSz, out);
|
||||
out += 2;
|
||||
outSz -= 2;
|
||||
|
||||
ssl->c_stream.next_in = in;
|
||||
ssl->c_stream.avail_in = inSz;
|
||||
ssl->c_stream.next_out = out;
|
||||
@ -281,7 +277,7 @@ static INLINE void ato32(const byte* c, word32* u32)
|
||||
err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
|
||||
if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
|
||||
|
||||
return ssl->c_stream.total_out - currTotal + sizeof(word16);
|
||||
return ssl->c_stream.total_out - currTotal;
|
||||
}
|
||||
|
||||
|
||||
@ -290,12 +286,6 @@ static INLINE void ato32(const byte* c, word32* u32)
|
||||
{
|
||||
int err;
|
||||
int currTotal = ssl->d_stream.total_out;
|
||||
word16 len;
|
||||
|
||||
/* find size in front of compression */
|
||||
ato16(in, &len);
|
||||
in += 2;
|
||||
inSz -= 2;
|
||||
|
||||
ssl->d_stream.next_in = in;
|
||||
ssl->d_stream.avail_in = inSz;
|
||||
@ -498,6 +488,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
if (tls1_2 && haveECDSA) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
|
||||
if (tls && haveECDSA) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
@ -505,6 +502,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
if (tls1_2 && haveECDSA && haveStaticECC) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
|
||||
if (tls && haveECDSA && haveStaticECC) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
@ -512,6 +516,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
if (tls1_2 && haveECDSA) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
|
||||
if (tls && haveECDSA) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
@ -519,6 +530,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
if (tls1_2 && haveECDSA && haveStaticECC) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
|
||||
if (tls && haveECDSA && haveStaticECC) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
@ -554,6 +572,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
if (tls1_2 && haveRSA) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|
||||
if (tls && haveRSA) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
@ -561,6 +586,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
|
||||
if (tls1_2 && haveRSA && haveStaticECC) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
|
||||
if (tls && haveRSA && haveStaticECC) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
@ -568,6 +600,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
if (tls1_2 && haveRSA) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|
||||
if (tls && haveRSA) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
@ -575,6 +614,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
|
||||
if (tls1_2 && haveRSA && haveStaticECC) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
|
||||
if (tls && haveRSA && haveStaticECC) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
@ -610,6 +656,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
if (tls1_2 && haveDH && haveRSA) {
|
||||
suites->suites[idx++] = 0;
|
||||
suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
|
||||
if (tls1_2 && haveDH && haveRSA) {
|
||||
suites->suites[idx++] = 0;
|
||||
@ -617,6 +670,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
if (tls1_2 && haveDH && haveRSA) {
|
||||
suites->suites[idx++] = 0;
|
||||
suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
|
||||
if (tls1_2 && haveDH && haveRSA) {
|
||||
suites->suites[idx++] = 0;
|
||||
@ -638,6 +698,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||
if (tls1_2 && haveRSA) {
|
||||
suites->suites[idx++] = 0;
|
||||
suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
|
||||
if (tls1_2 && haveRSA) {
|
||||
suites->suites[idx++] = 0;
|
||||
@ -645,6 +712,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||
if (tls1_2 && haveRSA) {
|
||||
suites->suites[idx++] = 0;
|
||||
suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
|
||||
if (tls1_2 && haveRSA) {
|
||||
suites->suites[idx++] = 0;
|
||||
@ -793,6 +867,9 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
||||
InitSha(&ssl->hashSha);
|
||||
#ifndef NO_SHA256
|
||||
InitSha256(&ssl->hashSha256);
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
InitSha384(&ssl->hashSha384);
|
||||
#endif
|
||||
InitRsaKey(&ssl->peerRsaKey, ctx->heap);
|
||||
|
||||
@ -1096,10 +1173,14 @@ static void HashOutput(CYASSL* ssl, const byte* output, int sz, int ivSz)
|
||||
|
||||
Md5Update(&ssl->hashMd5, adj, sz);
|
||||
ShaUpdate(&ssl->hashSha, adj, sz);
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
#ifndef NO_SHA256
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
Sha256Update(&ssl->hashSha256, adj, sz);
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
Sha384Update(&ssl->hashSha384, adj, sz);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1118,10 +1199,14 @@ static void HashInput(CYASSL* ssl, const byte* input, int sz)
|
||||
|
||||
Md5Update(&ssl->hashMd5, adj, sz);
|
||||
ShaUpdate(&ssl->hashSha, adj, sz);
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
#ifndef NO_SHA256
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
Sha256Update(&ssl->hashSha256, adj, sz);
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
Sha384Update(&ssl->hashSha384, adj, sz);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1539,10 +1624,21 @@ static void BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
|
||||
Sha sha = ssl->hashSha;
|
||||
#ifndef NO_SHA256
|
||||
Sha256 sha256;
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
Sha384 sha384;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA256
|
||||
InitSha256(&sha256);
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
sha256 = ssl->hashSha256;
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
InitSha384(&sha384);
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
sha384 = ssl->hashSha384;
|
||||
#endif
|
||||
|
||||
if (ssl->options.tls)
|
||||
BuildTlsFinished(ssl, hashes, sender);
|
||||
@ -1554,10 +1650,14 @@ static void BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
|
||||
/* restore */
|
||||
ssl->hashMd5 = md5;
|
||||
ssl->hashSha = sha;
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
#ifndef NO_SHA256
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
ssl->hashSha256 = sha256;
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
ssl->hashSha384 = sha384;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1936,23 +2036,28 @@ int DoFinished(CYASSL* ssl, const byte* input, word32* inOutIdx, int sniff)
|
||||
}
|
||||
}
|
||||
|
||||
ssl->hmac(ssl, verifyMAC, input + idx - headerSz, macSz,
|
||||
handshake, 1);
|
||||
idx += finishedSz;
|
||||
if (ssl->specs.cipher_type != aead) {
|
||||
ssl->hmac(ssl, verifyMAC, input + idx - headerSz, macSz,
|
||||
handshake, 1);
|
||||
idx += finishedSz;
|
||||
|
||||
/* read mac and fill */
|
||||
mac = input + idx;
|
||||
idx += ssl->specs.hash_size;
|
||||
/* read mac and fill */
|
||||
mac = input + idx;
|
||||
idx += ssl->specs.hash_size;
|
||||
|
||||
if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
|
||||
padSz -= ssl->specs.block_size;
|
||||
if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
|
||||
padSz -= ssl->specs.block_size;
|
||||
|
||||
idx += padSz;
|
||||
idx += padSz;
|
||||
|
||||
/* verify mac */
|
||||
if (XMEMCMP(mac, verifyMAC, ssl->specs.hash_size)) {
|
||||
CYASSL_MSG("Verify finished error on mac");
|
||||
return VERIFY_MAC_ERROR;
|
||||
/* verify mac */
|
||||
if (XMEMCMP(mac, verifyMAC, ssl->specs.hash_size)) {
|
||||
CYASSL_MSG("Verify finished error on mac");
|
||||
return VERIFY_MAC_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
idx += (finishedSz + AEAD_AUTH_TAG_SZ);
|
||||
}
|
||||
|
||||
if (ssl->options.side == CLIENT_END) {
|
||||
@ -2012,7 +2117,7 @@ static int DoHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
|
||||
|
||||
case server_hello:
|
||||
CYASSL_MSG("processing server hello");
|
||||
ret = DoServerHello(ssl, input, inOutIdx);
|
||||
ret = DoServerHello(ssl, input, inOutIdx, size);
|
||||
break;
|
||||
|
||||
case certificate_request:
|
||||
@ -2075,6 +2180,15 @@ static int DoHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
|
||||
}
|
||||
|
||||
|
||||
static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
|
||||
{
|
||||
if (verify)
|
||||
return ssl->keys.peer_sequence_number++;
|
||||
else
|
||||
return ssl->keys.sequence_number++;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz)
|
||||
{
|
||||
switch (ssl->specs.bulk_cipher_algorithm) {
|
||||
@ -2105,6 +2219,50 @@ static INLINE void Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_AESGCM
|
||||
case aes_gcm:
|
||||
{
|
||||
byte additional[AES_BLOCK_SIZE];
|
||||
byte nonce[AES_BLOCK_SIZE];
|
||||
|
||||
/* use this side's IV */
|
||||
if (ssl->options.side == SERVER_END) {
|
||||
XMEMCPY(nonce, ssl->keys.server_write_IV,
|
||||
AES_GCM_IMP_IV_SZ);
|
||||
}
|
||||
else {
|
||||
XMEMCPY(nonce, ssl->keys.client_write_IV,
|
||||
AES_GCM_IMP_IV_SZ);
|
||||
}
|
||||
XMEMCPY(nonce + AES_GCM_IMP_IV_SZ,
|
||||
input, AES_GCM_EXP_IV_SZ);
|
||||
XMEMSET(nonce + AES_GCM_IMP_IV_SZ + AES_GCM_EXP_IV_SZ,
|
||||
0, AES_GCM_CTR_IV_SZ);
|
||||
AesSetIV(&ssl->encrypt.aes, nonce);
|
||||
|
||||
XMEMSET(additional, 0, AES_BLOCK_SIZE);
|
||||
|
||||
/* sequence number field is 64-bits, we only use 32-bits */
|
||||
c32toa(GetSEQIncrement(ssl, 0),
|
||||
additional + AEAD_SEQ_OFFSET);
|
||||
|
||||
/* Store the type, version. Unfortunately, they are in
|
||||
* the input buffer ahead of the plaintext. */
|
||||
XMEMCPY(additional + AEAD_TYPE_OFFSET, input - 5, 3);
|
||||
|
||||
/* Store the length of the plain text minus the explicit
|
||||
* IV length minus the authentication tag size. */
|
||||
c16toa(sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
|
||||
additional + AEAD_LEN_OFFSET);
|
||||
AesGcmEncrypt(&ssl->encrypt.aes,
|
||||
out + AES_GCM_EXP_IV_SZ, input + AES_GCM_EXP_IV_SZ,
|
||||
sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
|
||||
out + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ,
|
||||
additional, AEAD_AUTH_DATA_SZ);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HC128
|
||||
case hc128:
|
||||
Hc128_Process(&ssl->encrypt.hc128, out, input, sz);
|
||||
@ -2123,7 +2281,7 @@ static INLINE void Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz)
|
||||
}
|
||||
|
||||
|
||||
static INLINE void Decrypt(CYASSL* ssl, byte* plain, const byte* input,
|
||||
static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input,
|
||||
word32 sz)
|
||||
{
|
||||
switch (ssl->specs.bulk_cipher_algorithm) {
|
||||
@ -2145,6 +2303,51 @@ static INLINE void Decrypt(CYASSL* ssl, byte* plain, const byte* input,
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_AESGCM
|
||||
case aes_gcm:
|
||||
{
|
||||
byte additional[AES_BLOCK_SIZE];
|
||||
byte nonce[AES_BLOCK_SIZE];
|
||||
|
||||
/* use the other side's IV */
|
||||
if (ssl->options.side == SERVER_END) {
|
||||
XMEMCPY(nonce, ssl->keys.client_write_IV,
|
||||
AES_GCM_IMP_IV_SZ);
|
||||
}
|
||||
else {
|
||||
XMEMCPY(nonce, ssl->keys.server_write_IV,
|
||||
AES_GCM_IMP_IV_SZ);
|
||||
}
|
||||
XMEMCPY(nonce + AES_GCM_IMP_IV_SZ,
|
||||
input, AES_GCM_EXP_IV_SZ);
|
||||
XMEMSET(nonce + AES_GCM_IMP_IV_SZ + AES_GCM_EXP_IV_SZ,
|
||||
0, AES_GCM_CTR_IV_SZ);
|
||||
AesSetIV(&ssl->decrypt.aes, nonce);
|
||||
|
||||
XMEMSET(additional, 0, AES_BLOCK_SIZE);
|
||||
|
||||
/* sequence number field is 64-bits, we only use 32-bits */
|
||||
c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
|
||||
|
||||
additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
|
||||
additional[AEAD_VMAJ_OFFSET] = ssl->curRL.version.major;
|
||||
additional[AEAD_VMIN_OFFSET] = ssl->curRL.version.minor;
|
||||
|
||||
c16toa(sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
|
||||
additional + AEAD_LEN_OFFSET);
|
||||
if (AesGcmDecrypt(&ssl->decrypt.aes,
|
||||
plain + AES_GCM_EXP_IV_SZ,
|
||||
input + AES_GCM_EXP_IV_SZ,
|
||||
sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ,
|
||||
input + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ,
|
||||
additional, AEAD_AUTH_DATA_SZ) < 0) {
|
||||
SendAlert(ssl, alert_fatal, bad_record_mac);
|
||||
return VERIFY_MAC_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HC128
|
||||
case hc128:
|
||||
Hc128_Process(&ssl->decrypt.hc128, plain, input, sz);
|
||||
@ -2160,27 +2363,25 @@ static INLINE void Decrypt(CYASSL* ssl, byte* plain, const byte* input,
|
||||
default:
|
||||
CYASSL_MSG("CyaSSL Decrypt programming error");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* decrypt input message in place */
|
||||
static int DecryptMessage(CYASSL* ssl, byte* input, word32 sz, word32* idx)
|
||||
{
|
||||
Decrypt(ssl, input, input, sz);
|
||||
ssl->keys.encryptSz = sz;
|
||||
if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
|
||||
*idx += ssl->specs.block_size; /* go past TLSv1.1 IV */
|
||||
int decryptResult = Decrypt(ssl, input, input, sz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (decryptResult == 0)
|
||||
{
|
||||
ssl->keys.encryptSz = sz;
|
||||
if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
|
||||
*idx += ssl->specs.block_size; /* go past TLSv1.1 IV */
|
||||
if (ssl->specs.cipher_type == aead)
|
||||
*idx += AES_GCM_EXP_IV_SZ;
|
||||
}
|
||||
|
||||
|
||||
static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
|
||||
{
|
||||
if (verify)
|
||||
return ssl->keys.peer_sequence_number++;
|
||||
else
|
||||
return ssl->keys.sequence_number++;
|
||||
return decryptResult;
|
||||
}
|
||||
|
||||
|
||||
@ -2207,6 +2408,10 @@ int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
|
||||
pad = *(input + idx + msgSz - ivExtra - 1);
|
||||
padByte = 1;
|
||||
}
|
||||
if (ssl->specs.cipher_type == aead) {
|
||||
ivExtra = AES_GCM_EXP_IV_SZ;
|
||||
digestSz = AEAD_AUTH_TAG_SZ;
|
||||
}
|
||||
|
||||
dataSz = msgSz - ivExtra - digestSz - pad - padByte;
|
||||
if (dataSz < 0) {
|
||||
@ -2218,7 +2423,8 @@ int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
|
||||
if (dataSz) {
|
||||
int rawSz = dataSz; /* keep raw size for hmac */
|
||||
|
||||
ssl->hmac(ssl, verify, rawData, rawSz, application_data, 1);
|
||||
if (ssl->specs.cipher_type != aead)
|
||||
ssl->hmac(ssl, verify, rawData, rawSz, application_data, 1);
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
if (ssl->options.usingCompression) {
|
||||
@ -2244,14 +2450,9 @@ int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
|
||||
if (padByte)
|
||||
idx++;
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
if (ssl->options.usingCompression)
|
||||
XMEMMOVE(rawData, decomp, dataSz);
|
||||
#endif
|
||||
|
||||
/* verify */
|
||||
if (dataSz) {
|
||||
if (XMEMCMP(mac, verify, digestSz)) {
|
||||
if (ssl->specs.cipher_type != aead && XMEMCMP(mac, verify, digestSz)) {
|
||||
CYASSL_MSG("App data verify mac error");
|
||||
return VERIFY_MAC_ERROR;
|
||||
}
|
||||
@ -2259,6 +2460,12 @@ int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx)
|
||||
else
|
||||
GetSEQIncrement(ssl, 1); /* even though no data, increment verify */
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
/* decompress could be bigger, overwrite after verify */
|
||||
if (ssl->options.usingCompression)
|
||||
XMEMMOVE(rawData, decomp, dataSz);
|
||||
#endif
|
||||
|
||||
*inOutIdx = idx;
|
||||
return 0;
|
||||
}
|
||||
@ -2288,21 +2495,26 @@ static int DoAlert(CYASSL* ssl, byte* input, word32* inOutIdx, int* type)
|
||||
CYASSL_ERROR(*type);
|
||||
|
||||
if (ssl->keys.encryptionOn) {
|
||||
int aSz = ALERT_SIZE;
|
||||
const byte* mac;
|
||||
byte verify[SHA256_DIGEST_SIZE];
|
||||
int padSz = ssl->keys.encryptSz - aSz - ssl->specs.hash_size;
|
||||
|
||||
ssl->hmac(ssl, verify, input + *inOutIdx - aSz, aSz, alert, 1);
|
||||
if (ssl->specs.cipher_type != aead) {
|
||||
int aSz = ALERT_SIZE;
|
||||
const byte* mac;
|
||||
byte verify[SHA256_DIGEST_SIZE];
|
||||
int padSz = ssl->keys.encryptSz - aSz - ssl->specs.hash_size;
|
||||
|
||||
/* read mac and fill */
|
||||
mac = input + *inOutIdx;
|
||||
*inOutIdx += (ssl->specs.hash_size + padSz);
|
||||
|
||||
/* verify */
|
||||
if (XMEMCMP(mac, verify, ssl->specs.hash_size)) {
|
||||
CYASSL_MSG(" alert verify mac error");
|
||||
return VERIFY_MAC_ERROR;
|
||||
ssl->hmac(ssl, verify, input + *inOutIdx - aSz, aSz, alert, 1);
|
||||
|
||||
/* read mac and fill */
|
||||
mac = input + *inOutIdx;
|
||||
*inOutIdx += (ssl->specs.hash_size + padSz);
|
||||
|
||||
/* verify */
|
||||
if (XMEMCMP(mac, verify, ssl->specs.hash_size)) {
|
||||
CYASSL_MSG(" alert verify mac error");
|
||||
return VERIFY_MAC_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*inOutIdx += AEAD_AUTH_TAG_SZ;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2820,6 +3032,11 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz,
|
||||
sz += pad;
|
||||
}
|
||||
|
||||
if (ssl->specs.cipher_type == aead) {
|
||||
ivSz = AES_GCM_EXP_IV_SZ;
|
||||
sz += (ivSz + 16 - digestSz);
|
||||
RNG_GenerateBlock(&ssl->rng, iv, ivSz);
|
||||
}
|
||||
size = (word16)(sz - headerSz); /* include mac and digest */
|
||||
AddRecordHeader(output, size, (byte)type, ssl);
|
||||
|
||||
@ -2833,8 +3050,10 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz,
|
||||
|
||||
if (type == handshake)
|
||||
HashOutput(ssl, output, headerSz + inSz, ivSz);
|
||||
ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, type, 0);
|
||||
idx += digestSz;
|
||||
if (ssl->specs.cipher_type != aead) {
|
||||
ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, type, 0);
|
||||
idx += digestSz;
|
||||
}
|
||||
|
||||
if (ssl->specs.cipher_type == block)
|
||||
for (i = 0; i <= pad; i++)
|
||||
@ -3715,7 +3934,55 @@ const char* const cipher_names[] =
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
|
||||
"ECDH-ECDSA-DES-CBC3-SHA"
|
||||
"ECDH-ECDSA-DES-CBC3-SHA",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||
"AES128-GCM-SHA256",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||
"AES256-GCM-SHA384",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
"DHE-RSA-AES128-GCM-SHA256",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
"DHE-RSA-AES256-GCM-SHA384",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
"ECDHE-RSA-AES128-GCM-SHA256",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
"ECDHE-RSA-AES256-GCM-SHA384",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
"ECDHE-ECDSA-AES128-GCM-SHA256",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
"ECDHE-ECDSA-AES256-GCM-SHA384",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
|
||||
"ECDH-RSA-AES128-GCM-SHA256",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
|
||||
"ECDH-RSA-AES256-GCM-SHA384",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
"ECDH-ECDSA-AES128-GCM-SHA256",
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
"ECDH-ECDSA-AES256-GCM-SHA384"
|
||||
#endif
|
||||
|
||||
};
|
||||
@ -3867,7 +4134,55 @@ int cipher_name_idx[] =
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
|
||||
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
|
||||
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||
TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
|
||||
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
|
||||
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
#endif
|
||||
|
||||
};
|
||||
@ -4089,7 +4404,10 @@ int SetCipherList(Suites* s, const char* list)
|
||||
length = sizeof(ProtocolVersion) + RAN_LEN
|
||||
+ idSz + ENUM_LEN
|
||||
+ ssl->suites.suiteSz + SUITE_LEN
|
||||
+ COMP_LEN + ENUM_LEN;
|
||||
+ COMP_LEN + ENUM_LEN;
|
||||
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
length += HELLO_EXT_SZ;
|
||||
|
||||
sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
|
||||
|
||||
@ -4155,7 +4473,29 @@ int SetCipherList(Suites* s, const char* list)
|
||||
output[idx++] = ZLIB_COMPRESSION;
|
||||
else
|
||||
output[idx++] = NO_COMPRESSION;
|
||||
|
||||
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
{
|
||||
/* add in the extensions length */
|
||||
c16toa(HELLO_EXT_LEN, output + idx);
|
||||
idx += 2;
|
||||
|
||||
c16toa(HELLO_EXT_SIG_ALGO, output + idx);
|
||||
idx += 2;
|
||||
c16toa(HELLO_EXT_SIGALGO_SZ, output + idx);
|
||||
idx += 2;
|
||||
/* This is a lazy list setup. Eventually, we'll need to support
|
||||
* using other hash types or even other extensions. */
|
||||
c16toa(HELLO_EXT_SIGALGO_LEN, output + idx);
|
||||
idx += 2;
|
||||
output[idx++] = sha_mac;
|
||||
output[idx++] = rsa_sa_algo;
|
||||
output[idx++] = sha_mac;
|
||||
output[idx++] = dsa_sa_algo;
|
||||
output[idx++] = sha_mac;
|
||||
output[idx++] = ecc_dsa_sa_algo;
|
||||
}
|
||||
|
||||
HashOutput(ssl, output, sendSz, 0);
|
||||
|
||||
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
|
||||
@ -4197,12 +4537,14 @@ int SetCipherList(Suites* s, const char* list)
|
||||
}
|
||||
|
||||
|
||||
static int DoServerHello(CYASSL* ssl, const byte* input, word32* inOutIdx)
|
||||
static int DoServerHello(CYASSL* ssl, const byte* input, word32* inOutIdx,
|
||||
word32 helloSz)
|
||||
{
|
||||
byte b;
|
||||
byte compression;
|
||||
ProtocolVersion pv;
|
||||
word32 i = *inOutIdx;
|
||||
word32 begin = i;
|
||||
|
||||
#ifdef CYASSL_CALLBACKS
|
||||
if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
|
||||
@ -4254,7 +4596,11 @@ int SetCipherList(Suites* s, const char* list)
|
||||
CYASSL_MSG("Server refused compression, turning off");
|
||||
ssl->options.usingCompression = 0; /* turn off if server refused */
|
||||
}
|
||||
|
||||
|
||||
*inOutIdx = i;
|
||||
if ( (i - begin) < helloSz)
|
||||
*inOutIdx = begin + helloSz; /* skip extensions */
|
||||
|
||||
ssl->options.serverState = SERVER_HELLO_COMPLETE;
|
||||
|
||||
*inOutIdx = i;
|
||||
@ -5563,6 +5909,46 @@ int SetCipherList(Suites* s, const char* list)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
|
||||
if (requirement == ecc_dsa_sa_algo)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
|
||||
if (requirement == ecc_dsa_sa_algo)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
|
||||
if (requirement == ecc_static_diffie_hellman_kea)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
|
||||
if (requirement == ecc_static_diffie_hellman_kea)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
|
||||
if (requirement == rsa_kea)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
|
||||
if (requirement == rsa_kea)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
|
||||
if (requirement == ecc_static_diffie_hellman_kea)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
|
||||
if (requirement == ecc_static_diffie_hellman_kea)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
CYASSL_MSG("Unsupported cipher suite, CipherRequires ECC");
|
||||
return 0;
|
||||
@ -5679,6 +6065,20 @@ int SetCipherList(Suites* s, const char* list)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case TLS_RSA_WITH_AES_128_GCM_SHA256 :
|
||||
case TLS_RSA_WITH_AES_256_GCM_SHA384 :
|
||||
if (requirement == rsa_kea)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
|
||||
case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
|
||||
if (requirement == rsa_kea)
|
||||
return 1;
|
||||
if (requirement == diffie_hellman_kea)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
CYASSL_MSG("Unsupported cipher suite, CipherRequires");
|
||||
return 0;
|
||||
|
230
src/keys.c
230
src/keys.c
@ -311,6 +311,142 @@ int SetCipherSpecs(CYASSL* ssl)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
|
||||
ssl->specs.bulk_cipher_algorithm = aes_gcm;
|
||||
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 = AES_128_KEY_SIZE;
|
||||
ssl->specs.block_size = AES_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = AES_GCM_IMP_IV_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
|
||||
ssl->specs.bulk_cipher_algorithm = aes_gcm;
|
||||
ssl->specs.cipher_type = aead;
|
||||
ssl->specs.mac_algorithm = sha384_mac;
|
||||
ssl->specs.kea = ecc_diffie_hellman_kea;
|
||||
ssl->specs.sig_algo = rsa_sa_algo;
|
||||
ssl->specs.hash_size = SHA384_DIGEST_SIZE;
|
||||
ssl->specs.pad_size = PAD_SHA;
|
||||
ssl->specs.static_ecdh = 0;
|
||||
ssl->specs.key_size = AES_256_KEY_SIZE;
|
||||
ssl->specs.block_size = AES_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = AES_GCM_IMP_IV_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
|
||||
ssl->specs.bulk_cipher_algorithm = aes_gcm;
|
||||
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 = AES_128_KEY_SIZE;
|
||||
ssl->specs.block_size = AES_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = AES_GCM_IMP_IV_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
|
||||
ssl->specs.bulk_cipher_algorithm = aes_gcm;
|
||||
ssl->specs.cipher_type = aead;
|
||||
ssl->specs.mac_algorithm = sha384_mac;
|
||||
ssl->specs.kea = ecc_diffie_hellman_kea;
|
||||
ssl->specs.sig_algo = ecc_dsa_sa_algo;
|
||||
ssl->specs.hash_size = SHA384_DIGEST_SIZE;
|
||||
ssl->specs.pad_size = PAD_SHA;
|
||||
ssl->specs.static_ecdh = 0;
|
||||
ssl->specs.key_size = AES_256_KEY_SIZE;
|
||||
ssl->specs.block_size = AES_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = AES_GCM_IMP_IV_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
|
||||
case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
|
||||
ssl->specs.bulk_cipher_algorithm = aes_gcm;
|
||||
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 = 1;
|
||||
ssl->specs.key_size = AES_128_KEY_SIZE;
|
||||
ssl->specs.block_size = AES_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = AES_GCM_IMP_IV_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
|
||||
case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
|
||||
ssl->specs.bulk_cipher_algorithm = aes_gcm;
|
||||
ssl->specs.cipher_type = aead;
|
||||
ssl->specs.mac_algorithm = sha384_mac;
|
||||
ssl->specs.kea = ecc_diffie_hellman_kea;
|
||||
ssl->specs.sig_algo = rsa_sa_algo;
|
||||
ssl->specs.hash_size = SHA384_DIGEST_SIZE;
|
||||
ssl->specs.pad_size = PAD_SHA;
|
||||
ssl->specs.static_ecdh = 1;
|
||||
ssl->specs.key_size = AES_256_KEY_SIZE;
|
||||
ssl->specs.block_size = AES_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = AES_GCM_IMP_IV_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
|
||||
ssl->specs.bulk_cipher_algorithm = aes_gcm;
|
||||
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 = 1;
|
||||
ssl->specs.key_size = AES_128_KEY_SIZE;
|
||||
ssl->specs.block_size = AES_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = AES_GCM_IMP_IV_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
|
||||
ssl->specs.bulk_cipher_algorithm = aes_gcm;
|
||||
ssl->specs.cipher_type = aead;
|
||||
ssl->specs.mac_algorithm = sha384_mac;
|
||||
ssl->specs.kea = ecc_diffie_hellman_kea;
|
||||
ssl->specs.sig_algo = ecc_dsa_sa_algo;
|
||||
ssl->specs.hash_size = SHA384_DIGEST_SIZE;
|
||||
ssl->specs.pad_size = PAD_SHA;
|
||||
ssl->specs.static_ecdh = 1;
|
||||
ssl->specs.key_size = AES_256_KEY_SIZE;
|
||||
ssl->specs.block_size = AES_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = AES_GCM_IMP_IV_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
CYASSL_MSG("Unsupported cipher suite, SetCipherSpecs ECC");
|
||||
return UNSUPPORTED_SUITE;
|
||||
@ -646,6 +782,74 @@ int SetCipherSpecs(CYASSL* ssl)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||
case TLS_RSA_WITH_AES_128_GCM_SHA256 :
|
||||
ssl->specs.bulk_cipher_algorithm = aes_gcm;
|
||||
ssl->specs.cipher_type = aead;
|
||||
ssl->specs.mac_algorithm = sha256_mac;
|
||||
ssl->specs.kea = rsa_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 = AES_128_KEY_SIZE;
|
||||
ssl->specs.block_size = AES_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = AES_GCM_IMP_IV_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||
case TLS_RSA_WITH_AES_256_GCM_SHA384 :
|
||||
ssl->specs.bulk_cipher_algorithm = aes_gcm;
|
||||
ssl->specs.cipher_type = aead;
|
||||
ssl->specs.mac_algorithm = sha384_mac;
|
||||
ssl->specs.kea = rsa_kea;
|
||||
ssl->specs.sig_algo = rsa_sa_algo;
|
||||
ssl->specs.hash_size = SHA384_DIGEST_SIZE;
|
||||
ssl->specs.pad_size = PAD_SHA;
|
||||
ssl->specs.static_ecdh = 0;
|
||||
ssl->specs.key_size = AES_256_KEY_SIZE;
|
||||
ssl->specs.block_size = AES_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = AES_GCM_IMP_IV_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
|
||||
ssl->specs.bulk_cipher_algorithm = aes_gcm;
|
||||
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 = AES_128_KEY_SIZE;
|
||||
ssl->specs.block_size = AES_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = AES_GCM_IMP_IV_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
|
||||
ssl->specs.bulk_cipher_algorithm = aes_gcm;
|
||||
ssl->specs.cipher_type = aead;
|
||||
ssl->specs.mac_algorithm = sha384_mac;
|
||||
ssl->specs.kea = diffie_hellman_kea;
|
||||
ssl->specs.sig_algo = rsa_sa_algo;
|
||||
ssl->specs.hash_size = SHA384_DIGEST_SIZE;
|
||||
ssl->specs.pad_size = PAD_SHA;
|
||||
ssl->specs.static_ecdh = 0;
|
||||
ssl->specs.key_size = AES_256_KEY_SIZE;
|
||||
ssl->specs.block_size = AES_BLOCK_SIZE;
|
||||
ssl->specs.iv_size = AES_GCM_IMP_IV_SZ;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
CYASSL_MSG("Unsupported cipher suite, SetCipherSpecs");
|
||||
return UNSUPPORTED_SUITE;
|
||||
@ -802,6 +1006,19 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_AESGCM
|
||||
if (specs->bulk_cipher_algorithm == aes_gcm) {
|
||||
if (side == CLIENT_END) {
|
||||
AesGcmSetKey(&enc->aes, keys->client_write_key, specs->key_size);
|
||||
AesGcmSetKey(&dec->aes, keys->server_write_key, specs->key_size);
|
||||
}
|
||||
else {
|
||||
AesGcmSetKey(&enc->aes, keys->server_write_key, specs->key_size);
|
||||
AesGcmSetKey(&dec->aes, keys->client_write_key, specs->key_size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
keys->sequence_number = 0;
|
||||
keys->peer_sequence_number = 0;
|
||||
keys->encryptionOn = 0;
|
||||
@ -813,12 +1030,15 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
|
||||
/* TLS can call too */
|
||||
int StoreKeys(CYASSL* ssl, const byte* keyData)
|
||||
{
|
||||
int sz = ssl->specs.hash_size, i;
|
||||
int sz, i = 0;
|
||||
|
||||
XMEMCPY(ssl->keys.client_write_MAC_secret, keyData, sz);
|
||||
i = sz;
|
||||
XMEMCPY(ssl->keys.server_write_MAC_secret,&keyData[i], sz);
|
||||
i += sz;
|
||||
if (ssl->specs.cipher_type != aead) {
|
||||
sz = ssl->specs.hash_size;
|
||||
XMEMCPY(ssl->keys.client_write_MAC_secret,&keyData[i], sz);
|
||||
i += sz;
|
||||
XMEMCPY(ssl->keys.server_write_MAC_secret,&keyData[i], sz);
|
||||
i += sz;
|
||||
}
|
||||
|
||||
sz = ssl->specs.key_size;
|
||||
XMEMCPY(ssl->keys.client_write_key, &keyData[i], sz);
|
||||
|
25
src/ssl.c
25
src/ssl.c
@ -5018,6 +5018,23 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
||||
case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
|
||||
return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
|
||||
|
||||
case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
|
||||
return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
|
||||
case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
|
||||
return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
|
||||
return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
|
||||
return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
|
||||
case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
|
||||
return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
|
||||
case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
|
||||
return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
|
||||
case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
|
||||
return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
|
||||
case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
|
||||
return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
|
||||
|
||||
default:
|
||||
return "NONE";
|
||||
}
|
||||
@ -5066,6 +5083,14 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
||||
return "TLS_NTRU_RSA_WITH_AES_128_CBC_SHA";
|
||||
case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
|
||||
return "TLS_NTRU_RSA_WITH_AES_256_CBC_SHA";
|
||||
case TLS_RSA_WITH_AES_128_GCM_SHA256 :
|
||||
return "TLS_RSA_WITH_AES_128_GCM_SHA256";
|
||||
case TLS_RSA_WITH_AES_256_GCM_SHA384 :
|
||||
return "TLS_RSA_WITH_AES_256_GCM_SHA384";
|
||||
case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
|
||||
return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
|
||||
case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
|
||||
return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
|
||||
default:
|
||||
return "NONE";
|
||||
} /* switch */
|
||||
|
84
src/tls.c
84
src/tls.c
@ -53,28 +53,51 @@ static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha)
|
||||
}
|
||||
|
||||
|
||||
#ifdef CYASSL_SHA384
|
||||
#define PHASH_MAX_DIGEST_SIZE SHA384_DIGEST_SIZE
|
||||
#else
|
||||
#define PHASH_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
|
||||
#endif
|
||||
|
||||
/* compute p_hash for MD5, SHA-1, or SHA-256 for TLSv1 PRF */
|
||||
/* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */
|
||||
static void p_hash(byte* result, word32 resLen, const byte* secret,
|
||||
word32 secLen, const byte* seed, word32 seedLen, int hash)
|
||||
{
|
||||
word32 len = hash == md5_mac ? MD5_DIGEST_SIZE : hash == sha_mac ?
|
||||
SHA_DIGEST_SIZE : SHA256_DIGEST_SIZE;
|
||||
word32 times = resLen / len;
|
||||
word32 lastLen = resLen % len;
|
||||
word32 len = MD5_DIGEST_SIZE;
|
||||
word32 times;
|
||||
word32 lastLen;
|
||||
word32 lastTime;
|
||||
word32 i;
|
||||
word32 idx = 0;
|
||||
byte previous[SHA256_DIGEST_SIZE]; /* max size */
|
||||
byte current[SHA256_DIGEST_SIZE]; /* max size */
|
||||
byte previous[PHASH_MAX_DIGEST_SIZE]; /* max size */
|
||||
byte current[PHASH_MAX_DIGEST_SIZE]; /* max size */
|
||||
|
||||
Hmac hmac;
|
||||
|
||||
if (hash == md5_mac) {
|
||||
hash = MD5;
|
||||
}
|
||||
else if (hash == sha_mac) {
|
||||
len = SHA_DIGEST_SIZE;
|
||||
hash = SHA;
|
||||
} else if (hash == sha256_mac) {
|
||||
len = SHA256_DIGEST_SIZE;
|
||||
hash = SHA256;
|
||||
}
|
||||
#ifdef CYASSL_SHA384
|
||||
else if (hash == sha384_mac)
|
||||
{
|
||||
len = SHA384_DIGEST_SIZE;
|
||||
hash = SHA384;
|
||||
}
|
||||
#endif
|
||||
|
||||
times = resLen / len;
|
||||
lastLen = resLen % len;
|
||||
if (lastLen) times += 1;
|
||||
lastTime = times - 1;
|
||||
|
||||
HmacSetKey(&hmac, hash == md5_mac ? MD5 : hash == sha_mac ? SHA : SHA256,
|
||||
secret, secLen);
|
||||
HmacSetKey(&hmac, hash, secret, secLen);
|
||||
HmacUpdate(&hmac, seed, seedLen); /* A0 = seed */
|
||||
HmacFinal(&hmac, previous); /* A1 */
|
||||
|
||||
@ -99,7 +122,7 @@ static void p_hash(byte* result, word32 resLen, const byte* secret,
|
||||
/* compute TLSv1 PRF (pseudo random function using HMAC) */
|
||||
static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
|
||||
const byte* label, word32 labLen, const byte* seed, word32 seedLen,
|
||||
int useSha256)
|
||||
int useAtLeastSha256, int hash_type)
|
||||
{
|
||||
word32 half = (secLen + 1) / 2;
|
||||
|
||||
@ -122,9 +145,13 @@ static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
|
||||
XMEMCPY(labelSeed, label, labLen);
|
||||
XMEMCPY(labelSeed + labLen, seed, seedLen);
|
||||
|
||||
if (useSha256) {
|
||||
if (useAtLeastSha256) {
|
||||
/* If a cipher suite wants an algorithm better than sha256, it
|
||||
* should use better. */
|
||||
if (hash_type < sha256_mac)
|
||||
hash_type = sha256_mac;
|
||||
p_hash(digest, digLen, secret, secLen, labelSeed, labLen + seedLen,
|
||||
sha256_mac);
|
||||
hash_type);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -136,20 +163,35 @@ static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
|
||||
}
|
||||
|
||||
|
||||
#ifdef CYASSL_SHA384
|
||||
#define HSHASH_SZ SHA384_DIGEST_SIZE
|
||||
#else
|
||||
#define HSHASH_SZ FINISHED_SZ
|
||||
#endif
|
||||
|
||||
|
||||
void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
|
||||
{
|
||||
const byte* side;
|
||||
byte handshake_hash[FINISHED_SZ];
|
||||
byte handshake_hash[HSHASH_SZ];
|
||||
word32 hashSz = FINISHED_SZ;
|
||||
|
||||
Md5Final(&ssl->hashMd5, handshake_hash);
|
||||
ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]);
|
||||
#ifndef NO_SHA256
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
Sha256Final(&ssl->hashSha256, handshake_hash);
|
||||
hashSz = SHA256_DIGEST_SIZE;
|
||||
}
|
||||
#ifndef NO_SHA256
|
||||
if (ssl->specs.mac_algorithm <= sha256_mac) {
|
||||
Sha256Final(&ssl->hashSha256, handshake_hash);
|
||||
hashSz = SHA256_DIGEST_SIZE;
|
||||
}
|
||||
#endif
|
||||
#ifdef CYASSL_SHA384
|
||||
if (ssl->specs.mac_algorithm == sha384_mac) {
|
||||
Sha384Final(&ssl->hashSha384, handshake_hash);
|
||||
hashSz = SHA384_DIGEST_SIZE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
|
||||
side = tls_client;
|
||||
@ -157,7 +199,8 @@ void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
|
||||
side = tls_server;
|
||||
|
||||
PRF(hashes->md5, TLS_FINISHED_SZ, ssl->arrays.masterSecret, SECRET_LEN,
|
||||
side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl));
|
||||
side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl),
|
||||
ssl->specs.mac_algorithm);
|
||||
}
|
||||
|
||||
|
||||
@ -207,7 +250,8 @@ int DeriveTlsKeys(CYASSL* ssl)
|
||||
XMEMCPY(&seed[RAN_LEN], ssl->arrays.clientRandom, RAN_LEN);
|
||||
|
||||
PRF(key_data, length, ssl->arrays.masterSecret, SECRET_LEN, key_label,
|
||||
KEY_LABEL_SZ, seed, SEED_LEN, IsAtLeastTLSv1_2(ssl));
|
||||
KEY_LABEL_SZ, seed, SEED_LEN, IsAtLeastTLSv1_2(ssl),
|
||||
ssl->specs.mac_algorithm);
|
||||
|
||||
return StoreKeys(ssl, key_data);
|
||||
}
|
||||
@ -223,7 +267,7 @@ int MakeTlsMasterSecret(CYASSL* ssl)
|
||||
PRF(ssl->arrays.masterSecret, SECRET_LEN,
|
||||
ssl->arrays.preMasterSecret, ssl->arrays.preMasterSz,
|
||||
master_label, MASTER_LABEL_SZ,
|
||||
seed, SEED_LEN, IsAtLeastTLSv1_2(ssl));
|
||||
seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
|
||||
|
||||
#ifdef SHOW_SECRETS
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user