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
139 lines
4.3 KiB
Rust
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(())
|
|
}
|