diff --git a/include/opendht/crypto.h b/include/opendht/crypto.h index 1033c04d99909885f1f225f2594f4597241d7727..1f14771f2b2166ad7f2792cc8e48fabf76a6650b 100644 --- a/include/opendht/crypto.h +++ b/include/opendht/crypto.h @@ -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). @@ -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()); +} + } } diff --git a/src/crypto.cpp b/src/crypto.cpp index 578003e2882f0ecb38f3fa5ab0385cda6def9138..49cbc9dea3fa237bde521a591ccefd8b03b55d6b 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -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); @@ -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);