ecc9090cfc
function old new delta xwrite_encrypted 604 599 -5 FlattenSzInBits 52 - -52 aesgcm_GHASH 395 262 -133 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 0/2 up/down: 0/-190) Total: -190 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
154 lines
3.9 KiB
C
154 lines
3.9 KiB
C
/*
|
|
* Copyright (C) 2018 Denys Vlasenko
|
|
*
|
|
* Licensed under GPLv2, see file LICENSE in this source tree.
|
|
*/
|
|
|
|
#include "tls.h"
|
|
|
|
typedef uint8_t byte;
|
|
typedef uint32_t word32;
|
|
#define XMEMSET memset
|
|
#define XMEMCPY memcpy
|
|
|
|
#define TLS_MAJ 3
|
|
#define TLS_MIN 3
|
|
#define RECHDR_LEN 5
|
|
#define OUTBUF_PFX (8 + AES_BLOCK_SIZE)
|
|
|
|
void FAST_FUNC xorbuf(void* buf, const void* mask, unsigned count)
|
|
{
|
|
word32 i;
|
|
byte* b = (byte*)buf;
|
|
const byte* m = (const byte*)mask;
|
|
for (i = 0; i < count; i++)
|
|
b[i] ^= m[i];
|
|
}
|
|
|
|
/* from wolfssl-3.15.3/wolfcrypt/src/aes.c */
|
|
|
|
static ALWAYS_INLINE void FlattenSzInBits(byte* buf, word32 sz)
|
|
{
|
|
/* Multiply the sz by 8 */
|
|
//bbox: these sizes are never even close to 2^32/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;
|
|
move_to_unaligned32(buf, 0);
|
|
// buf[4] = (sz >> 24) & 0xff;
|
|
// buf[5] = (sz >> 16) & 0xff;
|
|
// buf[6] = (sz >> 8) & 0xff;
|
|
// buf[7] = sz & 0xff;
|
|
move_to_unaligned32(buf + 4, SWAP_BE32(sz));
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static void GMULT(byte* X, byte* Y)
|
|
{
|
|
byte Z[AES_BLOCK_SIZE];
|
|
byte V[AES_BLOCK_SIZE];
|
|
int i, j;
|
|
|
|
XMEMSET(Z, 0, AES_BLOCK_SIZE);
|
|
XMEMCPY(V, X, AES_BLOCK_SIZE);
|
|
for (i = 0; i < AES_BLOCK_SIZE; i++)
|
|
{
|
|
byte y = Y[i];
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
if (y & 0x80) {
|
|
xorbuf(Z, V, AES_BLOCK_SIZE);
|
|
}
|
|
|
|
RIGHTSHIFTX(V);
|
|
y = y << 1;
|
|
}
|
|
}
|
|
XMEMCPY(X, Z, AES_BLOCK_SIZE);
|
|
}
|
|
|
|
//bbox:
|
|
// for TLS AES-GCM, a (which as AAD) is always 13 bytes long, and bbox code provides
|
|
// extra 3 zeroed bytes, making it a[16], or a[AES_BLOCK_SIZE].
|
|
// Resulting auth tag in s is also always AES_BLOCK_SIZE bytes.
|
|
//
|
|
// This allows some simplifications.
|
|
#define aSz AES_BLOCK_SIZE
|
|
#define sSz AES_BLOCK_SIZE
|
|
void FAST_FUNC aesgcm_GHASH(byte* h,
|
|
const byte* a, //unsigned aSz,
|
|
const byte* c, unsigned cSz,
|
|
byte* s //, unsigned sSz
|
|
)
|
|
{
|
|
byte x[AES_BLOCK_SIZE];
|
|
byte scratch[AES_BLOCK_SIZE];
|
|
word32 blocks, partial;
|
|
//was: byte* h = aes->H;
|
|
|
|
//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);
|
|
XMEMCPY(x, a, AES_BLOCK_SIZE);// memcpy(x,a) = memset(x,0)+xorbuf(x,a)
|
|
GMULT(x, h);
|
|
// 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, h);
|
|
// }
|
|
// }
|
|
|
|
/* 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, h);
|
|
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, h);
|
|
}
|
|
}
|
|
|
|
/* 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);
|
|
|
|
/* Copy the result into s. */
|
|
XMEMCPY(s, x, sSz);
|
|
}
|