@@ -5506,16 +5506,39 @@ DigestCache::Result DigestCache::insert(const char* name,
55065506#endif
55075507}
55085508
5509+ DigestCache::~DigestCache () = default ;
5510+
55095511void DigestCache::reset (uint64_t generation) {
55105512#if NCRYPTO_USE_OPENSSL_PROVIDER
55115513 if (generation_ == generation) return ;
55125514 aliases_.clear ();
5515+ hmac_templates_.clear ();
55135516 digests_.clear ();
55145517 first_id_ = next_id_;
55155518#endif
55165519 generation_ = generation;
55175520}
55185521
5522+ #if NCRYPTO_USE_OPENSSL_PROVIDER
5523+ const HMACCtxPointer* DigestCache::getHmacTemplate (const EVP_MD * digest,
5524+ uint64_t generation) {
5525+ if (generation_ != generation || digest == nullptr ) return nullptr ;
5526+ for (size_t index = 0 ; index < digests_.size (); index++) {
5527+ if (digests_[index].get () != digest) continue ;
5528+ if (hmac_templates_.size () <= index) {
5529+ hmac_templates_.resize (digests_.size ());
5530+ }
5531+ if (!hmac_templates_[index]) {
5532+ auto ctx = HMACCtxPointer::New (Digest::Ref (digest));
5533+ if (!ctx) return nullptr ;
5534+ hmac_templates_[index] = std::make_unique<HMACCtxPointer>(std::move (ctx));
5535+ }
5536+ return hmac_templates_[index].get ();
5537+ }
5538+ return nullptr ;
5539+ }
5540+ #endif
5541+
55195542const DigestCache::AliasMap& DigestCache::aliases () const {
55205543#if NCRYPTO_USE_OPENSSL_PROVIDER
55215544 return aliases_;
@@ -8584,15 +8607,19 @@ HMACCtxPointer::HMACCtxPointer(EVPMacPointer&& mac, EVPMacCtxPointer&& ctx)
85848607HMACCtxPointer::HMACCtxPointer (HMACCtxPointer&& other) noexcept
85858608 : mac_ (std::move (other.mac_ )),
85868609 ctx_ (std::move (other.ctx_ )),
8610+ md_ (other.md_ ),
85878611 md_size_ (other.md_size_ ) {
8612+ other.md_ = nullptr ;
85888613 other.md_size_ = 0 ;
85898614}
85908615
85918616HMACCtxPointer& HMACCtxPointer::operator =(HMACCtxPointer&& other) noexcept {
85928617 if (this == &other) return *this ;
85938618 mac_ = std::move (other.mac_ );
85948619 ctx_ = std::move (other.ctx_ );
8620+ md_ = other.md_ ;
85958621 md_size_ = other.md_size_ ;
8622+ other.md_ = nullptr ;
85968623 other.md_size_ = 0 ;
85978624 return *this ;
85988625}
@@ -8604,11 +8631,13 @@ HMACCtxPointer::~HMACCtxPointer() {
86048631void HMACCtxPointer::reset () {
86058632 ctx_.reset ();
86068633 mac_.reset ();
8634+ md_ = nullptr ;
86078635 md_size_ = 0 ;
86088636}
86098637
86108638bool HMACCtxPointer::init (const Buffer<const void >& buf, const Digest& md) {
86118639 if (!ctx_ || !md) return false ;
8640+ if (md.get () == md_) return ctx_.init (buf);
86128641
86138642 const char * md_name = EVP_MD_get0_name (md);
86148643 if (md_name == nullptr ) return false ;
@@ -8620,6 +8649,7 @@ bool HMACCtxPointer::init(const Buffer<const void>& buf, const Digest& md) {
86208649 };
86218650
86228651 if (!ctx_.init (buf, params)) return false ;
8652+ md_ = md.get ();
86238653 md_size_ = md.size ();
86248654 return true ;
86258655}
@@ -8651,6 +8681,16 @@ bool HMACCtxPointer::digestInto(Buffer<void>* buf) {
86518681 return true ;
86528682}
86538683
8684+ HMACCtxPointer HMACCtxPointer::clone () const {
8685+ if (!ctx_) return {};
8686+ EVPMacCtxPointer ctx (EVP_MAC_CTX_dup (ctx_.get ()));
8687+ if (!ctx) return {};
8688+ HMACCtxPointer result (EVPMacPointer (), std::move (ctx));
8689+ result.md_ = md_;
8690+ result.md_size_ = md_size_;
8691+ return result;
8692+ }
8693+
86548694HMACCtxPointer HMACCtxPointer::New () {
86558695 auto mac = EVPMacPointer::Fetch (OSSL_MAC_NAME_HMAC );
86568696 if (!mac) return {};
@@ -8660,6 +8700,25 @@ HMACCtxPointer HMACCtxPointer::New() {
86608700
86618701 return HMACCtxPointer (std::move (mac), std::move (ctx));
86628702}
8703+
8704+ HMACCtxPointer HMACCtxPointer::New (const Digest& md) {
8705+ if (!md) return {};
8706+ const char * md_name = EVP_MD_get0_name (md);
8707+ if (md_name == nullptr ) return {};
8708+
8709+ auto result = New ();
8710+ if (!result) return {};
8711+
8712+ OSSL_PARAM params[] = {
8713+ OSSL_PARAM_construct_utf8_string (
8714+ OSSL_MAC_PARAM_DIGEST , const_cast <char *>(md_name), 0 ),
8715+ OSSL_PARAM_construct_end (),
8716+ };
8717+ if (EVP_MAC_CTX_set_params (result.ctx_ .get (), params) != 1 ) return {};
8718+ result.md_ = md.get ();
8719+ result.md_size_ = md.size ();
8720+ return result;
8721+ }
86638722#endif // OPENSSL_WITH_EVP_MAC
86648723
86658724DataPointer hashDigest (const Buffer<const unsigned char >& buf,
0 commit comments