2015-10-27 22:19:06 +01:00
|
|
|
#pragma once
|
|
|
|
#ifndef MESSMER_CPPUTILS_CRYPTO_KDF_SCRYPT_H
|
|
|
|
#define MESSMER_CPPUTILS_CRYPTO_KDF_SCRYPT_H
|
|
|
|
|
|
|
|
#include "../../macros.h"
|
|
|
|
#include "../../random/Random.h"
|
|
|
|
extern "C" {
|
|
|
|
#include <messmer/scrypt/lib/crypto/crypto_scrypt.h>
|
|
|
|
}
|
|
|
|
#include <stdexcept>
|
|
|
|
#include "DerivedKey.h"
|
|
|
|
|
|
|
|
namespace cpputils {
|
|
|
|
|
2015-11-04 05:13:23 +01:00
|
|
|
struct SCryptSettings {
|
|
|
|
size_t SALT_LEN;
|
|
|
|
uint64_t N;
|
|
|
|
uint32_t r;
|
|
|
|
uint32_t p;
|
2015-10-27 22:19:06 +01:00
|
|
|
};
|
|
|
|
|
2015-11-04 05:13:23 +01:00
|
|
|
class SCrypt final {
|
2015-10-27 22:19:06 +01:00
|
|
|
public:
|
2015-11-04 05:13:23 +01:00
|
|
|
static constexpr SCryptSettings ParanoidSettings = SCryptSettings {32, 1048576, 8, 16};
|
|
|
|
static constexpr SCryptSettings DefaultSettings = SCryptSettings {32, 524288, 1, 1};
|
|
|
|
static constexpr SCryptSettings TestSettings = SCryptSettings {32, 1024, 1, 1};
|
|
|
|
|
2015-10-27 22:19:06 +01:00
|
|
|
SCrypt() {}
|
|
|
|
|
2015-11-04 05:13:23 +01:00
|
|
|
template<size_t KEYSIZE>
|
|
|
|
DerivedKey<KEYSIZE> generateKey(const std::string &password, const SCryptSettings &settings) {
|
|
|
|
auto salt = Random::PseudoRandom().get(settings.SALT_LEN);
|
|
|
|
auto config = DerivedKeyConfig(std::move(salt), settings.N, settings.r, settings.p);
|
2015-10-27 22:19:06 +01:00
|
|
|
auto key = generateKeyFromConfig<KEYSIZE>(password, config);
|
|
|
|
return DerivedKey<KEYSIZE>(std::move(config), key);
|
|
|
|
}
|
|
|
|
|
2015-11-04 05:13:23 +01:00
|
|
|
template<size_t KEYSIZE>
|
|
|
|
FixedSizeData<KEYSIZE> generateKeyFromConfig(const std::string &password, const DerivedKeyConfig &config) {
|
2015-10-27 22:19:06 +01:00
|
|
|
auto key = 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
|