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