1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2012 The Chromium OS Authors. 4 * 5 * (C) Copyright 2011 6 * Joe Hershberger, National Instruments, joe.hershberger@ni.com 7 * 8 * (C) Copyright 2000 9 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 10 */ 11 12#ifndef USE_HOSTCC 13#include <common.h> 14#include <command.h> 15#include <env.h> 16#include <log.h> 17#include <malloc.h> 18#include <mapmem.h> 19#include <hw_sha.h> 20#include <asm/cache.h> 21#include <asm/global_data.h> 22#include <asm/io.h> 23#include <linux/errno.h> 24#else 25#include "mkimage.h" 26#include <linux/compiler_attributes.h> 27#include <time.h> 28#include <linux/kconfig.h> 29#endif /* !USE_HOSTCC*/ 30 31#include <hash.h> 32#include <image.h> 33#include <u-boot/crc.h> 34#include <u-boot/sha1.h> 35#include <u-boot/sha256.h> 36#include <u-boot/sha512.h> 37#include <u-boot/md5.h> 38 39static int __maybe_unused hash_init_sha1(struct hash_algo *algo, void **ctxp) 40{ 41 sha1_context *ctx = malloc(sizeof(sha1_context)); 42 sha1_starts(ctx); 43 *ctxp = ctx; 44 return 0; 45} 46 47static int __maybe_unused hash_update_sha1(struct hash_algo *algo, void *ctx, 48 const void *buf, unsigned int size, 49 int is_last) 50{ 51 sha1_update((sha1_context *)ctx, buf, size); 52 return 0; 53} 54 55static int __maybe_unused hash_finish_sha1(struct hash_algo *algo, void *ctx, 56 void *dest_buf, int size) 57{ 58 if (size < algo->digest_size) 59 return -1; 60 61 sha1_finish((sha1_context *)ctx, dest_buf); 62 free(ctx); 63 return 0; 64} 65 66static int __maybe_unused hash_init_sha256(struct hash_algo *algo, void **ctxp) 67{ 68 sha256_context *ctx = malloc(sizeof(sha256_context)); 69 sha256_starts(ctx); 70 *ctxp = ctx; 71 return 0; 72} 73 74static int __maybe_unused hash_update_sha256(struct hash_algo *algo, void *ctx, 75 const void *buf, uint size, 76 int is_last) 77{ 78 sha256_update((sha256_context *)ctx, buf, size); 79 return 0; 80} 81 82static int __maybe_unused hash_finish_sha256(struct hash_algo *algo, void *ctx, 83 void *dest_buf, int size) 84{ 85 if (size < algo->digest_size) 86 return -1; 87 88 sha256_finish((sha256_context *)ctx, dest_buf); 89 free(ctx); 90 return 0; 91} 92 93static int __maybe_unused hash_init_sha384(struct hash_algo *algo, void **ctxp) 94{ 95 sha512_context *ctx = malloc(sizeof(sha512_context)); 96 sha384_starts(ctx); 97 *ctxp = ctx; 98 return 0; 99} 100 101static int __maybe_unused hash_update_sha384(struct hash_algo *algo, void *ctx, 102 const void *buf, uint size, 103 int is_last) 104{ 105 sha384_update((sha512_context *)ctx, buf, size); 106 return 0; 107} 108 109static int __maybe_unused hash_finish_sha384(struct hash_algo *algo, void *ctx, 110 void *dest_buf, int size) 111{ 112 if (size < algo->digest_size) 113 return -1; 114 115 sha384_finish((sha512_context *)ctx, dest_buf); 116 free(ctx); 117 return 0; 118} 119 120static int __maybe_unused hash_init_sha512(struct hash_algo *algo, void **ctxp) 121{ 122 sha512_context *ctx = malloc(sizeof(sha512_context)); 123 sha512_starts(ctx); 124 *ctxp = ctx; 125 return 0; 126} 127 128static int __maybe_unused hash_update_sha512(struct hash_algo *algo, void *ctx, 129 const void *buf, uint size, 130 int is_last) 131{ 132 sha512_update((sha512_context *)ctx, buf, size); 133 return 0; 134} 135 136static int __maybe_unused hash_finish_sha512(struct hash_algo *algo, void *ctx, 137 void *dest_buf, int size) 138{ 139 if (size < algo->digest_size) 140 return -1; 141 142 sha512_finish((sha512_context *)ctx, dest_buf); 143 free(ctx); 144 return 0; 145} 146 147static int hash_init_crc16_ccitt(struct hash_algo *algo, void **ctxp) 148{ 149 uint16_t *ctx = malloc(sizeof(uint16_t)); 150 *ctx = 0; 151 *ctxp = ctx; 152 return 0; 153} 154 155static int hash_update_crc16_ccitt(struct hash_algo *algo, void *ctx, 156 const void *buf, unsigned int size, 157 int is_last) 158{ 159 *((uint16_t *)ctx) = crc16_ccitt(*((uint16_t *)ctx), buf, size); 160 return 0; 161} 162 163static int hash_finish_crc16_ccitt(struct hash_algo *algo, void *ctx, 164 void *dest_buf, int size) 165{ 166 if (size < algo->digest_size) 167 return -1; 168 169 *((uint16_t *)dest_buf) = *((uint16_t *)ctx); 170 free(ctx); 171 return 0; 172} 173 174static int __maybe_unused hash_init_crc32(struct hash_algo *algo, void **ctxp) 175{ 176 uint32_t *ctx = malloc(sizeof(uint32_t)); 177 *ctx = 0; 178 *ctxp = ctx; 179 return 0; 180} 181 182static int __maybe_unused hash_update_crc32(struct hash_algo *algo, void *ctx, 183 const void *buf, unsigned int size, 184 int is_last) 185{ 186 *((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), buf, size); 187 return 0; 188} 189 190static int __maybe_unused hash_finish_crc32(struct hash_algo *algo, void *ctx, 191 void *dest_buf, int size) 192{ 193 if (size < algo->digest_size) 194 return -1; 195 196 *((uint32_t *)dest_buf) = *((uint32_t *)ctx); 197 free(ctx); 198 return 0; 199} 200 201/* 202 * These are the hash algorithms we support. If we have hardware acceleration 203 * is enable we will use that, otherwise a software version of the algorithm. 204 * Note that algorithm names must be in lower case. 205 */ 206static struct hash_algo hash_algo[] = { 207#if CONFIG_IS_ENABLED(MD5) 208 { 209 .name = "md5", 210 .digest_size = MD5_SUM_LEN, 211 .chunk_size = CHUNKSZ_MD5, 212 .hash_func_ws = md5_wd, 213 }, 214#endif 215#if CONFIG_IS_ENABLED(SHA1) 216 { 217 .name = "sha1", 218 .digest_size = SHA1_SUM_LEN, 219 .chunk_size = CHUNKSZ_SHA1, 220#if CONFIG_IS_ENABLED(SHA_HW_ACCEL) 221 .hash_func_ws = hw_sha1, 222#else 223 .hash_func_ws = sha1_csum_wd, 224#endif 225#if CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) 226 .hash_init = hw_sha_init, 227 .hash_update = hw_sha_update, 228 .hash_finish = hw_sha_finish, 229#else 230 .hash_init = hash_init_sha1, 231 .hash_update = hash_update_sha1, 232 .hash_finish = hash_finish_sha1, 233#endif 234 }, 235#endif 236#if CONFIG_IS_ENABLED(SHA256) 237 { 238 .name = "sha256", 239 .digest_size = SHA256_SUM_LEN, 240 .chunk_size = CHUNKSZ_SHA256, 241#if CONFIG_IS_ENABLED(SHA_HW_ACCEL) 242 .hash_func_ws = hw_sha256, 243#else 244 .hash_func_ws = sha256_csum_wd, 245#endif 246#if CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) 247 .hash_init = hw_sha_init, 248 .hash_update = hw_sha_update, 249 .hash_finish = hw_sha_finish, 250#else 251 .hash_init = hash_init_sha256, 252 .hash_update = hash_update_sha256, 253 .hash_finish = hash_finish_sha256, 254#endif 255 }, 256#endif 257#if CONFIG_IS_ENABLED(SHA384) 258 { 259 .name = "sha384", 260 .digest_size = SHA384_SUM_LEN, 261 .chunk_size = CHUNKSZ_SHA384, 262#if CONFIG_IS_ENABLED(SHA512_HW_ACCEL) 263 .hash_func_ws = hw_sha384, 264#else 265 .hash_func_ws = sha384_csum_wd, 266#endif 267#if CONFIG_IS_ENABLED(SHA512_HW_ACCEL) && CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) 268 .hash_init = hw_sha_init, 269 .hash_update = hw_sha_update, 270 .hash_finish = hw_sha_finish, 271#else 272 .hash_init = hash_init_sha384, 273 .hash_update = hash_update_sha384, 274 .hash_finish = hash_finish_sha384, 275#endif 276 }, 277#endif 278#if CONFIG_IS_ENABLED(SHA512) 279 { 280 .name = "sha512", 281 .digest_size = SHA512_SUM_LEN, 282 .chunk_size = CHUNKSZ_SHA512, 283#if CONFIG_IS_ENABLED(SHA512_HW_ACCEL) 284 .hash_func_ws = hw_sha512, 285#else 286 .hash_func_ws = sha512_csum_wd, 287#endif 288#if CONFIG_IS_ENABLED(SHA512_HW_ACCEL) && CONFIG_IS_ENABLED(SHA_PROG_HW_ACCEL) 289 .hash_init = hw_sha_init, 290 .hash_update = hw_sha_update, 291 .hash_finish = hw_sha_finish, 292#else 293 .hash_init = hash_init_sha512, 294 .hash_update = hash_update_sha512, 295 .hash_finish = hash_finish_sha512, 296#endif 297 }, 298#endif 299 { 300 .name = "crc16-ccitt", 301 .digest_size = 2, 302 .chunk_size = CHUNKSZ, 303 .hash_func_ws = crc16_ccitt_wd_buf, 304 .hash_init = hash_init_crc16_ccitt, 305 .hash_update = hash_update_crc16_ccitt, 306 .hash_finish = hash_finish_crc16_ccitt, 307 }, 308#if CONFIG_IS_ENABLED(CRC32) 309 { 310 .name = "crc32", 311 .digest_size = 4, 312 .chunk_size = CHUNKSZ_CRC32, 313 .hash_func_ws = crc32_wd_buf, 314 .hash_init = hash_init_crc32, 315 .hash_update = hash_update_crc32, 316 .hash_finish = hash_finish_crc32, 317 }, 318#endif 319}; 320 321/* Try to minimize code size for boards that don't want much hashing */ 322#if CONFIG_IS_ENABLED(SHA256) || IS_ENABLED(CONFIG_CMD_SHA1SUM) || \ 323 CONFIG_IS_ENABLED(CRC32_VERIFY) || IS_ENABLED(CONFIG_CMD_HASH) || \ 324 CONFIG_IS_ENABLED(SHA384) || CONFIG_IS_ENABLED(SHA512) || \ 325 IS_ENABLED(CONFIG_CMD_MD5SUM) 326#define multi_hash() 1 327#else 328#define multi_hash() 0 329#endif 330 331int hash_lookup_algo(const char *algo_name, struct hash_algo **algop) 332{ 333 int i; 334 335 for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { 336 if (!strcmp(algo_name, hash_algo[i].name)) { 337 *algop = &hash_algo[i]; 338 return 0; 339 } 340 } 341 342 debug("Unknown hash algorithm '%s'\n", algo_name); 343 return -EPROTONOSUPPORT; 344} 345 346int hash_progressive_lookup_algo(const char *algo_name, 347 struct hash_algo **algop) 348{ 349 int i; 350 351 for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { 352 if (!strcmp(algo_name, hash_algo[i].name)) { 353 if (hash_algo[i].hash_init) { 354 *algop = &hash_algo[i]; 355 return 0; 356 } 357 } 358 } 359 360 debug("Unknown hash algorithm '%s'\n", algo_name); 361 return -EPROTONOSUPPORT; 362} 363 364#ifndef USE_HOSTCC 365int hash_parse_string(const char *algo_name, const char *str, uint8_t *result) 366{ 367 struct hash_algo *algo; 368 int ret; 369 int i; 370 371 ret = hash_lookup_algo(algo_name, &algo); 372 if (ret) 373 return ret; 374 375 for (i = 0; i < algo->digest_size; i++) { 376 char chr[3]; 377 378 strlcpy(chr, &str[i * 2], 3); 379 result[i] = hextoul(chr, NULL); 380 } 381 382 return 0; 383} 384 385int hash_block(const char *algo_name, const void *data, unsigned int len, 386 uint8_t *output, int *output_size) 387{ 388 struct hash_algo *algo; 389 int ret; 390 391 ret = hash_lookup_algo(algo_name, &algo); 392 if (ret) 393 return ret; 394 395 if (output_size && *output_size < algo->digest_size) { 396 debug("Output buffer size %d too small (need %d bytes)", 397 *output_size, algo->digest_size); 398 return -ENOSPC; 399 } 400 if (output_size) 401 *output_size = algo->digest_size; 402 algo->hash_func_ws(data, len, output, algo->chunk_size); 403 404 return 0; 405} 406 407#if !defined(CONFIG_SPL_BUILD) && (defined(CONFIG_CMD_HASH) || \ 408 defined(CONFIG_CMD_SHA1SUM) || defined(CONFIG_CMD_CRC32)) || \ 409 defined(CONFIG_CMD_MD5SUM) 410/** 411 * store_result: Store the resulting sum to an address or variable 412 * 413 * @algo: Hash algorithm being used 414 * @sum: Hash digest (algo->digest_size bytes) 415 * @dest: Destination, interpreted as a hex address if it starts 416 * with * (or allow_env_vars is 0) or otherwise as an 417 * environment variable. 418 * @allow_env_vars: non-zero to permit storing the result to an 419 * variable environment 420 */ 421static void store_result(struct hash_algo *algo, const uint8_t *sum, 422 const char *dest, int allow_env_vars) 423{ 424 unsigned int i; 425 int env_var = 0; 426 427 /* 428 * If environment variables are allowed, then we assume that 'dest' 429 * is an environment variable, unless it starts with *, in which 430 * case we assume it is an address. If not allowed, it is always an 431 * address. This is to support the crc32 command. 432 */ 433 if (allow_env_vars) { 434 if (*dest == '*') 435 dest++; 436 else 437 env_var = 1; 438 } 439 440 if (env_var) { 441 char str_output[HASH_MAX_DIGEST_SIZE * 2 + 1]; 442 char *str_ptr = str_output; 443 444 for (i = 0; i < algo->digest_size; i++) { 445 sprintf(str_ptr, "%02x", sum[i]); 446 str_ptr += 2; 447 } 448 *str_ptr = '\0'; 449 env_set(dest, str_output); 450 } else { 451 ulong addr; 452 void *buf; 453 454 addr = hextoul(dest, NULL); 455 buf = map_sysmem(addr, algo->digest_size); 456 memcpy(buf, sum, algo->digest_size); 457 unmap_sysmem(buf); 458 } 459} 460 461/** 462 * parse_verify_sum: Parse a hash verification parameter 463 * 464 * @algo: Hash algorithm being used 465 * @verify_str: Argument to parse. If it starts with * then it is 466 * interpreted as a hex address containing the hash. 467 * If the length is exactly the right number of hex digits 468 * for the digest size, then we assume it is a hex digest. 469 * Otherwise we assume it is an environment variable, and 470 * look up its value (it must contain a hex digest). 471 * @vsum: Returns binary digest value (algo->digest_size bytes) 472 * @allow_env_vars: non-zero to permit storing the result to an environment 473 * variable. If 0 then verify_str is assumed to be an 474 * address, and the * prefix is not expected. 475 * Return: 0 if ok, non-zero on error 476 */ 477static int parse_verify_sum(struct hash_algo *algo, char *verify_str, 478 uint8_t *vsum, int allow_env_vars) 479{ 480 int env_var = 0; 481 482 /* See comment above in store_result() */ 483 if (allow_env_vars) { 484 if (*verify_str == '*') 485 verify_str++; 486 else 487 env_var = 1; 488 } 489 490 if (!env_var) { 491 ulong addr; 492 void *buf; 493 494 addr = hextoul(verify_str, NULL); 495 buf = map_sysmem(addr, algo->digest_size); 496 memcpy(vsum, buf, algo->digest_size); 497 } else { 498 char *vsum_str; 499 int digits = algo->digest_size * 2; 500 501 /* 502 * As with the original code from sha1sum.c, we assume that a 503 * string which matches the digest size exactly is a hex 504 * string and not an environment variable. 505 */ 506 if (strlen(verify_str) == digits) 507 vsum_str = verify_str; 508 else { 509 vsum_str = env_get(verify_str); 510 if (vsum_str == NULL || strlen(vsum_str) != digits) { 511 printf("Expected %d hex digits in env var\n", 512 digits); 513 return 1; 514 } 515 } 516 517 hash_parse_string(algo->name, vsum_str, vsum); 518 } 519 return 0; 520} 521 522static void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output) 523{ 524 int i; 525 526 printf("%s for %08lx ... %08lx ==> ", algo->name, addr, addr + len - 1); 527 for (i = 0; i < algo->digest_size; i++) 528 printf("%02x", output[i]); 529} 530 531int hash_command(const char *algo_name, int flags, struct cmd_tbl *cmdtp, 532 int flag, int argc, char *const argv[]) 533{ 534 ulong addr, len; 535 536 if ((argc < 2) || ((flags & HASH_FLAG_VERIFY) && (argc < 3))) 537 return CMD_RET_USAGE; 538 539 addr = hextoul(*argv++, NULL); 540 len = hextoul(*argv++, NULL); 541 542 if (multi_hash()) { 543 struct hash_algo *algo; 544 u8 *output; 545 uint8_t vsum[HASH_MAX_DIGEST_SIZE]; 546 void *buf; 547 548 if (hash_lookup_algo(algo_name, &algo)) { 549 printf("Unknown hash algorithm '%s'\n", algo_name); 550 return CMD_RET_USAGE; 551 } 552 argc -= 2; 553 554 if (algo->digest_size > HASH_MAX_DIGEST_SIZE) { 555 puts("HASH_MAX_DIGEST_SIZE exceeded\n"); 556 return 1; 557 } 558 559 output = memalign(ARCH_DMA_MINALIGN, 560 sizeof(uint32_t) * HASH_MAX_DIGEST_SIZE); 561 if (!output) 562 return CMD_RET_FAILURE; 563 564 buf = map_sysmem(addr, len); 565 algo->hash_func_ws(buf, len, output, algo->chunk_size); 566 unmap_sysmem(buf); 567 568 /* Try to avoid code bloat when verify is not needed */ 569#if defined(CONFIG_CRC32_VERIFY) || defined(CONFIG_SHA1SUM_VERIFY) || \ 570 defined(CONFIG_MD5SUM_VERIFY) || defined(CONFIG_HASH_VERIFY) 571 if (flags & HASH_FLAG_VERIFY) { 572#else 573 if (0) { 574#endif 575 if (parse_verify_sum(algo, *argv, vsum, 576 flags & HASH_FLAG_ENV)) { 577 printf("ERROR: %s does not contain a valid " 578 "%s sum\n", *argv, algo->name); 579 free(output); 580 return 1; 581 } 582 if (memcmp(output, vsum, algo->digest_size) != 0) { 583 int i; 584 585 hash_show(algo, addr, len, output); 586 printf(" != "); 587 for (i = 0; i < algo->digest_size; i++) 588 printf("%02x", vsum[i]); 589 puts(" ** ERROR **\n"); 590 free(output); 591 return 1; 592 } 593 } else { 594 hash_show(algo, addr, len, output); 595 printf("\n"); 596 597 if (argc) { 598 store_result(algo, output, *argv, 599 flags & HASH_FLAG_ENV); 600 } 601 } 602 603 free(output); 604 605 /* Horrible code size hack for boards that just want crc32 */ 606 } else { 607 ulong crc; 608 ulong *ptr; 609 610 crc = crc32_wd(0, (const uchar *)addr, len, CHUNKSZ_CRC32); 611 612 printf("CRC32 for %08lx ... %08lx ==> %08lx\n", 613 addr, addr + len - 1, crc); 614 615 if (argc >= 3) { 616 ptr = (ulong *)hextoul(argv[0], NULL); 617 *ptr = crc; 618 } 619 } 620 621 return 0; 622} 623#endif /* CONFIG_CMD_HASH || CONFIG_CMD_SHA1SUM || CONFIG_CMD_CRC32) */ 624#endif /* !USE_HOSTCC */ 625