wolfcrypt/src/aes.c and wolfssl/wolfcrypt/aes.h: add FIPS_AES_XTS_MAX_BYTES_PER_TWEAK and struct XtsAesStreamData, with improved error checking on streaming AES-XTS APIs;

wolfcrypt/test/test.c and linuxkm/lkcapi_glue.c: update AES-XTS streaming calls to use struct XtsAesStreamData;

linuxkm/lkcapi_glue.c: add handling for CONFIG_CRYPTO_MANAGER*.
This commit is contained in:
Daniel Pouzzner
2024-05-18 22:00:00 -05:00
parent 5c6218696b
commit d0e73783f1
4 changed files with 319 additions and 235 deletions

View File

@ -33,6 +33,12 @@
#define WOLFSSL_LINUXKM_LKCAPI_PRIORITY 10000 #define WOLFSSL_LINUXKM_LKCAPI_PRIORITY 10000
#endif #endif
#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
static int disable_setkey_warnings = 0;
#else
#define disable_setkey_warnings 0
#endif
#ifndef NO_AES #ifndef NO_AES
/* note the FIPS code will be returned on failure even in non-FIPS builds. */ /* note the FIPS code will be returned on failure even in non-FIPS builds. */
@ -198,7 +204,8 @@ static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key,
err = wc_AesSetKey(ctx->aes_encrypt, in_key, key_len, NULL, AES_ENCRYPTION); err = wc_AesSetKey(ctx->aes_encrypt, in_key, key_len, NULL, AES_ENCRYPTION);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesSetKey for encryption key failed: %d\n", name, err); if (! disable_setkey_warnings)
pr_err("%s: wc_AesSetKey for encryption key failed: %d\n", name, err);
return -ENOKEY; return -ENOKEY;
} }
@ -207,8 +214,9 @@ static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key,
AES_DECRYPTION); AES_DECRYPTION);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesSetKey for decryption key failed: %d\n", if (! disable_setkey_warnings)
name, err); pr_err("%s: wc_AesSetKey for decryption key failed: %d\n",
name, err);
return -ENOKEY; return -ENOKEY;
} }
} }
@ -320,8 +328,9 @@ static int km_AesCbcDecrypt(struct skcipher_request *req)
err = wc_AesSetIV(ctx->aes_decrypt, walk.iv); err = wc_AesSetIV(ctx->aes_decrypt, walk.iv);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesSetKey failed: %d\n", if (! disable_setkey_warnings)
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); pr_err("%s: wc_AesSetKey failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return -EINVAL; return -EINVAL;
} }
@ -408,8 +417,9 @@ static int km_AesCfbEncrypt(struct skcipher_request *req)
err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); err = wc_AesSetIV(ctx->aes_encrypt, walk.iv);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesSetKey failed: %d\n", if (! disable_setkey_warnings)
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); pr_err("%s: wc_AesSetKey failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return -EINVAL; return -EINVAL;
} }
@ -457,8 +467,9 @@ static int km_AesCfbDecrypt(struct skcipher_request *req)
err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); err = wc_AesSetIV(ctx->aes_encrypt, walk.iv);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesSetKey failed: %d\n", if (! disable_setkey_warnings)
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); pr_err("%s: wc_AesSetKey failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return -EINVAL; return -EINVAL;
} }
@ -534,8 +545,9 @@ static int km_AesGcmSetKey(struct crypto_aead *tfm, const u8 *in_key,
err = wc_AesGcmSetKey(ctx->aes_encrypt, in_key, key_len); err = wc_AesGcmSetKey(ctx->aes_encrypt, in_key, key_len);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesGcmSetKey failed: %d\n", if (! disable_setkey_warnings)
crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); pr_err("%s: wc_AesGcmSetKey failed: %d\n",
crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err);
return -ENOKEY; return -ENOKEY;
} }
@ -848,22 +860,13 @@ static int km_AesXtsSetKey(struct crypto_skcipher *tfm, const u8 *in_key,
int err; int err;
struct km_AesXtsCtx * ctx = crypto_skcipher_ctx(tfm); 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, err = wc_AesXtsSetKeyNoInit(ctx->aesXts, in_key, key_len,
AES_ENCRYPTION_AND_DECRYPTION); AES_ENCRYPTION_AND_DECRYPTION);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesXtsSetKeyNoInit failed: %d\n", if (! disable_setkey_warnings)
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); pr_err("%s: wc_AesXtsSetKeyNoInit failed: %d\n",
crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err);
return -EINVAL; return -EINVAL;
} }
@ -909,6 +912,7 @@ static int km_AesXtsEncrypt(struct skcipher_request *req)
} else { } else {
int tail = req->cryptlen % AES_BLOCK_SIZE; int tail = req->cryptlen % AES_BLOCK_SIZE;
struct skcipher_request subreq; struct skcipher_request subreq;
struct XtsAesStreamData stream;
if (tail > 0) { if (tail > 0) {
int blocks = DIV_ROUND_UP(req->cryptlen, AES_BLOCK_SIZE) - 2; int blocks = DIV_ROUND_UP(req->cryptlen, AES_BLOCK_SIZE) - 2;
@ -930,7 +934,7 @@ static int km_AesXtsEncrypt(struct skcipher_request *req)
tail = 0; tail = 0;
} }
err = wc_AesXtsEncryptInit(ctx->aesXts, walk.iv, walk.ivsize); err = wc_AesXtsEncryptInit(ctx->aesXts, walk.iv, walk.ivsize, &stream);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesXtsEncryptInit failed: %d\n", pr_err("%s: wc_AesXtsEncryptInit failed: %d\n",
@ -948,11 +952,11 @@ static int km_AesXtsEncrypt(struct skcipher_request *req)
if (nbytes & ((unsigned int)AES_BLOCK_SIZE - 1U)) if (nbytes & ((unsigned int)AES_BLOCK_SIZE - 1U))
err = wc_AesXtsEncryptFinal(ctx->aesXts, walk.dst.virt.addr, err = wc_AesXtsEncryptFinal(ctx->aesXts, walk.dst.virt.addr,
walk.src.virt.addr, nbytes, walk.src.virt.addr, nbytes,
walk.iv); &stream);
else else
err = wc_AesXtsEncryptUpdate(ctx->aesXts, walk.dst.virt.addr, err = wc_AesXtsEncryptUpdate(ctx->aesXts, walk.dst.virt.addr,
walk.src.virt.addr, nbytes, walk.src.virt.addr, nbytes,
walk.iv); &stream);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesXtsEncryptUpdate failed: %d\n", pr_err("%s: wc_AesXtsEncryptUpdate failed: %d\n",
@ -986,7 +990,7 @@ static int km_AesXtsEncrypt(struct skcipher_request *req)
err = wc_AesXtsEncryptFinal(ctx->aesXts, walk.dst.virt.addr, err = wc_AesXtsEncryptFinal(ctx->aesXts, walk.dst.virt.addr,
walk.src.virt.addr, walk.nbytes, walk.src.virt.addr, walk.nbytes,
walk.iv); &stream);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesXtsEncryptFinal failed: %d\n", pr_err("%s: wc_AesXtsEncryptFinal failed: %d\n",
@ -995,6 +999,8 @@ static int km_AesXtsEncrypt(struct skcipher_request *req)
} }
err = skcipher_walk_done(&walk, 0); err = skcipher_walk_done(&walk, 0);
} else if (! (stream.bytes_crypted_with_this_tweak & ((word32)AES_BLOCK_SIZE - 1U))) {
err = wc_AesXtsEncryptFinal(ctx->aesXts, NULL, NULL, 0, &stream);
} }
} }
@ -1024,7 +1030,6 @@ static int km_AesXtsDecrypt(struct skcipher_request *req)
} }
if (walk.nbytes == walk.total) { if (walk.nbytes == walk.total) {
err = wc_AesXtsDecrypt(ctx->aesXts, err = wc_AesXtsDecrypt(ctx->aesXts,
walk.dst.virt.addr, walk.src.virt.addr, walk.dst.virt.addr, walk.src.virt.addr,
walk.nbytes, walk.iv, walk.ivsize); walk.nbytes, walk.iv, walk.ivsize);
@ -1036,10 +1041,10 @@ static int km_AesXtsDecrypt(struct skcipher_request *req)
} }
err = skcipher_walk_done(&walk, 0); err = skcipher_walk_done(&walk, 0);
} else { } else {
int tail = req->cryptlen % AES_BLOCK_SIZE; int tail = req->cryptlen % AES_BLOCK_SIZE;
struct skcipher_request subreq; struct skcipher_request subreq;
struct XtsAesStreamData stream;
if (unlikely(tail > 0)) { if (unlikely(tail > 0)) {
int blocks = DIV_ROUND_UP(req->cryptlen, AES_BLOCK_SIZE) - 2; int blocks = DIV_ROUND_UP(req->cryptlen, AES_BLOCK_SIZE) - 2;
@ -1061,7 +1066,7 @@ static int km_AesXtsDecrypt(struct skcipher_request *req)
tail = 0; tail = 0;
} }
err = wc_AesXtsDecryptInit(ctx->aesXts, walk.iv, walk.ivsize); err = wc_AesXtsDecryptInit(ctx->aesXts, walk.iv, walk.ivsize, &stream);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesXtsDecryptInit failed: %d\n", pr_err("%s: wc_AesXtsDecryptInit failed: %d\n",
@ -1079,11 +1084,11 @@ static int km_AesXtsDecrypt(struct skcipher_request *req)
if (nbytes & ((unsigned int)AES_BLOCK_SIZE - 1U)) if (nbytes & ((unsigned int)AES_BLOCK_SIZE - 1U))
err = wc_AesXtsDecryptFinal(ctx->aesXts, walk.dst.virt.addr, err = wc_AesXtsDecryptFinal(ctx->aesXts, walk.dst.virt.addr,
walk.src.virt.addr, nbytes, walk.src.virt.addr, nbytes,
walk.iv); &stream);
else else
err = wc_AesXtsDecryptUpdate(ctx->aesXts, walk.dst.virt.addr, err = wc_AesXtsDecryptUpdate(ctx->aesXts, walk.dst.virt.addr,
walk.src.virt.addr, nbytes, walk.src.virt.addr, nbytes,
walk.iv); &stream);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesXtsDecryptUpdate failed: %d\n", pr_err("%s: wc_AesXtsDecryptUpdate failed: %d\n",
@ -1117,7 +1122,7 @@ static int km_AesXtsDecrypt(struct skcipher_request *req)
err = wc_AesXtsDecryptFinal(ctx->aesXts, walk.dst.virt.addr, err = wc_AesXtsDecryptFinal(ctx->aesXts, walk.dst.virt.addr,
walk.src.virt.addr, walk.nbytes, walk.src.virt.addr, walk.nbytes,
walk.iv); &stream);
if (unlikely(err)) { if (unlikely(err)) {
pr_err("%s: wc_AesXtsDecryptFinal failed: %d\n", pr_err("%s: wc_AesXtsDecryptFinal failed: %d\n",
@ -1126,8 +1131,9 @@ static int km_AesXtsDecrypt(struct skcipher_request *req)
} }
err = skcipher_walk_done(&walk, 0); err = skcipher_walk_done(&walk, 0);
} else if (! (stream.bytes_crypted_with_this_tweak & ((word32)AES_BLOCK_SIZE - 1U))) {
err = wc_AesXtsDecryptFinal(ctx->aesXts, NULL, NULL, 0, &stream);
} }
} }
return err; return err;
} }
@ -1886,7 +1892,7 @@ static int aes_xts_128_test(void)
struct scatterlist * dst = NULL; struct scatterlist * dst = NULL;
struct crypto_skcipher *tfm = NULL; struct crypto_skcipher *tfm = NULL;
struct skcipher_request *req = NULL; struct skcipher_request *req = NULL;
u8 iv[AES_BLOCK_SIZE]; struct XtsAesStreamData stream;
byte* large_input = NULL; byte* large_input = NULL;
/* 128 key tests */ /* 128 key tests */
@ -2032,16 +2038,15 @@ static int aes_xts_128_test(void)
XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ); XMEMSET(buf, 0, AES_XTS_128_TEST_BUF_SIZ);
XMEMCPY(iv, i2, sizeof(i2)); ret = wc_AesXtsEncryptInit(aes, i2, sizeof(i2), &stream);
ret = wc_AesXtsEncryptInit(aes, iv, sizeof(iv));
if (ret != 0) if (ret != 0)
goto out; goto out;
ret = wc_AesXtsEncryptUpdate(aes, buf, p2, AES_BLOCK_SIZE, iv); ret = wc_AesXtsEncryptUpdate(aes, buf, p2, AES_BLOCK_SIZE, &stream);
if (ret != 0) if (ret != 0)
goto out; goto out;
ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE,
p2 + AES_BLOCK_SIZE, p2 + AES_BLOCK_SIZE,
sizeof(p2) - AES_BLOCK_SIZE, iv); sizeof(p2) - AES_BLOCK_SIZE, &stream);
if (ret != 0) if (ret != 0)
goto out; goto out;
if (XMEMCMP(c2, buf, sizeof(c2))) { if (XMEMCMP(c2, buf, sizeof(c2))) {
@ -2219,15 +2224,14 @@ static int aes_xts_128_test(void)
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION);
if (ret != 0) if (ret != 0)
goto out; goto out;
XMEMCPY(iv, i1, sizeof(i1)); ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsEncryptInit(aes, iv, sizeof(iv));
if (ret != 0) if (ret != 0)
goto out; goto out;
for (k = 0; k < j; k += AES_BLOCK_SIZE) { for (k = 0; k < j; k += AES_BLOCK_SIZE) {
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
ret = wc_AesXtsEncryptFinal(aes, large_input + k, large_input + k, j - k, iv); ret = wc_AesXtsEncryptFinal(aes, large_input + k, large_input + k, j - k, &stream);
else else
ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, iv); ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, &stream);
if (ret != 0) if (ret != 0)
goto out; goto out;
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
@ -2260,15 +2264,14 @@ static int aes_xts_128_test(void)
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION);
if (ret != 0) if (ret != 0)
goto out; goto out;
XMEMCPY(iv, i1, sizeof(i1)); ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsDecryptInit(aes, iv, sizeof(iv));
if (ret != 0) if (ret != 0)
goto out; goto out;
for (k = 0; k < j; k += AES_BLOCK_SIZE) { for (k = 0; k < j; k += AES_BLOCK_SIZE) {
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
ret = wc_AesXtsDecryptFinal(aes, large_input + k, large_input + k, j - k, iv); ret = wc_AesXtsDecryptFinal(aes, large_input + k, large_input + k, j - k, &stream);
else else
ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, iv); ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, &stream);
if (ret != 0) if (ret != 0)
goto out; goto out;
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
@ -2335,10 +2338,10 @@ static int aes_xts_128_test(void)
#endif #endif
ret = crypto_skcipher_ivsize(tfm); ret = crypto_skcipher_ivsize(tfm);
if (ret != sizeof(iv)) { if (ret != sizeof(stream.tweak_block)) {
pr_err("error: AES skcipher algorithm %s crypto_skcipher_ivsize()" pr_err("error: AES skcipher algorithm %s crypto_skcipher_ivsize()"
" returned %d but expected %d\n", " returned %d but expected %d\n",
WOLFKM_AESXTS_DRIVER, ret, (int)sizeof(iv)); WOLFKM_AESXTS_DRIVER, ret, (int)sizeof(stream.tweak_block));
ret = -EINVAL; ret = -EINVAL;
goto test_xts_end; goto test_xts_end;
} }
@ -2364,8 +2367,8 @@ static int aes_xts_128_test(void)
sg_init_one(src, dec2, sizeof(p1)); sg_init_one(src, dec2, sizeof(p1));
sg_init_one(dst, enc2, sizeof(p1)); sg_init_one(dst, enc2, sizeof(p1));
memcpy(iv, i1, sizeof(iv)); memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block));
skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); skcipher_request_set_crypt(req, src, dst, sizeof(p1), stream.tweak_block);
ret = crypto_skcipher_encrypt(req); ret = crypto_skcipher_encrypt(req);
@ -2385,8 +2388,8 @@ static int aes_xts_128_test(void)
sg_init_one(src, enc2, sizeof(p1)); sg_init_one(src, enc2, sizeof(p1));
sg_init_one(dst, dec2, sizeof(p1)); sg_init_one(dst, dec2, sizeof(p1));
memcpy(iv, i1, sizeof(iv)); memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block));
skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); skcipher_request_set_crypt(req, src, dst, sizeof(p1), stream.tweak_block);
ret = crypto_skcipher_decrypt(req); ret = crypto_skcipher_decrypt(req);
@ -2408,8 +2411,8 @@ static int aes_xts_128_test(void)
sg_init_one(src, dec2, sizeof(pp)); sg_init_one(src, dec2, sizeof(pp));
sg_init_one(dst, enc2, sizeof(pp)); sg_init_one(dst, enc2, sizeof(pp));
memcpy(iv, i1, sizeof(iv)); memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block));
skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); skcipher_request_set_crypt(req, src, dst, sizeof(pp), stream.tweak_block);
ret = crypto_skcipher_encrypt(req); ret = crypto_skcipher_encrypt(req);
@ -2429,8 +2432,8 @@ static int aes_xts_128_test(void)
sg_init_one(src, enc2, sizeof(pp)); sg_init_one(src, enc2, sizeof(pp));
sg_init_one(dst, dec2, sizeof(pp)); sg_init_one(dst, dec2, sizeof(pp));
memcpy(iv, i1, sizeof(iv)); memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block));
skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); skcipher_request_set_crypt(req, src, dst, sizeof(pp), stream.tweak_block);
ret = crypto_skcipher_decrypt(req); ret = crypto_skcipher_decrypt(req);
@ -2498,7 +2501,7 @@ static int aes_xts_256_test(void)
struct scatterlist * dst = NULL; struct scatterlist * dst = NULL;
struct crypto_skcipher *tfm = NULL; struct crypto_skcipher *tfm = NULL;
struct skcipher_request *req = NULL; struct skcipher_request *req = NULL;
u8 iv[AES_BLOCK_SIZE]; struct XtsAesStreamData stream;
byte* large_input = NULL; byte* large_input = NULL;
/* 256 key tests */ /* 256 key tests */
@ -2620,16 +2623,15 @@ static int aes_xts_256_test(void)
XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ);
XMEMCPY(iv, i2, sizeof(i2)); ret = wc_AesXtsEncryptInit(aes, i2, sizeof(i2), &stream);
ret = wc_AesXtsEncryptInit(aes, iv, sizeof(iv));
if (ret != 0) if (ret != 0)
goto out; goto out;
ret = wc_AesXtsEncryptUpdate(aes, buf, p2, AES_BLOCK_SIZE, iv); ret = wc_AesXtsEncryptUpdate(aes, buf, p2, AES_BLOCK_SIZE, &stream);
if (ret != 0) if (ret != 0)
goto out; goto out;
ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE,
p2 + AES_BLOCK_SIZE, p2 + AES_BLOCK_SIZE,
sizeof(p2) - AES_BLOCK_SIZE, iv); sizeof(p2) - AES_BLOCK_SIZE, &stream);
if (ret != 0) if (ret != 0)
goto out; goto out;
if (XMEMCMP(c2, buf, sizeof(c2))) { if (XMEMCMP(c2, buf, sizeof(c2))) {
@ -2711,15 +2713,14 @@ static int aes_xts_256_test(void)
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION);
if (ret != 0) if (ret != 0)
goto out; goto out;
XMEMCPY(iv, i1, sizeof(i1)); ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsEncryptInit(aes, iv, sizeof(iv));
if (ret != 0) if (ret != 0)
goto out; goto out;
for (k = 0; k < j; k += AES_BLOCK_SIZE) { for (k = 0; k < j; k += AES_BLOCK_SIZE) {
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
ret = wc_AesXtsEncryptFinal(aes, large_input + k, large_input + k, j - k, iv); ret = wc_AesXtsEncryptFinal(aes, large_input + k, large_input + k, j - k, &stream);
else else
ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, iv); ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, &stream);
if (ret != 0) if (ret != 0)
goto out; goto out;
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
@ -2752,15 +2753,14 @@ static int aes_xts_256_test(void)
ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION);
if (ret != 0) if (ret != 0)
goto out; goto out;
XMEMCPY(iv, i1, sizeof(i1)); ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsDecryptInit(aes, iv, sizeof(iv));
if (ret != 0) if (ret != 0)
goto out; goto out;
for (k = 0; k < j; k += AES_BLOCK_SIZE) { for (k = 0; k < j; k += AES_BLOCK_SIZE) {
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
ret = wc_AesXtsDecryptFinal(aes, large_input + k, large_input + k, j - k, iv); ret = wc_AesXtsDecryptFinal(aes, large_input + k, large_input + k, j - k, &stream);
else else
ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, iv); ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, &stream);
if (ret != 0) if (ret != 0)
goto out; goto out;
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
@ -2826,10 +2826,10 @@ static int aes_xts_256_test(void)
#endif #endif
ret = crypto_skcipher_ivsize(tfm); ret = crypto_skcipher_ivsize(tfm);
if (ret != sizeof(iv)) { if (ret != sizeof(stream.tweak_block)) {
pr_err("error: AES skcipher algorithm %s crypto_skcipher_ivsize()" pr_err("error: AES skcipher algorithm %s crypto_skcipher_ivsize()"
" returned %d but expected %d\n", " returned %d but expected %d\n",
WOLFKM_AESXTS_DRIVER, ret, (int)sizeof(iv)); WOLFKM_AESXTS_DRIVER, ret, (int)sizeof(stream.tweak_block));
ret = -EINVAL; ret = -EINVAL;
goto test_xts_end; goto test_xts_end;
} }
@ -2855,8 +2855,8 @@ static int aes_xts_256_test(void)
sg_init_one(src, dec2, sizeof(p1)); sg_init_one(src, dec2, sizeof(p1));
sg_init_one(dst, enc2, sizeof(p1)); sg_init_one(dst, enc2, sizeof(p1));
memcpy(iv, i1, sizeof(iv)); memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block));
skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); skcipher_request_set_crypt(req, src, dst, sizeof(p1), stream.tweak_block);
ret = crypto_skcipher_encrypt(req); ret = crypto_skcipher_encrypt(req);
@ -2876,8 +2876,8 @@ static int aes_xts_256_test(void)
sg_init_one(src, enc2, sizeof(p1)); sg_init_one(src, enc2, sizeof(p1));
sg_init_one(dst, dec2, sizeof(p1)); sg_init_one(dst, dec2, sizeof(p1));
memcpy(iv, i1, sizeof(iv)); memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block));
skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); skcipher_request_set_crypt(req, src, dst, sizeof(p1), stream.tweak_block);
ret = crypto_skcipher_decrypt(req); ret = crypto_skcipher_decrypt(req);
@ -2899,8 +2899,8 @@ static int aes_xts_256_test(void)
sg_init_one(src, dec2, sizeof(pp)); sg_init_one(src, dec2, sizeof(pp));
sg_init_one(dst, enc2, sizeof(pp)); sg_init_one(dst, enc2, sizeof(pp));
memcpy(iv, i1, sizeof(iv)); memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block));
skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); skcipher_request_set_crypt(req, src, dst, sizeof(pp), stream.tweak_block);
ret = crypto_skcipher_encrypt(req); ret = crypto_skcipher_encrypt(req);
@ -2920,8 +2920,8 @@ static int aes_xts_256_test(void)
sg_init_one(src, enc2, sizeof(pp)); sg_init_one(src, enc2, sizeof(pp));
sg_init_one(dst, dec2, sizeof(pp)); sg_init_one(dst, dec2, sizeof(pp));
memcpy(iv, i1, sizeof(iv)); memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block));
skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); skcipher_request_set_crypt(req, src, dst, sizeof(pp), stream.tweak_block);
ret = crypto_skcipher_decrypt(req); ret = crypto_skcipher_decrypt(req);
@ -3003,15 +3003,46 @@ out:
#endif /* !NO_AES */ #endif /* !NO_AES */
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
#ifdef CONFIG_CRYPTO_FIPS
#include <linux/fips.h>
#else
#error wolfCrypt FIPS with LINUXKM_LKCAPI_REGISTER and CONFIG_CRYPTO_MANAGER requires CONFIG_CRYPTO_FIPS
#endif
#endif
static int linuxkm_lkcapi_register(void) static int linuxkm_lkcapi_register(void)
{ {
int ret = 0; int ret = 0;
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
int enabled_fips = 0;
#endif
#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
/* temporarily disable warnings around setkey failures, which are expected
* from the crypto fuzzer in FIPS configs, and potentially in others.
* unexpected setkey failures are fatal errors returned by the fuzzer.
*/
disable_setkey_warnings = 1;
#endif
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
if (! fips_enabled) {
/* temporarily assert system-wide FIPS status, to disable FIPS-forbidden
* test vectors and fuzzing from the CRYPTO_MANAGER.
*/
enabled_fips = fips_enabled = 1;
}
#endif
#define REGISTER_ALG(alg, installer, tester) do { \ #define REGISTER_ALG(alg, installer, tester) do { \
if (alg ## _loaded) { \ if (alg ## _loaded) { \
pr_err("ERROR: %s is already registered.\n", \ pr_err("ERROR: %s is already registered.\n", \
(alg).base.cra_driver_name); \ (alg).base.cra_driver_name); \
return -EEXIST; \ ret = -EEXIST; \
goto out; \
} \ } \
\ \
ret = (installer)(&(alg)); \ ret = (installer)(&(alg)); \
@ -3020,7 +3051,7 @@ static int linuxkm_lkcapi_register(void)
pr_err("ERROR: " #installer " for %s failed " \ pr_err("ERROR: " #installer " for %s failed " \
"with return code %d.\n", \ "with return code %d.\n", \
(alg).base.cra_driver_name, ret); \ (alg).base.cra_driver_name, ret); \
return ret; \ goto out; \
} \ } \
\ \
alg ## _loaded = 1; \ alg ## _loaded = 1; \
@ -3031,7 +3062,7 @@ static int linuxkm_lkcapi_register(void)
pr_err("ERROR: self-test for %s failed " \ pr_err("ERROR: self-test for %s failed " \
"with return code %d.\n", \ "with return code %d.\n", \
(alg).base.cra_driver_name, ret); \ (alg).base.cra_driver_name, ret); \
return ret; \ goto out; \
} \ } \
pr_info("%s self-test OK -- " \ pr_info("%s self-test OK -- " \
"registered for %s with priority %d.\n", \ "registered for %s with priority %d.\n", \
@ -3070,7 +3101,18 @@ static int linuxkm_lkcapi_register(void)
#undef REGISTER_ALG #undef REGISTER_ALG
return 0; out:
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
if (enabled_fips)
fips_enabled = 0;
#endif
#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
disable_setkey_warnings = 0;
#endif
return ret;
} }
static void linuxkm_lkcapi_unregister(void) static void linuxkm_lkcapi_unregister(void)

View File

@ -12783,15 +12783,18 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
aes = &xaes->aes; #if FIPS_VERSION3_GE(6,0,0)
/* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
* AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
* protect up to 1,048,576 blocks of AES_BLOCK_SIZE (16,777,216 bytes)
*/
if (sz > FIPS_AES_XTS_MAX_BYTES_PER_TWEAK) {
WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
return BAD_FUNC_ARG;
}
#endif
/* FIPS TODO: SP800-38E - Restrict data unit to 2^20 blocks per key. A block is aes = &xaes->aes;
* AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
* protect up to 1,048,576 blocks of AES_BLOCK_SIZE (16,777,216 bytes or
* 134,217,728-bits) Add helpful printout and message along with BAD_FUNC_ARG
* return whenever sz / AES_BLOCK_SIZE > 1,048,576 or equal to that and sz is
* not a sequence of complete blocks.
*/
if (aes->keylen == 0) { if (aes->keylen == 0) {
WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key."); WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
@ -12851,13 +12854,14 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
* *
* returns 0 on success * returns 0 on success
*/ */
int wc_AesXtsEncryptInit(XtsAes* xaes, byte* i, word32 iSz) int wc_AesXtsEncryptInit(XtsAes* xaes, const byte* i, word32 iSz,
struct XtsAesStreamData *stream)
{ {
int ret; int ret;
Aes *aes; Aes *aes;
if ((xaes == NULL) || (i == NULL)) { if ((xaes == NULL) || (i == NULL) || (stream == NULL)) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
@ -12876,20 +12880,25 @@ int wc_AesXtsEncryptInit(XtsAes* xaes, byte* i, word32 iSz)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
XMEMCPY(stream->tweak_block, i, AES_BLOCK_SIZE);
stream->bytes_crypted_with_this_tweak = 0;
{ {
#ifdef WOLFSSL_AESNI #ifdef WOLFSSL_AESNI
if (aes->use_aesni) { if (aes->use_aesni) {
SAVE_VECTOR_REGISTERS(return _svr_ret;); SAVE_VECTOR_REGISTERS(return _svr_ret;);
#if defined(HAVE_INTEL_AVX1) #if defined(HAVE_INTEL_AVX1)
if (IS_INTEL_AVX1(intel_flags)) { if (IS_INTEL_AVX1(intel_flags)) {
AES_XTS_init_avx1(i, (const byte*)xaes->tweak.key, AES_XTS_init_avx1(stream->tweak_block,
(const byte*)xaes->tweak.key,
(int)xaes->tweak.rounds); (int)xaes->tweak.rounds);
ret = 0; ret = 0;
} }
else else
#endif #endif
{ {
AES_XTS_init_aesni(i, (const byte*)xaes->tweak.key, AES_XTS_init_aesni(stream->tweak_block,
(const byte*)xaes->tweak.key,
(int)xaes->tweak.rounds); (int)xaes->tweak.rounds);
ret = 0; ret = 0;
} }
@ -12898,7 +12907,7 @@ int wc_AesXtsEncryptInit(XtsAes* xaes, byte* i, word32 iSz)
else else
#endif /* WOLFSSL_AESNI */ #endif /* WOLFSSL_AESNI */
{ {
ret = AesXtsInitTweak_sw(xaes, i); ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
} }
} }
@ -12922,7 +12931,7 @@ int wc_AesXtsEncryptInit(XtsAes* xaes, byte* i, word32 iSz)
* returns 0 on success * returns 0 on success
*/ */
static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz, static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
byte *i) struct XtsAesStreamData *stream)
{ {
int ret; int ret;
@ -12930,7 +12939,7 @@ static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s
Aes *aes; Aes *aes;
#endif #endif
if (xaes == NULL || out == NULL || in == NULL || i == NULL) { if (xaes == NULL || out == NULL || in == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
@ -12943,6 +12952,28 @@ static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
if (stream->bytes_crypted_with_this_tweak & ((word32)AES_BLOCK_SIZE - 1U))
{
WOLFSSL_MSG("Call to AesXtsEncryptUpdate after previous finalizing call");
return BAD_FUNC_ARG;
}
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
(void)WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
stream->bytes_crypted_with_this_tweak);
#endif
#if FIPS_VERSION3_GE(6,0,0)
/* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
* AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
* protect up to 1,048,576 blocks of AES_BLOCK_SIZE (16,777,216 bytes)
*/
if (stream->bytes_crypted_with_this_tweak >
FIPS_AES_XTS_MAX_BYTES_PER_TWEAK)
{
WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
return BAD_FUNC_ARG;
}
#endif
{ {
#ifdef WOLFSSL_AESNI #ifdef WOLFSSL_AESNI
if (aes->use_aesni) { if (aes->use_aesni) {
@ -12951,7 +12982,7 @@ static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s
if (IS_INTEL_AVX1(intel_flags)) { if (IS_INTEL_AVX1(intel_flags)) {
AES_XTS_encrypt_update_avx1(in, out, sz, AES_XTS_encrypt_update_avx1(in, out, sz,
(const byte*)aes->key, (const byte*)aes->key,
i, stream->tweak_block,
(int)aes->rounds); (int)aes->rounds);
ret = 0; ret = 0;
} }
@ -12960,7 +12991,7 @@ static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s
{ {
AES_XTS_encrypt_update_aesni(in, out, sz, AES_XTS_encrypt_update_aesni(in, out, sz,
(const byte*)aes->key, (const byte*)aes->key,
i, stream->tweak_block,
(int)aes->rounds); (int)aes->rounds);
ret = 0; ret = 0;
} }
@ -12969,7 +13000,7 @@ static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s
else else
#endif /* WOLFSSL_AESNI */ #endif /* WOLFSSL_AESNI */
{ {
ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, i); ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, stream->tweak_block);
} }
} }
@ -12977,24 +13008,32 @@ static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s
} }
int wc_AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz, int wc_AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
byte *i) struct XtsAesStreamData *stream)
{ {
if (stream == NULL)
return BAD_FUNC_ARG;
if (sz & ((word32)AES_BLOCK_SIZE - 1U)) if (sz & ((word32)AES_BLOCK_SIZE - 1U))
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
return AesXtsEncryptUpdate(xaes, out, in, sz, i); return AesXtsEncryptUpdate(xaes, out, in, sz, stream);
} }
int wc_AesXtsEncryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz, int wc_AesXtsEncryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
byte *i) struct XtsAesStreamData *stream)
{ {
int ret; int ret;
if (stream == NULL)
return BAD_FUNC_ARG;
if (sz > 0) if (sz > 0)
ret = AesXtsEncryptUpdate(xaes, out, in, sz, i); ret = AesXtsEncryptUpdate(xaes, out, in, sz, stream);
else else
ret = 0; ret = 0;
ForceZero(i, AES_BLOCK_SIZE); /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
* after finalization.
*/
stream->bytes_crypted_with_this_tweak |= 1U;
ForceZero(stream->tweak_block, AES_BLOCK_SIZE);
#ifdef WOLFSSL_CHECK_MEM_ZERO #ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Check(i, AES_BLOCK_SIZE); wc_MemZero_Check(stream->tweak_block, AES_BLOCK_SIZE);
#endif #endif
return ret; return ret;
} }
@ -13252,7 +13291,8 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
* *
* returns 0 on success * returns 0 on success
*/ */
int wc_AesXtsDecryptInit(XtsAes* xaes, byte* i, word32 iSz) int wc_AesXtsDecryptInit(XtsAes* xaes, const byte* i, word32 iSz,
struct XtsAesStreamData *stream)
{ {
int ret; int ret;
Aes *aes; Aes *aes;
@ -13276,20 +13316,25 @@ int wc_AesXtsDecryptInit(XtsAes* xaes, byte* i, word32 iSz)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
XMEMCPY(stream->tweak_block, i, AES_BLOCK_SIZE);
stream->bytes_crypted_with_this_tweak = 0;
{ {
#ifdef WOLFSSL_AESNI #ifdef WOLFSSL_AESNI
if (aes->use_aesni) { if (aes->use_aesni) {
SAVE_VECTOR_REGISTERS(return _svr_ret;); SAVE_VECTOR_REGISTERS(return _svr_ret;);
#if defined(HAVE_INTEL_AVX1) #if defined(HAVE_INTEL_AVX1)
if (IS_INTEL_AVX1(intel_flags)) { if (IS_INTEL_AVX1(intel_flags)) {
AES_XTS_init_avx1(i, (const byte*)xaes->tweak.key, AES_XTS_init_avx1(stream->tweak_block,
(const byte*)xaes->tweak.key,
(int)xaes->tweak.rounds); (int)xaes->tweak.rounds);
ret = 0; ret = 0;
} }
else else
#endif #endif
{ {
AES_XTS_init_aesni(i, (const byte*)xaes->tweak.key, AES_XTS_init_aesni(stream->tweak_block,
(const byte*)xaes->tweak.key,
(int)xaes->tweak.rounds); (int)xaes->tweak.rounds);
ret = 0; ret = 0;
} }
@ -13298,7 +13343,7 @@ int wc_AesXtsDecryptInit(XtsAes* xaes, byte* i, word32 iSz)
else else
#endif /* WOLFSSL_AESNI */ #endif /* WOLFSSL_AESNI */
{ {
ret = AesXtsInitTweak_sw(xaes, i); ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
} }
} }
@ -13321,7 +13366,7 @@ int wc_AesXtsDecryptInit(XtsAes* xaes, byte* i, word32 iSz)
* returns 0 on success * returns 0 on success
*/ */
static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz, static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
byte *i) struct XtsAesStreamData *stream)
{ {
int ret; int ret;
#ifdef WOLFSSL_AESNI #ifdef WOLFSSL_AESNI
@ -13345,6 +13390,17 @@ static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
if (stream->bytes_crypted_with_this_tweak & ((word32)AES_BLOCK_SIZE - 1U))
{
WOLFSSL_MSG("Call to AesXtsDecryptUpdate after previous finalizing call");
return BAD_FUNC_ARG;
}
#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
(void)WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
stream->bytes_crypted_with_this_tweak);
#endif
{ {
#ifdef WOLFSSL_AESNI #ifdef WOLFSSL_AESNI
if (aes->use_aesni) { if (aes->use_aesni) {
@ -13353,7 +13409,7 @@ static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s
if (IS_INTEL_AVX1(intel_flags)) { if (IS_INTEL_AVX1(intel_flags)) {
AES_XTS_decrypt_update_avx1(in, out, sz, AES_XTS_decrypt_update_avx1(in, out, sz,
(const byte*)aes->key, (const byte*)aes->key,
i, stream->tweak_block,
(int)aes->rounds); (int)aes->rounds);
ret = 0; ret = 0;
} }
@ -13362,7 +13418,7 @@ static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s
{ {
AES_XTS_decrypt_update_aesni(in, out, sz, AES_XTS_decrypt_update_aesni(in, out, sz,
(const byte*)aes->key, (const byte*)aes->key,
i, stream->tweak_block,
(int)aes->rounds); (int)aes->rounds);
ret = 0; ret = 0;
} }
@ -13371,7 +13427,8 @@ static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s
else else
#endif /* WOLFSSL_AESNI */ #endif /* WOLFSSL_AESNI */
{ {
ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz, i); ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz,
stream->tweak_block);
} }
} }
@ -13379,24 +13436,32 @@ static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s
} }
int wc_AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz, int wc_AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
byte *i) struct XtsAesStreamData *stream)
{ {
if (stream == NULL)
return BAD_FUNC_ARG;
if (sz & ((word32)AES_BLOCK_SIZE - 1U)) if (sz & ((word32)AES_BLOCK_SIZE - 1U))
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
return AesXtsDecryptUpdate(xaes, out, in, sz, i); return AesXtsDecryptUpdate(xaes, out, in, sz, stream);
} }
int wc_AesXtsDecryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz, int wc_AesXtsDecryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
byte *i) struct XtsAesStreamData *stream)
{ {
int ret; int ret;
if (stream == NULL)
return BAD_FUNC_ARG;
if (sz > 0) if (sz > 0)
ret = AesXtsDecryptUpdate(xaes, out, in, sz, i); ret = AesXtsDecryptUpdate(xaes, out, in, sz, stream);
else else
ret = 0; ret = 0;
ForceZero(i, AES_BLOCK_SIZE); ForceZero(stream->tweak_block, AES_BLOCK_SIZE);
/* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
* after finalization.
*/
stream->bytes_crypted_with_this_tweak |= 1U;
#ifdef WOLFSSL_CHECK_MEM_ZERO #ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Check(i, AES_BLOCK_SIZE); wc_MemZero_Check(stream->tweak_block, AES_BLOCK_SIZE);
#endif #endif
return ret; return ret;
} }

View File

@ -9876,7 +9876,7 @@ static wc_test_ret_t aes_xts_128_test(void)
unsigned char buf[AES_BLOCK_SIZE * 2 + 8]; unsigned char buf[AES_BLOCK_SIZE * 2 + 8];
unsigned char cipher[AES_BLOCK_SIZE * 2 + 8]; unsigned char cipher[AES_BLOCK_SIZE * 2 + 8];
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
unsigned char i_copy[AES_BLOCK_SIZE]; struct XtsAesStreamData stream;
#endif #endif
#if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \ #if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \
!defined(WOLFSSL_AFALG) !defined(WOLFSSL_AFALG)
@ -10012,23 +10012,21 @@ static wc_test_ret_t aes_xts_128_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i2, sizeof(i2)); ret = wc_AesXtsEncryptInit(aes, i2, sizeof(i2), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptUpdate(aes, buf, p2, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptUpdate(aes, buf, p2, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, p2 + AES_BLOCK_SIZE, sizeof(p2) - AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, p2 + AES_BLOCK_SIZE, sizeof(p2) - AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10068,23 +10066,21 @@ static wc_test_ret_t aes_xts_128_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i2), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptUpdate(aes, buf, p1, sizeof(p1), i_copy); ret = wc_AesXtsEncryptUpdate(aes, buf, p1, sizeof(p1), &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptFinal(aes, buf, NULL, 0, i_copy); ret = wc_AesXtsEncryptFinal(aes, buf, NULL, 0, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10121,23 +10117,21 @@ static wc_test_ret_t aes_xts_128_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptFinal(aes, buf, pp, sizeof(pp), i_copy); ret = wc_AesXtsEncryptFinal(aes, buf, pp, sizeof(pp), &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptFinal(aes, buf, NULL, 0, i_copy); ret = wc_AesXtsEncryptFinal(aes, buf, NULL, 0, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10182,16 +10176,14 @@ static wc_test_ret_t aes_xts_128_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsDecryptFinal(aes, buf, cipher, sizeof(pp), i_copy); ret = wc_AesXtsDecryptFinal(aes, buf, cipher, sizeof(pp), &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10237,16 +10229,14 @@ static wc_test_ret_t aes_xts_128_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsDecryptFinal(aes, buf, c1, sizeof(c1), i_copy); ret = wc_AesXtsDecryptFinal(aes, buf, c1, sizeof(c1), &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10327,23 +10317,21 @@ static wc_test_ret_t aes_xts_128_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i3, sizeof(i3)); ret = wc_AesXtsEncryptInit(aes, i3, sizeof(i3), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptUpdate(aes, buf, p3, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptUpdate(aes, buf, p3, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, p3 + AES_BLOCK_SIZE, sizeof(p3) - AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, p3 + AES_BLOCK_SIZE, sizeof(p3) - AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10371,23 +10359,21 @@ static wc_test_ret_t aes_xts_128_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i3, sizeof(i3)); ret = wc_AesXtsDecryptInit(aes, i3, sizeof(i3), &stream);
ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsDecryptUpdate(aes, buf, c3, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsDecryptUpdate(aes, buf, c3, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsDecryptFinal(aes, buf + AES_BLOCK_SIZE, c3 + AES_BLOCK_SIZE, sizeof(c3) - AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsDecryptFinal(aes, buf + AES_BLOCK_SIZE, c3 + AES_BLOCK_SIZE, sizeof(c3) - AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10462,8 +10448,7 @@ static wc_test_ret_t aes_xts_128_test(void)
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10472,9 +10457,9 @@ static wc_test_ret_t aes_xts_128_test(void)
for (k = 0; k < j; k += AES_BLOCK_SIZE) { for (k = 0; k < j; k += AES_BLOCK_SIZE) {
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
ret = wc_AesXtsEncryptFinal(aes, large_input + k, large_input + k, j - k, i_copy); ret = wc_AesXtsEncryptFinal(aes, large_input + k, large_input + k, j - k, &stream);
else else
ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10525,8 +10510,7 @@ static wc_test_ret_t aes_xts_128_test(void)
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10535,9 +10519,9 @@ static wc_test_ret_t aes_xts_128_test(void)
for (k = 0; k < j; k += AES_BLOCK_SIZE) { for (k = 0; k < j; k += AES_BLOCK_SIZE) {
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
ret = wc_AesXtsDecryptFinal(aes, large_input + k, large_input + k, j - k, i_copy); ret = wc_AesXtsDecryptFinal(aes, large_input + k, large_input + k, j - k, &stream);
else else
ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev,
@ -10598,7 +10582,7 @@ static wc_test_ret_t aes_xts_192_test(void)
unsigned char buf[AES_BLOCK_SIZE * 2 + 8]; unsigned char buf[AES_BLOCK_SIZE * 2 + 8];
unsigned char cipher[AES_BLOCK_SIZE * 2 + 8]; unsigned char cipher[AES_BLOCK_SIZE * 2 + 8];
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
unsigned char i_copy[AES_BLOCK_SIZE]; struct XtsAesStreamData stream;
#endif #endif
#if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \ #if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \
!defined(WOLFSSL_AFALG) !defined(WOLFSSL_AFALG)
@ -10730,23 +10714,21 @@ static wc_test_ret_t aes_xts_192_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i2, sizeof(i2)); ret = wc_AesXtsEncryptInit(aes, i2, sizeof(i2), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptUpdate(aes, buf, p2, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptUpdate(aes, buf, p2, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, p2 + AES_BLOCK_SIZE, sizeof(p2) - AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, p2 + AES_BLOCK_SIZE, sizeof(p2) - AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10786,23 +10768,21 @@ static wc_test_ret_t aes_xts_192_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptUpdate(aes, buf, p1, sizeof(p1), i_copy); ret = wc_AesXtsEncryptUpdate(aes, buf, p1, sizeof(p1), &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptFinal(aes, buf, NULL, 0, i_copy); ret = wc_AesXtsEncryptFinal(aes, buf, NULL, 0, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10839,23 +10819,21 @@ static wc_test_ret_t aes_xts_192_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptFinal(aes, buf, pp, sizeof(pp), i_copy); ret = wc_AesXtsEncryptFinal(aes, buf, pp, sizeof(pp), &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptFinal(aes, buf, NULL, 0, i_copy); ret = wc_AesXtsEncryptFinal(aes, buf, NULL, 0, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10900,16 +10878,14 @@ static wc_test_ret_t aes_xts_192_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsDecryptFinal(aes, buf, cipher, sizeof(pp), i_copy); ret = wc_AesXtsDecryptFinal(aes, buf, cipher, sizeof(pp), &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -10955,16 +10931,14 @@ static wc_test_ret_t aes_xts_192_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsDecryptFinal(aes, buf, c1, sizeof(c1), i_copy); ret = wc_AesXtsDecryptFinal(aes, buf, c1, sizeof(c1), &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -11045,23 +11019,21 @@ static wc_test_ret_t aes_xts_192_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i3, sizeof(i3)); ret = wc_AesXtsEncryptInit(aes, i3, sizeof(i3), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptUpdate(aes, buf, p3, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptUpdate(aes, buf, p3, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, p3 + AES_BLOCK_SIZE, sizeof(p3) - AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, p3 + AES_BLOCK_SIZE, sizeof(p3) - AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -11089,23 +11061,21 @@ static wc_test_ret_t aes_xts_192_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i3, sizeof(i3)); ret = wc_AesXtsDecryptInit(aes, i3, sizeof(i3), &stream);
ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsDecryptUpdate(aes, buf, c3, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsDecryptUpdate(aes, buf, c3, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsDecryptFinal(aes, buf + AES_BLOCK_SIZE, c3 + AES_BLOCK_SIZE, sizeof(c3) - AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsDecryptFinal(aes, buf + AES_BLOCK_SIZE, c3 + AES_BLOCK_SIZE, sizeof(c3) - AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -11180,8 +11150,7 @@ static wc_test_ret_t aes_xts_192_test(void)
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -11190,9 +11159,9 @@ static wc_test_ret_t aes_xts_192_test(void)
for (k = 0; k < j; k += AES_BLOCK_SIZE) { for (k = 0; k < j; k += AES_BLOCK_SIZE) {
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
ret = wc_AesXtsEncryptFinal(aes, large_input + k, large_input + k, j - k, i_copy); ret = wc_AesXtsEncryptFinal(aes, large_input + k, large_input + k, j - k, &stream);
else else
ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -11243,8 +11212,7 @@ static wc_test_ret_t aes_xts_192_test(void)
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -11253,9 +11221,9 @@ static wc_test_ret_t aes_xts_192_test(void)
for (k = 0; k < j; k += AES_BLOCK_SIZE) { for (k = 0; k < j; k += AES_BLOCK_SIZE) {
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
ret = wc_AesXtsDecryptFinal(aes, large_input + k, large_input + k, j - k, i_copy); ret = wc_AesXtsDecryptFinal(aes, large_input + k, large_input + k, j - k, &stream);
else else
ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev,
@ -11317,7 +11285,7 @@ static wc_test_ret_t aes_xts_256_test(void)
unsigned char buf[AES_BLOCK_SIZE * 3]; unsigned char buf[AES_BLOCK_SIZE * 3];
unsigned char cipher[AES_BLOCK_SIZE * 3]; unsigned char cipher[AES_BLOCK_SIZE * 3];
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
unsigned char i_copy[AES_BLOCK_SIZE]; struct XtsAesStreamData stream;
#endif #endif
#if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \ #if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \
!defined(WOLFSSL_AFALG) !defined(WOLFSSL_AFALG)
@ -11436,23 +11404,21 @@ static wc_test_ret_t aes_xts_256_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i2, sizeof(i2)); ret = wc_AesXtsEncryptInit(aes, i2, sizeof(i2), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptUpdate(aes, buf, p2, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptUpdate(aes, buf, p2, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, p2 + AES_BLOCK_SIZE, sizeof(p2) - AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, p2 + AES_BLOCK_SIZE, sizeof(p2) - AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -11477,23 +11443,21 @@ static wc_test_ret_t aes_xts_256_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptUpdate(aes, buf, p1, sizeof(p1), i_copy); ret = wc_AesXtsEncryptUpdate(aes, buf, p1, sizeof(p1), &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsEncryptFinal(aes, buf, NULL, 0, i_copy); ret = wc_AesXtsEncryptFinal(aes, buf, NULL, 0, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -11547,16 +11511,14 @@ static wc_test_ret_t aes_xts_256_test(void)
ERROR_OUT(WC_TEST_RET_ENC_NC, out); ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
ret = wc_AesXtsDecryptFinal(aes, buf, c1, sizeof(c1), i_copy); ret = wc_AesXtsDecryptFinal(aes, buf, c1, sizeof(c1), &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -11646,8 +11608,7 @@ static wc_test_ret_t aes_xts_256_test(void)
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -11656,9 +11617,9 @@ static wc_test_ret_t aes_xts_256_test(void)
for (k = 0; k < j; k += AES_BLOCK_SIZE) { for (k = 0; k < j; k += AES_BLOCK_SIZE) {
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
ret = wc_AesXtsEncryptFinal(aes, large_input + k, large_input + k, j - k, i_copy); ret = wc_AesXtsEncryptFinal(aes, large_input + k, large_input + k, j - k, &stream);
else else
ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -11708,8 +11669,7 @@ static wc_test_ret_t aes_xts_256_test(void)
if (ret != 0) if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
XMEMCPY(i_copy, i1, sizeof(i1)); ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream);
ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy));
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
@ -11718,9 +11678,9 @@ static wc_test_ret_t aes_xts_256_test(void)
for (k = 0; k < j; k += AES_BLOCK_SIZE) { for (k = 0; k < j; k += AES_BLOCK_SIZE) {
if ((j - k) < AES_BLOCK_SIZE*2) if ((j - k) < AES_BLOCK_SIZE*2)
ret = wc_AesXtsDecryptFinal(aes, large_input + k, large_input + k, j - k, i_copy); ret = wc_AesXtsDecryptFinal(aes, large_input + k, large_input + k, j - k, &stream);
else else
ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, i_copy); ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, AES_BLOCK_SIZE, &stream);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev,

View File

@ -405,6 +405,13 @@ struct Aes {
#endif #endif
#ifdef WOLFSSL_AES_XTS #ifdef WOLFSSL_AES_XTS
#if FIPS_VERSION3_GE(6,0,0)
/* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
* AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
* protect up to 1,048,576 blocks of AES_BLOCK_SIZE (16,777,216 bytes)
*/
#define FIPS_AES_XTS_MAX_BYTES_PER_TWEAK 16777216
#endif
struct XtsAes { struct XtsAes {
Aes aes; Aes aes;
#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
@ -417,6 +424,14 @@ struct Aes {
typedef struct XtsAes XtsAes; typedef struct XtsAes XtsAes;
#define WC_AESXTS_TYPE_DEFINED #define WC_AESXTS_TYPE_DEFINED
#endif #endif
#ifdef WOLFSSL_AESXTS_STREAM
struct XtsAesStreamData {
byte tweak_block[AES_BLOCK_SIZE];
word32 bytes_crypted_with_this_tweak;
};
#endif
#endif #endif
@ -671,21 +686,23 @@ WOLFSSL_API int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes,
#ifdef WOLFSSL_AESXTS_STREAM #ifdef WOLFSSL_AESXTS_STREAM
WOLFSSL_API int wc_AesXtsEncryptInit(XtsAes* aes, byte* i, word32 iSz); WOLFSSL_API int wc_AesXtsEncryptInit(XtsAes* aes, const byte* i, word32 iSz,
struct XtsAesStreamData *stream);
WOLFSSL_API int wc_AesXtsDecryptInit(XtsAes* aes, byte* i, word32 iSz); WOLFSSL_API int wc_AesXtsDecryptInit(XtsAes* aes, const byte* i, word32 iSz,
struct XtsAesStreamData *stream);
WOLFSSL_API int wc_AesXtsEncryptUpdate(XtsAes* aes, byte* out, WOLFSSL_API int wc_AesXtsEncryptUpdate(XtsAes* aes, byte* out,
const byte* in, word32 sz, byte *i); const byte* in, word32 sz, struct XtsAesStreamData *stream);
WOLFSSL_API int wc_AesXtsDecryptUpdate(XtsAes* aes, byte* out, WOLFSSL_API int wc_AesXtsDecryptUpdate(XtsAes* aes, byte* out,
const byte* in, word32 sz, byte *i); const byte* in, word32 sz, struct XtsAesStreamData *stream);
WOLFSSL_API int wc_AesXtsEncryptFinal(XtsAes* aes, byte* out, WOLFSSL_API int wc_AesXtsEncryptFinal(XtsAes* aes, byte* out,
const byte* in, word32 sz, byte *i); const byte* in, word32 sz, struct XtsAesStreamData *stream);
WOLFSSL_API int wc_AesXtsDecryptFinal(XtsAes* aes, byte* out, WOLFSSL_API int wc_AesXtsDecryptFinal(XtsAes* aes, byte* out,
const byte* in, word32 sz, byte *i); const byte* in, word32 sz, struct XtsAesStreamData *stream);
#endif /* WOLFSSL_AESXTS_STREAM */ #endif /* WOLFSSL_AESXTS_STREAM */