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