Skip to content

Commit

Permalink
wip: add HMAC to crypto.timingSafeEqual()
Browse files Browse the repository at this point in the history
  • Loading branch information
Trott committed Apr 30, 2021
1 parent 746cc88 commit 8e9466e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
42 changes: 41 additions & 1 deletion src/crypto/crypto_timing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "node.h"

#include <openssl/crypto.h>
#include <openssl/hmac.h>
#include <openssl/sha.h>

namespace node {

Expand Down Expand Up @@ -42,8 +44,46 @@ void TimingSafeEqual(const FunctionCallbackInfo<Value>& args) {
return;
}

uint16_t bufKey[8];
CHECK(crypto::EntropySource(reinterpret_cast<unsigned char*>(bufKey),
sizeof(bufKey)));
int keySize = 256;
char key[keySize];
snprintf(key, sizeof(key), "%04x%04x%04x%04x%04x%04x%04x%04x",
bufKey[0],
bufKey[1],
bufKey[2],
bufKey[3],
bufKey[4],
bufKey[5],
bufKey[6],
bufKey[7]);

std::array<unsigned char, EVP_MAX_MD_SIZE> hash1;
std::array<unsigned char, EVP_MAX_MD_SIZE> hash2;
unsigned int hash1Len;
unsigned int hash2Len;

HMAC(EVP_sha256(),
key,
keySize,
reinterpret_cast<unsigned char const*>(buf1.data()),
static_cast<int>(buf1.size()),
hash1.data(),
&hash1Len);

HMAC(EVP_sha256(),
key,
keySize,
reinterpret_cast<unsigned char const*>(buf2.data()),
static_cast<int>(buf2.size()),
hash2.data(),
&hash2Len);

assert(hash1Len == hash2Len);

return args.GetReturnValue().Set(
CRYPTO_memcmp(buf1.data(), buf2.data(), buf1.size()) == 0);
CRYPTO_memcmp(hash1.data(), hash2.data(), hash1Len) == 0);
}

void Initialize(Environment* env, Local<Object> target) {
Expand Down
2 changes: 1 addition & 1 deletion test/pummel/test-crypto-timing-safe-equal-benchmarks.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ assert(
`timingSafeEqual should not leak information from its execution time (t=${t})`
);

// As a sanity check to make sure the statistical tests are working, run the
// As a coherence check to make sure the statistical tests are working, run the
// same benchmarks again, this time with an unsafe comparison function. In this
// case the t-value should be above the threshold.
const unsafeCompare = (bufA, bufB) => bufA.equals(bufB);
Expand Down

0 comments on commit 8e9466e

Please sign in to comment.