xref: /optee_os/core/crypto/signed_hdr.c (revision 98ada65e9e6db4ac1b8c5bd3faa7a398ee410f7e)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2015-2022, Linaro Limited
4  */
5 
6 #include <crypto/crypto.h>
7 #include <kernel/panic.h>
8 #include <mempool.h>
9 #include <signed_hdr.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ta_pub_key.h>
13 #include <tee_api_types.h>
14 #include <tee/tee_cryp_utl.h>
15 #include <tee/uuid.h>
16 #include <utee_defines.h>
17 #include <util.h>
18 
19 struct shdr *shdr_alloc_and_copy(size_t offs, const void *img, size_t img_size)
20 {
21 	size_t shdr_size;
22 	struct shdr *shdr;
23 	vaddr_t img_va = (vaddr_t)img;
24 	vaddr_t tmp = 0;
25 	size_t end = 0;
26 
27 	if (ADD_OVERFLOW(offs, sizeof(struct shdr), &end) || end > img_size)
28 		return NULL;
29 
30 	shdr_size = SHDR_GET_SIZE((const struct shdr *)(img_va + offs));
31 	if (ADD_OVERFLOW(offs, shdr_size, &end) || end > img_size)
32 		return NULL;
33 
34 	if (ADD_OVERFLOW(img_va, shdr_size, &tmp))
35 		return NULL;
36 
37 	shdr = malloc(shdr_size);
38 	if (!shdr)
39 		return NULL;
40 	memcpy(shdr, (const uint8_t *)img + offs, shdr_size);
41 
42 	/* Check that the data wasn't modified before the copy was completed */
43 	if (shdr_size != SHDR_GET_SIZE(shdr)) {
44 		free(shdr);
45 		return NULL;
46 	}
47 
48 	return shdr;
49 }
50 
51 static bool is_weak_hash_algo(uint32_t algo)
52 {
53 	return algo == TEE_ALG_MD5 || algo == TEE_ALG_SHA1 ||
54 	       algo == TEE_ALG_MD5SHA1;
55 }
56 
57 TEE_Result shdr_verify_signature(const struct shdr *shdr)
58 {
59 	struct rsa_public_key key = { };
60 	TEE_Result res = TEE_SUCCESS;
61 	uint32_t e = TEE_U32_TO_BIG_ENDIAN(ta_pub_key_exponent);
62 	size_t hash_size = 0;
63 	size_t hash_algo = 0;
64 
65 	if (shdr->magic != SHDR_MAGIC)
66 		return TEE_ERROR_SECURITY;
67 
68 	if (TEE_ALG_GET_MAIN_ALG(shdr->algo) != TEE_MAIN_ALGO_RSA)
69 		return TEE_ERROR_SECURITY;
70 
71 	hash_algo = TEE_DIGEST_HASH_TO_ALGO(shdr->algo);
72 	if (is_weak_hash_algo(hash_algo))
73 		return TEE_ERROR_SECURITY;
74 
75 	res = tee_alg_get_digest_size(hash_algo, &hash_size);
76 	if (res)
77 		return TEE_ERROR_SECURITY;
78 	if (hash_size != shdr->hash_size)
79 		return TEE_ERROR_SECURITY;
80 
81 	res = crypto_acipher_alloc_rsa_public_key(&key,
82 						  ta_pub_key_modulus_size * 8);
83 	if (res)
84 		return TEE_ERROR_SECURITY;
85 
86 	res = crypto_bignum_bin2bn((uint8_t *)&e, sizeof(e), key.e);
87 	if (res)
88 		goto out;
89 	res = crypto_bignum_bin2bn(ta_pub_key_modulus, ta_pub_key_modulus_size,
90 				   key.n);
91 	if (res)
92 		goto out;
93 
94 	res = crypto_acipher_rsassa_verify(shdr->algo, &key, shdr->hash_size,
95 					   SHDR_GET_HASH(shdr), shdr->hash_size,
96 					   SHDR_GET_SIG(shdr), shdr->sig_size);
97 out:
98 	crypto_acipher_free_rsa_public_key(&key);
99 	if (res)
100 		return TEE_ERROR_SECURITY;
101 	return TEE_SUCCESS;
102 }
103 
104 static const struct shdr_subkey_attr *
105 find_attr(const struct shdr_subkey *subkey, uint32_t id)
106 {
107 	size_t n = 0;
108 
109 	for (n = 0; n < subkey->attr_count; n++)
110 		if (subkey->attrs[n].id == id)
111 			return subkey->attrs + n;
112 
113 	return NULL;
114 }
115 
116 static TEE_Result load_rsa_key(const struct shdr_subkey *subkey,
117 			       struct rsa_public_key **key_pp)
118 {
119 	const uint8_t *base = (const uint8_t *)subkey;
120 	const struct shdr_subkey_attr *pub_exp = NULL;
121 	const struct shdr_subkey_attr *modulus = NULL;
122 	struct rsa_public_key *key = NULL;
123 	TEE_Result res = TEE_SUCCESS;
124 
125 	pub_exp = find_attr(subkey, TEE_ATTR_RSA_PUBLIC_EXPONENT);
126 	if (!pub_exp)
127 		return TEE_ERROR_SECURITY;
128 	modulus = find_attr(subkey, TEE_ATTR_RSA_MODULUS);
129 	if (!modulus)
130 		return TEE_ERROR_SECURITY;
131 
132 	key = calloc(1, sizeof(*key));
133 	if (!key)
134 		return TEE_ERROR_OUT_OF_MEMORY;
135 	res = crypto_acipher_alloc_rsa_public_key(key, modulus->size * 8);
136 	if (res)
137 		goto err_key;
138 
139 	res = crypto_bignum_bin2bn(base + pub_exp->offs, pub_exp->size, key->e);
140 	if (res)
141 		goto err;
142 	res = crypto_bignum_bin2bn(base + modulus->offs, modulus->size, key->n);
143 	if (res)
144 		goto err;
145 
146 	*key_pp = key;
147 	return TEE_SUCCESS;
148 err:
149 	crypto_acipher_free_rsa_public_key(key);
150 err_key:
151 	free(key);
152 	return TEE_ERROR_SECURITY;
153 }
154 
155 static TEE_Result check_attrs(const struct shdr_subkey *subkey, size_t img_size)
156 {
157 	const struct shdr_subkey_attr *attrs = subkey->attrs;
158 	size_t end = 0;
159 	size_t n = 0;
160 
161 	if (MUL_OVERFLOW(subkey->attr_count, sizeof(*attrs), &end) ||
162 	    ADD_OVERFLOW(end, sizeof(*subkey), &end) ||
163 	    end > img_size)
164 		return TEE_ERROR_SECURITY;
165 
166 	for (n = 0; n < subkey->attr_count; n++)
167 		if (ADD_OVERFLOW(attrs[n].offs, attrs[n].size, &end) ||
168 		    end > img_size)
169 			return TEE_ERROR_SECURITY;
170 
171 	return TEE_SUCCESS;
172 }
173 
174 static TEE_Result calc_next_uuid(uint8_t uuid[sizeof(TEE_UUID)],
175 				 const uint8_t my_uuid[sizeof(TEE_UUID)],
176 				 const void *ns_name, size_t name_size)
177 {
178 	TEE_Result res = TEE_ERROR_SECURITY;
179 	void *ctx = NULL;
180 	struct {
181 		uint8_t digest[TEE_SHA1_HASH_SIZE];
182 		TEE_UUID uuid;
183 		char name_str[];
184 	} *tmp = NULL;
185 
186 	if (!name_size) {
187 		memcpy(uuid, my_uuid, sizeof(TEE_UUID));
188 		return TEE_SUCCESS;
189 	}
190 
191 	/*
192 	 * RFC 4122 requires a SHA-1 digest for UUID v5. Use SHA-512
193 	 * instead for better collision resistance.
194 	 */
195 	if (crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA512))
196 		return TEE_ERROR_SECURITY;
197 
198 	tmp = mempool_alloc(mempool_default, sizeof(*tmp) + name_size);
199 	if (!tmp)
200 		goto out_ctx;
201 	memcpy(tmp->name_str, ns_name, name_size);
202 
203 	if (crypto_hash_init(ctx) ||
204 	    crypto_hash_update(ctx, my_uuid, sizeof(TEE_UUID)) ||
205 	    crypto_hash_update(ctx, (const void *)tmp->name_str,
206 			       strnlen(tmp->name_str, name_size)) ||
207 	    crypto_hash_final(ctx, tmp->digest, sizeof(tmp->digest)))
208 		goto out_mempool;
209 
210 	tee_uuid_from_octets(&tmp->uuid, tmp->digest);
211 	/*
212 	 * Set the four most significant bits (bits 12 through 15) of the
213 	 * time_hi_and_version field to 5.
214 	 */
215 	tmp->uuid.timeHiAndVersion &= ~SHIFT_U32(0xf, 12);
216 	tmp->uuid.timeHiAndVersion |= SHIFT_U32(5, 12);
217 	/*
218 	 * Set the two most significant bits (bits 6 and 7) of the
219 	 * clock_seq_hi_and_reserved to zero and one, respectively.
220 	 */
221 	tmp->uuid.clockSeqAndNode[0] &= ~BIT(6);
222 	tmp->uuid.clockSeqAndNode[0] |= BIT(7);
223 
224 	tee_uuid_to_octets(uuid, &tmp->uuid);
225 	res = TEE_SUCCESS;
226 
227 out_mempool:
228 	mempool_free(mempool_default, tmp);
229 out_ctx:
230 	crypto_hash_free_ctx(ctx);
231 
232 	return res;
233 }
234 
235 TEE_Result shdr_load_pub_key(const struct shdr *shdr, size_t offs,
236 			     const uint8_t *ns_img, size_t ns_img_size,
237 			     const uint8_t next_uuid[sizeof(TEE_UUID)],
238 			     uint32_t max_depth, struct shdr_pub_key *key)
239 {
240 	struct shdr_subkey *subkey = NULL;
241 	TEE_Result res = TEE_SUCCESS;
242 	void *digest = NULL;
243 	uint8_t *img = NULL;
244 	void *ctx = NULL;
245 	size_t end = 0;
246 
247 	if (shdr->img_type != SHDR_SUBKEY)
248 		return TEE_ERROR_SECURITY;
249 
250 	if (shdr->img_size < sizeof(*subkey))
251 		return TEE_ERROR_SECURITY;
252 
253 	if (ADD_OVERFLOW(shdr->img_size, offs, &end) || end > ns_img_size)
254 		return TEE_ERROR_SECURITY;
255 
256 	img = mempool_alloc(mempool_default, shdr->img_size + shdr->hash_size);
257 	if (!img)
258 		return TEE_ERROR_OUT_OF_MEMORY;
259 	memcpy(img + shdr->hash_size, ns_img + offs, shdr->img_size);
260 	subkey = (void *)(img + shdr->hash_size);
261 	digest = img;
262 
263 	if (crypto_hash_alloc_ctx(&ctx, TEE_DIGEST_HASH_TO_ALGO(shdr->algo))) {
264 		res = TEE_ERROR_SECURITY;
265 		goto out_mempool;
266 	}
267 
268 	if (crypto_hash_init(ctx) ||
269 	    crypto_hash_update(ctx, (const void *)shdr, sizeof(*shdr)) ||
270 	    crypto_hash_update(ctx, (const void *)subkey, shdr->img_size) ||
271 	    crypto_hash_final(ctx, digest, shdr->hash_size) ||
272 	    memcmp(digest, SHDR_GET_HASH(shdr), shdr->hash_size)) {
273 		res = TEE_ERROR_SECURITY;
274 		goto out_ctx;
275 	}
276 
277 	res = check_attrs(subkey, shdr->img_size);
278 	if (res)
279 		goto out_ctx;
280 
281 	if (subkey->max_depth >= max_depth) {
282 		res = TEE_ERROR_SECURITY;
283 		goto out_ctx;
284 	}
285 	if (next_uuid && memcmp(next_uuid, subkey->uuid, sizeof(TEE_UUID))) {
286 		res = TEE_ERROR_SECURITY;
287 		goto out_ctx;
288 	}
289 
290 	key->max_depth = subkey->max_depth;
291 	key->name_size = subkey->name_size;
292 	memcpy(key->uuid, subkey->uuid, sizeof(TEE_UUID));
293 	if (ADD_OVERFLOW(key->name_size, offs + shdr->img_size, &end) ||
294 	    end > ns_img_size) {
295 		res = TEE_ERROR_SECURITY;
296 		goto out_ctx;
297 	}
298 	res = calc_next_uuid(key->next_uuid, key->uuid,
299 			     ns_img + offs + shdr->img_size, key->name_size);
300 	if (res)
301 		goto out_ctx;
302 
303 	key->main_algo = TEE_ALG_GET_MAIN_ALG(subkey->algo);
304 	switch (key->main_algo) {
305 	case TEE_MAIN_ALGO_RSA:
306 		res = load_rsa_key(subkey, &key->pub_key.rsa);
307 		break;
308 	default:
309 		res = TEE_ERROR_SECURITY;
310 		break;
311 	}
312 
313 out_ctx:
314 	crypto_hash_free_ctx(ctx);
315 out_mempool:
316 	mempool_free(mempool_default, img);
317 	return res;
318 }
319 
320 void shdr_free_pub_key(struct shdr_pub_key *key)
321 {
322 	if (key) {
323 		switch (key->main_algo) {
324 		case TEE_MAIN_ALGO_RSA:
325 			crypto_acipher_free_rsa_public_key(key->pub_key.rsa);
326 			free(key->pub_key.rsa);
327 			break;
328 		default:
329 			panic();
330 		}
331 	}
332 }
333 
334 TEE_Result shdr_verify_signature2(struct shdr_pub_key *key,
335 				  const struct shdr *shdr)
336 {
337 	size_t hash_size = 0;
338 	size_t hash_algo = 0;
339 
340 	if (shdr->magic != SHDR_MAGIC)
341 		return TEE_ERROR_SECURITY;
342 
343 	if (TEE_ALG_GET_MAIN_ALG(shdr->algo) != key->main_algo)
344 		return TEE_ERROR_SECURITY;
345 
346 	hash_algo = TEE_DIGEST_HASH_TO_ALGO(shdr->algo);
347 	if (is_weak_hash_algo(hash_algo))
348 		return TEE_ERROR_SECURITY;
349 
350 	if (tee_alg_get_digest_size(hash_algo, &hash_size) ||
351 	    hash_size != shdr->hash_size)
352 		return TEE_ERROR_SECURITY;
353 
354 	switch (key->main_algo) {
355 	case TEE_MAIN_ALGO_RSA:
356 		if (crypto_acipher_rsassa_verify(shdr->algo, key->pub_key.rsa,
357 						 shdr->hash_size,
358 						 SHDR_GET_HASH(shdr),
359 						 shdr->hash_size,
360 						 SHDR_GET_SIG(shdr),
361 						 shdr->sig_size))
362 			return TEE_ERROR_SECURITY;
363 		break;
364 	default:
365 		panic();
366 	}
367 
368 	return TEE_SUCCESS;
369 }
370