summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/cmd_mem.c75
-rw-r--r--common/hash.c118
-rw-r--r--include/hash.h2
-rw-r--r--include/u-boot/crc.h11
-rw-r--r--lib/crc32.c9
5 files changed, 108 insertions, 107 deletions
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index 12dbc16..95b49b2 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -32,6 +32,7 @@
#ifdef CONFIG_HAS_DATAFLASH
#include <dataflash.h>
#endif
+#include <hash.h>
#include <watchdog.h>
#include <asm/io.h>
#include <linux/compiler.h>
@@ -1098,89 +1099,27 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
#ifdef CONFIG_CMD_CRC32
-#ifndef CONFIG_CRC32_VERIFY
-
static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- ulong addr, length;
- ulong crc;
- ulong *ptr;
-
- if (argc < 3)
- return CMD_RET_USAGE;
-
- addr = simple_strtoul (argv[1], NULL, 16);
- addr += base_address;
-
- length = simple_strtoul (argv[2], NULL, 16);
-
- crc = crc32_wd (0, (const uchar *) addr, length, CHUNKSZ_CRC32);
-
- printf ("CRC32 for %08lx ... %08lx ==> %08lx\n",
- addr, addr + length - 1, crc);
-
- if (argc > 3) {
- ptr = (ulong *) simple_strtoul (argv[3], NULL, 16);
- *ptr = crc;
- }
-
- return 0;
-}
-
-#else /* CONFIG_CRC32_VERIFY */
-
-int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- ulong addr, length;
- ulong crc;
- ulong *ptr;
- ulong vcrc;
- int verify;
+ int flags = 0;
int ac;
char * const *av;
- if (argc < 3) {
-usage:
+ if (argc < 3)
return CMD_RET_USAGE;
- }
av = argv + 1;
ac = argc - 1;
+#ifdef CONFIG_HASH_VERIFY
if (strcmp(*av, "-v") == 0) {
- verify = 1;
+ flags |= HASH_FLAG_VERIFY;
av++;
ac--;
- if (ac < 3)
- goto usage;
- } else
- verify = 0;
-
- addr = simple_strtoul(*av++, NULL, 16);
- addr += base_address;
- length = simple_strtoul(*av++, NULL, 16);
-
- crc = crc32_wd (0, (const uchar *) addr, length, CHUNKSZ_CRC32);
-
- if (!verify) {
- printf ("CRC32 for %08lx ... %08lx ==> %08lx\n",
- addr, addr + length - 1, crc);
- if (ac > 2) {
- ptr = (ulong *) simple_strtoul (*av++, NULL, 16);
- *ptr = crc;
- }
- } else {
- vcrc = simple_strtoul(*av++, NULL, 16);
- if (vcrc != crc) {
- printf ("CRC32 for %08lx ... %08lx ==> %08lx != %08lx ** ERROR **\n",
- addr, addr + length - 1, crc, vcrc);
- return 1;
- }
}
+#endif
- return 0;
-
+ return hash_command("crc32", flags, cmdtp, flag, ac, av);
}
-#endif /* CONFIG_CRC32_VERIFY */
#endif
diff --git a/common/hash.c b/common/hash.c
index 462853d..ef6fe37 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -34,13 +34,19 @@
* crypto could perhaps add named version of these algorithms here.
*/
static struct hash_algo hash_algo[] = {
-#ifdef CONFIG_SHA1
+ /*
+ * This is CONFIG_CMD_SHA1SUM instead of CONFIG_SHA1 since otherwise
+ * it bloats the code for boards which use SHA1 but not the 'hash'
+ * or 'sha1sum' commands.
+ */
+#ifdef CONFIG_CMD_SHA1SUM
{
"SHA1",
SHA1_SUM_LEN,
sha1_csum_wd,
CHUNKSZ_SHA1,
},
+#define MULTI_HASH
#endif
#ifdef CONFIG_SHA256
{
@@ -49,9 +55,27 @@ static struct hash_algo hash_algo[] = {
sha256_csum_wd,
CHUNKSZ_SHA256,
},
+#define MULTI_HASH
#endif
+ {
+ "CRC32",
+ 4,
+ crc32_wd_buf,
+ CHUNKSZ_CRC32,
+ },
};
+#if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_CMD_HASH)
+#define MULTI_HASH
+#endif
+
+/* Try to minimize code size for boards that don't want much hashing */
+#ifdef MULTI_HASH
+#define multi_hash() 1
+#else
+#define multi_hash() 0
+#endif
+
/**
* store_result: Store the resulting sum to an address or variable
*
@@ -192,10 +216,7 @@ static void show_hash(struct hash_algo *algo, ulong addr, ulong len,
int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
- struct hash_algo *algo;
ulong addr, len;
- u8 output[HASH_MAX_DIGEST_SIZE];
- u8 vsum[HASH_MAX_DIGEST_SIZE];
if (argc < 2)
return CMD_RET_USAGE;
@@ -203,52 +224,73 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
addr = simple_strtoul(*argv++, NULL, 16);
len = simple_strtoul(*argv++, NULL, 16);
- algo = find_hash_algo(algo_name);
- if (!algo) {
- printf("Unknown hash algorithm '%s'\n", algo_name);
- return CMD_RET_USAGE;
- }
- argc -= 2;
+ if (multi_hash()) {
+ struct hash_algo *algo;
+ u8 output[HASH_MAX_DIGEST_SIZE];
+ u8 vsum[HASH_MAX_DIGEST_SIZE];
- if (algo->digest_size > HASH_MAX_DIGEST_SIZE) {
- puts("HASH_MAX_DIGEST_SIZE exceeded\n");
- return 1;
- }
+ algo = find_hash_algo(algo_name);
+ if (!algo) {
+ printf("Unknown hash algorithm '%s'\n", algo_name);
+ return CMD_RET_USAGE;
+ }
+ argc -= 2;
+
+ if (algo->digest_size > HASH_MAX_DIGEST_SIZE) {
+ puts("HASH_MAX_DIGEST_SIZE exceeded\n");
+ return 1;
+ }
- algo->hash_func_ws((const unsigned char *)addr, len, output,
- algo->chunk_size);
+ algo->hash_func_ws((const unsigned char *)addr, len, output,
+ algo->chunk_size);
- /* Try to avoid code bloat when verify is not needed */
+ /* Try to avoid code bloat when verify is not needed */
#ifdef CONFIG_HASH_VERIFY
- if (flags & HASH_FLAG_VERIFY) {
+ if (flags & HASH_FLAG_VERIFY) {
#else
- if (0) {
+ if (0) {
#endif
- if (!argc)
- return CMD_RET_USAGE;
- if (parse_verify_sum(algo, *argv, vsum,
+ if (!argc)
+ return CMD_RET_USAGE;
+ if (parse_verify_sum(algo, *argv, vsum,
flags & HASH_FLAG_ENV)) {
- printf("ERROR: %s does not contain a valid %s sum\n",
- *argv, algo->name);
- return 1;
- }
- if (memcmp(output, vsum, algo->digest_size) != 0) {
- int i;
+ printf("ERROR: %s does not contain a valid "
+ "%s sum\n", *argv, algo->name);
+ return 1;
+ }
+ if (memcmp(output, vsum, algo->digest_size) != 0) {
+ int i;
+ show_hash(algo, addr, len, output);
+ printf(" != ");
+ for (i = 0; i < algo->digest_size; i++)
+ printf("%02x", vsum[i]);
+ puts(" ** ERROR **\n");
+ return 1;
+ }
+ } else {
show_hash(algo, addr, len, output);
- printf(" != ");
- for (i = 0; i < algo->digest_size; i++)
- printf("%02x", vsum[i]);
- puts(" ** ERROR **\n");
- return 1;
+ printf("\n");
+
+ if (argc) {
+ store_result(algo, output, *argv,
+ flags & HASH_FLAG_ENV);
+ }
}
+
+ /* Horrible code size hack for boards that just want crc32 */
} else {
- show_hash(algo, addr, len, output);
- printf("\n");
+ ulong crc;
+ ulong *ptr;
+
+ crc = crc32_wd(0, (const uchar *)addr, len, CHUNKSZ_CRC32);
+
+ printf("CRC32 for %08lx ... %08lx ==> %08lx\n",
+ addr, addr + len - 1, crc);
- if (argc) {
- store_result(algo, output, *argv,
- flags & HASH_FLAG_ENV);
+ if (argc > 3) {
+ ptr = (ulong *)simple_strtoul(argv[3], NULL, 16);
+ *ptr = crc;
}
}
diff --git a/include/hash.h b/include/hash.h
index 88fa2b5..f2b2c45 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -22,7 +22,7 @@
#ifndef _HASH_H
#define _HASH_H
-#ifdef CONFIG_SHA1SUM_VERIFY
+#if defined(CONFIG_SHA1SUM_VERIFY) || defined(CONFIG_CRC32_VERIFY)
#define CONFIG_HASH_VERIFY
#endif
diff --git a/include/u-boot/crc.h b/include/u-boot/crc.h
index 07badbf..08e509e 100644
--- a/include/u-boot/crc.h
+++ b/include/u-boot/crc.h
@@ -30,4 +30,15 @@ uint32_t crc32 (uint32_t, const unsigned char *, uint);
uint32_t crc32_wd (uint32_t, const unsigned char *, uint, uint);
uint32_t crc32_no_comp (uint32_t, const unsigned char *, uint);
+/**
+ * crc32_wd_buf - Perform CRC32 on a buffer and return result in buffer
+ *
+ * @input: Input buffer
+ * @ilen: Input buffer length
+ * @output: Place to put checksum result (4 bytes)
+ * @chunk_sz: Trigger watchdog after processing this many bytes
+ */
+void crc32_wd_buf(const unsigned char *input, uint ilen,
+ unsigned char *output, uint chunk_sz);
+
#endif /* _UBOOT_CRC_H */
diff --git a/lib/crc32.c b/lib/crc32.c
index 27335a3..76205da 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -249,3 +249,12 @@ uint32_t ZEXPORT crc32_wd (uint32_t crc,
return crc;
}
+
+void crc32_wd_buf(const unsigned char *input, unsigned int ilen,
+ unsigned char *output, unsigned int chunk_sz)
+{
+ uint32_t crc;
+
+ crc = crc32_wd(0, input, ilen, chunk_sz);
+ memcpy(output, &crc, sizeof(crc));
+}