Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: utility/load_firmware_test.c

Issue 6465018: Add load_firmware_test utility program (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git@master
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« utility/include/fmap.h ('K') | « utility/include/fmap.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Routines for verifying a firmware image's signature.
6 */
7
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/mman.h>
14 #include <sys/stat.h>
15 #include <sys/types.h>
16 #include <unistd.h>
17
18 #include "fmap.h"
19 #include "gbb_header.h"
20 #include "load_firmware_fw.h"
21 #include "vboot_struct.h"
22
23
24 typedef struct _CallerInternal {
25 struct {
26 uint8_t *fw;
Randall Spangler 2011/02/09 19:42:14 Google style nit: * is next to the type, not the v
Che-Liang Chiou 2011/02/10 09:11:03 Done.
27 uint64_t size;
28 } firmware[2];
29 } CallerInternal;
30
31 static char *progname = NULL;
32 static char *image_path = NULL;
33
34
35 /* return -1 on error */
36 int area_index(FmapHeader *fh, AreaHeader *ah, const char name[]);
Randall Spangler 2011/02/09 19:42:14 move to fmap.h; add more description
Che-Liang Chiou 2011/02/10 09:11:03 Done.
37 /* wrapper of area_index; print error when not found */
38 int area_index_or_error(FmapHeader *fh, AreaHeader *ah, const char name[]);
39 /* return NULL on error */
40 const char *status_string(int status);
41
42 int GetFirmwareBody(LoadFirmwareParams *params, uint64_t firmware_index) {
43 CallerInternal* ci = (CallerInternal *) params->caller_internal;
44
45 if (firmware_index != 0 && firmware_index != 1)
46 return 1;
47
48 UpdateFirmwareBodyHash(params,
49 ci->firmware[firmware_index].fw,
50 ci->firmware[firmware_index].size);
51
52 return 0;
53 }
54
55 /* return zero on success, non-zero on error */
56 int drive_load_firmware(void *base_of_rom, void *fmap) {
gauravsh 2011/02/09 19:58:22 comment on arguments and what the function does?
Che-Liang Chiou 2011/02/10 09:11:03 Done.
57 LoadFirmwareParams lfp;
58 CallerInternal ci;
59
60 FmapHeader *fh = (FmapHeader *) fmap;
61 AreaHeader *ah = (AreaHeader *) (fmap + sizeof(FmapHeader));
62 int retval = 1;
63 int i, j, k, status;
64 void *gbb, *kb;
65 GoogleBinaryBlockHeader *gbbh;
66 VbKeyBlockHeader *kbh;
67 VbFirmwarePreambleHeader *fph;
68 const char *status_str;
69
70 const char *key_area_name[2] = {
71 "Firmware A Key",
72 "Firmware B Key"
73 };
74 void **vblock_ptr[2] = {
75 &lfp.verification_block_0,
76 &lfp.verification_block_1
77 };
78 uint64_t *vsize_ptr[2] = {
79 &lfp.verification_size_0,
80 &lfp.verification_size_1
81 };
82
83 const char *data_area_name[2] = {
84 "Firmware A Data",
85 "Firmware B Data"
86 };
87
88 i = area_index_or_error(fh, ah, "GBB Area");
89 if (i < 0)
90 goto EXIT;
91
92 gbb = base_of_rom + ah[i].area_offset;
gauravsh 2011/02/09 19:58:22 2 comments - 1) this method is pretty big. conside
Che-Liang Chiou 2011/02/10 09:11:03 Done.
93 gbbh = (GoogleBinaryBlockHeader *) gbb;
94 lfp.firmware_root_key_blob = gbb + gbbh->rootkey_offset;
95 printf("firmware root key blob at 0x%08" PRIx64 "\n",
96 lfp.firmware_root_key_blob - base_of_rom);
97
98 for (k = 0; k < 2; k ++) {
99 i = area_index_or_error(fh, ah, key_area_name[k]);
100 if (i < 0)
101 goto EXIT;
102
103 j = area_index_or_error(fh, ah, data_area_name[k]);
104 if (j < 0)
105 goto EXIT;
106
107 kb = base_of_rom + ah[i].area_offset;
108
109 *vblock_ptr[k] = kb;
110 printf("verification block %d at 0x%08" PRIx64 "\n", k,
111 *vblock_ptr[k] - base_of_rom);
112
113 kbh = (VbKeyBlockHeader *) kb;
114 fph = (VbFirmwarePreambleHeader *) (kb + kbh->key_block_size);
115
116 *vsize_ptr[k] = kbh->key_block_size + fph->preamble_size;
117 printf("verification block %d size is 0x%08" PRIx64 "\n", k, *vsize_ptr[k]);
118
119 ci.firmware[k].fw = (uint8_t *) (base_of_rom + ah[j].area_offset);
120 printf("firmware %c at 0x%08" PRIx64 "\n", "AB"[k],
121 (void *) ci.firmware[k].fw - base_of_rom);
122
123 ci.firmware[k].size = (uint64_t) fph->body_signature.data_size;
124 printf("firmware %c size is 0x%08" PRIx64 "\n", "AB"[k],
125 ci.firmware[k].size);
126 }
127 lfp.caller_internal = &ci;
128
129 /* remember to free kernel_sign_key_blob before exit */
130 lfp.kernel_sign_key_blob = malloc(LOAD_FIRMWARE_KEY_BLOB_REC_SIZE);
131 lfp.kernel_sign_key_size = LOAD_FIRMWARE_KEY_BLOB_REC_SIZE;
132 printf("kernel sign key size is 0x%08" PRIx64 "\n", lfp.kernel_sign_key_size);
133
134 lfp.boot_flags = 0;
135 printf("boot flags is 0x%08" PRIx64 "\n", lfp.boot_flags);
136
137 status = LoadFirmware(&lfp);
138 status_str = status_string(status);
139 if (status_str)
140 printf("LoadFirmware returns %s\n", status_str);
141 else
142 printf("LoadFirmware returns unknown status code: %d\n", status);
143 if (status == LOAD_FIRMWARE_SUCCESS)
144 printf("firmwiare index is %" PRIu64 "\n", lfp.firmware_index);
145
146 free(lfp.kernel_sign_key_blob);
147 retval = 0;
148
149 EXIT:
gauravsh 2011/02/09 19:58:22 in general, we try to avoid goto. refactor to not
Che-Liang Chiou 2011/02/10 09:11:03 Done.
150 return retval;
151 }
152
153 /* return -1 on error */
154 int area_index(FmapHeader *fh, AreaHeader *ah, const char name[]) {
Randall Spangler 2011/02/09 19:42:14 Move these to fmap.c Use Fmap prefix on all funct
Randall Spangler 2011/02/09 19:42:14 const char* name
Che-Liang Chiou 2011/02/10 09:11:03 Done.
Che-Liang Chiou 2011/02/10 09:11:03 Done.
155 size_t len = strlen(name);
Randall Spangler 2011/02/09 19:42:14 Is this just an optimization to save doing the imp
Che-Liang Chiou 2011/02/10 09:11:03 I guess not.
156 int i;
157 for (i = 0; i < fh->fmap_nareas; i++)
158 if (!strncmp((const char *) ah[i].area_name, name, len))
159 return i;
160 return -1;
161 }
162
163 /* wrap area_index; print error when not found */
164 int area_index_or_error(FmapHeader *fh, AreaHeader *ah, const char name[]) {
gauravsh 2011/02/09 19:58:22 this looks like it could be moved to fmap.c
Che-Liang Chiou 2011/02/10 09:11:03 progname is a static global variable of load_firmw
165 int i = area_index(fh, ah, name);
166 if (i < 0)
167 fprintf(stderr, "%s: can't find %s in firmware image\n", progname, name);
168 return i;
169 }
170
171 /* return NULL on error */
172 const char *status_string(int status) {
gauravsh 2011/02/09 19:58:22 comment?
Che-Liang Chiou 2011/02/10 09:11:03 Done.
173 switch (status) {
174 case LOAD_FIRMWARE_SUCCESS:
175 return "LOAD_FIRMWARE_SUCCESS";
176 case LOAD_FIRMWARE_RECOVERY:
177 return "LOAD_FIRMWARE_RECOVERY";
178 case LOAD_FIRMWARE_REBOOT:
179 return "LOAD_FIRMWARE_REBOOT";
180 case LOAD_FIRMWARE_RECOVERY_TPM:
181 return "LOAD_FIRMWARE_RECOVERY_TPM";
182 default:
183 return NULL;
184 }
185 }
186
187 /* main function and its subroutines */
188
189 void error_and_exit(char *action_name) {
190 fprintf(stderr, "%s: can't %s %s: %s\n",
191 progname,
192 action_name,
193 image_path,
194 strerror(errno));
195 exit(1);
196 }
197
198 int main(int argc, char *argv[]) {
199 int fd, retval = 0;
200 struct stat sb;
201 void *base_of_rom, *fmap;
202
203 progname = argv[0];
204
205 if (argc < 2) {
206 fprintf(stderr, "usage: %s <firmware_image>\n", progname);
207 exit(1);
208 }
209
210 image_path = argv[1];
211
212 if (0 != stat(image_path, &sb))
213 error_and_exit("stat");
214
215 fd = open(image_path, O_RDONLY);
Randall Spangler 2011/02/09 19:42:14 Why not just use ReadFile() from host lib? Code w
Che-Liang Chiou 2011/02/10 09:11:03 Done.
216 if (fd < 0)
217 error_and_exit("open");
218
219 printf("opened %s\n", image_path);
220
221 base_of_rom = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
gauravsh 2011/02/09 19:58:22 i don't think it is really any better to use mmap(
Che-Liang Chiou 2011/02/10 09:11:03 Done.
222 if (base_of_rom == (void *) -1) {
223 close(fd);
224 error_and_exit("mmap");
225 }
226
227 fmap = find_fmap((char *) base_of_rom, sb.st_size);
228
229 retval = drive_load_firmware(base_of_rom, fmap);
230
231 if (0 != munmap(base_of_rom, sb.st_size)) {
232 close(fd);
233 error_and_exit("munmap");
234 }
235
236 if (0 != close(fd))
237 error_and_exit("close");
238
239 return retval;
240 }
OLDNEW
« utility/include/fmap.h ('K') | « utility/include/fmap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698