xref: /aosp_15_r20/external/boringssl/src/FUZZING.md (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker# Fuzz testing
2*8fb009dcSAndroid Build Coastguard Worker
3*8fb009dcSAndroid Build Coastguard WorkerModern fuzz testers are very effective and we wish to use them to ensure that no silly bugs creep into BoringSSL.
4*8fb009dcSAndroid Build Coastguard Worker
5*8fb009dcSAndroid Build Coastguard WorkerWe use Clang's [libFuzzer](http://llvm.org/docs/LibFuzzer.html) for fuzz testing and there are a number of fuzz testing functions in `fuzz/`. They are not built by default because they require that the rest of BoringSSL be built with some changes that make fuzzing much more effective, but are completely unsafe for real use.
6*8fb009dcSAndroid Build Coastguard Worker
7*8fb009dcSAndroid Build Coastguard WorkerIn order to build the fuzz tests you will need at least Clang 6.0. Pass `-DFUZZ=1` on the CMake command line to enable building BoringSSL with coverage and AddressSanitizer, and to build the fuzz test binaries. You'll probably need to set the `CC` and `CXX` environment variables too, like this:
8*8fb009dcSAndroid Build Coastguard Worker
9*8fb009dcSAndroid Build Coastguard Worker```
10*8fb009dcSAndroid Build Coastguard WorkerCC=clang CXX=clang++ cmake -GNinja -DFUZZ=1 -B build
11*8fb009dcSAndroid Build Coastguard Workerninja -C build
12*8fb009dcSAndroid Build Coastguard Worker```
13*8fb009dcSAndroid Build Coastguard Worker
14*8fb009dcSAndroid Build Coastguard Worker
15*8fb009dcSAndroid Build Coastguard WorkerFrom the `build/` directory, you can then run the fuzzers. For example:
16*8fb009dcSAndroid Build Coastguard Worker
17*8fb009dcSAndroid Build Coastguard Worker```
18*8fb009dcSAndroid Build Coastguard Worker./fuzz/cert -max_len=10000 -jobs=32 -workers=32 ../fuzz/cert_corpus/
19*8fb009dcSAndroid Build Coastguard Worker```
20*8fb009dcSAndroid Build Coastguard Worker
21*8fb009dcSAndroid Build Coastguard WorkerThe arguments to `jobs` and `workers` should be the number of cores that you wish to dedicate to fuzzing. By default, libFuzzer uses the largest test in the corpus (or 64 if empty) as the maximum test case length. The `max_len` argument overrides this.
22*8fb009dcSAndroid Build Coastguard Worker
23*8fb009dcSAndroid Build Coastguard WorkerThe recommended values of `max_len` for each test are:
24*8fb009dcSAndroid Build Coastguard Worker
25*8fb009dcSAndroid Build Coastguard Worker| Test          | `max_len` value |
26*8fb009dcSAndroid Build Coastguard Worker|---------------|-----------------|
27*8fb009dcSAndroid Build Coastguard Worker| `bn_div`      | 384             |
28*8fb009dcSAndroid Build Coastguard Worker| `bn_mod_exp`  | 4096            |
29*8fb009dcSAndroid Build Coastguard Worker| `cert`        | 10000           |
30*8fb009dcSAndroid Build Coastguard Worker| `client`      | 20000           |
31*8fb009dcSAndroid Build Coastguard Worker| `pkcs8`       | 2048            |
32*8fb009dcSAndroid Build Coastguard Worker| `privkey`     | 2048            |
33*8fb009dcSAndroid Build Coastguard Worker| `server`      | 4096            |
34*8fb009dcSAndroid Build Coastguard Worker| `session`     | 8192            |
35*8fb009dcSAndroid Build Coastguard Worker| `spki`        | 1024            |
36*8fb009dcSAndroid Build Coastguard Worker| `read_pem`    | 512             |
37*8fb009dcSAndroid Build Coastguard Worker| `ssl_ctx_api` | 256             |
38*8fb009dcSAndroid Build Coastguard Worker
39*8fb009dcSAndroid Build Coastguard WorkerThese were determined by rounding up the length of the largest case in the corpus.
40*8fb009dcSAndroid Build Coastguard Worker
41*8fb009dcSAndroid Build Coastguard WorkerThere are directories in `fuzz/` for each of the fuzzing tests which contain seed files for fuzzing. Some of the seed files were generated manually but many of them are “interesting” results generated by the fuzzing itself. (Where “interesting” means that it triggered a previously unknown path in the code.)
42*8fb009dcSAndroid Build Coastguard Worker
43*8fb009dcSAndroid Build Coastguard Worker## Minimising the corpora
44*8fb009dcSAndroid Build Coastguard Worker
45*8fb009dcSAndroid Build Coastguard WorkerWhen a large number of new seeds are available, it's a good idea to minimise the corpus so that different seeds that trigger the same code paths can be deduplicated.
46*8fb009dcSAndroid Build Coastguard Worker
47*8fb009dcSAndroid Build Coastguard WorkerIn order to minimise all the corpora, build for fuzzing and run `./fuzz/minimise_corpora.sh`. Note that minimisation is, oddly, often not idempotent for unknown reasons.
48*8fb009dcSAndroid Build Coastguard Worker
49*8fb009dcSAndroid Build Coastguard Worker## Fuzzer mode
50*8fb009dcSAndroid Build Coastguard Worker
51*8fb009dcSAndroid Build Coastguard WorkerWhen `-DFUZZ=1` is passed into CMake, BoringSSL builds with `BORINGSSL_UNSAFE_FUZZER_MODE` and `BORINGSSL_UNSAFE_DETERMINISTIC_MODE` defined. This modifies the library to be more friendly to fuzzers. If `BORINGSSL_UNSAFE_DETERMINISTIC_MODE` is set, BoringSSL will:
52*8fb009dcSAndroid Build Coastguard Worker
53*8fb009dcSAndroid Build Coastguard Worker* Replace `RAND_bytes` with a deterministic PRNG. Call `RAND_reset_for_fuzzing()` at the start of fuzzers which use `RAND_bytes` to reset the PRNG state.
54*8fb009dcSAndroid Build Coastguard Worker
55*8fb009dcSAndroid Build Coastguard Worker* Use a hard-coded time instead of the actual time.
56*8fb009dcSAndroid Build Coastguard Worker
57*8fb009dcSAndroid Build Coastguard WorkerAdditionally, if `BORINGSSL_UNSAFE_FUZZER_MODE` is set, BoringSSL will:
58*8fb009dcSAndroid Build Coastguard Worker
59*8fb009dcSAndroid Build Coastguard Worker* Modify the TLS stack to perform all signature checks (CertificateVerify and ServerKeyExchange) and the Finished check, but always act as if the check succeeded.
60*8fb009dcSAndroid Build Coastguard Worker
61*8fb009dcSAndroid Build Coastguard Worker* Treat every cipher as the NULL cipher.
62*8fb009dcSAndroid Build Coastguard Worker
63*8fb009dcSAndroid Build Coastguard Worker* Tickets are unencrypted and the MAC check is performed but ignored.
64*8fb009dcSAndroid Build Coastguard Worker
65*8fb009dcSAndroid Build Coastguard Worker* renegotiation\_info checks are ignored.
66*8fb009dcSAndroid Build Coastguard Worker
67*8fb009dcSAndroid Build Coastguard WorkerThis is to prevent the fuzzer from getting stuck at a cryptographic invariant in the protocol.
68*8fb009dcSAndroid Build Coastguard Worker
69*8fb009dcSAndroid Build Coastguard Worker## TLS transcripts
70*8fb009dcSAndroid Build Coastguard Worker
71*8fb009dcSAndroid Build Coastguard WorkerThe `client` and `server` corpora are seeded from the test suite. The test suite has a `-fuzzer` flag which mirrors the fuzzer mode changes above and a `-deterministic` flag which removes all non-determinism on the Go side. Not all tests pass, so `ssl/test/runner/fuzzer_mode.json` contains the necessary suppressions. The `run_tests` target will pass appropriate command-line flags.
72*8fb009dcSAndroid Build Coastguard Worker
73*8fb009dcSAndroid Build Coastguard WorkerThere are separate corpora, `client_corpus_no_fuzzer_mode` and `server_corpus_no_fuzzer_mode`. These are transcripts for fuzzers with only `BORINGSSL_UNSAFE_DETERMINISTIC_MODE` defined. To build in this mode, pass `-DNO_FUZZER_MODE=1` into CMake. This configuration is run in the same way but without `-fuzzer` and `-shim-config` flags.
74*8fb009dcSAndroid Build Coastguard Worker
75*8fb009dcSAndroid Build Coastguard WorkerIf both sets of tests pass, refresh the fuzzer corpora with `refresh_ssl_corpora.sh`:
76*8fb009dcSAndroid Build Coastguard Worker
77*8fb009dcSAndroid Build Coastguard Worker```
78*8fb009dcSAndroid Build Coastguard Workercd fuzz
79*8fb009dcSAndroid Build Coastguard Worker./refresh_ssl_corpora.sh /path/to/fuzzer/mode/build /path/to/non/fuzzer/mode/build
80*8fb009dcSAndroid Build Coastguard Worker```
81