Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 104 additions & 1 deletion crypto/fipsmodule/modes/xts_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <openssl/cipher.h>
#include <openssl/aes.h>
#include <openssl/rand.h>

#include <vector>

Expand All @@ -23,6 +24,8 @@
#include "internal.h"
#include "../../test/test_util.h"

static constexpr size_t AESXTS_RAND_MSG_MAX_LEN = 8192;

#if defined(OPENSSL_LINUX)
#include <sys/mman.h>
#endif
Expand Down Expand Up @@ -1202,7 +1205,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.
Expand Down Expand Up @@ -1240,6 +1243,106 @@ TEST(XTSTest, TestVectors) {
#endif
}

TEST(XTSTest, EncryptDecryptRand) {
#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();
bssl::ScopedEVP_CIPHER_CTX ctx;
std::vector<uint8_t> 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) {

std::vector<uint8_t> plaintext(msg_len);
RAND_bytes(plaintext.data(), msg_len);

SCOPED_TRACE(plaintext.size());

int len = 0;
uint8_t *in_p = nullptr, *out_p = nullptr;
#if defined(OPENSSL_LINUX)
std::unique_ptr<uint8_t[]> in, out;

for (bool beg: {false, true}) {
if (pagesize < (int)plaintext.size() && !beg) {
// For small page sizes skip page bound edge cases
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) {
// Skip second iteration for small page sizes since it would use
// identical allocation for |in_p| and |out_p| buffers
continue;
} else {
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<uint8_t[]> in(new uint8_t[plaintext.size()]);
std::unique_ptr<uint8_t[]> 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);

// 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());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]

        OPENSSL_memcpy(in_p, plaintext.data(), plaintext.size());
        ^

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why this warning appears. in_p is used as the input message for the encryption function later on.

if (in_place) {
out_p = in_p;
}

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()));
ASSERT_EQ(static_cast<size_t>(len), plaintext.size());

// Test decryption.

if (!in_place) {
OPENSSL_memset(in_p, 0, len);
}

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, plaintext.size()));
ASSERT_EQ(static_cast<size_t>(len), plaintext.size());
EXPECT_EQ(Bytes(plaintext), Bytes(in_p, static_cast<size_t>(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) {

Expand Down
Loading