1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2013, Google Inc.
4  */
5 
6 #include <common.h>
7 #include <log.h>
8 #include <malloc.h>
9 #include <asm/global_data.h>
10 DECLARE_GLOBAL_DATA_PTR;
11 #include <image.h>
12 #include <relocate.h>
13 #include <u-boot/ecdsa.h>
14 #include <u-boot/rsa.h>
15 #include <u-boot/hash-checksum.h>
16 
17 #define IMAGE_MAX_HASHED_NODES		100
18 
19 struct checksum_algo checksum_algos[] = {
20 	{
21 		.name = "sha1",
22 		.checksum_len = SHA1_SUM_LEN,
23 		.der_len = SHA1_DER_LEN,
24 		.der_prefix = sha1_der_prefix,
25 		.calculate = hash_calculate,
26 	},
27 	{
28 		.name = "sha256",
29 		.checksum_len = SHA256_SUM_LEN,
30 		.der_len = SHA256_DER_LEN,
31 		.der_prefix = sha256_der_prefix,
32 		.calculate = hash_calculate,
33 	},
34 #ifdef CONFIG_SHA384
35 	{
36 		.name = "sha384",
37 		.checksum_len = SHA384_SUM_LEN,
38 		.der_len = SHA384_DER_LEN,
39 		.der_prefix = sha384_der_prefix,
40 		.calculate = hash_calculate,
41 	},
42 #endif
43 #ifdef CONFIG_SHA512
44 	{
45 		.name = "sha512",
46 		.checksum_len = SHA512_SUM_LEN,
47 		.der_len = SHA512_DER_LEN,
48 		.der_prefix = sha512_der_prefix,
49 		.calculate = hash_calculate,
50 	},
51 #endif
52 
53 };
54 
image_get_checksum_algo(const char * full_name)55 struct checksum_algo *image_get_checksum_algo(const char *full_name)
56 {
57 	int i;
58 	const char *name;
59 
60 	if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
61 		static bool done;
62 
63 		if (!done) {
64 			done = true;
65 			for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
66 				struct checksum_algo *algo = &checksum_algos[i];
67 
68 				MANUAL_RELOC(algo->name);
69 				MANUAL_RELOC(algo->calculate);
70 			}
71 		}
72 	}
73 
74 	for (i = 0; i < ARRAY_SIZE(checksum_algos); i++) {
75 		name = checksum_algos[i].name;
76 		/* Make sure names match and next char is a comma */
77 		if (!strncmp(name, full_name, strlen(name)) &&
78 		    full_name[strlen(name)] == ',')
79 			return &checksum_algos[i];
80 	}
81 
82 	return NULL;
83 }
84 
image_get_crypto_algo(const char * full_name)85 struct crypto_algo *image_get_crypto_algo(const char *full_name)
86 {
87 	struct crypto_algo *crypto, *end;
88 	const char *name;
89 
90 	if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
91 		static bool done;
92 
93 		if (!done) {
94 			done = true;
95 			crypto = ll_entry_start(struct crypto_algo, cryptos);
96 			end = ll_entry_end(struct crypto_algo, cryptos);
97 			for (; crypto < end; crypto++) {
98 				MANUAL_RELOC(crypto->name);
99 				MANUAL_RELOC(crypto->verify);
100 			}
101 		}
102 	}
103 
104 	/* Move name to after the comma */
105 	name = strchr(full_name, ',');
106 	if (!name)
107 		return NULL;
108 	name += 1;
109 
110 	crypto = ll_entry_start(struct crypto_algo, cryptos);
111 	end = ll_entry_end(struct crypto_algo, cryptos);
112 	for (; crypto < end; crypto++) {
113 		if (!strcmp(crypto->name, name))
114 			return crypto;
115 	}
116 
117 	/* Not found */
118 	return NULL;
119 }
120 
image_get_padding_algo(const char * name)121 struct padding_algo *image_get_padding_algo(const char *name)
122 {
123 	struct padding_algo *padding, *end;
124 
125 	if (!name)
126 		return NULL;
127 
128 	padding = ll_entry_start(struct padding_algo, paddings);
129 	end = ll_entry_end(struct padding_algo, paddings);
130 	for (; padding < end; padding++) {
131 		if (!strcmp(padding->name, name))
132 			return padding;
133 	}
134 
135 	return NULL;
136 }
137