FIPS Revalidation

1. Bug fixes to AES-GCM. Separated out the internal and external IV set functions.
cert-3389
John Safranek 2018-03-20 13:40:44 -07:00
parent c2f964039e
commit 6796ab5f8c
3 changed files with 58 additions and 39 deletions

View File

@ -3374,7 +3374,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
*/
enum {
GCM_NONCE_SZ = 12,
GCM_NONCE_MAX_SZ = 16, /* wolfCrypt's maximum nonce size allowed. */
GCM_NONCE_MID_SZ = 12, /* The usual default nonce size for AES-GCM. */
GCM_NONCE_MIN_SZ = 8, /* wolfCrypt's minimum nonce size allowed. */
CCM_NONCE_MIN_SZ = 7,
CCM_NONCE_MAX_SZ = 13,
CTR_SZ = 4,
@ -7497,7 +7499,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 == GCM_NONCE_SZ) {
if (ivSz == GCM_NONCE_MID_SZ) {
XMEMCPY(initialCounter, iv, ivSz);
initialCounter[AES_BLOCK_SIZE - 1] = 1;
}
@ -7584,7 +7586,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 != GCM_NONCE_SZ) {
if (ivSz != GCM_NONCE_MID_SZ) {
return BAD_FUNC_ARG;
}
@ -7732,7 +7734,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 != GCM_NONCE_SZ) {
if (ivSz != GCM_NONCE_MID_SZ) {
return BAD_FUNC_ARG;
}
@ -7866,7 +7868,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 == GCM_NONCE_SZ) {
if (ivSz == GCM_NONCE_MID_SZ) {
XMEMCPY(initialCounter, iv, ivSz);
initialCounter[AES_BLOCK_SIZE - 1] = 1;
}
@ -8036,18 +8038,43 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
#ifndef WC_NO_RNG
int wc_AesGcmSetIV(Aes* aes, const byte* extIv, word32 ivSz,
int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
{
int ret = 0;
if (aes == NULL || iv == NULL ||
(ivSz != GCM_NONCE_MIN_SZ && ivSz != GCM_NONCE_MID_SZ &&
ivSz != GCM_NONCE_MAX_SZ)) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
XMEMCPY((byte*)aes->reg, iv, ivSz);
/* If the IV is 96, allow for a 2^64 invocation counter.
* For any other size for the nonce, limit the invocation
* counter to 32-bits. (SP 800-38D 8.3) */
aes->invokeCtr[0] = 0;
aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
aes->nonceSz = ivSz;
}
return ret;
}
int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
const byte* ivFixed, word32 ivFixedSz,
WC_RNG* rng)
{
int ret = 0;
if (aes == NULL ||
(extIv != NULL && ivFixed != NULL) ||
(extIv == NULL && ivFixed == NULL && rng == NULL) ||
if (aes == NULL || rng == NULL ||
(ivSz != GCM_NONCE_MIN_SZ && ivSz != GCM_NONCE_MID_SZ &&
ivSz != GCM_NONCE_MAX_SZ) ||
(ivFixed == NULL && ivFixedSz != 0) ||
(ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ) ||
ivSz != GCM_NONCE_SZ) {
(ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
ret = BAD_FUNC_ARG;
}
@ -8055,24 +8082,19 @@ int wc_AesGcmSetIV(Aes* aes, const byte* extIv, word32 ivSz,
if (ret == 0) {
byte* iv = (byte*)aes->reg;
if (extIv == NULL) {
if (ivFixedSz)
XMEMCPY((byte*)aes->reg, ivFixed, ivFixedSz);
if (ivFixedSz)
XMEMCPY(iv, 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);
ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
}
if (ret == 0) {
/* If the IV is 96-bits, allow for a 2^64 invocation counter. */
/* If the IV is 96, allow for a 2^64 invocation counter.
* For any other size for the nonce, limit the invocation
* counter to 32-bits. (SP 800-38D 8.3) */
aes->invokeCtr[0] = 0;
aes->invokeCtr[1] = 0;
aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
aes->nonceSz = ivSz;
}
return ret;
@ -8087,7 +8109,7 @@ int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
int ret = 0;
if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
ivOut == NULL || ivOutSz != GCM_NONCE_SZ ||
ivOut == NULL || ivOutSz != aes->nonceSz ||
(authIn == NULL && authInSz != 0)) {
ret = BAD_FUNC_ARG;
@ -8104,11 +8126,11 @@ int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
if (ret == 0) {
ret = wc_AesGcmEncrypt(aes, out, in, sz,
(byte*)aes->reg, GCM_NONCE_SZ,
(byte*)aes->reg, ivOutSz,
authTag, authTagSz,
authIn, authInSz);
XMEMCPY(ivOut, aes->reg, GCM_NONCE_SZ);
IncCtr((byte*)aes->reg, GCM_NONCE_SZ);
XMEMCPY(ivOut, aes->reg, ivOutSz);
IncCtr((byte*)aes->reg, ivOutSz);
}
return ret;
@ -8121,9 +8143,8 @@ int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
Aes aes;
int ret = 0;
if (key == NULL || iv == NULL || ivSz != GCM_NONCE_SZ ||
(authIn == NULL && authInSz != 0) || authTag == NULL ||
authTagSz == 0 || rng == NULL) {
if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
authTag == NULL || authTagSz == 0 || rng == NULL) {
ret = BAD_FUNC_ARG;
}
@ -8131,7 +8152,7 @@ int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
if (ret == 0)
ret = wc_AesGcmSetKey(&aes, key, keySz);
if (ret == 0)
ret = wc_AesGcmSetIV(&aes, NULL, GCM_NONCE_SZ, NULL, 0, rng);
ret = wc_AesGcmSetIV(&aes, ivSz, NULL, 0, rng);
if (ret == 0)
ret = wc_AesGcmEncrypt_ex(&aes, NULL, NULL, 0, iv, ivSz,
authTag, authTagSz, authIn, authInSz);
@ -8148,9 +8169,8 @@ int wc_GmacVerify(const byte* key, word32 keySz,
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) {
if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
authTag == NULL || authTagSz == 0 || authTagSz > AES_BLOCK_SIZE) {
ret = BAD_FUNC_ARG;
}

View File

@ -6618,7 +6618,7 @@ int aesgcm_test(void)
XMEMSET(resultP, 0, sizeof(resultP));
wc_AesGcmSetKey(&enc, k1, sizeof(k1));
result = wc_AesGcmSetIV(&enc, NULL, sizeof(randIV), NULL, 0, &rng);
result = wc_AesGcmSetIV(&enc, sizeof(randIV), NULL, 0, &rng);
if (result != 0)
return -8213;

View File

@ -111,8 +111,6 @@ typedef struct Aes {
#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
word32 invokeCtr[2];
#endif
#ifdef HAVE_AESCCM
word32 nonceSz;
#endif
#ifdef HAVE_AESGCM
@ -225,7 +223,8 @@ 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,
WOLFSSL_API int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz);
WOLFSSL_API int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
const byte* ivFixed, word32 ivFixedSz,
WC_RNG* rng);
WOLFSSL_API int wc_AesGcmEncrypt_ex(Aes* aes, byte* out,