Added key derivation function scrypt
This commit is contained in:
parent
20b0034ab1
commit
8741853eef
@ -10,6 +10,7 @@
|
||||
messmer/fspp: 1
|
||||
messmer/gitversion: 5
|
||||
messmer/parallelaccessstore: 1
|
||||
messmer/scrypt: 0
|
||||
|
||||
[parent]
|
||||
messmer/cryfs: 3
|
||||
|
1
src/config/crypto/DerivedKey.cpp
Normal file
1
src/config/crypto/DerivedKey.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "DerivedKey.h"
|
31
src/config/crypto/DerivedKey.h
Normal file
31
src/config/crypto/DerivedKey.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_DERIVEDKEY_H
|
||||
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_DERIVEDKEY_H
|
||||
|
||||
#include <messmer/cpp-utils/data/FixedSizeData.h>
|
||||
#include "DerivedKeyConfig.h"
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
template<size_t KEY_LENGTH>
|
||||
class DerivedKey {
|
||||
public:
|
||||
DerivedKey(DerivedKeyConfig config, const cpputils::FixedSizeData<KEY_LENGTH> &key): _config(std::move(config)), _key(key) {}
|
||||
DerivedKey(DerivedKey &&rhs) = default;
|
||||
|
||||
const DerivedKeyConfig &config() const {
|
||||
return _config;
|
||||
}
|
||||
|
||||
const cpputils::FixedSizeData<KEY_LENGTH> &key() const {
|
||||
return _key;
|
||||
}
|
||||
private:
|
||||
DerivedKeyConfig _config;
|
||||
cpputils::FixedSizeData<KEY_LENGTH> _key;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DerivedKey);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
1
src/config/crypto/DerivedKeyConfig.cpp
Normal file
1
src/config/crypto/DerivedKeyConfig.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "DerivedKeyConfig.h"
|
44
src/config/crypto/DerivedKeyConfig.h
Normal file
44
src/config/crypto/DerivedKeyConfig.h
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_KEYCONFIG_H
|
||||
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_KEYCONFIG_H
|
||||
|
||||
#include <messmer/cpp-utils/data/Data.h>
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
class DerivedKeyConfig {
|
||||
public:
|
||||
DerivedKeyConfig(cpputils::Data salt, uint64_t N, uint32_t r, uint32_t p)
|
||||
: _salt(std::move(salt)),
|
||||
_N(N), _r(r), _p(p) { }
|
||||
|
||||
DerivedKeyConfig(DerivedKeyConfig &&rhs) = default;
|
||||
|
||||
const cpputils::Data &salt() const {
|
||||
return _salt;
|
||||
}
|
||||
|
||||
size_t N() const {
|
||||
return _N;
|
||||
}
|
||||
|
||||
size_t r() const {
|
||||
return _r;
|
||||
}
|
||||
|
||||
size_t p() const {
|
||||
return _p;
|
||||
}
|
||||
|
||||
private:
|
||||
cpputils::Data _salt;
|
||||
uint64_t _N;
|
||||
uint32_t _r;
|
||||
uint32_t _p;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DerivedKeyConfig);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
8
src/config/crypto/Scrypt.cpp
Normal file
8
src/config/crypto/Scrypt.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include "Scrypt.h"
|
||||
|
||||
namespace cryfs {
|
||||
constexpr size_t SCrypt::SALT_LEN;
|
||||
constexpr uint64_t SCrypt::N;
|
||||
constexpr uint32_t SCrypt::r;
|
||||
constexpr uint32_t SCrypt::p;
|
||||
}
|
49
src/config/crypto/Scrypt.h
Normal file
49
src/config/crypto/Scrypt.h
Normal file
@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_CRYFS_SRC_CONFIG_CRYPTO_SCRYPT_H
|
||||
#define MESSMER_CRYFS_SRC_CONFIG_CRYPTO_SCRYPT_H
|
||||
|
||||
#include <messmer/cpp-utils/macros.h>
|
||||
#include <messmer/cpp-utils/random/Random.h>
|
||||
extern "C" {
|
||||
#include <messmer/scrypt/lib/crypto/crypto_scrypt.h>
|
||||
}
|
||||
#include <stdexcept>
|
||||
#include "DerivedKey.h"
|
||||
|
||||
namespace cryfs {
|
||||
|
||||
class SCrypt {
|
||||
public:
|
||||
//TODO Make user-configurable. For sensitive storage, N=1048576, r=8 is recommended.
|
||||
constexpr static size_t SALT_LEN = 32; // Size of the salt
|
||||
constexpr static uint64_t N = 524288; // CPU/Memory cost
|
||||
constexpr static uint32_t r = 1; // Blocksize
|
||||
constexpr static uint32_t p = 1; // Parallelization
|
||||
|
||||
SCrypt() {}
|
||||
|
||||
template<size_t KEYSIZE> DerivedKey<KEYSIZE> generateKey(const std::string &password) {
|
||||
auto salt = cpputils::Random::PseudoRandom().get(SALT_LEN);
|
||||
auto config = DerivedKeyConfig(std::move(salt), N, r, p);
|
||||
auto key = generateKeyFromConfig<KEYSIZE>(password, config);
|
||||
return DerivedKey<KEYSIZE>(std::move(config), key);
|
||||
}
|
||||
|
||||
template<size_t KEYSIZE> cpputils::FixedSizeData<KEYSIZE> generateKeyFromConfig(const std::string &password, const DerivedKeyConfig &config) {
|
||||
auto key = cpputils::FixedSizeData<KEYSIZE>::Null();
|
||||
int errorcode = crypto_scrypt(reinterpret_cast<const uint8_t*>(password.c_str()), password.size(),
|
||||
reinterpret_cast<const uint8_t*>(config.salt().data()), config.salt().size(),
|
||||
config.N(), config.r(), config.p(),
|
||||
static_cast<uint8_t*>(key.data()), KEYSIZE);
|
||||
if (errorcode != 0) {
|
||||
throw std::runtime_error("Error running scrypt key derivation.");
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(SCrypt);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
51
test/config/crypto/DerivedKeyConfigTest.cpp
Normal file
51
test/config/crypto/DerivedKeyConfigTest.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include <google/gtest/gtest.h>
|
||||
#include "../../../src/config/crypto/DerivedKeyConfig.h"
|
||||
#include <messmer/cpp-utils/data/DataFixture.h>
|
||||
|
||||
using namespace cryfs;
|
||||
using cpputils::DataFixture;
|
||||
using cpputils::Data;
|
||||
|
||||
TEST(DerivedKeyConfigTest, Salt) {
|
||||
DerivedKeyConfig cfg(DataFixture::generate(32), 0, 0, 0);
|
||||
EXPECT_EQ(DataFixture::generate(32), cfg.salt());
|
||||
}
|
||||
|
||||
TEST(DerivedKeyConfigTest, Salt_Move) {
|
||||
DerivedKeyConfig cfg(DataFixture::generate(32), 0, 0, 0);
|
||||
DerivedKeyConfig moved = std::move(cfg);
|
||||
EXPECT_EQ(DataFixture::generate(32), moved.salt());
|
||||
}
|
||||
|
||||
TEST(DerivedKeyConfigTest, N) {
|
||||
DerivedKeyConfig cfg(Data(0), 1024, 0, 0);
|
||||
EXPECT_EQ(1024, cfg.N());
|
||||
}
|
||||
|
||||
TEST(DerivedKeyConfigTest, N_Move) {
|
||||
DerivedKeyConfig cfg(Data(0), 1024, 0, 0);
|
||||
DerivedKeyConfig moved = std::move(cfg);
|
||||
EXPECT_EQ(1024, moved.N());
|
||||
}
|
||||
|
||||
TEST(DerivedKeyConfigTest, r) {
|
||||
DerivedKeyConfig cfg(Data(0), 0, 8, 0);
|
||||
EXPECT_EQ(8, cfg.r());
|
||||
}
|
||||
|
||||
TEST(DerivedKeyConfigTest, r_Move) {
|
||||
DerivedKeyConfig cfg(Data(0), 0, 8, 0);
|
||||
DerivedKeyConfig moved = std::move(cfg);
|
||||
EXPECT_EQ(8, moved.r());
|
||||
}
|
||||
|
||||
TEST(DerivedKeyConfigTest, p) {
|
||||
DerivedKeyConfig cfg(Data(0), 0, 0, 16);
|
||||
EXPECT_EQ(16, cfg.p());
|
||||
}
|
||||
|
||||
TEST(DerivedKeyConfigTest, p_Move) {
|
||||
DerivedKeyConfig cfg(Data(0), 0, 0, 16);
|
||||
DerivedKeyConfig moved = std::move(cfg);
|
||||
EXPECT_EQ(16, moved.p());
|
||||
}
|
20
test/config/crypto/DerivedKeyTest.cpp
Normal file
20
test/config/crypto/DerivedKeyTest.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include <google/gtest/gtest.h>
|
||||
#include "../../../src/config/crypto/DerivedKey.h"
|
||||
#include <messmer/cpp-utils/data/DataFixture.h>
|
||||
|
||||
using namespace cryfs;
|
||||
using cpputils::DataFixture;
|
||||
using cpputils::Data;
|
||||
|
||||
TEST(DerivedKeyTest, Config) {
|
||||
DerivedKey<32> key(DerivedKeyConfig(DataFixture::generate(32, 1), 1024, 8, 16), DataFixture::generateFixedSize<32>(2));
|
||||
EXPECT_EQ(DataFixture::generate(32, 1), key.config().salt());
|
||||
EXPECT_EQ(1024, key.config().N());
|
||||
EXPECT_EQ(8, key.config().r());
|
||||
EXPECT_EQ(16, key.config().p());
|
||||
}
|
||||
|
||||
TEST(DerivedKeyTest, Key) {
|
||||
DerivedKey<32> key(DerivedKeyConfig(DataFixture::generate(32, 1), 1024, 8, 16), DataFixture::generateFixedSize<32>(2));
|
||||
EXPECT_EQ(DataFixture::generateFixedSize<32>(2), key.key());
|
||||
}
|
36
test/config/crypto/SCryptTest.cpp
Normal file
36
test/config/crypto/SCryptTest.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include <google/gtest/gtest.h>
|
||||
#include "../../../src/config/crypto/Scrypt.h"
|
||||
|
||||
using namespace cryfs;
|
||||
|
||||
TEST(SCryptTest, GeneratedKeyIsReproductible_448) {
|
||||
auto created = SCrypt().generateKey<56>("mypassword");
|
||||
auto recreated = SCrypt().generateKeyFromConfig<56>("mypassword", created.config());
|
||||
EXPECT_EQ(created.key(), recreated);
|
||||
}
|
||||
|
||||
TEST(SCryptTest, GeneratedKeyIsReproductible_256) {
|
||||
auto created = SCrypt().generateKey<32>("mypassword");
|
||||
auto recreated = SCrypt().generateKeyFromConfig<32>("mypassword", created.config());
|
||||
EXPECT_EQ(created.key(), recreated);
|
||||
}
|
||||
|
||||
TEST(SCryptTest, GeneratedKeyIsReproductible_128) {
|
||||
auto created = SCrypt().generateKey<16>("mypassword");
|
||||
auto recreated = SCrypt().generateKeyFromConfig<16>("mypassword", created.config());
|
||||
EXPECT_EQ(created.key(), recreated);
|
||||
}
|
||||
|
||||
TEST(SCryptTest, DifferentPasswordResultsInDifferentKey) {
|
||||
auto created = SCrypt().generateKey<16>("mypassword");
|
||||
auto recreated = SCrypt().generateKeyFromConfig<16>("mypassword2", created.config());
|
||||
EXPECT_NE(created.key(), recreated);
|
||||
}
|
||||
|
||||
TEST(SCryptTest, UsesCorrectDefaultParameters) {
|
||||
auto created = SCrypt().generateKey<16>("mypassword");
|
||||
EXPECT_EQ(SCrypt::SALT_LEN, created.config().salt().size());
|
||||
EXPECT_EQ(SCrypt::N, created.config().N());
|
||||
EXPECT_EQ(SCrypt::r, created.config().r());
|
||||
EXPECT_EQ(SCrypt::p, created.config().p());
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user