2016-02-11 16:39:42 +01:00
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <gmock/gmock.h>
|
2019-01-26 08:38:34 +01:00
|
|
|
#include <cryfs/impl/config/CryCipher.h>
|
2016-02-11 16:39:42 +01:00
|
|
|
#include <cpp-utils/crypto/symmetric/ciphers.h>
|
|
|
|
#include <cpp-utils/pointer/unique_ref_boost_optional_gtest_workaround.h>
|
2017-07-18 23:49:51 +02:00
|
|
|
#include <blockstore/implementations/inmemory/InMemoryBlockStore2.h>
|
|
|
|
#include <blockstore/implementations/encrypted/EncryptedBlockStore2.h>
|
2016-02-11 16:39:42 +01:00
|
|
|
#include <cpp-utils/data/DataFixture.h>
|
|
|
|
#include <cpp-utils/random/Random.h>
|
2015-10-19 14:22:01 +02:00
|
|
|
|
|
|
|
using namespace cryfs;
|
|
|
|
using namespace blockstore::encrypted;
|
2017-07-18 23:49:51 +02:00
|
|
|
using namespace blockstore::inmemory;
|
2015-10-19 14:22:01 +02:00
|
|
|
using namespace blockstore;
|
|
|
|
|
|
|
|
using std::initializer_list;
|
|
|
|
using std::string;
|
|
|
|
using std::vector;
|
|
|
|
using std::find;
|
|
|
|
using boost::none;
|
|
|
|
using testing::MatchesRegex;
|
2015-10-27 23:46:54 +01:00
|
|
|
using namespace cpputils;
|
2015-10-19 14:22:01 +02:00
|
|
|
|
|
|
|
class CryCipherTest : public ::testing::Test {
|
|
|
|
public:
|
|
|
|
void EXPECT_FINDS_CORRECT_CIPHERS(initializer_list<string> ciphers) {
|
|
|
|
for (const string & cipher : ciphers) {
|
|
|
|
EXPECT_FINDS_CORRECT_CIPHER(cipher);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EXPECT_FINDS_CORRECT_CIPHER(const string &cipherName) {
|
|
|
|
EXPECT_EQ(cipherName, CryCiphers::find(cipherName).cipherName());
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class ExpectedCipher>
|
|
|
|
void EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE(const string &cipherName) {
|
|
|
|
const auto &actualCipher = CryCiphers::find(cipherName);
|
|
|
|
Data dataFixture = DataFixture::generate(1024);
|
2018-10-21 22:53:53 +02:00
|
|
|
string encKey = ExpectedCipher::EncryptionKey::CreateKey(Random::PseudoRandom(), ExpectedCipher::KEYSIZE).ToString();
|
2015-10-19 14:22:01 +02:00
|
|
|
_EXPECT_ENCRYPTS_WITH_ACTUAL_BLOCKSTORE_DECRYPTS_CORRECTLY_WITH_EXPECTED_BLOCKSTORE<ExpectedCipher>(actualCipher, encKey, std::move(dataFixture));
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class ExpectedCipher>
|
|
|
|
void _EXPECT_ENCRYPTS_WITH_ACTUAL_BLOCKSTORE_DECRYPTS_CORRECTLY_WITH_EXPECTED_BLOCKSTORE(const CryCipher &actualCipher, const std::string &encKey, Data dataFixture) {
|
2017-09-17 03:07:27 +02:00
|
|
|
blockstore::BlockId blockId = blockstore::BlockId::Random();
|
|
|
|
Data encrypted = _encryptUsingEncryptedBlockStoreWithCipher(actualCipher, encKey, blockId, dataFixture.copy());
|
|
|
|
Data decrypted = _decryptUsingEncryptedBlockStoreWithCipher<ExpectedCipher>(encKey, blockId, std::move(encrypted));
|
2015-10-19 14:22:01 +02:00
|
|
|
EXPECT_EQ(dataFixture, decrypted);
|
|
|
|
}
|
|
|
|
|
2017-09-17 03:07:27 +02:00
|
|
|
Data _encryptUsingEncryptedBlockStoreWithCipher(const CryCipher &cipher, const std::string &encKey, const blockstore::BlockId &blockId, Data data) {
|
2017-07-18 23:49:51 +02:00
|
|
|
unique_ref<InMemoryBlockStore2> _baseStore = make_unique_ref<InMemoryBlockStore2>();
|
|
|
|
InMemoryBlockStore2 *baseStore = _baseStore.get();
|
|
|
|
unique_ref<BlockStore2> encryptedStore = cipher.createEncryptedBlockstore(std::move(_baseStore), encKey);
|
2017-12-01 16:01:49 +01:00
|
|
|
bool created = encryptedStore->tryCreate(blockId, data);
|
2017-07-18 23:49:51 +02:00
|
|
|
EXPECT_TRUE(created);
|
2017-09-17 03:07:27 +02:00
|
|
|
return _loadBlock(baseStore, blockId);
|
2015-10-19 14:22:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class Cipher>
|
2017-09-17 03:07:27 +02:00
|
|
|
Data _decryptUsingEncryptedBlockStoreWithCipher(const std::string &encKey, const blockstore::BlockId &blockId, Data data) {
|
2017-07-18 23:49:51 +02:00
|
|
|
unique_ref<InMemoryBlockStore2> baseStore = make_unique_ref<InMemoryBlockStore2>();
|
2017-12-01 16:01:49 +01:00
|
|
|
bool created = baseStore->tryCreate(blockId, data);
|
2017-07-18 23:49:51 +02:00
|
|
|
EXPECT_TRUE(created);
|
|
|
|
EncryptedBlockStore2<Cipher> encryptedStore(std::move(baseStore), Cipher::EncryptionKey::FromString(encKey));
|
2017-09-17 03:07:27 +02:00
|
|
|
return _loadBlock(&encryptedStore, blockId);
|
2015-10-19 14:22:01 +02:00
|
|
|
}
|
|
|
|
|
2017-09-17 03:07:27 +02:00
|
|
|
Data _loadBlock(BlockStore2 *store, const blockstore::BlockId &blockId) {
|
|
|
|
return store->load(blockId).value();
|
2015-10-19 14:22:01 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(CryCipherTest, FindsCorrectCipher) {
|
|
|
|
EXPECT_FINDS_CORRECT_CIPHERS({
|
|
|
|
"aes-256-gcm", "aes-256-cfb", "aes-256-gcm", "aes-256-cfb",
|
|
|
|
"twofish-256-gcm", "twofish-256-cfb", "twofish-256-gcm", "twofish-256-cfb",
|
|
|
|
"serpent-256-gcm", "serpent-256-cfb", "serpent-256-gcm", "serpent-256-cfb",
|
2019-01-20 23:07:06 +01:00
|
|
|
"cast-256-gcm", "cast-256-cfb", "mars-448-gcm", "mars-448-cfb",
|
2017-09-11 15:37:06 +02:00
|
|
|
"mars-256-gcm", "mars-256-cfb", "mars-256-gcm", "mars-256-cfb"
|
2015-10-19 14:22:01 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CryCipherTest, CreatesCorrectEncryptedBlockStore) {
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<AES256_GCM>("aes-256-gcm");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<AES256_CFB>("aes-256-cfb");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<AES128_GCM>("aes-128-gcm");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<AES128_CFB>("aes-128-cfb");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Twofish256_GCM>("twofish-256-gcm");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Twofish256_CFB>("twofish-256-cfb");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Twofish128_GCM>("twofish-128-gcm");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Twofish128_CFB>("twofish-128-cfb");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Serpent256_GCM>("serpent-256-gcm");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Serpent256_CFB>("serpent-256-cfb");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Serpent128_GCM>("serpent-128-gcm");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Serpent128_CFB>("serpent-128-cfb");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Cast256_GCM>("cast-256-gcm");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Cast256_CFB>("cast-256-cfb");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Mars448_GCM>("mars-448-gcm");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Mars448_CFB>("mars-448-cfb");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Mars256_GCM>("mars-256-gcm");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Mars256_CFB>("mars-256-cfb");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Mars128_GCM>("mars-128-gcm");
|
|
|
|
EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE<Mars128_CFB>("mars-128-cfb");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CryCipherTest, SupportedCipherNamesContainsACipher) {
|
|
|
|
vector<string> supportedCipherNames = CryCiphers::supportedCipherNames();
|
|
|
|
EXPECT_NE(supportedCipherNames.end(), find(supportedCipherNames.begin(), supportedCipherNames.end(), "aes-256-gcm"));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CryCipherTest, ThereIsACipherWithoutWarning) {
|
|
|
|
EXPECT_EQ(none, CryCiphers::find("aes-256-gcm").warning());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CryCipherTest, ThereIsACipherWithIntegrityWarning) {
|
2017-07-21 04:32:42 +02:00
|
|
|
EXPECT_THAT(CryCiphers::find("aes-256-cfb").warning().value(), MatchesRegex(".*integrity.*"));
|
2015-10-19 14:22:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CryCipherTest, EncryptionKeyHasCorrectSize_448) {
|
2018-10-21 22:53:53 +02:00
|
|
|
EXPECT_EQ(Mars448_GCM::STRING_KEYSIZE, CryCiphers::find("mars-448-gcm").createKey(Random::PseudoRandom()).size());
|
2015-10-19 14:22:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CryCipherTest, EncryptionKeyHasCorrectSize_256) {
|
2018-10-21 22:53:53 +02:00
|
|
|
EXPECT_EQ(AES256_GCM::STRING_KEYSIZE, CryCiphers::find("aes-256-gcm").createKey(Random::PseudoRandom()).size());
|
2015-10-19 14:22:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CryCipherTest, EncryptionKeyHasCorrectSize_128) {
|
2018-10-21 22:53:53 +02:00
|
|
|
EXPECT_EQ(AES128_GCM::STRING_KEYSIZE, CryCiphers::find("aes-128-gcm").createKey(Random::PseudoRandom()).size());
|
2015-10-19 14:22:01 +02:00
|
|
|
}
|