From 6b3642db36bd99c9f586efb53d3ab512225f81fd Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Thu, 16 Apr 2020 11:22:33 -0500 Subject: [PATCH] Fix forbidden iv length 0 with AES-GCM --- tests/api.c | 20 ++++++++++++++++++++ wolfcrypt/src/aes.c | 18 ++++++++++-------- wolfcrypt/test/test.c | 2 +- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/tests/api.c b/tests/api.c index 0f6e12f83..a9f2fdff6 100644 --- a/tests/api.c +++ b/tests/api.c @@ -11051,6 +11051,16 @@ static int test_wc_AesGcmEncryptDecrypt (void) resultT, sizeof(resultT) - 5, a, sizeof(a)); } +#if (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION == 2)) || defined(HAVE_SELFTEST) + /* FIPS does not check the lower bound of ivSz */ +#else + if (gcmE == BAD_FUNC_ARG) { + gcmE = wc_AesGcmEncrypt(&aes, enc, vector, + sizeof(vector), iv, 0, + resultT, sizeof(resultT), a, sizeof(a)); + } +#endif if (gcmE == BAD_FUNC_ARG) { gcmE = 0; } else { @@ -11111,6 +11121,16 @@ static int test_wc_AesGcmEncryptDecrypt (void) iv, sizeof(iv)/sizeof(byte), resultT, sizeof(resultT) + 1, a, sizeof(a)); } + #if (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION == 2)) || defined(HAVE_SELFTEST) + /* FIPS does not check the lower bound of ivSz */ + #else + if (gcmD == BAD_FUNC_ARG) { + gcmD = wc_AesGcmDecrypt(&aes, dec, enc, sizeof(enc)/sizeof(byte), + iv, 0, resultT, + sizeof(resultT), a, sizeof(a)); + } + #endif if (gcmD == BAD_FUNC_ARG) { gcmD = 0; } else { diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 69315d862..4b5b437ca 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -142,9 +142,9 @@ byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz) { - if (aes == NULL || authTagSz > AES_BLOCK_SIZE - || authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ || - ivSz > AES_BLOCK_SIZE) { + if (aes == NULL || authTagSz > AES_BLOCK_SIZE || + authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ || + ivSz == 0 || ivSz > AES_BLOCK_SIZE) { return BAD_FUNC_ARG; } @@ -160,7 +160,7 @@ { if (aes == NULL || out == NULL || in == NULL || iv == NULL || authTag == NULL || authTagSz > AES_BLOCK_SIZE || - ivSz > AES_BLOCK_SIZE) { + ivSz == 0 || ivSz > AES_BLOCK_SIZE) { return BAD_FUNC_ARG; } @@ -5891,7 +5891,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, word32 keySize; /* argument checks */ - if (aes == NULL || authTagSz > AES_BLOCK_SIZE) { + if (aes == NULL || authTagSz > AES_BLOCK_SIZE || ivSz == 0) { return BAD_FUNC_ARG; } @@ -6213,7 +6213,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, const byte* authIn, word32 authInSz) { /* argument checks */ - if (aes == NULL || authTagSz > AES_BLOCK_SIZE) { + if (aes == NULL || authTagSz > AES_BLOCK_SIZE || ivSz == 0) { return BAD_FUNC_ARG; } @@ -6329,7 +6329,8 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, /* 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) { + authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0 || + ivSz == 0) { return BAD_FUNC_ARG; } @@ -6662,7 +6663,8 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, /* 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) { + authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0 || + ivSz == 0) { return BAD_FUNC_ARG; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 2a48962ee..ac4d91d4e 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -8655,7 +8655,7 @@ int aesgcm_test(void) #endif /* BENCH_AESGCM_LARGE */ #if defined(ENABLE_NON_12BYTE_IV_TEST) && defined(WOLFSSL_AES_256) /* Variable IV length test */ - for (ivlen=0; ivlen<(int)sizeof(k1); ivlen++) { + for (ivlen=1; ivlen<(int)sizeof(k1); ivlen++) { /* AES-GCM encrypt and decrypt both use AES encrypt internally */ result = wc_AesGcmEncrypt(&enc, resultC, p, sizeof(p), k1, (word32)ivlen, resultT, sizeof(resultT), a, sizeof(a));