1 /*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include "tee_comm_elf_verify.h"
13 #include "tee_log.h"
14 #include "securec.h"
15 #include "tee_elf_verify.h"
16 #include "ta_lib_img_unpack.h"
17 #include "ta_framework.h"
18 #include "mem_ops.h"
19 #include "tee_crypto_api.h"
20 #include "dyn_conf_dispatch_inf.h"
21 #include "tee_elf_verify_inner.h"
22 #include "ta_load_key.h"
23 #include "tee_load_key_ops.h"
24 #include "tee_crypto_hal.h"
25 #include <sys/mman.h>
26 #ifdef OPENSSL3_ENABLE
27 #include <openssl/rsa.h>
28 #endif
29
tee_secure_img_header_check(uint32_t img_version)30 TEE_Result tee_secure_img_header_check(uint32_t img_version)
31 {
32 size_t ta_head_len;
33 teec_image_head *image_hd = get_image_hd();
34
35 if (img_version == TA_SIGN_VERSION)
36 ta_head_len = sizeof(teec_ta_head_v1);
37 else if (img_version == TA_RSA2048_VERSION)
38 ta_head_len = sizeof(teec_ta_head_v2);
39 else
40 return TEE_ERROR_BAD_PARAMETERS;
41
42 bool check = (image_hd->context_len + ta_head_len < image_hd->context_len) ||
43 (image_hd->context_len + ta_head_len > MAX_IMAGE_LEN) ||
44 (image_hd->context_len > MAX_IMAGE_LEN) ||
45 (image_hd->cipher_bin_len > MAX_IMAGE_LEN - ta_head_len) ||
46 (image_hd->cipher_bin_len < ELF_HEAD_SIZE) ||
47 (image_hd->manifest_plain_len != MANIFEST_PLAIN_LEN) ||
48 (image_hd->sign_len != RSA_SIGN_LEN) ||
49 (image_hd->manifest_crypto_len > MAX_MANIFEST_SIZE) ||
50 (image_hd->manifest_crypto_len < MIN_MANIFEST_SIZE) ||
51 (image_hd->manifest_str_len > image_hd->manifest_crypto_len - MIN_CRYPTO_LEN) ||
52 (image_hd->context_len != image_hd->cipher_bin_len + AES_CIPHER_PAD(image_hd->cipher_bin_len) +
53 image_hd->sign_len + image_hd->manifest_crypto_len + SIZE_ALIGN(image_hd->manifest_crypto_len));
54 if (check) {
55 tloge("image hd error context_len: 0x%x\n", image_hd->context_len);
56 tloge("image hd error cipher_bin_len: 0x%x\n", image_hd->cipher_bin_len);
57 tloge("image hd error manifest_plain_len: 0x%x\n", image_hd->manifest_plain_len);
58 tloge("image hd error sign_len: 0x%x\n", image_hd->sign_len);
59 tloge("image hd error manifest_crypto_len: 0x%x\n", image_hd->manifest_crypto_len);
60 tloge("image hd error manifest_str_len: 0x%x\n", image_hd->manifest_str_len);
61 return TEE_ERROR_GENERIC;
62 }
63 return TEE_SUCCESS;
64 }
65
manifest_rsa_decry_check_version(const uint8_t * src_data,uint32_t src_len,uint8_t * dest_data,uint32_t * dest_len)66 static TEE_Result manifest_rsa_decry_check_version(const uint8_t *src_data, uint32_t src_len, uint8_t *dest_data,
67 uint32_t *dest_len)
68 {
69 int32_t boringssl_ret;
70 load_img_info *img_info = get_img_info();
71 enum ta_type type = ((img_info->img_version == TA_RSA2048_VERSION) ? V2_TYPE : V1_TYPE);
72
73 RSA *ta_load_priv_key = get_private_key(img_info->img_version, type);
74 if (ta_load_priv_key == NULL) {
75 tloge("get private key fail");
76 return TEE_ERROR_GENERIC;
77 }
78 switch (img_info->img_version) {
79 case TA_SIGN_VERSION:
80 boringssl_ret = RSA_private_decrypt(src_len, src_data, dest_data, ta_load_priv_key, RSA_PKCS1_PADDING);
81 break;
82 case TA_RSA2048_VERSION:
83 boringssl_ret = RSA_private_decrypt(src_len, src_data, dest_data, ta_load_priv_key, RSA_PKCS1_OAEP_PADDING);
84 break;
85 default:
86 tloge("Unsupported secure image version!\n");
87 return TEE_ERROR_NOT_SUPPORTED;
88 }
89 free_private_key(ta_load_priv_key);
90 ta_load_priv_key = NULL;
91
92 if (boringssl_ret <= 0) {
93 tloge("Failed to decrypt TA manifest!\n");
94 return TEE_ERROR_GENERIC;
95 }
96
97 *dest_len = (uint32_t)boringssl_ret;
98
99 return TEE_SUCCESS;
100 }
101
manifest_rsa_decry(const uint8_t * src_data,uint32_t src_len,uint8_t * dest_data,uint32_t * dest_len)102 static TEE_Result manifest_rsa_decry(const uint8_t *src_data, uint32_t src_len, uint8_t *dest_data, uint32_t *dest_len)
103 {
104 TEE_Result ret = manifest_rsa_decry_check_version(src_data, src_len, dest_data, dest_len);
105 if (ret != TEE_SUCCESS) {
106 tloge("Failed to decrypt TA manifest\n");
107 return ret;
108 }
109
110 return TEE_SUCCESS;
111 }
112
cp_mani_item_inform(const uint8_t * manifest_buffer,uint32_t size,manifest_t * manifest)113 static TEE_Result cp_mani_item_inform(const uint8_t *manifest_buffer, uint32_t size, manifest_t *manifest)
114 {
115 if (boundary_check(size, sizeof(manifest->mani_info)))
116 return TEE_ERROR_GENERIC;
117 manifest->mani_info = *((manifest_info_t *)manifest_buffer);
118
119 bool check =
120 (manifest->mani_info.elf_cryptkey_len > KEY_HASH_MAX || manifest->mani_info.elf_hash_len > KEY_HASH_MAX ||
121 manifest->mani_info.service_name_len >= SERVICE_NAME_MAX_IN_MANIFEST);
122 if (check) {
123 tloge("ELF hash_len crypt_key_len or service_name_len is invalid\n");
124 return TEE_ERROR_BAD_FORMAT;
125 }
126
127 return TEE_SUCCESS;
128 }
129
parse_manifest(uint8_t * manifest_str,uint32_t size,uint32_t rsa_algo_byte_len)130 static TEE_Result parse_manifest(uint8_t *manifest_str, uint32_t size, uint32_t rsa_algo_byte_len)
131 {
132 if (manifest_str == NULL || size <= rsa_algo_byte_len)
133 return TEE_ERROR_BAD_PARAMETERS;
134
135 uint32_t mani_len = 0;
136 uint32_t off_set = 0;
137 load_img_info *img_info = get_img_info();
138 /* Decrypt manifest encrypted by RSA algorithm */
139 TEE_Result ret = manifest_rsa_decry(manifest_str, rsa_algo_byte_len, manifest_str, &mani_len);
140 if (ret != TEE_SUCCESS)
141 return ret;
142
143 /* Copy UUID */
144 if (boundary_check(mani_len, off_set + sizeof(img_info->manifest.srv_uuid)))
145 return TEE_ERROR_GENERIC;
146 img_info->manifest.srv_uuid = *((TEE_UUID *)(manifest_str + off_set));
147 off_set += sizeof(img_info->manifest.srv_uuid);
148
149 /* Copy and check manifest information */
150 ret = cp_mani_item_inform(manifest_str + off_set, mani_len - off_set, &img_info->manifest);
151 if (ret != TEE_SUCCESS)
152 return ret;
153 off_set += sizeof(img_info->manifest.mani_info);
154
155 /* Copy ELF hash result */
156 if (boundary_check(mani_len, off_set + img_info->manifest.mani_info.elf_hash_len))
157 return TEE_ERROR_GENERIC;
158 ret = tee_secure_img_duplicate_buff(manifest_str + off_set, img_info->manifest.mani_info.elf_hash_len,
159 (uint8_t **)&img_info->manifest.hash_val);
160 if (ret != TEE_SUCCESS)
161 return ret;
162 off_set += img_info->manifest.mani_info.elf_hash_len;
163
164 /* Copy ELF AES key */
165 if (boundary_check(mani_len, off_set + img_info->manifest.mani_info.elf_cryptkey_len))
166 return TEE_ERROR_GENERIC;
167 ret = tee_secure_img_duplicate_buff(manifest_str + off_set, img_info->manifest.mani_info.elf_cryptkey_len,
168 (uint8_t **)&img_info->manifest.key_val);
169 if (ret != TEE_SUCCESS)
170 return ret;
171
172 /* Allocate buffer and copy TA service name */
173 off_set = rsa_algo_byte_len;
174 if (boundary_check(size, off_set + img_info->manifest.mani_info.service_name_len))
175 return TEE_ERROR_GENERIC;
176 img_info->manifest.service_name = (int8_t *)TEE_Malloc(img_info->manifest.mani_info.service_name_len + 1, 0);
177 if (img_info->manifest.service_name == NULL)
178 return TEE_ERROR_OUT_OF_MEMORY;
179 errno_t eret = memcpy_s(img_info->manifest.service_name, img_info->manifest.mani_info.service_name_len + 1,
180 manifest_str + off_set, img_info->manifest.mani_info.service_name_len);
181 if (eret != EOK)
182 return TEE_ERROR_SECURITY;
183 off_set += img_info->manifest.mani_info.service_name_len;
184
185 /* Process manifest extension */
186 teec_image_head *image_hd = get_image_hd();
187 if (boundary_check(size, off_set + image_hd->manifest_str_len))
188 return TEE_ERROR_GENERIC;
189 ret = tee_secure_img_manifest_extention_process(manifest_str + off_set, image_hd->manifest_str_len,
190 &img_info->manifest.ext, NULL);
191 if (ret != TEE_SUCCESS)
192 return ret;
193
194 return TEE_SUCCESS;
195 }
196
197 #define DECRYPT_ELF_LEN (1 << DECRY_OFFSET)
198
aes_decrypt_elf(const uint8_t * decry_in,uint32_t in_len,uint8_t * decry_dst,uint32_t dst_len,TEE_ObjectHandle key)199 static TEE_Result aes_decrypt_elf(const uint8_t *decry_in, uint32_t in_len, uint8_t *decry_dst, uint32_t dst_len,
200 TEE_ObjectHandle key)
201 {
202 TEE_OperationHandle crypto_ops = NULL;
203 uint32_t index;
204 uint32_t decry_times = (in_len >> DECRY_OFFSET);
205 size_t out_len;
206 size_t total_out_len = 0;
207 size_t left_len = in_len;
208
209 TEE_Result ret = TEE_AllocateOperation(&crypto_ops, TEE_ALG_AES_CBC_NOPAD, TEE_MODE_DECRYPT, KEY_SIZE_MAX);
210 if (ret != TEE_SUCCESS)
211 return ret;
212 ret = TEE_SetCryptoFlag(crypto_ops, SOFT_CRYPTO);
213 if (ret != TEE_SUCCESS) {
214 tloge("set soft engine failed 0x%x\n", ret);
215 TEE_FreeOperation(crypto_ops);
216 return ret;
217 }
218
219 ret = TEE_SetOperationKey(crypto_ops, key);
220 if (ret != TEE_SUCCESS) {
221 tloge("set operation key fail:0x%x\n", ret);
222 TEE_FreeOperation(crypto_ops);
223 return ret;
224 }
225
226 /* IV len is 16, but key-len is 32, so only need 1/2,
227 * this change is corresponding to the openssl aes call in signtool.py */
228 load_img_info *img_info = get_img_info();
229 TEE_CipherInit(crypto_ops, img_info->manifest.key_val, img_info->manifest.mani_info.elf_cryptkey_len >> 1);
230
231 for (index = 0; index < decry_times; index++) {
232 out_len = DECRYPT_ELF_LEN;
233 ret = TEE_CipherUpdate(crypto_ops, decry_in, DECRYPT_ELF_LEN, decry_dst, &out_len);
234 if (ret != TEE_SUCCESS) {
235 TEE_FreeOperation(crypto_ops);
236 tloge("cipher update fail:0x%x\n", ret);
237 return ret;
238 }
239
240 decry_in += DECRYPT_ELF_LEN;
241 left_len -= DECRYPT_ELF_LEN;
242 decry_dst += out_len;
243 total_out_len += out_len;
244 }
245
246 out_len = dst_len - total_out_len;
247 ret = TEE_CipherDoFinal(crypto_ops, decry_in, left_len, decry_dst, &out_len);
248 TEE_FreeOperation(crypto_ops);
249 if (ret != TEE_SUCCESS) {
250 tloge("do final fail:0x%x\n", ret);
251 return ret;
252 }
253 return TEE_SUCCESS;
254 }
255
elf_decry(uint8_t * src,uint32_t in_len,uint8_t * dst,uint32_t dst_len)256 static TEE_Result elf_decry(uint8_t *src, uint32_t in_len, uint8_t *dst, uint32_t dst_len)
257 {
258 if (src == NULL || dst == NULL)
259 return TEE_ERROR_BAD_PARAMETERS;
260 TEE_ObjectHandleVar key_obj = {0};
261 load_img_info *img_info = get_img_info();
262
263 /* aes cipher init */
264 key_obj.Attribute = (TEE_Attribute *)TEE_Malloc(sizeof(TEE_Attribute), 0);
265 if (key_obj.Attribute == NULL) {
266 tloge("Failed to allocate key attribute for TA ELF decryption\n");
267 return TEE_ERROR_OUT_OF_MEMORY;
268 }
269
270 key_obj.Attribute->content.ref.length = img_info->manifest.mani_info.elf_cryptkey_len;
271 key_obj.Attribute->content.ref.buffer = img_info->manifest.key_val;
272
273 /* aes decrypto */
274 TEE_Result tee_ret = aes_decrypt_elf(src, in_len, src, in_len, &key_obj);
275 if (tee_ret != TEE_SUCCESS) {
276 tloge("elf decrypt fail\n");
277 TEE_Free(key_obj.Attribute);
278 key_obj.Attribute = NULL;
279 return tee_ret;
280 }
281
282 tee_ret = memmove_s(dst, dst_len, src, in_len);
283 if (tee_ret != TEE_SUCCESS) {
284 tloge("memory move fail\n");
285 TEE_Free(key_obj.Attribute);
286 key_obj.Attribute = NULL;
287 return tee_ret;
288 }
289
290 TEE_Free(key_obj.Attribute);
291 key_obj.Attribute = NULL;
292 return tee_ret;
293 }
294
elf_verify(const uint8_t * hash_context,uint32_t context_len,elf_hash_data * hash_data)295 static TEE_Result elf_verify(const uint8_t *hash_context, uint32_t context_len,
296 elf_hash_data *hash_data)
297 {
298 load_img_info *img_info = get_img_info();
299 if (img_info->manifest.hash_val == NULL)
300 return TEE_ERROR_BAD_PARAMETERS;
301 uint8_t calced_hash[SHA256_LEN] = {0};
302
303 TEE_Result tee_ret = tee_secure_img_hash_ops(hash_context, context_len, calced_hash, sizeof(calced_hash));
304 if (tee_ret != TEE_SUCCESS) {
305 tloge("Failed to calculate hash");
306 return tee_ret;
307 }
308
309 errno_t eret = TEE_MemCompare(img_info->manifest.hash_val, calced_hash, SHA256_LEN);
310 if (eret != 0) {
311 tloge("elf hash verify fail!\n ");
312 return TEE_ERROR_SECURITY;
313 }
314
315 /* copy hash data out of this func if hash_data ptr is not NULL */
316 copy_hash_data(hash_data, calced_hash, SHA256_LEN);
317
318 return TEE_SUCCESS;
319 }
320
321 /* Image process function for version 1, 2 */
tee_secure_img_unpack_v2(uint32_t rsa_algo_byte_len,uint32_t ta_hd_len,uint8_t * img_buf,uint32_t img_size,elf_hash_data * hash_data)322 TEE_Result tee_secure_img_unpack_v2(uint32_t rsa_algo_byte_len,
323 uint32_t ta_hd_len, uint8_t *img_buf, uint32_t img_size, elf_hash_data *hash_data)
324 {
325 uint32_t off_set = 0;
326 (void)img_buf;
327 (void)img_size;
328 load_img_info *img_info = get_img_info();
329 teec_image_head *image_hd = get_image_hd();
330
331 if (hash_data == NULL)
332 return TEE_ERROR_BAD_PARAMETERS;
333
334 /* manifest handle, if manifest crypto, this is crypto context */
335 if (overflow_check(off_set, ta_hd_len))
336 return TEE_ERROR_GENERIC;
337 off_set += ta_hd_len;
338 if (boundary_check(img_info->img_size, off_set))
339 return TEE_ERROR_GENERIC;
340
341 int8_t *manifest_str = img_info->img_buf + off_set;
342 TEE_Result ret = parse_manifest((uint8_t *)manifest_str, img_info->img_size - off_set, rsa_algo_byte_len);
343 if (ret != TEE_SUCCESS)
344 return ret;
345
346 if (overflow_check(off_set, (image_hd->manifest_crypto_len + SIZE_ALIGN(image_hd->manifest_crypto_len))))
347 return TEE_ERROR_GENERIC;
348
349 off_set += (image_hd->manifest_crypto_len + SIZE_ALIGN(image_hd->manifest_crypto_len));
350 if (boundary_check(img_info->img_size, off_set))
351 return TEE_ERROR_GENERIC;
352 int8_t *sign_crypt = img_info->img_buf + off_set;
353
354 /* rsa 2048 verify */
355 ret = tee_secure_ta_release_verify((uint8_t *)img_info->manifest.hash_val,
356 img_info->manifest.mani_info.elf_hash_len, (uint8_t *)sign_crypt, image_hd->sign_len);
357 if (ret != TEE_SUCCESS)
358 return TEE_ERROR_IMG_ELF_LOAD_FAIL;
359 if (overflow_check(off_set, image_hd->sign_len))
360 return TEE_ERROR_GENERIC;
361
362 off_set += image_hd->sign_len;
363 if (boundary_check(img_info->img_size, off_set))
364 return TEE_ERROR_GENERIC;
365
366 uint8_t *crypt_elf = (uint8_t *)(img_info->img_buf + off_set);
367
368 /* elf decrypto, let plain img in img_info->img_buf */
369 uint8_t *elf_plain = (uint8_t *)img_info->img_buf;
370
371 if (img_info->img_size <= off_set)
372 return TEE_ERROR_BAD_PARAMETERS;
373 if (overflow_check(image_hd->cipher_bin_len, AES_CIPHER_PAD(image_hd->cipher_bin_len)))
374 return TEE_ERROR_GENERIC;
375
376 uint32_t align_elf_len = (image_hd->cipher_bin_len + AES_CIPHER_PAD(image_hd->cipher_bin_len));
377 if (align_elf_len > img_info->img_size - off_set)
378 return TEE_ERROR_BAD_PARAMETERS;
379 if (elf_decry(crypt_elf, align_elf_len, elf_plain, img_info->img_size) != TEE_SUCCESS)
380 return TEE_ERROR_BAD_PARAMETERS;
381 return elf_verify(elf_plain, image_hd->cipher_bin_len, hash_data);
382 }
383
free_verify_v2(void)384 void free_verify_v2(void)
385 {
386 load_img_info *img_info = get_img_info();
387 teec_image_head *image_hd = get_image_hd();
388 /* do NOT free it, map from tafs */
389 if (img_info->img_buf != NULL) {
390 (void)munmap((void *)(uintptr_t)img_info->img_buf, get_img_size());
391 img_info->img_buf = NULL;
392 }
393
394 if (img_info->manifest.hash_val != NULL) {
395 TEE_Free(img_info->manifest.hash_val);
396 img_info->manifest.hash_val = NULL;
397 }
398
399 if (img_info->manifest.key_val != NULL) {
400 (void)memset_s(img_info->manifest.key_val, img_info->manifest.mani_info.elf_cryptkey_len, 0,
401 img_info->manifest.mani_info.elf_cryptkey_len);
402
403 TEE_Free(img_info->manifest.key_val);
404 img_info->manifest.key_val = NULL;
405 }
406
407 if (img_info->manifest.service_name != NULL) {
408 TEE_Free(img_info->manifest.service_name);
409 img_info->manifest.service_name = NULL;
410 }
411
412 (void)memset_s((void *)img_info, sizeof(load_img_info), 0, sizeof(load_img_info));
413 (void)memset_s((void *)image_hd, sizeof(teec_image_head), 0, sizeof(teec_image_head));
414 }
415
secure_img_copy_rsp_v2(elf_verify_reply * rep)416 TEE_Result secure_img_copy_rsp_v2(elf_verify_reply *rep)
417 {
418 if (rep == NULL)
419 return TEE_ERROR_BAD_PARAMETERS;
420
421 load_img_info *img_info = get_img_info();
422 teec_image_head *image_hd = get_image_hd();
423 rep->ta_property = img_info->manifest.mani_info.ta_property;
424 rep->service_name_len = img_info->manifest.mani_info.service_name_len;
425 rep->mani_ext = img_info->manifest.ext;
426 rep->srv_uuid = img_info->manifest.srv_uuid;
427
428 rep->payload_hdr.mani_ext_size = image_hd->manifest_str_len;
429 rep->payload_hdr.ta_elf_size = image_hd->cipher_bin_len;
430
431 if (memcpy_s(rep->service_name, SERVICE_NAME_MAX_IN_MANIFEST, img_info->manifest.service_name,
432 img_info->manifest.mani_info.service_name_len + 1) != 0) {
433 tloge("copy service name fail\n");
434 return TEE_ERROR_GENERIC;
435 }
436
437 rep->off_ta_elf = 0;
438 if (img_info->manifest_buf)
439 rep->off_manifest_buf = (img_info->manifest_buf - img_info->img_buf);
440 else
441 rep->off_manifest_buf = INVALID_OFFSET;
442
443 return TEE_SUCCESS;
444 }
445