diff --git a/projects/libsodium/Dockerfile b/projects/libsodium/Dockerfile new file mode 100644 index 000000000..cb3fb04d9 --- /dev/null +++ b/projects/libsodium/Dockerfile @@ -0,0 +1,22 @@ +# Copyright 2018 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 chriswwolfe@gmail.com +RUN apt-get update && apt-get install -y make +RUN git clone --depth 1 https://github.com/jedisct1/libsodium.git --branch stable libsodium +WORKDIR libsodium +COPY build.sh *.cc *.h $SRC/ diff --git a/projects/libsodium/build.sh b/projects/libsodium/build.sh new file mode 100755 index 000000000..059825565 --- /dev/null +++ b/projects/libsodium/build.sh @@ -0,0 +1,28 @@ +#!/bin/bash -eu +# Copyright 2018 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. +# +################################################################################ + +# build project +./configure --prefix="$WORK" --disable-shared --enable-static LDFLAGS="$CXXFLAGS" +make -j$(nproc) all + +# build fuzzers +for f in $SRC/*_fuzzer.cc; do + fuzzer=$(basename "$f" _fuzzer.cc) + $CXX $CXXFLAGS -std=c++11 -I"$WORK/include" \ + "$f" -o "$OUT/${fuzzer}_fuzzer" \ + "$WORK/lib/libsodium.a" -lFuzzingEngine +done diff --git a/projects/libsodium/fake_random.h b/projects/libsodium/fake_random.h new file mode 100644 index 000000000..36d8d89ba --- /dev/null +++ b/projects/libsodium/fake_random.h @@ -0,0 +1,51 @@ +#ifndef FAKE_RANDOM_H_ +#define FAKE_RANDOM_H_ + +#include +#include +#include +#include +#include + +static const unsigned char * SEED_DATA; +static size_t SEED_SIZE; + +static const char * +fake_implementation_name(void) { + return "fake_random"; +} + +static void +fake_random_buffer(void * const buf, const size_t size) { + static unsigned char seed[randombytes_SEEDBYTES]; + memset(seed, '0', randombytes_SEEDBYTES); + + size_t boundary = std::min((size_t) randombytes_SEEDBYTES, SEED_SIZE); + memcpy(&seed, SEED_DATA, boundary); + + randombytes_buf_deterministic(buf, size, seed); +} + +struct randombytes_implementation fake_random = { + .implementation_name = fake_implementation_name, + .random = NULL, + .stir = NULL, + .uniform = NULL, + .buf = fake_random_buffer, + .close = NULL +}; + +void +setup_fake_random(const unsigned char * seed, const size_t seed_size) { + SEED_DATA = seed; + SEED_SIZE = seed_size; + + int fake_random_set = randombytes_set_implementation(&fake_random); + assert(fake_random_set == 0); + + assert(randombytes_implementation_name() == "fake_random"); + int initialized = sodium_init(); + assert(initialized >= 0); +} + +#endif // FAKE_RANDOM_H_ diff --git a/projects/libsodium/project.yaml b/projects/libsodium/project.yaml new file mode 100644 index 000000000..692952658 --- /dev/null +++ b/projects/libsodium/project.yaml @@ -0,0 +1,4 @@ +homepage: "https://libsodium.org" +primary_contact: "ossfuzzz+sodium@gmail.com" +auto_ccs: + - "chriswwolfe@gmail.com" diff --git a/projects/libsodium/secret_key_auth_fuzzer.cc b/projects/libsodium/secret_key_auth_fuzzer.cc new file mode 100644 index 000000000..32bb5fe83 --- /dev/null +++ b/projects/libsodium/secret_key_auth_fuzzer.cc @@ -0,0 +1,21 @@ +#include +#include + +#include "fake_random.h" + +extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size) { + int initialized = sodium_init(); + assert(initialized >= 0); + + setup_fake_random(data, size); + + unsigned char key[crypto_auth_KEYBYTES]; + unsigned char mac[crypto_auth_BYTES]; + + // this uses a deterministic generator + crypto_auth_keygen(key); + + crypto_auth(mac, data, size, key); + crypto_auth_verify(mac, data, size, key); + return 0; +} diff --git a/projects/libsodium/secretbox_easy_fuzzer.cc b/projects/libsodium/secretbox_easy_fuzzer.cc new file mode 100644 index 000000000..4e25bcc7a --- /dev/null +++ b/projects/libsodium/secretbox_easy_fuzzer.cc @@ -0,0 +1,28 @@ +#include +#include + +#include "fake_random.h" + +extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size) { + int initialized = sodium_init(); + assert(initialized >= 0); + + setup_fake_random(data, size); + + unsigned char key[crypto_secretbox_KEYBYTES]; + unsigned char nonce[crypto_secretbox_NONCEBYTES]; + + // these use a deterministic generator + crypto_secretbox_keygen(key); + randombytes_buf(nonce, sizeof nonce); + + size_t ciphertext_len = crypto_secretbox_MACBYTES + size; + unsigned char ciphertext[ciphertext_len]; + + crypto_secretbox_easy(ciphertext, data, size, nonce, key); + + unsigned char decrypted[size]; + crypto_secretbox_open_easy(decrypted, ciphertext, ciphertext_len, nonce, key); + + return 0; +}