forked from wolfSSL/wolfssl
Merge pull request #1128 from JacobBarthelmeh/AES
AES XTS feature addition
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,71 @@ exit:
|
||||
#endif /* HAVE_AESGCM */
|
||||
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
void bench_aesxts(void)
|
||||
{
|
||||
XtsAes aes;
|
||||
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(&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(&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_AesXtsFree(&aes);
|
||||
|
||||
/* decryption benchmark */
|
||||
ret = wc_AesXtsSetKey(&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(&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_AesXtsFree(&aes);
|
||||
}
|
||||
#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);
|
||||
|
@ -8010,5 +8010,354 @@ 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(XtsAes* aes, const byte* key, word32 len, int dir,
|
||||
void* heap, int devId)
|
||||
{
|
||||
word32 keySz;
|
||||
int ret = 0;
|
||||
|
||||
if (aes == NULL || key == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
keySz = len/2;
|
||||
if (keySz != 16 && keySz != 32) {
|
||||
WOLFSSL_MSG("Unsupported key size");
|
||||
return WC_KEY_SIZE_E;
|
||||
}
|
||||
|
||||
if ((ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, dir)) == 0) {
|
||||
ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
|
||||
AES_ENCRYPTION);
|
||||
if (ret != 0) {
|
||||
wc_AesFree(&aes->aes);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* This is used to free up resources used by Aes structs
|
||||
*
|
||||
* aes AES keys to free
|
||||
*
|
||||
* return 0 on success
|
||||
*/
|
||||
int wc_AesXtsFree(XtsAes* aes)
|
||||
{
|
||||
if (aes != NULL) {
|
||||
wc_AesFree(&aes->aes);
|
||||
wc_AesFree(&aes->tweak);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* aes AES keys 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(XtsAes* aes, byte* out, const byte* in,
|
||||
word32 sz, word64 sector)
|
||||
{
|
||||
byte* pt;
|
||||
byte i[AES_BLOCK_SIZE];
|
||||
|
||||
XMEMSET(i, 0, AES_BLOCK_SIZE);
|
||||
#ifdef BIG_ENDIAN_ORDER
|
||||
sector = ByteReverseWord64(sector);
|
||||
#endif
|
||||
pt = (byte*)§or;
|
||||
XMEMCPY(i, pt, sizeof(word64));
|
||||
|
||||
return wc_AesXtsEncrypt(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.
|
||||
*
|
||||
* aes AES keys 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(XtsAes* aes, byte* out, const byte* in, word32 sz,
|
||||
word64 sector)
|
||||
{
|
||||
byte* pt;
|
||||
byte i[AES_BLOCK_SIZE];
|
||||
|
||||
XMEMSET(i, 0, AES_BLOCK_SIZE);
|
||||
#ifdef BIG_ENDIAN_ORDER
|
||||
sector = ByteReverseWord64(sector);
|
||||
#endif
|
||||
pt = (byte*)§or;
|
||||
XMEMCPY(i, pt, sizeof(word64));
|
||||
|
||||
return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
|
||||
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
|
||||
*
|
||||
* xaes AES keys 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(XtsAes* xaes, byte* out, const byte* in, word32 sz,
|
||||
const byte* i, word32 iSz)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 blocks = (sz / AES_BLOCK_SIZE);
|
||||
Aes *aes, *tweak;
|
||||
|
||||
if (xaes == NULL || out == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
aes = &xaes->aes;
|
||||
tweak = &xaes->tweak;
|
||||
|
||||
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.
|
||||
*
|
||||
* xaes AES keys 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(XtsAes* xaes, byte* out, const byte* in, word32 sz,
|
||||
const byte* i, word32 iSz)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 blocks = (sz / AES_BLOCK_SIZE);
|
||||
Aes *aes, *tweak;
|
||||
|
||||
if (xaes == NULL || out == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
aes = &xaes->aes;
|
||||
tweak = &xaes->tweak;
|
||||
|
||||
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 */
|
||||
|
@ -4202,6 +4202,509 @@ 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)
|
||||
{
|
||||
XtsAes aes;
|
||||
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(&aes, k2, sizeof(k2), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4000;
|
||||
ret = wc_AesXtsEncrypt(&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(&aes, k1, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4003;
|
||||
ret = wc_AesXtsEncrypt(&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(&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_AesXtsFree(&aes);
|
||||
|
||||
/* partial block decrypt test */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4007;
|
||||
ret = wc_AesXtsDecrypt(&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(&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(&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(&aes, k2, sizeof(k2), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4014;
|
||||
ret = wc_AesXtsDecrypt(&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_AesXtsFree(&aes);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int aes_xts_256_test(void)
|
||||
{
|
||||
XtsAes aes;
|
||||
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(&aes, k2, sizeof(k2), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4017;
|
||||
ret = wc_AesXtsEncrypt(&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(&aes, k1, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4020;
|
||||
ret = wc_AesXtsEncrypt(&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(&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_AesXtsFree(&aes);
|
||||
|
||||
/* partial block decrypt test */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4024;
|
||||
ret = wc_AesXtsDecrypt(&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(&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(&aes, k2, sizeof(k2), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4029;
|
||||
ret = wc_AesXtsDecrypt(&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_AesXtsFree(&aes);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* both 128 and 256 bit key test */
|
||||
static int aes_xts_sector_test(void)
|
||||
{
|
||||
XtsAes aes;
|
||||
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(&aes, k1, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4032;
|
||||
ret = wc_AesXtsEncryptSector(&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(&aes, k1, sizeof(k1), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4035;
|
||||
ret = wc_AesXtsDecryptSector(&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_AesXtsFree(&aes);
|
||||
|
||||
/* 256 bit key tests */
|
||||
XMEMSET(buf, 0, sizeof(buf));
|
||||
if (wc_AesXtsSetKey(&aes, k2, sizeof(k2), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4038;
|
||||
ret = wc_AesXtsEncryptSector(&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(&aes, k2, sizeof(k2), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4041;
|
||||
ret = wc_AesXtsDecryptSector(&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_AesXtsFree(&aes);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* testing of bad arguments */
|
||||
static int aes_xts_args_test(void)
|
||||
{
|
||||
XtsAes aes;
|
||||
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, k1, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) == 0)
|
||||
return -4044;
|
||||
if (wc_AesXtsSetKey(&aes, NULL, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) == 0)
|
||||
return -4045;
|
||||
|
||||
/* encryption operations */
|
||||
if (wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_ENCRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4046;
|
||||
ret = wc_AesXtsEncryptSector(NULL, 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;
|
||||
|
||||
ret = wc_AesXtsEncryptSector(&aes, NULL, 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_AesXtsFree(&aes);
|
||||
|
||||
/* decryption operations */
|
||||
if (wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_DECRYPTION,
|
||||
HEAP_HINT, devId) != 0)
|
||||
return -4046;
|
||||
ret = wc_AesXtsDecryptSector(NULL, 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 -4049;
|
||||
|
||||
ret = wc_AesXtsDecryptSector(&aes, NULL, 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_AesXtsFree(&aes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* WOLFSSL_AES_XTS */
|
||||
|
||||
#if defined(HAVE_AES_CBC)
|
||||
static int aes_cbc_test(void)
|
||||
{
|
||||
@ -4647,6 +5150,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);
|
||||
|
@ -113,6 +113,12 @@ typedef struct Aes {
|
||||
void* heap; /* memory hint to use */
|
||||
} Aes;
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
typedef struct XtsAes {
|
||||
Aes aes;
|
||||
Aes tweak;
|
||||
} XtsAes;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_AESGCM
|
||||
typedef struct Gmac {
|
||||
@ -210,6 +216,230 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out,
|
||||
const byte* iv);
|
||||
#endif /* HAVE_AES_KEYWRAP */
|
||||
|
||||
#ifdef WOLFSSL_AES_XTS
|
||||
/*!
|
||||
\ingroup AES
|
||||
|
||||
\brief This is to help with setting keys to correct encrypt or decrypt type.
|
||||
|
||||
\note Is up to user to call wc_AesXtsFree on aes key when done.
|
||||
|
||||
\return 0 Success
|
||||
|
||||
\param aes AES keys for encrypt/decrypt process
|
||||
\param key buffer holding aes key | tweak key
|
||||
\param len length of key buffer in bytes. Should be twice that of key size.
|
||||
i.e. 32 for a 16 byte key.
|
||||
\param dir direction, either AES_ENCRYPTION or AES_DECRYPTION
|
||||
\param heap heap hint to use for memory. Can be NULL
|
||||
\param devId id to use with async crypto. Can be 0
|
||||
|
||||
_Example_
|
||||
\code
|
||||
XtsAes aes;
|
||||
|
||||
if(wc_AesXtsSetKey(&aes, key, sizeof(key), AES_ENCRYPTION, NULL, 0) != 0)
|
||||
{
|
||||
// Handle error
|
||||
}
|
||||
wc_AesXtsFree(&aes);
|
||||
\endcode
|
||||
|
||||
\sa wc_AesXtsEncrypt
|
||||
\sa wc_AesXtsDecrypt
|
||||
\sa wc_AesXtsFree
|
||||
*/
|
||||
WOLFSSL_API int wc_AesXtsSetKey(XtsAes* aes, const byte* key,
|
||||
word32 len, int dir, void* heap, int devId);
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup AES
|
||||
|
||||
\brief 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.
|
||||
|
||||
\return 0 Success
|
||||
|
||||
\param aes AES keys to use for block encrypt/decrypt
|
||||
\param out output buffer to hold cipher text
|
||||
\param in input plain text buffer to encrypt
|
||||
\param sz size of both out and in buffers
|
||||
\param sector value to use for tweak
|
||||
|
||||
_Example_
|
||||
\code
|
||||
XtsAes aes;
|
||||
unsigned char plain[SIZE];
|
||||
unsigned char cipher[SIZE];
|
||||
word64 s = VALUE;
|
||||
|
||||
//set up keys with AES_ENCRYPTION as dir
|
||||
|
||||
if(wc_AesXtsEncryptSector(&aes, cipher, plain, SIZE, s) != 0)
|
||||
{
|
||||
// Handle error
|
||||
}
|
||||
wc_AesXtsFree(&aes);
|
||||
\endcode
|
||||
|
||||
\sa wc_AesXtsEncrypt
|
||||
\sa wc_AesXtsDecrypt
|
||||
\sa wc_AesXtsSetKey
|
||||
\sa wc_AesXtsFree
|
||||
*/
|
||||
WOLFSSL_API int wc_AesXtsEncryptSector(XtsAes* aes, byte* out,
|
||||
const byte* in, word32 sz, word64 sector);
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup AES
|
||||
|
||||
\brief 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.
|
||||
|
||||
\return 0 Success
|
||||
|
||||
\param aes AES keys to use for block encrypt/decrypt
|
||||
\param out output buffer to hold plain text
|
||||
\param in input cipher text buffer to decrypt
|
||||
\param sz size of both out and in buffers
|
||||
\param sector value to use for tweak
|
||||
|
||||
_Example_
|
||||
\code
|
||||
XtsAes aes;
|
||||
unsigned char plain[SIZE];
|
||||
unsigned char cipher[SIZE];
|
||||
word64 s = VALUE;
|
||||
|
||||
//set up aes key with AES_DECRYPTION as dir and tweak with AES_ENCRYPTION
|
||||
|
||||
if(wc_AesXtsDecryptSector(&aes, plain, cipher, SIZE, s) != 0)
|
||||
{
|
||||
// Handle error
|
||||
}
|
||||
wc_AesXtsFree(&aes);
|
||||
\endcode
|
||||
|
||||
\sa wc_AesXtsEncrypt
|
||||
\sa wc_AesXtsDecrypt
|
||||
\sa wc_AesXtsSetKey
|
||||
\sa wc_AesXtsFree
|
||||
*/
|
||||
WOLFSSL_API int wc_AesXtsDecryptSector(XtsAes* aes, byte* out,
|
||||
const byte* in, word32 sz, word64 sector);
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup AES
|
||||
|
||||
\brief AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text
|
||||
Stealing.
|
||||
|
||||
\return 0 Success
|
||||
|
||||
\param aes AES keys to use for block encrypt/decrypt
|
||||
\param out output buffer to hold cipher text
|
||||
\param in input plain text buffer to encrypt
|
||||
\param sz size of both out and in buffers
|
||||
\param i value to use for tweak
|
||||
\param 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.
|
||||
|
||||
_Example_
|
||||
\code
|
||||
XtsAes aes;
|
||||
unsigned char plain[SIZE];
|
||||
unsigned char cipher[SIZE];
|
||||
unsigned char i[AES_BLOCK_SIZE];
|
||||
|
||||
//set up key with AES_ENCRYPTION as dir
|
||||
|
||||
if(wc_AesXtsEncrypt(&aes, cipher, plain, SIZE, i, sizeof(i)) != 0)
|
||||
{
|
||||
// Handle error
|
||||
}
|
||||
wc_AesXtsFree(&aes);
|
||||
\endcode
|
||||
|
||||
\sa wc_AesXtsDecrypt
|
||||
\sa wc_AesXtsSetKey
|
||||
\sa wc_AesXtsFree
|
||||
*/
|
||||
WOLFSSL_API int wc_AesXtsEncrypt(XtsAes* aes, byte* out,
|
||||
const byte* in, word32 sz, const byte* i, word32 iSz);
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup AES
|
||||
|
||||
\brief Same process as encryption but Aes key is AES_DECRYPTION type.
|
||||
|
||||
\return 0 Success
|
||||
|
||||
\param aes AES keys to use for block encrypt/decrypt
|
||||
\param out output buffer to hold plain text
|
||||
\param in input cipher text buffer to decrypt
|
||||
\param sz size of both out and in buffers
|
||||
\param i value to use for tweak
|
||||
\param 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.
|
||||
_Example_
|
||||
\code
|
||||
XtsAes aes;
|
||||
unsigned char plain[SIZE];
|
||||
unsigned char cipher[SIZE];
|
||||
unsigned char i[AES_BLOCK_SIZE];
|
||||
|
||||
//set up key with AES_DECRYPTION as dir and tweak with AES_ENCRYPTION
|
||||
|
||||
if(wc_AesXtsDecrypt(&aes, plain, cipher, SIZE, i, sizeof(i)) != 0)
|
||||
{
|
||||
// Handle error
|
||||
}
|
||||
wc_AesXtsFree(&aes);
|
||||
\endcode
|
||||
|
||||
\sa wc_AesXtsEncrypt
|
||||
\sa wc_AesXtsSetKey
|
||||
\sa wc_AesXtsFree
|
||||
*/
|
||||
WOLFSSL_API int wc_AesXtsDecrypt(XtsAes* aes, byte* out,
|
||||
const byte* in, word32 sz, const byte* i, word32 iSz);
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup AES
|
||||
|
||||
\brief This is to free up any resources used by the XtsAes structure
|
||||
|
||||
\return 0 Success
|
||||
|
||||
\param aes AES keys to free
|
||||
|
||||
_Example_
|
||||
\code
|
||||
XtsAes aes;
|
||||
|
||||
if(wc_AesXtsSetKey(&aes, key, sizeof(key), AES_ENCRYPTION, NULL, 0) != 0)
|
||||
{
|
||||
// Handle error
|
||||
}
|
||||
wc_AesXtsFree(&aes);
|
||||
\endcode
|
||||
|
||||
\sa wc_AesXtsEncrypt
|
||||
\sa wc_AesXtsDecrypt
|
||||
\sa wc_AesXtsSetKey
|
||||
*/
|
||||
WOLFSSL_API int wc_AesXtsFree(XtsAes* aes);
|
||||
#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