diff --git a/implementations/encrypted/Cipher.cpp b/implementations/encrypted/Cipher.cpp deleted file mode 100644 index c866c29b..00000000 --- a/implementations/encrypted/Cipher.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "Cipher.h" - diff --git a/implementations/encrypted/Cipher.h b/implementations/encrypted/Cipher.h deleted file mode 100644 index b5528a34..00000000 --- a/implementations/encrypted/Cipher.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once -#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_ENCRYPTED_CIPHER_H_ -#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_ENCRYPTED_CIPHER_H_ - -#include - -namespace blockstore { -namespace encrypted { - -class Cipher { -public: - virtual ~Cipher() {} - - virtual unsigned int ciphertextBlockSize(unsigned int ciphertextBlockSize) const = 0; - virtual unsigned int plaintextBlockSize(unsigned int plaintextBlockSize) const = 0; - - virtual void encrypt(const byte *plaintext, unsigned int plaintextSize, byte *ciphertext) const = 0; - virtual void decrypt(const byte *ciphertext, byte *plaintext, unsigned int plaintextSize) const = 0; -}; - -} -} - - - -#endif diff --git a/implementations/encrypted/EncryptedBlock.h b/implementations/encrypted/EncryptedBlock.h index 4be10ef9..ee64a56b 100644 --- a/implementations/encrypted/EncryptedBlock.h +++ b/implementations/encrypted/EncryptedBlock.h @@ -3,7 +3,6 @@ #define BLOCKSTORE_IMPLEMENTATIONS_ENCRYPTED_ENCRYPTEDBLOCK_H_ #include "../../interface/Block.h" -#include "Cipher.h" #include "../../utils/Data.h" #include "../../interface/BlockStore.h" diff --git a/implementations/encrypted/EncryptedBlockStore.h b/implementations/encrypted/EncryptedBlockStore.h index c7933216..a8ce51ac 100644 --- a/implementations/encrypted/EncryptedBlockStore.h +++ b/implementations/encrypted/EncryptedBlockStore.h @@ -5,7 +5,6 @@ #include "../../interface/BlockStore.h" #include #include -#include "Cipher.h" #include "EncryptedBlock.h" namespace blockstore { diff --git a/implementations/encrypted/ciphers/AES256_CFB.h b/implementations/encrypted/ciphers/AES256_CFB.h index 16c8e5f8..46d4aece 100644 --- a/implementations/encrypted/ciphers/AES256_CFB.h +++ b/implementations/encrypted/ciphers/AES256_CFB.h @@ -8,6 +8,7 @@ namespace blockstore { namespace encrypted { +//TODO Add contract/interface for ciphers class AES256_CFB { public: using EncryptionKey = FixedSizeData<32>; diff --git a/test/implementations/encrypted/CipherTest.cpp b/test/implementations/encrypted/CipherTest.cpp new file mode 100644 index 00000000..0f1429cf --- /dev/null +++ b/test/implementations/encrypted/CipherTest.cpp @@ -0,0 +1,155 @@ +#include +#include "../../../implementations/encrypted/ciphers/AES256_CFB.h" + +#include "../../testutils/DataBlockFixture.h" +#include "../../../utils/Data.h" + +using namespace blockstore::encrypted; +using blockstore::Data; + +template +class CipherTest: public ::testing::Test { +public: + typename Cipher::EncryptionKey encKey = createRandomKey(); + + static typename Cipher::EncryptionKey createRandomKey(int seed = 0) { + DataBlockFixture data(Cipher::EncryptionKey::BINARY_LENGTH, seed); + return Cipher::EncryptionKey::FromBinary(data.data()); + } + + void CheckEncryptThenDecryptIsIdentity(const Data &plaintext) { + Data ciphertext(Cipher::ciphertextSize(plaintext.size())); + Data decrypted(plaintext.size()); + Cipher::encrypt((byte*)plaintext.data(), plaintext.size(), (byte*)ciphertext.data(), this->encKey); + Cipher::decrypt((byte*)ciphertext.data(), (byte*) decrypted.data(), decrypted.size(), this->encKey); + EXPECT_EQ(0, std::memcmp(plaintext.data(), decrypted.data(), plaintext.size())); + } + + Data CreateZeroes(unsigned int size) { + Data zeroes(size); + zeroes.FillWithZeroes(); + return zeroes; + } + + Data CreateData(unsigned int size, unsigned int seed = 0) { + DataBlockFixture data(size, seed); + Data result(size); + std::memcpy(result.data(), data.data(), size); + return result; + } +}; + +TYPED_TEST_CASE_P(CipherTest); + +TYPED_TEST_P(CipherTest, Size_0) { + EXPECT_EQ(0, TypeParam::ciphertextSize(TypeParam::plaintextSize(0))); +} + +TYPED_TEST_P(CipherTest, Size_1) { + EXPECT_EQ(1, TypeParam::ciphertextSize(TypeParam::plaintextSize(1))); +} + +TYPED_TEST_P(CipherTest, Size_1024) { + EXPECT_EQ(1024, TypeParam::ciphertextSize(TypeParam::plaintextSize(1024))); + EXPECT_EQ(1024, TypeParam::plaintextSize(TypeParam::ciphertextSize(1024))); +} + +TYPED_TEST_P(CipherTest, Size_4096) { + EXPECT_EQ(4096, TypeParam::ciphertextSize(TypeParam::plaintextSize(4096))); + EXPECT_EQ(4096, TypeParam::plaintextSize(TypeParam::ciphertextSize(4096))); +} + +TYPED_TEST_P(CipherTest, Size_1048576) { + EXPECT_EQ(1048576, TypeParam::ciphertextSize(TypeParam::plaintextSize(1048576))); + EXPECT_EQ(1048576, TypeParam::plaintextSize(TypeParam::ciphertextSize(1048576))); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Empty) { + Data plaintext = this->CreateZeroes(0); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Zeroes_1) { + Data plaintext = this->CreateZeroes(1); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Data_1) { + Data plaintext = this->CreateData(1); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Zeroes_100) { + Data plaintext = this->CreateZeroes(100); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Data_100) { + Data plaintext = this->CreateData(100); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Zeroes_1024) { + Data plaintext = this->CreateZeroes(1024); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Data_1024) { + Data plaintext = this->CreateData(1024); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Zeroes_5000) { + Data plaintext = this->CreateZeroes(5000); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Data_5000) { + Data plaintext = this->CreateData(5000); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Zeroes_1MB) { + Data plaintext = this->CreateZeroes(1048576); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Data_1MB) { + Data plaintext = this->CreateData(1048576); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Zeroes_50MB) { + Data plaintext = this->CreateZeroes(52428800); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +TYPED_TEST_P(CipherTest, EncryptThenDecrypt_Data_50MB) { + Data plaintext = this->CreateData(52428800); + this->CheckEncryptThenDecryptIsIdentity(plaintext); +} + +REGISTER_TYPED_TEST_CASE_P(CipherTest, + Size_0, + Size_1, + Size_1024, + Size_4096, + Size_1048576, + EncryptThenDecrypt_Empty, + EncryptThenDecrypt_Zeroes_1, + EncryptThenDecrypt_Data_1, + EncryptThenDecrypt_Zeroes_100, + EncryptThenDecrypt_Data_100, + EncryptThenDecrypt_Zeroes_1024, + EncryptThenDecrypt_Data_1024, + EncryptThenDecrypt_Zeroes_5000, + EncryptThenDecrypt_Data_5000, + EncryptThenDecrypt_Zeroes_1MB, + EncryptThenDecrypt_Data_1MB, + EncryptThenDecrypt_Zeroes_50MB, + EncryptThenDecrypt_Data_50MB +); + +//TODO For authenticated ciphers, we need test cases checking that authentication fails on manipulations + +INSTANTIATE_TYPED_TEST_CASE_P(AES256_CFB, CipherTest, AES256_CFB);