diff --git a/Cargo.lock b/Cargo.lock index e5a77a5..cde38e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -162,6 +162,7 @@ dependencies = [ "crypto-mac", "digest", "md-5", + "sha-1", "sha2", "streebog", ] @@ -216,6 +217,19 @@ version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +[[package]] +name = "sha-1" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfebf75d25bd900fd1e7d11501efab59bc846dbc76196839663e6637bba9f25f" +dependencies = [ + "block-buffer", + "cfg-if", + "cpuid-bool 0.1.2", + "digest", + "opaque-debug", +] + [[package]] name = "sha2" version = "0.9.3" diff --git a/cmac/tests/data/wycheproof-aes128.blb b/cmac/tests/data/wycheproof-aes128.blb new file mode 100644 index 0000000..dfde593 Binary files /dev/null and b/cmac/tests/data/wycheproof-aes128.blb differ diff --git a/cmac/tests/data/wycheproof-aes192.blb b/cmac/tests/data/wycheproof-aes192.blb new file mode 100644 index 0000000..cb21624 Binary files /dev/null and b/cmac/tests/data/wycheproof-aes192.blb differ diff --git a/cmac/tests/data/wycheproof-aes256.blb b/cmac/tests/data/wycheproof-aes256.blb new file mode 100644 index 0000000..1502473 Binary files /dev/null and b/cmac/tests/data/wycheproof-aes256.blb differ diff --git a/cmac/tests/wycheproof.rs b/cmac/tests/wycheproof.rs new file mode 100644 index 0000000..778d746 --- /dev/null +++ b/cmac/tests/wycheproof.rs @@ -0,0 +1,68 @@ +//! Tests from Project Wycheproof: +//! https://github.com/google/wycheproof +#![no_std] +use aes::{Aes128, Aes192, Aes256}; +use cmac::Cmac; +// TODO: use macro from crypto-mac crate +// use crypto_mac::new_trunc_test; + +macro_rules! new_trunc_test { + ($name:ident, $test_name:expr, $mac:ty) => { + #[test] + fn $name() { + use crypto_mac::dev::blobby::Blob3Iterator; + use crypto_mac::generic_array::typenum::Unsigned; + use crypto_mac::{Mac, NewMac}; + + fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { + let mut mac = <$mac as NewMac>::new_from_slice(key).unwrap(); + mac.update(input); + let result = mac.finalize_reset(); + let mut len = <$mac as Mac>::OutputSize::to_usize(); + if tag.len() < len { + len = tag.len(); + } + if &result.into_bytes()[..len] != tag { + return Some("whole message"); + } + // test if reset worked correctly + mac.update(input); + let result = mac.finalize(); + if &result.into_bytes()[..len] != tag { + return Some("after reset"); + } + + let mut mac = <$mac as NewMac>::new_from_slice(key).unwrap(); + // test reading byte by byte + for i in 0..input.len() { + mac.update(&input[i..i + 1]); + } + let result = mac.finalize(); + if &result.into_bytes()[..len] != tag { + return Some("message byte-by-byte"); + } + None + } + + let data = include_bytes!(concat!("data/", $test_name, ".blb")); + + for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { + let [key, input, tag] = row.unwrap(); + if let Some(desc) = run_test(key, input, tag) { + panic!( + "\n\ + Failed test №{}: {}\n\ + key:\t{:?}\n\ + input:\t{:?}\n\ + tag:\t{:?}\n", + i, desc, key, input, tag, + ); + } + } + } + }; +} + +new_trunc_test!(wycheproof_cmac_aes128, "wycheproof-aes128", Cmac); +new_trunc_test!(wycheproof_cmac_aes192, "wycheproof-aes192", Cmac); +new_trunc_test!(wycheproof_cmac_aes256, "wycheproof-aes256", Cmac); diff --git a/hmac/Cargo.toml b/hmac/Cargo.toml index 65620d0..61463a6 100644 --- a/hmac/Cargo.toml +++ b/hmac/Cargo.toml @@ -18,6 +18,7 @@ digest = "0.9" [dev-dependencies] crypto-mac = { version = "0.11.0-pre", features = ["dev"] } md-5 = { version = "0.9", default-features = false } +sha-1 = { version = "0.9", default-features = false } sha2 = { version = "0.9", default-features = false } streebog = { version = "0.9", default-features = false } diff --git a/hmac/tests/data/wycheproof-sha1.blb b/hmac/tests/data/wycheproof-sha1.blb new file mode 100644 index 0000000..a4f8f43 Binary files /dev/null and b/hmac/tests/data/wycheproof-sha1.blb differ diff --git a/hmac/tests/data/wycheproof-sha256.blb b/hmac/tests/data/wycheproof-sha256.blb new file mode 100644 index 0000000..62f1d35 Binary files /dev/null and b/hmac/tests/data/wycheproof-sha256.blb differ diff --git a/hmac/tests/data/wycheproof-sha384.blb b/hmac/tests/data/wycheproof-sha384.blb new file mode 100644 index 0000000..69a7874 Binary files /dev/null and b/hmac/tests/data/wycheproof-sha384.blb differ diff --git a/hmac/tests/data/wycheproof-sha512.blb b/hmac/tests/data/wycheproof-sha512.blb new file mode 100644 index 0000000..e061fd5 Binary files /dev/null and b/hmac/tests/data/wycheproof-sha512.blb differ diff --git a/hmac/tests/lib.rs b/hmac/tests/lib.rs index 38714a0..f280c89 100644 --- a/hmac/tests/lib.rs +++ b/hmac/tests/lib.rs @@ -16,3 +16,81 @@ new_test!(hmac_sha512, "sha512", Hmac); // https://tc26.ru/standard/rs/Р 50.1.113-2016.pdf new_test!(hmac_streebog256, "streebog256", Hmac); new_test!(hmac_streebog512, "streebog512", Hmac); + +// TODO: use macro from crypto-mac crate +// use crypto_mac::new_trunc_test; + +macro_rules! new_trunc_test { + ($name:ident, $test_name:expr, $mac:ty) => { + #[test] + fn $name() { + use crypto_mac::dev::blobby::Blob3Iterator; + use crypto_mac::generic_array::typenum::Unsigned; + use crypto_mac::{Mac, NewMac}; + + fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { + let mut mac = <$mac as NewMac>::new_from_slice(key).unwrap(); + mac.update(input); + let result = mac.finalize_reset(); + let mut len = <$mac as Mac>::OutputSize::to_usize(); + if tag.len() < len { + len = tag.len(); + } + if &result.into_bytes()[..len] != tag { + return Some("whole message"); + } + // test if reset worked correctly + mac.update(input); + let result = mac.finalize(); + if &result.into_bytes()[..len] != tag { + return Some("after reset"); + } + + let mut mac = <$mac as NewMac>::new_from_slice(key).unwrap(); + // test reading byte by byte + for i in 0..input.len() { + mac.update(&input[i..i + 1]); + } + let result = mac.finalize(); + if &result.into_bytes()[..len] != tag { + return Some("message byte-by-byte"); + } + None + } + + let data = include_bytes!(concat!("data/", $test_name, ".blb")); + + for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { + let [key, input, tag] = row.unwrap(); + if let Some(desc) = run_test(key, input, tag) { + panic!( + "\n\ + Failed test №{}: {}\n\ + key:\t{:?}\n\ + input:\t{:?}\n\ + tag:\t{:?}\n", + i, desc, key, input, tag, + ); + } + } + } + }; +} + +// Test vectors from Wycheproof; these may include truncated tags. +new_trunc_test!(hmac_sha1_wycheproof, "wycheproof-sha1", Hmac); +new_trunc_test!( + hmac_sha256_wycheproof, + "wycheproof-sha256", + Hmac +); +new_trunc_test!( + hmac_sha384_wycheproof, + "wycheproof-sha384", + Hmac +); +new_trunc_test!( + hmac_sha512_wycheproof, + "wycheproof-sha512", + Hmac +);