summaryrefslogtreecommitdiff
path: root/futility
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2015-03-26 16:34:28 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-03-31 06:28:18 +0000
commit1e35c3a51176edbe924acb8b9bcb68ae7b155ab4 (patch)
tree49d1af5d7f0592481e78e87d614d3735c852d16f /futility
parent453ecd19560af8efe3e518ba745dc6e8bfecac90 (diff)
downloadvboot-1e35c3a51176edbe924acb8b9bcb68ae7b155ab4.tar.gz
futility: export options for the sign and show commands
This declares the options for the sign and show commands in a header file. We want to split the code for logically separate file types into separate source files, but we don't want to have multiple option-parsing routines, so that we can be sure we're using the same option names consistently (for example, --hash_alg always takes the same args and means the same thing). BUG=chromium:231574 BRANCH=none TEST=make runtests Signed-off-by: Bill Richardson <wfrichar@chromium.org> Change-Id: I939bd19ba199b4c44eb41cff3571cff88df9a181 Reviewed-on: https://chromium-review.googlesource.com/262896 Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'futility')
-rw-r--r--futility/cmd_show.c77
-rw-r--r--futility/cmd_sign.c373
-rw-r--r--futility/futility_options.h59
3 files changed, 277 insertions, 232 deletions
diff --git a/futility/cmd_show.c b/futility/cmd_show.c
index f00f2224..714b0e58 100644
--- a/futility/cmd_show.c
+++ b/futility/cmd_show.c
@@ -24,6 +24,7 @@
#include "file_type.h"
#include "fmap.h"
#include "futility.h"
+#include "futility_options.h"
#include "gbb_header.h"
#include "host_common.h"
#include "traversal.h"
@@ -31,16 +32,8 @@
#include "vb1_helper.h"
#include "vboot_common.h"
-/* Local structure for args, etc. */
-static struct local_data_s {
- VbPublicKey *k;
- uint8_t *fv;
- uint64_t fv_size;
- uint32_t padding;
- int strict;
- int t_flag;
- enum futil_file_type type;
-} option = {
+/* Options */
+struct show_option_s show_option = {
.padding = 65536,
.type = FILE_TYPE_UNKNOWN,
};
@@ -278,7 +271,7 @@ int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data)
int ft_show_keyblock(const char *name, uint8_t *buf, uint32_t len, void *data)
{
VbKeyBlockHeader *block = (VbKeyBlockHeader *)buf;
- VbPublicKey *sign_key = option.k;
+ VbPublicKey *sign_key = show_option.k;
int good_sig = 0;
int retval = 0;
@@ -293,7 +286,7 @@ int ft_show_keyblock(const char *name, uint8_t *buf, uint32_t len, void *data)
KeyBlockVerify(block, len, sign_key, 0))
good_sig = 1;
- if (option.strict && (!sign_key || !good_sig))
+ if (show_option.strict && (!sign_key || !good_sig))
retval = 1;
show_keyblock(block, name, !!sign_key, good_sig);
@@ -333,9 +326,9 @@ int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len,
{
VbKeyBlockHeader *key_block = (VbKeyBlockHeader *)buf;
struct show_state_s *state = (struct show_state_s *)data;
- VbPublicKey *sign_key = option.k;
- uint8_t *fv_data = option.fv;
- uint64_t fv_size = option.fv_size;
+ VbPublicKey *sign_key = show_option.k;
+ uint8_t *fv_data = show_option.fv;
+ uint64_t fv_size = show_option.fv_size;
struct bios_area_s *fw_body_area = 0;
int good_sig = 0;
int retval = 0;
@@ -371,7 +364,7 @@ int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len,
show_keyblock(key_block, name, !!sign_key, good_sig);
- if (option.strict && (!sign_key || !good_sig))
+ if (show_option.strict && (!sign_key || !good_sig))
retval = 1;
RSAPublicKey *rsa = PublicKeyToRSA(&key_block->data_key);
@@ -428,7 +421,7 @@ int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len,
if (!fv_data) {
printf("No firmware body available to verify.\n");
- if (option.strict)
+ if (show_option.strict)
return 1;
return 0;
}
@@ -449,7 +442,7 @@ done:
state->area[state->c].is_valid = 1;
} else {
printf("Seems legit, but the signature is unverified.\n");
- if (option.strict)
+ if (show_option.strict)
retval = 1;
}
@@ -509,7 +502,7 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len,
void *data)
{
VbKeyBlockHeader *key_block = (VbKeyBlockHeader *)buf;
- VbPublicKey *sign_key = option.k;
+ VbPublicKey *sign_key = show_option.k;
uint8_t *kernel_blob = 0;
uint64_t kernel_size = 0;
int good_sig = 0;
@@ -532,7 +525,7 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len,
printf("Kernel partition: %s\n", name);
show_keyblock(key_block, NULL, !!sign_key, good_sig);
- if (option.strict && (!sign_key || !good_sig))
+ if (show_option.strict && (!sign_key || !good_sig))
retval = 1;
RSAPublicKey *rsa = PublicKeyToRSA(&key_block->data_key);
@@ -586,14 +579,14 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len,
printf(" Flags: 0x%" PRIx32 "\n", flags);
/* Verify kernel body */
- if (option.fv) {
+ if (show_option.fv) {
/* It's in a separate file, which we've already read in */
- kernel_blob = option.fv;
- kernel_size = option.fv_size;
- } else if (len > option.padding) {
+ kernel_blob = show_option.fv;
+ kernel_size = show_option.fv_size;
+ } else if (len > show_option.padding) {
/* It should be at an offset within the input file. */
- kernel_blob = buf + option.padding;
- kernel_size = len - option.padding;
+ kernel_blob = buf + show_option.padding;
+ kernel_size = len - show_option.padding;
}
if (!kernel_blob) {
@@ -661,7 +654,7 @@ static const struct option long_opts[] = {
{"fv", 1, 0, 'f'},
{"pad", 1, NULL, OPT_PADDING},
{"type", 1, NULL, OPT_TYPE},
- {"strict", 0, &option.strict, 1},
+ {"strict", 0, &show_option.strict, 1},
{"help", 0, NULL, OPT_HELP},
{NULL, 0, NULL, 0},
};
@@ -712,25 +705,26 @@ static int do_show(int argc, char *argv[])
while ((i = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) {
switch (i) {
case 'f':
- option.fv = ReadFile(optarg, &option.fv_size);
- if (!option.fv) {
+ show_option.fv = ReadFile(optarg,
+ &show_option.fv_size);
+ if (!show_option.fv) {
fprintf(stderr, "Error reading %s: %s\n",
optarg, strerror(errno));
errorcnt++;
}
break;
case 'k':
- option.k = PublicKeyRead(optarg);
- if (!option.k) {
+ show_option.k = PublicKeyRead(optarg);
+ if (!show_option.k) {
fprintf(stderr, "Error reading %s\n", optarg);
errorcnt++;
}
break;
case 't':
- option.t_flag = 1;
+ show_option.t_flag = 1;
break;
case OPT_PADDING:
- option.padding = strtoul(optarg, &e, 0);
+ show_option.padding = strtoul(optarg, &e, 0);
if (!*optarg || (e && *e)) {
fprintf(stderr,
"Invalid --padding \"%s\"\n", optarg);
@@ -738,7 +732,8 @@ static int do_show(int argc, char *argv[])
}
break;
case OPT_TYPE:
- if (!futil_str_to_file_type(optarg, &option.type)) {
+ if (!futil_str_to_file_type(optarg,
+ &show_option.type)) {
if (!strcasecmp("help", optarg))
print_file_types_and_exit(errorcnt);
fprintf(stderr,
@@ -781,7 +776,7 @@ static int do_show(int argc, char *argv[])
return 1;
}
- if (option.t_flag) {
+ if (show_option.t_flag) {
for (i = optind; i < argc; i++)
errorcnt += show_type(argv[i]);
goto done;
@@ -804,7 +799,7 @@ static int do_show(int argc, char *argv[])
/* Allow the user to override the type */
if (type_override)
- type = option.type;
+ type = show_option.type;
else
type = futil_file_type_buf(buf, len);
@@ -820,10 +815,10 @@ boo:
}
done:
- if (option.k)
- free(option.k);
- if (option.fv)
- free(option.fv);
+ if (show_option.k)
+ free(show_option.k);
+ if (show_option.fv)
+ free(show_option.fv);
return !!errorcnt;
}
@@ -833,7 +828,7 @@ DECLARE_FUTIL_COMMAND(show, do_show, VBOOT_VERSION_ALL,
static int do_verify(int argc, char *argv[])
{
- option.strict = 1;
+ show_option.strict = 1;
return do_show(argc, argv);
}
diff --git a/futility/cmd_sign.c b/futility/cmd_sign.c
index 98a197e0..3020215c 100644
--- a/futility/cmd_sign.c
+++ b/futility/cmd_sign.c
@@ -21,6 +21,7 @@
#include "file_type.h"
#include "fmap.h"
#include "futility.h"
+#include "futility_options.h"
#include "gbb_header.h"
#include "host_common.h"
#include "kernel_blob.h"
@@ -29,36 +30,8 @@
#include "vb1_helper.h"
#include "vboot_common.h"
-/* Local structure for args, etc. */
-static struct local_data_s {
- VbPrivateKey *signprivate;
- VbKeyBlockHeader *keyblock;
- VbPublicKey *kernel_subkey;
- VbPrivateKey *devsignprivate;
- VbKeyBlockHeader *devkeyblock;
- uint32_t version;
- int version_specified;
- uint32_t flags;
- int flags_specified;
- char *loemdir;
- char *loemid;
- uint8_t *bootloader_data;
- uint64_t bootloader_size;
- uint8_t *config_data;
- uint64_t config_size;
- enum arch_t arch;
- int fv_specified;
- uint32_t kloadaddr;
- uint32_t padding;
- int vblockonly;
- char *outfile;
- int create_new_outfile;
- char *pem_signpriv;
- int pem_algo_specified;
- uint32_t pem_algo;
- char *pem_external;
- enum futil_file_type type;
-} option = {
+/* Options */
+struct sign_option_s sign_option = {
.version = 1,
.arch = ARCH_UNSPECIFIED,
.kloadaddr = CROS_32BIT_ENTRY_ADDR,
@@ -66,7 +39,6 @@ static struct local_data_s {
.type = FILE_TYPE_UNKNOWN,
};
-
/* Helper to complain about invalid args. Returns num errors discovered */
static int no_opt_if(int expr, const char *optname)
{
@@ -118,34 +90,36 @@ int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data)
VbPublicKey *data_key = (VbPublicKey *)buf;
VbKeyBlockHeader *vblock;
- if (option.pem_signpriv) {
- if (option.pem_external) {
+ if (sign_option.pem_signpriv) {
+ if (sign_option.pem_external) {
/* External signing uses the PEM file directly. */
vblock = KeyBlockCreate_external(
data_key,
- option.pem_signpriv,
- option.pem_algo, option.flags,
- option.pem_external);
+ sign_option.pem_signpriv,
+ sign_option.pem_algo, sign_option.flags,
+ sign_option.pem_external);
} else {
- option.signprivate = PrivateKeyReadPem(
- option.pem_signpriv, option.pem_algo);
- if (!option.signprivate) {
+ sign_option.signprivate = PrivateKeyReadPem(
+ sign_option.pem_signpriv,
+ sign_option.pem_algo);
+ if (!sign_option.signprivate) {
fprintf(stderr,
"Unable to read PEM signing key: %s\n",
strerror(errno));
return 1;
}
- vblock = KeyBlockCreate(data_key, option.signprivate,
- option.flags);
+ vblock = KeyBlockCreate(data_key,
+ sign_option.signprivate,
+ sign_option.flags);
}
} else {
/* Not PEM. Should already have a signing key. */
- vblock = KeyBlockCreate(data_key, option.signprivate,
- option.flags);
+ vblock = KeyBlockCreate(data_key, sign_option.signprivate,
+ sign_option.flags);
}
/* Write it out */
- return WriteSomeParts(option.outfile,
+ return WriteSomeParts(sign_option.outfile,
vblock, vblock->key_block_size,
NULL, 0);
}
@@ -203,8 +177,8 @@ static int fmap_fw_preamble(const char *name, uint8_t *buf, uint32_t len,
case BIOS_FMAP_VBLOCK_A:
fw_body_area = &state->area[BIOS_FMAP_FW_MAIN_A];
/* Preserve the flags if they're not specified */
- if (!option.flags_specified)
- option.flags = preamble->flags;
+ if (!sign_option.flags_specified)
+ sign_option.flags = preamble->flags;
break;
case BIOS_FMAP_VBLOCK_B:
fw_body_area = &state->area[BIOS_FMAP_FW_MAIN_B];
@@ -241,9 +215,9 @@ int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len,
kblob_data = CreateKernelBlob(
vmlinuz_data, vmlinuz_size,
- option.arch, option.kloadaddr,
- option.config_data, option.config_size,
- option.bootloader_data, option.bootloader_size,
+ sign_option.arch, sign_option.kloadaddr,
+ sign_option.config_data, sign_option.config_size,
+ sign_option.bootloader_data, sign_option.bootloader_size,
&kblob_size);
if (!kblob_data) {
fprintf(stderr, "Unable to create kernel blob\n");
@@ -251,10 +225,13 @@ int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len,
}
Debug("kblob_size = 0x%" PRIx64 "\n", kblob_size);
- vblock_data = SignKernelBlob(kblob_data, kblob_size, option.padding,
- option.version, option.kloadaddr,
- option.keyblock, option.signprivate,
- option.flags, &vblock_size);
+ vblock_data = SignKernelBlob(kblob_data, kblob_size,
+ sign_option.padding,
+ sign_option.version,
+ sign_option.kloadaddr,
+ sign_option.keyblock,
+ sign_option.signprivate,
+ sign_option.flags, &vblock_size);
if (!vblock_data) {
fprintf(stderr, "Unable to sign kernel blob\n");
free(kblob_data);
@@ -264,15 +241,15 @@ int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len,
/* We should be creating a completely new output file.
* If not, something's wrong. */
- if (!option.create_new_outfile)
+ if (!sign_option.create_new_outfile)
DIE;
- if (option.vblockonly)
- rv = WriteSomeParts(option.outfile,
+ if (sign_option.vblockonly)
+ rv = WriteSomeParts(sign_option.outfile,
vblock_data, vblock_size,
NULL, 0);
else
- rv = WriteSomeParts(option.outfile,
+ rv = WriteSomeParts(sign_option.outfile,
vblock_data, vblock_size,
kblob_data, kblob_size);
@@ -294,7 +271,7 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len,
kpart_size = len;
/* Note: This just sets some static pointers. It doesn't malloc. */
- kblob_data = UnpackKPart(kpart_data, kpart_size, option.padding,
+ kblob_data = UnpackKPart(kpart_data, kpart_size, sign_option.padding,
&keyblock, &preamble, &kblob_size);
if (!kblob_data) {
@@ -309,50 +286,54 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len,
* it here either. To enable it, we'd need to update the zeropage
* table's cmd_line_ptr as well as the preamble.
*/
- option.kloadaddr = preamble->body_load_address;
+ sign_option.kloadaddr = preamble->body_load_address;
/* Replace the config if asked */
- if (option.config_data &&
+ if (sign_option.config_data &&
0 != UpdateKernelBlobConfig(kblob_data, kblob_size,
- option.config_data,
- option.config_size)) {
+ sign_option.config_data,
+ sign_option.config_size)) {
fprintf(stderr, "Unable to update config\n");
return 1;
}
/* Preserve the version unless a new one is given */
- if (!option.version_specified)
- option.version = preamble->kernel_version;
+ if (!sign_option.version_specified)
+ sign_option.version = preamble->kernel_version;
/* Preserve the flags if not specified */
if (VbKernelHasFlags(preamble) == VBOOT_SUCCESS) {
- if (option.flags_specified == 0)
- option.flags = preamble->flags;
+ if (sign_option.flags_specified == 0)
+ sign_option.flags = preamble->flags;
}
/* Replace the keyblock if asked */
- if (option.keyblock)
- keyblock = option.keyblock;
+ if (sign_option.keyblock)
+ keyblock = sign_option.keyblock;
/* Compute the new signature */
- vblock_data = SignKernelBlob(kblob_data, kblob_size, option.padding,
- option.version, option.kloadaddr,
- keyblock, option.signprivate,
- option.flags, &vblock_size);
+ vblock_data = SignKernelBlob(kblob_data, kblob_size,
+ sign_option.padding,
+ sign_option.version,
+ sign_option.kloadaddr,
+ keyblock,
+ sign_option.signprivate,
+ sign_option.flags,
+ &vblock_size);
if (!vblock_data) {
fprintf(stderr, "Unable to sign kernel blob\n");
return 1;
}
Debug("vblock_size = 0x%" PRIx64 "\n", vblock_size);
- if (option.create_new_outfile) {
+ if (sign_option.create_new_outfile) {
/* Write out what we've been asked for */
- if (option.vblockonly)
- rv = WriteSomeParts(option.outfile,
+ if (sign_option.vblockonly)
+ rv = WriteSomeParts(sign_option.outfile,
vblock_data, vblock_size,
NULL, 0);
else
- rv = WriteSomeParts(option.outfile,
+ rv = WriteSomeParts(sign_option.outfile,
vblock_data, vblock_size,
kblob_data, kblob_size);
} else {
@@ -374,25 +355,26 @@ int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len,
VbFirmwarePreambleHeader *preamble;
int rv;
- body_sig = CalculateSignature(buf, len, option.signprivate);
+ body_sig = CalculateSignature(buf, len, sign_option.signprivate);
if (!body_sig) {
fprintf(stderr, "Error calculating body signature\n");
return 1;
}
- preamble = CreateFirmwarePreamble(option.version,
- option.kernel_subkey,
+ preamble = CreateFirmwarePreamble(sign_option.version,
+ sign_option.kernel_subkey,
body_sig,
- option.signprivate,
- option.flags);
+ sign_option.signprivate,
+ sign_option.flags);
if (!preamble) {
fprintf(stderr, "Error creating firmware preamble.\n");
free(body_sig);
return 1;
}
- rv = WriteSomeParts(option.outfile,
- option.keyblock, option.keyblock->key_block_size,
+ rv = WriteSomeParts(sign_option.outfile,
+ sign_option.keyblock,
+ sign_option.keyblock->key_block_size,
preamble, preamble->preamble_size);
free(preamble);
@@ -416,11 +398,11 @@ static int write_new_preamble(struct bios_area_s *vblock,
return 1;
}
- preamble = CreateFirmwarePreamble(option.version,
- option.kernel_subkey,
+ preamble = CreateFirmwarePreamble(sign_option.version,
+ sign_option.kernel_subkey,
body_sig,
signkey,
- option.flags);
+ sign_option.flags);
if (!preamble) {
fprintf(stderr, "Error creating firmware preamble.\n");
free(body_sig);
@@ -444,8 +426,8 @@ static int write_loem(const char *ab, struct bios_area_s *vblock)
char filename[PATH_MAX];
int n;
n = snprintf(filename, sizeof(filename), "%s/vblock_%s.%s",
- option.loemdir ? option.loemdir : ".",
- ab, option.loemid);
+ sign_option.loemdir ? sign_option.loemdir : ".",
+ ab, sign_option.loemid);
if (n >= sizeof(filename)) {
fprintf(stderr, "LOEM args produce bogus filename\n");
return 1;
@@ -492,29 +474,29 @@ static int sign_bios_at_end(struct sign_state_s *state)
if (fw_a->len != fw_b->len ||
memcmp(fw_a->buf, fw_b->buf, fw_a->len)) {
/* Yes, must use DEV keys for A */
- if (!option.devsignprivate || !option.devkeyblock) {
+ if (!sign_option.devsignprivate || !sign_option.devkeyblock) {
fprintf(stderr,
"FW A & B differ. DEV keys are required.\n");
return 1;
}
retval |= write_new_preamble(vblock_a, fw_a,
- option.devsignprivate,
- option.devkeyblock);
+ sign_option.devsignprivate,
+ sign_option.devkeyblock);
} else {
retval |= write_new_preamble(vblock_a, fw_a,
- option.signprivate,
- option.keyblock);
+ sign_option.signprivate,
+ sign_option.keyblock);
}
/* FW B is always normal keys */
retval |= write_new_preamble(vblock_b, fw_b,
- option.signprivate,
- option.keyblock);
+ sign_option.signprivate,
+ sign_option.keyblock);
- if (option.loemid) {
+ if (sign_option.loemid) {
retval |= write_loem("A", vblock_a);
retval |= write_loem("B", vblock_b);
}
@@ -717,14 +699,14 @@ static void print_help(int argc, char *argv[])
puts(usage_fw_main);
return;
case FILE_TYPE_BIOS_IMAGE:
- printf(usage_bios, option.version);
+ printf(usage_bios, sign_option.version);
return;
case FILE_TYPE_RAW_KERNEL:
- printf(usage_new_kpart, option.kloadaddr,
- option.padding);
+ printf(usage_new_kpart, sign_option.kloadaddr,
+ sign_option.padding);
return;
case FILE_TYPE_KERN_PREAMBLE:
- printf(usage_old_kpart, option.padding);
+ printf(usage_old_kpart, sign_option.padding);
return;
default:
break;
@@ -779,7 +761,7 @@ static const struct option long_opts[] = {
{"pem_algo", 1, NULL, OPT_PEM_ALGO},
{"pem_external", 1, NULL, OPT_PEM_EXTERNAL},
{"type", 1, NULL, OPT_TYPE},
- {"vblockonly", 0, &option.vblockonly, 1},
+ {"vblockonly", 0, &sign_option.vblockonly, 1},
{"help", 0, NULL, OPT_HELP},
{NULL, 0, NULL, 0},
};
@@ -802,43 +784,43 @@ static int do_sign(int argc, char *argv[])
while ((i = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) {
switch (i) {
case 's':
- option.signprivate = PrivateKeyRead(optarg);
- if (!option.signprivate) {
+ sign_option.signprivate = PrivateKeyRead(optarg);
+ if (!sign_option.signprivate) {
fprintf(stderr, "Error reading %s\n", optarg);
errorcnt++;
}
break;
case 'b':
- option.keyblock = KeyBlockRead(optarg);
- if (!option.keyblock) {
+ sign_option.keyblock = KeyBlockRead(optarg);
+ if (!sign_option.keyblock) {
fprintf(stderr, "Error reading %s\n", optarg);
errorcnt++;
}
break;
case 'k':
- option.kernel_subkey = PublicKeyRead(optarg);
- if (!option.kernel_subkey) {
+ sign_option.kernel_subkey = PublicKeyRead(optarg);
+ if (!sign_option.kernel_subkey) {
fprintf(stderr, "Error reading %s\n", optarg);
errorcnt++;
}
break;
case 'S':
- option.devsignprivate = PrivateKeyRead(optarg);
- if (!option.devsignprivate) {
+ sign_option.devsignprivate = PrivateKeyRead(optarg);
+ if (!sign_option.devsignprivate) {
fprintf(stderr, "Error reading %s\n", optarg);
errorcnt++;
}
break;
case 'B':
- option.devkeyblock = KeyBlockRead(optarg);
- if (!option.devkeyblock) {
+ sign_option.devkeyblock = KeyBlockRead(optarg);
+ if (!sign_option.devkeyblock) {
fprintf(stderr, "Error reading %s\n", optarg);
errorcnt++;
}
break;
case 'v':
- option.version_specified = 1;
- option.version = strtoul(optarg, &e, 0);
+ sign_option.version_specified = 1;
+ sign_option.version = strtoul(optarg, &e, 0);
if (!*optarg || (e && *e)) {
fprintf(stderr,
"Invalid --version \"%s\"\n", optarg);
@@ -847,8 +829,8 @@ static int do_sign(int argc, char *argv[])
break;
case 'f':
- option.flags_specified = 1;
- option.flags = strtoul(optarg, &e, 0);
+ sign_option.flags_specified = 1;
+ sign_option.flags = strtoul(optarg, &e, 0);
if (!*optarg || (e && *e)) {
fprintf(stderr,
"Invalid --flags \"%s\"\n", optarg);
@@ -856,13 +838,13 @@ static int do_sign(int argc, char *argv[])
}
break;
case 'd':
- option.loemdir = optarg;
+ sign_option.loemdir = optarg;
break;
case 'l':
- option.loemid = optarg;
+ sign_option.loemid = optarg;
break;
case OPT_FV:
- option.fv_specified = 1;
+ sign_option.fv_specified = 1;
/* fallthrough */
case OPT_INFILE:
inout_file_count++;
@@ -870,24 +852,24 @@ static int do_sign(int argc, char *argv[])
break;
case OPT_OUTFILE:
inout_file_count++;
- option.outfile = optarg;
+ sign_option.outfile = optarg;
break;
case OPT_BOOTLOADER:
- option.bootloader_data = ReadFile(
- optarg, &option.bootloader_size);
- if (!option.bootloader_data) {
+ sign_option.bootloader_data = ReadFile(
+ optarg, &sign_option.bootloader_size);
+ if (!sign_option.bootloader_data) {
fprintf(stderr,
"Error reading bootloader file: %s\n",
strerror(errno));
errorcnt++;
}
Debug("bootloader file size=0x%" PRIx64 "\n",
- option.bootloader_size);
+ sign_option.bootloader_size);
break;
case OPT_CONFIG:
- option.config_data = ReadConfigFile(
- optarg, &option.config_size);
- if (!option.config_data) {
+ sign_option.config_data = ReadConfigFile(
+ optarg, &sign_option.config_size);
+ if (!sign_option.config_data) {
fprintf(stderr,
"Error reading config file: %s\n",
strerror(errno));
@@ -898,12 +880,12 @@ static int do_sign(int argc, char *argv[])
/* check the first 3 characters to also match x86_64 */
if ((!strncasecmp(optarg, "x86", 3)) ||
(!strcasecmp(optarg, "amd64")))
- option.arch = ARCH_X86;
+ sign_option.arch = ARCH_X86;
else if ((!strcasecmp(optarg, "arm")) ||
(!strcasecmp(optarg, "aarch64")))
- option.arch = ARCH_ARM;
+ sign_option.arch = ARCH_ARM;
else if (!strcasecmp(optarg, "mips"))
- option.arch = ARCH_MIPS;
+ sign_option.arch = ARCH_MIPS;
else {
fprintf(stderr,
"Unknown architecture: \"%s\"\n",
@@ -912,7 +894,7 @@ static int do_sign(int argc, char *argv[])
}
break;
case OPT_KLOADADDR:
- option.kloadaddr = strtoul(optarg, &e, 0);
+ sign_option.kloadaddr = strtoul(optarg, &e, 0);
if (!*optarg || (e && *e)) {
fprintf(stderr,
"Invalid --kloadaddr \"%s\"\n", optarg);
@@ -920,7 +902,7 @@ static int do_sign(int argc, char *argv[])
}
break;
case OPT_PADDING:
- option.padding = strtoul(optarg, &e, 0);
+ sign_option.padding = strtoul(optarg, &e, 0);
if (!*optarg || (e && *e)) {
fprintf(stderr,
"Invalid --padding \"%s\"\n", optarg);
@@ -928,23 +910,24 @@ static int do_sign(int argc, char *argv[])
}
break;
case OPT_PEM_SIGNPRIV:
- option.pem_signpriv = optarg;
+ sign_option.pem_signpriv = optarg;
break;
case OPT_PEM_ALGO:
- option.pem_algo_specified = 1;
- option.pem_algo = strtoul(optarg, &e, 0);
+ sign_option.pem_algo_specified = 1;
+ sign_option.pem_algo = strtoul(optarg, &e, 0);
if (!*optarg || (e && *e) ||
- (option.pem_algo >= kNumAlgorithms)) {
+ (sign_option.pem_algo >= kNumAlgorithms)) {
fprintf(stderr,
"Invalid --pem_algo \"%s\"\n", optarg);
errorcnt++;
}
break;
case OPT_PEM_EXTERNAL:
- option.pem_external = optarg;
+ sign_option.pem_external = optarg;
break;
case OPT_TYPE:
- if (!futil_str_to_file_type(optarg, &option.type)) {
+ if (!futil_str_to_file_type(optarg,
+ &sign_option.type)) {
if (!strcasecmp("help", optarg))
print_file_types_and_exit(errorcnt);
fprintf(stderr,
@@ -1000,46 +983,48 @@ static int do_sign(int argc, char *argv[])
}
/* Look for an output file if we don't have one, just in case. */
- if (!option.outfile && argc - optind > 0) {
+ if (!sign_option.outfile && argc - optind > 0) {
inout_file_count++;
- option.outfile = argv[optind++];
+ sign_option.outfile = argv[optind++];
}
/* What are we looking at? */
- if (option.type == FILE_TYPE_UNKNOWN &&
- futil_file_type(infile, &option.type)) {
+ if (sign_option.type == FILE_TYPE_UNKNOWN &&
+ futil_file_type(infile, &sign_option.type)) {
errorcnt++;
goto done;
}
/* We may be able to infer the type based on the other args */
- if (option.type == FILE_TYPE_UNKNOWN) {
- if (option.bootloader_data || option.config_data
- || option.arch != ARCH_UNSPECIFIED)
- option.type = FILE_TYPE_RAW_KERNEL;
- else if (option.kernel_subkey || option.fv_specified)
- option.type = FILE_TYPE_RAW_FIRMWARE;
+ if (sign_option.type == FILE_TYPE_UNKNOWN) {
+ if (sign_option.bootloader_data || sign_option.config_data
+ || sign_option.arch != ARCH_UNSPECIFIED)
+ sign_option.type = FILE_TYPE_RAW_KERNEL;
+ else if (sign_option.kernel_subkey || sign_option.fv_specified)
+ sign_option.type = FILE_TYPE_RAW_FIRMWARE;
}
- Debug("type=%s\n", futil_file_type_name(option.type));
+ Debug("type=%s\n", futil_file_type_name(sign_option.type));
/* Check the arguments for the type of thing we want to sign */
- switch (option.type) {
+ switch (sign_option.type) {
case FILE_TYPE_PUBKEY:
- option.create_new_outfile = 1;
- if (option.signprivate && option.pem_signpriv) {
+ sign_option.create_new_outfile = 1;
+ if (sign_option.signprivate && sign_option.pem_signpriv) {
fprintf(stderr,
"Only one of --signprivate and --pem_signpriv"
" can be specified\n");
errorcnt++;
}
- if ((option.signprivate && option.pem_algo_specified) ||
- (option.pem_signpriv && !option.pem_algo_specified)) {
+ if ((sign_option.signprivate &&
+ sign_option.pem_algo_specified) ||
+ (sign_option.pem_signpriv &&
+ !sign_option.pem_algo_specified)) {
fprintf(stderr, "--pem_algo must be used with"
" --pem_signpriv\n");
errorcnt++;
}
- if (option.pem_external && !option.pem_signpriv) {
+ if (sign_option.pem_external && !sign_option.pem_signpriv) {
fprintf(stderr, "--pem_external must be used with"
" --pem_signpriv\n");
errorcnt++;
@@ -1049,53 +1034,58 @@ static int do_sign(int argc, char *argv[])
break;
case FILE_TYPE_BIOS_IMAGE:
case FILE_TYPE_OLD_BIOS_IMAGE:
- errorcnt += no_opt_if(!option.signprivate, "signprivate");
- errorcnt += no_opt_if(!option.keyblock, "keyblock");
- errorcnt += no_opt_if(!option.kernel_subkey, "kernelkey");
+ errorcnt += no_opt_if(!sign_option.signprivate, "signprivate");
+ errorcnt += no_opt_if(!sign_option.keyblock, "keyblock");
+ errorcnt += no_opt_if(!sign_option.kernel_subkey, "kernelkey");
break;
case FILE_TYPE_KERN_PREAMBLE:
- errorcnt += no_opt_if(!option.signprivate, "signprivate");
- if (option.vblockonly || inout_file_count > 1)
- option.create_new_outfile = 1;
+ errorcnt += no_opt_if(!sign_option.signprivate, "signprivate");
+ if (sign_option.vblockonly || inout_file_count > 1)
+ sign_option.create_new_outfile = 1;
break;
case FILE_TYPE_RAW_FIRMWARE:
- option.create_new_outfile = 1;
- errorcnt += no_opt_if(!option.signprivate, "signprivate");
- errorcnt += no_opt_if(!option.keyblock, "keyblock");
- errorcnt += no_opt_if(!option.kernel_subkey, "kernelkey");
- errorcnt += no_opt_if(!option.version_specified, "version");
+ sign_option.create_new_outfile = 1;
+ errorcnt += no_opt_if(!sign_option.signprivate, "signprivate");
+ errorcnt += no_opt_if(!sign_option.keyblock, "keyblock");
+ errorcnt += no_opt_if(!sign_option.kernel_subkey, "kernelkey");
+ errorcnt += no_opt_if(!sign_option.version_specified,
+ "version");
break;
case FILE_TYPE_RAW_KERNEL:
- option.create_new_outfile = 1;
- errorcnt += no_opt_if(!option.signprivate, "signprivate");
- errorcnt += no_opt_if(!option.keyblock, "keyblock");
- errorcnt += no_opt_if(!option.version_specified, "version");
- errorcnt += no_opt_if(!option.bootloader_data, "bootloader");
- errorcnt += no_opt_if(!option.config_data, "config");
- errorcnt += no_opt_if(option.arch == ARCH_UNSPECIFIED, "arch");
+ sign_option.create_new_outfile = 1;
+ errorcnt += no_opt_if(!sign_option.signprivate, "signprivate");
+ errorcnt += no_opt_if(!sign_option.keyblock, "keyblock");
+ errorcnt += no_opt_if(!sign_option.version_specified,
+ "version");
+ errorcnt += no_opt_if(!sign_option.bootloader_data,
+ "bootloader");
+ errorcnt += no_opt_if(!sign_option.config_data, "config");
+ errorcnt += no_opt_if(sign_option.arch == ARCH_UNSPECIFIED,
+ "arch");
break;
default:
fprintf(stderr, "Unable to sign type %s\n",
- futil_file_type_name(option.type));
+ futil_file_type_name(sign_option.type));
errorcnt++;
}
Debug("infile=%s\n", infile);
Debug("inout_file_count=%d\n", inout_file_count);
- Debug("option.create_new_outfile=%d\n", option.create_new_outfile);
+ Debug("sign_option.create_new_outfile=%d\n",
+ sign_option.create_new_outfile);
/* Make sure we have an output file if one is needed */
- if (!option.outfile) {
- if (option.create_new_outfile) {
+ if (!sign_option.outfile) {
+ if (sign_option.create_new_outfile) {
errorcnt++;
fprintf(stderr, "Missing output filename\n");
goto done;
} else {
- option.outfile = infile;
+ sign_option.outfile = infile;
}
}
- Debug("option.outfile=%s\n", option.outfile);
+ Debug("sign_option.outfile=%s\n", sign_option.outfile);
if (argc - optind > 0) {
errorcnt++;
@@ -1105,7 +1095,7 @@ static int do_sign(int argc, char *argv[])
if (errorcnt)
goto done;
- if (option.create_new_outfile) {
+ if (sign_option.create_new_outfile) {
/* The input is read-only, the output is write-only. */
mapping = MAP_RO;
Debug("open RO %s\n", infile);
@@ -1120,14 +1110,14 @@ static int do_sign(int argc, char *argv[])
/* We'll read-modify-write the output file */
mapping = MAP_RW;
if (inout_file_count > 1)
- futil_copy_file_or_die(infile, option.outfile);
- Debug("open RW %s\n", option.outfile);
- infile = option.outfile;
- ifd = open(option.outfile, O_RDWR);
+ futil_copy_file_or_die(infile, sign_option.outfile);
+ Debug("open RW %s\n", sign_option.outfile);
+ infile = sign_option.outfile;
+ ifd = open(sign_option.outfile, O_RDWR);
if (ifd < 0) {
errorcnt++;
fprintf(stderr, "Can't open %s for writing: %s\n",
- option.outfile, strerror(errno));
+ sign_option.outfile, strerror(errno));
goto done;
}
}
@@ -1137,7 +1127,8 @@ static int do_sign(int argc, char *argv[])
goto done;
}
- errorcnt += futil_file_type_sign(option.type, infile, buf, buf_len);
+ errorcnt += futil_file_type_sign(sign_option.type, infile,
+ buf, buf_len);
errorcnt += futil_unmap_file(ifd, MAP_RW, buf, buf_len);
@@ -1148,12 +1139,12 @@ done:
strerror(errno));
}
- if (option.signprivate)
- free(option.signprivate);
- if (option.keyblock)
- free(option.keyblock);
- if (option.kernel_subkey)
- free(option.kernel_subkey);
+ if (sign_option.signprivate)
+ free(sign_option.signprivate);
+ if (sign_option.keyblock)
+ free(sign_option.keyblock);
+ if (sign_option.kernel_subkey)
+ free(sign_option.kernel_subkey);
if (errorcnt)
fprintf(stderr, "Use --help for usage instructions\n");
diff --git a/futility/futility_options.h b/futility/futility_options.h
new file mode 100644
index 00000000..3d416d5b
--- /dev/null
+++ b/futility/futility_options.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * We centralize option parsing but may split operations into multiple files,
+ * so let's declare the option structures in a single place (here).
+ */
+
+#ifndef VBOOT_REFERENCE_FUTILITY_OPTIONS_H_
+#define VBOOT_REFERENCE_FUTILITY_OPTIONS_H_
+#include <stdint.h>
+#include "vboot_common.h"
+
+struct show_option_s {
+ VbPublicKey *k;
+ uint8_t *fv;
+ uint64_t fv_size;
+ uint32_t padding;
+ int strict;
+ int t_flag;
+ enum futil_file_type type;
+};
+extern struct show_option_s show_option;
+
+struct sign_option_s {
+ VbPrivateKey *signprivate;
+ VbKeyBlockHeader *keyblock;
+ VbPublicKey *kernel_subkey;
+ VbPrivateKey *devsignprivate;
+ VbKeyBlockHeader *devkeyblock;
+ uint32_t version;
+ int version_specified;
+ uint32_t flags;
+ int flags_specified;
+ char *loemdir;
+ char *loemid;
+ uint8_t *bootloader_data;
+ uint64_t bootloader_size;
+ uint8_t *config_data;
+ uint64_t config_size;
+ enum arch_t arch;
+ int fv_specified;
+ uint32_t kloadaddr;
+ uint32_t padding;
+ int vblockonly;
+ char *outfile;
+ int create_new_outfile;
+ char *pem_signpriv;
+ int pem_algo_specified;
+ uint32_t pem_algo;
+ char *pem_external;
+ enum futil_file_type type;
+};
+extern struct sign_option_s sign_option;
+
+#endif /* VBOOT_REFERENCE_FUTILITY_OPTIONS_H_ */