[U-Boot-Users] [PATCH 0/2] 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(-)

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.
Signed-off-by: Bartlomiej Sieka tur@semihalf.com ---
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(-)
diff --git a/include/common.h b/include/common.h index 39bcd30..aee58ec 100644 --- a/include/common.h +++ b/include/common.h @@ -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 */ diff --git a/include/md5.h b/include/md5.h index 046d1ee..8b44a7f 100644 --- a/include/md5.h +++ b/include/md5.h @@ -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 */ diff --git a/include/sha1.h b/include/sha1.h index 15ea13c..734d1fb 100644 --- a/include/sha1.h +++ b/include/sha1.h @@ -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 diff --git a/lib_generic/crc32.c b/lib_generic/crc32.c index df0dbca..0bfb64b 100644 --- a/lib_generic/crc32.c +++ b/lib_generic/crc32.c @@ -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; +} diff --git a/lib_generic/md5.c b/lib_generic/md5.c index a51da45..8eaef0f 100644 --- a/lib_generic/md5.c +++ b/lib_generic/md5.c @@ -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); +} diff --git a/lib_generic/sha1.c b/lib_generic/sha1.c index 08ffa6b..6950659 100644 --- a/lib_generic/sha1.c +++ b/lib_generic/sha1.c @@ -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,

In message 20080412111502.16495.46710.stgit@pollux.denx.de 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.
Signed-off-by: Bartlomiej Sieka tur@semihalf.com
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

Signed-off-by: Bartlomiej Sieka tur@semihalf.com ---
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(-)
diff --git a/common/image.c b/common/image.c index 35356bd..e1b5c73 100644 --- a/common/image.c +++ b/common/image.c @@ -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"); diff --git a/include/image.h b/include/image.h index dbcee1c..3405457 100644 --- a/include/image.h +++ b/include/image.h @@ -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); diff --git a/lib_generic/crc32.c b/lib_generic/crc32.c index 0bfb64b..76ac838 100644 --- a/lib_generic/crc32.c +++ b/lib_generic/crc32.c @@ -12,6 +12,7 @@ #include <common.h> #endif
+#include <watchdog.h> #include "zlib.h"
#define local static diff --git a/lib_generic/md5.c b/lib_generic/md5.c index 8eaef0f..d1bb661 100644 --- a/lib_generic/md5.c +++ b/lib_generic/md5.c @@ -25,6 +25,10 @@ and to fit the cifs vfs by Steve French sfrench@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> diff --git a/lib_generic/sha1.c b/lib_generic/sha1.c index 6950659..c8ef4d2 100644 --- a/lib_generic/sha1.c +++ b/lib_generic/sha1.c @@ -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"

In message 20080412111520.16495.11791.stgit@pollux.denx.de you wrote:
Signed-off-by: Bartlomiej Sieka tur@semihalf.com
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

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(-)

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.
Signed-off-by: Bartlomiej Sieka tur@semihalf.com ---
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(-)
diff --git a/include/common.h b/include/common.h index 8630780..ec894e7 100644 --- a/include/common.h +++ b/include/common.h @@ -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 */ diff --git a/include/sha1.h b/include/sha1.h index 15ea13c..734d1fb 100644 --- a/include/sha1.h +++ b/include/sha1.h @@ -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 diff --git a/include/u-boot/md5.h b/include/u-boot/md5.h index 046d1ee..8b44a7f 100644 --- a/include/u-boot/md5.h +++ b/include/u-boot/md5.h @@ -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 */ diff --git a/lib_generic/crc32.c b/lib_generic/crc32.c index df0dbca..0bfb64b 100644 --- a/lib_generic/crc32.c +++ b/lib_generic/crc32.c @@ -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; +} diff --git a/lib_generic/md5.c b/lib_generic/md5.c index 3cee431..20178b8 100644 --- a/lib_generic/md5.c +++ b/lib_generic/md5.c @@ -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); +} diff --git a/lib_generic/sha1.c b/lib_generic/sha1.c index 08ffa6b..6950659 100644 --- a/lib_generic/sha1.c +++ b/lib_generic/sha1.c @@ -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,

In message 20080422102756.30118.38437.stgit@pollux.denx.de 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.
Signed-off-by: Bartlomiej Sieka tur@semihalf.com
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

Signed-off-by: Bartlomiej Sieka tur@semihalf.com ---
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(-)
diff --git a/common/image.c b/common/image.c index 9b1108f..efb0c4b 100644 --- a/common/image.c +++ b/common/image.c @@ -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"); diff --git a/include/image.h b/include/image.h index 4076484..664e51e 100644 --- a/include/image.h +++ b/include/image.h @@ -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); diff --git a/lib_generic/crc32.c b/lib_generic/crc32.c index 0bfb64b..76ac838 100644 --- a/lib_generic/crc32.c +++ b/lib_generic/crc32.c @@ -12,6 +12,7 @@ #include <common.h> #endif
+#include <watchdog.h> #include "zlib.h"
#define local static diff --git a/lib_generic/md5.c b/lib_generic/md5.c index 20178b8..78ef475 100644 --- a/lib_generic/md5.c +++ b/lib_generic/md5.c @@ -25,6 +25,10 @@ and to fit the cifs vfs by Steve French sfrench@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> diff --git a/lib_generic/sha1.c b/lib_generic/sha1.c index 6950659..c8ef4d2 100644 --- a/lib_generic/sha1.c +++ b/lib_generic/sha1.c @@ -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"

In message 20080422102802.30118.26894.stgit@pollux.denx.de you wrote:
Signed-off-by: Bartlomiej Sieka tur@semihalf.com
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

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(-)

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.
Signed-off-by: Bartlomiej Sieka tur@semihalf.com ---
lib_generic/crc32.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/lib_generic/crc32.c b/lib_generic/crc32.c index 58cd22e..a7073c0 100644 --- a/lib_generic/crc32.c +++ b/lib_generic/crc32.c @@ -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;

Signed-off-by: Bartlomiej Sieka tur@semihalf.com ---
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(-)
diff --git a/common/image.c b/common/image.c index 83e3593..4a024d4 100644 --- a/common/image.c +++ b/common/image.c @@ -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"); diff --git a/include/image.h b/include/image.h index 4076484..664e51e 100644 --- a/include/image.h +++ b/include/image.h @@ -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); diff --git a/lib_generic/crc32.c b/lib_generic/crc32.c index a7073c0..336a6e5 100644 --- a/lib_generic/crc32.c +++ b/lib_generic/crc32.c @@ -14,6 +14,7 @@ #include <stdint.h> #endif
+#include <watchdog.h> #include "zlib.h"
#define local static diff --git a/lib_generic/md5.c b/lib_generic/md5.c index 20178b8..78ef475 100644 --- a/lib_generic/md5.c +++ b/lib_generic/md5.c @@ -25,6 +25,10 @@ and to fit the cifs vfs by Steve French sfrench@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> diff --git a/lib_generic/sha1.c b/lib_generic/sha1.c index 6950659..c8ef4d2 100644 --- a/lib_generic/sha1.c +++ b/lib_generic/sha1.c @@ -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"

In message 20080425100950.32281.65923.stgit@pollux.denx.de you wrote:
Signed-off-by: Bartlomiej Sieka tur@semihalf.com
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
participants (2)
-
Bartlomiej Sieka
-
Wolfgang Denk