Skip to content

Commit d416ceb

Browse files
authored
feat(utils): harden constant-time comparison
Ensure comparison covers full input length and add tests for matching and mismatching cases.
1 parent 8b99d2a commit d416ceb

2 files changed

Lines changed: 15 additions & 4 deletions

File tree

hmac_utils.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
namespace hmac {
77

88
bool constant_time_equals(const std::string &a, const std::string &b) {
9-
if (a.size() != b.size()) return false;
10-
unsigned char diff = 0;
11-
for (size_t i = 0; i < a.size(); ++i) {
12-
diff |= static_cast<unsigned char>(a[i]) ^ static_cast<unsigned char>(b[i]);
9+
size_t max_len = a.size() > b.size() ? a.size() : b.size();
10+
unsigned char diff = static_cast<unsigned char>(a.size() ^ b.size());
11+
for (size_t i = 0; i < max_len; ++i) {
12+
unsigned char ac = i < a.size() ? static_cast<unsigned char>(a[i]) : 0;
13+
unsigned char bc = i < b.size() ? static_cast<unsigned char>(b[i]) : 0;
14+
diff |= ac ^ bc;
1315
}
1416
return diff == 0;
1517
}

test_all.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ TEST(UtilsTest, ToHex) {
4949
EXPECT_EQ(hmac::to_hex("012345"), "303132333435");
5050
}
5151

52+
TEST(UtilsTest, ConstantTimeEqualsMatch) {
53+
EXPECT_TRUE(hmac::constant_time_equals("alpha", "alpha"));
54+
}
55+
56+
TEST(UtilsTest, ConstantTimeEqualsMismatch) {
57+
EXPECT_FALSE(hmac::constant_time_equals("alpha", "beta"));
58+
EXPECT_FALSE(hmac::constant_time_equals("alpha", "alphabet"));
59+
}
60+
5261
TEST(HMACTest, SHA256) {
5362
const std::string key = "12345";
5463
const std::string input = "grape";

0 commit comments

Comments
 (0)