From 18bd53f91c2ae15d7c841cb77c97acadf64e3097 Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Thu, 7 Oct 2021 17:11:53 +0000 Subject: Revert "cr50_fuzz: Add fuzzer for u2f commands" This reverts commit 3cac98670745fc5ca82a058fab512567f8444759. Reason for revert: This patch breaks building of 'make buildall' and seems to be leaving some generated files in the root directory. Original change's description: > cr50_fuzz: Add fuzzer for u2f commands > > Currently there's only one fuzzer for Pinweaver and one for host > commands in cr50. Add a fuzzer for the u2f commands (generate, sign, > attest) used in the WebAuthn flow to ensure its security. Most regions > of the concerning functions are covered except for pure error code > returns and unreachable regions (currently auth secret is not used in > sign and attest command yet). > > Rename old cr50_fuzz namings to pinweaver_fuzz, since they only cover > Pinweaver commands. > > BUG=b:172367435 > TEST=make buildall -j > TEST=make host-u2f_fuzz && \ > ./build/host/u2f_fuzz/u2f_fuzz.exe -timeout=10 \ > -ignore_ooms=false -ignore_timeouts=false -fork=71; \ > llvm-profdata merge -sparse default.profraw -o default.profdata; \ > llvm-cov show ./build/host/u2f_fuzz/u2f_fuzz.exe \ > -object ./build/host/u2f_fuzz/RO/board/cr50/dcrypto/u2f.o \ > --instr-profile default.profdata \ > board/cr50/dcrypto/u2f.c common/u2f.c > report > > Cq-Depend: chromium:3162473 > Change-Id: I02b820cf03f7b46ccad7c3bc7b82e73ff45217c6 > Signed-off-by: Howard Yang > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3162469 > Reviewed-by: Andrey Pronin > Reviewed-by: Vadim Sukhomlinov > Reviewed-by: Leo Lai Bug: b:172367435 Change-Id: Ie844e44e0cd6254553694c23a535f18329cef77d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3212497 Reviewed-by: Vadim Bendebury Reviewed-by: Mary Ruthven Tested-by: Vadim Bendebury Bot-Commit: Rubber Stamper --- fuzz/build.mk | 20 ++-- fuzz/cr50_fuzz.cc | 148 ++++++++++++++++++++++++++ fuzz/cr50_fuzz.owners | 5 + fuzz/cr50_fuzz.proto | 31 ++++++ fuzz/cr50_fuzz.tasklist | 9 ++ fuzz/fuzz_config.h | 8 +- fuzz/pinweaver_fuzz.cc | 148 -------------------------- fuzz/pinweaver_fuzz.owners | 5 - fuzz/pinweaver_fuzz.proto | 31 ------ fuzz/pinweaver_fuzz.tasklist | 9 -- fuzz/pinweaver_model.h | 2 +- fuzz/u2f_fuzz.cc | 240 ------------------------------------------- fuzz/u2f_fuzz.tasklist | 9 -- 13 files changed, 206 insertions(+), 459 deletions(-) create mode 100644 fuzz/cr50_fuzz.cc create mode 100644 fuzz/cr50_fuzz.owners create mode 100644 fuzz/cr50_fuzz.proto create mode 100644 fuzz/cr50_fuzz.tasklist delete mode 100644 fuzz/pinweaver_fuzz.cc delete mode 100644 fuzz/pinweaver_fuzz.owners delete mode 100644 fuzz/pinweaver_fuzz.proto delete mode 100644 fuzz/pinweaver_fuzz.tasklist delete mode 100644 fuzz/u2f_fuzz.cc delete mode 100644 fuzz/u2f_fuzz.tasklist (limited to 'fuzz') diff --git a/fuzz/build.mk b/fuzz/build.mk index e769f5282e..5cc2a40859 100644 --- a/fuzz/build.mk +++ b/fuzz/build.mk @@ -9,7 +9,7 @@ fuzz-test-list-host = # Fuzzers should only be built for architectures that support sanitizers. ifeq ($(ARCH),amd64) -fuzz-test-list-host += pinweaver_fuzz host_command_fuzz u2f_fuzz +fuzz-test-list-host += cr50_fuzz host_command_fuzz endif # For fuzzing targets libec.a is built from the ro objects and hides functions @@ -24,24 +24,20 @@ endif # Does your object file need to link against cstdlib? # Yes -> use -rw # Otherwise use -y -pinweaver_fuzz-rw = pinweaver_fuzz.o pinweaver_model.o \ - mem_hash_tree.o nvmem_tpm2_mock.o +cr50_fuzz-rw = cr50_fuzz.o pinweaver_model.o mem_hash_tree.o nvmem_tpm2_mock.o host_command_fuzz-y = host_command_fuzz.o -u2f_fuzz-y = u2f_fuzz.o -u2f_fuzz-y += ../board/cr50/dcrypto/u2f.o -CR50_PROTO_HEADERS := $(out)/gen/fuzz/pinweaver_fuzz.pb.h \ +CR50_PROTO_HEADERS := $(out)/gen/fuzz/cr50_fuzz.pb.h \ $(out)/gen/fuzz/pinweaver/pinweaver.pb.h $(out)/RW/fuzz/pinweaver_model.o: ${CR50_PROTO_HEADERS} -$(out)/RW/fuzz/pinweaver_fuzz.o: ${CR50_PROTO_HEADERS} -$(out)/RW/fuzz/pinweaver_fuzz.o: CPPFLAGS+=${LIBPROTOBUF_MUTATOR_CFLAGS} +$(out)/RW/fuzz/cr50_fuzz.o: ${CR50_PROTO_HEADERS} +$(out)/RW/fuzz/cr50_fuzz.o: CPPFLAGS+=${LIBPROTOBUF_MUTATOR_CFLAGS} TPM2_LIB_ROOT := $(CROS_WORKON_SRCROOT)/src/third_party/tpm2 $(out)/RW/fuzz/nvmem_tpm2_mock.o: CFLAGS += -I$(TPM2_LIB_ROOT) -$(out)/RO/common/u2f.o: CFLAGS += -DU2F_TEST -$(out)/pinweaver_fuzz.exe: $(out)/cryptoc/libcryptoc.a \ - $(out)/gen/fuzz/pinweaver_fuzz.pb.o \ +$(out)/cr50_fuzz.exe: $(out)/cryptoc/libcryptoc.a \ + $(out)/gen/fuzz/cr50_fuzz.pb.o \ $(out)/gen/fuzz/pinweaver/pinweaver.pb.o \ -$(out)/pinweaver_fuzz.exe: LDFLAGS_EXTRA+=-lcrypto ${LIBPROTOBUF_MUTATOR_LDLIBS} +$(out)/cr50_fuzz.exe: LDFLAGS_EXTRA+=-lcrypto ${LIBPROTOBUF_MUTATOR_LDLIBS} diff --git a/fuzz/cr50_fuzz.cc b/fuzz/cr50_fuzz.cc new file mode 100644 index 0000000000..186700f415 --- /dev/null +++ b/fuzz/cr50_fuzz.cc @@ -0,0 +1,148 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Fuzzer for the TPM2 and vendor specific Cr50 commands. + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#define HIDE_EC_STDLIB +#include "chip/host/persistence.h" +#include "fuzz/cr50_fuzz.pb.h" +#include "fuzz/fuzz_config.h" +#include "fuzz/pinweaver_model.h" +#include "fuzz/span.h" +#include "include/nvmem.h" +#include "include/nvmem_vars.h" +#include "include/pinweaver.h" + +using protobuf_mutator::libfuzzer::LoadProtoInput; + +namespace { +constexpr size_t kBufferAlignment = alignof(pw_request_t) > + alignof(pw_response_t) + ? alignof(pw_request_t) + : alignof(pw_response_t); +} // namespace + +extern "C" uint32_t nvmem_user_sizes[NVMEM_NUM_USERS] = {NVMEM_TPM_SIZE, + NVMEM_CR50_SIZE}; + +extern "C" void rand_bytes(void* data, size_t len) { + size_t x = 0; + + uint8_t* buffer = reinterpret_cast(data); + for (; x < len; ++x) { + buffer[x] = rand(); + } +} + +extern "C" void get_storage_seed(void* buf, size_t* len) { + memset(buf, 0x77, *len); +} + +extern "C" uint8_t get_current_pcr_digest(const uint8_t bitmask[2], + uint8_t sha256_of_selected_pcr[32]) { + memset(sha256_of_selected_pcr, 0, 32); + return 0; +} + +extern "C" int DCRYPTO_ladder_is_enabled(void) { + return 1; +} + +extern "C" void nvmem_wipe_cache(void) { + // Nothing to do since there is no cache in this implementation. +} + +// Needed for test targets to build. +extern "C" void run_test(void) {} + +void InitializeFuzzerRun() { + memset(__host_flash, 0xff, sizeof(__host_flash)); + nvmem_init(); + nvmem_enable_commits(); + srand(0); +} + +// Used to verify the model hasn't become out of sync with the implementation. +// The usefulness of this fuzzer comes from its ability to reach all the code +// paths. +bool SelfTest() { + InitializeFuzzerRun(); + + PinweaverModel pinweaver_model; + alignas(kBufferAlignment) uint8_t buffer[PW_MAX_MESSAGE_SIZE] = {}; + fuzz::span buffer_view(buffer, sizeof(buffer)); + fuzz::pinweaver::Request request; + + fuzz::pinweaver::ResetTree* reset_tree = request.mutable_reset_tree(); + reset_tree->set_height(2); + reset_tree->set_bits_per_level(2); + assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); + + fuzz::pinweaver::InsertLeaf* insert_leaf = request.mutable_insert_leaf(); + constexpr char delay_schedule[] = "\000\000\000\005\377\377\377\377"; + insert_leaf->mutable_delay_schedule()->assign( + delay_schedule, delay_schedule + sizeof(delay_schedule)); + assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); + + request.mutable_try_auth(); + assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); + + request.mutable_get_log(); + assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); + + request.mutable_log_replay(); + assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); + + request.mutable_reset_auth(); + assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); + + request.mutable_remove_leaf(); + assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); + + return true; +} + +DEFINE_CUSTOM_PROTO_MUTATOR_IMPL(false, fuzz::Cr50FuzzerInput) +DEFINE_CUSTOM_PROTO_CROSSOVER_IMPL(false, fuzz::Cr50FuzzerInput) + +extern "C" int test_fuzz_one_input(const uint8_t* data, unsigned int size) { + static bool initialized = SelfTest(); + assert(initialized); + + fuzz::Cr50FuzzerInput input; + if (!LoadProtoInput(false, data, size, &input)) { + return 0; + } + + InitializeFuzzerRun(); + + PinweaverModel pinweaver_model; + alignas(kBufferAlignment) uint8_t buffer[PW_MAX_MESSAGE_SIZE] = {}; + fuzz::span buffer_view(buffer, sizeof(buffer)); + for (const fuzz::Cr50SubAction& action : input.sub_actions()) { + switch (action.sub_action_case()) { + case fuzz::Cr50SubAction::kRandomBytes: + fuzz::CopyWithPadding(action.random_bytes().value(), buffer_view, 0); + pinweaver_model.SendBuffer(buffer_view); + break; + case fuzz::Cr50SubAction::kPinweaver: + pinweaver_model.ApplyRequest(action.pinweaver(), buffer_view); + break; + case fuzz::Cr50SubAction::SUB_ACTION_NOT_SET: + break; + } + } + return 0; +} diff --git a/fuzz/cr50_fuzz.owners b/fuzz/cr50_fuzz.owners new file mode 100644 index 0000000000..80e5dc1dee --- /dev/null +++ b/fuzz/cr50_fuzz.owners @@ -0,0 +1,5 @@ +# Emails to CC on clusterfuzz bugs for this target: +allenwebb@google.com +mnissler@google.com +rspangler@chromium.org +vbendeb@chromium.org diff --git a/fuzz/cr50_fuzz.proto b/fuzz/cr50_fuzz.proto new file mode 100644 index 0000000000..0291eacd88 --- /dev/null +++ b/fuzz/cr50_fuzz.proto @@ -0,0 +1,31 @@ +// Copyright 2018 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = "proto3"; + +package fuzz; + +import public "fuzz/pinweaver/pinweaver.proto"; + +message RandomBytes { + bytes value = 1; +} + +message Cr50SubAction { + // Allows a logical representation of an action (PinWeaver) or a literal + // representation (RandomBytes). The logical representation fills out the + // expected values of particular fields when they are empty or not part of the + // proto so that the fuzzer can reach parts of the code without having to + // brute force an HMAC. The literal representation allows for the fuzzer to + // represent inputs that cannot be represented with the logical + // representation. + oneof sub_action { + RandomBytes random_bytes = 1; + pinweaver.Request pinweaver = 2; + } +} + +message Cr50FuzzerInput { + repeated Cr50SubAction sub_actions = 1; +} diff --git a/fuzz/cr50_fuzz.tasklist b/fuzz/cr50_fuzz.tasklist new file mode 100644 index 0000000000..24870f2abb --- /dev/null +++ b/fuzz/cr50_fuzz.tasklist @@ -0,0 +1,9 @@ +/* Copyright 2018 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * See CONFIG_TASK_LIST in config.h for details. + */ +#define CONFIG_TEST_TASK_LIST diff --git a/fuzz/fuzz_config.h b/fuzz/fuzz_config.h index bb10294c3c..781921870a 100644 --- a/fuzz/fuzz_config.h +++ b/fuzz/fuzz_config.h @@ -12,7 +12,7 @@ /* Disable hibernate: We never want to exit while fuzzing. */ #undef CONFIG_HIBERNATE -#ifdef TEST_PINWEAVER_FUZZ +#ifdef TEST_CR50_FUZZ #define CONFIG_DCRYPTO #define CONFIG_PINWEAVER #define CONFIG_UPTO_SHA512 @@ -80,7 +80,7 @@ enum nvmem_users { /******************************************************************************/ #define CONFIG_SW_CRC -#endif /* TEST_PINWEAVER_FUZZ */ +#endif /* TEST_CR50_FUZZ */ #ifdef TEST_HOST_COMMAND_FUZZ #undef CONFIG_HOSTCMD_DEBUG_MODE @@ -102,11 +102,11 @@ enum nvmem_users { #endif /* TEST_HOST_COMMAND_FUZZ */ -#ifdef TEST_U2F_FUZZ +#ifdef TEST_CR50_U2F_FUZZ #define CONFIG_DCRYPTO #define CONFIG_U2F #define CC_EXTENSION CC_COMMAND -#endif /* TEST_U2F_FUZZ */ +#endif /* TEST_CR50_U2F_FUZZ */ #endif /* TEST_FUZZ */ #endif /* __FUZZ_FUZZ_CONFIG_H */ diff --git a/fuzz/pinweaver_fuzz.cc b/fuzz/pinweaver_fuzz.cc deleted file mode 100644 index 853c4341fc..0000000000 --- a/fuzz/pinweaver_fuzz.cc +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2018 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Fuzzer for the Cr50 commands related to Pinweaver. - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#define HIDE_EC_STDLIB -#include "chip/host/persistence.h" -#include "fuzz/pinweaver_fuzz.pb.h" -#include "fuzz/fuzz_config.h" -#include "fuzz/pinweaver_model.h" -#include "fuzz/span.h" -#include "include/nvmem.h" -#include "include/nvmem_vars.h" -#include "include/pinweaver.h" - -using protobuf_mutator::libfuzzer::LoadProtoInput; - -namespace { -constexpr size_t kBufferAlignment = alignof(pw_request_t) > - alignof(pw_response_t) - ? alignof(pw_request_t) - : alignof(pw_response_t); -} // namespace - -extern "C" uint32_t nvmem_user_sizes[NVMEM_NUM_USERS] = {NVMEM_TPM_SIZE, - NVMEM_CR50_SIZE}; - -extern "C" void rand_bytes(void* data, size_t len) { - size_t x = 0; - - uint8_t* buffer = reinterpret_cast(data); - for (; x < len; ++x) { - buffer[x] = rand(); - } -} - -extern "C" void get_storage_seed(void* buf, size_t* len) { - memset(buf, 0x77, *len); -} - -extern "C" uint8_t get_current_pcr_digest(const uint8_t bitmask[2], - uint8_t sha256_of_selected_pcr[32]) { - memset(sha256_of_selected_pcr, 0, 32); - return 0; -} - -extern "C" int DCRYPTO_ladder_is_enabled(void) { - return 1; -} - -extern "C" void nvmem_wipe_cache(void) { - // Nothing to do since there is no cache in this implementation. -} - -// Needed for test targets to build. -extern "C" void run_test(void) {} - -void InitializeFuzzerRun() { - memset(__host_flash, 0xff, sizeof(__host_flash)); - nvmem_init(); - nvmem_enable_commits(); - srand(0); -} - -// Used to verify the model hasn't become out of sync with the implementation. -// The usefulness of this fuzzer comes from its ability to reach all the code -// paths. -bool SelfTest() { - InitializeFuzzerRun(); - - PinweaverModel pinweaver_model; - alignas(kBufferAlignment) uint8_t buffer[PW_MAX_MESSAGE_SIZE] = {}; - fuzz::span buffer_view(buffer, sizeof(buffer)); - fuzz::pinweaver::Request request; - - fuzz::pinweaver::ResetTree* reset_tree = request.mutable_reset_tree(); - reset_tree->set_height(2); - reset_tree->set_bits_per_level(2); - assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); - - fuzz::pinweaver::InsertLeaf* insert_leaf = request.mutable_insert_leaf(); - constexpr char delay_schedule[] = "\000\000\000\005\377\377\377\377"; - insert_leaf->mutable_delay_schedule()->assign( - delay_schedule, delay_schedule + sizeof(delay_schedule)); - assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); - - request.mutable_try_auth(); - assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); - - request.mutable_get_log(); - assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); - - request.mutable_log_replay(); - assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); - - request.mutable_reset_auth(); - assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); - - request.mutable_remove_leaf(); - assert(pinweaver_model.ApplyRequest(request, buffer_view) == EC_SUCCESS); - - return true; -} - -DEFINE_CUSTOM_PROTO_MUTATOR_IMPL(false, fuzz::Cr50FuzzerInput) -DEFINE_CUSTOM_PROTO_CROSSOVER_IMPL(false, fuzz::Cr50FuzzerInput) - -extern "C" int test_fuzz_one_input(const uint8_t* data, unsigned int size) { - static bool initialized = SelfTest(); - assert(initialized); - - fuzz::Cr50FuzzerInput input; - if (!LoadProtoInput(false, data, size, &input)) { - return 0; - } - - InitializeFuzzerRun(); - - PinweaverModel pinweaver_model; - alignas(kBufferAlignment) uint8_t buffer[PW_MAX_MESSAGE_SIZE] = {}; - fuzz::span buffer_view(buffer, sizeof(buffer)); - for (const fuzz::Cr50SubAction& action : input.sub_actions()) { - switch (action.sub_action_case()) { - case fuzz::Cr50SubAction::kRandomBytes: - fuzz::CopyWithPadding(action.random_bytes().value(), buffer_view, 0); - pinweaver_model.SendBuffer(buffer_view); - break; - case fuzz::Cr50SubAction::kPinweaver: - pinweaver_model.ApplyRequest(action.pinweaver(), buffer_view); - break; - case fuzz::Cr50SubAction::SUB_ACTION_NOT_SET: - break; - } - } - return 0; -} diff --git a/fuzz/pinweaver_fuzz.owners b/fuzz/pinweaver_fuzz.owners deleted file mode 100644 index 80e5dc1dee..0000000000 --- a/fuzz/pinweaver_fuzz.owners +++ /dev/null @@ -1,5 +0,0 @@ -# Emails to CC on clusterfuzz bugs for this target: -allenwebb@google.com -mnissler@google.com -rspangler@chromium.org -vbendeb@chromium.org diff --git a/fuzz/pinweaver_fuzz.proto b/fuzz/pinweaver_fuzz.proto deleted file mode 100644 index 0291eacd88..0000000000 --- a/fuzz/pinweaver_fuzz.proto +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2018 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -syntax = "proto3"; - -package fuzz; - -import public "fuzz/pinweaver/pinweaver.proto"; - -message RandomBytes { - bytes value = 1; -} - -message Cr50SubAction { - // Allows a logical representation of an action (PinWeaver) or a literal - // representation (RandomBytes). The logical representation fills out the - // expected values of particular fields when they are empty or not part of the - // proto so that the fuzzer can reach parts of the code without having to - // brute force an HMAC. The literal representation allows for the fuzzer to - // represent inputs that cannot be represented with the logical - // representation. - oneof sub_action { - RandomBytes random_bytes = 1; - pinweaver.Request pinweaver = 2; - } -} - -message Cr50FuzzerInput { - repeated Cr50SubAction sub_actions = 1; -} diff --git a/fuzz/pinweaver_fuzz.tasklist b/fuzz/pinweaver_fuzz.tasklist deleted file mode 100644 index 24870f2abb..0000000000 --- a/fuzz/pinweaver_fuzz.tasklist +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright 2018 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/** - * See CONFIG_TASK_LIST in config.h for details. - */ -#define CONFIG_TEST_TASK_LIST diff --git a/fuzz/pinweaver_model.h b/fuzz/pinweaver_model.h index a16e54690f..84508786f3 100644 --- a/fuzz/pinweaver_model.h +++ b/fuzz/pinweaver_model.h @@ -12,7 +12,7 @@ #include #define HIDE_EC_STDLIB -#include "fuzz/pinweaver_fuzz.pb.h" +#include "fuzz/cr50_fuzz.pb.h" #include "fuzz/mem_hash_tree.h" #include "fuzz/span.h" #include "include/pinweaver.h" diff --git a/fuzz/u2f_fuzz.cc b/fuzz/u2f_fuzz.cc deleted file mode 100644 index 356301e52a..0000000000 --- a/fuzz/u2f_fuzz.cc +++ /dev/null @@ -1,240 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include - -#include -#include -#include -#include - -#define HIDE_EC_STDLIB -extern "C" { -#include "physical_presence.h" -#include "u2f_cmds.h" -#include "u2f_impl.h" -#include "internal.h" -} - -extern "C" { -/******************************************************************************/ -/* Mock implementations of cr50 board. - */ -int system_get_chip_unique_id(uint8_t **id) -{ - return P256_NBYTES; -} - -/******************************************************************************/ -/* Mock implementations of Dcrypto functionality. - */ -int DCRYPTO_x509_gen_u2f_cert_name(const p256_int *d, const p256_int *pk_x, - const p256_int *pk_y, const p256_int *serial, - const char *name, uint8_t *cert, const int n) -{ - memset(cert, 1, n); - return n; -} - -enum dcrypto_result DCRYPTO_p256_key_from_bytes( - p256_int *x, p256_int *y, p256_int *d, - const uint8_t key_bytes[P256_NBYTES]) -{ - p256_int key; - - p256_from_bin(key_bytes, &key); - - // The actual condition for this function to fail happens rarely, - // and not able to to control. So we assume it fails for some inputs - // for fuzz purpose. - if (P256_DIGIT(&key, 0) % 10 == 0) { - return DCRYPTO_RETRY; - } - - if (p256_lt_blinded(&key, &SECP256r1_nMin2) >= 0) - return DCRYPTO_RETRY; - p256_add_d(&key, 1, d); - if (x == NULL || y == NULL) - return DCRYPTO_OK; - memset(x, 0, P256_NBYTES); - memset(y, 0, P256_NBYTES); - return DCRYPTO_OK; -} - -enum dcrypto_result dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg, - const p256_int *key, - const p256_int *message, - p256_int *r, p256_int *s) -{ - memset(r, 0, sizeof(p256_int)); - memset(s, 0, sizeof(p256_int)); - return DCRYPTO_OK; -} - -/******************************************************************************/ -/* Mock implementations of U2F functionality. - */ -static struct u2f_state ustate; -struct u2f_state *u2f_get_state(void) -{ - return &ustate; -} - -static enum touch_state tstate; -enum touch_state pop_check_presence(int consume) -{ - return tstate; -} - -uint8_t buffer[512]; - -int test_fuzz_one_input(const uint8_t *data, unsigned int size) -{ - FuzzedDataProvider data_provider(data, size); - - if (data_provider.ConsumeBool()) { - ustate.drbg_entropy_size = 64; - } else { - ustate.drbg_entropy_size = 32; - } - - if (data_provider.ConsumeBool()) { - tstate = POP_TOUCH_YES; - } else { - tstate = POP_TOUCH_NO; - } - - while (data_provider.remaining_bytes() > 0) { - std::vector bytes; - int command_num = data_provider.ConsumeIntegralInRange(0, 2); - size_t request_size, response_size; - struct u2f_generate_req *generate_req; - struct u2f_generate_resp *resp; - struct u2f_generate_versioned_resp *versioned_resp; - struct u2f_sign_req *sign_req; - struct u2f_sign_versioned_req *sign_versioned_req; - struct u2f_attest_req *attest_req; - struct g2f_register_msg *g2f_msg; - uint8_t appId[U2F_APPID_SIZE]; - uint8_t userSecret[U2F_USER_SECRET_SIZE]; - uint8_t flags; - struct u2f_key_handle kh; - struct u2f_versioned_key_handle versioned_kh; - struct u2f_ec_point public_key; - int kh_version; - vendor_cmd_rc rc; - - switch (command_num) { - case 0: - bytes = data_provider.ConsumeBytes( - sizeof(struct u2f_generate_req)); - memcpy(buffer, bytes.data(), bytes.size()); - generate_req = (u2f_generate_req *)buffer; - memcpy(appId, generate_req->appId, U2F_APPID_SIZE); - memcpy(userSecret, generate_req->userSecret, - U2F_USER_SECRET_SIZE); - flags = generate_req->flags; - response_size = 512; - rc = u2f_generate_cmd(VENDOR_CC_U2F_GENERATE, buffer, - sizeof(struct u2f_generate_req), - &response_size); - if (rc != VENDOR_RC_SUCCESS) { - break; - } - kh_version = (response_size == - sizeof(struct u2f_generate_resp)) ? - 0 : - 1; - if (!kh_version) { - resp = (u2f_generate_resp *)buffer; - kh = resp->keyHandle; - public_key = resp->pubKey; - sign_req = (u2f_sign_req *)buffer; - memcpy(sign_req->appId, appId, U2F_APPID_SIZE); - memcpy(sign_req->userSecret, userSecret, - U2F_USER_SECRET_SIZE); - sign_req->flags = flags; - sign_req->keyHandle = kh; - bytes = data_provider.ConsumeBytes( - U2F_P256_SIZE); - memcpy(sign_req->hash, bytes.data(), - bytes.size()); - request_size = sizeof(struct u2f_sign_req); - } else { - versioned_resp = - (u2f_generate_versioned_resp *)buffer; - versioned_kh = versioned_resp->keyHandle; - sign_versioned_req = - (u2f_sign_versioned_req *)buffer; - memcpy(sign_versioned_req->appId, appId, - U2F_APPID_SIZE); - memcpy(sign_versioned_req->userSecret, - userSecret, U2F_USER_SECRET_SIZE); - sign_versioned_req->flags = flags; - sign_versioned_req->keyHandle = versioned_kh; - bytes = data_provider.ConsumeBytes( - U2F_P256_SIZE); - memcpy(sign_versioned_req->hash, bytes.data(), - bytes.size()); - request_size = - sizeof(struct u2f_sign_versioned_req); - } - response_size = 512; - u2f_sign_cmd(VENDOR_CC_U2F_SIGN, buffer, request_size, - &response_size); - if (!kh_version) { - attest_req = (u2f_attest_req *)buffer; - attest_req->format = U2F_ATTEST_FORMAT_REG_RESP; - attest_req->dataLen = - sizeof(struct g2f_register_msg); - memcpy(attest_req->userSecret, userSecret, - U2F_USER_SECRET_SIZE); - g2f_msg = (g2f_register_msg *)attest_req->data; - g2f_msg->reserved = 0; - memcpy(g2f_msg->app_id, appId, U2F_APPID_SIZE); - memcpy(g2f_msg->key_handle.hmac, kh.hmac, - sizeof(kh.hmac)); - memcpy(g2f_msg->key_handle.origin_seed, - kh.origin_seed, sizeof(kh.origin_seed)); - g2f_msg->public_key = public_key; - bytes = data_provider.ConsumeBytes( - U2F_CHAL_SIZE); - memcpy(g2f_msg->challenge, bytes.data(), - bytes.size()); - response_size = 512; - u2f_attest_cmd(VENDOR_CC_U2F_ATTEST, buffer, - sizeof(struct u2f_attest_req), - &response_size); - } - break; - case 1: { - bool is_versioned = data_provider.ConsumeBool(); - request_size = - is_versioned ? - sizeof(struct u2f_sign_versioned_req) : - sizeof(struct u2f_sign_req); - bytes = data_provider.ConsumeBytes( - request_size); - memcpy(buffer, bytes.data(), bytes.size()); - response_size = 512; - u2f_sign_cmd(VENDOR_CC_U2F_SIGN, buffer, request_size, - &response_size); - break; - } - case 2: - auto str = data_provider.ConsumeRandomLengthString(256); - memcpy(buffer, str.data(), str.size()); - attest_req = (u2f_attest_req *)buffer; - attest_req->dataLen = sizeof(struct g2f_register_msg); - response_size = 512; - u2f_attest_cmd(VENDOR_CC_U2F_ATTEST, buffer, str.size(), - &response_size); - break; - } - break; - } - return 0; -} -} \ No newline at end of file diff --git a/fuzz/u2f_fuzz.tasklist b/fuzz/u2f_fuzz.tasklist deleted file mode 100644 index 24870f2abb..0000000000 --- a/fuzz/u2f_fuzz.tasklist +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright 2018 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/** - * See CONFIG_TASK_LIST in config.h for details. - */ -#define CONFIG_TEST_TASK_LIST -- cgit v1.2.1