forked from wolfSSL/wolfssl
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:
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
Reference in New Issue
Block a user