Overview
Implementation
From an implementation perspective, several modules exist to make the fuzzer reusable.
Fuzzing loop
The main fuzzing loop is made of the following modules, each at a different layer (from high-level to low-level):
puffin: Core fuzzing engine which is protocol- and target-agnostic. It deals at a high level with the terms algebra, the input traces and the fuzzing process (scheduling, logging, mutations, ...). This module is built on top of thelibAFLcrate.tlspuffin: TLS fuzzer which instantiatespuffinto the TLS protocol and is PUTs-agnostic. It notably instantiates the traces to TLS traces with the TLS-specific terms and functions for the TLS terms algebra, based on therustlscrate (e.g., ECSDA signatures, ECDHE encryption, ClientHello, etc.).harness, for example for OpenSSL PUTs: harness/openssl - Harnesses for some PUTs.
Finally, other protocols and PUTs can be fuzzed as well, by extending the fuzzer at layer 2. (new protocols) and 3. (new PUTs harnesses).. We did a preliminary version of those for SSH and OpenSSH in the module sshpuffin (WIP).
The following diagram shows the dependencies between the modules:
The interfaces between the modules are defined by the following Rust traits which define what a protocol is and what a PUT harness is:
ProtocolBehavior and Put<PB: ProtocolBehavior>.
Program Under Tests (PUTs)
The fuzzer then requires a target (that is a harness linked to some PUT) to fuzz. To build the PUTs (vendor libraries) and link them to the fuzzer, the following tooling is used:
puffin-build(generates themk_vendortool): contains a crate implements the build process, from creating PUTs (vendor libraries) to linking PUTs into the fuzzer (through some fuzzing harness).
Benchmarks
To benchmark the fuzzer and perform regression tests, the following tooling is used:
- puffin-bench: performance testbench for the
puffinfuzzer (external tooling; not part to thepuffincrate), see benchmarks.
Setup
The rest of this page is currently under development. Information presented here might be incomplete or outdated.
Configure your environment for developement on the puffin project:
- nix
- editor setup
- vscode (recommended extensions, change default features, ...)
Testing my changes
- justfile: use
just fmtfor code formatting,just checkfor basic checks, andjust check-workspacefor more advanced checks. Under-the-hood, it uses:- rustfmt
- clang-format
- cargo clippy
- cargo bench
- github PRs/github CI: use the PR's labels
ci:none,ci:fast,ci:fullto fine-tune the CI checks. The full checks (ci-full) must be checked prior to merging PRs. - puffin-bench: run
uv run benchmarkfor end-to-end, long, and comprehensive regressions and performance checks, see benchmarks.