Skip to content

Commit c46719c

Browse files
authored
feat(pbkdf2): add result struct overload
2 parents 23ba6bf + d405fc4 commit c46719c

3 files changed

Lines changed: 53 additions & 1 deletion

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ Returns: Binary digest as `std::vector<uint8_t>`
190190
std::string password = "password";
191191
std::vector<uint8_t> salt(16, 0x01); // at least 16 bytes
192192
std::vector<uint8_t> dk = hmac::pbkdf2(password, salt, 1000, 32);
193+
hmac::Pbkdf2Result stored{salt, 1000, dk};
194+
auto verify = hmac::pbkdf2(password, stored);
195+
bool ok = hmac::constant_time_equals(verify.key, stored.key);
193196
```
194197
195198
Parameters:

include/hmac_cpp/hmac_utils.hpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,21 @@ namespace hmac_cpp {
5353

5454
/// \brief Hash choices for PBKDF2
5555
enum class Pbkdf2Hash { Sha1, Sha256, Sha512 };
56-
56+
5757
/// PBKDF2 Security Notes:
5858
/// - Use a random salt of at least 16 bytes and never reuse it.
5959
/// - Choose iterations so the derivation takes about 200–500 ms on 2025 hardware.
6060
/// - Store {salt, iterations} with the ciphertext or hash; these values are public.
6161
/// - Salts and iteration counts must be unique per password.
6262
/// - Example serialization: {magic|ver|prf|salt|iters|dkLen|…}.
6363

64+
/// \brief
65+
struct Pbkdf2Result {
66+
std::vector<uint8_t> salt;
67+
uint32_t iters;
68+
std::vector<uint8_t> key;
69+
};
70+
6471
/// \brief Derives a key from a password using PBKDF2 (RFC 8018)
6572
/// \param password_ptr Pointer to the password buffer
6673
/// \param password_len Length of the password in bytes
@@ -113,6 +120,39 @@ namespace hmac_cpp {
113120
iterations, dk_len, prf);
114121
}
115122

123+
template<typename T>
124+
inline Pbkdf2Result pbkdf2(
125+
const std::vector<T>& password,
126+
const Pbkdf2Result& params,
127+
Pbkdf2Hash prf = Pbkdf2Hash::Sha256) {
128+
static_assert(std::is_same<T, char>::value || std::is_same<T, uint8_t>::value,
129+
"pbkdf2(vector<T>) supports only char or uint8_t");
130+
auto key = pbkdf2(password.data(), password.size(),
131+
params.salt.data(), params.salt.size(),
132+
params.iters, params.key.size(), prf);
133+
return {params.salt, params.iters, std::move(key)};
134+
}
135+
136+
inline Pbkdf2Result pbkdf2(
137+
const std::string& password,
138+
const Pbkdf2Result& params,
139+
Pbkdf2Hash prf = Pbkdf2Hash::Sha256) {
140+
auto key = pbkdf2(password.data(), password.size(),
141+
params.salt.data(), params.salt.size(),
142+
params.iters, params.key.size(), prf);
143+
return {params.salt, params.iters, std::move(key)};
144+
}
145+
146+
inline Pbkdf2Result pbkdf2(
147+
const secure_buffer<uint8_t>& password,
148+
const Pbkdf2Result& params,
149+
Pbkdf2Hash prf = Pbkdf2Hash::Sha256) {
150+
auto key = pbkdf2(password.data(), password.size(),
151+
params.salt.data(), params.salt.size(),
152+
params.iters, params.key.size(), prf);
153+
return {params.salt, params.iters, std::move(key)};
154+
}
155+
116156
/// \brief Derives PBKDF2 into caller-provided buffer using selected hash.
117157
/// \param prf Hash function to use (SHA1, SHA256, SHA512)
118158
/// \param password_ptr Pointer to the password buffer

test_all.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,15 @@ TEST(PBKDF2Test, SHA256WithValidSalt) {
361361
EXPECT_TRUE(hmac::constant_time_equals(dk, ref));
362362
}
363363

364+
TEST(PBKDF2ResultTest, ComputesFromStoredParams) {
365+
auto salt = from_hex("000102030405060708090a0b0c0d0e0f");
366+
std::string salt_str(salt.begin(), salt.end());
367+
auto dk = hmac::pbkdf2(std::string("password"), salt_str, 2, 32, hmac::Pbkdf2Hash::Sha256);
368+
hmac::Pbkdf2Result stored{salt, 2, dk};
369+
auto out = hmac::pbkdf2(std::string("password"), stored);
370+
EXPECT_TRUE(hmac::constant_time_equals(out.key, stored.key));
371+
}
372+
364373
TEST(PBKDF2BufferApiTest, SHA256ArrayOutput) {
365374
auto salt = from_hex("000102030405060708090a0b0c0d0e0f");
366375
std::string salt_str(salt.begin(), salt.end());

0 commit comments

Comments
 (0)