From 269ff3569799531fa2b7f7a5def012ea254ceb57 Mon Sep 17 00:00:00 2001 From: Allen Webb Date: Tue, 21 Aug 2018 07:50:27 -0700 Subject: cr50_fuzz: Add minimal fuzzer for pinweaver. This adds a minimal pinweaver fuzzer as a foundation for further work. It will not be able to achieve good coverage because it doesn't have a proper description of the protocol, however it demonstrates that the prerequisites to build against dcrypto, nvmem_vars, and nvcounter are satisfied for the host board. CQ-DEPEND=CL:1183532 BRANCH=none BUG=chromium:876582 TEST=make -j buildfuzztests && ./build/host/cr50_fuzz/cr50_fuzz.exe Change-Id: I520d71c224d583c51dc3292dc051ee8de4a4116a Signed-off-by: Allen Webb Reviewed-on: https://chromium-review.googlesource.com/1183534 Reviewed-by: Randall Spangler --- fuzz/build.mk | 8 ++++-- fuzz/cr50_fuzz.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ fuzz/cr50_fuzz.tasklist | 17 +++++++++++++ fuzz/fuzz_config.h | 56 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 fuzz/cr50_fuzz.c create mode 100644 fuzz/cr50_fuzz.tasklist (limited to 'fuzz') diff --git a/fuzz/build.mk b/fuzz/build.mk index 7a45116fe2..5e297b3d66 100644 --- a/fuzz/build.mk +++ b/fuzz/build.mk @@ -6,7 +6,7 @@ # fuzzer binaries # -fuzz-test-list-host = host_command_fuzz +fuzz-test-list-host = cr50_fuzz host_command_fuzz # For fuzzing targets libec.a is built from the ro objects and hides functions # that collide with stdlib. The rw only objects are then linked against libec.a @@ -20,4 +20,8 @@ fuzz-test-list-host = host_command_fuzz # Does your object file need to link against cstdlib? # Yes -> use -rw # Otherwise use -y -host_command_fuzz-rw = host_command_fuzz.o +cr50_fuzz-rw = cr50_fuzz.o +host_command_fuzz-y = host_command_fuzz.o + +$(out)/cr50_fuzz.exe: $(out)/cryptoc/libcryptoc.a +$(out)/cr50_fuzz.exe: LDFLAGS_EXTRA+=-lcrypto diff --git a/fuzz/cr50_fuzz.c b/fuzz/cr50_fuzz.c new file mode 100644 index 0000000000..ccf99172d6 --- /dev/null +++ b/fuzz/cr50_fuzz.c @@ -0,0 +1,68 @@ +/* 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 "fuzz_config.h" +#include "nvmem.h" +#include "nvmem_vars.h" +#include "persistence.h" +#include "pinweaver.h" + +#define NVMEM_TPM_SIZE ((sizeof((struct nvmem_partition *)0)->buffer) \ + - NVMEM_CR50_SIZE) + +uint32_t nvmem_user_sizes[NVMEM_NUM_USERS] = { + NVMEM_TPM_SIZE, + NVMEM_CR50_SIZE +}; + +void rand_bytes(void *buffer, size_t len) +{ + size_t x = 0; + + for (; x < len; ++x) + ((uint8_t *)buffer)[x] = rand(); +} + +void get_storage_seed(void *buf, size_t *len) +{ + memset(buf, 0x77, *len); +} + +void run_test(void) +{ +} + +static void assign_pw_field_from_bytes(const uint8_t *data, unsigned int size, + uint8_t *destination, size_t dest_size) +{ + if (size >= dest_size) { + memcpy(destination, data, dest_size); + } else { + memcpy(destination, data, size); + memset(destination + size, 0, dest_size - size); + } +} + +/* Prevent this from being stack allocated. */ +static uint8_t tpm_io_buffer[PW_MAX_MESSAGE_SIZE]; + +int test_fuzz_one_input(const uint8_t *data, unsigned int size) +{ + struct merkle_tree_t merkle_tree = {}; + struct pw_request_t *request = (struct pw_request_t *)tpm_io_buffer; + struct pw_response_t *response = (struct pw_response_t *)tpm_io_buffer; + + memset(__host_flash, 0xff, sizeof(__host_flash)); + pinweaver_init(); + assign_pw_field_from_bytes(data, size, tpm_io_buffer, sizeof(tpm_io_buffer)); + pw_handle_request(&merkle_tree, request, response); + return 0; +} diff --git a/fuzz/cr50_fuzz.tasklist b/fuzz/cr50_fuzz.tasklist new file mode 100644 index 0000000000..de4df33e13 --- /dev/null +++ b/fuzz/cr50_fuzz.tasklist @@ -0,0 +1,17 @@ +/* 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. + */ + +/** + * List of enabled tasks in the priority order + * + * The first one has the lowest priority. + * + * For each task, use the macro TASK_TEST(n, r, d, s) where : + * 'n' in the name of the task + * 'r' in the main routine of the task + * 'd' in an opaque parameter passed to the routine at startup + * 's' is the stack size in bytes; must be a multiple of 8 + */ +#define CONFIG_TEST_TASK_LIST diff --git a/fuzz/fuzz_config.h b/fuzz/fuzz_config.h index 6244340c7e..04d69c3743 100644 --- a/fuzz/fuzz_config.h +++ b/fuzz/fuzz_config.h @@ -12,6 +12,62 @@ /* Disable hibernate: We never want to exit while fuzzing. */ #undef CONFIG_HIBERNATE +#ifdef TEST_CR50_FUZZ +#define CONFIG_DCRYPTO +#define CONFIG_PINWEAVER +#define CONFIG_UPTO_SHA512 +#define SHA512_SUPPORT + +/******************************************************************************/ +/* From chip/g/config_chip.h */ + +#define CFG_FLASH_HALF (CONFIG_FLASH_SIZE >> 1) +#define CFG_TOP_SIZE 0x3800 +#define CFG_TOP_A_OFF (CFG_FLASH_HALF - CFG_TOP_SIZE) +#define CFG_TOP_B_OFF (CONFIG_FLASH_SIZE - CFG_TOP_SIZE) + +/******************************************************************************/ +/* From board/cr50/board.h */ +/* Non-volatile counter storage for U2F */ +#define CONFIG_FLASH_NVCOUNTER +#define CONFIG_FLASH_NVCTR_SIZE CONFIG_FLASH_BANK_SIZE +#define CONFIG_FLASH_NVCTR_BASE_A (CONFIG_PROGRAM_MEMORY_BASE + \ + CFG_TOP_A_OFF) +#define CONFIG_FLASH_NVCTR_BASE_B (CONFIG_PROGRAM_MEMORY_BASE + \ + CFG_TOP_B_OFF) +/* We're using TOP_A for partition 0, TOP_B for partition 1 */ +#define CONFIG_FLASH_NVMEM +/* Offset to start of NvMem area from base of flash */ +#define CONFIG_FLASH_NVMEM_OFFSET_A (CFG_TOP_A_OFF + CONFIG_FLASH_NVCTR_SIZE) +#define CONFIG_FLASH_NVMEM_OFFSET_B (CFG_TOP_B_OFF + CONFIG_FLASH_NVCTR_SIZE) +/* Address of start of Nvmem area */ +#define CONFIG_FLASH_NVMEM_BASE_A (CONFIG_PROGRAM_MEMORY_BASE + \ + CONFIG_FLASH_NVMEM_OFFSET_A) +#define CONFIG_FLASH_NVMEM_BASE_B (CONFIG_PROGRAM_MEMORY_BASE + \ + CONFIG_FLASH_NVMEM_OFFSET_B) +/* Size partition in NvMem */ +#define NVMEM_PARTITION_SIZE (CFG_TOP_SIZE - CONFIG_FLASH_NVCTR_SIZE) +/* Size in bytes of NvMem area */ +#define CONFIG_FLASH_NVMEM_SIZE (NVMEM_PARTITION_SIZE * NVMEM_NUM_PARTITIONS) +/* Enable variable support. */ +#define CONFIG_FLASH_NVMEM_VARS +#define NVMEM_CR50_SIZE 272 +#define CONFIG_FLASH_NVMEM_VARS_USER_SIZE NVMEM_CR50_SIZE + +#ifndef __ASSEMBLER__ +enum nvmem_users { + NVMEM_TPM = 0, + NVMEM_CR50, + NVMEM_NUM_USERS +}; +#endif +#define CONFIG_FLASH_NVMEM_VARS_USER_NUM NVMEM_NUM_USERS + +/******************************************************************************/ +#define CONFIG_SW_CRC + +#endif /* TEST_CR50_FUZZ */ + #ifdef TEST_HOST_COMMAND_FUZZ #undef CONFIG_HOSTCMD_DEBUG_MODE -- cgit v1.2.1