xref: /aosp_15_r20/external/vboot_reference/firmware/2lib/2load_kernel.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1 /* Copyright 2013 The ChromiumOS Authors
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 
9 #include "2api.h"
10 #include "2common.h"
11 #include "2misc.h"
12 #include "2nvstorage.h"
13 #include "2packed_key.h"
14 #include "2secdata.h"
15 #include "2sysincludes.h"
16 #include "cgptlib.h"
17 #include "cgptlib_internal.h"
18 #include "gpt_misc.h"
19 #include "vboot_api.h"
20 
21 enum vb2_load_partition_flags {
22 	VB2_LOAD_PARTITION_FLAG_VBLOCK_ONLY = (1 << 0),
23 	VB2_LOAD_PARTITION_FLAG_MINIOS = (1 << 1),
24 };
25 
26 #define KBUF_SIZE 65536  /* Bytes to read at start of kernel partition */
27 
28 #define LOWEST_TPM_VERSION 0xffffffff
29 
30 /**
31  * Check if a valid keyblock is required.
32  *
33  * @param ctx		Vboot context
34  * @return 1 if valid keyblock required (officially signed kernel);
35  *         0 if valid hash is enough (self-signed kernel).
36  */
need_valid_keyblock(struct vb2_context * ctx)37 static int need_valid_keyblock(struct vb2_context *ctx)
38 {
39 	/* Normal and recovery modes always require official OS */
40 	if (ctx->boot_mode != VB2_BOOT_MODE_DEVELOPER)
41 		return 1;
42 
43 	/* FWMP can require developer mode to use signed kernels */
44 	if (vb2_secdata_fwmp_get_flag(
45 		ctx, VB2_SECDATA_FWMP_DEV_ENABLE_OFFICIAL_ONLY))
46 		return 1;
47 
48 	/* Developers may require signed kernels */
49 	if (vb2_nv_get(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY))
50 		return 1;
51 
52 	return 0;
53 }
54 
55 /**
56  * Return a pointer to the keyblock inside a vblock.
57  *
58  * Must only be called during or after vb2_verify_kernel_vblock().
59  *
60  * @param kbuf		Buffer containing vblock
61  * @return The keyblock pointer.
62  */
get_keyblock(uint8_t * kbuf)63 static struct vb2_keyblock *get_keyblock(uint8_t *kbuf)
64 {
65 	return (struct vb2_keyblock *)kbuf;
66 }
67 
68 /**
69  * Return a pointer to the kernel preamble inside a vblock.
70  *
71  * Must only be called during or after vb2_verify_kernel_vblock().
72  *
73  * @param kbuf		Buffer containing vblock
74  * @return The kernel preamble pointer.
75  */
get_preamble(uint8_t * kbuf)76 static struct vb2_kernel_preamble *get_preamble(uint8_t *kbuf)
77 {
78 	return (struct vb2_kernel_preamble *)
79 			(kbuf + get_keyblock(kbuf)->keyblock_size);
80 }
81 
82 /**
83  * Return the offset of the kernel body from the start of the vblock.
84  *
85  * Must only be called during or after vb2_verify_kernel_vblock().
86  *
87  * @param kbuf		Buffer containing vblock
88  * @return The offset of the kernel body from the vblock start, in bytes.
89  */
get_body_offset(uint8_t * kbuf)90 static uint32_t get_body_offset(uint8_t *kbuf)
91 {
92 	return (get_keyblock(kbuf)->keyblock_size +
93 		get_preamble(kbuf)->preamble_size);
94 }
95 
96 /**
97  * Verify developer mode key hash.
98  *
99  * @param ctx		Vboot context
100  * @param keyblock	Keyblock to verify
101  * @return VB2_SUCCESS, or non-zero error code.
102  */
vb2_verify_kernel_dev_key_hash(struct vb2_context * ctx,struct vb2_keyblock * keyblock)103 static vb2_error_t vb2_verify_kernel_dev_key_hash(
104 	struct vb2_context *ctx, struct vb2_keyblock *keyblock)
105 {
106 	struct vb2_packed_key *key = &keyblock->data_key;
107 	uint8_t *buf = ((uint8_t *)key) + key->key_offset;
108 	uint32_t buflen = key->key_size;
109 	struct vb2_hash hash;
110 
111 	VB2_DEBUG("Checking developer key hash.\n");
112 	VB2_TRY(vb2_hash_calculate(vb2api_hwcrypto_allowed(ctx), buf, buflen,
113 				   VB2_HASH_SHA256, &hash));
114 
115 	uint8_t *fwmp_dev_key_hash =
116 		vb2_secdata_fwmp_get_dev_key_hash(ctx);
117 	if (fwmp_dev_key_hash == NULL) {
118 		VB2_DEBUG("Couldn't retrieve developer key hash.\n");
119 		return VB2_ERROR_KERNEL_KEYBLOCK_DEV_KEY_HASH;
120 	}
121 
122 	if (vb2_safe_memcmp(hash.sha256, fwmp_dev_key_hash,
123 			    sizeof(hash.sha256))) {
124 		int i;
125 
126 		VB2_DEBUG("Wrong developer key hash.\n");
127 		VB2_DEBUG("Want: ");
128 		for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++)
129 			VB2_DEBUG_RAW("%02x ", fwmp_dev_key_hash[i]);
130 		VB2_DEBUG_RAW("\n");
131 		VB2_DEBUG("Got:  ");
132 		for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++)
133 			VB2_DEBUG_RAW("%02x ", hash.sha256[i]);
134 		VB2_DEBUG_RAW("\n");
135 
136 		return VB2_ERROR_KERNEL_KEYBLOCK_DEV_KEY_HASH;
137 	}
138 
139 	return VB2_SUCCESS;
140 }
141 
142 /**
143  * Verify a kernel vblock.
144  *
145  * @param ctx			Vboot context
146  * @param kbuf			Buffer containing the vblock
147  * @param kbuf_size		Size of the buffer in bytes
148  * @param lpflags		Flags (one or more of vb2_load_partition_flags)
149  * @param wb			Work buffer.  Must be at least
150  *				VB2_VERIFY_KERNEL_PREAMBLE_WORKBUF_BYTES bytes.
151  * @param kernel_version	The kernel version of this vblock.
152  * @return VB2_SUCCESS, or non-zero error code.
153  */
vb2_verify_kernel_vblock(struct vb2_context * ctx,uint8_t * kbuf,uint32_t kbuf_size,uint32_t lpflags,struct vb2_workbuf * wb,uint32_t * kernel_version)154 static vb2_error_t vb2_verify_kernel_vblock(struct vb2_context *ctx,
155 					    uint8_t *kbuf, uint32_t kbuf_size,
156 					    uint32_t lpflags,
157 					    struct vb2_workbuf *wb,
158 					    uint32_t *kernel_version)
159 {
160 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
161 
162 	uint8_t *key_data;
163 	uint32_t key_size;
164 	struct vb2_public_key kernel_key;
165 
166 	int need_keyblock_valid = need_valid_keyblock(ctx);
167 	int keyblock_valid = 1;  /* Assume valid */
168 
169 	vb2_error_t rv;
170 
171 	/* Locate key to verify kernel.  This will either be a recovery key, or
172 	   a kernel subkey passed from firmware verification. */
173 	key_data = vb2_member_of(sd, sd->kernel_key_offset);
174 	key_size = sd->kernel_key_size;
175 	VB2_TRY(vb2_unpack_key_buffer(&kernel_key, key_data, key_size));
176 
177 	kernel_key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx);
178 
179 	/*
180 	 * Clear any previous keyblock-valid flag (for example, from a previous
181 	 * kernel where the keyblock was signed but the preamble failed
182 	 * verification).
183 	 */
184 	sd->flags &= ~VB2_SD_FLAG_KERNEL_SIGNED;
185 
186 	/* Verify the keyblock. */
187 	struct vb2_keyblock *keyblock = get_keyblock(kbuf);
188 	rv = vb2_verify_keyblock(keyblock, kbuf_size, &kernel_key, wb);
189 	if (rv) {
190 		VB2_DEBUG("Verifying keyblock signature failed.\n");
191 		keyblock_valid = 0;
192 
193 		/* Check if we must have an officially signed kernel */
194 		if (need_keyblock_valid) {
195 			VB2_DEBUG("Self-signed kernels not enabled.\n");
196 			return rv;
197 		}
198 
199 		/* Otherwise, allow the kernel if the keyblock hash is valid */
200 		rv = vb2_verify_keyblock_hash(keyblock, kbuf_size, wb);
201 		if (rv) {
202 			VB2_DEBUG("Verifying keyblock hash failed.\n");
203 			return rv;
204 		}
205 	}
206 
207 	/* Check the keyblock flags against boot flags. */
208 	if (!(keyblock->keyblock_flags &
209 	      ((ctx->flags & VB2_CONTEXT_DEVELOPER_MODE) ?
210 	       VB2_KEYBLOCK_FLAG_DEVELOPER_1 :
211 	       VB2_KEYBLOCK_FLAG_DEVELOPER_0))) {
212 		VB2_DEBUG("Keyblock developer flag mismatch.\n");
213 		keyblock_valid = 0;
214 		if (need_keyblock_valid)
215 			return VB2_ERROR_KERNEL_KEYBLOCK_DEV_FLAG;
216 	}
217 	if (!(keyblock->keyblock_flags &
218 	      ((ctx->flags & VB2_CONTEXT_RECOVERY_MODE) ?
219 	       VB2_KEYBLOCK_FLAG_RECOVERY_1 :
220 	       VB2_KEYBLOCK_FLAG_RECOVERY_0))) {
221 		VB2_DEBUG("Keyblock recovery flag mismatch.\n");
222 		keyblock_valid = 0;
223 		if (need_keyblock_valid)
224 			return VB2_ERROR_KERNEL_KEYBLOCK_REC_FLAG;
225 	}
226 	if (!(keyblock->keyblock_flags &
227 	      ((lpflags & VB2_LOAD_PARTITION_FLAG_MINIOS) ?
228 	       VB2_KEYBLOCK_FLAG_MINIOS_1 :
229 	       VB2_KEYBLOCK_FLAG_MINIOS_0))) {
230 		VB2_DEBUG("Keyblock miniOS flag mismatch.\n");
231 		keyblock_valid = 0;
232 		if (need_keyblock_valid)
233 			return VB2_ERROR_KERNEL_KEYBLOCK_MINIOS_FLAG;
234 	}
235 
236 	/* Check for rollback of key version except in recovery mode. */
237 	uint32_t key_version = keyblock->data_key.key_version;
238 	if (ctx->boot_mode != VB2_BOOT_MODE_MANUAL_RECOVERY) {
239 		if (key_version < (sd->kernel_version_secdata >> 16)) {
240 			keyblock_valid = 0;
241 			if (need_keyblock_valid) {
242 				VB2_DEBUG("Key version too old.\n");
243 				return VB2_ERROR_KERNEL_KEYBLOCK_VERSION_ROLLBACK;
244 			}
245 		}
246 		if (key_version > VB2_MAX_KEY_VERSION) {
247 			/*
248 			 * Key version is stored in 16 bits in the TPM, so key
249 			 * versions greater than 0xFFFF can't be stored
250 			 * properly.
251 			 */
252 			VB2_DEBUG("Key version > 0xFFFF.\n");
253 			keyblock_valid = 0;
254 			if (need_keyblock_valid)
255 				return VB2_ERROR_KERNEL_KEYBLOCK_VERSION_RANGE;
256 		}
257 	}
258 
259 	/* If in developer mode and using key hash, check it. */
260 	if (ctx->boot_mode == VB2_BOOT_MODE_DEVELOPER &&
261 	    vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_USE_KEY_HASH)) {
262 		VB2_TRY(vb2_verify_kernel_dev_key_hash(ctx, keyblock));
263 	}
264 
265 	/*
266 	 * At this point, we've checked everything.  The kernel keyblock is at
267 	 * least self-consistent, and has either a valid signature or a valid
268 	 * hash.  Track if it had a valid signature (that is, would we have
269 	 * been willing to boot it even if developer mode was off).
270 	 */
271 	if (keyblock_valid)
272 		sd->flags |= VB2_SD_FLAG_KERNEL_SIGNED;
273 
274 	/* Get key for preamble verification from the keyblock. */
275 	struct vb2_public_key data_key;
276 	rv = vb2_unpack_key(&data_key, &keyblock->data_key);
277 	if (rv) {
278 		VB2_DEBUG("Unable to unpack kernel data key\n");
279 		return rv;
280 	}
281 
282 	data_key.allow_hwcrypto = kernel_key.allow_hwcrypto;
283 
284 	/* Verify the preamble, which follows the keyblock */
285 	struct vb2_kernel_preamble *preamble = get_preamble(kbuf);
286 	rv = vb2_verify_kernel_preamble(preamble,
287 					kbuf_size - keyblock->keyblock_size,
288 					&data_key,
289 					wb);
290 	if (rv) {
291 		VB2_DEBUG("Preamble verification failed.\n");
292 		return rv;
293 	}
294 
295 	/* Rollback check for miniOS */
296 	if (need_keyblock_valid && (lpflags & VB2_LOAD_PARTITION_FLAG_MINIOS)) {
297 		if (preamble->kernel_version <
298 		    (sd->kernel_version_secdata >> 24)) {
299 			keyblock_valid = 0;
300 			if (need_keyblock_valid) {
301 				VB2_DEBUG("miniOS kernel version too old.\n");
302 				return VB2_ERROR_KERNEL_PREAMBLE_VERSION_ROLLBACK;
303 			}
304 		}
305 		if (preamble->kernel_version > 0xff) {
306 			/*
307 			 * Key version is stored in the top 8 bits of 16 bits
308 			 * in the TPM, so key versions greater than 0xFF can't
309 			 * be stored properly.
310 			 */
311 			VB2_DEBUG("Key version > 0xFF.\n");
312 			keyblock_valid = 0;
313 			if (need_keyblock_valid)
314 				return VB2_ERROR_KERNEL_PREAMBLE_VERSION_RANGE;
315 		}
316 	}
317 
318 	/*
319 	 * Kernel preamble version is the lower 16 bits of the composite
320 	 * kernel version.
321 	 */
322 	if (preamble->kernel_version > VB2_MAX_PREAMBLE_VERSION)
323 		return VB2_ERROR_KERNEL_PREAMBLE_VERSION_RANGE;
324 
325 	/* Combine with the key version. */
326 	*kernel_version = key_version << 16 | preamble->kernel_version;
327 
328 	/* If not in recovery mode, check for rollback of the kernel version. */
329 	if (need_keyblock_valid &&
330 	    ctx->boot_mode != VB2_BOOT_MODE_MANUAL_RECOVERY &&
331 	    *kernel_version < sd->kernel_version_secdata) {
332 		VB2_DEBUG("Kernel version too low.\n");
333 		return VB2_ERROR_KERNEL_PREAMBLE_VERSION_ROLLBACK;
334 	}
335 
336 	VB2_DEBUG("Kernel preamble is good.\n");
337 	return VB2_SUCCESS;
338 }
339 
340 /**
341  * Load and verify a partition from the stream.
342  *
343  * @param ctx			Vboot context
344  * @param params		Load-kernel parameters
345  * @param stream		Stream to load kernel from
346  * @param lpflags		Flags (one or more of vb2_load_partition_flags)
347  * @param kernel_version	The kernel version of this partition.
348  * @return VB2_SUCCESS, or non-zero error code.
349  */
vb2_load_partition(struct vb2_context * ctx,struct vb2_kernel_params * params,VbExStream_t stream,uint32_t lpflags,uint32_t * kernel_version)350 static vb2_error_t vb2_load_partition(struct vb2_context *ctx,
351 				      struct vb2_kernel_params *params,
352 				      VbExStream_t stream, uint32_t lpflags,
353 				      uint32_t *kernel_version)
354 {
355 	uint32_t read_ms = 0, start_ts;
356 	struct vb2_workbuf wb;
357 
358 	vb2_workbuf_from_ctx(ctx, &wb);
359 
360 	/* Allocate kernel header buffer in workbuf */
361 	uint8_t *kbuf = vb2_workbuf_alloc(&wb, KBUF_SIZE);
362 	if (!kbuf)
363 		return VB2_ERROR_LOAD_PARTITION_WORKBUF;
364 
365 	start_ts = vb2ex_mtime();
366 	if (VbExStreamRead(stream, KBUF_SIZE, kbuf)) {
367 		VB2_DEBUG("Unable to read start of partition.\n");
368 		return VB2_ERROR_LOAD_PARTITION_READ_VBLOCK;
369 	}
370 	read_ms += vb2ex_mtime() - start_ts;
371 
372 	if (vb2_verify_kernel_vblock(ctx, kbuf, KBUF_SIZE, lpflags, &wb,
373 				     kernel_version))
374 		return VB2_ERROR_LOAD_PARTITION_VERIFY_VBLOCK;
375 
376 	if (lpflags & VB2_LOAD_PARTITION_FLAG_VBLOCK_ONLY)
377 		return VB2_SUCCESS;
378 
379 	struct vb2_keyblock *keyblock = get_keyblock(kbuf);
380 	struct vb2_kernel_preamble *preamble = get_preamble(kbuf);
381 
382 	/*
383 	 * Make sure the kernel starts at or before what we already read into
384 	 * kbuf.
385 	 *
386 	 * We could deal with a larger offset by reading and discarding the
387 	 * data in between the vblock and the kernel data.
388 	 */
389 	uint32_t body_offset = get_body_offset(kbuf);
390 	if (body_offset > KBUF_SIZE) {
391 		VB2_DEBUG("Kernel body offset is %u > 64KB.\n", body_offset);
392 		return VB2_ERROR_LOAD_PARTITION_BODY_OFFSET;
393 	}
394 
395 	uint8_t *kernbuf = params->kernel_buffer;
396 	uint32_t kernbuf_size = params->kernel_buffer_size;
397 	if (!kernbuf) {
398 		/* Get kernel load address and size from the header. */
399 		kernbuf = (uint8_t *)((long)preamble->body_load_address);
400 		kernbuf_size = preamble->body_signature.data_size;
401 	} else if (preamble->body_signature.data_size > kernbuf_size) {
402 		VB2_DEBUG("Kernel body doesn't fit in memory.\n");
403 		return 	VB2_ERROR_LOAD_PARTITION_BODY_SIZE;
404 	}
405 
406 	uint32_t body_toread = preamble->body_signature.data_size;
407 	uint8_t *body_readptr = kernbuf;
408 
409 	/*
410 	 * If we've already read part of the kernel, copy that to the beginning
411 	 * of the kernel buffer.
412 	 */
413 	uint32_t body_copied = KBUF_SIZE - body_offset;
414 	if (body_copied > body_toread)
415 		body_copied = body_toread;  /* Don't over-copy tiny kernel */
416 	memcpy(body_readptr, kbuf + body_offset, body_copied);
417 	body_toread -= body_copied;
418 	body_readptr += body_copied;
419 
420 	/* Read the kernel data */
421 	start_ts = vb2ex_mtime();
422 	if (body_toread && VbExStreamRead(stream, body_toread, body_readptr)) {
423 		VB2_DEBUG("Unable to read kernel data.\n");
424 		return VB2_ERROR_LOAD_PARTITION_READ_BODY;
425 	}
426 	read_ms += vb2ex_mtime() - start_ts;
427 	if (read_ms == 0)  /* Avoid division by 0 in speed calculation */
428 		read_ms = 1;
429 	VB2_DEBUG("read %u KB in %u ms at %u KB/s.\n",
430 		  (body_toread + KBUF_SIZE) / 1024, read_ms,
431 		  (uint32_t)(((body_toread + KBUF_SIZE) * VB2_MSEC_PER_SEC) /
432 			     (read_ms * 1024)));
433 
434 	/* Get key for preamble/data verification from the keyblock. */
435 	struct vb2_public_key data_key;
436 	if (vb2_unpack_key(&data_key, &keyblock->data_key)) {
437 		VB2_DEBUG("Unable to unpack kernel data key\n");
438 		return VB2_ERROR_LOAD_PARTITION_DATA_KEY;
439 	}
440 
441 	data_key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx);
442 
443 	/* Verify kernel data */
444 	if (vb2_verify_data(kernbuf, kernbuf_size, &preamble->body_signature,
445 			    &data_key, &wb)) {
446 		VB2_DEBUG("Kernel data verification failed.\n");
447 		return VB2_ERROR_LOAD_PARTITION_VERIFY_BODY;
448 	}
449 
450 	/* If we're still here, the kernel is valid */
451 	VB2_DEBUG("Partition is good.\n");
452 
453 	/* Save kernel data back to parameters */
454 	params->bootloader_offset = preamble->bootloader_address -
455 				    preamble->body_load_address;
456 	params->bootloader_size = preamble->bootloader_size;
457 	params->flags = vb2_kernel_get_flags(preamble);
458 	if (!params->kernel_buffer) {
459 		params->kernel_buffer = kernbuf;
460 		params->kernel_buffer_size = kernbuf_size;
461 	}
462 
463 	return VB2_SUCCESS;
464 }
465 
try_minios_kernel(struct vb2_context * ctx,struct vb2_kernel_params * params,struct vb2_disk_info * disk_info,uint64_t sector)466 static vb2_error_t try_minios_kernel(struct vb2_context *ctx,
467 				     struct vb2_kernel_params *params,
468 				     struct vb2_disk_info *disk_info,
469 				     uint64_t sector) {
470 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
471 	VbExStream_t stream;
472 	uint64_t sectors_left = disk_info->lba_count - sector;
473 	const uint32_t lpflags = VB2_LOAD_PARTITION_FLAG_MINIOS;
474 	uint32_t kernel_version = 0;
475 	vb2_error_t rv = VB2_ERROR_LK_NO_KERNEL_FOUND;
476 
477 	/* Re-open stream at correct offset to pass to vb2_load_partition. */
478 	if (VbExStreamOpen(disk_info->handle, sector, sectors_left,
479 			   &stream)) {
480 		VB2_DEBUG("Unable to open disk handle.\n");
481 		return rv;
482 	}
483 
484 	rv = vb2_load_partition(ctx, params, stream, lpflags, &kernel_version);
485 	VB2_DEBUG("vb2_load_partition returned: %d\n", rv);
486 
487 	VbExStreamClose(stream);
488 
489 	if (rv)
490 		return VB2_ERROR_LK_NO_KERNEL_FOUND;
491 
492 	sd->kernel_version = kernel_version;
493 
494 	return rv;
495 }
496 
try_minios_sectors(struct vb2_context * ctx,struct vb2_kernel_params * params,struct vb2_disk_info * disk_info,uint64_t start,uint64_t count)497 static vb2_error_t try_minios_sectors(struct vb2_context *ctx,
498 				      struct vb2_kernel_params *params,
499 				      struct vb2_disk_info *disk_info,
500 				      uint64_t start, uint64_t count)
501 {
502 	const uint32_t buf_size = count * disk_info->bytes_per_lba;
503 	char *buf;
504 	VbExStream_t stream;
505 	uint64_t isector;
506 	vb2_error_t rv = VB2_ERROR_LK_NO_KERNEL_FOUND;
507 
508 	buf = malloc(buf_size);
509 	if (buf == NULL) {
510 		VB2_DEBUG("Unable to allocate disk read buffer.\n");
511 		return rv;
512 	}
513 
514 	if (VbExStreamOpen(disk_info->handle, start, count, &stream)) {
515 		VB2_DEBUG("Unable to open disk handle.\n");
516 		free(buf);
517 		return rv;
518 	}
519 	if (VbExStreamRead(stream, buf_size, buf)) {
520 		VB2_DEBUG("Unable to read disk.\n");
521 		free(buf);
522 		VbExStreamClose(stream);
523 		return rv;
524 	}
525 	VbExStreamClose(stream);
526 
527 	for (isector = 0; isector < count; isector++) {
528 		if (memcmp(buf + isector * disk_info->bytes_per_lba,
529 			   VB2_KEYBLOCK_MAGIC, VB2_KEYBLOCK_MAGIC_SIZE))
530 			continue;
531 		VB2_DEBUG("Match on sector %" PRIu64 " / %" PRIu64 "\n",
532 			  start + isector,
533 			  disk_info->lba_count - 1);
534 		rv = try_minios_kernel(ctx, params, disk_info, start + isector);
535 		if (rv == VB2_SUCCESS)
536 			break;
537 	}
538 
539 	free(buf);
540 	return rv;
541 }
542 
try_minios_sector_region(struct vb2_context * ctx,struct vb2_kernel_params * params,struct vb2_disk_info * disk_info,int end_region)543 static vb2_error_t try_minios_sector_region(struct vb2_context *ctx,
544 					    struct vb2_kernel_params *params,
545 					    struct vb2_disk_info *disk_info,
546 					    int end_region)
547 {
548 	const uint64_t disk_count_half = (disk_info->lba_count + 1) / 2;
549 	const uint64_t check_count_256 = 256 * 1024
550 		* 1024 / disk_info->bytes_per_lba;  // 256 MB
551 	const uint64_t batch_count_1 = 1024
552 		* 1024 / disk_info->bytes_per_lba;  // 1 MB
553 	const uint64_t check_count = VB2_MIN(disk_count_half, check_count_256);
554 	const uint64_t batch_count = VB2_MIN(disk_count_half, batch_count_1);
555 	uint64_t sector;
556 	uint64_t start;
557 	uint64_t end;
558 	const char *region_name;
559 	vb2_error_t rv = VB2_ERROR_LK_NO_KERNEL_FOUND;
560 
561 	if (!end_region) {
562 		start = 0;
563 		end = check_count;
564 		region_name = "start";
565 	} else {
566 		start = disk_info->lba_count - check_count;
567 		end = disk_info->lba_count;
568 		region_name = "end";
569 	}
570 
571 	VB2_DEBUG("Checking %s of disk for kernels...\n", region_name);
572 	for (sector = start; sector < end; sector += batch_count) {
573 		rv = try_minios_sectors(ctx, params, disk_info, sector,
574 					batch_count);
575 		if (rv == VB2_SUCCESS)
576 			return rv;
577 	}
578 
579 	return rv;
580 }
581 
582 /*
583  * Search for kernels by sector, rather than by partition.  Only sectors near
584  * the start and end of disks are considered, and the kernel must start exactly
585  * at the first byte of the sector.
586  */
vb2api_load_minios_kernel(struct vb2_context * ctx,struct vb2_kernel_params * params,struct vb2_disk_info * disk_info,uint32_t minios_flags)587 vb2_error_t vb2api_load_minios_kernel(struct vb2_context *ctx,
588 				      struct vb2_kernel_params *params,
589 				      struct vb2_disk_info *disk_info,
590 				      uint32_t minios_flags)
591 {
592 	vb2_error_t rv;
593 	int end_region_first = vb2_nv_get(ctx, VB2_NV_MINIOS_PRIORITY);
594 
595 	if (minios_flags & VB2_MINIOS_FLAG_NON_ACTIVE)
596 		rv = VB2_ERROR_UNKNOWN;  /* Ignore active partition */
597 	else
598 		rv = try_minios_sector_region(ctx, params, disk_info,
599 					      end_region_first);
600 
601 	if (rv)
602 		rv = try_minios_sector_region(ctx, params, disk_info,
603 					      !end_region_first);
604 
605 	if (rv == VB2_SUCCESS)
606 		params->disk_handle = disk_info->handle;
607 
608 	return rv;
609 }
610 
vb2api_load_kernel(struct vb2_context * ctx,struct vb2_kernel_params * params,struct vb2_disk_info * disk_info)611 vb2_error_t vb2api_load_kernel(struct vb2_context *ctx,
612 			       struct vb2_kernel_params *params,
613 			       struct vb2_disk_info *disk_info)
614 {
615 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
616 	int found_partitions = 0;
617 	uint32_t lowest_version = LOWEST_TPM_VERSION;
618 	vb2_error_t rv;
619 
620 	/* Clear output params */
621 	params->partition_number = 0;
622 
623 	/* Read GPT data */
624 	GptData gpt;
625 	gpt.sector_bytes = (uint32_t)disk_info->bytes_per_lba;
626 	gpt.streaming_drive_sectors = disk_info->streaming_lba_count
627 		?: disk_info->lba_count;
628 	gpt.gpt_drive_sectors = disk_info->lba_count;
629 	gpt.flags = disk_info->flags & VB2_DISK_FLAG_EXTERNAL_GPT
630 			? GPT_FLAG_EXTERNAL : 0;
631 	if (AllocAndReadGptData(disk_info->handle, &gpt)) {
632 		VB2_DEBUG("Unable to read GPT data\n");
633 		goto gpt_done;
634 	}
635 
636 	/* Initialize GPT library */
637 	if (GptInit(&gpt)) {
638 		VB2_DEBUG("Error parsing GPT\n");
639 		goto gpt_done;
640 	}
641 
642 	/* Loop over candidate kernel partitions */
643 	uint64_t part_start, part_size;
644 	while (GptNextKernelEntry(&gpt, &part_start, &part_size) ==
645 	       GPT_SUCCESS) {
646 
647 		VB2_DEBUG("Found kernel entry at %"
648 			  PRIu64 " size %" PRIu64 "\n",
649 			  part_start, part_size);
650 
651 		/* Found at least one kernel partition. */
652 		found_partitions++;
653 
654 		/* Set up the stream */
655 		VbExStream_t stream = NULL;
656 		if (VbExStreamOpen(disk_info->handle,
657 				   part_start, part_size, &stream)) {
658 			VB2_DEBUG("Partition error getting stream.\n");
659 			VB2_DEBUG("Marking kernel as invalid.\n");
660 			GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_BAD);
661 			continue;
662 		}
663 
664 		uint32_t lpflags = 0;
665 		if (params->partition_number > 0) {
666 			/*
667 			 * If we already have a good kernel, we only needed to
668 			 * look at the vblock versions to check for rollback.
669 			 */
670 			lpflags |= VB2_LOAD_PARTITION_FLAG_VBLOCK_ONLY;
671 		}
672 
673 		uint32_t kernel_version = 0;
674 		rv = vb2_load_partition(ctx, params, stream, lpflags,
675 					&kernel_version);
676 		VbExStreamClose(stream);
677 
678 		if (rv) {
679 			VB2_DEBUG("Marking kernel as invalid (err=%x).\n", rv);
680 			GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_BAD);
681 			continue;
682 		}
683 
684 		int keyblock_valid = sd->flags & VB2_SD_FLAG_KERNEL_SIGNED;
685 		/* Track lowest version from a valid header. */
686 		if (keyblock_valid && lowest_version > kernel_version)
687 			lowest_version = kernel_version;
688 
689 		VB2_DEBUG("Keyblock valid: %d\n", keyblock_valid);
690 		VB2_DEBUG("Combined version: %u\n", kernel_version);
691 
692 		/*
693 		 * If we're only looking at headers, we're done with this
694 		 * partition.
695 		 */
696 		if (lpflags & VB2_LOAD_PARTITION_FLAG_VBLOCK_ONLY)
697 			continue;
698 
699 		/*
700 		 * Otherwise, we found a partition we like.
701 		 *
702 		 * TODO: GPT partitions start at 1, but cgptlib starts them at
703 		 * 0.  Adjust here, until cgptlib is fixed.
704 		 */
705 		params->partition_number = gpt.current_kernel + 1;
706 
707 		sd->kernel_version = kernel_version;
708 
709 		/*
710 		 * TODO: GetCurrentKernelUniqueGuid() should take a destination
711 		 * size, or the dest should be a struct, so we know it's big
712 		 * enough.
713 		 */
714 		GetCurrentKernelUniqueGuid(&gpt, &params->partition_guid);
715 
716 		/* Update GPT to note this is the kernel we're trying.
717 		 * But not when we assume that the boot process may
718 		 * not complete for valid reasons (eg. early shutdown).
719 		 */
720 		if (!(ctx->flags & VB2_CONTEXT_NOFAIL_BOOT))
721 			GptUpdateKernelEntry(&gpt, GPT_UPDATE_ENTRY_TRY);
722 
723 		/*
724 		 * If we're in recovery mode or we're about to boot a
725 		 * non-officially-signed kernel, there's no rollback
726 		 * protection, so we can stop at the first valid kernel.
727 		 */
728 		if (ctx->boot_mode == VB2_BOOT_MODE_MANUAL_RECOVERY ||
729 		    !keyblock_valid) {
730 			VB2_DEBUG("In recovery mode or dev-signed kernel\n");
731 			break;
732 		}
733 
734 		/*
735 		 * Otherwise, we do care about the key index in the TPM.  If
736 		 * the good partition's key version is the same as the tpm,
737 		 * then the TPM doesn't need updating; we can stop now.
738 		 * Otherwise, we'll check all the other headers to see if they
739 		 * contain a newer key.
740 		 */
741 		if (sd->kernel_version == sd->kernel_version_secdata) {
742 			VB2_DEBUG("Same kernel version\n");
743 			break;
744 		}
745 	} /* while (GptNextKernelEntry) */
746 
747  gpt_done:
748 	/* Write and free GPT data */
749 	WriteAndFreeGptData(disk_info->handle, &gpt);
750 
751 	/* Handle finding a good partition */
752 	if (params->partition_number > 0) {
753 		VB2_DEBUG("Good partition %d\n", params->partition_number);
754 		/*
755 		 * Validity check - only store a new TPM version if we found
756 		 * one. If lowest_version is still at its initial value, we
757 		 * didn't find one; for example, we're in developer mode and
758 		 * just didn't look.
759 		 */
760 		if (lowest_version != LOWEST_TPM_VERSION &&
761 		    lowest_version > sd->kernel_version_secdata)
762 			sd->kernel_version_secdata = lowest_version;
763 
764 		/* Success! */
765 		rv = VB2_SUCCESS;
766 		params->disk_handle = disk_info->handle;
767 	} else if (found_partitions > 0) {
768 		rv = VB2_ERROR_LK_INVALID_KERNEL_FOUND;
769 	} else {
770 		rv = VB2_ERROR_LK_NO_KERNEL_FOUND;
771 	}
772 
773 	return rv;
774 }
775