From b11d6285a7df780cf902e508dae03accf5ee8124 Mon Sep 17 00:00:00 2001 From: Or Ozeri Date: Thu, 21 Jan 2021 17:51:23 +0200 Subject: [PATCH] librbd: use 512 sector size for crypto IV This commit aligns with the LUKS2 format which requires plain-64 mode IV to be derived from the 512 bytes sector number Signed-off-by: Or Ozeri --- src/librbd/crypto/BlockCrypto.cc | 7 ++-- .../librbd/crypto/test_mock_BlockCrypto.cc | 34 +++++++++---------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/librbd/crypto/BlockCrypto.cc b/src/librbd/crypto/BlockCrypto.cc index 172bf146001f8..9d866c8057795 100644 --- a/src/librbd/crypto/BlockCrypto.cc +++ b/src/librbd/crypto/BlockCrypto.cc @@ -17,6 +17,7 @@ BlockCrypto::BlockCrypto(CephContext* cct, DataCryptor* data_cryptor, m_data_offset(data_offset), m_iv_size(data_cryptor->get_iv_size()) { ceph_assert(isp2(block_size)); ceph_assert((block_size % data_cryptor->get_block_size()) == 0); + ceph_assert((block_size % 512) == 0); } template @@ -53,7 +54,7 @@ int BlockCrypto::crypt(ceph::bufferlist* data, uint64_t image_offset, lderr(m_cct) << "unable to get crypt context" << dendl; return -EIO; } - auto block_offset = image_offset / m_block_size; + auto sector_number = image_offset / 512; auto appender = data->get_contiguous_appender(src.length()); unsigned char* out_buf_ptr = nullptr; uint32_t remaining_block_bytes = 0; @@ -62,7 +63,7 @@ int BlockCrypto::crypt(ceph::bufferlist* data, uint64_t image_offset, auto remaining_buf_bytes = buf->length(); while (remaining_buf_bytes > 0) { if (remaining_block_bytes == 0) { - auto block_offset_le = init_le64(block_offset); + auto block_offset_le = init_le64(sector_number); memcpy(iv, &block_offset_le, sizeof(block_offset_le)); auto r = m_data_cryptor->init_context(ctx, iv, m_iv_size); if (r != 0) { @@ -73,7 +74,7 @@ int BlockCrypto::crypt(ceph::bufferlist* data, uint64_t image_offset, out_buf_ptr = reinterpret_cast( appender.get_pos_add(m_block_size)); remaining_block_bytes = m_block_size; - ++block_offset; + sector_number += m_block_size / 512; } auto crypto_input_length = std::min(remaining_buf_bytes, diff --git a/src/test/librbd/crypto/test_mock_BlockCrypto.cc b/src/test/librbd/crypto/test_mock_BlockCrypto.cc index cb38d86c24ce8..6d0a42172331a 100644 --- a/src/test/librbd/crypto/test_mock_BlockCrypto.cc +++ b/src/test/librbd/crypto/test_mock_BlockCrypto.cc @@ -24,9 +24,9 @@ MATCHER_P(CompareArrayToString, s, "") { struct TestMockCryptoBlockCrypto : public TestFixture { MockDataCryptor cryptor; ceph::ref_t> bc; - int cryptor_block_size = 2; + int cryptor_block_size = 16; int cryptor_iv_size = 16; - int block_size = 4; + int block_size = 4096; int data_offset = 0; ExpectationSet* expectation_set; @@ -74,49 +74,47 @@ struct TestMockCryptoBlockCrypto : public TestFixture { }; TEST_F(TestMockCryptoBlockCrypto, Encrypt) { - uint32_t image_offset = 0x1234 * block_size; + uint32_t image_offset = 0x1230 * 512; ceph::bufferlist data1; - data1.append("123"); + data1.append(std::string(2048, '1')); ceph::bufferlist data2; - data2.append("456"); + data2.append(std::string(4096, '2')); ceph::bufferlist data3; - data3.append("78"); + data3.append(std::string(2048, '3')); - // bufferlist buffers: "123", "456", "78" ceph::bufferlist data; data.claim_append(data1); data.claim_append(data2); data.claim_append(data3); expect_get_context(CipherMode::CIPHER_MODE_ENC); - expect_init_context(std::string("\x34\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)); - expect_update_context("1234", 4); - expect_init_context(std::string("\x35\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)); - expect_update_context("5678", 4); + expect_init_context(std::string("\x30\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)); + expect_update_context(std::string(2048, '1') + std::string(2048, '2'), 4096); + expect_init_context(std::string("\x38\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)); + expect_update_context(std::string(2048, '2') + std::string(2048, '3'), 4096); EXPECT_CALL(cryptor, return_context(_, CipherMode::CIPHER_MODE_ENC)); ASSERT_EQ(0, bc->encrypt(&data, image_offset)); - ASSERT_EQ(data.length(), 8); - ASSERT_TRUE(data.is_aligned(block_size)); + ASSERT_EQ(data.length(), 8192); } TEST_F(TestMockCryptoBlockCrypto, UnalignedImageOffset) { ceph::bufferlist data; - data.append("1234"); + data.append(std::string(4096, '1')); ASSERT_EQ(-EINVAL, bc->encrypt(&data, 2)); } TEST_F(TestMockCryptoBlockCrypto, UnalignedDataLength) { ceph::bufferlist data; - data.append("123"); + data.append(std::string(512, '1')); ASSERT_EQ(-EINVAL, bc->encrypt(&data, 0)); } TEST_F(TestMockCryptoBlockCrypto, GetContextError) { ceph::bufferlist data; - data.append("1234"); + data.append(std::string(4096, '1')); EXPECT_CALL(cryptor, get_context(CipherMode::CIPHER_MODE_ENC)).WillOnce( Return(nullptr)); ASSERT_EQ(-EIO, bc->encrypt(&data, 0)); @@ -124,7 +122,7 @@ TEST_F(TestMockCryptoBlockCrypto, GetContextError) { TEST_F(TestMockCryptoBlockCrypto, InitContextError) { ceph::bufferlist data; - data.append("1234"); + data.append(std::string(4096, '1')); expect_get_context(CipherMode::CIPHER_MODE_ENC); EXPECT_CALL(cryptor, init_context(_, _, _)).WillOnce(Return(-123)); ASSERT_EQ(-123, bc->encrypt(&data, 0)); @@ -132,7 +130,7 @@ TEST_F(TestMockCryptoBlockCrypto, InitContextError) { TEST_F(TestMockCryptoBlockCrypto, UpdateContextError) { ceph::bufferlist data; - data.append("1234"); + data.append(std::string(4096, '1')); expect_get_context(CipherMode::CIPHER_MODE_ENC); EXPECT_CALL(cryptor, init_context(_, _, _)); EXPECT_CALL(cryptor, update_context(_, _, _, _)).WillOnce(Return(-123)); -- 2.39.5