mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 19:54:40 +02:00
update CFB mode to handle partial AES block sizes
This commit is contained in:
@@ -1828,7 +1828,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
|||||||
#ifndef WOLFSSL_STM32_CUBEMX
|
#ifndef WOLFSSL_STM32_CUBEMX
|
||||||
ByteReverseWords(rk, rk, keylen);
|
ByteReverseWords(rk, rk, keylen);
|
||||||
#endif
|
#endif
|
||||||
#ifdef WOLFSSL_AES_COUNTER
|
#if defined(HAVE_AES_CFB) || defined(WOLFSSL_AES_COUNTER)
|
||||||
aes->left = 0;
|
aes->left = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1901,6 +1901,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
|||||||
if (iv)
|
if (iv)
|
||||||
XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
|
XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
#if defined(HAVE_AES_CFB) || defined(WOLFSSL_AES_COUNTER)
|
||||||
|
aes->left = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#elif defined(FREESCALE_LTC)
|
#elif defined(FREESCALE_LTC)
|
||||||
@@ -1912,7 +1916,8 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
|||||||
|
|
||||||
aes->rounds = keylen/4 + 6;
|
aes->rounds = keylen/4 + 6;
|
||||||
XMEMCPY(aes->key, userKey, keylen);
|
XMEMCPY(aes->key, userKey, keylen);
|
||||||
#ifdef WOLFSSL_AES_COUNTER
|
|
||||||
|
#if defined(HAVE_AES_CFB) || defined(WOLFSSL_AES_COUNTER)
|
||||||
aes->left = 0;
|
aes->left = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1939,10 +1944,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
|||||||
if (rk == NULL)
|
if (rk == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
#ifdef WOLFSSL_AES_COUNTER
|
#if defined(HAVE_AES_CFB) || defined(WOLFSSL_AES_COUNTER)
|
||||||
aes->left = 0;
|
aes->left = 0;
|
||||||
#endif
|
#endif
|
||||||
aes->keylen = keylen;
|
|
||||||
aes->rounds = keylen/4 + 6;
|
aes->rounds = keylen/4 + 6;
|
||||||
|
|
||||||
ret = wolfSSL_CryptHwMutexLock();
|
ret = wolfSSL_CryptHwMutexLock();
|
||||||
@@ -1982,6 +1987,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
|||||||
aes->rounds = keylen/4 + 6;
|
aes->rounds = keylen/4 + 6;
|
||||||
ret = nrf51_aes_set_key(userKey);
|
ret = nrf51_aes_set_key(userKey);
|
||||||
|
|
||||||
|
#if defined(HAVE_AES_CFB) || defined(WOLFSSL_AES_COUNTER)
|
||||||
|
aes->left = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2004,12 +2013,12 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
|||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_AESNI
|
#ifdef WOLFSSL_AESNI
|
||||||
aes->use_aesni = 0;
|
aes->use_aesni = 0;
|
||||||
#endif /* WOLFSSL_AESNI */
|
#endif /* WOLFSSL_AESNI */
|
||||||
#ifdef WOLFSSL_AES_COUNTER
|
#if defined(HAVE_AES_CFB) || defined(WOLFSSL_AES_COUNTER)
|
||||||
aes->left = 0;
|
aes->left = 0;
|
||||||
#endif /* WOLFSSL_AES_COUNTER */
|
#endif
|
||||||
|
|
||||||
aes->keylen = keylen;
|
aes->keylen = keylen;
|
||||||
aes->rounds = (keylen/4) + 6;
|
aes->rounds = (keylen/4) + 6;
|
||||||
@@ -3053,7 +3062,8 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
|
|||||||
/* CFB 128 */
|
/* CFB 128 */
|
||||||
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
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");
|
WOLFSSL_ENTER("wc_AesCfbEncrypt");
|
||||||
|
|
||||||
@@ -3061,12 +3071,39 @@ int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
|||||||
return BAD_FUNC_ARG;
|
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);
|
wc_AesEncrypt(aes, (byte*)aes->reg, out);
|
||||||
xorbuf(out, in, AES_BLOCK_SIZE);
|
xorbuf(out, in, AES_BLOCK_SIZE);
|
||||||
XMEMCPY(aes->reg, out, AES_BLOCK_SIZE);
|
XMEMCPY(aes->reg, out, AES_BLOCK_SIZE);
|
||||||
out += AES_BLOCK_SIZE;
|
out += AES_BLOCK_SIZE;
|
||||||
in += 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;
|
return 0;
|
||||||
@@ -3076,7 +3113,7 @@ int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
|||||||
#ifdef HAVE_AES_DECRYPT
|
#ifdef HAVE_AES_DECRYPT
|
||||||
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||||
{
|
{
|
||||||
word32 blocks = sz / AES_BLOCK_SIZE;
|
byte* tmp;
|
||||||
|
|
||||||
WOLFSSL_ENTER("wc_AesCfbDecrypt");
|
WOLFSSL_ENTER("wc_AesCfbDecrypt");
|
||||||
|
|
||||||
@@ -3084,12 +3121,41 @@ int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
|||||||
return BAD_FUNC_ARG;
|
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);
|
wc_AesEncrypt(aes, (byte*)aes->reg, out);
|
||||||
xorbuf(out, in, AES_BLOCK_SIZE);
|
xorbuf(out, in, AES_BLOCK_SIZE);
|
||||||
XMEMCPY(aes->reg, in, AES_BLOCK_SIZE);
|
XMEMCPY(aes->reg, in, AES_BLOCK_SIZE);
|
||||||
out += AES_BLOCK_SIZE;
|
out += AES_BLOCK_SIZE;
|
||||||
in += 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;
|
return 0;
|
||||||
|
@@ -4454,21 +4454,56 @@ int des3_test(void)
|
|||||||
return -1118;
|
return -1118;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* test with data left overs, magic lengths are checking near edges */
|
||||||
XMEMSET(cipher, 0, sizeof(cipher));
|
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)
|
if (ret != 0)
|
||||||
return -1119;
|
return -1119;
|
||||||
|
|
||||||
if (XMEMCMP(cipher, cipher3, AES_BLOCK_SIZE * 4))
|
if (XMEMCMP(cipher, cipher3, 4))
|
||||||
return -1120;
|
return -1120;
|
||||||
|
|
||||||
#ifdef HAVE_AES_DECRYPT
|
ret = wc_AesCfbEncrypt(&enc, cipher + 4, msg3 + 4, 27);
|
||||||
ret = wc_AesCfbDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE * 4);
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return -1121;
|
return -1121;
|
||||||
|
|
||||||
if (XMEMCMP(plain, msg3, AES_BLOCK_SIZE * 4))
|
if (XMEMCMP(cipher + 4, cipher3 + 4, 27))
|
||||||
return -1122;
|
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 */
|
#endif /* HAVE_AES_DECRYPT */
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@@ -97,7 +97,7 @@ typedef struct Aes {
|
|||||||
word32 asyncIv[AES_BLOCK_SIZE/sizeof(word32)]; /* raw IV */
|
word32 asyncIv[AES_BLOCK_SIZE/sizeof(word32)]; /* raw IV */
|
||||||
WC_ASYNC_DEV asyncDev;
|
WC_ASYNC_DEV asyncDev;
|
||||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
#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 */
|
word32 left; /* unused bytes left from last call */
|
||||||
#endif
|
#endif
|
||||||
#ifdef WOLFSSL_XILINX_CRYPT
|
#ifdef WOLFSSL_XILINX_CRYPT
|
||||||
|
Reference in New Issue
Block a user