update CFB mode to handle partial AES block sizes

This commit is contained in:
Jacob Barthelmeh
2017-03-03 16:51:57 -07:00
parent c2a6c6c395
commit 953fc0d4a8
3 changed files with 121 additions and 20 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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