Skip to content

Commit 3b22818

Browse files
panvanpaun
authored andcommitted
crypto: add KMAC Web Cryptography algorithms
PR-URL: nodejs/node#59647 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 033e0de commit 3b22818

2 files changed

Lines changed: 142 additions & 0 deletions

File tree

include/ncrypto.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ class DataPointer;
235235
class DHPointer;
236236
class ECKeyPointer;
237237
class EVPKeyPointer;
238+
class EVPMacCtxPointer;
239+
class EVPMacPointer;
238240
class EVPMDCtxPointer;
239241
class SSLCtxPointer;
240242
class SSLPointer;
@@ -1329,6 +1331,56 @@ class HMACCtxPointer final {
13291331
DeleteFnPtr<HMAC_CTX, HMAC_CTX_free> ctx_;
13301332
};
13311333

1334+
#if OPENSSL_VERSION_MAJOR >= 3
1335+
class EVPMacPointer final {
1336+
public:
1337+
EVPMacPointer() = default;
1338+
explicit EVPMacPointer(EVP_MAC* mac);
1339+
EVPMacPointer(EVPMacPointer&& other) noexcept;
1340+
EVPMacPointer& operator=(EVPMacPointer&& other) noexcept;
1341+
NCRYPTO_DISALLOW_COPY(EVPMacPointer)
1342+
~EVPMacPointer();
1343+
1344+
inline bool operator==(std::nullptr_t) noexcept { return mac_ == nullptr; }
1345+
inline operator bool() const { return mac_ != nullptr; }
1346+
inline EVP_MAC* get() const { return mac_.get(); }
1347+
inline operator EVP_MAC*() const { return mac_.get(); }
1348+
void reset(EVP_MAC* mac = nullptr);
1349+
EVP_MAC* release();
1350+
1351+
static EVPMacPointer Fetch(const char* algorithm);
1352+
1353+
private:
1354+
DeleteFnPtr<EVP_MAC, EVP_MAC_free> mac_;
1355+
};
1356+
1357+
class EVPMacCtxPointer final {
1358+
public:
1359+
EVPMacCtxPointer() = default;
1360+
explicit EVPMacCtxPointer(EVP_MAC_CTX* ctx);
1361+
EVPMacCtxPointer(EVPMacCtxPointer&& other) noexcept;
1362+
EVPMacCtxPointer& operator=(EVPMacCtxPointer&& other) noexcept;
1363+
NCRYPTO_DISALLOW_COPY(EVPMacCtxPointer)
1364+
~EVPMacCtxPointer();
1365+
1366+
inline bool operator==(std::nullptr_t) noexcept { return ctx_ == nullptr; }
1367+
inline operator bool() const { return ctx_ != nullptr; }
1368+
inline EVP_MAC_CTX* get() const { return ctx_.get(); }
1369+
inline operator EVP_MAC_CTX*() const { return ctx_.get(); }
1370+
void reset(EVP_MAC_CTX* ctx = nullptr);
1371+
EVP_MAC_CTX* release();
1372+
1373+
bool init(const Buffer<const void>& key, const OSSL_PARAM* params = nullptr);
1374+
bool update(const Buffer<const void>& data);
1375+
DataPointer final(size_t length);
1376+
1377+
static EVPMacCtxPointer New(EVP_MAC* mac);
1378+
1379+
private:
1380+
DeleteFnPtr<EVP_MAC_CTX, EVP_MAC_CTX_free> ctx_;
1381+
};
1382+
#endif // OPENSSL_VERSION_MAJOR >= 3
1383+
13321384
#ifndef OPENSSL_NO_ENGINE
13331385
class EnginePointer final {
13341386
public:

src/ncrypto.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4083,6 +4083,96 @@ bool HMACCtxPointer::digestInto(Buffer<void>* buf) {
40834083

40844084
HMACCtxPointer HMACCtxPointer::New() { return HMACCtxPointer(HMAC_CTX_new()); }
40854085

4086+
#if OPENSSL_VERSION_MAJOR >= 3
4087+
EVPMacPointer::EVPMacPointer(EVP_MAC* mac) : mac_(mac) {}
4088+
4089+
EVPMacPointer::EVPMacPointer(EVPMacPointer&& other) noexcept
4090+
: mac_(std::move(other.mac_)) {}
4091+
4092+
EVPMacPointer& EVPMacPointer::operator=(EVPMacPointer&& other) noexcept {
4093+
if (this == &other) return *this;
4094+
mac_ = std::move(other.mac_);
4095+
return *this;
4096+
}
4097+
4098+
EVPMacPointer::~EVPMacPointer() {
4099+
mac_.reset();
4100+
}
4101+
4102+
void EVPMacPointer::reset(EVP_MAC* mac) {
4103+
mac_.reset(mac);
4104+
}
4105+
4106+
EVP_MAC* EVPMacPointer::release() {
4107+
return mac_.release();
4108+
}
4109+
4110+
EVPMacPointer EVPMacPointer::Fetch(const char* algorithm) {
4111+
return EVPMacPointer(EVP_MAC_fetch(nullptr, algorithm, nullptr));
4112+
}
4113+
4114+
EVPMacCtxPointer::EVPMacCtxPointer(EVP_MAC_CTX* ctx) : ctx_(ctx) {}
4115+
4116+
EVPMacCtxPointer::EVPMacCtxPointer(EVPMacCtxPointer&& other) noexcept
4117+
: ctx_(std::move(other.ctx_)) {}
4118+
4119+
EVPMacCtxPointer& EVPMacCtxPointer::operator=(
4120+
EVPMacCtxPointer&& other) noexcept {
4121+
if (this == &other) return *this;
4122+
ctx_ = std::move(other.ctx_);
4123+
return *this;
4124+
}
4125+
4126+
EVPMacCtxPointer::~EVPMacCtxPointer() {
4127+
ctx_.reset();
4128+
}
4129+
4130+
void EVPMacCtxPointer::reset(EVP_MAC_CTX* ctx) {
4131+
ctx_.reset(ctx);
4132+
}
4133+
4134+
EVP_MAC_CTX* EVPMacCtxPointer::release() {
4135+
return ctx_.release();
4136+
}
4137+
4138+
bool EVPMacCtxPointer::init(const Buffer<const void>& key,
4139+
const OSSL_PARAM* params) {
4140+
if (!ctx_) return false;
4141+
return EVP_MAC_init(ctx_.get(),
4142+
static_cast<const unsigned char*>(key.data),
4143+
key.len,
4144+
params) == 1;
4145+
}
4146+
4147+
bool EVPMacCtxPointer::update(const Buffer<const void>& data) {
4148+
if (!ctx_) return false;
4149+
return EVP_MAC_update(ctx_.get(),
4150+
static_cast<const unsigned char*>(data.data),
4151+
data.len) == 1;
4152+
}
4153+
4154+
DataPointer EVPMacCtxPointer::final(size_t length) {
4155+
if (!ctx_) return {};
4156+
auto buf = DataPointer::Alloc(length);
4157+
if (!buf) return {};
4158+
4159+
size_t result_len = length;
4160+
if (EVP_MAC_final(ctx_.get(),
4161+
static_cast<unsigned char*>(buf.get()),
4162+
&result_len,
4163+
length) != 1) {
4164+
return {};
4165+
}
4166+
4167+
return buf;
4168+
}
4169+
4170+
EVPMacCtxPointer EVPMacCtxPointer::New(EVP_MAC* mac) {
4171+
if (!mac) return EVPMacCtxPointer();
4172+
return EVPMacCtxPointer(EVP_MAC_CTX_new(mac));
4173+
}
4174+
#endif // OPENSSL_VERSION_MAJOR >= 3
4175+
40864176
DataPointer hashDigest(const Buffer<const unsigned char>& buf,
40874177
const EVP_MD* md) {
40884178
if (md == nullptr) return {};

0 commit comments

Comments
 (0)