Home | History | Annotate | Download | only in tests
      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(&params, &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