xref: /rk3399_rockchip-uboot/lib/rsa/rsa-checksum.c (revision 008ec9b4bc06f98dd7efdc7d2f44eb066be036e6)
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