From a447503a43b9ce6a749994c32ef49946762d2b97 Mon Sep 17 00:00:00 2001 From: Guido Vranken Date: Wed, 5 May 2021 22:22:25 +0200 Subject: [PATCH 1/5] [bitcoin-core] Support AFL builds --- projects/bitcoin-core/build.sh | 5 +++-- projects/bitcoin-core/project.yaml | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/projects/bitcoin-core/build.sh b/projects/bitcoin-core/build.sh index 1b077d4e5998..92cd4f949b81 100755 --- a/projects/bitcoin-core/build.sh +++ b/projects/bitcoin-core/build.sh @@ -44,8 +44,8 @@ fi if [ "$FUZZING_ENGINE" = "libfuzzer" ]; then CONFIG_SITE="$PWD/depends/$BUILD_TRIPLET/share/config.site" ./configure --enable-fuzz --with-sanitizers=fuzzer else - # See https://google.github.io/oss-fuzz/getting-started/new-project-guide/#Requirements - CONFIG_SITE="$PWD/depends/$BUILD_TRIPLET/share/config.site" ./configure --enable-fuzz LDFLAGS="$LIB_FUZZING_ENGINE" + sed -i "s|PROVIDE_FUZZ_MAIN_FUNCTION|NEVER_PROVIDE_MAIN_FOR_OSS_FUZZ|g" "./src/test/fuzz/fuzz.cpp" + CONFIG_SITE="$PWD/depends/$BUILD_TRIPLET/share/config.site" ./configure --enable-fuzz SANITIZER_LDFLAGS="$LIB_FUZZING_ENGINE" fi make -j$(nproc) @@ -55,6 +55,7 @@ FUZZ_TARGETS=( 'process_messages' 'asmap' ) for fuzz_target in ${FUZZ_TARGETS[@]}; do git checkout -- "./src/test/fuzz/fuzz.cpp" sed -i "s|std::getenv(\"FUZZ\")|\"$fuzz_target\"|g" "./src/test/fuzz/fuzz.cpp" + sed -i "s|PROVIDE_FUZZ_MAIN_FUNCTION|NEVER_PROVIDE_MAIN_FOR_OSS_FUZZ|g" "./src/test/fuzz/fuzz.cpp" make -j$(nproc) mv ./src/test/fuzz/fuzz $OUT/$fuzz_target ( diff --git a/projects/bitcoin-core/project.yaml b/projects/bitcoin-core/project.yaml index c217b4c0b768..e81cb8a1fb11 100644 --- a/projects/bitcoin-core/project.yaml +++ b/projects/bitcoin-core/project.yaml @@ -18,3 +18,4 @@ architectures: fuzzing_engines: - libfuzzer - honggfuzz + - afl From bbd78748add4e837239baf69a090a52e474b401a Mon Sep 17 00:00:00 2001 From: Guido Vranken Date: Thu, 6 May 2021 00:49:08 +0200 Subject: [PATCH 2/5] [bitcoin-core] Add differential cryptography fuzzer --- projects/bitcoin-core/Dockerfile | 7 ++ projects/bitcoin-core/build.sh | 4 + projects/bitcoin-core/build_cryptofuzz.sh | 97 +++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 projects/bitcoin-core/build_cryptofuzz.sh diff --git a/projects/bitcoin-core/Dockerfile b/projects/bitcoin-core/Dockerfile index 734470e3cf96..8556c8924530 100644 --- a/projects/bitcoin-core/Dockerfile +++ b/projects/bitcoin-core/Dockerfile @@ -27,5 +27,12 @@ RUN apt-get update && apt-get install -y \ RUN git clone --depth=1 https://github.com/bitcoin/bitcoin.git bitcoin-core RUN git clone --depth=1 https://github.com/bitcoin-core/qa-assets bitcoin-core/assets +RUN git clone --depth 1 https://github.com/guidovranken/cryptofuzz +RUN git clone --depth 1 https://github.com/bitcoin-core/secp256k1.git +RUN git clone --depth 1 https://github.com/randombit/botan.git +RUN git clone --depth 1 https://github.com/trezor/trezor-firmware.git +RUN git clone --depth 1 https://github.com/google/wycheproof.git +RUN wget https://boostorg.jfrog.io/artifactory/main/release/1.74.0/source/boost_1_74_0.tar.bz2 WORKDIR bitcoin-core COPY build.sh $SRC/ +COPY build_cryptofuzz.sh $SRC/ diff --git a/projects/bitcoin-core/build.sh b/projects/bitcoin-core/build.sh index 92cd4f949b81..4a4e659bc90d 100755 --- a/projects/bitcoin-core/build.sh +++ b/projects/bitcoin-core/build.sh @@ -15,6 +15,10 @@ # ################################################################################ +bash $SRC/build_cryptofuzz.sh + +cd $SRC/bitcoin-core/ + # Build dependencies # This will also force static builds if [ "$ARCHITECTURE" = "i386" ]; then diff --git a/projects/bitcoin-core/build_cryptofuzz.sh b/projects/bitcoin-core/build_cryptofuzz.sh new file mode 100644 index 000000000000..d252a8be8f82 --- /dev/null +++ b/projects/bitcoin-core/build_cryptofuzz.sh @@ -0,0 +1,97 @@ +#!/bin/bash -eu +# Copyright 2021 Google LLC +# +# 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. +# +################################################################################ + +export CXXFLAGS="$CXXFLAGS -DCRYPTOFUZZ_NO_OPENSSL" +export LIBFUZZER_LINK="$LIB_FUZZING_ENGINE" + +# Install Boost headers +cd $SRC/ +tar jxf boost_1_74_0.tar.bz2 +cd boost_1_74_0/ +CFLAGS="" CXXFLAGS="" ./bootstrap.sh +CFLAGS="" CXXFLAGS="" ./b2 headers +export CXXFLAGS="$CXXFLAGS -I $SRC/boost_1_74_0/" + +# Prevent Boost compilation error with -std=c++17 +export CXXFLAGS="$CXXFLAGS -D_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR" + +# Build libsecp256k1 +cd $SRC/secp256k1/ +autoreconf -ivf +if [[ $CFLAGS = *sanitize=memory* ]] +then + ./configure --enable-static --disable-tests --disable-benchmark --with-bignum=no --disable-exhaustive-tests --disable-valgrind --enable-module-recovery --with-asm=no +else + ./configure --enable-static --disable-tests --disable-benchmark --with-bignum=no --disable-exhaustive-tests --disable-valgrind --enable-module-recovery +fi +make +export SECP256K1_INCLUDE_PATH=$(realpath include) +export LIBSECP256K1_A_PATH=$(realpath .libs/libsecp256k1.a) +export CXXFLAGS="$CXXFLAGS -DCRYPTOFUZZ_SECP256K1" + +# Build Trezor firmware +cd $SRC/trezor-firmware/crypto/ +# Rename blake2b_* functions to avoid symbol collisions with other libraries +sed -i "s/\>extra_options.h +echo -n '--operations=Digest,HMAC,KDF_HKDF,SymmetricEncrypt,SymmetricDecrypt,ECC_PrivateToPublic,ECC_ValidatePubkey,ECDSA_Sign,ECDSA_Verify,ECDSA_Recover,BignumCalc_Mod_2Exp256 ' >>extra_options.h +echo -n '--curves=secp256k1 ' >>extra_options.h +echo -n '--digests=NULL,SHA1,SHA256,SHA512,RIPEMD160,SHA3-256,SIPHASH64 ' >>extra_options.h +echo -n '--ciphers=CHACHA20,AES_256_CBC ' >>extra_options.h +echo -n '--calcops=Add,And,Div,IsEq,IsGt,IsGte,IsLt,IsLte,IsOdd,Mul,NumBits,Or,Set,Sub,Xor ' >>extra_options.h +echo -n '"' >>extra_options.h +cd modules/bitcoin/ +make -B -j$(nproc) +cd ../secp256k1/ +make -B -j$(nproc) +cd ../trezor/ +make -B -j$(nproc) +cd ../botan/ +make -B -j$(nproc) +cd ../../ +make -B -j$(nproc) + +cp cryptofuzz $OUT/cryptofuzz-bitcoin-cryptography + +# Convert Wycheproof test vectors to Cryptofuzz corpus format +mkdir $SRC/corpus-cryptofuzz-wycheproof/ +find $SRC/wycheproof/testvectors/ -type f -name 'ecdsa_secp256k1_*' -exec $SRC/cryptofuzz/cryptofuzz --from-wycheproof={},$SRC/corpus-cryptofuzz-wycheproof/ \; +# Pack it and use it as seed corpus +zip -j $OUT/cryptofuzz-bitcoin-cryptography_seed_corpus.zip $SRC/corpus-cryptofuzz-wycheproof/* From f35ebf5e5ed48631dfb62e1d3df98ce98e91fa0b Mon Sep 17 00:00:00 2001 From: Guido Vranken Date: Thu, 6 May 2021 19:08:27 +0200 Subject: [PATCH 3/5] [bitcoin-core] Update secp256k1 build procedure --- projects/bitcoin-core/build_cryptofuzz.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/bitcoin-core/build_cryptofuzz.sh b/projects/bitcoin-core/build_cryptofuzz.sh index d252a8be8f82..e44d9cce82e9 100644 --- a/projects/bitcoin-core/build_cryptofuzz.sh +++ b/projects/bitcoin-core/build_cryptofuzz.sh @@ -34,9 +34,9 @@ cd $SRC/secp256k1/ autoreconf -ivf if [[ $CFLAGS = *sanitize=memory* ]] then - ./configure --enable-static --disable-tests --disable-benchmark --with-bignum=no --disable-exhaustive-tests --disable-valgrind --enable-module-recovery --with-asm=no + ./configure --enable-static --disable-tests --disable-benchmark --disable-exhaustive-tests --disable-valgrind --enable-module-recovery --enable-module-schnorrsig --enable-experimental --with-asm=no else - ./configure --enable-static --disable-tests --disable-benchmark --with-bignum=no --disable-exhaustive-tests --disable-valgrind --enable-module-recovery + ./configure --enable-static --disable-tests --disable-benchmark --disable-exhaustive-tests --disable-valgrind --enable-module-recovery --enable-module-schnorrsig --enable-experimental fi make export SECP256K1_INCLUDE_PATH=$(realpath include) From b11e849826cb9c1c545bdbfad2dd61b9e85e1ff8 Mon Sep 17 00:00:00 2001 From: Guido Vranken Date: Tue, 18 May 2021 03:58:34 +0200 Subject: [PATCH 4/5] [bitcoin-core] Build libsecp256k1 without schnorrsig support --- projects/bitcoin-core/build_cryptofuzz.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/bitcoin-core/build_cryptofuzz.sh b/projects/bitcoin-core/build_cryptofuzz.sh index e44d9cce82e9..5e4562ef90f7 100644 --- a/projects/bitcoin-core/build_cryptofuzz.sh +++ b/projects/bitcoin-core/build_cryptofuzz.sh @@ -34,9 +34,9 @@ cd $SRC/secp256k1/ autoreconf -ivf if [[ $CFLAGS = *sanitize=memory* ]] then - ./configure --enable-static --disable-tests --disable-benchmark --disable-exhaustive-tests --disable-valgrind --enable-module-recovery --enable-module-schnorrsig --enable-experimental --with-asm=no + ./configure --enable-static --disable-tests --disable-benchmark --disable-exhaustive-tests --disable-valgrind --enable-module-recovery --enable-experimental --with-asm=no else - ./configure --enable-static --disable-tests --disable-benchmark --disable-exhaustive-tests --disable-valgrind --enable-module-recovery --enable-module-schnorrsig --enable-experimental + ./configure --enable-static --disable-tests --disable-benchmark --disable-exhaustive-tests --disable-valgrind --enable-module-recovery --enable-experimental fi make export SECP256K1_INCLUDE_PATH=$(realpath include) From f7132b4f1e7afe962a3669b65af67b95710e2acb Mon Sep 17 00:00:00 2001 From: Guido Vranken Date: Tue, 18 May 2021 04:49:11 +0200 Subject: [PATCH 5/5] [bitcoin-core] Cryptofuzz: Build 3 versions of libsecp256k1 --- projects/bitcoin-core/build_cryptofuzz.sh | 57 +++++++++++++++++------ 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/projects/bitcoin-core/build_cryptofuzz.sh b/projects/bitcoin-core/build_cryptofuzz.sh index 5e4562ef90f7..c69d419d9913 100644 --- a/projects/bitcoin-core/build_cryptofuzz.sh +++ b/projects/bitcoin-core/build_cryptofuzz.sh @@ -29,20 +29,36 @@ export CXXFLAGS="$CXXFLAGS -I $SRC/boost_1_74_0/" # Prevent Boost compilation error with -std=c++17 export CXXFLAGS="$CXXFLAGS -D_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR" -# Build libsecp256k1 +# Preconfigure libsecp256k1 cd $SRC/secp256k1/ autoreconf -ivf -if [[ $CFLAGS = *sanitize=memory* ]] -then - ./configure --enable-static --disable-tests --disable-benchmark --disable-exhaustive-tests --disable-valgrind --enable-module-recovery --enable-experimental --with-asm=no -else - ./configure --enable-static --disable-tests --disable-benchmark --disable-exhaustive-tests --disable-valgrind --enable-module-recovery --enable-experimental -fi -make -export SECP256K1_INCLUDE_PATH=$(realpath include) -export LIBSECP256K1_A_PATH=$(realpath .libs/libsecp256k1.a) export CXXFLAGS="$CXXFLAGS -DCRYPTOFUZZ_SECP256K1" +function build_libsecp256k1() { + # Build libsecp256k1 + cd $SRC/secp256k1/ + + if test -f "Makefile"; then + # Remove old configuration if it exists + make clean + fi + + if [[ $CFLAGS = *sanitize=memory* ]] + then + ./configure --enable-static --disable-tests --disable-benchmark --disable-exhaustive-tests --enable-module-recovery --enable-experimental --with-asm=no "$@" + else + ./configure --enable-static --disable-tests --disable-benchmark --disable-exhaustive-tests --enable-module-recovery --enable-experimental "$@" + fi + make + + export SECP256K1_INCLUDE_PATH=$(realpath include) + export LIBSECP256K1_A_PATH=$(realpath .libs/libsecp256k1.a) + + # Build libsecp256k1 Cryptofuzz module + cd $SRC/cryptofuzz/modules/secp256k1/ + make -B -j$(nproc) +} + # Build Trezor firmware cd $SRC/trezor-firmware/crypto/ # Rename blake2b_* functions to avoid symbol collisions with other libraries @@ -79,16 +95,31 @@ echo -n '--calcops=Add,And,Div,IsEq,IsGt,IsGte,IsLt,IsLte,IsOdd,Mul,NumBits,Or,S echo -n '"' >>extra_options.h cd modules/bitcoin/ make -B -j$(nproc) -cd ../secp256k1/ -make -B -j$(nproc) cd ../trezor/ make -B -j$(nproc) cd ../botan/ make -B -j$(nproc) cd ../../ + +# Build with 3 configurations of libsecp256k1 +# Discussion: https://github.com/google/oss-fuzz/pull/5717#issuecomment-842765383 + +build_libsecp256k1 "--with-ecmult-window=2" "--with-ecmult-gen-precision=2" +cd $SRC/cryptofuzz/ make -B -j$(nproc) +cp cryptofuzz $OUT/cryptofuzz-bitcoin-cryptography-w2-p2 -cp cryptofuzz $OUT/cryptofuzz-bitcoin-cryptography +build_libsecp256k1 "--with-ecmult-window=15" "--with-ecmult-gen-precision=4" +cd $SRC/cryptofuzz/ +rm cryptofuzz +make +cp cryptofuzz $OUT/cryptofuzz-bitcoin-cryptography-w15-p4 + +build_libsecp256k1 "--with-ecmult-window=24" "--with-ecmult-gen-precision=8" +cd $SRC/cryptofuzz/ +rm cryptofuzz +make +cp cryptofuzz $OUT/cryptofuzz-bitcoin-cryptography-w24-p8 # Convert Wycheproof test vectors to Cryptofuzz corpus format mkdir $SRC/corpus-cryptofuzz-wycheproof/