blob: 3bf3492b081649c6e1f7c0c82b284016da5c396d [file] [log] [blame]
Bill Richardson6f396152014-07-15 12:52:19 -07001/* Copyright 2011 The Chromium OS Authors. All rights reserved.
Randall Spanglerdcab8fa2010-06-15 14:50:51 -07002 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Verified boot firmware utility
6 */
7
8#include <getopt.h>
Bill Richardson31d95c22014-08-24 22:07:17 -07009#include <inttypes.h> /* For PRIu64 */
Randall Spanglerdcab8fa2010-06-15 14:50:51 -070010#include <stddef.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <unistd.h>
14
Randall Spangler98263a12016-06-02 16:05:49 -070015#include "2sysincludes.h"
16#include "2api.h"
17#include "2common.h"
18#include "2rsa.h"
Bill Richardson6f396152014-07-15 12:52:19 -070019#include "futility.h"
Randall Spanglerdcab8fa2010-06-15 14:50:51 -070020#include "host_common.h"
Randall Spangler98263a12016-06-02 16:05:49 -070021#include "host_key2.h"
Randall Spanglerdcab8fa2010-06-15 14:50:51 -070022#include "kernel_blob.h"
Bill Richardson78299022014-06-20 14:33:00 -070023#include "util_misc.h"
Randall Spanglerdcab8fa2010-06-15 14:50:51 -070024#include "vboot_common.h"
Randall Spangler98263a12016-06-02 16:05:49 -070025#include "vb1_helper.h"
26#include "vb2_common.h"
Randall Spanglerdcab8fa2010-06-15 14:50:51 -070027
Randall Spanglerdcab8fa2010-06-15 14:50:51 -070028/* Command line options */
29enum {
Bill Richardson31d95c22014-08-24 22:07:17 -070030 OPT_MODE_VBLOCK = 1000,
31 OPT_MODE_VERIFY,
32 OPT_KEYBLOCK,
33 OPT_SIGNPUBKEY,
34 OPT_SIGNPRIVATE,
35 OPT_VERSION,
36 OPT_FV,
37 OPT_KERNELKEY,
38 OPT_FLAGS,
Bill Richardson01466d32015-03-11 11:21:47 -070039 OPT_HELP,
Randall Spanglerdcab8fa2010-06-15 14:50:51 -070040};
41
Mike Frysinger7351ed72014-08-18 10:47:42 -040042static const struct option long_opts[] = {
Bill Richardson31d95c22014-08-24 22:07:17 -070043 {"vblock", 1, 0, OPT_MODE_VBLOCK},
44 {"verify", 1, 0, OPT_MODE_VERIFY},
45 {"keyblock", 1, 0, OPT_KEYBLOCK},
46 {"signpubkey", 1, 0, OPT_SIGNPUBKEY},
47 {"signprivate", 1, 0, OPT_SIGNPRIVATE},
48 {"version", 1, 0, OPT_VERSION},
49 {"fv", 1, 0, OPT_FV},
50 {"kernelkey", 1, 0, OPT_KERNELKEY},
51 {"flags", 1, 0, OPT_FLAGS},
Bill Richardson01466d32015-03-11 11:21:47 -070052 {"help", 0, 0, OPT_HELP},
Bill Richardson31d95c22014-08-24 22:07:17 -070053 {NULL, 0, 0, 0}
Randall Spanglerdcab8fa2010-06-15 14:50:51 -070054};
55
Randall Spanglerdcab8fa2010-06-15 14:50:51 -070056/* Print help and return error */
Bill Richardson49a422f2015-03-05 13:49:36 -080057static void print_help(int argc, char *argv[])
Bill Richardson31d95c22014-08-24 22:07:17 -070058{
Bill Richardson779796f2014-09-23 11:47:40 -070059 printf("\nUsage: " MYNAME " %s <--vblock|--verify> <file> [OPTIONS]\n"
60 "\n"
61 "For '--vblock <file>', required OPTIONS are:\n"
62 "\n"
63 " --keyblock <file> Key block in .keyblock format\n"
64 " --signprivate <file>"
65 " Signing private key in .vbprivk format\n"
66 " --version <number> Firmware version\n"
67 " --fv <file> Firmware volume to sign\n"
68 " --kernelkey <file> Kernel subkey in .vbpubk format\n"
69 "\n"
70 "optional OPTIONS are:\n"
71 " --flags <number> Preamble flags (defaults to 0)\n"
72 "\n"
73 "For '--verify <file>', required OPTIONS are:\n"
74 "\n"
75 " --signpubkey <file>"
76 " Signing public key in .vbpubk format\n"
77 " --fv <file> Firmware volume to verify\n"
78 "\n"
79 "For '--verify <file>', optional OPTIONS are:\n"
80 " --kernelkey <file>"
81 " Write the kernel subkey to this file\n\n",
Bill Richardson49a422f2015-03-05 13:49:36 -080082 argv[0]);
Randall Spanglerdcab8fa2010-06-15 14:50:51 -070083}
84
Randall Spanglerdcab8fa2010-06-15 14:50:51 -070085/* Create a firmware .vblock */
Randall Spanglerd46461c2016-06-22 16:46:23 -070086static int do_vblock(const char *outfile, const char *keyblock_file,
87 const char *signprivate, uint32_t version,
88 const char *fv_file, const char *kernelkey_file,
89 uint32_t preamble_flags)
Bill Richardson31d95c22014-08-24 22:07:17 -070090{
Randall Spanglerd8a9ede2016-09-02 12:25:27 -070091 struct vb2_keyblock *keyblock = NULL;
92 struct vb2_private_key *signing_key = NULL;
93 struct vb2_packed_key *kernel_subkey = NULL;
94 struct vb2_signature *body_sig = NULL;
95 struct vb2_fw_preamble *preamble = NULL;
96 uint8_t *fv_data = NULL;
97 int retval = 1;
98
Bill Richardson31d95c22014-08-24 22:07:17 -070099 if (!outfile) {
100 VbExError("Must specify output filename\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700101 goto vblock_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700102 }
103 if (!keyblock_file || !signprivate || !kernelkey_file) {
104 VbExError("Must specify all keys\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700105 goto vblock_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700106 }
107 if (!fv_file) {
108 VbExError("Must specify firmware volume\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700109 goto vblock_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700110 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700111
Bill Richardson31d95c22014-08-24 22:07:17 -0700112 /* Read the key block and keys */
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700113 keyblock = vb2_read_keyblock(keyblock_file);
Randall Spangler939cc3a2016-06-21 15:23:32 -0700114 if (!keyblock) {
Bill Richardson31d95c22014-08-24 22:07:17 -0700115 VbExError("Error reading key block.\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700116 goto vblock_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700117 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700118
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700119 signing_key = vb2_read_private_key(signprivate);
Bill Richardson31d95c22014-08-24 22:07:17 -0700120 if (!signing_key) {
121 VbExError("Error reading signing key.\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700122 goto vblock_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700123 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700124
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700125 kernel_subkey = vb2_read_packed_key(kernelkey_file);
Bill Richardson31d95c22014-08-24 22:07:17 -0700126 if (!kernel_subkey) {
127 VbExError("Error reading kernel subkey.\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700128 goto vblock_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700129 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700130
Bill Richardson31d95c22014-08-24 22:07:17 -0700131 /* Read and sign the firmware volume */
Randall Spanglerd46461c2016-06-22 16:46:23 -0700132 uint32_t fv_size;
133 if (VB2_SUCCESS != vb2_read_file(fv_file, &fv_data, &fv_size))
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700134 goto vblock_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700135 if (!fv_size) {
136 VbExError("Empty firmware volume file\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700137 goto vblock_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700138 }
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700139 body_sig = vb2_calculate_signature(fv_data, fv_size, signing_key);
Bill Richardson31d95c22014-08-24 22:07:17 -0700140 if (!body_sig) {
141 VbExError("Error calculating body signature\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700142 goto vblock_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700143 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700144
Bill Richardson31d95c22014-08-24 22:07:17 -0700145 /* Create preamble */
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700146 preamble = vb2_create_fw_preamble(version, kernel_subkey, body_sig,
147 signing_key, preamble_flags);
Bill Richardson31d95c22014-08-24 22:07:17 -0700148 if (!preamble) {
149 VbExError("Error creating preamble.\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700150 goto vblock_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700151 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700152
Bill Richardson31d95c22014-08-24 22:07:17 -0700153 /* Write the output file */
Randall Spanglerd46461c2016-06-22 16:46:23 -0700154 FILE *f = fopen(outfile, "wb");
Bill Richardson31d95c22014-08-24 22:07:17 -0700155 if (!f) {
156 VbExError("Can't open output file %s\n", outfile);
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700157 goto vblock_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700158 }
Randall Spanglerd46461c2016-06-22 16:46:23 -0700159 int i = ((1 != fwrite(keyblock, keyblock->keyblock_size, 1, f)) ||
160 (1 != fwrite(preamble, preamble->preamble_size, 1, f)));
Bill Richardson31d95c22014-08-24 22:07:17 -0700161 fclose(f);
162 if (i) {
163 VbExError("Can't write output file %s\n", outfile);
164 unlink(outfile);
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700165 goto vblock_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700166 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700167
Bill Richardson31d95c22014-08-24 22:07:17 -0700168 /* Success */
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700169 retval = 0;
170
171vblock_cleanup:
172 if (keyblock)
173 free(keyblock);
174 if (signing_key)
175 free(signing_key);
176 if (kernel_subkey)
177 free(kernel_subkey);
178 if (fv_data)
179 free(fv_data);
180 if (body_sig)
181 free(body_sig);
182 if (preamble)
183 free(preamble);
184
185 return retval;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700186}
187
Randall Spanglerd46461c2016-06-22 16:46:23 -0700188static int do_verify(const char *infile, const char *signpubkey,
189 const char *fv_file, const char *kernelkey_file)
Bill Richardson31d95c22014-08-24 22:07:17 -0700190{
Randall Spangler98263a12016-06-02 16:05:49 -0700191 uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE];
192 struct vb2_workbuf wb;
193 vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700194
Randall Spangler98263a12016-06-02 16:05:49 -0700195 uint32_t now = 0;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700196
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700197 uint8_t *pubkbuf = NULL;
198 uint8_t *blob = NULL;
199 uint8_t *fv_data = NULL;
200 int retval = 1;
201
Bill Richardson31d95c22014-08-24 22:07:17 -0700202 if (!infile || !signpubkey || !fv_file) {
203 VbExError("Must specify filename, signpubkey, and fv\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700204 goto verify_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700205 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700206
Bill Richardson31d95c22014-08-24 22:07:17 -0700207 /* Read public signing key */
Randall Spangler98263a12016-06-02 16:05:49 -0700208 uint32_t pubklen;
209 struct vb2_public_key sign_key;
210 if (VB2_SUCCESS != vb2_read_file(signpubkey, &pubkbuf, &pubklen)) {
211 fprintf(stderr, "Error reading signpubkey.\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700212 goto verify_cleanup;
Randall Spangler98263a12016-06-02 16:05:49 -0700213 }
214 if (VB2_SUCCESS != vb2_unpack_key(&sign_key, pubkbuf, pubklen)) {
215 fprintf(stderr, "Error unpacking signpubkey.\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700216 goto verify_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700217 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700218
Bill Richardson31d95c22014-08-24 22:07:17 -0700219 /* Read blob */
Randall Spangler98263a12016-06-02 16:05:49 -0700220 uint32_t blob_size;
221 if (VB2_SUCCESS != vb2_read_file(infile, &blob, &blob_size)) {
Bill Richardson31d95c22014-08-24 22:07:17 -0700222 VbExError("Error reading input file\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700223 goto verify_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700224 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700225
Bill Richardson31d95c22014-08-24 22:07:17 -0700226 /* Read firmware volume */
Randall Spangler98263a12016-06-02 16:05:49 -0700227 uint32_t fv_size;
228 if (VB2_SUCCESS != vb2_read_file(fv_file, &fv_data, &fv_size)) {
Bill Richardson31d95c22014-08-24 22:07:17 -0700229 VbExError("Error reading firmware volume\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700230 goto verify_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700231 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700232
Bill Richardson31d95c22014-08-24 22:07:17 -0700233 /* Verify key block */
Randall Spangler98263a12016-06-02 16:05:49 -0700234 struct vb2_keyblock *keyblock = (struct vb2_keyblock *)blob;
235 if (VB2_SUCCESS !=
236 vb2_verify_keyblock(keyblock, blob_size, &sign_key, &wb)) {
Bill Richardson31d95c22014-08-24 22:07:17 -0700237 VbExError("Error verifying key block.\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700238 goto verify_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700239 }
Randall Spangler98263a12016-06-02 16:05:49 -0700240
241 now += keyblock->keyblock_size;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700242
Bill Richardson31d95c22014-08-24 22:07:17 -0700243 printf("Key block:\n");
Randall Spangler98263a12016-06-02 16:05:49 -0700244 printf(" Size: %d\n", keyblock->keyblock_size);
245 printf(" Flags: %d (ignored)\n",
246 keyblock->keyblock_flags);
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700247
Randall Spangler98263a12016-06-02 16:05:49 -0700248 struct vb2_packed_key *packed_key = &keyblock->data_key;
249 printf(" Data key algorithm: %d %s\n", packed_key->algorithm,
Randall Spangler46a382d2016-10-18 12:00:07 -0700250 vb2_get_crypto_algorithm_name(packed_key->algorithm));
Randall Spangler98263a12016-06-02 16:05:49 -0700251 printf(" Data key version: %d\n", packed_key->key_version);
252 printf(" Data key sha1sum: %s\n",
253 packed_key_sha1_string(packed_key));
254
255 struct vb2_public_key data_key;
256 if (VB2_SUCCESS !=
257 vb2_unpack_key(&data_key, (const uint8_t *)&keyblock->data_key,
258 keyblock->data_key.key_offset +
259 keyblock->data_key.key_size)) {
260 fprintf(stderr, "Error parsing data key.\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700261 goto verify_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700262 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700263
Bill Richardson31d95c22014-08-24 22:07:17 -0700264 /* Verify preamble */
Randall Spangler98263a12016-06-02 16:05:49 -0700265 struct vb2_fw_preamble *pre2 = (struct vb2_fw_preamble *)(blob + now);
266 if (VB2_SUCCESS !=
267 vb2_verify_fw_preamble(pre2, blob_size - now, &data_key, &wb)) {
268 VbExError("Error2 verifying preamble.\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700269 goto verify_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700270 }
Randall Spangler98263a12016-06-02 16:05:49 -0700271 now += pre2->preamble_size;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700272
Randall Spangler98263a12016-06-02 16:05:49 -0700273 uint32_t flags = pre2->flags;
274 if (pre2->header_version_minor < 1)
275 flags = 0; /* Old 2.0 structure didn't have flags */
276
Bill Richardson31d95c22014-08-24 22:07:17 -0700277 printf("Preamble:\n");
Randall Spangler98263a12016-06-02 16:05:49 -0700278 printf(" Size: %d\n", pre2->preamble_size);
279 printf(" Header version: %d.%d\n",
280 pre2->header_version_major, pre2->header_version_minor);
281 printf(" Firmware version: %d\n", pre2->firmware_version);
282
283 struct vb2_packed_key *kernel_subkey = &pre2->kernel_subkey;
284 printf(" Kernel key algorithm: %d %s\n", kernel_subkey->algorithm,
Randall Spangler46a382d2016-10-18 12:00:07 -0700285 vb2_get_crypto_algorithm_name(kernel_subkey->algorithm));
Randall Spangler98263a12016-06-02 16:05:49 -0700286 printf(" Kernel key version: %d\n", kernel_subkey->key_version);
287 printf(" Kernel key sha1sum: %s\n",
288 packed_key_sha1_string(kernel_subkey));
289 printf(" Firmware body size: %d\n", pre2->body_signature.data_size);
290 printf(" Preamble flags: %d\n", flags);
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700291
Bill Richardson31d95c22014-08-24 22:07:17 -0700292 /* TODO: verify body size same as signature size */
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700293
Bill Richardson31d95c22014-08-24 22:07:17 -0700294 /* Verify body */
Randall Spangler814aaf02016-06-17 10:48:16 -0700295 if (flags & VB2_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
Randall Spangler98263a12016-06-02 16:05:49 -0700296 printf("Preamble requests USE_RO_NORMAL;"
297 " skipping body verification.\n");
298 } else if (VB2_SUCCESS ==
299 vb2_verify_data(fv_data, fv_size, &pre2->body_signature,
300 &data_key, &wb)) {
Bill Richardson31d95c22014-08-24 22:07:17 -0700301 printf("Body verification succeeded.\n");
Randall Spangler98263a12016-06-02 16:05:49 -0700302 } else {
303 VbExError("Error verifying firmware body.\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700304 goto verify_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700305 }
Bill Richardson60bcbe32010-09-09 14:53:56 -0700306
Randall Spanglerf7559e42016-06-23 13:45:59 -0700307 if (kernelkey_file &&
308 VB2_SUCCESS != vb2_write_packed_key(kernelkey_file,
309 kernel_subkey)) {
310 VbExError("Unable to write kernel subkey\n");
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700311 goto verify_cleanup;
Bill Richardson31d95c22014-08-24 22:07:17 -0700312 }
Bill Richardson60bcbe32010-09-09 14:53:56 -0700313
Randall Spanglerd8a9ede2016-09-02 12:25:27 -0700314 /* Success */
315 retval = 0;
316
317verify_cleanup:
318 if (pubkbuf)
319 free(pubkbuf);
320 if (blob)
321 free(blob);
322 if (fv_data)
323 free(fv_data);
324
325 return retval;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700326}
327
Bill Richardson31d95c22014-08-24 22:07:17 -0700328static int do_vbutil_firmware(int argc, char *argv[])
329{
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700330
Bill Richardson31d95c22014-08-24 22:07:17 -0700331 char *filename = NULL;
332 char *key_block_file = NULL;
333 char *signpubkey = NULL;
334 char *signprivate = NULL;
Randall Spanglerd46461c2016-06-22 16:46:23 -0700335 uint32_t version = 0;
Bill Richardson31d95c22014-08-24 22:07:17 -0700336 char *fv_file = NULL;
337 char *kernelkey_file = NULL;
338 uint32_t preamble_flags = 0;
339 int mode = 0;
340 int parse_error = 0;
341 char *e;
342 int i;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700343
Bill Richardson31d95c22014-08-24 22:07:17 -0700344 while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
345 switch (i) {
346 case '?':
347 /* Unhandled option */
348 printf("Unknown option\n");
349 parse_error = 1;
350 break;
Bill Richardson01466d32015-03-11 11:21:47 -0700351 case OPT_HELP:
352 print_help(argc, argv);
353 return !!parse_error;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700354
Bill Richardson31d95c22014-08-24 22:07:17 -0700355 case OPT_MODE_VBLOCK:
356 case OPT_MODE_VERIFY:
357 mode = i;
358 filename = optarg;
359 break;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700360
Bill Richardson31d95c22014-08-24 22:07:17 -0700361 case OPT_KEYBLOCK:
362 key_block_file = optarg;
363 break;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700364
Bill Richardson31d95c22014-08-24 22:07:17 -0700365 case OPT_SIGNPUBKEY:
366 signpubkey = optarg;
367 break;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700368
Bill Richardson31d95c22014-08-24 22:07:17 -0700369 case OPT_SIGNPRIVATE:
370 signprivate = optarg;
371 break;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700372
Bill Richardson31d95c22014-08-24 22:07:17 -0700373 case OPT_FV:
374 fv_file = optarg;
375 break;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700376
Bill Richardson31d95c22014-08-24 22:07:17 -0700377 case OPT_KERNELKEY:
378 kernelkey_file = optarg;
379 break;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700380
Bill Richardson31d95c22014-08-24 22:07:17 -0700381 case OPT_VERSION:
382 version = strtoul(optarg, &e, 0);
383 if (!*optarg || (e && *e)) {
384 printf("Invalid --version\n");
385 parse_error = 1;
386 }
387 break;
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700388
Bill Richardson31d95c22014-08-24 22:07:17 -0700389 case OPT_FLAGS:
390 preamble_flags = strtoul(optarg, &e, 0);
391 if (!*optarg || (e && *e)) {
392 printf("Invalid --flags\n");
393 parse_error = 1;
394 }
395 break;
396 }
397 }
Randall Spanglera712e012011-07-13 09:48:41 -0700398
Bill Richardson779796f2014-09-23 11:47:40 -0700399 if (parse_error) {
Bill Richardson49a422f2015-03-05 13:49:36 -0800400 print_help(argc, argv);
Bill Richardson779796f2014-09-23 11:47:40 -0700401 return 1;
402 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700403
Bill Richardson31d95c22014-08-24 22:07:17 -0700404 switch (mode) {
405 case OPT_MODE_VBLOCK:
Randall Spanglerd46461c2016-06-22 16:46:23 -0700406 return do_vblock(filename, key_block_file, signprivate, version,
407 fv_file, kernelkey_file, preamble_flags);
Bill Richardson31d95c22014-08-24 22:07:17 -0700408 case OPT_MODE_VERIFY:
Randall Spanglerd46461c2016-06-22 16:46:23 -0700409 return do_verify(filename, signpubkey, fv_file, kernelkey_file);
Bill Richardson31d95c22014-08-24 22:07:17 -0700410 default:
Bill Richardson779796f2014-09-23 11:47:40 -0700411 fprintf(stderr, "Must specify a mode.\n");
Bill Richardson49a422f2015-03-05 13:49:36 -0800412 print_help(argc, argv);
Bill Richardson779796f2014-09-23 11:47:40 -0700413 return 1;
Bill Richardson31d95c22014-08-24 22:07:17 -0700414 }
Randall Spanglerdcab8fa2010-06-15 14:50:51 -0700415}
Bill Richardson6f396152014-07-15 12:52:19 -0700416
Bill Richardson01466d32015-03-11 11:21:47 -0700417DECLARE_FUTIL_COMMAND(vbutil_firmware, do_vbutil_firmware, VBOOT_VERSION_1_0,
418 "Verified boot firmware utility");