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