]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: use 512 sector size for crypto IV 39005/head
authorOr Ozeri <oro@il.ibm.com>
Thu, 21 Jan 2021 15:51:23 +0000 (17:51 +0200)
committerOr Ozeri <oro@il.ibm.com>
Thu, 21 Jan 2021 16:21:32 +0000 (18:21 +0200)
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 <oro@il.ibm.com>
src/librbd/crypto/BlockCrypto.cc
src/test/librbd/crypto/test_mock_BlockCrypto.cc

index 172bf146001f820d67b3e7e6092c62eaea31ebe0..9d866c8057795b0feb076d66b2c4f8482c03009d 100644 (file)
@@ -17,6 +17,7 @@ BlockCrypto<T>::BlockCrypto(CephContext* cct, DataCryptor<T>* 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 <typename T>
@@ -53,7 +54,7 @@ int BlockCrypto<T>::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<T>::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<T>::crypt(ceph::bufferlist* data, uint64_t image_offset,
         out_buf_ptr = reinterpret_cast<unsigned char*>(
                 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,
index cb38d86c24ce8c12e7fe0b1c5c5d5403b5829d1c..6d0a42172331a0f8b9ec2bf120d5b330dc96242a 100644 (file)
@@ -24,9 +24,9 @@ MATCHER_P(CompareArrayToString, s, "") {
 struct TestMockCryptoBlockCrypto : public TestFixture {
     MockDataCryptor cryptor;
     ceph::ref_t<BlockCrypto<MockCryptoContext>> 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));