diff --git a/implementations/encrypted/EncryptedBlock.h b/implementations/encrypted/EncryptedBlock.h index b5414217..cb0e10a4 100644 --- a/implementations/encrypted/EncryptedBlock.h +++ b/implementations/encrypted/EncryptedBlock.h @@ -9,6 +9,7 @@ #include "messmer/cpp-utils/macros.h" #include #include +#include "ciphers/Cipher.h" namespace blockstore { namespace encrypted { @@ -19,6 +20,7 @@ template class EncryptedBlockStore; template class EncryptedBlock: public Block { public: + BOOST_CONCEPT_ASSERT((CipherConcept)); static std::unique_ptr TryCreateNew(BlockStore *baseBlockStore, const Key &key, Data data, const typename Cipher::EncryptionKey &encKey); static std::unique_ptr TryDecrypt(std::unique_ptr baseBlock, const typename Cipher::EncryptionKey &key); diff --git a/implementations/encrypted/ciphers/AES256_CFB.h b/implementations/encrypted/ciphers/AES256_CFB.h index 5a817f35..154106ce 100644 --- a/implementations/encrypted/ciphers/AES256_CFB.h +++ b/implementations/encrypted/ciphers/AES256_CFB.h @@ -6,6 +6,7 @@ #include "../../../utils/Data.h" #include #include +#include "Cipher.h" namespace blockstore { namespace encrypted { @@ -13,11 +14,11 @@ namespace encrypted { //TODO Add contract/interface for ciphers class AES256_CFB { public: + BOOST_CONCEPT_ASSERT((CipherConcept)); + using EncryptionKey = FixedSizeData<32>; static_assert(32 == CryptoPP::AES::MAX_KEYLENGTH, "If AES offered larger keys, we should offer a variant with it"); - AES256_CFB(const EncryptionKey &key); - static constexpr unsigned int ciphertextSize(unsigned int plaintextBlockSize) { return plaintextBlockSize + IV_SIZE; } diff --git a/implementations/encrypted/ciphers/Cipher.h b/implementations/encrypted/ciphers/Cipher.h new file mode 100644 index 00000000..08936427 --- /dev/null +++ b/implementations/encrypted/ciphers/Cipher.h @@ -0,0 +1,32 @@ +#pragma once +#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_ENCRYPTED_CIPHERS_CIPHER_H_ +#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_ENCRYPTED_CIPHERS_CIPHER_H_ + +#include +#include + +namespace blockstore { +namespace encrypted { + +template +struct CipherConcept { +public: + BOOST_CONCEPT_USAGE(CipherConcept) { + same_type(UINT32_C(0), X::ciphertextSize(UINT32_C(5))); + same_type(UINT32_C(0), X::plaintextSize(UINT32_C(5))); + typename X::EncryptionKey key = X::EncryptionKey::CreateRandom(); + same_type(Data(0), X::encrypt((byte*)nullptr, UINT32_C(0), key)); + same_type(boost::optional(Data(0)), X::decrypt((byte*)nullptr, UINT32_C(0), key)); + } + +private: + // Type deduction will fail unless the arguments have the same type. + template void same_type(T const&, T const&); +}; + +} +} + + + +#endif diff --git a/test/implementations/encrypted/CipherTest.cpp b/test/implementations/encrypted/CipherTest.cpp index f1bccee3..a4385998 100644 --- a/test/implementations/encrypted/CipherTest.cpp +++ b/test/implementations/encrypted/CipherTest.cpp @@ -1,5 +1,6 @@ #include #include "../../../implementations/encrypted/ciphers/AES256_CFB.h" +#include "../../../implementations/encrypted/ciphers/Cipher.h" #include "../../testutils/DataBlockFixture.h" #include "../../../utils/Data.h" @@ -10,6 +11,7 @@ using blockstore::Data; template class CipherTest: public ::testing::Test { public: + BOOST_CONCEPT_ASSERT((CipherConcept)); typename Cipher::EncryptionKey encKey = createRandomKey(); static typename Cipher::EncryptionKey createRandomKey(int seed = 0) { @@ -82,7 +84,7 @@ TYPED_TEST_P(CipherTest, Size_1048576) { EXPECT_EQ(1048576, TypeParam::plaintextSize(TypeParam::ciphertextSize(1048576))); } -constexpr std::initializer_list SIZES = {0, 1, 100, 1024, 5000, 1048576, 52428800}; +constexpr std::initializer_list SIZES = {0, 1, 100, 1024, 5000, 1048576, 20971520}; TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Zeroes) { for (auto size: SIZES) {