Skip to main content
← All libraries
Crypto · C

How to fuzz libsodium

libsodium trades footprint for correctness — fuzzing validates those guarantees hold.

libsodium is designed to be misuse-resistant, but its internal MAC verification, key derivation functions, and base64/hex codecs still process attacker-supplied byte strings. Fuzzing verifies that the API's length-check preconditions are uniformly enforced and that no code path exists to bypass constant-time comparisons.

Common bug classes

  • Heap buffer overflow in base64 decode length miscalculation
  • Out-of-bounds read in hex-to-binary conversion on odd-length input
  • Integer overflow in secret-stream chunk length arithmetic
  • Incorrect MAC length check allowing authentication bypass
  • Uninitialised-memory read in generichash state finalisation

Recommended setup

Fuzzers

  • AFL++
  • libFuzzer

Sanitizers

  • ASan
  • UBSan
  • MSan

Harness scaffold

#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <sodium.h>

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  if (sodium_init() < 0) return 0;
  /* Fuzz secretstream open */
  if (size < crypto_secretstream_xchacha20poly1305_HEADERBYTES) return 0;
  crypto_secretstream_xchacha20poly1305_state st;
  unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES];
  memset(key, 0x42, sizeof(key));
  crypto_secretstream_xchacha20poly1305_init_pull(&st, data, key);
  if (size > crypto_secretstream_xchacha20poly1305_HEADERBYTES) {
    const uint8_t *msg = data + crypto_secretstream_xchacha20poly1305_HEADERBYTES;
    size_t mlen = size - crypto_secretstream_xchacha20poly1305_HEADERBYTES;
    uint8_t *out = malloc(mlen);
    if (out) {
      unsigned long long outlen; unsigned char tag;
      crypto_secretstream_xchacha20poly1305_pull(
          &st, out, &outlen, &tag, msg, mlen, NULL, 0);
      free(out);
    }
  }
  return 0;
}

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

Start fuzzing libsodium on Fuzze.rs →

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