summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllen Webb <allenwebb@google.com>2018-08-21 07:50:27 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-09-07 18:36:34 -0700
commit269ff3569799531fa2b7f7a5def012ea254ceb57 (patch)
tree5175c35320981d22707ed108bfe975ab29e37064
parent8961872603f6d7b66ef97d444711e83d6a55e2f4 (diff)
downloadchrome-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.rules2
-rw-r--r--fuzz/build.mk8
-rw-r--r--fuzz/cr50_fuzz.c68
-rw-r--r--fuzz/cr50_fuzz.tasklist17
-rw-r--r--fuzz/fuzz_config.h56
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