summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--tests/vb2_keyblock_fuzzer.c98
-rw-r--r--tests/vb2_preamble_fuzzer.c95
3 files changed, 196 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 93ac67c1..0bb8de90 100644
--- a/Makefile
+++ b/Makefile
@@ -783,7 +783,9 @@ TEST_KEYS = ${SRC_RUN}/tests/testkeys
# Fuzzing binaries
FUZZ_TEST_NAMES = \
- tests/cgpt_fuzzer
+ tests/cgpt_fuzzer \
+ tests/vb2_keyblock_fuzzer \
+ tests/vb2_preamble_fuzzer
FUZZ_TEST_BINS = $(addprefix ${BUILD}/,${FUZZ_TEST_NAMES})
FUZZ_TEST_OBJS += $(addsuffix .o,${FUZZ_TEST_BINS})
diff --git a/tests/vb2_keyblock_fuzzer.c b/tests/vb2_keyblock_fuzzer.c
new file mode 100644
index 00000000..7ac7499c
--- /dev/null
+++ b/tests/vb2_keyblock_fuzzer.c
@@ -0,0 +1,98 @@
+// Copyright 2019 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 <assert.h>
+
+#include "2api.h"
+#include "2common.h"
+#include "2misc.h"
+#include "2rsa.h"
+#include "vboot_test.h"
+
+static struct vb2_context ctx;
+__attribute__((aligned(VB2_WORKBUF_ALIGN)))
+static uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE];
+static struct {
+ struct vb2_gbb_header h;
+ uint8_t rootkey[4096];
+} gbb;
+
+static const uint8_t *mock_keyblock;
+static size_t mock_keyblock_size;
+
+/* Limit exposure of code for which we didn't set up the environment right. */
+void vb2api_fail(struct vb2_context *c, uint8_t reason, uint8_t subcode)
+{
+ return;
+}
+
+struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c)
+{
+ return &gbb.h;
+}
+
+vb2_error_t vb2ex_read_resource(struct vb2_context *c,
+ enum vb2_resource_index index, uint32_t offset,
+ void *buf, uint32_t size)
+{
+ const void *rbase;
+ size_t rsize;
+
+ switch (index) {
+ case VB2_RES_GBB:
+ rbase = &gbb;
+ rsize = sizeof(gbb);
+ break;
+ case VB2_RES_FW_VBLOCK:
+ rbase = mock_keyblock;
+ rsize = mock_keyblock_size;
+ break;
+ default:
+ return VB2_ERROR_EX_READ_RESOURCE_INDEX;
+ }
+
+ if (offset > rsize || rsize - offset < size)
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ memcpy(buf, rbase + offset, size);
+ return VB2_SUCCESS;
+}
+
+/* Pretend that signature checks always succeed so the fuzzer can cover more. */
+vb2_error_t vb2_check_padding(const uint8_t *sig,
+ const struct vb2_public_key *key)
+{
+ return VB2_SUCCESS;
+}
+
+vb2_error_t vb2_safe_memcmp(const void *s1, const void *s2, size_t size)
+{
+ return VB2_SUCCESS;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ vb2_error_t rv;
+
+ if (size < sizeof(gbb.rootkey))
+ return 0;
+
+ memset(&gbb.h, 0, sizeof(gbb.h));
+ gbb.h.rootkey_offset = gbb.rootkey - (uint8_t *)&gbb;
+ gbb.h.rootkey_size = sizeof(gbb.rootkey);
+
+ memcpy(gbb.rootkey, data, sizeof(gbb.rootkey));
+ mock_keyblock = data + sizeof(gbb.rootkey);
+ mock_keyblock_size = size - sizeof(gbb.rootkey);
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.workbuf = workbuf;
+ ctx.workbuf_size = sizeof(workbuf);
+ rv = vb2_init_context(&ctx);
+ assert(rv == VB2_SUCCESS);
+
+ vb2_load_fw_keyblock(&ctx);
+
+ return 0;
+}
diff --git a/tests/vb2_preamble_fuzzer.c b/tests/vb2_preamble_fuzzer.c
new file mode 100644
index 00000000..0ad2298e
--- /dev/null
+++ b/tests/vb2_preamble_fuzzer.c
@@ -0,0 +1,95 @@
+// Copyright 2019 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 <assert.h>
+
+#include "2api.h"
+#include "2common.h"
+#include "2misc.h"
+#include "2rsa.h"
+#include "2secdata.h"
+#include "vboot_test.h"
+
+static struct vb2_context ctx;
+__attribute__((aligned(VB2_WORKBUF_ALIGN)))
+static uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE];
+
+static const uint8_t *mock_preamble;
+static size_t mock_preamble_size;
+
+/* Limit exposure of code for which we didn't set up the environment right. */
+void vb2api_fail(struct vb2_context *c, uint8_t reason, uint8_t subcode)
+{
+ return;
+}
+
+void vb2_secdata_firmware_set(struct vb2_context *c,
+ enum vb2_secdata_firmware_param param,
+ uint32_t value)
+{
+ /* prevent abort from uninitialized secdata */
+}
+
+vb2_error_t vb2ex_read_resource(struct vb2_context *c,
+ enum vb2_resource_index index, uint32_t offset,
+ void *buf, uint32_t size)
+{
+ if (index != VB2_RES_FW_VBLOCK)
+ return VB2_ERROR_EX_READ_RESOURCE_INDEX;
+
+ /* The preamble_offset in our mock shared data is 0, so we can assume
+ that offset here is a direct offset into the preamble. */
+ if (offset > mock_preamble_size || mock_preamble_size - offset < size)
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ memcpy(buf, mock_preamble + offset, size);
+ return VB2_SUCCESS;
+}
+
+/* Pretend that signature checks always succeed so the fuzzer can cover more. */
+vb2_error_t vb2_check_padding(const uint8_t *sig,
+ const struct vb2_public_key *key)
+{
+ return VB2_SUCCESS;
+}
+
+vb2_error_t vb2_safe_memcmp(const void *s1, const void *s2, size_t size)
+{
+ return VB2_SUCCESS;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ const size_t datakey_size = 4096; // enough for all our signatures
+ vb2_error_t rv;
+
+ if (size < datakey_size)
+ return 0;
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.workbuf = workbuf;
+ ctx.workbuf_size = sizeof(workbuf);
+ rv = vb2_init_context(&ctx);
+ assert(rv == VB2_SUCCESS);
+
+ struct vb2_workbuf wb;
+ vb2_workbuf_from_ctx(&ctx, &wb);
+
+ uint8_t *key = vb2_workbuf_alloc(&wb, datakey_size);
+ assert(key);
+ memcpy(key, data, datakey_size);
+
+ mock_preamble = data + datakey_size;
+ mock_preamble_size = size - datakey_size;
+
+ struct vb2_shared_data *sd = vb2_get_sd(&ctx);
+ sd->data_key_offset = vb2_offset_of(sd, key);
+ sd->data_key_size = datakey_size;
+ vb2_set_workbuf_used(&ctx, sd->data_key_offset + sd->data_key_size);
+
+ sd->vblock_preamble_offset = 0;
+ vb2_load_fw_preamble(&ctx);
+
+ return 0;
+}