initial cfb1/cfb8 support added

This commit is contained in:
Jacob Barthelmeh
2020-01-29 09:59:51 -07:00
committed by Eric Blankenhorn
parent 9c4e0807e2
commit 9d61ba6c62
3 changed files with 355 additions and 1 deletions

View File

@@ -7476,6 +7476,196 @@ int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_CFB_MODE);
}
#endif /* HAVE_AES_DECRYPT */
/* shift the whole AES_BLOCK_SIZE array left by 8 or 1 bits */
static void shiftLeftArray(byte* ary, byte shift)
{
int i;
if (shift == WOLFSSL_BIT_SIZE) {
/* shifting over by 8 bits */
for (i = 0; i < AES_BLOCK_SIZE - 1; i++) {
ary[i] = ary[i+1];
}
ary[i] = 0;
}
else {
byte carry = 0;
/* shifting over by 7 or less bits */
for (i = 0; i < AES_BLOCK_SIZE - 1; i++) {
carry = ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift));
carry >>= (WOLFSSL_BIT_SIZE - shift);
ary[i] = (ary[i] << shift) + carry;
}
ary[i] = ary[i] << shift;
}
}
/* returns 0 on success and negative values on failure */
static int wc_AesFeedbackCFB8(Aes* aes, byte* out, const byte* in,
word32 sz, byte dir)
{
byte *pt;
if (aes == NULL || out == NULL || in == NULL) {
return BAD_FUNC_ARG;
}
while (sz > 0) {
wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
if (dir == AES_DECRYPTION) {
pt = (byte*)aes->reg;
/* LSB + CAT */
shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
pt[AES_BLOCK_SIZE - 1] = in[0];
}
/* MSB + XOR */
out[0] = aes->tmp[0] ^ in[0];
if (dir == AES_ENCRYPTION) {
pt = (byte*)aes->reg;
/* LSB + CAT */
shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
pt[AES_BLOCK_SIZE - 1] = out[0];
}
out += 1;
in += 1;
sz -= 1;
}
return 0;
}
/* returns 0 on success and negative values on failure */
static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in,
word32 sz, byte dir)
{
byte tmp;
byte* pt;
int bit = 7;
if (aes == NULL || out == NULL || in == NULL) {
return BAD_FUNC_ARG;
}
out[0] = 0;
while (sz > 0) {
wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
if (dir == AES_DECRYPTION) {
pt = (byte*)aes->reg;
/* LSB + CAT */
tmp = (0X01 << bit) & in[0];
tmp = tmp >> bit;
shiftLeftArray((byte*)aes->reg, 1);
pt[AES_BLOCK_SIZE - 1] |= tmp;
}
/* MSB + XOR */
tmp = (0X01 << bit) & in[0];
pt = (byte*)aes->tmp;
tmp = pt[0] ^ (tmp >> bit);
tmp &= 0x01;
out[0] |= (tmp << bit);
if (dir == AES_ENCRYPTION) {
pt = (byte*)aes->reg;
/* LSB + CAT */
shiftLeftArray((byte*)aes->reg, 1);
pt[AES_BLOCK_SIZE - 1] |= tmp;
}
bit--;
if (bit < 0) {
out += 1;
in += 1;
sz -= 1;
bit = 7;
if (sz > 0) {
out[0] = 0;
}
}
else {
sz -= 1;
}
}
return 0;
}
/* CFB 1
*
* aes structure holding key to use for encryption
* out buffer to hold result of encryption (must be at least as large as input
* buffer)
* in buffer to encrypt
* sz size of input buffer
*
* returns 0 on success and negative values on failure
*/
int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
}
/* CFB 8
*
* aes structure holding key to use for encryption
* out buffer to hold result of encryption (must be at least as large as input
* buffer)
* in buffer to encrypt
* sz size of input buffer
*
* returns 0 on success and negative values on failure
*/
int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
}
#ifdef HAVE_AES_DECRYPT
/* CFB 1
*
* aes structure holding key to use for encryption
* out buffer to hold result of encryption (must be at least as large as input
* buffer)
* in buffer to encrypt
* sz size of input buffer
*
* returns 0 on success and negative values on failure
*/
int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
}
/* CFB 8
*
* aes structure holding key to use for encryption
* out buffer to hold result of encryption (must be at least as large as input
* buffer)
* in buffer to encrypt
* sz size of input buffer
*
* returns 0 on success and negative values on failure
*/
int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
}
#endif /* HAVE_AES_DECRYPT */
#endif /* WOLFSSL_AES_CFB */
#ifdef WOLFSSL_AES_OFB
@@ -7513,7 +7703,7 @@ int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_OFB_MODE);
}
#endif /* HAVE_AES_DECRYPT */
#endif /* WOLFSSL_AES_CFB */
#endif /* WOLFSSL_AES_OFB */
#ifdef HAVE_AES_KEYWRAP

View File

@@ -5863,8 +5863,156 @@ int des3_test(void)
return ret;
}
static int aescfb1_test(void)
{
Aes enc;
byte cipher[AES_BLOCK_SIZE];
#ifdef HAVE_AES_DECRYPT
Aes dec;
byte plain [AES_BLOCK_SIZE];
#endif
int ret = 0;
const byte iv[] = {
0x4d,0xbb,0xdc,0xaa,0x59,0xf3,0x63,0xc9,
0x2a,0x3b,0x98,0x43,0xad,0x20,0xe2,0xb7
};
#ifdef WOLFSSL_AES_128
const byte key1[] =
{
0xcd,0xef,0x9d,0x06,0x61,0xba,0xe4,0x73,
0x8d,0x1a,0x58,0xa2,0xa6,0x22,0x8b,0x66
};
const byte cipher1[] =
{
0x00
};
const byte msg1[] =
{
0xC0
};
#endif /* WOLFSSL_AES_128 */
if (wc_AesInit(&enc, HEAP_HINT, devId) != 0)
return -4739;
#ifdef HAVE_AES_DECRYPT
if (wc_AesInit(&dec, HEAP_HINT, devId) != 0)
return -4740;
#endif
#ifdef WOLFSSL_AES_128
/* 128 key tests */
ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION);
if (ret != 0)
return -4741;
#ifdef HAVE_AES_DECRYPT
/* decrypt uses AES_ENCRYPTION */
ret = wc_AesSetKey(&dec, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION);
if (ret != 0)
return -4742;
#endif
XMEMSET(cipher, 0, sizeof(cipher));
ret = wc_AesCfb1Encrypt(&enc, cipher, msg1, 2);
if (ret != 0)
return -4743;
if (cipher[0] != cipher1[0])
return -4744;
#ifdef HAVE_AES_DECRYPT
ret = wc_AesCfb1Decrypt(&dec, plain, cipher, 2);
if (ret != 0)
return -4745;
if (plain[0] != msg1[0])
return -4746;
#endif /* HAVE_AES_DECRYPT */
#endif /* WOLFSSL_AES_128 */
return ret;
}
static int aescfb8_test(void)
{
Aes enc;
byte cipher[AES_BLOCK_SIZE];
#ifdef HAVE_AES_DECRYPT
Aes dec;
byte plain [AES_BLOCK_SIZE];
#endif
int ret = 0;
const byte iv[] = {
0xf4,0x75,0xc6,0x49,0x91,0xb2,0x0e,0xae,
0xe1,0x83,0xa2,0x26,0x29,0xe2,0x1e,0x22
};
#ifdef WOLFSSL_AES_128
const byte key1[] =
{
0xc8,0xfe,0x9b,0xf7,0x7b,0x93,0x0f,0x46,
0xd2,0x07,0x8b,0x8c,0x0e,0x65,0x7c,0xd4
};
const byte cipher1[] =
{
0xd2,0x76,0x91
};
const byte msg1[] =
{
0xc9,0x06,0x35
};
#endif /* WOLFSSL_AES_128 */
if (wc_AesInit(&enc, HEAP_HINT, devId) != 0)
return -4739;
#ifdef HAVE_AES_DECRYPT
if (wc_AesInit(&dec, HEAP_HINT, devId) != 0)
return -4740;
#endif
#ifdef WOLFSSL_AES_128
/* 128 key tests */
ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION);
if (ret != 0)
return -4741;
#ifdef HAVE_AES_DECRYPT
/* decrypt uses AES_ENCRYPTION */
ret = wc_AesSetKey(&dec, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION);
if (ret != 0)
return -4742;
#endif
XMEMSET(cipher, 0, sizeof(cipher));
ret = wc_AesCfb8Encrypt(&enc, cipher, msg1, sizeof(msg1));
if (ret != 0)
return -4743;
if (XMEMCMP(cipher, cipher1, sizeof(cipher1)) != 0)
return -4744;
#ifdef HAVE_AES_DECRYPT
ret = wc_AesCfb8Decrypt(&dec, plain, cipher, sizeof(msg1));
if (ret != 0)
return -4745;
if (XMEMCMP(plain, msg1, sizeof(msg1)) != 0)
return -4746;
#endif /* HAVE_AES_DECRYPT */
#endif /* WOLFSSL_AES_128 */
return ret;
}
#endif /* WOLFSSL_AES_CFB */
#ifdef WOLFSSL_AES_OFB
#ifdef OPENSSL_EXTRA
/* pass in the function, key, iv, plain text and expected and this function
@@ -7476,6 +7624,14 @@ int aes_test(void)
ret = aescfb_test();
if (ret != 0)
return ret;
ret = aescfb1_test();
if (ret != 0)
return ret;
ret = aescfb8_test();
if (ret != 0)
return ret;
#endif

View File

@@ -277,9 +277,17 @@ WOLFSSL_API int wc_AesCbcDecrypt(Aes* aes, byte* out,
#ifdef WOLFSSL_AES_CFB
WOLFSSL_API int wc_AesCfbEncrypt(Aes* aes, byte* out,
const byte* in, word32 sz);
WOLFSSL_API int wc_AesCfb1Encrypt(Aes* aes, byte* out,
const byte* in, word32 sz);
WOLFSSL_API int wc_AesCfb8Encrypt(Aes* aes, byte* out,
const byte* in, word32 sz);
#ifdef HAVE_AES_DECRYPT
WOLFSSL_API int wc_AesCfbDecrypt(Aes* aes, byte* out,
const byte* in, word32 sz);
WOLFSSL_API int wc_AesCfb1Decrypt(Aes* aes, byte* out,
const byte* in, word32 sz);
WOLFSSL_API int wc_AesCfb8Decrypt(Aes* aes, byte* out,
const byte* in, word32 sz);
#endif /* HAVE_AES_DECRYPT */
#endif /* WOLFSSL_AES_CFB */