hash: Add a flag to support saving hashes in the environment
authorSimon Glass <sjg@chromium.org>
Sun, 24 Feb 2013 17:33:26 +0000 (17:33 +0000)
committerSimon Glass <sjg@chromium.org>
Fri, 1 Mar 2013 03:09:23 +0000 (19:09 -0800)
Some hashing commands permit saving the hash in an environment variable,
and verifying a hash from there. But the crc32 command does not support
this. In order to permit crc32 to use the generic hashing infrastructure,
add a flag to select which behaviour to use.

Signed-off-by: Simon Glass <sjg@chromium.org>
common/cmd_hash.c
common/cmd_sha1sum.c
common/hash.c
include/hash.h

index eb6a338..8c03b5c 100644 (file)
 static int do_hash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 #ifdef CONFIG_HASH_VERIFY
-       int verify = 0;
+       int flags = HASH_FLAG_ENV;
 
        if (argc < 4)
                return CMD_RET_USAGE;
        if (!strcmp(argv[1], "-v")) {
-               verify = 1;
+               flags |= HASH_FLAG_VERIFY;
                argc--;
                argv++;
        }
 #else
-       const int verify = 0;
+       const int flags = HASH_FLAG_ENV;
 #endif
        /* Move forward to 'algorithm' parameter */
        argc--;
        argv++;
-       return hash_command(*argv, verify, cmdtp, flag, argc - 1, argv + 1);
+       return hash_command(*argv, flags, cmdtp, flag, argc - 1, argv + 1);
 }
 
 #ifdef CONFIG_HASH_VERIFY
index fe927ab..9f08629 100644 (file)
@@ -31,7 +31,7 @@
 
 int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       int verify = 0;
+       int flags = HASH_FLAG_ENV;
        int ac;
        char * const *av;
 
@@ -42,13 +42,13 @@ int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        ac = argc - 1;
 #ifdef CONFIG_SHA1SUM_VERIFY
        if (strcmp(*av, "-v") == 0) {
-               verify = 1;
+               flags |= HASH_FLAG_VERIFY;
                av++;
                ac--;
        }
 #endif
 
-       return hash_command("sha1", verify, cmdtp, flag, ac, av);
+       return hash_command("sha1", flags, cmdtp, flag, ac, av);
 }
 
 #ifdef CONFIG_SHA1SUM_VERIFY
index e3a6e43..462853d 100644 (file)
@@ -58,19 +58,31 @@ static struct hash_algo hash_algo[] = {
  * @algo:              Hash algorithm being used
  * @sum:               Hash digest (algo->digest_size bytes)
  * @dest:              Destination, interpreted as a hex address if it starts
- *                     with * or otherwise as an environment variable.
+ *                     with * (or allow_env_vars is 0) or otherwise as an
+ *                     environment variable.
+ * @allow_env_vars:    non-zero to permit storing the result to an
+ *                     variable environment
  */
 static void store_result(struct hash_algo *algo, const u8 *sum,
-                        const char *dest)
+                        const char *dest, int allow_env_vars)
 {
        unsigned int i;
+       int env_var = 0;
 
-       if (*dest == '*') {
-               u8 *ptr;
+       /*
+        * If environment variables are allowed, then we assume that 'dest'
+        * is an environment variable, unless it starts with *, in which
+        * case we assume it is an address. If not allowed, it is always an
+        * address. This is to support the crc32 command.
+        */
+       if (allow_env_vars) {
+               if (*dest == '*')
+                       dest++;
+               else
+                       env_var = 1;
+       }
 
-               ptr = (u8 *)simple_strtoul(dest + 1, NULL, 16);
-               memcpy(ptr, sum, algo->digest_size);
-       } else {
+       if (env_var) {
                char str_output[HASH_MAX_DIGEST_SIZE * 2 + 1];
                char *str_ptr = str_output;
 
@@ -80,6 +92,11 @@ static void store_result(struct hash_algo *algo, const u8 *sum,
                }
                str_ptr = '\0';
                setenv(dest, str_output);
+       } else {
+               u8 *ptr;
+
+               ptr = (u8 *)simple_strtoul(dest, NULL, 16);
+               memcpy(ptr, sum, algo->digest_size);
        }
 }
 
@@ -94,14 +111,28 @@ static void store_result(struct hash_algo *algo, const u8 *sum,
  *                     Otherwise we assume it is an environment variable, and
  *                     look up its value (it must contain a hex digest).
  * @vsum:              Returns binary digest value (algo->digest_size bytes)
+ * @allow_env_vars:    non-zero to permit storing the result to an environment
+ *                     variable. If 0 then verify_str is assumed to be an
+ *                     address, and the * prefix is not expected.
  * @return 0 if ok, non-zero on error
  */
-static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum)
+static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum,
+                           int allow_env_vars)
 {
-       if (*verify_str == '*') {
+       int env_var = 0;
+
+       /* See comment above in store_result() */
+       if (allow_env_vars) {
+               if (*verify_str == '*')
+                       verify_str++;
+               else
+                       env_var = 1;
+       }
+
+       if (env_var) {
                u8 *ptr;
 
-               ptr = (u8 *)simple_strtoul(verify_str + 1, NULL, 16);
+               ptr = (u8 *)simple_strtoul(verify_str, NULL, 16);
                memcpy(vsum, ptr, algo->digest_size);
        } else {
                unsigned int i;
@@ -158,7 +189,7 @@ static void show_hash(struct hash_algo *algo, ulong addr, ulong len,
                printf("%02x", output[i]);
 }
 
-int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag,
+int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
                 int argc, char * const argv[])
 {
        struct hash_algo *algo;
@@ -169,13 +200,14 @@ int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag,
        if (argc < 2)
                return CMD_RET_USAGE;
 
+       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;
        }
-       addr = simple_strtoul(*argv++, NULL, 16);
-       len = simple_strtoul(*argv++, NULL, 16);
        argc -= 2;
 
        if (algo->digest_size > HASH_MAX_DIGEST_SIZE) {
@@ -188,13 +220,14 @@ int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag,
 
        /* Try to avoid code bloat when verify is not needed */
 #ifdef CONFIG_HASH_VERIFY
-       if (verify) {
+       if (flags & HASH_FLAG_VERIFY) {
 #else
        if (0) {
 #endif
                if (!argc)
                        return CMD_RET_USAGE;
-               if (parse_verify_sum(algo, *argv, vsum)) {
+               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;
@@ -213,8 +246,10 @@ int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag,
                show_hash(algo, addr, len, output);
                printf("\n");
 
-               if (argc)
-                       store_result(algo, output, *argv);
+               if (argc) {
+                       store_result(algo, output, *argv,
+                               flags & HASH_FLAG_ENV);
+               }
        }
 
        return 0;
index 34ba558..88fa2b5 100644 (file)
@@ -51,19 +51,24 @@ struct hash_algo {
  */
 #define HASH_MAX_DIGEST_SIZE   32
 
+enum {
+       HASH_FLAG_VERIFY        = 1 << 0,       /* Enable verify mode */
+       HASH_FLAG_ENV           = 1 << 1,       /* Allow env vars */
+};
+
 /**
  * hash_command: Process a hash command for a particular algorithm
  *
  * This common function is used to implement specific hash commands.
  *
  * @algo_name:         Hash algorithm being used
- * @verify:            Non-zero to enable verify mode
+ * @flags:             Flags value (HASH_FLAG_...)
  * @cmdtp:             Pointer to command table entry
  * @flag:              Some flags normally 0 (see CMD_FLAG_.. above)
  * @argc:              Number of arguments (arg 0 must be the command text)
  * @argv:              Arguments
  */
-int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag,
+int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
                 int argc, char * const argv[]);
 
 #endif