Skip to contentSkip to conversation

Calculate image hashes with watchdog triggering

PATCH Superseded Bartlomiej Sieka 2 participants 14 messages Apr 12, 2008 – Apr 25, 2008

lore
Share & tools
lore
#0 lore raw

cover Calculate image hashes with watchdog triggering

Hash calculation of an image can be a time consuming operation, with the possibility of making the hardware watchdog (if present/enabled) expire in the middle. Add watchdog-aware hash calculation functions and make image hash calculation use them.
---

Bartlomiej Sieka (2):
Use watchdog-aware functions when calculating hashes of images Add support for calulacting hashes with watchdog triggering

 common/image.c      |   43 +++++++++----------------------------------
 include/common.h    |    1 +
 include/image.h     |   17 +++++++++++++++--
 include/md5.h       |    8 ++++++++
 include/sha1.h      |   11 +++++++++++
 lib_generic/crc32.c |   28 ++++++++++++++++++++++++++++
 lib_generic/md5.c   |   40 ++++++++++++++++++++++++++++++++++++++++
 lib_generic/sha1.c  |   37 +++++++++++++++++++++++++++++++++++++
 8 files changed, 149 insertions(+), 36 deletions(-)
Signature · 1 line
Bartlomiej
#1 lore raw

PATCH 1/2 Add support for calulacting hashes with watchdog triggering

Implement watchodg-aware variants of hash calculation functions:
- crc32_wd()
- md5_wd()
- sha1_csum_wd()
The above functions calculate the hash of the input buffer in chunks, triggering the watchdog after processing each chunk. The chunk size is given as a function call parameter.

---

 include/common.h    |    1 +
 include/md5.h       |    8 ++++++++
 include/sha1.h      |   11 +++++++++++
 lib_generic/crc32.c |   27 +++++++++++++++++++++++++++
 lib_generic/md5.c   |   36 ++++++++++++++++++++++++++++++++++++
 lib_generic/sha1.c  |   33 +++++++++++++++++++++++++++++++++
 6 files changed, 116 insertions(+), 0 deletions(-)
include/common.h +1 -0
index 39bcd30..aee58ec 100644
@@ -604,6 +604,7 @@ int	vsprintf(char *buf, const char *fmt, va_list args);
 
 /* lib_generic/crc32.c */
 ulong crc32 (ulong, const unsigned char *, uint);
+ulong crc32_wd (ulong, const unsigned char *, uint, uint);
 ulong crc32_no_comp (ulong, const unsigned char *, uint);
 
 /* common/console.c */
include/md5.h +8 -0
index 046d1ee..8b44a7f 100644
@@ -20,4 +20,12 @@ struct MD5Context {
  */
 void md5 (unsigned char *input, int len, unsigned char output[16]);
 
+/*
+ * Calculate and store in 'output' the MD5 digest of 'len' bytes at 'input'.
+ * 'output' must have enough space to hold 16 bytes. If 'chunk' Trigger the
+ * watchdog every 'chunk_sz' bytes of input processed.
+ */
+void md5_wd (unsigned char *input, int len, unsigned char output[16],
+		unsigned int chunk_sz);
+
 #endif /* _MD5_H */
include/sha1.h +11 -0
index 15ea13c..734d1fb 100644
@@ -80,6 +80,17 @@ void sha1_csum( unsigned char *input, int ilen,
 		unsigned char output[20] );
 
 /**
+ * \brief	   Output = SHA-1( input buffer ), with watchdog triggering
+ *
+ * \param input    buffer holding the  data
+ * \param ilen	   length of the input data
+ * \param output   SHA-1 checksum result
+ * \param chunk_sz watchdog triggering period (in bytes of input processed)
+ */
+void sha1_csum_wd (unsigned char *input, int ilen,
+		unsigned char output[20], unsigned int chunk_sz);
+
+/**
  * \brief	   Output = SHA-1( file contents )
  *
  * \param path	   input file name
lib_generic/crc32.c +27 -0
index df0dbca..0bfb64b 100644
@@ -197,3 +197,30 @@ uLong ZEXPORT crc32_no_comp(uLong crc, const Bytef *buf, uInt len)
 }
 
 #endif
+
+/*
+ * Calculate the crc32 checksum triggering the watchdog every 'chunk_sz' bytes
+ * of input.
+ */
+ulong crc32_wd (ulong crc, const unsigned char *buf, uint len, uint chunk_sz)
+{
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	const unsigned char *end, *curr;
+	int chunk;
+
+	curr = buf;
+	end = buf + len;
+	while (curr < end) {
+		chunk = end - curr;
+		if (chunk > chunk_sz)
+			chunk = chunk_sz;
+		crc = crc32 (crc, curr, chunk);
+		curr += chunk;
+		WATCHDOG_RESET ();
+	}
+#else
+        crc = crc32 (crc, buf, len);
+#endif
+
+	return crc;
+}
lib_generic/md5.c +36 -0
index a51da45..8eaef0f 100644
@@ -272,3 +272,39 @@ md5 (unsigned char *input, int len, unsigned char output[16])
 	MD5Update(&context, input, len);
 	MD5Final(output, &context);
 }
+
+
+/*
+ * Calculate and store in 'output' the MD5 digest of 'len' bytes at 'input'.
+ * 'output' must have enough space to hold 16 bytes. If 'chunk' Trigger the
+ * watchdog every 'chunk_sz' bytes of input processed.
+ */
+void
+md5_wd (unsigned char *input, int len, unsigned char output[16],
+	unsigned int chunk_sz)
+{
+	struct MD5Context context;
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	unsigned char *end, *curr;
+	int chunk;
+#endif
+
+	MD5Init(&context);
+
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	curr = input;
+	end = input + len;
+	while (curr < end) {
+		chunk = end - curr;
+		if (chunk > chunk_sz)
+			chunk = chunk_sz;
+		MD5Update(&context, curr, chunk);
+		curr += chunk;
+		WATCHDOG_RESET ();
+	}
+#else
+	MD5Update(&context, input, len);
+#endif
+
+	MD5Final(output, &context);
+}
lib_generic/sha1.c +33 -0
index 08ffa6b..6950659 100644
@@ -309,6 +309,39 @@ void sha1_csum (unsigned char *input, int ilen, unsigned char output[20])
 }
 
 /*
+ * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
+ * bytes of input processed.
+ */
+void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20],
+			unsigned int chunk_sz)
+{
+	sha1_context ctx;
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	unsigned char *end, *curr;
+	int chunk;
+#endif
+
+	sha1_starts (&ctx);
+
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	curr = input;
+	end = input + ilen;
+	while (curr < end) {
+		chunk = end - curr;
+		if (chunk > chunk_sz)
+			chunk = chunk_sz;
+		sha1_update (&ctx, curr, chunk);
+		curr += chunk;
+		WATCHDOG_RESET ();
+	}
+#else
+	sha1_update (&ctx, input, ilen);
+#endif
+
+	sha1_finish (&ctx, output);
+}
+
+/*
  * Output = HMAC-SHA-1( input buffer, hmac key )
  */
 void sha1_hmac (unsigned char *key, int keylen,
#2 lore raw

PATCH 1/2 Add support for calulacting hashes with watchdog triggering

Quoted 11 lines · In message <[email protected]> you wrote:

Implement watchodg-aware variants of hash calculation functions:
- crc32_wd()
- md5_wd()
- sha1_csum_wd()
The above functions calculate the hash of the input buffer in chunks, triggering the watchdog after processing each chunk. The chunk size is given as a function call parameter.

---

Quoted 7 lines
 include/common.h    |    1 +
 include/md5.h       |    8 ++++++++
 include/sha1.h      |   11 +++++++++++
 lib_generic/crc32.c |   27 +++++++++++++++++++++++++++
 lib_generic/md5.c   |   36 ++++++++++++++++++++++++++++++++++++
 lib_generic/sha1.c  |   33 +++++++++++++++++++++++++++++++++
 6 files changed, 116 insertions(+), 0 deletions(-)

This doesn't apply any more - for example, include/md5.h does not exist any more.

Please rebase against current top of tree and resubmit.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
It is not best to swap horses while crossing the river.
- Abraham Lincoln
#3 lore raw

PATCH 2/2 Use watchdog-aware functions when calculating hashes of images

In reply to Bartlomiej Sieka

---

 common/image.c      |   43 +++++++++----------------------------------
 include/image.h     |   17 +++++++++++++++--
 lib_generic/crc32.c |    1 +
 lib_generic/md5.c   |    4 ++++
 lib_generic/sha1.c  |    4 ++++
 5 files changed, 33 insertions(+), 36 deletions(-)
common/image.c +9 -34
index 35356bd..e1b5c73 100644
@@ -156,6 +156,8 @@ static table_entry_t uimage_comp[] = {
 };
 
 unsigned long crc32 (unsigned long, const unsigned char *, unsigned int);
+unsigned long crc32_wd (unsigned long, const unsigned char *,
+			unsigned int, unsigned int);
 static void genimg_print_size (uint32_t size);
 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
 static void genimg_print_time (time_t timestamp);
@@ -183,39 +185,11 @@ int image_check_dcrc (image_header_t *hdr)
 {
 	ulong data = image_get_data (hdr);
 	ulong len = image_get_data_size (hdr);
-	ulong dcrc = crc32 (0, (unsigned char *)data, len);
+	ulong dcrc = crc32_wd (0, (unsigned char *)data, len, CHUNKSZ_CRC32);
 
 	return (dcrc == image_get_dcrc (hdr));
 }
 
-#ifndef USE_HOSTCC
-int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz)
-{
-	ulong dcrc = 0;
-	ulong len = image_get_data_size (hdr);
-	ulong data = image_get_data (hdr);
-
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
-	ulong cdata = data;
-	ulong edata = cdata + len;
-
-	while (cdata < edata) {
-		ulong chunk = edata - cdata;
-
-		if (chunk > chunksz)
-			chunk = chunksz;
-		dcrc = crc32 (dcrc, (unsigned char *)cdata, chunk);
-		cdata += chunk;
-
-		WATCHDOG_RESET ();
-	}
-#else
-	dcrc = crc32 (0, (unsigned char *)data, len);
-#endif
-
-	return (dcrc == image_get_dcrc (hdr));
-}
-#endif /* !USE_HOSTCC */
 
 /**
  * image_multi_count - get component (sub-image) count
@@ -408,7 +382,7 @@ static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
 
 	if (verify) {
 		puts("   Verifying Checksum ... ");
-		if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
+		if (!image_check_dcrc (rd_hdr)) {
 			puts ("Bad Data CRC\n");
 			show_boot_progress (-12);
 			return NULL;
@@ -1908,15 +1882,16 @@ static int calculate_hash (const void *data, int data_len, const char *algo,
 			uint8_t *value, int *value_len)
 {
 	if (strcmp (algo, "crc32") == 0 ) {
-		*((uint32_t *)value) = crc32 (0, data, data_len);
+		*((uint32_t *)value) = crc32_wd (0, data, data_len,
+							CHUNKSZ_CRC32);
 		*((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value));
 		*value_len = 4;
 	} else if (strcmp (algo, "sha1") == 0 ) {
-		sha1_csum ((unsigned char *) data, data_len,
-				(unsigned char *) value);
+		sha1_csum_wd ((unsigned char *) data, data_len,
+				(unsigned char *) value, CHUNKSZ_SHA1);
 		*value_len = 20;
 	} else if (strcmp (algo, "md5") == 0 ) {
-		md5 ((unsigned char *)data, data_len, value);
+		md5_wd ((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
 		*value_len = 16;
 	} else {
 		debug ("Unsupported hash alogrithm\n");
include/image.h +15 -2
index dbcee1c..3405457 100644
@@ -226,9 +226,23 @@ typedef struct bootm_headers {
 /*
  * Some systems (for example LWMON) have very short watchdog periods;
  * we must make sure to split long operations like memmove() or
- * crc32() into reasonable chunks.
+ * checksum calculations into reasonable chunks.
  */
+#ifndef CHUNKSZ
 #define CHUNKSZ (64 * 1024)
+#endif
+
+#ifndef CHUNKSZ_CRC32
+#define CHUNKSZ_CRC32 (64 * 1024)
+#endif
+
+#ifndef CHUNKSZ_MD5
+#define CHUNKSZ_MD5 (64 * 1024)
+#endif
+
+#ifndef CHUNKSZ_SHA1
+#define CHUNKSZ_SHA1 (64 * 1024)
+#endif
 
 #define uimage_to_cpu(x)		ntohl(x)
 #define cpu_to_uimage(x)		htonl(x)
@@ -362,7 +376,6 @@ static inline void image_set_name (image_header_t *hdr, const char *name)
 int image_check_hcrc (image_header_t *hdr);
 int image_check_dcrc (image_header_t *hdr);
 #ifndef USE_HOSTCC
-int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize);
 int getenv_yesno (char *var);
 ulong getenv_bootm_low(void);
 ulong getenv_bootm_size(void);
lib_generic/crc32.c +1 -0
index 0bfb64b..76ac838 100644
@@ -12,6 +12,7 @@
 #include <common.h>
 #endif
 
+#include <watchdog.h>
 #include "zlib.h"
 
 #define local static
lib_generic/md5.c +4 -0
index 8eaef0f..d1bb661 100644
@@ -25,6 +25,10 @@
    and to fit the cifs vfs by
    Steve French sfrench at us.ibm.com */
 
+#ifndef USE_HOSTCC
+#include <common.h>
+#endif /* USE_HOSTCC */
+#include <watchdog.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <md5.h>
lib_generic/sha1.c +4 -0
index 6950659..c8ef4d2 100644
@@ -29,6 +29,10 @@
 #define _CRT_SECURE_NO_DEPRECATE 1
 #endif
 
+#ifndef USE_HOSTCC
+#include <common.h>
+#endif /* USE_HOSTCC */
+#include <watchdog.h>
 #include <linux/string.h>
 #include "sha1.h"
 
#4 lore raw

PATCH 2/2 Use watchdog-aware functions when calculating hashes of images

Quoted 9 lines · In message <[email protected]> you wrote:

---

 common/image.c      |   43 +++++++++----------------------------------
 include/image.h     |   17 +++++++++++++++--
 lib_generic/crc32.c |    1 +
 lib_generic/md5.c   |    4 ++++
 lib_generic/sha1.c  |    4 ++++
 5 files changed, 33 insertions(+), 36 deletions(-)

This patch doesn't apply - please rebase against current top of tree and resubmit.

Best regards,

Wolfgang Denk

Signature · 6 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
The ideal situation is to have massive computing power right at home.
Something that dims the streetlights and shrinks the picture  on  the
neighbours' TVs when you boot it up.
#5 lore raw

v2 cover Calculate image hashes with watchdog triggering

In reply to Bartlomiej Sieka

Hash calculation of an image can be a time consuming operation, with the possibility of making the hardware watchdog (if present/enabled) expire in the middle. Add watchdog-aware hash calculation functions and make image hash calculation use them.
---
v2 of the patchset, rebased against current TOT (commit dc7746d8).

Bartlomiej Sieka (2):
Use watchdog-aware functions when calculating hashes of images Add support for calulacting hashes with watchdog triggering

 common/image.c       |   43 +++++++++----------------------------------
 include/common.h     |    1 +
 include/image.h      |   17 +++++++++++++++--
 include/sha1.h       |   11 +++++++++++
 include/u-boot/md5.h |    8 ++++++++
 lib_generic/crc32.c  |   28 ++++++++++++++++++++++++++++
 lib_generic/md5.c    |   40 ++++++++++++++++++++++++++++++++++++++++
 lib_generic/sha1.c   |   37 +++++++++++++++++++++++++++++++++++++
 8 files changed, 149 insertions(+), 36 deletions(-)
#6 lore raw

PATCH v2 1/2 Add support for calulacting hashes with watchdog triggering

Implement watchodg-aware variants of hash calculation functions:
- crc32_wd()
- md5_wd()
- sha1_csum_wd()
The above functions calculate the hash of the input buffer in chunks, triggering the watchdog after processing each chunk. The chunk size is given as a function call parameter.

---

 include/common.h     |    1 +
 include/sha1.h       |   11 +++++++++++
 include/u-boot/md5.h |    8 ++++++++
 lib_generic/crc32.c  |   27 +++++++++++++++++++++++++++
 lib_generic/md5.c    |   36 ++++++++++++++++++++++++++++++++++++
 lib_generic/sha1.c   |   33 +++++++++++++++++++++++++++++++++
 6 files changed, 116 insertions(+), 0 deletions(-)
include/common.h +1 -0
index 8630780..ec894e7 100644
@@ -605,6 +605,7 @@ int	vsprintf(char *buf, const char *fmt, va_list args);
 
 /* lib_generic/crc32.c */
 ulong crc32 (ulong, const unsigned char *, uint);
+ulong crc32_wd (ulong, const unsigned char *, uint, uint);
 ulong crc32_no_comp (ulong, const unsigned char *, uint);
 
 /* common/console.c */
include/sha1.h +11 -0
index 15ea13c..734d1fb 100644
@@ -80,6 +80,17 @@ void sha1_csum( unsigned char *input, int ilen,
 		unsigned char output[20] );
 
 /**
+ * \brief	   Output = SHA-1( input buffer ), with watchdog triggering
+ *
+ * \param input    buffer holding the  data
+ * \param ilen	   length of the input data
+ * \param output   SHA-1 checksum result
+ * \param chunk_sz watchdog triggering period (in bytes of input processed)
+ */
+void sha1_csum_wd (unsigned char *input, int ilen,
+		unsigned char output[20], unsigned int chunk_sz);
+
+/**
  * \brief	   Output = SHA-1( file contents )
  *
  * \param path	   input file name
include/u-boot/md5.h +8 -0
index 046d1ee..8b44a7f 100644
@@ -20,4 +20,12 @@ struct MD5Context {
  */
 void md5 (unsigned char *input, int len, unsigned char output[16]);
 
+/*
+ * Calculate and store in 'output' the MD5 digest of 'len' bytes at 'input'.
+ * 'output' must have enough space to hold 16 bytes. If 'chunk' Trigger the
+ * watchdog every 'chunk_sz' bytes of input processed.
+ */
+void md5_wd (unsigned char *input, int len, unsigned char output[16],
+		unsigned int chunk_sz);
+
 #endif /* _MD5_H */
lib_generic/crc32.c +27 -0
index df0dbca..0bfb64b 100644
@@ -197,3 +197,30 @@ uLong ZEXPORT crc32_no_comp(uLong crc, const Bytef *buf, uInt len)
 }
 
 #endif
+
+/*
+ * Calculate the crc32 checksum triggering the watchdog every 'chunk_sz' bytes
+ * of input.
+ */
+ulong crc32_wd (ulong crc, const unsigned char *buf, uint len, uint chunk_sz)
+{
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	const unsigned char *end, *curr;
+	int chunk;
+
+	curr = buf;
+	end = buf + len;
+	while (curr < end) {
+		chunk = end - curr;
+		if (chunk > chunk_sz)
+			chunk = chunk_sz;
+		crc = crc32 (crc, curr, chunk);
+		curr += chunk;
+		WATCHDOG_RESET ();
+	}
+#else
+        crc = crc32 (crc, buf, len);
+#endif
+
+	return crc;
+}
lib_generic/md5.c +36 -0
index 3cee431..20178b8 100644
@@ -272,3 +272,39 @@ md5 (unsigned char *input, int len, unsigned char output[16])
 	MD5Update(&context, input, len);
 	MD5Final(output, &context);
 }
+
+
+/*
+ * Calculate and store in 'output' the MD5 digest of 'len' bytes at 'input'.
+ * 'output' must have enough space to hold 16 bytes. If 'chunk' Trigger the
+ * watchdog every 'chunk_sz' bytes of input processed.
+ */
+void
+md5_wd (unsigned char *input, int len, unsigned char output[16],
+	unsigned int chunk_sz)
+{
+	struct MD5Context context;
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	unsigned char *end, *curr;
+	int chunk;
+#endif
+
+	MD5Init(&context);
+
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	curr = input;
+	end = input + len;
+	while (curr < end) {
+		chunk = end - curr;
+		if (chunk > chunk_sz)
+			chunk = chunk_sz;
+		MD5Update(&context, curr, chunk);
+		curr += chunk;
+		WATCHDOG_RESET ();
+	}
+#else
+	MD5Update(&context, input, len);
+#endif
+
+	MD5Final(output, &context);
+}
lib_generic/sha1.c +33 -0
index 08ffa6b..6950659 100644
@@ -309,6 +309,39 @@ void sha1_csum (unsigned char *input, int ilen, unsigned char output[20])
 }
 
 /*
+ * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz'
+ * bytes of input processed.
+ */
+void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20],
+			unsigned int chunk_sz)
+{
+	sha1_context ctx;
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	unsigned char *end, *curr;
+	int chunk;
+#endif
+
+	sha1_starts (&ctx);
+
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	curr = input;
+	end = input + ilen;
+	while (curr < end) {
+		chunk = end - curr;
+		if (chunk > chunk_sz)
+			chunk = chunk_sz;
+		sha1_update (&ctx, curr, chunk);
+		curr += chunk;
+		WATCHDOG_RESET ();
+	}
+#else
+	sha1_update (&ctx, input, ilen);
+#endif
+
+	sha1_finish (&ctx, output);
+}
+
+/*
  * Output = HMAC-SHA-1( input buffer, hmac key )
  */
 void sha1_hmac (unsigned char *key, int keylen,
#7 lore raw

PATCH v2 1/2 Add support for calulacting hashes with watchdog triggering

Quoted 11 lines · In message <[email protected]> you wrote:

Implement watchodg-aware variants of hash calculation functions:
- crc32_wd()
- md5_wd()
- sha1_csum_wd()
The above functions calculate the hash of the input buffer in chunks, triggering the watchdog after processing each chunk. The chunk size is given as a function call parameter.

---

Quoted 7 lines
 include/common.h     |    1 +
 include/sha1.h       |   11 +++++++++++
 include/u-boot/md5.h |    8 ++++++++
 lib_generic/crc32.c  |   27 +++++++++++++++++++++++++++
 lib_generic/md5.c    |   36 ++++++++++++++++++++++++++++++++++++
 lib_generic/sha1.c   |   33 +++++++++++++++++++++++++++++++++
 6 files changed, 116 insertions(+), 0 deletions(-)

Applied, thanks.

Best regards,

Wolfgang Denk

Signature · 4 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
All easy problems have already been solved.
#8 lore raw

PATCH v2 2/2 Use watchdog-aware functions when calculating hashes of images

In reply to Bartlomiej Sieka

---

 common/image.c      |   43 +++++++++----------------------------------
 include/image.h     |   17 +++++++++++++++--
 lib_generic/crc32.c |    1 +
 lib_generic/md5.c   |    4 ++++
 lib_generic/sha1.c  |    4 ++++
 5 files changed, 33 insertions(+), 36 deletions(-)
common/image.c +9 -34
index 9b1108f..efb0c4b 100644
@@ -156,6 +156,8 @@ static table_entry_t uimage_comp[] = {
 };
 
 unsigned long crc32 (unsigned long, const unsigned char *, unsigned int);
+unsigned long crc32_wd (unsigned long, const unsigned char *,
+			unsigned int, unsigned int);
 static void genimg_print_size (uint32_t size);
 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
 static void genimg_print_time (time_t timestamp);
@@ -183,39 +185,11 @@ int image_check_dcrc (image_header_t *hdr)
 {
 	ulong data = image_get_data (hdr);
 	ulong len = image_get_data_size (hdr);
-	ulong dcrc = crc32 (0, (unsigned char *)data, len);
+	ulong dcrc = crc32_wd (0, (unsigned char *)data, len, CHUNKSZ_CRC32);
 
 	return (dcrc == image_get_dcrc (hdr));
 }
 
-#ifndef USE_HOSTCC
-int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz)
-{
-	ulong dcrc = 0;
-	ulong len = image_get_data_size (hdr);
-	ulong data = image_get_data (hdr);
-
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
-	ulong cdata = data;
-	ulong edata = cdata + len;
-
-	while (cdata < edata) {
-		ulong chunk = edata - cdata;
-
-		if (chunk > chunksz)
-			chunk = chunksz;
-		dcrc = crc32 (dcrc, (unsigned char *)cdata, chunk);
-		cdata += chunk;
-
-		WATCHDOG_RESET ();
-	}
-#else
-	dcrc = crc32 (0, (unsigned char *)data, len);
-#endif
-
-	return (dcrc == image_get_dcrc (hdr));
-}
-#endif /* !USE_HOSTCC */
 
 /**
  * image_multi_count - get component (sub-image) count
@@ -416,7 +390,7 @@ static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
 
 	if (verify) {
 		puts("   Verifying Checksum ... ");
-		if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
+		if (!image_check_dcrc (rd_hdr)) {
 			puts ("Bad Data CRC\n");
 			show_boot_progress (-12);
 			return NULL;
@@ -1923,15 +1897,16 @@ static int calculate_hash (const void *data, int data_len, const char *algo,
 			uint8_t *value, int *value_len)
 {
 	if (strcmp (algo, "crc32") == 0 ) {
-		*((uint32_t *)value) = crc32 (0, data, data_len);
+		*((uint32_t *)value) = crc32_wd (0, data, data_len,
+							CHUNKSZ_CRC32);
 		*((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value));
 		*value_len = 4;
 	} else if (strcmp (algo, "sha1") == 0 ) {
-		sha1_csum ((unsigned char *) data, data_len,
-				(unsigned char *) value);
+		sha1_csum_wd ((unsigned char *) data, data_len,
+				(unsigned char *) value, CHUNKSZ_SHA1);
 		*value_len = 20;
 	} else if (strcmp (algo, "md5") == 0 ) {
-		md5 ((unsigned char *)data, data_len, value);
+		md5_wd ((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
 		*value_len = 16;
 	} else {
 		debug ("Unsupported hash alogrithm\n");
include/image.h +15 -2
index 4076484..664e51e 100644
@@ -227,9 +227,23 @@ typedef struct bootm_headers {
 /*
  * Some systems (for example LWMON) have very short watchdog periods;
  * we must make sure to split long operations like memmove() or
- * crc32() into reasonable chunks.
+ * checksum calculations into reasonable chunks.
  */
+#ifndef CHUNKSZ
 #define CHUNKSZ (64 * 1024)
+#endif
+
+#ifndef CHUNKSZ_CRC32
+#define CHUNKSZ_CRC32 (64 * 1024)
+#endif
+
+#ifndef CHUNKSZ_MD5
+#define CHUNKSZ_MD5 (64 * 1024)
+#endif
+
+#ifndef CHUNKSZ_SHA1
+#define CHUNKSZ_SHA1 (64 * 1024)
+#endif
 
 #define uimage_to_cpu(x)		ntohl(x)
 #define cpu_to_uimage(x)		htonl(x)
@@ -363,7 +377,6 @@ static inline void image_set_name (image_header_t *hdr, const char *name)
 int image_check_hcrc (image_header_t *hdr);
 int image_check_dcrc (image_header_t *hdr);
 #ifndef USE_HOSTCC
-int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize);
 int getenv_yesno (char *var);
 ulong getenv_bootm_low(void);
 ulong getenv_bootm_size(void);
lib_generic/crc32.c +1 -0
index 0bfb64b..76ac838 100644
@@ -12,6 +12,7 @@
 #include <common.h>
 #endif
 
+#include <watchdog.h>
 #include "zlib.h"
 
 #define local static
lib_generic/md5.c +4 -0
index 20178b8..78ef475 100644
@@ -25,6 +25,10 @@
    and to fit the cifs vfs by
    Steve French sfrench at us.ibm.com */
 
+#ifndef USE_HOSTCC
+#include <common.h>
+#endif /* USE_HOSTCC */
+#include <watchdog.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <u-boot/md5.h>
lib_generic/sha1.c +4 -0
index 6950659..c8ef4d2 100644
@@ -29,6 +29,10 @@
 #define _CRT_SECURE_NO_DEPRECATE 1
 #endif
 
+#ifndef USE_HOSTCC
+#include <common.h>
+#endif /* USE_HOSTCC */
+#include <watchdog.h>
 #include <linux/string.h>
 #include "sha1.h"
 
#9 lore raw

PATCH v2 2/2 Use watchdog-aware functions when calculating hashes of images

Quoted 9 lines · In message <[email protected]> you wrote:

---

 common/image.c      |   43 +++++++++----------------------------------
 include/image.h     |   17 +++++++++++++++--
 lib_generic/crc32.c |    1 +
 lib_generic/md5.c   |    4 ++++
 lib_generic/sha1.c  |    4 ++++
 5 files changed, 33 insertions(+), 36 deletions(-)

Sorry, but this patch does not apply any more:

Applying Use watchdog-aware functions when calculating hashes of images
error: patch failed: common/image.c:156
error: common/image.c: patch does not apply
error: patch failed: lib_generic/crc32.c:12
error: lib_generic/crc32.c: patch does not apply
fatal: sha1 information is lacking or useless (common/image.c). Repository lacks necessary blobs to fall back on 3-way merge. Cannot fall back to three-way merge.
Patch failed at 0001.

Please rebase and resubmit.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Perl itself is  usually  pretty  good  about  telling  you  what  you
shouldn't do. :-)     - Larry Wall in <[email protected]>
#10 lore raw

v3 cover Calculate image hashes with watchdog triggering

In reply to Bartlomiej Sieka

Hash calculation of an image can be a time consuming operation, with the possibility of making the hardware watchdog (if present/enabled) expire in the middle. Make image hash calculation use use watchdog-aware functions.
---
v3 of the patchset, rebased against current TOT (commit 04a5b03d), dropped one patch already applied and added a patch changing crc32_wd prototype.

Bartlomiej Sieka (2):
Use watchdog-aware functions when calculating hashes of images
crc32: use uint32_t rather than unsigned long in watchdog-aware variant

 common/image.c      |   42 ++++++++----------------------------------
 include/image.h     |   17 +++++++++++++++--
 lib_generic/crc32.c |    4 +++-
 lib_generic/md5.c   |    4 ++++
 lib_generic/sha1.c  |    4 ++++
 5 files changed, 34 insertions(+), 37 deletions(-)
#11 lore raw

PATCH 1/2 crc32: use uint32_t rather than unsigned long in watchdog-aware variant

Propagate change introduced by "crc32: use uint32_t rather than unsigned long", commit id 89cdab788f3716b335fefb60b836ebcf975aceab. While there, change uint to uInt in crc32_wd prototype, to match convention already present in the file.

---

 lib_generic/crc32.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
lib_generic/crc32.c +2 -1
index 58cd22e..a7073c0 100644
@@ -203,7 +203,8 @@ uint32_t ZEXPORT crc32_no_comp(uint32_t crc, const Bytef *buf, uInt len)
  * Calculate the crc32 checksum triggering the watchdog every 'chunk_sz' bytes
  * of input.
  */
-ulong crc32_wd (ulong crc, const unsigned char *buf, uint len, uint chunk_sz)
+uint32_t crc32_wd (uint32_t crc, const unsigned char *buf, uInt len,
+		uInt chunk_sz)
 {
 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
 	const unsigned char *end, *curr;
#12 lore raw

PATCH v3 2/2 Use watchdog-aware functions when calculating hashes of images

In reply to Bartlomiej Sieka

---

 common/image.c      |   42 ++++++++----------------------------------
 include/image.h     |   17 +++++++++++++++--
 lib_generic/crc32.c |    1 +
 lib_generic/md5.c   |    4 ++++
 lib_generic/sha1.c  |    4 ++++
 5 files changed, 32 insertions(+), 36 deletions(-)
common/image.c +8 -34
index 83e3593..4a024d4 100644
@@ -156,6 +156,7 @@ static table_entry_t uimage_comp[] = {
 };
 
 uint32_t crc32 (uint32_t, const unsigned char *, uint);
+uint32_t crc32_wd (uint32_t, const unsigned char *, uint, uint);
 static void genimg_print_size (uint32_t size);
 #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
 static void genimg_print_time (time_t timestamp);
@@ -183,39 +184,11 @@ int image_check_dcrc (image_header_t *hdr)
 {
 	ulong data = image_get_data (hdr);
 	ulong len = image_get_data_size (hdr);
-	ulong dcrc = crc32 (0, (unsigned char *)data, len);
+	ulong dcrc = crc32_wd (0, (unsigned char *)data, len, CHUNKSZ_CRC32);
 
 	return (dcrc == image_get_dcrc (hdr));
 }
 
-#ifndef USE_HOSTCC
-int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz)
-{
-	ulong dcrc = 0;
-	ulong len = image_get_data_size (hdr);
-	ulong data = image_get_data (hdr);
-
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
-	ulong cdata = data;
-	ulong edata = cdata + len;
-
-	while (cdata < edata) {
-		ulong chunk = edata - cdata;
-
-		if (chunk > chunksz)
-			chunk = chunksz;
-		dcrc = crc32 (dcrc, (unsigned char *)cdata, chunk);
-		cdata += chunk;
-
-		WATCHDOG_RESET ();
-	}
-#else
-	dcrc = crc32 (0, (unsigned char *)data, len);
-#endif
-
-	return (dcrc == image_get_dcrc (hdr));
-}
-#endif /* !USE_HOSTCC */
 
 /**
  * image_multi_count - get component (sub-image) count
@@ -416,7 +389,7 @@ static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
 
 	if (verify) {
 		puts("   Verifying Checksum ... ");
-		if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
+		if (!image_check_dcrc (rd_hdr)) {
 			puts ("Bad Data CRC\n");
 			show_boot_progress (-12);
 			return NULL;
@@ -1923,15 +1896,16 @@ static int calculate_hash (const void *data, int data_len, const char *algo,
 			uint8_t *value, int *value_len)
 {
 	if (strcmp (algo, "crc32") == 0 ) {
-		*((uint32_t *)value) = crc32 (0, data, data_len);
+		*((uint32_t *)value) = crc32_wd (0, data, data_len,
+							CHUNKSZ_CRC32);
 		*((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value));
 		*value_len = 4;
 	} else if (strcmp (algo, "sha1") == 0 ) {
-		sha1_csum ((unsigned char *) data, data_len,
-				(unsigned char *) value);
+		sha1_csum_wd ((unsigned char *) data, data_len,
+				(unsigned char *) value, CHUNKSZ_SHA1);
 		*value_len = 20;
 	} else if (strcmp (algo, "md5") == 0 ) {
-		md5 ((unsigned char *)data, data_len, value);
+		md5_wd ((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
 		*value_len = 16;
 	} else {
 		debug ("Unsupported hash alogrithm\n");
include/image.h +15 -2
index 4076484..664e51e 100644
@@ -227,9 +227,23 @@ typedef struct bootm_headers {
 /*
  * Some systems (for example LWMON) have very short watchdog periods;
  * we must make sure to split long operations like memmove() or
- * crc32() into reasonable chunks.
+ * checksum calculations into reasonable chunks.
  */
+#ifndef CHUNKSZ
 #define CHUNKSZ (64 * 1024)
+#endif
+
+#ifndef CHUNKSZ_CRC32
+#define CHUNKSZ_CRC32 (64 * 1024)
+#endif
+
+#ifndef CHUNKSZ_MD5
+#define CHUNKSZ_MD5 (64 * 1024)
+#endif
+
+#ifndef CHUNKSZ_SHA1
+#define CHUNKSZ_SHA1 (64 * 1024)
+#endif
 
 #define uimage_to_cpu(x)		ntohl(x)
 #define cpu_to_uimage(x)		htonl(x)
@@ -363,7 +377,6 @@ static inline void image_set_name (image_header_t *hdr, const char *name)
 int image_check_hcrc (image_header_t *hdr);
 int image_check_dcrc (image_header_t *hdr);
 #ifndef USE_HOSTCC
-int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize);
 int getenv_yesno (char *var);
 ulong getenv_bootm_low(void);
 ulong getenv_bootm_size(void);
lib_generic/crc32.c +1 -0
index a7073c0..336a6e5 100644
@@ -14,6 +14,7 @@
 #include <stdint.h>
 #endif
 
+#include <watchdog.h>
 #include "zlib.h"
 
 #define local static
lib_generic/md5.c +4 -0
index 20178b8..78ef475 100644
@@ -25,6 +25,10 @@
    and to fit the cifs vfs by
    Steve French sfrench at us.ibm.com */
 
+#ifndef USE_HOSTCC
+#include <common.h>
+#endif /* USE_HOSTCC */
+#include <watchdog.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <u-boot/md5.h>
lib_generic/sha1.c +4 -0
index 6950659..c8ef4d2 100644
@@ -29,6 +29,10 @@
 #define _CRT_SECURE_NO_DEPRECATE 1
 #endif
 
+#ifndef USE_HOSTCC
+#include <common.h>
+#endif /* USE_HOSTCC */
+#include <watchdog.h>
 #include <linux/string.h>
 #include "sha1.h"
 
#13 lore raw

PATCH v3 2/2 Use watchdog-aware functions when calculating hashes of images

Quoted 9 lines · In message <[email protected]> you wrote:

---

 common/image.c      |   42 ++++++++----------------------------------
 include/image.h     |   17 +++++++++++++++--
 lib_generic/crc32.c |    1 +
 lib_generic/md5.c   |    4 ++++
 lib_generic/sha1.c  |    4 ++++
 5 files changed, 32 insertions(+), 36 deletions(-)

Applied, thanks.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
The flow chart is a most thoroughly oversold piece of  program  docu-
mentation.              -- Frederick Brooks, "The Mythical Man Month"