Skip to main content
← All libraries
Crypto · C

How to fuzz libgcrypt

GnuPG's cryptographic heart — its S-expression parser processes untrusted key material.

libgcrypt parses S-expressions containing arbitrary-precision integers sourced from PGP keys and TLS certificates. Its MPI (multi-precision integer) layer performs pointer arithmetic on limb arrays that can overflow when processing adversarially crafted key parameters, directly impacting GnuPG and any application using GPGME.

Common bug classes

  • Heap buffer overflow in MPI limb array resize during import
  • Integer overflow in S-expression token length field
  • Out-of-bounds read in point decompression for elliptic curves
  • Null dereference in gcry_sexp_nth_buffer on malformed list
  • Divide-by-zero in DH key generation with crafted group parameters

Recommended setup

Fuzzers

  • AFL++
  • libFuzzer

Sanitizers

  • ASan
  • UBSan

Harness scaffold

#include <stdint.h>
#include <stddef.h>
#include <gcrypt.h>

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  gcry_sexp_t sexp = NULL;
  gcry_sexp_new(&sexp, (const char *)data, size, 0);
  if (sexp) gcry_sexp_release(sexp);
  /* Also probe MPI import */
  gcry_mpi_t mpi = NULL;
  size_t scanned;
  gcry_mpi_scan(&mpi, GCRYMPI_FMT_USG, data, size, &scanned);
  if (mpi) gcry_mpi_release(mpi);
  return 0;
}

Save this as fuzz_target.cc, build with your compiler + sanitizer flags, and you have a working starting point.

Start fuzzing libgcrypt on Fuzze.rs →

Push the harness above + a Dockerfile. First month 50% off.