diff options
author | Julius Werner <jwerner@chromium.org> | 2019-10-17 18:01:02 -0700 |
---|---|---|
committer | Manoj Gupta <manojgupta@chromium.org> | 2019-10-22 14:24:52 +0000 |
commit | 34307d894dfad7fdb962ab1b126d44a2a4a5fd68 (patch) | |
tree | cf1f8d3d790c30feffcc9197d432a03ed9f8001d /tests | |
parent | 2abf0e7b7038b4ac12ea5edf7db00dad09a8e5c7 (diff) | |
download | vboot-34307d894dfad7fdb962ab1b126d44a2a4a5fd68.tar.gz |
tests: Add fuzzers for payload and preamble parsing
This patch adds fuzzers for vb2_load_fw_keyblock() and
vb2_load_fw_preamble(). I'm new at fuzzing so please let me know if I
did something dumb.
BRANCH=None
BUG=None
TEST=Ran them manually with cros_fuzz.
Change-Id: Ica39fcf4a3d250e69c51214afcee9e9815667ff8
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1867969
Commit-Queue: Manoj Gupta <manojgupta@chromium.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/vb2_keyblock_fuzzer.c | 98 | ||||
-rw-r--r-- | tests/vb2_preamble_fuzzer.c | 95 |
2 files changed, 193 insertions, 0 deletions
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; +} |