verify_kernel.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "2sysincludes.h"
  11. #include "2api.h"
  12. #include "2misc.h"
  13. #include "host_common.h"
  14. #include "util_misc.h"
  15. #include "vboot_common.h"
  16. #include "vboot_api.h"
  17. #include "vboot_kernel.h"
  18. static uint8_t *diskbuf;
  19. static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
  20. static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
  21. static VbNvContext nvc;
  22. static LoadKernelParams params;
  23. static VbCommonParams cparams;
  24. VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start,
  25. uint64_t lba_count, void *buffer)
  26. {
  27. if (handle != (VbExDiskHandle_t)1)
  28. return VBERROR_UNKNOWN;
  29. if (lba_start >= params.streaming_lba_count)
  30. return VBERROR_UNKNOWN;
  31. if (lba_start + lba_count > params.streaming_lba_count)
  32. return VBERROR_UNKNOWN;
  33. memcpy(buffer, diskbuf + lba_start * 512, lba_count * 512);
  34. return VBERROR_SUCCESS;
  35. }
  36. VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start,
  37. uint64_t lba_count, const void *buffer)
  38. {
  39. if (handle != (VbExDiskHandle_t)1)
  40. return VBERROR_UNKNOWN;
  41. if (lba_start >= params.streaming_lba_count)
  42. return VBERROR_UNKNOWN;
  43. if (lba_start + lba_count > params.streaming_lba_count)
  44. return VBERROR_UNKNOWN;
  45. memcpy(diskbuf + lba_start * 512, buffer, lba_count * 512);
  46. return VBERROR_SUCCESS;
  47. }
  48. static void print_help(const char *progname)
  49. {
  50. printf("\nUsage: %s <disk_image> <kernel.vbpubk>\n\n",
  51. progname);
  52. }
  53. int main(int argc, char *argv[])
  54. {
  55. VbPublicKey *kernkey;
  56. uint64_t disk_bytes = 0;
  57. int rv;
  58. if (argc < 3) {
  59. print_help(argv[0]);
  60. return 1;
  61. }
  62. /* Load disk file */
  63. /* TODO: is it better to mmap() in the long run? */
  64. diskbuf = ReadFile(argv[1], &disk_bytes);
  65. if (!diskbuf) {
  66. fprintf(stderr, "Can't read disk file %s\n", argv[1]);
  67. return 1;
  68. }
  69. /* Read public key */
  70. kernkey = (VbPublicKey *)vb2_read_packed_key(argv[2]);
  71. if (!kernkey) {
  72. fprintf(stderr, "Can't read key file %s\n", argv[2]);
  73. return 1;
  74. }
  75. /* Set up shared data blob */
  76. VbSharedDataInit(shared, sizeof(shared_data));
  77. VbSharedDataSetKernelKey(shared, kernkey);
  78. /* TODO: optional TPM current kernel version */
  79. /* Set up params */
  80. cparams.shared_data_blob = shared_data;
  81. cparams.shared_data_size = sizeof(shared_data);
  82. params.disk_handle = (VbExDiskHandle_t)1;
  83. params.bytes_per_lba = 512;
  84. params.streaming_lba_count = disk_bytes / 512;
  85. params.gpt_lba_count = params.streaming_lba_count;
  86. params.kernel_buffer_size = 16 * 1024 * 1024;
  87. params.kernel_buffer = malloc(params.kernel_buffer_size);
  88. if (!params.kernel_buffer) {
  89. fprintf(stderr, "Can't allocate kernel buffer\n");
  90. return 1;
  91. }
  92. /* TODO(chromium:441893): support dev-mode flag and external gpt flag */
  93. params.boot_flags = 0;
  94. /*
  95. * LoadKernel() cares only about VBNV_DEV_BOOT_SIGNED_ONLY, and only in
  96. * dev mode. So just use defaults.
  97. */
  98. VbNvSetup(&nvc);
  99. params.nv_context = &nvc;
  100. /*
  101. * Set up vboot context.
  102. *
  103. * TODO: Propagate this up to higher API levels
  104. */
  105. struct vb2_context ctx;
  106. memset(&ctx, 0, sizeof(ctx));
  107. /* No need to initialize ctx->nvdata[]; defaults are fine */
  108. /* TODO(chromium:441893): support dev-mode flag and external gpt flag */
  109. ctx.workbuf = malloc(VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE);
  110. if (!ctx.workbuf) {
  111. fprintf(stderr, "Can't allocate workbuf\n");
  112. return 1;
  113. }
  114. ctx.workbuf_size = VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE;
  115. if (VB2_SUCCESS != vb2_init_context(&ctx)) {
  116. free(ctx.workbuf);
  117. fprintf(stderr, "Can't init context\n");
  118. return 1;
  119. }
  120. /* Try loading kernel */
  121. rv = LoadKernel(&ctx, &params, &cparams);
  122. if (rv != VBERROR_SUCCESS) {
  123. fprintf(stderr, "LoadKernel() failed with code %d\n", rv);
  124. return 1;
  125. }
  126. printf("Found a good kernel.\n");
  127. printf("Partition number: %u\n", params.partition_number);
  128. printf("Bootloader address: 0x%" PRIx64 "\n",
  129. params.bootloader_address);
  130. /* TODO: print other things (partition GUID, nv_context, shared_data) */
  131. printf("Yaay!\n");
  132. return 0;
  133. }