From 977350a57a886eb50cd5cd497856d7ee1b1f3ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 13 Oct 2025 05:03:38 +0300 Subject: [PATCH 1/3] hkdf: unseal `HmacImpl` --- hkdf/src/{sealed.rs => hmac_impl.rs} | 27 ++++++++++++++++----------- hkdf/src/lib.rs | 8 ++------ 2 files changed, 18 insertions(+), 17 deletions(-) rename hkdf/src/{sealed.rs => hmac_impl.rs} (57%) diff --git a/hkdf/src/sealed.rs b/hkdf/src/hmac_impl.rs similarity index 57% rename from hkdf/src/sealed.rs rename to hkdf/src/hmac_impl.rs index 377bea8..aed4026 100644 --- a/hkdf/src/sealed.rs +++ b/hkdf/src/hmac_impl.rs @@ -4,15 +4,21 @@ use hmac::digest::{ }; use hmac::{EagerHash, Hmac, SimpleHmac}; -pub trait Sealed { +/// Trait representing a HMAC implementation. +/// +/// Most users should use [`Hmac`] or [`SimpleHmac`]. +pub trait HmacImpl: Clone { + /// Create new HMAC state with the given key. fn new_from_slice(key: &[u8]) -> Self; + /// Update HMAC state. fn update(&mut self, data: &[u8]); + /// Finalize the HMAC state and get generated tag. fn finalize(self) -> Output; } -impl Sealed for Hmac { +impl HmacImpl for Hmac { #[inline(always)] fn new_from_slice(key: &[u8]) -> Self { KeyInit::new_from_slice(key).expect("HMAC can take a key of any size") @@ -24,15 +30,16 @@ impl Sealed for Hmac { } #[inline(always)] - #[allow(deprecated)] // clone_from_slice fn finalize(self) -> Output { - // Output and Output are always equal to each other, - // but we can not prove it at type level - Output::::clone_from_slice(&self.finalize_fixed()) + Output::::try_from(&self.finalize_fixed()[..]) + .expect("Output and Output are always equal to each other") } } -impl Sealed for SimpleHmac { +impl HmacImpl for SimpleHmac +where + H: Digest + BlockSizeUser + Clone, +{ #[inline(always)] fn new_from_slice(key: &[u8]) -> Self { KeyInit::new_from_slice(key).expect("HMAC can take a key of any size") @@ -44,10 +51,8 @@ impl Sealed for SimpleHmac { } #[inline(always)] - #[allow(deprecated)] // clone_from_slice fn finalize(self) -> Output { - // Output and Output are always equal to each other, - // but we can not prove it at type level - Output::::clone_from_slice(&self.finalize_fixed()) + Output::::try_from(&self.finalize_fixed()[..]) + .expect("Output and Output are always equal to each other") } } diff --git a/hkdf/src/lib.rs b/hkdf/src/lib.rs index 98c5ddb..11c233b 100644 --- a/hkdf/src/lib.rs +++ b/hkdf/src/lib.rs @@ -18,9 +18,10 @@ use hmac::digest::{ use hmac::{Hmac, SimpleHmac}; mod errors; -mod sealed; +mod hmac_impl; pub use errors::{InvalidLength, InvalidPrkLength}; +pub use hmac_impl::HmacImpl; /// [`HkdfExtract`] variant which uses [`SimpleHmac`] for underlying HMAC /// implementation. @@ -192,8 +193,3 @@ where f.write_str("> { ... }") } } - -/// Sealed trait implemented for [`Hmac`] and [`SimpleHmac`]. -pub trait HmacImpl: sealed::Sealed + Clone {} - -impl + Clone> HmacImpl for T {} From 25ebda30c52df177b6877006a305e9d4251a3c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 13 Oct 2025 05:09:06 +0300 Subject: [PATCH 2/3] tweak panic messaged --- hkdf/src/hmac_impl.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hkdf/src/hmac_impl.rs b/hkdf/src/hmac_impl.rs index aed4026..a5bcd6f 100644 --- a/hkdf/src/hmac_impl.rs +++ b/hkdf/src/hmac_impl.rs @@ -32,7 +32,7 @@ impl HmacImpl for Hmac { #[inline(always)] fn finalize(self) -> Output { Output::::try_from(&self.finalize_fixed()[..]) - .expect("Output and Output are always equal to each other") + .expect("Output and Output> are always equal to each other") } } @@ -53,6 +53,6 @@ where #[inline(always)] fn finalize(self) -> Output { Output::::try_from(&self.finalize_fixed()[..]) - .expect("Output and Output are always equal to each other") + .expect("Output and Output> are always equal to each other") } } From 3ca5a5b2b11d9e4203522819073f99832a0a9754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 13 Oct 2025 05:09:25 +0300 Subject: [PATCH 3/3] Update changelog --- hkdf/CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hkdf/CHANGELOG.md b/hkdf/CHANGELOG.md index d2ce4f3..2d7b25d 100644 --- a/hkdf/CHANGELOG.md +++ b/hkdf/CHANGELOG.md @@ -4,13 +4,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## UNRELEASED -### Breaking changes +## 0.13.0 (unreleased) +### Changed - Removed `std` crate feature ([#105]) - Bump MSRV to 1.81 ([#105]) - Bump `hmac` dependency to v0.13 +- Unseal `HmacImpl` trait ([#154]) [#105]: https://github.com/RustCrypto/KDFs/pull/105 +[#154]: https://github.com/RustCrypto/KDFs/pull/154 ## 0.12.3 (2022-02-17) ### Fixed