Skip to main content

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):

  1. 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 the libAFL crate.
  2. tlspuffin: TLS fuzzer which instantiates puffin to 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 the rustls crate (e.g., ECSDA signatures, ECDHE encryption, ClientHello, etc.).
  3. 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 the mk_vendor tool): 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 puffin fuzzer (external tooling; not part to the puffin crate), see benchmarks.

Setup​

Ongoing Work

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 fmt for code formatting, just check for basic checks, and just check-workspace for 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:full to fine-tune the CI checks. The full checks (ci-full) must be checked prior to merging PRs.
  • puffin-bench: run uv run benchmark for end-to-end, long, and comprehensive regressions and performance checks, see benchmarks.