1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2014 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker *
5*8617a60dSAndroid Build Coastguard Worker * Routines for verifying a kernel or disk image
6*8617a60dSAndroid Build Coastguard Worker */
7*8617a60dSAndroid Build Coastguard Worker
8*8617a60dSAndroid Build Coastguard Worker #include "2sysincludes.h"
9*8617a60dSAndroid Build Coastguard Worker #include "2api.h"
10*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
11*8617a60dSAndroid Build Coastguard Worker #include "2misc.h"
12*8617a60dSAndroid Build Coastguard Worker #include "2nvstorage.h"
13*8617a60dSAndroid Build Coastguard Worker #include "2secdata.h"
14*8617a60dSAndroid Build Coastguard Worker #include "host_common.h"
15*8617a60dSAndroid Build Coastguard Worker #include "util_misc.h"
16*8617a60dSAndroid Build Coastguard Worker #include "vboot_api.h"
17*8617a60dSAndroid Build Coastguard Worker
18*8617a60dSAndroid Build Coastguard Worker static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
19*8617a60dSAndroid Build Coastguard Worker __attribute__((aligned(VB2_WORKBUF_ALIGN)));
20*8617a60dSAndroid Build Coastguard Worker static struct vb2_context *ctx;
21*8617a60dSAndroid Build Coastguard Worker
22*8617a60dSAndroid Build Coastguard Worker static uint8_t *diskbuf;
23*8617a60dSAndroid Build Coastguard Worker
24*8617a60dSAndroid Build Coastguard Worker static struct vb2_kernel_params params;
25*8617a60dSAndroid Build Coastguard Worker static struct vb2_disk_info disk_info;
26*8617a60dSAndroid Build Coastguard Worker
VbExDiskRead(vb2ex_disk_handle_t handle,uint64_t lba_start,uint64_t lba_count,void * buffer)27*8617a60dSAndroid Build Coastguard Worker vb2_error_t VbExDiskRead(vb2ex_disk_handle_t handle, uint64_t lba_start,
28*8617a60dSAndroid Build Coastguard Worker uint64_t lba_count, void *buffer)
29*8617a60dSAndroid Build Coastguard Worker {
30*8617a60dSAndroid Build Coastguard Worker if (handle != (vb2ex_disk_handle_t)1)
31*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
32*8617a60dSAndroid Build Coastguard Worker if (lba_start >= disk_info.streaming_lba_count)
33*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
34*8617a60dSAndroid Build Coastguard Worker if (lba_start + lba_count > disk_info.streaming_lba_count)
35*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
36*8617a60dSAndroid Build Coastguard Worker
37*8617a60dSAndroid Build Coastguard Worker memcpy(buffer, diskbuf + lba_start * 512, lba_count * 512);
38*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
39*8617a60dSAndroid Build Coastguard Worker }
40*8617a60dSAndroid Build Coastguard Worker
VbExDiskWrite(vb2ex_disk_handle_t handle,uint64_t lba_start,uint64_t lba_count,const void * buffer)41*8617a60dSAndroid Build Coastguard Worker vb2_error_t VbExDiskWrite(vb2ex_disk_handle_t handle, uint64_t lba_start,
42*8617a60dSAndroid Build Coastguard Worker uint64_t lba_count, const void *buffer)
43*8617a60dSAndroid Build Coastguard Worker {
44*8617a60dSAndroid Build Coastguard Worker if (handle != (vb2ex_disk_handle_t)1)
45*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
46*8617a60dSAndroid Build Coastguard Worker if (lba_start >= disk_info.streaming_lba_count)
47*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
48*8617a60dSAndroid Build Coastguard Worker if (lba_start + lba_count > disk_info.streaming_lba_count)
49*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
50*8617a60dSAndroid Build Coastguard Worker
51*8617a60dSAndroid Build Coastguard Worker memcpy(diskbuf + lba_start * 512, buffer, lba_count * 512);
52*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
53*8617a60dSAndroid Build Coastguard Worker }
54*8617a60dSAndroid Build Coastguard Worker
print_help(const char * progname)55*8617a60dSAndroid Build Coastguard Worker static void print_help(const char *progname)
56*8617a60dSAndroid Build Coastguard Worker {
57*8617a60dSAndroid Build Coastguard Worker printf("\nUsage: %s <disk_image> <kernel.vbpubk>\n\n",
58*8617a60dSAndroid Build Coastguard Worker progname);
59*8617a60dSAndroid Build Coastguard Worker }
60*8617a60dSAndroid Build Coastguard Worker
main(int argc,char * argv[])61*8617a60dSAndroid Build Coastguard Worker int main(int argc, char *argv[])
62*8617a60dSAndroid Build Coastguard Worker {
63*8617a60dSAndroid Build Coastguard Worker uint8_t *kernkey = NULL;
64*8617a60dSAndroid Build Coastguard Worker uint64_t kernkey_size = 0;
65*8617a60dSAndroid Build Coastguard Worker uint64_t disk_bytes = 0;
66*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv;
67*8617a60dSAndroid Build Coastguard Worker
68*8617a60dSAndroid Build Coastguard Worker if (argc < 3) {
69*8617a60dSAndroid Build Coastguard Worker print_help(argv[0]);
70*8617a60dSAndroid Build Coastguard Worker return 1;
71*8617a60dSAndroid Build Coastguard Worker }
72*8617a60dSAndroid Build Coastguard Worker
73*8617a60dSAndroid Build Coastguard Worker /* Load disk file */
74*8617a60dSAndroid Build Coastguard Worker /* TODO: is it better to mmap() in the long run? */
75*8617a60dSAndroid Build Coastguard Worker diskbuf = ReadFile(argv[1], &disk_bytes);
76*8617a60dSAndroid Build Coastguard Worker if (!diskbuf) {
77*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Can't read disk file %s\n", argv[1]);
78*8617a60dSAndroid Build Coastguard Worker return 1;
79*8617a60dSAndroid Build Coastguard Worker }
80*8617a60dSAndroid Build Coastguard Worker
81*8617a60dSAndroid Build Coastguard Worker /* Read public key */
82*8617a60dSAndroid Build Coastguard Worker kernkey = ReadFile(argv[2], &kernkey_size);
83*8617a60dSAndroid Build Coastguard Worker if (!kernkey) {
84*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Can't read key file %s\n", argv[2]);
85*8617a60dSAndroid Build Coastguard Worker return 1;
86*8617a60dSAndroid Build Coastguard Worker }
87*8617a60dSAndroid Build Coastguard Worker
88*8617a60dSAndroid Build Coastguard Worker /* Set up params */
89*8617a60dSAndroid Build Coastguard Worker disk_info.handle = (vb2ex_disk_handle_t)1;
90*8617a60dSAndroid Build Coastguard Worker disk_info.bytes_per_lba = 512;
91*8617a60dSAndroid Build Coastguard Worker disk_info.streaming_lba_count = disk_bytes / 512;
92*8617a60dSAndroid Build Coastguard Worker disk_info.lba_count = disk_info.streaming_lba_count;
93*8617a60dSAndroid Build Coastguard Worker
94*8617a60dSAndroid Build Coastguard Worker params.kernel_buffer_size = 16 * 1024 * 1024;
95*8617a60dSAndroid Build Coastguard Worker params.kernel_buffer = malloc(params.kernel_buffer_size);
96*8617a60dSAndroid Build Coastguard Worker if (!params.kernel_buffer) {
97*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Can't allocate kernel buffer\n");
98*8617a60dSAndroid Build Coastguard Worker return 1;
99*8617a60dSAndroid Build Coastguard Worker }
100*8617a60dSAndroid Build Coastguard Worker
101*8617a60dSAndroid Build Coastguard Worker /* TODO(chromium:441893): support dev-mode flag and external gpt flag */
102*8617a60dSAndroid Build Coastguard Worker disk_info.flags = 0;
103*8617a60dSAndroid Build Coastguard Worker
104*8617a60dSAndroid Build Coastguard Worker if (vb2api_init(&workbuf, sizeof(workbuf), &ctx)) {
105*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Can't initialize workbuf\n");
106*8617a60dSAndroid Build Coastguard Worker return 1;
107*8617a60dSAndroid Build Coastguard Worker }
108*8617a60dSAndroid Build Coastguard Worker
109*8617a60dSAndroid Build Coastguard Worker rv = vb2api_inject_kernel_subkey(ctx, kernkey, kernkey_size);
110*8617a60dSAndroid Build Coastguard Worker if (rv != VB2_SUCCESS) {
111*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "vb2api_inject_kernel_subkey failed: %x\n",
112*8617a60dSAndroid Build Coastguard Worker rv);
113*8617a60dSAndroid Build Coastguard Worker return 1;
114*8617a60dSAndroid Build Coastguard Worker }
115*8617a60dSAndroid Build Coastguard Worker
116*8617a60dSAndroid Build Coastguard Worker /* Try loading kernel */
117*8617a60dSAndroid Build Coastguard Worker rv = vb2api_load_kernel(ctx, ¶ms, &disk_info);
118*8617a60dSAndroid Build Coastguard Worker if (rv != VB2_SUCCESS) {
119*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "vb2api_load_kernel() failed with code %x\n",
120*8617a60dSAndroid Build Coastguard Worker rv);
121*8617a60dSAndroid Build Coastguard Worker return 1;
122*8617a60dSAndroid Build Coastguard Worker }
123*8617a60dSAndroid Build Coastguard Worker
124*8617a60dSAndroid Build Coastguard Worker printf("Found a good kernel.\n");
125*8617a60dSAndroid Build Coastguard Worker printf("Partition number: %u\n", params.partition_number);
126*8617a60dSAndroid Build Coastguard Worker printf("Bootloader offset: 0x%" PRIx64 "\n",
127*8617a60dSAndroid Build Coastguard Worker params.bootloader_offset);
128*8617a60dSAndroid Build Coastguard Worker
129*8617a60dSAndroid Build Coastguard Worker /* TODO: print other things (partition GUID, shared_data) */
130*8617a60dSAndroid Build Coastguard Worker
131*8617a60dSAndroid Build Coastguard Worker printf("Yaay!\n");
132*8617a60dSAndroid Build Coastguard Worker return 0;
133*8617a60dSAndroid Build Coastguard Worker }
134