Skip to content

Commit ed8cfad

Browse files
authored
feat: add constant_time_equal alias
2 parents 748b0f8 + e8a54e7 commit ed8cfad

3 files changed

Lines changed: 30 additions & 6 deletions

File tree

README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,21 +282,25 @@ The example is in `example.cpp` and is built automatically when `BUILD_EXAMPLE=O
282282
```cpp
283283
#include <iostream>
284284
#include <hmac_cpp/hmac.hpp>
285+
#include <hmac_cpp/hmac_utils.hpp>
285286

286287
int main() {
287288
std::string input = "grape";
288289
std::string key = "12345";
289290

290-
std::string hmac_sha256 = hmac::get_hmac(key, input, hmac::TypeHash::SHA256);
291-
std::cout << "HMAC-SHA256: " << hmac_sha256 << std::endl;
292-
293-
std::string hmac_sha512 = hmac::get_hmac(key, input, hmac::TypeHash::SHA512);
294-
std::cout << "HMAC-SHA512: " << hmac_sha512 << std::endl;
291+
std::string mac = hmac::get_hmac(key, input, hmac::TypeHash::SHA256);
292+
if (hmac::constant_time_equal(mac,
293+
"7632ac2e8ddedaf4b3e7ab195fefd17571c37c970e02e169195a158ef59e53ca")) {
294+
std::cout << "MAC verified\n";
295+
}
295296

296297
return 0;
297298
}
298299
```
299300

301+
**Note:** avoid checking input lengths before calling `constant_time_equal`.
302+
Early length comparisons can leak information through timing side channels.
303+
300304
## 📚 Resources
301305

302306
* Original [SHA256 implementation](http://www.zedwood.com/article/cpp-sha256-function)

example.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ int main() {
3939
print_section("HMAC-SHA256");
4040
std::string hmac_sha256 = hmac::get_hmac(key, input, hmac::TypeHash::SHA256, true);
4141
std::cout << "HMAC('" << key << "', '" << input << "', SHA256) = " << hmac_sha256 << std::endl;
42-
std::cout << "Expected: 7632ac2e8ddedaf4b3e7ab195fefd17571c37c970e02e169195a158ef59e53ca\n\n";
42+
std::string expected_hmac_sha256 =
43+
"7632ac2e8ddedaf4b3e7ab195fefd17571c37c970e02e169195a158ef59e53ca";
44+
bool mac_valid = hmac::constant_time_equal(hmac_sha256, expected_hmac_sha256);
45+
std::cout << "MAC valid? = " << (mac_valid ? "YES" : "NO") << "\n\n";
4346

4447
// HMAC-SHA512
4548
print_section("HMAC-SHA512");

include/hmac_cpp/hmac_utils.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,23 @@ namespace hmac_cpp {
2828
reinterpret_cast<const uint8_t*>(b.data()), b.size());
2929
}
3030

31+
/// \brief Alias for constant_time_equals.
32+
/// Avoids early length checks to mitigate timing attacks.
33+
inline bool constant_time_equal(const uint8_t* a, size_t a_len,
34+
const uint8_t* b, size_t b_len) {
35+
return constant_time_equals(a, a_len, b, b_len);
36+
}
37+
38+
inline bool constant_time_equal(const std::vector<uint8_t>& a,
39+
const std::vector<uint8_t>& b) {
40+
return constant_time_equal(a.data(), a.size(), b.data(), b.size());
41+
}
42+
43+
inline bool constant_time_equal(const std::string& a, const std::string& b) {
44+
return constant_time_equal(reinterpret_cast<const uint8_t*>(a.data()), a.size(),
45+
reinterpret_cast<const uint8_t*>(b.data()), b.size());
46+
}
47+
3148
/// \brief Hash choices for PBKDF2
3249
enum class Pbkdf2Hash { Sha1, Sha256, Sha512 };
3350

0 commit comments

Comments
 (0)