From 8e9466e306119af3b77e7e623ce71988d2b7f86f Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Fri, 30 Apr 2021 12:00:40 -0700 Subject: [PATCH] wip: add HMAC to crypto.timingSafeEqual() Refs: https://github.com/nodejs/node/issues/38226 --- src/crypto/crypto_timing.cc | 42 ++++++++++++++++++- ...est-crypto-timing-safe-equal-benchmarks.js | 2 +- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/crypto/crypto_timing.cc b/src/crypto/crypto_timing.cc index 0a9b167223b846..9fc0fe3eb3a4c9 100644 --- a/src/crypto/crypto_timing.cc +++ b/src/crypto/crypto_timing.cc @@ -6,6 +6,8 @@ #include "node.h" #include +#include +#include namespace node { @@ -42,8 +44,46 @@ void TimingSafeEqual(const FunctionCallbackInfo& args) { return; } + uint16_t bufKey[8]; + CHECK(crypto::EntropySource(reinterpret_cast(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 hash1; + std::array hash2; + unsigned int hash1Len; + unsigned int hash2Len; + + HMAC(EVP_sha256(), + key, + keySize, + reinterpret_cast(buf1.data()), + static_cast(buf1.size()), + hash1.data(), + &hash1Len); + + HMAC(EVP_sha256(), + key, + keySize, + reinterpret_cast(buf2.data()), + static_cast(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 target) { diff --git a/test/pummel/test-crypto-timing-safe-equal-benchmarks.js b/test/pummel/test-crypto-timing-safe-equal-benchmarks.js index b649b071e1e49d..3c6e31e8294cc8 100644 --- a/test/pummel/test-crypto-timing-safe-equal-benchmarks.js +++ b/test/pummel/test-crypto-timing-safe-equal-benchmarks.js @@ -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);