1646257d1SHeiko Schocher /* 2646257d1SHeiko Schocher * Copyright (c) 2013, Andreas Oetken. 3646257d1SHeiko Schocher * 4646257d1SHeiko Schocher * SPDX-License-Identifier: GPL-2.0+ 5646257d1SHeiko Schocher */ 6646257d1SHeiko Schocher 729a23f9dSHeiko Schocher #ifndef USE_HOSTCC 8646257d1SHeiko Schocher #include <common.h> 9*008ec9b4SJoseph Chen #include <crypto.h> 10646257d1SHeiko Schocher #include <fdtdec.h> 11646257d1SHeiko Schocher #include <asm/byteorder.h> 121221ce45SMasahiro Yamada #include <linux/errno.h> 13646257d1SHeiko Schocher #include <asm/unaligned.h> 14b37b46f0SRuchika Gupta #include <hash.h> 1529a23f9dSHeiko Schocher #else 1629a23f9dSHeiko Schocher #include "fdt_host.h" 17b37b46f0SRuchika Gupta #endif 18b37b46f0SRuchika Gupta #include <u-boot/rsa.h> 19646257d1SHeiko Schocher 20*008ec9b4SJoseph Chen int hash_calculate_sw(const char *name, 21b37b46f0SRuchika Gupta const struct image_region region[], 22b37b46f0SRuchika Gupta int region_count, uint8_t *checksum) 23646257d1SHeiko Schocher { 24b37b46f0SRuchika Gupta struct hash_algo *algo; 25b37b46f0SRuchika Gupta int ret = 0; 26b37b46f0SRuchika Gupta void *ctx; 27646257d1SHeiko Schocher uint32_t i; 28646257d1SHeiko Schocher i = 0; 29646257d1SHeiko Schocher 30b37b46f0SRuchika Gupta ret = hash_progressive_lookup_algo(name, &algo); 31b37b46f0SRuchika Gupta if (ret) 32b37b46f0SRuchika Gupta return ret; 33b37b46f0SRuchika Gupta 34b37b46f0SRuchika Gupta ret = algo->hash_init(algo, &ctx); 35b37b46f0SRuchika Gupta if (ret) 36b37b46f0SRuchika Gupta return ret; 37b37b46f0SRuchika Gupta 38b37b46f0SRuchika Gupta for (i = 0; i < region_count - 1; i++) { 39b37b46f0SRuchika Gupta ret = algo->hash_update(algo, ctx, region[i].data, 40b37b46f0SRuchika Gupta region[i].size, 0); 41b37b46f0SRuchika Gupta if (ret) 42b37b46f0SRuchika Gupta return ret; 43646257d1SHeiko Schocher } 44646257d1SHeiko Schocher 45b37b46f0SRuchika Gupta ret = algo->hash_update(algo, ctx, region[i].data, region[i].size, 1); 46b37b46f0SRuchika Gupta if (ret) 47b37b46f0SRuchika Gupta return ret; 48b37b46f0SRuchika Gupta ret = algo->hash_finish(algo, ctx, checksum, algo->digest_size); 49b37b46f0SRuchika Gupta if (ret) 50b37b46f0SRuchika Gupta return ret; 51646257d1SHeiko Schocher 52b37b46f0SRuchika Gupta return 0; 53646257d1SHeiko Schocher } 54*008ec9b4SJoseph Chen 55*008ec9b4SJoseph Chen #if defined(USE_HOSTCC) 56*008ec9b4SJoseph Chen int hash_calculate(const char *name, 57*008ec9b4SJoseph Chen const struct image_region region[], 58*008ec9b4SJoseph Chen int region_count, uint8_t *checksum) 59*008ec9b4SJoseph Chen { 60*008ec9b4SJoseph Chen return hash_calculate_sw(name, region, region_count, checksum); 61*008ec9b4SJoseph Chen } 62*008ec9b4SJoseph Chen #else 63*008ec9b4SJoseph Chen #if CONFIG_IS_ENABLED(FIT_HW_CRYPTO) 64*008ec9b4SJoseph Chen int hash_calculate(const char *name, 65*008ec9b4SJoseph Chen const struct image_region region[], 66*008ec9b4SJoseph Chen int region_count, uint8_t *checksum) 67*008ec9b4SJoseph Chen 68*008ec9b4SJoseph Chen { 69*008ec9b4SJoseph Chen struct udevice *dev; 70*008ec9b4SJoseph Chen sha_context ctx; 71*008ec9b4SJoseph Chen 72*008ec9b4SJoseph Chen if (!name) 73*008ec9b4SJoseph Chen return -EINVAL; 74*008ec9b4SJoseph Chen 75*008ec9b4SJoseph Chen if (!strcmp(name, "sha1")) 76*008ec9b4SJoseph Chen ctx.algo = CRYPTO_SHA1; 77*008ec9b4SJoseph Chen else if (!strcmp(name, "sha256")) 78*008ec9b4SJoseph Chen ctx.algo = CRYPTO_SHA256; 79*008ec9b4SJoseph Chen else 80*008ec9b4SJoseph Chen return -EPERM; 81*008ec9b4SJoseph Chen 82*008ec9b4SJoseph Chen dev = crypto_get_device(ctx.algo); 83*008ec9b4SJoseph Chen if (!dev) { 84*008ec9b4SJoseph Chen printf("No crypto device for expected capability\n"); 85*008ec9b4SJoseph Chen return -ENODEV; 86*008ec9b4SJoseph Chen } 87*008ec9b4SJoseph Chen 88*008ec9b4SJoseph Chen return crypto_sha_regions_csum(dev, &ctx, region, 89*008ec9b4SJoseph Chen region_count, checksum); 90*008ec9b4SJoseph Chen } 91*008ec9b4SJoseph Chen #else 92*008ec9b4SJoseph Chen int hash_calculate(const char *name, 93*008ec9b4SJoseph Chen const struct image_region region[], 94*008ec9b4SJoseph Chen int region_count, uint8_t *checksum) 95*008ec9b4SJoseph Chen { 96*008ec9b4SJoseph Chen return hash_calculate_sw(name, region, region_count, checksum); 97*008ec9b4SJoseph Chen } 98*008ec9b4SJoseph Chen #endif 99*008ec9b4SJoseph Chen #endif 100