diff options
| author | Jack O'Connor <[email protected]> | 2022-01-24 20:47:37 -0500 |
|---|---|---|
| committer | Jack O'Connor <[email protected]> | 2022-01-24 20:52:22 -0500 |
| commit | 540f708a94e1a50e20d6dbf6921a59560645f342 (patch) | |
| tree | a3d44d8fa39761f59ad57eb2345452ded85092b6 | |
| parent | 509e97ed9080e933fc1741811f5b61ef217107a1 (diff) | |
check the HMAC output bytes
| -rw-r--r-- | src/traits.rs | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/src/traits.rs b/src/traits.rs index 14b0f55..70b1c06 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -171,12 +171,57 @@ mod test { assert_eq!(out1.as_bytes(), out2.into_bytes().as_slice()); } + fn expected_hmac_blake3(key: &[u8], input: &[u8]) -> [u8; 32] { + // See https://en.wikipedia.org/wiki/HMAC. + let key_hash; + let key_prime = if key.len() <= 64 { + key + } else { + key_hash = *crate::hash(key).as_bytes(); + &key_hash + }; + let mut ipad = [0x36; 64]; + let mut opad = [0x5c; 64]; + for i in 0..key_prime.len() { + ipad[i] ^= key_prime[i]; + opad[i] ^= key_prime[i]; + } + let mut inner_state = crate::Hasher::new(); + inner_state.update(&ipad); + inner_state.update(input); + let mut outer_state = crate::Hasher::new(); + outer_state.update(&opad); + outer_state.update(inner_state.finalize().as_bytes()); + outer_state.finalize().into() + } + #[test] fn test_hmac_compatibility() { - use hmac::{SimpleHmac, Mac}; + use hmac::{Mac, SimpleHmac}; + // Test a short key. let mut x = SimpleHmac::<Hasher>::new_from_slice(b"key").unwrap(); hmac::digest::Update::update(&mut x, b"data"); - assert_ne!(x.finalize().into_bytes().len(), 0); + let output = x.finalize().into_bytes(); + assert_ne!(output.len(), 0); + let expected = expected_hmac_blake3(b"key", b"data"); + assert_eq!(expected, output.as_ref()); + + // Test a range of key and data lengths, particularly to exercise the long-key logic. + let mut input_bytes = [0; crate::test::TEST_CASES_MAX]; + crate::test::paint_test_input(&mut input_bytes); + for &input_len in crate::test::TEST_CASES { + #[cfg(feature = "std")] + dbg!(input_len); + let input = &input_bytes[..input_len]; + + let mut x = SimpleHmac::<Hasher>::new_from_slice(input).unwrap(); + hmac::digest::Update::update(&mut x, input); + let output = x.finalize().into_bytes(); + assert_ne!(output.len(), 0); + + let expected = expected_hmac_blake3(input, input); + assert_eq!(expected, output.as_ref()); + } } } |
