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

Commit 022ac83

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. PR-URL: #65615 Backport-PR-URL: #66128 Assisted-by: Codex Signed-off-by: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent c61953e commit 022ac83

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
@@ -136,9 +136,12 @@ void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
136136
ECDH* ecdh;
137137
ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.This());
138138

139+
const uint64_t generation = ncrypto::getFipsStateGeneration();
140+
ecdh->has_valid_key_pair_ = false;
139141
if (!ecdh->key_.generate()) {
140142
return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to generate key");
141143
}
144+
ecdh->MaybeCacheValidKeyPair(generation);
142145
}
143146

144147
ECPointPointer ECDH::BufferToPoint(Environment* env,
@@ -309,6 +312,7 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
309312

310313
ecdh->key_ = std::move(new_key);
311314
ecdh->group_ = ecdh->key_.getGroup();
315+
ecdh->has_valid_key_pair_ = false;
312316
}
313317

314318
void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
@@ -327,6 +331,7 @@ void ECDH::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
327331
"Failed to convert Buffer to EC_POINT");
328332
}
329333

334+
ecdh->has_valid_key_pair_ = false;
330335
if (!ecdh->key_.setPublicKey(pub)) {
331336
return THROW_ERR_CRYPTO_OPERATION_FAILED(env,
332337
"Failed to set EC_POINT as the public key");
@@ -347,9 +352,22 @@ bool ECDH::IsKeyValidForCurve(const BignumPointer& private_key) {
347352
private_key < order;
348353
}
349354

355+
void ECDH::MaybeCacheValidKeyPair(uint64_t generation) {
356+
has_valid_key_pair_ = generation == ncrypto::getFipsStateGeneration();
357+
if (has_valid_key_pair_) valid_key_pair_generation_ = generation;
358+
}
359+
350360
bool ECDH::IsKeyPairValid() {
361+
const uint64_t generation = ncrypto::getFipsStateGeneration();
362+
if (has_valid_key_pair_ && valid_key_pair_generation_ == generation) {
363+
return true;
364+
}
365+
has_valid_key_pair_ = false;
366+
351367
MarkPopErrorOnReturn mark_pop_error_on_return;
352-
return key_.checkKey();
368+
const bool is_valid = key_.checkKey();
369+
if (is_valid) MaybeCacheValidKeyPair(generation);
370+
return is_valid;
353371
}
354372

355373
// 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)