hash.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /*
  2. * Copyright (c) 2012 The Chromium OS Authors.
  3. *
  4. * (C) Copyright 2011
  5. * Joe Hershberger, National Instruments, joe.hershberger@ni.com
  6. *
  7. * (C) Copyright 2000
  8. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  9. *
  10. * SPDX-License-Identifier: GPL-2.0+
  11. */
  12. #include <common.h>
  13. #include <command.h>
  14. #include <malloc.h>
  15. #include <hw_sha.h>
  16. #include <hash.h>
  17. #include <u-boot/sha1.h>
  18. #include <u-boot/sha256.h>
  19. #include <asm/io.h>
  20. #include <asm/errno.h>
  21. #ifdef CONFIG_SHA1
  22. static int hash_init_sha1(struct hash_algo *algo, void **ctxp)
  23. {
  24. sha1_context *ctx = malloc(sizeof(sha1_context));
  25. sha1_starts(ctx);
  26. *ctxp = ctx;
  27. return 0;
  28. }
  29. static int hash_update_sha1(struct hash_algo *algo, void *ctx, const void *buf,
  30. unsigned int size, int is_last)
  31. {
  32. sha1_update((sha1_context *)ctx, buf, size);
  33. return 0;
  34. }
  35. static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf,
  36. int size)
  37. {
  38. if (size < algo->digest_size)
  39. return -1;
  40. sha1_finish((sha1_context *)ctx, dest_buf);
  41. free(ctx);
  42. return 0;
  43. }
  44. #endif
  45. #ifdef CONFIG_SHA256
  46. static int hash_init_sha256(struct hash_algo *algo, void **ctxp)
  47. {
  48. sha256_context *ctx = malloc(sizeof(sha256_context));
  49. sha256_starts(ctx);
  50. *ctxp = ctx;
  51. return 0;
  52. }
  53. static int hash_update_sha256(struct hash_algo *algo, void *ctx,
  54. const void *buf, unsigned int size, int is_last)
  55. {
  56. sha256_update((sha256_context *)ctx, buf, size);
  57. return 0;
  58. }
  59. static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void
  60. *dest_buf, int size)
  61. {
  62. if (size < algo->digest_size)
  63. return -1;
  64. sha256_finish((sha256_context *)ctx, dest_buf);
  65. free(ctx);
  66. return 0;
  67. }
  68. #endif
  69. static int hash_init_crc32(struct hash_algo *algo, void **ctxp)
  70. {
  71. uint32_t *ctx = malloc(sizeof(uint32_t));
  72. *ctx = 0;
  73. *ctxp = ctx;
  74. return 0;
  75. }
  76. static int hash_update_crc32(struct hash_algo *algo, void *ctx,
  77. const void *buf, unsigned int size, int is_last)
  78. {
  79. *((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), buf, size);
  80. return 0;
  81. }
  82. static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf,
  83. int size)
  84. {
  85. if (size < algo->digest_size)
  86. return -1;
  87. *((uint32_t *)dest_buf) = *((uint32_t *)ctx);
  88. free(ctx);
  89. return 0;
  90. }
  91. /*
  92. * These are the hash algorithms we support. Chips which support accelerated
  93. * crypto could perhaps add named version of these algorithms here. Note that
  94. * algorithm names must be in lower case.
  95. */
  96. static struct hash_algo hash_algo[] = {
  97. /*
  98. * CONFIG_SHA_HW_ACCEL is defined if hardware acceleration is
  99. * available.
  100. */
  101. #ifdef CONFIG_SHA_HW_ACCEL
  102. {
  103. "sha1",
  104. SHA1_SUM_LEN,
  105. hw_sha1,
  106. CHUNKSZ_SHA1,
  107. }, {
  108. "sha256",
  109. SHA256_SUM_LEN,
  110. hw_sha256,
  111. CHUNKSZ_SHA256,
  112. },
  113. #endif
  114. #ifdef CONFIG_SHA1
  115. {
  116. "sha1",
  117. SHA1_SUM_LEN,
  118. sha1_csum_wd,
  119. CHUNKSZ_SHA1,
  120. hash_init_sha1,
  121. hash_update_sha1,
  122. hash_finish_sha1,
  123. },
  124. #endif
  125. #ifdef CONFIG_SHA256
  126. {
  127. "sha256",
  128. SHA256_SUM_LEN,
  129. sha256_csum_wd,
  130. CHUNKSZ_SHA256,
  131. hash_init_sha256,
  132. hash_update_sha256,
  133. hash_finish_sha256,
  134. },
  135. #endif
  136. {
  137. "crc32",
  138. 4,
  139. crc32_wd_buf,
  140. CHUNKSZ_CRC32,
  141. hash_init_crc32,
  142. hash_update_crc32,
  143. hash_finish_crc32,
  144. },
  145. };
  146. #if defined(CONFIG_SHA256) || defined(CONFIG_CMD_SHA1SUM)
  147. #define MULTI_HASH
  148. #endif
  149. #if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_CMD_HASH)
  150. #define MULTI_HASH
  151. #endif
  152. /* Try to minimize code size for boards that don't want much hashing */
  153. #ifdef MULTI_HASH
  154. #define multi_hash() 1
  155. #else
  156. #define multi_hash() 0
  157. #endif
  158. /**
  159. * store_result: Store the resulting sum to an address or variable
  160. *
  161. * @algo: Hash algorithm being used
  162. * @sum: Hash digest (algo->digest_size bytes)
  163. * @dest: Destination, interpreted as a hex address if it starts
  164. * with * (or allow_env_vars is 0) or otherwise as an
  165. * environment variable.
  166. * @allow_env_vars: non-zero to permit storing the result to an
  167. * variable environment
  168. */
  169. static void store_result(struct hash_algo *algo, const uint8_t *sum,
  170. const char *dest, int allow_env_vars)
  171. {
  172. unsigned int i;
  173. int env_var = 0;
  174. /*
  175. * If environment variables are allowed, then we assume that 'dest'
  176. * is an environment variable, unless it starts with *, in which
  177. * case we assume it is an address. If not allowed, it is always an
  178. * address. This is to support the crc32 command.
  179. */
  180. if (allow_env_vars) {
  181. if (*dest == '*')
  182. dest++;
  183. else
  184. env_var = 1;
  185. }
  186. if (env_var) {
  187. char str_output[HASH_MAX_DIGEST_SIZE * 2 + 1];
  188. char *str_ptr = str_output;
  189. for (i = 0; i < algo->digest_size; i++) {
  190. sprintf(str_ptr, "%02x", sum[i]);
  191. str_ptr += 2;
  192. }
  193. *str_ptr = '\0';
  194. setenv(dest, str_output);
  195. } else {
  196. ulong addr;
  197. void *buf;
  198. addr = simple_strtoul(dest, NULL, 16);
  199. buf = map_sysmem(addr, algo->digest_size);
  200. memcpy(buf, sum, algo->digest_size);
  201. unmap_sysmem(buf);
  202. }
  203. }
  204. /**
  205. * parse_verify_sum: Parse a hash verification parameter
  206. *
  207. * @algo: Hash algorithm being used
  208. * @verify_str: Argument to parse. If it starts with * then it is
  209. * interpreted as a hex address containing the hash.
  210. * If the length is exactly the right number of hex digits
  211. * for the digest size, then we assume it is a hex digest.
  212. * Otherwise we assume it is an environment variable, and
  213. * look up its value (it must contain a hex digest).
  214. * @vsum: Returns binary digest value (algo->digest_size bytes)
  215. * @allow_env_vars: non-zero to permit storing the result to an environment
  216. * variable. If 0 then verify_str is assumed to be an
  217. * address, and the * prefix is not expected.
  218. * @return 0 if ok, non-zero on error
  219. */
  220. static int parse_verify_sum(struct hash_algo *algo, char *verify_str,
  221. uint8_t *vsum, int allow_env_vars)
  222. {
  223. int env_var = 0;
  224. /* See comment above in store_result() */
  225. if (allow_env_vars) {
  226. if (*verify_str == '*')
  227. verify_str++;
  228. else
  229. env_var = 1;
  230. }
  231. if (!env_var) {
  232. ulong addr;
  233. void *buf;
  234. addr = simple_strtoul(verify_str, NULL, 16);
  235. buf = map_sysmem(addr, algo->digest_size);
  236. memcpy(vsum, buf, algo->digest_size);
  237. } else {
  238. unsigned int i;
  239. char *vsum_str;
  240. int digits = algo->digest_size * 2;
  241. /*
  242. * As with the original code from sha1sum.c, we assume that a
  243. * string which matches the digest size exactly is a hex
  244. * string and not an environment variable.
  245. */
  246. if (strlen(verify_str) == digits)
  247. vsum_str = verify_str;
  248. else {
  249. vsum_str = getenv(verify_str);
  250. if (vsum_str == NULL || strlen(vsum_str) != digits) {
  251. printf("Expected %d hex digits in env var\n",
  252. digits);
  253. return 1;
  254. }
  255. }
  256. for (i = 0; i < algo->digest_size; i++) {
  257. char *nullp = vsum_str + (i + 1) * 2;
  258. char end = *nullp;
  259. *nullp = '\0';
  260. vsum[i] = simple_strtoul(vsum_str + (i * 2), NULL, 16);
  261. *nullp = end;
  262. }
  263. }
  264. return 0;
  265. }
  266. int hash_lookup_algo(const char *algo_name, struct hash_algo **algop)
  267. {
  268. int i;
  269. for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
  270. if (!strcmp(algo_name, hash_algo[i].name)) {
  271. *algop = &hash_algo[i];
  272. return 0;
  273. }
  274. }
  275. debug("Unknown hash algorithm '%s'\n", algo_name);
  276. return -EPROTONOSUPPORT;
  277. }
  278. int hash_progressive_lookup_algo(const char *algo_name,
  279. struct hash_algo **algop)
  280. {
  281. int i;
  282. for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
  283. if (!strcmp(algo_name, hash_algo[i].name)) {
  284. if (hash_algo[i].hash_init) {
  285. *algop = &hash_algo[i];
  286. return 0;
  287. }
  288. }
  289. }
  290. debug("Unknown hash algorithm '%s'\n", algo_name);
  291. return -EPROTONOSUPPORT;
  292. }
  293. void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output)
  294. {
  295. int i;
  296. printf("%s for %08lx ... %08lx ==> ", algo->name, addr, addr + len - 1);
  297. for (i = 0; i < algo->digest_size; i++)
  298. printf("%02x", output[i]);
  299. }
  300. int hash_block(const char *algo_name, const void *data, unsigned int len,
  301. uint8_t *output, int *output_size)
  302. {
  303. struct hash_algo *algo;
  304. int ret;
  305. ret = hash_lookup_algo(algo_name, &algo);
  306. if (ret)
  307. return ret;
  308. if (output_size && *output_size < algo->digest_size) {
  309. debug("Output buffer size %d too small (need %d bytes)",
  310. *output_size, algo->digest_size);
  311. return -ENOSPC;
  312. }
  313. if (output_size)
  314. *output_size = algo->digest_size;
  315. algo->hash_func_ws(data, len, output, algo->chunk_size);
  316. return 0;
  317. }
  318. int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
  319. int argc, char * const argv[])
  320. {
  321. ulong addr, len;
  322. if ((argc < 2) || ((flags & HASH_FLAG_VERIFY) && (argc < 3)))
  323. return CMD_RET_USAGE;
  324. addr = simple_strtoul(*argv++, NULL, 16);
  325. len = simple_strtoul(*argv++, NULL, 16);
  326. if (multi_hash()) {
  327. struct hash_algo *algo;
  328. uint8_t output[HASH_MAX_DIGEST_SIZE];
  329. uint8_t vsum[HASH_MAX_DIGEST_SIZE];
  330. void *buf;
  331. if (hash_lookup_algo(algo_name, &algo)) {
  332. printf("Unknown hash algorithm '%s'\n", algo_name);
  333. return CMD_RET_USAGE;
  334. }
  335. argc -= 2;
  336. if (algo->digest_size > HASH_MAX_DIGEST_SIZE) {
  337. puts("HASH_MAX_DIGEST_SIZE exceeded\n");
  338. return 1;
  339. }
  340. buf = map_sysmem(addr, len);
  341. algo->hash_func_ws(buf, len, output, algo->chunk_size);
  342. unmap_sysmem(buf);
  343. /* Try to avoid code bloat when verify is not needed */
  344. #ifdef CONFIG_HASH_VERIFY
  345. if (flags & HASH_FLAG_VERIFY) {
  346. #else
  347. if (0) {
  348. #endif
  349. if (parse_verify_sum(algo, *argv, vsum,
  350. flags & HASH_FLAG_ENV)) {
  351. printf("ERROR: %s does not contain a valid "
  352. "%s sum\n", *argv, algo->name);
  353. return 1;
  354. }
  355. if (memcmp(output, vsum, algo->digest_size) != 0) {
  356. int i;
  357. hash_show(algo, addr, len, output);
  358. printf(" != ");
  359. for (i = 0; i < algo->digest_size; i++)
  360. printf("%02x", vsum[i]);
  361. puts(" ** ERROR **\n");
  362. return 1;
  363. }
  364. } else {
  365. hash_show(algo, addr, len, output);
  366. printf("\n");
  367. if (argc) {
  368. store_result(algo, output, *argv,
  369. flags & HASH_FLAG_ENV);
  370. }
  371. }
  372. /* Horrible code size hack for boards that just want crc32 */
  373. } else {
  374. ulong crc;
  375. ulong *ptr;
  376. crc = crc32_wd(0, (const uchar *)addr, len, CHUNKSZ_CRC32);
  377. printf("CRC32 for %08lx ... %08lx ==> %08lx\n",
  378. addr, addr + len - 1, crc);
  379. if (argc >= 3) {
  380. ptr = (ulong *)simple_strtoul(argv[0], NULL, 16);
  381. *ptr = crc;
  382. }
  383. }
  384. return 0;
  385. }