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