mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-01 19:54:40 +02:00
add CFB mode for AES
This commit is contained in:
@@ -143,6 +143,7 @@
|
||||
#define BENCH_CHACHA20_POLY1305 0x00002000
|
||||
#define BENCH_DES 0x00004000
|
||||
#define BENCH_IDEA 0x00008000
|
||||
#define BENCH_AES_CFB 0x00010000
|
||||
/* Digest algorithms. */
|
||||
#define BENCH_MD5 0x00000001
|
||||
#define BENCH_POLY1305 0x00000002
|
||||
@@ -231,6 +232,9 @@ static const bench_alg bench_cipher_opt[] = {
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
{ "-aes-xts", BENCH_AES_XTS },
|
||||
#endif
|
||||
#ifdef HAVE_AES_CFB
|
||||
{ "-aes-cfb", BENCH_AES_CFB },
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
{ "-aes-ctr", BENCH_AES_CTR },
|
||||
#endif
|
||||
@@ -1077,6 +1081,10 @@ static void* benchmarks_do(void* args)
|
||||
if (bench_all || (bench_cipher_algs & BENCH_AES_XTS))
|
||||
bench_aesxts();
|
||||
#endif
|
||||
#ifdef HAVE_AES_CFB
|
||||
if (bench_all || (bench_cipher_algs & BENCH_AES_CFB))
|
||||
bench_aescfb();
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
if (bench_all || (bench_cipher_algs & BENCH_AES_CTR))
|
||||
bench_aesctr();
|
||||
@@ -1904,9 +1912,44 @@ void bench_aesecb(int doAsync)
|
||||
bench_aesecb_internal(doAsync, bench_key, 32,
|
||||
"AES-256-ECB-enc", "AES-256-ECB-dec");
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_AES_DIRECT */
|
||||
|
||||
#ifdef HAVE_AES_CFB
|
||||
static void bench_aescfb_internal(const byte* key, word32 keySz, const byte* iv,
|
||||
const char* label)
|
||||
{
|
||||
Aes enc;
|
||||
double start;
|
||||
int i, ret, count;
|
||||
|
||||
ret = wc_AesSetKey(&enc, key, keySz, iv, AES_ENCRYPTION);
|
||||
if (ret != 0) {
|
||||
printf("AesSetKey failed, ret = %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
for (i = 0; i < numBlocks; i++) {
|
||||
if((ret = wc_AesCfbEncrypt(&enc, bench_plain, bench_cipher,
|
||||
BENCH_SIZE)) != 0) {
|
||||
printf("wc_AesCfbEncrypt failed, ret = %d\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
count += i;
|
||||
} while (bench_stats_sym_check(start));
|
||||
bench_stats_sym_finish(label, 0, count, bench_size, start, ret);
|
||||
}
|
||||
|
||||
void bench_aescfb(void)
|
||||
{
|
||||
bench_aescfb_internal(bench_key, 16, bench_iv, "AES-128-CFB");
|
||||
bench_aescfb_internal(bench_key, 24, bench_iv, "AES-192-CFB");
|
||||
bench_aescfb_internal(bench_key, 32, bench_iv, "AES-256-CFB");
|
||||
}
|
||||
#endif /* HAVE_AES_CFB */
|
||||
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
void bench_aesxts(void)
|
||||
|
@@ -53,6 +53,7 @@ void bench_aesccm(void);
|
||||
void bench_aesecb(int);
|
||||
void bench_aesxts(void);
|
||||
void bench_aesctr(void);
|
||||
void bench_aescfb(void);
|
||||
void bench_poly1305(void);
|
||||
void bench_camellia(void);
|
||||
void bench_md5(int);
|
||||
|
@@ -3049,6 +3049,54 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
|
||||
#endif /* AES-CBC block */
|
||||
#endif /* HAVE_AES_CBC */
|
||||
|
||||
#ifdef HAVE_AES_CFB
|
||||
/* CFB 128 */
|
||||
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
{
|
||||
word32 blocks = sz / AES_BLOCK_SIZE;
|
||||
|
||||
WOLFSSL_ENTER("wc_AesCfbEncrypt");
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
while (blocks--) {
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_AES_DECRYPT
|
||||
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
{
|
||||
word32 blocks = sz / AES_BLOCK_SIZE;
|
||||
|
||||
WOLFSSL_ENTER("wc_AesCfbDecrypt");
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
while (blocks--) {
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
#endif /* HAVE_AES_CFB */
|
||||
|
||||
#ifdef HAVE_AES_ECB
|
||||
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES)
|
||||
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||
|
@@ -4267,6 +4267,214 @@ int des3_test(void)
|
||||
|
||||
|
||||
#ifndef NO_AES
|
||||
#ifdef HAVE_AES_CFB
|
||||
/* Test cases from NIST SP 800-38A, Recommendation for Block Cipher Modes of Operation Methods an*/
|
||||
static int aescfb_test(void)
|
||||
{
|
||||
Aes enc;
|
||||
byte cipher[AES_BLOCK_SIZE * 4];
|
||||
#ifdef HAVE_AES_DECRYPT
|
||||
Aes dec;
|
||||
byte plain [AES_BLOCK_SIZE * 4];
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
const byte iv[] = {
|
||||
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
|
||||
};
|
||||
|
||||
const byte key1[] =
|
||||
{
|
||||
0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,
|
||||
0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c
|
||||
};
|
||||
|
||||
const byte cipher1[] =
|
||||
{
|
||||
0x3b,0x3f,0xd9,0x2e,0xb7,0x2d,0xad,0x20,
|
||||
0x33,0x34,0x49,0xf8,0xe8,0x3c,0xfb,0x4a,
|
||||
0xc8,0xa6,0x45,0x37,0xa0,0xb3,0xa9,0x3f,
|
||||
0xcd,0xe3,0xcd,0xad,0x9f,0x1c,0xe5,0x8b,
|
||||
0x26,0x75,0x1f,0x67,0xa3,0xcb,0xb1,0x40,
|
||||
0xb1,0x80,0x8c,0xf1,0x87,0xa4,0xf4,0xdf
|
||||
};
|
||||
|
||||
const byte msg1[] =
|
||||
{
|
||||
0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,
|
||||
0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,
|
||||
0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,
|
||||
0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51,
|
||||
0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11,
|
||||
0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef
|
||||
};
|
||||
|
||||
/* 192 size key test */
|
||||
const byte key2[] =
|
||||
{
|
||||
0x8e,0x73,0xb0,0xf7,0xda,0x0e,0x64,0x52,
|
||||
0xc8,0x10,0xf3,0x2b,0x80,0x90,0x79,0xe5,
|
||||
0x62,0xf8,0xea,0xd2,0x52,0x2c,0x6b,0x7b
|
||||
};
|
||||
|
||||
const byte cipher2[] =
|
||||
{
|
||||
0xcd,0xc8,0x0d,0x6f,0xdd,0xf1,0x8c,0xab,
|
||||
0x34,0xc2,0x59,0x09,0xc9,0x9a,0x41,0x74,
|
||||
0x67,0xce,0x7f,0x7f,0x81,0x17,0x36,0x21,
|
||||
0x96,0x1a,0x2b,0x70,0x17,0x1d,0x3d,0x7a,
|
||||
0x2e,0x1e,0x8a,0x1d,0xd5,0x9b,0x88,0xb1,
|
||||
0xc8,0xe6,0x0f,0xed,0x1e,0xfa,0xc4,0xc9,
|
||||
0xc0,0x5f,0x9f,0x9c,0xa9,0x83,0x4f,0xa0,
|
||||
0x42,0xae,0x8f,0xba,0x58,0x4b,0x09,0xff
|
||||
};
|
||||
|
||||
const byte msg2[] =
|
||||
{
|
||||
0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,
|
||||
0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,
|
||||
0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,
|
||||
0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51,
|
||||
0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11,
|
||||
0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef,
|
||||
0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17,
|
||||
0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10
|
||||
};
|
||||
|
||||
/* 256 size key simple test */
|
||||
const byte key3[] =
|
||||
{
|
||||
0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,
|
||||
0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,
|
||||
0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,
|
||||
0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4
|
||||
};
|
||||
|
||||
const byte cipher3[] =
|
||||
{
|
||||
0xdc,0x7e,0x84,0xbf,0xda,0x79,0x16,0x4b,
|
||||
0x7e,0xcd,0x84,0x86,0x98,0x5d,0x38,0x60,
|
||||
0x39,0xff,0xed,0x14,0x3b,0x28,0xb1,0xc8,
|
||||
0x32,0x11,0x3c,0x63,0x31,0xe5,0x40,0x7b,
|
||||
0xdf,0x10,0x13,0x24,0x15,0xe5,0x4b,0x92,
|
||||
0xa1,0x3e,0xd0,0xa8,0x26,0x7a,0xe2,0xf9,
|
||||
0x75,0xa3,0x85,0x74,0x1a,0xb9,0xce,0xf8,
|
||||
0x20,0x31,0x62,0x3d,0x55,0xb1,0xe4,0x71
|
||||
};
|
||||
|
||||
const byte msg3[] =
|
||||
{
|
||||
0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,
|
||||
0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,
|
||||
0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,
|
||||
0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51,
|
||||
0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11,
|
||||
0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef,
|
||||
0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17,
|
||||
0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10
|
||||
};
|
||||
|
||||
|
||||
/* 128 key tests */
|
||||
ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION);
|
||||
if (ret != 0)
|
||||
return -1101;
|
||||
#ifdef HAVE_AES_DECRYPT
|
||||
/* decrypt uses AES_ENCRYPTION */
|
||||
ret = wc_AesSetKey(&dec, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION);
|
||||
if (ret != 0)
|
||||
return -1102;
|
||||
#endif
|
||||
|
||||
XMEMSET(cipher, 0, sizeof(cipher));
|
||||
ret = wc_AesCfbEncrypt(&enc, cipher, msg1, AES_BLOCK_SIZE * 2);
|
||||
if (ret != 0)
|
||||
return -1105;
|
||||
|
||||
if (XMEMCMP(cipher, cipher1, AES_BLOCK_SIZE * 2))
|
||||
return -1106;
|
||||
|
||||
/* test restarting encryption process */
|
||||
ret = wc_AesCfbEncrypt(&enc, cipher + (AES_BLOCK_SIZE * 2),
|
||||
msg1 + (AES_BLOCK_SIZE * 2), AES_BLOCK_SIZE);
|
||||
if (ret != 0)
|
||||
return -1107;
|
||||
|
||||
if (XMEMCMP(cipher + (AES_BLOCK_SIZE * 2),
|
||||
cipher1 + (AES_BLOCK_SIZE * 2), AES_BLOCK_SIZE))
|
||||
return -1108;
|
||||
|
||||
#ifdef HAVE_AES_DECRYPT
|
||||
ret = wc_AesCfbDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE * 3);
|
||||
if (ret != 0)
|
||||
return -1109;
|
||||
|
||||
if (XMEMCMP(plain, msg1, AES_BLOCK_SIZE * 3))
|
||||
return -1110;
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
|
||||
/* 192 key size test */
|
||||
ret = wc_AesSetKey(&enc, key2, sizeof(key2), iv, AES_ENCRYPTION);
|
||||
if (ret != 0)
|
||||
return -1111;
|
||||
#ifdef HAVE_AES_DECRYPT
|
||||
/* decrypt uses AES_ENCRYPTION */
|
||||
ret = wc_AesSetKey(&dec, key2, sizeof(key2), iv, AES_ENCRYPTION);
|
||||
if (ret != 0)
|
||||
return -1112;
|
||||
#endif
|
||||
|
||||
XMEMSET(cipher, 0, sizeof(cipher));
|
||||
ret = wc_AesCfbEncrypt(&enc, cipher, msg2, AES_BLOCK_SIZE * 4);
|
||||
if (ret != 0)
|
||||
return -1113;
|
||||
|
||||
if (XMEMCMP(cipher, cipher2, AES_BLOCK_SIZE * 4))
|
||||
return -1114;
|
||||
|
||||
#ifdef HAVE_AES_DECRYPT
|
||||
ret = wc_AesCfbDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE * 4);
|
||||
if (ret != 0)
|
||||
return -1115;
|
||||
|
||||
if (XMEMCMP(plain, msg2, AES_BLOCK_SIZE * 4))
|
||||
return -1116;
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
|
||||
|
||||
/* 256 key size test */
|
||||
ret = wc_AesSetKey(&enc, key3, sizeof(key3), iv, AES_ENCRYPTION);
|
||||
if (ret != 0)
|
||||
return -1117;
|
||||
#ifdef HAVE_AES_DECRYPT
|
||||
/* decrypt uses AES_ENCRYPTION */
|
||||
ret = wc_AesSetKey(&dec, key3, sizeof(key3), iv, AES_ENCRYPTION);
|
||||
if (ret != 0)
|
||||
return -1118;
|
||||
#endif
|
||||
|
||||
XMEMSET(cipher, 0, sizeof(cipher));
|
||||
ret = wc_AesCfbEncrypt(&enc, cipher, msg3, AES_BLOCK_SIZE * 4);
|
||||
if (ret != 0)
|
||||
return -1119;
|
||||
|
||||
if (XMEMCMP(cipher, cipher3, AES_BLOCK_SIZE * 4))
|
||||
return -1120;
|
||||
|
||||
#ifdef HAVE_AES_DECRYPT
|
||||
ret = wc_AesCfbDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE * 4);
|
||||
if (ret != 0)
|
||||
return -1121;
|
||||
|
||||
if (XMEMCMP(plain, msg3, AES_BLOCK_SIZE * 4))
|
||||
return -1122;
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_AES_CFB */
|
||||
|
||||
static int aes_key_size_test(void)
|
||||
{
|
||||
int ret;
|
||||
@@ -5404,6 +5612,12 @@ int aes192_test(void)
|
||||
|
||||
#endif /* HAVE_AES_CBC */
|
||||
|
||||
#if defined(HAVE_AES_CFB)
|
||||
ret = aescfb_test();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -145,6 +145,15 @@ WOLFSSL_API int wc_AesCbcEncrypt(Aes* aes, byte* out,
|
||||
WOLFSSL_API int wc_AesCbcDecrypt(Aes* aes, byte* out,
|
||||
const byte* in, word32 sz);
|
||||
|
||||
#ifdef HAVE_AES_CFB
|
||||
WOLFSSL_API int wc_AesCfbEncrypt(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);
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
#endif /* HAVE_AES_CFB */
|
||||
|
||||
#ifdef HAVE_AES_ECB
|
||||
WOLFSSL_API int wc_AesEcbEncrypt(Aes* aes, byte* out,
|
||||
const byte* in, word32 sz);
|
||||
|
Reference in New Issue
Block a user