Fuzzing The Library

Botan comes with a set of fuzzing endpoints which can be used to test the library.

Fuzzing with libFuzzer

As of Clang Version 6.0 libFuzzer is automatically included in the compiler. Therefore you don’t need to install any new software. You can build the fuzzers by running

$ ./configure.py --cc=clang --build-fuzzer=libfuzzer --enable-sanitizers=fuzzer
$ make fuzzers

The option –enable-sanitizers=fuzzer compiles the library for coverage-guided fuzzing. You can add additional sanitizers like address, undefined and memory or with/without additional information during building by either adding –unsafe-fuzzer-mode or –with-debug-info. The coverage sanitizer is not compatible with this configuration.

If you want to link additional libraries you can use the –with-fuzzer-lib option while configuring the build with configure.py. The fuzzer binaries will be in build/fuzzer. Simply pick one and run it, optionally also passing a directory containing corpus inputs. Running

$ make fuzzer_corpus

downloads a specific corpus from https://github.com/randombit/crypto-corpus.git. Together with

$ ./src/scripts/test_fuzzers.py fuzzer_corpus build/fuzzer

you can test the Fuzzers.

Fuzzing with AFL++

Please make sure that you have installed AFL++ according to https://aflplus.plus/building/. The version of Clang should match the version of afl-clang-fast++/ afl-clang-fast. You can fuzz with AFL++ in LLVM mode (https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.llvm.md) by running

$ ./configure.py --cc=clang --with-sanitizers --build-fuzzer=afl --unsafe-fuzzer-mode --cc-bin=afl-clang-fast++
$ make fuzzers

For AFL++ in GCC mode make sure that you have afl-g++-fast installed. Otherwise follow https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.gcc_plugin.md to build and install it. You can configure the build by running

$ ./configure.py --cc=gcc --with-sanitizers --build-fuzzer=afl --unsafe-fuzzer-mode --cc-bin=afl-g++-fast
$ make fuzzers

The fuzzer binaries will be in build/fuzzer. To run them you need to run under afl-fuzz:

$ afl-fuzz -i corpus_path -o output_path ./build/fuzzer/binary

Fuzzing with TLS-Attacker

TLS-Attacker (https://github.com/RUB-NDS/TLS-Attacker) includes a mode for fuzzing TLS servers. A prebuilt copy of TLS-Attacker is available in a git repository:

$ git clone --depth 1 https://github.com/randombit/botan-ci-tools.git

To run it against Botan’s server:

$ ./configure.py --with-sanitizers
$ make botan
$ ./src/scripts/run_tls_attacker.py ./botan ./botan-ci-tools

Output and logs from the fuzzer are placed into /tmp. See the TLS-Attacker documentation for more information about how to use this tool.

Input Corpus

AFL requires an input corpus, and libFuzzer can certainly make good use of it.

Some other crypto corpus repositories include

Adding new fuzzers

New fuzzers are created by adding a source file to src/fuzzers which have the signature:

void fuzz(std::span<const uint8_t> in)

After adding your fuzzer, rerun ./configure.py and build.