diff --git a/.github/workflows/openvpn.yml b/.github/workflows/openvpn.yml index 97243cb9e..10a20b065 100644 --- a/.github/workflows/openvpn.yml +++ b/.github/workflows/openvpn.yml @@ -39,7 +39,8 @@ jobs: fail-fast: false matrix: # List of refs to test - ref: [ release/2.6, v2.6.0, master ] + # disabled master on 20240514 -- see https://github.com/wolfSSL/wolfssl/issues/7508 + ref: [ release/2.6, v2.6.0 ] name: ${{ matrix.ref }} runs-on: ubuntu-latest # This should be a safe limit for the tests to run. diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index 467aa4856..746edc929 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -925,7 +925,7 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); if (!walk.nbytes) - return err; + return err ? : -EINVAL; } else { tail = 0; } @@ -939,6 +939,9 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) } while ((nbytes = walk.nbytes) != 0) { + /* if this isn't the final call, pass block-aligned data to prevent + * end-of-message ciphertext stealing. + */ if (nbytes < walk.total) nbytes &= ~(AES_BLOCK_SIZE - 1); @@ -961,7 +964,7 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) } } - if (unlikely(tail > 0 && !err)) { + if (unlikely(tail > 0)) { struct scatterlist sg_src[2], sg_dst[2]; struct scatterlist *src, *dst; @@ -1048,7 +1051,7 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) err = skcipher_walk_virt(&walk, req, false); if (!walk.nbytes) - return err; + return err ? : -EINVAL; } else { tail = 0; } @@ -1062,6 +1065,9 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) } while ((nbytes = walk.nbytes) != 0) { + /* if this isn't the final call, pass block-aligned data to prevent + * end-of-message ciphertext stealing. + */ if (nbytes < walk.total) nbytes &= ~(AES_BLOCK_SIZE - 1); @@ -1084,32 +1090,32 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) } } - if (unlikely(tail > 0 && !err)) { - struct scatterlist sg_src[2], sg_dst[2]; - struct scatterlist *src, *dst; + if (unlikely(tail > 0)) { + struct scatterlist sg_src[2], sg_dst[2]; + struct scatterlist *src, *dst; - dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); - if (req->dst != req->src) - dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); + dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen); + if (req->dst != req->src) + dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen); - skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail, - req->iv); + skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail, + req->iv); - err = skcipher_walk_virt(&walk, &subreq, false); - if (err) - return err; + err = skcipher_walk_virt(&walk, &subreq, false); + if (err) + return err; - err = wc_AesXtsDecryptUpdate(ctx->aesXts, walk.dst.virt.addr, - walk.src.virt.addr, walk.nbytes, - walk.iv); + err = wc_AesXtsDecryptUpdate(ctx->aesXts, walk.dst.virt.addr, + walk.src.virt.addr, walk.nbytes, + walk.iv); - if (unlikely(err)) { - pr_err("%s: wc_AesXtsDecryptUpdate failed: %d\n", - crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; - } + if (unlikely(err)) { + pr_err("%s: wc_AesXtsDecryptUpdate failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + return -EINVAL; + } - err = skcipher_walk_done(&walk, 0); + err = skcipher_walk_done(&walk, 0); } } diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 931a69f3f..e19ec0eed 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -12840,6 +12840,15 @@ int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, #ifdef WOLFSSL_AESXTS_STREAM +/* Block-streaming AES-XTS. + * + * xaes AES keys to use for block encrypt/decrypt + * i readwrite value to use for tweak + * iSz size of i buffer, should always be AES_BLOCK_SIZE but having this input + * adds a sanity check on how the user calls the function. + * + * returns 0 on success + */ int wc_AesXtsEncryptInit(XtsAes* xaes, byte* i, word32 iSz) { int ret; @@ -12894,12 +12903,15 @@ int wc_AesXtsEncryptInit(XtsAes* xaes, byte* i, word32 iSz) return ret; } -/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing. +/* Block-streaming AES-XTS + * + * Note that sz must be greater than AES_BLOCK_SIZE in each call, and must be a + * multiple of AES_BLOCK_SIZE in all but the final call. * * xaes AES keys to use for block encrypt/decrypt * out output buffer to hold cipher text * in input plain text buffer to encrypt - * sz size of both out and in buffers + * sz size of both out and in buffers -- must be >= AES_BLOCK_SIZE. * i value to use for tweak * iSz size of i buffer, should always be AES_BLOCK_SIZE but having this input * adds a sanity check on how the user calls the function. @@ -13211,7 +13223,6 @@ int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz, * i readwrite value to use for tweak * iSz size of i buffer, should always be AES_BLOCK_SIZE but having this input * adds a sanity check on how the user calls the function. - * tweak_block buffer of size AES_BLOCK_SIZE to use for tweak state * * returns 0 on success */ @@ -13269,7 +13280,10 @@ int wc_AesXtsDecryptInit(XtsAes* xaes, byte* i, word32 iSz) return ret; } -/* Same process as encryption but Aes key is AES_DECRYPTION type. +/* Block-streaming AES-XTS + * + * Note that sz must be greater than AES_BLOCK_SIZE in each call, and must be a + * multiple of AES_BLOCK_SIZE in all but the final call. * * xaes AES keys to use for block encrypt/decrypt * out output buffer to hold plain text diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index e1bde7b1b..e07329a6d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -9863,6 +9863,9 @@ static wc_test_ret_t aes_xts_128_test(void) wc_test_ret_t ret = 0; 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]; +#endif /* 128 key tests */ WOLFSSL_SMALL_STACK_STATIC unsigned char k1[] = { @@ -9987,6 +9990,34 @@ static wc_test_ret_t aes_xts_128_test(void) if (XMEMCMP(c2, buf, sizeof(c2))) 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)); +#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); +#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 + AES_BLOCK_SIZE, p2 + AES_BLOCK_SIZE, sizeof(p2) - AES_BLOCK_SIZE, i_copy); +#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); + + if (XMEMCMP(c2, buf, sizeof(c2))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif /* WOLFSSL_AESXTS_STREAM */ + #if defined(DEBUG_VECTOR_REGISTER_ACCESS_AESXTS) && \ defined(WC_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); @@ -10015,6 +10046,27 @@ static wc_test_ret_t aes_xts_128_test(void) if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) 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)); +#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); +#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); + + if (XMEMCMP(c1, buf, sizeof(c1))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif /* WOLFSSL_AESXTS_STREAM */ + #if defined(DEBUG_VECTOR_REGISTER_ACCESS_AESXTS) && \ defined(WC_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); @@ -10040,6 +10092,27 @@ static wc_test_ret_t aes_xts_128_test(void) if (XMEMCMP(cp2, cipher, sizeof(cp2))) 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)); +#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, pp, sizeof(pp), i_copy); +#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); + + if (XMEMCMP(cp2, buf, sizeof(cp2))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif /* WOLFSSL_AESXTS_STREAM */ + #if defined(DEBUG_VECTOR_REGISTER_ACCESS_AESXTS) && \ defined(WC_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); @@ -10073,6 +10146,27 @@ static wc_test_ret_t aes_xts_128_test(void) if (XMEMCMP(pp, buf, sizeof(pp))) 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)); +#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, cipher, sizeof(pp), i_copy); +#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); + + if (XMEMCMP(pp, buf, sizeof(pp))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif /* WOLFSSL_AESXTS_STREAM */ + #if defined(DEBUG_VECTOR_REGISTER_ACCESS_AESXTS) && \ defined(WC_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); @@ -10104,9 +10198,30 @@ static wc_test_ret_t aes_xts_128_test(void) #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) + if (XMEMCMP(p1, buf, sizeof(p1))) 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)); +#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, c1, sizeof(c1), i_copy); +#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); + + if (XMEMCMP(p1, buf, sizeof(p1))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif /* WOLFSSL_AESXTS_STREAM */ + #if defined(DEBUG_VECTOR_REGISTER_ACCESS_AESXTS) && \ defined(WC_C_DYNAMIC_FALLBACK) WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E); @@ -10176,6 +10291,34 @@ static wc_test_ret_t aes_xts_128_test(void) if (XMEMCMP(c3, buf, sizeof(c3))) 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)); +#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); +#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 + AES_BLOCK_SIZE, p3 + AES_BLOCK_SIZE, sizeof(p3) - AES_BLOCK_SIZE, i_copy); +#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); + + if (XMEMCMP(c3, buf, sizeof(c3))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif /* WOLFSSL_AESXTS_STREAM */ + ret = wc_AesXtsSetKeyNoInit(aes, k3, sizeof(k3), AES_DECRYPTION); if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); @@ -10192,6 +10335,34 @@ static wc_test_ret_t aes_xts_128_test(void) if (XMEMCMP(p3, buf, sizeof(p3))) 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)); +#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); +#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 + AES_BLOCK_SIZE, c3 + AES_BLOCK_SIZE, sizeof(c3) - AES_BLOCK_SIZE, i_copy); +#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); + + if (XMEMCMP(p3, buf, sizeof(p3))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif /* WOLFSSL_AESXTS_STREAM */ + #endif /* !HAVE_FIPS */ #if !defined(BENCH_EMBEDDED) && !defined(HAVE_CAVIUM) && \ @@ -10206,6 +10377,9 @@ static wc_test_ret_t aes_xts_128_test(void) #endif int i; int j; +#ifdef WOLFSSL_AESXTS_STREAM + int k; +#endif #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) if (large_input == NULL) ERROR_OUT(WC_TEST_RET_ENC_EC(MEMORY_E), out); @@ -10247,6 +10421,71 @@ static wc_test_ret_t aes_xts_128_test(void) } } } + +#ifdef WOLFSSL_AESXTS_STREAM + for (i = 0; i < (int)LARGE_XTS_SZ; i++) + large_input[i] = (byte)i; + + for (j = 16; j < (int)LARGE_XTS_SZ; j++) { + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); + 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)); + #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); + + for (k = 0; k < j; k += AES_BLOCK_SIZE) { + ret = wc_AesXtsEncryptUpdate(aes, large_input + k, large_input + k, (j - k) < AES_BLOCK_SIZE*2 ? j - k : AES_BLOCK_SIZE, i_copy); + #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); + if ((j - k) < AES_BLOCK_SIZE*2) + break; + } + + ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_DECRYPTION); + 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)); + #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); + + for (k = 0; k < j; k += AES_BLOCK_SIZE) { + ret = wc_AesXtsDecryptUpdate(aes, large_input + k, large_input + k, (j - k) < AES_BLOCK_SIZE*2 ? j - k : AES_BLOCK_SIZE, i_copy); + #if defined(WOLFSSL_ASYNC_CRYPT) + #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS + ret = wc_AsyncWait(ret, &aes->aes_decrypt.asyncDev, + WC_ASYNC_FLAG_NONE); + #else + ret = wc_AsyncWait(ret, &aes->aes.asyncDev, WC_ASYNC_FLAG_NONE); + #endif + #endif + if (ret != 0) + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); + if ((j - k) < AES_BLOCK_SIZE*2) + break; + } + + for (i = 0; i < j; i++) { + if (large_input[i] != (byte)i) { + ERROR_OUT(WC_TEST_RET_ENC_NC, out); + } + } + } +#endif /* WOLFSSL_AESXTS_STREAM */ + #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) XFREE(large_input, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -10282,6 +10521,9 @@ static wc_test_ret_t aes_xts_256_test(void) wc_test_ret_t ret = 0; 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]; +#endif /* 256 key tests */ WOLFSSL_SMALL_STACK_STATIC unsigned char k1[] = { @@ -10389,6 +10631,34 @@ static wc_test_ret_t aes_xts_256_test(void) if (XMEMCMP(c2, buf, sizeof(c2))) 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)); +#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); +#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 + AES_BLOCK_SIZE, p2 + AES_BLOCK_SIZE, sizeof(p2) - AES_BLOCK_SIZE, i_copy); +#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); + + if (XMEMCMP(c2, buf, sizeof(c2))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif /* WOLFSSL_AESXTS_STREAM */ + XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsSetKeyNoInit(aes, k1, sizeof(k1), AES_ENCRYPTION); if (ret != 0) @@ -10402,6 +10672,27 @@ static wc_test_ret_t aes_xts_256_test(void) if (XMEMCMP(c1, buf, AES_BLOCK_SIZE)) 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)); +#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); +#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); + + if (XMEMCMP(c1, buf, sizeof(c1))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif /* WOLFSSL_AESXTS_STREAM */ + /* partial block encryption test */ XMEMSET(cipher, 0, sizeof(cipher)); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); @@ -10441,9 +10732,30 @@ static wc_test_ret_t aes_xts_256_test(void) #endif if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out); - if (XMEMCMP(p1, buf, AES_BLOCK_SIZE)) + if (XMEMCMP(p1, buf, sizeof(p1))) 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)); +#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, c1, sizeof(c1), i_copy); +#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); + + if (XMEMCMP(p1, buf, sizeof(p1))) + ERROR_OUT(WC_TEST_RET_ENC_NC, out); +#endif /* WOLFSSL_AESXTS_STREAM */ + XMEMSET(buf, 0, sizeof(buf)); ret = wc_AesXtsSetKeyNoInit(aes, k2, sizeof(k2), AES_DECRYPTION); if (ret != 0)