summaryrefslogtreecommitdiff
path: root/fuzz/cr50_fuzz.cc
diff options
context:
space:
mode:
Diffstat (limited to 'fuzz/cr50_fuzz.cc')
-rw-r--r--fuzz/cr50_fuzz.cc135
1 files changed, 77 insertions, 58 deletions
diff --git a/fuzz/cr50_fuzz.cc b/fuzz/cr50_fuzz.cc
index 90b8350fc2..dcd80e93e9 100644
--- a/fuzz/cr50_fuzz.cc
+++ b/fuzz/cr50_fuzz.cc
@@ -1,78 +1,97 @@
-/* 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.
- */
+// 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 <unistd.h>
#include <cstdint>
-#include <cstdlib>
#include <cstring>
+#include <unordered_map>
+#include <vector>
+
+#include <src/libfuzzer/libfuzzer_macro.h>
+#include <src/mutator.h>
#define HIDE_EC_STDLIB
-#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)
-
-extern "C" uint32_t nvmem_user_sizes[NVMEM_NUM_USERS] = {
- NVMEM_TPM_SIZE,
- NVMEM_CR50_SIZE
-};
-
-extern "C" void rand_bytes(void *buffer, size_t len)
-{
- size_t x = 0;
-
- for (; x < len; ++x)
- ((uint8_t *)buffer)[x] = rand();
+#include "chip/host/persistence.h"
+#include "fuzz/cr50_fuzz.pb.h"
+#include "fuzz/fuzz_config.h"
+#include "fuzz/pinweaver_model.h"
+#include "fuzz/span.h"
+#include "include/nvmem.h"
+#include "include/nvmem_vars.h"
+#include "include/pinweaver.h"
+
+using protobuf_mutator::libfuzzer::LoadProtoInput;
+
+namespace {
+constexpr size_t kBufferAlignment = alignof(pw_request_t) >
+ alignof(pw_response_t)
+ ? alignof(pw_request_t)
+ : alignof(pw_response_t);
+} // namespace
+
+extern "C" uint32_t nvmem_user_sizes[NVMEM_NUM_USERS] = {NVMEM_TPM_SIZE,
+ NVMEM_CR50_SIZE};
+
+extern "C" void rand_bytes(void* data, size_t len) {
+ size_t x = 0;
+
+ uint8_t* buffer = reinterpret_cast<uint8_t*>(data);
+ for (; x < len; ++x) {
+ buffer[x] = rand();
+ }
}
-extern "C" void get_storage_seed(void *buf, size_t *len)
-{
- memset(buf, 0x77, *len);
+extern "C" void get_storage_seed(void* buf, size_t* len) {
+ memset(buf, 0x77, *len);
}
extern "C" uint8_t get_current_pcr_digest(const uint8_t bitmask[2],
- uint8_t sha256_of_selected_pcr[32])
-{
- memset(sha256_of_selected_pcr, 0, 32);
- return 0;
+ uint8_t sha256_of_selected_pcr[32]) {
+ memset(sha256_of_selected_pcr, 0, 32);
+ return 0;
}
-extern "C" void run_test(void)
-{
-}
+// Needed for test targets to build.
+extern "C" 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);
- }
+void InitializeFuzzerRun() {
+ memset(__host_flash, 0xff, sizeof(__host_flash));
+ nvmem_init();
+ nvmem_enable_commits();
+ initvars();
+ srand(0);
}
-/* Prevent this from being stack allocated. */
-static uint8_t tpm_io_buffer[PW_MAX_MESSAGE_SIZE];
+DEFINE_CUSTOM_PROTO_MUTATOR_IMPL(false, fuzz::Cr50FuzzerInput)
+DEFINE_CUSTOM_PROTO_CROSSOVER_IMPL(false, fuzz::Cr50FuzzerInput)
+
+extern "C" int test_fuzz_one_input(const uint8_t* data, unsigned int size) {
+ fuzz::Cr50FuzzerInput input;
+ if (!LoadProtoInput(false, data, size, &input)) {
+ return 0;
+ }
-extern "C" 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;
+ InitializeFuzzerRun();
- 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;
+ PinweaverModel pinweaver_model;
+ alignas(kBufferAlignment) uint8_t buffer[PW_MAX_MESSAGE_SIZE] = {};
+ fuzz::span<uint8_t> buffer_view(buffer, sizeof(buffer));
+ for (const fuzz::Cr50SubAction& action : input.sub_actions()) {
+ switch (action.sub_action_case()) {
+ case fuzz::Cr50SubAction::kRandomBytes:
+ fuzz::CopyWithPadding(action.random_bytes().value(), buffer_view, 0);
+ pinweaver_model.SendBuffer(buffer_view);
+ break;
+ case fuzz::Cr50SubAction::kPinweaver:
+ pinweaver_model.ApplyRequest(action.pinweaver(), buffer_view);
+ break;
+ case fuzz::Cr50SubAction::SUB_ACTION_NOT_SET:
+ break;
+ }
+ }
+ return 0;
}