xref: /aosp_15_r20/external/vboot_reference/tests/vb2_preamble_fuzzer.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1 // Copyright 2019 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "2api.h"
6 #include "2common.h"
7 #include "2misc.h"
8 #include "2nvstorage.h"
9 #include "2rsa.h"
10 #include "2rsa_private.h"
11 #include "2secdata.h"
12 
13 static struct vb2_context *ctx;
14 static uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE]
15 	__attribute__((aligned(VB2_WORKBUF_ALIGN)));
16 
17 static const uint8_t *mock_preamble;
18 static size_t mock_preamble_size;
19 
20 /* Limit exposure of code for which we didn't set up the environment right. */
vb2api_fail(struct vb2_context * c,uint8_t reason,uint8_t subcode)21 void vb2api_fail(struct vb2_context *c, uint8_t reason, uint8_t subcode)
22 {
23 	return;
24 }
25 
vb2ex_read_resource(struct vb2_context * c,enum vb2_resource_index index,uint32_t offset,void * buf,uint32_t size)26 vb2_error_t vb2ex_read_resource(struct vb2_context *c,
27 				enum vb2_resource_index index, uint32_t offset,
28 				void *buf, uint32_t size)
29 {
30 	if (index != VB2_RES_FW_VBLOCK)
31 		return VB2_ERROR_EX_READ_RESOURCE_INDEX;
32 
33 	/* The preamble_offset in our mock shared data is 0, so we can assume
34 	   that offset here is a direct offset into the preamble. */
35 	if (offset > mock_preamble_size || mock_preamble_size - offset < size)
36 		return VB2_ERROR_EX_READ_RESOURCE_SIZE;
37 
38 	memcpy(buf, mock_preamble + offset, size);
39 	return VB2_SUCCESS;
40 }
41 
42 /* Pretend that signature checks always succeed so the fuzzer can cover more. */
vb2_check_padding(const uint8_t * sig,const struct vb2_public_key * key)43 vb2_error_t vb2_check_padding(const uint8_t *sig,
44 			      const struct vb2_public_key *key)
45 {
46 	return VB2_SUCCESS;
47 }
48 
vb2_safe_memcmp(const void * s1,const void * s2,size_t size)49 vb2_error_t vb2_safe_memcmp(const void *s1, const void *s2, size_t size)
50 {
51 	return VB2_SUCCESS;
52 }
53 
54 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)55 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
56 	const size_t datakey_size = 4096;	// enough for all our signatures
57 
58 	if (size < datakey_size)
59 		return 0;
60 
61 	if (vb2api_init(workbuf, sizeof(workbuf), &ctx))
62 		abort();
63 	vb2_nv_init(ctx);
64 	vb2api_secdata_firmware_create(ctx);
65 	vb2api_secdata_kernel_create(ctx);
66 	if (vb2_secdata_firmware_init(ctx) || vb2_secdata_kernel_init(ctx))
67 		abort();
68 
69 	struct vb2_workbuf wb;
70 	vb2_workbuf_from_ctx(ctx, &wb);
71 
72 	uint8_t *key = vb2_workbuf_alloc(&wb, datakey_size);
73 	if (!key)
74 		abort();
75 	memcpy(key, data, datakey_size);
76 
77 	mock_preamble = data + datakey_size;
78 	mock_preamble_size = size - datakey_size;
79 
80 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
81 	sd->data_key_offset = vb2_offset_of(sd, key);
82 	sd->data_key_size = datakey_size;
83 	vb2_set_workbuf_used(ctx, sd->data_key_offset + sd->data_key_size);
84 
85 	sd->vblock_preamble_offset = 0;
86 	vb2_load_fw_preamble(ctx);
87 
88 	return 0;
89 }
90