1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 * 5 * Routines for verifying a kernel or disk image 6 */ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include "host_common.h" 13 #include "util_misc.h" 14 #include "vboot_common.h" 15 #include "vboot_api.h" 16 #include "vboot_kernel.h" 17 18 static uint8_t *diskbuf; 19 20 static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE]; 21 static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data; 22 static VbNvContext nvc; 23 24 static LoadKernelParams params; 25 static VbCommonParams cparams; 26 27 VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start, 28 uint64_t lba_count, void *buffer) 29 { 30 if (handle != (VbExDiskHandle_t)1) 31 return VBERROR_UNKNOWN; 32 if (lba_start >= params.streaming_lba_count) 33 return VBERROR_UNKNOWN; 34 if (lba_start + lba_count > params.streaming_lba_count) 35 return VBERROR_UNKNOWN; 36 37 memcpy(buffer, diskbuf + lba_start * 512, lba_count * 512); 38 return VBERROR_SUCCESS; 39 } 40 41 VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start, 42 uint64_t lba_count, const void *buffer) 43 { 44 if (handle != (VbExDiskHandle_t)1) 45 return VBERROR_UNKNOWN; 46 if (lba_start >= params.streaming_lba_count) 47 return VBERROR_UNKNOWN; 48 if (lba_start + lba_count > params.streaming_lba_count) 49 return VBERROR_UNKNOWN; 50 51 memcpy(diskbuf + lba_start * 512, buffer, lba_count * 512); 52 return VBERROR_SUCCESS; 53 } 54 55 static void print_help(const char *progname) 56 { 57 printf("\nUsage: %s <disk_image> <kernel.vbpubk>\n\n", 58 progname); 59 } 60 61 int main(int argc, char *argv[]) 62 { 63 VbPublicKey *kernkey; 64 uint64_t disk_bytes = 0; 65 int rv; 66 67 if (argc < 3) { 68 print_help(argv[0]); 69 return 1; 70 } 71 72 /* Load disk file */ 73 /* TODO: is it better to mmap() in the long run? */ 74 diskbuf = ReadFile(argv[1], &disk_bytes); 75 if (!diskbuf) { 76 fprintf(stderr, "Can't read disk file %s\n", argv[1]); 77 return 1; 78 } 79 80 /* Read public key */ 81 kernkey = PublicKeyRead(argv[2]); 82 if (!kernkey) { 83 fprintf(stderr, "Can't read key file %s\n", argv[2]); 84 return 1; 85 } 86 87 /* Set up shared data blob */ 88 VbSharedDataInit(shared, sizeof(shared_data)); 89 VbSharedDataSetKernelKey(shared, kernkey); 90 /* TODO: optional TPM current kernel version */ 91 92 /* Set up params */ 93 params.shared_data_blob = shared_data; 94 params.shared_data_size = sizeof(shared_data); 95 params.disk_handle = (VbExDiskHandle_t)1; 96 params.bytes_per_lba = 512; 97 params.streaming_lba_count = disk_bytes / 512; 98 params.gpt_lba_count = params.streaming_lba_count; 99 100 params.kernel_buffer_size = 16 * 1024 * 1024; 101 params.kernel_buffer = malloc(params.kernel_buffer_size); 102 if (!params.kernel_buffer) { 103 fprintf(stderr, "Can't allocate kernel buffer\n"); 104 return 1; 105 } 106 107 /* GBB and cparams only needed by LoadKernel() in recovery mode */ 108 params.gbb_data = NULL; 109 params.gbb_size = 0; 110 111 /* TODO(chromium:441893): support dev-mode flag and external gpt flag */ 112 params.boot_flags = 0; 113 114 /* 115 * LoadKernel() cares only about VBNV_DEV_BOOT_SIGNED_ONLY, and only in 116 * dev mode. So just use defaults. 117 */ 118 VbNvSetup(&nvc); 119 params.nv_context = &nvc; 120 121 /* Try loading kernel */ 122 rv = LoadKernel(¶ms, &cparams); 123 if (rv != VBERROR_SUCCESS) { 124 fprintf(stderr, "LoadKernel() failed with code %d\n", rv); 125 return 1; 126 } 127 128 printf("Found a good kernel.\n"); 129 printf("Partition number: %d\n", (int)params.partition_number); 130 printf("Bootloader address: 0x%" PRIx64 "\n", 131 params.bootloader_address); 132 133 /* TODO: print other things (partition GUID, nv_context, shared_data) */ 134 135 printf("Yaay!\n"); 136 return 0; 137 } 138