Skip to content

Commit e3d7835

Browse files
committed
crypto: add HMAC to crypto.timingSafeEqual()
Add HMAC to crypto.timingSafeEqual(). This makes things slower but also makes them far more timing safe. Refs: #38226 (comment) Fixes: #38226
1 parent ca0044b commit e3d7835

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

src/crypto/crypto_timing.cc

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "node.h"
77

88
#include <openssl/crypto.h>
9+
#include <openssl/hmac.h>
10+
#include <openssl/sha.h>
911

1012
namespace node {
1113

@@ -42,8 +44,47 @@ void TimingSafeEqual(const FunctionCallbackInfo<Value>& args) {
4244
return;
4345
}
4446

47+
uint16_t bufKey[8];
48+
CHECK(crypto::EntropySource(reinterpret_cast<unsigned char*>(bufKey),
49+
sizeof(bufKey)));
50+
char key[kKeySize];
51+
snprintf(key,
52+
sizeof(key),
53+
"%04x%04x%04x%04x%04x%04x%04x%04x",
54+
bufKey[0],
55+
bufKey[1],
56+
bufKey[2],
57+
bufKey[3],
58+
bufKey[4],
59+
bufKey[5],
60+
bufKey[6],
61+
bufKey[7]);
62+
63+
std::array<unsigned char, EVP_MAX_MD_SIZE> hash1;
64+
std::array<unsigned char, EVP_MAX_MD_SIZE> hash2;
65+
unsigned int hash1Len;
66+
unsigned int hash2Len;
67+
68+
HMAC(EVP_sha256(),
69+
key,
70+
kKeySize,
71+
reinterpret_cast<unsigned char const*>(buf1.data()),
72+
static_cast<int>(buf1.size()),
73+
hash1.data(),
74+
&hash1Len);
75+
76+
HMAC(EVP_sha256(),
77+
key,
78+
kKeySize,
79+
reinterpret_cast<unsigned char const*>(buf2.data()),
80+
static_cast<int>(buf2.size()),
81+
hash2.data(),
82+
&hash2Len);
83+
84+
assert(hash1Len == hash2Len);
85+
4586
return args.GetReturnValue().Set(
46-
CRYPTO_memcmp(buf1.data(), buf2.data(), buf1.size()) == 0);
87+
CRYPTO_memcmp(hash1.data(), hash2.data(), hash1Len) == 0);
4788
}
4889

4990
void Initialize(Environment* env, Local<Object> target) {

src/crypto/crypto_timing.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ namespace crypto {
1111
namespace Timing {
1212
void Initialize(Environment* env, v8::Local<v8::Object> target);
1313
void RegisterExternalReferences(ExternalReferenceRegistry* registry);
14+
15+
static const int kKeySize = 256;
16+
1417
} // namespace Timing
1518
} // namespace crypto
1619
} // namespace node

0 commit comments

Comments
 (0)