Reworked the AES Key Wrap to use existing code in aes.c (instead of duplicating code in armv8-aes.c). Cleanup for GE/FE math on 32-bit to remove duplicate #ifdef check. Fixed AES GCM arg check for authIn to allows NULL.

This commit is contained in:
David Garske
2017-07-10 19:12:41 -07:00
parent 205da48416
commit a5cdbb18cb
4 changed files with 69 additions and 241 deletions

View File

@ -92,10 +92,9 @@ endif
endif
if BUILD_AES
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c
if BUILD_ARMASM
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-aes.c
else
src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c
endif
endif

View File

@ -27,9 +27,10 @@
#include <wolfssl/wolfcrypt/settings.h>
#ifndef NO_AES
#include <wolfssl/wolfcrypt/aes.h>
#ifndef WOLFSSL_ARMASM
/* fips wrapper calls, user can call direct */
#ifdef HAVE_FIPS
int wc_AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv,
@ -5197,6 +5198,70 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
#endif /* HAVE_AESCCM */
/* Initialize Aes for use with async hardware */
int wc_AesInit(Aes* aes, void* heap, int devId)
{
int ret = 0;
if (aes == NULL)
return BAD_FUNC_ARG;
aes->heap = heap;
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
aes->heap, devId);
#else
(void)devId;
#endif /* WOLFSSL_ASYNC_CRYPT */
return ret;
}
/* Free Aes from use with async hardware */
void wc_AesFree(Aes* aes)
{
if (aes == NULL)
return;
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
#endif /* WOLFSSL_ASYNC_CRYPT */
}
int wc_AesGetKeySize(Aes* aes, word32* keySize)
{
int ret = 0;
if (aes == NULL || keySize == NULL) {
return BAD_FUNC_ARG;
}
switch (aes->rounds) {
case 10:
*keySize = 16;
break;
case 12:
*keySize = 24;
break;
case 14:
*keySize = 32;
break;
default:
*keySize = 0;
ret = BAD_FUNC_ARG;
}
return ret;
}
#endif /* !WOLFSSL_TI_CRYPT */
#endif /* HAVE_FIPS */
#endif /* !WOLFSSL_ARMASM */
#ifdef HAVE_AES_KEYWRAP
/* Initialize key wrap counter with value */
@ -5368,67 +5433,4 @@ int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
#endif /* HAVE_AES_KEYWRAP */
/* Initialize Aes for use with async hardware */
int wc_AesInit(Aes* aes, void* heap, int devId)
{
int ret = 0;
if (aes == NULL)
return BAD_FUNC_ARG;
aes->heap = heap;
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
aes->heap, devId);
#else
(void)devId;
#endif /* WOLFSSL_ASYNC_CRYPT */
return ret;
}
/* Free Aes from use with async hardware */
void wc_AesFree(Aes* aes)
{
if (aes == NULL)
return;
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
#endif /* WOLFSSL_ASYNC_CRYPT */
}
int wc_AesGetKeySize(Aes* aes, word32* keySize)
{
int ret = 0;
if (aes == NULL || keySize == NULL) {
return BAD_FUNC_ARG;
}
switch (aes->rounds) {
case 10:
*keySize = 16;
break;
case 12:
*keySize = 24;
break;
case 14:
*keySize = 32;
break;
default:
*keySize = 0;
ret = BAD_FUNC_ARG;
}
return ret;
}
#endif /* !WOLFSSL_TI_CRYPT */
#endif /* HAVE_FIPS */
#endif /* NO_AES */
#endif /* !NO_AES */

View File

@ -2531,7 +2531,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
/* sanity checks */
if (aes == NULL || (iv == NULL && ivSz > 0) ||
(authTag == NULL) ||
(authIn == NULL) ||
(authIn == NULL && authInSz > 0) ||
(in == NULL && sz > 0) ||
(out == NULL && sz > 0)) {
WOLFSSL_MSG("a NULL parameter passed in when size is larger than 0");
@ -4645,177 +4645,6 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
#endif /* HAVE_AES_DECRYPT */
#endif /* WOLFSSL_AES_DIRECT */
#ifdef HAVE_AES_KEYWRAP
/* Initialize key wrap counter with value */
static INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
{
int i;
word32 bytes;
bytes = sizeof(word32);
for (i = 0; i < (int)sizeof(word32); i++) {
inOutCtr[i+sizeof(word32)] = (value >> ((bytes - 1) * 8)) & 0xFF;
bytes--;
}
}
/* Increment key wrap counter */
static INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
{
int i;
/* in network byte order so start at end and work back */
for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
if (++inOutCtr[i]) /* we're done unless we overflow */
return;
}
}
/* Decrement key wrap counter */
static INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
{
int i;
for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
if (--inOutCtr[i] != 0xFF) /* we're done unless we underflow */
return;
}
}
/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
byte* out, word32 outSz, const byte* iv)
{
Aes aes;
byte* r;
word32 i;
int ret, j;
byte t[KEYWRAP_BLOCK_SIZE];
byte tmp[AES_BLOCK_SIZE];
/* n must be at least 2, output size is n + 8 bytes */
if (key == NULL || in == NULL || inSz < 2 ||
out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
return BAD_FUNC_ARG;
/* input must be multiple of 64-bits */
if (inSz % KEYWRAP_BLOCK_SIZE != 0)
return BAD_FUNC_ARG;
/* user IV is optional */
if (iv == NULL) {
XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
} else {
XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
}
r = out + 8;
XMEMCPY(r, in, inSz);
XMEMSET(t, 0, sizeof(t));
ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_ENCRYPTION);
if (ret != 0)
return ret;
for (j = 0; j <= 5; j++) {
for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
/* load R[i] */
XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
wc_AesEncryptDirect(&aes, tmp, tmp);
/* calculate new A */
IncrementKeyWrapCounter(t);
xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
/* save R[i] */
XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
r += KEYWRAP_BLOCK_SIZE;
}
r = out + KEYWRAP_BLOCK_SIZE;
}
/* C[0] = A */
XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
return inSz + KEYWRAP_BLOCK_SIZE;
}
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
byte* out, word32 outSz, const byte* iv)
{
Aes aes;
byte* r;
word32 i, n;
int ret, j;
byte t[KEYWRAP_BLOCK_SIZE];
byte tmp[AES_BLOCK_SIZE];
const byte* expIv;
const byte defaultIV[] = {
0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
};
(void)iv;
if (key == NULL || in == NULL || inSz < 3 ||
out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
return BAD_FUNC_ARG;
/* input must be multiple of 64-bits */
if (inSz % KEYWRAP_BLOCK_SIZE != 0)
return BAD_FUNC_ARG;
/* user IV optional */
if (iv != NULL) {
expIv = iv;
} else {
expIv = defaultIV;
}
/* A = C[0], R[i] = C[i] */
XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
XMEMSET(t, 0, sizeof(t));
ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_DECRYPTION);
if (ret != 0)
return ret;
/* initialize counter to 6n */
n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
InitKeyWrapCounter(t, 6 * n);
for (j = 5; j >= 0; j--) {
for (i = n; i >= 1; i--) {
/* calculate A */
xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
DecrementKeyWrapCounter(t);
/* load R[i], starting at end of R */
r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
wc_AesDecryptDirect(&aes, tmp, tmp);
/* save R[i] */
XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
}
}
/* verify IV */
if (XMEMCMP(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
return BAD_KEYWRAP_IV_E;
return inSz - KEYWRAP_BLOCK_SIZE;
}
#endif /* HAVE_AES_KEYWRAP */
int wc_AesGetKeySize(Aes* aes, word32* keySize)
{
int ret = 0;

View File

@ -90,11 +90,9 @@ WOLFSSL_LOCAL void fe_mul121666(fe,fe);
WOLFSSL_LOCAL void fe_cmov(fe,const fe, int);
WOLFSSL_LOCAL void fe_pow22523(fe,const fe);
#if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL)
/* 64 type needed for SHA512 */
WOLFSSL_LOCAL uint64_t load_3(const unsigned char *in);
WOLFSSL_LOCAL uint64_t load_4(const unsigned char *in);
#endif
#endif /* !CURVE25519_SMALL || !ED25519_SMALL */