Files
emsha-rs/tests/hmac.rs
T
kyle 7755be49e9 Fix SHA-256 padding bug for messages of length 63 mod 64
pad_message wrote 0x00 into the last byte of the current block and
deferred the 0x80 pad byte to the next block when mbi == 63, producing
incorrect digests for every message whose length is 63 mod 64 (and
correspondingly wrong HMAC tags). Always write the pad byte in the
current block first, then flush an extra block only when the 8-byte
length field no longer fits.

Adds regression tests for SHA-256 boundary lengths 55/56/63/64/65 and
HMAC with a 63-byte message. Bumps to 1.0.4 for crates.io publication.

Ref: docs/LAGUNA-AUDIT.md
2026-09-17 12:25:23 -07:00

139 lines
4.3 KiB
Rust

use emsha::hexstr::to_hex;
use emsha::{Hash, Result, hmac, sha256};
#[test]
fn test_hmac_00() -> Result<()> {
let k: [u8; 20] = [
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
];
let input = b"Hi There";
let output = b"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(input)?;
h.finalize(&mut digest)?;
to_hex(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}
#[test]
fn test_hmac_01() -> Result<()> {
let k: [u8; 4] = [0x4a, 0x65, 0x66, 0x65];
let input = b"what do ya want for nothing?";
let output = b"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(input)?;
h.finalize(&mut digest)?;
to_hex(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}
#[test]
fn test_hmac_02() -> Result<()> {
let k: [u8; 20] = [
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
];
let input = &[0xddu8; 50];
let output = b"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(input)?;
h.finalize(&mut digest)?;
to_hex(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}
#[test]
fn test_hmac_pad_boundary() -> Result<()> {
// A 63-byte message makes the inner SHA-256 process 127 bytes
// (64 key-pad + 63 message), which is 63 mod 64 — the boundary
// where the pad byte must start a new block.
let k: [u8; 20] = [
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
];
let msg = [0x61u8; 63];
let output = b"2396ff2784cd6b8bdf0ac13df75a30de92e3f15374065b9f21ac81a268a93904";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(&msg)?;
h.finalize(&mut digest)?;
to_hex(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}
#[test]
fn test_hmac_03() -> Result<()> {
let k: [u8; 25] = [
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19,
];
let input = &[0xcdu8; 50];
let output = b"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(input)?;
h.finalize(&mut digest)?;
to_hex(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}
#[test]
fn test_hmac_04() -> Result<()> {
let k = [0xaau8; 131];
let input =
b"Test Using Larger Than Block-Size Key - Hash Key First";
let output = b"60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(input)?;
h.finalize(&mut digest)?;
to_hex(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}
#[test]
fn test_hmac_05() -> Result<()> {
let k = [0xaau8; 131];
let input = b"This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.";
let output = b"9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(input)?;
h.finalize(&mut digest)?;
to_hex(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}