blob: 89cf5e9302b26c3d703c514d4cb87c75296d5a6d [file] [log] [blame] [view]
Adam Langley9a4beb82015-11-09 13:57:26 -08001# Fuzz testing
2
3Modern fuzz testers are very effective and we wish to use them to ensure that no silly bugs creep into BoringSSL.
4
Adam Langley9c969bf2018-08-24 10:46:01 -07005We 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.
Adam Langley9a4beb82015-11-09 13:57:26 -08006
Adam Langley9c969bf2018-08-24 10:46:01 -07007In 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:
Adam Langley7104cc92015-11-10 15:00:51 -08008
9```
David Benjamin1a5570b2023-04-19 15:38:47 -040010CC=clang CXX=clang++ cmake -GNinja -DFUZZ=1 -B build
11ninja -C build
Adam Langley7104cc92015-11-10 15:00:51 -080012```
13
Adam Langley7104cc92015-11-10 15:00:51 -080014
Adam Langley9a4beb82015-11-09 13:57:26 -080015From the `build/` directory, you can then run the fuzzers. For example:
16
17```
David Benjamin2ad3c982016-12-10 11:44:45 -050018./fuzz/cert -max_len=10000 -jobs=32 -workers=32 ../fuzz/cert_corpus/
Adam Langley9a4beb82015-11-09 13:57:26 -080019```
20
David Benjamin9539ebb2016-03-21 18:24:53 -040021The 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
Max Moroz188487f2016-04-11 15:36:49 +020023The recommended values of `max_len` for each test are:
24
Adam Langley3871dc92016-10-02 10:03:36 -070025| Test | `max_len` value |
26|---------------|-----------------|
Adam Langley31f94b02019-10-21 09:03:49 -070027| `bn_div` | 384 |
Adam Langley9c969bf2018-08-24 10:46:01 -070028| `bn_mod_exp` | 4096 |
David Benjamin2ad3c982016-12-10 11:44:45 -050029| `cert` | 10000 |
Adam Langley3871dc92016-10-02 10:03:36 -070030| `client` | 20000 |
31| `pkcs8` | 2048 |
32| `privkey` | 2048 |
33| `server` | 4096 |
Robert Sloan15073af2016-11-29 10:52:24 -080034| `session` | 8192 |
Adam Langley3871dc92016-10-02 10:03:36 -070035| `spki` | 1024 |
36| `read_pem` | 512 |
37| `ssl_ctx_api` | 256 |
Max Moroz188487f2016-04-11 15:36:49 +020038
39These were determined by rounding up the length of the largest case in the corpus.
Adam Langley9a4beb82015-11-09 13:57:26 -080040
41There 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.)
Adam Langley7104cc92015-11-10 15:00:51 -080042
David Benjamin5545b612021-04-14 16:23:27 -040043## Minimising the corpora
Adam Langleyddcc1862016-03-03 09:50:25 -080044
45When 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
David Benjamin5545b612021-04-14 16:23:27 -040047In 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.
David Benjamine11988f2016-03-21 15:55:19 -040048
49## Fuzzer mode
50
David Benjaminec978dd2016-11-04 18:59:33 -040051When `-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:
David Benjamine11988f2016-03-21 15:55:19 -040052
53* 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
David Benjaminec978dd2016-11-04 18:59:33 -040055* Use a hard-coded time instead of the actual time.
56
57Additionally, if `BORINGSSL_UNSAFE_FUZZER_MODE` is set, BoringSSL will:
58
David Benjamine11988f2016-03-21 15:55:19 -040059* 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
61* Treat every cipher as the NULL cipher.
62
David Benjaminfbc45d72016-09-22 01:21:24 -040063* Tickets are unencrypted and the MAC check is performed but ignored.
64
David Benjamin9343b0b2017-07-01 00:31:27 -040065* renegotiation\_info checks are ignored.
66
David Benjamine11988f2016-03-21 15:55:19 -040067This is to prevent the fuzzer from getting stuck at a cryptographic invariant in the protocol.
David Benjamin1e663e82016-09-22 01:02:13 -040068
69## TLS transcripts
70
David Benjaminfd066012016-11-15 00:47:17 -050071The `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
David Benjamin13f1f172017-07-06 11:15:09 -040073There 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.
David Benjaminfd066012016-11-15 00:47:17 -050074
75If both sets of tests pass, refresh the fuzzer corpora with `refresh_ssl_corpora.sh`:
David Benjamin1e663e82016-09-22 01:02:13 -040076
77```
David Benjaminfd066012016-11-15 00:47:17 -050078cd fuzz
David Benjamin519118f2017-03-30 12:33:29 -040079./refresh_ssl_corpora.sh /path/to/fuzzer/mode/build /path/to/non/fuzzer/mode/build
David Benjamin1e663e82016-09-22 01:02:13 -040080```