2017-08-16 04:00:46 +02:00
|
|
|
#include "cpp-utils/crypto/cryptopp_byte.h"
|
2016-02-11 15:19:58 +01:00
|
|
|
#include <gtest/gtest.h>
|
2017-12-01 16:01:49 +01:00
|
|
|
#include "cpp-utils/crypto/symmetric/testutils/FakeAuthenticatedCipher.h"
|
2017-07-21 04:32:42 +02:00
|
|
|
#include "blockstore/implementations/encrypted/EncryptedBlockStore2.h"
|
|
|
|
#include "blockstore/implementations/inmemory/InMemoryBlockStore2.h"
|
2016-02-11 15:19:58 +01:00
|
|
|
#include "blockstore/utils/BlockStoreUtils.h"
|
2017-09-11 15:37:06 +02:00
|
|
|
#include "../../testutils/gtest_printers.h"
|
2016-02-11 15:19:58 +01:00
|
|
|
#include <cpp-utils/data/DataFixture.h>
|
2015-05-06 00:09:11 +02:00
|
|
|
|
|
|
|
using ::testing::Test;
|
|
|
|
|
2015-05-06 00:37:57 +02:00
|
|
|
using cpputils::DataFixture;
|
|
|
|
using cpputils::Data;
|
2015-07-21 18:19:34 +02:00
|
|
|
using cpputils::unique_ref;
|
|
|
|
using cpputils::make_unique_ref;
|
2015-10-27 23:27:40 +01:00
|
|
|
using cpputils::FakeAuthenticatedCipher;
|
2015-05-06 00:37:57 +02:00
|
|
|
|
2017-07-21 04:32:42 +02:00
|
|
|
using blockstore::inmemory::InMemoryBlockStore2;
|
2015-05-06 00:09:11 +02:00
|
|
|
|
|
|
|
using namespace blockstore::encrypted;
|
|
|
|
|
|
|
|
class EncryptedBlockStoreTest: public Test {
|
|
|
|
public:
|
2015-05-06 00:37:57 +02:00
|
|
|
static constexpr unsigned int BLOCKSIZE = 1024;
|
|
|
|
EncryptedBlockStoreTest():
|
2017-07-21 04:32:42 +02:00
|
|
|
baseBlockStore(new InMemoryBlockStore2),
|
|
|
|
blockStore(make_unique_ref<EncryptedBlockStore2<FakeAuthenticatedCipher>>(std::move(cpputils::nullcheck(std::unique_ptr<InMemoryBlockStore2>(baseBlockStore)).value()), FakeAuthenticatedCipher::Key1())),
|
2015-05-06 00:37:57 +02:00
|
|
|
data(DataFixture::generate(BLOCKSIZE)) {
|
|
|
|
}
|
2017-07-21 04:32:42 +02:00
|
|
|
InMemoryBlockStore2 *baseBlockStore;
|
|
|
|
unique_ref<EncryptedBlockStore2<FakeAuthenticatedCipher>> blockStore;
|
2015-05-06 00:37:57 +02:00
|
|
|
Data data;
|
|
|
|
|
2017-09-17 03:07:27 +02:00
|
|
|
blockstore::BlockId CreateBlockDirectlyWithFixtureAndReturnKey() {
|
2016-03-16 19:35:56 +01:00
|
|
|
return CreateBlockReturnKey(data);
|
|
|
|
}
|
|
|
|
|
2017-09-17 03:07:27 +02:00
|
|
|
blockstore::BlockId CreateBlockReturnKey(const Data &initData) {
|
2017-07-21 04:32:42 +02:00
|
|
|
return blockStore->create(initData.copy());
|
2015-05-06 00:37:57 +02:00
|
|
|
}
|
|
|
|
|
2017-09-17 03:07:27 +02:00
|
|
|
blockstore::BlockId CreateBlockWriteFixtureToItAndReturnKey() {
|
|
|
|
auto blockId = blockStore->create(Data(data.size()));
|
|
|
|
blockStore->store(blockId, data);
|
|
|
|
return blockId;
|
2015-05-06 00:37:57 +02:00
|
|
|
}
|
|
|
|
|
2017-09-17 03:07:27 +02:00
|
|
|
void ModifyBaseBlock(const blockstore::BlockId &blockId) {
|
|
|
|
auto block = baseBlockStore->load(blockId).value();
|
2018-02-18 03:54:22 +01:00
|
|
|
CryptoPP::byte* middle_byte = static_cast<CryptoPP::byte*>(block.data()) + 10;
|
2017-07-21 04:32:42 +02:00
|
|
|
*middle_byte = *middle_byte + 1;
|
2017-09-17 03:07:27 +02:00
|
|
|
baseBlockStore->store(blockId, block);
|
2015-05-06 00:37:57 +02:00
|
|
|
}
|
|
|
|
|
2017-09-17 03:07:27 +02:00
|
|
|
blockstore::BlockId CopyBaseBlock(const blockstore::BlockId &blockId) {
|
|
|
|
auto source = baseBlockStore->load(blockId).value();
|
2017-12-01 16:01:49 +01:00
|
|
|
return baseBlockStore->create(source);
|
2015-05-06 00:37:57 +02:00
|
|
|
}
|
2015-10-17 21:10:26 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(EncryptedBlockStoreTest);
|
2015-05-06 00:09:11 +02:00
|
|
|
};
|
|
|
|
|
2015-05-06 00:37:57 +02:00
|
|
|
TEST_F(EncryptedBlockStoreTest, LoadingWithSameKeyWorks_WriteOnCreate) {
|
2017-09-17 03:07:27 +02:00
|
|
|
auto blockId = CreateBlockDirectlyWithFixtureAndReturnKey();
|
|
|
|
auto loaded = blockStore->load(blockId);
|
2015-07-21 14:50:52 +02:00
|
|
|
EXPECT_NE(boost::none, loaded);
|
2017-07-21 04:32:42 +02:00
|
|
|
EXPECT_EQ(data.size(), loaded->size());
|
|
|
|
EXPECT_EQ(0, std::memcmp(data.data(), loaded->data(), data.size()));
|
2015-05-06 00:37:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(EncryptedBlockStoreTest, LoadingWithSameKeyWorks_WriteSeparately) {
|
2017-09-17 03:07:27 +02:00
|
|
|
auto blockId = CreateBlockWriteFixtureToItAndReturnKey();
|
|
|
|
auto loaded = blockStore->load(blockId);
|
2015-07-21 14:50:52 +02:00
|
|
|
EXPECT_NE(boost::none, loaded);
|
2017-07-21 04:32:42 +02:00
|
|
|
EXPECT_EQ(data.size(), loaded->size());
|
|
|
|
EXPECT_EQ(0, std::memcmp(data.data(), loaded->data(), data.size()));
|
2015-05-06 00:37:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(EncryptedBlockStoreTest, LoadingWithDifferentKeyDoesntWork_WriteOnCreate) {
|
2017-09-17 03:07:27 +02:00
|
|
|
auto blockId = CreateBlockDirectlyWithFixtureAndReturnKey();
|
2015-05-06 00:37:57 +02:00
|
|
|
blockStore->__setKey(FakeAuthenticatedCipher::Key2());
|
2017-09-17 03:07:27 +02:00
|
|
|
auto loaded = blockStore->load(blockId);
|
2015-07-21 14:50:52 +02:00
|
|
|
EXPECT_EQ(boost::none, loaded);
|
2015-05-06 00:37:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(EncryptedBlockStoreTest, LoadingWithDifferentKeyDoesntWork_WriteSeparately) {
|
2017-09-17 03:07:27 +02:00
|
|
|
auto blockId = CreateBlockWriteFixtureToItAndReturnKey();
|
2015-05-06 00:37:57 +02:00
|
|
|
blockStore->__setKey(FakeAuthenticatedCipher::Key2());
|
2017-09-17 03:07:27 +02:00
|
|
|
auto loaded = blockStore->load(blockId);
|
2015-07-21 14:50:52 +02:00
|
|
|
EXPECT_EQ(boost::none, loaded);
|
2015-05-06 00:37:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(EncryptedBlockStoreTest, LoadingModifiedBlockFails_WriteOnCreate) {
|
2017-09-17 03:07:27 +02:00
|
|
|
auto blockId = CreateBlockDirectlyWithFixtureAndReturnKey();
|
|
|
|
ModifyBaseBlock(blockId);
|
|
|
|
auto loaded = blockStore->load(blockId);
|
2015-07-21 14:50:52 +02:00
|
|
|
EXPECT_EQ(boost::none, loaded);
|
2015-05-06 00:09:11 +02:00
|
|
|
}
|
|
|
|
|
2015-05-06 00:37:57 +02:00
|
|
|
TEST_F(EncryptedBlockStoreTest, LoadingModifiedBlockFails_WriteSeparately) {
|
2017-09-17 03:07:27 +02:00
|
|
|
auto blockId = CreateBlockWriteFixtureToItAndReturnKey();
|
|
|
|
ModifyBaseBlock(blockId);
|
|
|
|
auto loaded = blockStore->load(blockId);
|
2015-07-21 14:50:52 +02:00
|
|
|
EXPECT_EQ(boost::none, loaded);
|
2015-05-06 00:09:11 +02:00
|
|
|
}
|
|
|
|
|
2016-03-16 19:35:56 +01:00
|
|
|
TEST_F(EncryptedBlockStoreTest, PhysicalBlockSize_zerophysical) {
|
|
|
|
EXPECT_EQ(0u, blockStore->blockSizeFromPhysicalBlockSize(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(EncryptedBlockStoreTest, PhysicalBlockSize_zerovirtual) {
|
2017-09-17 03:07:27 +02:00
|
|
|
auto blockId = CreateBlockReturnKey(Data(0));
|
|
|
|
auto base = baseBlockStore->load(blockId).value();
|
2017-07-21 04:32:42 +02:00
|
|
|
EXPECT_EQ(0u, blockStore->blockSizeFromPhysicalBlockSize(base.size()));
|
2016-03-16 19:35:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(EncryptedBlockStoreTest, PhysicalBlockSize_negativeboundaries) {
|
|
|
|
// This tests that a potential if/else in blockSizeFromPhysicalBlockSize that catches negative values has the
|
|
|
|
// correct boundary set. We test the highest value that is negative and the smallest value that is positive.
|
2017-07-21 04:32:42 +02:00
|
|
|
auto physicalSizeForVirtualSizeZero = baseBlockStore->load(CreateBlockReturnKey(Data(0))).value().size();
|
2016-03-16 19:35:56 +01:00
|
|
|
if (physicalSizeForVirtualSizeZero > 0) {
|
|
|
|
EXPECT_EQ(0u, blockStore->blockSizeFromPhysicalBlockSize(physicalSizeForVirtualSizeZero - 1));
|
|
|
|
}
|
|
|
|
EXPECT_EQ(0u, blockStore->blockSizeFromPhysicalBlockSize(physicalSizeForVirtualSizeZero));
|
|
|
|
EXPECT_EQ(1u, blockStore->blockSizeFromPhysicalBlockSize(physicalSizeForVirtualSizeZero + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(EncryptedBlockStoreTest, PhysicalBlockSize_positive) {
|
2017-09-17 03:07:27 +02:00
|
|
|
auto blockId = CreateBlockReturnKey(Data(10*1024));
|
|
|
|
auto base = baseBlockStore->load(blockId).value();
|
2017-07-21 04:32:42 +02:00
|
|
|
EXPECT_EQ(10*1024u, blockStore->blockSizeFromPhysicalBlockSize(base.size()));
|
2016-03-16 19:35:56 +01:00
|
|
|
}
|