1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2011 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker *
5*8617a60dSAndroid Build Coastguard Worker * Verified boot keyblock utility
6*8617a60dSAndroid Build Coastguard Worker */
7*8617a60dSAndroid Build Coastguard Worker
8*8617a60dSAndroid Build Coastguard Worker #include <getopt.h>
9*8617a60dSAndroid Build Coastguard Worker #include <stdint.h>
10*8617a60dSAndroid Build Coastguard Worker #include <stdio.h>
11*8617a60dSAndroid Build Coastguard Worker #include <stdlib.h>
12*8617a60dSAndroid Build Coastguard Worker #include <string.h>
13*8617a60dSAndroid Build Coastguard Worker
14*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
15*8617a60dSAndroid Build Coastguard Worker #include "2rsa.h"
16*8617a60dSAndroid Build Coastguard Worker #include "2sysincludes.h"
17*8617a60dSAndroid Build Coastguard Worker #include "futility.h"
18*8617a60dSAndroid Build Coastguard Worker #include "host_common.h"
19*8617a60dSAndroid Build Coastguard Worker #include "host_key21.h"
20*8617a60dSAndroid Build Coastguard Worker #include "util_misc.h"
21*8617a60dSAndroid Build Coastguard Worker #include "vb1_helper.h"
22*8617a60dSAndroid Build Coastguard Worker
23*8617a60dSAndroid Build Coastguard Worker /* Command line options */
24*8617a60dSAndroid Build Coastguard Worker enum {
25*8617a60dSAndroid Build Coastguard Worker OPT_MODE_PACK = 1000,
26*8617a60dSAndroid Build Coastguard Worker OPT_MODE_UNPACK,
27*8617a60dSAndroid Build Coastguard Worker OPT_DATAPUBKEY,
28*8617a60dSAndroid Build Coastguard Worker OPT_SIGNPUBKEY,
29*8617a60dSAndroid Build Coastguard Worker OPT_SIGNPRIVATE,
30*8617a60dSAndroid Build Coastguard Worker OPT_SIGNPRIVATE_PEM,
31*8617a60dSAndroid Build Coastguard Worker OPT_PEM_ALGORITHM,
32*8617a60dSAndroid Build Coastguard Worker OPT_EXTERNAL_SIGNER,
33*8617a60dSAndroid Build Coastguard Worker OPT_FLAGS,
34*8617a60dSAndroid Build Coastguard Worker OPT_HELP,
35*8617a60dSAndroid Build Coastguard Worker };
36*8617a60dSAndroid Build Coastguard Worker
37*8617a60dSAndroid Build Coastguard Worker static const struct option long_opts[] = {
38*8617a60dSAndroid Build Coastguard Worker {"pack", 1, 0, OPT_MODE_PACK},
39*8617a60dSAndroid Build Coastguard Worker {"unpack", 1, 0, OPT_MODE_UNPACK},
40*8617a60dSAndroid Build Coastguard Worker {"datapubkey", 1, 0, OPT_DATAPUBKEY},
41*8617a60dSAndroid Build Coastguard Worker {"signpubkey", 1, 0, OPT_SIGNPUBKEY},
42*8617a60dSAndroid Build Coastguard Worker {"signprivate", 1, 0, OPT_SIGNPRIVATE},
43*8617a60dSAndroid Build Coastguard Worker {"signprivate_pem", 1, 0, OPT_SIGNPRIVATE_PEM},
44*8617a60dSAndroid Build Coastguard Worker {"pem_algorithm", 1, 0, OPT_PEM_ALGORITHM},
45*8617a60dSAndroid Build Coastguard Worker {"externalsigner", 1, 0, OPT_EXTERNAL_SIGNER},
46*8617a60dSAndroid Build Coastguard Worker {"flags", 1, 0, OPT_FLAGS},
47*8617a60dSAndroid Build Coastguard Worker {"help", 0, 0, OPT_HELP},
48*8617a60dSAndroid Build Coastguard Worker {NULL, 0, 0, 0}
49*8617a60dSAndroid Build Coastguard Worker };
50*8617a60dSAndroid Build Coastguard Worker
51*8617a60dSAndroid Build Coastguard Worker static const char usage[] =
52*8617a60dSAndroid Build Coastguard Worker "\n"
53*8617a60dSAndroid Build Coastguard Worker "Usage: " MYNAME " %s <--pack|--unpack> <file> [OPTIONS]\n"
54*8617a60dSAndroid Build Coastguard Worker "\n"
55*8617a60dSAndroid Build Coastguard Worker "For '--pack <file>', required OPTIONS are:\n"
56*8617a60dSAndroid Build Coastguard Worker " --datapubkey <file> Data public key in .vbpubk format\n"
57*8617a60dSAndroid Build Coastguard Worker "\n"
58*8617a60dSAndroid Build Coastguard Worker "Optional OPTIONS are:\n"
59*8617a60dSAndroid Build Coastguard Worker " --signprivate <file>"
60*8617a60dSAndroid Build Coastguard Worker " Signing private key in .vbprivk format.\n"
61*8617a60dSAndroid Build Coastguard Worker "OR\n"
62*8617a60dSAndroid Build Coastguard Worker " --signprivate_pem <file>\n"
63*8617a60dSAndroid Build Coastguard Worker " --pem_algorithm <algo>\n"
64*8617a60dSAndroid Build Coastguard Worker " Signing private key in .pem format and algorithm id.\n"
65*8617a60dSAndroid Build Coastguard Worker "(If one of the above arguments is not specified, the keyblock will\n"
66*8617a60dSAndroid Build Coastguard Worker "not be signed.)\n"
67*8617a60dSAndroid Build Coastguard Worker "\n"
68*8617a60dSAndroid Build Coastguard Worker " --flags <number> Specifies allowed use conditions.\n"
69*8617a60dSAndroid Build Coastguard Worker " --externalsigner \"cmd\""
70*8617a60dSAndroid Build Coastguard Worker " Use an external program cmd to calculate the signatures.\n"
71*8617a60dSAndroid Build Coastguard Worker "\n"
72*8617a60dSAndroid Build Coastguard Worker "For '--unpack <file>', optional OPTIONS are:\n"
73*8617a60dSAndroid Build Coastguard Worker " --signpubkey <file>"
74*8617a60dSAndroid Build Coastguard Worker " Signing public key in .vbpubk format. This is required to\n"
75*8617a60dSAndroid Build Coastguard Worker " verify a signed keyblock.\n"
76*8617a60dSAndroid Build Coastguard Worker " --datapubkey <file>"
77*8617a60dSAndroid Build Coastguard Worker " Write the data public key to this file.\n\n";
78*8617a60dSAndroid Build Coastguard Worker
print_help(int argc,char * argv[])79*8617a60dSAndroid Build Coastguard Worker static void print_help(int argc, char *argv[])
80*8617a60dSAndroid Build Coastguard Worker {
81*8617a60dSAndroid Build Coastguard Worker printf(usage, argv[0]);
82*8617a60dSAndroid Build Coastguard Worker }
83*8617a60dSAndroid Build Coastguard Worker
84*8617a60dSAndroid Build Coastguard Worker /* Pack a .keyblock */
Pack(const char * outfile,const char * datapubkey,const char * signprivate,const char * signprivate_pem,uint64_t pem_algorithm,uint64_t flags,const char * external_signer)85*8617a60dSAndroid Build Coastguard Worker static int Pack(const char *outfile, const char *datapubkey,
86*8617a60dSAndroid Build Coastguard Worker const char *signprivate,
87*8617a60dSAndroid Build Coastguard Worker const char *signprivate_pem, uint64_t pem_algorithm,
88*8617a60dSAndroid Build Coastguard Worker uint64_t flags, const char *external_signer)
89*8617a60dSAndroid Build Coastguard Worker {
90*8617a60dSAndroid Build Coastguard Worker struct vb2_private_key *signing_key = NULL;
91*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *block;
92*8617a60dSAndroid Build Coastguard Worker
93*8617a60dSAndroid Build Coastguard Worker if (!outfile) {
94*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock: Must specify output filename.\n");
95*8617a60dSAndroid Build Coastguard Worker return 1;
96*8617a60dSAndroid Build Coastguard Worker }
97*8617a60dSAndroid Build Coastguard Worker if (!datapubkey) {
98*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock: Must specify data public key.\n");
99*8617a60dSAndroid Build Coastguard Worker return 1;
100*8617a60dSAndroid Build Coastguard Worker }
101*8617a60dSAndroid Build Coastguard Worker
102*8617a60dSAndroid Build Coastguard Worker struct vb2_packed_key *data_key = vb2_read_packed_key(datapubkey);
103*8617a60dSAndroid Build Coastguard Worker if (!data_key) {
104*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock: Error reading data key.\n");
105*8617a60dSAndroid Build Coastguard Worker return 1;
106*8617a60dSAndroid Build Coastguard Worker }
107*8617a60dSAndroid Build Coastguard Worker
108*8617a60dSAndroid Build Coastguard Worker if (signprivate_pem) {
109*8617a60dSAndroid Build Coastguard Worker if (pem_algorithm >= VB2_ALG_COUNT) {
110*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock: Invalid --pem_algorithm %"
111*8617a60dSAndroid Build Coastguard Worker PRIu64 "\n", pem_algorithm);
112*8617a60dSAndroid Build Coastguard Worker return 1;
113*8617a60dSAndroid Build Coastguard Worker }
114*8617a60dSAndroid Build Coastguard Worker if (external_signer) {
115*8617a60dSAndroid Build Coastguard Worker /* External signing uses the PEM file directly. */
116*8617a60dSAndroid Build Coastguard Worker block = vb2_create_keyblock_external(data_key,
117*8617a60dSAndroid Build Coastguard Worker signprivate_pem,
118*8617a60dSAndroid Build Coastguard Worker pem_algorithm,
119*8617a60dSAndroid Build Coastguard Worker flags,
120*8617a60dSAndroid Build Coastguard Worker external_signer);
121*8617a60dSAndroid Build Coastguard Worker } else {
122*8617a60dSAndroid Build Coastguard Worker signing_key =
123*8617a60dSAndroid Build Coastguard Worker vb2_read_private_key_pem(signprivate_pem,
124*8617a60dSAndroid Build Coastguard Worker pem_algorithm);
125*8617a60dSAndroid Build Coastguard Worker if (!signing_key) {
126*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock:"
127*8617a60dSAndroid Build Coastguard Worker " Error reading signing key.\n");
128*8617a60dSAndroid Build Coastguard Worker return 1;
129*8617a60dSAndroid Build Coastguard Worker }
130*8617a60dSAndroid Build Coastguard Worker block = vb2_create_keyblock(data_key, signing_key,
131*8617a60dSAndroid Build Coastguard Worker flags);
132*8617a60dSAndroid Build Coastguard Worker }
133*8617a60dSAndroid Build Coastguard Worker } else {
134*8617a60dSAndroid Build Coastguard Worker if (signprivate) {
135*8617a60dSAndroid Build Coastguard Worker signing_key = vb2_read_private_key(signprivate);
136*8617a60dSAndroid Build Coastguard Worker if (!signing_key) {
137*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock:"
138*8617a60dSAndroid Build Coastguard Worker " Error reading signing key.\n");
139*8617a60dSAndroid Build Coastguard Worker return 1;
140*8617a60dSAndroid Build Coastguard Worker }
141*8617a60dSAndroid Build Coastguard Worker }
142*8617a60dSAndroid Build Coastguard Worker block = vb2_create_keyblock(data_key, signing_key, flags);
143*8617a60dSAndroid Build Coastguard Worker }
144*8617a60dSAndroid Build Coastguard Worker
145*8617a60dSAndroid Build Coastguard Worker free(data_key);
146*8617a60dSAndroid Build Coastguard Worker if (signing_key)
147*8617a60dSAndroid Build Coastguard Worker free(signing_key);
148*8617a60dSAndroid Build Coastguard Worker
149*8617a60dSAndroid Build Coastguard Worker if (VB2_SUCCESS != vb2_write_keyblock(outfile, block)) {
150*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock: Error writing keyblock.\n");
151*8617a60dSAndroid Build Coastguard Worker return 1;
152*8617a60dSAndroid Build Coastguard Worker }
153*8617a60dSAndroid Build Coastguard Worker free(block);
154*8617a60dSAndroid Build Coastguard Worker return 0;
155*8617a60dSAndroid Build Coastguard Worker }
156*8617a60dSAndroid Build Coastguard Worker
Unpack(const char * infile,const char * datapubkey,const char * signpubkey)157*8617a60dSAndroid Build Coastguard Worker static int Unpack(const char *infile, const char *datapubkey,
158*8617a60dSAndroid Build Coastguard Worker const char *signpubkey)
159*8617a60dSAndroid Build Coastguard Worker {
160*8617a60dSAndroid Build Coastguard Worker struct vb2_packed_key *sign_key = NULL;
161*8617a60dSAndroid Build Coastguard Worker
162*8617a60dSAndroid Build Coastguard Worker if (!infile) {
163*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock: Must specify filename\n");
164*8617a60dSAndroid Build Coastguard Worker return 1;
165*8617a60dSAndroid Build Coastguard Worker }
166*8617a60dSAndroid Build Coastguard Worker
167*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *block = vb2_read_keyblock(infile);
168*8617a60dSAndroid Build Coastguard Worker if (!block) {
169*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock: Error reading keyblock.\n");
170*8617a60dSAndroid Build Coastguard Worker return 1;
171*8617a60dSAndroid Build Coastguard Worker }
172*8617a60dSAndroid Build Coastguard Worker
173*8617a60dSAndroid Build Coastguard Worker /* If the signing public key is provided, then verify the block
174*8617a60dSAndroid Build Coastguard Worker * signature, since vb2_read_keyblock() only verified the hash. */
175*8617a60dSAndroid Build Coastguard Worker if (signpubkey) {
176*8617a60dSAndroid Build Coastguard Worker static uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE]
177*8617a60dSAndroid Build Coastguard Worker __attribute__((aligned(VB2_WORKBUF_ALIGN)));
178*8617a60dSAndroid Build Coastguard Worker static struct vb2_workbuf wb;
179*8617a60dSAndroid Build Coastguard Worker
180*8617a60dSAndroid Build Coastguard Worker if (block->keyblock_signature.sig_size == 0) {
181*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock: signpubkey provided but keyblock is not signed.\n");
182*8617a60dSAndroid Build Coastguard Worker return 1;
183*8617a60dSAndroid Build Coastguard Worker }
184*8617a60dSAndroid Build Coastguard Worker
185*8617a60dSAndroid Build Coastguard Worker vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
186*8617a60dSAndroid Build Coastguard Worker
187*8617a60dSAndroid Build Coastguard Worker sign_key = vb2_read_packed_key(signpubkey);
188*8617a60dSAndroid Build Coastguard Worker if (!sign_key) {
189*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock: Error reading signpubkey.\n");
190*8617a60dSAndroid Build Coastguard Worker return 1;
191*8617a60dSAndroid Build Coastguard Worker }
192*8617a60dSAndroid Build Coastguard Worker struct vb2_public_key key;
193*8617a60dSAndroid Build Coastguard Worker if (VB2_SUCCESS != vb2_unpack_key(&key, sign_key)) {
194*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock: Error reading signpubkey.\n");
195*8617a60dSAndroid Build Coastguard Worker return 1;
196*8617a60dSAndroid Build Coastguard Worker }
197*8617a60dSAndroid Build Coastguard Worker
198*8617a60dSAndroid Build Coastguard Worker if (VB2_SUCCESS !=
199*8617a60dSAndroid Build Coastguard Worker vb2_verify_keyblock(block, block->keyblock_size,
200*8617a60dSAndroid Build Coastguard Worker &key, &wb)) {
201*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock: Error verifying keyblock.\n");
202*8617a60dSAndroid Build Coastguard Worker return 1;
203*8617a60dSAndroid Build Coastguard Worker }
204*8617a60dSAndroid Build Coastguard Worker free(sign_key);
205*8617a60dSAndroid Build Coastguard Worker }
206*8617a60dSAndroid Build Coastguard Worker
207*8617a60dSAndroid Build Coastguard Worker printf("Keyblock file: %s\n", infile);
208*8617a60dSAndroid Build Coastguard Worker printf("Signature %s\n", sign_key ? "valid" : "ignored");
209*8617a60dSAndroid Build Coastguard Worker printf("Flags: %u ", block->keyblock_flags);
210*8617a60dSAndroid Build Coastguard Worker if (block->keyblock_flags & VB2_KEYBLOCK_FLAG_DEVELOPER_0)
211*8617a60dSAndroid Build Coastguard Worker printf(" !DEV");
212*8617a60dSAndroid Build Coastguard Worker if (block->keyblock_flags & VB2_KEYBLOCK_FLAG_DEVELOPER_1)
213*8617a60dSAndroid Build Coastguard Worker printf(" DEV");
214*8617a60dSAndroid Build Coastguard Worker if (block->keyblock_flags & VB2_KEYBLOCK_FLAG_RECOVERY_0)
215*8617a60dSAndroid Build Coastguard Worker printf(" !REC");
216*8617a60dSAndroid Build Coastguard Worker if (block->keyblock_flags & VB2_KEYBLOCK_FLAG_RECOVERY_1)
217*8617a60dSAndroid Build Coastguard Worker printf(" REC");
218*8617a60dSAndroid Build Coastguard Worker if (block->keyblock_flags & VB2_KEYBLOCK_FLAG_MINIOS_0)
219*8617a60dSAndroid Build Coastguard Worker printf(" !MINIOS");
220*8617a60dSAndroid Build Coastguard Worker if (block->keyblock_flags & VB2_KEYBLOCK_FLAG_MINIOS_1)
221*8617a60dSAndroid Build Coastguard Worker printf(" MINIOS");
222*8617a60dSAndroid Build Coastguard Worker printf("\n");
223*8617a60dSAndroid Build Coastguard Worker
224*8617a60dSAndroid Build Coastguard Worker struct vb2_packed_key *data_key = &block->data_key;
225*8617a60dSAndroid Build Coastguard Worker printf("Data key algorithm: %u %s\n", data_key->algorithm,
226*8617a60dSAndroid Build Coastguard Worker vb2_get_crypto_algorithm_name(data_key->algorithm));
227*8617a60dSAndroid Build Coastguard Worker printf("Data key version: %u\n", data_key->key_version);
228*8617a60dSAndroid Build Coastguard Worker printf("Data key sha1sum: %s\n",
229*8617a60dSAndroid Build Coastguard Worker packed_key_sha1_string(data_key));
230*8617a60dSAndroid Build Coastguard Worker
231*8617a60dSAndroid Build Coastguard Worker if (datapubkey &&
232*8617a60dSAndroid Build Coastguard Worker VB2_SUCCESS != vb2_write_packed_key(datapubkey, data_key)) {
233*8617a60dSAndroid Build Coastguard Worker ERROR("vbutil_keyblock: error writing public key\n");
234*8617a60dSAndroid Build Coastguard Worker return 1;
235*8617a60dSAndroid Build Coastguard Worker }
236*8617a60dSAndroid Build Coastguard Worker
237*8617a60dSAndroid Build Coastguard Worker free(block);
238*8617a60dSAndroid Build Coastguard Worker return 0;
239*8617a60dSAndroid Build Coastguard Worker }
240*8617a60dSAndroid Build Coastguard Worker
do_vbutil_keyblock(int argc,char * argv[])241*8617a60dSAndroid Build Coastguard Worker static int do_vbutil_keyblock(int argc, char *argv[])
242*8617a60dSAndroid Build Coastguard Worker {
243*8617a60dSAndroid Build Coastguard Worker
244*8617a60dSAndroid Build Coastguard Worker char *filename = NULL;
245*8617a60dSAndroid Build Coastguard Worker char *datapubkey = NULL;
246*8617a60dSAndroid Build Coastguard Worker char *signpubkey = NULL;
247*8617a60dSAndroid Build Coastguard Worker char *signprivate = NULL;
248*8617a60dSAndroid Build Coastguard Worker char *signprivate_pem = NULL;
249*8617a60dSAndroid Build Coastguard Worker char *external_signer = NULL;
250*8617a60dSAndroid Build Coastguard Worker uint64_t flags = 0;
251*8617a60dSAndroid Build Coastguard Worker uint64_t pem_algorithm = 0;
252*8617a60dSAndroid Build Coastguard Worker int is_pem_algorithm = 0;
253*8617a60dSAndroid Build Coastguard Worker int mode = 0;
254*8617a60dSAndroid Build Coastguard Worker int parse_error = 0;
255*8617a60dSAndroid Build Coastguard Worker char *e;
256*8617a60dSAndroid Build Coastguard Worker int i;
257*8617a60dSAndroid Build Coastguard Worker
258*8617a60dSAndroid Build Coastguard Worker while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
259*8617a60dSAndroid Build Coastguard Worker switch (i) {
260*8617a60dSAndroid Build Coastguard Worker case '?':
261*8617a60dSAndroid Build Coastguard Worker /* Unhandled option */
262*8617a60dSAndroid Build Coastguard Worker printf("Unknown option\n");
263*8617a60dSAndroid Build Coastguard Worker parse_error = 1;
264*8617a60dSAndroid Build Coastguard Worker break;
265*8617a60dSAndroid Build Coastguard Worker case OPT_HELP:
266*8617a60dSAndroid Build Coastguard Worker print_help(argc, argv);
267*8617a60dSAndroid Build Coastguard Worker return !!parse_error;
268*8617a60dSAndroid Build Coastguard Worker
269*8617a60dSAndroid Build Coastguard Worker case OPT_MODE_PACK:
270*8617a60dSAndroid Build Coastguard Worker case OPT_MODE_UNPACK:
271*8617a60dSAndroid Build Coastguard Worker mode = i;
272*8617a60dSAndroid Build Coastguard Worker filename = optarg;
273*8617a60dSAndroid Build Coastguard Worker break;
274*8617a60dSAndroid Build Coastguard Worker
275*8617a60dSAndroid Build Coastguard Worker case OPT_DATAPUBKEY:
276*8617a60dSAndroid Build Coastguard Worker datapubkey = optarg;
277*8617a60dSAndroid Build Coastguard Worker break;
278*8617a60dSAndroid Build Coastguard Worker
279*8617a60dSAndroid Build Coastguard Worker case OPT_SIGNPUBKEY:
280*8617a60dSAndroid Build Coastguard Worker signpubkey = optarg;
281*8617a60dSAndroid Build Coastguard Worker break;
282*8617a60dSAndroid Build Coastguard Worker
283*8617a60dSAndroid Build Coastguard Worker case OPT_SIGNPRIVATE:
284*8617a60dSAndroid Build Coastguard Worker signprivate = optarg;
285*8617a60dSAndroid Build Coastguard Worker break;
286*8617a60dSAndroid Build Coastguard Worker
287*8617a60dSAndroid Build Coastguard Worker case OPT_SIGNPRIVATE_PEM:
288*8617a60dSAndroid Build Coastguard Worker signprivate_pem = optarg;
289*8617a60dSAndroid Build Coastguard Worker break;
290*8617a60dSAndroid Build Coastguard Worker
291*8617a60dSAndroid Build Coastguard Worker case OPT_PEM_ALGORITHM:
292*8617a60dSAndroid Build Coastguard Worker pem_algorithm = strtoul(optarg, &e, 0);
293*8617a60dSAndroid Build Coastguard Worker if (!*optarg || (e && *e)) {
294*8617a60dSAndroid Build Coastguard Worker ERROR("Invalid --pem_algorithm\n");
295*8617a60dSAndroid Build Coastguard Worker parse_error = 1;
296*8617a60dSAndroid Build Coastguard Worker } else {
297*8617a60dSAndroid Build Coastguard Worker is_pem_algorithm = 1;
298*8617a60dSAndroid Build Coastguard Worker }
299*8617a60dSAndroid Build Coastguard Worker break;
300*8617a60dSAndroid Build Coastguard Worker
301*8617a60dSAndroid Build Coastguard Worker case OPT_EXTERNAL_SIGNER:
302*8617a60dSAndroid Build Coastguard Worker external_signer = optarg;
303*8617a60dSAndroid Build Coastguard Worker break;
304*8617a60dSAndroid Build Coastguard Worker
305*8617a60dSAndroid Build Coastguard Worker case OPT_FLAGS:
306*8617a60dSAndroid Build Coastguard Worker flags = strtoul(optarg, &e, 0);
307*8617a60dSAndroid Build Coastguard Worker if (!*optarg || (e && *e)) {
308*8617a60dSAndroid Build Coastguard Worker ERROR("Invalid --flags\n");
309*8617a60dSAndroid Build Coastguard Worker parse_error = 1;
310*8617a60dSAndroid Build Coastguard Worker }
311*8617a60dSAndroid Build Coastguard Worker break;
312*8617a60dSAndroid Build Coastguard Worker }
313*8617a60dSAndroid Build Coastguard Worker }
314*8617a60dSAndroid Build Coastguard Worker
315*8617a60dSAndroid Build Coastguard Worker /* Check if the right combination of options was provided. */
316*8617a60dSAndroid Build Coastguard Worker if (signprivate && signprivate_pem) {
317*8617a60dSAndroid Build Coastguard Worker ERROR("Only one of --signprivate or --signprivate_pem must"
318*8617a60dSAndroid Build Coastguard Worker " be specified\n");
319*8617a60dSAndroid Build Coastguard Worker parse_error = 1;
320*8617a60dSAndroid Build Coastguard Worker }
321*8617a60dSAndroid Build Coastguard Worker
322*8617a60dSAndroid Build Coastguard Worker if (signprivate_pem && !is_pem_algorithm) {
323*8617a60dSAndroid Build Coastguard Worker ERROR("--pem_algorithm must be used with"
324*8617a60dSAndroid Build Coastguard Worker " --signprivate_pem\n");
325*8617a60dSAndroid Build Coastguard Worker parse_error = 1;
326*8617a60dSAndroid Build Coastguard Worker }
327*8617a60dSAndroid Build Coastguard Worker
328*8617a60dSAndroid Build Coastguard Worker if (external_signer && !signprivate_pem) {
329*8617a60dSAndroid Build Coastguard Worker ERROR("--externalsigner must be used with --signprivate_pem\n");
330*8617a60dSAndroid Build Coastguard Worker parse_error = 1;
331*8617a60dSAndroid Build Coastguard Worker }
332*8617a60dSAndroid Build Coastguard Worker
333*8617a60dSAndroid Build Coastguard Worker if (parse_error) {
334*8617a60dSAndroid Build Coastguard Worker print_help(argc, argv);
335*8617a60dSAndroid Build Coastguard Worker return 1;
336*8617a60dSAndroid Build Coastguard Worker }
337*8617a60dSAndroid Build Coastguard Worker
338*8617a60dSAndroid Build Coastguard Worker switch (mode) {
339*8617a60dSAndroid Build Coastguard Worker case OPT_MODE_PACK:
340*8617a60dSAndroid Build Coastguard Worker return Pack(filename, datapubkey, signprivate,
341*8617a60dSAndroid Build Coastguard Worker signprivate_pem, pem_algorithm,
342*8617a60dSAndroid Build Coastguard Worker flags, external_signer);
343*8617a60dSAndroid Build Coastguard Worker case OPT_MODE_UNPACK:
344*8617a60dSAndroid Build Coastguard Worker return Unpack(filename, datapubkey, signpubkey);
345*8617a60dSAndroid Build Coastguard Worker default:
346*8617a60dSAndroid Build Coastguard Worker printf("Must specify a mode.\n");
347*8617a60dSAndroid Build Coastguard Worker print_help(argc, argv);
348*8617a60dSAndroid Build Coastguard Worker return 1;
349*8617a60dSAndroid Build Coastguard Worker }
350*8617a60dSAndroid Build Coastguard Worker }
351*8617a60dSAndroid Build Coastguard Worker
352*8617a60dSAndroid Build Coastguard Worker DECLARE_FUTIL_COMMAND(vbutil_keyblock, do_vbutil_keyblock, VBOOT_VERSION_1_0,
353*8617a60dSAndroid Build Coastguard Worker "Creates, signs, and verifies a keyblock");
354