[U-Boot] [PATCH 1/2] Implementation of a auto-update hash-check- if image has new hash, update flash, otherwise boot device immediately

--- common/image.c | 2 +- common/update.c | 42 +++++++++++++++++++++++++++++++++++------- include/image.h | 3 +++ 3 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/common/image.c b/common/image.c index f63a2ff..cdb7581 100644 --- a/common/image.c +++ b/common/image.c @@ -2398,7 +2398,7 @@ int fit_set_timestamp (void *fit, int noffset, time_t timestamp) * 0, on success * -1, when algo is unsupported */ -static int calculate_hash (const void *data, int data_len, const char *algo, +int calculate_hash (const void *data, int data_len, const char *algo, uint8_t *value, int *value_len) { if (strcmp (algo, "crc32") == 0 ) { diff --git a/common/update.c b/common/update.c index 7528474..fe2139a 100644 --- a/common/update.c +++ b/common/update.c @@ -62,9 +62,10 @@ extern ulong load_addr;
static uchar *saved_prot_info;
-static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr) +static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr, int *size) { - int size, rv; + //int size, rv; + int rv; ulong saved_timeout_msecs; int saved_timeout_count; char *saved_netretry, *saved_bootfile; @@ -86,12 +87,12 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr) /* download the update file */ load_addr = addr; copy_filename(BootFile, filename, sizeof(BootFile)); - size = NetLoop(TFTP); + *size = NetLoop(TFTP);
- if (size < 0) + if (*size < 0) rv = 1; - else if (size > 0) - flush_cache(addr, size); + else if (*size > 0) + flush_cache(addr, *size);
/* restore changed globals and env variable */ TftpRRQTimeoutMSecs = saved_timeout_msecs; @@ -245,6 +246,12 @@ void update_tftp(void) ulong update_addr, update_fladdr, update_size; ulong addr; void *fit; + uint8_t value[FIT_MAX_HASH_LEN]; + char hash_string[2*FIT_MAX_HASH_LEN]; + int value_len; + char *algo = "sha1"; + char *current_hash; + int size = 0, i;
printf("Auto-update from TFTP: ");
@@ -266,7 +273,7 @@ void update_tftp(void)
if (update_load(filename, CONFIG_UPDATE_TFTP_MSEC_MAX, - CONFIG_UPDATE_TFTP_CNT_MAX, addr)) { + CONFIG_UPDATE_TFTP_CNT_MAX, addr, &size)) { printf("Can't load update file, aborting auto-update\n"); return; } @@ -279,6 +286,27 @@ void update_tftp(void) return; }
+ /* check for image hash */ + current_hash = getenv("update_image_hash_sha1"); + + if (calculate_hash((void *)addr, size, algo, &value, &value_len)) { + printf(" Error: Error during hash calculation\n"); + return 1; + } + + /* make hash human readable, this doubles the size */ + for (i=0; i < value_len; i++) + sprintf(hash_string + 2*i, "%02x", value[i]); + + if (memcmp( &hash_string, current_hash, 2*value_len ) != 0) { + printf("Unequal hashes, start auto-update\n"); + setenv("update_image_hash_sha1", hash_string); + saveenv(); + } else { + printf("Equal hashes, stopping auto-update and start regular booting\n"); + return 1; + } + /* process updates */ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
diff --git a/include/image.h b/include/image.h index 005e0d2..0132263 100644 --- a/include/image.h +++ b/include/image.h @@ -567,6 +567,9 @@ static inline ulong fit_get_size (const void *fit) return fdt_totalsize (fit); }
+int calculate_hash (const void *data, int data_len, const char *algo, + uint8_t *value, int *value_len); + /** * fit_get_end - get FIT image end * @fit: pointer to the FIT format image header

--- common/update.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/common/update.c b/common/update.c index fe2139a..8b858bd 100644 --- a/common/update.c +++ b/common/update.c @@ -195,6 +195,13 @@ static int update_flash(ulong addr_source, ulong addr_first, ulong size) return 1; }
+#ifdef CONFIG_SYSTEM_START_ADDR + if (addr_first < CONFIG_SYSTEM_START_ADDR) { + printf("Error: auto-update does not allow to write a new bootloader\n"); + return 1; + } +#endif + /* remove protection on processed sectors */ if (update_flash_protect(0, addr_first, addr_last) > 0) { printf("Error: could not unprotect flash sectors\n");

Dear Christoph Koenig,
In message 1301671320-16131-2-git-send-email-christoph.koenig@ikt.uni-hannover.de you wrote:
Subjecxt too long.
Commit message missing.
No explanation given what the code is supposed to do.
SoB line missing.
+#ifdef CONFIG_SYSTEM_START_ADDR
- if (addr_first < CONFIG_SYSTEM_START_ADDR) {
printf("Error: auto-update does not allow to write a new bootloader\n");
return 1;
- }
+#endif
Explanation and documentation for new CONFIG_ option (in README) missing.
I think this approach is too simplistic. Some boards have the boot loader at the beginning of the OR flash, some at the end, others right in the middle. Still others boot from NAND flash or SDCard.
Best regards,
Wolfgang Denk

Dear Christoph Koenig,
In message 1301671320-16131-1-git-send-email-christoph.koenig@ikt.uni-hannover.de you wrote:
common/image.c | 2 +- common/update.c | 42 +++++++++++++++++++++++++++++++++++------- include/image.h | 3 +++ 3 files changed, 39 insertions(+), 8 deletions(-)
Please use a short subject line, and provide a proper commit message.
Your SoB line is missing.
-static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr) +static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr, int *size)
Line too long. Please fix globally.
- if (calculate_hash((void *)addr, size, algo, &value, &value_len)) {
printf(" Error: Error during hash calculation\n");
return 1;
No spaces at the beginning of the line. "Error" is redundant here.
Best regards,
Wolfgang Denk
participants (2)
-
Christoph Koenig
-
Wolfgang Denk