From e8a54e744b9d2ceb1f4aa7c618d7f7f04d0404b4 Mon Sep 17 00:00:00 2001 From: Aster Seker Date: Fri, 5 Sep 2025 23:31:32 +0300 Subject: [PATCH] feat(utils): add constant_time_equal alias Expose constant_time_equal as alias and document MAC verification. --- README.md | 14 +++++++++----- example.cpp | 5 ++++- include/hmac_cpp/hmac_utils.hpp | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9dee38a..66d3751 100644 --- a/README.md +++ b/README.md @@ -265,21 +265,25 @@ The example is in `example.cpp` and is built automatically when `BUILD_EXAMPLE=O ```cpp #include #include +#include int main() { std::string input = "grape"; std::string key = "12345"; - std::string hmac_sha256 = hmac::get_hmac(key, input, hmac::TypeHash::SHA256); - std::cout << "HMAC-SHA256: " << hmac_sha256 << std::endl; - - std::string hmac_sha512 = hmac::get_hmac(key, input, hmac::TypeHash::SHA512); - std::cout << "HMAC-SHA512: " << hmac_sha512 << std::endl; + std::string mac = hmac::get_hmac(key, input, hmac::TypeHash::SHA256); + if (hmac::constant_time_equal(mac, + "7632ac2e8ddedaf4b3e7ab195fefd17571c37c970e02e169195a158ef59e53ca")) { + std::cout << "MAC verified\n"; + } return 0; } ``` +**Note:** avoid checking input lengths before calling `constant_time_equal`. +Early length comparisons can leak information through timing side channels. + ## 📚 Resources * Original [SHA256 implementation](http://www.zedwood.com/article/cpp-sha256-function) diff --git a/example.cpp b/example.cpp index 78891e2..7fd336f 100644 --- a/example.cpp +++ b/example.cpp @@ -39,7 +39,10 @@ int main() { print_section("HMAC-SHA256"); std::string hmac_sha256 = hmac::get_hmac(key, input, hmac::TypeHash::SHA256, true); std::cout << "HMAC('" << key << "', '" << input << "', SHA256) = " << hmac_sha256 << std::endl; - std::cout << "Expected: 7632ac2e8ddedaf4b3e7ab195fefd17571c37c970e02e169195a158ef59e53ca\n\n"; + std::string expected_hmac_sha256 = + "7632ac2e8ddedaf4b3e7ab195fefd17571c37c970e02e169195a158ef59e53ca"; + bool mac_valid = hmac::constant_time_equal(hmac_sha256, expected_hmac_sha256); + std::cout << "MAC valid? = " << (mac_valid ? "YES" : "NO") << "\n\n"; // HMAC-SHA512 print_section("HMAC-SHA512"); diff --git a/include/hmac_cpp/hmac_utils.hpp b/include/hmac_cpp/hmac_utils.hpp index 1539904..5fcb7de 100644 --- a/include/hmac_cpp/hmac_utils.hpp +++ b/include/hmac_cpp/hmac_utils.hpp @@ -27,6 +27,23 @@ namespace hmac_cpp { reinterpret_cast(b.data()), b.size()); } + /// \brief Alias for constant_time_equals. + /// Avoids early length checks to mitigate timing attacks. + inline bool constant_time_equal(const uint8_t* a, size_t a_len, + const uint8_t* b, size_t b_len) { + return constant_time_equals(a, a_len, b, b_len); + } + + inline bool constant_time_equal(const std::vector& a, + const std::vector& b) { + return constant_time_equal(a.data(), a.size(), b.data(), b.size()); + } + + inline bool constant_time_equal(const std::string& a, const std::string& b) { + return constant_time_equal(reinterpret_cast(a.data()), a.size(), + reinterpret_cast(b.data()), b.size()); + } + /// \brief Hash choices for PBKDF2 enum class Pbkdf2Hash { Sha1, Sha256, Sha512 };