Skip to content
Snippets Groups Projects
Commit 047ba76f authored by Adrien Béraud's avatar Adrien Béraud Committed by GitHub
Browse files

Merge pull request #125 from savoirfairelinux/wip/crypto

crypto: add length parameters
parents e5a9a2af e57eb63c
No related branches found
No related tags found
No related merge requests found
...@@ -329,9 +329,14 @@ Identity generateIdentity(const std::string& name = "dhtnode", Identity ca = {}, ...@@ -329,9 +329,14 @@ Identity generateIdentity(const std::string& name = "dhtnode", Identity ca = {},
/** /**
* SHA512 * Performs SHA512, SHA256 or SHA1, depending on hash_length.
* Attempts to choose an hash function with
* output size of at least hash_length bytes, Current implementation
* will use SHA1 for hash_length up to 20 bytes,
* will use SHA256 for hash_length up to 32 bytes,
* will use SHA512 for hash_length of 33 bytes and more.
*/ */
Blob hash(const Blob& data); Blob hash(const Blob& data, size_t hash_length = 512/8);
/** /**
* Generates an encryption key from a text password, * Generates an encryption key from a text password,
...@@ -340,7 +345,7 @@ Blob hash(const Blob& data); ...@@ -340,7 +345,7 @@ Blob hash(const Blob& data);
* that can be transmitted in clear, and will be generated if * that can be transmitted in clear, and will be generated if
* not provided (32 bytes). * not provided (32 bytes).
*/ */
Blob stretchKey(const std::string& password, Blob& salt); Blob stretchKey(const std::string& password, Blob& salt, size_t key_length = 512/8);
/** /**
* AES-GCM encryption. Key must be 128, 192 or 256 bits long (16, 24 or 32 bytes). * AES-GCM encryption. Key must be 128, 192 or 256 bits long (16, 24 or 32 bytes).
......
...@@ -83,6 +83,18 @@ namespace crypto { ...@@ -83,6 +83,18 @@ namespace crypto {
static constexpr std::array<size_t, 3> AES_LENGTHS {{128/8, 192/8, 256/8}}; static constexpr std::array<size_t, 3> AES_LENGTHS {{128/8, 192/8, 256/8}};
static constexpr size_t PASSWORD_SALT_LENGTH {16}; static constexpr size_t PASSWORD_SALT_LENGTH {16};
constexpr gnutls_digest_algorithm_t gnutlsHashAlgo(size_t min_res) {
return (min_res > 256/8) ? GNUTLS_DIG_SHA512 : (
(min_res > 128/8) ? GNUTLS_DIG_SHA256 : (
GNUTLS_DIG_SHA1));
}
constexpr size_t gnutlsHashSize(int algo) {
return (algo == GNUTLS_DIG_SHA512) ? 512/8 : (
(algo == GNUTLS_DIG_SHA256) ? 256/8 : (
(algo == GNUTLS_DIG_SHA1) ? 160/8 : 0 ));
}
size_t aesKeySize(size_t max) size_t aesKeySize(size_t max)
{ {
size_t aes_key_len = 0; size_t aes_key_len = 0;
...@@ -128,8 +140,7 @@ Blob aesEncrypt(const Blob& data, const Blob& key) ...@@ -128,8 +140,7 @@ Blob aesEncrypt(const Blob& data, const Blob& key)
Blob aesEncrypt(const Blob& data, const std::string& password) Blob aesEncrypt(const Blob& data, const std::string& password)
{ {
Blob salt; Blob salt;
Blob key = stretchKey(password, salt); Blob key = stretchKey(password, salt, 256 / 8);
key.resize(256 / 8);
Blob encrypted = aesEncrypt(data, key); Blob encrypted = aesEncrypt(data, key);
encrypted.insert(encrypted.begin(), salt.begin(), salt.end()); encrypted.insert(encrypted.begin(), salt.begin(), salt.end());
return encrypted; return encrypted;
...@@ -175,13 +186,12 @@ Blob aesDecrypt(const Blob& data, const std::string& password) ...@@ -175,13 +186,12 @@ Blob aesDecrypt(const Blob& data, const std::string& password)
if (data.size() <= PASSWORD_SALT_LENGTH) if (data.size() <= PASSWORD_SALT_LENGTH)
throw DecryptError("Wrong data size"); throw DecryptError("Wrong data size");
Blob salt {data.begin(), data.begin()+PASSWORD_SALT_LENGTH}; Blob salt {data.begin(), data.begin()+PASSWORD_SALT_LENGTH};
Blob key = stretchKey(password, salt); Blob key = stretchKey(password, salt, 256/8);
key.resize(256 / 8);
Blob encrypted {data.begin()+PASSWORD_SALT_LENGTH, data.end()}; Blob encrypted {data.begin()+PASSWORD_SALT_LENGTH, data.end()};
return aesDecrypt(encrypted, key); return aesDecrypt(encrypted, key);
} }
Blob stretchKey(const std::string& password, Blob& salt) Blob stretchKey(const std::string& password, Blob& salt, size_t key_length)
{ {
if (salt.empty()) { if (salt.empty()) {
salt.resize(PASSWORD_SALT_LENGTH); salt.resize(PASSWORD_SALT_LENGTH);
...@@ -193,18 +203,19 @@ Blob stretchKey(const std::string& password, Blob& salt) ...@@ -193,18 +203,19 @@ Blob stretchKey(const std::string& password, Blob& salt)
auto ret = argon2i_hash_raw(16, 64*1024, 1, password.data(), password.size(), salt.data(), salt.size(), res.data(), res.size()); auto ret = argon2i_hash_raw(16, 64*1024, 1, password.data(), password.size(), salt.data(), salt.size(), res.data(), res.size());
if (ret != ARGON2_OK) if (ret != ARGON2_OK)
throw CryptoException("Can't compute argon2i !"); throw CryptoException("Can't compute argon2i !");
return hash(res); return hash(res, key_length);
} }
Blob hash(const Blob& data) Blob hash(const Blob& data, size_t hash_len)
{ {
auto algo = gnutlsHashAlgo(hash_len);
size_t res_size = gnutlsHashSize(algo);
Blob res; Blob res;
size_t res_size = 64;
res.resize(res_size); res.resize(res_size);
const gnutls_datum_t gdat {(uint8_t*)data.data(), (unsigned)data.size()}; const gnutls_datum_t gdat {(uint8_t*)data.data(), (unsigned)data.size()};
if (gnutls_fingerprint(GNUTLS_DIG_SHA512, &gdat, res.data(), &res_size)) if (gnutls_fingerprint(algo, &gdat, res.data(), &res_size))
throw CryptoException("Can't compute hash !"); throw CryptoException("Can't compute hash !");
res.resize(res_size); res.resize(std::min(hash_len, res_size));
return res; return res;
} }
......
...@@ -76,8 +76,6 @@ SecureDht::SecureDht(int s, int s6, SecureDht::Config conf) ...@@ -76,8 +76,6 @@ SecureDht::SecureDht(int s, int s6, SecureDht::Config conf)
}, [this](bool ok) { }, [this](bool ok) {
if (ok) if (ok)
DHT_LOG.DEBUG("SecureDht: public key announced successfully"); DHT_LOG.DEBUG("SecureDht: public key announced successfully");
else
DHT_LOG.ERR("SecureDht: error while announcing public key!");
}, {}, true); }, {}, true);
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment