summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--futility/cmd_dump_fmap.c11
-rw-r--r--futility/cmd_dump_kernel_config.c1
-rw-r--r--futility/cmd_gbb_utility.c39
-rw-r--r--futility/cmd_load_fmap.c1
-rw-r--r--futility/cmd_pcr.c1
-rw-r--r--futility/cmd_show.c2
-rw-r--r--futility/cmd_sign.c1
-rw-r--r--futility/cmd_vbutil_firmware.c1
-rw-r--r--futility/cmd_vbutil_kernel.c1
-rw-r--r--futility/cmd_vbutil_key.c1
-rw-r--r--futility/cmd_vbutil_keyblock.c1
-rw-r--r--futility/futility.c93
-rw-r--r--futility/futility.h39
-rwxr-xr-xtests/futility/test_dump_fmap.sh2
-rwxr-xr-xtests/futility/test_gbb_utility.sh10
15 files changed, 157 insertions, 47 deletions
diff --git a/futility/cmd_dump_fmap.c b/futility/cmd_dump_fmap.c
index 4bc4bd26..1c233fda 100644
--- a/futility/cmd_dump_fmap.c
+++ b/futility/cmd_dump_fmap.c
@@ -398,11 +398,11 @@ static const char usage[] =
"Display (and extract) the FMAP components from a BIOS image.\n"
"\n"
"Options:\n"
- " -p Use a format easy to parse by scripts\n"
- " -f Use the format expected by flashrom\n"
+ " -x Extract the named sections from the file\n"
" -h Use a human-readable format\n"
" -H With -h, display any gaps\n"
- " -x Extract the named sections from the file\n"
+ " -p Use a format easy to parse by scripts\n"
+ " -F Use the format expected by flashrom\n"
"\n"
"Specify one or more NAMEs to dump only those sections.\n"
"\n";
@@ -424,7 +424,7 @@ static int do_dump_fmap(int argc, char *argv[])
progname = argv[0];
opterr = 0; /* quiet, you */
- while ((c = getopt(argc, argv, ":xpfhH")) != -1) {
+ while ((c = getopt(argc, argv, ":xpFhH")) != -1) {
switch (c) {
case 'x':
opt_extract = 1;
@@ -432,7 +432,7 @@ static int do_dump_fmap(int argc, char *argv[])
case 'p':
opt_format = FMT_PRETTY;
break;
- case 'f':
+ case 'F':
opt_format = FMT_FLASHROM;
break;
case 'H':
@@ -514,5 +514,6 @@ static int do_dump_fmap(int argc, char *argv[])
}
DECLARE_FUTIL_COMMAND(dump_fmap, do_dump_fmap,
+ VBOOT_VERSION_ALL,
"Display FMAP contents from a firmware image",
print_help);
diff --git a/futility/cmd_dump_kernel_config.c b/futility/cmd_dump_kernel_config.c
index 520d2802..fad7e292 100644
--- a/futility/cmd_dump_kernel_config.c
+++ b/futility/cmd_dump_kernel_config.c
@@ -88,5 +88,6 @@ static int do_dump_kernel_config(int argc, char *argv[])
}
DECLARE_FUTIL_COMMAND(dump_kernel_config, do_dump_kernel_config,
+ VBOOT_VERSION_ALL,
"Prints the kernel command line",
PrintHelp);
diff --git a/futility/cmd_gbb_utility.c b/futility/cmd_gbb_utility.c
index 9e608d1f..65d5f938 100644
--- a/futility/cmd_gbb_utility.c
+++ b/futility/cmd_gbb_utility.c
@@ -57,26 +57,39 @@ static void print_help(const char *prog)
}
enum {
- OPT_DIGEST = 1000,
+ OPT_HWID = 1000,
+ OPT_FLAGS,
+ OPT_DIGEST,
};
/* Command line options */
-static const struct option long_opts[] = {
- /* name hasarg *flag val */
+static struct option long_opts[] = {
+ /* name has_arg *flag val */
{"get", 0, NULL, 'g'},
{"set", 0, NULL, 's'},
{"create", 1, NULL, 'c'},
{"output", 1, NULL, 'o'},
{"rootkey", 1, NULL, 'k'},
{"bmpfv", 1, NULL, 'b'},
- {"recoverykey", 1, NULL, 'R'},
- {"hwid", 2, NULL, 'i'},
- {"flags", 2, NULL, 'L'},
+ {"recoverykey", 1, NULL, 'r'},
+ {"hwid", 0, NULL, OPT_HWID},
+ {"flags", 0, NULL, OPT_FLAGS},
{"digest", 0, NULL, OPT_DIGEST},
{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:";
+
+/* Change the has_arg field of a long_opts entry */
+static void opt_has_arg(const char *name, int val)
+{
+ struct option *p;
+ for (p = long_opts; p->name; p++)
+ if (!strcmp(name, p->name)) {
+ p->has_arg = val;
+ break;
+ }
+}
static int errorcnt;
@@ -360,9 +373,13 @@ static int do_gbb_utility(int argc, char *argv[])
switch (i) {
case 'g':
mode = DO_GET;
+ opt_has_arg("flags", 0);
+ opt_has_arg("hwid", 0);
break;
case 's':
mode = DO_SET;
+ opt_has_arg("flags", 1);
+ opt_has_arg("hwid", 1);
break;
case 'c':
mode = DO_CREATE;
@@ -377,18 +394,15 @@ static int do_gbb_utility(int argc, char *argv[])
case 'b':
opt_bmpfv = optarg;
break;
- case 'R':
case 'r':
opt_recoverykey = optarg;
break;
- case 'i':
- case 'h':
+ case OPT_HWID:
/* --hwid is optional: null might be okay */
opt_hwid = optarg;
sel_hwid = 1;
break;
- case 'L':
- case 'f':
+ case OPT_FLAGS:
/* --flags is optional: null might be okay */
opt_flags = optarg;
sel_flags = 1;
@@ -624,5 +638,6 @@ static int do_gbb_utility(int argc, char *argv[])
}
DECLARE_FUTIL_COMMAND(gbb_utility, do_gbb_utility,
+ VBOOT_VERSION_ALL,
"Manipulate the Google Binary Block (GBB)",
print_help);
diff --git a/futility/cmd_load_fmap.c b/futility/cmd_load_fmap.c
index 7922ad62..cd81b303 100644
--- a/futility/cmd_load_fmap.c
+++ b/futility/cmd_load_fmap.c
@@ -199,5 +199,6 @@ done_file:
}
DECLARE_FUTIL_COMMAND(load_fmap, do_load_fmap,
+ VBOOT_VERSION_ALL,
"Replace the contents of specified FMAP areas",
help_and_quit);
diff --git a/futility/cmd_pcr.c b/futility/cmd_pcr.c
index 9149ccfe..ef44453e 100644
--- a/futility/cmd_pcr.c
+++ b/futility/cmd_pcr.c
@@ -182,5 +182,6 @@ static int do_pcr(int argc, char *argv[])
}
DECLARE_FUTIL_COMMAND(pcr, do_pcr,
+ VBOOT_VERSION_ALL,
"Simulate a TPM PCR extension operation",
help_and_quit);
diff --git a/futility/cmd_show.c b/futility/cmd_show.c
index b6c2574a..875689d5 100644
--- a/futility/cmd_show.c
+++ b/futility/cmd_show.c
@@ -730,6 +730,7 @@ done:
}
DECLARE_FUTIL_COMMAND(show, do_show,
+ VBOOT_VERSION_ALL,
"Display the content of various binary components",
print_help);
@@ -740,5 +741,6 @@ static int do_verify(int argc, char *argv[])
}
DECLARE_FUTIL_COMMAND(verify, do_verify,
+ VBOOT_VERSION_ALL,
"Verify the signatures of various binary components",
print_help);
diff --git a/futility/cmd_sign.c b/futility/cmd_sign.c
index 2d247bcd..192305f7 100644
--- a/futility/cmd_sign.c
+++ b/futility/cmd_sign.c
@@ -1079,5 +1079,6 @@ done:
}
DECLARE_FUTIL_COMMAND(sign, do_sign,
+ VBOOT_VERSION_ALL,
"Sign / resign various binary components",
print_help);
diff --git a/futility/cmd_vbutil_firmware.c b/futility/cmd_vbutil_firmware.c
index dcb325e1..4f748e86 100644
--- a/futility/cmd_vbutil_firmware.c
+++ b/futility/cmd_vbutil_firmware.c
@@ -386,5 +386,6 @@ static int do_vbutil_firmware(int argc, char *argv[])
}
DECLARE_FUTIL_COMMAND(vbutil_firmware, do_vbutil_firmware,
+ VBOOT_VERSION_1_0,
"Verified boot firmware utility",
print_help);
diff --git a/futility/cmd_vbutil_kernel.c b/futility/cmd_vbutil_kernel.c
index 3322e4b8..c7b3c78c 100644
--- a/futility/cmd_vbutil_kernel.c
+++ b/futility/cmd_vbutil_kernel.c
@@ -648,5 +648,6 @@ static int do_vbutil_kernel(int argc, char *argv[])
}
DECLARE_FUTIL_COMMAND(vbutil_kernel, do_vbutil_kernel,
+ VBOOT_VERSION_1_0,
"Creates, signs, and verifies the kernel partition",
print_help);
diff --git a/futility/cmd_vbutil_key.c b/futility/cmd_vbutil_key.c
index ea8dea0b..de9f97ff 100644
--- a/futility/cmd_vbutil_key.c
+++ b/futility/cmd_vbutil_key.c
@@ -235,5 +235,6 @@ static int do_vbutil_key(int argc, char *argv[])
}
DECLARE_FUTIL_COMMAND(vbutil_key, do_vbutil_key,
+ VBOOT_VERSION_1_0,
"Wraps RSA keys with vboot headers",
print_help);
diff --git a/futility/cmd_vbutil_keyblock.c b/futility/cmd_vbutil_keyblock.c
index c73fd9ae..64a1760b 100644
--- a/futility/cmd_vbutil_keyblock.c
+++ b/futility/cmd_vbutil_keyblock.c
@@ -332,5 +332,6 @@ static int do_vbutil_keyblock(int argc, char *argv[])
}
DECLARE_FUTIL_COMMAND(vbutil_keyblock, do_vbutil_keyblock,
+ VBOOT_VERSION_1_0,
"Creates, signs, and verifies a keyblock",
print_help);
diff --git a/futility/futility.c b/futility/futility.c
index ba9fb163..02f61af9 100644
--- a/futility/futility.c
+++ b/futility/futility.c
@@ -6,6 +6,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <getopt.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
@@ -175,8 +176,11 @@ static void log_args(int argc, char *argv[])
/******************************************************************************/
+/* Default is to support everything we can */
+enum vboot_version vboot_version = VBOOT_VERSION_ALL;
+
static const char *const usage = "\n"
-"Usage: " MYNAME " COMMAND [args...]\n"
+"Usage: " MYNAME " [options] COMMAND [args...]\n"
"\n"
"This is the unified firmware utility, which will eventually replace\n"
"most of the distinct verified boot tools formerly produced by the\n"
@@ -187,10 +191,12 @@ static const char *const usage = "\n"
"as " MYNAME ", followed by the original name as the first argument.\n"
"\n";
-static void print_help(const char *cmd)
-{
- puts(usage);
-}
+static const char *const options =
+"Global options:\n"
+"\n"
+" --vb1 Use only vboot v1.0 binary formats\n"
+" --vb21 Use only vboot v2.1 binary formats\n"
+"\n";
static const struct futil_cmd_t *find_command(const char *name)
{
@@ -208,12 +214,15 @@ static void list_commands(void)
const struct futil_cmd_t *const *cmd;
for (cmd = futil_cmds; *cmd; cmd++)
- printf(" %-20s %s\n", (*cmd)->name, (*cmd)->shorthelp);
+ if (vboot_version & (*cmd)->version)
+ printf(" %-20s %s\n",
+ (*cmd)->name, (*cmd)->shorthelp);
}
static int do_help(int argc, char *argv[])
{
const struct futil_cmd_t *cmd;
+ const char *vstr;
if (argc >= 2) {
cmd = find_command(argv[1]);
@@ -227,16 +236,30 @@ static int do_help(int argc, char *argv[])
fputs(usage, stdout);
- printf("The following commands are built-in:\n\n");
+ if (vboot_version == VBOOT_VERSION_ALL)
+ fputs(options, stdout);
+
+ switch (vboot_version) {
+ case VBOOT_VERSION_1_0:
+ vstr = "version 1.0 ";
+ break;
+ case VBOOT_VERSION_2_1:
+ vstr = "version 2.1 ";
+ break;
+ case VBOOT_VERSION_ALL:
+ vstr = "";
+ break;
+ }
+ printf("The following %scommands are built-in:\n\n", vstr);
list_commands();
printf("\nUse \"" MYNAME " help COMMAND\" for more information.\n\n");
return 0;
}
-DECLARE_FUTIL_COMMAND(help, do_help,
+DECLARE_FUTIL_COMMAND(help, do_help, VBOOT_VERSION_ALL,
"Show a bit of help (you're looking at it)",
- print_help);
+ NULL);
static int do_version(int argc, char *argv[])
{
@@ -244,7 +267,7 @@ static int do_version(int argc, char *argv[])
return 0;
}
-DECLARE_FUTIL_COMMAND(version, do_version,
+DECLARE_FUTIL_COMMAND(version, do_version, VBOOT_VERSION_ALL,
"Show the futility source revision and build date",
NULL);
@@ -276,6 +299,13 @@ int main(int argc, char *argv[], char *envp[])
{
char *progname;
const struct futil_cmd_t *cmd;
+ int i, errorcnt = 0;
+ int vb_ver = VBOOT_VERSION_ALL;
+ struct option long_opts[] = {
+ {"vb1" , 0, &vb_ver, VBOOT_VERSION_1_0},
+ {"vb21", 0, &vb_ver, VBOOT_VERSION_2_1},
+ { 0, 0, 0, 0},
+ };
log_args(argc, argv);
@@ -285,23 +315,48 @@ int main(int argc, char *argv[], char *envp[])
/* See if the program name is a command we recognize */
cmd = find_command(progname);
if (cmd)
+ /* Yep, just do that */
return run_command(cmd, argc, argv);
- /* The program name means nothing, so we require an argument. */
- if (argc < 2) {
+ /* Parse the global options, stopping at the first non-option. */
+ opterr = 0; /* quiet, you. */
+ while ((i = getopt_long(argc, argv, "+:", long_opts, NULL)) != -1) {
+ switch (i) {
+ case '?':
+ if (optopt)
+ fprintf(stderr, "Unrecognized option: -%c\n",
+ optopt);
+ else
+ fprintf(stderr, "Unrecognized option: %s\n",
+ argv[optind - 1]);
+ errorcnt++;
+ break;
+ case ':':
+ fprintf(stderr, "Missing argument to -%c\n", optopt);
+ errorcnt++;
+ break;
+ case 0: /* handled option */
+ break;
+ default:
+ Debug("i=%d\n", i);
+ DIE;
+ }
+ }
+ vboot_version = vb_ver;
+
+ /* Reset the getopt state so commands can parse their own options. */
+ argc -= optind;
+ argv += optind;
+ optind = 0;
+
+ /* We require a command name. */
+ if (errorcnt || argc < 1) {
do_help(0, 0);
return 1;
}
- /* The first arg should be a command we recognize */
- argc--;
- argv++;
-
/* For reasons I've forgotten, treat /blah/blah/CMD the same as CMD */
progname = simple_basename(argv[0]);
- /* Oh, and treat "--foo" the same as "foo" */
- while (*progname == '-')
- progname++;
/* Do we recognize the command? */
cmd = find_command(progname);
diff --git a/futility/futility.h b/futility/futility.h
index 5f9a5b78..550e381e 100644
--- a/futility/futility.h
+++ b/futility/futility.h
@@ -17,21 +17,48 @@
/* Version string (autogenerated) */
extern const char futility_version[];
+/* Bitfields indicating the struct/format versions supported by a command */
+enum vboot_version {
+ /*
+ * v1.0 is the original structs used since the dawn of time.
+ * v2.0 can verify the firmware in smaller chunks, but there's
+ * no difference in the on-device structs, so it's only
+ * meaningful for the firmware API. Futility doesn't care.
+ */
+ VBOOT_VERSION_1_0 = 0x00000001,
+
+ /*
+ * v2.1 uses new and different structs, and is what v2.0 would have
+ * been if someone hadn't started using it before it was ready.
+ */
+ VBOOT_VERSION_2_1 = 0x00000002,
+
+ /*
+ * Everything we know about to date.
+ */
+ VBOOT_VERSION_ALL = 0x00000003,
+};
+
+/* What's our preferred API & data format? */
+enum vboot_version vboot_version;
+
/* Here's a structure to define the commands that futility implements. */
struct futil_cmd_t {
const char *const name;
int (*const handler) (int argc, char **argv);
+ enum vboot_version version;
const char *const shorthelp;
void (*longhelp) (const char *cmd);
};
/* Macro to define a command */
-#define DECLARE_FUTIL_COMMAND(NAME, HANDLER, SHORTHELP, LONGHELP) \
- const struct futil_cmd_t __cmd_##NAME = { \
- .name = #NAME, \
- .handler = HANDLER, \
- .shorthelp = SHORTHELP, \
- .longhelp = LONGHELP, \
+#define DECLARE_FUTIL_COMMAND(NAME, HANDLER, VERSION, SHORTHELP, LONGHELP) \
+ const struct futil_cmd_t __cmd_##NAME = { \
+ .name = #NAME, \
+ .handler = HANDLER, \
+ .version = VERSION, \
+ .shorthelp = SHORTHELP, \
+ .longhelp = LONGHELP, \
}
/* This is the list of pointers to all commands. */
diff --git a/tests/futility/test_dump_fmap.sh b/tests/futility/test_dump_fmap.sh
index bcdb27e6..5a58a0c8 100755
--- a/tests/futility/test_dump_fmap.sh
+++ b/tests/futility/test_dump_fmap.sh
@@ -10,7 +10,7 @@ TMP="$me.tmp"
cd "$OUTDIR"
# Good FMAP
-"$FUTILITY" dump_fmap -f "${SCRIPTDIR}/data_fmap.bin" > "$TMP"
+"$FUTILITY" dump_fmap -F "${SCRIPTDIR}/data_fmap.bin" > "$TMP"
cmp "${SCRIPTDIR}/data_fmap_expect_f.txt" "$TMP"
"$FUTILITY" dump_fmap -p "${SCRIPTDIR}/data_fmap.bin" > "$TMP"
diff --git a/tests/futility/test_gbb_utility.sh b/tests/futility/test_gbb_utility.sh
index 3d8e576b..3dc7d351 100755
--- a/tests/futility/test_gbb_utility.sh
+++ b/tests/futility/test_gbb_utility.sh
@@ -22,9 +22,11 @@ ${FUTILITY} gbb_utility -s --flags=0xdeadbeef ${TMP}.blob
${FUTILITY} gbb_utility -g --flags ${TMP}.blob | grep -i 0xdeadbeef
# HWID length should include the terminating null - this is too long
-if ${FUTILITY} gbb_utility -s -i "0123456789ABCDEF" ${TMP}.blob; then false; fi
+if ${FUTILITY} gbb_utility -s --hwid="0123456789ABCDEF" ${TMP}.blob; then
+ false;
+fi
# This works
-${FUTILITY} gbb_utility -s -i "0123456789ABCDE" ${TMP}.blob
+${FUTILITY} gbb_utility -s --hwid="0123456789ABCDE" ${TMP}.blob
# Read it back?
${FUTILITY} gbb_utility -g ${TMP}.blob | grep "0123456789ABCDE"
@@ -184,7 +186,7 @@ if ${FUTILITY} gbb_utility -g ${TMP}.blob.bad; then false; fi
# hwid_size == 0 doesn't complain, but can't be set
cat ${TMP}.blob | ${REPLACE} 0x14 0x00 > ${TMP}.blob.bad
${FUTILITY} gbb_utility -g ${TMP}.blob.bad
-if ${FUTILITY} gbb_utility -s -i "A" ${TMP}.blob.bad; then false; fi
+if ${FUTILITY} gbb_utility -s --hwid="A" ${TMP}.blob.bad; then false; fi
# rootkey_size == 0 gives warning, gets nothing, can't be set
cat ${TMP}.blob | ${REPLACE} 0x1c 0x00 > ${TMP}.blob.bad
@@ -213,7 +215,7 @@ if ${FUTILITY} gbb_utility -s --recoverykey ${TMP}.data2 ${TMP}.blob.bad; then f
# See that the digest is updated properly.
hwid="123456789ABCDEF"
-${FUTILITY} gbb_utility -s -i ${hwid} ${TMP}.blob
+${FUTILITY} gbb_utility -s --hwid=${hwid} ${TMP}.blob
expect=$(echo -n "$hwid" | sha256sum | cut -d ' ' -f 1)
[ $(echo -n ${expect} | wc -c) == "64" ]
${FUTILITY} gbb_utility -g --digest ${TMP}.blob | grep ${expect}