forked from wolfSSL/wolfssl
FIPS Revalidation
1. Add new APIs for AES-GCM so it can manage the IV per SP 800-38D. 2. Add new APIs for AES-CCM so it can manage the IV, similar to the behavior in AES-GCM. 3. Add new APIs for GMAC that use the new AES-GCM APIs.
This commit is contained in:
@ -3331,20 +3331,40 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
|
||||
#endif /* WOLFSSL_AES_COUNTER */
|
||||
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
|
||||
/*
|
||||
* The IV for AES GCM, stored in struct Aes's member reg, is comprised of
|
||||
* three parts in order:
|
||||
* 1. The implicit IV. This is generated from the PRF using the shared
|
||||
* secrets between endpoints. It is 4 bytes long.
|
||||
* 2. The explicit IV. This is set by the user of the AES. It needs to be
|
||||
* unique for each call to encrypt. The explicit IV is shared with the
|
||||
* other end of the transaction in the clear.
|
||||
* 3. The counter. Each block of data is encrypted with its own sequence
|
||||
* number counter.
|
||||
* The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
|
||||
* of two parts in order:
|
||||
* 1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
|
||||
* to the implicit IV.
|
||||
* 2. The explicit IV is generated by wolfCrypt. It needs to be managed
|
||||
* by wolfCrypt to ensure the IV is unique for each call to encrypt.
|
||||
* The IV may be a 96-bit random value, or the 32-bit fixed value and a
|
||||
* 64-bit set of 0 or random data. The final 32-bits of reg is used as a
|
||||
* block counter during the encryption.
|
||||
*/
|
||||
|
||||
enum {
|
||||
GCM_NONCE_SZ = 12,
|
||||
CCM_NONCE_MIN_SZ = 7,
|
||||
CCM_NONCE_MAX_SZ = 13,
|
||||
CTR_SZ = 4,
|
||||
AES_IV_FIXED_SZ = 4
|
||||
};
|
||||
|
||||
#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
|
||||
static INLINE void IncCtr(byte* ctr, word32 ctrSz)
|
||||
{
|
||||
int i;
|
||||
for (i = ctrSz-1; i >= 0; i--) {
|
||||
if (++ctr[i])
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_AESGCM || HAVE_AESCCM */
|
||||
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
|
||||
#if defined(HAVE_COLDFIRE_SEC)
|
||||
#error "Coldfire SEC doesn't currently support AES-GCM mode"
|
||||
|
||||
@ -3353,11 +3373,6 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
|
||||
|
||||
#endif
|
||||
|
||||
enum {
|
||||
NONCE_SZ = 12,
|
||||
CTR_SZ = 4
|
||||
};
|
||||
|
||||
#if !defined(FREESCALE_LTC_AES_GCM)
|
||||
static INLINE void IncrementGcmCounter(byte* inOutCtr)
|
||||
{
|
||||
@ -7452,7 +7467,7 @@ int AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
|
||||
ctr = counter;
|
||||
XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
|
||||
if (ivSz == NONCE_SZ) {
|
||||
if (ivSz == GCM_NONCE_SZ) {
|
||||
XMEMCPY(initialCounter, iv, ivSz);
|
||||
initialCounter[AES_BLOCK_SIZE - 1] = 1;
|
||||
}
|
||||
@ -7464,10 +7479,10 @@ int AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
#ifdef WOLFSSL_PIC32MZ_CRYPT
|
||||
if (blocks) {
|
||||
/* use intitial IV for PIC32 HW, but don't use it below */
|
||||
XMEMCPY(aes->reg, ctr, AES_BLOCK_SIZE);
|
||||
XMEMCPY(aes->tmp, ctr, AES_BLOCK_SIZE);
|
||||
|
||||
ret = wc_Pic32AesCrypt(
|
||||
aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
|
||||
aes->key, aes->keylen, aes->tmp, AES_BLOCK_SIZE,
|
||||
out, in, (blocks * AES_BLOCK_SIZE),
|
||||
PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
|
||||
if (ret != 0)
|
||||
@ -7539,7 +7554,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
defined(WOLFSSL_STM32F7))
|
||||
|
||||
/* additional argument checks - STM32 HW only supports 12 byte IV */
|
||||
if (ivSz != NONCE_SZ) {
|
||||
if (ivSz != GCM_NONCE_SZ) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
@ -7680,7 +7695,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
}
|
||||
|
||||
/* additional argument checks - STM32 HW only supports 12 byte IV */
|
||||
if (ivSz != NONCE_SZ) {
|
||||
if (ivSz != GCM_NONCE_SZ) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
@ -7814,7 +7829,7 @@ int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
ctr = counter;
|
||||
|
||||
XMEMSET(initialCounter, 0, AES_BLOCK_SIZE);
|
||||
if (ivSz == NONCE_SZ) {
|
||||
if (ivSz == GCM_NONCE_SZ) {
|
||||
XMEMCPY(initialCounter, iv, ivSz);
|
||||
initialCounter[AES_BLOCK_SIZE - 1] = 1;
|
||||
}
|
||||
@ -7835,10 +7850,10 @@ int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
#ifdef WOLFSSL_PIC32MZ_CRYPT
|
||||
if (blocks) {
|
||||
/* use intitial IV for PIC32 HW, but don't use it below */
|
||||
XMEMCPY(aes->reg, ctr, AES_BLOCK_SIZE);
|
||||
XMEMCPY(aes->tmp, ctr, AES_BLOCK_SIZE);
|
||||
|
||||
ret = wc_Pic32AesCrypt(
|
||||
aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
|
||||
aes->key, aes->keylen, aes->tmp, AES_BLOCK_SIZE,
|
||||
out, in, (blocks * AES_BLOCK_SIZE),
|
||||
PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
|
||||
if (ret != 0)
|
||||
@ -7896,8 +7911,11 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
#endif
|
||||
|
||||
/* argument checks */
|
||||
if (aes == NULL || out == NULL || in == NULL || iv == NULL ||
|
||||
authTag == NULL || authTagSz > AES_BLOCK_SIZE) {
|
||||
/* If the sz is non-zero, both in and out must be set. If sz is 0,
|
||||
* in and out are don't cares, as this is is the GMAC case. */
|
||||
if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
|
||||
authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0) {
|
||||
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
@ -7974,25 +7992,131 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
|
||||
#ifndef WC_NO_RNG
|
||||
|
||||
int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
byte* iv, word32 ivSz, byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz, WC_RNG* rng)
|
||||
int wc_AesGcmSetIV(Aes* aes, const byte* extIv, word32 ivSz,
|
||||
const byte* ivFixed, word32 ivFixedSz,
|
||||
WC_RNG* rng)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (aes == NULL || out == NULL || (in == NULL && sz != 0) ||
|
||||
iv == NULL || ivSz == 0 || (authIn == NULL && authInSz != 0) ||
|
||||
rng == NULL) {
|
||||
if (aes == NULL ||
|
||||
(extIv != NULL && ivFixed != NULL) ||
|
||||
(extIv == NULL && ivFixed == NULL && rng == NULL) ||
|
||||
(ivFixed == NULL && ivFixedSz != 0) ||
|
||||
(ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ) ||
|
||||
ivSz != GCM_NONCE_SZ) {
|
||||
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
byte* iv = (byte*)aes->reg;
|
||||
|
||||
if (extIv == NULL) {
|
||||
if (ivFixedSz)
|
||||
XMEMCPY((byte*)aes->reg, ivFixed, ivFixedSz);
|
||||
|
||||
if (rng == NULL)
|
||||
XMEMSET(iv + ivFixedSz, 0, ivSz - ivFixedSz);
|
||||
else
|
||||
ret = wc_RNG_GenerateBlock(rng,
|
||||
iv + ivFixedSz, ivSz - ivFixedSz);
|
||||
}
|
||||
else
|
||||
XMEMCPY(iv, extIv, ivSz);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* If the IV is 96-bits, allow for a 2^64 invocation counter. */
|
||||
aes->invokeCtr[0] = 0;
|
||||
aes->invokeCtr[1] = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
byte* ivOut, word32 ivOutSz,
|
||||
byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
|
||||
ivOut == NULL || ivOutSz != GCM_NONCE_SZ ||
|
||||
(authIn == NULL && authInSz != 0)) {
|
||||
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
aes->invokeCtr[0]++;
|
||||
if (aes->invokeCtr[0] == 0) {
|
||||
aes->invokeCtr[1]++;
|
||||
if (aes->invokeCtr[1] == 0)
|
||||
ret = AES_GCM_OVERFLOW_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_AesGcmEncrypt(aes, out, in, sz,
|
||||
(byte*)aes->reg, GCM_NONCE_SZ,
|
||||
authTag, authTagSz,
|
||||
authIn, authInSz);
|
||||
XMEMCPY(ivOut, aes->reg, GCM_NONCE_SZ);
|
||||
IncCtr((byte*)aes->reg, GCM_NONCE_SZ);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
|
||||
const byte* authIn, word32 authInSz,
|
||||
byte* authTag, word32 authTagSz, WC_RNG* rng)
|
||||
{
|
||||
Aes aes;
|
||||
int ret = 0;
|
||||
|
||||
if (key == NULL || iv == NULL || ivSz != GCM_NONCE_SZ ||
|
||||
(authIn == NULL && authInSz != 0) || authTag == NULL ||
|
||||
authTagSz == 0 || rng == NULL) {
|
||||
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
ret = wc_RNG_GenerateBlock(rng, iv, ivSz);
|
||||
ret = wc_AesGcmSetKey(&aes, key, keySz);
|
||||
if (ret == 0)
|
||||
ret = wc_AesGcmSetIV(&aes, NULL, GCM_NONCE_SZ, NULL, 0, rng);
|
||||
if (ret == 0)
|
||||
ret = wc_AesGcmEncrypt_ex(&aes, NULL, NULL, 0, iv, ivSz,
|
||||
authTag, authTagSz, authIn, authInSz);
|
||||
ForceZero(&aes, sizeof(aes));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_GmacVerify(const byte* key, word32 keySz,
|
||||
const byte* iv, word32 ivSz,
|
||||
const byte* authIn, word32 authInSz,
|
||||
const byte* authTag, word32 authTagSz)
|
||||
{
|
||||
Aes aes;
|
||||
int ret = 0;
|
||||
|
||||
if (key == NULL || iv == NULL || ivSz != GCM_NONCE_SZ ||
|
||||
(authIn == NULL && authInSz != 0) || authTag == NULL ||
|
||||
authTagSz == 0 || authTagSz > AES_BLOCK_SIZE) {
|
||||
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
ret = wc_AesGcmEncrypt(aes, out, in, sz, iv, ivSz,
|
||||
authTag, authTagSz, authIn, authInSz);
|
||||
ret = wc_AesGcmSetKey(&aes, key, keySz);
|
||||
if (ret == 0)
|
||||
ret = wc_AesGcmDecrypt(&aes, NULL, NULL, 0, iv, ivSz,
|
||||
authTag, authTagSz, authIn, authInSz);
|
||||
ForceZero(&aes, sizeof(aes));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -8331,7 +8455,72 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
|
||||
#ifndef WC_NO_RNG
|
||||
|
||||
int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (aes == NULL || nonce == NULL ||
|
||||
nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
|
||||
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
XMEMCPY(aes->reg, nonce, nonceSz);
|
||||
aes->nonceSz = nonceSz;
|
||||
|
||||
/* Invocation counter should be 2^61 */
|
||||
aes->invokeCtr[0] = 0;
|
||||
aes->invokeCtr[1] = 0xE0000000;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
byte* ivOut, word32 ivOutSz,
|
||||
byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (aes == NULL || out == NULL ||
|
||||
(in == NULL && sz != 0) ||
|
||||
ivOut == NULL ||
|
||||
(authIn == NULL && authInSz != 0) ||
|
||||
(ivOutSz != aes->nonceSz)) {
|
||||
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
aes->invokeCtr[0]++;
|
||||
if (aes->invokeCtr[0] == 0) {
|
||||
aes->invokeCtr[1]++;
|
||||
if (aes->invokeCtr[1] == 0)
|
||||
ret = AES_CCM_OVERFLOW_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_AesCcmEncrypt(aes, out, in, sz,
|
||||
(byte*)aes->reg, aes->nonceSz,
|
||||
authTag, authTagSz,
|
||||
authIn, authInSz);
|
||||
XMEMCPY(ivOut, aes->reg, aes->nonceSz);
|
||||
IncCtr((byte*)aes->reg, aes->nonceSz);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* WC_NO_RNG */
|
||||
#endif /* software AES CCM */
|
||||
|
||||
#endif /* HAVE_AESCCM */
|
||||
|
@ -467,6 +467,12 @@ const char* wc_GetErrorString(int error)
|
||||
case ECDHE_KAT_FIPS_E:
|
||||
return "wolfcrypt FIPS ECDHE Known Answer Test Failure";
|
||||
|
||||
case AES_GCM_OVERFLOW_E:
|
||||
return "AES-GCM invocation counter overflow";
|
||||
|
||||
case AES_CCM_OVERFLOW_E:
|
||||
return "AES-CCM invocation counter overflow";
|
||||
|
||||
default:
|
||||
return "unknown error number";
|
||||
|
||||
|
@ -6488,9 +6488,10 @@ int aesgcm_test(void)
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
#endif /* WOLFSSL_AES_256 */
|
||||
|
||||
/* Test encrypt with internally generated IV */
|
||||
#if !defined(WC_NO_RNG) && \
|
||||
#if !defined(HAVE_FIPS) || \
|
||||
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))
|
||||
/* Test encrypt with internally generated IV */
|
||||
#ifndef WC_NO_RNG
|
||||
{
|
||||
WC_RNG rng;
|
||||
byte randIV[12];
|
||||
@ -6505,9 +6506,15 @@ int aesgcm_test(void)
|
||||
XMEMSET(resultP, 0, sizeof(resultP));
|
||||
|
||||
wc_AesGcmSetKey(&enc, k1, sizeof(k1));
|
||||
result = wc_AesGcmEncrypt_ex(&enc, resultC, p, sizeof(p),
|
||||
randIV, sizeof(randIV), resultT, sizeof(resultT),
|
||||
a, sizeof(a), &rng);
|
||||
result = wc_AesGcmSetIV(&enc, NULL, sizeof(randIV), NULL, 0, &rng);
|
||||
if (result != 0)
|
||||
return -8213;
|
||||
|
||||
result = wc_AesGcmEncrypt_ex(&enc,
|
||||
resultC, p, sizeof(p),
|
||||
randIV, sizeof(randIV),
|
||||
resultT, sizeof(resultT),
|
||||
a, sizeof(a));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
result = wc_AsyncWait(result, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
@ -6524,8 +6531,10 @@ int aesgcm_test(void)
|
||||
return -8210;
|
||||
}
|
||||
|
||||
result = wc_AesGcmDecrypt(&enc, resultP, resultC, sizeof(resultC),
|
||||
randIV, sizeof(randIV), resultT, sizeof(resultT),
|
||||
result = wc_AesGcmDecrypt(&enc,
|
||||
resultP, resultC, sizeof(resultC),
|
||||
randIV, sizeof(randIV),
|
||||
resultT, sizeof(resultT),
|
||||
a, sizeof(a));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
result = wc_AsyncWait(result, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
@ -6536,7 +6545,8 @@ int aesgcm_test(void)
|
||||
return -8212;
|
||||
wc_FreeRng(&rng);
|
||||
}
|
||||
#endif /* WC_NO_RNG && FIPSv2 */
|
||||
#endif /* WC_NO_RNG */
|
||||
#endif
|
||||
|
||||
wc_AesFree(&enc);
|
||||
|
||||
@ -6569,7 +6579,8 @@ int gmac_test(void)
|
||||
0xaa, 0x10, 0xf1, 0x6d, 0x22, 0x7d, 0xc4, 0x1b
|
||||
};
|
||||
|
||||
#if !defined(HAVE_FIPS)
|
||||
#if !defined(HAVE_FIPS) || \
|
||||
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))
|
||||
/* FIPS builds only allow 16-byte auth tags. */
|
||||
/* This sample uses a 15-byte auth tag. */
|
||||
const byte k2[] =
|
||||
@ -6592,7 +6603,7 @@ int gmac_test(void)
|
||||
0xc6, 0x81, 0x79, 0x8e, 0x3d, 0xda, 0xb0, 0x9f,
|
||||
0x8d, 0x83, 0xb0, 0xbb, 0x14, 0xb6, 0x91
|
||||
};
|
||||
#endif /* HAVE_FIPS */
|
||||
#endif
|
||||
|
||||
byte tag[16];
|
||||
|
||||
@ -6603,12 +6614,54 @@ int gmac_test(void)
|
||||
if (XMEMCMP(t1, tag, sizeof(t1)) != 0)
|
||||
return -4400;
|
||||
|
||||
#if !defined(HAVE_FIPS)
|
||||
#if !defined(HAVE_FIPS) || \
|
||||
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))
|
||||
XMEMSET(tag, 0, sizeof(tag));
|
||||
wc_GmacSetKey(&gmac, k2, sizeof(k2));
|
||||
wc_GmacUpdate(&gmac, iv2, sizeof(iv2), a2, sizeof(a2), tag, sizeof(t2));
|
||||
if (XMEMCMP(t2, tag, sizeof(t2)) != 0)
|
||||
return -4401;
|
||||
|
||||
#ifndef WC_NO_RNG
|
||||
{
|
||||
const byte badT[] =
|
||||
{
|
||||
0xde, 0xad, 0xbe, 0xef, 0x17, 0x2e, 0xd0, 0x43,
|
||||
0xaa, 0x10, 0xf1, 0x6d, 0x22, 0x7d, 0xc4, 0x1b
|
||||
};
|
||||
|
||||
WC_RNG rng;
|
||||
byte iv[12];
|
||||
|
||||
#ifndef HAVE_FIPS
|
||||
if (wc_InitRng_ex(&rng, HEAP_HINT, devId) != 0)
|
||||
return -8214;
|
||||
#else
|
||||
if (wc_InitRng(&rng) != 0)
|
||||
return -8214;
|
||||
#endif
|
||||
|
||||
if (wc_GmacVerify(k1, sizeof(k1), iv1, sizeof(iv1), a1, sizeof(a1),
|
||||
t1, sizeof(t1)) != 0)
|
||||
return -8215;
|
||||
if (wc_GmacVerify(k1, sizeof(k1), iv1, sizeof(iv1), a1, sizeof(a1),
|
||||
badT, sizeof(badT)) != AES_GCM_AUTH_E)
|
||||
return -8216;
|
||||
if (wc_GmacVerify(k2, sizeof(k2), iv2, sizeof(iv2), a2, sizeof(a2),
|
||||
t2, sizeof(t2)) != 0)
|
||||
return -8217;
|
||||
|
||||
XMEMSET(tag, 0, sizeof(tag));
|
||||
XMEMSET(iv, 0, sizeof(iv));
|
||||
if (wc_Gmac(k1, sizeof(k1), iv, sizeof(iv), a1, sizeof(a1),
|
||||
tag, sizeof(tag), &rng) != 0)
|
||||
return -8218;
|
||||
if (wc_GmacVerify(k1, sizeof(k1), iv, sizeof(iv), a1, sizeof(a1),
|
||||
tag, sizeof(tag)) != 0)
|
||||
return -8219;
|
||||
wc_FreeRng(&rng);
|
||||
}
|
||||
#endif /* WC_NO_RNG */
|
||||
#endif /* HAVE_FIPS */
|
||||
|
||||
return 0;
|
||||
@ -6663,6 +6716,7 @@ int aesccm_test(void)
|
||||
byte t2[sizeof(t)];
|
||||
byte p2[sizeof(p)];
|
||||
byte c2[sizeof(c)];
|
||||
byte iv2[sizeof(iv)];
|
||||
|
||||
int result;
|
||||
|
||||
@ -6705,6 +6759,26 @@ int aesccm_test(void)
|
||||
if (XMEMCMP(p2, c2, sizeof(p2)))
|
||||
return -4507;
|
||||
|
||||
XMEMSET(&enc, 0, sizeof(Aes)); /* clear context */
|
||||
XMEMSET(t2, 0, sizeof(t2));
|
||||
XMEMSET(c2, 0, sizeof(c2));
|
||||
XMEMSET(p2, 0, sizeof(p2));
|
||||
XMEMSET(iv2, 0, sizeof(iv2));
|
||||
|
||||
if (wc_AesCcmSetKey(&enc, k, sizeof(k)) != 0)
|
||||
return -8220;
|
||||
if (wc_AesCcmSetNonce(&enc, iv, sizeof(iv)) != 0)
|
||||
return -8221;
|
||||
if (wc_AesCcmEncrypt_ex(&enc, c2, p, sizeof(c2), iv2, sizeof(iv2),
|
||||
t2, sizeof(t2), a, sizeof(a)) != 0)
|
||||
return -8222;
|
||||
if (XMEMCMP(iv, iv2, sizeof(iv2)))
|
||||
return -8223;
|
||||
if (XMEMCMP(c, c2, sizeof(c2)))
|
||||
return -8224;
|
||||
if (XMEMCMP(t, t2, sizeof(t2)))
|
||||
return -8225;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_AESCCM WOLFSSL_AES_128 */
|
||||
|
@ -97,6 +97,12 @@ typedef struct Aes {
|
||||
ALIGN16 word32 reg[AES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
|
||||
ALIGN16 word32 tmp[AES_BLOCK_SIZE / sizeof(word32)]; /* same */
|
||||
|
||||
#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
|
||||
word32 invokeCtr[2];
|
||||
#endif
|
||||
#ifdef HAVE_AESCCM
|
||||
word32 nonceSz;
|
||||
#endif
|
||||
#ifdef HAVE_AESGCM
|
||||
ALIGN16 byte H[AES_BLOCK_SIZE];
|
||||
#ifdef GCM_TABLE
|
||||
@ -188,6 +194,7 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out,
|
||||
WOLFSSL_API int wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len,
|
||||
const byte* iv, int dir);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
#ifdef WOLFSSL_XILINX_CRYPT
|
||||
WOLFSSL_API int wc_AesGcmSetKey_ex(Aes* aes, const byte* key, word32 len,
|
||||
@ -206,18 +213,29 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out,
|
||||
const byte* authIn, word32 authInSz);
|
||||
|
||||
#ifndef WC_NO_RNG
|
||||
WOLFSSL_API int wc_AesGcmSetIV(Aes* aes, const byte* extIv, word32 ivSz,
|
||||
const byte* ivFixed, word32 ivFixedSz,
|
||||
WC_RNG* rng);
|
||||
WOLFSSL_API int wc_AesGcmEncrypt_ex(Aes* aes, byte* out,
|
||||
const byte* in, word32 sz,
|
||||
byte* iv, word32 ivSz,
|
||||
byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz,
|
||||
WC_RNG* rng);
|
||||
const byte* in, word32 sz,
|
||||
byte* ivOut, word32 ivOutSz,
|
||||
byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz);
|
||||
#endif /* WC_NO_RNG */
|
||||
|
||||
WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len);
|
||||
WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
|
||||
const byte* authIn, word32 authInSz,
|
||||
byte* authTag, word32 authTagSz);
|
||||
#ifndef WC_NO_RNG
|
||||
WOLFSSL_API int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
|
||||
const byte* authIn, word32 authInSz,
|
||||
byte* authTag, word32 authTagSz, WC_RNG* rng);
|
||||
WOLFSSL_API int wc_GmacVerify(const byte* key, word32 keySz,
|
||||
const byte* iv, word32 ivSz,
|
||||
const byte* authIn, word32 authInSz,
|
||||
const byte* authTag, word32 authTagSz);
|
||||
#endif /* WC_NO_RNG */
|
||||
WOLFSSL_LOCAL void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c,
|
||||
word32 cSz, byte* s, word32 sSz);
|
||||
#endif /* HAVE_AESGCM */
|
||||
@ -233,6 +251,13 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out,
|
||||
const byte* nonce, word32 nonceSz,
|
||||
const byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz);
|
||||
WOLFSSL_API int wc_AesCcmSetNonce(Aes* aes,
|
||||
const byte* nonce, word32 nonceSz);
|
||||
WOLFSSL_API int wc_AesCcmEncrypt_ex(Aes* aes, byte* out,
|
||||
const byte* in, word32 sz,
|
||||
byte* ivOut, word32 ivOutSz,
|
||||
byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz);
|
||||
#endif /* HAVE_AESCCM */
|
||||
#ifdef HAVE_AES_KEYWRAP
|
||||
WOLFSSL_API int wc_AesKeyWrap(const byte* key, word32 keySz,
|
||||
|
@ -207,8 +207,10 @@ enum {
|
||||
AESCCM_KAT_FIPS_E = -257, /* AESCCM KAT failure */
|
||||
SHA3_KAT_FIPS_E = -258, /* SHA-3 KAT failure */
|
||||
ECDHE_KAT_FIPS_E = -259, /* ECDHE KAT failure */
|
||||
AES_GCM_OVERFLOW_E = -260, /* AES-GCM invocation counter overflow. */
|
||||
AES_CCM_OVERFLOW_E = -261, /* AES-CCM invocation counter overflow. */
|
||||
|
||||
WC_LAST_E = -259, /* Update this to indicate last error */
|
||||
WC_LAST_E = -261, /* Update this to indicate last error */
|
||||
MIN_CODE_E = -300 /* errors -101 - -299 */
|
||||
|
||||
/* add new companion error id strings for any new error codes
|
||||
|
Reference in New Issue
Block a user