diff options
author | Allen Webb <allenwebb@google.com> | 2018-08-21 07:50:27 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-09-07 18:36:34 -0700 |
commit | 269ff3569799531fa2b7f7a5def012ea254ceb57 (patch) | |
tree | 5175c35320981d22707ed108bfe975ab29e37064 | |
parent | 8961872603f6d7b66ef97d444711e83d6a55e2f4 (diff) | |
download | chrome-ec-269ff3569799531fa2b7f7a5def012ea254ceb57.tar.gz |
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 <allenwebb@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1183534
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | Makefile.rules | 2 | ||||
-rw-r--r-- | fuzz/build.mk | 8 | ||||
-rw-r--r-- | fuzz/cr50_fuzz.c | 68 | ||||
-rw-r--r-- | fuzz/cr50_fuzz.tasklist | 17 | ||||
-rw-r--r-- | fuzz/fuzz_config.h | 56 |
5 files changed, 148 insertions, 3 deletions
diff --git a/Makefile.rules b/Makefile.rules index 8857b24f47..d44db81ba5 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -74,7 +74,7 @@ cmd_bin_to_hex = $(OBJCOPY) -I binary -O ihex \ cmd_smap = $(NM) $< | sort > $@ cmd_elf = $(CC) $(objs) $(libsharedobjs_elf-y) $(LDFLAGS) \ -o $@ -Wl,-T,$< -Wl,-Map,$(patsubst %.elf,%.map,$@) -cmd_fuzz_exe = $(CXX) $^ $(HOST_TEST_LDFLAGS) -o $@ +cmd_fuzz_exe = $(CXX) $^ $(HOST_TEST_LDFLAGS) $(LDFLAGS_EXTRA) -o $@ cmd_exe = $(CC) $(ro-objs) $(HOST_TEST_LDFLAGS) -o $@ cmd_c_to_o = $(CC) $(CFLAGS) -MMD -MP -MF $@.d -c $< -o $(@D)/$(@F) cmd_c_to_build = $(BUILDCC) $(BUILD_CFLAGS) \ 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 <obj_name>-rw # Otherwise use <obj_name>-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 <stdint.h> +#include <stdlib.h> +#include <unistd.h> + +#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 <key, value> 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 |