crypto: cache valid ECDH key pairs · nodejs/node@501d8ac · GitHub
Skip to content

Commit 501d8ac

Browse files
panvaaduh95
authored andcommitted
crypto: cache valid ECDH key pairs
Avoid repeating EC key-pair validation after a pair has already been established or validated. Invalidate the positive-only cache whenever public-key mutation can make the pair inconsistent. Signed-off-by: Filip Skokan <panva.ip@gmail.com> PR-URL: #65615 Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent cf78d42 commit 501d8ac

4 files changed

Lines changed: 175 additions & 1 deletion

File tree

Lines changed: 117 additions & 0 deletions

‎src/crypto/crypto_ec.cc‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,12 @@ void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
134134
ECDH* ecdh;
135135
ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.This());
136136

137+
const uint64_t generation = ncrypto::getFipsStateGeneration();
138+
ecdh->has_valid_key_pair_ = false;
137139
if (!ecdh->key_.generate()) {
138140
return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to generate key");
139141
}
142+
ecdh->MaybeCacheValidKeyPair(generation);
140143
}
141144

142145
ECPointPointer ECDH::BufferToPoint(Environment* env,
@@ -307,6 +310,7 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
307310

308311
ecdh->key_ = std::move(new_key);
309312
ecdh->group_ = ecdh->key_.getGroup();
313+
ecdh->has_valid_key_pair_ = false;
310314
}
311315

312316
void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
@@ -325,6 +329,7 @@ void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
325329
"Failed to convert Buffer to EC_POINT");
326330
}
327331

332+
ecdh->has_valid_key_pair_ = false;
328333
if (!ecdh->key_.setPublicKey(pub)) {
329334
return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
330335
"Failed to set EC_POINT as the public key");
@@ -345,9 +350,22 @@ bool ECDH::IsKeyValidForCurve(const BignumPointer& private_key) {
345350
private_key < order;
346351
}
347352

353+
void ECDH::MaybeCacheValidKeyPair(uint64_t generation) {
354+
has_valid_key_pair_ = generation == ncrypto::getFipsStateGeneration();
355+
if (has_valid_key_pair_) valid_key_pair_generation_ = generation;
356+
}
357+
348358
bool ECDH::IsKeyPairValid() {
359+
const uint64_t generation = ncrypto::getFipsStateGeneration();
360+
if (has_valid_key_pair_ && valid_key_pair_generation_ == generation) {
361+
return true;
362+
}
363+
has_valid_key_pair_ = false;
364+
349365
MarkPopErrorOnReturn mark_pop_error_on_return;
350-
return key_.checkKey();
366+
const bool is_valid = key_.checkKey();
367+
if (is_valid) MaybeCacheValidKeyPair(generation);
368+
return is_valid;
351369
}
352370

353371
// Convert the input public key to compressed, uncompressed, or hybrid formats.

‎src/crypto/crypto_ec.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,14 @@ class ECDH final : public BaseObject {
4848
static void GetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
4949
static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
5050

51+
void MaybeCacheValidKeyPair(uint64_t generation);
5152
bool IsKeyPairValid();
5253
bool IsKeyValidForCurve(const ncrypto::BignumPointer& private_key);
5354

5455
ncrypto::ECKeyPointer key_;
5556
const EC_GROUP* group_;
57+
bool has_valid_key_pair_ = false;
58+
uint64_t valid_key_pair_generation_ = 0;
5659
};
5760

5861
struct EcKeyPairParams final : public MemoryRetainer {

‎test/parallel/test-crypto-dh-curves.js‎

Lines changed: 36 additions & 0 deletions

0 commit comments

Comments
 (0)