-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[fuzzing] Implementing initial support for fuzzing LMS (#618)
* treewide: Refactor SHA256 driver into an implemented trait `Sha256HardwareDriver` is now the primary implementation of `Sha256`. Where a concrete implementation is required, `Sha256HardwareDriver` is almost always the correct instance. This refactor makes it easier to test consumers of this driver, where software implementations of SHA256 may be preferred. Follow-up commits will provide a software implementation, which will then be used for fuzz testing the LMS driver. Signed-off-by: Benjamin Doron <[email protected]> * [fuzzing] Implement initial support for LMS driver fuzzing Instructions for running the supported fuzzers can be found at https://gist.github.com/benjamindoron/59313b863b079f6f5af56af83d32648e. This can be migrated to official documentation. Signed-off-by: Benjamin Doron <[email protected]> * Make Sha256 driver refactor as minimal as possible. Signed-off-by: Benjamin Doron <[email protected]> Co-authored-by: Kor Nielsen <[email protected]>
- Loading branch information
1 parent
00b0503
commit 8d1f779
Showing
12 changed files
with
230 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
target | ||
corpus | ||
artifacts | ||
coverage | ||
*.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Licensed under the Apache-2.0 license | ||
|
||
[package] | ||
name = "caliptra-drivers-fuzz" | ||
version = "0.0.0" | ||
publish = false | ||
edition = "2021" | ||
|
||
[package.metadata] | ||
cargo-fuzz = true | ||
|
||
[dependencies] | ||
libfuzzer-sys = { version = "0.4.6", optional = true } | ||
afl = { version = "0.13.3", optional = true } | ||
zerocopy = "0.6.1" | ||
arbitrary = { version = "1.3.0", optional = true, features = ["derive"] } | ||
sha2 = { version = "0.10.2", default-features = false, features = ["compress"] } | ||
|
||
[patch.crates-io] | ||
byteorder = { git = "https://github.com/benjamindoron/byteorder.git", branch = "struct_aware-1.4.3" } | ||
zerocopy = { git = "https://github.com/benjamindoron/zerocopy.git", branch = "struct_aware-v0.6.3" } | ||
|
||
[dependencies.caliptra-drivers] | ||
path = ".." | ||
|
||
[dependencies.caliptra-image-types] | ||
path = "../../image/types" | ||
features = ["arbitrary"] | ||
|
||
[dependencies.caliptra-lms-types] | ||
path = "../../lms-types" | ||
features = ["arbitrary"] | ||
|
||
[features] | ||
struct-aware = ["arbitrary"] | ||
|
||
# Prevent this from interfering with workspaces | ||
[workspace] | ||
members = ["."] | ||
|
||
[profile.release] | ||
debug = 1 | ||
|
||
[[bin]] | ||
name = "fuzz_target_lms" | ||
path = "src/fuzz_target_lms.rs" | ||
test = false | ||
doc = false |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// Licensed under the Apache-2.0 license | ||
|
||
#![cfg_attr(feature = "libfuzzer-sys", no_main)] | ||
|
||
#[cfg(all(not(feature = "libfuzzer-sys"), not(feature = "afl")))] | ||
compile_error!("Either feature \"libfuzzer-sys\" or \"afl\" must be enabled!"); | ||
|
||
#[cfg(feature = "libfuzzer-sys")] | ||
use libfuzzer_sys::fuzz_target; | ||
|
||
#[cfg(feature = "afl")] | ||
use afl::fuzz; | ||
|
||
#[cfg(not(feature = "struct-aware"))] | ||
use std::mem::size_of; | ||
|
||
#[cfg(not(feature = "struct-aware"))] | ||
use zerocopy::FromBytes; | ||
|
||
use caliptra_drivers::Lms; | ||
mod sha256; | ||
use sha256::Sha256SoftwareDriver; | ||
|
||
// For consistency with the ROM, use its type definitions | ||
use caliptra_image_types::{ImageLmsPublicKey, ImageLmsSignature}; | ||
|
||
#[cfg(feature = "struct-aware")] | ||
#[derive(arbitrary::Arbitrary, Debug)] | ||
struct StructuredInput<'a> { | ||
pub_key: ImageLmsPublicKey, | ||
sig: ImageLmsSignature, | ||
input: &'a [u8], | ||
} | ||
|
||
#[cfg(feature = "struct-aware")] | ||
fn harness_structured(args: StructuredInput) { | ||
let _result = Lms::default().verify_lms_signature_generic( | ||
&mut Sha256SoftwareDriver::new(), | ||
args.input, | ||
&args.pub_key, | ||
&args.sig, | ||
); | ||
} | ||
|
||
#[cfg(not(feature = "struct-aware"))] | ||
fn harness_unstructured(data: &[u8]) { | ||
if data.len() < (size_of::<ImageLmsPublicKey>() + size_of::<ImageLmsSignature>()) { | ||
return; | ||
} | ||
|
||
// The corpus is seeded with (pub_key, sig, input), so parse the data in this order | ||
let mut offset = 0; | ||
let pub_key = ImageLmsPublicKey::read_from_prefix(data).unwrap(); | ||
offset += size_of::<ImageLmsPublicKey>(); | ||
let sig = ImageLmsSignature::read_from_prefix(&data[offset..]).unwrap(); | ||
offset += size_of::<ImageLmsSignature>(); | ||
let input = &data[offset..]; | ||
|
||
let _result = Lms::default().verify_lms_signature_generic( | ||
&mut Sha256SoftwareDriver::new(), | ||
input, | ||
&pub_key, | ||
&sig, | ||
); | ||
} | ||
|
||
// cargo-fuzz target | ||
#[cfg(all(feature = "libfuzzer-sys", not(feature = "struct-aware")))] | ||
fuzz_target!(|data: &[u8]| { | ||
harness_unstructured(data); | ||
}); | ||
|
||
#[cfg(all(feature = "libfuzzer-sys", feature = "struct-aware"))] | ||
fuzz_target!(|data: StructuredInput| { | ||
harness_structured(data); | ||
}); | ||
|
||
// cargo-afl target | ||
#[cfg(all(feature = "afl", not(feature = "struct-aware")))] | ||
fn main() { | ||
fuzz!(|data: &[u8]| { | ||
harness_unstructured(data); | ||
}); | ||
} | ||
|
||
#[cfg(all(feature = "afl", feature = "struct-aware"))] | ||
fn main() { | ||
fuzz!(|data: StructuredInput| { | ||
harness_structured(data); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Licensed under the Apache-2.0 license | ||
|
||
use caliptra_drivers::{Array4x8, CaliptraResult, Sha256Alg, Sha256DigestOp}; | ||
use std::marker::PhantomData; | ||
|
||
use sha2::Digest; | ||
|
||
#[derive(Default)] | ||
pub struct Sha256SoftwareDriver {} | ||
|
||
pub struct Sha256DigestOpSw<'a> { | ||
driver: PhantomData<&'a mut Sha256SoftwareDriver>, | ||
digest: sha2::Sha256, | ||
} | ||
impl<'a> Sha256DigestOp<'a> for Sha256DigestOpSw<'a> { | ||
fn update(&mut self, data: &[u8]) -> CaliptraResult<()> { | ||
self.digest.update(data); | ||
Ok(()) | ||
} | ||
fn finalize(self, digest: &mut Array4x8) -> CaliptraResult<()> { | ||
let result = self.digest.finalize(); | ||
*digest = Array4x8::from(<[u8; 32]>::try_from(result.as_slice()).unwrap()); | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl Sha256Alg for Sha256SoftwareDriver { | ||
type DigestOp<'a> = Sha256DigestOpSw<'a>; | ||
|
||
fn digest(&mut self, buf: &[u8]) -> CaliptraResult<Array4x8> { | ||
let result = sha2::Sha256::digest(buf); | ||
Ok(Array4x8::from(<[u8; 32]>::try_from(result).unwrap())) | ||
} | ||
|
||
fn digest_init(&mut self) -> CaliptraResult<Self::DigestOp<'_>> { | ||
Ok(Sha256DigestOpSw { | ||
driver: PhantomData::default(), | ||
digest: sha2::Sha256::new(), | ||
}) | ||
} | ||
} | ||
|
||
impl Sha256SoftwareDriver { | ||
pub fn new() -> Self { | ||
Self {} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters