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