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

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: Code review & remove tabs 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/dump_fmap.c ('K') | « utility/dump_fmap.c ('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 <stdio.h>
9
10 #include "fmap.h"
11 #include "gbb_header.h"
12 #include "host_misc.h"
13 #include "load_firmware_fw.h"
14 #include "vboot_struct.h"
15
16
17 typedef struct _CallerInternal {
18 struct {
19 uint8_t* fw;
20 uint64_t size;
21 } firmware[2];
22 } CallerInternal;
23
24 static char* progname = NULL;
25 static char* image_path = NULL;
26
27
28 /* wrapper of FmapAreaIndex; print error when not found */
29 int FmapAreaIndexOrError(const FmapHeader* fh, const FmapAreaHeader* ah,
30 const char* name);
31 /* return NULL on error */
32 const char* status_string(int status);
33
34 int GetFirmwareBody(LoadFirmwareParams* params, uint64_t firmware_index) {
35 CallerInternal* ci = (CallerInternal*) params->caller_internal;
36
37 if (firmware_index != 0 && firmware_index != 1)
38 return 1;
39
40 UpdateFirmwareBodyHash(params,
41 ci->firmware[firmware_index].fw,
42 ci->firmware[firmware_index].size);
43
44 return 0;
45 }
46
47 /* Return NULL if cannot get firmware root key */
gauravsh 2011/02/10 20:02:05 i still don't see any comments for the arguments o
Che-Liang Chiou 2011/02/14 02:27:53 Done.
48 void* GetFirmwareRootKey(const void* base_of_rom, const void* fmap) {
49 const FmapHeader* fh = (const FmapHeader*) fmap;
50 const FmapAreaHeader* ah = (const FmapAreaHeader*)
51 (fmap + sizeof(FmapHeader));
52 int i = FmapAreaIndexOrError(fh, ah, "GBB Area");
53 const void* gbb;
54 const GoogleBinaryBlockHeader* gbbh;
55
56 if (i < 0)
57 return NULL;
58
59 gbb = base_of_rom + ah[i].area_offset;
60 gbbh = (const GoogleBinaryBlockHeader*) gbb;
61 return (void*) gbb + gbbh->rootkey_offset;
62 }
63
64 /* Return non-zero if cannot get verification block */
gauravsh 2011/02/10 20:02:05 comment about the arguments and what this function
Che-Liang Chiou 2011/02/14 02:27:53 Done.
65 int GetVerificationBlock(const void* base_of_rom, const void* fmap, int index,
66 void** verification_block_ptr, uint64_t* verification_size_ptr) {
67 const char* key_area_name[2] = {
68 "Firmware A Key",
69 "Firmware B Key"
70 };
71 const FmapHeader* fh = (const FmapHeader*) fmap;
72 const FmapAreaHeader* ah = (const FmapAreaHeader*)
73 (fmap + sizeof(FmapHeader));
74 int i = FmapAreaIndexOrError(fh, ah, key_area_name[index]);
75 const void* kb;
76 const VbKeyBlockHeader* kbh;
77 const VbFirmwarePreambleHeader* fph;
78
79 if (i < 0)
80 return 1;
81
82 kb = base_of_rom + ah[i].area_offset;
83 *verification_block_ptr = (void*) kb;
84
85 kbh = (const VbKeyBlockHeader*) kb;
86 fph = (const VbFirmwarePreambleHeader*) (kb + kbh->key_block_size);
87
88 *verification_size_ptr = kbh->key_block_size + fph->preamble_size;
89
90 return 0;
91 }
92
93 /* Return non-zero if not found */
94 int GetFirmwareData(const void* base_of_rom, const void* fmap, int index,
95 void *verification_block, uint8_t** body_ptr, uint64_t *size_ptr) {
96 const char* data_area_name[2] = {
97 "Firmware A Data",
98 "Firmware B Data"
99 };
100 const FmapHeader* fh = (const FmapHeader*) fmap;
101 const FmapAreaHeader* ah = (const FmapAreaHeader*)
102 (fmap + sizeof(FmapHeader));
103 const VbKeyBlockHeader* kbh = (const VbKeyBlockHeader*) verification_block;
104 const VbFirmwarePreambleHeader* fph = (const VbFirmwarePreambleHeader*)
105 (verification_block + kbh->key_block_size);
106 int i = FmapAreaIndexOrError(fh, ah, data_area_name[index]);
107
108 if (i < 0)
109 return 1;
110
111 *body_ptr = (uint8_t*) (base_of_rom + ah[i].area_offset);
112 *size_ptr = (uint64_t) fph->body_signature.data_size;
113 return 0;
114 }
115
116 /* Verify firmware image [base_of_rom] using [fmap] for looking up areas.
117 * Return zero on success, non-zero on error */
gauravsh 2011/02/10 20:02:05 ok, I see you added the comment here - but still t
Che-Liang Chiou 2011/02/14 02:27:53 Done.
118 int DriveLoadFirmware(const void* base_of_rom, const void* fmap) {
119 LoadFirmwareParams lfp;
120 CallerInternal ci;
121
122 const char* status_str;
123 int index, status;
124
125 void** vblock_ptr[2] = {
126 &lfp.verification_block_0, &lfp.verification_block_1
127 };
128 uint64_t* vsize_ptr[2] = {
129 &lfp.verification_size_0, &lfp.verification_size_1
130 };
131
132 /* Initialize LoadFirmwareParams lfp */
133
134 lfp.caller_internal = &ci;
135
136 lfp.firmware_root_key_blob = GetFirmwareRootKey(base_of_rom, fmap);
137 if (lfp.firmware_root_key_blob == NULL) {
gauravsh 2011/02/10 20:02:05 !lfp.firmware_root_key_blob is the usual way than
Che-Liang Chiou 2011/02/14 02:27:53 Done.
138 printf("ERROR: cannot get firmware root key blob\n");
139 return 1;
140 }
141
142 printf("firmware root key blob at 0x%08" PRIx64 "\n",
143 lfp.firmware_root_key_blob - base_of_rom);
144
145 /* Loop for initialize firmware key and data A / B */
gauravsh 2011/02/10 20:02:05 s/for/to/
Che-Liang Chiou 2011/02/14 02:27:53 Done.
146 for (index = 0; index < 2; ++index) {
147 if (GetVerificationBlock(base_of_rom, fmap, index,
148 vblock_ptr[index], vsize_ptr[index])) {
149 printf("ERROR: cannot get key block %d\n", index);
150 return 1;
151 }
152
153 printf("verification block %d at 0x%08" PRIx64 "\n", index,
154 *vblock_ptr[index] - base_of_rom);
155 printf("verification block %d size is 0x%08" PRIx64 "\n", index,
156 *vsize_ptr[index]);
157
158 if (GetFirmwareData(base_of_rom, fmap, index, *vblock_ptr[index],
159 &(ci.firmware[index].fw), &(ci.firmware[index].size))) {
160 printf("ERROR: cannot get firmware body %d\n", index);
161 return 1;
162 }
163
164 printf("firmware %c at 0x%08" PRIx64 "\n", "AB"[index],
165 (void*) ci.firmware[index].fw - base_of_rom);
166 printf("firmware %c size is 0x%08" PRIx64 "\n", "AB"[index],
167 ci.firmware[index].size);
168 }
169
170 /* remember to free kernel_sign_key_blob before exit */
gauravsh 2011/02/10 20:02:05 i would get rid of the comment. it is not clear wh
Che-Liang Chiou 2011/02/14 02:27:53 Done.
171 lfp.kernel_sign_key_blob = Malloc(LOAD_FIRMWARE_KEY_BLOB_REC_SIZE);
172 lfp.kernel_sign_key_size = LOAD_FIRMWARE_KEY_BLOB_REC_SIZE;
173 printf("kernel sign key size is 0x%08" PRIx64 "\n", lfp.kernel_sign_key_size);
174
175 lfp.boot_flags = 0;
176 printf("boot flags is 0x%08" PRIx64 "\n", lfp.boot_flags);
177
178 /* Call to LoadFirmware */
gauravsh 2011/02/10 20:02:05 this is not a useful comment. please remove.
Che-Liang Chiou 2011/02/14 02:27:53 Done.
179
180 status = LoadFirmware(&lfp);
181 status_str = status_string(status);
182 if (status_str)
183 printf("LoadFirmware returns %s\n", status_str);
184 else
185 printf("LoadFirmware returns unknown status code: %d\n", status);
186 if (status == LOAD_FIRMWARE_SUCCESS)
187 printf("firmwiare index is %" PRIu64 "\n", lfp.firmware_index);
188
189 Free(lfp.kernel_sign_key_blob);
190
191 return 0;
192 }
193
194 /* wrap FmapAreaIndex; print error when not found */
195 int FmapAreaIndexOrError(const FmapHeader* fh, const FmapAreaHeader* ah,
196 const char* name) {
197 int i = FmapAreaIndex(fh, ah, name);
198 if (i < 0)
199 fprintf(stderr, "%s: can't find %s in firmware image\n", progname, name);
200 return i;
201 }
202
203 /* Convert status returned by LoadFirmware to string. Return NULL on error. */
204 const char* status_string(int status) {
205 switch (status) {
206 case LOAD_FIRMWARE_SUCCESS:
207 return "LOAD_FIRMWARE_SUCCESS";
208 case LOAD_FIRMWARE_RECOVERY:
209 return "LOAD_FIRMWARE_RECOVERY";
210 case LOAD_FIRMWARE_REBOOT:
211 return "LOAD_FIRMWARE_REBOOT";
212 case LOAD_FIRMWARE_RECOVERY_TPM:
213 return "LOAD_FIRMWARE_RECOVERY_TPM";
214 default:
215 return NULL;
216 }
217 }
218
219 int main(int argc, char* argv[]) {
220 int retval = 0;
221 const void* base_of_rom;
222 const void* fmap;
223 uint64_t rom_size;
224
225 progname = argv[0];
226
227 if (argc < 2) {
228 fprintf(stderr, "usage: %s <firmware_image>\n", progname);
229 exit(1);
230 }
231
232 image_path = argv[1];
233
234 base_of_rom = ReadFile(image_path, &rom_size);
235 if (base_of_rom == NULL) {
236 fprintf(stderr, "%s: can not open %s\n", progname, image_path);
237 exit(1);
238 }
239
240 printf("opened %s\n", image_path);
241
242 fmap = FindFmap((char*) base_of_rom, rom_size);
243
244 retval = DriveLoadFirmware(base_of_rom, fmap);
245
246 Free((void*) base_of_rom);
247
248 return retval;
249 }
OLDNEW
« utility/dump_fmap.c ('K') | « utility/dump_fmap.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698