[coreboot-gerrit] Patch set updated for coreboot: 4999bb1 util/bimgtool: Add verification mode

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Fri Apr 10 08:46:05 CEST 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9452

-gerrit

commit 4999bb104c20791800c142b0f5760f4212d46254
Author: Vadim Bendebury <vbendeb at chromium.org>
Date:   Tue Nov 4 16:17:33 2014 -0800

    util/bimgtool: Add verification mode
    
    When only one argument is passed on the command line, consider this
    argument the name of the BIMG formatted file, and verity its
    integrity.
    
    Updated the help/usage text to match new behavior.
    
    BRANCH=none
    BUG=none
    
    TEST=when the corrupted coreboot BIMG image is passed as the only
         argument, this utility reports the problem. With the build fixed,
         the check passes without errors (the second invocation below).
    
    $ build/util/bimgtool/bimgtool /build/urara/firmware/coreboot.rom.serial
    Data header CRC mismatch at 0
    $ build/util/bimgtool/bimgtool /build/urara/firmware/coreboot.rom.serial
    $
    
    Change-Id: I9f0672caa38e3d27917471fc5137ede4ca466e9a
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 3e631c311dbf2fb04714e437f95c41629155527f
    Original-Change-Id: Ie56f87f99838891d8e341d7989c614efbcabe0cd
    Original-Signed-off-by: Vadim Bendebury <vbendeb at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/227522
    Original-Reviewed-by: Zdenko Pulitika <zdenko.pulitika at imgtec.com>
    Original-Tested-by: Ionela Voinescu <ionela.voinescu at imgtec.com>
---
 util/bimgtool/bimgtool.c | 164 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 146 insertions(+), 18 deletions(-)

diff --git a/util/bimgtool/bimgtool.c b/util/bimgtool/bimgtool.c
index acbfdfb..b7b6491 100644
--- a/util/bimgtool/bimgtool.c
+++ b/util/bimgtool/bimgtool.c
@@ -23,6 +23,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
@@ -59,6 +60,9 @@ struct crc_t {
 #define BIMG_OP_EXEC_NO_RETURN	(0x2 << 0)
 #define BIMG_DATA_CHECKSUM	(0x1 << 4)
 
+/* Typical use case for this utility. */
+#define BIMG_FLAGS (BIMG_OP_EXEC_NO_RETURN | BIMG_DATA_CHECKSUM)
+
 #define MAX_RECORD_BYTES	0x8000
 
 #define CRC_16
@@ -140,8 +144,7 @@ static uint16_t crc_16(uint16_t crc, void *void_buf, size_t size)
 
 }
 
-
-static struct crc_t crc_type = {
+static const struct crc_t crc_type = {
 #if defined(CRC_16)
 	.crc_f = crc_16,
 	.crc_init = 0,
@@ -211,20 +214,141 @@ static int write_final(FILE *out, struct bimg_header *hdr)
 	return 0;
 }
 
+static const char *help_message =
+	"Usage: bimgtool <input> [<output> <base-address>]\n"
+	"\n"
+	"This is a simple tool which generates and verifies boot images in\n"
+	"the BIMG format, used in systems designed by Imagination\n"
+	"Technologies, for example the Pistachio SoC. This version of the\n"
+	"tool works with BIMG images version %d.\n"
+	"\n"
+	"  input:          The binary file to be converted to a BIMG\n"
+	"                  or verified\n"
+	"  output:         The name of the output BIMG file\n"
+	"  base-address:   The address in memory at which you wish the "
+	"                  input binary to be loaded.\n";
+
 static void usage(FILE *f)
 {
-	fprintf(f,
-		"Usage: bimgtool <input> <output> <base-address>\n"
-		"\n"
-		"bimgtool is a simple tool which generates boot images in the "
-		"BIMG format used in systems designed by Imagination "
-		"Technologies, for example the Pistachio SoC. This version of the "
-		"tool generates BIMG version 1.0 images.\n"
-		"\n"
-		"  input:          The binary file to be converted to a BIMG\n"
-		"  output:         The name of the output BIMG file\n"
-		"  base-address:   The address in memory at which you wish the "
-		"input binary to be loaded.\n");
+	fprintf(f, help_message, crc_type.ver_major);
+}
+
+static int verify_file(FILE *f)
+{
+	struct bimg_header file_header;
+	struct bimg_data_header data_header;
+	char *file_pointer;
+	char *file_data;
+	struct stat buf;
+	int data_size;
+	int fd = fileno(f);
+	uint32_t data_crc = crc_type.crc_init;
+	uint32_t crc_result;
+
+	if (fread(&file_header, 1, sizeof(struct bimg_header), f) !=
+	    sizeof(struct bimg_header)) {
+		perror("Problems trying to read input file header\n");
+		return -1;
+	}
+
+	if (fstat(fd, &buf)) {
+		perror("Problems trying to stat input file\n");
+		return -1;
+	}
+
+	if (file_header.magic != BIMG_MAGIC) {
+		fprintf(stderr, "Wrong magic value %#x\n", file_header.magic);
+		return -1;
+	}
+
+	crc_result = crc_type.crc_f(crc_type.crc_init, &file_header,
+				    sizeof(file_header) -
+				    sizeof(file_header.crc));
+	if (file_header.crc != crc_result) {
+		fprintf(stderr, "File header CRC mismatch\n");
+		return -1;
+	}
+
+	if ((file_header.data_size + sizeof(struct bimg_header)) >
+	    buf.st_size) {
+		fprintf(stderr, "Data size too big: %d > %d\n",
+			file_header.data_size, buf.st_size);
+		return -1;
+	}
+
+	if (file_header.ver_major != crc_type.ver_major) {
+		fprintf(stderr, "Image version mismatch: %d\n",
+			file_header.ver_major);
+		return -1;
+	}
+
+	if ((file_header.flags & BIMG_FLAGS) != BIMG_FLAGS) {
+		fprintf(stderr, "Unexpected file header flags: %#x\n",
+			file_header.flags);
+		return -1;
+	}
+
+	if (file_header.ver_minor != crc_type.ver_minor) {
+		fprintf(stderr,
+			"Minor version mismatch: %d, will try anyways\n",
+			file_header.ver_minor);
+	}
+
+	data_size = file_header.data_size;
+	file_pointer = malloc(data_size);
+	if (!file_pointer) {
+		fprintf(stderr, "Failed to allocate %d bytes\n",
+			file_header.data_size);
+		return -1;
+	}
+
+	if (fread(file_pointer, 1, data_size, f) != data_size) {
+		fprintf(stderr, "Failed to read %d bytes\n", data_size);
+		free(file_pointer);
+		return -1;
+	}
+
+	file_data = file_pointer;
+	while (data_size > 0) {
+		memcpy(&data_header, file_data,  sizeof(data_header));
+
+		/* Check the data block header integrity. */
+		crc_result = crc_type.crc_f(crc_type.crc_init, &data_header,
+					    sizeof(data_header) -
+					    sizeof(data_header.crc));
+		if (data_header.crc != crc_result) {
+			fprintf(stderr, "Data header CRC mismatch at %d\n",
+				file_header.data_size - data_size);
+			free(file_pointer);
+			return -1;
+		}
+
+		/*
+		 * Add the block data to the CRC stream, the last block size
+		 * will be zero.
+		 */
+		file_data += sizeof(data_header);
+		data_crc = crc_type.crc_f(data_crc,
+					  file_data, data_header.size);
+
+		data_size -= data_header.size + sizeof(data_header);
+		file_data += data_header.size;
+	}
+
+	if (data_size) {
+		fprintf(stderr, "File size mismatch\n");
+		free(file_pointer);
+		return -1;
+	}
+
+	if (data_crc != file_header.data_crc) {
+		fprintf(stderr, "File data CRC mismatch\n");
+		free(file_pointer);
+		return -1;
+	}
+
+	free(file_pointer);
+	return 0;
 }
 
 int main(int argc, char *argv[])
@@ -236,18 +360,16 @@ int main(int argc, char *argv[])
 		.magic = BIMG_MAGIC,
 		.ver_major = crc_type.ver_major,
 		.ver_minor = crc_type.ver_minor,
-		.flags = BIMG_OP_EXEC_NO_RETURN | BIMG_DATA_CHECKSUM,
+		.flags = BIMG_FLAGS,
 		.data_crc = crc_type.crc_init,
 	};
 
-	if (argc != 4) {
+	if ((argc != 4) && (argc != 2)) {
 		usage(stderr);
 		goto out_err;
 	}
 
 	in_filename = argv[1];
-	out_filename = argv[2];
-	hdr.entry_addr = strtoul(argv[3], NULL, 16);
 
 	in_file = fopen(in_filename, "r");
 	if (!in_file) {
@@ -255,6 +377,12 @@ int main(int argc, char *argv[])
 		goto out_err;
 	}
 
+	if (argc == 2)
+		return verify_file(in_file);
+
+	out_filename = argv[2];
+	hdr.entry_addr = strtoul(argv[3], NULL, 16);
+
 	out_file = fopen(out_filename, "w");
 	if (!out_file) {
 		error("Failed to open output file '%s'\n", out_filename);



More information about the coreboot-gerrit mailing list