diff --git a/include/hmac_cpp/hmac_utils.hpp b/include/hmac_cpp/hmac_utils.hpp index 213befa..9186070 100644 --- a/include/hmac_cpp/hmac_utils.hpp +++ b/include/hmac_cpp/hmac_utils.hpp @@ -110,6 +110,21 @@ namespace hmac_cpp { uint32_t iterations, size_t dk_len, Pbkdf2Hash prf = Pbkdf2Hash::Sha256); + /// \brief Derives a key into a page-locked secure buffer using PBKDF2 + /// \param password_ptr Pointer to the password buffer + /// \param password_len Length of the password in bytes + /// \param salt_ptr Pointer to the salt buffer + /// \param salt_len Length of the salt in bytes + /// \param iterations Number of iterations, must be positive + /// \param dk_len Desired length of the derived key in bytes, must be positive + /// \param prf Hash function to use (SHA1, SHA256, SHA512) + /// \return Derived key as a page-locked secure buffer + HMAC_CPP_API secure_buffer pbkdf2_secure( + const void* password_ptr, size_t password_len, + const void* salt_ptr, size_t salt_len, + uint32_t iterations, size_t dk_len, + Pbkdf2Hash prf = Pbkdf2Hash::Sha256); + /// \brief Derive key using PBKDF2 from vector-based password and salt. /// \tparam T Byte type; must be char or uint8_t. /// \param password Password bytes. diff --git a/src/hmac_utils.cpp b/src/hmac_utils.cpp index 7891bb1..9b2083f 100644 --- a/src/hmac_utils.cpp +++ b/src/hmac_utils.cpp @@ -102,13 +102,13 @@ namespace hmac_cpp { salt_block[salt_len + 2] = static_cast((i >> 8) & 0xFF); salt_block[salt_len + 3] = static_cast(i & 0xFF); - secure_buffer u(std::move(get_hmac(password_ptr, password_len, - salt_block.data(), salt_block.size(), - hash_type))); - secure_buffer t = u; + secure_buffer u(std::move(get_hmac(password_ptr, password_len, + salt_block.data(), salt_block.size(), + hash_type))); + secure_buffer t = u; for (uint32_t j = 1; j < iterations; ++j) { - u = secure_buffer(get_hmac(password_ptr, password_len, - u.data(), u.size(), hash_type)); + u = secure_buffer(get_hmac(password_ptr, password_len, + u.data(), u.size(), hash_type)); for (size_t k = 0; k < t.size(); ++k) { t[k] ^= u[k]; } @@ -125,6 +125,20 @@ namespace hmac_cpp { return derived; } + secure_buffer pbkdf2_secure( + const void* password_ptr, size_t password_len, + const void* salt_ptr, size_t salt_len, + uint32_t iterations, size_t dk_len, + Pbkdf2Hash prf) { + auto derived = pbkdf2(password_ptr, password_len, + salt_ptr, salt_len, + iterations, dk_len, prf); + PageLockGuard lock(derived.data(), derived.size()); + secure_buffer out(std::move(derived)); + lock.locked = false; + return out; + } + bool pbkdf2(Pbkdf2Hash prf, const void* password_ptr, size_t password_len, const void* salt_ptr, size_t salt_len, @@ -175,8 +189,8 @@ namespace hmac_cpp { salt_block[salt_len + 2] = static_cast((i >> 8) & 0xFF); salt_block[salt_len + 3] = static_cast(i & 0xFF); - secure_buffer u(hlen); - secure_buffer t(hlen); + secure_buffer u(hlen); + secure_buffer t(hlen); HmacContext ctx(hash_type); ctx.init(password_ptr, password_len); ctx.update(salt_block.data(), salt_block.size()); @@ -221,7 +235,7 @@ namespace hmac_cpp { Pbkdf2Hash prf) { TypeHash hash_type = to_type_hash(prf); auto pwd_prime = get_hmac(pepper_ptr, pepper_len, password_ptr, password_len, hash_type); - secure_buffer tmp(std::move(pwd_prime)); + secure_buffer tmp(std::move(pwd_prime)); auto dk = pbkdf2(tmp.data(), tmp.size(), salt_ptr, salt_len, iterations, dk_len, prf); secure_zero(tmp.data(), tmp.size()); return dk;