forked from wolfSSL/wolfssl
add AES-XTS mode --enable-xts
This commit is contained in:
12
configure.ac
12
configure.ac
@@ -185,6 +185,7 @@ then
|
||||
enable_psk=yes
|
||||
enable_idea=yes
|
||||
enable_cmac=yes
|
||||
enable_xts=yes
|
||||
enable_webserver=yes
|
||||
enable_hc128=yes
|
||||
enable_rabbit=yes
|
||||
@@ -1749,6 +1750,17 @@ AS_IF([test "x$ENABLED_CMAC" = "xyes"],
|
||||
AM_CONDITIONAL([BUILD_CMAC], [test "x$ENABLED_CMAC" = "xyes"])
|
||||
|
||||
|
||||
# AES-XTS
|
||||
AC_ARG_ENABLE([xts],
|
||||
[AS_HELP_STRING([--enable-xts],[Enable XTS (default: disabled)])],
|
||||
[ ENABLED_XTS=$enableval ],
|
||||
[ ENABLED_XTS=no ]
|
||||
)
|
||||
|
||||
AS_IF([test "x$ENABLED_XTS" = "xyes"],
|
||||
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_XTS -DWOLFSSL_AES_DIRECT"])
|
||||
|
||||
|
||||
# Web Server Build
|
||||
AC_ARG_ENABLE([webserver],
|
||||
[AS_HELP_STRING([--enable-webserver],[Enable Web Server (default: disabled)])],
|
||||
|
@@ -718,6 +718,9 @@ static void* benchmarks_do(void* args)
|
||||
bench_aesgcm(1);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
bench_aesxts();
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
bench_aesctr();
|
||||
#endif
|
||||
@@ -1337,6 +1340,73 @@ exit:
|
||||
#endif /* HAVE_AESGCM */
|
||||
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
void bench_aesxts(void)
|
||||
{
|
||||
Aes aes, tweak;
|
||||
double start;
|
||||
int i, count, ret;
|
||||
|
||||
static unsigned char k1[] = {
|
||||
0xa1, 0xb9, 0x0c, 0xba, 0x3f, 0x06, 0xac, 0x35,
|
||||
0x3b, 0x2c, 0x34, 0x38, 0x76, 0x08, 0x17, 0x62,
|
||||
0x09, 0x09, 0x23, 0x02, 0x6e, 0x91, 0x77, 0x18,
|
||||
0x15, 0xf2, 0x9d, 0xab, 0x01, 0x93, 0x2f, 0x2f
|
||||
};
|
||||
|
||||
static unsigned char i1[] = {
|
||||
0x4f, 0xae, 0xf7, 0x11, 0x7c, 0xda, 0x59, 0xc6,
|
||||
0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5
|
||||
};
|
||||
|
||||
ret = wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId);
|
||||
if (ret != 0) {
|
||||
printf("wc_AesXtsSetKey failed, ret = %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
for (i = 0; i < numBlocks; i++) {
|
||||
if ((ret = wc_AesXtsEncrypt(&tweak, &aes, bench_plain, bench_cipher,
|
||||
BENCH_SIZE, i1, sizeof(i1))) != 0) {
|
||||
printf("wc_AesXtsEncrypt failed, ret = %d\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
count += i;
|
||||
} while (bench_stats_sym_check(start));
|
||||
bench_stats_sym_finish("AES-XTS-enc", 0, count, start, ret);
|
||||
wc_AesFree(&aes);
|
||||
wc_AesFree(&tweak);
|
||||
|
||||
/* decryption benchmark */
|
||||
ret = wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_DECRYPTION,
|
||||
HEAP_HINT, devId);
|
||||
if (ret != 0) {
|
||||
printf("wc_AesXtsSetKey failed, ret = %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
for (i = 0; i < numBlocks; i++) {
|
||||
if ((ret = wc_AesXtsDecrypt(&tweak, &aes, bench_plain, bench_cipher,
|
||||
BENCH_SIZE, i1, sizeof(i1))) != 0) {
|
||||
printf("wc_AesXtsDecrypt failed, ret = %d\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
count += i;
|
||||
} while (bench_stats_sym_check(start));
|
||||
bench_stats_sym_finish("AES-XTS-dec", 0, count, start, ret);
|
||||
wc_AesFree(&aes);
|
||||
wc_AesFree(&tweak);
|
||||
}
|
||||
#endif /* WOLFSSL_AES_XTS */
|
||||
|
||||
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
void bench_aesctr(void)
|
||||
{
|
||||
|
@@ -50,6 +50,7 @@ void bench_chacha20_poly1305_aead(void);
|
||||
void bench_aescbc(int);
|
||||
void bench_aesgcm(int);
|
||||
void bench_aesccm(void);
|
||||
void bench_aesxts(void);
|
||||
void bench_aesctr(void);
|
||||
void bench_poly1305(void);
|
||||
void bench_camellia(void);
|
||||
|
@@ -1794,6 +1794,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
||||
if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
aes->type = (byte)dir;
|
||||
#endif
|
||||
aes->keylen = keylen;
|
||||
aes->rounds = keylen/4 + 6;
|
||||
XMEMCPY(rk, userKey, keylen);
|
||||
@@ -1863,6 +1866,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
||||
if (aes == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
aes->type = (byte)dir;
|
||||
#endif
|
||||
aes->keylen = keylen;
|
||||
aes->rounds = keylen/4 + 6;
|
||||
XMEMCPY(aes->key, userKey, keylen);
|
||||
@@ -1882,6 +1888,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
||||
aes->rounds = keylen/4 + 6;
|
||||
XMEMCPY(aes->key, userKey, keylen);
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
aes->type = (byte)dir;
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
aes->left = 0;
|
||||
#endif /* WOLFSSL_AES_COUNTER */
|
||||
@@ -1909,6 +1918,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
||||
if (rk == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
aes->type = (byte)dir;
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
aes->left = 0;
|
||||
#endif /* WOLFSSL_AES_COUNTER */
|
||||
@@ -1949,6 +1961,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
||||
if (keylen != 16)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
aes->type = (byte)dir;
|
||||
#endif
|
||||
aes->keylen = keylen;
|
||||
aes->rounds = keylen/4 + 6;
|
||||
ret = nrf51_aes_set_key(userKey);
|
||||
@@ -1975,6 +1990,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
||||
#ifdef WOLFSSL_AESNI
|
||||
aes->use_aesni = 0;
|
||||
#endif /* WOLFSSL_AESNI */
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
aes->type = (byte)dir;
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
aes->left = 0;
|
||||
#endif /* WOLFSSL_AES_COUNTER */
|
||||
@@ -2137,6 +2155,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
||||
if (keylen > max_key_len) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
aes->type = (byte)dir;
|
||||
#endif
|
||||
aes->keylen = keylen;
|
||||
aes->rounds = keylen/4 + 6;
|
||||
@@ -8010,5 +8031,333 @@ int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
|
||||
|
||||
#endif /* HAVE_AES_KEYWRAP */
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
|
||||
/* Galios Field to use */
|
||||
#define GF_XTS 0x87
|
||||
|
||||
/* This is to help with setting keys to correct encrypt or decrypt type.
|
||||
*
|
||||
* tweak AES key for tweak in XTS
|
||||
* aes AES key for encrypt/decrypt process
|
||||
* key buffer holding aes key | tweak key
|
||||
* len length of key buffer in bytes. Should be twice that of key size. i.e.
|
||||
* 32 for a 16 byte key.
|
||||
* dir direction, either AES_ENCRYPTION or AES_DECRYPTION
|
||||
* heap heap hint to use for memory. Can be NULL
|
||||
* devId id to use with async crypto. Can be 0
|
||||
*
|
||||
* Note: is up to user to call wc_AesFree on tweak and aes key when done.
|
||||
*
|
||||
* return 0 on success
|
||||
*/
|
||||
int wc_AesXtsSetKey(Aes* tweak, Aes* aes, const byte* key, word32 len, int dir,
|
||||
void* heap, int devId)
|
||||
{
|
||||
word32 keySz;
|
||||
int ret = 0;
|
||||
|
||||
if (aes == NULL || tweak == NULL || key == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if ((ret = wc_AesInit(tweak, heap, devId)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = wc_AesInit(aes, heap, devId)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
keySz = len/2;
|
||||
if ((ret = wc_AesSetKey(aes, key, keySz, NULL, dir)) == 0) {
|
||||
ret = wc_AesSetKey(tweak, key + keySz, keySz, NULL, AES_ENCRYPTION);
|
||||
if (ret != 0) {
|
||||
wc_AesFree(aes);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
|
||||
* instead of a byte array. This just converts the word64 to a byte array and
|
||||
* calls wc_AesXtsEncrypt.
|
||||
*
|
||||
* tweak AES tweak key to use
|
||||
* aes AES key to use for block encrypt/decrypt
|
||||
* out output buffer to hold cipher text
|
||||
* in input plain text buffer to encrypt
|
||||
* sz size of both out and in buffers
|
||||
* sector value to use for tweak
|
||||
*
|
||||
* returns 0 on success
|
||||
*/
|
||||
int wc_AesXtsEncryptSector(Aes* tweak, Aes* aes, byte* out, const byte* in,
|
||||
word32 sz, word64 sector)
|
||||
{
|
||||
byte* pt;
|
||||
byte i[AES_BLOCK_SIZE];
|
||||
|
||||
XMEMSET(i, 0, AES_BLOCK_SIZE);
|
||||
pt = (byte*)§or;
|
||||
XMEMCPY(i, pt, sizeof(word64));
|
||||
|
||||
return wc_AesXtsEncrypt(tweak, aes, out, in, sz,
|
||||
(const byte*)i, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
|
||||
/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
|
||||
* instead of a byte array. This just converts the word64 to a byte array.
|
||||
*
|
||||
* tweak AES tweak key to use
|
||||
* aes AES key to use for block encrypt/decrypt
|
||||
* out output buffer to hold plain text
|
||||
* in input cipher text buffer to encrypt
|
||||
* sz size of both out and in buffers
|
||||
* sector value to use for tweak
|
||||
*
|
||||
* returns 0 on success
|
||||
*/
|
||||
int wc_AesXtsDecryptSector(Aes* tweak, Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
word64 sector)
|
||||
{
|
||||
byte* pt;
|
||||
byte i[AES_BLOCK_SIZE];
|
||||
|
||||
XMEMSET(i, 0, AES_BLOCK_SIZE);
|
||||
pt = (byte*)§or;
|
||||
XMEMCPY(i, pt, sizeof(word64));
|
||||
|
||||
return wc_AesXtsDecrypt(tweak, aes, out, in, sz,
|
||||
(const byte*)i, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
|
||||
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
|
||||
*
|
||||
* tweak AES tweak key to use
|
||||
* aes AES key to use for block encrypt/decrypt
|
||||
* out output buffer to hold cipher text
|
||||
* in input plain text buffer to encrypt
|
||||
* sz size of both out and in buffers
|
||||
* i value to use for tweak
|
||||
* iSz size of i buffer, should always be AES_BLOCK_SIZE but having this input
|
||||
* adds a sanity check on how the user calls the function.
|
||||
*
|
||||
* returns 0 on success
|
||||
*/
|
||||
int wc_AesXtsEncrypt(Aes* tweak, Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
const byte* i, word32 iSz)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 blocks = (sz / AES_BLOCK_SIZE);
|
||||
|
||||
if (aes == NULL || tweak == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (aes->type != AES_ENCRYPTION || tweak->type != AES_ENCRYPTION) {
|
||||
WOLFSSL_MSG("Both aes and tweak type should be AES_ENCRYPTION");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (iSz < AES_BLOCK_SIZE) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (in == NULL && sz > 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (blocks > 0) {
|
||||
byte tmp[AES_BLOCK_SIZE];
|
||||
|
||||
wc_AesEncryptDirect(tweak, tmp, i);
|
||||
|
||||
while (blocks > 0) {
|
||||
word32 j;
|
||||
byte carry = 0;
|
||||
byte buf[AES_BLOCK_SIZE];
|
||||
|
||||
XMEMCPY(buf, in, AES_BLOCK_SIZE);
|
||||
xorbuf(buf, tmp, AES_BLOCK_SIZE);
|
||||
wc_AesEncryptDirect(aes, out, buf);
|
||||
xorbuf(out, tmp, AES_BLOCK_SIZE);
|
||||
|
||||
/* multiply by shift left and propogate carry */
|
||||
for (j = 0; j < AES_BLOCK_SIZE; j++) {
|
||||
byte tmpC;
|
||||
|
||||
tmpC = (tmp[j] >> 7) & 0x01;
|
||||
tmp[j] = ((tmp[j] << 1) + carry) & 0xFF;
|
||||
carry = tmpC;
|
||||
}
|
||||
if (carry) {
|
||||
tmp[0] ^= GF_XTS;
|
||||
}
|
||||
carry = 0;
|
||||
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
sz -= AES_BLOCK_SIZE;
|
||||
blocks--;
|
||||
}
|
||||
|
||||
/* stealing operation of XTS to handle left overs */
|
||||
if (sz > 0) {
|
||||
byte buf[AES_BLOCK_SIZE];
|
||||
|
||||
XMEMCPY(buf, out - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
|
||||
if (sz >= AES_BLOCK_SIZE) { /* extra sanity check before copy */
|
||||
return BUFFER_E;
|
||||
}
|
||||
XMEMCPY(out, buf, sz);
|
||||
XMEMCPY(buf, in, sz);
|
||||
|
||||
xorbuf(buf, tmp, AES_BLOCK_SIZE);
|
||||
wc_AesEncryptDirect(aes, out - AES_BLOCK_SIZE, buf);
|
||||
xorbuf(out - AES_BLOCK_SIZE, tmp, AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("Plain text input too small for encryption");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Same process as encryption but Aes key is AES_DECRYPTION type.
|
||||
*
|
||||
* tweak AES tweak key to use
|
||||
* aes AES key to use for block encrypt/decrypt
|
||||
* out output buffer to hold plain text
|
||||
* in input cipher text buffer to decrypt
|
||||
* sz size of both out and in buffers
|
||||
* i value to use for tweak
|
||||
* iSz size of i buffer, should always be AES_BLOCK_SIZE but having this input
|
||||
* adds a sanity check on how the user calls the function.
|
||||
*
|
||||
* returns 0 on success
|
||||
*/
|
||||
int wc_AesXtsDecrypt(Aes* tweak, Aes* aes, byte* out, const byte* in, word32 sz,
|
||||
const byte* i, word32 iSz)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 blocks = (sz / AES_BLOCK_SIZE);
|
||||
|
||||
if (aes == NULL || tweak == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (aes->type != AES_DECRYPTION || tweak->type != AES_ENCRYPTION) {
|
||||
WOLFSSL_MSG("aes param should be decryption type and tweak encryption");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (iSz < AES_BLOCK_SIZE) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (in == NULL && sz > 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (blocks > 0) {
|
||||
word32 j;
|
||||
byte carry = 0;
|
||||
byte tmp[AES_BLOCK_SIZE];
|
||||
byte stl = (sz % AES_BLOCK_SIZE);
|
||||
|
||||
wc_AesEncryptDirect(tweak, tmp, i);
|
||||
|
||||
/* if Stealing then break out of loop one block early to handle special
|
||||
* case */
|
||||
if (stl > 0) {
|
||||
blocks--;
|
||||
}
|
||||
|
||||
while (blocks > 0) {
|
||||
byte buf[AES_BLOCK_SIZE];
|
||||
|
||||
XMEMCPY(buf, in, AES_BLOCK_SIZE);
|
||||
xorbuf(buf, tmp, AES_BLOCK_SIZE);
|
||||
wc_AesDecryptDirect(aes, out, buf);
|
||||
xorbuf(out, tmp, AES_BLOCK_SIZE);
|
||||
|
||||
/* multiply by shift left and propogate carry */
|
||||
for (j = 0; j < AES_BLOCK_SIZE; j++) {
|
||||
byte tmpC;
|
||||
|
||||
tmpC = (tmp[j] >> 7) & 0x01;
|
||||
tmp[j] = ((tmp[j] << 1) + carry) & 0xFF;
|
||||
carry = tmpC;
|
||||
}
|
||||
if (carry) {
|
||||
tmp[0] ^= GF_XTS;
|
||||
}
|
||||
carry = 0;
|
||||
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
sz -= AES_BLOCK_SIZE;
|
||||
blocks--;
|
||||
}
|
||||
|
||||
/* stealing operation of XTS to handle left overs */
|
||||
if (sz > 0) {
|
||||
byte buf[AES_BLOCK_SIZE];
|
||||
byte tmp2[AES_BLOCK_SIZE];
|
||||
|
||||
/* multiply by shift left and propogate carry */
|
||||
for (j = 0; j < AES_BLOCK_SIZE; j++) {
|
||||
byte tmpC;
|
||||
|
||||
tmpC = (tmp[j] >> 7) & 0x01;
|
||||
tmp2[j] = ((tmp[j] << 1) + carry) & 0xFF;
|
||||
carry = tmpC;
|
||||
}
|
||||
if (carry) {
|
||||
tmp2[0] ^= GF_XTS;
|
||||
}
|
||||
|
||||
XMEMCPY(buf, in, AES_BLOCK_SIZE);
|
||||
xorbuf(buf, tmp2, AES_BLOCK_SIZE);
|
||||
wc_AesDecryptDirect(aes, out, buf);
|
||||
xorbuf(out, tmp2, AES_BLOCK_SIZE);
|
||||
|
||||
/* tmp2 holds partial | last */
|
||||
XMEMCPY(tmp2, out, AES_BLOCK_SIZE);
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
sz -= AES_BLOCK_SIZE;
|
||||
|
||||
/* Make buffer with end of cipher text | last */
|
||||
XMEMCPY(buf, tmp2, AES_BLOCK_SIZE);
|
||||
if (sz >= AES_BLOCK_SIZE) { /* extra sanity check before copy */
|
||||
return BUFFER_E;
|
||||
}
|
||||
XMEMCPY(buf, in, sz);
|
||||
XMEMCPY(out, tmp2, sz);
|
||||
|
||||
xorbuf(buf, tmp, AES_BLOCK_SIZE);
|
||||
wc_AesDecryptDirect(aes, tmp2, buf);
|
||||
xorbuf(tmp2, tmp, AES_BLOCK_SIZE);
|
||||
XMEMCPY(out - AES_BLOCK_SIZE, tmp2, AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("Plain text input too small for encryption");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_AES_XTS */
|
||||
|
||||
#endif /* HAVE_FIPS */
|
||||
#endif /* !NO_AES */
|
||||
|
@@ -172,6 +172,9 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
aes->type = dir;
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
aes->left = 0;
|
||||
#endif /* WOLFSSL_AES_COUNTER */
|
||||
|
@@ -75,6 +75,9 @@ WOLFSSL_API int wc_AesSetKey(Aes* aes, const byte* key, word32 len, const byte*
|
||||
}
|
||||
|
||||
XMEMCPY(aes->key, key, len) ;
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
aes->type = dir;
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_COUNTER
|
||||
aes->left = 0;
|
||||
#endif /* WOLFSSL_AES_COUNTER */
|
||||
|
@@ -4202,6 +4202,521 @@ static int aes_key_size_test(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_AES_XTS)
|
||||
/* test vectors from http://csrc.nist.gov/groups/STM/cavp/block-cipher-modes.html */
|
||||
static int aes_xts_128_test(void)
|
||||
{
|
||||
Aes aes;
|
||||
Aes tweak;
|
||||
int ret = 0;
|
||||
unsigned char buf[AES_BLOCK_SIZE * 2];
|
||||
unsigned char cipher[AES_BLOCK_SIZE * 2];
|
||||
|
||||
/* 128 key tests */
|
||||
static unsigned char k1[] = {
|
||||
0xa1, 0xb9, 0x0c, 0xba, 0x3f, 0x06, 0xac, 0x35,
|
||||
0x3b, 0x2c, 0x34, 0x38, 0x76, 0x08, 0x17, 0x62,
|
||||
0x09, 0x09, 0x23, 0x02, 0x6e, 0x91, 0x77, 0x18,
|
||||
0x15, 0xf2, 0x9d, 0xab, 0x01, 0x93, 0x2f, 0x2f
|
||||
};
|
||||
|
||||
static unsigned char i1[] = {
|
||||
0x4f, 0xae, 0xf7, 0x11, 0x7c, 0xda, 0x59, 0xc6,
|
||||
0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5
|
||||
};
|
||||
|
||||
static unsigned char p1[] = {
|
||||
0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d,
|
||||
0x6f, 0xb3, 0x50, 0x39, 0x07, 0x90, 0x31, 0x1c
|
||||
};
|
||||
|
||||
/* plain text test of partial block is not from NIST test vector list */
|
||||
static unsigned char pp[] = {
|
||||
0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d,
|
||||
0x6f, 0xb3, 0x50, 0x39, 0x07, 0x90, 0x31, 0x1c,
|
||||
0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5
|
||||
};
|
||||
|
||||
static unsigned char c1[] = {
|
||||
0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a,
|
||||
0x82, 0x50, 0x81, 0xd5, 0xbe, 0x47, 0x1c, 0x63
|
||||
};
|
||||
|
||||
static unsigned char k2[] = {
|
||||
0x39, 0x25, 0x79, 0x05, 0xdf, 0xcc, 0x77, 0x76,
|
||||
0x6c, 0x87, 0x0a, 0x80, 0x6a, 0x60, 0xe3, 0xc0,
|
||||
0x93, 0xd1, 0x2a, 0xcf, 0xcb, 0x51, 0x42, 0xfa,
|
||||
0x09, 0x69, 0x89, 0x62, 0x5b, 0x60, 0xdb, 0x16
|
||||
};
|
||||
|
||||
static unsigned char i2[] = {
|
||||
0x5c, 0xf7, 0x9d, 0xb6, 0xc5, 0xcd, 0x99, 0x1a,
|
||||
0x1c, 0x78, 0x81, 0x42, 0x24, 0x95, 0x1e, 0x84
|
||||
};
|
||||
|
||||
static unsigned char p2[] = {
|
||||
0xbd, 0xc5, 0x46, 0x8f, 0xbc, 0x8d, 0x50, 0xa1,
|
||||
0x0d, 0x1c, 0x85, 0x7f, 0x79, 0x1c, 0x5c, 0xba,
|
||||
0xb3, 0x81, 0x0d, 0x0d, 0x73, 0xcf, 0x8f, 0x20,
|
||||
0x46, 0xb1, 0xd1, 0x9e, 0x7d, 0x5d, 0x8a, 0x56
|
||||
};
|
||||
|
||||
static unsigned char c2[] = {
|
||||
0xd6, 0xbe, 0x04, 0x6d, 0x41, 0xf2, 0x3b, 0x5e,
|
||||
0xd7, 0x0b, 0x6b, 0x3d, 0x5c, 0x8e, 0x66, 0x23,
|
||||
0x2b, 0xe6, 0xb8, 0x07, 0xd4, 0xdc, 0xc6, 0x0e,
|
||||
0xff, 0x8d, 0xbc, 0x1d, 0x9f, 0x7f, 0xc8, 0x22
|
||||
};
|
||||
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k2, sizeof(k2), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4000;
|
||||
ret = wc_AesXtsEncrypt(&tweak, &aes, buf, p2, sizeof(p2), i2, sizeof(i2));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4001;
|
||||
if (XMEMCMP(c2, buf, sizeof(c2)))
|
||||
return -4002;
|
||||
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4003;
|
||||
ret = wc_AesXtsEncrypt(&tweak, &aes, buf, p1, sizeof(p1), i1, sizeof(i1));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4004;
|
||||
if (XMEMCMP(c1, buf, AES_BLOCK_SIZE))
|
||||
return -4005;
|
||||
|
||||
/* partial block encryption test */
|
||||
XMEMSET(cipher, 0, sizeof(cipher));
|
||||
ret = wc_AesXtsEncrypt(&tweak, &aes, cipher, pp, sizeof(pp), i1, sizeof(i1));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4006;
|
||||
wc_AesFree(&aes);
|
||||
wc_AesFree(&tweak);
|
||||
|
||||
/* partial block decrypt test */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4007;
|
||||
ret = wc_AesXtsDecrypt(&tweak, &aes, buf, cipher, sizeof(pp), i1, sizeof(i1));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4008;
|
||||
if (XMEMCMP(pp, buf, sizeof(pp)))
|
||||
return -4009;
|
||||
|
||||
/* NIST decrypt test vector */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
ret = wc_AesXtsDecrypt(&tweak, &aes, buf, c1, sizeof(c1), i1, sizeof(i1));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4010;
|
||||
if (XMEMCMP(p1, buf, AES_BLOCK_SIZE))
|
||||
return -4011;
|
||||
|
||||
/* fail case with decrypting using wrong key */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
ret = wc_AesXtsDecrypt(&tweak, &aes, buf, c2, sizeof(c2), i2, sizeof(i2));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4012;
|
||||
if (XMEMCMP(p2, buf, sizeof(p2)) == 0) /* fail case with wrong key */
|
||||
return -4013;
|
||||
|
||||
/* set correct key and retest */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k2, sizeof(k2), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4014;
|
||||
ret = wc_AesXtsDecrypt(&tweak, &aes, buf, c2, sizeof(c2), i2, sizeof(i2));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4015;
|
||||
if (XMEMCMP(p2, buf, sizeof(p2)))
|
||||
return -4016;
|
||||
wc_AesFree(&aes);
|
||||
wc_AesFree(&tweak);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int aes_xts_256_test(void)
|
||||
{
|
||||
Aes aes;
|
||||
Aes tweak;
|
||||
int ret = 0;
|
||||
unsigned char buf[AES_BLOCK_SIZE * 3];
|
||||
unsigned char cipher[AES_BLOCK_SIZE * 3];
|
||||
|
||||
/* 256 key tests */
|
||||
static unsigned char k1[] = {
|
||||
0x1e, 0xa6, 0x61, 0xc5, 0x8d, 0x94, 0x3a, 0x0e,
|
||||
0x48, 0x01, 0xe4, 0x2f, 0x4b, 0x09, 0x47, 0x14,
|
||||
0x9e, 0x7f, 0x9f, 0x8e, 0x3e, 0x68, 0xd0, 0xc7,
|
||||
0x50, 0x52, 0x10, 0xbd, 0x31, 0x1a, 0x0e, 0x7c,
|
||||
0xd6, 0xe1, 0x3f, 0xfd, 0xf2, 0x41, 0x8d, 0x8d,
|
||||
0x19, 0x11, 0xc0, 0x04, 0xcd, 0xa5, 0x8d, 0xa3,
|
||||
0xd6, 0x19, 0xb7, 0xe2, 0xb9, 0x14, 0x1e, 0x58,
|
||||
0x31, 0x8e, 0xea, 0x39, 0x2c, 0xf4, 0x1b, 0x08
|
||||
};
|
||||
|
||||
static unsigned char i1[] = {
|
||||
0xad, 0xf8, 0xd9, 0x26, 0x27, 0x46, 0x4a, 0xd2,
|
||||
0xf0, 0x42, 0x8e, 0x84, 0xa9, 0xf8, 0x75, 0x64
|
||||
};
|
||||
|
||||
static unsigned char p1[] = {
|
||||
0x2e, 0xed, 0xea, 0x52, 0xcd, 0x82, 0x15, 0xe1,
|
||||
0xac, 0xc6, 0x47, 0xe8, 0x10, 0xbb, 0xc3, 0x64,
|
||||
0x2e, 0x87, 0x28, 0x7f, 0x8d, 0x2e, 0x57, 0xe3,
|
||||
0x6c, 0x0a, 0x24, 0xfb, 0xc1, 0x2a, 0x20, 0x2e
|
||||
};
|
||||
|
||||
/* plain text test of partial block is not from NIST test vector list */
|
||||
static unsigned char pp[] = {
|
||||
0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d,
|
||||
0x6f, 0xb3, 0x50, 0x39, 0x07, 0x90, 0x31, 0x1c,
|
||||
0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5
|
||||
};
|
||||
|
||||
static unsigned char c1[] = {
|
||||
0xcb, 0xaa, 0xd0, 0xe2, 0xf6, 0xce, 0xa3, 0xf5,
|
||||
0x0b, 0x37, 0xf9, 0x34, 0xd4, 0x6a, 0x9b, 0x13,
|
||||
0x0b, 0x9d, 0x54, 0xf0, 0x7e, 0x34, 0xf3, 0x6a,
|
||||
0xf7, 0x93, 0xe8, 0x6f, 0x73, 0xc6, 0xd7, 0xdb
|
||||
};
|
||||
|
||||
static unsigned char k2[] = {
|
||||
0xad, 0x50, 0x4b, 0x85, 0xd7, 0x51, 0xbf, 0xba,
|
||||
0x69, 0x13, 0xb4, 0xcc, 0x79, 0xb6, 0x5a, 0x62,
|
||||
0xf7, 0xf3, 0x9d, 0x36, 0x0f, 0x35, 0xb5, 0xec,
|
||||
0x4a, 0x7e, 0x95, 0xbd, 0x9b, 0xa5, 0xf2, 0xec,
|
||||
0xc1, 0xd7, 0x7e, 0xa3, 0xc3, 0x74, 0xbd, 0x4b,
|
||||
0x13, 0x1b, 0x07, 0x83, 0x87, 0xdd, 0x55, 0x5a,
|
||||
0xb5, 0xb0, 0xc7, 0xe5, 0x2d, 0xb5, 0x06, 0x12,
|
||||
0xd2, 0xb5, 0x3a, 0xcb, 0x47, 0x8a, 0x53, 0xb4
|
||||
};
|
||||
|
||||
static unsigned char i2[] = {
|
||||
0xe6, 0x42, 0x19, 0xed, 0xe0, 0xe1, 0xc2, 0xa0,
|
||||
0x0e, 0xf5, 0x58, 0x6a, 0xc4, 0x9b, 0xeb, 0x6f
|
||||
};
|
||||
|
||||
static unsigned char p2[] = {
|
||||
0x24, 0xcb, 0x76, 0x22, 0x55, 0xb5, 0xa8, 0x00,
|
||||
0xf4, 0x6e, 0x80, 0x60, 0x56, 0x9e, 0x05, 0x53,
|
||||
0xbc, 0xfe, 0x86, 0x55, 0x3b, 0xca, 0xd5, 0x89,
|
||||
0xc7, 0x54, 0x1a, 0x73, 0xac, 0xc3, 0x9a, 0xbd,
|
||||
0x53, 0xc4, 0x07, 0x76, 0xd8, 0xe8, 0x22, 0x61,
|
||||
0x9e, 0xa9, 0xad, 0x77, 0xa0, 0x13, 0x4c, 0xfc
|
||||
};
|
||||
|
||||
static unsigned char c2[] = {
|
||||
0xa3, 0xc6, 0xf3, 0xf3, 0x82, 0x79, 0x5b, 0x10,
|
||||
0x87, 0xd7, 0x02, 0x50, 0xdb, 0x2c, 0xd3, 0xb1,
|
||||
0xa1, 0x62, 0xa8, 0xb6, 0xdc, 0x12, 0x60, 0x61,
|
||||
0xc1, 0x0a, 0x84, 0xa5, 0x85, 0x3f, 0x3a, 0x89,
|
||||
0xe6, 0x6c, 0xdb, 0xb7, 0x9a, 0xb4, 0x28, 0x9b,
|
||||
0xc3, 0xea, 0xd8, 0x10, 0xe9, 0xc0, 0xaf, 0x92
|
||||
};
|
||||
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k2, sizeof(k2), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4017;
|
||||
ret = wc_AesXtsEncrypt(&tweak, &aes, buf, p2, sizeof(p2), i2, sizeof(i2));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4018;
|
||||
if (XMEMCMP(c2, buf, sizeof(c2)))
|
||||
return -4019;
|
||||
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4020;
|
||||
ret = wc_AesXtsEncrypt(&tweak, &aes, buf, p1, sizeof(p1), i1, sizeof(i1));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4021;
|
||||
if (XMEMCMP(c1, buf, AES_BLOCK_SIZE))
|
||||
return -4022;
|
||||
|
||||
/* partial block encryption test */
|
||||
XMEMSET(cipher, 0, sizeof(cipher));
|
||||
ret = wc_AesXtsEncrypt(&tweak, &aes, cipher, pp, sizeof(pp), i1, sizeof(i1));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4023;
|
||||
wc_AesFree(&aes);
|
||||
wc_AesFree(&tweak);
|
||||
|
||||
/* partial block decrypt test */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4024;
|
||||
ret = wc_AesXtsDecrypt(&tweak, &aes, buf, cipher, sizeof(pp), i1, sizeof(i1));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4025;
|
||||
if (XMEMCMP(pp, buf, sizeof(pp)))
|
||||
return -4026;
|
||||
|
||||
/* NIST decrypt test vector */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
ret = wc_AesXtsDecrypt(&tweak, &aes, buf, c1, sizeof(c1), i1, sizeof(i1));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4027;
|
||||
if (XMEMCMP(p1, buf, AES_BLOCK_SIZE))
|
||||
return -4028;
|
||||
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k2, sizeof(k2), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4029;
|
||||
ret = wc_AesXtsDecrypt(&tweak, &aes, buf, c2, sizeof(c2), i2, sizeof(i2));
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4030;
|
||||
if (XMEMCMP(p2, buf, sizeof(p2)))
|
||||
return -4031;
|
||||
wc_AesFree(&aes);
|
||||
wc_AesFree(&tweak);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* both 128 and 256 bit key test */
|
||||
static int aes_xts_sector_test(void)
|
||||
{
|
||||
Aes aes;
|
||||
Aes tweak;
|
||||
int ret = 0;
|
||||
unsigned char buf[AES_BLOCK_SIZE * 2];
|
||||
|
||||
/* 128 key tests */
|
||||
static unsigned char k1[] = {
|
||||
0xa3, 0xe4, 0x0d, 0x5b, 0xd4, 0xb6, 0xbb, 0xed,
|
||||
0xb2, 0xd1, 0x8c, 0x70, 0x0a, 0xd2, 0xdb, 0x22,
|
||||
0x10, 0xc8, 0x11, 0x90, 0x64, 0x6d, 0x67, 0x3c,
|
||||
0xbc, 0xa5, 0x3f, 0x13, 0x3e, 0xab, 0x37, 0x3c
|
||||
};
|
||||
|
||||
static unsigned char p1[] = {
|
||||
0x20, 0xe0, 0x71, 0x94, 0x05, 0x99, 0x3f, 0x09,
|
||||
0xa6, 0x6a, 0xe5, 0xbb, 0x50, 0x0e, 0x56, 0x2c
|
||||
};
|
||||
|
||||
static unsigned char c1[] = {
|
||||
0x74, 0x62, 0x35, 0x51, 0x21, 0x02, 0x16, 0xac,
|
||||
0x92, 0x6b, 0x96, 0x50, 0xb6, 0xd3, 0xfa, 0x52
|
||||
};
|
||||
word64 s1 = 141;
|
||||
|
||||
/* 256 key tests */
|
||||
static unsigned char k2[] = {
|
||||
0xef, 0x01, 0x0c, 0xa1, 0xa3, 0x66, 0x3e, 0x32,
|
||||
0x53, 0x43, 0x49, 0xbc, 0x0b, 0xae, 0x62, 0x23,
|
||||
0x2a, 0x15, 0x73, 0x34, 0x85, 0x68, 0xfb, 0x9e,
|
||||
0xf4, 0x17, 0x68, 0xa7, 0x67, 0x4f, 0x50, 0x7a,
|
||||
0x72, 0x7f, 0x98, 0x75, 0x53, 0x97, 0xd0, 0xe0,
|
||||
0xaa, 0x32, 0xf8, 0x30, 0x33, 0x8c, 0xc7, 0xa9,
|
||||
0x26, 0xc7, 0x73, 0xf0, 0x9e, 0x57, 0xb3, 0x57,
|
||||
0xcd, 0x15, 0x6a, 0xfb, 0xca, 0x46, 0xe1, 0xa0
|
||||
};
|
||||
|
||||
static unsigned char p2[] = {
|
||||
0xed, 0x98, 0xe0, 0x17, 0x70, 0xa8, 0x53, 0xb4,
|
||||
0x9d, 0xb9, 0xe6, 0xaa, 0xf8, 0x8f, 0x0a, 0x41,
|
||||
0xb9, 0xb5, 0x6e, 0x91, 0xa5, 0xa2, 0xb1, 0x1d,
|
||||
0x40, 0x52, 0x92, 0x54, 0xf5, 0x52, 0x3e, 0x75
|
||||
};
|
||||
|
||||
static unsigned char c2[] = {
|
||||
0xca, 0x20, 0xc5, 0x5e, 0x8d, 0xc1, 0x49, 0x68,
|
||||
0x7d, 0x25, 0x41, 0xde, 0x39, 0xc3, 0xdf, 0x63,
|
||||
0x00, 0xbb, 0x5a, 0x16, 0x3c, 0x10, 0xce, 0xd3,
|
||||
0x66, 0x6b, 0x13, 0x57, 0xdb, 0x8b, 0xd3, 0x9d
|
||||
};
|
||||
word64 s2 = 187;
|
||||
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4032;
|
||||
ret = wc_AesXtsEncryptSector(&tweak, &aes, buf, p1, sizeof(p1), s1);
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4033;
|
||||
if (XMEMCMP(c1, buf, AES_BLOCK_SIZE))
|
||||
return -4034;
|
||||
|
||||
/* decrypt test */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4035;
|
||||
ret = wc_AesXtsDecryptSector(&tweak, &aes, buf, c1, sizeof(c1), s1);
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4036;
|
||||
if (XMEMCMP(p1, buf, AES_BLOCK_SIZE))
|
||||
return -4037;
|
||||
wc_AesFree(&aes);
|
||||
wc_AesFree(&tweak);
|
||||
|
||||
/* 256 bit key tests */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k2, sizeof(k2), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4038;
|
||||
ret = wc_AesXtsEncryptSector(&tweak, &aes, buf, p2, sizeof(p2), s2);
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4039;
|
||||
if (XMEMCMP(c2, buf, sizeof(c2)))
|
||||
return -4040;
|
||||
|
||||
/* decrypt test */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k2, sizeof(k2), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4041;
|
||||
ret = wc_AesXtsDecryptSector(&tweak, &aes, buf, c2, sizeof(c2), s2);
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return -4042;
|
||||
if (XMEMCMP(p2, buf, sizeof(p2)))
|
||||
return -4043;
|
||||
wc_AesFree(&aes);
|
||||
wc_AesFree(&tweak);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* testing of bad arguments */
|
||||
static int aes_xts_args_test(void)
|
||||
{
|
||||
Aes aes;
|
||||
Aes tweak;
|
||||
int ret = 0;
|
||||
unsigned char buf[AES_BLOCK_SIZE * 2];
|
||||
|
||||
/* 128 key tests */
|
||||
static unsigned char k1[] = {
|
||||
0xa3, 0xe4, 0x0d, 0x5b, 0xd4, 0xb6, 0xbb, 0xed,
|
||||
0xb2, 0xd1, 0x8c, 0x70, 0x0a, 0xd2, 0xdb, 0x22,
|
||||
0x10, 0xc8, 0x11, 0x90, 0x64, 0x6d, 0x67, 0x3c,
|
||||
0xbc, 0xa5, 0x3f, 0x13, 0x3e, 0xab, 0x37, 0x3c
|
||||
};
|
||||
|
||||
static unsigned char p1[] = {
|
||||
0x20, 0xe0, 0x71, 0x94, 0x05, 0x99, 0x3f, 0x09,
|
||||
0xa6, 0x6a, 0xe5, 0xbb, 0x50, 0x0e, 0x56, 0x2c
|
||||
};
|
||||
|
||||
static unsigned char c1[] = {
|
||||
0x74, 0x62, 0x35, 0x51, 0x21, 0x02, 0x16, 0xac,
|
||||
0x92, 0x6b, 0x96, 0x50, 0xb6, 0xd3, 0xfa, 0x52
|
||||
};
|
||||
word64 s1 = 141;
|
||||
|
||||
if (wc_AesXtsSetKey(NULL, &aes, k1, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) == 0)
|
||||
return -4044;
|
||||
if (wc_AesXtsSetKey(&tweak, NULL, k1, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) == 0)
|
||||
return -4045;
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, NULL, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) == 0)
|
||||
return -4046;
|
||||
|
||||
/* set up wrong encrypt / decrypt types for key */
|
||||
wc_AesSetKey(&aes, k1, sizeof(k1)/2, NULL, AES_DECRYPTION);
|
||||
wc_AesSetKey(&tweak, k1 + sizeof(k1)/2, sizeof(k1)/2, NULL, AES_ENCRYPTION);
|
||||
ret = wc_AesXtsEncryptSector(&tweak, &aes, buf, p1, sizeof(p1), s1);
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret == 0)
|
||||
return -4047;
|
||||
wc_AesFree(&aes);
|
||||
wc_AesFree(&tweak);
|
||||
|
||||
/* tweak must be encryption type. Test with wrong decryption type used */
|
||||
wc_AesSetKey(&aes, k1, sizeof(k1)/2, NULL, AES_ENCRYPTION);
|
||||
wc_AesSetKey(&tweak, k1 + sizeof(k1)/2, sizeof(k1)/2, NULL, AES_DECRYPTION);
|
||||
ret = wc_AesXtsEncryptSector(&tweak, &aes, buf, p1, sizeof(p1), s1);
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret == 0)
|
||||
return -4048;
|
||||
wc_AesFree(&aes);
|
||||
wc_AesFree(&tweak);
|
||||
|
||||
/* Test for fail with encryption key used for decryption */
|
||||
if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4049;
|
||||
ret = wc_AesXtsDecryptSector(&tweak, &aes, buf, c1, sizeof(c1), s1);
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||
ret = wc_AsyncWait(ret, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
|
||||
#endif
|
||||
if (ret == 0)
|
||||
return -4050;
|
||||
wc_AesFree(&aes);
|
||||
wc_AesFree(&tweak);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* WOLFSSL_AES_XTS */
|
||||
|
||||
#if defined(HAVE_AES_CBC)
|
||||
static int aes_cbc_test(void)
|
||||
{
|
||||
@@ -4647,6 +5162,21 @@ int aes_test(void)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_AES_XTS)
|
||||
ret = aes_xts_128_test();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = aes_xts_256_test();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = aes_xts_sector_test();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = aes_xts_args_test();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
wc_AesFree(&enc);
|
||||
#ifdef HAVE_AES_DECRYPT
|
||||
wc_AesFree(&dec);
|
||||
|
@@ -109,6 +109,10 @@ typedef struct Aes {
|
||||
XCsuDma dma;
|
||||
word32 key_init[8];
|
||||
word32 kup;
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
byte type; /* adds the ability to do a sanity check on key for
|
||||
* encrypt/decrypt */
|
||||
#endif
|
||||
void* heap; /* memory hint to use */
|
||||
} Aes;
|
||||
@@ -210,6 +214,19 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out,
|
||||
const byte* iv);
|
||||
#endif /* HAVE_AES_KEYWRAP */
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
WOLFSSL_API int wc_AesXtsSetKey(Aes* tweak, Aes* aes, const byte* key,
|
||||
word32 len, int dir, void* heap, int devId);
|
||||
WOLFSSL_API int wc_AesXtsEncryptSector(Aes* tweak, Aes* aes, byte* out,
|
||||
const byte* in, word32 sz, word64 sector);
|
||||
WOLFSSL_API int wc_AesXtsDecryptSector(Aes* tweak, Aes* aes, byte* out,
|
||||
const byte* in, word32 sz, word64 sector);
|
||||
WOLFSSL_API int wc_AesXtsEncrypt(Aes* tweak, Aes* aes, byte* out,
|
||||
const byte* in, word32 sz, const byte* i, word32 iSz);
|
||||
WOLFSSL_API int wc_AesXtsDecrypt(Aes* tweak, Aes* aes, byte* out,
|
||||
const byte* in, word32 sz, const byte* i, word32 iSz);
|
||||
#endif
|
||||
|
||||
WOLFSSL_API int wc_AesGetKeySize(Aes* aes, word32* keySize);
|
||||
|
||||
WOLFSSL_API int wc_AesInit(Aes*, void*, int);
|
||||
|
@@ -1344,6 +1344,12 @@ extern void uITRON4_free(void *p) ;
|
||||
#error "AES CBC is required for TLS and can only be disabled for WOLFCRYPT_ONLY builds"
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
/* AES-XTS makes calls to AES direct functions */
|
||||
#ifndef WOLFSSL_AES_DIRECT
|
||||
#define WOLFSSL_AES_DIRECT
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* if desktop type system and fastmath increase default max bits */
|
||||
|
Reference in New Issue
Block a user