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