From 98f09b06884c550878a1310bae08dd37f377e9bf Mon Sep 17 00:00:00 2001 From: manastasova Date: Mon, 3 Nov 2025 19:44:55 +0000 Subject: [PATCH 1/5] Add Encrypt and Decrypt test on random input messages of incremental lengths for AES-XTS --- crypto/fipsmodule/modes/xts_test.cc | 90 ++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/crypto/fipsmodule/modes/xts_test.cc b/crypto/fipsmodule/modes/xts_test.cc index 2f6aebb395e..03a49c6bb81 100644 --- a/crypto/fipsmodule/modes/xts_test.cc +++ b/crypto/fipsmodule/modes/xts_test.cc @@ -15,6 +15,8 @@ #include #include +#include + #include #include @@ -23,6 +25,8 @@ #include "internal.h" #include "../../test/test_util.h" +#define AESXTS_RAND_MSG_MAX_LEN 4096 + #if defined(OPENSSL_LINUX) #include #endif @@ -1202,7 +1206,7 @@ TEST(XTSTest, TestVectors) { in_p = in.get(); out_p = out.get(); #endif - for (bool in_place : {false, true}) { + for (bool in_place : {false, true}) { SCOPED_TRACE(in_place); // Test encryption. @@ -1240,6 +1244,90 @@ TEST(XTSTest, TestVectors) { #endif } +TEST(XTSTest, EncryptDecyptRand) { +#if defined(OPENSSL_LINUX) + int pagesize = sysconf(_SC_PAGE_SIZE); + ASSERT_GE(pagesize, 0); + uint8_t *in_buffer_beg = get_buffer_beg(pagesize); + uint8_t *out_buffer_beg = get_buffer_beg(pagesize); + uint8_t *in_buffer_end = in_buffer_beg + pagesize; + uint8_t *out_buffer_end = out_buffer_beg + pagesize; +#endif + +const EVP_CIPHER *cipher = EVP_aes_256_xts(); + + // Test AESXTS Encrypt and Decrypt with random messages of incremental lenghts + for (size_t msg_len = 16; msg_len < AESXTS_RAND_MSG_MAX_LEN ; msg_len += 1) { + + std::vector key(EVP_CIPHER_key_length(cipher)), iv(EVP_CIPHER_iv_length(cipher)), + plaintext(msg_len), ciphertext(msg_len), plaintext_test(msg_len); + RAND_bytes(key.data(), EVP_CIPHER_key_length(cipher)); + RAND_bytes(iv.data(), EVP_CIPHER_iv_length(cipher)); + RAND_bytes(plaintext.data(), msg_len); + OPENSSL_memset(ciphertext.data(), 0, msg_len); + OPENSSL_memset(plaintext_test.data(), 0, msg_len); + + SCOPED_TRACE(plaintext.size()); + + int len; + uint8_t *in_p, *out_p; + #if defined(OPENSSL_LINUX) + ASSERT_GE(pagesize, (int)plaintext.size()); + + for (bool beg: {false, true}) { + if (!beg) { + in_p = in_buffer_end - plaintext.size(); + out_p = out_buffer_end - plaintext.size(); + } else { + in_p = in_buffer_end - pagesize; + out_p = out_buffer_end - pagesize; + } + OPENSSL_memset(in_p, 0x00, plaintext.size()); + OPENSSL_memset(out_p, 0x00, plaintext.size()); + #else + std::unique_ptr in(new uint8_t[plaintext.size()]); + std::unique_ptr out(new uint8_t[plaintext.size()]); + in_p = in.get(); + out_p = out.get(); + #endif + for (bool in_place : {false, true}) { + SCOPED_TRACE(in_place); + + // Test encryption. + + OPENSSL_memcpy(in_p, plaintext.data(), plaintext.size()); + if (in_place) { + out_p = in_p; + } + + bssl::ScopedEVP_CIPHER_CTX ctx; + ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), cipher, nullptr, key.data(), + iv.data())); + ASSERT_TRUE( + EVP_EncryptUpdate(ctx.get(), out_p, &len, in_p, plaintext.size())); + OPENSSL_memcpy(ciphertext.data(), out_p, plaintext.size()); + + // Test decryption. + + if (!in_place) { + OPENSSL_memset(in_p, 0, len); + } + + ctx.Reset(); + ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), cipher, nullptr, key.data(), + iv.data())); + ASSERT_TRUE( + EVP_DecryptUpdate(ctx.get(), in_p, &len, out_p, ciphertext.size())); + EXPECT_EQ(Bytes(plaintext), Bytes(in_p, static_cast(len))); + } + } +#if defined(OPENSSL_LINUX) + } + free_memory(in_buffer_end, pagesize); + free_memory(out_buffer_end, pagesize); +#endif +} + // Negative test for key1 = key2 TEST(XTSTest, DuplicateKey) { From 4afa2b2771865c0368fdcb294f9435effe37c751 Mon Sep 17 00:00:00 2001 From: manastasova Date: Fri, 7 Nov 2025 21:50:54 +0000 Subject: [PATCH 2/5] Add plaintext and ciphertext length equality check --- crypto/fipsmodule/modes/xts_test.cc | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/crypto/fipsmodule/modes/xts_test.cc b/crypto/fipsmodule/modes/xts_test.cc index 03a49c6bb81..d3084e612bd 100644 --- a/crypto/fipsmodule/modes/xts_test.cc +++ b/crypto/fipsmodule/modes/xts_test.cc @@ -1244,7 +1244,7 @@ TEST(XTSTest, TestVectors) { #endif } -TEST(XTSTest, EncryptDecyptRand) { +TEST(XTSTest, EncryptDecryptRand) { #if defined(OPENSSL_LINUX) int pagesize = sysconf(_SC_PAGE_SIZE); ASSERT_GE(pagesize, 0); @@ -1260,17 +1260,17 @@ const EVP_CIPHER *cipher = EVP_aes_256_xts(); for (size_t msg_len = 16; msg_len < AESXTS_RAND_MSG_MAX_LEN ; msg_len += 1) { std::vector key(EVP_CIPHER_key_length(cipher)), iv(EVP_CIPHER_iv_length(cipher)), - plaintext(msg_len), ciphertext(msg_len), plaintext_test(msg_len); + plaintext(msg_len), plaintext_test(msg_len); RAND_bytes(key.data(), EVP_CIPHER_key_length(cipher)); RAND_bytes(iv.data(), EVP_CIPHER_iv_length(cipher)); RAND_bytes(plaintext.data(), msg_len); - OPENSSL_memset(ciphertext.data(), 0, msg_len); OPENSSL_memset(plaintext_test.data(), 0, msg_len); SCOPED_TRACE(plaintext.size()); - int len; - uint8_t *in_p, *out_p; + int len = 0; + size_t decrypted_len = 0, encrypted_len = 0; + uint8_t *in_p = nullptr, *out_p = nullptr; #if defined(OPENSSL_LINUX) ASSERT_GE(pagesize, (int)plaintext.size()); @@ -1305,7 +1305,9 @@ const EVP_CIPHER *cipher = EVP_aes_256_xts(); iv.data())); ASSERT_TRUE( EVP_EncryptUpdate(ctx.get(), out_p, &len, in_p, plaintext.size())); - OPENSSL_memcpy(ciphertext.data(), out_p, plaintext.size()); + + encrypted_len = len; + ASSERT_EQ(encrypted_len, plaintext.size()); // Test decryption. @@ -1314,10 +1316,14 @@ const EVP_CIPHER *cipher = EVP_aes_256_xts(); } ctx.Reset(); + len = 0; ASSERT_TRUE(EVP_DecryptInit_ex(ctx.get(), cipher, nullptr, key.data(), iv.data())); ASSERT_TRUE( - EVP_DecryptUpdate(ctx.get(), in_p, &len, out_p, ciphertext.size())); + EVP_DecryptUpdate(ctx.get(), in_p, &len, out_p, plaintext.size())); + + decrypted_len = len; + ASSERT_EQ(decrypted_len, plaintext.size()); EXPECT_EQ(Bytes(plaintext), Bytes(in_p, static_cast(len))); } } From 3344d031dabb0bec0e4df3bb3598d20b60d1b5ba Mon Sep 17 00:00:00 2001 From: manastasova Date: Fri, 7 Nov 2025 22:08:43 +0000 Subject: [PATCH 3/5] Clean unused variables --- crypto/fipsmodule/modes/xts_test.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crypto/fipsmodule/modes/xts_test.cc b/crypto/fipsmodule/modes/xts_test.cc index d3084e612bd..8921f6bac07 100644 --- a/crypto/fipsmodule/modes/xts_test.cc +++ b/crypto/fipsmodule/modes/xts_test.cc @@ -1260,11 +1260,10 @@ const EVP_CIPHER *cipher = EVP_aes_256_xts(); for (size_t msg_len = 16; msg_len < AESXTS_RAND_MSG_MAX_LEN ; msg_len += 1) { std::vector key(EVP_CIPHER_key_length(cipher)), iv(EVP_CIPHER_iv_length(cipher)), - plaintext(msg_len), plaintext_test(msg_len); + plaintext(msg_len); RAND_bytes(key.data(), EVP_CIPHER_key_length(cipher)); RAND_bytes(iv.data(), EVP_CIPHER_iv_length(cipher)); RAND_bytes(plaintext.data(), msg_len); - OPENSSL_memset(plaintext_test.data(), 0, msg_len); SCOPED_TRACE(plaintext.size()); From 6421ec803880e36b9d2fa5d315c667970b89acc5 Mon Sep 17 00:00:00 2001 From: manastasova Date: Mon, 10 Nov 2025 21:12:10 +0000 Subject: [PATCH 4/5] Add linux small page size tests and increase input lengths --- crypto/fipsmodule/modes/xts_test.cc | 60 ++++++++++++++++------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/crypto/fipsmodule/modes/xts_test.cc b/crypto/fipsmodule/modes/xts_test.cc index 8921f6bac07..ad0d9c97495 100644 --- a/crypto/fipsmodule/modes/xts_test.cc +++ b/crypto/fipsmodule/modes/xts_test.cc @@ -14,7 +14,6 @@ #include #include - #include #include @@ -25,7 +24,7 @@ #include "internal.h" #include "../../test/test_util.h" -#define AESXTS_RAND_MSG_MAX_LEN 4096 +static constexpr size_t AESXTS_RAND_MSG_MAX_LEN = 8192; #if defined(OPENSSL_LINUX) #include @@ -1254,44 +1253,56 @@ TEST(XTSTest, EncryptDecryptRand) { uint8_t *out_buffer_end = out_buffer_beg + pagesize; #endif -const EVP_CIPHER *cipher = EVP_aes_256_xts(); + const EVP_CIPHER *cipher = EVP_aes_256_xts(); + bssl::ScopedEVP_CIPHER_CTX ctx; + std::vector key(EVP_CIPHER_key_length(cipher)), iv(EVP_CIPHER_iv_length(cipher)); // Test AESXTS Encrypt and Decrypt with random messages of incremental lenghts - for (size_t msg_len = 16; msg_len < AESXTS_RAND_MSG_MAX_LEN ; msg_len += 1) { + for (size_t msg_len = 16; msg_len < AESXTS_RAND_MSG_MAX_LEN; msg_len += 1) { - std::vector key(EVP_CIPHER_key_length(cipher)), iv(EVP_CIPHER_iv_length(cipher)), - plaintext(msg_len); - RAND_bytes(key.data(), EVP_CIPHER_key_length(cipher)); - RAND_bytes(iv.data(), EVP_CIPHER_iv_length(cipher)); + std::vector plaintext(msg_len); RAND_bytes(plaintext.data(), msg_len); SCOPED_TRACE(plaintext.size()); int len = 0; - size_t decrypted_len = 0, encrypted_len = 0; uint8_t *in_p = nullptr, *out_p = nullptr; #if defined(OPENSSL_LINUX) - ASSERT_GE(pagesize, (int)plaintext.size()); - for (bool beg: {false, true}) { - if (!beg) { - in_p = in_buffer_end - plaintext.size(); - out_p = out_buffer_end - plaintext.size(); + if (pagesize < (int)plaintext.size() && !beg) { + // For small page sizes skip page bound edge cases + std::unique_ptr in(new uint8_t[plaintext.size()]); + std::unique_ptr out(new uint8_t[plaintext.size()]); + in_p = in.get(); + out_p = out.get(); + } else if (pagesize < (int)plaintext.size() && beg) { + // Skip second iteration for small page sizes since it would use + // identical allocation for |in_p| and |out_p| buffers + continue; } else { - in_p = in_buffer_end - pagesize; - out_p = out_buffer_end - pagesize; - } + if (!beg) { + in_p = in_buffer_end - plaintext.size(); + out_p = out_buffer_end - plaintext.size(); + } else { + in_p = in_buffer_end - pagesize; + out_p = out_buffer_end - pagesize; + } OPENSSL_memset(in_p, 0x00, plaintext.size()); OPENSSL_memset(out_p, 0x00, plaintext.size()); - #else + } + #else std::unique_ptr in(new uint8_t[plaintext.size()]); std::unique_ptr out(new uint8_t[plaintext.size()]); in_p = in.get(); out_p = out.get(); - #endif + #endif for (bool in_place : {false, true}) { SCOPED_TRACE(in_place); + // Generate random key and iv for each encryption test + RAND_bytes(key.data(), EVP_CIPHER_key_length(cipher)); + RAND_bytes(iv.data(), EVP_CIPHER_iv_length(cipher)); + // Test encryption. OPENSSL_memcpy(in_p, plaintext.data(), plaintext.size()); @@ -1299,14 +1310,13 @@ const EVP_CIPHER *cipher = EVP_aes_256_xts(); out_p = in_p; } - bssl::ScopedEVP_CIPHER_CTX ctx; + ctx.Reset(); + len = 0; ASSERT_TRUE(EVP_EncryptInit_ex(ctx.get(), cipher, nullptr, key.data(), iv.data())); ASSERT_TRUE( EVP_EncryptUpdate(ctx.get(), out_p, &len, in_p, plaintext.size())); - - encrypted_len = len; - ASSERT_EQ(encrypted_len, plaintext.size()); + ASSERT_EQ(static_cast(len), plaintext.size()); // Test decryption. @@ -1320,9 +1330,7 @@ const EVP_CIPHER *cipher = EVP_aes_256_xts(); iv.data())); ASSERT_TRUE( EVP_DecryptUpdate(ctx.get(), in_p, &len, out_p, plaintext.size())); - - decrypted_len = len; - ASSERT_EQ(decrypted_len, plaintext.size()); + ASSERT_EQ(static_cast(len), plaintext.size()); EXPECT_EQ(Bytes(plaintext), Bytes(in_p, static_cast(len))); } } From 699201f88fb66797e9a68a6fa68780d0d1fabd35 Mon Sep 17 00:00:00 2001 From: manastasova Date: Mon, 10 Nov 2025 22:04:30 +0000 Subject: [PATCH 5/5] Fix memory issue --- crypto/fipsmodule/modes/xts_test.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crypto/fipsmodule/modes/xts_test.cc b/crypto/fipsmodule/modes/xts_test.cc index ad0d9c97495..07d9eebf84d 100644 --- a/crypto/fipsmodule/modes/xts_test.cc +++ b/crypto/fipsmodule/modes/xts_test.cc @@ -1268,11 +1268,13 @@ TEST(XTSTest, EncryptDecryptRand) { int len = 0; uint8_t *in_p = nullptr, *out_p = nullptr; #if defined(OPENSSL_LINUX) + std::unique_ptr in, out; + for (bool beg: {false, true}) { if (pagesize < (int)plaintext.size() && !beg) { // For small page sizes skip page bound edge cases - std::unique_ptr in(new uint8_t[plaintext.size()]); - std::unique_ptr out(new uint8_t[plaintext.size()]); + in.reset(new uint8_t[plaintext.size()]); + out.reset(new uint8_t[plaintext.size()]); in_p = in.get(); out_p = out.get(); } else if (pagesize < (int)plaintext.size() && beg) {