forked from wolfSSL/wolfssl
initial cfb1/cfb8 support added
This commit is contained in:
committed by
Eric Blankenhorn
parent
9c4e0807e2
commit
9d61ba6c62
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
||||
|
@@ -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 */
|
||||
|
||||
|
Reference in New Issue
Block a user