Merge pull request #7522 from douzzer/20240511-aes-xts-stream

20240511-aes-xts-stream
This commit is contained in:
David Garske
2024-05-15 06:22:20 -07:00
committed by GitHub
9 changed files with 4776 additions and 92 deletions

View File

@@ -39,7 +39,8 @@ jobs:
fail-fast: false
matrix:
# List of refs to test
ref: [ release/2.6, v2.6.0, master ]
# disabled master on 20240514 -- see https://github.com/wolfSSL/wolfssl/issues/7508
ref: [ release/2.6, v2.6.0 ]
name: ${{ matrix.ref }}
runs-on: ubuntu-latest
# This should be a safe limit for the tests to run.

View File

@@ -939,6 +939,7 @@ then
if test "$ENABLED_FIPS" = "no" || test "$HAVE_FIPS_VERSION" -ge 6 || test "$FIPS_VERSION" = "v5-dev"; then
test "$enable_aesxts" = "" && enable_aesxts=yes
test "$enable_aesxts_stream" = "" && test "$enable_aesxts" = "yes" && (test "$enable_armasm" = "" || test "$enable_armasm" = "no") && enable_aesxts_stream=yes
test "$enable_aessiv" = "" && enable_aessiv=yes
fi
@@ -1078,6 +1079,7 @@ then
if test "$ENABLED_FIPS" = "no" || test "$HAVE_FIPS_VERSION" -ge 6 || test "$FIPS_VERSION" = "v5-dev"; then
test "$enable_aesxts" = "" && enable_aesxts=yes
test "$enable_aesxts_stream" = "" && test "$enable_aesxts" = "yes" && (test "$enable_armasm" = "" || test "$enable_armasm" = "no") && enable_aesxts_stream=yes
test "$enable_aessiv" = "" && enable_aessiv=yes
fi
@@ -4848,6 +4850,17 @@ AC_ARG_ENABLE([aesxts],
[ ENABLED_AESXTS=no ]
)
AS_IF([test "$ENABLED_AESXTS" = "yes" && test "$ENABLED_ARMASM" = "no"],
[ ENABLED_AESXTS_STREAM_DEFAULT=yes ],
[ ENABLED_AESXTS_STREAM_DEFAULT=no ]
)
AC_ARG_ENABLE([aesxts-stream],
[AS_HELP_STRING([--enable-aesxts-stream],[Enable wolfSSL AES-XTS support with streaming APIs (default: disabled)])],
[ ENABLED_AESXTS_STREAM=$enableval ],
[ ENABLED_AESXTS_STREAM=$ENABLED_AESXTS_STREAM_DEFAULT ]
)
# legacy old option name, for compatibility:
AC_ARG_ENABLE([xts],
[AS_HELP_STRING([--enable-xts],[Please use --enable-aesxts])],
@@ -5070,6 +5083,9 @@ AS_CASE([$FIPS_VERSION],
AS_IF([test "x$ENABLED_AESXTS" = "xyes" && test "x$ENABLED_AESNI" = "xyes"],
[AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_AES_XTS"])
AS_IF([test "x$ENABLED_AESXTS_STREAM" = "xno" && ! (test "$ENABLED_ARMASM" = "yes" || test "$ENABLED_ARMASM_CRYPTO" = "no")],
[ENABLED_AESXTS_STREAM="yes"])
AS_IF([(test "$ENABLED_AESCCM" = "yes" && test "$HAVE_AESCCM_PORT" != "yes") ||
(test "$ENABLED_AESCTR" = "yes" && test "$HAVE_AESCTR_PORT" != "yes") ||
(test "$ENABLED_AESGCM" = "yes" && test "$HAVE_AESGCM_PORT" != "yes") ||
@@ -8351,15 +8367,20 @@ then
for lkcapi_alg in $(echo "$ENABLED_LINUXKM_LKCAPI_REGISTER" | tr ',' ' ')
do
case "$lkcapi_alg" in
all) AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_ALL" ;;
all) test "$ENABLED_EXPERIMENTAL" = "yes" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: requires --enable-experimental.])
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_ALL" ;;
'cbc(aes)') test "$ENABLED_AESCBC" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-CBC implementation not enabled.])
test "$ENABLED_EXPERIMENTAL" = "yes" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: requires --enable-experimental.])
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESCBC" ;;
'cfb(aes)') test "$ENABLED_AESCFB" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-CFB implementation not enabled.])
test "$ENABLED_EXPERIMENTAL" = "yes" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: requires --enable-experimental.])
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESCFB" ;;
'gcm(aes)') test "$ENABLED_AESGCM" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-GCM implementation not enabled.])
test "$ENABLED_AESGCM_STREAM" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: --enable-aesgcm-stream is required for LKCAPI.])
test "$ENABLED_EXPERIMENTAL" = "yes" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: requires --enable-experimental.])
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESGCM" ;;
'xts(aes)') test "$ENABLED_AESXTS" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: AES-XTS implementation not enabled.])
test "$ENABLED_AESXTS_STREAM" != "no" || AC_MSG_ERROR([linuxkm-lkcapi-register ${lkcapi_alg}: --enable-aesxts-stream is required for LKCAPI.])
AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER_AESXTS" ;;
*) AC_MSG_ERROR([Unsupported LKCAPI algorithm "$lkcapi_alg".]) ;;
esac
@@ -9009,6 +9030,17 @@ then
fi
fi
if test "$ENABLED_AESXTS_STREAM" != "no"
then
if test "$ENABLED_AESXTS" = "no"
then
AC_MSG_ERROR([AES-XTS streaming enabled but AES-XTS is disabled])
else
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AESXTS_STREAM"
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_AESXTS_STREAM"
fi
fi
if test "$ENABLED_IOTSAFE" != "no"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_IOTSAFE"
@@ -9769,6 +9801,7 @@ echo " * AES-CTR: $ENABLED_AESCTR"
echo " * AES-CFB: $ENABLED_AESCFB"
echo " * AES-OFB: $ENABLED_AESOFB"
echo " * AES-XTS: $ENABLED_AESXTS"
echo " * AES-XTS streaming: $ENABLED_AESXTS_STREAM"
echo " * AES-SIV: $ENABLED_AESSIV"
echo " * AES-EAX: $ENABLED_AESEAX"
echo " * AES Bitspliced: $ENABLED_AESBS"

View File

@@ -75,16 +75,25 @@
#if defined(HAVE_AES_CBC) && \
(defined(LINUXKM_LKCAPI_REGISTER_ALL) || \
defined(LINUXKM_LKCAPI_REGISTER_AESCBC))
#ifndef WOLFSSL_EXPERIMENTAL_SETTINGS
#error Experimental settings without WOLFSSL_EXPERIMENTAL_SETTINGS
#endif
static int linuxkm_test_aescbc(void);
#endif
#if defined(WOLFSSL_AES_CFB) && \
(defined(LINUXKM_LKCAPI_REGISTER_ALL) || \
defined(LINUXKM_LKCAPI_REGISTER_AESCFB))
#ifndef WOLFSSL_EXPERIMENTAL_SETTINGS
#error Experimental settings without WOLFSSL_EXPERIMENTAL_SETTINGS
#endif
static int linuxkm_test_aescfb(void);
#endif
#if defined(HAVE_AESGCM) && \
(defined(LINUXKM_LKCAPI_REGISTER_ALL) || \
defined(LINUXKM_LKCAPI_REGISTER_AESGCM))
#ifndef WOLFSSL_EXPERIMENTAL_SETTINGS
#error Experimental settings without WOLFSSL_EXPERIMENTAL_SETTINGS
#endif
static int linuxkm_test_aesgcm(void);
#endif
#if defined(WOLFSSL_AES_XTS) && \
@@ -790,6 +799,10 @@ static int gcmAesAead_loaded = 0;
(defined(LINUXKM_LKCAPI_REGISTER_ALL) || \
defined(LINUXKM_LKCAPI_REGISTER_AESXTS))
#ifndef WOLFSSL_AESXTS_STREAM
#error LKCAPI registration of AES-XTS requires WOLFSSL_AESXTS_STREAM (--enable-aesxts-stream).
#endif
struct km_AesXtsCtx {
XtsAes *aesXts; /* allocated in km_AesXtsInitCommon() to assure alignment
* for AESNI.
@@ -835,6 +848,16 @@ static int km_AesXtsSetKey(struct crypto_skcipher *tfm, const u8 *in_key,
int err;
struct km_AesXtsCtx * ctx = crypto_skcipher_ctx(tfm);
/* filter bad keysizes here, to avoid console noise from
* CONFIG_CRYPTO_MANAGER_EXTRA_TESTS.
*/
if ((key_len != (AES_128_KEY_SIZE*2)) &&
(key_len != (AES_192_KEY_SIZE*2)) &&
(key_len != (AES_256_KEY_SIZE*2)))
{
return -EINVAL;
}
err = wc_AesXtsSetKeyNoInit(ctx->aesXts, in_key, key_len,
AES_ENCRYPTION_AND_DECRYPTION);
@@ -852,7 +875,6 @@ static int km_AesXtsSetKey(struct crypto_skcipher *tfm, const u8 *in_key,
static int km_AesXtsEncrypt(struct skcipher_request *req)
{
int err = 0;
struct crypto_skcipher * tfm = NULL;
struct km_AesXtsCtx * ctx = NULL;
struct skcipher_walk walk;
@@ -861,6 +883,9 @@ static int km_AesXtsEncrypt(struct skcipher_request *req)
tfm = crypto_skcipher_reqtfm(req);
ctx = crypto_skcipher_ctx(tfm);
if (req->cryptlen < AES_BLOCK_SIZE)
return -EINVAL;
err = skcipher_walk_virt(&walk, req, false);
if (unlikely(err)) {
@@ -869,10 +894,9 @@ static int km_AesXtsEncrypt(struct skcipher_request *req)
return err;
}
while ((nbytes = walk.nbytes) != 0) {
if (walk.nbytes == walk.total) {
err = wc_AesXtsEncrypt(ctx->aesXts, walk.dst.virt.addr,
walk.src.virt.addr, nbytes,
walk.iv, walk.ivsize);
walk.src.virt.addr, walk.nbytes, walk.iv, walk.ivsize);
if (unlikely(err)) {
pr_err("%s: wc_AesXtsEncrypt failed: %d\n",
@@ -880,12 +904,92 @@ static int km_AesXtsEncrypt(struct skcipher_request *req)
return -EINVAL;
}
err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
err = skcipher_walk_done(&walk, 0);
} else {
int tail = req->cryptlen % AES_BLOCK_SIZE;
struct skcipher_request subreq;
if (tail > 0) {
int blocks = DIV_ROUND_UP(req->cryptlen, AES_BLOCK_SIZE) - 2;
skcipher_walk_abort(&walk);
skcipher_request_set_tfm(&subreq, tfm);
skcipher_request_set_callback(&subreq,
skcipher_request_flags(req),
NULL, NULL);
skcipher_request_set_crypt(&subreq, req->src, req->dst,
blocks * AES_BLOCK_SIZE, req->iv);
req = &subreq;
err = skcipher_walk_virt(&walk, req, false);
if (!walk.nbytes)
return err ? : -EINVAL;
} else {
tail = 0;
}
err = wc_AesXtsEncryptInit(ctx->aesXts, walk.iv, walk.ivsize);
if (unlikely(err)) {
pr_err("%s: skcipher_walk_done failed: %d\n",
pr_err("%s: wc_AesXtsEncryptInit failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return err;
return -EINVAL;
}
while ((nbytes = walk.nbytes) != 0) {
/* if this isn't the final call, pass block-aligned data to prevent
* end-of-message ciphertext stealing.
*/
if (nbytes < walk.total)
nbytes &= ~(AES_BLOCK_SIZE - 1);
err = wc_AesXtsEncryptUpdate(ctx->aesXts, walk.dst.virt.addr,
walk.src.virt.addr, nbytes,
walk.iv);
if (unlikely(err)) {
pr_err("%s: wc_AesXtsEncryptUpdate failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return -EINVAL;
}
err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
if (unlikely(err)) {
pr_err("%s: skcipher_walk_done failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return err;
}
}
if (unlikely(tail > 0)) {
struct scatterlist sg_src[2], sg_dst[2];
struct scatterlist *src, *dst;
dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen);
if (req->dst != req->src)
dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen);
skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail,
req->iv);
err = skcipher_walk_virt(&walk, &subreq, false);
if (err)
return err;
err = wc_AesXtsEncryptUpdate(ctx->aesXts, walk.dst.virt.addr,
walk.src.virt.addr, walk.nbytes,
walk.iv);
if (unlikely(err)) {
pr_err("%s: wc_AesXtsEncryptUpdate failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return -EINVAL;
}
err = skcipher_walk_done(&walk, 0);
}
}
@@ -903,6 +1007,9 @@ static int km_AesXtsDecrypt(struct skcipher_request *req)
tfm = crypto_skcipher_reqtfm(req);
ctx = crypto_skcipher_ctx(tfm);
if (req->cryptlen < AES_BLOCK_SIZE)
return -EINVAL;
err = skcipher_walk_virt(&walk, req, false);
if (unlikely(err)) {
@@ -911,26 +1018,107 @@ static int km_AesXtsDecrypt(struct skcipher_request *req)
return err;
}
while ((nbytes = walk.nbytes) != 0) {
err = wc_AesXtsDecrypt(ctx->aesXts, walk.dst.virt.addr,
walk.src.virt.addr, nbytes,
walk.iv, walk.ivsize);
if (walk.nbytes == walk.total) {
err = wc_AesXtsDecrypt(ctx->aesXts,
walk.dst.virt.addr, walk.src.virt.addr,
walk.nbytes, walk.iv, walk.ivsize);
if (unlikely(err)) {
pr_err("%s: wc_AesCbcDecrypt failed: %d\n",
pr_err("%s: wc_AesXtsDecrypt failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return -EINVAL;
}
err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
err = skcipher_walk_done(&walk, 0);
} else {
int tail = req->cryptlen % AES_BLOCK_SIZE;
struct skcipher_request subreq;
if (unlikely(tail > 0)) {
int blocks = DIV_ROUND_UP(req->cryptlen, AES_BLOCK_SIZE) - 2;
skcipher_walk_abort(&walk);
skcipher_request_set_tfm(&subreq, tfm);
skcipher_request_set_callback(&subreq,
skcipher_request_flags(req),
NULL, NULL);
skcipher_request_set_crypt(&subreq, req->src, req->dst,
blocks * AES_BLOCK_SIZE, req->iv);
req = &subreq;
err = skcipher_walk_virt(&walk, req, false);
if (!walk.nbytes)
return err ? : -EINVAL;
} else {
tail = 0;
}
err = wc_AesXtsDecryptInit(ctx->aesXts, walk.iv, walk.ivsize);
if (unlikely(err)) {
pr_err("%s: skcipher_walk_done failed: %d\n",
pr_err("%s: wc_AesXtsDecryptInit failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return err;
return -EINVAL;
}
}
while ((nbytes = walk.nbytes) != 0) {
/* if this isn't the final call, pass block-aligned data to prevent
* end-of-message ciphertext stealing.
*/
if (nbytes < walk.total)
nbytes &= ~(AES_BLOCK_SIZE - 1);
err = wc_AesXtsDecryptUpdate(ctx->aesXts, walk.dst.virt.addr,
walk.src.virt.addr, nbytes,
walk.iv);
if (unlikely(err)) {
pr_err("%s: wc_AesXtsDecryptUpdate failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return -EINVAL;
}
err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
if (unlikely(err)) {
pr_err("%s: skcipher_walk_done failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return err;
}
}
if (unlikely(tail > 0)) {
struct scatterlist sg_src[2], sg_dst[2];
struct scatterlist *src, *dst;
dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen);
if (req->dst != req->src)
dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen);
skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail,
req->iv);
err = skcipher_walk_virt(&walk, &subreq, false);
if (err)
return err;
err = wc_AesXtsDecryptUpdate(ctx->aesXts, walk.dst.virt.addr,
walk.src.virt.addr, walk.nbytes,
walk.iv);
if (unlikely(err)) {
pr_err("%s: wc_AesXtsDecryptUpdate failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return -EINVAL;
}
err = skcipher_walk_done(&walk, 0);
}
}
return err;
}
@@ -1834,6 +2022,25 @@ static int aes_xts_128_test(void)
XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ);
XMEMCPY(iv, i2, sizeof(i2));
ret = wc_AesXtsEncryptInit(aes, iv, sizeof(iv));
if (ret != 0)
goto out;
ret = wc_AesXtsEncryptUpdate(aes, buf, p2, AES_BLOCK_SIZE, iv);
if (ret != 0)
goto out;
ret = wc_AesXtsEncryptUpdate(aes, buf + AES_BLOCK_SIZE,
p2 + AES_BLOCK_SIZE,
sizeof(p2) - AES_BLOCK_SIZE, iv);
if (ret != 0)
goto out;
if (XMEMCMP(c2, buf, sizeof(c2))) {
ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E;
goto out;
}
XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ);
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION);
if (ret != 0)
goto out;
@@ -1985,6 +2192,7 @@ static int aes_xts_128_test(void)
#define LARGE_XTS_SZ 1024
int i;
int j;
int k;
large_input = (byte *)XMALLOC(LARGE_XTS_SZ, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
@@ -1996,6 +2204,38 @@ static int aes_xts_128_test(void)
for (i = 0; i < (int)LARGE_XTS_SZ; i++)
large_input[i] = (byte)i;
/* first, encrypt block by block then decrypt with a one-shot call. */
for (j = 16; j < (int)LARGE_XTS_SZ; j++) {
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION);
if (ret != 0)
goto out;
XMEMCPY(iv, i1, sizeof(i1));
ret = wc_AesXtsEncryptInit(aes, iv, sizeof(iv));
if (ret != 0)
goto out;
for (k = 0; k < j; k += AES_BLOCK_SIZE) {
ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, (j - k) < AES_BLOCK_SIZE*2 ? j - k : AES_BLOCK_SIZE, iv);
if (ret != 0)
goto out;
if ((j - k) < AES_BLOCK_SIZE*2)
break;
}
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION);
if (ret != 0)
goto out;
ret = wc_AesXtsDecrypt(aes, large_input, large_input, j, i1,
sizeof(i1));
if (ret != 0)
goto out;
for (i = 0; i < j; i++) {
if (large_input[i] != (byte)i) {
ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E;
goto out;
}
}
}
/* second, encrypt with a one-shot call then decrypt block by block. */
for (j = 16; j < (int)LARGE_XTS_SZ; j++) {
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION);
if (ret != 0)
@@ -2004,14 +2244,20 @@ static int aes_xts_128_test(void)
sizeof(i1));
if (ret != 0)
goto out;
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION);
if (ret != 0)
goto out;
ret = wc_AesXtsDecrypt(aes, large_input, large_input, j, i1,
sizeof(i1));
XMEMCPY(iv, i1, sizeof(i1));
ret = wc_AesXtsDecryptInit(aes, iv, sizeof(iv));
if (ret != 0)
goto out;
for (k = 0; k < j; k += AES_BLOCK_SIZE) {
ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, (j - k) < AES_BLOCK_SIZE*2 ? j - k : AES_BLOCK_SIZE, iv);
if (ret != 0)
goto out;
if ((j - k) < AES_BLOCK_SIZE*2)
break;
}
for (i = 0; i < j; i++) {
if (large_input[i] != (byte)i) {
ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E;
@@ -2237,6 +2483,7 @@ static int aes_xts_256_test(void)
struct crypto_skcipher *tfm = NULL;
struct skcipher_request *req = NULL;
u8 iv[AES_BLOCK_SIZE];
byte* large_input = NULL;
/* 256 key tests */
static const unsigned char k1[] = {
@@ -2355,6 +2602,25 @@ static int aes_xts_256_test(void)
goto out;
}
XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ);
XMEMCPY(iv, i2, sizeof(i2));
ret = wc_AesXtsEncryptInit(aes, iv, sizeof(iv));
if (ret != 0)
goto out;
ret = wc_AesXtsEncryptUpdate(aes, buf, p2, AES_BLOCK_SIZE, iv);
if (ret != 0)
goto out;
ret = wc_AesXtsEncryptUpdate(aes, buf + AES_BLOCK_SIZE,
p2 + AES_BLOCK_SIZE,
sizeof(p2) - AES_BLOCK_SIZE, iv);
if (ret != 0)
goto out;
if (XMEMCMP(c2, buf, sizeof(c2))) {
ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E;
goto out;
}
XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ);
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION);
if (ret != 0)
@@ -2408,6 +2674,85 @@ static int aes_xts_256_test(void)
goto out;
}
{
#define LARGE_XTS_SZ 1024
int i;
int j;
int k;
large_input = (byte *)XMALLOC(LARGE_XTS_SZ, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (large_input == NULL) {
ret = MEMORY_E;
goto out;
}
for (i = 0; i < (int)LARGE_XTS_SZ; i++)
large_input[i] = (byte)i;
/* first, encrypt block by block then decrypt with a one-shot call. */
for (j = 16; j < (int)LARGE_XTS_SZ; j++) {
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION);
if (ret != 0)
goto out;
XMEMCPY(iv, i1, sizeof(i1));
ret = wc_AesXtsEncryptInit(aes, iv, sizeof(iv));
if (ret != 0)
goto out;
for (k = 0; k < j; k += AES_BLOCK_SIZE) {
ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, (j - k) < AES_BLOCK_SIZE*2 ? j - k : AES_BLOCK_SIZE, iv);
if (ret != 0)
goto out;
if ((j - k) < AES_BLOCK_SIZE*2)
break;
}
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION);
if (ret != 0)
goto out;
ret = wc_AesXtsDecrypt(aes, large_input, large_input, j, i1,
sizeof(i1));
if (ret != 0)
goto out;
for (i = 0; i < j; i++) {
if (large_input[i] != (byte)i) {
ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E;
goto out;
}
}
}
/* second, encrypt with a one-shot call then decrypt block by block. */
for (j = 16; j < (int)LARGE_XTS_SZ; j++) {
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION);
if (ret != 0)
goto out;
ret = wc_AesXtsEncrypt(aes, large_input, large_input, j, i1,
sizeof(i1));
if (ret != 0)
goto out;
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION);
if (ret != 0)
goto out;
XMEMCPY(iv, i1, sizeof(i1));
ret = wc_AesXtsDecryptInit(aes, iv, sizeof(iv));
if (ret != 0)
goto out;
for (k = 0; k < j; k += AES_BLOCK_SIZE) {
ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, (j - k) < AES_BLOCK_SIZE*2 ? j - k : AES_BLOCK_SIZE, iv);
if (ret != 0)
goto out;
if ((j - k) < AES_BLOCK_SIZE*2)
break;
}
for (i = 0; i < j; i++) {
if (large_input[i] != (byte)i) {
ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E;
goto out;
}
}
}
}
/* now the kernel crypto part */
enc2 = XMALLOC(sizeof(p1), NULL, DYNAMIC_TYPE_AES);
@@ -2587,6 +2932,9 @@ static int aes_xts_256_test(void)
out:
if (large_input)
XFREE(large_input, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (aes_inited)
wc_AesXtsFree(aes);

View File

@@ -189,8 +189,7 @@ static struct wc_thread_fpu_count_ent *wc_linuxkm_fpu_state_assoc(int create_p)
* dependency loop on intelasm builds, we allocate here.
* this is not thread-safe and doesn't need to be.
*/
int ret = allocate_wolfcrypt_linuxkm_fpu_states();
if (ret != 0)
if ((! create_p) || (allocate_wolfcrypt_linuxkm_fpu_states() != 0))
#endif
{
if (_warned_on_null == 0) {

View File

@@ -12336,12 +12336,16 @@ int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir)
return BAD_FUNC_ARG;
}
keySz = len/2;
if (keySz != AES_128_KEY_SIZE && keySz != AES_256_KEY_SIZE) {
if ((len != (AES_128_KEY_SIZE*2)) &&
(len != (AES_192_KEY_SIZE*2)) &&
(len != (AES_256_KEY_SIZE*2)))
{
WOLFSSL_MSG("Unsupported key size");
return WC_KEY_SIZE_E;
}
keySz = len/2;
#ifdef HAVE_FIPS
if (XMEMCMP(key, key + keySz, keySz) == 0) {
WOLFSSL_MSG("FIPS AES-XTS main and tweak keys must differ");
@@ -12525,12 +12529,28 @@ void AES_XTS_encrypt_aesni(const unsigned char *in, unsigned char *out, word32 s
const unsigned char* i, const unsigned char* key,
const unsigned char* key2, int nr)
XASM_LINK("AES_XTS_encrypt_aesni");
#ifdef WOLFSSL_AESXTS_STREAM
void AES_XTS_init_aesni(unsigned char* i, const unsigned char* tweak_key,
int tweak_nr)
XASM_LINK("AES_XTS_init_aesni");
void AES_XTS_encrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
const unsigned char* key, unsigned char *i, int nr)
XASM_LINK("AES_XTS_encrypt_update_aesni");
#endif
#ifdef HAVE_INTEL_AVX1
void AES_XTS_encrypt_avx1(const unsigned char *in, unsigned char *out,
word32 sz, const unsigned char* i,
const unsigned char* key, const unsigned char* key2,
int nr)
XASM_LINK("AES_XTS_encrypt_avx1");
word32 sz, const unsigned char* i,
const unsigned char* key, const unsigned char* key2,
int nr)
XASM_LINK("AES_XTS_encrypt_avx1");
#ifdef WOLFSSL_AESXTS_STREAM
void AES_XTS_init_avx1(unsigned char* i, const unsigned char* tweak_key,
int tweak_nr)
XASM_LINK("AES_XTS_init_avx1");
void AES_XTS_encrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
const unsigned char* key, unsigned char *i, int nr)
XASM_LINK("AES_XTS_encrypt_update_avx1");
#endif
#endif /* HAVE_INTEL_AVX1 */
#ifdef HAVE_AES_DECRYPT
@@ -12538,12 +12558,22 @@ void AES_XTS_decrypt_aesni(const unsigned char *in, unsigned char *out, word32 s
const unsigned char* i, const unsigned char* key,
const unsigned char* key2, int nr)
XASM_LINK("AES_XTS_decrypt_aesni");
#ifdef WOLFSSL_AESXTS_STREAM
void AES_XTS_decrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
const unsigned char* key, unsigned char *i, int nr)
XASM_LINK("AES_XTS_decrypt_update_aesni");
#endif
#ifdef HAVE_INTEL_AVX1
void AES_XTS_decrypt_avx1(const unsigned char *in, unsigned char *out,
word32 sz, const unsigned char* i,
const unsigned char* key, const unsigned char* key2,
int nr)
XASM_LINK("AES_XTS_decrypt_avx1");
word32 sz, const unsigned char* i,
const unsigned char* key, const unsigned char* key2,
int nr)
XASM_LINK("AES_XTS_decrypt_avx1");
#ifdef WOLFSSL_AESXTS_STREAM
void AES_XTS_decrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
const unsigned char* key, unsigned char *i, int nr)
XASM_LINK("AES_XTS_decrypt_update_avx1");
#endif
#endif /* HAVE_INTEL_AVX1 */
#endif /* HAVE_AES_DECRYPT */
@@ -12590,7 +12620,6 @@ static WARN_UNUSED_RESULT int _AesXtsHelper(
}
#endif /* HAVE_AES_ECB */
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
*
* xaes AES keys to use for block encrypt/decrypt
@@ -12602,27 +12631,63 @@ static WARN_UNUSED_RESULT int _AesXtsHelper(
* returns 0 on success
*/
/* Software AES - XTS Encrypt */
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
word32 sz,
byte *i);
static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
const byte* i)
{
int ret;
byte tweak_block[AES_BLOCK_SIZE];
ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
if (ret != 0)
return ret;
return AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
}
#ifdef WOLFSSL_AESXTS_STREAM
/* Block-streaming AES-XTS tweak setup.
*
* xaes AES keys to use for block encrypt/decrypt
* i readwrite value to use for tweak
*
* returns 0 on success
*/
static int AesXtsInitTweak_sw(XtsAes* xaes, byte* i) {
return wc_AesEncryptDirect(&xaes->tweak, i, i);
}
#endif /* WOLFSSL_AESXTS_STREAM */
/* Block-streaming AES-XTS.
*
* Supply block-aligned input data with successive calls. Final call need not
* be block aligned.
*
* 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
*
* returns 0 on success
*/
/* Software AES - XTS Encrypt */
static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
word32 sz,
byte *i)
{
int ret = 0;
word32 blocks = (sz / AES_BLOCK_SIZE);
Aes *aes = &xaes->aes;
Aes *tweak = &xaes->tweak;
byte tmp[AES_BLOCK_SIZE];
XMEMSET(tmp, 0, AES_BLOCK_SIZE); /* set to 0's in case of improper AES
* key setup passed to encrypt direct*/
ret = wc_AesEncryptDirect(tweak, tmp, i);
if (ret != 0)
return ret;
#ifdef HAVE_AES_ECB
/* encrypt all of buffer at once when possible */
if (in != out) { /* can not handle inline */
XMEMCPY(out, tmp, AES_BLOCK_SIZE);
XMEMCPY(out, i, AES_BLOCK_SIZE);
if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0)
return ret;
}
@@ -12639,23 +12704,23 @@ static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
byte buf[AES_BLOCK_SIZE];
XMEMCPY(buf, in, AES_BLOCK_SIZE);
xorbuf(buf, tmp, AES_BLOCK_SIZE);
xorbuf(buf, i, AES_BLOCK_SIZE);
ret = wc_AesEncryptDirect(aes, out, buf);
if (ret != 0)
return ret;
}
xorbuf(out, tmp, AES_BLOCK_SIZE);
xorbuf(out, i, AES_BLOCK_SIZE);
/* multiply by shift left and propagate carry */
for (j = 0; j < AES_BLOCK_SIZE; j++) {
byte tmpC;
tmpC = (tmp[j] >> 7) & 0x01;
tmp[j] = (byte)((tmp[j] << 1) + carry);
tmpC = (i[j] >> 7) & 0x01;
i[j] = (byte)((i[j] << 1) + carry);
carry = tmpC;
}
if (carry) {
tmp[0] ^= GF_XTS;
i[0] ^= GF_XTS;
}
in += AES_BLOCK_SIZE;
@@ -12684,10 +12749,10 @@ static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
XMEMCPY(out, buf2, sz);
}
xorbuf(buf, tmp, AES_BLOCK_SIZE);
xorbuf(buf, i, AES_BLOCK_SIZE);
ret = wc_AesEncryptDirect(aes, out - AES_BLOCK_SIZE, buf);
if (ret == 0)
xorbuf(out - AES_BLOCK_SIZE, tmp, AES_BLOCK_SIZE);
xorbuf(out - AES_BLOCK_SIZE, i, AES_BLOCK_SIZE);
}
return ret;
@@ -12773,6 +12838,144 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
return ret;
}
#ifdef WOLFSSL_AESXTS_STREAM
/* Block-streaming AES-XTS.
*
* xaes AES keys to use for block encrypt/decrypt
* i readwrite 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_AesXtsEncryptInit(XtsAes* xaes, byte* i, word32 iSz)
{
int ret;
Aes *aes;
if ((xaes == NULL) || (i == NULL)) {
return BAD_FUNC_ARG;
}
if (iSz < AES_BLOCK_SIZE) {
return BAD_FUNC_ARG;
}
aes = &xaes->aes;
if (aes->keylen == 0) {
WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
return BAD_FUNC_ARG;
}
if (iSz < AES_BLOCK_SIZE) {
return BAD_FUNC_ARG;
}
{
#ifdef WOLFSSL_AESNI
if (aes->use_aesni) {
SAVE_VECTOR_REGISTERS(return _svr_ret;);
#if defined(HAVE_INTEL_AVX1)
if (IS_INTEL_AVX1(intel_flags)) {
AES_XTS_init_avx1(i, (const byte*)xaes->tweak.key,
(int)xaes->tweak.rounds);
ret = 0;
}
else
#endif
{
AES_XTS_init_aesni(i, (const byte*)xaes->tweak.key,
(int)xaes->tweak.rounds);
ret = 0;
}
RESTORE_VECTOR_REGISTERS();
}
else
#endif /* WOLFSSL_AESNI */
{
ret = AesXtsInitTweak_sw(xaes, i);
}
}
return ret;
}
/* Block-streaming AES-XTS
*
* Note that sz must be greater than AES_BLOCK_SIZE in each call, and must be a
* multiple of AES_BLOCK_SIZE in all but the final call.
*
* 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 -- must be >= AES_BLOCK_SIZE.
* 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_AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
byte *i)
{
int ret;
#ifdef WOLFSSL_AESNI
Aes *aes;
#endif
if (xaes == NULL || out == NULL || in == NULL || i == NULL) {
return BAD_FUNC_ARG;
}
#ifdef WOLFSSL_AESNI
aes = &xaes->aes;
#endif
if (sz < AES_BLOCK_SIZE) {
WOLFSSL_MSG("Plain text input too small for encryption");
return BAD_FUNC_ARG;
}
{
#ifdef WOLFSSL_AESNI
if (aes->use_aesni) {
SAVE_VECTOR_REGISTERS(return _svr_ret;);
#if defined(HAVE_INTEL_AVX1)
if (IS_INTEL_AVX1(intel_flags)) {
AES_XTS_encrypt_update_avx1(in, out, sz,
(const byte*)aes->key,
i,
(int)aes->rounds);
ret = 0;
}
else
#endif
{
AES_XTS_encrypt_update_aesni(in, out, sz,
(const byte*)aes->key,
i,
(int)aes->rounds);
ret = 0;
}
RESTORE_VECTOR_REGISTERS();
}
else
#endif /* WOLFSSL_AESNI */
{
ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, i);
}
}
return ret;
}
#endif /* WOLFSSL_AESXTS_STREAM */
/* Same process as encryption but use aes_decrypt key.
*
* xaes AES keys to use for block encrypt/decrypt
@@ -12784,8 +12987,41 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
* returns 0 on success
*/
/* Software AES - XTS Decrypt */
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
word32 sz, byte *i);
static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
const byte* i)
{
int ret;
byte tweak_block[AES_BLOCK_SIZE];
ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
if (ret != 0)
return ret;
return AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
}
/* Block-streaming AES-XTS.
*
* Same process as encryption but use decrypt key.
*
* Supply block-aligned input data with successive calls. Final call need not
* be block aligned.
*
* 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
*
* returns 0 on success
*/
/* Software AES - XTS Decrypt */
static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
word32 sz, byte *i)
{
int ret = 0;
word32 blocks = (sz / AES_BLOCK_SIZE);
@@ -12794,19 +13030,10 @@ static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
#else
Aes *aes = &xaes->aes;
#endif
Aes *tweak = &xaes->tweak;
word32 j;
byte carry = 0;
byte tmp[AES_BLOCK_SIZE];
byte stl = (sz % AES_BLOCK_SIZE);
XMEMSET(tmp, 0, AES_BLOCK_SIZE); /* set to 0's in case of improper AES
* key setup passed to decrypt direct*/
ret = wc_AesEncryptDirect(tweak, tmp, i);
if (ret != 0)
return ret;
/* if Stealing then break out of loop one block early to handle special
* case */
if (stl > 0) {
@@ -12816,7 +13043,7 @@ static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
#ifdef HAVE_AES_ECB
/* decrypt all of buffer at once when possible */
if (in != out) { /* can not handle inline */
XMEMCPY(out, tmp, AES_BLOCK_SIZE);
XMEMCPY(out, i, AES_BLOCK_SIZE);
if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0)
return ret;
}
@@ -12830,23 +13057,23 @@ static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
byte buf[AES_BLOCK_SIZE];
XMEMCPY(buf, in, AES_BLOCK_SIZE);
xorbuf(buf, tmp, AES_BLOCK_SIZE);
xorbuf(buf, i, AES_BLOCK_SIZE);
ret = wc_AesDecryptDirect(aes, out, buf);
if (ret != 0)
return ret;
}
xorbuf(out, tmp, AES_BLOCK_SIZE);
xorbuf(out, i, AES_BLOCK_SIZE);
/* multiply by shift left and propagate carry */
for (j = 0; j < AES_BLOCK_SIZE; j++) {
byte tmpC;
tmpC = (tmp[j] >> 7) & 0x01;
tmp[j] = (byte)((tmp[j] << 1) + carry);
tmpC = (i[j] >> 7) & 0x01;
i[j] = (byte)((i[j] << 1) + carry);
carry = tmpC;
}
if (carry) {
tmp[0] ^= GF_XTS;
i[0] ^= GF_XTS;
}
carry = 0;
@@ -12865,8 +13092,8 @@ static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
for (j = 0; j < AES_BLOCK_SIZE; j++) {
byte tmpC;
tmpC = (tmp[j] >> 7) & 0x01;
tmp2[j] = (byte)((tmp[j] << 1) + carry);
tmpC = (i[j] >> 7) & 0x01;
tmp2[j] = (byte)((i[j] << 1) + carry);
carry = tmpC;
}
if (carry) {
@@ -12894,11 +13121,11 @@ static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
XMEMCPY(buf, in, sz);
XMEMCPY(out, tmp2, sz);
xorbuf(buf, tmp, AES_BLOCK_SIZE);
xorbuf(buf, i, AES_BLOCK_SIZE);
ret = wc_AesDecryptDirect(aes, tmp2, buf);
if (ret != 0)
return ret;
xorbuf(tmp2, tmp, AES_BLOCK_SIZE);
xorbuf(tmp2, i, AES_BLOCK_SIZE);
XMEMCPY(out - AES_BLOCK_SIZE, tmp2, AES_BLOCK_SIZE);
}
@@ -12987,6 +13214,145 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
return ret;
}
}
#ifdef WOLFSSL_AESXTS_STREAM
/* Same process as encryption but Aes key is AES_DECRYPTION type.
*
* xaes AES keys to use for block encrypt/decrypt
* i readwrite 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_AesXtsDecryptInit(XtsAes* xaes, byte* i, word32 iSz)
{
int ret;
Aes *aes;
if (xaes == NULL) {
return BAD_FUNC_ARG;
}
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
aes = &xaes->aes_decrypt;
#else
aes = &xaes->aes;
#endif
if (aes->keylen == 0) {
WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
return BAD_FUNC_ARG;
}
if (iSz < AES_BLOCK_SIZE) {
return BAD_FUNC_ARG;
}
{
#ifdef WOLFSSL_AESNI
if (aes->use_aesni) {
SAVE_VECTOR_REGISTERS(return _svr_ret;);
#if defined(HAVE_INTEL_AVX1)
if (IS_INTEL_AVX1(intel_flags)) {
AES_XTS_init_avx1(i, (const byte*)xaes->tweak.key,
(int)xaes->tweak.rounds);
ret = 0;
}
else
#endif
{
AES_XTS_init_aesni(i, (const byte*)xaes->tweak.key,
(int)xaes->tweak.rounds);
ret = 0;
}
RESTORE_VECTOR_REGISTERS();
}
else
#endif /* WOLFSSL_AESNI */
{
ret = AesXtsInitTweak_sw(xaes, i);
}
}
return ret;
}
/* Block-streaming AES-XTS
*
* Note that sz must be greater than AES_BLOCK_SIZE in each call, and must be a
* multiple of AES_BLOCK_SIZE in all but the final call.
*
* 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 tweak buffer of size AES_BLOCK_SIZE.
*
* returns 0 on success
*/
int wc_AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
byte *i)
{
int ret;
#ifdef WOLFSSL_AESNI
Aes *aes;
#endif
if (xaes == NULL || out == NULL || in == NULL) {
return BAD_FUNC_ARG;
}
#ifdef WOLFSSL_AESNI
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
aes = &xaes->aes_decrypt;
#else
aes = &xaes->aes;
#endif
#endif
if (sz < AES_BLOCK_SIZE) {
WOLFSSL_MSG("Cipher text input too small for decryption");
return BAD_FUNC_ARG;
}
{
#ifdef WOLFSSL_AESNI
if (aes->use_aesni) {
SAVE_VECTOR_REGISTERS(return _svr_ret;);
#if defined(HAVE_INTEL_AVX1)
if (IS_INTEL_AVX1(intel_flags)) {
AES_XTS_decrypt_update_avx1(in, out, sz,
(const byte*)aes->key,
i,
(int)aes->rounds);
ret = 0;
}
else
#endif
{
AES_XTS_decrypt_update_aesni(in, out, sz,
(const byte*)aes->key,
i,
(int)aes->rounds);
ret = 0;
}
RESTORE_VECTOR_REGISTERS();
}
else
#endif /* WOLFSSL_AESNI */
{
ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz, i);
}
}
return ret;
}
#endif /* WOLFSSL_AESXTS_STREAM */
#endif /* !WOLFSSL_ARMASM || WOLFSSL_ARMASM_NO_HW_CRYPTO */
/* Same as wc_AesXtsEncryptSector but the sector gets incremented by one every

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -669,6 +669,20 @@ WOLFSSL_API int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes,
byte* out, const byte* in, word32 sz, word64 sector,
word32 sectorSz);
#ifdef WOLFSSL_AESXTS_STREAM
WOLFSSL_API int wc_AesXtsEncryptInit(XtsAes* aes, byte* i, word32 iSz);
WOLFSSL_API int wc_AesXtsDecryptInit(XtsAes* aes, byte* i, word32 iSz);
WOLFSSL_API int wc_AesXtsEncryptUpdate(XtsAes* aes, byte* out,
const byte* in, word32 sz, byte *i);
WOLFSSL_API int wc_AesXtsDecryptUpdate(XtsAes* aes, byte* out,
const byte* in, word32 sz, byte *i);
#endif /* WOLFSSL_AESXTS_STREAM */
WOLFSSL_API int wc_AesXtsFree(XtsAes* aes);
#endif