googleinterns, updated 🕥 2023-01-20 06:08:48

Fuzzing Hardware Like Software

Maintainer: Timothy Trippel
Personal Website:

Figure 1: Fuzzing Hardware Like Software.

Due to the economic and reputational incentives to design and fabricate flawless hardware, design verification research has been an active arena. Unfortunately the fruits of this labor mainly consist of strategies concentrated at two extremes: 1) broad coverage through constrained random verification, or 2) (bounded) formal verification. Moreover, both of these techniques require extensive implementation knowledge of the Design Under Test (DUT) to be effective.

To close this gap, we propose fuzzing hardware like software to automate test vector generation in an intelligent manner---that boosts coverage---without requiring expensive Design Verification (DV) engineers and tools. A technical paper describing this project can be found here.

In this project, we demonstrate how to translate RTL hardware to a software model, and leverage coverage-guided software fuzzers---like AFL---to automate test vector generation for hardware verification (Figure 1). Specifically we demonstrate this technique on hardware from the OpenTitan IP ecosystem. While we do not suggest this as a replacement to traditional DV methods for sign-off, we argue this technique serves a low-cost preventative mechanism to identify complex hardware vulnerabilities before they are exploited for malice.

To understand the layout of this project and how to get started, read below.

Directory Structure


This directory currently only contains a document that describes how to contribute to this project and some figures that are displayed in this README. However, it will be the location of any future documentation that is added.


This directory contains some python scripts to automate launching large batches of fuzzing experiments on GCP VMs. Additionally there are some scripts that can be used to plot fuzzing data using Seaborn/Matplotlib.


This directory contains several supporting files to fuzz various various OpenTitan hardware IP blocks. Currently, the following OpenTitan IP blocks are supported: AES, HMAC, KMAC, and the RV Timer. Additionally, a subdirectory called ot_template can be copied, and the files within edited, to bring-up another OpenTitan IP block for fuzzing. Lastly, a custom digital lock hardware block is included to stress test our fuzzing infrastructure. This block is actually autogenerated by a tool written in Rust (using the kaze crate). For more details checkout the technical paper linked above.


This directory contains several subdirectories that contain Dockerfiles and Shell/Python scripts that makeup a containerized infrastructure for fuzzing hardware designs at scale. This infrastructure is modeled after Google's OSS-Fuzz project. This infrastructure can be used to jumpstart fuzzing hardware locally or on GCP (provided you have an active account). See Getting Started below for how to build this infrastructure. Read the technical paper above for exactly what is included in the fuzzing infrastructure.


This directory contains some HJSON fuzzing configuration files along with a Python script to test the overall fuzzing infrastructure is successfully simulating OpenTitan hardware.

Getting Started

I. Clone/Fork Repository

  1. git clone
  2. cd hw-fuzzing

II. Set Environment Variables

To use any of the fuzzing infrastructure, which consists of: 1) building several Docker images to isolate fuzzing each target hardware IP block, and 2) using two (included) Python packages, some environment variables must be set. You can set them system wide, however, I recommend using the direnv tool to set/unset them when you enter/leave your hw-fuzzing project directory.

Using direnv (assuming it is installed):
  1. Create a .envrc file in the hw-fuzzing root directory with the following:

export HW_FUZZING=$(pwd) export PYTHONPATH="./:../:$(pwd)/infra/hwfp:$(pwd)/infra/base-sim/hwfutils"

  1. direnv allow
Setting system-wide:

Add the above two lines to your .bashrc or .zshrc (depending on the shell you use), except replace the \$(pwd) within each statement with the global path to your hw-fuzzing directory.

III. Install Python Dependencies

The automated Hardware Fuzzing Pipeline (HWFP) Python tooling is tested using Python 3.8, and requires the following dependencies.

  1. Create Python virtual environment (not required, but recommended).
  2. Activate virtual environment (if you made one).
  3. pip install -r infra/hwfp/requirements.txt
  4. pip install -r infra/base-sim/hwfutils/requirements.txt

IV. Install Docker

V. Build Docker Infrastructure

  1. make build-infra
  2. Grab a cup of coffee ☕... this will take a while since we are building LLVM here.

VI. Fuzz a Design

a. Fuzzing Locally
  1. make fuzz-<core> where <core> is [aes, hmac, kmac, rv_timer] to launch interactive container.
  2. run to begin RTL translation, intrustmentation, and fuzzing (if in manual mode, which is default, otherwise this step can be skipped).
  3. Press Ctrl+c to terminate fuzzing and begin final coverage tracing.
b. Fuzzing on GCP
  1. Create GCP account.
  2. Create a GCS bucket to store all fuzzing data.
  3. Edit the gcp_config.hjson file with your GCP project details.
  4. Edit the value for the run_on_gcp key in the cpp_afl.hjson configuration file for the core you want to fuzz in hw/<core>/.
  5. Run make fuzz-<core>


HW Fuzzing Results

opened on 2023-03-02 16:22:31 by rsar97


Once the hw fuzzing is completed, how can we extract the results. There is no output files after the HW is fuzzed .

Fixes for infra build

opened on 2023-01-20 05:52:29 by addisoncrump

Multiple python packages have upgraded in such a way that they are no longer compatible with Ubuntu 18.04, at least as used here. This PR provides the necessary changes to a) successfully complete the docker build for all of the base images and b) improve build time by utilising CPUs more effectively.

Bump mako from 1.1.3 to 1.2.2 in /infra/base-sim

opened on 2022-09-16 18:32:10 by dependabot[bot]

Bumps mako from 1.1.3 to 1.2.2.

Release notes

Sourced from mako's releases.


Released: Mon Aug 29 2022


  • [bug] [lexer] Fixed issue in lexer where the regexp used to match tags would not correctly interpret quoted sections individually. While this parsing issue still produced the same expected tag structure later on, the mis-handling of quoted sections was also subject to a regexp crash if a tag had a large number of quotes within its quoted sections.

    References: #366


Released: Thu Jun 30 2022


  • [bug] [tests] Various fixes to the test suite in the area of exception message rendering to accommodate for variability in Python versions as well as Pygments.

    References: #360


  • [performance] Optimized some codepaths within the lexer/Python code generation process, improving performance for generation of templates prior to their being cached. Pull request courtesy Takuto Ikuta.

    References: #361


Released: Thu Mar 10 2022


  • [changed] [py3k] Corrected "universal wheel" directive in setup.cfg so that building a wheel does not target Python 2.

    References: #351

  • [changed] [py3k] The bytestring_passthrough template argument is removed, as this flag only applied to Python 2.

... (truncated)


Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.

Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) - `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language - `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language - `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language - `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language You can disable automated security fix PRs for this repo from the [Security Alerts page](


opened on 2021-09-13 02:34:31 by zhanggenex

VI. Fuzz a Design a. Fuzzing Locally make fuzz-<core>

should be: VI. Fuzz a Design a. Fuzzing Locally make fuzz-ot-<core>


Initial Release 2021-02-05 18:06:12

Demonstrate fuzzing four OpenTitan IP blocks (AES, HMAC, KMAC, and RV Timer) using hardware fuzzing infrastructure.

Google Interns
GitHub Repository