tree: e994617aead439e444aefc29ed56099afcac7941 [path history] [tgz]
  1. build.sh
  2. Dockerfile
  3. project.yaml
  4. README.md
projects/cryptofuzz/README.md

This OSS-Fuzz project is a composite of multiple cryptographic libraries. It invokes a large amount of implementations for cryptographic primitives across multiple popular libraries, coordinated from a single fuzzing harness.

Its objectives are:

  1. To assert programmatic soundness: find memory bugs, crashes and time-outs with the help of sanitizers.
  2. To assert semantic soundness: detect invalid output occurring under legal use of the library's API.

One method to detect invalid results (point 2) is to assert equivalence between two or more outputs generated by a single library with the same input (but where each output allowed to be computed differently), aka “self-differential” testing. See here for a bug found with self-differential testing.

Another method is to compare a result against the result of different library, where both results are expected to be the same. If they are not the same, this indicates a bug in at least one library. This second method is what merits the composite setup of the project; adherence to the normative specification of a cryptographic primitive is implicitly asserted under the assumption that at least one implementation gets it right. Because determining which one of libraries gets it wrong cannot be reliably automated, all library maintainers are notified in this event, so that the cause of discrepancy can be resolved collaboratively.

Library builds embedding optimized assembly language code and those using pure C implementations have been assigned seperate fuzzer targets (binaries), because either implementation can have distinct bugs that will not transpire if only the other one is tested.

OpenSSL, BoringSSL and LibreSSL are assigned separate fuzzing targets because their exported symbols largely overlap and can therefore not be bundled into a single binary.

At this time of writing, no differential testing is performed, because support for additional libraries is not ready yet, but I intend to support mbed TLS and libsodium shortly, and support for popular or built-in cryptography implementations for Go, Rust, Java and Javascript is planned.

To further clear things up, at some point in the future, the matrix of support libraries versus fuzzing binaries could look like this:

A binary embedding OpenSSL, mbed TLS, libsodium, Go, Rust, Java, Javascript, ..., ...

A binary embedding BoringSSL, mbed TLS, libsodium, Go, Rust, Java, Javascript, ..., ...

A binary embedding LibreSSL, mbed TLS, libsodium, Go, Rust, Java, Javascript, ..., ...

and another 3 binaries for all of the pure C versions (no assembly language optimizations) of these libraries.

As more libraries are added, I will add a throttle mechanism to Cryptofuzz to ensure that no more than, say, 4 libraries will be called during a single iteration, so that no amount of supported libraries will impact the overall speed of the fuzzing process.

More information can be found at Cryptofuzz.