crypto: cache valid ECDH key pairs by panva · Pull Request #65615 · nodejs/node · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions benchmark/crypto/ecdh-compute-secret.js
20 changes: 19 additions & 1 deletion src/crypto/crypto_ec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,12 @@ void ECDH::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
ECDH* ecdh;
ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.This());

const uint64_t generation = ncrypto::getFipsStateGeneration();
ecdh->has_valid_key_pair_ = false;
if (!ecdh->key_.generate()) {
return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to generate key");
}
ecdh->MaybeCacheValidKeyPair(generation);
}

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

ecdh->key_ = std::move(new_key);
ecdh->group_ = ecdh->key_.getGroup();
ecdh->has_valid_key_pair_ = false;
}

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

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

void ECDH::MaybeCacheValidKeyPair(uint64_t generation) {
has_valid_key_pair_ = generation == ncrypto::getFipsStateGeneration();
if (has_valid_key_pair_) valid_key_pair_generation_ = generation;
}

bool ECDH::IsKeyPairValid() {
const uint64_t generation = ncrypto::getFipsStateGeneration();
if (has_valid_key_pair_ && valid_key_pair_generation_ == generation) {
return true;
}
has_valid_key_pair_ = false;

MarkPopErrorOnReturn mark_pop_error_on_return;
return key_.checkKey();
const bool is_valid = key_.checkKey();
if (is_valid) MaybeCacheValidKeyPair(generation);
return is_valid;
}

// Convert the input public key to compressed, uncompressed, or hybrid formats.
Expand Down
3 changes: 3 additions & 0 deletions src/crypto/crypto_ec.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,14 @@ class ECDH final : public BaseObject {
static void GetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args);

void MaybeCacheValidKeyPair(uint64_t generation);
bool IsKeyPairValid();
bool IsKeyValidForCurve(const ncrypto::BignumPointer& private_key);

ncrypto::ECKeyPointer key_;
const EC_GROUP* group_;
bool has_valid_key_pair_ = false;
uint64_t valid_key_pair_generation_ = 0;
};

struct EcKeyPairParams final : public MemoryRetainer {
Expand Down
36 changes: 36 additions & 0 deletions test/parallel/test-crypto-dh-curves.js
Loading