X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fhash.c;h=ff4986a6190269ed4659685fd9cb77d8c423fae2;hb=515f613253cf0a892c3a321770ab927fa3d925cf;hp=771d8fa87f9424521ce0b5d3ceb465f079404ea8;hpb=1b87f9538f28566a4f718532f9c6a2a19842dbde;p=oweals%2Fu-boot.git diff --git a/common/hash.c b/common/hash.c index 771d8fa87f..ff4986a619 100644 --- a/common/hash.c +++ b/common/hash.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2012 The Chromium OS Authors. * @@ -6,18 +7,18 @@ * * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ */ #ifndef USE_HOSTCC #include #include +#include #include #include #include #include #include +#include #else #include "mkimage.h" #include @@ -30,7 +31,13 @@ #include #include -#ifdef CONFIG_SHA1 +#if !defined(USE_HOSTCC) && defined(CONFIG_NEEDS_MANUAL_RELOC) +DECLARE_GLOBAL_DATA_PTR; +#endif + +static void reloc_update(void); + +#if defined(CONFIG_SHA1) && !defined(CONFIG_SHA_PROG_HW_ACCEL) static int hash_init_sha1(struct hash_algo *algo, void **ctxp) { sha1_context *ctx = malloc(sizeof(sha1_context)); @@ -58,7 +65,7 @@ static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf, } #endif -#ifdef CONFIG_SHA256 +#if defined(CONFIG_SHA256) && !defined(CONFIG_SHA_PROG_HW_ACCEL) static int hash_init_sha256(struct hash_algo *algo, void **ctxp) { sha256_context *ctx = malloc(sizeof(sha256_context)); @@ -86,6 +93,33 @@ static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void } #endif +static int hash_init_crc16_ccitt(struct hash_algo *algo, void **ctxp) +{ + uint16_t *ctx = malloc(sizeof(uint16_t)); + *ctx = 0; + *ctxp = ctx; + return 0; +} + +static int hash_update_crc16_ccitt(struct hash_algo *algo, void *ctx, + const void *buf, unsigned int size, + int is_last) +{ + *((uint16_t *)ctx) = crc16_ccitt(*((uint16_t *)ctx), buf, size); + return 0; +} + +static int hash_finish_crc16_ccitt(struct hash_algo *algo, void *ctx, + void *dest_buf, int size) +{ + if (size < algo->digest_size) + return -1; + + *((uint16_t *)dest_buf) = *((uint16_t *)ctx); + free(ctx); + return 0; +} + static int hash_init_crc32(struct hash_algo *algo, void **ctxp) { uint32_t *ctx = malloc(sizeof(uint32_t)); @@ -113,68 +147,70 @@ static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf, } /* - * These are the hash algorithms we support. Chips which support accelerated - * crypto could perhaps add named version of these algorithms here. Note that - * algorithm names must be in lower case. + * These are the hash algorithms we support. If we have hardware acceleration + * is enable we will use that, otherwise a software version of the algorithm. + * Note that algorithm names must be in lower case. */ static struct hash_algo hash_algo[] = { - /* - * CONFIG_SHA_HW_ACCEL is defined if hardware acceleration is - * available. - */ -#ifdef CONFIG_SHA_HW_ACCEL +#ifdef CONFIG_SHA1 { - "sha1", - SHA1_SUM_LEN, - hw_sha1, - CHUNKSZ_SHA1, -#ifdef CONFIG_SHA_PROG_HW_ACCEL - hw_sha_init, - hw_sha_update, - hw_sha_finish, + .name = "sha1", + .digest_size = SHA1_SUM_LEN, + .chunk_size = CHUNKSZ_SHA1, +#ifdef CONFIG_SHA_HW_ACCEL + .hash_func_ws = hw_sha1, +#else + .hash_func_ws = sha1_csum_wd, #endif - }, { - "sha256", - SHA256_SUM_LEN, - hw_sha256, - CHUNKSZ_SHA256, #ifdef CONFIG_SHA_PROG_HW_ACCEL - hw_sha_init, - hw_sha_update, - hw_sha_finish, + .hash_init = hw_sha_init, + .hash_update = hw_sha_update, + .hash_finish = hw_sha_finish, +#else + .hash_init = hash_init_sha1, + .hash_update = hash_update_sha1, + .hash_finish = hash_finish_sha1, #endif }, #endif -#ifdef CONFIG_SHA1 +#ifdef CONFIG_SHA256 { - "sha1", - SHA1_SUM_LEN, - sha1_csum_wd, - CHUNKSZ_SHA1, - hash_init_sha1, - hash_update_sha1, - hash_finish_sha1, + .name = "sha256", + .digest_size = SHA256_SUM_LEN, + .chunk_size = CHUNKSZ_SHA256, +#ifdef CONFIG_SHA_HW_ACCEL + .hash_func_ws = hw_sha256, +#else + .hash_func_ws = sha256_csum_wd, +#endif +#ifdef CONFIG_SHA_PROG_HW_ACCEL + .hash_init = hw_sha_init, + .hash_update = hw_sha_update, + .hash_finish = hw_sha_finish, +#else + .hash_init = hash_init_sha256, + .hash_update = hash_update_sha256, + .hash_finish = hash_finish_sha256, +#endif }, #endif -#ifdef CONFIG_SHA256 { - "sha256", - SHA256_SUM_LEN, - sha256_csum_wd, - CHUNKSZ_SHA256, - hash_init_sha256, - hash_update_sha256, - hash_finish_sha256, + .name = "crc16-ccitt", + .digest_size = 2, + .chunk_size = CHUNKSZ, + .hash_func_ws = crc16_ccitt_wd_buf, + .hash_init = hash_init_crc16_ccitt, + .hash_update = hash_update_crc16_ccitt, + .hash_finish = hash_finish_crc16_ccitt, }, -#endif { - "crc32", - 4, - crc32_wd_buf, - CHUNKSZ_CRC32, - hash_init_crc32, - hash_update_crc32, - hash_finish_crc32, + .name = "crc32", + .digest_size = 4, + .chunk_size = CHUNKSZ_CRC32, + .hash_func_ws = crc32_wd_buf, + .hash_init = hash_init_crc32, + .hash_update = hash_update_crc32, + .hash_finish = hash_finish_crc32, }, }; @@ -186,10 +222,31 @@ static struct hash_algo hash_algo[] = { #define multi_hash() 0 #endif +static void reloc_update(void) +{ +#if !defined(USE_HOSTCC) && defined(CONFIG_NEEDS_MANUAL_RELOC) + int i; + static bool done; + + if (!done) { + done = true; + for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { + hash_algo[i].name += gd->reloc_off; + hash_algo[i].hash_func_ws += gd->reloc_off; + hash_algo[i].hash_init += gd->reloc_off; + hash_algo[i].hash_update += gd->reloc_off; + hash_algo[i].hash_finish += gd->reloc_off; + } + } +#endif +} + int hash_lookup_algo(const char *algo_name, struct hash_algo **algop) { int i; + reloc_update(); + for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { if (!strcmp(algo_name, hash_algo[i].name)) { *algop = &hash_algo[i]; @@ -206,6 +263,8 @@ int hash_progressive_lookup_algo(const char *algo_name, { int i; + reloc_update(); + for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { if (!strcmp(algo_name, hash_algo[i].name)) { if (hash_algo[i].hash_init) { @@ -302,7 +361,7 @@ static void store_result(struct hash_algo *algo, const uint8_t *sum, str_ptr += 2; } *str_ptr = '\0'; - setenv(dest, str_output); + env_set(dest, str_output); } else { ulong addr; void *buf; @@ -362,7 +421,7 @@ static int parse_verify_sum(struct hash_algo *algo, char *verify_str, if (strlen(verify_str) == digits) vsum_str = verify_str; else { - vsum_str = getenv(verify_str); + vsum_str = env_get(verify_str); if (vsum_str == NULL || strlen(vsum_str) != digits) { printf("Expected %d hex digits in env var\n", digits); @@ -397,7 +456,7 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, if (multi_hash()) { struct hash_algo *algo; - uint8_t output[HASH_MAX_DIGEST_SIZE]; + u8 *output; uint8_t vsum[HASH_MAX_DIGEST_SIZE]; void *buf; @@ -412,6 +471,9 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, return 1; } + output = memalign(ARCH_DMA_MINALIGN, + sizeof(uint32_t) * HASH_MAX_DIGEST_SIZE); + buf = map_sysmem(addr, len); algo->hash_func_ws(buf, len, output, algo->chunk_size); unmap_sysmem(buf); @@ -447,6 +509,8 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, store_result(algo, output, *argv, flags & HASH_FLAG_ENV); } + unmap_sysmem(output); + } /* Horrible code size hack for boards that just want crc32 */