blob: 8703697e28e82d41bca6fe36bd3f4434a2ee9261 [file] [log] [blame]
Randall Spangler7993f252013-01-29 15:01:12 -08001/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
Randall Spanglerd1836442010-06-10 09:59:04 -07002 * 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
Randall Spangler7c3ae422016-05-11 13:50:18 -07009#include "2common.h"
Randall Spanglere4136dc2016-10-27 14:34:59 -070010#include "2misc.h"
11#include "2nvstorage.h"
Joel Kitchinga82bb0e2021-01-18 15:37:56 +080012#include "2packed_key.h"
Randall Spangler13b10972016-10-14 11:04:27 -070013#include "2rsa.h"
Randall Spangler7c3ae422016-05-11 13:50:18 -070014#include "2sha.h"
Joel Kitching479f2d62019-08-30 14:31:46 +080015#include "2secdata.h"
Joel Kitching9adf2aa2019-08-20 17:43:50 +080016#include "2sysincludes.h"
Randall Spanglerd1836442010-06-10 09:59:04 -070017#include "cgptlib.h"
Bill Richardson5deb67f2010-07-23 17:22:25 -070018#include "cgptlib_internal.h"
Dan Ehrenberg7c2beb02014-10-21 16:15:54 -070019#include "gpt_misc.h"
Randall Spanglerd1836442010-06-10 09:59:04 -070020#include "load_kernel_fw.h"
Randall Spangler13b10972016-10-14 11:04:27 -070021#include "vb2_common.h"
Randall Spanglere49e8af2011-07-08 13:03:32 -070022#include "vboot_api.h"
Randall Spanglere49e8af2011-07-08 13:03:32 -070023#include "vboot_kernel.h"
Joel Kitchingb85ce072019-10-07 17:05:13 +080024#include "vboot_struct.h"
Randall Spanglere49e8af2011-07-08 13:03:32 -070025
Stefan Reinauer55db6a62011-03-15 16:23:41 -070026#define LOWEST_TPM_VERSION 0xffffffff
Randall Spanglerd1836442010-06-10 09:59:04 -070027
Joel Kitchingd68fbe42021-02-11 16:21:04 +080028enum vb2_boot_mode {
29 /* Normal boot: kernel must be verified. */
30 VB2_BOOT_MODE_NORMAL = 0,
31
32 /* Recovery boot, regardless of dev mode state. */
33 VB2_BOOT_MODE_RECOVERY = 1,
34
35 /* Developer boot: self-signed kernel okay. */
36 VB2_BOOT_MODE_DEVELOPER = 2,
Randall Spanglerf1824012016-10-25 10:00:27 -070037};
38
39/**
Joel Kitchingd68fbe42021-02-11 16:21:04 +080040 * Return the current boot mode (normal, recovery, or dev).
Randall Spanglerf1824012016-10-25 10:00:27 -070041 *
Joel Kitchingd68fbe42021-02-11 16:21:04 +080042 * @param ctx Vboot context
43 * @return Current boot mode (see vb2_boot_mode enum).
Randall Spanglerf1824012016-10-25 10:00:27 -070044 */
Joel Kitchingd68fbe42021-02-11 16:21:04 +080045static enum vb2_boot_mode get_boot_mode(struct vb2_context *ctx)
Randall Spanglerf1824012016-10-25 10:00:27 -070046{
Randall Spanglere4136dc2016-10-27 14:34:59 -070047 if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
Joel Kitchingd68fbe42021-02-11 16:21:04 +080048 return VB2_BOOT_MODE_RECOVERY;
Randall Spanglerf1824012016-10-25 10:00:27 -070049
Randall Spanglere4136dc2016-10-27 14:34:59 -070050 if (ctx->flags & VB2_CONTEXT_DEVELOPER_MODE)
Joel Kitchingd68fbe42021-02-11 16:21:04 +080051 return VB2_BOOT_MODE_DEVELOPER;
Randall Spanglerf1824012016-10-25 10:00:27 -070052
Joel Kitchingd68fbe42021-02-11 16:21:04 +080053 return VB2_BOOT_MODE_NORMAL;
54}
Randall Spanglerf1824012016-10-25 10:00:27 -070055
56/**
Joel Kitching230d9682021-02-12 09:56:29 +080057 * Check if a valid keyblock is required.
Randall Spanglerf1824012016-10-25 10:00:27 -070058 *
Joel Kitching230d9682021-02-12 09:56:29 +080059 * @param ctx Vboot context
60 * @return 1 if valid keyblock required (officially signed kernel);
61 * 0 if valid hash is enough (self-signed kernel).
Randall Spanglerf1824012016-10-25 10:00:27 -070062 */
Joel Kitching230d9682021-02-12 09:56:29 +080063static int need_valid_keyblock(struct vb2_context *ctx)
Randall Spanglerf1824012016-10-25 10:00:27 -070064{
65 /* Normal and recovery modes always require official OS */
Joel Kitchingd68fbe42021-02-11 16:21:04 +080066 if (get_boot_mode(ctx) != VB2_BOOT_MODE_DEVELOPER)
Randall Spanglerf1824012016-10-25 10:00:27 -070067 return 1;
68
Joel Kitching230d9682021-02-12 09:56:29 +080069 /* FWMP can require developer mode to use signed kernels */
Joel Kitchingadb41832019-09-23 22:53:49 +080070 if (vb2_secdata_fwmp_get_flag(
71 ctx, VB2_SECDATA_FWMP_DEV_ENABLE_OFFICIAL_ONLY))
Randall Spanglerf1824012016-10-25 10:00:27 -070072 return 1;
73
Joel Kitching230d9682021-02-12 09:56:29 +080074 /* Developers may require signed kernels */
75 if (vb2_nv_get(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY))
76 return 1;
77
78 return 0;
Randall Spanglerf1824012016-10-25 10:00:27 -070079}
80
81/**
82 * Return a pointer to the keyblock inside a vblock.
83 *
84 * Must only be called during or after vb2_verify_kernel_vblock().
85 *
86 * @param kbuf Buffer containing vblock
87 * @return The keyblock pointer.
88 */
89static struct vb2_keyblock *get_keyblock(uint8_t *kbuf)
90{
91 return (struct vb2_keyblock *)kbuf;
92}
93
94/**
95 * Return a pointer to the kernel preamble inside a vblock.
96 *
97 * Must only be called during or after vb2_verify_kernel_vblock().
98 *
99 * @param kbuf Buffer containing vblock
100 * @return The kernel preamble pointer.
101 */
102static struct vb2_kernel_preamble *get_preamble(uint8_t *kbuf)
103{
104 return (struct vb2_kernel_preamble *)
105 (kbuf + get_keyblock(kbuf)->keyblock_size);
106}
107
108/**
109 * Return the offset of the kernel body from the start of the vblock.
110 *
111 * Must only be called during or after vb2_verify_kernel_vblock().
112 *
113 * @param kbuf Buffer containing vblock
114 * @return The offset of the kernel body from the vblock start, in bytes.
115 */
116static uint32_t get_body_offset(uint8_t *kbuf)
117{
118 return (get_keyblock(kbuf)->keyblock_size +
119 get_preamble(kbuf)->preamble_size);
120}
121
122/**
Joel Kitchingf3f56e92021-04-14 13:30:53 +0800123 * Verify developer mode key hash.
124 *
125 * @param ctx Vboot context
126 * @param keyblock Keyblock to verify
127 * @return VB2_SUCCESS, or non-zero error code.
128 */
129static vb2_error_t vb2_verify_kernel_dev_key_hash(
130 struct vb2_context *ctx, struct vb2_keyblock *keyblock)
131{
132 struct vb2_packed_key *key = &keyblock->data_key;
133 uint8_t *buf = ((uint8_t *)key) + key->key_offset;
134 uint32_t buflen = key->key_size;
135 uint8_t digest[VB2_SHA256_DIGEST_SIZE];
136
137 VB2_DEBUG("Checking developer key hash.\n");
138 VB2_TRY(vb2_digest_buffer(buf, buflen, VB2_HASH_SHA256, digest,
139 sizeof(digest)));
140
141 uint8_t *fwmp_dev_key_hash =
142 vb2_secdata_fwmp_get_dev_key_hash(ctx);
143 if (fwmp_dev_key_hash == NULL) {
144 VB2_DEBUG("Couldn't retrieve developer key hash.\n");
145 return VB2_ERROR_KERNEL_KEYBLOCK_DEV_KEY_HASH;
146 }
147
148 if (vb2_safe_memcmp(digest, fwmp_dev_key_hash,
149 VB2_SHA256_DIGEST_SIZE)) {
150 int i;
151
152 VB2_DEBUG("Wrong developer key hash.\n");
153 VB2_DEBUG("Want: ");
154 for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++)
155 VB2_DEBUG_RAW("%02x ", fwmp_dev_key_hash[i]);
156 VB2_DEBUG_RAW("\n");
157 VB2_DEBUG("Got: ");
158 for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++)
159 VB2_DEBUG_RAW("%02x ", digest[i]);
160 VB2_DEBUG_RAW("\n");
161
162 return VB2_ERROR_KERNEL_KEYBLOCK_DEV_KEY_HASH;
163 }
164
165 return VB2_SUCCESS;
166}
167
168/**
Randall Spanglerf1824012016-10-25 10:00:27 -0700169 * Verify a kernel vblock.
170 *
171 * @param kbuf Buffer containing the vblock
172 * @param kbuf_size Size of the buffer in bytes
Randall Spanglerf1824012016-10-25 10:00:27 -0700173 * @param wb Work buffer. Must be at least
174 * VB2_VERIFY_KERNEL_PREAMBLE_WORKBUF_BYTES bytes.
175 * @return VB2_SUCCESS, or non-zero error code.
176 */
Joel Kitchinge6700f42019-07-31 14:12:30 +0800177static vb2_error_t vb2_verify_kernel_vblock(
178 struct vb2_context *ctx, uint8_t *kbuf, uint32_t kbuf_size,
Joel Kitching31b9ca22021-03-15 15:25:21 +0800179 struct vb2_workbuf *wb)
Randall Spanglerf1824012016-10-25 10:00:27 -0700180{
Joel Kitching74214a32021-02-12 16:26:03 +0800181 struct vb2_shared_data *sd = vb2_get_sd(ctx);
182
Joel Kitching542149a2021-02-12 16:58:44 +0800183 uint8_t *key_data;
184 uint32_t key_size;
185 struct vb2_public_key kernel_key;
186
Joel Kitching230d9682021-02-12 09:56:29 +0800187 int need_keyblock_valid = need_valid_keyblock(ctx);
188 int keyblock_valid = 1; /* Assume valid */
189
Joel Kitching21655912021-02-12 11:13:33 +0800190 vb2_error_t rv;
191
Joel Kitching542149a2021-02-12 16:58:44 +0800192 /* Locate key to verify kernel. This will either be a recovery key, or
193 a kernel subkey passed from firmware verification. */
194 key_data = vb2_member_of(sd, sd->kernel_key_offset);
195 key_size = sd->kernel_key_size;
196 VB2_TRY(vb2_unpack_key_buffer(&kernel_key, key_data, key_size));
Randall Spanglerf1824012016-10-25 10:00:27 -0700197
Kangheui Wona2b582f2021-02-02 17:32:06 +1100198 if (vb2_hwcrypto_allowed(ctx))
Joel Kitching542149a2021-02-12 16:58:44 +0800199 kernel_key.allow_hwcrypto = 1;
Kangheui Wona2b582f2021-02-02 17:32:06 +1100200
Joel Kitching13793e12021-02-12 17:28:02 +0800201 /*
202 * Clear any previous keyblock-valid flag (for example, from a previous
203 * kernel where the keyblock was signed but the preamble failed
204 * verification).
205 */
206 sd->flags &= ~VB2_SD_FLAG_KERNEL_SIGNED;
207
Joel Kitchingd3b21172019-09-04 14:12:42 +0800208 /* Verify the keyblock. */
Randall Spanglerf1824012016-10-25 10:00:27 -0700209 struct vb2_keyblock *keyblock = get_keyblock(kbuf);
Joel Kitching542149a2021-02-12 16:58:44 +0800210 rv = vb2_verify_keyblock(keyblock, kbuf_size, &kernel_key, wb);
Joel Kitching21655912021-02-12 11:13:33 +0800211 if (rv) {
Joel Kitchingd3b21172019-09-04 14:12:42 +0800212 VB2_DEBUG("Verifying keyblock signature failed.\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700213 keyblock_valid = 0;
214
215 /* Check if we must have an officially signed kernel */
Joel Kitching230d9682021-02-12 09:56:29 +0800216 if (need_keyblock_valid) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700217 VB2_DEBUG("Self-signed kernels not enabled.\n");
Joel Kitching21655912021-02-12 11:13:33 +0800218 return rv;
Randall Spanglerf1824012016-10-25 10:00:27 -0700219 }
220
Joel Kitchingd3b21172019-09-04 14:12:42 +0800221 /* Otherwise, allow the kernel if the keyblock hash is valid */
Joel Kitching21655912021-02-12 11:13:33 +0800222 rv = vb2_verify_keyblock_hash(keyblock, kbuf_size, wb);
223 if (rv) {
Joel Kitchingd3b21172019-09-04 14:12:42 +0800224 VB2_DEBUG("Verifying keyblock hash failed.\n");
Joel Kitching21655912021-02-12 11:13:33 +0800225 return rv;
Randall Spanglerf1824012016-10-25 10:00:27 -0700226 }
227 }
228
Joel Kitchingd3b21172019-09-04 14:12:42 +0800229 /* Check the keyblock flags against boot flags. */
Randall Spanglerf1824012016-10-25 10:00:27 -0700230 if (!(keyblock->keyblock_flags &
Randall Spanglere4136dc2016-10-27 14:34:59 -0700231 ((ctx->flags & VB2_CONTEXT_DEVELOPER_MODE) ?
Joel Kitching1ff55972019-08-30 16:02:24 +0800232 VB2_KEYBLOCK_FLAG_DEVELOPER_1 :
233 VB2_KEYBLOCK_FLAG_DEVELOPER_0))) {
Joel Kitchingd3b21172019-09-04 14:12:42 +0800234 VB2_DEBUG("Keyblock developer flag mismatch.\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700235 keyblock_valid = 0;
Joel Kitching230d9682021-02-12 09:56:29 +0800236 if (need_keyblock_valid)
237 return VB2_ERROR_KERNEL_KEYBLOCK_DEV_FLAG;
Randall Spanglerf1824012016-10-25 10:00:27 -0700238 }
239 if (!(keyblock->keyblock_flags &
Randall Spanglere4136dc2016-10-27 14:34:59 -0700240 ((ctx->flags & VB2_CONTEXT_RECOVERY_MODE) ?
Joel Kitching1ff55972019-08-30 16:02:24 +0800241 VB2_KEYBLOCK_FLAG_RECOVERY_1 :
242 VB2_KEYBLOCK_FLAG_RECOVERY_0))) {
Joel Kitchingd3b21172019-09-04 14:12:42 +0800243 VB2_DEBUG("Keyblock recovery flag mismatch.\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700244 keyblock_valid = 0;
Joel Kitching230d9682021-02-12 09:56:29 +0800245 if (need_keyblock_valid)
246 return VB2_ERROR_KERNEL_KEYBLOCK_REC_FLAG;
Randall Spanglerf1824012016-10-25 10:00:27 -0700247 }
248
249 /* Check for rollback of key version except in recovery mode. */
Joel Kitchingd68fbe42021-02-11 16:21:04 +0800250 enum vb2_boot_mode boot_mode = get_boot_mode(ctx);
Randall Spanglerf1824012016-10-25 10:00:27 -0700251 uint32_t key_version = keyblock->data_key.key_version;
Joel Kitchingd68fbe42021-02-11 16:21:04 +0800252 if (boot_mode != VB2_BOOT_MODE_RECOVERY) {
Joel Kitching74214a32021-02-12 16:26:03 +0800253 if (key_version < (sd->kernel_version_secdata >> 16)) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700254 VB2_DEBUG("Key version too old.\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700255 keyblock_valid = 0;
Joel Kitching230d9682021-02-12 09:56:29 +0800256 if (need_keyblock_valid)
257 return VB2_ERROR_KERNEL_KEYBLOCK_VERSION_ROLLBACK;
Randall Spanglerf1824012016-10-25 10:00:27 -0700258 }
Joel Kitching74214a32021-02-12 16:26:03 +0800259 if (key_version > VB2_MAX_KEY_VERSION) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700260 /*
261 * Key version is stored in 16 bits in the TPM, so key
262 * versions greater than 0xFFFF can't be stored
263 * properly.
264 */
265 VB2_DEBUG("Key version > 0xFFFF.\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700266 keyblock_valid = 0;
Joel Kitching230d9682021-02-12 09:56:29 +0800267 if (need_keyblock_valid)
268 return VB2_ERROR_KERNEL_KEYBLOCK_VERSION_RANGE;
Randall Spanglerf1824012016-10-25 10:00:27 -0700269 }
270 }
271
Joel Kitchingf3f56e92021-04-14 13:30:53 +0800272 /* If in developer mode and using key hash, check it. */
Joel Kitchingd68fbe42021-02-11 16:21:04 +0800273 if (boot_mode == VB2_BOOT_MODE_DEVELOPER &&
Joel Kitchingadb41832019-09-23 22:53:49 +0800274 vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_USE_KEY_HASH)) {
Joel Kitchingf3f56e92021-04-14 13:30:53 +0800275 VB2_TRY(vb2_verify_kernel_dev_key_hash(ctx, keyblock));
Randall Spanglerf1824012016-10-25 10:00:27 -0700276 }
277
Joel Kitching13793e12021-02-12 17:28:02 +0800278 /*
279 * At this point, we've checked everything. The kernel keyblock is at
280 * least self-consistent, and has either a valid signature or a valid
281 * hash. Track if it had a valid signature (that is, would we have
282 * been willing to boot it even if developer mode was off).
283 */
284 if (keyblock_valid)
285 sd->flags |= VB2_SD_FLAG_KERNEL_SIGNED;
286
Joel Kitchingd3b21172019-09-04 14:12:42 +0800287 /* Get key for preamble verification from the keyblock. */
Randall Spanglerf1824012016-10-25 10:00:27 -0700288 struct vb2_public_key data_key;
Joel Kitching21655912021-02-12 11:13:33 +0800289 rv = vb2_unpack_key(&data_key, &keyblock->data_key);
290 if (rv) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700291 VB2_DEBUG("Unable to unpack kernel data key\n");
Joel Kitching21655912021-02-12 11:13:33 +0800292 return rv;
Randall Spanglerf1824012016-10-25 10:00:27 -0700293 }
294
Joel Kitchingd3b21172019-09-04 14:12:42 +0800295 /* Verify the preamble, which follows the keyblock */
Randall Spanglerf1824012016-10-25 10:00:27 -0700296 struct vb2_kernel_preamble *preamble = get_preamble(kbuf);
Joel Kitching21655912021-02-12 11:13:33 +0800297 rv = vb2_verify_kernel_preamble(preamble,
298 kbuf_size - keyblock->keyblock_size,
299 &data_key,
300 wb);
301 if (rv) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700302 VB2_DEBUG("Preamble verification failed.\n");
Joel Kitching21655912021-02-12 11:13:33 +0800303 return rv;
Randall Spanglerf1824012016-10-25 10:00:27 -0700304 }
305
306 /*
Joel Kitching92ab6092021-02-12 16:47:28 +0800307 * Kernel preamble version is the lower 16 bits of the composite
308 * kernel version.
Randall Spanglerf1824012016-10-25 10:00:27 -0700309 */
Joel Kitching92ab6092021-02-12 16:47:28 +0800310 if (preamble->kernel_version > VB2_MAX_PREAMBLE_VERSION)
311 return VB2_ERROR_KERNEL_PREAMBLE_VERSION_RANGE;
312
313 /* Combine with the key version. */
314 sd->kernel_version = key_version << 16 | preamble->kernel_version;
Joel Kitching92ab6092021-02-12 16:47:28 +0800315
316 /* If not in recovery mode, check for rollback of the kernel version. */
317 if (need_keyblock_valid &&
318 boot_mode != VB2_BOOT_MODE_RECOVERY &&
319 sd->kernel_version < sd->kernel_version_secdata) {
320 VB2_DEBUG("Kernel version too low.\n");
Joel Kitching92ab6092021-02-12 16:47:28 +0800321 return VB2_ERROR_KERNEL_PREAMBLE_VERSION_ROLLBACK;
Randall Spanglerf1824012016-10-25 10:00:27 -0700322 }
323
324 VB2_DEBUG("Kernel preamble is good.\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700325 return VB2_SUCCESS;
326}
327
328enum vb2_load_partition_flags {
329 /* Only check the vblock to */
330 VB2_LOAD_PARTITION_VBLOCK_ONLY = (1 << 0),
331};
332
333#define KBUF_SIZE 65536 /* Bytes to read at start of kernel partition */
Randall Spanglere4136dc2016-10-27 14:34:59 -0700334
335/* Minimum context work buffer size needed for vb2_load_partition() */
Randall Spanglerf1824012016-10-25 10:00:27 -0700336#define VB2_LOAD_PARTITION_WORKBUF_BYTES \
337 (VB2_VERIFY_KERNEL_PREAMBLE_WORKBUF_BYTES + KBUF_SIZE)
338
339/**
340 * Load and verify a partition from the stream.
341 *
Randall Spanglere4136dc2016-10-27 14:34:59 -0700342 * @param ctx Vboot context
Randall Spanglerf1824012016-10-25 10:00:27 -0700343 * @param stream Stream to load kernel from
Randall Spanglerf1824012016-10-25 10:00:27 -0700344 * @param flags Flags (one or more of vb2_load_partition_flags)
345 * @param params Load-kernel parameters
Joel Kitching3eb00ef2019-05-23 15:33:54 +0800346 * @param wb Workbuf for data storage
Randall Spanglerf1824012016-10-25 10:00:27 -0700347 * @return VB2_SUCCESS, or non-zero error code.
348 */
Joel Kitchinge6700f42019-07-31 14:12:30 +0800349static vb2_error_t vb2_load_partition(
Joel Kitching542149a2021-02-12 16:58:44 +0800350 struct vb2_context *ctx, VbExStream_t stream, uint32_t flags,
351 LoadKernelParams *params, struct vb2_workbuf *wb)
Randall Spanglerf1824012016-10-25 10:00:27 -0700352{
Joel Kitching72d4c9d2020-04-21 12:50:03 +0800353 uint32_t read_ms = 0, start_ts;
Joel Kitching3eb00ef2019-05-23 15:33:54 +0800354 struct vb2_workbuf wblocal = *wb;
Randall Spanglerf1824012016-10-25 10:00:27 -0700355
356 /* Allocate kernel header buffer in workbuf */
357 uint8_t *kbuf = vb2_workbuf_alloc(&wblocal, KBUF_SIZE);
358 if (!kbuf)
359 return VB2_ERROR_LOAD_PARTITION_WORKBUF;
360
Joel Kitching72d4c9d2020-04-21 12:50:03 +0800361 start_ts = vb2ex_mtime();
Randall Spanglerf1824012016-10-25 10:00:27 -0700362 if (VbExStreamRead(stream, KBUF_SIZE, kbuf)) {
363 VB2_DEBUG("Unable to read start of partition.\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700364 return VB2_ERROR_LOAD_PARTITION_READ_VBLOCK;
365 }
Joel Kitching72d4c9d2020-04-21 12:50:03 +0800366 read_ms += vb2ex_mtime() - start_ts;
Randall Spanglerf1824012016-10-25 10:00:27 -0700367
Joel Kitchinge79d2762021-04-19 17:42:16 +0800368 if (vb2_verify_kernel_vblock(ctx, kbuf, KBUF_SIZE, &wblocal)) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700369 return VB2_ERROR_LOAD_PARTITION_VERIFY_VBLOCK;
370 }
371
372 if (flags & VB2_LOAD_PARTITION_VBLOCK_ONLY)
373 return VB2_SUCCESS;
374
375 struct vb2_keyblock *keyblock = get_keyblock(kbuf);
376 struct vb2_kernel_preamble *preamble = get_preamble(kbuf);
377
378 /*
379 * Make sure the kernel starts at or before what we already read into
380 * kbuf.
381 *
382 * We could deal with a larger offset by reading and discarding the
383 * data in between the vblock and the kernel data.
384 */
385 uint32_t body_offset = get_body_offset(kbuf);
386 if (body_offset > KBUF_SIZE) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700387 VB2_DEBUG("Kernel body offset is %u > 64KB.\n", body_offset);
388 return VB2_ERROR_LOAD_PARTITION_BODY_OFFSET;
389 }
390
391 uint8_t *kernbuf = params->kernel_buffer;
392 uint32_t kernbuf_size = params->kernel_buffer_size;
393 if (!kernbuf) {
394 /* Get kernel load address and size from the header. */
395 kernbuf = (uint8_t *)((long)preamble->body_load_address);
396 kernbuf_size = preamble->body_signature.data_size;
397 } else if (preamble->body_signature.data_size > kernbuf_size) {
398 VB2_DEBUG("Kernel body doesn't fit in memory.\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700399 return VB2_ERROR_LOAD_PARTITION_BODY_SIZE;
400 }
401
402 uint32_t body_toread = preamble->body_signature.data_size;
403 uint8_t *body_readptr = kernbuf;
404
405 /*
406 * If we've already read part of the kernel, copy that to the beginning
407 * of the kernel buffer.
408 */
409 uint32_t body_copied = KBUF_SIZE - body_offset;
410 if (body_copied > body_toread)
411 body_copied = body_toread; /* Don't over-copy tiny kernel */
412 memcpy(body_readptr, kbuf + body_offset, body_copied);
413 body_toread -= body_copied;
414 body_readptr += body_copied;
415
416 /* Read the kernel data */
Joel Kitching72d4c9d2020-04-21 12:50:03 +0800417 start_ts = vb2ex_mtime();
Randall Spanglerf1824012016-10-25 10:00:27 -0700418 if (body_toread && VbExStreamRead(stream, body_toread, body_readptr)) {
419 VB2_DEBUG("Unable to read kernel data.\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700420 return VB2_ERROR_LOAD_PARTITION_READ_BODY;
421 }
Joel Kitching72d4c9d2020-04-21 12:50:03 +0800422 read_ms += vb2ex_mtime() - start_ts;
423 if (read_ms == 0) /* Avoid division by 0 in speed calculation */
424 read_ms = 1;
425 VB2_DEBUG("read %u KB in %u ms at %u KB/s.\n",
426 (body_toread + KBUF_SIZE) / 1024, read_ms,
427 (uint32_t)(((body_toread + KBUF_SIZE) * VB2_MSEC_PER_SEC) /
428 (read_ms * 1024)));
Randall Spanglerf1824012016-10-25 10:00:27 -0700429
Joel Kitchingd3b21172019-09-04 14:12:42 +0800430 /* Get key for preamble/data verification from the keyblock. */
Randall Spanglerf1824012016-10-25 10:00:27 -0700431 struct vb2_public_key data_key;
Joel Kitchinge79d2762021-04-19 17:42:16 +0800432 if (vb2_unpack_key(&data_key, &keyblock->data_key)) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700433 VB2_DEBUG("Unable to unpack kernel data key\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700434 return VB2_ERROR_LOAD_PARTITION_DATA_KEY;
435 }
436
Kangheui Wona2b582f2021-02-02 17:32:06 +1100437 if (vb2_hwcrypto_allowed(ctx))
438 data_key.allow_hwcrypto = 1;
439
Randall Spanglerf1824012016-10-25 10:00:27 -0700440 /* Verify kernel data */
Joel Kitchinge79d2762021-04-19 17:42:16 +0800441 if (vb2_verify_data(kernbuf, kernbuf_size, &preamble->body_signature,
442 &data_key, &wblocal)) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700443 VB2_DEBUG("Kernel data verification failed.\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700444 return VB2_ERROR_LOAD_PARTITION_VERIFY_BODY;
445 }
446
447 /* If we're still here, the kernel is valid */
448 VB2_DEBUG("Partition is good.\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700449
450 /* Save kernel data back to parameters */
451 params->bootloader_address = preamble->bootloader_address;
452 params->bootloader_size = preamble->bootloader_size;
453 params->flags = vb2_kernel_get_flags(preamble);
454 if (!params->kernel_buffer) {
455 params->kernel_buffer = kernbuf;
456 params->kernel_buffer_size = kernbuf_size;
457 }
458
459 return VB2_SUCCESS;
460}
Randall Spangler640fb512011-03-03 10:11:17 -0800461
Joel Kitching90671fa2019-07-31 13:17:08 +0800462vb2_error_t LoadKernel(struct vb2_context *ctx, LoadKernelParams *params)
Randall Spangler7993f252013-01-29 15:01:12 -0800463{
Randall Spangler79c1c612018-01-03 13:42:40 -0800464 struct vb2_shared_data *sd = vb2_get_sd(ctx);
Joel Kitching3eb00ef2019-05-23 15:33:54 +0800465 struct vb2_workbuf wb;
Randall Spangler7993f252013-01-29 15:01:12 -0800466 int found_partitions = 0;
Randall Spangler7993f252013-01-29 15:01:12 -0800467 uint32_t lowest_version = LOWEST_TPM_VERSION;
Joel Kitchinge6700f42019-07-31 14:12:30 +0800468 vb2_error_t rv;
Randall Spanglerd1836442010-06-10 09:59:04 -0700469
Joel Kitching3eb00ef2019-05-23 15:33:54 +0800470 vb2_workbuf_from_ctx(ctx, &wb);
471
Randall Spangler7993f252013-01-29 15:01:12 -0800472 /* Clear output params in case we fail */
473 params->partition_number = 0;
474 params->bootloader_address = 0;
475 params->bootloader_size = 0;
Furquan Shaikhb7d1f032015-02-03 16:28:31 -0800476 params->flags = 0;
Bill Richardsone2729402010-07-22 12:23:47 -0700477
Randall Spangler7993f252013-01-29 15:01:12 -0800478 /* Read GPT data */
Randall Spanglerf1824012016-10-25 10:00:27 -0700479 GptData gpt;
480 gpt.sector_bytes = (uint32_t)params->bytes_per_lba;
Dan Ehrenberg3f4d8d02014-12-02 08:21:57 -0800481 gpt.streaming_drive_sectors = params->streaming_lba_count;
482 gpt.gpt_drive_sectors = params->gpt_lba_count;
483 gpt.flags = params->boot_flags & BOOT_FLAG_EXTERNAL_GPT
484 ? GPT_FLAG_EXTERNAL : 0;
Joel Kitchinge79d2762021-04-19 17:42:16 +0800485 if (AllocAndReadGptData(params->disk_handle, &gpt)) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700486 VB2_DEBUG("Unable to read GPT data\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700487 goto gpt_done;
Randall Spangler7993f252013-01-29 15:01:12 -0800488 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700489
Randall Spangler7993f252013-01-29 15:01:12 -0800490 /* Initialize GPT library */
Joel Kitchinge79d2762021-04-19 17:42:16 +0800491 if (GptInit(&gpt)) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700492 VB2_DEBUG("Error parsing GPT\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700493 goto gpt_done;
Randall Spangler13b10972016-10-14 11:04:27 -0700494 }
495
Gwendal Grignoue2e14ae2015-04-27 09:46:52 -0700496 /* Loop over candidate kernel partitions */
Randall Spanglerf1824012016-10-25 10:00:27 -0700497 uint64_t part_start, part_size;
Joel Kitchinge79d2762021-04-19 17:42:16 +0800498 while (GptNextKernelEntry(&gpt, &part_start, &part_size) ==
499 GPT_SUCCESS) {
Randall Spanglerd1836442010-06-10 09:59:04 -0700500
Randall Spanglerf1824012016-10-25 10:00:27 -0700501 VB2_DEBUG("Found kernel entry at %"
502 PRIu64 " size %" PRIu64 "\n",
503 part_start, part_size);
Randall Spanglerd1836442010-06-10 09:59:04 -0700504
Randall Spangler7993f252013-01-29 15:01:12 -0800505 /* Found at least one kernel partition. */
506 found_partitions++;
Randall Spangler17c71262011-03-18 11:24:27 -0700507
Randall Spangler4184e622014-10-08 16:41:01 -0700508 /* Set up the stream */
Randall Spanglerf1824012016-10-25 10:00:27 -0700509 VbExStream_t stream = NULL;
Randall Spangler4184e622014-10-08 16:41:01 -0700510 if (VbExStreamOpen(params->disk_handle,
511 part_start, part_size, &stream)) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700512 VB2_DEBUG("Partition error getting stream.\n");
Randall Spanglerf1824012016-10-25 10:00:27 -0700513 VB2_DEBUG("Marking kernel as invalid.\n");
514 GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_BAD);
Randall Spangler7993f252013-01-29 15:01:12 -0800515 continue;
Randall Spangler4184e622014-10-08 16:41:01 -0700516 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700517
Randall Spanglerf1824012016-10-25 10:00:27 -0700518 uint32_t lpflags = 0;
519 if (params->partition_number > 0) {
520 /*
521 * If we already have a good kernel, we only needed to
522 * look at the vblock versions to check for rollback.
523 */
524 lpflags |= VB2_LOAD_PARTITION_VBLOCK_ONLY;
Randall Spangler7993f252013-01-29 15:01:12 -0800525 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700526
Joel Kitchinge79d2762021-04-19 17:42:16 +0800527 rv = vb2_load_partition(ctx, stream, lpflags, params, &wb);
Randall Spangler4184e622014-10-08 16:41:01 -0700528 VbExStreamClose(stream);
Randall Spangler4184e622014-10-08 16:41:01 -0700529
Joel Kitchinge79d2762021-04-19 17:42:16 +0800530 if (rv) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700531 VB2_DEBUG("Marking kernel as invalid.\n");
532 GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_BAD);
533 continue;
Randall Spangler7993f252013-01-29 15:01:12 -0800534 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700535
Joel Kitching13793e12021-02-12 17:28:02 +0800536 int keyblock_valid = sd->flags & VB2_SD_FLAG_KERNEL_SIGNED;
537 /* Track lowest version from a valid header. */
538 if (keyblock_valid && lowest_version > sd->kernel_version) {
539 lowest_version = sd->kernel_version;
Randall Spanglerf1824012016-10-25 10:00:27 -0700540 }
Joel Kitchingd3b21172019-09-04 14:12:42 +0800541 VB2_DEBUG("Keyblock valid: %d\n", keyblock_valid);
Joel Kitching92ab6092021-02-12 16:47:28 +0800542 VB2_DEBUG("Combined version: %u\n", sd->kernel_version);
Randall Spangler17c71262011-03-18 11:24:27 -0700543
Randall Spangler7993f252013-01-29 15:01:12 -0800544 /*
Randall Spanglerf1824012016-10-25 10:00:27 -0700545 * If we're only looking at headers, we're done with this
546 * partition.
547 */
548 if (lpflags & VB2_LOAD_PARTITION_VBLOCK_ONLY)
549 continue;
550
551 /*
552 * Otherwise, we found a partition we like.
553 *
Randall Spangler7993f252013-01-29 15:01:12 -0800554 * TODO: GPT partitions start at 1, but cgptlib starts them at
555 * 0. Adjust here, until cgptlib is fixed.
556 */
Randall Spangler7993f252013-01-29 15:01:12 -0800557 params->partition_number = gpt.current_kernel + 1;
Randall Spanglerf1824012016-10-25 10:00:27 -0700558
Randall Spangler7993f252013-01-29 15:01:12 -0800559 /*
560 * TODO: GetCurrentKernelUniqueGuid() should take a destination
561 * size, or the dest should be a struct, so we know it's big
562 * enough.
563 */
Randall Spanglerf1824012016-10-25 10:00:27 -0700564 GetCurrentKernelUniqueGuid(&gpt, &params->partition_guid);
Randall Spangler741d2b22010-08-20 16:37:12 -0700565
Patrick Georgiebf886b2015-02-10 14:58:28 +0100566 /* Update GPT to note this is the kernel we're trying.
567 * But not when we assume that the boot process may
568 * not complete for valid reasons (eg. early shutdown).
569 */
Joel Kitching2efe82c2020-01-21 11:05:18 +0800570 if (!(ctx->flags & VB2_CONTEXT_NOFAIL_BOOT))
Patrick Georgiebf886b2015-02-10 14:58:28 +0100571 GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_TRY);
Randall Spangler741d2b22010-08-20 16:37:12 -0700572
Randall Spangler7993f252013-01-29 15:01:12 -0800573 /*
574 * If we're in recovery mode or we're about to boot a
Randall Spanglerf1824012016-10-25 10:00:27 -0700575 * non-officially-signed kernel, there's no rollback
576 * protection, so we can stop at the first valid kernel.
Randall Spangler7993f252013-01-29 15:01:12 -0800577 */
Joel Kitchingd68fbe42021-02-11 16:21:04 +0800578 if (get_boot_mode(ctx) == VB2_BOOT_MODE_RECOVERY ||
579 !keyblock_valid) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700580 VB2_DEBUG("In recovery mode or dev-signed kernel\n");
Randall Spangler7993f252013-01-29 15:01:12 -0800581 break;
582 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700583
Randall Spangler7993f252013-01-29 15:01:12 -0800584 /*
585 * Otherwise, we do care about the key index in the TPM. If
586 * the good partition's key version is the same as the tpm,
587 * then the TPM doesn't need updating; we can stop now.
588 * Otherwise, we'll check all the other headers to see if they
589 * contain a newer key.
590 */
Joel Kitching92ab6092021-02-12 16:47:28 +0800591 if (sd->kernel_version == sd->kernel_version_secdata) {
Randall Spanglerf1824012016-10-25 10:00:27 -0700592 VB2_DEBUG("Same kernel version\n");
Randall Spangler7993f252013-01-29 15:01:12 -0800593 break;
594 }
Gwendal Grignoue2e14ae2015-04-27 09:46:52 -0700595 } /* while(GptNextKernelEntry) */
Randall Spangler49cb0d32013-01-29 14:28:16 -0800596
Yu-Ping Wu896864c2020-04-09 11:08:27 +0800597 gpt_done:
Randall Spangler7993f252013-01-29 15:01:12 -0800598 /* Write and free GPT data */
599 WriteAndFreeGptData(params->disk_handle, &gpt);
Randall Spanglerd1836442010-06-10 09:59:04 -0700600
Randall Spangler7993f252013-01-29 15:01:12 -0800601 /* Handle finding a good partition */
Randall Spanglerf1824012016-10-25 10:00:27 -0700602 if (params->partition_number > 0) {
603 VB2_DEBUG("Good partition %d\n", params->partition_number);
Randall Spangler7993f252013-01-29 15:01:12 -0800604 /*
Daisuke Nojiri053592b2020-08-12 15:46:30 -0700605 * Validity check - only store a new TPM version if we found
606 * one. If lowest_version is still at its initial value, we
607 * didn't find one; for example, we're in developer mode and
608 * just didn't look.
Randall Spangler7993f252013-01-29 15:01:12 -0800609 */
610 if (lowest_version != LOWEST_TPM_VERSION &&
Joel Kitching74214a32021-02-12 16:26:03 +0800611 lowest_version > sd->kernel_version_secdata)
Joel Kitching83ab1902020-02-13 17:13:04 +0800612 sd->kernel_version = lowest_version;
Randall Spanglerd1836442010-06-10 09:59:04 -0700613
Randall Spangler7993f252013-01-29 15:01:12 -0800614 /* Success! */
Joel Kitching09f66702019-07-30 10:07:45 +0800615 rv = VB2_SUCCESS;
Randall Spangler7993f252013-01-29 15:01:12 -0800616 } else if (found_partitions > 0) {
Joel Kitching09f66702019-07-30 10:07:45 +0800617 rv = VB2_ERROR_LK_INVALID_KERNEL_FOUND;
Randall Spangler7993f252013-01-29 15:01:12 -0800618 } else {
Joel Kitching09f66702019-07-30 10:07:45 +0800619 rv = VB2_ERROR_LK_NO_KERNEL_FOUND;
Randall Spangler7993f252013-01-29 15:01:12 -0800620 }
Randall Spanglerd1836442010-06-10 09:59:04 -0700621
Joel Kitching09f66702019-07-30 10:07:45 +0800622 return rv;
Randall Spanglerd1836442010-06-10 09:59:04 -0700623}