Rust wrapper: implement Clone for HMAC types

This commit is contained in:
Josh Holtrop
2026-05-01 07:49:26 -04:00
parent b3aa7ef260
commit d88d5702e5
3 changed files with 40 additions and 0 deletions
@@ -330,6 +330,24 @@ impl HMAC {
}
}
impl Clone for HMAC {
/// Deep-copy the HMAC state via `wc_HmacCopy()`.
///
/// Panics if the underlying wolfSSL copy fails.
fn clone(&self) -> Self {
let mut wc_hmac: MaybeUninit<sys::Hmac> = MaybeUninit::uninit();
let rc = unsafe {
sys::wc_HmacCopy(&self.wc_hmac as *const _ as *mut _,
wc_hmac.as_mut_ptr())
};
if rc != 0 {
panic!("wc_HmacCopy() failed: {}", rc);
}
let wc_hmac = unsafe { wc_hmac.assume_init() };
HMAC { wc_hmac }
}
}
impl Drop for HMAC {
/// Safely free the underlying wolfSSL Hmac context.
///
@@ -42,6 +42,7 @@ macro_rules! impl_hmac_mac {
$name:ident, hmac_type = $hmac_type:expr, key = $key_size:ty, out = $out_size:ty
) => {
$(#[$attr])*
#[derive(Clone)]
pub struct $name {
hmac: crate::hmac::HMAC,
}
@@ -40,6 +40,27 @@ fn test_hmac_sha256_mac_finalize() {
assert_eq!(result.as_bytes().as_slice(), expected);
}
#[test]
fn test_hmac_sha256_mac_clone() {
let key = b"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
let prefix = b"Hi ";
let suffix = b"There";
let expected = b"\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7";
let mut mac = HmacSha256::new_from_slice(key)
.expect("HMAC init failed");
mac.update(prefix);
let mut forked = mac.clone();
forked.update(suffix);
let forked_tag = forked.finalize();
assert_eq!(forked_tag.as_bytes().as_slice(), expected);
mac.update(suffix);
let original_tag = mac.finalize();
assert_eq!(original_tag.as_bytes().as_slice(), expected);
}
#[test]
fn test_hmac_sha256_mac_verify_fail() {
let key = b"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";