futility: Reformat to use kernel coding style

This just reformats the futility sources to conform to the Linux kernel
coding style. No functional changes.

BUG=chromium:224734
BRANCH=ToT
TEST=make runtests

Change-Id: I82df07dd3f8be2ad2f3df24cebe00a9a378b13f4
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/213915
Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
Bill Richardson
2014-08-24 22:07:17 -07:00
committed by chrome-internal-fetch
parent 8f15d74fd6
commit 31d95c2386
12 changed files with 3098 additions and 2997 deletions

View File

@@ -23,7 +23,6 @@
#include "kernel_blob.h" #include "kernel_blob.h"
#include "vboot_common.h" #include "vboot_common.h"
/* Global opt */ /* Global opt */
static int opt_debug = 0; static int opt_debug = 0;
@@ -46,11 +45,11 @@ static const struct option long_opts[] = {
{NULL, 0, 0, 0} {NULL, 0, 0, 0}
}; };
/* Print help and return error */ /* Print help and return error */
static int PrintHelp(const char *progname) { static int PrintHelp(const char *progname)
{
fprintf(stderr, fprintf(stderr,
"This program is used to sign and verify developer-mode files\n"); "This is used to sign and verify developer-mode files\n");
fprintf(stderr, fprintf(stderr,
"\n" "\n"
"Usage: %s --sign <file> [PARAMETERS]\n" "Usage: %s --sign <file> [PARAMETERS]\n"
@@ -59,25 +58,26 @@ static int PrintHelp(const char *progname) {
" --keyblock <file> Key block in .keyblock format\n" " --keyblock <file> Key block in .keyblock format\n"
" --signprivate <file>" " --signprivate <file>"
" Private key to sign file data, in .vbprivk format\n" " Private key to sign file data, in .vbprivk format\n"
" --vblock <file> Output signature in .vblock format\n" " --vblock <file>"
"\n", " Output signature in .vblock format\n"
progname); "\n", progname);
fprintf(stderr, fprintf(stderr,
"OR\n\n" "OR\n\n"
"Usage: %s --verify <file> [PARAMETERS]\n" "Usage: %s --verify <file> [PARAMETERS]\n"
"\n" "\n"
" Required parameters:\n" " Required parameters:\n"
" --vblock <file> Signature file in .vblock format\n" " --vblock <file>"
" Signature file in .vblock format\n"
"\n" "\n"
" Optional parameters:\n" " Optional parameters:\n"
" --keyblock <file>" " --keyblock <file>"
" Extract .keyblock to file if verification succeeds\n" " Extract .keyblock to file if verification succeeds\n"
"\n", "\n", progname);
progname);
return 1; return 1;
} }
static void Debug(const char *format, ...) { static void Debug(const char *format, ...)
{
if (!opt_debug) if (!opt_debug)
return; return;
@@ -88,11 +88,11 @@ static void Debug(const char *format, ...) {
va_end(ap); va_end(ap);
} }
/* Sign a file. We'll reuse the same structs used to sign kernels, to avoid /* Sign a file. We'll reuse the same structs used to sign kernels, to avoid
having to declare yet another one for just this purpose. */ having to declare yet another one for just this purpose. */
static int Sign(const char *filename, const char *keyblock_file, static int Sign(const char *filename, const char *keyblock_file,
const char* signprivate_file, const char* outfile) { const char *signprivate_file, const char *outfile)
{
uint8_t *file_data; uint8_t *file_data;
uint64_t file_size; uint64_t file_size;
VbKeyBlockHeader *key_block; VbKeyBlockHeader *key_block;
@@ -110,7 +110,8 @@ static int Sign(const char* filename, const char* keyblock_file,
} }
/* Get the key block and read the private key corresponding to it. */ /* Get the key block and read the private key corresponding to it. */
key_block = (VbKeyBlockHeader*)ReadFile(keyblock_file, &key_block_size); key_block =
(VbKeyBlockHeader *) ReadFile(keyblock_file, &key_block_size);
if (!key_block) { if (!key_block) {
VbExError("Error reading key block.\n"); VbExError("Error reading key block.\n");
return 1; return 1;
@@ -133,9 +134,7 @@ static int Sign(const char* filename, const char* keyblock_file,
(uint64_t) 0, (uint64_t) 0,
(uint64_t) 0, (uint64_t) 0,
(uint64_t) 0, (uint64_t) 0,
body_sig, body_sig, (uint64_t) 0, signing_key);
(uint64_t)0,
signing_key);
if (!preamble) { if (!preamble) {
VbExError("Error creating preamble.\n"); VbExError("Error creating preamble.\n");
return 1; return 1;
@@ -171,7 +170,8 @@ static int Sign(const char* filename, const char* keyblock_file,
} }
static int Verify(const char *filename, const char *vblock_file, static int Verify(const char *filename, const char *vblock_file,
const char* keyblock_file) { const char *keyblock_file)
{
uint8_t *file_data; uint8_t *file_data;
uint64_t file_size; uint64_t file_size;
uint8_t *buf; uint8_t *buf;
@@ -201,7 +201,8 @@ static int Verify(const char* filename, const char* vblock_file,
Debug("Keyblock is 0x%" PRIx64 " bytes\n", key_block->key_block_size); Debug("Keyblock is 0x%" PRIx64 " bytes\n", key_block->key_block_size);
current_buf_offset += key_block->key_block_size; current_buf_offset += key_block->key_block_size;
if (current_buf_offset > buf_size) { if (current_buf_offset > buf_size) {
VbExError("key_block_size advances past the end of the buffer\n"); VbExError
("key_block_size advances past the end of the buffer\n");
return 1; return 1;
} }
@@ -210,27 +211,32 @@ static int Verify(const char* filename, const char* vblock_file,
Debug("Preamble is 0x%" PRIx64 " bytes\n", preamble->preamble_size); Debug("Preamble is 0x%" PRIx64 " bytes\n", preamble->preamble_size);
current_buf_offset += preamble->preamble_size; current_buf_offset += preamble->preamble_size;
if (current_buf_offset > buf_size) { if (current_buf_offset > buf_size) {
VbExError("preamble_size advances past the end of the buffer\n"); VbExError
("preamble_size advances past the end of the buffer\n");
return 1; return 1;
} }
Debug("Current buf offset is at 0x%" PRIx64 " bytes\n", current_buf_offset); Debug("Current buf offset is at 0x%" PRIx64 " bytes\n",
current_buf_offset);
/* Check the key block (hash only) */ /* Check the key block (hash only) */
if (0 != KeyBlockVerify(key_block, key_block->key_block_size, NULL, 1)) { if (0 != KeyBlockVerify(key_block, key_block->key_block_size,
NULL, 1)) {
VbExError("Error verifying key block.\n"); VbExError("Error verifying key block.\n");
return 1; return 1;
} }
printf("Key block:\n"); printf("Key block:\n");
data_key = &key_block->data_key; data_key = &key_block->data_key;
printf(" Size: 0x%" PRIx64 "\n", key_block->key_block_size); printf(" Size: 0x%" PRIx64 "\n",
key_block->key_block_size);
printf(" Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm, printf(" Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm,
(data_key->algorithm < kNumAlgorithms ? (data_key->algorithm <
algo_strings[data_key->algorithm] : "(invalid)")); kNumAlgorithms ? algo_strings[data_key->
algorithm] : "(invalid)"));
printf(" Data key version: %" PRIu64 "\n", data_key->key_version); printf(" Data key version: %" PRIu64 "\n", data_key->key_version);
printf(" Flags: %" PRIu64 "\n", key_block->key_block_flags); printf(" Flags: %" PRIu64 "\n",
key_block->key_block_flags);
/* Verify preamble */ /* Verify preamble */
rsa = PublicKeyToRSA(&key_block->data_key); rsa = PublicKeyToRSA(&key_block->data_key);
@@ -244,26 +250,33 @@ static int Verify(const char* filename, const char* vblock_file,
} }
printf("Preamble:\n"); printf("Preamble:\n");
printf(" Size: 0x%" PRIx64 "\n", preamble->preamble_size); printf(" Size: 0x%" PRIx64 "\n",
preamble->preamble_size);
printf(" Header version: %" PRIu32 ".%" PRIu32 "\n", printf(" Header version: %" PRIu32 ".%" PRIu32 "\n",
preamble->header_version_major, preamble->header_version_minor); preamble->header_version_major, preamble->header_version_minor);
printf(" Kernel version: %" PRIu64 "\n", preamble->kernel_version); printf(" Kernel version: %" PRIu64 "\n",
printf(" Body load address: 0x%" PRIx64 "\n", preamble->body_load_address); preamble->kernel_version);
printf(" Body load address: 0x%" PRIx64 "\n",
preamble->body_load_address);
printf(" Body size: 0x%" PRIx64 "\n", printf(" Body size: 0x%" PRIx64 "\n",
preamble->body_signature.data_size); preamble->body_signature.data_size);
printf(" Bootloader address: 0x%" PRIx64 "\n", printf(" Bootloader address: 0x%" PRIx64 "\n",
preamble->bootloader_address); preamble->bootloader_address);
printf(" Bootloader size: 0x%" PRIx64 "\n", preamble->bootloader_size); printf(" Bootloader size: 0x%" PRIx64 "\n",
preamble->bootloader_size);
/* Verify body */ /* Verify body */
if (0 != VerifyData(file_data, file_size, &preamble->body_signature, rsa)) { if (0 !=
VerifyData(file_data, file_size, &preamble->body_signature, rsa)) {
VbExError("Error verifying kernel body.\n"); VbExError("Error verifying kernel body.\n");
return 1; return 1;
} }
printf("Body verification succeeded.\n"); printf("Body verification succeeded.\n");
if (keyblock_file) { if (keyblock_file) {
if (0 != WriteFile(keyblock_file, key_block, key_block->key_block_size)) { if (0 !=
WriteFile(keyblock_file, key_block,
key_block->key_block_size)) {
VbExError("Unable to export keyblock file\n"); VbExError("Unable to export keyblock file\n");
return 1; return 1;
} }
@@ -273,8 +286,8 @@ static int Verify(const char* filename, const char* vblock_file,
return 0; return 0;
} }
static int do_dev_sign_file(int argc, char *argv[])
static int do_dev_sign_file(int argc, char* argv[]) { {
char *filename = NULL; char *filename = NULL;
char *keyblock_file = NULL; char *keyblock_file = NULL;
char *signprivate_file = NULL; char *signprivate_file = NULL;
@@ -289,8 +302,9 @@ static int do_dev_sign_file(int argc, char* argv[]) {
else else
progname = argv[0]; progname = argv[0];
while ((option_index = getopt_long(argc, argv, ":", long_opts, NULL)) != -1 && while ((option_index =
!parse_error) { getopt_long(argc, argv, ":", long_opts, NULL)) != -1
&& !parse_error) {
switch (option_index) { switch (option_index) {
default: default:
case '?': case '?':
@@ -305,7 +319,8 @@ static int do_dev_sign_file(int argc, char* argv[]) {
case OPT_MODE_SIGN: case OPT_MODE_SIGN:
case OPT_MODE_VERIFY: case OPT_MODE_VERIFY:
if (mode && (mode != option_index)) { if (mode && (mode != option_index)) {
fprintf(stderr, "Only a single mode can be specified\n"); fprintf(stderr,
"Only one mode can be specified\n");
parse_error = 1; parse_error = 1;
break; break;
} }
@@ -336,7 +351,8 @@ static int do_dev_sign_file(int argc, char* argv[]) {
fprintf(stderr, "Some required options are missing\n"); fprintf(stderr, "Some required options are missing\n");
return PrintHelp(progname); return PrintHelp(progname);
} }
return Sign(filename, keyblock_file, signprivate_file, vblock_file); return Sign(filename, keyblock_file, signprivate_file,
vblock_file);
case OPT_MODE_VERIFY: case OPT_MODE_VERIFY:
if (!vblock_file) { if (!vblock_file) {
@@ -346,8 +362,7 @@ static int do_dev_sign_file(int argc, char* argv[]) {
return Verify(filename, vblock_file, keyblock_file); return Verify(filename, vblock_file, keyblock_file);
default: default:
fprintf(stderr, fprintf(stderr, "You must specify either --sign or --verify\n");
"You must specify either --sign or --verify\n");
return PrintHelp(progname); return PrintHelp(progname);
} }

View File

@@ -29,22 +29,24 @@ static void *base_of_rom;
static size_t size_of_rom; static size_t size_of_rom;
static int opt_gaps = 0; static int opt_gaps = 0;
/* Return 0 if successful */ /* Return 0 if successful */
static int dump_fmap(const void *ptr, int argc, char *argv[]) static int dump_fmap(const void *ptr, int argc, char *argv[])
{ {
int i, retval = 0; int i, retval = 0;
char buf[80]; // DWR: magic number char buf[80]; /* DWR: magic number */
const FmapHeader *fmh = (const FmapHeader *)ptr; const FmapHeader *fmh = (const FmapHeader *)ptr;
const FmapAreaHeader *ah = (const FmapAreaHeader*)(ptr + sizeof(FmapHeader)); const FmapAreaHeader *ah =
(const FmapAreaHeader *)(ptr + sizeof(FmapHeader));
if (FMT_NORMAL == opt_format) { if (FMT_NORMAL == opt_format) {
snprintf(buf, FMAP_SIGNATURE_SIZE+1, "%s", fmh->fmap_signature); snprintf(buf, FMAP_SIGNATURE_SIZE + 1, "%s",
fmh->fmap_signature);
printf("fmap_signature %s\n", buf); printf("fmap_signature %s\n", buf);
printf("fmap_version: %d.%d\n", printf("fmap_version: %d.%d\n",
fmh->fmap_ver_major, fmh->fmap_ver_minor); fmh->fmap_ver_major, fmh->fmap_ver_minor);
printf("fmap_base: 0x%" PRIx64 "\n", fmh->fmap_base); printf("fmap_base: 0x%" PRIx64 "\n", fmh->fmap_base);
printf("fmap_size: 0x%08x (%d)\n", fmh->fmap_size, fmh->fmap_size); printf("fmap_size: 0x%08x (%d)\n", fmh->fmap_size,
fmh->fmap_size);
snprintf(buf, FMAP_NAMELEN + 1, "%s", fmh->fmap_name); snprintf(buf, FMAP_NAMELEN + 1, "%s", fmh->fmap_name);
printf("fmap_name: %s\n", buf); printf("fmap_name: %s\n", buf);
printf("fmap_nareas: %d\n", fmh->fmap_nareas); printf("fmap_nareas: %d\n", fmh->fmap_nareas);
@@ -67,17 +69,20 @@ static int dump_fmap(const void *ptr, int argc, char *argv[])
switch (opt_format) { switch (opt_format) {
case FMT_PRETTY: case FMT_PRETTY:
printf("%s %d %d\n", buf, ah->area_offset, ah->area_size); printf("%s %d %d\n", buf, ah->area_offset,
ah->area_size);
break; break;
case FMT_FLASHROM: case FMT_FLASHROM:
if (ah->area_size) if (ah->area_size)
printf("0x%08x:0x%08x %s\n", ah->area_offset, printf("0x%08x:0x%08x %s\n", ah->area_offset,
ah->area_offset + ah->area_size - 1, buf); ah->area_offset + ah->area_size - 1,
buf);
break; break;
default: default:
printf("area: %d\n", i + 1); printf("area: %d\n", i + 1);
printf("area_offset: 0x%08x\n", ah->area_offset); printf("area_offset: 0x%08x\n", ah->area_offset);
printf("area_size: 0x%08x (%d)\n", ah->area_size, ah->area_size); printf("area_size: 0x%08x (%d)\n", ah->area_size,
ah->area_size);
printf("area_name: %s\n", buf); printf("area_name: %s\n", buf);
} }
@@ -92,10 +97,13 @@ static int dump_fmap(const void *ptr, int argc, char *argv[])
progname, buf, strerror(errno)); progname, buf, strerror(errno));
retval = 1; retval = 1;
} else if (!ah->area_size) { } else if (!ah->area_size) {
fprintf(stderr, "%s: section %s has zero size\n", progname, buf); fprintf(stderr,
} else if (ah->area_offset + ah->area_size > size_of_rom) { "%s: section %s has zero size\n",
fprintf(stderr, "%s: section %s is larger than the image\n",
progname, buf); progname, buf);
} else if (ah->area_offset + ah->area_size >
size_of_rom) {
fprintf(stderr, "%s: section %s is larger"
" than the image\n", progname, buf);
retval = 1; retval = 1;
} else if (1 != fwrite(base_of_rom + ah->area_offset, } else if (1 != fwrite(base_of_rom + ah->area_offset,
ah->area_size, 1, fp)) { ah->area_size, 1, fp)) {
@@ -113,7 +121,6 @@ static int dump_fmap(const void *ptr, int argc, char *argv[])
return retval; return retval;
} }
/****************************************************************************/ /****************************************************************************/
/* Stuff for human-readable form */ /* Stuff for human-readable form */
@@ -152,7 +159,6 @@ static void sort_nodes(int num, node_t *ary[])
} }
} }
static void line(int indent, char *name, static void line(int indent, char *name,
uint32_t start, uint32_t end, uint32_t size, char *append) uint32_t start, uint32_t end, uint32_t size, char *append)
{ {
@@ -181,15 +187,18 @@ static void show(node_t *p, int indent, int show_first)
if (show_first) { if (show_first) {
line(indent, p->name, p->start, p->end, p->size, 0); line(indent, p->name, p->start, p->end, p->size, 0);
for (alias = p->alias; alias; alias = alias->next) for (alias = p->alias; alias; alias = alias->next)
line(indent, alias->name, p->start, p->end, p->size, " // DUPLICATE"); line(indent, alias->name, p->start, p->end, p->size,
" // DUPLICATE");
} }
sort_nodes(p->num_children, p->child); sort_nodes(p->num_children, p->child);
for (i = 0; i < p->num_children; i++) { for (i = 0; i < p->num_children; i++) {
if (i == 0 && p->end != p->child[i]->end) if (i == 0 && p->end != p->child[i]->end)
empty(indent, p->child[i]->end, p->end, p->name); empty(indent, p->child[i]->end, p->end, p->name);
show(p->child[i], indent + show_first, 1); show(p->child[i], indent + show_first, 1);
if (i < p->num_children - 1 && p->child[i]->start != p->child[i+1]->end) if (i < p->num_children - 1
empty(indent, p->child[i+1]->end, p->child[i]->start, p->name); && p->child[i]->start != p->child[i + 1]->end)
empty(indent, p->child[i + 1]->end, p->child[i]->start,
p->name);
if (i == p->num_children - 1 && p->child[i]->start != p->start) if (i == p->num_children - 1 && p->child[i]->start != p->start)
empty(indent, p->start, p->child[i]->start, p->name); empty(indent, p->start, p->child[i]->start, p->name);
} }
@@ -209,8 +218,7 @@ static int encloses(int i, int j)
node_t *a = all_nodes + i; node_t *a = all_nodes + i;
node_t *b = all_nodes + j; node_t *b = all_nodes + j;
return ((a->start <= b->start) && return ((a->start <= b->start) && (a->end >= b->end));
(a->end >= b->end));
} }
static int duplicates(int i, int j) static int duplicates(int i, int j)
@@ -218,8 +226,7 @@ static int duplicates(int i, int j)
node_t *a = all_nodes + i; node_t *a = all_nodes + i;
node_t *b = all_nodes + j; node_t *b = all_nodes + j;
return ((a->start == b->start) && return ((a->start == b->start) && (a->end == b->end));
(a->end == b->end));
} }
static void add_dupe(int i, int j, int numnodes) static void add_dupe(int i, int j, int numnodes)
@@ -239,7 +246,8 @@ static void add_child(node_t *p, int n)
{ {
int i; int i;
if (p->num_children && !p->child) { if (p->num_children && !p->child) {
p->child = (struct node_s **)calloc(p->num_children, sizeof(node_t *)); p->child =
(struct node_s **)calloc(p->num_children, sizeof(node_t *));
if (!p->child) { if (!p->child) {
perror("calloc failed"); perror("calloc failed");
exit(1); exit(1);
@@ -294,7 +302,6 @@ static int human_fmap(void *p)
all_nodes[numnodes].size = fmh->fmap_size; all_nodes[numnodes].size = fmh->fmap_size;
all_nodes[numnodes].end = fmh->fmap_base + fmh->fmap_size; all_nodes[numnodes].end = fmh->fmap_base + fmh->fmap_size;
/* First, coalesce any duplicates */ /* First, coalesce any duplicates */
for (i = 0; i < numnodes; i++) { for (i = 0; i < numnodes; i++) {
for (j = i + 1; j < numnodes; j++) { for (j = i + 1; j < numnodes; j++) {
@@ -305,13 +312,14 @@ static int human_fmap(void *p)
} }
} }
/* Each node should have at most one parent, which is the smallest enclosing /* Each node should have at most one parent, which is the smallest
* node. Duplicate nodes "enclose" each other, but if there's already a * enclosing node. Duplicate nodes "enclose" each other, but if there's
* relationship in one direction, we won't create another. */ * already a relationship in one direction, we won't create another.
*/
for (i = 0; i < numnodes; i++) { for (i = 0; i < numnodes; i++) {
/* Find the smallest parent, which might be the root node. */ /* Find the smallest parent, which might be the root node. */
int k = numnodes; int k = numnodes;
for (j = 0; j < numnodes; j++) { /* full O(N^2), not triangular */ for (j = 0; j < numnodes; j++) { /* full O(N^2) comparison */
if (i == j) if (i == j)
continue; continue;
if (overlaps(i, j)) { if (overlaps(i, j)) {
@@ -322,12 +330,14 @@ static int human_fmap(void *p)
printf(" %s: 0x%x - 0x%x\n", all_nodes[j].name, printf(" %s: 0x%x - 0x%x\n", all_nodes[j].name,
all_nodes[j].start, all_nodes[j].end); all_nodes[j].start, all_nodes[j].end);
if (opt_overlap < 2) { if (opt_overlap < 2) {
printf("Use more -h args to ignore this error\n"); printf("Use more -h args to ignore"
" this error\n");
errorcnt++; errorcnt++;
} }
continue; continue;
} }
if (encloses(j, i) && all_nodes[j].size < all_nodes[k].size) if (encloses(j, i)
&& all_nodes[j].size < all_nodes[k].size)
k = j; k = j;
} }
all_nodes[i].parent = all_nodes + k; all_nodes[i].parent = all_nodes + k;
@@ -356,6 +366,18 @@ static int human_fmap(void *p)
/* End of human-reable stuff */ /* End of human-reable stuff */
/****************************************************************************/ /****************************************************************************/
static const char usage[] =
"\nUsage: %s [-x] [-p|-f|-h] FLASHIMAGE [NAME...]\n\n"
"Display (and extract with -x) the FMAP components from a BIOS image.\n"
"The -p option makes the output easier to parse by scripts.\n"
"The -f option emits the FMAP in the format used by flashrom.\n"
"\n"
"Specify one or more NAMEs to only print sections that exactly match.\n"
"\n"
"The -h option shows the whole FMAP in human-readable form.\n"
" Use -H to also display any gaps.\n"
"\n";
static int do_dump_fmap(int argc, char *argv[]) static int do_dump_fmap(int argc, char *argv[])
{ {
int c; int c;
@@ -407,44 +429,28 @@ static int do_dump_fmap(int argc, char *argv[])
} }
if (errorcnt || optind >= argc) { if (errorcnt || optind >= argc) {
fprintf(stderr, fprintf(stderr, usage, progname);
"\nUsage: %s [-x] [-p|-f|-h] FLASHIMAGE [NAME...]\n\n"
"Display (and extract with -x) the FMAP components from a BIOS image.\n"
"The -p option makes the output easier to parse by scripts.\n"
"The -f option emits the FMAP in the format used by flashrom.\n"
"\n"
"Specify one or more NAMEs to only print sections that exactly match.\n"
"\n"
"The -h option shows the whole FMAP in human-readable form.\n"
" Use -H to also display any gaps.\n"
"\n",
progname);
return 1; return 1;
} }
if (0 != stat(argv[optind], &sb)) { if (0 != stat(argv[optind], &sb)) {
fprintf(stderr, "%s: can't stat %s: %s\n", fprintf(stderr, "%s: can't stat %s: %s\n",
progname, progname, argv[optind], strerror(errno));
argv[optind],
strerror(errno));
return 1; return 1;
} }
fd = open(argv[optind], O_RDONLY); fd = open(argv[optind], O_RDONLY);
if (fd < 0) { if (fd < 0) {
fprintf(stderr, "%s: can't open %s: %s\n", fprintf(stderr, "%s: can't open %s: %s\n",
progname, progname, argv[optind], strerror(errno));
argv[optind],
strerror(errno));
return 1; return 1;
} }
base_of_rom = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); base_of_rom =
mmap(0, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (base_of_rom == (char *)-1) { if (base_of_rom == (char *)-1) {
fprintf(stderr, "%s: can't mmap %s: %s\n", fprintf(stderr, "%s: can't mmap %s: %s\n",
progname, progname, argv[optind], strerror(errno));
argv[optind],
strerror(errno));
close(fd); close(fd);
return 1; return 1;
} }
@@ -458,18 +464,19 @@ static int do_dump_fmap(int argc, char *argv[])
retval = human_fmap((void *)fmap); retval = human_fmap((void *)fmap);
break; break;
case FMT_NORMAL: case FMT_NORMAL:
printf("hit at 0x%08x\n", (uint32_t) (fmap - (char*) base_of_rom)); printf("hit at 0x%08x\n",
(uint32_t) (fmap - (char *)base_of_rom));
/* fallthrough */ /* fallthrough */
default: default:
retval = dump_fmap(fmap, argc-optind-1, argv+optind+1); retval =
dump_fmap(fmap, argc - optind - 1,
argv + optind + 1);
} }
} }
if (0 != munmap(base_of_rom, sb.st_size)) { if (0 != munmap(base_of_rom, sb.st_size)) {
fprintf(stderr, "%s: can't munmap %s: %s\n", fprintf(stderr, "%s: can't munmap %s: %s\n",
progname, progname, argv[optind], strerror(errno));
argv[optind],
strerror(errno));
return 1; return 1;
} }

View File

@@ -5,7 +5,6 @@
* Exports the kernel commandline from a given partition/image. * Exports the kernel commandline from a given partition/image.
*/ */
#include <getopt.h> #include <getopt.h>
#include <stdio.h> #include <stdio.h>
#include <sys/mman.h> #include <sys/mman.h>
@@ -24,17 +23,17 @@ static const struct option long_opts[] = {
}; };
/* Print help and return error */ /* Print help and return error */
static int PrintHelp(void) { static int PrintHelp(void)
{
puts("dump_kernel_config - Prints the kernel command line\n" puts("dump_kernel_config - Prints the kernel command line\n"
"\n" "\n"
"Usage: dump_kernel_config [--kloadaddr <ADDRESS>] " "Usage: dump_kernel_config [--kloadaddr <ADDRESS>] "
"<image/blockdevice>\n" "<image/blockdevice>\n" "\n" "");
"\n"
"");
return 1; return 1;
} }
static int do_dump_kernel_config(int argc, char* argv[]) { static int do_dump_kernel_config(int argc, char *argv[])
{
char *infile = NULL; char *infile = NULL;
char *config = NULL; char *config = NULL;
uint64_t kernel_body_load_address = USE_PREAMBLE_LOAD_ADDR; uint64_t kernel_body_load_address = USE_PREAMBLE_LOAD_ADDR;

View File

@@ -18,7 +18,8 @@
#include "futility.h" #include "futility.h"
#include "gbb_header.h" #include "gbb_header.h"
static void help_and_quit(const char *prog) { static void help_and_quit(const char *prog)
{
fprintf(stderr, "\n" fprintf(stderr, "\n"
"Usage: %s [-g|-s|-c] [OPTIONS] bios_file [output_file]\n" "Usage: %s [-g|-s|-c] [OPTIONS] bios_file [output_file]\n"
"\n" "\n"
@@ -42,11 +43,13 @@ static void help_and_quit(const char *prog) {
" -r --recoverykey=FILE\tFile name of new Recovery Key.\n" " -r --recoverykey=FILE\tFile name of new Recovery Key.\n"
"\n" "\n"
"CREATE MODE:\n" "CREATE MODE:\n"
"-c, --create=hwid_size,rootkey_size,bmpfv_size,recoverykey_size\n" "-c, --create=hwid_size,rootkey_size,bmpfv_size,"
"recoverykey_size\n"
" \tCreate a GBB blob by given size list.\n" " \tCreate a GBB blob by given size list.\n"
"SAMPLE:\n" "SAMPLE:\n"
" %s -g bios.bin\n" " %s -g bios.bin\n"
" %s --set --hwid='New Model' -k key.bin bios.bin newbios.bin\n" " %s --set --hwid='New Model' -k key.bin"
" bios.bin newbios.bin\n"
" %s -c 0x100,0x1000,0x03DE80,0x1000 gbb.blob\n\n", " %s -c 0x100,0x1000,0x03DE80,0x1000 gbb.blob\n\n",
prog, prog, prog, prog); prog, prog, prog, prog);
exit(1); exit(1);
@@ -66,6 +69,7 @@ static const struct option long_opts[] = {
{"flags", 2, NULL, 'L'}, {"flags", 2, NULL, 'L'},
{NULL, 0, NULL, 0}, {NULL, 0, NULL, 0},
}; };
static char *short_opts = ":gsc:o:k:b:R:r:h:i:L:f:"; static char *short_opts = ":gsc:o:k:b:R:r:h:i:L:f:";
static int errorcnt; static int errorcnt;
@@ -84,7 +88,7 @@ static int ValidGBB(GoogleBinaryBlockHeader *gbb, size_t maxlen)
if (gbb->hwid_offset + gbb->hwid_size > maxlen) if (gbb->hwid_offset + gbb->hwid_size > maxlen)
goto bad; goto bad;
if (gbb->hwid_size) { if (gbb->hwid_size) {
/* Make sure the HWID is null-terminated (assumes ASCII, not unicode). */ /* Make sure the HWID is null-terminated (ASCII, not unicode) */
s = (char *)((char *)gbb + gbb->hwid_offset); s = (char *)((char *)gbb + gbb->hwid_offset);
for (i = 0; i < gbb->hwid_size; i++) for (i = 0; i < gbb->hwid_size; i++)
if (*s++ == '\0') if (*s++ == '\0')
@@ -119,9 +123,7 @@ GoogleBinaryBlockHeader *FindGbbHeader(uint8_t *ptr, size_t size)
GoogleBinaryBlockHeader *tmp, *gbb_header = NULL; GoogleBinaryBlockHeader *tmp, *gbb_header = NULL;
int count = 0; int count = 0;
for (i = 0; for (i = 0; i <= size - GBB_SEARCH_STRIDE; i += GBB_SEARCH_STRIDE) {
i <= size - GBB_SEARCH_STRIDE;
i += GBB_SEARCH_STRIDE) {
if (0 != memcmp(ptr + i, GBB_SIGNATURE, GBB_SIGNATURE_SIZE)) if (0 != memcmp(ptr + i, GBB_SIGNATURE, GBB_SIGNATURE_SIZE))
continue; continue;
@@ -158,7 +160,8 @@ static uint8_t *create_gbb(const char *desc, off_t *sizeptr)
sizes = strdup(desc); sizes = strdup(desc);
if (!sizes) { if (!sizes) {
errorcnt++; errorcnt++;
fprintf(stderr, "ERROR: strdup() failed: %s\n", strerror(errno)); fprintf(stderr, "ERROR: strdup() failed: %s\n",
strerror(errno));
return NULL; return NULL;
} }
@@ -166,7 +169,9 @@ static uint8_t *create_gbb(const char *desc, off_t *sizeptr)
val[i] = (uint32_t) strtoul(param, &e, 0); val[i] = (uint32_t) strtoul(param, &e, 0);
if (e && *e) { if (e && *e) {
errorcnt++; errorcnt++;
fprintf(stderr, "ERROR: invalid creation parameter: \"%s\"\n", param); fprintf(stderr,
"ERROR: invalid creation parameter: \"%s\"\n",
param);
free(sizes); free(sizes);
return NULL; return NULL;
} }
@@ -329,7 +334,8 @@ static int read_from_file(const char *msg, const char *filename,
} }
if (sb.st_size > size) { if (sb.st_size > size) {
fprintf(stderr, "ERROR: file %s exceeds capacity (%" PRIu32 ")\n", fprintf(stderr,
"ERROR: file %s exceeds capacity (%" PRIu32 ")\n",
filename, size); filename, size);
errorcnt++; errorcnt++;
r = errno; r = errno;
@@ -339,7 +345,8 @@ static int read_from_file(const char *msg, const char *filename,
/* It's okay if we read less than size. That's just the max. */ /* It's okay if we read less than size. That's just the max. */
count = fread(start, 1, size, fp); count = fread(start, 1, size, fp);
if (ferror(fp)) { if (ferror(fp)) {
fprintf(stderr, "ERROR: Read %zu/%" PRIi64 " bytes from %s: %s\n", fprintf(stderr,
"ERROR: Read %zu/%" PRIi64 " bytes from %s: %s\n",
count, sb.st_size, filename, strerror(errno)); count, sb.st_size, filename, strerror(errno));
errorcnt++; errorcnt++;
r = errno; r = errno;
@@ -402,25 +409,32 @@ static int do_gbb_utility(int argc, char *argv[])
case 'b': case 'b':
opt_bmpfv = optarg; opt_bmpfv = optarg;
break; break;
case 'R': case 'r': case 'R':
case 'r':
opt_recoverykey = optarg; opt_recoverykey = optarg;
break; break;
case 'i': case 'h': case 'i':
/* --hwid is optional: might be null, which could be okay */ case 'h':
/* --hwid is optional: null might be okay */
opt_hwid = optarg; opt_hwid = optarg;
sel_hwid = 1; sel_hwid = 1;
break; break;
case 'L': case 'f': case 'L':
/* --flags is optional: might be null, which could be okay */ case 'f':
/* --flags is optional: null might be okay */
opt_flags = optarg; opt_flags = optarg;
sel_flags = 1; sel_flags = 1;
break; break;
case '?': case '?':
errorcnt++; errorcnt++;
if (optopt) if (optopt)
fprintf(stderr, "ERROR: unrecognized option: -%c\n", optopt); fprintf(stderr,
"ERROR: unrecognized option: -%c\n",
optopt);
else if (argv[optind - 1]) else if (argv[optind - 1])
fprintf(stderr, "ERROR: unrecognized option (possibly \"%s\")\n", fprintf(stderr,
"ERROR: unrecognized option "
"(possibly \"%s\")\n",
argv[optind - 1]); argv[optind - 1]);
else else
fprintf(stderr, "ERROR: unrecognized option\n"); fprintf(stderr, "ERROR: unrecognized option\n");
@@ -428,14 +442,18 @@ static int do_gbb_utility(int argc, char *argv[])
case ':': case ':':
errorcnt++; errorcnt++;
if (argv[optind - 1]) if (argv[optind - 1])
fprintf(stderr, "ERROR: missing argument to -%c (%s)\n", fprintf(stderr,
"ERROR: missing argument to -%c (%s)\n",
optopt, argv[optind - 1]); optopt, argv[optind - 1]);
else else
fprintf(stderr, "ERROR: missing argument to -%c\n", optopt); fprintf(stderr,
"ERROR: missing argument to -%c\n",
optopt);
break; break;
default: default:
errorcnt++; errorcnt++;
fprintf(stderr, "ERROR: unexpected error while parsing options\n"); fprintf(stderr,
"ERROR: error while parsing options\n");
} }
} }
@@ -454,7 +472,8 @@ static int do_gbb_utility(int argc, char *argv[])
} }
/* With no args, show the HWID */ /* With no args, show the HWID */
if (!opt_rootkey && !opt_bmpfv && !opt_recoverykey && !sel_flags) if (!opt_rootkey && !opt_bmpfv && !opt_recoverykey
&& !sel_flags)
sel_hwid = 1; sel_hwid = 1;
inbuf = read_entire_file(infile, &filesize); inbuf = read_entire_file(infile, &filesize);
@@ -471,11 +490,14 @@ static int do_gbb_utility(int argc, char *argv[])
/* Get the stuff */ /* Get the stuff */
if (sel_hwid) if (sel_hwid)
printf("hardware_id: %s\n", printf("hardware_id: %s\n",
gbb->hwid_size ? (char *)(gbb_base + gbb->hwid_offset) : ""); gbb->hwid_size ? (char *)(gbb_base +
gbb->
hwid_offset) : "");
if (sel_flags) if (sel_flags)
printf("flags: 0x%08x\n", gbb->flags); printf("flags: 0x%08x\n", gbb->flags);
if (opt_rootkey) if (opt_rootkey)
write_to_file(" - exported root_key to file:", opt_rootkey, write_to_file(" - exported root_key to file:",
opt_rootkey,
gbb_base + gbb->rootkey_offset, gbb_base + gbb->rootkey_offset,
gbb->rootkey_size); gbb->rootkey_size);
if (opt_bmpfv) if (opt_bmpfv)
@@ -483,7 +505,8 @@ static int do_gbb_utility(int argc, char *argv[])
gbb_base + gbb->bmpfv_offset, gbb_base + gbb->bmpfv_offset,
gbb->bmpfv_size); gbb->bmpfv_size);
if (opt_recoverykey) if (opt_recoverykey)
write_to_file(" - exported recovery_key to file:", opt_recoverykey, write_to_file(" - exported recovery_key to file:",
opt_recoverykey,
gbb_base + gbb->recovery_key_offset, gbb_base + gbb->recovery_key_offset,
gbb->recovery_key_size); gbb->recovery_key_size);
break; break;
@@ -521,7 +544,8 @@ static int do_gbb_utility(int argc, char *argv[])
outbuf = (uint8_t *) malloc(filesize); outbuf = (uint8_t *) malloc(filesize);
if (!outbuf) { if (!outbuf) {
errorcnt++; errorcnt++;
fprintf(stderr, "ERROR: can't malloc %" PRIi64 " bytes: %s\n", fprintf(stderr,
"ERROR: can't malloc %" PRIi64 " bytes: %s\n",
filesize, strerror(errno)); filesize, strerror(errno));
break; break;
} }
@@ -530,7 +554,8 @@ static int do_gbb_utility(int argc, char *argv[])
memcpy(outbuf, inbuf, filesize); memcpy(outbuf, inbuf, filesize);
gbb = FindGbbHeader(outbuf, filesize); gbb = FindGbbHeader(outbuf, filesize);
if (!gbb) { if (!gbb) {
fprintf(stderr, "INTERNAL ERROR: No GBB found in outbuf\n"); fprintf(stderr,
"INTERNAL ERROR: No GBB found in outbuf\n");
exit(1); exit(1);
} }
gbb_base = (uint8_t *) gbb; gbb_base = (uint8_t *) gbb;
@@ -538,11 +563,13 @@ static int do_gbb_utility(int argc, char *argv[])
if (opt_hwid) { if (opt_hwid) {
if (strlen(opt_hwid) + 1 > gbb->hwid_size) { if (strlen(opt_hwid) + 1 > gbb->hwid_size) {
fprintf(stderr, fprintf(stderr,
"ERROR: null-terminated HWID exceeds capacity (%d)\n", "ERROR: null-terminated HWID"
" exceeds capacity (%d)\n",
gbb->hwid_size); gbb->hwid_size);
errorcnt++; errorcnt++;
} else { } else {
strcpy((char *)(gbb_base + gbb->hwid_offset), opt_hwid); strcpy((char *)(gbb_base + gbb->hwid_offset),
opt_hwid);
} }
} }
@@ -551,7 +578,9 @@ static int do_gbb_utility(int argc, char *argv[])
uint32_t val; uint32_t val;
val = (uint32_t) strtoul(opt_flags, &e, 0); val = (uint32_t) strtoul(opt_flags, &e, 0);
if (e && *e) { if (e && *e) {
fprintf(stderr, "ERROR: invalid flags value: %s\n", opt_flags); fprintf(stderr,
"ERROR: invalid flags value: %s\n",
opt_flags);
errorcnt++; errorcnt++;
} else { } else {
gbb->flags = val; gbb->flags = val;
@@ -581,7 +610,8 @@ static int do_gbb_utility(int argc, char *argv[])
case DO_CREATE: case DO_CREATE:
if (!outfile) { if (!outfile) {
if (argc - optind < 1) { if (argc - optind < 1) {
fprintf(stderr, "\nERROR: missing output filename\n"); fprintf(stderr,
"\nERROR: missing output filename\n");
help_and_quit(argv[0]); help_and_quit(argv[0]);
} }
outfile = argv[optind++]; outfile = argv[optind++];
@@ -590,7 +620,8 @@ static int do_gbb_utility(int argc, char *argv[])
outbuf = create_gbb(opt_create, &filesize); outbuf = create_gbb(opt_create, &filesize);
if (!outbuf) { if (!outbuf) {
fprintf(stderr, fprintf(stderr,
"\nERROR: unable to parse creation spec (%s)\n", opt_create); "\nERROR: unable to parse creation spec (%s)\n",
opt_create);
help_and_quit(argv[0]); help_and_quit(argv[0]);
} }
if (!errorcnt) if (!errorcnt)
@@ -599,7 +630,6 @@ static int do_gbb_utility(int argc, char *argv[])
break; break;
} }
if (inbuf) if (inbuf)
free(inbuf); free(inbuf);
if (outbuf) if (outbuf)

View File

@@ -19,7 +19,6 @@
#include "util_misc.h" #include "util_misc.h"
#include "vboot_common.h" #include "vboot_common.h"
/* Command line options */ /* Command line options */
enum { enum {
OPT_MODE_VBLOCK = 1000, OPT_MODE_VBLOCK = 1000,
@@ -46,9 +45,9 @@ static const struct option long_opts[] = {
{NULL, 0, 0, 0} {NULL, 0, 0, 0}
}; };
/* Print help and return error */ /* Print help and return error */
static int PrintHelp(void) { static int PrintHelp(void)
{
puts("vbutil_firmware - Verified boot key block utility\n" puts("vbutil_firmware - Verified boot key block utility\n"
"\n" "\n"
@@ -56,7 +55,8 @@ static int PrintHelp(void) {
"\n" "\n"
"For '--vblock <file>', required OPTIONS are:\n" "For '--vblock <file>', required OPTIONS are:\n"
" --keyblock <file> Key block in .keyblock format\n" " --keyblock <file> Key block in .keyblock format\n"
" --signprivate <file> Signing private key in .vbprivk format\n" " --signprivate <file>"
" Signing private key in .vbprivk format\n"
" --version <number> Firmware version\n" " --version <number> Firmware version\n"
" --fv <file> Firmware volume to sign\n" " --fv <file> Firmware volume to sign\n"
" --kernelkey <file> Kernel subkey in .vbpubk format\n" " --kernelkey <file> Kernel subkey in .vbpubk format\n"
@@ -64,21 +64,23 @@ static int PrintHelp(void) {
" --flags <number> Preamble flags (defaults to 0)\n" " --flags <number> Preamble flags (defaults to 0)\n"
"\n" "\n"
"For '--verify <file>', required OPTIONS are:\n" "For '--verify <file>', required OPTIONS are:\n"
" --signpubkey <file> Signing public key in .vbpubk format\n" " --signpubkey <file>"
" Signing public key in .vbpubk format\n"
" --fv <file> Firmware volume to verify\n" " --fv <file> Firmware volume to verify\n"
"\n" "\n"
"For '--verify <file>', optional OPTIONS are:\n" "For '--verify <file>', optional OPTIONS are:\n"
" --kernelkey <file> Write the kernel subkey to this file\n" " --kernelkey <file>"
" Write the kernel subkey to this file\n"
""); "");
return 1; return 1;
} }
/* Create a firmware .vblock */ /* Create a firmware .vblock */
static int Vblock(const char *outfile, const char *keyblock_file, static int Vblock(const char *outfile, const char *keyblock_file,
const char *signprivate, uint64_t version, const char *signprivate, uint64_t version,
const char *fv_file, const char *kernelkey_file, const char *fv_file, const char *kernelkey_file,
uint32_t preamble_flags) { uint32_t preamble_flags)
{
VbPrivateKey *signing_key; VbPrivateKey *signing_key;
VbPublicKey *kernel_subkey; VbPublicKey *kernel_subkey;
@@ -105,7 +107,8 @@ static int Vblock(const char* outfile, const char* keyblock_file,
} }
/* Read the key block and keys */ /* Read the key block and keys */
key_block = (VbKeyBlockHeader*)ReadFile(keyblock_file, &key_block_size); key_block =
(VbKeyBlockHeader *) ReadFile(keyblock_file, &key_block_size);
if (!key_block) { if (!key_block) {
VbExError("Error reading key block.\n"); VbExError("Error reading key block.\n");
return 1; return 1;
@@ -142,8 +145,7 @@ static int Vblock(const char* outfile, const char* keyblock_file,
preamble = CreateFirmwarePreamble(version, preamble = CreateFirmwarePreamble(version,
kernel_subkey, kernel_subkey,
body_sig, body_sig,
signing_key, signing_key, preamble_flags);
preamble_flags);
if (!preamble) { if (!preamble) {
VbExError("Error creating preamble.\n"); VbExError("Error creating preamble.\n");
return 1; return 1;
@@ -169,7 +171,8 @@ static int Vblock(const char* outfile, const char* keyblock_file,
} }
static int Verify(const char *infile, const char *signpubkey, static int Verify(const char *infile, const char *signpubkey,
const char* fv_file, const char* kernelkey_file) { const char *fv_file, const char *kernelkey_file)
{
VbKeyBlockHeader *key_block; VbKeyBlockHeader *key_block;
VbFirmwarePreambleHeader *preamble; VbFirmwarePreambleHeader *preamble;
@@ -221,12 +224,14 @@ static int Verify(const char* infile, const char* signpubkey,
printf("Key block:\n"); printf("Key block:\n");
data_key = &key_block->data_key; data_key = &key_block->data_key;
printf(" Size: %" PRIu64 "\n", key_block->key_block_size); printf(" Size: %" PRIu64 "\n",
key_block->key_block_size);
printf(" Flags: %" PRIu64 " (ignored)\n", printf(" Flags: %" PRIu64 " (ignored)\n",
key_block->key_block_flags); key_block->key_block_flags);
printf(" Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm, printf(" Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm,
(data_key->algorithm < kNumAlgorithms ? (data_key->algorithm <
algo_strings[data_key->algorithm] : "(invalid)")); kNumAlgorithms ? algo_strings[data_key->
algorithm] : "(invalid)"));
printf(" Data key version: %" PRIu64 "\n", data_key->key_version); printf(" Data key version: %" PRIu64 "\n", data_key->key_version);
printf(" Data key sha1sum: "); printf(" Data key sha1sum: ");
PrintPubKeySha1Sum(data_key); PrintPubKeySha1Sum(data_key);
@@ -248,10 +253,12 @@ static int Verify(const char* infile, const char* signpubkey,
flags = VbGetFirmwarePreambleFlags(preamble); flags = VbGetFirmwarePreambleFlags(preamble);
printf("Preamble:\n"); printf("Preamble:\n");
printf(" Size: %" PRIu64 "\n", preamble->preamble_size); printf(" Size: %" PRIu64 "\n",
preamble->preamble_size);
printf(" Header version: %" PRIu32 ".%" PRIu32 "\n", printf(" Header version: %" PRIu32 ".%" PRIu32 "\n",
preamble->header_version_major, preamble->header_version_minor); preamble->header_version_major, preamble->header_version_minor);
printf(" Firmware version: %" PRIu64 "\n", preamble->firmware_version); printf(" Firmware version: %" PRIu64 "\n",
preamble->firmware_version);
kernel_subkey = &preamble->kernel_subkey; kernel_subkey = &preamble->kernel_subkey;
printf(" Kernel key algorithm: %" PRIu64 " %s\n", printf(" Kernel key algorithm: %" PRIu64 " %s\n",
kernel_subkey->algorithm, kernel_subkey->algorithm,
@@ -270,9 +277,13 @@ static int Verify(const char* infile, const char* signpubkey,
/* Verify body */ /* Verify body */
if (flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) { if (flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
printf("Preamble requests USE_RO_NORMAL; skipping body verification.\n"); printf
("Preamble requests USE_RO_NORMAL;"
" skipping body verification.\n");
} else { } else {
if (0 != VerifyData(fv_data, fv_size, &preamble->body_signature, rsa)) { if (0 !=
VerifyData(fv_data, fv_size, &preamble->body_signature,
rsa)) {
VbExError("Error verifying firmware body.\n"); VbExError("Error verifying firmware body.\n");
return 1; return 1;
} }
@@ -281,8 +292,7 @@ static int Verify(const char* infile, const char* signpubkey,
if (kernelkey_file) { if (kernelkey_file) {
if (0 != PublicKeyWrite(kernelkey_file, kernel_subkey)) { if (0 != PublicKeyWrite(kernelkey_file, kernel_subkey)) {
fprintf(stderr, VbExError("Unable to write kernel subkey\n");
"vbutil_firmware: unable to write kernel subkey\n");
return 1; return 1;
} }
} }
@@ -290,8 +300,8 @@ static int Verify(const char* infile, const char* signpubkey,
return 0; return 0;
} }
static int do_vbutil_firmware(int argc, char *argv[])
static int do_vbutil_firmware(int argc, char* argv[]) { {
char *filename = NULL; char *filename = NULL;
char *key_block_file = NULL; char *key_block_file = NULL;
@@ -363,8 +373,8 @@ static int do_vbutil_firmware(int argc, char* argv[]) {
switch (mode) { switch (mode) {
case OPT_MODE_VBLOCK: case OPT_MODE_VBLOCK:
return Vblock(filename, key_block_file, signprivate, version, fv_file, return Vblock(filename, key_block_file, signprivate, version,
kernelkey_file, preamble_flags); fv_file, kernelkey_file, preamble_flags);
case OPT_MODE_VERIFY: case OPT_MODE_VERIFY:
return Verify(filename, signpubkey, fv_file, kernelkey_file); return Verify(filename, signpubkey, fv_file, kernelkey_file);
default: default:

View File

@@ -33,7 +33,6 @@ static int opt_verbose = 0;
static int opt_vblockonly = 0; static int opt_vblockonly = 0;
static uint64_t opt_pad = 65536; static uint64_t opt_pad = 65536;
/* Command line options */ /* Command line options */
enum { enum {
OPT_MODE_PACK = 1000, OPT_MODE_PACK = 1000,
@@ -84,11 +83,9 @@ static const struct option long_opts[] = {
}; };
/* Print help and return error */
static int PrintHelp(char *progname) { static const char usage[] =
fprintf(stderr, "This program creates, signs, and verifies the kernel blob\n"
"This program creates, signs, and verifies the kernel blob\n");
fprintf(stderr,
"\n" "\n"
"Usage: %s --pack <file> [PARAMETERS]\n" "Usage: %s --pack <file> [PARAMETERS]\n"
"\n" "\n"
@@ -105,9 +102,7 @@ static int PrintHelp(char *progname) {
" Optional:\n" " Optional:\n"
" --kloadaddr <address> Assign kernel body load address\n" " --kloadaddr <address> Assign kernel body load address\n"
" --pad <number> Verification padding size in bytes\n" " --pad <number> Verification padding size in bytes\n"
" --vblockonly Emit just the verification blob\n", " --vblockonly Emit just the verification blob\n"
progname);
fprintf(stderr,
"\nOR\n\n" "\nOR\n\n"
"Usage: %s --repack <file> [PARAMETERS]\n" "Usage: %s --repack <file> [PARAMETERS]\n"
"\n" "\n"
@@ -123,9 +118,7 @@ static int PrintHelp(char *progname) {
" --version <number> Kernel version\n" " --version <number> Kernel version\n"
" --kloadaddr <address> Assign kernel body load address\n" " --kloadaddr <address> Assign kernel body load address\n"
" --pad <number> Verification blob size in bytes\n" " --pad <number> Verification blob size in bytes\n"
" --vblockonly Emit just the verification blob\n", " --vblockonly Emit just the verification blob\n"
progname);
fprintf(stderr,
"\nOR\n\n" "\nOR\n\n"
"Usage: %s --verify <file> [PARAMETERS]\n" "Usage: %s --verify <file> [PARAMETERS]\n"
"\n" "\n"
@@ -139,12 +132,18 @@ static int PrintHelp(char *progname) {
" --pad <number> Verification padding size in bytes\n" " --pad <number> Verification padding size in bytes\n"
" --minversion <number> Minimum combined kernel key version\n" " --minversion <number> Minimum combined kernel key version\n"
" and kernel version\n" " and kernel version\n"
"\n", "\n";
progname);
/* Print help and return error */
static int PrintHelp(char *progname)
{
fprintf(stderr, usage, progname, progname, progname);
return 1; return 1;
} }
static void Debug(const char *format, ...) { static void Debug(const char *format, ...)
{
if (!opt_debug) if (!opt_debug)
return; return;
@@ -155,7 +154,8 @@ static void Debug(const char *format, ...) {
va_end(ap); va_end(ap);
} }
static void Fatal(const char *format, ...) { static void Fatal(const char *format, ...)
{
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
fprintf(stderr, "ERROR: "); fprintf(stderr, "ERROR: ");
@@ -165,7 +165,8 @@ static void Fatal(const char *format, ...) {
} }
/* Return an explanation when fread() fails. */ /* Return an explanation when fread() fails. */
static const char *error_fread(FILE *fp) { static const char *error_fread(FILE * fp)
{
const char *retval = "beats me why"; const char *retval = "beats me why";
if (feof(fp)) if (feof(fp))
retval = "EOF"; retval = "EOF";
@@ -179,24 +180,26 @@ static const char *error_fread(FILE *fp) {
* to or greater than [val]. Used to determine the number of * to or greater than [val]. Used to determine the number of
* pages/sectors/blocks/whatever needed to contain [val] * pages/sectors/blocks/whatever needed to contain [val]
* items/bytes/etc. */ * items/bytes/etc. */
static uint64_t roundup(uint64_t val, uint64_t alignment) { static uint64_t roundup(uint64_t val, uint64_t alignment)
{
uint64_t rem = val % alignment; uint64_t rem = val % alignment;
if (rem) if (rem)
return val + (alignment - rem); return val + (alignment - rem);
return val; return val;
} }
/* Match regexp /\b--\b/ to delimit the start of the kernel commandline. If we /* Match regexp /\b--\b/ to delimit the start of the kernel commandline. If we
* don't find one, we'll use the whole thing. */ * don't find one, we'll use the whole thing. */
static unsigned int find_cmdline_start(char *input, unsigned int max_len) { static unsigned int find_cmdline_start(char *input, unsigned int max_len)
{
int start = 0; int start = 0;
int i; int i;
for (i = 0; i < max_len - 1 && input[i]; i++) { for (i = 0; i < max_len - 1 && input[i]; i++) {
if ('-' == input[i] && '-' == input[i + 1]) { /* found a "--" */ if ('-' == input[i] && '-' == input[i + 1]) {
if ((i == 0 || ' ' == input[i - 1]) && /* nothing before it */ if ((i == 0 || ' ' == input[i - 1]) &&
(i + 2 >= max_len || ' ' == input[i+2])) { /* nothing after it */ (i + 2 >= max_len || ' ' == input[i + 2])) {
start = i+2; /* note: hope there's a trailing '\0' */ /* found "--" with nothing before or after it */
start = i + 2; /* hope for a trailing '\0' */
break; break;
} }
} }
@@ -207,7 +210,6 @@ static unsigned int find_cmdline_start(char *input, unsigned int max_len) {
return start; return start;
} }
/****************************************************************************/ /****************************************************************************/
/* Here are globals containing all the bits & pieces I'm working on. */ /* Here are globals containing all the bits & pieces I'm working on. */
@@ -222,7 +224,6 @@ static uint8_t *g_bootloader_data;
static uint64_t g_bootloader_size; static uint64_t g_bootloader_size;
static uint64_t g_bootloader_address; static uint64_t g_bootloader_address;
/* The individual parts of the verification blob (including the data that /* The individual parts of the verification blob (including the data that
* immediately follows the headers) */ * immediately follows the headers) */
static VbKeyBlockHeader *g_keyblock; static VbKeyBlockHeader *g_keyblock;
@@ -244,7 +245,7 @@ static uint8_t* ReadConfigFile(const char* config_file, uint64_t* config_size)
config_buf = ReadFile(config_file, config_size); config_buf = ReadFile(config_file, config_size);
Debug(" config file size=0x%" PRIx64 "\n", *config_size); Debug(" config file size=0x%" PRIx64 "\n", *config_size);
if (CROS_CONFIG_SIZE <= *config_size) { /* need room for trailing '\0' */ if (CROS_CONFIG_SIZE <= *config_size) { /* room for trailing '\0' */
VbExError("Config file %s is too large (>= %d bytes)\n", VbExError("Config file %s is too large (>= %d bytes)\n",
config_file, CROS_CONFIG_SIZE); config_file, CROS_CONFIG_SIZE);
return NULL; return NULL;
@@ -259,9 +260,9 @@ static uint8_t* ReadConfigFile(const char* config_file, uint64_t* config_size)
return config_buf; return config_buf;
} }
/* Offset of kernel command line string from start of packed kernel blob */ /* Offset of kernel command line string from start of packed kernel blob */
static uint64_t CmdLineOffset(VbKernelPreambleHeader *preamble) { static uint64_t CmdLineOffset(VbKernelPreambleHeader * preamble)
{
return preamble->bootloader_address - preamble->body_load_address - return preamble->bootloader_address - preamble->body_load_address -
CROS_CONFIG_SIZE - CROS_PARAMS_SIZE; CROS_CONFIG_SIZE - CROS_PARAMS_SIZE;
} }
@@ -269,7 +270,8 @@ static uint64_t CmdLineOffset(VbKernelPreambleHeader *preamble) {
/* This initializes g_vmlinuz and g_param from a standard vmlinuz file. /* This initializes g_vmlinuz and g_param from a standard vmlinuz file.
* It returns 0 on error. */ * It returns 0 on error. */
static int ImportVmlinuzFile(const char *vmlinuz_file, arch_t arch, static int ImportVmlinuzFile(const char *vmlinuz_file, arch_t arch,
uint64_t kernel_body_load_address) { uint64_t kernel_body_load_address)
{
uint8_t *kernel_buf; uint8_t *kernel_buf;
uint64_t kernel_size; uint64_t kernel_size;
uint64_t kernel32_start = 0; uint64_t kernel32_start = 0;
@@ -285,21 +287,21 @@ static int ImportVmlinuzFile(const char *vmlinuz_file, arch_t arch,
if (!kernel_size) if (!kernel_size)
Fatal("Empty kernel file\n"); Fatal("Empty kernel file\n");
/* Go ahead and allocate the param region anyway. I don't think we need it /* Go ahead and allocate the param region anyway. I don't think we need
* for non-x86, but let's keep it for now. */ * it for non-x86, but let's keep it for now. */
g_param_size = CROS_PARAMS_SIZE; g_param_size = CROS_PARAMS_SIZE;
g_param_data = VbExMalloc(g_param_size); g_param_data = VbExMalloc(g_param_size);
Memset(g_param_data, 0, g_param_size); Memset(g_param_data, 0, g_param_size);
/* Unless we're handling x86, the kernel is the kernel, so we're done. */ /* Unless we're handling x86, the kernel is the kernel; we're done. */
if (arch != ARCH_X86) { if (arch != ARCH_X86) {
g_kernel_data = kernel_buf; g_kernel_data = kernel_buf;
g_kernel_size = kernel_size; g_kernel_size = kernel_size;
return 1; return 1;
} }
/* The first part of the x86 vmlinuz is a header, followed by a real-mode /* The first part of the x86 vmlinuz is a header, followed by a
* boot stub. We only want the 32-bit part. */ * real-mode boot stub. We only want the 32-bit part. */
lh = (struct linux_kernel_params *)kernel_buf; lh = (struct linux_kernel_params *)kernel_buf;
kernel32_start = (lh->setup_sects + 1) << 9; kernel32_start = (lh->setup_sects + 1) << 9;
if (kernel32_start >= kernel_size) if (kernel32_start >= kernel_size)
@@ -313,11 +315,12 @@ static int ImportVmlinuzFile(const char *vmlinuz_file, arch_t arch,
if (kernel32_size) { if (kernel32_size) {
g_kernel_size = kernel32_size; g_kernel_size = kernel32_size;
g_kernel_data = VbExMalloc(g_kernel_size); g_kernel_data = VbExMalloc(g_kernel_size);
Memcpy(g_kernel_data, kernel_buf + kernel32_start, kernel32_size); Memcpy(g_kernel_data, kernel_buf + kernel32_start,
kernel32_size);
} }
/* Copy the original zeropage data from kernel_buf into g_param_data, then /* Copy the original zeropage data from kernel_buf into g_param_data,
* tweak a few fields for our purposes */ * then tweak a few fields for our purposes */
params = (struct linux_kernel_params *)(g_param_data); params = (struct linux_kernel_params *)(g_param_data);
Memcpy(&(params->setup_sects), &(lh->setup_sects), Memcpy(&(params->setup_sects), &(lh->setup_sects),
offsetof(struct linux_kernel_params, e820_entries) offsetof(struct linux_kernel_params, e820_entries)
@@ -352,7 +355,8 @@ static int ImportVmlinuzFile(const char *vmlinuz_file, arch_t arch,
/* This returns just the kernel blob, with the verification blob separated /* This returns just the kernel blob, with the verification blob separated
* and copied to new memory in g_keyblock and g_preamble. */ * and copied to new memory in g_keyblock and g_preamble. */
static uint8_t *ReadOldBlobFromFileOrDie(const char *filename, static uint8_t *ReadOldBlobFromFileOrDie(const char *filename,
uint64_t* size_ptr) { uint64_t * size_ptr)
{
FILE *fp = NULL; FILE *fp = NULL;
struct stat statbuf; struct stat statbuf;
VbKeyBlockHeader *key_block; VbKeyBlockHeader *key_block;
@@ -383,11 +387,13 @@ static uint8_t* ReadOldBlobFromFileOrDie(const char *filename,
Debug("Reading %s\n", filename); Debug("Reading %s\n", filename);
fp = fopen(filename, "rb"); fp = fopen(filename, "rb");
if (!fp) if (!fp)
Fatal("Unable to open file %s: %s\n", filename, strerror(errno)); Fatal("Unable to open file %s: %s\n", filename,
strerror(errno));
buf = VbExMalloc(opt_pad); buf = VbExMalloc(opt_pad);
if (1 != fread(buf, opt_pad, 1, fp)) if (1 != fread(buf, opt_pad, 1, fp))
Fatal("Unable to read header from %s: %s\n", filename, error_fread(fp)); Fatal("Unable to read header from %s: %s\n", filename,
error_fread(fp));
/* Sanity-check the key_block */ /* Sanity-check the key_block */
key_block = (VbKeyBlockHeader *) buf; key_block = (VbKeyBlockHeader *) buf;
@@ -413,25 +419,28 @@ static uint8_t* ReadOldBlobFromFileOrDie(const char *filename,
opt_pad); opt_pad);
/* LGTM */ /* LGTM */
Debug(" kernel_version = %d\n", preamble->kernel_version); Debug(" kernel_version = %d\n", preamble->kernel_version);
Debug(" bootloader_address = 0x%" PRIx64 "\n", preamble->bootloader_address); Debug(" bootloader_address = 0x%" PRIx64 "\n",
preamble->bootloader_address);
Debug(" bootloader_size = 0x%" PRIx64 "\n", preamble->bootloader_size); Debug(" bootloader_size = 0x%" PRIx64 "\n", preamble->bootloader_size);
Debug(" kern_blob_size = 0x%" PRIx64 "\n", Debug(" kern_blob_size = 0x%" PRIx64 "\n",
preamble->body_signature.data_size); preamble->body_signature.data_size);
g_preamble = (VbKernelPreambleHeader*)VbExMalloc(preamble->preamble_size); g_preamble =
(VbKernelPreambleHeader *) VbExMalloc(preamble->preamble_size);
Memcpy(g_preamble, preamble, preamble->preamble_size); Memcpy(g_preamble, preamble, preamble->preamble_size);
/* Now for the kernel blob */ /* Now for the kernel blob */
Debug("kernel blob is at offset 0x%" PRIx64 "\n", now); Debug("kernel blob is at offset 0x%" PRIx64 "\n", now);
if (0 != fseek(fp, now, SEEK_SET)) if (0 != fseek(fp, now, SEEK_SET))
Fatal("Unable to seek to 0x%" PRIx64 " in %s: %s\n", now, filename, Fatal("Unable to seek to 0x%" PRIx64 " in %s: %s\n", now,
strerror(errno)); filename, strerror(errno));
/* Sanity check */ /* Sanity check */
kernel_blob_size = file_size - now; kernel_blob_size = file_size - now;
if (!kernel_blob_size) if (!kernel_blob_size)
Fatal("No kernel blob found\n"); Fatal("No kernel blob found\n");
if (kernel_blob_size < preamble->body_signature.data_size) if (kernel_blob_size < preamble->body_signature.data_size)
fprintf(stderr, "Warning: kernel file only has 0x%" PRIx64 " bytes\n", fprintf(stderr,
"Warning: kernel file only has 0x%" PRIx64 " bytes\n",
kernel_blob_size); kernel_blob_size);
kernel_blob_data = VbExMalloc(kernel_blob_size); kernel_blob_data = VbExMalloc(kernel_blob_size);
@@ -449,11 +458,11 @@ static uint8_t* ReadOldBlobFromFileOrDie(const char *filename,
return kernel_blob_data; return kernel_blob_data;
} }
/* Split a kernel blob into separate g_kernel, g_param, g_config, and /* Split a kernel blob into separate g_kernel, g_param, g_config, and
* g_bootloader parts. */ * g_bootloader parts. */
static void UnpackKernelBlob(uint8_t * kernel_blob_data, static void UnpackKernelBlob(uint8_t * kernel_blob_data,
uint64_t kernel_blob_size) { uint64_t kernel_blob_size)
{
uint64_t k_blob_size = g_preamble->body_signature.data_size; uint64_t k_blob_size = g_preamble->body_signature.data_size;
uint64_t k_blob_ofs = 0; uint64_t k_blob_ofs = 0;
@@ -487,13 +496,11 @@ static void UnpackKernelBlob(uint8_t *kernel_blob_data,
Memcpy(g_bootloader_data, kernel_blob_data + b_ofs, g_bootloader_size); Memcpy(g_bootloader_data, kernel_blob_data + b_ofs, g_bootloader_size);
} }
/****************************************************************************/ /****************************************************************************/
static uint8_t *CreateKernelBlob(uint64_t kernel_body_load_address, static uint8_t *CreateKernelBlob(uint64_t kernel_body_load_address,
arch_t arch, arch_t arch, uint64_t * size_ptr)
uint64_t *size_ptr) { {
uint8_t *kern_blob; uint8_t *kern_blob;
uint64_t kern_blob_size; uint64_t kern_blob_size;
uint64_t now; uint64_t now;
@@ -543,8 +550,8 @@ static int Pack(const char* outfile,
uint8_t * kernel_blob, uint8_t * kernel_blob,
uint64_t kernel_size, uint64_t kernel_size,
int version, int version,
uint64_t kernel_body_load_address, uint64_t kernel_body_load_address, VbPrivateKey * signpriv_key)
VbPrivateKey* signpriv_key) { {
VbSignature *body_sig; VbSignature *body_sig;
FILE *f; FILE *f;
uint64_t i; uint64_t i;
@@ -559,8 +566,8 @@ static int Pack(const char* outfile,
g_preamble = CreateKernelPreamble(version, g_preamble = CreateKernelPreamble(version,
kernel_body_load_address, kernel_body_load_address,
g_bootloader_address, g_bootloader_address,
roundup(g_bootloader_size, CROS_ALIGN), roundup(g_bootloader_size,
body_sig, CROS_ALIGN), body_sig,
opt_pad - g_keyblock->key_block_size, opt_pad - g_keyblock->key_block_size,
signpriv_key); signpriv_key);
if (!g_preamble) { if (!g_preamble) {
@@ -607,8 +614,8 @@ static int Pack(const char* outfile,
static int Verify(uint8_t * kernel_blob, static int Verify(uint8_t * kernel_blob,
uint64_t kernel_size, uint64_t kernel_size,
VbPublicKey * signpub_key, VbPublicKey * signpub_key,
const char* keyblock_outfile, const char *keyblock_outfile, uint64_t min_version)
uint64_t min_version) { {
VbPublicKey *data_key; VbPublicKey *data_key;
RSAPublicKey *rsa; RSAPublicKey *rsa;
@@ -619,9 +626,12 @@ static int Verify(uint8_t* kernel_blob,
printf("Key block:\n"); printf("Key block:\n");
data_key = &g_keyblock->data_key; data_key = &g_keyblock->data_key;
if (opt_verbose) if (opt_verbose)
printf(" Signature: %s\n", signpub_key ? "valid" : "ignored"); printf(" Signature: %s\n",
printf(" Size: 0x%" PRIx64 "\n", g_keyblock->key_block_size); signpub_key ? "valid" : "ignored");
printf(" Flags: %" PRIu64 " ", g_keyblock->key_block_flags); printf(" Size: 0x%" PRIx64 "\n",
g_keyblock->key_block_size);
printf(" Flags: %" PRIu64 " ",
g_keyblock->key_block_flags);
if (g_keyblock->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_0) if (g_keyblock->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_0)
printf(" !DEV"); printf(" !DEV");
if (g_keyblock->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_1) if (g_keyblock->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_1)
@@ -643,9 +653,11 @@ static int Verify(uint8_t* kernel_blob,
FILE *f = NULL; FILE *f = NULL;
f = fopen(keyblock_outfile, "wb"); f = fopen(keyblock_outfile, "wb");
if (!f) if (!f)
Fatal("Can't open key block file %s\n", keyblock_outfile); Fatal("Can't open key block file %s\n",
keyblock_outfile);
if (1 != fwrite(g_keyblock, g_keyblock->key_block_size, 1, f)) if (1 != fwrite(g_keyblock, g_keyblock->key_block_size, 1, f))
Fatal("Can't write key block file %s\n", keyblock_outfile); Fatal("Can't write key block file %s\n",
keyblock_outfile);
fclose(f); fclose(f);
} }
@@ -659,15 +671,18 @@ static int Verify(uint8_t* kernel_blob,
Fatal("Error parsing data key.\n"); Fatal("Error parsing data key.\n");
/* Verify preamble */ /* Verify preamble */
if (0 != VerifyKernelPreamble( if (0 !=
g_preamble, g_preamble->preamble_size, rsa)) VerifyKernelPreamble(g_preamble, g_preamble->preamble_size, rsa))
Fatal("Error verifying preamble.\n"); Fatal("Error verifying preamble.\n");
printf("Preamble:\n"); printf("Preamble:\n");
printf(" Size: 0x%" PRIx64 "\n", g_preamble->preamble_size); printf(" Size: 0x%" PRIx64 "\n",
g_preamble->preamble_size);
printf(" Header version: %" PRIu32 ".%" PRIu32 "\n", printf(" Header version: %" PRIu32 ".%" PRIu32 "\n",
g_preamble->header_version_major, g_preamble->header_version_minor); g_preamble->header_version_major,
printf(" Kernel version: %" PRIu64 "\n", g_preamble->kernel_version); g_preamble->header_version_minor);
printf(" Kernel version: %" PRIu64 "\n",
g_preamble->kernel_version);
printf(" Body load address: 0x%" PRIx64 "\n", printf(" Body load address: 0x%" PRIx64 "\n",
g_preamble->body_load_address); g_preamble->body_load_address);
printf(" Body size: 0x%" PRIx64 "\n", printf(" Body size: 0x%" PRIx64 "\n",
@@ -678,8 +693,9 @@ static int Verify(uint8_t* kernel_blob,
g_preamble->bootloader_size); g_preamble->bootloader_size);
if (g_preamble->kernel_version < (min_version & 0xFFFF)) if (g_preamble->kernel_version < (min_version & 0xFFFF))
Fatal("Kernel version %" PRIu64 " is lower than minimum %" PRIu64 ".\n", Fatal("Kernel version %" PRIu64 " is lower than minimum %"
g_preamble->kernel_version, (min_version & 0xFFFF)); PRIu64 ".\n", g_preamble->kernel_version,
(min_version & 0xFFFF));
/* Verify body */ /* Verify body */
if (0 != VerifyData(kernel_blob, kernel_size, if (0 != VerifyData(kernel_blob, kernel_size,
@@ -687,16 +703,17 @@ static int Verify(uint8_t* kernel_blob,
Fatal("Error verifying kernel body.\n"); Fatal("Error verifying kernel body.\n");
printf("Body verification succeeded.\n"); printf("Body verification succeeded.\n");
if (opt_verbose) if (opt_verbose)
printf("Config:\n%s\n", kernel_blob + CmdLineOffset(g_preamble)); printf("Config:\n%s\n",
kernel_blob + CmdLineOffset(g_preamble));
return 0; return 0;
} }
/****************************************************************************/ /****************************************************************************/
static int do_vbutil_kernel(int argc, char* argv[]) { static int do_vbutil_kernel(int argc, char *argv[])
{
char *filename = NULL; char *filename = NULL;
char *oldfile = NULL; char *oldfile = NULL;
char *keyblock_file = NULL; char *keyblock_file = NULL;
@@ -743,7 +760,8 @@ static int do_vbutil_kernel(int argc, char* argv[]) {
case OPT_MODE_REPACK: case OPT_MODE_REPACK:
case OPT_MODE_VERIFY: case OPT_MODE_VERIFY:
if (mode && (mode != i)) { if (mode && (mode != i)) {
fprintf(stderr, "Only a single mode can be specified\n"); fprintf(stderr,
"Only one mode can be specified\n");
parse_error = 1; parse_error = 1;
break; break;
} }
@@ -762,7 +780,9 @@ static int do_vbutil_kernel(int argc, char* argv[]) {
else if (!strcasecmp(optarg, "mips")) else if (!strcasecmp(optarg, "mips"))
arch = ARCH_MIPS; arch = ARCH_MIPS;
else { else {
fprintf(stderr, "Unknown architecture string: %s\n", optarg); fprintf(stderr,
"Unknown architecture string: %s\n",
optarg);
parse_error = 1; parse_error = 1;
} }
break; break;
@@ -861,21 +881,25 @@ static int do_vbutil_kernel(int argc, char* argv[]) {
if (config_file) { if (config_file) {
Debug("Reading %s\n", config_file); Debug("Reading %s\n", config_file);
g_config_data = ReadConfigFile(config_file, &g_config_size); g_config_data =
ReadConfigFile(config_file, &g_config_size);
if (!g_config_data) if (!g_config_data)
Fatal("Error reading config file.\n"); Fatal("Error reading config file.\n");
} }
if (vmlinuz_file) if (vmlinuz_file)
if (!ImportVmlinuzFile(vmlinuz_file, arch, kernel_body_load_address)) if (!ImportVmlinuzFile
(vmlinuz_file, arch, kernel_body_load_address))
Fatal("Error reading kernel file.\n"); Fatal("Error reading kernel file.\n");
if (bootloader_file) { if (bootloader_file) {
Debug("Reading %s\n", bootloader_file); Debug("Reading %s\n", bootloader_file);
g_bootloader_data = ReadFile(bootloader_file, &g_bootloader_size); g_bootloader_data =
ReadFile(bootloader_file, &g_bootloader_size);
if (!g_bootloader_data) if (!g_bootloader_data)
Fatal("Error reading bootloader file.\n"); Fatal("Error reading bootloader file.\n");
Debug(" bootloader file size=0x%" PRIx64 "\n", g_bootloader_size); Debug(" bootloader file size=0x%" PRIx64 "\n",
g_bootloader_size);
} }
/* Do it */ /* Do it */
@@ -884,8 +908,7 @@ static int do_vbutil_kernel(int argc, char* argv[]) {
&kernel_size); &kernel_size);
return Pack(filename, kernel_blob, kernel_size, return Pack(filename, kernel_blob, kernel_size,
version, kernel_body_load_address, version, kernel_body_load_address, signpriv_key);
signpriv_key);
case OPT_MODE_REPACK: case OPT_MODE_REPACK:
@@ -918,13 +941,15 @@ static int do_vbutil_kernel(int argc, char* argv[]) {
version = g_preamble->kernel_version; version = g_preamble->kernel_version;
if (!address_str) if (!address_str)
kernel_body_load_address = g_preamble->body_load_address; kernel_body_load_address =
g_preamble->body_load_address;
if (config_file) { if (config_file) {
if (g_config_data) if (g_config_data)
free(g_config_data); free(g_config_data);
Debug("Reading %s\n", config_file); Debug("Reading %s\n", config_file);
g_config_data = ReadConfigFile(config_file, &g_config_size); g_config_data =
ReadConfigFile(config_file, &g_config_size);
if (!g_config_data) if (!g_config_data)
Fatal("Error reading config file.\n"); Fatal("Error reading config file.\n");
} }
@@ -932,7 +957,8 @@ static int do_vbutil_kernel(int argc, char* argv[]) {
if (keyblock_file) { if (keyblock_file) {
if (g_keyblock) if (g_keyblock)
free(g_keyblock); free(g_keyblock);
g_keyblock = (VbKeyBlockHeader*)ReadFile(keyblock_file, 0); g_keyblock =
(VbKeyBlockHeader *) ReadFile(keyblock_file, 0);
if (!g_keyblock) if (!g_keyblock)
Fatal("Error reading key block.\n"); Fatal("Error reading key block.\n");
} }
@@ -943,9 +969,7 @@ static int do_vbutil_kernel(int argc, char* argv[]) {
&kernel_size); &kernel_size);
return Pack(filename, kernel_blob, kernel_size, return Pack(filename, kernel_blob, kernel_size,
version, kernel_body_load_address, version, kernel_body_load_address, signpriv_key);
signpriv_key);
case OPT_MODE_VERIFY: case OPT_MODE_VERIFY:
@@ -965,7 +989,8 @@ static int do_vbutil_kernel(int argc, char* argv[]) {
keyblock_file, min_version); keyblock_file, min_version);
} }
fprintf(stderr, "You must specify a mode: --pack, --repack or --verify\n"); fprintf(stderr,
"You must specify a mode: --pack, --repack or --verify\n");
return PrintHelp(progname); return PrintHelp(progname);
} }

View File

@@ -18,7 +18,6 @@
#include "util_misc.h" #include "util_misc.h"
#include "vboot_common.h" #include "vboot_common.h"
/* Command line options */ /* Command line options */
enum { enum {
OPT_INKEY = 1000, OPT_INKEY = 1000,
@@ -39,9 +38,9 @@ static const struct option long_opts[] = {
{NULL, 0, 0, 0} {NULL, 0, 0, 0}
}; };
/* Print help and return error */ /* Print help and return error */
static int PrintHelp(char *progname) { static int PrintHelp(char *progname)
{
int i; int i;
fprintf(stderr, fprintf(stderr,
@@ -56,8 +55,7 @@ static int PrintHelp(char *progname) {
"(required for .keyb,\n" "(required for .keyb,\n"
" ignored for .pem)\n" " ignored for .pem)\n"
" --algorithm <number> " " --algorithm <number> "
"Signing algorithm to use with key:\n", "Signing algorithm to use with key:\n", progname);
progname);
for (i = 0; i < kNumAlgorithms; i++) { for (i = 0; i < kNumAlgorithms; i++) {
fprintf(stderr, fprintf(stderr,
@@ -71,16 +69,15 @@ static int PrintHelp(char *progname) {
"\n" "\n"
" Optional parameters:\n" " Optional parameters:\n"
" --copyto <file> " " --copyto <file> "
"Write a copy of the key to this file.\n" "Write a copy of the key to this file.\n" "\n", progname);
"\n",
progname);
return 1; return 1;
} }
/* Pack a .keyb file into a .vbpubk, or a .pem into a .vbprivk */ /* Pack a .keyb file into a .vbpubk, or a .pem into a .vbprivk */
static int Pack(const char *infile, const char *outfile, uint64_t algorithm, static int Pack(const char *infile, const char *outfile, uint64_t algorithm,
uint64_t version) { uint64_t version)
{
VbPublicKey *pubkey; VbPublicKey *pubkey;
VbPrivateKey *privkey; VbPrivateKey *privkey;
@@ -111,9 +108,9 @@ static int Pack(const char *infile, const char *outfile, uint64_t algorithm,
return 1; return 1;
} }
/* Unpack a .vbpubk or .vbprivk */ /* Unpack a .vbpubk or .vbprivk */
static int Unpack(const char *infile, const char *outfile) { static int Unpack(const char *infile, const char *outfile)
{
VbPublicKey *pubkey; VbPublicKey *pubkey;
VbPrivateKey *privkey; VbPrivateKey *privkey;
@@ -133,7 +130,8 @@ static int Unpack(const char *infile, const char *outfile) {
printf("\n"); printf("\n");
if (outfile) { if (outfile) {
if (0 != PublicKeyWrite(outfile, pubkey)) { if (0 != PublicKeyWrite(outfile, pubkey)) {
fprintf(stderr, "vbutil_key: Error writing key copy.\n"); fprintf(stderr,
"vbutil_key: Error writing key copy\n");
free(pubkey); free(pubkey);
return 1; return 1;
} }
@@ -144,12 +142,16 @@ static int Unpack(const char *infile, const char *outfile) {
if ((privkey = PrivateKeyRead(infile))) { if ((privkey = PrivateKeyRead(infile))) {
printf("Private Key file: %s\n", infile); printf("Private Key file: %s\n", infile);
printf("Algorithm: %" PRIu64 " %s\n", privkey->algorithm, printf("Algorithm: %" PRIu64 " %s\n",
(privkey->algorithm < kNumAlgorithms ? privkey->algorithm,
algo_strings[privkey->algorithm] : "(invalid)")); (privkey->algorithm <
kNumAlgorithms ? algo_strings[privkey->
algorithm] :
"(invalid)"));
if (outfile) { if (outfile) {
if (0 != PrivateKeyWrite(outfile, privkey)) { if (0 != PrivateKeyWrite(outfile, privkey)) {
fprintf(stderr, "vbutil_key: Error writing key copy.\n"); fprintf(stderr,
"vbutil_key: Error writing key copy\n");
free(privkey); free(privkey);
return 1; return 1;
} }
@@ -158,12 +160,13 @@ static int Unpack(const char *infile, const char *outfile) {
return 0; return 0;
} }
VbExError("Unable to parse either .vbpubk or vbprivk from %s\n", infile); VbExError("Unable to parse either .vbpubk or vbprivk from %s\n",
infile);
return 1; return 1;
} }
static int do_vbutil_key(int argc, char *argv[])
static int do_vbutil_key(int argc, char* argv[]) { {
char *infile = NULL; char *infile = NULL;
char *outfile = NULL; char *outfile = NULL;

View File

@@ -17,7 +17,6 @@
#include "util_misc.h" #include "util_misc.h"
#include "vboot_common.h" #include "vboot_common.h"
/* Command line options */ /* Command line options */
enum { enum {
OPT_MODE_PACK = 1000, OPT_MODE_PACK = 1000,
@@ -44,10 +43,7 @@ static const struct option long_opts[] = {
{NULL, 0, 0, 0} {NULL, 0, 0, 0}
}; };
static const char usage[] =
/* Print help and return error */
static int PrintHelp(char *progname) {
fprintf(stderr,
"Verified boot key block utility\n" "Verified boot key block utility\n"
"\n" "\n"
"Usage: %s <--pack|--unpack> <file> [OPTIONS]\n" "Usage: %s <--pack|--unpack> <file> [OPTIONS]\n"
@@ -74,8 +70,12 @@ static int PrintHelp(char *progname) {
" Signing public key in .vbpubk format. This is required to\n" " Signing public key in .vbpubk format. This is required to\n"
" verify a signed keyblock.\n" " verify a signed keyblock.\n"
" --datapubkey <file>" " --datapubkey <file>"
" Write the data public key to this file.\n", " Write the data public key to this file.\n";
progname);
/* Print help and return error */
static int PrintHelp(char *progname)
{
fprintf(stderr, usage, progname);
return 1; return 1;
} }
@@ -83,18 +83,20 @@ static int PrintHelp(char *progname) {
static int Pack(const char *outfile, const char *datapubkey, static int Pack(const char *outfile, const char *datapubkey,
const char *signprivate, const char *signprivate,
const char *signprivate_pem, uint64_t pem_algorithm, const char *signprivate_pem, uint64_t pem_algorithm,
uint64_t flags, uint64_t flags, const char *external_signer)
const char* external_signer) { {
VbPublicKey *data_key; VbPublicKey *data_key;
VbPrivateKey *signing_key = NULL; VbPrivateKey *signing_key = NULL;
VbKeyBlockHeader *block; VbKeyBlockHeader *block;
if (!outfile) { if (!outfile) {
fprintf(stderr, "vbutil_keyblock: Must specify output filename.\n"); fprintf(stderr,
"vbutil_keyblock: Must specify output filename.\n");
return 1; return 1;
} }
if (!datapubkey) { if (!datapubkey) {
fprintf(stderr, "vbutil_keyblock: Must specify data public key.\n"); fprintf(stderr,
"vbutil_keyblock: Must specify data public key.\n");
return 1; return 1;
} }
@@ -106,20 +108,23 @@ static int Pack(const char* outfile, const char* datapubkey,
if (signprivate_pem) { if (signprivate_pem) {
if (pem_algorithm >= kNumAlgorithms) { if (pem_algorithm >= kNumAlgorithms) {
fprintf(stderr, "vbutil_keyblock: Invalid --pem_algorithm %" PRIu64 "\n", fprintf(stderr,
pem_algorithm); "vbutil_keyblock: Invalid --pem_algorithm %"
PRIu64 "\n", pem_algorithm);
return 1; return 1;
} }
if (external_signer) { if (external_signer) {
/* External signing uses the PEM file directly. */ /* External signing uses the PEM file directly. */
block = KeyBlockCreate_external(data_key, block = KeyBlockCreate_external(data_key,
signprivate_pem, pem_algorithm, signprivate_pem,
flags, pem_algorithm, flags,
external_signer); external_signer);
} else { } else {
signing_key = PrivateKeyReadPem(signprivate_pem, pem_algorithm); signing_key =
PrivateKeyReadPem(signprivate_pem, pem_algorithm);
if (!signing_key) { if (!signing_key) {
fprintf(stderr, "vbutil_keyblock: Error reading signing key.\n"); fprintf(stderr, "vbutil_keyblock:"
" Error reading signing key.\n");
return 1; return 1;
} }
block = KeyBlockCreate(data_key, signing_key, flags); block = KeyBlockCreate(data_key, signing_key, flags);
@@ -128,7 +133,8 @@ static int Pack(const char* outfile, const char* datapubkey,
if (signprivate) { if (signprivate) {
signing_key = PrivateKeyRead(signprivate); signing_key = PrivateKeyRead(signprivate);
if (!signing_key) { if (!signing_key) {
fprintf(stderr, "vbutil_keyblock: Error reading signing key.\n"); fprintf(stderr, "vbutil_keyblock:"
" Error reading signing key.\n");
return 1; return 1;
} }
} }
@@ -148,7 +154,8 @@ static int Pack(const char* outfile, const char* datapubkey,
} }
static int Unpack(const char *infile, const char *datapubkey, static int Unpack(const char *infile, const char *datapubkey,
const char* signpubkey) { const char *signpubkey)
{
VbPublicKey *data_key; VbPublicKey *data_key;
VbPublicKey *sign_key = NULL; VbPublicKey *sign_key = NULL;
VbKeyBlockHeader *block; VbKeyBlockHeader *block;
@@ -164,16 +171,19 @@ static int Unpack(const char* infile, const char* datapubkey,
return 1; return 1;
} }
/* If the block is signed, then verify it with the signing public key, since /* If the block is signed, then verify it with the signing public key,
KeyBlockRead() only verified the hash. */ * since KeyBlockRead() only verified the hash. */
if (block->key_block_signature.sig_size && signpubkey) { if (block->key_block_signature.sig_size && signpubkey) {
sign_key = PublicKeyRead(signpubkey); sign_key = PublicKeyRead(signpubkey);
if (!sign_key) { if (!sign_key) {
fprintf(stderr, "vbutil_keyblock: Error reading signpubkey.\n"); fprintf(stderr,
"vbutil_keyblock: Error reading signpubkey.\n");
return 1; return 1;
} }
if (0 != KeyBlockVerify(block, block->key_block_size, sign_key, 0)) { if (0 !=
fprintf(stderr, "vbutil_keyblock: Error verifying key block.\n"); KeyBlockVerify(block, block->key_block_size, sign_key, 0)) {
fprintf(stderr, "vbutil_keyblock:"
" Error verifying key block.\n");
return 1; return 1;
} }
free(sign_key); free(sign_key);
@@ -203,8 +213,8 @@ static int Unpack(const char* infile, const char* datapubkey,
if (datapubkey) { if (datapubkey) {
if (0 != PublicKeyWrite(datapubkey, data_key)) { if (0 != PublicKeyWrite(datapubkey, data_key)) {
fprintf(stderr, fprintf(stderr, "vbutil_keyblock:"
"vbutil_keyblock: unable to write public key\n"); " unable to write public key\n");
return 1; return 1;
} }
} }
@@ -213,8 +223,8 @@ static int Unpack(const char* infile, const char* datapubkey,
return 0; return 0;
} }
static int do_vbutil_keyblock(int argc, char *argv[])
static int do_vbutil_keyblock(int argc, char* argv[]) { {
char *filename = NULL; char *filename = NULL;
char *datapubkey = NULL; char *datapubkey = NULL;
@@ -292,18 +302,21 @@ static int do_vbutil_keyblock(int argc, char* argv[]) {
/* Check if the right combination of options was provided. */ /* Check if the right combination of options was provided. */
if (signprivate && signprivate_pem) { if (signprivate && signprivate_pem) {
fprintf(stderr, "Only one of --signprivate or --signprivate_pem must" fprintf(stderr,
"Only one of --signprivate or --signprivate_pem must"
" be specified\n"); " be specified\n");
parse_error = 1; parse_error = 1;
} }
if (signprivate_pem && !is_pem_algorithm) { if (signprivate_pem && !is_pem_algorithm) {
fprintf(stderr, "--pem_algorithm must be used with --signprivate_pem\n"); fprintf(stderr, "--pem_algorithm must be used with"
" --signprivate_pem\n");
parse_error = 1; parse_error = 1;
} }
if (external_signer && !signprivate_pem) { if (external_signer && !signprivate_pem) {
fprintf(stderr, "--externalsigner must be used with --signprivate_pem" fprintf(stderr,
"--externalsigner must be used with --signprivate_pem"
"\n"); "\n");
parse_error = 1; parse_error = 1;
} }
@@ -315,8 +328,7 @@ static int do_vbutil_keyblock(int argc, char* argv[]) {
case OPT_MODE_PACK: case OPT_MODE_PACK:
return Pack(filename, datapubkey, signprivate, return Pack(filename, datapubkey, signprivate,
signprivate_pem, pem_algorithm, signprivate_pem, pem_algorithm,
flags, flags, external_signer);
external_signer);
case OPT_MODE_UNPACK: case OPT_MODE_UNPACK:
return Unpack(filename, datapubkey, signpubkey); return Unpack(filename, datapubkey, signpubkey);
default: default:

View File

@@ -15,7 +15,8 @@
#include "vboot_host.h" #include "vboot_host.h"
static uint8_t *GetKernelConfig(uint8_t * blob, size_t blob_size, static uint8_t *GetKernelConfig(uint8_t * blob, size_t blob_size,
uint64_t kernel_body_load_address) { uint64_t kernel_body_load_address)
{
VbKeyBlockHeader *key_block; VbKeyBlockHeader *key_block;
VbKernelPreambleHeader *preamble; VbKernelPreambleHeader *preamble;
@@ -38,24 +39,27 @@ static uint8_t* GetKernelConfig(uint8_t* blob, size_t blob_size,
return NULL; return NULL;
} }
/* Read body_load_address from preamble if no kernel_body_load_address */ /* Read body_load_address from preamble if no
* kernel_body_load_address */
if (kernel_body_load_address == USE_PREAMBLE_LOAD_ADDR) if (kernel_body_load_address == USE_PREAMBLE_LOAD_ADDR)
kernel_body_load_address = preamble->body_load_address; kernel_body_load_address = preamble->body_load_address;
/* The x86 kernels have a pointer to the kernel commandline in the zeropage /* The x86 kernels have a pointer to the kernel commandline in the
* table, but that's irrelevant for ARM. Both types keep the config blob in * zeropage table, but that's irrelevant for ARM. Both types keep the
* the same place, so just go find it. */ * config blob in the same place, so just go find it. */
offset = preamble->bootloader_address - offset = preamble->bootloader_address -
(kernel_body_load_address + CROS_PARAMS_SIZE + (kernel_body_load_address + CROS_PARAMS_SIZE +
CROS_CONFIG_SIZE) + now; CROS_CONFIG_SIZE) + now;
if (offset > blob_size) { if (offset > blob_size) {
VbExError("params are outside of the memory blob: %x\n", offset); VbExError("params are outside of the memory blob: %x\n",
offset);
return NULL; return NULL;
} }
return blob + offset; return blob + offset;
} }
static void* MMapFile(const char* filename, size_t *size) { static void *MMapFile(const char *filename, size_t * size)
{
FILE *f; FILE *f;
uint8_t *buf; uint8_t *buf;
long file_size = 0; long file_size = 0;
@@ -88,7 +92,6 @@ static void* MMapFile(const char* filename, size_t *size) {
return buf; return buf;
} }
char *FindKernelConfig(const char *infile, uint64_t kernel_body_load_address) char *FindKernelConfig(const char *infile, uint64_t kernel_body_load_address)
{ {
uint8_t *blob; uint8_t *blob;

View File

@@ -64,6 +64,7 @@ static int do_help(int argc, char *argv[])
return 0; return 0;
} }
DECLARE_FUTIL_COMMAND(help, do_help, DECLARE_FUTIL_COMMAND(help, do_help,
"Show a bit of help (you're looking at it)"); "Show a bit of help (you're looking at it)");
@@ -209,7 +210,6 @@ static void log_args(int argc, char *argv[])
log_close(); log_close();
} }
/******************************************************************************/ /******************************************************************************/
/* Here we go */ /* Here we go */

View File

@@ -1,29 +1,28 @@
// Copyright 2010 The Chromium OS Authors. All rights reserved. /* Copyright 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be * Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. * found in the LICENSE file.
// *
// Constants describing the kernel blob content. * Constants describing the kernel blob content.
*/
#ifndef VBOOT_REFERENCE_KERNEL_BLOB_H_ #ifndef VBOOT_REFERENCE_KERNEL_BLOB_H_
#define VBOOT_REFERENCE_KERNEL_BLOB_H_ #define VBOOT_REFERENCE_KERNEL_BLOB_H_
/* Maximum kernel command-line size */
// Maximum kernel command-line size
#define CROS_CONFIG_SIZE 4096 #define CROS_CONFIG_SIZE 4096
// Size of the x86 zeropage table /* Size of the x86 zeropage table */
#define CROS_PARAMS_SIZE 4096 #define CROS_PARAMS_SIZE 4096
// Alignment of various chunks within the kernel blob /* Alignment of various chunks within the kernel blob */
#define CROS_ALIGN 4096 #define CROS_ALIGN 4096
// Sentinel RAM address indicating that no entry address is specified /* Sentinel RAM address indicating that no entry address is specified */
#define CROS_NO_ENTRY_ADDR (~0) #define CROS_NO_ENTRY_ADDR (~0)
// RAM address where the 32-bit kernel expects to be started /* RAM address where the 32-bit kernel expects to be started */
#define CROS_32BIT_ENTRY_ADDR 0x100000 #define CROS_32BIT_ENTRY_ADDR 0x100000
// Simplified version of x86 kernel e820 memory map entries /* Simplified version of x86 kernel e820 memory map entries */
#define E820_ENTRY_MAX 128 #define E820_ENTRY_MAX 128
#define E820_TYPE_RAM 1 #define E820_TYPE_RAM 1
#define E820_TYPE_RESERVED 2 #define E820_TYPE_RESERVED 2
@@ -34,32 +33,30 @@ struct linux_kernel_e820entry {
uint32_t segment_type; uint32_t segment_type;
} __attribute__ ((packed)); } __attribute__ ((packed));
// Simplified version of the x86 kernel zeropage table /* Simplified version of the x86 kernel zeropage table */
struct linux_kernel_params struct linux_kernel_params {
{
uint8_t pad0[0x1e8 - 0x0]; uint8_t pad0[0x1e8 - 0x0];
uint8_t n_e820_entry; // 1e8 uint8_t n_e820_entry; /* 1e8 */
uint8_t pad1[0x1f1 - 0x1e9]; uint8_t pad1[0x1f1 - 0x1e9];
uint8_t setup_sects; // 1f1 uint8_t setup_sects; /* 1f1 */
uint8_t pad2[0x1fe - 0x1f2]; uint8_t pad2[0x1fe - 0x1f2];
uint16_t boot_flag; // 1fe uint16_t boot_flag; /* 1fe */
uint16_t jump; // 200 uint16_t jump; /* 200 */
uint32_t header; // 202 uint32_t header; /* 202 */
uint16_t version; // 206 uint16_t version; /* 206 */
uint8_t pad3[0x210 - 0x208]; uint8_t pad3[0x210 - 0x208];
uint8_t type_of_loader; // 210 uint8_t type_of_loader; /* 210 */
uint8_t pad4[0x218 - 0x211]; uint8_t pad4[0x218 - 0x211];
uint32_t ramdisk_image; // 218 uint32_t ramdisk_image; /* 218 */
uint32_t ramdisk_size; // 21c uint32_t ramdisk_size; /* 21c */
uint8_t pad5[0x228 - 0x220]; uint8_t pad5[0x228 - 0x220];
uint32_t cmd_line_ptr; // 228 uint32_t cmd_line_ptr; /* 228 */
uint32_t ramdisk_max; // 22c uint32_t ramdisk_max; /* 22c */
uint32_t kernel_alignment; // 230 uint32_t kernel_alignment; /* 230 */
uint8_t relocatable_kernel; // 234 uint8_t relocatable_kernel; /* 234 */
uint8_t min_alignment; // 235 uint8_t min_alignment; /* 235 */
uint8_t pad6[0x2d0 - 0x236]; uint8_t pad6[0x2d0 - 0x236];
struct linux_kernel_e820entry e820_entries[E820_ENTRY_MAX]; // 2d0 - cd0 struct linux_kernel_e820entry e820_entries[E820_ENTRY_MAX]; /* 2d0-cd0 */
} __attribute__ ((packed)); } __attribute__ ((packed));
#endif /* VBOOT_REFERENCE_KERNEL_BLOB_H_ */
#endif // VBOOT_REFERENCE_KERNEL_BLOB_H_