From 218463cf91102286630d3d03346e944693e03f6c Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Tue, 1 Sep 2015 00:25:14 +0200 Subject: [PATCH] Add more encryption ciphers --- src/CryCipher.cpp | 80 +++++++++++++++++++++++++++++++++++++++++ src/CryCipher.h | 30 ++++++++++++++++ src/CryConfigLoader.cpp | 17 +++++---- src/CryConfigLoader.h | 6 ++-- src/CryDevice.cpp | 14 ++------ 5 files changed, 122 insertions(+), 25 deletions(-) create mode 100644 src/CryCipher.cpp create mode 100644 src/CryCipher.h diff --git a/src/CryCipher.cpp b/src/CryCipher.cpp new file mode 100644 index 00000000..41e263d6 --- /dev/null +++ b/src/CryCipher.cpp @@ -0,0 +1,80 @@ +#include "CryCipher.h" + +#include +#include + +using std::vector; +using std::string; +using cpputils::unique_ref; +using cpputils::make_unique_ref; +using blockstore::BlockStore; +using std::shared_ptr; +using std::make_shared; + +using namespace cryfs; +using namespace blockstore::encrypted; + +template +class CryCipherInstance: public CryCipher { +public: + BOOST_CONCEPT_ASSERT((CipherConcept)); + + CryCipherInstance(const std::string &cipherName): _cipherName(cipherName) { + } + + string cipherName() const override { + return _cipherName; + } + + unique_ref createEncryptedBlockstore(unique_ref baseBlockStore, const string &encKey) const override { + return make_unique_ref>(std::move(baseBlockStore), Cipher::EncryptionKey::FromString(encKey)); + } + + string createKey() const override { + return Cipher::EncryptionKey::CreateOSRandom().ToString(); + } + +private: + string _cipherName; +}; + +//We have to use shared_ptr instead of unique_ref, because c++ initializer_list needs copyable values +const vector> CryCiphers::SUPPORTED_CIPHERS = { + make_shared>("aes-256-gcm"), + make_shared>("aes-256-cfb"), + make_shared>("aes-128-gcm"), + make_shared>("aes-128-cfb"), + make_shared>("twofish-256-gcm"), + make_shared>("twofish-256-cfb"), + make_shared>("twofish-128-gcm"), + make_shared>("twofish-128-cfb"), + make_shared>("serpent-256-gcm"), + make_shared>("serpent-256-cfb"), + make_shared>("serpent-128-gcm"), + make_shared>("serpent-128-cfb"), + make_shared>("cast-256-gcm"), + make_shared>("cast-256-cfb"), + make_shared>("mars-448-gcm"), + make_shared>("mars-448-cfb"), + make_shared>("mars-256-gcm"), + make_shared>("mars-256-cfb"), + make_shared>("mars-128-gcm"), + make_shared>("mars-128-cfb") +}; + +const CryCipher& CryCiphers::find(const string &cipherName) { + auto found = std::find_if(CryCiphers::SUPPORTED_CIPHERS.begin(), CryCiphers::SUPPORTED_CIPHERS.end(), + [cipherName] (const auto& element) { + return element->cipherName() == cipherName; + }); + ASSERT(found != CryCiphers::SUPPORTED_CIPHERS.end(), "Unknown Cipher"); + return **found; +} + +vector CryCiphers::supportedCiphers() { + vector result; + for (const auto& cipher : CryCiphers::SUPPORTED_CIPHERS) { + result.push_back(cipher->cipherName()); + } + return result; +} \ No newline at end of file diff --git a/src/CryCipher.h b/src/CryCipher.h new file mode 100644 index 00000000..06ae099c --- /dev/null +++ b/src/CryCipher.h @@ -0,0 +1,30 @@ +#ifndef CRYFS_CRYCIPHER_H +#define CRYFS_CRYCIPHER_H + +#include +#include +#include +#include + +namespace cryfs { + +class CryCipher { +public: + virtual std::string cipherName() const = 0; + virtual cpputils::unique_ref createEncryptedBlockstore(cpputils::unique_ref baseBlockStore, const std::string &encKey) const = 0; + virtual std::string createKey() const = 0; +}; + +class CryCiphers { +public: + static std::vector supportedCiphers(); + + static const CryCipher& find(const std::string &cipherName); + +private: + static const std::vector> SUPPORTED_CIPHERS; +}; + +} + +#endif diff --git a/src/CryConfigLoader.cpp b/src/CryConfigLoader.cpp index d02b9fbd..2bcbc36a 100644 --- a/src/CryConfigLoader.cpp +++ b/src/CryConfigLoader.cpp @@ -43,24 +43,23 @@ void CryConfigLoader::_initializeConfigWithWeakKey(CryConfig *config) { } void CryConfigLoader::_generateCipher(CryConfig *config) { - vector ciphers = {"aes-256-gcm", "aes-256-cfb"}; + vector ciphers = CryCiphers::supportedCiphers(); int cipherIndex = _console->ask("Which block cipher do you want to use?", ciphers); config->SetCipher(ciphers[cipherIndex]); } +void CryConfigLoader::_generateEncKey(CryConfig *config) { + _console->print("Generating secure encryption key..."); + config->SetEncryptionKey(CryCiphers::find(config->Cipher()).createKey()); + _console->print("done\n"); +} + void CryConfigLoader::_generateTestCipher(CryConfig *config) { config->SetCipher("aes-256-gcm"); } -void CryConfigLoader::_generateEncKey(CryConfig *config) { - _console->print("Generating secure encryption key..."); - auto new_key = Cipher::EncryptionKey::CreateOSRandom(); - config->SetEncryptionKey(new_key.ToString()); - _console->print("done\n"); -} - void CryConfigLoader::_generateWeakEncKey(CryConfig *config) { - auto new_key = Cipher::EncryptionKey::CreatePseudoRandom(); + auto new_key = blockstore::encrypted::AES256_GCM::EncryptionKey::CreatePseudoRandom(); config->SetEncryptionKey(new_key.ToString()); } diff --git a/src/CryConfigLoader.h b/src/CryConfigLoader.h index ded78dd5..55c8a8be 100644 --- a/src/CryConfigLoader.h +++ b/src/CryConfigLoader.h @@ -5,16 +5,14 @@ #include #include #include "CryConfig.h" -#include +#include "CryCipher.h" +#include #include "utils/Console.h" namespace cryfs { class CryConfigLoader { public: - //TODO Get rid of this and use dynamically configured Cipher instead - using Cipher = blockstore::encrypted::AES256_GCM; - CryConfigLoader(); explicit CryConfigLoader(cpputils::unique_ref console); diff --git a/src/CryDevice.cpp b/src/CryDevice.cpp index 3836ba80..09f37a6b 100644 --- a/src/CryDevice.cpp +++ b/src/CryDevice.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include "impl/DirBlob.h" #include "CryDevice.h" @@ -133,18 +133,8 @@ Key CryDevice::GetOrCreateRootKey(CryConfig *config) { } cpputils::unique_ref CryDevice::CreateEncryptedBlockStore(const CryConfig &config, unique_ref baseBlockStore) { - //TODO Can we somehow ensure that the if/else chain here doesn't forget a valid value? //TODO Test that CryFS is using the specified cipher - std::string cipherName = config.Cipher(); - if (cipherName == "aes-256-gcm") { - using Cipher = blockstore::encrypted::AES256_GCM; - return make_unique_ref>(std::move(baseBlockStore), Cipher::EncryptionKey::FromString(config.EncryptionKey())); - } else if (cipherName == "aes-256-cfb") { - using Cipher = blockstore::encrypted::AES256_CFB; - return make_unique_ref>(std::move(baseBlockStore), Cipher::EncryptionKey::FromString(config.EncryptionKey())); - } else { - ASSERT(false, "Unknown cipher"); - } + return CryCiphers::find(config.Cipher()).createEncryptedBlockstore(std::move(baseBlockStore), config.EncryptionKey()); } }