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@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");