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 * Description: UPG verification functions source file
15 */
16
17 #include <string.h>
18 #include <stddef.h>
19 #include <stdint.h>
20 #include <stdbool.h>
21 #include <securec.h>
22 #include "common_def.h"
23 #include "upg_definitions.h"
24 #include "upg_otp_reg.h"
25 #include "errcode.h"
26 #include "upg_config.h"
27 #include "upg_debug.h"
28 #include "chip_io.h"
29 #include "upg_common.h"
30 #include "upg_common_porting.h"
31 #include "upg_porting.h"
32 #include "upg_alloc.h"
33 #if (UPG_CFG_VERIFICATION_MODE_RSA == YES)
34 #include "pke.h"
35 #include "cipher_api.h"
36 #elif ((UPG_CFG_VERIFICATION_MODE_ECC == YES) || (UPG_CFG_VERIFICATION_MODE_SM2_SM3 == YES))
37 #include "unified_cipher_pke.h"
38 #include "cipher.h"
39 #endif
40 #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_SAMPLE_VERIFY
41 #include "drv_flashboot_cipher.h"
42 #include "drv_rom_cipher.h"
43 #endif
44 #if (UPG_CFG_VERIFICATION_MODE_SW_HASH == YES)
45 #include "sha256/sha256.h"
46 #endif
47 #if (UPG_CFG_MEMORY_DCACHE_ENABLED == YES)
48 #include "soc_osal.h"
49 #endif
50 #include "upg_verify.h"
51 #if (UPG_CFG_VERIFICATION_SUPPORT == YES)
52
53 #define ECC_KEY_OFFSET 32
54 #define UPG_SM2_ID "\x31\x32\x33\x34\x35\x36\x37\x38\x31\x32\x33\x34\x35\x36\x37\x38"
55 #define UPG_SM2_ID_LEN 0x10
56
57 #define RSA_N_KEY_LEN 512
58 #define RSA_E_KEY_LEN 512
59 #define RSA_SIG_LEN 512
60
61 #define ECC_X_KEY_LEN 32
62 #define ECC_Y_KEY_LEN 32
63 #define ECC_KEY_LEN 32
64
65 #define ECC_R_SIG_LEN 32
66 #define ECC_S_SIG_LEN 32
67 #define ECC_SIG_LEN 32
68
69 #if (defined(CONFIG_APPS_CORE) || defined(CONFIG_MAIN_CORE))
70 #define UPG_VERIFY_CIPHER_BUF_ATTR UAPI_DRV_CIPHER_BUF_NONSECURE
71 #else
72 #define UPG_VERIFY_CIPHER_BUF_ATTR UAPI_DRV_CIPHER_BUF_SECURE
73 #endif /* CONFIG_APPS_CORE */
74
75 STATIC uapi_upg_user_defined_check g_user_defined_check_func = NULL;
76 STATIC uintptr_t g_user_defined_param = 0;
77
verify_hash_cmp(const uint8_t * hash,const uint8_t * hash_res,uint32_t hash_len)78 errcode_t verify_hash_cmp(const uint8_t *hash, const uint8_t *hash_res, uint32_t hash_len)
79 {
80 if (memcmp(hash, hash_res, hash_len) != 0) {
81 upg_log_err("[UPG] upg_verify_hash: memcmp hash fail.\r\n");
82 return ERRCODE_FAIL;
83 }
84 return ERRCODE_SUCC;
85 }
86
87 #if (UPG_CFG_VERIFICATION_MODE_SW_HASH == YES)
upg_verify_hash(uintptr_t verify_data,uint32_t verify_size,const uint8_t * hash,uint32_t hash_len)88 STATIC errcode_t upg_verify_hash(uintptr_t verify_data, uint32_t verify_size, const uint8_t *hash, uint32_t hash_len)
89 {
90 uint8_t hash_res[SHA_256_LENGTH] = {0};
91 sha256_context_t md;
92 (void)sha256_init(&md);
93 (void)SHA256Update(&md, (unsigned char *)((uintptr_t)verify_data), verify_size);
94 (void)sha256_final(&md, (unsigned char *)hash_res, SHA256_HASH_SIZE);
95
96 errcode_t ret_val = verify_hash_cmp(hash, hash_res, hash_len);
97 if (ret_val != ERRCODE_SUCC) {
98 upg_log_err("upg_verify_hash: memcmp hash fail.");
99 return ERRCODE_FAIL;
100 }
101
102 upg_log_err("upg_verify_hash image table OK");
103 return ERRCODE_SUCC;
104 }
105 #else
hash_operation(uapi_drv_cipher_buf_attr_t * src_buf,uint32_t src_len,uint8_t * data_sha,uapi_drv_cipher_hash_attr_t * hash_attr)106 STATIC errcode_t hash_operation(uapi_drv_cipher_buf_attr_t *src_buf, uint32_t src_len, uint8_t *data_sha,
107 uapi_drv_cipher_hash_attr_t *hash_attr)
108 {
109 errcode_t ret;
110 uint32_t out_length = SHA_256_LENGTH;
111
112 #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_SAMPLE_VERIFY
113 if (hash_attr->hash_type == UAPI_DRV_CIPHER_HASH_TYPE_SHA256) {
114 ret = drv_rom_cipher_sha256((uint8_t *)src_buf->virt_addr, src_len, data_sha, out_length);
115 } else if (hash_attr->hash_type == UAPI_DRV_CIPHER_HASH_TYPE_HMAC_SM3) {
116 ret = drv_rom_cipher_sm3((uint8_t *)src_buf->virt_addr, src_len, data_sha, out_length);
117 } else {
118 upg_log_err("[UPG] hash_operation fail, no support hash_type = 0x%x\r\n", hash_attr->hash_type);
119 return ERRCODE_FAIL;
120 }
121 if (ret != ERRCODE_SUCC) {
122 upg_log_err("[UPG] hash_operation: drv_rom_cipher_hash fail ret_val = 0x%x\r\n", ret);
123 }
124 return ret;
125 #else
126 uint32_t handle;
127 ret = uapi_drv_cipher_hash_start(&handle, hash_attr);
128 if (ret != ERRCODE_SUCC) {
129 upg_log_err("[UPG] uapi_drv_cipher_hash_start fail ret = 0x%x\r\n", ret);
130 return ret;
131 }
132
133 #if (UPG_CFG_MEMORY_DCACHE_ENABLED == YES)
134 osal_dcache_region_wb(NULL, (unsigned long)(uintptr_t)src_buf->address, src_len);
135 #endif
136
137 ret = uapi_drv_cipher_hash_update(handle, src_buf, src_len);
138 if (ret != ERRCODE_SUCC) {
139 upg_log_err("[UPG] uapi_drv_cipher_hash_update fail ret = 0x%x\r\n", ret);
140 uapi_drv_cipher_hash_finish(handle, data_sha, &out_length);
141 return ret;
142 }
143
144 return uapi_drv_cipher_hash_finish(handle, data_sha, &out_length);
145 #endif
146 }
147
upg_verify_hash(uintptr_t verify_data,uint32_t verify_size,const uint8_t * hash,uint32_t hash_len)148 STATIC errcode_t upg_verify_hash(uintptr_t verify_data, uint32_t verify_size, const uint8_t *hash, uint32_t hash_len)
149 {
150 uint8_t hash_res[SHA_256_LENGTH] = {0};
151
152 uapi_drv_cipher_hash_attr_t hash_attr;
153 uapi_drv_cipher_buf_attr_t src_buf;
154
155 hash_attr.hash_type = UAPI_DRV_CIPHER_HASH_TYPE_SHA256;
156 hash_attr.keyslot_handle = 0;
157 #if (UPG_CFG_VERIFICATION_MODE_ECC == YES)
158 src_buf.virt_addr = (void *)verify_data;
159 #else
160 src_buf.phys_addr = verify_data;
161 #endif
162 src_buf.buf_sec = UAPI_DRV_CIPHER_BUF_SECURE;
163
164 errcode_t ret_val = hash_operation(&src_buf, verify_size, hash_res, &hash_attr);
165 if (ret_val != ERRCODE_SUCC) {
166 upg_log_err("[UPG] upg_verify_hash: hash_operation fail ret_val = 0x%x\r\n", ret_val);
167 return ERRCODE_FAIL;
168 }
169
170 ret_val = verify_hash_cmp(hash, hash_res, hash_len);
171 if (ret_val != ERRCODE_SUCC) {
172 upg_log_err("[UPG] upg_verify_hash: memcmp hash fail.\r\n");
173 return ERRCODE_FAIL;
174 }
175
176 return ERRCODE_SUCC;
177 }
178
calc_hash_by_type(uint32_t src_addr,uint32_t src_len,uint8_t * data_sha,uint32_t data_sha_len,uapi_drv_cipher_hash_type_t hash_type)179 STATIC errcode_t calc_hash_by_type(uint32_t src_addr, uint32_t src_len, uint8_t *data_sha,
180 uint32_t data_sha_len, uapi_drv_cipher_hash_type_t hash_type)
181 {
182 uapi_drv_cipher_hash_attr_t hash_attr;
183 uapi_drv_cipher_buf_attr_t src_buf;
184
185 if (data_sha_len != SHA_256_LENGTH) {
186 return ERRCODE_FAIL;
187 }
188
189 hash_attr.hash_type = hash_type;
190 hash_attr.keyslot_handle = 0;
191
192 #if (UPG_CFG_VERIFICATION_MODE_ECC == YES)
193 src_buf.virt_addr = (void *)src_addr;
194 #else
195 src_buf.phys_addr = (uintptr_t)src_addr;
196 #endif
197 src_buf.buf_sec = UAPI_DRV_CIPHER_BUF_SECURE;
198
199 return hash_operation(&src_buf, src_len, data_sha, &hash_attr);
200 }
201
calc_hash(uint32_t src_addr,uint32_t src_len,uint8_t * data_sha,uint32_t data_sha_len)202 errcode_t calc_hash(uint32_t src_addr, uint32_t src_len, uint8_t *data_sha,
203 uint32_t data_sha_len)
204 {
205 return calc_hash_by_type(src_addr, src_len, data_sha, data_sha_len, UAPI_DRV_CIPHER_HASH_TYPE_SHA256);
206 }
207
208 #if (UPG_CFG_VERIFICATION_MODE_SM2_SM3 == YES) // SM2&SM3
209
verify_signature(const uapi_drv_cipher_pke_data_t * data,uapi_drv_cipher_pke_ecc_point_t * pub_key,const uapi_drv_cipher_pke_ecc_sig_t * sign)210 STATIC errcode_t verify_signature(const uapi_drv_cipher_pke_data_t *data, uapi_drv_cipher_pke_ecc_point_t *pub_key,
211 const uapi_drv_cipher_pke_ecc_sig_t *sign)
212 {
213 uint8_t data_hash[SHA_256_LENGTH];
214 uapi_drv_cipher_pke_data_t hash;
215 uapi_drv_cipher_pke_data_t sm2_id;
216 uapi_drv_cipher_pke_msg_t pke_msg;
217 uapi_drv_cipher_pke_ecc_curve_type_t curve_type = UAPI_DRV_CIPHER_PKE_ECC_TYPE_SM2;
218 int32_t ret = ERRCODE_FAIL;
219 /* Initialise hash arrays and structs */
220 ret = memset_s(data_hash, SHA_256_LENGTH, 0x5a, SHA_256_LENGTH);
221
222 hash.data = data_hash;
223 hash.length = SHA_256_LENGTH;
224
225 #if (UPG_CFG_VERIFICATION_MODE_SM3_ONLY == YES)
226 uapi_drv_cipher_hash_type_t hash_type = UAPI_DRV_CIPHER_HASH_TYPE_SM3;
227 ret = calc_hash_by_type((uintptr_t)data->data, data->length, data_hash, SHA_256_LENGTH, hash_type);
228 if (ret != ERRCODE_SUCC) {
229 upg_log_err("[UPG] sm3 calc_hash fail ret = 0x%x\r\n", ret);
230 return ret;
231 }
232 return verify_hash_cmp((uint8_t *)sign, data_hash, SHA_256_LENGTH);
233 #endif
234 sm2_id.data = (uint8_t *)UPG_SM2_ID;
235 sm2_id.length = UPG_SM2_ID_LEN;
236 pke_msg.data = data->data;
237 pke_msg.length = data->length;
238 pke_msg.buf_sec = UAPI_DRV_CIPHER_PKE_BUF_SECURE;
239 ret = uapi_drv_cipher_pke_sm2_dsa_hash(&sm2_id, pub_key, &pke_msg, &hash);
240 if (ret != ERRCODE_SUCC) {
241 upg_log_err("[UPG] calc_hash fail ret = 0x%x\r\n", ret);
242 return ret;
243 }
244
245 return uapi_drv_cipher_pke_ecdsa_verify(curve_type, pub_key, &hash, sign);
246 }
247
248 #elif (UPG_CFG_VERIFICATION_MODE_ECC == YES) // ECC
verify_signature(const uapi_drv_cipher_pke_data_t * data,uapi_drv_cipher_pke_ecc_point_t * pub_key,const uapi_drv_cipher_pke_ecc_sig_t * sign)249 STATIC errcode_t verify_signature(const uapi_drv_cipher_pke_data_t *data, uapi_drv_cipher_pke_ecc_point_t *pub_key,
250 const uapi_drv_cipher_pke_ecc_sig_t *sign)
251 {
252 uint8_t data_hash[SHA_256_LENGTH];
253 uapi_drv_cipher_pke_data_t hash;
254 uapi_drv_cipher_hash_type_t hash_type = UAPI_DRV_CIPHER_HASH_TYPE_SHA256;
255 int32_t ret = ERRCODE_FAIL;
256 /* Initialise hash arrays and structs */
257 memset_s(data_hash, SHA_256_LENGTH, 0x5a, SHA_256_LENGTH);
258
259 hash.data = data_hash;
260 hash.length = SHA_256_LENGTH;
261
262 ret = calc_hash_by_type((uintptr_t)data->data, data->length, data_hash, SHA_256_LENGTH, hash_type);
263 #if (UPG_CFG_VERIFICATION_MODE_SHA256_ONLY == YES)
264 if (ret != ERRCODE_SUCC) {
265 upg_log_err("[UPG] sha 256 calc_hash fail ret = 0x%x\r\n", ret);
266 return ret;
267 }
268 return verify_hash_cmp((uint8_t *)sign, data_hash, SHA_256_LENGTH);
269 #endif
270
271 if (ret != ERRCODE_SUCC) {
272 upg_log_err("[UPG] calc_hash fail ret = 0x%x\r\n", ret);
273 return ret;
274 }
275
276 #ifdef CONFIG_MIDDLEWARE_SUPPORT_UPG_SAMPLE_VERIFY
277 return drv_rom_cipher_pke_bp256r_verify((drv_rom_cipher_ecc_point *)pub_key,
278 (drv_rom_cipher_data *)&hash, (drv_rom_cipher_ecc_sig *)sign);
279 #else
280 return uapi_drv_cipher_pke_ecdsa_verify(UAPI_DRV_CIPHER_PKE_ECC_TYPE_RFC5639_P256, pub_key, &hash, sign);
281 #endif
282 }
283 #elif (UPG_CFG_VERIFICATION_MODE_RSA == YES) // RSA
verify_signature(const uapi_drv_cipher_pke_data_t * data,uapi_drv_cipher_pke_rsa_pub_key_t * pub_key,const uapi_drv_cipher_pke_data_t * sign)284 STATIC errcode_t verify_signature(const uapi_drv_cipher_pke_data_t *data, uapi_drv_cipher_pke_rsa_pub_key_t *pub_key,
285 const uapi_drv_cipher_pke_data_t *sign)
286 {
287 uint8_t data_hash[SHA_256_LENGTH];
288 uapi_drv_cipher_pke_data_t hash;
289 uapi_drv_cipher_pke_rsa_pub_key_t pub_key_tmp = {0};
290
291 uapi_drv_cipher_pke_rsa_scheme_t scheme = UAPI_DRV_CIPHER_PKE_RSA_SCHEME_PKCS1_V21;
292 errcode_t ret = ERRCODE_SUCC;
293
294 /* Initialise hash arrays and structs */
295 (void)memset_s(data_hash, sizeof(data_hash), 0x5a, SHA_256_LENGTH);
296
297 hash.data = data_hash;
298 hash.length = SHA_256_LENGTH;
299
300 ret = calc_hash((uintptr_t)data->data, data->length, data_hash, SHA_256_LENGTH);
301 if (ret != ERRCODE_SUCC) {
302 upg_log_err("[UPG] calc_hash fail ret = 0x%x\r\n", ret);
303 return ret;
304 }
305
306 uint8_t *e_in = upg_malloc(RSA_E_KEY_LEN);
307 if (e_in == NULL) {
308 return ERRCODE_MALLOC;
309 }
310 uint8_t e_value[] = {0x0, 0x1, 0x0, 0x1};
311 uint32_t offset = RSA_E_KEY_LEN - (uint32_t)sizeof(e_value);
312 memset_s(e_in, RSA_N_KEY_LEN, 0, RSA_N_KEY_LEN);
313 memcpy_s(e_in + offset, RSA_E_KEY_LEN - offset, e_value, sizeof(e_value));
314 pub_key_tmp.len = pub_key->len;
315 pub_key_tmp.n = pub_key->n;
316 pub_key_tmp.e = e_in;
317
318 ret = uapi_drv_cipher_pke_rsa_verify(&pub_key_tmp, scheme, UAPI_DRV_CIPHER_PKE_HASH_TYPE_SHA256, &hash, sign);
319 if (ret != ERRCODE_SUCC) {
320 upg_free(e_in);
321 upg_log_err("[UPG] uapi_drv_cipher_pke_rsa_verify fail ret = 0x%x\r\n", ret);
322 return ret;
323 }
324
325 upg_log_info("[UPG] verify_signature success\r\n");
326 upg_free(e_in);
327 return ret;
328 }
329
secure_authenticate(const uint8_t * key,const upg_auth_data_t * data,uint8_t * sign_buff)330 errcode_t secure_authenticate(const uint8_t *key, const upg_auth_data_t *data, uint8_t *sign_buff)
331 {
332 volatile errcode_t ret = ERRCODE_FAIL;
333 uapi_drv_cipher_pke_rsa_pub_key_t pub_key;
334 uapi_drv_cipher_pke_data_t sign;
335
336 if ((key == NULL) || (data == NULL) || (sign_buff == NULL)) {
337 return ERRCODE_FAIL;
338 }
339
340 pub_key.n = (uint8_t *)key;
341 pub_key.e = (uint8_t *)key + RSA_N_KEY_LEN;
342 pub_key.len = RSA_N_KEY_LEN;
343 sign.data = sign_buff;
344 sign.length = RSA_SIG_LEN;
345
346 ret = verify_signature((const uapi_drv_cipher_pke_data_t *)data, &pub_key, &sign);
347 if (ret != ERRCODE_SUCC) {
348 upg_log_err("[UPG] verify_signature is fail, ret = 0x%x\r\n", ret);
349 }
350
351 return ret;
352 }
353
verify_fota_key_area(uint32_t type,upg_key_area_data_t * key_area,uint8_t * public_key)354 STATIC errcode_t verify_fota_key_area(uint32_t type, upg_key_area_data_t *key_area, uint8_t *public_key)
355 {
356 unused(type);
357 if (key_area->signature_length == SHA_256_LENGTH) {
358 upg_log_info("[UPG] verify_fota_key_area -> verify SHA256\r\n");
359 uint32_t key_area_len = (uint32_t)sizeof(upg_key_area_data_t) - RSA_SIG_LEN;
360 return upg_verify_hash((uintptr_t)key_area, key_area_len, key_area->sig_fota_key_area, SHA_256_LENGTH);
361 }
362 upg_log_info("[UPG] verify_fota_key_area -> verify signed\r\n");
363 uapi_drv_cipher_pke_data_t data;
364
365 /* Verify app key area with flash root public key */
366 data.data = (uint8_t *)key_area;
367 data.length = (uint32_t)sizeof(upg_key_area_data_t) - RSA_SIG_LEN;
368
369 return secure_authenticate(public_key, (upg_auth_data_t *)&data, key_area->sig_fota_key_area);
370 }
371 #endif
372 #endif /* #if UPG_CFG_VERIFICATION_MODE_SW_HASH */
373
374 #if (UPG_CFG_VERIFICATION_MODE_ECC == YES || UPG_CFG_VERIFICATION_MODE_SM2_SM3 == YES)
secure_authenticate(const uint8_t * key,const upg_auth_data_t * data,uint8_t * sign_buff)375 errcode_t secure_authenticate(const uint8_t *key, const upg_auth_data_t *data, uint8_t *sign_buff)
376 {
377 volatile errcode_t ret = ERRCODE_FAIL;
378 uapi_drv_cipher_pke_ecc_point_t pub_key;
379 uapi_drv_cipher_pke_ecc_sig_t sign;
380
381 if ((key == NULL) || (data == NULL) || (sign_buff == NULL)) {
382 return ERRCODE_FAIL;
383 }
384 pub_key.x = (uint8_t *)key;
385 pub_key.y = (uint8_t *)key + ECC_X_KEY_LEN;
386 pub_key.length = ECC_KEY_LEN;
387 sign.r = sign_buff;
388 sign.s = sign_buff + ECC_R_SIG_LEN;
389 sign.length = ECC_SIG_LEN;
390
391 ret = verify_signature((uapi_drv_cipher_pke_data_t *)data, &pub_key, &sign);
392 if (ret != ERRCODE_SUCC) {
393 upg_log_err("[UPG] verify_signature is fail, ret = 0x%x\r\n", ret);
394 }
395 return ret;
396 }
397
verify_fota_key_area(uint32_t type,upg_key_area_data_t * key_area,uint8_t * public_key)398 STATIC errcode_t verify_fota_key_area(uint32_t type, upg_key_area_data_t *key_area, uint8_t *public_key)
399 {
400 unused(type);
401 upg_auth_data_t data;
402 if (key_area->signature_length == SHA_256_LENGTH) {
403 upg_log_info("[UPG] verify_fota_key_area -> verify SHA256\r\n");
404 uint32_t key_area_len = (uint32_t)sizeof(upg_key_area_data_t) - SIG_LEN;
405 return upg_verify_hash((uintptr_t)key_area, key_area_len, key_area->sig_fota_key_area, SHA_256_LENGTH);
406 }
407 /* Verify app key area with flash root public key */
408 data.data = (uint8_t *)key_area;
409 data.length = sizeof(upg_key_area_data_t) - SIG_LEN;
410
411 return secure_authenticate(public_key, &data, key_area->sig_fota_key_area);
412 }
413 #endif
414
verify_fota_info(uint32_t type,upg_fota_info_data_t * fota_info,uint8_t * public_key)415 STATIC errcode_t verify_fota_info(uint32_t type, upg_fota_info_data_t *fota_info, uint8_t *public_key)
416 {
417 unused(type);
418 if (fota_info->signature_length == SHA_256_LENGTH) {
419 upg_log_info("[UPG] verify_fota_info -> verify SHA256\r\n");
420 uint32_t fota_info_len = (uint32_t)sizeof(upg_fota_info_data_t) - SIG_LEN;
421 return upg_verify_hash((uintptr_t)fota_info, fota_info_len, fota_info->sign_fota_info, SHA_256_LENGTH);
422 }
423 #if (UPG_CFG_INTEGRITY_VERIFICATION_ONLY == YES)
424 unused(public_key);
425 return ERRCODE_SUCC;
426 #else
427 upg_log_info("[UPG] verify_fota_info -> verify signed\r\n");
428 upg_auth_data_t data;
429
430 data.data = (uint8_t *)fota_info;
431 data.length = (uint32_t)sizeof(upg_fota_info_data_t) - SIG_LEN;
432
433 return secure_authenticate(public_key, &data, fota_info->sign_fota_info);
434 #endif
435 }
436
upg_check_fota_image_id(const upg_key_area_data_t * upg_key_info,const upg_fota_info_data_t * fota_info)437 STATIC errcode_t upg_check_fota_image_id(const upg_key_area_data_t *upg_key_info, const upg_fota_info_data_t *fota_info)
438 {
439 if (upg_key_info->image_id != UPG_IMAGE_ID_KEY_AREA) {
440 return ERRCODE_FAIL;
441 }
442 if (fota_info->image_id != UPG_IMAGE_ID_FOTA_INFO_AREA) {
443 return ERRCODE_FAIL;
444 }
445 return ERRCODE_SUCC;
446 }
447
uapi_upg_register_user_defined_verify_func(uapi_upg_user_defined_check func,uintptr_t param)448 void uapi_upg_register_user_defined_verify_func(uapi_upg_user_defined_check func, uintptr_t param)
449 {
450 g_user_defined_check_func = func;
451 g_user_defined_param = param;
452 }
453
454 #if (UPG_CFG_INTEGRITY_VERIFICATION_ONLY == NO)
455 /*
456 步骤一,使用Root_Public_Key校验Key Area的签名
457 步骤二,使用存储在升级包Key Area的FOTA_External_Public_Key校验FOTA Info区签名
458 步骤三,如用户注册了定义字段的校验函数,则校验自定义字段(user_defined),如未注册,此步骤默认校验通过
459 */
uapi_upg_verify_file_head(const upg_package_header_t * pkg_header)460 errcode_t uapi_upg_verify_file_head(const upg_package_header_t *pkg_header)
461 {
462 upg_key_area_data_t *key_area = (upg_key_area_data_t *)&(pkg_header->key_area);
463 uint32_t type = key_area->image_id;
464 uint8_t *public_key = NULL;
465
466 if (upg_is_inited() == false) {
467 return ERRCODE_UPG_NOT_INIT;
468 }
469
470 public_key = upg_get_root_public_key();
471 if (public_key == NULL) {
472 return ERRCODE_UPG_VERIFICATION_KEY_ERROR;
473 }
474
475 upg_fota_info_data_t *fota_info = (upg_fota_info_data_t *)&(pkg_header->info_area);
476
477 errcode_t ret = upg_check_fota_image_id(key_area, fota_info);
478 if (ret != ERRCODE_SUCC) {
479 /* image id 不正确就不用校验了,直接返回失败 */
480 upg_log_err("[UPG] upg verify: image ID error\r\n");
481 return ret;
482 }
483
484 /* 步骤一 */
485 ret = verify_fota_key_area(type, key_area, public_key);
486 if (ret != ERRCODE_SUCC) {
487 upg_log_err("[UPG] upg verify: key area error. ret = 0x%x\r\n", ret);
488 return ret;
489 }
490
491 /* 步骤二 */
492 ret = verify_fota_info(fota_info->image_id, fota_info, key_area->fota_external_public_key);
493 if (ret != ERRCODE_SUCC) {
494 upg_log_err("[UPG] upg verify: fota info error. ret = 0x%x\r\n", ret);
495 return ret;
496 }
497
498 ret = upg_check_fota_information(pkg_header);
499 if (ret != ERRCODE_SUCC) {
500 upg_log_err("[UPG] upg verify: upg_check_fota_information. ret = 0x%x\r\n", ret);
501 return ret;
502 }
503
504 /* 步骤三 */
505 if (g_user_defined_check_func != NULL) {
506 ret = g_user_defined_check_func(fota_info->user_defined, sizeof(fota_info->user_defined), g_user_defined_param);
507 }
508
509 return ret;
510 }
511 #endif
512
uapi_upg_verify_image(const upg_package_header_t * pkg_header,upg_image_hash_node_t * img_hash_table)513 STATIC errcode_t uapi_upg_verify_image(const upg_package_header_t *pkg_header, upg_image_hash_node_t *img_hash_table)
514 {
515 errcode_t ret = ERRCODE_SUCC;
516 upg_image_header_t *img_header = NULL;
517 upg_fota_info_data_t *fota_info = (upg_fota_info_data_t *)&(pkg_header->info_area);
518 for (uint32_t i = 0; i < fota_info->image_num; i++) {
519 ret = upg_get_pkg_image_header((const upg_image_hash_node_t *)&(img_hash_table[i]), &img_header);
520 if (ret != ERRCODE_SUCC || img_header == NULL) {
521 upg_log_err("[UPG] upg_get_pkg_image_header fail\r\n");
522 break;
523 }
524
525 ret = uapi_upg_verify_file_image((const upg_image_header_t *)img_header,
526 (const uint8_t *)img_hash_table[i].image_hash, SHA_256_LENGTH, true);
527 if (ret != ERRCODE_SUCC) {
528 break;
529 }
530 /* 步骤八:校验防回滚版本号,只有镜像中的防回滚版本号大于等于OTP中的防回滚版本号时才能升级 */
531 #if (UPG_CFG_ANTI_ROLLBACK_SUPPORT == YES)
532 ret = upg_anti_rollback_version_verify(pkg_header, img_header);
533 if (ret != ERRCODE_SUCC) {
534 upg_set_temporary_result(UPG_RESULT_VERIFY_VERSION_FAILED);
535 break;
536 }
537 #endif
538 upg_free(img_header);
539 img_header = NULL;
540 }
541 upg_free(img_header);
542 return ret;
543 }
544
545 /*
546 步骤一,使用Root_Public_Key校验Key Area的签名
547 步骤二,使用存储在升级包Key Area的FOTA_External_Public_Key校验FOTA Info区签名
548 步骤三,如用户注册了定义字段的校验函数,则校验自定义字段(user_defined),如未注册,此步骤默认校验通过
549 步骤四,使用存储在FOTA Info区的Image_Hash_Table中的HASH值,校验Image_Hash_Table
550 步骤五,使用保存在Image_Hash_Table中的每个镜像Header的HASH值校验对应的Image_Header
551 步骤六:使用保存在Image_Header中的新镜像HASH值校验对应的新镜像。
552 步骤七,如果为差分升级,镜像的Image_Header中保存了旧版本镜像的HASH值,根据这个HASH值校验flash上的旧镜像是否是制作差分包
553 时用的旧镜像。非差分镜像,可忽略此步骤
554 步骤八,校验防回滚版本号,只有镜像中的防回滚版本号大于等于OTP中的防回滚版本号时才能升级
555 */
uapi_upg_verify_file(const upg_package_header_t * pkg_header)556 errcode_t uapi_upg_verify_file(const upg_package_header_t *pkg_header)
557 {
558 upg_image_hash_node_t *img_hash_table = NULL;
559
560 if (upg_is_inited() == false) {
561 return ERRCODE_UPG_NOT_INIT;
562 }
563
564 /* 步骤一,步骤二,步骤三 */
565 errcode_t ret = uapi_upg_verify_file_head(pkg_header);
566 if (ret != ERRCODE_SUCC) {
567 upg_set_temporary_result(UPG_RESULT_VERIFY_HEAD_FAILED);
568 return ret;
569 }
570 upg_log_info("[UPG] upg verify head OK\r\n");
571
572 ret = upg_get_pkg_image_hash_table(pkg_header, &img_hash_table);
573 if (ret != ERRCODE_SUCC || img_hash_table == NULL) {
574 upg_log_err("[UPG] upg_get_pkg_image_hash_table fail\r\n");
575 return ret;
576 }
577
578 upg_fota_info_data_t *fota_info = (upg_fota_info_data_t *)&(pkg_header->info_area);
579 /* 步骤四 使用存储在FOTA Info区的Image_Hash_Table中的HASH值,校验Image_Hash_Table */
580 /* 由于ImageHashTable为了16字节对齐有填充字段,此处的长度不能使用image_num * sizeof(upg_image_hash_node_t)) */
581 ret = upg_verify_hash((uintptr_t)img_hash_table, fota_info->image_hash_table_length,
582 fota_info->image_hash_table_hash, sizeof(fota_info->image_hash_table_hash));
583 if (ret != ERRCODE_SUCC) {
584 upg_set_temporary_result(UPG_RESULT_VERIFY_HASH_TABLE_FAILED);
585 upg_free(img_hash_table);
586 return ret;
587 }
588 upg_log_info("[UPG] upg_verify_hash image table OK\r\n");
589 /* 循环遍历校验每个升级image
590 步骤五至八
591 */
592 ret = uapi_upg_verify_image(pkg_header, img_hash_table);
593 upg_free(img_hash_table);
594 return ret;
595 }
596
597 #if (UPG_CFG_DIRECT_FLASH_ACCESS == NO)
598 #if (UPG_CFG_VERIFICATION_MODE_SW_HASH == NO)
upg_verify_image_multi_segment_data(const upg_image_header_t * img_header)599 STATIC errcode_t upg_verify_image_multi_segment_data(const upg_image_header_t *img_header)
600 {
601 errcode_t ret_val;
602 uint32_t handle;
603 uint32_t out_length = SHA_256_LENGTH;
604 uapi_drv_cipher_hash_attr_t hash_attr = {NULL, 0, 0, UAPI_DRV_CIPHER_HASH_TYPE_SHA256, 0, 0};
605 uapi_drv_cipher_buf_attr_t src_buf;
606 uint32_t read_len;
607 uint32_t image_offset = 0;
608 uint8_t data_sha[SHA_256_LENGTH] = {0};
609 uint32_t aligned_image_len = upg_aligned(img_header->image_len, 16); /* 16-byte alignment */
610
611 ret_val = uapi_drv_cipher_hash_start(&handle, &hash_attr);
612 if (ret_val != ERRCODE_SUCC) {
613 upg_log_err("[UPG] uapi_drv_cipher_hash_start fail\r\n");
614 return ret_val;
615 }
616
617 uint8_t *image_data = (uint8_t *)upg_malloc(VERIFY_BUFF_LEN);
618 if (image_data == NULL) {
619 return ERRCODE_MALLOC;
620 }
621
622 do {
623 read_len = (image_offset + VERIFY_BUFF_LEN < aligned_image_len) ?
624 VERIFY_BUFF_LEN : (aligned_image_len - image_offset);
625
626 ret_val = upg_copy_pkg_image_data(img_header, image_offset, &read_len, image_data);
627 if (ret_val != ERRCODE_SUCC) {
628 upg_free(image_data);
629 return ret_val;
630 }
631
632 src_buf.phys_addr = (uintptr_t)image_data;
633 src_buf.buf_sec = UAPI_DRV_CIPHER_BUF_SECURE;
634
635 ret_val = uapi_drv_cipher_hash_update(handle, &src_buf, read_len);
636 if (ret_val != ERRCODE_SUCC) {
637 upg_free(image_data);
638 return ret_val;
639 }
640 image_offset += read_len;
641 } while (image_offset < aligned_image_len);
642
643 upg_free(image_data);
644
645 ret_val = uapi_drv_cipher_hash_finish(handle, data_sha, &out_length);
646 if (ret_val != ERRCODE_SUCC) {
647 return ret_val;
648 }
649
650 return verify_hash_cmp(img_header->image_hash, data_sha, SHA_256_LENGTH);
651 }
652 #else
upg_verify_image_multi_segment_data(const upg_image_header_t * img_header)653 STATIC errcode_t upg_verify_image_multi_segment_data(const upg_image_header_t *img_header)
654 {
655 errcode_t ret_val;
656 uint32_t out_length = SHA_256_LENGTH;
657 uint32_t read_len;
658 uint32_t image_offset = 0;
659 uint8_t data_sha[SHA_256_LENGTH] = {0};
660 sha256_context_t md;
661 (void)sha256_init(&md);
662 uint32_t aligned_image_len = upg_aligned(img_header->image_len, 16); /* 16-byte alignment */
663 uint8_t *image_data = (uint8_t *)upg_malloc(VERIFY_BUFF_LEN);
664
665 if (image_data == NULL) {
666 return ERRCODE_MALLOC;
667 }
668
669 do {
670 read_len = (image_offset + VERIFY_BUFF_LEN < aligned_image_len) ?
671 VERIFY_BUFF_LEN : (aligned_image_len - image_offset);
672
673 ret_val = upg_copy_pkg_image_data(img_header, image_offset, &read_len, image_data);
674 if (ret_val != ERRCODE_SUCC) {
675 upg_free(image_data);
676 return ret_val;
677 }
678 (void)SHA256Update(&md, (unsigned char *)((uintptr_t)image_data), read_len);
679 image_offset += read_len;
680 } while (image_offset < aligned_image_len);
681 upg_free(image_data);
682 (void)sha256_final(&md, (unsigned char *)data_sha, out_length);
683 return verify_hash_cmp(img_header->image_hash, data_sha, SHA_256_LENGTH);
684 }
685 #endif /* #if UPG_CFG_VERIFICATION_MODE_SW_HASH */
686 #endif /* #if UPG_CFG_DIRECT_FLASH_ACCESS */
687
upg_verify_image_data(const upg_image_header_t * img_header)688 STATIC errcode_t upg_verify_image_data(const upg_image_header_t *img_header)
689 {
690 #if (UPG_CFG_DIRECT_FLASH_ACCESS == NO)
691 return upg_verify_image_multi_segment_data(img_header);
692 #else
693 uint8_t *image_data = NULL;
694 errcode_t ret;
695 uint32_t aligned_image_len = upg_aligned(img_header->image_len, 16); /* 16-byte alignment */
696 ret = upg_get_pkg_image_data(img_header, 0, &aligned_image_len, &image_data);
697 if (ret != ERRCODE_SUCC || image_data == NULL) {
698 return ret;
699 }
700
701 ret = upg_verify_hash((uintptr_t)image_data, aligned_image_len,
702 img_header->image_hash, sizeof(img_header->image_hash));
703 if (ret != ERRCODE_SUCC) {
704 return ret;
705 }
706 return ERRCODE_SUCC;
707 #endif /* #if UPG_CFG_DIRECT_FLASH_ACCESS */
708 }
709
710 #if (UPG_CFG_DIFF_UPGRADE_SUPPORT == YES)
upg_verify_old_image(const upg_image_header_t * img_header)711 STATIC errcode_t upg_verify_old_image(const upg_image_header_t *img_header)
712 {
713 errcode_t ret;
714 uint32_t handle;
715 uint32_t out_length = SHA_256_LENGTH;
716 uapi_drv_cipher_hash_attr_t hash_attr = { .hash_type = UAPI_DRV_CIPHER_HASH_TYPE_SHA256 };
717 uapi_drv_cipher_buf_attr_t src_buf;
718 uint32_t read_len;
719 uint32_t image_offset = 0;
720 uint8_t data_sha[SHA_256_LENGTH] = {0};
721 uint32_t image_len = img_header->old_image_len;
722
723 ret = uapi_drv_cipher_hash_start(&handle, &hash_attr);
724 if (ret != ERRCODE_SUCC) {
725 upg_log_err("[UPG] uapi_drv_cipher_hash_start fail\r\n");
726 return ret;
727 }
728
729 uint8_t *old_image_data = (uint8_t *)upg_malloc(VERIFY_BUFF_LEN);
730 if (old_image_data == NULL) {
731 return ERRCODE_MALLOC;
732 }
733
734 do {
735 read_len = (image_offset + VERIFY_BUFF_LEN < image_len) ?
736 VERIFY_BUFF_LEN : (image_len - image_offset);
737
738 ret = upg_read_old_image_data(image_offset, old_image_data, &read_len, img_header->image_id);
739 if (ret != ERRCODE_SUCC) {
740 upg_free(old_image_data);
741 return ret;
742 }
743
744 src_buf.phys_addr = (uintptr_t)old_image_data;
745 src_buf.buf_sec = UPG_VERIFY_CIPHER_BUF_ATTR;
746
747 ret = uapi_drv_cipher_hash_update(handle, &src_buf, read_len);
748 if (ret != ERRCODE_SUCC) {
749 upg_free(old_image_data);
750 return ret;
751 }
752 image_offset += read_len;
753 } while (image_offset < image_len);
754
755 upg_free(old_image_data);
756
757 ret = uapi_drv_cipher_hash_finish(handle, data_sha, &out_length);
758 if (ret != ERRCODE_SUCC) {
759 return ret;
760 }
761
762 return verify_hash_cmp(img_header->old_image_hash, data_sha, SHA_256_LENGTH);
763 }
764 #endif
765 /*
766 步骤五,使用保存在Image_Hash_Table中的每个镜像Header的HASH值校验对应的Image_Header
767 步骤六:使用保存在Image_Header中的新镜像HASH值校验对应的新镜像。
768 步骤七,如果为差分升级,镜像的Image_Header中保存了旧版本镜像的HASH值,根据这个HASH值校验flash上的旧镜像是否是制作差分包
769 时用的旧镜像。非差分镜像,可忽略此步骤
770 步骤八,校验防回滚版本号,只有镜像中的防回滚版本号大于等于OTP中的防回滚版本号时才能升级
771 */
uapi_upg_verify_file_image(const upg_image_header_t * img_header,const uint8_t * hash,uint32_t hash_len,bool verify_old)772 errcode_t uapi_upg_verify_file_image(const upg_image_header_t *img_header,
773 const uint8_t *hash, uint32_t hash_len, bool verify_old)
774 {
775 uint32_t ret;
776 UNUSED(verify_old);
777 /* 校验HeaderMagic有效性 */
778 if (img_header->header_magic != UPG_IMAGE_HRADER_MAGIC) {
779 upg_log_err("[UPG] upg verify: file image check error. header_magic = 0x%x\r\n", img_header->header_magic);
780 upg_set_temporary_result(UPG_RESULT_VERIFY_IMAGE_FAILED);
781 return ERRCODE_FAIL;
782 }
783 /* 步骤五: 使用保存在Image_Hash_Table中的每个镜像Header的HASH值校验对应的Image_Header */
784 ret = upg_verify_hash((uintptr_t)img_header, sizeof(upg_image_header_t), hash, hash_len);
785 if (ret != ERRCODE_SUCC) {
786 upg_set_temporary_result(UPG_RESULT_VERIFY_IMAGE_FAILED);
787 return ret;
788 }
789
790 /* 步骤六: 使用保存在Image_Header中的新镜像HASH值校验对应的新镜像。 */
791 ret = upg_verify_image_data(img_header);
792 if (ret != ERRCODE_SUCC) {
793 upg_set_temporary_result(UPG_RESULT_VERIFY_IMAGE_FAILED);
794 return ret;
795 }
796
797 /* 步骤七:如果为差分升级,镜像的Image_Header中保存了旧版本镜像的HASH值,根据这个HASH值校验flash上的旧镜像是否是制作差分包
798 时用的旧镜像。非差分镜像,可忽略此步骤
799 */
800 #if (UPG_CFG_DIFF_UPGRADE_SUPPORT == YES)
801 if (verify_old && img_header->decompress_flag == DECOMPRESS_FLAG_DIFF) {
802 ret = upg_verify_old_image(img_header);
803 if (ret != ERRCODE_SUCC) {
804 upg_set_temporary_result(UPG_RESULT_VERIFY_OLD_IMAGE_FAILED);
805 return ret;
806 }
807 }
808 #endif
809 upg_log_info("[UPG] upg verify: image check OK. image_id = 0x%x\r\n", img_header->image_id);
810 /* 步骤八:校验防回滚版本号,只有镜像中的防回滚版本号大于等于OTP中的防回滚版本号时才能升级 */
811 return ERRCODE_SUCC;
812 }
813
uapi_upg_check_head_integrity(const upg_package_header_t * pkg_header)814 errcode_t uapi_upg_check_head_integrity(const upg_package_header_t *pkg_header)
815 {
816 upg_key_area_data_t *key_area = (upg_key_area_data_t *)&(pkg_header->key_area);
817 upg_fota_info_data_t *fota_info = (upg_fota_info_data_t *)&(pkg_header->info_area);
818 upg_image_hash_node_t *img_hash_table = NULL;
819
820 if (upg_is_inited() == false) {
821 return ERRCODE_UPG_NOT_INIT;
822 }
823
824 errcode_t ret = upg_check_fota_image_id(key_area, fota_info);
825 if (ret != ERRCODE_SUCC) {
826 /* image id 不正确就不用校验了,直接返回失败 */
827 upg_log_err("[UPG] upg verify: image ID error\r\n");
828 return ret;
829 }
830
831 /* 校验FOTA info */
832 ret = verify_fota_info(fota_info->image_id, fota_info, key_area->fota_external_public_key);
833 if (ret != ERRCODE_SUCC) {
834 upg_log_err("[UPG] upg verify: fota info error. ret = 0x%x\r\n", ret);
835 return ret;
836 }
837
838 ret = upg_get_pkg_image_hash_table(pkg_header, &img_hash_table);
839 if (ret != ERRCODE_SUCC || img_hash_table == NULL) {
840 upg_log_err("[UPG] upg_get_pkg_image_hash_table fail\r\n");
841 return ret;
842 }
843
844 /* 步骤四 使用存储在FOTA Info区的Image_Hash_Table中的HASH值,校验Image_Hash_Table */
845 /* 由于ImageHashTable为了16字节对齐有填充字段,此处的长度不能使用image_num * sizeof(upg_image_hash_node_t)) */
846 ret = upg_verify_hash((uintptr_t)img_hash_table,
847 fota_info->image_hash_table_length,
848 fota_info->image_hash_table_hash,
849 sizeof(fota_info->image_hash_table_hash));
850 if (ret != ERRCODE_SUCC) {
851 upg_free(img_hash_table);
852 upg_log_err("[UPG] upg verify: verify hash table failed. ret = 0x%x\r\n", ret);
853 return ret;
854 }
855
856 upg_free(img_hash_table);
857 return ERRCODE_SUCC;
858 }
859 #endif
860