diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index f831f2de4..d3dc495a8 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -1828,7 +1828,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) #ifndef WOLFSSL_STM32_CUBEMX ByteReverseWords(rk, rk, keylen); #endif - #ifdef WOLFSSL_AES_COUNTER + #if defined(HAVE_AES_CFB) || defined(WOLFSSL_AES_COUNTER) aes->left = 0; #endif @@ -1901,6 +1901,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) if (iv) XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); + #if defined(HAVE_AES_CFB) || defined(WOLFSSL_AES_COUNTER) + aes->left = 0; + #endif + return 0; } #elif defined(FREESCALE_LTC) @@ -1912,7 +1916,8 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) aes->rounds = keylen/4 + 6; XMEMCPY(aes->key, userKey, keylen); - #ifdef WOLFSSL_AES_COUNTER + + #if defined(HAVE_AES_CFB) || defined(WOLFSSL_AES_COUNTER) aes->left = 0; #endif @@ -1939,10 +1944,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) if (rk == NULL) return BAD_FUNC_ARG; - #ifdef WOLFSSL_AES_COUNTER + #if defined(HAVE_AES_CFB) || defined(WOLFSSL_AES_COUNTER) aes->left = 0; #endif - aes->keylen = keylen; + aes->rounds = keylen/4 + 6; ret = wolfSSL_CryptHwMutexLock(); @@ -1982,6 +1987,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) aes->rounds = keylen/4 + 6; ret = nrf51_aes_set_key(userKey); + #if defined(HAVE_AES_CFB) || defined(WOLFSSL_AES_COUNTER) + aes->left = 0; + #endif + return ret; } @@ -2004,12 +2013,12 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) unsigned int i = 0; #endif - #ifdef WOLFSSL_AESNI - aes->use_aesni = 0; - #endif /* WOLFSSL_AESNI */ - #ifdef WOLFSSL_AES_COUNTER - aes->left = 0; - #endif /* WOLFSSL_AES_COUNTER */ + #ifdef WOLFSSL_AESNI + aes->use_aesni = 0; + #endif /* WOLFSSL_AESNI */ + #if defined(HAVE_AES_CFB) || defined(WOLFSSL_AES_COUNTER) + aes->left = 0; + #endif aes->keylen = keylen; aes->rounds = (keylen/4) + 6; @@ -3053,7 +3062,8 @@ int wc_AesSetIV(Aes* aes, const byte* iv) /* CFB 128 */ int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { - word32 blocks = sz / AES_BLOCK_SIZE; + byte* reg = NULL; + byte* tmp; WOLFSSL_ENTER("wc_AesCfbEncrypt"); @@ -3061,12 +3071,39 @@ int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) return BAD_FUNC_ARG; } - while (blocks--) { + if (aes->left && sz) { + reg = (byte*)aes->reg + AES_BLOCK_SIZE - aes->left; + } + + /* consume any unused bytes left in aes->tmp */ + tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left; + while (aes->left && sz) { + *(out++) = *(reg++) = *(in++) ^ *(tmp++); + aes->left--; + sz--; + } + + while (sz >= AES_BLOCK_SIZE) { wc_AesEncrypt(aes, (byte*)aes->reg, out); xorbuf(out, in, AES_BLOCK_SIZE); XMEMCPY(aes->reg, out, AES_BLOCK_SIZE); out += AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; + sz -= AES_BLOCK_SIZE; + aes->left = 0; + } + + /* encrypt left over data */ + if (sz) { + wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp); + aes->left = AES_BLOCK_SIZE; + tmp = (byte*)aes->tmp; + reg = (byte*)aes->reg; + + while (sz--) { + *(out++) = *(reg++) = *(in++) ^ *(tmp++); + aes->left--; + } } return 0; @@ -3076,7 +3113,7 @@ int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) #ifdef HAVE_AES_DECRYPT int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) { - word32 blocks = sz / AES_BLOCK_SIZE; + byte* tmp; WOLFSSL_ENTER("wc_AesCfbDecrypt"); @@ -3084,12 +3121,41 @@ int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) return BAD_FUNC_ARG; } - while (blocks--) { + /* check if more input needs copied over to aes->reg */ + if (aes->left && sz) { + int size = min(aes->left, sz); + XMEMCPY((byte*)aes->reg + AES_BLOCK_SIZE - aes->left, in, size); + } + + /* consume any unused bytes left in aes->tmp */ + tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left; + while (aes->left && sz) { + *(out++) = *(in++) ^ *(tmp++); + aes->left--; + sz--; + } + + while (sz > AES_BLOCK_SIZE) { wc_AesEncrypt(aes, (byte*)aes->reg, out); xorbuf(out, in, AES_BLOCK_SIZE); XMEMCPY(aes->reg, in, AES_BLOCK_SIZE); out += AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; + sz -= AES_BLOCK_SIZE; + aes->left = 0; + } + + /* decrypt left over data */ + if (sz) { + wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp); + XMEMCPY(aes->reg, in, sz); + aes->left = AES_BLOCK_SIZE; + tmp = (byte*)aes->tmp; + + while (sz--) { + *(out++) = *(in++) ^ *(tmp++); + aes->left--; + } } return 0; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index b03466d88..9271d6398 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -4454,21 +4454,56 @@ int des3_test(void) return -1118; #endif + /* test with data left overs, magic lengths are checking near edges */ XMEMSET(cipher, 0, sizeof(cipher)); - ret = wc_AesCfbEncrypt(&enc, cipher, msg3, AES_BLOCK_SIZE * 4); + ret = wc_AesCfbEncrypt(&enc, cipher, msg3, 4); if (ret != 0) return -1119; - if (XMEMCMP(cipher, cipher3, AES_BLOCK_SIZE * 4)) + if (XMEMCMP(cipher, cipher3, 4)) return -1120; - #ifdef HAVE_AES_DECRYPT - ret = wc_AesCfbDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE * 4); + ret = wc_AesCfbEncrypt(&enc, cipher + 4, msg3 + 4, 27); if (ret != 0) return -1121; - if (XMEMCMP(plain, msg3, AES_BLOCK_SIZE * 4)) + if (XMEMCMP(cipher + 4, cipher3 + 4, 27)) return -1122; + + ret = wc_AesCfbEncrypt(&enc, cipher + 31, msg3 + 31, + (AES_BLOCK_SIZE * 4) - 31); + if (ret != 0) + return -1123; + + if (XMEMCMP(cipher, cipher3, AES_BLOCK_SIZE * 4)) + return -1124; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesCfbDecrypt(&dec, plain, cipher, 4); + if (ret != 0) + return -1125; + + if (XMEMCMP(plain, msg3, 4)) + return -1126; + + ret = wc_AesCfbDecrypt(&dec, plain + 4, cipher + 4, 4); + if (ret != 0) + return -1127; + + ret = wc_AesCfbDecrypt(&dec, plain + 8, cipher + 8, 23); + if (ret != 0) + return -1128; + + if (XMEMCMP(plain + 4, msg3 + 4, 27)) + return -1129; + + ret = wc_AesCfbDecrypt(&dec, plain + 31, cipher + 31, + (AES_BLOCK_SIZE * 4) - 31); + if (ret != 0) + return -1130; + + if (XMEMCMP(plain, msg3, AES_BLOCK_SIZE * 4)) + return -1131; #endif /* HAVE_AES_DECRYPT */ return ret; diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index aaafc9c5a..a39c4ffb2 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -97,7 +97,7 @@ typedef struct Aes { word32 asyncIv[AES_BLOCK_SIZE/sizeof(word32)]; /* raw IV */ WC_ASYNC_DEV asyncDev; #endif /* WOLFSSL_ASYNC_CRYPT */ -#ifdef WOLFSSL_AES_COUNTER +#if defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AES_CFB) word32 left; /* unused bytes left from last call */ #endif #ifdef WOLFSSL_XILINX_CRYPT