aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Guido Vranken <guidovranken@users.noreply.github.com>2019-04-18 05:33:50 +0200
committerGravatar Kostya Serebryany <konstantin.s.serebryany@gmail.com>2019-04-17 20:33:50 -0700
commit7bdfb2b7d82bd7b9166969688894791e79065588 (patch)
tree4ae33098137d38636442001e5d325050551255d6
parent7b8971290d97c2e3826b2483ae2cae338fbd7df8 (diff)
Cryptofuzz (differential crypto fuzzing) (#2273)
* Add cryptofuzz * [cryptofuzz] Specify sanitizers * [cryptofuzz] Actually disable assembly in second OpenSSL build * [cryptofuzz] Add BoringSSL * [cryptofuzz] Enable MemorySanitizer builds * [cryptofuzz] Fix OpenSSL build * [cryptofuzz] Add LibreSSL target * [cryptofuzz] Don't build LibreSSL if MemorySanitizer is enabled * [cryptofuzz] Adapt build script to latest cryptofuzz code * [cryptofuzz] Force rebuild of OpenSSL * [cryptofuzz] Comment and move to Dockerfile OpenSSL's commit lock * [cryptofuzz] BoringSSL, LibreSSL: only build libcrypto.a for faster builds * [cryptofuzz] Replace -lFuzzingEngine -> $LIB_FUZZING_ENGINE for compatibility with OSS-Fuzz' new build setup * [cryptofuzz] Add README.md
-rw-r--r--projects/cryptofuzz/Dockerfile39
-rw-r--r--projects/cryptofuzz/README.md30
-rwxr-xr-xprojects/cryptofuzz/build.sh164
-rw-r--r--projects/cryptofuzz/project.yaml16
4 files changed, 249 insertions, 0 deletions
diff --git a/projects/cryptofuzz/Dockerfile b/projects/cryptofuzz/Dockerfile
new file mode 100644
index 00000000..b6e69d1f
--- /dev/null
+++ b/projects/cryptofuzz/Dockerfile
@@ -0,0 +1,39 @@
+# Copyright 2019 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER guidovranken@gmail.com
+
+RUN apt-get update && apt-get install -y software-properties-common python-software-properties make autoconf automake libtool build-essential cmake
+
+# BoringSSL needs Go to build
+RUN add-apt-repository -y ppa:gophers/archive && apt-get update && apt-get install -y golang-1.9-go
+RUN ln -s /usr/lib/go-1.9/bin/go /usr/bin/go
+
+RUN git clone --depth 1 https://github.com/guidovranken/cryptofuzz
+RUN git clone --depth 1 https://github.com/guidovranken/cryptofuzz-corpora
+RUN git clone https://github.com/openssl/openssl
+
+# The OpenSSL build system is currently broken, see also: https://github.com/google/oss-fuzz/issues/2314
+# Lock OpenSSL to an older commit that does not cause build problems.
+# This should be removed as soon as OpenSSL's build system is repaired.
+RUN cd openssl && git checkout 9efa0ae0b602c1c0e356009a58410a2e8b80201a
+
+RUN git clone --depth 1 https://boringssl.googlesource.com/boringssl
+RUN git clone --depth 1 https://github.com/libressl-portable/portable libressl
+RUN cd $SRC/libressl && ./update.sh
+
+COPY build.sh $SRC/
diff --git a/projects/cryptofuzz/README.md b/projects/cryptofuzz/README.md
new file mode 100644
index 00000000..74d0e965
--- /dev/null
+++ b/projects/cryptofuzz/README.md
@@ -0,0 +1,30 @@
+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](https://github.com/openssl/openssl/issues/8675) 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](https://github.com/guidovranken/cryptofuzz).
diff --git a/projects/cryptofuzz/build.sh b/projects/cryptofuzz/build.sh
new file mode 100755
index 00000000..71192bc1
--- /dev/null
+++ b/projects/cryptofuzz/build.sh
@@ -0,0 +1,164 @@
+#!/bin/bash -eu
+# Copyright 2019 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+# Generate lookup tables. This only needs to be done once.
+cd $SRC/cryptofuzz
+python gen_repository.py
+
+cd $SRC/openssl
+
+export CXXFLAGS="$CXXFLAGS -I $SRC/cryptofuzz/fuzzing-headers/include"
+if [[ $CFLAGS = *sanitize=memory* ]]
+then
+ export CXXFLAGS="$CXXFLAGS -DMSAN"
+fi
+
+##############################################################################
+if [[ $CFLAGS != *sanitize=memory* ]]
+then
+ # Compile LibreSSL (with assembly)
+ cd $SRC/libressl
+ rm -rf build ; mkdir build
+ cd build
+ cmake -DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX -DCMAKE_CXX_FLAGS="$CXXFLAGS" -DCMAKE_C_FLAGS="$CFLAGS" ..
+ make -j$(nproc) crypto
+
+ # Compile Cryptofuzz LibreSSL (with assembly) module
+ cd $SRC/cryptofuzz/modules/openssl
+ OPENSSL_INCLUDE_PATH="$SRC/libressl/include" OPENSSL_LIBCRYPTO_A_PATH="$SRC/libressl/build/crypto/libcrypto.a" CXXFLAGS="$CXXFLAGS -DCRYPTOFUZZ_LIBRESSL" make -B
+
+ # Compile Cryptofuzz
+ cd $SRC/cryptofuzz
+ LIBFUZZER_LINK="$LIB_FUZZING_ENGINE" CXXFLAGS="$CXXFLAGS -I $SRC/libressl/include -DCRYPTOFUZZ_LIBRESSL" make -B -j$(nproc)
+
+ # Generate dictionary
+ ./generate_dict
+
+ # Copy fuzzer
+ cp $SRC/cryptofuzz/cryptofuzz $OUT/cryptofuzz-libressl
+ # Copy dictionary
+ cp $SRC/cryptofuzz/cryptofuzz-dict.txt $OUT/cryptofuzz-libressl.dict
+ # Copy seed corpus
+ cp $SRC/cryptofuzz-corpora/libressl_latest.zip $OUT/cryptofuzz-libressl_seed_corpus.zip
+fi
+
+##############################################################################
+if [[ $CFLAGS != *sanitize=memory* ]]
+then
+ # Compile Openssl (with assembly)
+ cd $SRC/openssl
+ ./config --debug enable-md2 enable-rc5
+ make -j$(nproc)
+
+ # Compile Cryptofuzz OpenSSL (with assembly) module
+ cd $SRC/cryptofuzz/modules/openssl
+ OPENSSL_INCLUDE_PATH="$SRC/openssl/include" OPENSSL_LIBCRYPTO_A_PATH="$SRC/openssl/libcrypto.a" make -B
+
+ # Compile Cryptofuzz
+ cd $SRC/cryptofuzz
+ LIBFUZZER_LINK="$LIB_FUZZING_ENGINE" CXXFLAGS="$CXXFLAGS -I $SRC/openssl/include" make -B -j$(nproc)
+
+ # Generate dictionary
+ ./generate_dict
+
+ # Copy fuzzer
+ cp $SRC/cryptofuzz/cryptofuzz $OUT/cryptofuzz-openssl
+ # Copy dictionary
+ cp $SRC/cryptofuzz/cryptofuzz-dict.txt $OUT/cryptofuzz-openssl.dict
+ # Copy seed corpus
+ cp $SRC/cryptofuzz-corpora/openssl_latest.zip $OUT/cryptofuzz-openssl_seed_corpus.zip
+fi
+
+##############################################################################
+# Compile Openssl (without assembly)
+cd $SRC/openssl
+./config --debug no-asm enable-md2 enable-rc5
+make clean
+make -j$(nproc)
+
+# Compile Cryptofuzz OpenSSL (without assembly) module
+cd $SRC/cryptofuzz/modules/openssl
+OPENSSL_INCLUDE_PATH="$SRC/openssl/include" OPENSSL_LIBCRYPTO_A_PATH="$SRC/openssl/libcrypto.a" make -B
+
+# Compile Cryptofuzz
+cd $SRC/cryptofuzz
+LIBFUZZER_LINK="$LIB_FUZZING_ENGINE" CXXFLAGS="$CXXFLAGS -I $SRC/openssl/include" make -B -j$(nproc)
+
+# Generate dictionary
+./generate_dict
+
+# Copy fuzzer
+cp $SRC/cryptofuzz/cryptofuzz $OUT/cryptofuzz-openssl-noasm
+# Copy dictionary
+cp $SRC/cryptofuzz/cryptofuzz-dict.txt $OUT/cryptofuzz-openssl-noasm.dict
+# Copy seed corpus
+cp $SRC/cryptofuzz-corpora/openssl_latest.zip $OUT/cryptofuzz-openssl-noasm_seed_corpus.zip
+
+##############################################################################
+if [[ $CFLAGS != *sanitize=memory* ]]
+then
+ # Compile BoringSSL (with assembly)
+ cd $SRC/boringssl
+ rm -rf build ; mkdir build
+ cd build
+ cmake -DCMAKE_CXX_FLAGS="$CXXFLAGS" -DCMAKE_C_FLAGS="$CFLAGS" -DBORINGSSL_ALLOW_CXX_RUNTIME=1 ..
+ make -j$(nproc) crypto
+
+ # Compile Cryptofuzz BoringSSL (with assembly) module
+ cd $SRC/cryptofuzz/modules/openssl
+ OPENSSL_INCLUDE_PATH="$SRC/boringssl/include" OPENSSL_LIBCRYPTO_A_PATH="$SRC/boringssl/build/crypto/libcrypto.a" CXXFLAGS="$CXXFLAGS -DCRYPTOFUZZ_BORINGSSL" make -B
+
+ # Compile Cryptofuzz
+ cd $SRC/cryptofuzz
+ LIBFUZZER_LINK="$LIB_FUZZING_ENGINE" CXXFLAGS="$CXXFLAGS -I $SRC/openssl/include" make -B -j$(nproc)
+
+ # Generate dictionary
+ ./generate_dict
+
+ # Copy fuzzer
+ cp $SRC/cryptofuzz/cryptofuzz $OUT/cryptofuzz-boringssl
+ # Copy dictionary
+ cp $SRC/cryptofuzz/cryptofuzz-dict.txt $OUT/cryptofuzz-boringssl.dict
+ # Copy seed corpus
+ cp $SRC/cryptofuzz-corpora/boringssl_latest.zip $OUT/cryptofuzz-boringssl_seed_corpus.zip
+fi
+
+##############################################################################
+# Compile BoringSSL (with assembly)
+cd $SRC/boringssl
+rm -rf build ; mkdir build
+cd build
+cmake -DCMAKE_CXX_FLAGS="$CXXFLAGS" -DCMAKE_C_FLAGS="$CFLAGS" -DBORINGSSL_ALLOW_CXX_RUNTIME=1 -DOPENSSL_NO_ASM=1 ..
+make -j$(nproc) crypto
+
+# Compile Cryptofuzz BoringSSL (with assembly) module
+cd $SRC/cryptofuzz/modules/openssl
+OPENSSL_INCLUDE_PATH="$SRC/boringssl/include" OPENSSL_LIBCRYPTO_A_PATH="$SRC/boringssl/build/crypto/libcrypto.a" CXXFLAGS="$CXXFLAGS -DCRYPTOFUZZ_BORINGSSL" make -B
+
+# Compile Cryptofuzz
+cd $SRC/cryptofuzz
+LIBFUZZER_LINK="$LIB_FUZZING_ENGINE" CXXFLAGS="$CXXFLAGS -I $SRC/openssl/include" make -B -j$(nproc)
+
+# Generate dictionary
+./generate_dict
+
+# Copy fuzzer
+cp $SRC/cryptofuzz/cryptofuzz $OUT/cryptofuzz-boringssl-noasm
+# Copy dictionary
+cp $SRC/cryptofuzz/cryptofuzz-dict.txt $OUT/cryptofuzz-boringssl-noasm.dict
+# Copy seed corpus
+cp $SRC/cryptofuzz-corpora/boringssl_latest.zip $OUT/cryptofuzz-boringssl-noasm_seed_corpus.zip
diff --git a/projects/cryptofuzz/project.yaml b/projects/cryptofuzz/project.yaml
new file mode 100644
index 00000000..0a237016
--- /dev/null
+++ b/projects/cryptofuzz/project.yaml
@@ -0,0 +1,16 @@
+homepage: "https://github.com/guidovranken/cryptofuzz"
+primary_contact: "guidovranken@gmail.com"
+auto_ccs:
+ - "openssl-security@openssl.org"
+ - "kurt@roeckx.be"
+ - "caswell.matt@googlemail.com"
+ - "agl@google.com"
+ - "davidben@google.com"
+ - "svaldez@google.com"
+ - "beck@obtuse.com"
+ - "joel.sing@gmail.com"
+ - "kinichiro.inoguchi@gmail.com"
+sanitizers:
+ - address
+ - undefined
+ - memory