123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Routines for verifying a kernel or disk image
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "2sysincludes.h"
- #include "2api.h"
- #include "2misc.h"
- #include "host_common.h"
- #include "util_misc.h"
- #include "vboot_common.h"
- #include "vboot_api.h"
- #include "vboot_kernel.h"
- static uint8_t *diskbuf;
- static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
- static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
- static VbNvContext nvc;
- static LoadKernelParams params;
- static VbCommonParams cparams;
- VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start,
- uint64_t lba_count, void *buffer)
- {
- if (handle != (VbExDiskHandle_t)1)
- return VBERROR_UNKNOWN;
- if (lba_start >= params.streaming_lba_count)
- return VBERROR_UNKNOWN;
- if (lba_start + lba_count > params.streaming_lba_count)
- return VBERROR_UNKNOWN;
- memcpy(buffer, diskbuf + lba_start * 512, lba_count * 512);
- return VBERROR_SUCCESS;
- }
- VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start,
- uint64_t lba_count, const void *buffer)
- {
- if (handle != (VbExDiskHandle_t)1)
- return VBERROR_UNKNOWN;
- if (lba_start >= params.streaming_lba_count)
- return VBERROR_UNKNOWN;
- if (lba_start + lba_count > params.streaming_lba_count)
- return VBERROR_UNKNOWN;
- memcpy(diskbuf + lba_start * 512, buffer, lba_count * 512);
- return VBERROR_SUCCESS;
- }
- static void print_help(const char *progname)
- {
- printf("\nUsage: %s <disk_image> <kernel.vbpubk>\n\n",
- progname);
- }
- int main(int argc, char *argv[])
- {
- VbPublicKey *kernkey;
- uint64_t disk_bytes = 0;
- int rv;
- if (argc < 3) {
- print_help(argv[0]);
- return 1;
- }
- /* Load disk file */
- /* TODO: is it better to mmap() in the long run? */
- diskbuf = ReadFile(argv[1], &disk_bytes);
- if (!diskbuf) {
- fprintf(stderr, "Can't read disk file %s\n", argv[1]);
- return 1;
- }
- /* Read public key */
- kernkey = (VbPublicKey *)vb2_read_packed_key(argv[2]);
- if (!kernkey) {
- fprintf(stderr, "Can't read key file %s\n", argv[2]);
- return 1;
- }
- /* Set up shared data blob */
- VbSharedDataInit(shared, sizeof(shared_data));
- VbSharedDataSetKernelKey(shared, kernkey);
- /* TODO: optional TPM current kernel version */
- /* Set up params */
- cparams.shared_data_blob = shared_data;
- cparams.shared_data_size = sizeof(shared_data);
- params.disk_handle = (VbExDiskHandle_t)1;
- params.bytes_per_lba = 512;
- params.streaming_lba_count = disk_bytes / 512;
- params.gpt_lba_count = params.streaming_lba_count;
- params.kernel_buffer_size = 16 * 1024 * 1024;
- params.kernel_buffer = malloc(params.kernel_buffer_size);
- if (!params.kernel_buffer) {
- fprintf(stderr, "Can't allocate kernel buffer\n");
- return 1;
- }
- /* TODO(chromium:441893): support dev-mode flag and external gpt flag */
- params.boot_flags = 0;
- /*
- * LoadKernel() cares only about VBNV_DEV_BOOT_SIGNED_ONLY, and only in
- * dev mode. So just use defaults.
- */
- VbNvSetup(&nvc);
- params.nv_context = &nvc;
- /*
- * Set up vboot context.
- *
- * TODO: Propagate this up to higher API levels
- */
- struct vb2_context ctx;
- memset(&ctx, 0, sizeof(ctx));
- /* No need to initialize ctx->nvdata[]; defaults are fine */
- /* TODO(chromium:441893): support dev-mode flag and external gpt flag */
- ctx.workbuf = malloc(VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE);
- if (!ctx.workbuf) {
- fprintf(stderr, "Can't allocate workbuf\n");
- return 1;
- }
- ctx.workbuf_size = VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE;
- if (VB2_SUCCESS != vb2_init_context(&ctx)) {
- free(ctx.workbuf);
- fprintf(stderr, "Can't init context\n");
- return 1;
- }
- /* Try loading kernel */
- rv = LoadKernel(&ctx, ¶ms, &cparams);
- if (rv != VBERROR_SUCCESS) {
- fprintf(stderr, "LoadKernel() failed with code %d\n", rv);
- return 1;
- }
- printf("Found a good kernel.\n");
- printf("Partition number: %u\n", params.partition_number);
- printf("Bootloader address: 0x%" PRIx64 "\n",
- params.bootloader_address);
- /* TODO: print other things (partition GUID, nv_context, shared_data) */
- printf("Yaay!\n");
- return 0;
- }
|