file_type_bios.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. /*
  2. * Copyright 2014 The Chromium OS Authors. All rights reserved.
  3. * Use of this source code is governed by a BSD-style license that can be
  4. * found in the LICENSE file.
  5. */
  6. #include <errno.h>
  7. #include <limits.h>
  8. #include <stdint.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "bmpblk_header.h"
  12. #include "fmap.h"
  13. #include "file_type.h"
  14. #include "file_type_bios.h"
  15. #include "futility.h"
  16. #include "futility_options.h"
  17. #include "gbb_header.h"
  18. #include "host_common.h"
  19. #include "vb1_helper.h"
  20. #include "vb2_common.h"
  21. static const char * const fmap_name[] = {
  22. "GBB", /* BIOS_FMAP_GBB */
  23. "FW_MAIN_A", /* BIOS_FMAP_FW_MAIN_A */
  24. "FW_MAIN_B", /* BIOS_FMAP_FW_MAIN_B */
  25. "VBLOCK_A", /* BIOS_FMAP_VBLOCK_A */
  26. "VBLOCK_B", /* BIOS_FMAP_VBLOCK_B */
  27. };
  28. BUILD_ASSERT(ARRAY_SIZE(fmap_name) == NUM_BIOS_COMPONENTS);
  29. static const char * const fmap_oldname[] = {
  30. "GBB Area", /* BIOS_FMAP_GBB */
  31. "Firmware A Data", /* BIOS_FMAP_FW_MAIN_A */
  32. "Firmware B Data", /* BIOS_FMAP_FW_MAIN_B */
  33. "Firmware A Key", /* BIOS_FMAP_VBLOCK_A */
  34. "Firmware B Key", /* BIOS_FMAP_VBLOCK_B */
  35. };
  36. BUILD_ASSERT(ARRAY_SIZE(fmap_oldname) == NUM_BIOS_COMPONENTS);
  37. static void fmap_limit_area(FmapAreaHeader *ah, uint32_t len)
  38. {
  39. uint32_t sum = ah->area_offset + ah->area_size;
  40. if (sum < ah->area_size || sum > len) {
  41. Debug("%s(%s) 0x%x + 0x%x > 0x%x\n",
  42. __func__, ah->area_name,
  43. ah->area_offset, ah->area_size, len);
  44. ah->area_offset = 0;
  45. ah->area_size = 0;
  46. }
  47. }
  48. /** Show functions **/
  49. int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data)
  50. {
  51. GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader *)buf;
  52. struct bios_state_s *state = (struct bios_state_s *)data;
  53. BmpBlockHeader *bmp;
  54. int retval = 0;
  55. uint32_t maxlen = 0;
  56. if (!len) {
  57. printf("GBB header: %s <invalid>\n", name);
  58. return 1;
  59. }
  60. /* It looks like a GBB or we wouldn't be called. */
  61. if (!futil_valid_gbb_header(gbb, len, &maxlen))
  62. retval = 1;
  63. printf("GBB header: %s\n", name);
  64. printf(" Version: %d.%d\n",
  65. gbb->major_version, gbb->minor_version);
  66. printf(" Flags: 0x%08x\n", gbb->flags);
  67. printf(" Regions: offset size\n");
  68. printf(" hwid 0x%08x 0x%08x\n",
  69. gbb->hwid_offset, gbb->hwid_size);
  70. printf(" bmpvf 0x%08x 0x%08x\n",
  71. gbb->bmpfv_offset, gbb->bmpfv_size);
  72. printf(" rootkey 0x%08x 0x%08x\n",
  73. gbb->rootkey_offset, gbb->rootkey_size);
  74. printf(" recovery_key 0x%08x 0x%08x\n",
  75. gbb->recovery_key_offset, gbb->recovery_key_size);
  76. printf(" Size: 0x%08x / 0x%08x%s\n",
  77. maxlen, len, maxlen > len ? " (not enough)" : "");
  78. if (retval) {
  79. printf("GBB header is invalid, ignoring content\n");
  80. return 1;
  81. }
  82. printf("GBB content:\n");
  83. printf(" HWID: %s\n", buf + gbb->hwid_offset);
  84. print_hwid_digest(gbb, " digest: ", "\n");
  85. struct vb2_packed_key *pubkey =
  86. (struct vb2_packed_key *)(buf + gbb->rootkey_offset);
  87. if (packed_key_looks_ok(pubkey, gbb->rootkey_size)) {
  88. if (state) {
  89. state->rootkey.offset =
  90. state->area[BIOS_FMAP_GBB].offset +
  91. gbb->rootkey_offset;
  92. state->rootkey.buf = buf + gbb->rootkey_offset;
  93. state->rootkey.len = gbb->rootkey_size;
  94. state->rootkey.is_valid = 1;
  95. }
  96. printf(" Root Key:\n");
  97. show_pubkey(pubkey, " ");
  98. } else {
  99. retval = 1;
  100. printf(" Root Key: <invalid>\n");
  101. }
  102. pubkey = (struct vb2_packed_key *)(buf + gbb->recovery_key_offset);
  103. if (packed_key_looks_ok(pubkey, gbb->recovery_key_size)) {
  104. if (state) {
  105. state->recovery_key.offset =
  106. state->area[BIOS_FMAP_GBB].offset +
  107. gbb->recovery_key_offset;
  108. state->recovery_key.buf = buf +
  109. gbb->recovery_key_offset;
  110. state->recovery_key.len = gbb->recovery_key_size;
  111. state->recovery_key.is_valid = 1;
  112. }
  113. printf(" Recovery Key:\n");
  114. show_pubkey(pubkey, " ");
  115. } else {
  116. retval = 1;
  117. printf(" Recovery Key: <invalid>\n");
  118. }
  119. bmp = (BmpBlockHeader *)(buf + gbb->bmpfv_offset);
  120. if (0 != memcmp(bmp, BMPBLOCK_SIGNATURE, BMPBLOCK_SIGNATURE_SIZE)) {
  121. printf(" BmpBlock: <invalid>\n");
  122. /* We don't support older BmpBlock formats, so we can't
  123. * be strict about this. */
  124. } else {
  125. printf(" BmpBlock:\n");
  126. printf(" Version: %d.%d\n",
  127. bmp->major_version, bmp->minor_version);
  128. printf(" Localizations: %d\n",
  129. bmp->number_of_localizations);
  130. printf(" Screen layouts: %d\n",
  131. bmp->number_of_screenlayouts);
  132. printf(" Image infos: %d\n",
  133. bmp->number_of_imageinfos);
  134. }
  135. if (!retval && state)
  136. state->area[BIOS_FMAP_GBB].is_valid = 1;
  137. return retval;
  138. }
  139. /*
  140. * This handles FW_MAIN_A and FW_MAIN_B while processing a BIOS image.
  141. *
  142. * The data is just the RW firmware blob, so there's nothing useful to show
  143. * about it. We'll just mark it as present so when we encounter corresponding
  144. * VBLOCK area, we'll have this to verify.
  145. */
  146. static int fmap_show_fw_main(const char *name, uint8_t *buf, uint32_t len,
  147. void *data)
  148. {
  149. struct bios_state_s *state = (struct bios_state_s *)data;
  150. if (!len) {
  151. printf("Firmware body: %s <invalid>\n", name);
  152. return 1;
  153. }
  154. printf("Firmware body: %s\n", name);
  155. printf(" Offset: 0x%08x\n",
  156. state->area[state->c].offset);
  157. printf(" Size: 0x%08x\n", len);
  158. state->area[state->c].is_valid = 1;
  159. return 0;
  160. }
  161. /* Functions to call to show the bios components */
  162. static int (*fmap_show_fn[])(const char *name, uint8_t *buf, uint32_t len,
  163. void *data) = {
  164. ft_show_gbb,
  165. fmap_show_fw_main,
  166. fmap_show_fw_main,
  167. ft_show_fw_preamble,
  168. ft_show_fw_preamble,
  169. };
  170. BUILD_ASSERT(ARRAY_SIZE(fmap_show_fn) == NUM_BIOS_COMPONENTS);
  171. int ft_show_bios(const char *name, uint8_t *buf, uint32_t len, void *data)
  172. {
  173. FmapHeader *fmap;
  174. FmapAreaHeader *ah = 0;
  175. char ah_name[FMAP_NAMELEN + 1];
  176. enum bios_component c;
  177. int retval = 0;
  178. struct bios_state_s state;
  179. memset(&state, 0, sizeof(state));
  180. printf("BIOS: %s\n", name);
  181. /* We've already checked, so we know this will work. */
  182. fmap = fmap_find(buf, len);
  183. for (c = 0; c < NUM_BIOS_COMPONENTS; c++) {
  184. /* We know one of these will work, too */
  185. if (fmap_find_by_name(buf, len, fmap, fmap_name[c], &ah) ||
  186. fmap_find_by_name(buf, len, fmap, fmap_oldname[c], &ah)) {
  187. /* But the file might be truncated */
  188. fmap_limit_area(ah, len);
  189. /* The name is not necessarily null-terminated */
  190. snprintf(ah_name, sizeof(ah_name), "%s", ah->area_name);
  191. /* Update the state we're passing around */
  192. state.c = c;
  193. state.area[c].offset = ah->area_offset;
  194. state.area[c].buf = buf + ah->area_offset;
  195. state.area[c].len = ah->area_size;
  196. Debug("%s() showing FMAP area %d (%s),"
  197. " offset=0x%08x len=0x%08x\n",
  198. __func__, c, ah_name,
  199. ah->area_offset, ah->area_size);
  200. /* Go look at it. */
  201. if (fmap_show_fn[c])
  202. retval += fmap_show_fn[c](ah_name,
  203. state.area[c].buf,
  204. state.area[c].len,
  205. &state);
  206. }
  207. }
  208. return retval;
  209. }
  210. /** Sign functions **/
  211. /*
  212. * This handles FW_MAIN_A and FW_MAIN_B while signing a BIOS image. The data is
  213. * just the RW firmware blob so there's nothing useful to do with it, but we'll
  214. * mark it as valid so that we'll know that this FMAP area exists and can
  215. * be signed.
  216. */
  217. static int fmap_sign_fw_main(const char *name, uint8_t *buf, uint32_t len,
  218. void *data)
  219. {
  220. struct bios_state_s *state = (struct bios_state_s *)data;
  221. state->area[state->c].is_valid = 1;
  222. return 0;
  223. }
  224. /*
  225. * This handles VBLOCK_A and VBLOCK_B while processing a BIOS image. We don't
  226. * do any signing here. We just check to see if the existing FMAP area contains
  227. * a firmware preamble so we can preserve its contents. We do the signing once
  228. * we've looked over all the components.
  229. */
  230. static int fmap_sign_fw_preamble(const char *name, uint8_t *buf, uint32_t len,
  231. void *data)
  232. {
  233. static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE];
  234. static struct vb2_workbuf wb;
  235. vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
  236. struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf;
  237. struct bios_state_s *state = (struct bios_state_s *)data;
  238. /*
  239. * If we have a valid keyblock and fw_preamble, then we can use them to
  240. * determine the size of the firmware body. Otherwise, we'll have to
  241. * just sign the whole region.
  242. */
  243. if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) {
  244. fprintf(stderr, "Warning: %s keyblock is invalid. "
  245. "Signing the entire FW FMAP region...\n", name);
  246. goto whatever;
  247. }
  248. if (!packed_key_looks_ok(&keyblock->data_key,
  249. keyblock->data_key.key_offset +
  250. keyblock->data_key.key_size)) {
  251. fprintf(stderr, "Warning: %s public key is invalid. "
  252. "Signing the entire FW FMAP region...\n", name);
  253. goto whatever;
  254. }
  255. uint32_t more = keyblock->keyblock_size;
  256. struct vb2_fw_preamble *preamble =
  257. (struct vb2_fw_preamble *)(buf + more);
  258. uint32_t fw_size = preamble->body_signature.data_size;
  259. struct bios_area_s *fw_body_area = 0;
  260. switch (state->c) {
  261. case BIOS_FMAP_VBLOCK_A:
  262. fw_body_area = &state->area[BIOS_FMAP_FW_MAIN_A];
  263. /* Preserve the flags if they're not specified */
  264. if (!sign_option.flags_specified)
  265. sign_option.flags = preamble->flags;
  266. break;
  267. case BIOS_FMAP_VBLOCK_B:
  268. fw_body_area = &state->area[BIOS_FMAP_FW_MAIN_B];
  269. break;
  270. default:
  271. DIE;
  272. }
  273. if (fw_size > fw_body_area->len) {
  274. fprintf(stderr,
  275. "%s says the firmware is larger than we have\n",
  276. name);
  277. return 1;
  278. }
  279. /* Update the firmware size */
  280. fw_body_area->len = fw_size;
  281. whatever:
  282. state->area[state->c].is_valid = 1;
  283. return 0;
  284. }
  285. static int write_new_preamble(struct bios_area_s *vblock,
  286. struct bios_area_s *fw_body,
  287. struct vb2_private_key *signkey,
  288. struct vb2_keyblock *keyblock)
  289. {
  290. struct vb2_signature *body_sig;
  291. struct vb2_fw_preamble *preamble;
  292. body_sig = vb2_calculate_signature(fw_body->buf, fw_body->len, signkey);
  293. if (!body_sig) {
  294. fprintf(stderr, "Error calculating body signature\n");
  295. return 1;
  296. }
  297. preamble = vb2_create_fw_preamble(sign_option.version,
  298. (struct vb2_packed_key *)sign_option.kernel_subkey,
  299. body_sig,
  300. signkey,
  301. sign_option.flags);
  302. if (!preamble) {
  303. fprintf(stderr, "Error creating firmware preamble.\n");
  304. free(body_sig);
  305. return 1;
  306. }
  307. /* Write the new keyblock */
  308. uint32_t more = keyblock->keyblock_size;
  309. memcpy(vblock->buf, keyblock, more);
  310. /* and the new preamble */
  311. memcpy(vblock->buf + more, preamble, preamble->preamble_size);
  312. free(preamble);
  313. free(body_sig);
  314. return 0;
  315. }
  316. static int write_loem(const char *ab, struct bios_area_s *vblock)
  317. {
  318. char filename[PATH_MAX];
  319. int n;
  320. n = snprintf(filename, sizeof(filename), "%s/vblock_%s.%s",
  321. sign_option.loemdir ? sign_option.loemdir : ".",
  322. ab, sign_option.loemid);
  323. if (n >= sizeof(filename)) {
  324. fprintf(stderr, "LOEM args produce bogus filename\n");
  325. return 1;
  326. }
  327. FILE *fp = fopen(filename, "w");
  328. if (!fp) {
  329. fprintf(stderr, "Can't open %s for writing: %s\n",
  330. filename, strerror(errno));
  331. return 1;
  332. }
  333. if (1 != fwrite(vblock->buf, vblock->len, 1, fp)) {
  334. fprintf(stderr, "Can't write to %s: %s\n",
  335. filename, strerror(errno));
  336. fclose(fp);
  337. return 1;
  338. }
  339. if (fclose(fp)) {
  340. fprintf(stderr, "Failed closing loem output: %s\n",
  341. strerror(errno));
  342. return 1;
  343. }
  344. return 0;
  345. }
  346. /* This signs a full BIOS image after it's been traversed. */
  347. static int sign_bios_at_end(struct bios_state_s *state)
  348. {
  349. struct bios_area_s *vblock_a = &state->area[BIOS_FMAP_VBLOCK_A];
  350. struct bios_area_s *vblock_b = &state->area[BIOS_FMAP_VBLOCK_B];
  351. struct bios_area_s *fw_a = &state->area[BIOS_FMAP_FW_MAIN_A];
  352. struct bios_area_s *fw_b = &state->area[BIOS_FMAP_FW_MAIN_B];
  353. int retval = 0;
  354. if (!vblock_a->is_valid || !vblock_b->is_valid ||
  355. !fw_a->is_valid || !fw_b->is_valid) {
  356. fprintf(stderr, "Something's wrong. Not changing anything\n");
  357. return 1;
  358. }
  359. /* Do A & B differ ? */
  360. if (fw_a->len != fw_b->len ||
  361. memcmp(fw_a->buf, fw_b->buf, fw_a->len)) {
  362. /* Yes, must use DEV keys for A */
  363. if (!sign_option.devsignprivate || !sign_option.devkeyblock) {
  364. fprintf(stderr,
  365. "FW A & B differ. DEV keys are required.\n");
  366. return 1;
  367. }
  368. retval |= write_new_preamble(vblock_a, fw_a,
  369. sign_option.devsignprivate,
  370. sign_option.devkeyblock);
  371. } else {
  372. retval |= write_new_preamble(vblock_a, fw_a,
  373. sign_option.signprivate,
  374. sign_option.keyblock);
  375. }
  376. /* FW B is always normal keys */
  377. retval |= write_new_preamble(vblock_b, fw_b,
  378. sign_option.signprivate,
  379. sign_option.keyblock);
  380. if (sign_option.loemid) {
  381. retval |= write_loem("A", vblock_a);
  382. retval |= write_loem("B", vblock_b);
  383. }
  384. return retval;
  385. }
  386. /* Functions to call while preparing to sign the bios */
  387. static int (*fmap_sign_fn[])(const char *name, uint8_t *buf, uint32_t len,
  388. void *data) = {
  389. 0,
  390. fmap_sign_fw_main,
  391. fmap_sign_fw_main,
  392. fmap_sign_fw_preamble,
  393. fmap_sign_fw_preamble,
  394. };
  395. BUILD_ASSERT(ARRAY_SIZE(fmap_sign_fn) == NUM_BIOS_COMPONENTS);
  396. int ft_sign_bios(const char *name, uint8_t *buf, uint32_t len, void *data)
  397. {
  398. FmapHeader *fmap;
  399. FmapAreaHeader *ah = 0;
  400. char ah_name[FMAP_NAMELEN + 1];
  401. enum bios_component c;
  402. int retval = 0;
  403. struct bios_state_s state;
  404. memset(&state, 0, sizeof(state));
  405. /* We've already checked, so we know this will work. */
  406. fmap = fmap_find(buf, len);
  407. for (c = 0; c < NUM_BIOS_COMPONENTS; c++) {
  408. /* We know one of these will work, too */
  409. if (fmap_find_by_name(buf, len, fmap, fmap_name[c], &ah) ||
  410. fmap_find_by_name(buf, len, fmap, fmap_oldname[c], &ah)) {
  411. /* But the file might be truncated */
  412. fmap_limit_area(ah, len);
  413. /* The name is not necessarily null-terminated */
  414. snprintf(ah_name, sizeof(ah_name), "%s", ah->area_name);
  415. /* Update the state we're passing around */
  416. state.c = c;
  417. state.area[c].buf = buf + ah->area_offset;
  418. state.area[c].len = ah->area_size;
  419. Debug("%s() examining FMAP area %d (%s),"
  420. " offset=0x%08x len=0x%08x\n",
  421. __func__, c, ah_name,
  422. ah->area_offset, ah->area_size);
  423. /* Go look at it, but abort on error */
  424. if (fmap_sign_fn[c])
  425. retval += fmap_sign_fn[c](ah_name,
  426. state.area[c].buf,
  427. state.area[c].len,
  428. &state);
  429. }
  430. }
  431. retval += sign_bios_at_end(&state);
  432. return retval;
  433. }
  434. enum futil_file_type ft_recognize_bios_image(uint8_t *buf, uint32_t len)
  435. {
  436. FmapHeader *fmap;
  437. enum bios_component c;
  438. fmap = fmap_find(buf, len);
  439. if (!fmap)
  440. return FILE_TYPE_UNKNOWN;
  441. for (c = 0; c < NUM_BIOS_COMPONENTS; c++)
  442. if (!fmap_find_by_name(buf, len, fmap, fmap_name[c], 0))
  443. break;
  444. if (c == NUM_BIOS_COMPONENTS)
  445. return FILE_TYPE_BIOS_IMAGE;
  446. for (c = 0; c < NUM_BIOS_COMPONENTS; c++)
  447. if (!fmap_find_by_name(buf, len, fmap, fmap_oldname[c], 0))
  448. break;
  449. if (c == NUM_BIOS_COMPONENTS)
  450. return FILE_TYPE_OLD_BIOS_IMAGE;
  451. return FILE_TYPE_UNKNOWN;
  452. }