• 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 #ifdef CONFIG_FLASH_ENCRYPT_SUPPORT
17 #include <hi_stdlib.h>
18 #include <hi_mem.h>
19 #include <hi_cipher.h>
20 #include <hi_efuse.h>
21 #include <hi_flash.h>
22 #include <hi_nv.h>
23 #include <hi_upg_file.h>
24 #include <hi_partition_table.h>
25 #include "upg_common.h"
26 #include "kernel_crypto.h"
27 
28 #define SFC_BUFFER_BASE_ADDRESS             0x400000
29 
30 static const hi_u8 g_upg_file_magic[IV_BYTE_LENGTH] = {
31     0xE4, 0xEE, 0x10, 0x0E, 0x43, 0x4D, 0x94, 0x24,
32     0xC7, 0x54, 0x6D, 0xFB, 0x15, 0xA1, 0x46, 0x97
33 };
34 
35 encrypt_ctx g_encrypt_param = {0};
36 
encrypt_get_ctx(hi_void)37 encrypt_ctx *encrypt_get_ctx(hi_void)
38 {
39     return &g_encrypt_param;
40 }
41 
crypto_clear_content(hi_u8 * content,hi_u32 content_len)42 hi_void crypto_clear_content(hi_u8 *content, hi_u32 content_len)
43 {
44     if ((content == HI_NULL) || (content_len == 0)) {
45         return;
46     }
47 
48     (hi_void)memset_s(content, content_len, 0x0, content_len);
49 }
50 
crypto_content_id(encrypt_ctx * cfg,crypto_workkey_partition * content,crypto_workkey_partition * content_bak)51 hi_u32 crypto_content_id(encrypt_ctx *cfg, crypto_workkey_partition *content, crypto_workkey_partition *content_bak)
52 {
53     hi_flash_partition_table *partition = hi_get_partition_table();
54     hi_u32 kernel_a = partition->table[HI_FLASH_PARTITON_KERNEL_A].addr;
55     hi_u32 kernel_b = partition->table[HI_FLASH_PARTITON_KERNEL_B].addr;
56     if (cfg->kernel_start == kernel_a) {
57         *content = CRYPTO_WORKKEY_KERNEL_A;
58         *content_bak = CRYPTO_WORKKEY_KERNEL_A_BACKUP;
59     } else if (cfg->kernel_start == kernel_b) {
60         *content = CRYPTO_WORKKEY_KERNEL_B;
61         *content_bak = CRYPTO_WORKKEY_KERNEL_B_BACKUP;
62     } else {
63         return HI_ERR_FLASH_CRYPTO_KERNEL_ADDR_ERR;
64     }
65 
66     return HI_ERR_SUCCESS;
67 }
68 
crypto_load_salt(crypto_workkey_partition part,hi_flash_crypto_content * key_content)69 static hi_u32 crypto_load_salt(crypto_workkey_partition part, hi_flash_crypto_content *key_content)
70 {
71     hi_u32 ret = HI_ERR_SUCCESS;
72     hi_u8 salt_e[ROOT_SALT_LENGTH] = { 0 };
73 
74     (hi_void) memset_s(salt_e, sizeof(salt_e), 0x0, ROOT_SALT_LENGTH);
75     if (part == CRYPTO_WORKKEY_KERNEL_A) {
76         ret = hi_factory_nv_read(HI_NV_FTM_KERNELA_WORK_ID, key_content, sizeof(hi_flash_crypto_content), 0);
77         if (ret != HI_ERR_SUCCESS) {
78             goto fail;
79         }
80     } else if (part == CRYPTO_WORKKEY_KERNEL_A_BACKUP) {
81         ret = hi_factory_nv_read(HI_NV_FTM_BACKUP_KERNELA_WORK_ID, key_content, sizeof(hi_flash_crypto_content), 0);
82         if (ret != HI_ERR_SUCCESS) {
83             goto fail;
84         }
85     }
86 
87     if (memcmp(key_content->root_salt, salt_e, ROOT_SALT_LENGTH) == HI_ERR_SUCCESS) {
88         ret = HI_ERR_FLASH_CRYPTO_ROOT_SALT_EMPTY_ERR;
89         goto fail;
90     }
91 fail:
92     return ret;
93 }
94 
crypto_get_root_salt(hi_flash_crypto_content * key_content)95 static hi_u32 crypto_get_root_salt(hi_flash_crypto_content *key_content)
96 {
97     hi_u32 ret = crypto_load_salt(CRYPTO_WORKKEY_KERNEL_A, key_content);
98     if (ret != HI_ERR_SUCCESS) {
99         ret = crypto_load_salt(CRYPTO_WORKKEY_KERNEL_A_BACKUP, key_content);
100         if (ret != HI_ERR_SUCCESS) {
101             return ret;
102         }
103     }
104 
105     return HI_ERR_SUCCESS;
106 }
107 
crypto_prepare(hi_flash_crypto_content * save_content)108 static hi_u32 crypto_prepare(hi_flash_crypto_content *save_content)
109 {
110     hi_u32 ret;
111     hi_u8 rootkey_iv[ROOTKEY_IV_BYTE_LENGTH];
112     hi_cipher_kdf_ctrl ctrl;
113 
114     ret = hi_cipher_init();
115     if (ret != HI_ERR_SUCCESS) {
116         return ret;
117     }
118 
119     ret = crypto_get_root_salt(save_content);
120     if (ret != HI_ERR_SUCCESS) {
121         return ret;
122     }
123 
124     ret = memcpy_s(rootkey_iv, sizeof(rootkey_iv), save_content->root_salt, ROOT_SALT_LENGTH);
125     if (ret != HI_ERR_SUCCESS) {
126         return ret;
127     }
128 
129     ctrl.salt = rootkey_iv;
130     ctrl.salt_len = sizeof(rootkey_iv);
131     ctrl.kdf_cnt = ENCRYPT_KDF_ITERATION_CNT;
132     ctrl.kdf_mode = HI_CIPHER_SSS_KDF_KEY_STORAGE;
133     return hi_cipher_kdf_key_derive(&ctrl);
134 }
135 
crpto_set_aes_ctrl_default_value(hi_cipher_aes_ctrl * aes_ctrl)136 static hi_void crpto_set_aes_ctrl_default_value(hi_cipher_aes_ctrl *aes_ctrl)
137 {
138     if (aes_ctrl == HI_NULL) {
139         return;
140     }
141     aes_ctrl->random_en = HI_FALSE;
142     aes_ctrl->key_from = HI_CIPHER_AES_KEY_FROM_CPU;
143     aes_ctrl->work_mode = HI_CIPHER_AES_WORK_MODE_CBC;
144     aes_ctrl->key_len = HI_CIPHER_AES_KEY_LENGTH_256BIT;
145 }
146 
crypto_decrypt_hash(hi_flash_crypto_content * key_content)147 static hi_u32 crypto_decrypt_hash(hi_flash_crypto_content *key_content)
148 {
149     hi_u32 ret;
150     hi_u32 content_size = (hi_u32)sizeof(hi_flash_crypto_content);
151 
152     hi_flash_crypto_content *content_tmp = (hi_flash_crypto_content *)hi_malloc(HI_MOD_ID_CRYPTO, content_size);
153     if (content_tmp == HI_NULL) {
154         return HI_ERR_FLASH_CRYPTO_MALLOC_FAIL;
155     }
156 
157     ret = (hi_u32)memcpy_s(content_tmp, content_size, key_content, content_size);
158     if (ret != EOK) {
159         goto fail;
160     }
161 
162     hi_cipher_aes_ctrl aes_ctrl = {
163         .random_en = HI_FALSE,
164         .key_from = HI_CIPHER_AES_KEY_FROM_KDF,
165         .work_mode = HI_CIPHER_AES_WORK_MODE_CBC,
166         .key_len = HI_CIPHER_AES_KEY_LENGTH_256BIT,
167     };
168 
169     ret = (hi_u32)memcpy_s(aes_ctrl.iv, sizeof(aes_ctrl.iv), content_tmp->iv_nv, IV_BYTE_LENGTH);
170     if (ret != EOK) {
171         goto fail;
172     }
173     ret = hi_cipher_aes_config(&aes_ctrl);
174     if (ret != HI_ERR_SUCCESS) {
175         goto crypto_fail;
176     }
177     ret = hi_cipher_aes_crypto((uintptr_t)content_tmp->iv_content, (uintptr_t)key_content->iv_content,
178         content_size - ROOT_SALT_LENGTH - IV_BYTE_LENGTH, HI_FALSE);
179     if (ret != HI_ERR_SUCCESS) {
180         goto crypto_fail;
181     }
182 
183 crypto_fail:
184     (hi_void) hi_cipher_aes_destroy_config();
185 fail:
186     crypto_clear_content((hi_u8 *)content_tmp, content_size);
187     crypto_mem_free(content_tmp);
188     return ret;
189 }
190 
crypto_encrypt_hash(hi_flash_crypto_content * key_content)191 static hi_u32 crypto_encrypt_hash(hi_flash_crypto_content *key_content)
192 {
193     hi_cipher_aes_ctrl aes_ctrl;
194     hi_u32 content_size = (hi_u32)sizeof(hi_flash_crypto_content);
195     hi_u32 encrypt_size = content_size - ROOT_SALT_LENGTH - IV_BYTE_LENGTH;
196 
197     hi_flash_crypto_content *data_tmp = (hi_flash_crypto_content *)hi_malloc(HI_MOD_ID_CRYPTO, content_size);
198     if (data_tmp == HI_NULL) {
199         return HI_ERR_FLASH_CRYPTO_MALLOC_FAIL;
200     }
201 
202     hi_u32 ret = (hi_u32)memcpy_s(aes_ctrl.iv, sizeof(aes_ctrl.iv), key_content->iv_nv, IV_BYTE_LENGTH);
203     if (ret != EOK) {
204         goto fail;
205     }
206 
207     aes_ctrl.random_en = HI_FALSE;
208     aes_ctrl.key_from = HI_CIPHER_AES_KEY_FROM_KDF;
209     aes_ctrl.work_mode = HI_CIPHER_AES_WORK_MODE_CBC;
210     aes_ctrl.key_len = HI_CIPHER_AES_KEY_LENGTH_256BIT;
211     ret = hi_cipher_aes_config(&aes_ctrl);
212     if (ret != HI_ERR_SUCCESS) {
213         goto crypto_fail;
214     }
215     ret = hi_cipher_aes_crypto((hi_u32)(uintptr_t)key_content->iv_content, (hi_u32)(uintptr_t)(data_tmp->iv_content),
216         encrypt_size, HI_TRUE);
217     if (ret != HI_ERR_SUCCESS) {
218         goto crypto_fail;
219     }
220 
221     ret = (hi_u32)memcpy_s(key_content->iv_content, encrypt_size, data_tmp->iv_content, encrypt_size);
222 
223 crypto_fail:
224     (hi_void) hi_cipher_aes_destroy_config();
225 fail:
226     crypto_clear_content((hi_u8 *)data_tmp, content_size);
227     crypto_mem_free(data_tmp);
228     return ret;
229 }
230 
crypto_load_key_content(crypto_workkey_partition part,hi_flash_crypto_content * key_content)231 static hi_u32 crypto_load_key_content(crypto_workkey_partition part, hi_flash_crypto_content *key_content)
232 {
233     hi_u32 ret = HI_ERR_SUCCESS;
234     hi_u8 hash[SHA_256_LENGTH];
235     hi_u8 key_e[KEY_BYTE_LENGTH] = { 0 };
236 
237     (hi_void) memset_s(key_e, sizeof(key_e), 0x0, KEY_BYTE_LENGTH);
238     if (part == CRYPTO_WORKKEY_KERNEL_A) {
239         ret = hi_factory_nv_read(HI_NV_FTM_KERNELA_WORK_ID, key_content, sizeof(hi_flash_crypto_content), 0);
240         if (ret != HI_ERR_SUCCESS) {
241             goto fail;
242         }
243     } else if (part == CRYPTO_WORKKEY_KERNEL_A_BACKUP) {
244         ret = hi_factory_nv_read(HI_NV_FTM_BACKUP_KERNELA_WORK_ID, key_content, sizeof(hi_flash_crypto_content), 0);
245         if (ret != HI_ERR_SUCCESS) {
246             goto fail;
247         }
248     } else if (part == CRYPTO_WORKKEY_KERNEL_B) {
249         ret = hi_factory_nv_read(HI_NV_FTM_KERNELB_WORK_ID, key_content, sizeof(hi_flash_crypto_content), 0);
250         if (ret != HI_ERR_SUCCESS) {
251             goto fail;
252         }
253     } else if (part == CRYPTO_WORKKEY_KERNEL_B_BACKUP) {
254         ret = hi_factory_nv_read(HI_NV_FTM_BACKUP_KERNELB_WORK_ID, key_content, sizeof(hi_flash_crypto_content), 0);
255         if (ret != HI_ERR_SUCCESS) {
256             goto fail;
257         }
258     }
259 
260     if (memcmp(key_content->work_text, key_e, KEY_BYTE_LENGTH) == HI_ERR_SUCCESS) {
261         ret = HI_ERR_FLASH_CRYPTO_KEY_EMPTY_ERR;
262         goto fail;
263     }
264 
265     ret = crypto_decrypt_hash(key_content);
266     if (ret != HI_ERR_SUCCESS) {
267         goto fail;
268     }
269 
270     ret = hi_cipher_hash_sha256((uintptr_t)(key_content->root_salt), sizeof(hi_flash_crypto_content) - SHA_256_LENGTH,
271                                 hash, SHA_256_LENGTH);
272     if (ret != HI_ERR_SUCCESS) {
273         goto fail;
274     }
275     if (memcmp(key_content->content_sh256, hash, SHA_256_LENGTH) != HI_ERR_SUCCESS) {
276         ret = HI_ERR_FLASH_CRYPTO_KEY_INVALID_ERR;
277         goto fail;
278     }
279 fail:
280     return ret;
281 }
282 
crypto_save_work_key(crypto_workkey_partition part,hi_flash_crypto_content * key_content)283 static hi_u32 crypto_save_work_key(crypto_workkey_partition part, hi_flash_crypto_content *key_content)
284 {
285     hi_u32 ret;
286     hi_u32 content_size = (hi_u32)sizeof(hi_flash_crypto_content);
287     hi_flash_crypto_content *content_tmp = (hi_flash_crypto_content *)hi_malloc(HI_MOD_ID_CRYPTO, content_size);
288     if (content_tmp == HI_NULL) {
289         return HI_ERR_FLASH_CRYPTO_MALLOC_FAIL;
290     }
291 
292     ret = (hi_u32)memcpy_s(content_tmp, content_size, key_content, content_size);
293     if (ret != EOK) {
294         goto fail;
295     }
296 
297     /* Encrypt,then save to factory NV. */
298     ret = crypto_encrypt_hash(content_tmp);
299     if (ret != HI_ERR_SUCCESS) {
300         goto fail;
301     }
302 
303     if ((hi_u32)part & CRYPTO_WORKKEY_KERNEL_A) {
304         ret = hi_factory_nv_write(HI_NV_FTM_KERNELA_WORK_ID, content_tmp, content_size, 0);
305         if (ret != HI_ERR_SUCCESS) {
306             ret = HI_ERR_FLASH_CRYPTO_KEY_SAVE_ERR;
307             goto fail;
308         }
309     }
310     if ((hi_u32)part & CRYPTO_WORKKEY_KERNEL_A_BACKUP) {
311         ret = hi_factory_nv_write(HI_NV_FTM_BACKUP_KERNELA_WORK_ID, content_tmp, content_size, 0);
312         if (ret != HI_ERR_SUCCESS) {
313             ret =  HI_ERR_FLASH_CRYPTO_KEY_SAVE_ERR;
314             goto fail;
315         }
316     }
317 
318     if ((hi_u32)part & CRYPTO_WORKKEY_KERNEL_B) {
319         ret = hi_factory_nv_write(HI_NV_FTM_KERNELB_WORK_ID, content_tmp, content_size, 0);
320         if (ret != HI_ERR_SUCCESS) {
321             ret = HI_ERR_FLASH_CRYPTO_KEY_SAVE_ERR;
322             goto fail;
323         }
324     }
325     if ((hi_u32)part & CRYPTO_WORKKEY_KERNEL_B_BACKUP) {
326         ret = hi_factory_nv_write(HI_NV_FTM_BACKUP_KERNELB_WORK_ID, content_tmp, content_size, 0);
327         if (ret != HI_ERR_SUCCESS) {
328             ret =  HI_ERR_FLASH_CRYPTO_KEY_SAVE_ERR;
329             goto fail;
330         }
331     }
332 
333 fail:
334     crypto_clear_content((hi_u8 *)content_tmp, content_size);
335     crypto_mem_free(content_tmp);
336     return ret;
337 }
338 
crypto_gen_key_content(hi_flash_crypto_content * key_content)339 static hi_u32 crypto_gen_key_content(hi_flash_crypto_content *key_content)
340 {
341     hi_u8 salt[IV_BYTE_LENGTH];
342     hi_u8 kdf_key[KEY_BYTE_LENGTH];
343     hi_cipher_kdf_ctrl ctrl;
344 
345     (hi_void)hi_cipher_trng_get_random_bytes(salt, IV_BYTE_LENGTH);
346     (hi_void)hi_cipher_trng_get_random_bytes(kdf_key, KEY_BYTE_LENGTH);
347     (hi_void)hi_cipher_trng_get_random_bytes(key_content->iv_nv, IV_BYTE_LENGTH);
348     (hi_void)hi_cipher_trng_get_random_bytes(key_content->iv_content, IV_BYTE_LENGTH);
349 
350     if ((hi_u32)memcpy_s(ctrl.key, sizeof(ctrl.key), kdf_key, sizeof(kdf_key)) != EOK) {
351         return HI_ERR_FAILURE;
352     }
353     ctrl.salt = salt;
354     ctrl.salt_len = sizeof(salt);
355     ctrl.kdf_cnt = ENCRYPT_KDF_ITERATION_CNT;
356     ctrl.kdf_mode = HI_CIPHER_SSS_KDF_KEY_DEVICE; /* In this mode, user should provide root key. */
357     if (hi_cipher_kdf_key_derive(&ctrl) != HI_ERR_SUCCESS) {
358         return HI_ERR_FAILURE;
359     }
360 
361     if (memcpy_s(key_content->work_text, KEY_BYTE_LENGTH, ctrl.result, sizeof(ctrl.result)) != EOK) {
362         return HI_ERR_FAILURE;
363     }
364 
365     if (hi_cipher_hash_sha256((uintptr_t)(key_content->root_salt), sizeof(hi_flash_crypto_content) - SHA_256_LENGTH,
366         key_content->content_sh256, SHA_256_LENGTH) != HI_ERR_SUCCESS) {
367         return HI_ERR_FAILURE;
368     }
369 
370     return HI_ERR_SUCCESS;
371 }
372 
crypto_decrypt_kernel(hi_flash_crypto_content * content,encrypt_ctx * para)373 static hi_u32 crypto_decrypt_kernel(hi_flash_crypto_content *content, encrypt_ctx *para)
374 {
375     hi_u32 ret;
376     hi_cipher_aes_ctrl aes_ctrl;
377     hi_u8 *fw_raw_data = para->raw_buf;
378 
379     ret = (hi_u32)memcpy_s(aes_ctrl.key, sizeof(aes_ctrl.key), content->work_text, KEY_BYTE_LENGTH);
380     if (ret != HI_ERR_SUCCESS) {
381         goto fail;
382     }
383 
384     ret = (hi_u32)memcpy_s(aes_ctrl.iv, sizeof(aes_ctrl.iv), content->iv_content, IV_BYTE_LENGTH);
385     if (ret != HI_ERR_SUCCESS) {
386         goto fail;
387     }
388 
389     crpto_set_aes_ctrl_default_value(&aes_ctrl);
390     ret = hi_cipher_aes_config(&aes_ctrl);
391     if (ret != HI_ERR_SUCCESS) {
392         goto fail;
393     }
394 
395     ret = hi_cipher_aes_crypto(para->kernel_start + para->encrypt_offset + SFC_BUFFER_BASE_ADDRESS,
396         (uintptr_t)fw_raw_data, para->encrypt_size, HI_FALSE);
397     if (ret != HI_ERR_SUCCESS) {
398         goto crypto_fail;
399     }
400 
401 crypto_fail:
402     (hi_void) hi_cipher_aes_destroy_config();
403 fail:
404     return ret;
405 }
406 
crypto_decrypt(encrypt_ctx * para)407 hi_u32 crypto_decrypt(encrypt_ctx *para)
408 {
409     hi_bool is_backup_content = HI_FALSE;
410     crypto_workkey_partition werk_content;
411     crypto_workkey_partition werk_content_bak;
412     hi_u32 ret = crypto_content_id(para, &werk_content, &werk_content_bak);
413     if (ret != HI_ERR_SUCCESS) {
414         return ret;
415     }
416 
417     hi_flash_crypto_content *key_content = (hi_flash_crypto_content *)hi_malloc(HI_MOD_ID_CRYPTO,
418         sizeof(hi_flash_crypto_content));
419     if (key_content == HI_NULL) {
420         return HI_ERR_FLASH_CRYPTO_PREPARE_ERR;
421     }
422 
423     ret = crypto_prepare(key_content);
424     if (ret != HI_ERR_SUCCESS) {
425         crypto_clear_content((hi_u8 *)key_content, (hi_u32)sizeof(hi_flash_crypto_content));
426         crypto_mem_free(key_content);
427         return HI_ERR_FLASH_CRYPTO_PREPARE_ERR;
428     }
429 
430     ret = crypto_load_key_content(werk_content, key_content);
431     if (ret != HI_ERR_SUCCESS) {
432         ret = crypto_load_key_content(werk_content_bak, key_content);
433         if (ret != HI_ERR_SUCCESS) {
434             goto fail;
435         } else {
436             ret = crypto_save_work_key(werk_content, key_content);
437             if (ret != HI_ERR_SUCCESS) {
438                 goto fail;
439             }
440             is_backup_content = HI_TRUE;
441         }
442     }
443 
444     ret = crypto_decrypt_kernel(key_content, para);
445     if ((ret != HI_ERR_SUCCESS) && (is_backup_content == HI_FALSE)) {
446         ret = crypto_load_key_content(werk_content_bak, key_content);
447         if (ret != HI_ERR_SUCCESS) {
448             goto fail;
449         }
450         ret = crypto_decrypt_kernel(key_content, para);
451         if (ret != HI_ERR_SUCCESS) {
452             ret = HI_ERR_FLASH_CRYPTO_DATA_DECRYPT_ERR;
453             goto fail;
454         }
455     }
456 fail:
457     crypto_clear_content((hi_u8 *)key_content, (hi_u32)sizeof(hi_flash_crypto_content));
458     crypto_mem_free(key_content);
459     return ret;
460 }
461 
crypto_encrypt_data(hi_flash_crypto_content * new_content,encrypt_ctx * para)462 static hi_u32 crypto_encrypt_data(hi_flash_crypto_content *new_content, encrypt_ctx *para)
463 {
464     hi_u32 ret = HI_ERR_FAILURE;
465     hi_cipher_aes_ctrl aes_ctrl;
466 
467     hi_u8 *fw_cyp_data = hi_malloc(HI_MOD_ID_CRYPTO, para->encrypt_size);
468     if (fw_cyp_data == HI_NULL) {
469         return HI_ERR_FLASH_CRYPTO_PREPARE_ERR;
470     }
471 
472     if (memcpy_s(aes_ctrl.key, sizeof(aes_ctrl.key), new_content->work_text, KEY_BYTE_LENGTH) != EOK) {
473         goto fail;
474     }
475 
476     if (memcpy_s(aes_ctrl.iv, sizeof(aes_ctrl.iv), new_content->iv_content, IV_BYTE_LENGTH) != EOK) {
477         goto fail;
478     }
479 
480     crpto_set_aes_ctrl_default_value(&aes_ctrl);
481     ret = hi_cipher_aes_config(&aes_ctrl);
482     if (ret != HI_ERR_SUCCESS) {
483         goto fail;
484     }
485 
486     ret = hi_cipher_aes_crypto((uintptr_t)(para->raw_buf), (uintptr_t)fw_cyp_data, para->encrypt_size, HI_TRUE);
487     (hi_void) hi_cipher_aes_destroy_config();
488     if (ret != HI_ERR_SUCCESS) {
489         goto fail;
490     }
491 
492     ret = hi_flash_write(para->kernel_start + para->encrypt_offset, para->encrypt_size, fw_cyp_data, HI_TRUE);
493     if (ret != HI_ERR_SUCCESS) {
494         goto fail;
495     }
496 
497 fail:
498     crypto_mem_free(fw_cyp_data);
499     return ret;
500 }
501 
encrypt_check_start_addr(hi_u32 offset_addr)502 hi_u32 encrypt_check_start_addr(hi_u32 offset_addr)
503 {
504     hi_flash_partition_table *partition = hi_get_partition_table();
505     hi_u32 kernel_a = partition->table[HI_FLASH_PARTITON_KERNEL_A].addr;
506     hi_u32 kernel_b = partition->table[HI_FLASH_PARTITON_KERNEL_B].addr;
507 
508     if ((offset_addr != kernel_a) && (offset_addr != kernel_b)) {
509         return HI_ERR_FLASH_CRYPTO_INVALID_PARAM;
510     }
511 
512     return HI_ERR_SUCCESS;
513 }
514 
encrypt_upg_data(encrypt_ctx * para)515 hi_u32 encrypt_upg_data(encrypt_ctx *para)
516 {
517     hi_u32 ret;
518     crypto_workkey_partition werk_content;
519     crypto_workkey_partition werk_content_bak;
520     ret = crypto_content_id(para, &werk_content, &werk_content_bak);
521     if (ret != HI_ERR_SUCCESS) {
522         return ret;
523     }
524 
525     hi_flash_crypto_content *new_content = (hi_flash_crypto_content *)hi_malloc(HI_MOD_ID_CRYPTO,
526         sizeof(hi_flash_crypto_content));
527     if (new_content == HI_NULL) {
528         return HI_ERR_FLASH_CRYPTO_PREPARE_ERR;
529     }
530 
531     ret = crypto_prepare(new_content);
532     if (ret != HI_ERR_SUCCESS) {
533         crypto_clear_content((hi_u8 *)new_content, (hi_u32)sizeof(hi_flash_crypto_content));
534         crypto_mem_free(new_content);
535         return HI_ERR_FLASH_CRYPTO_PREPARE_ERR;
536     }
537 
538     ret = crypto_gen_key_content(new_content);
539     if (ret != HI_ERR_SUCCESS) {
540         goto fail;
541     }
542 
543     ret = crypto_save_work_key(werk_content, new_content);
544     if (ret != HI_ERR_SUCCESS) {
545         goto fail;
546     }
547 
548     ret = crypto_encrypt_data(new_content, para);
549     if (ret != HI_ERR_SUCCESS) {
550         goto fail;
551     }
552 
553     ret = crypto_save_work_key(werk_content_bak, new_content);
554     if (ret != HI_ERR_SUCCESS) {
555     }
556 
557 fail:
558     crypto_clear_content((hi_u8 *)new_content, (hi_u32)sizeof(hi_flash_crypto_content));
559     crypto_mem_free(new_content);
560     return ret;
561 }
562 
crypto_init_param(encrypt_ctx * para,uintptr_t kernel_start)563 hi_u32 crypto_init_param(encrypt_ctx *para, uintptr_t kernel_start)
564 {
565     hi_u32 ret;
566 
567     hi_upg_head *upg_head = (hi_upg_head *)hi_malloc(HI_MOD_ID_CRYPTO, sizeof(hi_upg_head));
568     if (upg_head == HI_NULL) {
569         return HI_ERR_UPG_CRYPTO_PREPARE_ERR;
570     }
571     ret = hi_flash_read(kernel_start, sizeof(hi_upg_head), (hi_u8 *)upg_head);
572     if (ret != HI_ERR_SUCCESS) {
573         crypto_print("[%s]get upg head addr:0x%x ret:0x%x \r\n", __FUNCTION__, kernel_start, ret);
574         goto fail;
575     }
576 
577     para->kernel_start = kernel_start;
578     para->encrypt_offset = sizeof(hi_upg_file_head);
579     para->encrypt_size = CRYPTO_KERNEL_LENGTH;
580     ret = (hi_u32)memcpy_s(para->upg_salt, IV_BYTE_LENGTH, upg_head->common.aes_key, IV_BYTE_LENGTH);
581     if (ret != EOK) {
582         goto fail;
583     }
584     ret = (hi_u32)memcpy_s(para->upg_iv, IV_BYTE_LENGTH, upg_head->common.aes_iv, IV_BYTE_LENGTH);
585     if (ret != EOK) {
586         goto fail;
587     }
588     para->raw_buf = (hi_u8 *)hi_malloc(0, para->encrypt_size);
589     if (para->raw_buf == HI_NULL) {
590         ret = HI_ERR_UPG_CRYPTO_PREPARE_ERR;
591         goto fail;
592     }
593 
594 fail:
595     crypto_mem_free(upg_head);
596     return ret;
597 }
598 
crypto_upg_file_prepare(encrypt_ctx * para)599 hi_u32 crypto_upg_file_prepare(encrypt_ctx *para)
600 {
601     hi_u32 ret;
602     hi_cipher_kdf_ctrl ctrl;
603     hi_u8 salt[ROOTKEY_IV_BYTE_LENGTH] = {0};
604 
605     ret = (hi_u32)memcpy_s((hi_void *)salt, sizeof(salt), (hi_void *)(para->upg_salt), IV_BYTE_LENGTH);
606     if (ret != EOK) {
607         return ret;
608     }
609 
610     ret = (hi_u32)memcpy_s((hi_void *)(salt + IV_BYTE_LENGTH), sizeof(salt) - IV_BYTE_LENGTH,
611         (hi_void *)g_upg_file_magic, IV_BYTE_LENGTH);
612     if (ret != EOK) {
613         return ret;
614     }
615 
616     ctrl.salt = salt;
617     ctrl.salt_len = ROOTKEY_IV_BYTE_LENGTH;
618     ctrl.kdf_cnt = ENCRYPT_KDF_ITERATION_CNT;
619     ctrl.kdf_mode = HI_CIPHER_SSS_KDF_KEY_STORAGE;
620 
621     ret = hi_cipher_kdf_key_derive(&ctrl);
622     if (ret != HI_ERR_SUCCESS) {
623         return ret;
624     }
625 
626     return HI_ERR_SUCCESS;
627 }
628 
crypto_upg_file_decrypt(encrypt_ctx * para)629 hi_u32 crypto_upg_file_decrypt(encrypt_ctx *para)
630 {
631     hi_u32 ret;
632     hi_cipher_aes_ctrl aes_ctrl;
633     hi_u8 *fw_raw_data = para->raw_buf;
634 
635     ret = crypto_upg_file_prepare(para);
636     if (ret != HI_ERR_SUCCESS) {
637         return HI_ERR_UPG_CRYPTO_PREPARE_ERR;
638     }
639 
640     ret = (hi_u32)memcpy_s(aes_ctrl.iv, sizeof(aes_ctrl.iv), para->upg_iv, IV_BYTE_LENGTH);
641     if (ret != HI_ERR_SUCCESS) {
642         goto fail;
643     }
644 
645     aes_ctrl.random_en = HI_FALSE;
646     aes_ctrl.key_from = HI_CIPHER_AES_KEY_FROM_KDF;
647     aes_ctrl.work_mode = HI_CIPHER_AES_WORK_MODE_CBC;
648     aes_ctrl.key_len = HI_CIPHER_AES_KEY_LENGTH_256BIT;
649     ret = hi_cipher_aes_config(&aes_ctrl);
650     if (ret != HI_ERR_SUCCESS) {
651         goto fail;
652     }
653 
654     ret = hi_cipher_aes_crypto(para->kernel_start + para->encrypt_offset + SFC_BUFFER_BASE_ADDRESS,
655         (uintptr_t)fw_raw_data, para->encrypt_size, HI_FALSE);
656     if (ret != HI_ERR_SUCCESS) {
657         goto crypto_fail;
658     }
659 
660 crypto_fail:
661     (hi_void) hi_cipher_aes_destroy_config();
662 fail:
663     return ret;
664 }
665 
666 
crypto_encrypt_data_to_flash(uintptr_t kernel_offset)667 hi_u32 crypto_encrypt_data_to_flash(uintptr_t kernel_offset)
668 {
669     hi_u32 ret;
670     encrypt_ctx *data = encrypt_get_ctx();
671 
672     ret = crypto_init_param(data, kernel_offset);
673     if (ret != HI_ERR_SUCCESS) {
674         goto fail;
675     }
676 
677     ret = crypto_upg_file_decrypt(data);
678     if (ret != HI_ERR_SUCCESS) {
679         goto fail;
680     }
681 
682     ret = encrypt_upg_data(data);
683     if (ret != HI_ERR_SUCCESS) {
684         goto fail;
685     }
686 
687 fail:
688     crypto_mem_free(data->raw_buf);
689     return ret;
690 }
691 
692 #endif
693