/** * calculate_hash - calculate and return hash for provided input data * @data: pointer to the input data * @data_len: data length * @algo: requested hash algorithm * @value: pointer to the char, will hold hash value data (caller must * allocate enough free space) * value_len: length of the calculated hash * * calculate_hash() computes input data hash according to the requested * algorithm. * Resulting hash value is placed in caller provided 'value' buffer, length * of the calculated hash is returned via value_len pointer argument. * * returns: * 0, on success * -1, when algo is unsupported */ int calculate_hash(const void *data, int data_len, const char *algo, uint8_t *value, int *value_len) { if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) { *((uint32_t *)value) = crc32_wd(0, data, data_len, CHUNKSZ_CRC32); *((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value)); *value_len = 4; } else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) { sha1_csum_wd((unsigned char *)data, data_len, (unsigned char *)value, CHUNKSZ_SHA1); *value_len = 20; } else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) { sha256_csum_wd((unsigned char *)data, data_len, (unsigned char *)value, CHUNKSZ_SHA256); *value_len = SHA256_SUM_LEN; } else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) { md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5); *value_len = 16; } else { debug("Unsupported hash alogrithm\n"); return -1; } return 0; }
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; }
int image_check_dcrc(const image_header_t *hdr) { ulong data = image_get_data(hdr); ulong len = image_get_data_size(hdr); ulong dcrc = crc32_wd(0, (unsigned char *)data, len, CHUNKSZ_CRC32); return (dcrc == image_get_dcrc(hdr)); }
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 ac; char * const *av; if (argc < 3) { usage: return CMD_RET_USAGE; } av = argv + 1; ac = argc - 1; if (strcmp(*av, "-v") == 0) { verify = 1; 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; } } return 0; }
int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong addr, len; if (argc < 2) return CMD_RET_USAGE; addr = simple_strtoul(*argv++, NULL, 16); len = simple_strtoul(*argv++, NULL, 16); if (multi_hash()) { struct hash_algo *algo; u8 output[HASH_MAX_DIGEST_SIZE]; u8 vsum[HASH_MAX_DIGEST_SIZE]; void *buf; if (hash_lookup_algo(algo_name, &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; } buf = map_sysmem(addr, len); algo->hash_func_ws(buf, len, output, algo->chunk_size); unmap_sysmem(buf); /* Try to avoid code bloat when verify is not needed */ #ifdef CONFIG_HASH_VERIFY if (flags & HASH_FLAG_VERIFY) { #else if (0) { #endif 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; 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("\n"); if (argc) { store_result(algo, output, *argv, flags & HASH_FLAG_ENV); } } /* Horrible code size hack for boards that just want crc32 */ } else { 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 >= 3) { ptr = (ulong *)simple_strtoul(argv[0], NULL, 16); *ptr = crc; } } return 0; }
__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { typedef void __noreturn (*image_entry_noargs_t)(u32 *); image_entry_noargs_t image_entry = (image_entry_noargs_t) spl_image->entry_point; #ifdef CONFIG_HW_WATCHDOG WATCHDOG_RESET(); #endif #ifdef CONFIG_SPL_CHECKSUM_NEXT_IMAGE u32 calculated_crc; if (spl_image->crc_size != 0) { #if defined(CONFIG_SPL_SDRAM_ECC_PADDING) && !defined(CONFIG_SPL_SPI_XIP) /* * do additional memory initialization / padding to avoid * the false double bit error (DBE) during read back * (for checksum purpose) when ECC is enabled */ debug("Padding the SDRAM to avoid false ECC DBE\n"); memset((unsigned char *) (spl_image->entry_point + spl_image->crc_size), 0, CONFIG_SPL_SDRAM_ECC_PADDING); #endif debug("Verifying Checksum ... "); calculated_crc = crc32_wd(0, (unsigned char *)spl_image->entry_point, spl_image->crc_size, CHUNKSZ_CRC32); if (calculated_crc != spl_image->crc) { puts("Bad image with mismatched CRC\n"); debug("CRC calculate from 0x%08x " "with length 0x%08x\n", spl_image->entry_point, spl_image->size); debug("CRC Result : Expected 0x%08x " "Calculated 0x%08x\n", spl_image->crc, calculated_crc); hang(); } else debug("OK\n"); } #endif #if (CONFIG_PRELOADER_SDRAM_SCRUB_REMAIN_REGION == 1) /* Ensure scrubbing finished before hand over to next stage */ sdram_scrub_remain_region_finish(); #endif /* CONFIG_PRELOADER_SDRAM_SCRUB_REMAIN_REGION */ debug("image entry point: 0x%X\n", spl_image->entry_point); /* Pass the saved boot_params from rom code */ #if defined(CONFIG_VIRTIO) || defined(CONFIG_ZEBU) image_entry = (image_entry_noargs_t)0x80100000; #endif #if defined(CONFIG_SOCFPGA) && (CONFIG_PRELOADER_STATE_REG_ENABLE == 1) /* to indicate a successful run */ writel(CONFIG_PRELOADER_STATE_VALID, CONFIG_PRELOADER_STATE_REG); #endif #ifdef CONFIG_HW_WATCHDOG WATCHDOG_RESET(); #endif image_entry((u32 *)boot_params_ptr); }