diff --git a/.gitignore b/.gitignore index ea8c4bf7..a58b3517 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ /target +/fuzz/corpus +/fuzz/artifacts +/fuzz/coverage \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 57c2fc1e..1d4e4de2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,6 +67,15 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "arbitrary" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2e1373abdaa212b704512ec2bd8b26bd0b7d5c3f70117411a5d9a451383c859" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -115,6 +124,7 @@ version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ + "jobserver", "libc", ] @@ -223,6 +233,17 @@ dependencies = [ "typenum", ] +[[package]] +name = "derive_arbitrary" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "digest" version = "0.10.7" @@ -296,6 +317,15 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "fuzz" +version = "0.1.0" +dependencies = [ + "arbitrary", + "libfuzzer-sys", + "lockstitch", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -350,6 +380,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -362,6 +401,17 @@ version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + [[package]] name = "libm" version = "0.2.8" diff --git a/Cargo.toml b/Cargo.toml index 03a74d21..2a6f03c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ portable = ["aes"] std = [] [workspace] -members = ["xtask"] +members = ["fuzz", "xtask"] [dev-dependencies] divan = "0.1.0" diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml new file mode 100644 index 00000000..5a5608ab --- /dev/null +++ b/fuzz/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "fuzz" +version = "0.1.0" +edition = "2021" + +[dependencies] +arbitrary = { version = "1.3.1", features = ["derive"] } +libfuzzer-sys = "0.4.7" +lockstitch = { path = ".." } + +[[bin]] +name = "aead" +path = "fuzz_targets/aead.rs" + +[[bin]] +name = "hash" +path = "fuzz_targets/hash.rs" + +[[bin]] +name = "new" +path = "fuzz_targets/new.rs" + +[package.metadata] +cargo-fuzz = true + +[package.metadata.release] +release = false diff --git a/fuzz/fuzz_targets/aead.rs b/fuzz/fuzz_targets/aead.rs new file mode 100644 index 00000000..81cc228a --- /dev/null +++ b/fuzz/fuzz_targets/aead.rs @@ -0,0 +1,23 @@ +#![no_main] +use arbitrary::Arbitrary; +use libfuzzer_sys::fuzz_target; +use lockstitch::{Protocol, TAG_LEN}; + +#[derive(Debug, Arbitrary)] +struct Input { + key: Vec, + nonce: Vec, + ad: Vec, + plaintext: Vec, +} + +fuzz_target!(|input: Input| { + let mut aead = Protocol::new("lockstitch.fuzz.aead"); + aead.mix(&input.key); + aead.mix(&input.nonce); + aead.mix(&input.ad); + + let mut ciphertext = input.plaintext.clone(); + ciphertext.extend_from_slice(&[0u8; TAG_LEN]); + aead.seal(&mut ciphertext); +}); diff --git a/fuzz/fuzz_targets/hash.rs b/fuzz/fuzz_targets/hash.rs new file mode 100644 index 00000000..d7d5ef7a --- /dev/null +++ b/fuzz/fuzz_targets/hash.rs @@ -0,0 +1,9 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; +use lockstitch::Protocol; + +fuzz_target!(|data: &[u8]| { + let mut hash = Protocol::new("lockstitch.fuzz.hash"); + hash.mix(data); + let _ = hash.derive_array::<32>(); +}); diff --git a/fuzz/fuzz_targets/new.rs b/fuzz/fuzz_targets/new.rs new file mode 100644 index 00000000..cfbe79a3 --- /dev/null +++ b/fuzz/fuzz_targets/new.rs @@ -0,0 +1,11 @@ +#![no_main] +use std::str; + +use libfuzzer_sys::fuzz_target; +use lockstitch::Protocol; + +fuzz_target!(|data: &[u8]| { + if let Ok(utf8) = str::from_utf8(data) { + let _ = Protocol::new(utf8); + } +});