Simplify: key size is only known at runtime, not a template parameter anymore
This commit is contained in:
parent
42f0b00828
commit
954d6662f6
@ -9,22 +9,12 @@ namespace cpputils {
|
||||
|
||||
class PasswordBasedKDF {
|
||||
public:
|
||||
virtual ~PasswordBasedKDF() {}
|
||||
virtual ~PasswordBasedKDF() = default;
|
||||
|
||||
template<size_t KEYSIZE> EncryptionKey<KEYSIZE> deriveKey(const std::string &password);
|
||||
virtual EncryptionKey deriveKey(size_t keySize, const std::string &password) = 0;
|
||||
virtual const Data &kdfParameters() const = 0;
|
||||
|
||||
protected:
|
||||
virtual void derive(void *destination, size_t size, const std::string &password) = 0;
|
||||
};
|
||||
|
||||
template<size_t KEYSIZE> EncryptionKey<KEYSIZE>
|
||||
inline PasswordBasedKDF::deriveKey(const std::string &password) {
|
||||
auto result = EncryptionKey<KEYSIZE>::Null();
|
||||
derive(result.data(), result.BINARY_LENGTH, password);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,11 +22,13 @@ namespace cpputils {
|
||||
:_config(std::move(config)), _serializedConfig(_config.serialize()), _wasGeneratedBefore(false) {
|
||||
}
|
||||
|
||||
void SCrypt::derive(void *destination, size_t size, const string &password) {
|
||||
EncryptionKey SCrypt::deriveKey(size_t keySize, const std::string &password) {
|
||||
_checkCallOnlyOnce();
|
||||
|
||||
auto result = EncryptionKey::Null(keySize);
|
||||
|
||||
size_t status = CryptoPP::Scrypt().DeriveKey(
|
||||
static_cast<uint8_t*>(destination), size,
|
||||
static_cast<uint8_t*>(result.data()), result.binaryLength(),
|
||||
reinterpret_cast<const uint8_t*>(password.c_str()), password.size(),
|
||||
static_cast<const uint8_t*>(_config.salt().data()), _config.salt().size(),
|
||||
_config.N(), _config.r(), _config.p()
|
||||
@ -34,6 +36,8 @@ namespace cpputils {
|
||||
if (status != 1) {
|
||||
throw std::runtime_error("Error running scrypt key derivation. Error code: "+std::to_string(status));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const Data &SCrypt::kdfParameters() const {
|
||||
|
@ -32,8 +32,7 @@ namespace cpputils {
|
||||
|
||||
SCrypt(SCryptParameters config);
|
||||
|
||||
protected:
|
||||
void derive(void *destination, size_t size, const std::string &password) override;
|
||||
EncryptionKey deriveKey(size_t keySize, const std::string &password) override;
|
||||
|
||||
private:
|
||||
void _checkCallOnlyOnce();
|
||||
|
@ -16,7 +16,10 @@ namespace cpputils {
|
||||
template<typename BlockCipher, unsigned int KeySize>
|
||||
class CFB_Cipher {
|
||||
public:
|
||||
using EncryptionKey = cpputils::EncryptionKey<KeySize>;
|
||||
using EncryptionKey = cpputils::EncryptionKey;
|
||||
|
||||
static constexpr unsigned int KEYSIZE = KeySize;
|
||||
static constexpr unsigned int STRING_KEYSIZE = 2 * KEYSIZE;
|
||||
|
||||
static constexpr unsigned int ciphertextSize(unsigned int plaintextBlockSize) {
|
||||
return plaintextBlockSize + IV_SIZE;
|
||||
@ -33,10 +36,17 @@ private:
|
||||
static constexpr unsigned int IV_SIZE = BlockCipher::BLOCKSIZE;
|
||||
};
|
||||
|
||||
template<class BlockCipher, unsigned int KeySize>
|
||||
constexpr unsigned int CFB_Cipher<BlockCipher, KeySize>::KEYSIZE;
|
||||
template<class BlockCipher, unsigned int KeySize>
|
||||
constexpr unsigned int CFB_Cipher<BlockCipher, KeySize>::STRING_KEYSIZE;
|
||||
|
||||
template<typename BlockCipher, unsigned int KeySize>
|
||||
Data CFB_Cipher<BlockCipher, KeySize>::encrypt(const CryptoPP::byte *plaintext, unsigned int plaintextSize, const EncryptionKey &encKey) {
|
||||
ASSERT(encKey.binaryLength() == KeySize, "Wrong key size");
|
||||
|
||||
FixedSizeData<IV_SIZE> iv = Random::PseudoRandom().getFixedSize<IV_SIZE>();
|
||||
auto encryption = typename CryptoPP::CFB_Mode<BlockCipher>::Encryption(static_cast<const CryptoPP::byte*>(encKey.data()), encKey.BINARY_LENGTH, iv.data());
|
||||
auto encryption = typename CryptoPP::CFB_Mode<BlockCipher>::Encryption(static_cast<const CryptoPP::byte*>(encKey.data()), encKey.binaryLength(), iv.data());
|
||||
Data ciphertext(ciphertextSize(plaintextSize));
|
||||
iv.ToBinary(ciphertext.data());
|
||||
if (plaintextSize > 0) {
|
||||
@ -47,13 +57,15 @@ Data CFB_Cipher<BlockCipher, KeySize>::encrypt(const CryptoPP::byte *plaintext,
|
||||
|
||||
template<typename BlockCipher, unsigned int KeySize>
|
||||
boost::optional<Data> CFB_Cipher<BlockCipher, KeySize>::decrypt(const CryptoPP::byte *ciphertext, unsigned int ciphertextSize, const EncryptionKey &encKey) {
|
||||
ASSERT(encKey.binaryLength() == KeySize, "Wrong key size");
|
||||
|
||||
if (ciphertextSize < IV_SIZE) {
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
const CryptoPP::byte *ciphertextIV = ciphertext;
|
||||
const CryptoPP::byte *ciphertextData = ciphertext + IV_SIZE;
|
||||
auto decryption = typename CryptoPP::CFB_Mode<BlockCipher>::Decryption(static_cast<const CryptoPP::byte*>(encKey.data()), encKey.BINARY_LENGTH, ciphertextIV);
|
||||
auto decryption = typename CryptoPP::CFB_Mode<BlockCipher>::Decryption(static_cast<const CryptoPP::byte*>(encKey.data()), encKey.binaryLength(), ciphertextIV);
|
||||
Data plaintext(plaintextSize(ciphertextSize));
|
||||
if (plaintext.size() > 0) {
|
||||
// TODO Shouldn't we pass in ciphertextSize instead of plaintext.size() here as last argument (and also in the if above)?
|
||||
|
@ -17,7 +17,9 @@ 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::CreateKey(Random::OSRandom());
|
||||
same_type(UINT32_C(0), X::KEYSIZE);
|
||||
same_type(UINT32_C(0), X::STRING_KEYSIZE);
|
||||
typename X::EncryptionKey key = X::EncryptionKey::CreateKey(Random::OSRandom(), X::KEYSIZE);
|
||||
same_type(Data(0), X::encrypt(static_cast<uint8_t*>(nullptr), UINT32_C(0), key));
|
||||
same_type(boost::optional<Data>(Data(0)), X::decrypt(static_cast<uint8_t*>(nullptr), UINT32_C(0), key));
|
||||
string name = X::NAME;
|
||||
|
@ -19,14 +19,11 @@ namespace cpputils {
|
||||
* that there aren't any copies made to different memory regions. However, these other memory regions should be short-lived
|
||||
* and therefore much less likely to swap.
|
||||
*/
|
||||
template<size_t KeySize>
|
||||
class EncryptionKey final {
|
||||
private:
|
||||
explicit EncryptionKey(std::shared_ptr<Data> keyData)
|
||||
: _keyData(std::move(keyData)) {
|
||||
ASSERT(_keyData->size() == KeySize, "Wrong key data size");
|
||||
}
|
||||
template<size_t OtherKeySize> friend class EncryptionKey;
|
||||
|
||||
public:
|
||||
EncryptionKey(const EncryptionKey& rhs) = default;
|
||||
@ -34,12 +31,17 @@ public:
|
||||
EncryptionKey& operator=(const EncryptionKey& rhs) = default;
|
||||
EncryptionKey& operator=(EncryptionKey&& rhs) = default;
|
||||
|
||||
static constexpr size_t BINARY_LENGTH = KeySize;
|
||||
static constexpr size_t STRING_LENGTH = 2 * BINARY_LENGTH;
|
||||
size_t binaryLength() const {
|
||||
return _keyData->size();
|
||||
}
|
||||
|
||||
static EncryptionKey Null() {
|
||||
size_t stringLength() const {
|
||||
return 2 * binaryLength();
|
||||
}
|
||||
|
||||
static EncryptionKey Null(size_t keySize) {
|
||||
auto data = std::make_shared<Data>(
|
||||
KeySize,
|
||||
keySize,
|
||||
make_unique_ref<UnswappableAllocator>()
|
||||
);
|
||||
data->FillWithZeroes();
|
||||
@ -47,28 +49,27 @@ public:
|
||||
}
|
||||
|
||||
static EncryptionKey FromString(const std::string& keyData) {
|
||||
ASSERT(keyData.size() == STRING_LENGTH, "Wrong input size or EncryptionKey::FromString()");
|
||||
|
||||
auto data = std::make_shared<Data>(
|
||||
Data::FromString(keyData, make_unique_ref<UnswappableAllocator>())
|
||||
);
|
||||
ASSERT(data->size() == KeySize, "Wrong input size for EncryptionKey::FromString()");
|
||||
EncryptionKey key(std::move(data));
|
||||
ASSERT(key.stringLength() == keyData.size(), "Wrong input size for EncryptionKey::FromString()");
|
||||
|
||||
return EncryptionKey(std::move(data));
|
||||
return key;
|
||||
}
|
||||
|
||||
std::string ToString() const {
|
||||
auto result = _keyData->ToString();
|
||||
ASSERT(result.size() == STRING_LENGTH, "Wrong string length");
|
||||
ASSERT(result.size() == stringLength(), "Wrong string length");
|
||||
return result;
|
||||
}
|
||||
|
||||
static EncryptionKey CreateKey(RandomGenerator &randomGenerator) {
|
||||
static EncryptionKey CreateKey(RandomGenerator &randomGenerator, size_t keySize) {
|
||||
EncryptionKey result(std::make_shared<Data>(
|
||||
KeySize,
|
||||
keySize,
|
||||
make_unique_ref<UnswappableAllocator>() // the allocator makes sure key data is never swapped to disk
|
||||
));
|
||||
randomGenerator.write(result._keyData->data(), KeySize);
|
||||
randomGenerator.write(result._keyData->data(), keySize);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -82,29 +83,25 @@ public:
|
||||
|
||||
// TODO Test take/drop
|
||||
|
||||
template<size_t NumTaken>
|
||||
EncryptionKey<NumTaken> take() const {
|
||||
static_assert(NumTaken <= KeySize, "Out of bounds");
|
||||
auto result = std::make_shared<Data>(NumTaken, make_unique_ref<UnswappableAllocator>());
|
||||
std::memcpy(result->data(), _keyData->data(), NumTaken);
|
||||
return EncryptionKey<NumTaken>(std::move(result));
|
||||
EncryptionKey take(size_t numTaken) const {
|
||||
ASSERT(numTaken <= _keyData->size(), "Out of bounds");
|
||||
auto result = std::make_shared<Data>(numTaken, make_unique_ref<UnswappableAllocator>());
|
||||
std::memcpy(result->data(), _keyData->data(), numTaken);
|
||||
return EncryptionKey(std::move(result));
|
||||
}
|
||||
|
||||
template<size_t NumDropped>
|
||||
EncryptionKey<KeySize - NumDropped> drop() const {
|
||||
static_assert(NumDropped <= KeySize, "Out of bounds");
|
||||
auto result = std::make_shared<Data>(KeySize - NumDropped, make_unique_ref<UnswappableAllocator>());
|
||||
std::memcpy(result->data(), _keyData->dataOffset(NumDropped), KeySize - NumDropped);
|
||||
return EncryptionKey<KeySize - NumDropped>(std::move(result));
|
||||
EncryptionKey drop(size_t numDropped) const {
|
||||
ASSERT(numDropped <= _keyData->size(), "Out of bounds");
|
||||
const size_t resultSize = _keyData->size() - numDropped;
|
||||
auto result = std::make_shared<Data>(resultSize, make_unique_ref<UnswappableAllocator>());
|
||||
std::memcpy(result->data(), _keyData->dataOffset(numDropped), resultSize);
|
||||
return EncryptionKey(std::move(result));
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<Data> _keyData;
|
||||
};
|
||||
|
||||
template<size_t KeySize> constexpr size_t EncryptionKey<KeySize>::BINARY_LENGTH;
|
||||
template<size_t KeySize> constexpr size_t EncryptionKey<KeySize>::STRING_LENGTH;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -15,7 +15,10 @@ namespace cpputils {
|
||||
template<typename BlockCipher, unsigned int KeySize>
|
||||
class GCM_Cipher {
|
||||
public:
|
||||
using EncryptionKey = cpputils::EncryptionKey<KeySize>;
|
||||
using EncryptionKey = cpputils::EncryptionKey;
|
||||
|
||||
static constexpr unsigned int KEYSIZE = KeySize;
|
||||
static constexpr unsigned int STRING_KEYSIZE = 2 * KEYSIZE;
|
||||
|
||||
static constexpr unsigned int ciphertextSize(unsigned int plaintextBlockSize) {
|
||||
return plaintextBlockSize + IV_SIZE + TAG_SIZE;
|
||||
@ -33,11 +36,18 @@ private:
|
||||
static constexpr unsigned int TAG_SIZE = 16;
|
||||
};
|
||||
|
||||
template<class BlockCipher, unsigned int KeySize>
|
||||
constexpr unsigned int GCM_Cipher<BlockCipher, KeySize>::KEYSIZE;
|
||||
template<class BlockCipher, unsigned int KeySize>
|
||||
constexpr unsigned int GCM_Cipher<BlockCipher, KeySize>::STRING_KEYSIZE;
|
||||
|
||||
template<typename BlockCipher, unsigned int KeySize>
|
||||
Data GCM_Cipher<BlockCipher, KeySize>::encrypt(const CryptoPP::byte *plaintext, unsigned int plaintextSize, const EncryptionKey &encKey) {
|
||||
ASSERT(encKey.binaryLength() == KeySize, "Wrong key size");
|
||||
|
||||
FixedSizeData<IV_SIZE> iv = Random::PseudoRandom().getFixedSize<IV_SIZE>();
|
||||
typename CryptoPP::GCM<BlockCipher, CryptoPP::GCM_64K_Tables>::Encryption encryption;
|
||||
encryption.SetKeyWithIV(static_cast<const CryptoPP::byte*>(encKey.data()), encKey.BINARY_LENGTH, iv.data(), IV_SIZE);
|
||||
encryption.SetKeyWithIV(static_cast<const CryptoPP::byte*>(encKey.data()), encKey.binaryLength(), iv.data(), IV_SIZE);
|
||||
Data ciphertext(ciphertextSize(plaintextSize));
|
||||
|
||||
iv.ToBinary(ciphertext.data());
|
||||
@ -52,6 +62,8 @@ Data GCM_Cipher<BlockCipher, KeySize>::encrypt(const CryptoPP::byte *plaintext,
|
||||
|
||||
template<typename BlockCipher, unsigned int KeySize>
|
||||
boost::optional<Data> GCM_Cipher<BlockCipher, KeySize>::decrypt(const CryptoPP::byte *ciphertext, unsigned int ciphertextSize, const EncryptionKey &encKey) {
|
||||
ASSERT(encKey.binaryLength() == KeySize, "Wrong key size");
|
||||
|
||||
if (ciphertextSize < IV_SIZE + TAG_SIZE) {
|
||||
return boost::none;
|
||||
}
|
||||
@ -59,7 +71,7 @@ boost::optional<Data> GCM_Cipher<BlockCipher, KeySize>::decrypt(const CryptoPP::
|
||||
const CryptoPP::byte *ciphertextIV = ciphertext;
|
||||
const CryptoPP::byte *ciphertextData = ciphertext + IV_SIZE;
|
||||
typename CryptoPP::GCM<BlockCipher, CryptoPP::GCM_64K_Tables>::Decryption decryption;
|
||||
decryption.SetKeyWithIV(static_cast<const CryptoPP::byte*>(encKey.data()), encKey.BINARY_LENGTH, ciphertextIV, IV_SIZE);
|
||||
decryption.SetKeyWithIV(static_cast<const CryptoPP::byte*>(encKey.data()), encKey.binaryLength(), ciphertextIV, IV_SIZE);
|
||||
Data plaintext(plaintextSize(ciphertextSize));
|
||||
|
||||
try {
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "FakeAuthenticatedCipher.h"
|
||||
|
||||
namespace cpputils {
|
||||
constexpr unsigned int FakeKey::BINARY_LENGTH;
|
||||
|
||||
constexpr unsigned int FakeAuthenticatedCipher::KEYSIZE;
|
||||
constexpr unsigned int FakeAuthenticatedCipher::STRING_KEYSIZE;
|
||||
std::random_device FakeAuthenticatedCipher::random_;
|
||||
}
|
||||
|
@ -17,9 +17,12 @@ namespace cpputils {
|
||||
return FakeKey{static_cast<uint64_t>(std::strtol(keyData.c_str(), nullptr, 10))};
|
||||
}
|
||||
|
||||
static constexpr unsigned int BINARY_LENGTH = sizeof(uint64_t);
|
||||
size_t binaryLength() const {
|
||||
return sizeof(uint64_t);
|
||||
}
|
||||
|
||||
static FakeKey CreateKey(RandomGenerator &randomGenerator) {
|
||||
static FakeKey CreateKey(RandomGenerator &randomGenerator, size_t keySize) {
|
||||
ASSERT(keySize == sizeof(uint64_t), "Wrong key size");
|
||||
auto data = randomGenerator.getFixedSize<sizeof(uint64_t)>();
|
||||
return FakeKey {*reinterpret_cast<uint64_t*>(data.data())};
|
||||
}
|
||||
@ -34,6 +37,9 @@ namespace cpputils {
|
||||
|
||||
using EncryptionKey = FakeKey;
|
||||
|
||||
static constexpr unsigned int KEYSIZE = sizeof(uint64_t);
|
||||
static constexpr unsigned int STRING_KEYSIZE = 2 * KEYSIZE;
|
||||
|
||||
static EncryptionKey Key1() {
|
||||
return FakeKey{5};
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class CryCipherInstance: public CryCipher {
|
||||
public:
|
||||
BOOST_CONCEPT_ASSERT((CipherConcept<Cipher>));
|
||||
|
||||
static_assert(Cipher::EncryptionKey::BINARY_LENGTH <= CryCiphers::MAX_KEY_SIZE, "The key size for this cipher is too large. Please modify CryCiphers::MAX_KEY_SIZE");
|
||||
static_assert(Cipher::KEYSIZE <= CryCiphers::MAX_KEY_SIZE, "The key size for this cipher is too large. Please modify CryCiphers::MAX_KEY_SIZE");
|
||||
|
||||
CryCipherInstance(const optional<string> warning = none): _warning(warning) {
|
||||
}
|
||||
@ -43,11 +43,12 @@ public:
|
||||
}
|
||||
|
||||
string createKey(cpputils::RandomGenerator &randomGenerator) const override {
|
||||
return Cipher::EncryptionKey::CreateKey(randomGenerator).ToString();
|
||||
return Cipher::EncryptionKey::CreateKey(randomGenerator, Cipher::KEYSIZE).ToString();
|
||||
}
|
||||
|
||||
unique_ref<InnerEncryptor> createInnerConfigEncryptor(const EncryptionKey<CryCiphers::MAX_KEY_SIZE>& key) const override {
|
||||
return make_unique_ref<ConcreteInnerEncryptor<Cipher>>(key.take<Cipher::EncryptionKey::BINARY_LENGTH>());
|
||||
unique_ref<InnerEncryptor> createInnerConfigEncryptor(const EncryptionKey& key) const override {
|
||||
ASSERT(key.binaryLength() == CryCiphers::MAX_KEY_SIZE, "Wrong key size");
|
||||
return make_unique_ref<ConcreteInnerEncryptor<Cipher>>(key.take(Cipher::KEYSIZE));
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -41,7 +41,7 @@ public:
|
||||
virtual const boost::optional<std::string> &warning() const = 0;
|
||||
virtual cpputils::unique_ref<blockstore::BlockStore2> createEncryptedBlockstore(cpputils::unique_ref<blockstore::BlockStore2> baseBlockStore, const std::string &encKey) const = 0;
|
||||
virtual std::string createKey(cpputils::RandomGenerator &randomGenerator) const = 0;
|
||||
virtual cpputils::unique_ref<InnerEncryptor> createInnerConfigEncryptor(const cpputils::EncryptionKey<CryCiphers::MAX_KEY_SIZE> &key) const = 0;
|
||||
virtual cpputils::unique_ref<InnerEncryptor> createInnerConfigEncryptor(const cpputils::EncryptionKey &key) const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -13,8 +13,9 @@ namespace cryfs {
|
||||
constexpr size_t CryConfigEncryptor::OuterKeySize;
|
||||
constexpr size_t CryConfigEncryptor::MaxTotalKeySize;
|
||||
|
||||
CryConfigEncryptor::CryConfigEncryptor(cpputils::EncryptionKey<MaxTotalKeySize> derivedKey, cpputils::Data kdfParameters)
|
||||
CryConfigEncryptor::CryConfigEncryptor(cpputils::EncryptionKey derivedKey, cpputils::Data kdfParameters)
|
||||
: _derivedKey(std::move(derivedKey)), _kdfParameters(std::move(kdfParameters)) {
|
||||
ASSERT(_derivedKey.binaryLength() == MaxTotalKeySize, "Wrong key size");
|
||||
}
|
||||
|
||||
Data CryConfigEncryptor::encrypt(const Data &plaintext, const string &cipherName) const {
|
||||
@ -45,12 +46,12 @@ namespace cryfs {
|
||||
}
|
||||
|
||||
unique_ref<OuterEncryptor> CryConfigEncryptor::_outerEncryptor() const {
|
||||
auto outerKey = _derivedKey.take<OuterKeySize>();
|
||||
auto outerKey = _derivedKey.take(OuterKeySize);
|
||||
return make_unique_ref<OuterEncryptor>(std::move(outerKey), _kdfParameters.copy());
|
||||
}
|
||||
|
||||
unique_ref<InnerEncryptor> CryConfigEncryptor::_innerEncryptor(const string &cipherName) const {
|
||||
auto innerKey = _derivedKey.drop<OuterKeySize>();
|
||||
auto innerKey = _derivedKey.drop(OuterKeySize);
|
||||
return CryCiphers::find(cipherName).createInnerConfigEncryptor(std::move(innerKey));
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ namespace cryfs {
|
||||
//TODO Use own exception for cpputils::Serializer/cpputils::Deserializer errors and only catch them
|
||||
class CryConfigEncryptor final {
|
||||
public:
|
||||
static constexpr size_t OuterKeySize = OuterEncryptor::Cipher::EncryptionKey::BINARY_LENGTH;
|
||||
static constexpr size_t OuterKeySize = OuterEncryptor::Cipher::KEYSIZE;
|
||||
static constexpr size_t MaxTotalKeySize = OuterKeySize + CryCiphers::MAX_KEY_SIZE;
|
||||
|
||||
struct Decrypted {
|
||||
@ -23,7 +23,7 @@ namespace cryfs {
|
||||
bool wasInDeprecatedConfigFormat;
|
||||
};
|
||||
|
||||
CryConfigEncryptor(cpputils::EncryptionKey<MaxTotalKeySize> derivedKey, cpputils::Data _kdfParameters);
|
||||
CryConfigEncryptor(cpputils::EncryptionKey derivedKey, cpputils::Data _kdfParameters);
|
||||
|
||||
cpputils::Data encrypt(const cpputils::Data &plaintext, const std::string &cipherName) const;
|
||||
boost::optional<Decrypted> decrypt(const cpputils::Data &data) const;
|
||||
@ -32,7 +32,7 @@ namespace cryfs {
|
||||
cpputils::unique_ref<OuterEncryptor> _outerEncryptor() const;
|
||||
cpputils::unique_ref<InnerEncryptor> _innerEncryptor(const std::string &cipherName) const;
|
||||
|
||||
cpputils::EncryptionKey<MaxTotalKeySize> _derivedKey;
|
||||
cpputils::EncryptionKey _derivedKey;
|
||||
cpputils::Data _kdfParameters;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CryConfigEncryptor);
|
||||
|
@ -33,7 +33,7 @@ namespace cryfs {
|
||||
// (once we know which inner cipher was used) only generate as many key bytes as we need for the inner cipher.
|
||||
// This would need a change in the scrypt interface though, because right now we can't continue past key computations.
|
||||
//TODO I might be able to know the actual key size here (at runtime) and switch the SCrypt deriveKey() interface to getting a dynamic size.
|
||||
auto key = kdf->deriveKey<CryConfigEncryptor::MaxTotalKeySize>(password);
|
||||
auto key = kdf->deriveKey(CryConfigEncryptor::MaxTotalKeySize, password);
|
||||
return make_unique_ref<CryConfigEncryptor>(key, kdf->kdfParameters().copy());
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
private:
|
||||
static typename Cipher::EncryptionKey createKeyFixture(int seed = 0) {
|
||||
return Cipher::EncryptionKey::FromString(
|
||||
DataFixture::generate(Cipher::EncryptionKey::BINARY_LENGTH, seed).ToString()
|
||||
DataFixture::generate(Cipher::KEYSIZE, seed).ToString()
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -55,7 +55,7 @@ public:
|
||||
private:
|
||||
static typename Cipher::EncryptionKey createKeyFixture(int seed = 0) {
|
||||
return Cipher::EncryptionKey::FromString(
|
||||
DataFixture::generate(Cipher::EncryptionKey::BINARY_LENGTH, seed).ToString()
|
||||
DataFixture::generate(Cipher::KEYSIZE, seed).ToString()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -14,39 +14,39 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
template<size_t SIZE>
|
||||
bool keyEquals(const EncryptionKey<SIZE>& lhs, const EncryptionKey<SIZE>& rhs) {
|
||||
return 0 == std::memcmp(lhs.data(), rhs.data(), SIZE);
|
||||
bool keyEquals(const EncryptionKey& lhs, const EncryptionKey& rhs) {
|
||||
ASSERT(lhs.binaryLength() == rhs.binaryLength(), "Keys must have equal size to be comparable");
|
||||
return 0 == std::memcmp(lhs.data(), rhs.data(), lhs.binaryLength());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(SCryptTest, GeneratedKeyIsReproductible_448) {
|
||||
auto derivedKey = scryptForNewKey->deriveKey<56>("mypassword");
|
||||
auto rederivedKey = scryptForExistingKey->deriveKey<56>("mypassword");
|
||||
auto derivedKey = scryptForNewKey->deriveKey(56, "mypassword");
|
||||
auto rederivedKey = scryptForExistingKey->deriveKey(56, "mypassword");
|
||||
EXPECT_TRUE(keyEquals(derivedKey, rederivedKey));
|
||||
}
|
||||
|
||||
TEST_F(SCryptTest, GeneratedKeyIsReproductible_256) {
|
||||
auto derivedKey = scryptForNewKey->deriveKey<32>("mypassword");
|
||||
auto rederivedKey = scryptForExistingKey->deriveKey<32>("mypassword");
|
||||
auto derivedKey = scryptForNewKey->deriveKey(32, "mypassword");
|
||||
auto rederivedKey = scryptForExistingKey->deriveKey(32, "mypassword");
|
||||
EXPECT_TRUE(keyEquals(derivedKey, rederivedKey));
|
||||
}
|
||||
|
||||
TEST_F(SCryptTest, GeneratedKeyIsReproductible_128) {
|
||||
auto derivedKey = scryptForNewKey->deriveKey<16>("mypassword");
|
||||
auto rederivedKey = scryptForExistingKey->deriveKey<16>("mypassword");
|
||||
auto derivedKey = scryptForNewKey->deriveKey(16, "mypassword");
|
||||
auto rederivedKey = scryptForExistingKey->deriveKey(16, "mypassword");
|
||||
EXPECT_TRUE(keyEquals(derivedKey, rederivedKey));
|
||||
}
|
||||
|
||||
TEST_F(SCryptTest, GeneratedKeyIsReproductible_DefaultSettings) {
|
||||
auto derivedKey = scryptForNewKey->deriveKey<16>("mypassword");
|
||||
auto rederivedKey = scryptForExistingKey->deriveKey<16>("mypassword");
|
||||
auto derivedKey = scryptForNewKey->deriveKey(16, "mypassword");
|
||||
auto rederivedKey = scryptForExistingKey->deriveKey(16, "mypassword");
|
||||
EXPECT_TRUE(keyEquals(derivedKey, rederivedKey));
|
||||
}
|
||||
|
||||
TEST_F(SCryptTest, DifferentPasswordResultsInDifferentKey) {
|
||||
auto derivedKey = scryptForNewKey->deriveKey<16>("mypassword");
|
||||
auto rederivedKey = scryptForExistingKey->deriveKey<16>("mypassword2");
|
||||
auto derivedKey = scryptForNewKey->deriveKey(16, "mypassword");
|
||||
auto rederivedKey = scryptForExistingKey->deriveKey(16, "mypassword2");
|
||||
EXPECT_FALSE(keyEquals(derivedKey, rederivedKey));
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ public:
|
||||
typename Cipher::EncryptionKey encKey = createKeyFixture();
|
||||
|
||||
static typename Cipher::EncryptionKey createKeyFixture(int seed = 0) {
|
||||
Data data = DataFixture::generate(Cipher::EncryptionKey::BINARY_LENGTH, seed);
|
||||
Data data = DataFixture::generate(Cipher::KEYSIZE, seed);
|
||||
return Cipher::EncryptionKey::FromString(data.ToString());
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ public:
|
||||
void EXPECT_CREATES_CORRECT_ENCRYPTED_BLOCKSTORE(const string &cipherName) {
|
||||
const auto &actualCipher = CryCiphers::find(cipherName);
|
||||
Data dataFixture = DataFixture::generate(1024);
|
||||
string encKey = ExpectedCipher::EncryptionKey::CreateKey(Random::PseudoRandom()).ToString();
|
||||
string encKey = ExpectedCipher::EncryptionKey::CreateKey(Random::PseudoRandom(), ExpectedCipher::KEYSIZE).ToString();
|
||||
_EXPECT_ENCRYPTS_WITH_ACTUAL_BLOCKSTORE_DECRYPTS_CORRECTLY_WITH_EXPECTED_BLOCKSTORE<ExpectedCipher>(actualCipher, encKey, std::move(dataFixture));
|
||||
}
|
||||
|
||||
@ -125,14 +125,14 @@ TEST_F(CryCipherTest, ThereIsACipherWithIntegrityWarning) {
|
||||
|
||||
#if CRYPTOPP_VERSION != 564
|
||||
TEST_F(CryCipherTest, EncryptionKeyHasCorrectSize_448) {
|
||||
EXPECT_EQ(Mars448_GCM::EncryptionKey::STRING_LENGTH, CryCiphers::find("mars-448-gcm").createKey(Random::PseudoRandom()).size());
|
||||
EXPECT_EQ(Mars448_GCM::STRING_KEYSIZE, CryCiphers::find("mars-448-gcm").createKey(Random::PseudoRandom()).size());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_F(CryCipherTest, EncryptionKeyHasCorrectSize_256) {
|
||||
EXPECT_EQ(AES256_GCM::EncryptionKey::STRING_LENGTH, CryCiphers::find("aes-256-gcm").createKey(Random::PseudoRandom()).size());
|
||||
EXPECT_EQ(AES256_GCM::STRING_KEYSIZE, CryCiphers::find("aes-256-gcm").createKey(Random::PseudoRandom()).size());
|
||||
}
|
||||
|
||||
TEST_F(CryCipherTest, EncryptionKeyHasCorrectSize_128) {
|
||||
EXPECT_EQ(AES128_GCM::EncryptionKey::STRING_LENGTH, CryCiphers::find("aes-128-gcm").createKey(Random::PseudoRandom()).size());
|
||||
EXPECT_EQ(AES128_GCM::STRING_KEYSIZE, CryCiphers::find("aes-128-gcm").createKey(Random::PseudoRandom()).size());
|
||||
}
|
||||
|
@ -40,8 +40,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
EncryptionKey<CryConfigEncryptor::MaxTotalKeySize> _derivedKey() {
|
||||
return EncryptionKey<CryConfigEncryptor::MaxTotalKeySize>::FromString(
|
||||
EncryptionKey _derivedKey() {
|
||||
return EncryptionKey::FromString(
|
||||
DataFixture::generateFixedSize<CryConfigEncryptor::MaxTotalKeySize>(3).ToString()
|
||||
);
|
||||
}
|
||||
@ -51,7 +51,7 @@ private:
|
||||
}
|
||||
|
||||
unique_ref<OuterEncryptor> _outerEncryptor() {
|
||||
auto outerKey = _derivedKey().take<CryConfigEncryptor::OuterKeySize>();
|
||||
auto outerKey = _derivedKey().take(CryConfigEncryptor::OuterKeySize);
|
||||
return make_unique_ref<OuterEncryptor>(outerKey, _kdfParameters());
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
template<class Cipher>
|
||||
unique_ref<InnerEncryptor> makeInnerEncryptor() {
|
||||
auto key = Cipher::EncryptionKey::FromString(
|
||||
DataFixture::generateFixedSize<Cipher::EncryptionKey::BINARY_LENGTH>().ToString()
|
||||
DataFixture::generateFixedSize<Cipher::KEYSIZE>().ToString()
|
||||
);
|
||||
return make_unique_ref<ConcreteInnerEncryptor<Cipher>>(key);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
|
||||
unique_ref<OuterEncryptor> makeOuterEncryptor() {
|
||||
auto key = OuterEncryptor::Cipher::EncryptionKey::FromString(
|
||||
DataFixture::generateFixedSize<OuterEncryptor::Cipher::EncryptionKey::BINARY_LENGTH>().ToString()
|
||||
DataFixture::generateFixedSize<OuterEncryptor::Cipher::KEYSIZE>().ToString()
|
||||
);
|
||||
return make_unique_ref<OuterEncryptor>(key, kdfParameters());
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
cryfs::CryConfigFile configFile() {
|
||||
cryfs::CryConfig config;
|
||||
config.SetCipher("aes-256-gcm");
|
||||
config.SetEncryptionKey(cpputils::AES256_GCM::EncryptionKey::CreateKey(cpputils::Random::PseudoRandom()).ToString());
|
||||
config.SetEncryptionKey(cpputils::AES256_GCM::EncryptionKey::CreateKey(cpputils::Random::PseudoRandom(), cpputils::AES256_GCM::KEYSIZE).ToString());
|
||||
config.SetBlocksizeBytes(10240);
|
||||
return cryfs::CryConfigFile::create(_configFile.path(), std::move(config), "mypassword", cpputils::SCrypt::TestSettings);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user