1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//! SideFuzz is an adaptive fuzzer that uses a genetic-algorithim optimizer in combination with t-statistics to find side-channel (timing) vulnerabilities in cryptography compiled to wasm.
//!
//! See the [README](https://github.com/phayes/sidefuzz) for complete documentation.
//!
//! Creating a target in rust is done in the following way:
//!
//! ```rust,ignore
//! // lib.rs
//! #[no_mangle]
//! pub extern "C" fn fuzz() {
//! let input = sidefuzz::fetch_input(32); // 32 bytes of of fuzzing input as a &[u8]
//! sidefuzz::black_box(my_hopefully_constant_fn(input));
//! }
//! ```
//! ```toml
//! # Cargo.toml
//! [lib]
//! crate-type = ["cdylib"]
//!
//! [dependencies]
//! sidefuzz = "0.1.2"
//! ```
//! Compile and fuzz the target like so:
//!
//! ```bash
//! cargo build --release --target wasm32-unknown-unknown # Always build in release mode
//! sidefuzz fuzz ./target/wasm32-unknown-unknown/release/my_target.wasm # Fuzzing!
//! ```
// This section contains utility functions used by WASM targets
// ------------------------------------------------------------
/// A function that is opaque to the optimizer, to allow fuzzed functions to
/// pretend to use outputs to assist in avoiding dead-code elimination.
///
/// NOTE: We don't have a proper black box in stable Rust. This is
/// a workaround implementation, that may have a too big performance overhead,
/// depending on operation, or it may fail to properly avoid having code
/// optimized out. It is good enough that it is used.
// Assign a 1024 byte vector to hold inputs
lazy_static!
// The actual input length (generally less than 1024)
static mut INPUT_LEN: i32 = 0;
/// Get an input of the desired length.
/// This function should be called with a constant unchanging len argument.
/// Calling it with different lengths will result in invalid fuzzing.
///
/// Example:
/// ```ignore
/// let input = sidefuzz::fetch_input(32); // get 32 bytes of input
/// sidefuzz::black_box(my_contant_time_fn(input));
/// ```
///
// This is a VERY odd fuction that provides us with a really nice external API.
// 1. It is called once before fuzzing starts in order to set the size of INPUT.
// 2. After it is called once, we call input_pointer and input_len from the host to get a stable pointer to INPUT.
// 3. Fuzzing starts, we write data to INPUT from the host, then call the exported `fuzz` function.
/// Get a pointer to the input array
/// This needs to be public so we can call it across host/wasm boundary,
/// but it should be considered a "private" function to sidefuzz.
/// It's API is not stable and may be subject to change
pub extern "C"
/// Get the length of the input array
/// This needs to be public so we can call it across host/wasm boundary,
/// but it should be considered a "private" function to sidefuzz.
/// It's API is not stable and may be subject to change
pub extern "C"