Commit bf007ebb6f4b01af675782d23bacbddd17e1a627

Authored by Hung-ying Tyan
Committed by Tom Rini
1 parent db1b5f3d20

gen: Add progressive hash API

Add hash_init(), hash_update() and hash_finish() to the
hash_algo struct. Add hash_lookup_algo() to look up the
struct given an algorithm name.

Signed-off-by: Hung-ying Tyan <tyanh@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heiko Schocher <hs@denx.de>
Acked-by: Simon Glass <sjg@chromium.org>

Showing 2 changed files with 153 additions and 11 deletions Side-by-side Diff

... ... @@ -12,6 +12,7 @@
12 12  
13 13 #include <common.h>
14 14 #include <command.h>
  15 +#include <malloc.h>
15 16 #include <hw_sha.h>
16 17 #include <hash.h>
17 18 #include <sha1.h>
... ... @@ -19,6 +20,88 @@
19 20 #include <asm/io.h>
20 21 #include <asm/errno.h>
21 22  
  23 +#ifdef CONFIG_CMD_SHA1SUM
  24 +static int hash_init_sha1(struct hash_algo *algo, void **ctxp)
  25 +{
  26 + sha1_context *ctx = malloc(sizeof(sha1_context));
  27 + sha1_starts(ctx);
  28 + *ctxp = ctx;
  29 + return 0;
  30 +}
  31 +
  32 +static int hash_update_sha1(struct hash_algo *algo, void *ctx, const void *buf,
  33 + unsigned int size, int is_last)
  34 +{
  35 + sha1_update((sha1_context *)ctx, buf, size);
  36 + return 0;
  37 +}
  38 +
  39 +static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf,
  40 + int size)
  41 +{
  42 + if (size < algo->digest_size)
  43 + return -1;
  44 +
  45 + sha1_finish((sha1_context *)ctx, dest_buf);
  46 + free(ctx);
  47 + return 0;
  48 +}
  49 +#endif
  50 +
  51 +#ifdef CONFIG_SHA256
  52 +static int hash_init_sha256(struct hash_algo *algo, void **ctxp)
  53 +{
  54 + sha256_context *ctx = malloc(sizeof(sha256_context));
  55 + sha256_starts(ctx);
  56 + *ctxp = ctx;
  57 + return 0;
  58 +}
  59 +
  60 +static int hash_update_sha256(struct hash_algo *algo, void *ctx,
  61 + const void *buf, unsigned int size, int is_last)
  62 +{
  63 + sha256_update((sha256_context *)ctx, buf, size);
  64 + return 0;
  65 +}
  66 +
  67 +static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void
  68 + *dest_buf, int size)
  69 +{
  70 + if (size < algo->digest_size)
  71 + return -1;
  72 +
  73 + sha256_finish((sha256_context *)ctx, dest_buf);
  74 + free(ctx);
  75 + return 0;
  76 +}
  77 +#endif
  78 +
  79 +static int hash_init_crc32(struct hash_algo *algo, void **ctxp)
  80 +{
  81 + uint32_t *ctx = malloc(sizeof(uint32_t));
  82 + *ctx = 0;
  83 + *ctxp = ctx;
  84 + return 0;
  85 +}
  86 +
  87 +static int hash_update_crc32(struct hash_algo *algo, void *ctx,
  88 + const void *buf, unsigned int size, int is_last)
  89 +{
  90 + *((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), buf, size);
  91 + return 0;
  92 +}
  93 +
  94 +static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf,
  95 + int size)
  96 +{
  97 + if (size < algo->digest_size)
  98 + return -1;
  99 +
  100 + *((uint32_t *)dest_buf) = *((uint32_t *)ctx);
  101 + free(ctx);
  102 + return 0;
  103 +}
  104 +
22 105 /*
23 106 * These are the hash algorithms we support. Chips which support accelerated
24 107 * crypto could perhaps add named version of these algorithms here. Note that
... ... @@ -53,6 +136,9 @@
53 136 SHA1_SUM_LEN,
54 137 sha1_csum_wd,
55 138 CHUNKSZ_SHA1,
  139 + hash_init_sha1,
  140 + hash_update_sha1,
  141 + hash_finish_sha1,
56 142 },
57 143 #define MULTI_HASH
58 144 #endif
... ... @@ -62,6 +148,9 @@
62 148 SHA256_SUM_LEN,
63 149 sha256_csum_wd,
64 150 CHUNKSZ_SHA256,
  151 + hash_init_sha256,
  152 + hash_update_sha256,
  153 + hash_finish_sha256,
65 154 },
66 155 #define MULTI_HASH
67 156 #endif
... ... @@ -70,6 +159,9 @@
70 159 4,
71 160 crc32_wd_buf,
72 161 CHUNKSZ_CRC32,
  162 + hash_init_crc32,
  163 + hash_update_crc32,
  164 + hash_finish_crc32,
73 165 },
74 166 };
75 167  
76 168  
77 169  
... ... @@ -204,16 +296,19 @@
204 296 return 0;
205 297 }
206 298  
207   -static struct hash_algo *find_hash_algo(const char *name)
  299 +int hash_lookup_algo(const char *algo_name, struct hash_algo **algop)
208 300 {
209 301 int i;
210 302  
211 303 for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
212   - if (!strcmp(name, hash_algo[i].name))
213   - return &hash_algo[i];
  304 + if (!strcmp(algo_name, hash_algo[i].name)) {
  305 + *algop = &hash_algo[i];
  306 + return 0;
  307 + }
214 308 }
215 309  
216   - return NULL;
  310 + debug("Unknown hash algorithm '%s'\n", algo_name);
  311 + return -EPROTONOSUPPORT;
217 312 }
218 313  
219 314 static void show_hash(struct hash_algo *algo, ulong addr, ulong len,
220 315  
... ... @@ -230,12 +325,12 @@
230 325 uint8_t *output, int *output_size)
231 326 {
232 327 struct hash_algo *algo;
  328 + int ret;
233 329  
234   - algo = find_hash_algo(algo_name);
235   - if (!algo) {
236   - debug("Unknown hash algorithm '%s'\n", algo_name);
237   - return -EPROTONOSUPPORT;
238   - }
  330 + ret = hash_lookup_algo(algo_name, &algo);
  331 + if (ret)
  332 + return ret;
  333 +
239 334 if (output_size && *output_size < algo->digest_size) {
240 335 debug("Output buffer size %d too small (need %d bytes)",
241 336 *output_size, algo->digest_size);
... ... @@ -265,8 +360,7 @@
265 360 u8 vsum[HASH_MAX_DIGEST_SIZE];
266 361 void *buf;
267 362  
268   - algo = find_hash_algo(algo_name);
269   - if (!algo) {
  363 + if (hash_lookup_algo(algo_name, &algo)) {
270 364 printf("Unknown hash algorithm '%s'\n", algo_name);
271 365 return CMD_RET_USAGE;
272 366 }
... ... @@ -27,6 +27,42 @@
27 27 void (*hash_func_ws)(const unsigned char *input, unsigned int ilen,
28 28 unsigned char *output, unsigned int chunk_sz);
29 29 int chunk_size; /* Watchdog chunk size */
  30 + /*
  31 + * hash_init: Create the context for progressive hashing
  32 + *
  33 + * @algo: Pointer to the hash_algo struct
  34 + * @ctxp: Pointer to the pointer of the context for hashing
  35 + * @return 0 if ok, -1 on error
  36 + */
  37 + int (*hash_init)(struct hash_algo *algo, void **ctxp);
  38 + /*
  39 + * hash_update: Perform hashing on the given buffer
  40 + *
  41 + * The context is freed by this function if an error occurs.
  42 + *
  43 + * @algo: Pointer to the hash_algo struct
  44 + * @ctx: Pointer to the context for hashing
  45 + * @buf: Pointer to the buffer being hashed
  46 + * @size: Size of the buffer being hashed
  47 + * @is_last: 1 if this is the last update; 0 otherwise
  48 + * @return 0 if ok, -1 on error
  49 + */
  50 + int (*hash_update)(struct hash_algo *algo, void *ctx, const void *buf,
  51 + unsigned int size, int is_last);
  52 + /*
  53 + * hash_finish: Write the hash result to the given buffer
  54 + *
  55 + * The context is freed by this function.
  56 + *
  57 + * @algo: Pointer to the hash_algo struct
  58 + * @ctx: Pointer to the context for hashing
  59 + * @dest_buf: Pointer to the buffer for the result
  60 + * @size: Size of the buffer for the result
  61 + * @return 0 if ok, -ENOSPC if size of the result buffer is too small
  62 + * or -1 on other errors
  63 + */
  64 + int (*hash_finish)(struct hash_algo *algo, void *ctx, void *dest_buf,
  65 + int size);
30 66 };
31 67  
32 68 /*
... ... @@ -77,5 +113,17 @@
77 113 int hash_block(const char *algo_name, const void *data, unsigned int len,
78 114 uint8_t *output, int *output_size);
79 115  
  116 +/**
  117 + * hash_lookup_algo() - Look up the hash_algo struct for an algorithm
  118 + *
  119 + * The function returns the pointer to the struct or -EPROTONOSUPPORT if the
  120 + * algorithm is not available.
  121 + *
  122 + * @algo_name: Hash algorithm to look up
  123 + * @algop: Pointer to the hash_algo struct if found
  124 + *
  125 + * @return 0 if ok, -EPROTONOSUPPORT for an unknown algorithm.
  126 + */
  127 +int hash_lookup_algo(const char *algo_name, struct hash_algo **algop);
80 128 #endif