From 5c6218696b0d375e86647b4ce927e119fae50bb0 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sat, 18 May 2024 02:31:58 -0500 Subject: [PATCH 1/2] wolfcrypt/src/misc.c: fix -Wconversions in CopyString(); src/ssl.c: fix missing semicolon in wolfSSL_CTX_check_private_key(). --- src/ssl.c | 2 +- wolfcrypt/src/misc.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index fcb8bf99a3..f468dc5e0e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6349,7 +6349,7 @@ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx) res = check_cert_key(ctx->certificate, ctx->privateKey, ctx->altPrivateKey, ctx->heap, ctx->privateKeyDevId, ctx->privateKeyLabel, ctx->privateKeyId, ctx->altPrivateKeyDevId, ctx->altPrivateKeyLabel, - ctx->altPrivateKeyId) != 0 + ctx->altPrivateKeyId) != 0; #ifdef WOLFSSL_BLIND_PRIVATE_KEY { int ret; diff --git a/wolfcrypt/src/misc.c b/wolfcrypt/src/misc.c index a0f53cfddc..10f733bd02 100644 --- a/wolfcrypt/src/misc.c +++ b/wolfcrypt/src/misc.c @@ -1011,9 +1011,9 @@ WC_MISC_STATIC WC_INLINE char* CopyString(const char* src, int srcLen, if (srcLen <= 0) srcLen = (int)XSTRLEN(src); - dst = (char*)XMALLOC(srcLen + 1, heap, type); + dst = (char*)XMALLOC((size_t)srcLen + 1, heap, type); if (dst != NULL) { - XMEMCPY(dst, src, srcLen); + XMEMCPY(dst, src, (size_t)srcLen); dst[srcLen] = '\0'; } From d0e73783f1107ca88ba7cd967bea9bf3d8be4620 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sat, 18 May 2024 22:00:00 -0500 Subject: [PATCH 2/2] 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*. --- linuxkm/lkcapi_glue.c | 210 ++++++++++++++++++++++++---------------- wolfcrypt/src/aes.c | 141 +++++++++++++++++++-------- wolfcrypt/test/test.c | 174 +++++++++++++-------------------- wolfssl/wolfcrypt/aes.h | 29 ++++-- 4 files changed, 319 insertions(+), 235 deletions(-) diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index 643a653e0c..7b2c135f54 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -33,6 +33,12 @@ #define WOLFSSL_LINUXKM_LKCAPI_PRIORITY 10000 #endif +#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS +static int disable_setkey_warnings = 0; +#else +#define disable_setkey_warnings 0 +#endif + #ifndef NO_AES /* 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); 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; } @@ -207,8 +214,9 @@ static int km_AesSetKeyCommon(struct km_AesCtx * ctx, const u8 *in_key, AES_DECRYPTION); if (unlikely(err)) { - pr_err("%s: wc_AesSetKey for decryption key failed: %d\n", - name, err); + if (! disable_setkey_warnings) + pr_err("%s: wc_AesSetKey for decryption key failed: %d\n", + name, err); return -ENOKEY; } } @@ -320,8 +328,9 @@ static int km_AesCbcDecrypt(struct skcipher_request *req) err = wc_AesSetIV(ctx->aes_decrypt, walk.iv); if (unlikely(err)) { - pr_err("%s: wc_AesSetKey failed: %d\n", - crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + if (! disable_setkey_warnings) + pr_err("%s: wc_AesSetKey failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); return -EINVAL; } @@ -408,8 +417,9 @@ static int km_AesCfbEncrypt(struct skcipher_request *req) err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); if (unlikely(err)) { - pr_err("%s: wc_AesSetKey failed: %d\n", - crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + if (! disable_setkey_warnings) + pr_err("%s: wc_AesSetKey failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); return -EINVAL; } @@ -457,8 +467,9 @@ static int km_AesCfbDecrypt(struct skcipher_request *req) err = wc_AesSetIV(ctx->aes_encrypt, walk.iv); if (unlikely(err)) { - pr_err("%s: wc_AesSetKey failed: %d\n", - crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + if (! disable_setkey_warnings) + pr_err("%s: wc_AesSetKey failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); 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); if (unlikely(err)) { - pr_err("%s: wc_AesGcmSetKey failed: %d\n", - crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); + if (! disable_setkey_warnings) + pr_err("%s: wc_AesGcmSetKey failed: %d\n", + crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), err); return -ENOKEY; } @@ -848,22 +860,13 @@ 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); if (unlikely(err)) { - pr_err("%s: wc_AesXtsSetKeyNoInit failed: %d\n", - crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + if (! disable_setkey_warnings) + pr_err("%s: wc_AesXtsSetKeyNoInit failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); return -EINVAL; } @@ -909,6 +912,7 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) } else { int tail = req->cryptlen % AES_BLOCK_SIZE; struct skcipher_request subreq; + struct XtsAesStreamData stream; if (tail > 0) { 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; } - err = wc_AesXtsEncryptInit(ctx->aesXts, walk.iv, walk.ivsize); + err = wc_AesXtsEncryptInit(ctx->aesXts, walk.iv, walk.ivsize, &stream); if (unlikely(err)) { 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)) err = wc_AesXtsEncryptFinal(ctx->aesXts, walk.dst.virt.addr, walk.src.virt.addr, nbytes, - walk.iv); + &stream); else err = wc_AesXtsEncryptUpdate(ctx->aesXts, walk.dst.virt.addr, walk.src.virt.addr, nbytes, - walk.iv); + &stream); if (unlikely(err)) { 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, walk.src.virt.addr, walk.nbytes, - walk.iv); + &stream); if (unlikely(err)) { 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); + } 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) { - err = wc_AesXtsDecrypt(ctx->aesXts, walk.dst.virt.addr, walk.src.virt.addr, walk.nbytes, walk.iv, walk.ivsize); @@ -1036,10 +1041,10 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) } err = skcipher_walk_done(&walk, 0); - } else { int tail = req->cryptlen % AES_BLOCK_SIZE; struct skcipher_request subreq; + struct XtsAesStreamData stream; if (unlikely(tail > 0)) { 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; } - err = wc_AesXtsDecryptInit(ctx->aesXts, walk.iv, walk.ivsize); + err = wc_AesXtsDecryptInit(ctx->aesXts, walk.iv, walk.ivsize, &stream); if (unlikely(err)) { 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)) err = wc_AesXtsDecryptFinal(ctx->aesXts, walk.dst.virt.addr, walk.src.virt.addr, nbytes, - walk.iv); + &stream); else err = wc_AesXtsDecryptUpdate(ctx->aesXts, walk.dst.virt.addr, walk.src.virt.addr, nbytes, - walk.iv); + &stream); if (unlikely(err)) { 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, walk.src.virt.addr, walk.nbytes, - walk.iv); + &stream); if (unlikely(err)) { 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); + } else if (! (stream.bytes_crypted_with_this_tweak & ((word32)AES_BLOCK_SIZE - 1U))) { + err = wc_AesXtsDecryptFinal(ctx->aesXts, NULL, NULL, 0, &stream); } - } return err; } @@ -1886,7 +1892,7 @@ static int aes_xts_128_test(void) struct scatterlist * dst = NULL; struct crypto_skcipher *tfm = NULL; struct skcipher_request *req = NULL; - u8 iv[AES_BLOCK_SIZE]; + struct XtsAesStreamData stream; byte* large_input = NULL; /* 128 key tests */ @@ -2032,16 +2038,15 @@ 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)); + ret = wc_AesXtsEncryptInit(aes, i2, sizeof(i2), &stream); if (ret != 0) 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) goto out; ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, p2 + AES_BLOCK_SIZE, - sizeof(p2) - AES_BLOCK_SIZE, iv); + sizeof(p2) - AES_BLOCK_SIZE, &stream); if (ret != 0) goto out; 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); if (ret != 0) goto out; - XMEMCPY(iv, i1, sizeof(i1)); - ret = wc_AesXtsEncryptInit(aes, iv, sizeof(iv)); + ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream); if (ret != 0) goto out; for (k = 0; k < j; k += AES_BLOCK_SIZE) { 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 - 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) goto out; 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); if (ret != 0) goto out; - XMEMCPY(iv, i1, sizeof(i1)); - ret = wc_AesXtsDecryptInit(aes, iv, sizeof(iv)); + ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream); if (ret != 0) goto out; for (k = 0; k < j; k += AES_BLOCK_SIZE) { 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 - 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) goto out; if ((j - k) < AES_BLOCK_SIZE*2) @@ -2335,10 +2338,10 @@ static int aes_xts_128_test(void) #endif 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()" " returned %d but expected %d\n", - WOLFKM_AESXTS_DRIVER, ret, (int)sizeof(iv)); + WOLFKM_AESXTS_DRIVER, ret, (int)sizeof(stream.tweak_block)); ret = -EINVAL; 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(dst, enc2, sizeof(p1)); - memcpy(iv, i1, sizeof(iv)); - skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); + memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block)); + skcipher_request_set_crypt(req, src, dst, sizeof(p1), stream.tweak_block); 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(dst, dec2, sizeof(p1)); - memcpy(iv, i1, sizeof(iv)); - skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); + memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block)); + skcipher_request_set_crypt(req, src, dst, sizeof(p1), stream.tweak_block); 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(dst, enc2, sizeof(pp)); - memcpy(iv, i1, sizeof(iv)); - skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); + memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block)); + skcipher_request_set_crypt(req, src, dst, sizeof(pp), stream.tweak_block); 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(dst, dec2, sizeof(pp)); - memcpy(iv, i1, sizeof(iv)); - skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); + memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block)); + skcipher_request_set_crypt(req, src, dst, sizeof(pp), stream.tweak_block); ret = crypto_skcipher_decrypt(req); @@ -2498,7 +2501,7 @@ static int aes_xts_256_test(void) struct scatterlist * dst = NULL; struct crypto_skcipher *tfm = NULL; struct skcipher_request *req = NULL; - u8 iv[AES_BLOCK_SIZE]; + struct XtsAesStreamData stream; byte* large_input = NULL; /* 256 key tests */ @@ -2620,16 +2623,15 @@ static int aes_xts_256_test(void) XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); - XMEMCPY(iv, i2, sizeof(i2)); - ret = wc_AesXtsEncryptInit(aes, iv, sizeof(iv)); + ret = wc_AesXtsEncryptInit(aes, i2, sizeof(i2), &stream); if (ret != 0) 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) goto out; ret = wc_AesXtsEncryptFinal(aes, buf + AES_BLOCK_SIZE, p2 + AES_BLOCK_SIZE, - sizeof(p2) - AES_BLOCK_SIZE, iv); + sizeof(p2) - AES_BLOCK_SIZE, &stream); if (ret != 0) goto out; 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); if (ret != 0) goto out; - XMEMCPY(iv, i1, sizeof(i1)); - ret = wc_AesXtsEncryptInit(aes, iv, sizeof(iv)); + ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream); if (ret != 0) goto out; for (k = 0; k < j; k += AES_BLOCK_SIZE) { 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 - 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) goto out; 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); if (ret != 0) goto out; - XMEMCPY(iv, i1, sizeof(i1)); - ret = wc_AesXtsDecryptInit(aes, iv, sizeof(iv)); + ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream); if (ret != 0) goto out; for (k = 0; k < j; k += AES_BLOCK_SIZE) { 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 - 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) goto out; if ((j - k) < AES_BLOCK_SIZE*2) @@ -2826,10 +2826,10 @@ static int aes_xts_256_test(void) #endif 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()" " returned %d but expected %d\n", - WOLFKM_AESXTS_DRIVER, ret, (int)sizeof(iv)); + WOLFKM_AESXTS_DRIVER, ret, (int)sizeof(stream.tweak_block)); ret = -EINVAL; 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(dst, enc2, sizeof(p1)); - memcpy(iv, i1, sizeof(iv)); - skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); + memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block)); + skcipher_request_set_crypt(req, src, dst, sizeof(p1), stream.tweak_block); 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(dst, dec2, sizeof(p1)); - memcpy(iv, i1, sizeof(iv)); - skcipher_request_set_crypt(req, src, dst, sizeof(p1), iv); + memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block)); + skcipher_request_set_crypt(req, src, dst, sizeof(p1), stream.tweak_block); 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(dst, enc2, sizeof(pp)); - memcpy(iv, i1, sizeof(iv)); - skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); + memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block)); + skcipher_request_set_crypt(req, src, dst, sizeof(pp), stream.tweak_block); 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(dst, dec2, sizeof(pp)); - memcpy(iv, i1, sizeof(iv)); - skcipher_request_set_crypt(req, src, dst, sizeof(pp), iv); + memcpy(stream.tweak_block, i1, sizeof(stream.tweak_block)); + skcipher_request_set_crypt(req, src, dst, sizeof(pp), stream.tweak_block); ret = crypto_skcipher_decrypt(req); @@ -3003,15 +3003,46 @@ static int linuxkm_test_aesxts(void) { #endif /* !NO_AES */ +#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \ + !defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS) + #ifdef CONFIG_CRYPTO_FIPS + #include + #else + #error wolfCrypt FIPS with LINUXKM_LKCAPI_REGISTER and CONFIG_CRYPTO_MANAGER requires CONFIG_CRYPTO_FIPS + #endif +#endif + static int linuxkm_lkcapi_register(void) { 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 { \ if (alg ## _loaded) { \ pr_err("ERROR: %s is already registered.\n", \ (alg).base.cra_driver_name); \ - return -EEXIST; \ + ret = -EEXIST; \ + goto out; \ } \ \ ret = (installer)(&(alg)); \ @@ -3020,7 +3051,7 @@ static int linuxkm_lkcapi_register(void) pr_err("ERROR: " #installer " for %s failed " \ "with return code %d.\n", \ (alg).base.cra_driver_name, ret); \ - return ret; \ + goto out; \ } \ \ alg ## _loaded = 1; \ @@ -3031,7 +3062,7 @@ static int linuxkm_lkcapi_register(void) pr_err("ERROR: self-test for %s failed " \ "with return code %d.\n", \ (alg).base.cra_driver_name, ret); \ - return ret; \ + goto out; \ } \ pr_info("%s self-test OK -- " \ "registered for %s with priority %d.\n", \ @@ -3070,7 +3101,18 @@ static int linuxkm_lkcapi_register(void) #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) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 0416cd2947..30cdba3cba 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -12783,15 +12783,18 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, 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_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. - */ + aes = &xaes->aes; if (aes->keylen == 0) { 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 */ -int wc_AesXtsEncryptInit(XtsAes* xaes, byte* i, word32 iSz) +int wc_AesXtsEncryptInit(XtsAes* xaes, const byte* i, word32 iSz, + struct XtsAesStreamData *stream) { int ret; Aes *aes; - if ((xaes == NULL) || (i == NULL)) { + if ((xaes == NULL) || (i == NULL) || (stream == NULL)) { return BAD_FUNC_ARG; } @@ -12876,20 +12880,25 @@ int wc_AesXtsEncryptInit(XtsAes* xaes, byte* i, word32 iSz) return BAD_FUNC_ARG; } + XMEMCPY(stream->tweak_block, i, AES_BLOCK_SIZE); + stream->bytes_crypted_with_this_tweak = 0; + { #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, + AES_XTS_init_avx1(stream->tweak_block, + (const byte*)xaes->tweak.key, (int)xaes->tweak.rounds); ret = 0; } else #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); ret = 0; } @@ -12898,7 +12907,7 @@ int wc_AesXtsEncryptInit(XtsAes* xaes, byte* i, word32 iSz) else #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 */ static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz, - byte *i) + struct XtsAesStreamData *stream) { int ret; @@ -12930,7 +12939,7 @@ static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s Aes *aes; #endif - if (xaes == NULL || out == NULL || in == NULL || i == NULL) { + if (xaes == NULL || out == NULL || in == NULL) { return BAD_FUNC_ARG; } @@ -12943,6 +12952,28 @@ static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s 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 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)) { AES_XTS_encrypt_update_avx1(in, out, sz, (const byte*)aes->key, - i, + stream->tweak_block, (int)aes->rounds); 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, (const byte*)aes->key, - i, + stream->tweak_block, (int)aes->rounds); ret = 0; } @@ -12969,7 +13000,7 @@ static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s else #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, - byte *i) + struct XtsAesStreamData *stream) { + if (stream == NULL) + return BAD_FUNC_ARG; if (sz & ((word32)AES_BLOCK_SIZE - 1U)) 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, - byte *i) + struct XtsAesStreamData *stream) { int ret; + if (stream == NULL) + return BAD_FUNC_ARG; if (sz > 0) - ret = AesXtsEncryptUpdate(xaes, out, in, sz, i); + ret = AesXtsEncryptUpdate(xaes, out, in, sz, stream); else 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 - wc_MemZero_Check(i, AES_BLOCK_SIZE); + wc_MemZero_Check(stream->tweak_block, AES_BLOCK_SIZE); #endif return ret; } @@ -13252,7 +13291,8 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, * * 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; Aes *aes; @@ -13276,20 +13316,25 @@ int wc_AesXtsDecryptInit(XtsAes* xaes, byte* i, word32 iSz) return BAD_FUNC_ARG; } + XMEMCPY(stream->tweak_block, i, AES_BLOCK_SIZE); + stream->bytes_crypted_with_this_tweak = 0; + { #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, + AES_XTS_init_avx1(stream->tweak_block, + (const byte*)xaes->tweak.key, (int)xaes->tweak.rounds); ret = 0; } else #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); ret = 0; } @@ -13298,7 +13343,7 @@ int wc_AesXtsDecryptInit(XtsAes* xaes, byte* i, word32 iSz) else #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 */ static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz, - byte *i) + struct XtsAesStreamData *stream) { int ret; #ifdef WOLFSSL_AESNI @@ -13345,6 +13390,17 @@ static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s 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 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)) { AES_XTS_decrypt_update_avx1(in, out, sz, (const byte*)aes->key, - i, + stream->tweak_block, (int)aes->rounds); 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, (const byte*)aes->key, - i, + stream->tweak_block, (int)aes->rounds); ret = 0; } @@ -13371,7 +13427,8 @@ static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 s else #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, - byte *i) + struct XtsAesStreamData *stream) { + if (stream == NULL) + return BAD_FUNC_ARG; if (sz & ((word32)AES_BLOCK_SIZE - 1U)) 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, - byte *i) + struct XtsAesStreamData *stream) { int ret; + if (stream == NULL) + return BAD_FUNC_ARG; if (sz > 0) - ret = AesXtsDecryptUpdate(xaes, out, in, sz, i); + ret = AesXtsDecryptUpdate(xaes, out, in, sz, stream); else 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 - wc_MemZero_Check(i, AES_BLOCK_SIZE); + wc_MemZero_Check(stream->tweak_block, AES_BLOCK_SIZE); #endif return ret; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 81553be03b..78bf1cdc40 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -9876,7 +9876,7 @@ static wc_test_ret_t aes_xts_128_test(void) unsigned char buf[AES_BLOCK_SIZE * 2 + 8]; unsigned char cipher[AES_BLOCK_SIZE * 2 + 8]; #ifdef WOLFSSL_AESXTS_STREAM - unsigned char i_copy[AES_BLOCK_SIZE]; + struct XtsAesStreamData stream; #endif #if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \ !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); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i2, sizeof(i2)); - - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i2, sizeof(i2), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10068,23 +10066,21 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i1, sizeof(i1)); - - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i2), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10121,23 +10117,21 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i1, sizeof(i1)); - - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10182,16 +10176,14 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i1, sizeof(i1)); - - ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10237,16 +10229,14 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i1, sizeof(i1)); - - ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10327,23 +10317,21 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i3, sizeof(i3)); - - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i3, sizeof(i3), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10371,23 +10359,21 @@ static wc_test_ret_t aes_xts_128_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i3, sizeof(i3)); - - ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsDecryptInit(aes, i3, sizeof(i3), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10462,8 +10448,7 @@ static wc_test_ret_t aes_xts_128_test(void) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - XMEMCPY(i_copy, i1, sizeof(i1)); - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10472,9 +10457,9 @@ static wc_test_ret_t aes_xts_128_test(void) for (k = 0; k < j; k += AES_BLOCK_SIZE) { 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 - 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10525,8 +10510,7 @@ static wc_test_ret_t aes_xts_128_test(void) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - XMEMCPY(i_copy, i1, sizeof(i1)); - ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10535,9 +10519,9 @@ static wc_test_ret_t aes_xts_128_test(void) for (k = 0; k < j; k += AES_BLOCK_SIZE) { 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 - 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) #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS 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 cipher[AES_BLOCK_SIZE * 2 + 8]; #ifdef WOLFSSL_AESXTS_STREAM - unsigned char i_copy[AES_BLOCK_SIZE]; + struct XtsAesStreamData stream; #endif #if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \ !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); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i2, sizeof(i2)); - - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i2, sizeof(i2), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10786,23 +10768,21 @@ static wc_test_ret_t aes_xts_192_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i1, sizeof(i1)); - - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10839,23 +10819,21 @@ static wc_test_ret_t aes_xts_192_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i1, sizeof(i1)); - - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10900,16 +10878,14 @@ static wc_test_ret_t aes_xts_192_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i1, sizeof(i1)); - - ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -10955,16 +10931,14 @@ static wc_test_ret_t aes_xts_192_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i1, sizeof(i1)); - - ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -11045,23 +11019,21 @@ static wc_test_ret_t aes_xts_192_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i3, sizeof(i3)); - - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i3, sizeof(i3), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -11089,23 +11061,21 @@ static wc_test_ret_t aes_xts_192_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i3, sizeof(i3)); - - ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsDecryptInit(aes, i3, sizeof(i3), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -11180,8 +11150,7 @@ static wc_test_ret_t aes_xts_192_test(void) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - XMEMCPY(i_copy, i1, sizeof(i1)); - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -11190,9 +11159,9 @@ static wc_test_ret_t aes_xts_192_test(void) for (k = 0; k < j; k += AES_BLOCK_SIZE) { 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 - 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -11243,8 +11212,7 @@ static wc_test_ret_t aes_xts_192_test(void) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - XMEMCPY(i_copy, i1, sizeof(i1)); - ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -11253,9 +11221,9 @@ static wc_test_ret_t aes_xts_192_test(void) for (k = 0; k < j; k += AES_BLOCK_SIZE) { 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 - 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) #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS 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 cipher[AES_BLOCK_SIZE * 3]; #ifdef WOLFSSL_AESXTS_STREAM - unsigned char i_copy[AES_BLOCK_SIZE]; + struct XtsAesStreamData stream; #endif #if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \ !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); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i2, sizeof(i2)); - - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i2, sizeof(i2), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -11477,23 +11443,21 @@ static wc_test_ret_t aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i1, sizeof(i1)); - - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -11547,16 +11511,14 @@ static wc_test_ret_t aes_xts_256_test(void) ERROR_OUT(WC_TEST_RET_ENC_NC, out); #ifdef WOLFSSL_AESXTS_STREAM - XMEMCPY(i_copy, i1, sizeof(i1)); - - ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -11646,8 +11608,7 @@ static wc_test_ret_t aes_xts_256_test(void) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - XMEMCPY(i_copy, i1, sizeof(i1)); - ret = wc_AesXtsEncryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsEncryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -11656,9 +11617,9 @@ static wc_test_ret_t aes_xts_256_test(void) for (k = 0; k < j; k += AES_BLOCK_SIZE) { 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 - 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) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -11708,8 +11669,7 @@ static wc_test_ret_t aes_xts_256_test(void) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - XMEMCPY(i_copy, i1, sizeof(i1)); - ret = wc_AesXtsDecryptInit(aes, i_copy, sizeof(i_copy)); + ret = wc_AesXtsDecryptInit(aes, i1, sizeof(i1), &stream); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); #endif @@ -11718,9 +11678,9 @@ static wc_test_ret_t aes_xts_256_test(void) for (k = 0; k < j; k += AES_BLOCK_SIZE) { 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 - 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) #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 38bc8c32ce..9325d6580e 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -405,6 +405,13 @@ struct Aes { #endif #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 { Aes aes; #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS @@ -417,6 +424,14 @@ struct Aes { typedef struct XtsAes XtsAes; #define WC_AESXTS_TYPE_DEFINED #endif + + #ifdef WOLFSSL_AESXTS_STREAM + struct XtsAesStreamData { + byte tweak_block[AES_BLOCK_SIZE]; + word32 bytes_crypted_with_this_tweak; + }; + #endif + #endif @@ -671,21 +686,23 @@ WOLFSSL_API int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes, #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, - const byte* in, word32 sz, byte *i); + const byte* in, word32 sz, struct XtsAesStreamData *stream); 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, - const byte* in, word32 sz, byte *i); + const byte* in, word32 sz, struct XtsAesStreamData *stream); 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 */