• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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