[flashrom] [PATCH 3/3] proof of concept patch for calculating and printing of MD5 hashes of flash and file contents

Stefan Tauner stefan.tauner at student.tuwien.ac.at
Sat Jun 25 03:36:08 CEST 2011


This patch is not for merge. It uses libmhash to calculate the MD5 hashes of the files read
before write/validate and of the flash contents read to ease debugging and emergency
recovery.

open question: decide on which library to use - or if we want to just copy an
implementation verbatim.
if no one can think of a realistic use case for more advanced/crypto hashers or cryptography
(like signing/verifying images), i think just copying a md5 implementation is fine.

Signed-off-by: Stefan Tauner <stefan.tauner at student.tuwien.ac.at>
---
 Makefile   |    2 +-
 flashrom.c |   36 +++++++++++++++++++++++++++++++++++-
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 6e6e2de..3f32349 100644
--- a/Makefile
+++ b/Makefile
@@ -361,7 +361,7 @@ ifeq ($(OS_ARCH), DOS)
 # FIXME There needs to be a better way to do this
 LIBS += ../libpci/lib/libpci.a
 else
-LIBS += -lpci
+LIBS += -lpci -lmhash
 ifeq ($(OS_ARCH), OpenBSD)
 # For (i386|amd64)_iopl(2).
 LIBS += -l$(shell uname -m)
diff --git a/flashrom.c b/flashrom.c
index c664a50..787bddb 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -34,6 +34,7 @@
 #if HAVE_UTSNAME == 1
 #include <sys/utsname.h>
 #endif
+#include "mhash.h"
 #include "flash.h"
 #include "flashchips.h"
 #include "programmer.h"
@@ -727,6 +728,32 @@ int check_erased_range(struct flashchip *flash, int start, int len)
 	return ret;
 }
 
+int md5_get_hash(const void *plaintext, unsigned int size, unsigned char *hash)
+{
+	MHASH td = mhash_init(MHASH_MD5);
+	if (td == MHASH_FAILED)
+		return 1;
+
+	mhash(td, plaintext, size);
+	mhash_deinit(td, hash);
+	if (hash == NULL)
+		return 1;
+	return 0;
+}
+
+/* Calculates and prints the MD5 hash of the given plaintext. */
+void md5_print_hash(const void *plaintext, unsigned int size, const char *text)
+{
+	unsigned char md5[16];
+	int i;
+	if (md5_get_hash(plaintext, size, md5) == 0) {
+		msg_cinfo("MD5 hash of %s is ", text);
+		for (i = 0; i < 16; i++)
+			msg_cinfo("%02x", md5[i]);
+		msg_cinfo(".\n");
+	}
+}
+
 /*
  * @cmpbuf	buffer to compare against, cmpbuf[0] is expected to match the
 		flash content at location start
@@ -1299,8 +1326,9 @@ int read_flash_to_file(struct flashchip *flash, const char *filename)
 
 	ret = write_buf_to_file(buf, size, filename);
 out_free:
-	free(buf);
 	msg_cinfo("%s.\n", ret ? "FAILED" : "done");
+	md5_print_hash(buf, size, "the flash content read");
+	free(buf);
 	return ret;
 }
 
@@ -1898,6 +1926,8 @@ int doit(struct flashchip *flash, int force, const char *filename, int read_it,
 			goto out;
 		}
 
+		md5_print_hash(newcontents, size, filename);
+
 #if CONFIG_INTERNAL == 1
 		if (programmer == PROGRAMMER_INTERNAL)
 			show_id(newcontents, size, force);
@@ -1918,6 +1948,8 @@ int doit(struct flashchip *flash, int force, const char *filename, int read_it,
 	}
 	msg_cdbg("done.\n");
 
+	md5_print_hash(oldcontents, size, "the old flash chip contents");
+
 	// This should be moved into each flash part's code to do it 
 	// cleanly. This does the job.
 	handle_romentries(flash, oldcontents, newcontents);
@@ -1929,6 +1961,8 @@ int doit(struct flashchip *flash, int force, const char *filename, int read_it,
 			msg_cerr("Uh oh. Erase/write failed. Checking if "
 				 "anything changed.\n");
 			if (!flash->read(flash, newcontents, 0, size)) {
+				md5_print_hash(newcontents, size,
+					"the current flash chip contents");
 				if (!memcmp(oldcontents, newcontents, size)) {
 					msg_cinfo("Good. It seems nothing was "
 						  "changed.\n");
-- 
1.7.1





More information about the flashrom mailing list