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

Side by Side Diff: utility/vbutil_kernel.c

Issue 2859019: Add some debug output to vbutil_kernel, display values in hex. (Closed) Base URL: ssh://git@chromiumos-git//vboot_reference.git
Patch Set: Created 10 years, 6 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
« no previous file with comments | « no previous file | 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
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be 2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. 3 * found in the LICENSE file.
4 * 4 *
5 * Verified boot kernel utility 5 * Verified boot kernel utility
6 */ 6 */
7 7
8 #include <getopt.h> 8 #include <getopt.h>
9 #include <inttypes.h> /* For PRIu64 */ 9 #include <inttypes.h> /* For PRIu64 */
10 #include <stdarg.h>
10 #include <stddef.h> 11 #include <stddef.h>
11 #include <stdio.h> 12 #include <stdio.h>
12 #include <stdlib.h> 13 #include <stdlib.h>
13 #include <unistd.h> 14 #include <unistd.h>
14 15
15 #include "cryptolib.h" 16 #include "cryptolib.h"
16 #include "host_common.h" 17 #include "host_common.h"
17 #include "kernel_blob.h" 18 #include "kernel_blob.h"
18 #include "vboot_common.h" 19 #include "vboot_common.h"
19 20
20 21
22 /* Global opt */
23 static int opt_debug = 0;
24
25
21 /* Command line options */ 26 /* Command line options */
22 enum { 27 enum {
23 OPT_MODE_PACK = 1000, 28 OPT_MODE_PACK = 1000,
24 OPT_MODE_VERIFY, 29 OPT_MODE_VERIFY,
25 OPT_KEYBLOCK, 30 OPT_KEYBLOCK,
26 OPT_SIGNPUBKEY, 31 OPT_SIGNPUBKEY,
27 OPT_SIGNPRIVATE, 32 OPT_SIGNPRIVATE,
28 OPT_VERSION, 33 OPT_VERSION,
29 OPT_VMLINUZ, 34 OPT_VMLINUZ,
30 OPT_BOOTLOADER, 35 OPT_BOOTLOADER,
31 OPT_CONFIG, 36 OPT_CONFIG,
32 OPT_PAD, 37 OPT_PAD,
33 }; 38 };
34 39
35 static struct option long_opts[] = { 40 static struct option long_opts[] = {
36 {"pack", 1, 0, OPT_MODE_PACK }, 41 {"pack", 1, 0, OPT_MODE_PACK },
37 {"verify", 1, 0, OPT_MODE_VERIFY }, 42 {"verify", 1, 0, OPT_MODE_VERIFY },
38 {"keyblock", 1, 0, OPT_KEYBLOCK }, 43 {"keyblock", 1, 0, OPT_KEYBLOCK },
39 {"signpubkey", 1, 0, OPT_SIGNPUBKEY }, 44 {"signpubkey", 1, 0, OPT_SIGNPUBKEY },
40 {"signprivate", 1, 0, OPT_SIGNPRIVATE }, 45 {"signprivate", 1, 0, OPT_SIGNPRIVATE },
41 {"version", 1, 0, OPT_VERSION }, 46 {"version", 1, 0, OPT_VERSION },
42 {"vmlinuz", 1, 0, OPT_VMLINUZ }, 47 {"vmlinuz", 1, 0, OPT_VMLINUZ },
43 {"bootloader", 1, 0, OPT_BOOTLOADER }, 48 {"bootloader", 1, 0, OPT_BOOTLOADER },
44 {"config", 1, 0, OPT_CONFIG }, 49 {"config", 1, 0, OPT_CONFIG },
45 {"pad", 1, 0, OPT_PAD }, 50 {"pad", 1, 0, OPT_PAD },
51 {"debug", 0, &opt_debug, 1 },
46 {NULL, 0, 0, 0} 52 {NULL, 0, 0, 0}
47 }; 53 };
48 54
49 55
50 /* Print help and return error */ 56 /* Print help and return error */
51 static int PrintHelp(void) { 57 static int PrintHelp(void) {
52 58
53 puts("vbutil_kernel - Verified boot key block utility\n" 59 puts("vbutil_kernel - Verified boot key block utility\n"
54 "\n" 60 "\n"
55 "Usage: vbutil_kernel <--pack|--verify> <file> [OPTIONS]\n" 61 "Usage: vbutil_kernel <--pack|--verify> <file> [OPTIONS]\n"
56 "\n" 62 "\n"
57 "For '--pack <file>', required OPTIONS are:\n" 63 "For '--pack <file>', required OPTIONS are:\n"
58 " --keyblock <file> Key block in .keyblock format\n" 64 " --keyblock <file> Key block in .keyblock format\n"
59 " --signprivate <file> Signing private key in .pem format\n" 65 " --signprivate <file> Signing private key in .pem format\n"
60 " --version <number> Kernel version\n" 66 " --version <number> Kernel version\n"
61 " --vmlinuz <file> Linux kernel image\n" 67 " --vmlinuz <file> Linux kernel image\n"
62 " --bootloader <file> Bootloader stub\n" 68 " --bootloader <file> Bootloader stub\n"
63 " --config <file> Config file\n" 69 " --config <file> Config file\n"
64 "Optional OPTIONS are:\n" 70 "Optional OPTIONS are:\n"
65 " --pad <number> Padding size in bytes\n" 71 " --pad <number> Padding size in bytes\n"
66 "\n" 72 "\n"
67 "For '--verify <file>', required OPTIONS are:\n" 73 "For '--verify <file>', required OPTIONS are:\n"
68 " --signpubkey <file> Signing public key in .vbpubk format\n" 74 " --signpubkey <file> Signing public key in .vbpubk format\n"
69 ""); 75 "");
70 return 1; 76 return 1;
71 } 77 }
72 78
79 static void Debug(const char *format, ...) {
80 if (!opt_debug)
81 return;
82
83 va_list ap;
84 va_start(ap, format);
85 fprintf(stderr, "DEBUG: ");
86 vfprintf(stderr, format, ap);
87 va_end(ap);
88 }
89
73 90
74 /* Return the smallest integral multiple of [alignment] that is equal 91 /* Return the smallest integral multiple of [alignment] that is equal
75 * to or greater than [val]. Used to determine the number of 92 * to or greater than [val]. Used to determine the number of
76 * pages/sectors/blocks/whatever needed to contain [val] 93 * pages/sectors/blocks/whatever needed to contain [val]
77 * items/bytes/etc. */ 94 * items/bytes/etc. */
78 static uint64_t roundup(uint64_t val, uint64_t alignment) { 95 static uint64_t roundup(uint64_t val, uint64_t alignment) {
79 uint64_t rem = val % alignment; 96 uint64_t rem = val % alignment;
80 if ( rem ) 97 if ( rem )
81 return val + (alignment - rem); 98 return val + (alignment - rem);
82 return val; 99 return val;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 return 1; 175 return 1;
159 } 176 }
160 177
161 signing_key = PrivateKeyRead(signprivate, key_block->data_key.algorithm); 178 signing_key = PrivateKeyRead(signprivate, key_block->data_key.algorithm);
162 if (!signing_key) { 179 if (!signing_key) {
163 error("Error reading signing key.\n"); 180 error("Error reading signing key.\n");
164 return 1; 181 return 1;
165 } 182 }
166 183
167 /* Read the config file */ 184 /* Read the config file */
185 Debug("Reading %s\n", config_file);
168 config_buf = ReadFile(config_file, &config_size); 186 config_buf = ReadFile(config_file, &config_size);
169 if (!config_buf) 187 if (!config_buf)
170 return 1; 188 return 1;
189 Debug(" config file size=0x%" PRIx64 "\n", config_size);
171 if (CROS_CONFIG_SIZE <= config_size) { /* need room for trailing '\0' */ 190 if (CROS_CONFIG_SIZE <= config_size) { /* need room for trailing '\0' */
172 error("Config file %s is too large (>= %d bytes)\n", 191 error("Config file %s is too large (>= %d bytes)\n",
173 config_file, CROS_CONFIG_SIZE); 192 config_file, CROS_CONFIG_SIZE);
174 return 1; 193 return 1;
175 } 194 }
176 /* Replace newlines with spaces */ 195 /* Replace newlines with spaces */
177 for (i = 0; i < config_size; i++) 196 for (i = 0; i < config_size; i++)
178 if ('\n' == config_buf[i]) 197 if ('\n' == config_buf[i])
179 config_buf[i] = ' '; 198 config_buf[i] = ' ';
180 199
181 /* Read the bootloader */ 200 /* Read the bootloader */
201 Debug("Reading %s\n", bootloader_file);
182 bootloader_buf = ReadFile(bootloader_file, &bootloader_size); 202 bootloader_buf = ReadFile(bootloader_file, &bootloader_size);
183 if (!bootloader_buf) 203 if (!bootloader_buf)
184 return 1; 204 return 1;
205 Debug(" bootloader file size=0x%" PRIx64 "\n", bootloader_size);
185 206
186 /* Read the kernel */ 207 /* Read the kernel */
208 Debug("Reading %s\n", vmlinuz);
187 kernel_buf = ReadFile(vmlinuz, &kernel_size); 209 kernel_buf = ReadFile(vmlinuz, &kernel_size);
188 if (!kernel_buf) 210 if (!kernel_buf)
189 return 1; 211 return 1;
212 Debug(" kernel file size=0x%" PRIx64 "\n", kernel_size);
190 if (!kernel_size) { 213 if (!kernel_size) {
191 error("Empty kernel file\n"); 214 error("Empty kernel file\n");
192 return 1; 215 return 1;
193 } 216 }
194 217
195 /* The first part of vmlinuz is a header, followed by a real-mode 218 /* The first part of vmlinuz is a header, followed by a real-mode
196 * boot stub. We only want the 32-bit part. */ 219 * boot stub. We only want the 32-bit part. */
197 lh = (struct linux_kernel_header *)kernel_buf; 220 lh = (struct linux_kernel_header *)kernel_buf;
198 kernel32_start = (lh->setup_sects + 1) << 9; 221 kernel32_start = (lh->setup_sects + 1) << 9;
199 if (kernel32_start >= kernel_size) { 222 if (kernel32_start >= kernel_size) {
200 error("Malformed kernel\n"); 223 error("Malformed kernel\n");
201 return 1; 224 return 1;
202 } 225 }
203 kernel32_size = kernel_size - kernel32_start; 226 kernel32_size = kernel_size - kernel32_start;
227 Debug(" kernel32_start=0x%" PRIx64 "\n", kernel32_start);
228 Debug(" kernel32_size=0x%" PRIx64 "\n", kernel32_size);
204 229
205 /* Allocate and zero the blob we need. */ 230 /* Allocate and zero the blob we need. */
206 blob_size = roundup(kernel32_size, CROS_ALIGN) + 231 blob_size = roundup(kernel32_size, CROS_ALIGN) +
207 CROS_CONFIG_SIZE + 232 CROS_CONFIG_SIZE +
208 CROS_PARAMS_SIZE + 233 CROS_PARAMS_SIZE +
209 roundup(bootloader_size, CROS_ALIGN); 234 roundup(bootloader_size, CROS_ALIGN);
210 blob = (uint8_t *)Malloc(blob_size); 235 blob = (uint8_t *)Malloc(blob_size);
236 Debug("blob_size=0x%" PRIx64 "\n", blob_size);
211 if (!blob) { 237 if (!blob) {
212 error("Couldn't allocate %ld bytes.\n", blob_size); 238 error("Couldn't allocate %ld bytes.\n", blob_size);
213 return 1; 239 return 1;
214 } 240 }
215 Memset(blob, 0, blob_size); 241 Memset(blob, 0, blob_size);
216 242
217 /* Copy the 32-bit kernel. */ 243 /* Copy the 32-bit kernel. */
244 Debug("kernel goes at blob+=0x%" PRIx64 "\n", now);
218 if (kernel32_size) 245 if (kernel32_size)
219 Memcpy(blob + now, kernel_buf + kernel32_start, kernel32_size); 246 Memcpy(blob + now, kernel_buf + kernel32_start, kernel32_size);
220 now += roundup(now + kernel32_size, CROS_ALIGN); 247 now += roundup(now + kernel32_size, CROS_ALIGN);
221 248
249 Debug("config goes at blob+0x%" PRIx64 "\n", now);
222 /* Find the load address of the commandline. We'll need it later. */ 250 /* Find the load address of the commandline. We'll need it later. */
223 cmdline_addr = CROS_32BIT_ENTRY_ADDR + now + 251 cmdline_addr = CROS_32BIT_ENTRY_ADDR + now +
224 find_cmdline_start((char *)config_buf, config_size); 252 find_cmdline_start((char *)config_buf, config_size);
253 Debug(" cmdline_addr=0x%" PRIx64 "\n", cmdline_addr);
225 254
226 /* Copy the config. */ 255 /* Copy the config. */
227 if (config_size) 256 if (config_size)
228 Memcpy(blob + now, config_buf, config_size); 257 Memcpy(blob + now, config_buf, config_size);
229 now += CROS_CONFIG_SIZE; 258 now += CROS_CONFIG_SIZE;
230 259
231 /* The zeropage data is next. Overlay the linux_kernel_header onto it, and 260 /* The zeropage data is next. Overlay the linux_kernel_header onto it, and
232 * tweak a few fields. */ 261 * tweak a few fields. */
262 Debug("params goes at blob+=0x%" PRIx64 "\n", now);
233 params = (struct linux_kernel_params *)(blob + now); 263 params = (struct linux_kernel_params *)(blob + now);
234 Memcpy(&(params->setup_sects), &(lh->setup_sects), 264 Memcpy(&(params->setup_sects), &(lh->setup_sects),
235 sizeof(*lh) - offsetof(struct linux_kernel_header, setup_sects)); 265 sizeof(*lh) - offsetof(struct linux_kernel_header, setup_sects));
236 params->boot_flag = 0; 266 params->boot_flag = 0;
237 params->ramdisk_image = 0; /* we don't support initrd */ 267 params->ramdisk_image = 0; /* we don't support initrd */
238 params->ramdisk_size = 0; 268 params->ramdisk_size = 0;
239 params->type_of_loader = 0xff; 269 params->type_of_loader = 0xff;
240 params->cmd_line_ptr = cmdline_addr; 270 params->cmd_line_ptr = cmdline_addr;
241 now += CROS_PARAMS_SIZE; 271 now += CROS_PARAMS_SIZE;
242 272
243 /* Finally, append the bootloader. Remember where it will load in 273 /* Finally, append the bootloader. Remember where it will load in
244 * memory, too. */ 274 * memory, too. */
275 Debug("bootloader goes at blob+=0x%" PRIx64 "\n", now);
245 bootloader_mem_start = CROS_32BIT_ENTRY_ADDR + now; 276 bootloader_mem_start = CROS_32BIT_ENTRY_ADDR + now;
246 bootloader_mem_size = roundup(bootloader_size, CROS_ALIGN); 277 bootloader_mem_size = roundup(bootloader_size, CROS_ALIGN);
278 Debug(" bootloader_mem_start=0x%" PRIx64 "\n", bootloader_mem_start);
279 Debug(" bootloader_mem_size=0x%" PRIx64 "\n", bootloader_mem_size);
247 if (bootloader_size) 280 if (bootloader_size)
248 Memcpy(blob + now, bootloader_buf, bootloader_size); 281 Memcpy(blob + now, bootloader_buf, bootloader_size);
249 now += bootloader_mem_size; 282 now += bootloader_mem_size;
283 Debug("end of blob is 0x%" PRIx64 "\n", now);
250 284
251 /* Free input buffers */ 285 /* Free input buffers */
252 Free(kernel_buf); 286 Free(kernel_buf);
253 Free(config_buf); 287 Free(config_buf);
254 Free(bootloader_buf); 288 Free(bootloader_buf);
255 289
256 /* Sign the kernel data */ 290 /* Sign the kernel data */
257 body_sig = CalculateSignature(blob, blob_size, signing_key); 291 body_sig = CalculateSignature(blob, blob_size, signing_key);
258 if (!body_sig) { 292 if (!body_sig) {
259 error("Error calculating body signature\n"); 293 error("Error calculating body signature\n");
260 return 1; 294 return 1;
261 } 295 }
262 296
263 /* Create preamble */ 297 /* Create preamble */
264 preamble = CreateKernelPreamble(version, 298 preamble = CreateKernelPreamble(version,
265 CROS_32BIT_ENTRY_ADDR, 299 CROS_32BIT_ENTRY_ADDR,
266 bootloader_mem_start, 300 bootloader_mem_start,
267 bootloader_mem_size, 301 bootloader_mem_size,
268 body_sig, 302 body_sig,
269 pad - key_block_size, 303 pad - key_block_size,
270 signing_key); 304 signing_key);
271 if (!preamble) { 305 if (!preamble) {
272 error("Error creating preamble.\n"); 306 error("Error creating preamble.\n");
273 return 1; 307 return 1;
274 } 308 }
275 309
276 /* Write the output file */ 310 /* Write the output file */
311 Debug("writing %s...\n", outfile);
277 f = fopen(outfile, "wb"); 312 f = fopen(outfile, "wb");
278 if (!f) { 313 if (!f) {
279 error("Can't open output file %s\n", outfile); 314 error("Can't open output file %s\n", outfile);
280 return 1; 315 return 1;
281 } 316 }
317 Debug("0x%" PRIx64 " bytes of key_block\n", key_block_size);
318 Debug("0x%" PRIx64 " bytes of preamble\n", preamble->preamble_size);
319 Debug("0x%" PRIx64 " bytes of blob\n", blob_size);
282 i = ((1 != fwrite(key_block, key_block_size, 1, f)) || 320 i = ((1 != fwrite(key_block, key_block_size, 1, f)) ||
283 (1 != fwrite(preamble, preamble->preamble_size, 1, f)) || 321 (1 != fwrite(preamble, preamble->preamble_size, 1, f)) ||
284 (1 != fwrite(blob, blob_size, 1, f))); 322 (1 != fwrite(blob, blob_size, 1, f)));
285 fclose(f); 323 fclose(f);
286 if (i) { 324 if (i) {
287 error("Can't write output file %s\n", outfile); 325 error("Can't write output file %s\n", outfile);
288 unlink(outfile); 326 unlink(outfile);
289 return 1; 327 return 1;
290 } 328 }
291 329
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 error("Error verifying preamble.\n"); 392 error("Error verifying preamble.\n");
355 return 1; 393 return 1;
356 } 394 }
357 now += preamble->preamble_size; 395 now += preamble->preamble_size;
358 396
359 printf("Preamble:\n"); 397 printf("Preamble:\n");
360 printf(" Size: %" PRIu64 "\n", preamble->preamble_size); 398 printf(" Size: %" PRIu64 "\n", preamble->preamble_size);
361 printf(" Header version: %" PRIu32 ".%" PRIu32"\n", 399 printf(" Header version: %" PRIu32 ".%" PRIu32"\n",
362 preamble->header_version_major, preamble->header_version_minor); 400 preamble->header_version_major, preamble->header_version_minor);
363 printf(" Kernel version: %" PRIu64 "\n", preamble->kernel_version); 401 printf(" Kernel version: %" PRIu64 "\n", preamble->kernel_version);
364 printf(" Body load address: %" PRIu64 "\n", preamble->body_load_address); 402 printf(" Body load address: 0x%" PRIx64 "\n", preamble->body_load_address);
365 printf(" Body size: %" PRIu64 "\n", 403 printf(" Body size: 0x%" PRIx64 "\n",
366 preamble->body_signature.data_size); 404 preamble->body_signature.data_size);
367 printf(" Bootloader address: %" PRIu64 "\n", preamble->bootloader_address); 405 printf(" Bootloader address: 0x%" PRIx64 "\n", preamble->bootloader_address) ;
368 printf(" Bootloader size: %" PRIu64 "\n", preamble->bootloader_size); 406 printf(" Bootloader size: 0x%" PRIx64 "\n", preamble->bootloader_size);
369 407
370 /* Verify body */ 408 /* Verify body */
371 if (0 != VerifyData(blob + now, &preamble->body_signature, rsa)) { 409 if (0 != VerifyData(blob + now, &preamble->body_signature, rsa)) {
372 error("Error verifying kernel body.\n"); 410 error("Error verifying kernel body.\n");
373 return 1; 411 return 1;
374 } 412 }
375 printf("Body verification succeeded.\n"); 413 printf("Body verification succeeded.\n");
376 return 0; 414 return 0;
377 } 415 }
378 416
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 case OPT_MODE_PACK: 494 case OPT_MODE_PACK:
457 return Pack(filename, key_block_file, signprivate, version, vmlinuz, 495 return Pack(filename, key_block_file, signprivate, version, vmlinuz,
458 bootloader, config_file, pad); 496 bootloader, config_file, pad);
459 case OPT_MODE_VERIFY: 497 case OPT_MODE_VERIFY:
460 return Verify(filename, signpubkey); 498 return Verify(filename, signpubkey);
461 default: 499 default:
462 printf("Must specify a mode.\n"); 500 printf("Must specify a mode.\n");
463 return PrintHelp(); 501 return PrintHelp();
464 } 502 }
465 } 503 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698