Skip to content

Commit

Permalink
crypto: add aesGetKey, aesGetSalt, aesGetEncrypted
Browse files Browse the repository at this point in the history
Allows to retrieve the encryption key and salt from
an encrypted blob, leading the way for biometry support.
  • Loading branch information
Adrien Béraud authored and aberaud committed Nov 28, 2023
1 parent 95fdadf commit 24e7b00
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
30 changes: 26 additions & 4 deletions include/opendht/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ OPENDHT_PUBLIC void hash(const uint8_t* data, size_t data_length, uint8_t* hash,
* that can be transmitted in clear, and will be generated if
* not provided (32 bytes).
*/
OPENDHT_PUBLIC Blob stretchKey(const std::string& password, Blob& salt, size_t key_length = 512/8);
OPENDHT_PUBLIC Blob stretchKey(std::string_view 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).
Expand All @@ -802,15 +802,37 @@ OPENDHT_PUBLIC Blob aesEncrypt(const uint8_t* data, size_t data_length, const Bl
OPENDHT_PUBLIC inline Blob aesEncrypt(const Blob& data, const Blob& key) {
return aesEncrypt(data.data(), data.size(), key);
}
OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, const std::string& password);
OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, std::string_view password);

/**
* AES-GCM decryption.
*/
OPENDHT_PUBLIC Blob aesDecrypt(const uint8_t* data, size_t data_length, const Blob& key);
OPENDHT_PUBLIC inline Blob aesDecrypt(const Blob& data, const Blob& key) { return aesDecrypt(data.data(), data.size(), key); }
OPENDHT_PUBLIC Blob aesDecrypt(const uint8_t* data, size_t data_length, const std::string& password);
OPENDHT_PUBLIC inline Blob aesDecrypt(const Blob& data, const std::string& password) { return aesDecrypt(data.data(), data.size(), password); }
OPENDHT_PUBLIC inline Blob aesDecrypt(std::string_view data, const Blob& key) { return aesDecrypt((uint8_t*)data.data(), data.size(), key); }

OPENDHT_PUBLIC Blob aesDecrypt(const uint8_t* data, size_t data_length, std::string_view password);
OPENDHT_PUBLIC inline Blob aesDecrypt(const Blob& data, std::string_view password) { return aesDecrypt(data.data(), data.size(), password); }
OPENDHT_PUBLIC inline Blob aesDecrypt(std::string_view data, std::string_view password) { return aesDecrypt((uint8_t*)data.data(), data.size(), password); }

/**
* Get raw AES key from password and salt stored with the encrypted data.
*/
OPENDHT_PUBLIC Blob aesGetKey(const uint8_t* data, size_t data_length, std::string_view password);
OPENDHT_PUBLIC Blob inline aesGetKey(const Blob& data, std::string_view password) {
return aesGetKey(data.data(), data.size(), password);
}
/** Get the salt part of data password-encrypted with `aesEncrypt(data, password)` */
OPENDHT_PUBLIC Blob aesGetSalt(const uint8_t* data, size_t data_length);
OPENDHT_PUBLIC Blob inline aesGetSalt(const Blob& data) {
return aesGetSalt(data.data(), data.size());
}
/** Get the salt part of data password-encrypted with `aesEncrypt(data, password)` */
OPENDHT_PUBLIC std::string_view aesGetEncrypted(const uint8_t* data, size_t data_length);
OPENDHT_PUBLIC std::string_view inline aesGetEncrypted(const Blob& data) {
return aesGetEncrypted(data.data(), data.size());
}


}
}
33 changes: 26 additions & 7 deletions src/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Blob aesEncrypt(const uint8_t* data, size_t data_length, const Blob& key)
return ret;
}

Blob aesEncrypt(const Blob& data, const std::string& password)
Blob aesEncrypt(const Blob& data, std::string_view password)
{
Blob salt;
Blob key = stretchKey(password, salt, 256 / 8);
Expand Down Expand Up @@ -152,16 +152,35 @@ Blob aesDecrypt(const uint8_t* data, size_t data_length, const Blob& key)
return ret;
}

Blob aesDecrypt(const uint8_t* data, size_t data_len, const std::string& password)
Blob aesDecrypt(const uint8_t* data, size_t data_length, std::string_view password)
{
if (data_len <= PASSWORD_SALT_LENGTH)
return aesDecrypt(
aesGetEncrypted(data, data_length),
aesGetKey(data, data_length, password)
);
}

Blob aesGetSalt(const uint8_t* data, size_t data_length)
{
if (data_length <= PASSWORD_SALT_LENGTH)
throw DecryptError("Wrong data size");
return Blob {data, data+PASSWORD_SALT_LENGTH};
}

std::string_view aesGetEncrypted(const uint8_t* data, size_t data_length)
{
if (data_length <= PASSWORD_SALT_LENGTH)
throw DecryptError("Wrong data size");
Blob salt {data, data+PASSWORD_SALT_LENGTH};
Blob key = stretchKey(password, salt, 256/8);
return aesDecrypt(data+PASSWORD_SALT_LENGTH, data_len - PASSWORD_SALT_LENGTH, key);
return std::string_view((const char*)(data+PASSWORD_SALT_LENGTH), data_length - PASSWORD_SALT_LENGTH);
}

Blob aesGetKey(const uint8_t* data, size_t data_length, std::string_view password)
{
Blob salt = aesGetSalt(data, data_length);
return stretchKey(password, salt, 256/8);
}

Blob stretchKey(const std::string& password, Blob& salt, size_t key_length)
Blob stretchKey(std::string_view password, Blob& salt, size_t key_length)
{
if (salt.empty()) {
salt.resize(PASSWORD_SALT_LENGTH);
Expand Down

0 comments on commit 24e7b00

Please sign in to comment.