summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOr Ozeri <oro@il.ibm.com>2022-07-06 20:03:15 +0200
committerOr Ozeri <oro@il.ibm.com>2022-08-25 17:13:21 +0200
commit496d62a339dc798995d8ff87d62a026ae492d039 (patch)
tree96b7943056402ede7be47ac53d8d319aa04a5303 /src
parentlibrbd/crypto: apply ShutDownCryptoRequest to ancestors (diff)
downloadceph-496d62a339dc798995d8ff87d62a026ae492d039.tar.xz
ceph-496d62a339dc798995d8ff87d62a026ae492d039.zip
librbd/crypto: switch LUKS magic on formatted clones
This commit switches the luks magic from LUKS to RBDL when formatting a cloned image, so that if the user tries to load the image using external LUKS parser (such as dm-crypt) it will fail. Note that formatted clones are not valid LUKS format, and thus we aim to fail LUKS parsers. Signed-off-by: Or Ozeri <oro@il.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/librbd/CMakeLists.txt3
-rw-r--r--src/librbd/crypto/luks/FormatRequest.cc13
-rw-r--r--src/librbd/crypto/luks/Header.cc10
-rw-r--r--src/librbd/crypto/luks/LoadRequest.cc43
-rw-r--r--src/librbd/crypto/luks/LoadRequest.h1
-rw-r--r--src/librbd/crypto/luks/Magic.cc139
-rw-r--r--src/librbd/crypto/luks/Magic.h32
-rw-r--r--src/test/librbd/crypto/luks/test_mock_FormatRequest.cc48
-rw-r--r--src/test/librbd/crypto/luks/test_mock_LoadRequest.cc47
9 files changed, 310 insertions, 26 deletions
diff --git a/src/librbd/CMakeLists.txt b/src/librbd/CMakeLists.txt
index 5a446859342..079b8af0157 100644
--- a/src/librbd/CMakeLists.txt
+++ b/src/librbd/CMakeLists.txt
@@ -215,7 +215,8 @@ if(LINUX AND HAVE_LIBCRYPTSETUP)
crypto/luks/LUKSEncryptionFormat.cc
crypto/luks/Header.cc
crypto/luks/FormatRequest.cc
- crypto/luks/LoadRequest.cc)
+ crypto/luks/LoadRequest.cc
+ crypto/luks/Magic.cc)
endif()
add_library(rbd_api STATIC librbd.cc)
diff --git a/src/librbd/crypto/luks/FormatRequest.cc b/src/librbd/crypto/luks/FormatRequest.cc
index c517bedcf0a..659fffd3fd7 100644
--- a/src/librbd/crypto/luks/FormatRequest.cc
+++ b/src/librbd/crypto/luks/FormatRequest.cc
@@ -11,6 +11,7 @@
#include "librbd/Utils.h"
#include "librbd/crypto/Utils.h"
#include "librbd/crypto/luks/Header.h"
+#include "librbd/crypto/luks/Magic.h"
#include "librbd/io/AioCompletion.h"
#include "librbd/io/ImageDispatchSpec.h"
@@ -138,6 +139,18 @@ void FormatRequest<I>::send() {
return;
}
+ if (m_image_ctx->parent != nullptr) {
+ // parent is not encrypted with same key
+ // change LUKS magic to prevent decryption by other LUKS implementations
+ r = Magic::replace_magic(m_image_ctx->cct, bl);
+ if (r < 0) {
+ lderr(m_image_ctx->cct) << "error replacing LUKS magic: "
+ << cpp_strerror(r) << dendl;
+ finish(r);
+ return;
+ }
+ }
+
// pad header to stripe period alignment to prevent copyup of parent data
// when writing encryption header to the child image
auto alignment = bl.length() % stripe_period;
diff --git a/src/librbd/crypto/luks/Header.cc b/src/librbd/crypto/luks/Header.cc
index 2b84f42d6ba..f6018e65a1b 100644
--- a/src/librbd/crypto/luks/Header.cc
+++ b/src/librbd/crypto/luks/Header.cc
@@ -55,6 +55,10 @@ void Header::libcryptsetup_log(int level, const char* msg) {
}
int Header::init() {
+ if (m_fd != -1) {
+ return 0;
+ }
+
// create anonymous file
m_fd = syscall(SYS_memfd_create, "LibcryptsetupInterface", 0);
if (m_fd == -1) {
@@ -201,7 +205,7 @@ int Header::load(const char* type) {
auto r = crypt_load(m_cd, type, NULL);
if (r != 0) {
- lderr(m_cct) << "crypt_load failed: " << cpp_strerror(r) << dendl;
+ ldout(m_cct, 20) << "crypt_load failed: " << cpp_strerror(r) << dendl;
return r;
}
@@ -219,8 +223,8 @@ int Header::read_volume_key(const char* passphrase, size_t passphrase_size,
m_cd, CRYPT_ANY_SLOT, volume_key, volume_key_size, passphrase,
passphrase_size);
if (r < 0) {
- lderr(m_cct) << "crypt_volume_key_get failed: " << cpp_strerror(r)
- << dendl;
+ ldout(m_cct, 20) << "crypt_volume_key_get failed: " << cpp_strerror(r)
+ << dendl;
return r;
}
diff --git a/src/librbd/crypto/luks/LoadRequest.cc b/src/librbd/crypto/luks/LoadRequest.cc
index 0a13eb41f13..d1f636389ed 100644
--- a/src/librbd/crypto/luks/LoadRequest.cc
+++ b/src/librbd/crypto/luks/LoadRequest.cc
@@ -7,6 +7,7 @@
#include "common/errno.h"
#include "librbd/Utils.h"
#include "librbd/crypto/Utils.h"
+#include "librbd/crypto/luks/Magic.h"
#include "librbd/io/AioCompletion.h"
#include "librbd/io/ImageDispatchSpec.h"
#include "librbd/io/ReadResult.h"
@@ -41,13 +42,6 @@ void LoadRequest<I>::set_initial_read_size(uint64_t read_size) {
template <typename I>
void LoadRequest<I>::send() {
- // setup interface with libcryptsetup
- auto r = m_header.init();
- if (r < 0) {
- finish(r);
- return;
- }
-
auto ctx = create_context_callback<
LoadRequest<I>, &LoadRequest<I>::handle_read_header>(this);
read(m_initial_read_size, ctx);
@@ -78,6 +72,39 @@ bool LoadRequest<I>::handle_read(int r) {
return false;
}
+ m_offset += m_bl.length();
+
+ if (m_last_read_bl.length() > 0) {
+ m_last_read_bl.claim_append(m_bl);
+ m_bl = std::move(m_last_read_bl);
+ }
+
+ if (m_image_ctx->parent != nullptr && m_bl.length() == m_offset &&
+ Magic::is_rbd_clone(m_bl) > 0) {
+ r = Magic::replace_magic(m_image_ctx->cct, m_bl);
+ if (r < 0) {
+ if (r == -EINVAL && m_offset < MAXIMUM_HEADER_SIZE) {
+ m_last_read_bl = std::move(m_bl);
+ auto ctx = create_context_callback<
+ LoadRequest<I>, &LoadRequest<I>::handle_read_header>(this);
+ read(MAXIMUM_HEADER_SIZE, ctx);
+ return false;
+ }
+
+ lderr(m_image_ctx->cct) << "error replacing rbd clone magic: "
+ << cpp_strerror(r) << dendl;
+ finish(r);
+ return false;
+ }
+ }
+
+ // setup interface with libcryptsetup
+ r = m_header.init();
+ if (r < 0) {
+ finish(r);
+ return false;
+ }
+
// write header to libcryptsetup interface
r = m_header.write(m_bl);
if (r < 0) {
@@ -85,8 +112,8 @@ bool LoadRequest<I>::handle_read(int r) {
return false;
}
- m_offset += m_bl.length();
m_bl.clear();
+
return true;
}
diff --git a/src/librbd/crypto/luks/LoadRequest.h b/src/librbd/crypto/luks/LoadRequest.h
index f33e52e4fa4..e8d7bb2d88d 100644
--- a/src/librbd/crypto/luks/LoadRequest.h
+++ b/src/librbd/crypto/luks/LoadRequest.h
@@ -44,6 +44,7 @@ private:
std::string_view m_passphrase;
Context* m_on_finish;
ceph::bufferlist m_bl;
+ ceph::bufferlist m_last_read_bl;
std::unique_ptr<CryptoInterface>* m_result_crypto;
uint64_t m_initial_read_size;
Header m_header;
diff --git a/src/librbd/crypto/luks/Magic.cc b/src/librbd/crypto/luks/Magic.cc
new file mode 100644
index 00000000000..bc5e19704b1
--- /dev/null
+++ b/src/librbd/crypto/luks/Magic.cc
@@ -0,0 +1,139 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "Magic.h"
+
+#include "common/dout.h"
+#include "common/errno.h"
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::crypto::luks::Magic: " << __func__ \
+ << ": "
+
+namespace librbd {
+namespace crypto {
+namespace luks {
+
+namespace {
+
+constexpr uint64_t MAGIC_LENGTH = 6;
+const std::string LUKS_MAGIC = "LUKS\xba\xbe";
+const std::string RBD_CLONE_MAGIC = "RBDL\xba\xbe";
+
+} // anonymous namespace
+
+int Magic::read(ceph::bufferlist &bl, uint32_t bl_off,
+ uint32_t read_size, char* result) {
+ if (bl_off + read_size > bl.length()) {
+ return -EINVAL;
+ }
+
+ memcpy(result, bl.c_str() + bl_off, read_size);
+ return 0;
+}
+
+int Magic::cmp(ceph::bufferlist &bl, uint32_t bl_off,
+ const std::string &cmp_str) {
+ auto cmp_length = cmp_str.length();
+
+ if (bl_off + cmp_length > bl.length()) {
+ return -EINVAL;
+ }
+
+ if (memcmp(bl.c_str() + bl_off, cmp_str.c_str(), cmp_length)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+int Magic::is_luks(ceph::bufferlist& bl) {
+ return cmp(bl, 0, LUKS_MAGIC);
+}
+
+int Magic::is_rbd_clone(ceph::bufferlist& bl) {
+ return cmp(bl, 0, RBD_CLONE_MAGIC);
+}
+
+void Magic::transform_secondary_header_magic(char* magic) {
+ std::swap(magic[0], magic[3]);
+ std::swap(magic[1], magic[2]);
+}
+
+int Magic::replace_magic(CephContext* cct, ceph::bufferlist& bl) {
+ const std::string *old_magic, *new_magic;
+ if (is_luks(bl) > 0) {
+ old_magic = &LUKS_MAGIC;
+ new_magic = &RBD_CLONE_MAGIC;
+ } else if (is_rbd_clone(bl) > 0) {
+ old_magic = &RBD_CLONE_MAGIC;
+ new_magic = &LUKS_MAGIC;
+ } else {
+ lderr(cct) << "invalid magic: " << dendl;
+ return -EILSEQ;
+ }
+
+ // read luks version
+ uint16_t version;
+ auto r = read(bl, MAGIC_LENGTH, sizeof(version), (char*)&version);
+ if (r < 0) {
+ lderr(cct) << "cannot read header version: " << cpp_strerror(r) << dendl;
+ return r;
+ }
+ boost::endian::big_to_native_inplace(version);
+
+ switch (version) {
+ case 1: {
+ // LUKS1, no secondary header
+ break;
+ }
+ case 2: {
+ // LUKS2, secondary header follows primary header
+ // read header size
+ uint64_t hdr_size;
+ r = read(bl, MAGIC_LENGTH + sizeof(version), sizeof(hdr_size),
+ (char*)&hdr_size);
+ if (r < 0) {
+ lderr(cct) << "cannot read header size: " << cpp_strerror(r) << dendl;
+ return r;
+ }
+ boost::endian::big_to_native_inplace(hdr_size);
+
+ if ((uint32_t)hdr_size + MAGIC_LENGTH > bl.length()) {
+ ldout(cct, 20) << "cannot replace secondary header magic" << dendl;
+ return -EINVAL;
+ }
+
+ // check secondary header magic
+ auto secondary_header_magic = bl.c_str() + hdr_size;
+ transform_secondary_header_magic(secondary_header_magic);
+ auto is_secondary_header_magic_valid =
+ !memcmp(secondary_header_magic, old_magic->c_str(), MAGIC_LENGTH);
+ if (!is_secondary_header_magic_valid) {
+ transform_secondary_header_magic(secondary_header_magic);
+ lderr(cct) << "invalid secondary header magic" << dendl;
+ return -EILSEQ;
+ }
+
+ // replace secondary header magic
+ memcpy(secondary_header_magic, new_magic->c_str(), MAGIC_LENGTH);
+ transform_secondary_header_magic(secondary_header_magic);
+
+ break;
+ }
+ default: {
+ lderr(cct) << "bad header version: " << version << dendl;
+ return -EINVAL;
+ }
+ }
+
+ // switch primary header magic
+ memcpy(bl.c_str(), new_magic->c_str(), MAGIC_LENGTH);
+
+ return 0;
+}
+
+} // namespace luks
+} // namespace crypto
+} // namespace librbd
diff --git a/src/librbd/crypto/luks/Magic.h b/src/librbd/crypto/luks/Magic.h
new file mode 100644
index 00000000000..ad06e67f500
--- /dev/null
+++ b/src/librbd/crypto/luks/Magic.h
@@ -0,0 +1,32 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_CRYPTO_LUKS_MAGIC_H
+#define CEPH_LIBRBD_CRYPTO_LUKS_MAGIC_H
+
+#include "common/ceph_context.h"
+#include "include/buffer.h"
+
+namespace librbd {
+namespace crypto {
+namespace luks {
+
+class Magic {
+public:
+ static int is_luks(ceph::bufferlist& bl);
+ static int is_rbd_clone(ceph::bufferlist& bl);
+
+ static int replace_magic(CephContext* cct, ceph::bufferlist& bl);
+private:
+ static int read(ceph::bufferlist& bl, uint32_t bl_off,
+ uint32_t read_size, char* result);
+ static int cmp(ceph::bufferlist& bl, uint32_t bl_off,
+ const std::string& cmp_str);
+ static void transform_secondary_header_magic(char* magic);
+};
+
+} // namespace luks
+} // namespace crypto
+} // namespace librbd
+
+#endif // CEPH_LIBRBD_CRYPTO_LUKS_MAGIC_H
diff --git a/src/test/librbd/crypto/luks/test_mock_FormatRequest.cc b/src/test/librbd/crypto/luks/test_mock_FormatRequest.cc
index c4d7369a5d0..1a2838e9639 100644
--- a/src/test/librbd/crypto/luks/test_mock_FormatRequest.cc
+++ b/src/test/librbd/crypto/luks/test_mock_FormatRequest.cc
@@ -91,10 +91,18 @@ struct TestMockCryptoLuksFormatRequest : public TestMockFixture {
}
void verify_header(const char* expected_format, size_t expected_key_length,
- uint64_t expected_sector_size) {
+ uint64_t expected_sector_size, bool magic_switched) {
Header header(mock_image_ctx->cct);
ASSERT_EQ(0, header.init());
+
+ if (magic_switched) {
+ Header non_switched_header(mock_image_ctx->cct);
+ ASSERT_EQ(0, non_switched_header.init());
+ ASSERT_EQ(0, non_switched_header.write(header_bl));
+ ASSERT_EQ(-EINVAL, non_switched_header.load(expected_format));
+ ASSERT_LT(0, Magic::replace_magic(mock_image_ctx->cct, header_bl));
+ }
ASSERT_EQ(0, header.write(header_bl));
ASSERT_EQ(0, header.load(expected_format));
@@ -127,7 +135,7 @@ TEST_F(TestMockCryptoLuksFormatRequest, LUKS1) {
ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0));
complete_aio(0);
ASSERT_EQ(0, finished_cond.wait());
- ASSERT_NO_FATAL_FAILURE(verify_header(CRYPT_LUKS1, 32, 512));
+ ASSERT_NO_FATAL_FAILURE(verify_header(CRYPT_LUKS1, 32, 512, false));
}
TEST_F(TestMockCryptoLuksFormatRequest, AES128) {
@@ -142,7 +150,7 @@ TEST_F(TestMockCryptoLuksFormatRequest, AES128) {
ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0));
complete_aio(0);
ASSERT_EQ(0, finished_cond.wait());
- ASSERT_NO_FATAL_FAILURE(verify_header(CRYPT_LUKS2, 32, 4096));
+ ASSERT_NO_FATAL_FAILURE(verify_header(CRYPT_LUKS2, 32, 4096, false));
}
TEST_F(TestMockCryptoLuksFormatRequest, AES256) {
@@ -157,7 +165,39 @@ TEST_F(TestMockCryptoLuksFormatRequest, AES256) {
ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0));
complete_aio(0);
ASSERT_EQ(0, finished_cond.wait());
- ASSERT_NO_FATAL_FAILURE(verify_header(CRYPT_LUKS2, 64, 4096));
+ ASSERT_NO_FATAL_FAILURE(verify_header(CRYPT_LUKS2, 64, 4096, false));
+}
+
+TEST_F(TestMockCryptoLuksFormatRequest, LUKS1OnCloned) {
+ mock_image_ctx->parent = mock_image_ctx;
+ auto mock_format_request = MockFormatRequest::create(
+ mock_image_ctx, RBD_ENCRYPTION_FORMAT_LUKS1,
+ RBD_ENCRYPTION_ALGORITHM_AES256, std::move(passphrase), &crypto,
+ on_finish, true);
+ expect_get_stripe_period();
+ expect_get_image_size(IMAGE_SIZE);
+ expect_image_write();
+ mock_format_request->send();
+ ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0));
+ complete_aio(0);
+ ASSERT_EQ(0, finished_cond.wait());
+ ASSERT_NO_FATAL_FAILURE(verify_header(CRYPT_LUKS1, 64, 512, true));
+}
+
+TEST_F(TestMockCryptoLuksFormatRequest, LUKS2OnCloned) {
+ mock_image_ctx->parent = mock_image_ctx;
+ auto mock_format_request = MockFormatRequest::create(
+ mock_image_ctx, RBD_ENCRYPTION_FORMAT_LUKS2,
+ RBD_ENCRYPTION_ALGORITHM_AES256, std::move(passphrase), &crypto,
+ on_finish, true);
+ expect_get_stripe_period();
+ expect_get_image_size(IMAGE_SIZE);
+ expect_image_write();
+ mock_format_request->send();
+ ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0));
+ complete_aio(0);
+ ASSERT_EQ(0, finished_cond.wait());
+ ASSERT_NO_FATAL_FAILURE(verify_header(CRYPT_LUKS2, 64, 4096, true));
}
TEST_F(TestMockCryptoLuksFormatRequest, ImageTooSmall) {
diff --git a/src/test/librbd/crypto/luks/test_mock_LoadRequest.cc b/src/test/librbd/crypto/luks/test_mock_LoadRequest.cc
index 7e09d2408a3..1b79c7189e8 100644
--- a/src/test/librbd/crypto/luks/test_mock_LoadRequest.cc
+++ b/src/test/librbd/crypto/luks/test_mock_LoadRequest.cc
@@ -58,14 +58,18 @@ struct TestMockCryptoLuksLoadRequest : public TestMockFixture {
// returns data offset in bytes
void generate_header(const char* type, const char* alg, size_t key_size,
- const char* cipher_mode, uint32_t sector_size) {
+ const char* cipher_mode, uint32_t sector_size,
+ bool magic_switched) {
Header header(mock_image_ctx->cct);
ASSERT_EQ(0, header.init());
ASSERT_EQ(0, header.format(type, alg, nullptr, key_size, cipher_mode,
sector_size, OBJECT_SIZE, true));
ASSERT_EQ(0, header.add_keyslot(passphrase_cstr, strlen(passphrase_cstr)));
- ASSERT_LE(0, header.read(&header_bl));
+ ASSERT_LT(0, header.read(&header_bl));
+ if (magic_switched) {
+ ASSERT_EQ(0, Magic::replace_magic(mock_image_ctx->cct, header_bl));
+ }
data_offset = header.get_data_offset();
}
@@ -99,7 +103,7 @@ struct TestMockCryptoLuksLoadRequest : public TestMockFixture {
};
TEST_F(TestMockCryptoLuksLoadRequest, AES128) {
- generate_header(CRYPT_LUKS2, "aes", 32, "xts-plain64", 4096);
+ generate_header(CRYPT_LUKS2, "aes", 32, "xts-plain64", 4096, false);
expect_image_read(0, DEFAULT_INITIAL_READ_SIZE);
mock_load_request->send();
image_read_request->complete(DEFAULT_INITIAL_READ_SIZE);
@@ -108,7 +112,7 @@ TEST_F(TestMockCryptoLuksLoadRequest, AES128) {
}
TEST_F(TestMockCryptoLuksLoadRequest, AES256) {
- generate_header(CRYPT_LUKS2, "aes", 64, "xts-plain64", 4096);
+ generate_header(CRYPT_LUKS2, "aes", 64, "xts-plain64", 4096, false);
expect_image_read(0, DEFAULT_INITIAL_READ_SIZE);
mock_load_request->send();
image_read_request->complete(DEFAULT_INITIAL_READ_SIZE);
@@ -120,7 +124,7 @@ TEST_F(TestMockCryptoLuksLoadRequest, LUKS1) {
delete mock_load_request;
mock_load_request = MockLoadRequest::create(
mock_image_ctx, {passphrase_cstr}, &crypto, on_finish);
- generate_header(CRYPT_LUKS1, "aes", 32, "xts-plain64", 512);
+ generate_header(CRYPT_LUKS1, "aes", 32, "xts-plain64", 512, false);
expect_image_read(0, DEFAULT_INITIAL_READ_SIZE);
mock_load_request->send();
image_read_request->complete(DEFAULT_INITIAL_READ_SIZE);
@@ -144,7 +148,7 @@ TEST_F(TestMockCryptoLuksLoadRequest, WrongFormat) {
}
TEST_F(TestMockCryptoLuksLoadRequest, UnsupportedAlgorithm) {
- generate_header(CRYPT_LUKS2, "twofish", 32, "xts-plain64", 4096);
+ generate_header(CRYPT_LUKS2, "twofish", 32, "xts-plain64", 4096, false);
expect_image_read(0, DEFAULT_INITIAL_READ_SIZE);
mock_load_request->send();
image_read_request->complete(DEFAULT_INITIAL_READ_SIZE);
@@ -153,7 +157,7 @@ TEST_F(TestMockCryptoLuksLoadRequest, UnsupportedAlgorithm) {
}
TEST_F(TestMockCryptoLuksLoadRequest, UnsupportedCipherMode) {
- generate_header(CRYPT_LUKS2, "aes", 32, "cbc-essiv:sha256", 4096);
+ generate_header(CRYPT_LUKS2, "aes", 32, "cbc-essiv:sha256", 4096, false);
expect_image_read(0, DEFAULT_INITIAL_READ_SIZE);
mock_load_request->send();
image_read_request->complete(DEFAULT_INITIAL_READ_SIZE);
@@ -162,7 +166,7 @@ TEST_F(TestMockCryptoLuksLoadRequest, UnsupportedCipherMode) {
}
TEST_F(TestMockCryptoLuksLoadRequest, HeaderBiggerThanInitialRead) {
- generate_header(CRYPT_LUKS2, "aes", 64, "xts-plain64", 4096);
+ generate_header(CRYPT_LUKS2, "aes", 64, "xts-plain64", 4096, false);
mock_load_request->set_initial_read_size(4096);
expect_image_read(0, 4096);
mock_load_request->send();
@@ -175,8 +179,31 @@ TEST_F(TestMockCryptoLuksLoadRequest, HeaderBiggerThanInitialRead) {
ASSERT_NE(crypto.get(), nullptr);
}
+TEST_F(TestMockCryptoLuksLoadRequest, LUKS1FormattedClone) {
+ mock_image_ctx->parent = mock_image_ctx;
+ delete mock_load_request;
+ mock_load_request = MockLoadRequest::create(
+ mock_image_ctx, {passphrase_cstr}, &crypto, on_finish);
+ generate_header(CRYPT_LUKS1, "aes", 64, "xts-plain64", 512, true);
+ expect_image_read(0, DEFAULT_INITIAL_READ_SIZE);
+ mock_load_request->send();
+ image_read_request->complete(DEFAULT_INITIAL_READ_SIZE);
+ ASSERT_EQ(0, finished_cond.wait());
+ ASSERT_NE(crypto.get(), nullptr);
+}
+
+TEST_F(TestMockCryptoLuksLoadRequest, LUKS2FormattedClone) {
+ mock_image_ctx->parent = mock_image_ctx;
+ generate_header(CRYPT_LUKS2, "aes", 64, "xts-plain64", 4096, true);
+ expect_image_read(0, DEFAULT_INITIAL_READ_SIZE);
+ mock_load_request->send();
+ image_read_request->complete(DEFAULT_INITIAL_READ_SIZE);
+ ASSERT_EQ(0, finished_cond.wait());
+ ASSERT_NE(crypto.get(), nullptr);
+}
+
TEST_F(TestMockCryptoLuksLoadRequest, KeyslotsBiggerThanInitialRead) {
- generate_header(CRYPT_LUKS2, "aes", 64, "xts-plain64", 4096);
+ generate_header(CRYPT_LUKS2, "aes", 64, "xts-plain64", 4096, false);
mock_load_request->set_initial_read_size(16384);
expect_image_read(0, 16384);
mock_load_request->send();
@@ -194,7 +221,7 @@ TEST_F(TestMockCryptoLuksLoadRequest, WrongPassphrase) {
mock_load_request = MockLoadRequest::create(
mock_image_ctx, "wrong", &crypto, on_finish);
- generate_header(CRYPT_LUKS2, "aes", 64, "xts-plain64", 4096);
+ generate_header(CRYPT_LUKS2, "aes", 64, "xts-plain64", 4096, false);
expect_image_read(0, DEFAULT_INITIAL_READ_SIZE);
mock_load_request->send();