Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Unified Diff: utility/load_firmware_test.c

Issue 6465018: Add load_firmware_test utility program (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git@master
Patch Set: Code review & remove tabs Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« utility/dump_fmap.c ('K') | « utility/dump_fmap.c ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: utility/load_firmware_test.c
diff --git a/utility/load_firmware_test.c b/utility/load_firmware_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..c8759152022fb6fc71a2e69cbb26aa0cc9b231ba
--- /dev/null
+++ b/utility/load_firmware_test.c
@@ -0,0 +1,249 @@
+/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Routines for verifying a firmware image's signature.
+ */
+
+#include <stdio.h>
+
+#include "fmap.h"
+#include "gbb_header.h"
+#include "host_misc.h"
+#include "load_firmware_fw.h"
+#include "vboot_struct.h"
+
+
+typedef struct _CallerInternal {
+ struct {
+ uint8_t* fw;
+ uint64_t size;
+ } firmware[2];
+} CallerInternal;
+
+static char* progname = NULL;
+static char* image_path = NULL;
+
+
+/* wrapper of FmapAreaIndex; print error when not found */
+int FmapAreaIndexOrError(const FmapHeader* fh, const FmapAreaHeader* ah,
+ const char* name);
+/* return NULL on error */
+const char* status_string(int status);
+
+int GetFirmwareBody(LoadFirmwareParams* params, uint64_t firmware_index) {
+ CallerInternal* ci = (CallerInternal*) params->caller_internal;
+
+ if (firmware_index != 0 && firmware_index != 1)
+ return 1;
+
+ UpdateFirmwareBodyHash(params,
+ ci->firmware[firmware_index].fw,
+ ci->firmware[firmware_index].size);
+
+ return 0;
+}
+
+/* Return NULL if cannot get firmware root key */
gauravsh 2011/02/10 20:02:05 i still don't see any comments for the arguments o
Che-Liang Chiou 2011/02/14 02:27:53 Done.
+void* GetFirmwareRootKey(const void* base_of_rom, const void* fmap) {
+ const FmapHeader* fh = (const FmapHeader*) fmap;
+ const FmapAreaHeader* ah = (const FmapAreaHeader*)
+ (fmap + sizeof(FmapHeader));
+ int i = FmapAreaIndexOrError(fh, ah, "GBB Area");
+ const void* gbb;
+ const GoogleBinaryBlockHeader* gbbh;
+
+ if (i < 0)
+ return NULL;
+
+ gbb = base_of_rom + ah[i].area_offset;
+ gbbh = (const GoogleBinaryBlockHeader*) gbb;
+ return (void*) gbb + gbbh->rootkey_offset;
+}
+
+/* Return non-zero if cannot get verification block */
gauravsh 2011/02/10 20:02:05 comment about the arguments and what this function
Che-Liang Chiou 2011/02/14 02:27:53 Done.
+int GetVerificationBlock(const void* base_of_rom, const void* fmap, int index,
+ void** verification_block_ptr, uint64_t* verification_size_ptr) {
+ const char* key_area_name[2] = {
+ "Firmware A Key",
+ "Firmware B Key"
+ };
+ const FmapHeader* fh = (const FmapHeader*) fmap;
+ const FmapAreaHeader* ah = (const FmapAreaHeader*)
+ (fmap + sizeof(FmapHeader));
+ int i = FmapAreaIndexOrError(fh, ah, key_area_name[index]);
+ const void* kb;
+ const VbKeyBlockHeader* kbh;
+ const VbFirmwarePreambleHeader* fph;
+
+ if (i < 0)
+ return 1;
+
+ kb = base_of_rom + ah[i].area_offset;
+ *verification_block_ptr = (void*) kb;
+
+ kbh = (const VbKeyBlockHeader*) kb;
+ fph = (const VbFirmwarePreambleHeader*) (kb + kbh->key_block_size);
+
+ *verification_size_ptr = kbh->key_block_size + fph->preamble_size;
+
+ return 0;
+}
+
+/* Return non-zero if not found */
+int GetFirmwareData(const void* base_of_rom, const void* fmap, int index,
+ void *verification_block, uint8_t** body_ptr, uint64_t *size_ptr) {
+ const char* data_area_name[2] = {
+ "Firmware A Data",
+ "Firmware B Data"
+ };
+ const FmapHeader* fh = (const FmapHeader*) fmap;
+ const FmapAreaHeader* ah = (const FmapAreaHeader*)
+ (fmap + sizeof(FmapHeader));
+ const VbKeyBlockHeader* kbh = (const VbKeyBlockHeader*) verification_block;
+ const VbFirmwarePreambleHeader* fph = (const VbFirmwarePreambleHeader*)
+ (verification_block + kbh->key_block_size);
+ int i = FmapAreaIndexOrError(fh, ah, data_area_name[index]);
+
+ if (i < 0)
+ return 1;
+
+ *body_ptr = (uint8_t*) (base_of_rom + ah[i].area_offset);
+ *size_ptr = (uint64_t) fph->body_signature.data_size;
+ return 0;
+}
+
+/* Verify firmware image [base_of_rom] using [fmap] for looking up areas.
+ * Return zero on success, non-zero on error */
gauravsh 2011/02/10 20:02:05 ok, I see you added the comment here - but still t
Che-Liang Chiou 2011/02/14 02:27:53 Done.
+int DriveLoadFirmware(const void* base_of_rom, const void* fmap) {
+ LoadFirmwareParams lfp;
+ CallerInternal ci;
+
+ const char* status_str;
+ int index, status;
+
+ void** vblock_ptr[2] = {
+ &lfp.verification_block_0, &lfp.verification_block_1
+ };
+ uint64_t* vsize_ptr[2] = {
+ &lfp.verification_size_0, &lfp.verification_size_1
+ };
+
+ /* Initialize LoadFirmwareParams lfp */
+
+ lfp.caller_internal = &ci;
+
+ lfp.firmware_root_key_blob = GetFirmwareRootKey(base_of_rom, fmap);
+ if (lfp.firmware_root_key_blob == NULL) {
gauravsh 2011/02/10 20:02:05 !lfp.firmware_root_key_blob is the usual way than
Che-Liang Chiou 2011/02/14 02:27:53 Done.
+ printf("ERROR: cannot get firmware root key blob\n");
+ return 1;
+ }
+
+ printf("firmware root key blob at 0x%08" PRIx64 "\n",
+ lfp.firmware_root_key_blob - base_of_rom);
+
+ /* Loop for initialize firmware key and data A / B */
gauravsh 2011/02/10 20:02:05 s/for/to/
Che-Liang Chiou 2011/02/14 02:27:53 Done.
+ for (index = 0; index < 2; ++index) {
+ if (GetVerificationBlock(base_of_rom, fmap, index,
+ vblock_ptr[index], vsize_ptr[index])) {
+ printf("ERROR: cannot get key block %d\n", index);
+ return 1;
+ }
+
+ printf("verification block %d at 0x%08" PRIx64 "\n", index,
+ *vblock_ptr[index] - base_of_rom);
+ printf("verification block %d size is 0x%08" PRIx64 "\n", index,
+ *vsize_ptr[index]);
+
+ if (GetFirmwareData(base_of_rom, fmap, index, *vblock_ptr[index],
+ &(ci.firmware[index].fw), &(ci.firmware[index].size))) {
+ printf("ERROR: cannot get firmware body %d\n", index);
+ return 1;
+ }
+
+ printf("firmware %c at 0x%08" PRIx64 "\n", "AB"[index],
+ (void*) ci.firmware[index].fw - base_of_rom);
+ printf("firmware %c size is 0x%08" PRIx64 "\n", "AB"[index],
+ ci.firmware[index].size);
+ }
+
+ /* remember to free kernel_sign_key_blob before exit */
gauravsh 2011/02/10 20:02:05 i would get rid of the comment. it is not clear wh
Che-Liang Chiou 2011/02/14 02:27:53 Done.
+ lfp.kernel_sign_key_blob = Malloc(LOAD_FIRMWARE_KEY_BLOB_REC_SIZE);
+ lfp.kernel_sign_key_size = LOAD_FIRMWARE_KEY_BLOB_REC_SIZE;
+ printf("kernel sign key size is 0x%08" PRIx64 "\n", lfp.kernel_sign_key_size);
+
+ lfp.boot_flags = 0;
+ printf("boot flags is 0x%08" PRIx64 "\n", lfp.boot_flags);
+
+ /* Call to LoadFirmware */
gauravsh 2011/02/10 20:02:05 this is not a useful comment. please remove.
Che-Liang Chiou 2011/02/14 02:27:53 Done.
+
+ status = LoadFirmware(&lfp);
+ status_str = status_string(status);
+ if (status_str)
+ printf("LoadFirmware returns %s\n", status_str);
+ else
+ printf("LoadFirmware returns unknown status code: %d\n", status);
+ if (status == LOAD_FIRMWARE_SUCCESS)
+ printf("firmwiare index is %" PRIu64 "\n", lfp.firmware_index);
+
+ Free(lfp.kernel_sign_key_blob);
+
+ return 0;
+}
+
+/* wrap FmapAreaIndex; print error when not found */
+int FmapAreaIndexOrError(const FmapHeader* fh, const FmapAreaHeader* ah,
+ const char* name) {
+ int i = FmapAreaIndex(fh, ah, name);
+ if (i < 0)
+ fprintf(stderr, "%s: can't find %s in firmware image\n", progname, name);
+ return i;
+}
+
+/* Convert status returned by LoadFirmware to string. Return NULL on error. */
+const char* status_string(int status) {
+ switch (status) {
+ case LOAD_FIRMWARE_SUCCESS:
+ return "LOAD_FIRMWARE_SUCCESS";
+ case LOAD_FIRMWARE_RECOVERY:
+ return "LOAD_FIRMWARE_RECOVERY";
+ case LOAD_FIRMWARE_REBOOT:
+ return "LOAD_FIRMWARE_REBOOT";
+ case LOAD_FIRMWARE_RECOVERY_TPM:
+ return "LOAD_FIRMWARE_RECOVERY_TPM";
+ default:
+ return NULL;
+ }
+}
+
+int main(int argc, char* argv[]) {
+ int retval = 0;
+ const void* base_of_rom;
+ const void* fmap;
+ uint64_t rom_size;
+
+ progname = argv[0];
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s <firmware_image>\n", progname);
+ exit(1);
+ }
+
+ image_path = argv[1];
+
+ base_of_rom = ReadFile(image_path, &rom_size);
+ if (base_of_rom == NULL) {
+ fprintf(stderr, "%s: can not open %s\n", progname, image_path);
+ exit(1);
+ }
+
+ printf("opened %s\n", image_path);
+
+ fmap = FindFmap((char*) base_of_rom, rom_size);
+
+ retval = DriveLoadFirmware(base_of_rom, fmap);
+
+ Free((void*) base_of_rom);
+
+ return retval;
+}
« utility/dump_fmap.c ('K') | « utility/dump_fmap.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698