From ef73c1df7c2d041b881cd72d4e918e9449977870 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 30 Aug 2017 17:50:15 -0600 Subject: [PATCH 1/4] add AES-XTS mode --enable-xts --- configure.ac | 12 + wolfcrypt/benchmark/benchmark.c | 70 ++++ wolfcrypt/benchmark/benchmark.h | 1 + wolfcrypt/src/aes.c | 349 +++++++++++++++++++ wolfcrypt/src/port/arm/armv8-aes.c | 3 + wolfcrypt/src/port/ti/ti-aes.c | 3 + wolfcrypt/test/test.c | 530 +++++++++++++++++++++++++++++ wolfssl/wolfcrypt/aes.h | 17 + wolfssl/wolfcrypt/settings.h | 6 + 9 files changed, 991 insertions(+) diff --git a/configure.ac b/configure.ac index 0f9606038..9a3ca0088 100644 --- a/configure.ac +++ b/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)])], diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 3c6d831e9..3b22d2159 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -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) { diff --git a/wolfcrypt/benchmark/benchmark.h b/wolfcrypt/benchmark/benchmark.h index 8f1615bc9..7fc7b31f0 100644 --- a/wolfcrypt/benchmark/benchmark.h +++ b/wolfcrypt/benchmark/benchmark.h @@ -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); diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index c59fa616d..9e0dbd133 100755 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -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 */ diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index 535239647..112aba5ef 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -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 */ diff --git a/wolfcrypt/src/port/ti/ti-aes.c b/wolfcrypt/src/port/ti/ti-aes.c index cd8d2eed9..7673ee96a 100644 --- a/wolfcrypt/src/port/ti/ti-aes.c +++ b/wolfcrypt/src/port/ti/ti-aes.c @@ -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 */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index f9cf28c0a..416c017bf 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -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); diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index aa5fb9465..b0a26873a 100755 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -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); diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index c3c9e513f..6fba5a8a4 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -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 */ From d48c940334965f2d3848d1b6f618d91d8c692b4c Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 30 Aug 2017 13:51:17 -0600 Subject: [PATCH 2/4] add comments for AES-XTS functions to aes.h --- wolfssl/wolfcrypt/aes.h | 207 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 203 insertions(+), 4 deletions(-) diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index b0a26873a..89892a774 100755 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -215,14 +215,213 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out, #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_AesFree on tweak and aes key when done. + + \return 0 Success + + \param tweak AES key for tweak in XTS + \param aes AES key 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 + Aes aes; + Aes tweak; + + if(wc_AesXtsSetKey(&tweak, &aes, key, sizeof(key), AES_ENCRYPTION, NULL, 0) != 0) + { + // Handle error + } + wc_AesFree(&aes); + wc_AesFree(&tweak); + \endcode + + \sa wc_AesXtsEncrypt + \sa wc_AesXtsDecrypt + \sa wc_AesFree +*/ WOLFSSL_API int wc_AesXtsSetKey(Aes* tweak, Aes* aes, const byte* key, - word32 len, int dir, void* heap, int devId); + 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 tweak tweak AES tweak key to use + \param aes AES key 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 + Aes aes; + Aes tweak; + unsigned char plain[SIZE]; + unsigned char cipher[SIZE]; + word64 s = VALUE; + + //set up keys with AES_ENCRYPTION as dir + + if(wc_AesXtsEncryptSector(&tweak, &aes, cipher, plain, SIZE, s) != 0) + { + // Handle error + } + wc_AesFree(&aes); + wc_AesFree(&tweak); + \endcode + + \sa wc_AesXtsEncrypt + \sa wc_AesXtsDecrypt + \sa wc_AesXtsSetKey + \sa wc_AesFree +*/ WOLFSSL_API int wc_AesXtsEncryptSector(Aes* tweak, Aes* aes, byte* out, - const byte* in, word32 sz, word64 sector); + 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 tweak AES tweak key to use + \param aes AES key 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 + Aes aes; + Aes tweak; + 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(&tweak, &aes, plain, cipher, SIZE, s) != 0) + { + // Handle error + } + wc_AesFree(&aes); + wc_AesFree(&tweak); + \endcode + + \sa wc_AesXtsEncrypt + \sa wc_AesXtsDecrypt + \sa wc_AesXtsSetKey + \sa wc_AesFree +*/ WOLFSSL_API int wc_AesXtsDecryptSector(Aes* tweak, Aes* aes, byte* out, - const byte* in, word32 sz, word64 sector); + 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 tweak AES tweak key to use + \param aes AES key 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 + Aes aes; + Aes tweak; + 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(&tweak, &aes, cipher, plain, SIZE, i, sizeof(i)) != 0) + { + // Handle error + } + wc_AesFree(&aes); + wc_AesFree(&tweak); + \endcode + + \sa wc_AesXtsDecrypt + \sa wc_AesXtsSetKey + \sa wc_AesFree +*/ WOLFSSL_API int wc_AesXtsEncrypt(Aes* tweak, Aes* aes, byte* out, - const byte* in, word32 sz, const byte* i, word32 iSz); + 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 tweak AES tweak key to use + \param aes AES key 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 + Aes aes; + Aes tweak; + 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(&tweak, &aes, plain, cipher, SIZE, i, sizeof(i)) != 0) + { + // Handle error + } + wc_AesFree(&aes); + wc_AesFree(&tweak); + \endcode + + \sa wc_AesXtsEncrypt + \sa wc_AesXtsSetKey + \sa wc_AesFree +*/ WOLFSSL_API int wc_AesXtsDecrypt(Aes* tweak, Aes* aes, byte* out, const byte* in, word32 sz, const byte* i, word32 iSz); #endif From c482524b78a20aa77687c917990827037fde0786 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 1 Sep 2017 15:32:55 -0600 Subject: [PATCH 3/4] big endian testing and packing Aes struct --- wolfcrypt/src/aes.c | 6 ++++++ wolfssl/wolfcrypt/aes.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 9e0dbd133..f94a1fba5 100755 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -8100,6 +8100,9 @@ int wc_AesXtsEncryptSector(Aes* tweak, Aes* aes, byte* out, const byte* in, 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)); @@ -8127,6 +8130,9 @@ int wc_AesXtsDecryptSector(Aes* tweak, Aes* aes, byte* out, const byte* in, word 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)); diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 89892a774..7ba85f0a2 100755 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -110,11 +110,11 @@ typedef struct Aes { word32 key_init[8]; word32 kup; #endif + void* heap; /* memory hint to use */ #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; From 398252ddad931bf705690ba3294bbcd66c488605 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 8 Sep 2017 16:00:33 -0600 Subject: [PATCH 4/4] add XtsAes structure and change XTS-AES API --- wolfcrypt/benchmark/benchmark.c | 16 ++-- wolfcrypt/src/aes.c | 102 +++++++++++----------- wolfcrypt/src/port/arm/armv8-aes.c | 3 - wolfcrypt/src/port/ti/ti-aes.c | 3 - wolfcrypt/test/test.c | 130 +++++++++++++---------------- wolfssl/wolfcrypt/aes.h | 114 ++++++++++++++----------- 6 files changed, 178 insertions(+), 190 deletions(-) diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 3b22d2159..2de5c16a0 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -1343,7 +1343,7 @@ exit: #ifdef WOLFSSL_AES_XTS void bench_aesxts(void) { - Aes aes, tweak; + XtsAes aes; double start; int i, count, ret; @@ -1359,7 +1359,7 @@ void bench_aesxts(void) 0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5 }; - ret = wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_ENCRYPTION, + ret = wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_ENCRYPTION, HEAP_HINT, devId); if (ret != 0) { printf("wc_AesXtsSetKey failed, ret = %d\n", ret); @@ -1369,7 +1369,7 @@ void bench_aesxts(void) bench_stats_start(&count, &start); do { for (i = 0; i < numBlocks; i++) { - if ((ret = wc_AesXtsEncrypt(&tweak, &aes, bench_plain, bench_cipher, + if ((ret = wc_AesXtsEncrypt(&aes, bench_plain, bench_cipher, BENCH_SIZE, i1, sizeof(i1))) != 0) { printf("wc_AesXtsEncrypt failed, ret = %d\n", ret); return; @@ -1378,11 +1378,10 @@ void bench_aesxts(void) 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); + wc_AesXtsFree(&aes); /* decryption benchmark */ - ret = wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_DECRYPTION, + ret = wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_DECRYPTION, HEAP_HINT, devId); if (ret != 0) { printf("wc_AesXtsSetKey failed, ret = %d\n", ret); @@ -1392,7 +1391,7 @@ void bench_aesxts(void) bench_stats_start(&count, &start); do { for (i = 0; i < numBlocks; i++) { - if ((ret = wc_AesXtsDecrypt(&tweak, &aes, bench_plain, bench_cipher, + if ((ret = wc_AesXtsDecrypt(&aes, bench_plain, bench_cipher, BENCH_SIZE, i1, sizeof(i1))) != 0) { printf("wc_AesXtsDecrypt failed, ret = %d\n", ret); return; @@ -1401,8 +1400,7 @@ void bench_aesxts(void) 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); + wc_AesXtsFree(&aes); } #endif /* WOLFSSL_AES_XTS */ diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index f94a1fba5..8175083bc 100755 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -1794,9 +1794,6 @@ 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); @@ -1866,9 +1863,6 @@ 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); @@ -1888,9 +1882,6 @@ 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 */ @@ -1918,9 +1909,6 @@ 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 */ @@ -1961,9 +1949,6 @@ 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); @@ -1990,9 +1975,6 @@ 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 */ @@ -2155,9 +2137,6 @@ 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; @@ -8051,28 +8030,34 @@ int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, * * return 0 on success */ -int wc_AesXtsSetKey(Aes* tweak, Aes* aes, const byte* key, word32 len, int dir, +int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir, void* heap, int devId) { word32 keySz; int ret = 0; - if (aes == NULL || tweak == NULL || key == NULL) { + if (aes == NULL || key == NULL) { return BAD_FUNC_ARG; } - if ((ret = wc_AesInit(tweak, heap, devId)) != 0) { + if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) { return ret; } - if ((ret = wc_AesInit(aes, heap, devId)) != 0) { + if ((ret = wc_AesInit(&aes->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 (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); + wc_AesFree(&aes->aes); } } @@ -8080,12 +8065,28 @@ int wc_AesXtsSetKey(Aes* tweak, Aes* aes, const byte* key, word32 len, int dir, } +/* 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. * - * tweak AES tweak key to use - * aes AES key to use for block encrypt/decrypt + * 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 @@ -8093,7 +8094,7 @@ int wc_AesXtsSetKey(Aes* tweak, Aes* aes, const byte* key, word32 len, int dir, * * returns 0 on success */ -int wc_AesXtsEncryptSector(Aes* tweak, Aes* aes, byte* out, const byte* in, +int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz, word64 sector) { byte* pt; @@ -8106,16 +8107,14 @@ int wc_AesXtsEncryptSector(Aes* tweak, Aes* aes, byte* out, const byte* in, pt = (byte*)§or; XMEMCPY(i, pt, sizeof(word64)); - return wc_AesXtsEncrypt(tweak, aes, out, in, sz, - (const byte*)i, AES_BLOCK_SIZE); + 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. * - * tweak AES tweak key to use - * aes AES key to use for block encrypt/decrypt + * 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 @@ -8123,7 +8122,7 @@ int wc_AesXtsEncryptSector(Aes* tweak, Aes* aes, byte* out, const byte* in, * * returns 0 on success */ -int wc_AesXtsDecryptSector(Aes* tweak, Aes* aes, byte* out, const byte* in, word32 sz, +int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz, word64 sector) { byte* pt; @@ -8136,15 +8135,13 @@ int wc_AesXtsDecryptSector(Aes* tweak, Aes* aes, byte* out, const byte* in, word pt = (byte*)§or; XMEMCPY(i, pt, sizeof(word64)); - return wc_AesXtsDecrypt(tweak, aes, out, in, sz, - (const byte*)i, AES_BLOCK_SIZE); + 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. * - * tweak AES tweak key to use - * aes AES key to use for block encrypt/decrypt + * 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 @@ -8154,20 +8151,19 @@ int wc_AesXtsDecryptSector(Aes* tweak, Aes* aes, byte* out, const byte* in, word * * returns 0 on success */ -int wc_AesXtsEncrypt(Aes* tweak, Aes* aes, byte* out, const byte* in, word32 sz, +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 (aes == NULL || tweak == NULL) { + if (xaes == NULL || out == 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; - } + aes = &xaes->aes; + tweak = &xaes->tweak; if (iSz < AES_BLOCK_SIZE) { return BAD_FUNC_ARG; @@ -8238,8 +8234,7 @@ int wc_AesXtsEncrypt(Aes* tweak, Aes* aes, byte* out, const byte* in, word32 sz, /* 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 + * 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 @@ -8249,20 +8244,19 @@ int wc_AesXtsEncrypt(Aes* tweak, Aes* aes, byte* out, const byte* in, word32 sz, * * returns 0 on success */ -int wc_AesXtsDecrypt(Aes* tweak, Aes* aes, byte* out, const byte* in, word32 sz, +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 (aes == NULL || tweak == NULL) { + if (xaes == NULL || out == 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; - } + aes = &xaes->aes; + tweak = &xaes->tweak; if (iSz < AES_BLOCK_SIZE) { return BAD_FUNC_ARG; diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index 112aba5ef..535239647 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -172,9 +172,6 @@ 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 */ diff --git a/wolfcrypt/src/port/ti/ti-aes.c b/wolfcrypt/src/port/ti/ti-aes.c index 7673ee96a..cd8d2eed9 100644 --- a/wolfcrypt/src/port/ti/ti-aes.c +++ b/wolfcrypt/src/port/ti/ti-aes.c @@ -75,9 +75,6 @@ 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 */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 416c017bf..ffc552928 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -4206,8 +4206,7 @@ static int aes_key_size_test(void) /* 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; + XtsAes aes; int ret = 0; unsigned char buf[AES_BLOCK_SIZE * 2]; unsigned char cipher[AES_BLOCK_SIZE * 2]; @@ -4269,10 +4268,10 @@ static int aes_xts_128_test(void) }; XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&tweak, &aes, k2, sizeof(k2), AES_ENCRYPTION, + if (wc_AesXtsSetKey(&aes, k2, sizeof(k2), AES_ENCRYPTION, HEAP_HINT, devId) != 0) return -4000; - ret = wc_AesXtsEncrypt(&tweak, &aes, buf, p2, sizeof(p2), i2, sizeof(i2)); + 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 @@ -4282,10 +4281,10 @@ static int aes_xts_128_test(void) return -4002; XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_ENCRYPTION, + if (wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_ENCRYPTION, HEAP_HINT, devId) != 0) return -4003; - ret = wc_AesXtsEncrypt(&tweak, &aes, buf, p1, sizeof(p1), i1, sizeof(i1)); + 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 @@ -4296,21 +4295,20 @@ static int aes_xts_128_test(void) /* partial block encryption test */ XMEMSET(cipher, 0, sizeof(cipher)); - ret = wc_AesXtsEncrypt(&tweak, &aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); + 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_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); /* partial block decrypt test */ XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_DECRYPTION, + if (wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_DECRYPTION, HEAP_HINT, devId) != 0) return -4007; - ret = wc_AesXtsDecrypt(&tweak, &aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); + 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 @@ -4321,7 +4319,7 @@ static int aes_xts_128_test(void) /* NIST decrypt test vector */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsDecrypt(&tweak, &aes, buf, c1, sizeof(c1), i1, sizeof(i1)); + 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 @@ -4332,7 +4330,7 @@ static int aes_xts_128_test(void) /* fail case with decrypting using wrong key */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsDecrypt(&tweak, &aes, buf, c2, sizeof(c2), i2, sizeof(i2)); + 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 @@ -4343,10 +4341,10 @@ static int aes_xts_128_test(void) /* set correct key and retest */ XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&tweak, &aes, k2, sizeof(k2), AES_DECRYPTION, + if (wc_AesXtsSetKey(&aes, k2, sizeof(k2), AES_DECRYPTION, HEAP_HINT, devId) != 0) return -4014; - ret = wc_AesXtsDecrypt(&tweak, &aes, buf, c2, sizeof(c2), i2, sizeof(i2)); + 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 @@ -4354,8 +4352,7 @@ static int aes_xts_128_test(void) return -4015; if (XMEMCMP(p2, buf, sizeof(p2))) return -4016; - wc_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); return ret; } @@ -4363,8 +4360,7 @@ static int aes_xts_128_test(void) static int aes_xts_256_test(void) { - Aes aes; - Aes tweak; + XtsAes aes; int ret = 0; unsigned char buf[AES_BLOCK_SIZE * 3]; unsigned char cipher[AES_BLOCK_SIZE * 3]; @@ -4442,10 +4438,10 @@ static int aes_xts_256_test(void) }; XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&tweak, &aes, k2, sizeof(k2), AES_ENCRYPTION, + if (wc_AesXtsSetKey(&aes, k2, sizeof(k2), AES_ENCRYPTION, HEAP_HINT, devId) != 0) return -4017; - ret = wc_AesXtsEncrypt(&tweak, &aes, buf, p2, sizeof(p2), i2, sizeof(i2)); + 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 @@ -4455,10 +4451,10 @@ static int aes_xts_256_test(void) return -4019; XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_ENCRYPTION, + if (wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_ENCRYPTION, HEAP_HINT, devId) != 0) return -4020; - ret = wc_AesXtsEncrypt(&tweak, &aes, buf, p1, sizeof(p1), i1, sizeof(i1)); + 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 @@ -4469,21 +4465,20 @@ static int aes_xts_256_test(void) /* partial block encryption test */ XMEMSET(cipher, 0, sizeof(cipher)); - ret = wc_AesXtsEncrypt(&tweak, &aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); + 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_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); /* partial block decrypt test */ XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_DECRYPTION, + if (wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_DECRYPTION, HEAP_HINT, devId) != 0) return -4024; - ret = wc_AesXtsDecrypt(&tweak, &aes, buf, cipher, sizeof(pp), i1, sizeof(i1)); + 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 @@ -4494,7 +4489,7 @@ static int aes_xts_256_test(void) /* NIST decrypt test vector */ XMEMSET(buf, 0, sizeof(buf)); - ret = wc_AesXtsDecrypt(&tweak, &aes, buf, c1, sizeof(c1), i1, sizeof(i1)); + 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 @@ -4504,10 +4499,10 @@ static int aes_xts_256_test(void) return -4028; XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&tweak, &aes, k2, sizeof(k2), AES_DECRYPTION, + if (wc_AesXtsSetKey(&aes, k2, sizeof(k2), AES_DECRYPTION, HEAP_HINT, devId) != 0) return -4029; - ret = wc_AesXtsDecrypt(&tweak, &aes, buf, c2, sizeof(c2), i2, sizeof(i2)); + 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 @@ -4515,8 +4510,7 @@ static int aes_xts_256_test(void) return -4030; if (XMEMCMP(p2, buf, sizeof(p2))) return -4031; - wc_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); return ret; } @@ -4525,8 +4519,7 @@ static int aes_xts_256_test(void) /* both 128 and 256 bit key test */ static int aes_xts_sector_test(void) { - Aes aes; - Aes tweak; + XtsAes aes; int ret = 0; unsigned char buf[AES_BLOCK_SIZE * 2]; @@ -4577,10 +4570,10 @@ static int aes_xts_sector_test(void) word64 s2 = 187; XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_ENCRYPTION, + if (wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_ENCRYPTION, HEAP_HINT, devId) != 0) return -4032; - ret = wc_AesXtsEncryptSector(&tweak, &aes, buf, p1, sizeof(p1), s1); + 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 @@ -4591,10 +4584,10 @@ static int aes_xts_sector_test(void) /* decrypt test */ XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_DECRYPTION, + if (wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_DECRYPTION, HEAP_HINT, devId) != 0) return -4035; - ret = wc_AesXtsDecryptSector(&tweak, &aes, buf, c1, sizeof(c1), s1); + 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 @@ -4602,15 +4595,14 @@ static int aes_xts_sector_test(void) return -4036; if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) return -4037; - wc_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); /* 256 bit key tests */ XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&tweak, &aes, k2, sizeof(k2), AES_ENCRYPTION, + if (wc_AesXtsSetKey(&aes, k2, sizeof(k2), AES_ENCRYPTION, HEAP_HINT, devId) != 0) return -4038; - ret = wc_AesXtsEncryptSector(&tweak, &aes, buf, p2, sizeof(p2), s2); + 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 @@ -4621,10 +4613,10 @@ static int aes_xts_sector_test(void) /* decrypt test */ XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&tweak, &aes, k2, sizeof(k2), AES_DECRYPTION, + if (wc_AesXtsSetKey(&aes, k2, sizeof(k2), AES_DECRYPTION, HEAP_HINT, devId) != 0) return -4041; - ret = wc_AesXtsDecryptSector(&tweak, &aes, buf, c2, sizeof(c2), s2); + 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 @@ -4632,8 +4624,7 @@ static int aes_xts_sector_test(void) return -4042; if (XMEMCMP(p2, buf, sizeof(p2))) return -4043; - wc_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); return ret; } @@ -4642,8 +4633,7 @@ static int aes_xts_sector_test(void) /* testing of bad arguments */ static int aes_xts_args_test(void) { - Aes aes; - Aes tweak; + XtsAes aes; int ret = 0; unsigned char buf[AES_BLOCK_SIZE * 2]; @@ -4666,52 +4656,50 @@ static int aes_xts_args_test(void) }; word64 s1 = 141; - if (wc_AesXtsSetKey(NULL, &aes, k1, sizeof(k1), AES_ENCRYPTION, + if (wc_AesXtsSetKey(NULL, k1, sizeof(k1), AES_ENCRYPTION, HEAP_HINT, devId) == 0) return -4044; - if (wc_AesXtsSetKey(&tweak, NULL, k1, sizeof(k1), AES_ENCRYPTION, + if (wc_AesXtsSetKey(&aes, NULL, 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); + /* 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; - 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); + 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_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); - /* Test for fail with encryption key used for decryption */ - if (wc_AesXtsSetKey(&tweak, &aes, k1, sizeof(k1), AES_ENCRYPTION, + /* 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(&tweak, &aes, buf, c1, sizeof(c1), s1); + + 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_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); return 0; } diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 7ba85f0a2..587432341 100755 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -111,12 +111,14 @@ typedef struct Aes { word32 kup; #endif void* heap; /* memory hint to use */ -#ifdef WOLFSSL_AES_XTS - byte type; /* adds the ability to do a sanity check on key for - * encrypt/decrypt */ -#endif } Aes; +#ifdef WOLFSSL_AES_XTS +typedef struct XtsAes { + Aes aes; + Aes tweak; +} XtsAes; +#endif #ifdef HAVE_AESGCM typedef struct Gmac { @@ -220,12 +222,11 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out, \brief This is to help with setting keys to correct encrypt or decrypt type. - \note Is up to user to call wc_AesFree on tweak and aes key when done. + \note Is up to user to call wc_AesXtsFree on aes key when done. \return 0 Success - \param tweak AES key for tweak in XTS - \param aes AES key for encrypt/decrypt process + \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. @@ -235,22 +236,20 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out, _Example_ \code - Aes aes; - Aes tweak; + XtsAes aes; - if(wc_AesXtsSetKey(&tweak, &aes, key, sizeof(key), AES_ENCRYPTION, NULL, 0) != 0) + if(wc_AesXtsSetKey(&aes, key, sizeof(key), AES_ENCRYPTION, NULL, 0) != 0) { // Handle error } - wc_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); \endcode \sa wc_AesXtsEncrypt \sa wc_AesXtsDecrypt - \sa wc_AesFree + \sa wc_AesXtsFree */ -WOLFSSL_API int wc_AesXtsSetKey(Aes* tweak, Aes* aes, const byte* key, +WOLFSSL_API int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir, void* heap, int devId); @@ -263,8 +262,7 @@ WOLFSSL_API int wc_AesXtsSetKey(Aes* tweak, Aes* aes, const byte* key, \return 0 Success - \param tweak tweak AES tweak key to use - \param aes AES key to use for block encrypt/decrypt + \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 @@ -272,28 +270,26 @@ WOLFSSL_API int wc_AesXtsSetKey(Aes* tweak, Aes* aes, const byte* key, _Example_ \code - Aes aes; - Aes tweak; + XtsAes aes; unsigned char plain[SIZE]; unsigned char cipher[SIZE]; word64 s = VALUE; //set up keys with AES_ENCRYPTION as dir - if(wc_AesXtsEncryptSector(&tweak, &aes, cipher, plain, SIZE, s) != 0) + if(wc_AesXtsEncryptSector(&aes, cipher, plain, SIZE, s) != 0) { // Handle error } - wc_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); \endcode \sa wc_AesXtsEncrypt \sa wc_AesXtsDecrypt \sa wc_AesXtsSetKey - \sa wc_AesFree + \sa wc_AesXtsFree */ -WOLFSSL_API int wc_AesXtsEncryptSector(Aes* tweak, Aes* aes, byte* out, +WOLFSSL_API int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz, word64 sector); @@ -306,8 +302,7 @@ WOLFSSL_API int wc_AesXtsEncryptSector(Aes* tweak, Aes* aes, byte* out, \return 0 Success - \param tweak AES tweak key to use - \param aes AES key to use for block encrypt/decrypt + \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 @@ -315,28 +310,26 @@ WOLFSSL_API int wc_AesXtsEncryptSector(Aes* tweak, Aes* aes, byte* out, _Example_ \code - Aes aes; - Aes tweak; + 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(&tweak, &aes, plain, cipher, SIZE, s) != 0) + if(wc_AesXtsDecryptSector(&aes, plain, cipher, SIZE, s) != 0) { // Handle error } - wc_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); \endcode \sa wc_AesXtsEncrypt \sa wc_AesXtsDecrypt \sa wc_AesXtsSetKey - \sa wc_AesFree + \sa wc_AesXtsFree */ -WOLFSSL_API int wc_AesXtsDecryptSector(Aes* tweak, Aes* aes, byte* out, +WOLFSSL_API int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz, word64 sector); @@ -348,8 +341,7 @@ WOLFSSL_API int wc_AesXtsDecryptSector(Aes* tweak, Aes* aes, byte* out, \return 0 Success - \param tweak AES tweak key to use - \param aes AES key to use for block encrypt/decrypt + \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 @@ -360,27 +352,25 @@ WOLFSSL_API int wc_AesXtsDecryptSector(Aes* tweak, Aes* aes, byte* out, _Example_ \code - Aes aes; - Aes tweak; + 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(&tweak, &aes, cipher, plain, SIZE, i, sizeof(i)) != 0) + if(wc_AesXtsEncrypt(&aes, cipher, plain, SIZE, i, sizeof(i)) != 0) { // Handle error } - wc_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); \endcode \sa wc_AesXtsDecrypt \sa wc_AesXtsSetKey - \sa wc_AesFree + \sa wc_AesXtsFree */ -WOLFSSL_API int wc_AesXtsEncrypt(Aes* tweak, Aes* aes, byte* out, +WOLFSSL_API int wc_AesXtsEncrypt(XtsAes* aes, byte* out, const byte* in, word32 sz, const byte* i, word32 iSz); @@ -391,8 +381,7 @@ WOLFSSL_API int wc_AesXtsEncrypt(Aes* tweak, Aes* aes, byte* out, \return 0 Success - \param tweak AES tweak key to use - \param aes AES key to use for block encrypt/decrypt + \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 @@ -402,28 +391,53 @@ WOLFSSL_API int wc_AesXtsEncrypt(Aes* tweak, Aes* aes, byte* out, function. _Example_ \code - Aes aes; - Aes tweak; + 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(&tweak, &aes, plain, cipher, SIZE, i, sizeof(i)) != 0) + if(wc_AesXtsDecrypt(&aes, plain, cipher, SIZE, i, sizeof(i)) != 0) { // Handle error } - wc_AesFree(&aes); - wc_AesFree(&tweak); + wc_AesXtsFree(&aes); \endcode \sa wc_AesXtsEncrypt \sa wc_AesXtsSetKey - \sa wc_AesFree + \sa wc_AesXtsFree */ -WOLFSSL_API int wc_AesXtsDecrypt(Aes* tweak, Aes* aes, byte* out, +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);