• 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  * 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