cmd_vbutil_firmware.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /* Copyright 2011 The Chromium OS Authors. All rights reserved.
  2. * 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. #include <getopt.h>
  8. #include <inttypes.h> /* For PRIu64 */
  9. #include <stddef.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <unistd.h>
  13. #include "2sysincludes.h"
  14. #include "2api.h"
  15. #include "2common.h"
  16. #include "2rsa.h"
  17. #include "futility.h"
  18. #include "host_common.h"
  19. #include "host_key2.h"
  20. #include "kernel_blob.h"
  21. #include "util_misc.h"
  22. #include "vboot_common.h"
  23. #include "vb1_helper.h"
  24. #include "vb2_common.h"
  25. /* Command line options */
  26. enum {
  27. OPT_MODE_VBLOCK = 1000,
  28. OPT_MODE_VERIFY,
  29. OPT_KEYBLOCK,
  30. OPT_SIGNPUBKEY,
  31. OPT_SIGNPRIVATE,
  32. OPT_VERSION,
  33. OPT_FV,
  34. OPT_KERNELKEY,
  35. OPT_FLAGS,
  36. OPT_HELP,
  37. };
  38. static const struct option long_opts[] = {
  39. {"vblock", 1, 0, OPT_MODE_VBLOCK},
  40. {"verify", 1, 0, OPT_MODE_VERIFY},
  41. {"keyblock", 1, 0, OPT_KEYBLOCK},
  42. {"signpubkey", 1, 0, OPT_SIGNPUBKEY},
  43. {"signprivate", 1, 0, OPT_SIGNPRIVATE},
  44. {"version", 1, 0, OPT_VERSION},
  45. {"fv", 1, 0, OPT_FV},
  46. {"kernelkey", 1, 0, OPT_KERNELKEY},
  47. {"flags", 1, 0, OPT_FLAGS},
  48. {"help", 0, 0, OPT_HELP},
  49. {NULL, 0, 0, 0}
  50. };
  51. /* Print help and return error */
  52. static void print_help(int argc, char *argv[])
  53. {
  54. printf("\nUsage: " MYNAME " %s <--vblock|--verify> <file> [OPTIONS]\n"
  55. "\n"
  56. "For '--vblock <file>', required OPTIONS are:\n"
  57. "\n"
  58. " --keyblock <file> Key block in .keyblock format\n"
  59. " --signprivate <file>"
  60. " Signing private key in .vbprivk format\n"
  61. " --version <number> Firmware version\n"
  62. " --fv <file> Firmware volume to sign\n"
  63. " --kernelkey <file> Kernel subkey in .vbpubk format\n"
  64. "\n"
  65. "optional OPTIONS are:\n"
  66. " --flags <number> Preamble flags (defaults to 0)\n"
  67. "\n"
  68. "For '--verify <file>', required OPTIONS are:\n"
  69. "\n"
  70. " --signpubkey <file>"
  71. " Signing public key in .vbpubk format\n"
  72. " --fv <file> Firmware volume to verify\n"
  73. "\n"
  74. "For '--verify <file>', optional OPTIONS are:\n"
  75. " --kernelkey <file>"
  76. " Write the kernel subkey to this file\n\n",
  77. argv[0]);
  78. }
  79. /* Create a firmware .vblock */
  80. static int do_vblock(const char *outfile, const char *keyblock_file,
  81. const char *signprivate, uint32_t version,
  82. const char *fv_file, const char *kernelkey_file,
  83. uint32_t preamble_flags)
  84. {
  85. struct vb2_keyblock *keyblock = NULL;
  86. struct vb2_private_key *signing_key = NULL;
  87. struct vb2_packed_key *kernel_subkey = NULL;
  88. struct vb2_signature *body_sig = NULL;
  89. struct vb2_fw_preamble *preamble = NULL;
  90. uint8_t *fv_data = NULL;
  91. int retval = 1;
  92. if (!outfile) {
  93. VbExError("Must specify output filename\n");
  94. goto vblock_cleanup;
  95. }
  96. if (!keyblock_file || !signprivate || !kernelkey_file) {
  97. VbExError("Must specify all keys\n");
  98. goto vblock_cleanup;
  99. }
  100. if (!fv_file) {
  101. VbExError("Must specify firmware volume\n");
  102. goto vblock_cleanup;
  103. }
  104. /* Read the key block and keys */
  105. keyblock = vb2_read_keyblock(keyblock_file);
  106. if (!keyblock) {
  107. VbExError("Error reading key block.\n");
  108. goto vblock_cleanup;
  109. }
  110. signing_key = vb2_read_private_key(signprivate);
  111. if (!signing_key) {
  112. VbExError("Error reading signing key.\n");
  113. goto vblock_cleanup;
  114. }
  115. kernel_subkey = vb2_read_packed_key(kernelkey_file);
  116. if (!kernel_subkey) {
  117. VbExError("Error reading kernel subkey.\n");
  118. goto vblock_cleanup;
  119. }
  120. /* Read and sign the firmware volume */
  121. uint32_t fv_size;
  122. if (VB2_SUCCESS != vb2_read_file(fv_file, &fv_data, &fv_size))
  123. goto vblock_cleanup;
  124. if (!fv_size) {
  125. VbExError("Empty firmware volume file\n");
  126. goto vblock_cleanup;
  127. }
  128. body_sig = vb2_calculate_signature(fv_data, fv_size, signing_key);
  129. if (!body_sig) {
  130. VbExError("Error calculating body signature\n");
  131. goto vblock_cleanup;
  132. }
  133. /* Create preamble */
  134. preamble = vb2_create_fw_preamble(version, kernel_subkey, body_sig,
  135. signing_key, preamble_flags);
  136. if (!preamble) {
  137. VbExError("Error creating preamble.\n");
  138. goto vblock_cleanup;
  139. }
  140. /* Write the output file */
  141. FILE *f = fopen(outfile, "wb");
  142. if (!f) {
  143. VbExError("Can't open output file %s\n", outfile);
  144. goto vblock_cleanup;
  145. }
  146. int i = ((1 != fwrite(keyblock, keyblock->keyblock_size, 1, f)) ||
  147. (1 != fwrite(preamble, preamble->preamble_size, 1, f)));
  148. fclose(f);
  149. if (i) {
  150. VbExError("Can't write output file %s\n", outfile);
  151. unlink(outfile);
  152. goto vblock_cleanup;
  153. }
  154. /* Success */
  155. retval = 0;
  156. vblock_cleanup:
  157. if (keyblock)
  158. free(keyblock);
  159. if (signing_key)
  160. free(signing_key);
  161. if (kernel_subkey)
  162. free(kernel_subkey);
  163. if (fv_data)
  164. free(fv_data);
  165. if (body_sig)
  166. free(body_sig);
  167. if (preamble)
  168. free(preamble);
  169. return retval;
  170. }
  171. static int do_verify(const char *infile, const char *signpubkey,
  172. const char *fv_file, const char *kernelkey_file)
  173. {
  174. uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE];
  175. struct vb2_workbuf wb;
  176. vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
  177. uint32_t now = 0;
  178. uint8_t *pubkbuf = NULL;
  179. uint8_t *blob = NULL;
  180. uint8_t *fv_data = NULL;
  181. int retval = 1;
  182. if (!infile || !signpubkey || !fv_file) {
  183. VbExError("Must specify filename, signpubkey, and fv\n");
  184. goto verify_cleanup;
  185. }
  186. /* Read public signing key */
  187. uint32_t pubklen;
  188. struct vb2_public_key sign_key;
  189. if (VB2_SUCCESS != vb2_read_file(signpubkey, &pubkbuf, &pubklen)) {
  190. fprintf(stderr, "Error reading signpubkey.\n");
  191. goto verify_cleanup;
  192. }
  193. if (VB2_SUCCESS != vb2_unpack_key_buffer(&sign_key, pubkbuf, pubklen)) {
  194. fprintf(stderr, "Error unpacking signpubkey.\n");
  195. goto verify_cleanup;
  196. }
  197. /* Read blob */
  198. uint32_t blob_size;
  199. if (VB2_SUCCESS != vb2_read_file(infile, &blob, &blob_size)) {
  200. VbExError("Error reading input file\n");
  201. goto verify_cleanup;
  202. }
  203. /* Read firmware volume */
  204. uint32_t fv_size;
  205. if (VB2_SUCCESS != vb2_read_file(fv_file, &fv_data, &fv_size)) {
  206. VbExError("Error reading firmware volume\n");
  207. goto verify_cleanup;
  208. }
  209. /* Verify key block */
  210. struct vb2_keyblock *keyblock = (struct vb2_keyblock *)blob;
  211. if (VB2_SUCCESS !=
  212. vb2_verify_keyblock(keyblock, blob_size, &sign_key, &wb)) {
  213. VbExError("Error verifying key block.\n");
  214. goto verify_cleanup;
  215. }
  216. now += keyblock->keyblock_size;
  217. printf("Key block:\n");
  218. printf(" Size: %d\n", keyblock->keyblock_size);
  219. printf(" Flags: %d (ignored)\n",
  220. keyblock->keyblock_flags);
  221. struct vb2_packed_key *packed_key = &keyblock->data_key;
  222. printf(" Data key algorithm: %d %s\n", packed_key->algorithm,
  223. vb2_get_crypto_algorithm_name(packed_key->algorithm));
  224. printf(" Data key version: %d\n", packed_key->key_version);
  225. printf(" Data key sha1sum: %s\n",
  226. packed_key_sha1_string(packed_key));
  227. struct vb2_public_key data_key;
  228. if (VB2_SUCCESS !=
  229. vb2_unpack_key(&data_key, &keyblock->data_key)) {
  230. fprintf(stderr, "Error parsing data key.\n");
  231. goto verify_cleanup;
  232. }
  233. /* Verify preamble */
  234. struct vb2_fw_preamble *pre2 = (struct vb2_fw_preamble *)(blob + now);
  235. if (VB2_SUCCESS !=
  236. vb2_verify_fw_preamble(pre2, blob_size - now, &data_key, &wb)) {
  237. VbExError("Error2 verifying preamble.\n");
  238. goto verify_cleanup;
  239. }
  240. now += pre2->preamble_size;
  241. uint32_t flags = pre2->flags;
  242. if (pre2->header_version_minor < 1)
  243. flags = 0; /* Old 2.0 structure didn't have flags */
  244. printf("Preamble:\n");
  245. printf(" Size: %d\n", pre2->preamble_size);
  246. printf(" Header version: %d.%d\n",
  247. pre2->header_version_major, pre2->header_version_minor);
  248. printf(" Firmware version: %d\n", pre2->firmware_version);
  249. struct vb2_packed_key *kernel_subkey = &pre2->kernel_subkey;
  250. printf(" Kernel key algorithm: %d %s\n", kernel_subkey->algorithm,
  251. vb2_get_crypto_algorithm_name(kernel_subkey->algorithm));
  252. printf(" Kernel key version: %d\n", kernel_subkey->key_version);
  253. printf(" Kernel key sha1sum: %s\n",
  254. packed_key_sha1_string(kernel_subkey));
  255. printf(" Firmware body size: %d\n", pre2->body_signature.data_size);
  256. printf(" Preamble flags: %d\n", flags);
  257. /* TODO: verify body size same as signature size */
  258. /* Verify body */
  259. if (flags & VB2_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
  260. printf("Preamble requests USE_RO_NORMAL;"
  261. " skipping body verification.\n");
  262. } else if (VB2_SUCCESS ==
  263. vb2_verify_data(fv_data, fv_size, &pre2->body_signature,
  264. &data_key, &wb)) {
  265. printf("Body verification succeeded.\n");
  266. } else {
  267. VbExError("Error verifying firmware body.\n");
  268. goto verify_cleanup;
  269. }
  270. if (kernelkey_file &&
  271. VB2_SUCCESS != vb2_write_packed_key(kernelkey_file,
  272. kernel_subkey)) {
  273. VbExError("Unable to write kernel subkey\n");
  274. goto verify_cleanup;
  275. }
  276. /* Success */
  277. retval = 0;
  278. verify_cleanup:
  279. if (pubkbuf)
  280. free(pubkbuf);
  281. if (blob)
  282. free(blob);
  283. if (fv_data)
  284. free(fv_data);
  285. return retval;
  286. }
  287. static int do_vbutil_firmware(int argc, char *argv[])
  288. {
  289. char *filename = NULL;
  290. char *key_block_file = NULL;
  291. char *signpubkey = NULL;
  292. char *signprivate = NULL;
  293. uint32_t version = 0;
  294. char *fv_file = NULL;
  295. char *kernelkey_file = NULL;
  296. uint32_t preamble_flags = 0;
  297. int mode = 0;
  298. int parse_error = 0;
  299. char *e;
  300. int i;
  301. while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
  302. switch (i) {
  303. case '?':
  304. /* Unhandled option */
  305. printf("Unknown option\n");
  306. parse_error = 1;
  307. break;
  308. case OPT_HELP:
  309. print_help(argc, argv);
  310. return !!parse_error;
  311. case OPT_MODE_VBLOCK:
  312. case OPT_MODE_VERIFY:
  313. mode = i;
  314. filename = optarg;
  315. break;
  316. case OPT_KEYBLOCK:
  317. key_block_file = optarg;
  318. break;
  319. case OPT_SIGNPUBKEY:
  320. signpubkey = optarg;
  321. break;
  322. case OPT_SIGNPRIVATE:
  323. signprivate = optarg;
  324. break;
  325. case OPT_FV:
  326. fv_file = optarg;
  327. break;
  328. case OPT_KERNELKEY:
  329. kernelkey_file = optarg;
  330. break;
  331. case OPT_VERSION:
  332. version = strtoul(optarg, &e, 0);
  333. if (!*optarg || (e && *e)) {
  334. printf("Invalid --version\n");
  335. parse_error = 1;
  336. }
  337. break;
  338. case OPT_FLAGS:
  339. preamble_flags = strtoul(optarg, &e, 0);
  340. if (!*optarg || (e && *e)) {
  341. printf("Invalid --flags\n");
  342. parse_error = 1;
  343. }
  344. break;
  345. }
  346. }
  347. if (parse_error) {
  348. print_help(argc, argv);
  349. return 1;
  350. }
  351. switch (mode) {
  352. case OPT_MODE_VBLOCK:
  353. return do_vblock(filename, key_block_file, signprivate, version,
  354. fv_file, kernelkey_file, preamble_flags);
  355. case OPT_MODE_VERIFY:
  356. return do_verify(filename, signpubkey, fv_file, kernelkey_file);
  357. default:
  358. fprintf(stderr, "Must specify a mode.\n");
  359. print_help(argc, argv);
  360. return 1;
  361. }
  362. }
  363. DECLARE_FUTIL_COMMAND(vbutil_firmware, do_vbutil_firmware, VBOOT_VERSION_1_0,
  364. "Verified boot firmware utility");