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