xref: /aosp_15_r20/external/vboot_reference/tests/vb20_verify_fw.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2011 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker  * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker  *
5*8617a60dSAndroid Build Coastguard Worker  * Routines for verifying a firmware image's signature.
6*8617a60dSAndroid Build Coastguard Worker  */
7*8617a60dSAndroid Build Coastguard Worker 
8*8617a60dSAndroid Build Coastguard Worker #include <stdio.h>
9*8617a60dSAndroid Build Coastguard Worker #include <stdlib.h>
10*8617a60dSAndroid Build Coastguard Worker #include <string.h>
11*8617a60dSAndroid Build Coastguard Worker 
12*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
13*8617a60dSAndroid Build Coastguard Worker #include "2misc.h"
14*8617a60dSAndroid Build Coastguard Worker #include "2secdata.h"
15*8617a60dSAndroid Build Coastguard Worker #include "2sysincludes.h"
16*8617a60dSAndroid Build Coastguard Worker 
17*8617a60dSAndroid Build Coastguard Worker const char *gbb_fname;
18*8617a60dSAndroid Build Coastguard Worker const char *vblock_fname;
19*8617a60dSAndroid Build Coastguard Worker const char *body_fname;
20*8617a60dSAndroid Build Coastguard Worker 
21*8617a60dSAndroid Build Coastguard Worker #if defined(ENABLE_HWCRYPTO_RSA_TESTS)
vb2api_hwcrypto_allowed(struct vb2_context * ctx)22*8617a60dSAndroid Build Coastguard Worker bool vb2api_hwcrypto_allowed(struct vb2_context *ctx)
23*8617a60dSAndroid Build Coastguard Worker {
24*8617a60dSAndroid Build Coastguard Worker 	printf("hwcrypto is allowed.\n");
25*8617a60dSAndroid Build Coastguard Worker 	return true;
26*8617a60dSAndroid Build Coastguard Worker }
27*8617a60dSAndroid Build Coastguard Worker #endif
28*8617a60dSAndroid Build Coastguard Worker 
29*8617a60dSAndroid Build Coastguard Worker /**
30*8617a60dSAndroid Build Coastguard Worker  * Local implementation which reads resources from individual files.  Could be
31*8617a60dSAndroid Build Coastguard Worker  * more elegant and read from image.bin, if we understood the fmap.
32*8617a60dSAndroid Build Coastguard Worker  */
vb2ex_read_resource(struct vb2_context * c,enum vb2_resource_index index,uint32_t offset,void * buf,uint32_t size)33*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2ex_read_resource(struct vb2_context *c,
34*8617a60dSAndroid Build Coastguard Worker 				enum vb2_resource_index index, uint32_t offset,
35*8617a60dSAndroid Build Coastguard Worker 				void *buf, uint32_t size)
36*8617a60dSAndroid Build Coastguard Worker {
37*8617a60dSAndroid Build Coastguard Worker 	const char *fname;
38*8617a60dSAndroid Build Coastguard Worker 	FILE *f;
39*8617a60dSAndroid Build Coastguard Worker 	int got_size;
40*8617a60dSAndroid Build Coastguard Worker 
41*8617a60dSAndroid Build Coastguard Worker 	/* Get the filename for the resource */
42*8617a60dSAndroid Build Coastguard Worker 	switch (index) {
43*8617a60dSAndroid Build Coastguard Worker 	case VB2_RES_GBB:
44*8617a60dSAndroid Build Coastguard Worker 		fname = gbb_fname;
45*8617a60dSAndroid Build Coastguard Worker 		break;
46*8617a60dSAndroid Build Coastguard Worker 	case VB2_RES_FW_VBLOCK:
47*8617a60dSAndroid Build Coastguard Worker 		fname = vblock_fname;
48*8617a60dSAndroid Build Coastguard Worker 		break;
49*8617a60dSAndroid Build Coastguard Worker 	default:
50*8617a60dSAndroid Build Coastguard Worker 		return VB2_ERROR_UNKNOWN;
51*8617a60dSAndroid Build Coastguard Worker 	}
52*8617a60dSAndroid Build Coastguard Worker 
53*8617a60dSAndroid Build Coastguard Worker 	/* Open file and seek to the requested offset */
54*8617a60dSAndroid Build Coastguard Worker 	f = fopen(fname, "rb");
55*8617a60dSAndroid Build Coastguard Worker 	if (!f)
56*8617a60dSAndroid Build Coastguard Worker 		return VB2_ERROR_UNKNOWN;
57*8617a60dSAndroid Build Coastguard Worker 
58*8617a60dSAndroid Build Coastguard Worker 	if (fseek(f, offset, SEEK_SET)) {
59*8617a60dSAndroid Build Coastguard Worker 		fclose(f);
60*8617a60dSAndroid Build Coastguard Worker 		return VB2_ERROR_UNKNOWN;
61*8617a60dSAndroid Build Coastguard Worker 	}
62*8617a60dSAndroid Build Coastguard Worker 
63*8617a60dSAndroid Build Coastguard Worker 	/* Read data and close file */
64*8617a60dSAndroid Build Coastguard Worker 	got_size = fread(buf, 1, size, f);
65*8617a60dSAndroid Build Coastguard Worker 	fclose(f);
66*8617a60dSAndroid Build Coastguard Worker 
67*8617a60dSAndroid Build Coastguard Worker 	/* Return success if we read everything */
68*8617a60dSAndroid Build Coastguard Worker 	return got_size == size ? VB2_SUCCESS : VB2_ERROR_UNKNOWN;
69*8617a60dSAndroid Build Coastguard Worker }
70*8617a60dSAndroid Build Coastguard Worker 
vb2ex_tpm_clear_owner(struct vb2_context * c)71*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2ex_tpm_clear_owner(struct vb2_context *c)
72*8617a60dSAndroid Build Coastguard Worker {
73*8617a60dSAndroid Build Coastguard Worker 	// TODO: implement
74*8617a60dSAndroid Build Coastguard Worker 	return VB2_SUCCESS;
75*8617a60dSAndroid Build Coastguard Worker }
76*8617a60dSAndroid Build Coastguard Worker 
77*8617a60dSAndroid Build Coastguard Worker /**
78*8617a60dSAndroid Build Coastguard Worker  * Save non-volatile and/or secure data if needed.
79*8617a60dSAndroid Build Coastguard Worker  */
save_if_needed(struct vb2_context * c)80*8617a60dSAndroid Build Coastguard Worker static void save_if_needed(struct vb2_context *c)
81*8617a60dSAndroid Build Coastguard Worker {
82*8617a60dSAndroid Build Coastguard Worker 
83*8617a60dSAndroid Build Coastguard Worker 	if (c->flags & VB2_CONTEXT_NVDATA_CHANGED) {
84*8617a60dSAndroid Build Coastguard Worker 		// TODO: implement
85*8617a60dSAndroid Build Coastguard Worker 		c->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
86*8617a60dSAndroid Build Coastguard Worker 	}
87*8617a60dSAndroid Build Coastguard Worker 
88*8617a60dSAndroid Build Coastguard Worker 	if (c->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED) {
89*8617a60dSAndroid Build Coastguard Worker 		// TODO: implement
90*8617a60dSAndroid Build Coastguard Worker 		c->flags &= ~VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED;
91*8617a60dSAndroid Build Coastguard Worker 	}
92*8617a60dSAndroid Build Coastguard Worker }
93*8617a60dSAndroid Build Coastguard Worker 
94*8617a60dSAndroid Build Coastguard Worker /**
95*8617a60dSAndroid Build Coastguard Worker  * Verify firmware body
96*8617a60dSAndroid Build Coastguard Worker  */
hash_body(struct vb2_context * c)97*8617a60dSAndroid Build Coastguard Worker static vb2_error_t hash_body(struct vb2_context *c)
98*8617a60dSAndroid Build Coastguard Worker {
99*8617a60dSAndroid Build Coastguard Worker 	uint32_t remaining;
100*8617a60dSAndroid Build Coastguard Worker 	uint8_t block[8192];
101*8617a60dSAndroid Build Coastguard Worker 	uint32_t size;
102*8617a60dSAndroid Build Coastguard Worker 	FILE *f;
103*8617a60dSAndroid Build Coastguard Worker 	vb2_error_t rv;
104*8617a60dSAndroid Build Coastguard Worker 
105*8617a60dSAndroid Build Coastguard Worker 	/* Open the body data */
106*8617a60dSAndroid Build Coastguard Worker 	f = fopen(body_fname, "rb");
107*8617a60dSAndroid Build Coastguard Worker 	if (!f)
108*8617a60dSAndroid Build Coastguard Worker 		return VB2_ERROR_TEST_INPUT_FILE;
109*8617a60dSAndroid Build Coastguard Worker 
110*8617a60dSAndroid Build Coastguard Worker 	/* Start the body hash */
111*8617a60dSAndroid Build Coastguard Worker 	rv = vb2api_init_hash(c, VB2_HASH_TAG_FW_BODY);
112*8617a60dSAndroid Build Coastguard Worker 	if (rv) {
113*8617a60dSAndroid Build Coastguard Worker 		fclose(f);
114*8617a60dSAndroid Build Coastguard Worker 		return rv;
115*8617a60dSAndroid Build Coastguard Worker 	}
116*8617a60dSAndroid Build Coastguard Worker 
117*8617a60dSAndroid Build Coastguard Worker 	remaining = vb2api_get_firmware_size(c);
118*8617a60dSAndroid Build Coastguard Worker 	printf("Expect %d bytes of body...\n", remaining);
119*8617a60dSAndroid Build Coastguard Worker 
120*8617a60dSAndroid Build Coastguard Worker 	/* Extend over the body */
121*8617a60dSAndroid Build Coastguard Worker 	while (remaining) {
122*8617a60dSAndroid Build Coastguard Worker 		size = sizeof(block);
123*8617a60dSAndroid Build Coastguard Worker 		if (size > remaining)
124*8617a60dSAndroid Build Coastguard Worker 			size = remaining;
125*8617a60dSAndroid Build Coastguard Worker 
126*8617a60dSAndroid Build Coastguard Worker 		/* Read next body block */
127*8617a60dSAndroid Build Coastguard Worker 		size = fread(block, 1, size, f);
128*8617a60dSAndroid Build Coastguard Worker 		if (size <= 0)
129*8617a60dSAndroid Build Coastguard Worker 			break;
130*8617a60dSAndroid Build Coastguard Worker 
131*8617a60dSAndroid Build Coastguard Worker 		/* Hash it */
132*8617a60dSAndroid Build Coastguard Worker 		rv = vb2api_extend_hash(c, block, size);
133*8617a60dSAndroid Build Coastguard Worker 		if (rv) {
134*8617a60dSAndroid Build Coastguard Worker 			fclose(f);
135*8617a60dSAndroid Build Coastguard Worker 			return rv;
136*8617a60dSAndroid Build Coastguard Worker 		}
137*8617a60dSAndroid Build Coastguard Worker 
138*8617a60dSAndroid Build Coastguard Worker 		remaining -= size;
139*8617a60dSAndroid Build Coastguard Worker 	}
140*8617a60dSAndroid Build Coastguard Worker 
141*8617a60dSAndroid Build Coastguard Worker 	fclose(f);
142*8617a60dSAndroid Build Coastguard Worker 
143*8617a60dSAndroid Build Coastguard Worker 	/* Check the result */
144*8617a60dSAndroid Build Coastguard Worker 	rv = vb2api_check_hash(c);
145*8617a60dSAndroid Build Coastguard Worker 	if (rv)
146*8617a60dSAndroid Build Coastguard Worker 		return rv;
147*8617a60dSAndroid Build Coastguard Worker 
148*8617a60dSAndroid Build Coastguard Worker 	return VB2_SUCCESS;
149*8617a60dSAndroid Build Coastguard Worker }
150*8617a60dSAndroid Build Coastguard Worker 
print_help(const char * progname)151*8617a60dSAndroid Build Coastguard Worker static void print_help(const char *progname)
152*8617a60dSAndroid Build Coastguard Worker {
153*8617a60dSAndroid Build Coastguard Worker 	printf("Usage: %s <gbb> <vblock> <body>\n", progname);
154*8617a60dSAndroid Build Coastguard Worker }
155*8617a60dSAndroid Build Coastguard Worker 
main(int argc,char * argv[])156*8617a60dSAndroid Build Coastguard Worker int main(int argc, char *argv[])
157*8617a60dSAndroid Build Coastguard Worker {
158*8617a60dSAndroid Build Coastguard Worker 	uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE]
159*8617a60dSAndroid Build Coastguard Worker 		__attribute__((aligned(VB2_WORKBUF_ALIGN)));
160*8617a60dSAndroid Build Coastguard Worker 	struct vb2_context *ctx;
161*8617a60dSAndroid Build Coastguard Worker 	struct vb2_shared_data *sd;
162*8617a60dSAndroid Build Coastguard Worker 	vb2_error_t rv;
163*8617a60dSAndroid Build Coastguard Worker 
164*8617a60dSAndroid Build Coastguard Worker 	if (argc < 4) {
165*8617a60dSAndroid Build Coastguard Worker 		print_help(argv[0]);
166*8617a60dSAndroid Build Coastguard Worker 		return 1;
167*8617a60dSAndroid Build Coastguard Worker 	}
168*8617a60dSAndroid Build Coastguard Worker 
169*8617a60dSAndroid Build Coastguard Worker 	/* Save filenames */
170*8617a60dSAndroid Build Coastguard Worker 	gbb_fname = argv[1];
171*8617a60dSAndroid Build Coastguard Worker 	vblock_fname = argv[2];
172*8617a60dSAndroid Build Coastguard Worker 	body_fname = argv[3];
173*8617a60dSAndroid Build Coastguard Worker 
174*8617a60dSAndroid Build Coastguard Worker 	/* Intialize workbuf with sentinel value to see how much we'll use. */
175*8617a60dSAndroid Build Coastguard Worker 	uint32_t *ptr = (uint32_t *)workbuf;
176*8617a60dSAndroid Build Coastguard Worker 	while ((uint8_t *)ptr + sizeof(*ptr) <= workbuf + sizeof(workbuf))
177*8617a60dSAndroid Build Coastguard Worker 		*ptr++ = 0xbeefdead;
178*8617a60dSAndroid Build Coastguard Worker 
179*8617a60dSAndroid Build Coastguard Worker 	/* Set up context */
180*8617a60dSAndroid Build Coastguard Worker 	if (vb2api_init(workbuf, sizeof(workbuf), &ctx)) {
181*8617a60dSAndroid Build Coastguard Worker 		printf("Failed to initialize workbuf.\n");
182*8617a60dSAndroid Build Coastguard Worker 		return 1;
183*8617a60dSAndroid Build Coastguard Worker 	}
184*8617a60dSAndroid Build Coastguard Worker 	sd = vb2_get_sd(ctx);
185*8617a60dSAndroid Build Coastguard Worker 
186*8617a60dSAndroid Build Coastguard Worker 	/* Initialize secure context */
187*8617a60dSAndroid Build Coastguard Worker 	vb2api_secdata_firmware_create(ctx);
188*8617a60dSAndroid Build Coastguard Worker 	vb2api_secdata_kernel_create(ctx);
189*8617a60dSAndroid Build Coastguard Worker 
190*8617a60dSAndroid Build Coastguard Worker 	// TODO: optional args to set contents for nvdata, secdata?
191*8617a60dSAndroid Build Coastguard Worker 
192*8617a60dSAndroid Build Coastguard Worker 	/* Do early init */
193*8617a60dSAndroid Build Coastguard Worker 	printf("Phase 1...\n");
194*8617a60dSAndroid Build Coastguard Worker 	rv = vb2api_fw_phase1(ctx);
195*8617a60dSAndroid Build Coastguard Worker 	if (rv) {
196*8617a60dSAndroid Build Coastguard Worker 		printf("Phase 1 wants recovery mode.\n");
197*8617a60dSAndroid Build Coastguard Worker 		save_if_needed(ctx);
198*8617a60dSAndroid Build Coastguard Worker 		return rv;
199*8617a60dSAndroid Build Coastguard Worker 	}
200*8617a60dSAndroid Build Coastguard Worker 
201*8617a60dSAndroid Build Coastguard Worker 	/* Determine which firmware slot to boot */
202*8617a60dSAndroid Build Coastguard Worker 	printf("Phase 2...\n");
203*8617a60dSAndroid Build Coastguard Worker 	rv = vb2api_fw_phase2(ctx);
204*8617a60dSAndroid Build Coastguard Worker 	if (rv) {
205*8617a60dSAndroid Build Coastguard Worker 		printf("Phase 2 wants reboot.\n");
206*8617a60dSAndroid Build Coastguard Worker 		save_if_needed(ctx);
207*8617a60dSAndroid Build Coastguard Worker 		return rv;
208*8617a60dSAndroid Build Coastguard Worker 	}
209*8617a60dSAndroid Build Coastguard Worker 
210*8617a60dSAndroid Build Coastguard Worker 	/* Try that slot */
211*8617a60dSAndroid Build Coastguard Worker 	printf("Phase 3...\n");
212*8617a60dSAndroid Build Coastguard Worker 	rv = vb2api_fw_phase3(ctx);
213*8617a60dSAndroid Build Coastguard Worker 	if (rv) {
214*8617a60dSAndroid Build Coastguard Worker 		printf("Phase 3 wants reboot.\n");
215*8617a60dSAndroid Build Coastguard Worker 		save_if_needed(ctx);
216*8617a60dSAndroid Build Coastguard Worker 		return rv;
217*8617a60dSAndroid Build Coastguard Worker 	}
218*8617a60dSAndroid Build Coastguard Worker 
219*8617a60dSAndroid Build Coastguard Worker 	/* Verify body */
220*8617a60dSAndroid Build Coastguard Worker 	printf("Hash body...\n");
221*8617a60dSAndroid Build Coastguard Worker 	rv = hash_body(ctx);
222*8617a60dSAndroid Build Coastguard Worker 	save_if_needed(ctx);
223*8617a60dSAndroid Build Coastguard Worker 	if (rv) {
224*8617a60dSAndroid Build Coastguard Worker 		printf("Phase 4 wants reboot.\n");
225*8617a60dSAndroid Build Coastguard Worker 		return rv;
226*8617a60dSAndroid Build Coastguard Worker 	}
227*8617a60dSAndroid Build Coastguard Worker 
228*8617a60dSAndroid Build Coastguard Worker 	printf("Yaay!\n");
229*8617a60dSAndroid Build Coastguard Worker 
230*8617a60dSAndroid Build Coastguard Worker 	while ((uint8_t *)ptr > workbuf && *--ptr == 0xbeefdead)
231*8617a60dSAndroid Build Coastguard Worker 		/* find last used workbuf offset */;
232*8617a60dSAndroid Build Coastguard Worker 	printf("Workbuf used = %d bytes, high watermark = %zu bytes\n",
233*8617a60dSAndroid Build Coastguard Worker 		sd->workbuf_used, (uint8_t *)ptr + sizeof(*ptr) - workbuf);
234*8617a60dSAndroid Build Coastguard Worker 
235*8617a60dSAndroid Build Coastguard Worker 	return 0;
236*8617a60dSAndroid Build Coastguard Worker }
237