vboot_kernel.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. /* Copyright (c) 2013 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. * Functions for loading a kernel from disk.
  6. * (Firmware portion)
  7. */
  8. #include "sysincludes.h"
  9. #include "2sysincludes.h"
  10. #include "2common.h"
  11. #include "2misc.h"
  12. #include "2nvstorage.h"
  13. #include "2rsa.h"
  14. #include "2sha.h"
  15. #include "cgptlib.h"
  16. #include "cgptlib_internal.h"
  17. #include "region.h"
  18. #include "gbb_access.h"
  19. #include "gbb_header.h"
  20. #include "gpt_misc.h"
  21. #include "load_kernel_fw.h"
  22. #include "rollback_index.h"
  23. #include "utility.h"
  24. #include "vb2_common.h"
  25. #include "vboot_api.h"
  26. #include "vboot_common.h"
  27. #include "vboot_kernel.h"
  28. #define LOWEST_TPM_VERSION 0xffffffff
  29. enum vboot_mode {
  30. kBootRecovery = 0, /* Recovery firmware, any dev switch position */
  31. kBootNormal = 1, /* Normal boot - kernel must be verified */
  32. kBootDev = 2 /* Developer boot - self-signed kernel ok */
  33. };
  34. /**
  35. * Return the boot mode based on the parameters.
  36. *
  37. * @param params Load kernel parameters
  38. * @return The current boot mode.
  39. */
  40. static enum vboot_mode get_kernel_boot_mode(struct vb2_context *ctx)
  41. {
  42. if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
  43. return kBootRecovery;
  44. if (ctx->flags & VB2_CONTEXT_DEVELOPER_MODE)
  45. return kBootDev;
  46. return kBootNormal;
  47. };
  48. /**
  49. * Check if the parameters require an officially signed OS.
  50. *
  51. * @param params Load kernel parameters
  52. * @return 1 if official OS required; 0 if self-signed kernels are ok
  53. */
  54. static int require_official_os(struct vb2_context *ctx,
  55. const LoadKernelParams *params)
  56. {
  57. /* Normal and recovery modes always require official OS */
  58. if (get_kernel_boot_mode(ctx) != kBootDev)
  59. return 1;
  60. /* FWMP can require developer mode to use official OS */
  61. if (params->fwmp &&
  62. (params->fwmp->flags & FWMP_DEV_ENABLE_OFFICIAL_ONLY))
  63. return 1;
  64. /* Developer can request official OS via nvstorage */
  65. return vb2_nv_get(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY);
  66. }
  67. /**
  68. * Return a pointer to the keyblock inside a vblock.
  69. *
  70. * Must only be called during or after vb2_verify_kernel_vblock().
  71. *
  72. * @param kbuf Buffer containing vblock
  73. * @return The keyblock pointer.
  74. */
  75. static struct vb2_keyblock *get_keyblock(uint8_t *kbuf)
  76. {
  77. return (struct vb2_keyblock *)kbuf;
  78. }
  79. /**
  80. * Return a pointer to the kernel preamble inside a vblock.
  81. *
  82. * Must only be called during or after vb2_verify_kernel_vblock().
  83. *
  84. * @param kbuf Buffer containing vblock
  85. * @return The kernel preamble pointer.
  86. */
  87. static struct vb2_kernel_preamble *get_preamble(uint8_t *kbuf)
  88. {
  89. return (struct vb2_kernel_preamble *)
  90. (kbuf + get_keyblock(kbuf)->keyblock_size);
  91. }
  92. /**
  93. * Return the offset of the kernel body from the start of the vblock.
  94. *
  95. * Must only be called during or after vb2_verify_kernel_vblock().
  96. *
  97. * @param kbuf Buffer containing vblock
  98. * @return The offset of the kernel body from the vblock start, in bytes.
  99. */
  100. static uint32_t get_body_offset(uint8_t *kbuf)
  101. {
  102. return (get_keyblock(kbuf)->keyblock_size +
  103. get_preamble(kbuf)->preamble_size);
  104. }
  105. /**
  106. * Verify a kernel vblock.
  107. *
  108. * @param kbuf Buffer containing the vblock
  109. * @param kbuf_size Size of the buffer in bytes
  110. * @param kernel_subkey Packed kernel subkey to use in validating keyblock
  111. * @param params Load kernel parameters
  112. * @param min_version Minimum kernel version
  113. * @param shpart Destination for verification results
  114. * @param wb Work buffer. Must be at least
  115. * VB2_VERIFY_KERNEL_PREAMBLE_WORKBUF_BYTES bytes.
  116. * @return VB2_SUCCESS, or non-zero error code.
  117. */
  118. int vb2_verify_kernel_vblock(struct vb2_context *ctx,
  119. uint8_t *kbuf,
  120. uint32_t kbuf_size,
  121. const struct vb2_packed_key *kernel_subkey,
  122. const LoadKernelParams *params,
  123. uint32_t min_version,
  124. VbSharedDataKernelPart *shpart,
  125. struct vb2_workbuf *wb)
  126. {
  127. /* Unpack kernel subkey */
  128. struct vb2_public_key kernel_subkey2;
  129. if (VB2_SUCCESS != vb2_unpack_key(&kernel_subkey2, kernel_subkey)) {
  130. VB2_DEBUG("Unable to unpack kernel subkey\n");
  131. return VB2_ERROR_VBLOCK_KERNEL_SUBKEY;
  132. }
  133. /* Verify the key block. */
  134. int keyblock_valid = 1; /* Assume valid */
  135. struct vb2_keyblock *keyblock = get_keyblock(kbuf);
  136. if (VB2_SUCCESS != vb2_verify_keyblock(keyblock, kbuf_size,
  137. &kernel_subkey2, wb)) {
  138. VB2_DEBUG("Verifying key block signature failed.\n");
  139. shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_SIG;
  140. keyblock_valid = 0;
  141. /* Check if we must have an officially signed kernel */
  142. if (require_official_os(ctx, params)) {
  143. VB2_DEBUG("Self-signed kernels not enabled.\n");
  144. shpart->check_result = VBSD_LKP_CHECK_SELF_SIGNED;
  145. return VB2_ERROR_VBLOCK_SELF_SIGNED;
  146. }
  147. /* Otherwise, allow the kernel if the key block hash is valid */
  148. if (VB2_SUCCESS !=
  149. vb2_verify_keyblock_hash(keyblock, kbuf_size, wb)) {
  150. VB2_DEBUG("Verifying key block hash failed.\n");
  151. shpart->check_result = VBSD_LKP_CHECK_KEY_BLOCK_HASH;
  152. return VB2_ERROR_VBLOCK_KEYBLOCK_HASH;
  153. }
  154. }
  155. /* Check the key block flags against boot flags. */
  156. if (!(keyblock->keyblock_flags &
  157. ((ctx->flags & VB2_CONTEXT_DEVELOPER_MODE) ?
  158. KEY_BLOCK_FLAG_DEVELOPER_1 : KEY_BLOCK_FLAG_DEVELOPER_0))) {
  159. VB2_DEBUG("Key block developer flag mismatch.\n");
  160. shpart->check_result = VBSD_LKP_CHECK_DEV_MISMATCH;
  161. keyblock_valid = 0;
  162. }
  163. if (!(keyblock->keyblock_flags &
  164. ((ctx->flags & VB2_CONTEXT_RECOVERY_MODE) ?
  165. KEY_BLOCK_FLAG_RECOVERY_1 : KEY_BLOCK_FLAG_RECOVERY_0))) {
  166. VB2_DEBUG("Key block recovery flag mismatch.\n");
  167. shpart->check_result = VBSD_LKP_CHECK_REC_MISMATCH;
  168. keyblock_valid = 0;
  169. }
  170. /* Check for rollback of key version except in recovery mode. */
  171. enum vboot_mode boot_mode = get_kernel_boot_mode(ctx);
  172. uint32_t key_version = keyblock->data_key.key_version;
  173. if (kBootRecovery != boot_mode) {
  174. if (key_version < (min_version >> 16)) {
  175. VB2_DEBUG("Key version too old.\n");
  176. shpart->check_result = VBSD_LKP_CHECK_KEY_ROLLBACK;
  177. keyblock_valid = 0;
  178. }
  179. if (key_version > 0xFFFF) {
  180. /*
  181. * Key version is stored in 16 bits in the TPM, so key
  182. * versions greater than 0xFFFF can't be stored
  183. * properly.
  184. */
  185. VB2_DEBUG("Key version > 0xFFFF.\n");
  186. shpart->check_result = VBSD_LKP_CHECK_KEY_ROLLBACK;
  187. keyblock_valid = 0;
  188. }
  189. }
  190. /* If not in developer mode, key block required to be valid. */
  191. if (kBootDev != boot_mode && !keyblock_valid) {
  192. VB2_DEBUG("Key block is invalid.\n");
  193. return VB2_ERROR_VBLOCK_KEYBLOCK;
  194. }
  195. /* If in developer mode and using key hash, check it */
  196. if ((kBootDev == boot_mode) &&
  197. params->fwmp && (params->fwmp->flags & FWMP_DEV_USE_KEY_HASH)) {
  198. struct vb2_packed_key *key = &keyblock->data_key;
  199. uint8_t *buf = ((uint8_t *)key) + key->key_offset;
  200. uint32_t buflen = key->key_size;
  201. uint8_t digest[VB2_SHA256_DIGEST_SIZE];
  202. VB2_DEBUG("Checking developer key hash.\n");
  203. vb2_digest_buffer(buf, buflen, VB2_HASH_SHA256,
  204. digest, sizeof(digest));
  205. if (0 != vb2_safe_memcmp(digest, params->fwmp->dev_key_hash,
  206. VB2_SHA256_DIGEST_SIZE)) {
  207. int i;
  208. VB2_DEBUG("Wrong developer key hash.\n");
  209. VB2_DEBUG("Want: ");
  210. for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++)
  211. VB2_DEBUG("%02x",
  212. params->fwmp->dev_key_hash[i]);
  213. VB2_DEBUG("\nGot: ");
  214. for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++)
  215. VB2_DEBUG("%02x", digest[i]);
  216. VB2_DEBUG("\n");
  217. return VB2_ERROR_VBLOCK_DEV_KEY_HASH;
  218. }
  219. }
  220. /* Get key for preamble verification from the key block. */
  221. struct vb2_public_key data_key;
  222. if (VB2_SUCCESS != vb2_unpack_key(&data_key, &keyblock->data_key)) {
  223. VB2_DEBUG("Unable to unpack kernel data key\n");
  224. shpart->check_result = VBSD_LKP_CHECK_DATA_KEY_PARSE;
  225. return VB2_ERROR_UNKNOWN;
  226. }
  227. /* Verify the preamble, which follows the key block */
  228. struct vb2_kernel_preamble *preamble = get_preamble(kbuf);
  229. if (VB2_SUCCESS !=
  230. vb2_verify_kernel_preamble(preamble,
  231. kbuf_size - keyblock->keyblock_size,
  232. &data_key,
  233. wb)) {
  234. VB2_DEBUG("Preamble verification failed.\n");
  235. shpart->check_result = VBSD_LKP_CHECK_VERIFY_PREAMBLE;
  236. return VB2_ERROR_UNKNOWN;
  237. }
  238. /*
  239. * If the key block is valid and we're not in recovery mode, check for
  240. * rollback of the kernel version.
  241. */
  242. uint32_t combined_version = (key_version << 16) |
  243. (preamble->kernel_version & 0xFFFF);
  244. shpart->combined_version = combined_version;
  245. if (keyblock_valid && kBootRecovery != boot_mode) {
  246. if (combined_version < min_version) {
  247. VB2_DEBUG("Kernel version too low.\n");
  248. shpart->check_result = VBSD_LKP_CHECK_KERNEL_ROLLBACK;
  249. /*
  250. * If not in developer mode, kernel version
  251. * must be valid.
  252. */
  253. if (kBootDev != boot_mode)
  254. return VB2_ERROR_UNKNOWN;
  255. }
  256. }
  257. VB2_DEBUG("Kernel preamble is good.\n");
  258. shpart->check_result = VBSD_LKP_CHECK_PREAMBLE_VALID;
  259. if (keyblock_valid)
  260. shpart->flags |= VBSD_LKP_FLAG_KEY_BLOCK_VALID;
  261. return VB2_SUCCESS;
  262. }
  263. enum vb2_load_partition_flags {
  264. /* Only check the vblock to */
  265. VB2_LOAD_PARTITION_VBLOCK_ONLY = (1 << 0),
  266. };
  267. #define KBUF_SIZE 65536 /* Bytes to read at start of kernel partition */
  268. /* Minimum context work buffer size needed for vb2_load_partition() */
  269. #define VB2_LOAD_PARTITION_WORKBUF_BYTES \
  270. (VB2_VERIFY_KERNEL_PREAMBLE_WORKBUF_BYTES + KBUF_SIZE)
  271. /**
  272. * Load and verify a partition from the stream.
  273. *
  274. * @param ctx Vboot context
  275. * @param stream Stream to load kernel from
  276. * @param kernel_subkey Key to use to verify vblock
  277. * @param flags Flags (one or more of vb2_load_partition_flags)
  278. * @param params Load-kernel parameters
  279. * @param min_version Minimum kernel version from TPM
  280. * @param shpart Destination for verification results
  281. * @return VB2_SUCCESS, or non-zero error code.
  282. */
  283. int vb2_load_partition(struct vb2_context *ctx,
  284. VbExStream_t stream,
  285. const struct vb2_packed_key *kernel_subkey,
  286. uint32_t flags,
  287. LoadKernelParams *params,
  288. uint32_t min_version,
  289. VbSharedDataKernelPart *shpart)
  290. {
  291. struct vb2_workbuf wblocal;
  292. vb2_workbuf_from_ctx(ctx, &wblocal);
  293. /* Allocate kernel header buffer in workbuf */
  294. uint8_t *kbuf = vb2_workbuf_alloc(&wblocal, KBUF_SIZE);
  295. if (!kbuf)
  296. return VB2_ERROR_LOAD_PARTITION_WORKBUF;
  297. if (VbExStreamRead(stream, KBUF_SIZE, kbuf)) {
  298. VB2_DEBUG("Unable to read start of partition.\n");
  299. shpart->check_result = VBSD_LKP_CHECK_READ_START;
  300. return VB2_ERROR_LOAD_PARTITION_READ_VBLOCK;
  301. }
  302. if (VB2_SUCCESS !=
  303. vb2_verify_kernel_vblock(ctx, kbuf, KBUF_SIZE, kernel_subkey,
  304. params, min_version, shpart, &wblocal)) {
  305. return VB2_ERROR_LOAD_PARTITION_VERIFY_VBLOCK;
  306. }
  307. if (flags & VB2_LOAD_PARTITION_VBLOCK_ONLY)
  308. return VB2_SUCCESS;
  309. struct vb2_keyblock *keyblock = get_keyblock(kbuf);
  310. struct vb2_kernel_preamble *preamble = get_preamble(kbuf);
  311. /*
  312. * Make sure the kernel starts at or before what we already read into
  313. * kbuf.
  314. *
  315. * We could deal with a larger offset by reading and discarding the
  316. * data in between the vblock and the kernel data.
  317. */
  318. uint32_t body_offset = get_body_offset(kbuf);
  319. if (body_offset > KBUF_SIZE) {
  320. shpart->check_result = VBSD_LKP_CHECK_BODY_OFFSET;
  321. VB2_DEBUG("Kernel body offset is %u > 64KB.\n", body_offset);
  322. return VB2_ERROR_LOAD_PARTITION_BODY_OFFSET;
  323. }
  324. uint8_t *kernbuf = params->kernel_buffer;
  325. uint32_t kernbuf_size = params->kernel_buffer_size;
  326. if (!kernbuf) {
  327. /* Get kernel load address and size from the header. */
  328. kernbuf = (uint8_t *)((long)preamble->body_load_address);
  329. kernbuf_size = preamble->body_signature.data_size;
  330. } else if (preamble->body_signature.data_size > kernbuf_size) {
  331. VB2_DEBUG("Kernel body doesn't fit in memory.\n");
  332. shpart->check_result = VBSD_LKP_CHECK_BODY_EXCEEDS_MEM;
  333. return VB2_ERROR_LOAD_PARTITION_BODY_SIZE;
  334. }
  335. uint32_t body_toread = preamble->body_signature.data_size;
  336. uint8_t *body_readptr = kernbuf;
  337. /*
  338. * If we've already read part of the kernel, copy that to the beginning
  339. * of the kernel buffer.
  340. */
  341. uint32_t body_copied = KBUF_SIZE - body_offset;
  342. if (body_copied > body_toread)
  343. body_copied = body_toread; /* Don't over-copy tiny kernel */
  344. memcpy(body_readptr, kbuf + body_offset, body_copied);
  345. body_toread -= body_copied;
  346. body_readptr += body_copied;
  347. /* Read the kernel data */
  348. if (body_toread && VbExStreamRead(stream, body_toread, body_readptr)) {
  349. VB2_DEBUG("Unable to read kernel data.\n");
  350. shpart->check_result = VBSD_LKP_CHECK_READ_DATA;
  351. return VB2_ERROR_LOAD_PARTITION_READ_BODY;
  352. }
  353. /* Get key for preamble/data verification from the key block. */
  354. struct vb2_public_key data_key;
  355. if (VB2_SUCCESS != vb2_unpack_key(&data_key, &keyblock->data_key)) {
  356. VB2_DEBUG("Unable to unpack kernel data key\n");
  357. shpart->check_result = VBSD_LKP_CHECK_DATA_KEY_PARSE;
  358. return VB2_ERROR_LOAD_PARTITION_DATA_KEY;
  359. }
  360. /* Verify kernel data */
  361. if (VB2_SUCCESS != vb2_verify_data(kernbuf, kernbuf_size,
  362. &preamble->body_signature,
  363. &data_key, &wblocal)) {
  364. VB2_DEBUG("Kernel data verification failed.\n");
  365. shpart->check_result = VBSD_LKP_CHECK_VERIFY_DATA;
  366. return VB2_ERROR_LOAD_PARTITION_VERIFY_BODY;
  367. }
  368. /* If we're still here, the kernel is valid */
  369. VB2_DEBUG("Partition is good.\n");
  370. shpart->check_result = VBSD_LKP_CHECK_KERNEL_GOOD;
  371. /* Save kernel data back to parameters */
  372. params->bootloader_address = preamble->bootloader_address;
  373. params->bootloader_size = preamble->bootloader_size;
  374. params->flags = vb2_kernel_get_flags(preamble);
  375. if (!params->kernel_buffer) {
  376. params->kernel_buffer = kernbuf;
  377. params->kernel_buffer_size = kernbuf_size;
  378. }
  379. return VB2_SUCCESS;
  380. }
  381. VbError_t LoadKernel(struct vb2_context *ctx, LoadKernelParams *params,
  382. VbCommonParams *cparams)
  383. {
  384. VbSharedDataHeader *shared = cparams->shared_data_blob;
  385. VbSharedDataKernelCall *shcall = NULL;
  386. struct vb2_packed_key *recovery_key = NULL;
  387. int found_partitions = 0;
  388. uint32_t lowest_version = LOWEST_TPM_VERSION;
  389. VbError_t retval = VBERROR_UNKNOWN;
  390. int recovery = VBNV_RECOVERY_LK_UNSPECIFIED;
  391. /* Clear output params in case we fail */
  392. params->partition_number = 0;
  393. params->bootloader_address = 0;
  394. params->bootloader_size = 0;
  395. params->flags = 0;
  396. /*
  397. * Set up tracking for this call. This wraps around if called many
  398. * times, so we need to initialize the call entry each time.
  399. */
  400. shcall = shared->lk_calls +
  401. (shared->lk_call_count & (VBSD_MAX_KERNEL_CALLS - 1));
  402. memset(shcall, 0, sizeof(*shcall));
  403. shcall->boot_flags = (uint32_t)params->boot_flags;
  404. shcall->boot_mode = get_kernel_boot_mode(ctx);
  405. shcall->sector_size = (uint32_t)params->bytes_per_lba;
  406. shcall->sector_count = params->streaming_lba_count;
  407. shared->lk_call_count++;
  408. /* Choose key to verify kernel */
  409. struct vb2_packed_key *kernel_subkey;
  410. if (kBootRecovery == shcall->boot_mode) {
  411. /* Use the recovery key to verify the kernel */
  412. retval = VbGbbReadRecoveryKey(cparams,
  413. (VbPublicKey **)&recovery_key);
  414. if (VBERROR_SUCCESS != retval)
  415. goto load_kernel_exit;
  416. kernel_subkey = recovery_key;
  417. } else {
  418. /* Use the kernel subkey passed from firmware verification */
  419. kernel_subkey = (struct vb2_packed_key *)&shared->kernel_subkey;
  420. }
  421. /* Read GPT data */
  422. GptData gpt;
  423. gpt.sector_bytes = (uint32_t)params->bytes_per_lba;
  424. gpt.streaming_drive_sectors = params->streaming_lba_count;
  425. gpt.gpt_drive_sectors = params->gpt_lba_count;
  426. gpt.flags = params->boot_flags & BOOT_FLAG_EXTERNAL_GPT
  427. ? GPT_FLAG_EXTERNAL : 0;
  428. if (0 != AllocAndReadGptData(params->disk_handle, &gpt)) {
  429. VB2_DEBUG("Unable to read GPT data\n");
  430. shcall->check_result = VBSD_LKC_CHECK_GPT_READ_ERROR;
  431. goto gpt_done;
  432. }
  433. /* Initialize GPT library */
  434. if (GPT_SUCCESS != GptInit(&gpt)) {
  435. VB2_DEBUG("Error parsing GPT\n");
  436. shcall->check_result = VBSD_LKC_CHECK_GPT_PARSE_ERROR;
  437. goto gpt_done;
  438. }
  439. /* Loop over candidate kernel partitions */
  440. uint64_t part_start, part_size;
  441. while (GPT_SUCCESS ==
  442. GptNextKernelEntry(&gpt, &part_start, &part_size)) {
  443. VB2_DEBUG("Found kernel entry at %"
  444. PRIu64 " size %" PRIu64 "\n",
  445. part_start, part_size);
  446. /*
  447. * Set up tracking for this partition. This wraps around if
  448. * called many times, so initialize the partition entry each
  449. * time.
  450. */
  451. VbSharedDataKernelPart *shpart =
  452. shcall->parts + (shcall->kernel_parts_found
  453. & (VBSD_MAX_KERNEL_PARTS - 1));
  454. memset(shpart, 0, sizeof(VbSharedDataKernelPart));
  455. shpart->sector_start = part_start;
  456. shpart->sector_count = part_size;
  457. /*
  458. * TODO: GPT partitions start at 1, but cgptlib starts them at
  459. * 0. Adjust here, until cgptlib is fixed.
  460. */
  461. shpart->gpt_index = (uint8_t)(gpt.current_kernel + 1);
  462. shcall->kernel_parts_found++;
  463. /* Found at least one kernel partition. */
  464. found_partitions++;
  465. /* Set up the stream */
  466. VbExStream_t stream = NULL;
  467. if (VbExStreamOpen(params->disk_handle,
  468. part_start, part_size, &stream)) {
  469. VB2_DEBUG("Partition error getting stream.\n");
  470. shpart->check_result = VBSD_LKP_CHECK_TOO_SMALL;
  471. VB2_DEBUG("Marking kernel as invalid.\n");
  472. GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_BAD);
  473. continue;
  474. }
  475. uint32_t lpflags = 0;
  476. if (params->partition_number > 0) {
  477. /*
  478. * If we already have a good kernel, we only needed to
  479. * look at the vblock versions to check for rollback.
  480. */
  481. lpflags |= VB2_LOAD_PARTITION_VBLOCK_ONLY;
  482. }
  483. int rv = vb2_load_partition(ctx,
  484. stream,
  485. kernel_subkey,
  486. lpflags,
  487. params,
  488. shared->kernel_version_tpm,
  489. shpart);
  490. VbExStreamClose(stream);
  491. if (rv != VB2_SUCCESS) {
  492. VB2_DEBUG("Marking kernel as invalid.\n");
  493. GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_BAD);
  494. continue;
  495. }
  496. int keyblock_valid = (shpart->flags &
  497. VBSD_LKP_FLAG_KEY_BLOCK_VALID);
  498. if (keyblock_valid) {
  499. shared->flags |= VBSD_KERNEL_KEY_VERIFIED;
  500. /* Track lowest version from a valid header. */
  501. if (lowest_version > shpart->combined_version)
  502. lowest_version = shpart->combined_version;
  503. }
  504. VB2_DEBUG("Key block valid: %d\n", keyblock_valid);
  505. VB2_DEBUG("Combined version: %u\n", shpart->combined_version);
  506. /*
  507. * If we're only looking at headers, we're done with this
  508. * partition.
  509. */
  510. if (lpflags & VB2_LOAD_PARTITION_VBLOCK_ONLY)
  511. continue;
  512. /*
  513. * Otherwise, we found a partition we like.
  514. *
  515. * TODO: GPT partitions start at 1, but cgptlib starts them at
  516. * 0. Adjust here, until cgptlib is fixed.
  517. */
  518. params->partition_number = gpt.current_kernel + 1;
  519. /*
  520. * TODO: GetCurrentKernelUniqueGuid() should take a destination
  521. * size, or the dest should be a struct, so we know it's big
  522. * enough.
  523. */
  524. GetCurrentKernelUniqueGuid(&gpt, &params->partition_guid);
  525. /* Update GPT to note this is the kernel we're trying.
  526. * But not when we assume that the boot process may
  527. * not complete for valid reasons (eg. early shutdown).
  528. */
  529. if (!(shared->flags & VBSD_NOFAIL_BOOT))
  530. GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_TRY);
  531. /*
  532. * If we're in recovery mode or we're about to boot a
  533. * non-officially-signed kernel, there's no rollback
  534. * protection, so we can stop at the first valid kernel.
  535. */
  536. if (kBootRecovery == shcall->boot_mode || !keyblock_valid) {
  537. VB2_DEBUG("In recovery mode or dev-signed kernel\n");
  538. break;
  539. }
  540. /*
  541. * Otherwise, we do care about the key index in the TPM. If
  542. * the good partition's key version is the same as the tpm,
  543. * then the TPM doesn't need updating; we can stop now.
  544. * Otherwise, we'll check all the other headers to see if they
  545. * contain a newer key.
  546. */
  547. if (shpart->combined_version == shared->kernel_version_tpm) {
  548. VB2_DEBUG("Same kernel version\n");
  549. break;
  550. }
  551. } /* while(GptNextKernelEntry) */
  552. gpt_done:
  553. /* Write and free GPT data */
  554. WriteAndFreeGptData(params->disk_handle, &gpt);
  555. /* Handle finding a good partition */
  556. if (params->partition_number > 0) {
  557. VB2_DEBUG("Good partition %d\n", params->partition_number);
  558. shcall->check_result = VBSD_LKC_CHECK_GOOD_PARTITION;
  559. shared->kernel_version_lowest = lowest_version;
  560. /*
  561. * Sanity check - only store a new TPM version if we found one.
  562. * If lowest_version is still at its initial value, we didn't
  563. * find one; for example, we're in developer mode and just
  564. * didn't look.
  565. */
  566. if (lowest_version != LOWEST_TPM_VERSION &&
  567. lowest_version > shared->kernel_version_tpm)
  568. shared->kernel_version_tpm = lowest_version;
  569. /* Success! */
  570. retval = VBERROR_SUCCESS;
  571. } else if (found_partitions > 0) {
  572. shcall->check_result = VBSD_LKC_CHECK_INVALID_PARTITIONS;
  573. recovery = VBNV_RECOVERY_RW_INVALID_OS;
  574. retval = VBERROR_INVALID_KERNEL_FOUND;
  575. } else {
  576. shcall->check_result = VBSD_LKC_CHECK_NO_PARTITIONS;
  577. recovery = VBNV_RECOVERY_RW_NO_OS;
  578. retval = VBERROR_NO_KERNEL_FOUND;
  579. }
  580. load_kernel_exit:
  581. /* Store recovery request, if any */
  582. vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST,
  583. VBERROR_SUCCESS != retval ?
  584. recovery : VBNV_RECOVERY_NOT_REQUESTED);
  585. /* Store how much shared data we used, if any */
  586. cparams->shared_data_size = shared->data_used;
  587. free(recovery_key);
  588. shcall->return_code = (uint8_t)retval;
  589. return retval;
  590. }