• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <upg_check_boot_bin.h>
17 #include <upg_check_secure.h>
18 #include <hi_cipher.h>
19 #include <upg_common.h>
20 
upg_check_boot_root_pub_key(HI_CONST boot_header * head,HI_CONST hi_u8 * pubk,hi_u32 pubk_len)21 hi_u32 upg_check_boot_root_pub_key(HI_CONST boot_header *head, HI_CONST hi_u8 *pubk, hi_u32 pubk_len)
22 {
23     hi_u8 hash[SHA_256_LENGTH];
24     hi_u8 efuse_hash[SHA_256_LENGTH];
25 
26     if ((head == HI_NULL) || (pubk == HI_NULL)) {
27         return HI_ERR_UPG_NULL_POINTER;
28     }
29 
30     if (head->root_pubk_length != pubk_len) {
31         return HI_ERR_UPG_BOOT_ROOT_KEY_LEN;
32     }
33 
34     (hi_void) memset_s(hash, SHA_256_LENGTH, 0, SHA_256_LENGTH);
35     hi_u32 ret = hi_cipher_hash_sha256((uintptr_t)pubk, pubk_len, hash, sizeof(hash));
36     if (ret != HI_ERR_SUCCESS) {
37         return ret;
38     }
39 
40     (hi_void) memset_s(efuse_hash, SHA_256_LENGTH, 0, SHA_256_LENGTH);
41     ret = hi_efuse_read(HI_EFUSE_ROOT_PUBKEY_RW_ID, efuse_hash, SHA_256_LENGTH);
42     if (ret != HI_ERR_SUCCESS) {
43         return ret;
44     }
45 
46     if (memcmp(hash, efuse_hash, SHA_256_LENGTH) != EOK) {
47         ret = HI_ERR_UPG_BOOT_ROOT_KEY;
48     }
49 
50     return ret;
51 }
52 
upg_check_die_id(HI_CONST hi_void * sub_key_data)53 hi_u32 upg_check_die_id(HI_CONST hi_void *sub_key_data)
54 {
55     hi_u8 die_id[DIE_ID_LENGTH] = { 0 };
56     hi_u32 ret = HI_ERR_SUCCESS;
57     sub_key_common *sub_key = (sub_key_common *)sub_key_data;
58 
59     if (sub_key->key_type == MAINTENANCE_KEY_TPYE) {
60         ret = hi_efuse_read(HI_EFUSE_DIE_RW_ID, (hi_u8 *)die_id, (hi_u8)sizeof(die_id));
61         if (ret != HI_ERR_SUCCESS) {
62             return ret;
63         }
64 
65         if (memcmp(sub_key->die_id, die_id, DIE_ID_LENGTH) != EOK) {
66             return HI_ERR_UPG_BOOT_DIE_ID;
67         }
68     }
69     return ret;
70 }
71 
upg_check_boot_subk_attr(HI_CONST hi_void * key,hi_u32 alg)72 hi_u32 upg_check_boot_subk_attr(HI_CONST hi_void *key, hi_u32 alg)
73 {
74     hi_u32 category = (hi_u32)(-1);
75     hi_u32 rsim = (hi_u32)(-1);
76     hi_u32 ret = hi_efuse_read(HI_EFUSE_SUBKEY_CAT_RW_ID, (hi_u8 *)(&category), sizeof(hi_u32));
77     if (ret != HI_ERR_SUCCESS) {
78         return ret;
79     }
80     sub_key_common *sub_key_com = (sub_key_common *)key;
81     if (sub_key_com->category != category) {
82         return HI_ERR_UPG_BOOT_SUB_KEY_CAT;
83     }
84     ret = hi_efuse_read(HI_EFUSE_SUBKEY_RSIM_RW_ID, (hi_u8 *)&rsim, SUBKEY_RSIM_BYTES);
85     if (ret != HI_ERR_SUCCESS) {
86         return ret;
87     }
88 
89     if ((sub_key_com->key_id > SUBKEY_ID_MAX) || (((rsim >> sub_key_com->key_id) & 1) == 1)) {
90         return HI_ERR_UPG_BOOT_SUB_KEY_RSIM;
91     }
92 
93     if (alg == SIGN_ALG_ECC) {
94         sub_ecc_key *sub_key = (sub_ecc_key *)key;
95         if ((sub_key->sign_alg.hash_alg != HI_HASH_ALG_SHA256) ||
96             (sub_key->sign_alg.sign_alg != SIGN_ALG_ECC) ||
97             (sub_key->subkey_length != ECC_64_BYTES)) {
98             return HI_ERR_UPG_BOOT_SIGN_ALG;
99         }
100     } else {
101         sub_rsa_key *sub_key = (sub_rsa_key *)key;
102         if ((sub_key->sign_alg.hash_alg != HI_HASH_ALG_SHA256) ||
103             (sub_key->sign_alg.sign_alg > SIGN_ALG_RSA_PSS) ||
104             (sub_key->subkey_length != (RSA_2048_LENGTH + RSA_EXP_E_LENGTH))) {
105             return HI_ERR_UPG_BOOT_SIGN_ALG;
106         }
107     }
108     ret = upg_check_die_id(key);
109     if (ret != HI_ERR_SUCCESS) {
110         upg_print("[upg check boot subk attr] die id err:0x%x \r\n", ret);
111     }
112 
113     return ret;
114 }
115 
upg_check_boot_sub_key_cpy(const root_rsa_pub_key * root_key,hi_u8 * exp_e)116 hi_u32 upg_check_boot_sub_key_cpy(const root_rsa_pub_key *root_key, hi_u8 *exp_e)
117 {
118     if (memset_s(exp_e, RSA_4096_LENGTH, 0, RSA_4096_LENGTH) != EOK) {
119         return HI_ERR_FAILURE;
120     }
121     if (memcpy_s((exp_e + RSA_4096_LENGTH - RSA_EXP_E_LENGTH), RSA_EXP_E_LENGTH, root_key->exp_e, RSA_EXP_E_LENGTH)
122         != EOK) {
123         return HI_ERR_FAILURE;
124     }
125 
126     return HI_ERR_SUCCESS;
127 }
128 
upg_check_boot_sub_key(HI_CONST hi_u8 * pubk,HI_CONST hi_u8 * subk,hi_u32 alg)129 hi_u32 upg_check_boot_sub_key(HI_CONST hi_u8 *pubk, HI_CONST hi_u8 *subk, hi_u32 alg)
130 {
131     hi_u8 hash[SHA_256_LENGTH] = { 0 };
132     hi_u32 ret = upg_check_boot_subk_attr(subk, alg);
133     if (ret != HI_ERR_SUCCESS) {
134         upg_print("[upg check boot sub key]attr err:0x%x \r\n", ret);
135         return ret;
136     }
137 
138     if (alg == SIGN_ALG_ECC) {
139         sub_ecc_key *sub_key = (sub_ecc_key *)subk;
140         root_ecc_pub_key *root_key = (root_ecc_pub_key *)pubk;
141         ret = hi_cipher_hash_sha256((uintptr_t)sub_key, sizeof(sub_ecc_key) - ECC_64_BYTES, hash, sizeof(hash));
142         if (ret != HI_ERR_SUCCESS) {
143             upg_print("[upg check bootbin]hash ecc key hash err:0x%x \r\n", ret);
144             return ret;
145         }
146 
147         hi_cipher_ecc_verify ecc_verify = {
148             .px = root_key->px,
149             .py = root_key->py,
150             .hash = hash,
151             .hash_len = PKE_LEN_32_BYTES,
152             .r = sub_key->r,
153             .s = sub_key->s,
154         };
155         ret = hi_cipher_ecc_verify_hash(&g_brain_pool_p256r1_verify, &ecc_verify);
156     } else {
157         sub_rsa_key *sub_key = (sub_rsa_key *)subk;
158         root_rsa_pub_key *root_key = (root_rsa_pub_key *)pubk;
159         ret = hi_cipher_hash_sha256((uintptr_t)sub_key, sizeof(sub_rsa_key) - RSA_4096_LENGTH, hash, sizeof(hash));
160         if (ret != HI_ERR_SUCCESS) {
161             return ret;
162         }
163         hi_u8 *exp_e = hi_malloc(HI_MOD_ID_UPG, RSA_4096_LENGTH);
164         if (exp_e == HI_NULL) {
165             return HI_ERR_UPG_MALLOC_FAIL;
166         }
167 
168         if (upg_check_boot_sub_key_cpy(root_key, exp_e) != HI_ERR_SUCCESS) {
169             hi_free(HI_MOD_ID_UPG, exp_e);
170             return HI_ERR_FAILURE;
171         }
172 
173         hi_cipher_rsa_verify rsa_verify;
174         rsa_verify.n = root_key->mod_n;
175         rsa_verify.e = exp_e;
176         rsa_verify.klen = RSA_4096_LENGTH;
177         rsa_verify.scheme = (hi_cipher_rsa_sign_scheme)(sub_key->sign_alg.sign_alg);
178 
179         ret = hi_cipher_rsa_verify_hash(&rsa_verify, hash, PKE_LEN_32_BYTES, sub_key->sign, RSA_4096_LENGTH);
180         hi_free(HI_MOD_ID_UPG, exp_e);
181     }
182     return ((ret == HI_ERR_FAILURE) ? HI_ERR_UPG_BOOT_SUB_KEY_HASH : ret);
183 }
184 
185 /* data: total boot bin. data_len: length of boot bin. */
upg_boot_decrypt(hi_u8 * data,hi_u32 data_len)186 hi_u32 upg_boot_decrypt(hi_u8 *data, hi_u32 data_len)
187 {
188     hi_u8 rootkey_iv[ROOTKEY_IV_BYTE_LENGTH] = { 0 };
189     boot_header *head = (boot_header *)data;
190     hi_u32 ret = HI_ERR_FAILURE;
191 
192     if ((head == HI_NULL) || (data_len != (head->sign_offset + head->sign_length + sizeof(boot_tail)))) {
193         return HI_ERR_UPG_PARAMETER;
194     }
195 
196     hi_u32 decrypt_addr = (hi_u32)(uintptr_t)data + head->code_section_offset;
197     sub_key_common *sub_key_com = (sub_key_common *)(data + head->sub_key_offset);
198     hi_cipher_kdf_ctrl *ctrl = hi_malloc(HI_MOD_ID_UPG, sizeof(hi_cipher_kdf_ctrl));
199     hi_cipher_aes_ctrl *aes_ctrl = hi_malloc(HI_MOD_ID_UPG, sizeof(hi_cipher_aes_ctrl));
200     if ((ctrl == HI_NULL) || (aes_ctrl == HI_NULL)) {
201         goto end;
202     }
203 
204     memset_s(ctrl, sizeof(hi_cipher_kdf_ctrl), 0, sizeof(hi_cipher_kdf_ctrl));
205     memset_s(aes_ctrl, sizeof(hi_cipher_aes_ctrl), 0, sizeof(hi_cipher_aes_ctrl));
206     if ((memcpy_s(rootkey_iv, sizeof(rootkey_iv), sub_key_com->boot_key, IV_BYTE_LEN) != EOK) ||
207         (memcpy_s((rootkey_iv + IV_BYTE_LEN), sizeof(rootkey_iv) - IV_BYTE_LEN, g_magic, IV_BYTE_LEN) != EOK)) {
208         goto end;
209     }
210 
211     ctrl->salt = rootkey_iv;
212     ctrl->salt_len = ROOTKEY_IV_BYTE_LENGTH;
213     ctrl->kdf_cnt = KDF_ITERATION_CNT;
214     ctrl->kdf_mode = HI_CIPHER_SSS_KDF_KEY_STORAGE;
215     ret = hi_cipher_kdf_key_derive(ctrl);
216     if (ret != HI_ERR_SUCCESS) {
217         goto end;
218     }
219     if (memcpy_s(aes_ctrl->iv, sizeof(aes_ctrl->iv), sub_key_com->aes_iv, IV_BYTE_LEN) != EOK) {
220         goto end;
221     }
222     aes_ctrl->random_en = HI_TRUE;
223     aes_ctrl->key_from = HI_CIPHER_AES_KEY_FROM_KDF;
224     aes_ctrl->work_mode = HI_CIPHER_AES_WORK_MODE_CBC;
225     aes_ctrl->key_len = HI_CIPHER_AES_KEY_LENGTH_256BIT;
226     ret = hi_cipher_aes_config(aes_ctrl);
227     if (ret != HI_ERR_SUCCESS) {
228         goto end;
229     }
230     ret = hi_cipher_aes_crypto(decrypt_addr, decrypt_addr, head->code_section_length, HI_FALSE);
231     (hi_void) hi_cipher_aes_destroy_config();
232 end:
233     upg_clear_contset((hi_u8 *)ctrl, sizeof(hi_cipher_kdf_ctrl));
234     upg_clear_contset((hi_u8 *)aes_ctrl, sizeof(hi_cipher_aes_ctrl));
235     upg_mem_free(ctrl);
236     upg_mem_free(aes_ctrl);
237     return ret;
238 }
239 
upg_check_boot_from_mem(hi_u8 * data,hi_u32 data_len,hi_u8 * key_part1,hi_u8 * key_part2)240 hi_u32 upg_check_boot_from_mem(hi_u8 *data, hi_u32 data_len, hi_u8 *key_part1, hi_u8 *key_part2)
241 {
242     hi_u32 ret;
243     hi_u8 hash[SHA_256_LENGTH] = { 0 };
244     boot_header *head = HI_NULL;
245     hi_u8 *signature = HI_NULL;
246 
247     head = (boot_header *)data;
248     if (data_len != (head->sign_offset + head->sign_length + sizeof(boot_tail))) {
249         return HI_ERR_UPG_BOOT_LEN;
250     }
251     ret = hi_cipher_hash_sha256((uintptr_t)data, (head->code_section_offset + head->code_section_length),
252                                 hash, sizeof(hash));
253     if (ret != HI_ERR_SUCCESS) {
254         upg_print("[upg check boot code]sha256 err:0x%x \r\n", ret);
255         return ret;
256     }
257 
258     signature = data + head->sign_offset;
259     if (head->sign_alg.sign_alg == SIGN_ALG_ECC) {
260         hi_cipher_ecc_verify ecc_verify = {
261             .px = key_part1,
262             .py = key_part2,
263             .hash = hash,
264             .hash_len = PKE_LEN_32_BYTES,
265             .r = signature,
266             .s = signature + ECC_32_BYTES,
267         };
268         ret = hi_cipher_ecc_verify_hash(&g_brain_pool_p256r1_verify, &ecc_verify);
269     } else {
270         hi_cipher_rsa_verify rsa_verify = {
271             .n = key_part1,
272             .e = key_part2,
273             .klen = RSA_2048_LENGTH,
274             .scheme = (hi_cipher_rsa_sign_scheme)(head->sign_alg.sign_alg),
275         };
276         ret = hi_cipher_rsa_verify_hash(&rsa_verify, hash, PKE_LEN_32_BYTES, signature, head->sign_length);
277     }
278     ret = ((ret == HI_ERR_FAILURE) ? HI_ERR_UPG_BOOT_SECTION_HASH : ret);
279     upg_print("[upg check boot code]verify ret:0x%x \r\n", ret);
280     return ret;
281 }
282 
283 /* boot_addr:flashboot bin addr without ota head. boot_len: total len. */
upg_check_encrpt_boot_code(hi_u32 boot_addr,hi_u32 boot_len,hi_u8 * key_part1,hi_u8 * key_part2)284 hi_u32 upg_check_encrpt_boot_code(hi_u32 boot_addr, hi_u32 boot_len, hi_u8 *key_part1, hi_u8 *key_part2)
285 {
286     upg_print("[upg check encrpt boot]addr-len:0x%x-0x%x \r\n", boot_addr, boot_len);
287     hi_u8 *boot = hi_malloc(HI_MOD_ID_UPG, boot_len);
288     if (boot == HI_NULL) {
289         upg_print("[upg check encrpt boot]malloc fail,boot_len:0x%x \r\n", boot_len);
290         return HI_ERR_UPG_MALLOC_FAIL;
291     }
292 
293     hi_u32 ret = hi_flash_read(boot_addr, boot_len, boot);
294     if (ret != HI_ERR_SUCCESS) {
295         upg_print("[upg check encrpt boot]flash read err:0x%x \r\n", ret);
296         goto end;
297     }
298     /* decrypt data */
299     ret = upg_boot_decrypt(boot, boot_len);
300     if (ret != HI_ERR_SUCCESS) {
301         upg_print("[upg check encrpt boot]decrypt ret:0x%x \r\n", ret);
302         goto end;
303     }
304 
305     ret = upg_check_boot_from_mem(boot, boot_len, key_part1, key_part2);
306 end:
307     upg_mem_free(boot);
308     return ret;
309 }
310 
311 /* addr:flashboot bin addr without ota head. */
upg_check_unencrpt_boot_code(hi_u32 addr,HI_CONST boot_header * head,hi_u8 * key_part1,hi_u8 * key_part2)312 hi_u32 upg_check_unencrpt_boot_code(hi_u32 addr, HI_CONST boot_header *head, hi_u8 *key_part1, hi_u8 *key_part2)
313 {
314     hi_u8 hash[SHA_256_LENGTH] = { 0 };
315 
316     if (head->sign_length == 0) {
317         return HI_ERR_UPG_PARAMETER;
318     }
319     hi_u32 ret = upg_hash_one_content(addr, (head->code_section_offset + head->code_section_length),
320                                       hash, sizeof(hash));
321     if (ret != HI_ERR_SUCCESS) {
322         return ret;
323     }
324 
325     hi_u8 *signature = hi_malloc(HI_MOD_ID_UPG, head->sign_length);
326     if (signature == HI_NULL) {
327         return HI_ERR_UPG_MALLOC_FAIL;
328     }
329 
330     ret = hi_flash_read(addr + head->sign_offset, head->sign_length, signature);
331     if (ret != HI_ERR_SUCCESS) {
332         goto end;
333     }
334 
335     if (head->sign_alg.sign_alg == SIGN_ALG_ECC) {
336         hi_cipher_ecc_verify ecc_verify = {
337             .px = key_part1,
338             .py = key_part2,
339             .hash = hash,
340             .hash_len = PKE_LEN_32_BYTES,
341             .r = signature,
342             .s = signature + ECC_32_BYTES,
343         };
344         ret = hi_cipher_ecc_verify_hash(&g_brain_pool_p256r1_verify, &ecc_verify);
345     } else {
346         hi_cipher_rsa_verify rsa_verify = {
347             .n = key_part1,
348             .e = key_part2,
349             .klen = RSA_2048_LENGTH,
350             .scheme = (hi_cipher_rsa_sign_scheme)(head->sign_alg.sign_alg),
351         };
352         ret = hi_cipher_rsa_verify_hash(&rsa_verify, hash, PKE_LEN_32_BYTES, signature, head->sign_length);
353     }
354     ret = ((ret == HI_ERR_FAILURE) ? HI_ERR_UPG_BOOT_SECTION_HASH : ret);
355     upg_print("[upg check unencrpt boot code]alg-ret:0x%x-0x%x \r\n", head->sign_alg.sign_alg, ret);
356 end:
357     upg_mem_free(signature);
358     return ret;
359 }
360 
361 /* addr:flashboot bin addr without ota head. */
upg_verify_flashboot(hi_u32 addr,HI_CONST boot_header * head,hi_u8 * key_part1,hi_u8 * key_part2,const sub_key_common * subk_com)362 hi_u32 upg_verify_flashboot(hi_u32 addr, HI_CONST boot_header *head, hi_u8 *key_part1,
363                             hi_u8 *key_part2, const sub_key_common *subk_com)
364 {
365     hi_u8 encrypt_flag = 0xFF;
366     hi_u32 ret = hi_efuse_read(HI_EFUSE_ENCRYPT_FLAG_RW_ID, (hi_u8 *)(&encrypt_flag), sizeof(hi_u8));
367     if (ret != HI_ERR_SUCCESS) {
368         upg_print("[upg verify flashboot]efuse read err:0x%x \r\n", ret);
369         return ret;
370     }
371 
372     if ((encrypt_flag == NON_ENCRYPT_FLAG) && (subk_com->encrypt_flag == NON_ENCRYPT_FLAG)) {
373         ret = upg_check_unencrpt_boot_code(addr, head, key_part1, key_part2);
374     } else {
375         ret = upg_check_encrpt_boot_code(addr, (head->sign_offset + head->sign_length + sizeof(boot_tail)),
376                                          key_part1, key_part2);
377     }
378     upg_print("[upg verify flashboot]ret-efuse-fileflag:0x%x-0x%x-0x%x \r\n", ret, encrypt_flag,
379               subk_com->encrypt_flag);
380     return ret;
381 }
382 
upg_get_boot_sign_key(HI_CONST boot_header * head,HI_CONST hi_u8 * key,hi_u8 ** pubk1,hi_u8 * pubk2,hi_u32 pubk2_len)383 hi_u32 upg_get_boot_sign_key(HI_CONST boot_header *head, HI_CONST hi_u8 *key, hi_u8 **pubk1,
384                              hi_u8 *pubk2, hi_u32 pubk2_len)
385 {
386     if ((head == HI_NULL) || (key == HI_NULL) || (pubk1 == HI_NULL) || (pubk2 == HI_NULL)) {
387         return HI_ERR_UPG_NULL_POINTER;
388     }
389 
390     if (head->root_pubk_alg < SIGN_ALG_ECC) {
391         sub_rsa_key *sub_key = (sub_rsa_key *)key;
392         if (pubk2_len != RSA_2048_LENGTH) {
393             return HI_ERR_UPG_PARAMETER;
394         }
395         *pubk1 = sub_key->mod_n;
396         if (memcpy_s((pubk2 + RSA_2048_LENGTH - RSA_EXP_E_LENGTH), RSA_EXP_E_LENGTH,
397             sub_key->exp_e, RSA_EXP_E_LENGTH) != EOK) {
398             return HI_ERR_FAILURE;
399         }
400     } else {
401         sub_ecc_key *sub_key = (sub_ecc_key *)key;
402         if (pubk2_len != ECC_32_BYTES) {
403             return HI_ERR_UPG_PARAMETER;
404         }
405         *pubk1 = sub_key->px;
406         if (memcpy_s(pubk2, ECC_32_BYTES, sub_key->py, ECC_32_BYTES) != EOK) {
407             return HI_ERR_FAILURE;
408         }
409     }
410 
411     return HI_ERR_SUCCESS;
412 }
413 
414 /* boot_addr:flashboot bin addr without ota head. verify_len: from head to sign(not include). */
upg_check_non_secure_boot_bin(hi_u32 boot_addr,hi_u32 verify_len,hi_u32 sign_addr)415 hi_u32 upg_check_non_secure_boot_bin(hi_u32 boot_addr, hi_u32 verify_len, hi_u32 sign_addr)
416 {
417     hi_u32 ret;
418     hi_u8 *cal_hash = hi_malloc(HI_MOD_ID_UPG, SHA_256_LENGTH);
419     hi_u8 *file_hash = hi_malloc(HI_MOD_ID_UPG, SHA_256_LENGTH);
420     if ((cal_hash == HI_NULL) || (file_hash == HI_NULL)) {
421         ret = HI_ERR_UPG_MALLOC_FAIL;
422         goto end;
423     }
424     memset_s(cal_hash, SHA_256_LENGTH, 0, SHA_256_LENGTH);
425     memset_s(file_hash, SHA_256_LENGTH, 0, SHA_256_LENGTH);
426     upg_print("[upg_non_secure_boot_bin]addr-verifylen-signaddr:0x%x-0x%x-0x%x \r\n", boot_addr, verify_len,
427               sign_addr);
428     ret = upg_hash_one_content(boot_addr, verify_len, cal_hash, SHA_256_LENGTH);
429     if (ret != HI_ERR_SUCCESS) {
430         goto end;
431     }
432     ret = hi_flash_read(sign_addr, SHA_256_LENGTH, file_hash);
433     if (ret != HI_ERR_SUCCESS) {
434         goto end;
435     }
436     if (memcmp(cal_hash, file_hash, SHA_256_LENGTH) != EOK) {
437         ret = HI_ERR_UPG_BOOT_HASH;
438     }
439 end:
440     upg_mem_free(cal_hash);
441     upg_mem_free(file_hash);
442     return ret;
443 }
444 
upg_check_boot_bin_key(HI_CONST boot_header * head,HI_CONST hi_u8 * pubk,hi_u32 pubk_len,HI_CONST hi_u8 * subk)445 hi_u32 upg_check_boot_bin_key(HI_CONST boot_header *head, HI_CONST hi_u8 *pubk, hi_u32 pubk_len,
446                               HI_CONST hi_u8 *subk)
447 {
448     hi_u32 ret = upg_check_boot_root_pub_key(head, pubk, pubk_len);
449     if (ret != HI_ERR_SUCCESS) {
450         upg_print("[upg check boot pub key]fail,ret:0x%x \r\n", ret);
451         return ret;
452     }
453 
454     ret = upg_check_boot_sub_key(pubk, subk, head->root_pubk_alg);
455     if (ret != HI_ERR_SUCCESS) {
456         upg_print("[upg check boot sub key]fail,ret:0x%x \r\n", ret)
457     }
458     return ret;
459 }
460 
upg_check_boot_get_key_len(HI_CONST boot_header * head,hi_u32 * pubk_len,hi_u32 * subk_len)461 hi_u32 upg_check_boot_get_key_len(HI_CONST boot_header *head, hi_u32 *pubk_len, hi_u32 *subk_len)
462 {
463     if ((head->root_pubk_alg < SIGN_ALG_ECC) && (head->sub_key_length == sizeof(sub_rsa_key))) {
464         *pubk_len = sizeof(root_rsa_pub_key);
465         *subk_len = sizeof(sub_rsa_key);
466         return HI_ERR_SUCCESS;
467     }
468 
469     if ((head->root_pubk_alg == SIGN_ALG_ECC) && (head->sub_key_length == sizeof(sub_ecc_key))) {
470         *pubk_len = sizeof(root_ecc_pub_key);
471         *subk_len = sizeof(sub_ecc_key);
472         return HI_ERR_SUCCESS;
473     }
474     return HI_ERR_UPG_BOOT_SUB_KEY_LEN;
475 }
476 
477 /* addr:flashboot bin addr without ota head. */
upg_check_secure_boot_bin(hi_u32 addr,HI_CONST boot_header * head)478 hi_u32 upg_check_secure_boot_bin(hi_u32 addr, HI_CONST boot_header *head)
479 {
480     hi_u8 *pubk1 = HI_NULL;
481     hi_u32 pubk_len;
482     hi_u32 subk_len;
483     hi_u32 puk2_len = RSA_2048_LENGTH;
484     hi_u32 ret = upg_check_boot_get_key_len(head, &pubk_len, &subk_len);
485     if (ret != HI_ERR_SUCCESS) {
486         return ret;
487     }
488 
489     if (head->root_pubk_alg == SIGN_ALG_ECC) {
490         puk2_len = ECC_32_BYTES;
491     }
492     upg_print("[verify flashboot]pubklen-subklen-puk2len:0x%x-0x%x-0x%x \r\n", pubk_len, subk_len, puk2_len);
493     hi_u8 *pubk = hi_malloc(HI_MOD_ID_UPG, pubk_len);
494     hi_u8 *subk = hi_malloc(HI_MOD_ID_UPG, subk_len);
495     hi_u8 *pubk2 = hi_malloc(HI_MOD_ID_UPG, puk2_len);
496     if ((pubk == HI_NULL) || (subk == HI_NULL) || (pubk2 == HI_NULL)) {
497         ret = HI_ERR_UPG_MALLOC_FAIL;
498         goto end;
499     }
500     memset_s(pubk2, puk2_len, 0, puk2_len);
501     ret = hi_flash_read((addr + head->root_pubk_offset), pubk_len, pubk);
502     ret |= hi_flash_read((addr + head->sub_key_offset), subk_len, subk);
503     if (ret != HI_ERR_SUCCESS) {
504         goto end;
505     }
506 
507     ret = upg_check_boot_bin_key(head, pubk, pubk_len, subk);
508     if (ret != HI_ERR_SUCCESS) {
509         goto end;
510     }
511 
512     ret = upg_get_boot_sign_key(head, subk, &pubk1, pubk2, puk2_len);
513     if (ret != HI_ERR_SUCCESS) {
514         goto end;
515     }
516 
517     ret = upg_verify_flashboot(addr, head, pubk1, pubk2, (sub_key_common *)subk);
518     if (ret != HI_ERR_SUCCESS) {
519         goto end;
520     }
521 end:
522     upg_clear_contset((hi_u8 *)pubk, pubk_len);
523     upg_clear_contset((hi_u8 *)subk, subk_len);
524     upg_clear_contset((hi_u8 *)pubk2, puk2_len);
525     upg_mem_free(pubk);
526     upg_mem_free(subk);
527     upg_mem_free(pubk2);
528     return ret;
529 }
530 
531 /* addr:flashboot bin addr(without ota head). len: length of flashboot bin. */
upg_check_boot_file(hi_u32 addr,hi_u32 len)532 hi_u32 upg_check_boot_file(hi_u32 addr, hi_u32 len)
533 {
534     hi_bool flag;
535     hi_unref_param(len);
536     hi_u32 ret = upg_is_secure_efuse(&flag);
537     if (ret != HI_ERR_SUCCESS) {
538         upg_print("[upg check boot bin]get secure efuse err:0x%x \r\n", ret);
539         return ret;
540     }
541     upg_print("[upg check boot bin]addr-len:0x%x-0x%x \r\n", addr, len);
542     boot_header *head = (boot_header *)hi_malloc(HI_MOD_ID_UPG, sizeof(boot_header));
543     if (head == HI_NULL) {
544         return HI_ERR_UPG_MALLOC_FAIL;
545     }
546     ret = hi_flash_read(addr, sizeof(boot_header), (hi_u8 *)head);
547     if (ret != HI_ERR_SUCCESS) {
548         goto end;
549     }
550 
551     if ((head->preamble != BOOT_PREAMBLE) || (head->head_magic != BOOT_HEAD_MAGIC)) {
552         ret = HI_ERR_UPG_BOOT_HEAD;
553         goto end;
554     }
555 
556     hi_u32 boot_len = head->sign_offset + head->sign_length + sizeof(boot_tail);
557     if ((boot_len < BOOT_SECURE_MIN_LEN) || (boot_len > BOOT_MAX_LEN)) {
558         ret = HI_ERR_UPG_BOOT_LEN;
559         goto end;
560     }
561 
562     if (flag == HI_TRUE) {
563         ret = upg_check_secure_boot_bin(addr, head);
564     } else {
565         ret = upg_check_non_secure_boot_bin(addr, (head->code_section_offset + head->code_section_length),
566                                             addr + head->sign_offset);
567     }
568 end:
569     hi_free(HI_MOD_ID_UPG, head);
570     return ret;
571 }
572