• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
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 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include "hvb.h"
19 #include "hvb_util.h"
20 #include "hvb_crypto.h"
21 #include "hvb_sysdeps.h"
22 #include "hvb_cert.h"
23 #include "hvb_sm2.h"
24 #include "hvb_sm3.h"
25 
26 #define SM2_KEY_X_LEN SM2_KEY_LEN
27 #define SM2_KEY_Y_LEN SM2_KEY_LEN
28 #define SM_ALGO 3
hvb_need_verify_hash(const char * const * hash_ptn_list,const char * ptn)29 static bool hvb_need_verify_hash(const char *const *hash_ptn_list, const char *ptn)
30 {
31     size_t n;
32     size_t ptn_len = hvb_strnlen(ptn, HVB_MAX_PARTITION_NAME_LEN);
33     if (ptn_len >= HVB_MAX_PARTITION_NAME_LEN) {
34         hvb_print("invalid ptn name len\n");
35         return false;
36     }
37 
38     if (hash_ptn_list == NULL)
39         return false;
40 
41     for (n = 0; hash_ptn_list[n] != NULL; n++) {
42         if (hvb_strnlen(hash_ptn_list[n], HVB_MAX_PARTITION_NAME_LEN) == ptn_len &&
43             hvb_strncmp(hash_ptn_list[n], ptn, HVB_MAX_PARTITION_NAME_LEN) == 0) {
44             return true;
45         }
46     }
47 
48     return false;
49 }
50 
get_hash_size(uint32_t algo)51 static uint64_t get_hash_size(uint32_t algo)
52 {
53     switch (algo) {
54         case 0: // SHA256_RSA3072
55         case 1: // SHA256_RSA4096
56         case 2: // SHA256_RSA2048
57             return HVB_HASH_SIZE_RSA;
58         case 3: // SM3
59             return SM3_IV_BYTE_SIZE;
60         default:
61             return 0;
62     }
63 
64     return 0;
65 }
66 
67 
hvb_compare_hash_rsa(struct hvb_buf * digest_buf,struct hvb_buf * msg_buf,struct hvb_buf * salt_buf,uint32_t hash_algo)68 static enum hvb_errno hvb_compare_hash_rsa(struct hvb_buf *digest_buf, struct hvb_buf *msg_buf,
69                                            struct hvb_buf *salt_buf, uint32_t hash_algo)
70 {
71     int hash_err;
72     struct hash_ctx_t ctx = {0};
73     uint8_t computed_hash[HVB_HASH_MAX_BYTES] = {0};
74 
75     uint32_t computed_hash_size = get_hash_size(hash_algo);
76     if (computed_hash_size != digest_buf->size) {
77         hvb_print("computed_hash_size error\n");
78         return HVB_ERROR_INVALID_ARGUMENT;
79     }
80 
81     hash_err = hash_ctx_init(&ctx, hash_algo);
82     if (hash_err != HASH_OK) {
83         hvb_print("hash init error\n");
84         return HVB_ERROR_VERIFY_HASH;
85     }
86 
87     hash_err = hash_calc_update(&ctx, salt_buf->addr, salt_buf->size);
88     if (hash_err != HASH_OK) {
89         hvb_print("hash updata salt error\n");
90         return HVB_ERROR_VERIFY_HASH;
91     }
92 
93     hash_err = hash_calc_do_final(&ctx, msg_buf->addr, msg_buf->size, &computed_hash[0], digest_buf->size);
94     if (hash_err != HASH_OK) {
95         hvb_print("hash updata msg error\n");
96         return HVB_ERROR_VERIFY_HASH;
97     }
98 
99     if (hvb_memcmp(&computed_hash[0], digest_buf->addr, computed_hash_size) != 0) {
100         hvb_print("compare fail\n");
101         return HVB_ERROR_VERIFY_HASH;
102     }
103 
104     return HVB_OK;
105 }
106 
hvb_compare_hash_sm(struct hvb_buf * digest_buf,struct hvb_buf * msg_buf)107 static enum hvb_errno hvb_compare_hash_sm(struct hvb_buf *digest_buf, struct hvb_buf *msg_buf)
108 {
109     int hash_err;
110     uint8_t computed_hash[HVB_HASH_MAX_BYTES] = {0};
111 
112     if (digest_buf == NULL || msg_buf == NULL) {
113         hvb_print("arguments are invalid in hvb_compare_hash_sm\n");
114         return HVB_ERROR_INVALID_ARGUMENT;
115     }
116 
117     uint32_t computed_hash_size = SM3_IV_BYTE_SIZE;
118     if (computed_hash_size != digest_buf->size) {
119         hvb_print("computed_hash_size error\n");
120         return HVB_ERROR_INVALID_ARGUMENT;
121     }
122 
123     hash_err = hvb_sm3_single(msg_buf->addr, msg_buf->size, &computed_hash[0], &computed_hash_size);
124     if (hash_err != SM3_OK) {
125         hvb_print("hvb_sm3_single error\n");
126         return HVB_ERROR_VERIFY_HASH;
127     }
128 
129     if (hvb_memcmp(&computed_hash[0], digest_buf->addr, computed_hash_size) != 0) {
130         hvb_print("hash compare fail\n");
131         return HVB_ERROR_VERIFY_HASH;
132     }
133 
134     return HVB_OK;
135 }
136 
hvb_compare_hash(struct hvb_buf * digest_buf,struct hvb_buf * msg_buf,struct hvb_buf * salt_buf,uint32_t hash_algo)137 static enum hvb_errno hvb_compare_hash(struct hvb_buf *digest_buf, struct hvb_buf *msg_buf,
138                                        struct hvb_buf *salt_buf, uint32_t hash_algo)
139 {
140     switch (hash_algo) {
141         case 0: // SHA256_RSA3072
142         case 1: // SHA256_RSA4096
143         case 2: // SHA256_RSA2048
144             return hvb_compare_hash_rsa(digest_buf, msg_buf, salt_buf, hash_algo);
145         case 3: // sm2_sm3
146             return hvb_compare_hash_sm(digest_buf, msg_buf);
147         default: {
148             hvb_print("invalid algorithm\n");
149             return HVB_ERROR_INVALID_ARGUMENT;
150         }
151     }
152 }
153 
hash_image_init_desc(struct hvb_ops * ops,const char * ptn,struct hvb_cert * cert,const char * const * hash_ptn_list,struct hvb_verified_data * vd)154 static enum hvb_errno hash_image_init_desc(struct hvb_ops *ops, const char *ptn,
155                                            struct hvb_cert *cert, const char *const *hash_ptn_list,
156                                            struct hvb_verified_data *vd)
157 {
158     enum hvb_io_errno io_ret = HVB_IO_OK;
159     enum hvb_errno ret = HVB_OK;
160     struct hvb_buf image_buf = {NULL, 0};
161     struct hvb_buf salt_buf = {cert->hash_payload.salt, cert->salt_size};
162     struct hvb_buf digest_buf = {cert->hash_payload.digest, cert->digest_size};
163     uint64_t read_bytes = 0;
164     struct hvb_image_data *image = NULL;
165     enum hvb_image_type image_type = (enum hvb_image_type)cert->verity_type;
166 
167     if (image_type != HVB_IMAGE_TYPE_HASH || !hvb_need_verify_hash(hash_ptn_list, ptn)) {
168         hvb_printv(ptn, ": no need verify hash image.\n", NULL);
169         return HVB_OK;
170     }
171 
172     image_buf.size = cert->image_original_len;
173     image_buf.addr = hvb_malloc(image_buf.size);
174     if (image_buf.addr == NULL) {
175         hvb_print("malloc image_buf fail\n");
176         return HVB_ERROR_OOM;
177     }
178 
179     io_ret = ops->read_partition(ops, ptn, 0, image_buf.size, image_buf.addr, &read_bytes);
180     if (io_ret != HVB_IO_OK) {
181         hvb_printv(ptn, ": Error loading data.\n", NULL);
182         ret = HVB_ERROR_IO;
183         goto out;
184     }
185     if (read_bytes != image_buf.size) {
186         hvb_printv(ptn, ": Read incorrect number of bytes from.\n", NULL);
187         ret = HVB_ERROR_IO;
188         goto out;
189     }
190 
191     ret = hvb_compare_hash(&digest_buf, &image_buf, &salt_buf, cert->hash_algo);
192     if (ret != HVB_OK) {
193         hvb_printv(ptn, ": compare hash error.\n", NULL);
194         goto out;
195     }
196 
197     if (vd->num_loaded_images >= HVB_MAX_NUMBER_OF_LOADED_IMAGES) {
198         hvb_print("error, too many images\n");
199         ret = HVB_ERROR_OOM;
200         goto out;
201     }
202 
203     image = &vd->images[vd->num_loaded_images++];
204     image->partition_name = hvb_strdup(ptn);
205     image->data = image_buf;
206     image->preloaded = true;
207 
208     return HVB_OK;
209 
210 out:
211     if (image_buf.addr != NULL)
212         hvb_free(image_buf.addr);
213 
214     return ret;
215 }
216 
_decode_octets(struct hvb_buf * buf,size_t size,uint8_t ** p,uint8_t * end)217 static bool _decode_octets(struct hvb_buf *buf, size_t size, uint8_t **p, uint8_t *end)
218 {
219     /* check range */
220     if (*p + size > end || *p + size < *p)
221         return false;
222 
223     buf->addr = *p;
224     buf->size = size;
225 
226     /* forward move */
227     *p += size;
228 
229     return true;
230 }
231 
_hvb_cert_payload_parser(struct hvb_cert * cert,uint8_t ** p,uint8_t * end)232 static enum hvb_errno _hvb_cert_payload_parser(struct hvb_cert *cert, uint8_t **p, uint8_t *end)
233 {
234     struct hvb_buf buf;
235     struct hash_payload *payload = &cert->hash_payload;
236 
237     if (!_decode_octets(&buf, cert->salt_size, p, end)) {
238         hvb_print("error, dc salt.\n");
239         return HVB_ERROR_INVALID_CERT_FORMAT;
240     }
241     payload->salt = buf.addr;
242 
243     if (!_decode_octets(&buf, cert->digest_size, p, end)) {
244         hvb_print("error, dc digest.\n");
245         return HVB_ERROR_INVALID_CERT_FORMAT;
246     }
247     payload->digest = buf.addr;
248 
249     return HVB_OK;
250 }
251 
_hvb_cert_payload_parser_v2(struct hvb_cert * cert,uint8_t ** p,uint8_t * end,uint8_t * header)252 static enum hvb_errno _hvb_cert_payload_parser_v2(struct hvb_cert *cert, uint8_t **p, uint8_t *end, uint8_t *header)
253 {
254     struct hash_payload *payload = &cert->hash_payload;
255     uint8_t *cur_header;
256 
257     if (header + cert->salt_offset > end || header + cert->salt_offset <= header) {
258         hvb_print("error, illegal salt offset.\n");
259         return HVB_ERROR_INVALID_CERT_FORMAT;
260     }
261     cur_header = header + cert->salt_offset;
262 
263     if (cur_header + cert->salt_size > end || cur_header + cert->salt_size <= cur_header) {
264         hvb_print("error, dc salt.\n");
265         return HVB_ERROR_INVALID_CERT_FORMAT;
266     }
267     payload->salt = cur_header;
268 
269     if (header + cert->digest_offset > end || header + cert->digest_offset <= header) {
270         hvb_print("error, illegal digest offset.\n");
271         return HVB_ERROR_INVALID_CERT_FORMAT;
272     }
273     cur_header = header + cert->digest_offset;
274 
275     if (cur_header + cert->digest_size > end || cur_header + cert->digest_size <= cur_header) {
276         hvb_print("error, dc digest.\n");
277         return HVB_ERROR_INVALID_CERT_FORMAT;
278     }
279     payload->digest = cur_header;
280     *p = cur_header + cert->digest_size;
281 
282     return HVB_OK;
283 }
284 
_hvb_cert_signature_parser(struct hvb_cert * cert,uint8_t ** p,uint8_t * end)285 static enum hvb_errno _hvb_cert_signature_parser(struct hvb_cert *cert, uint8_t **p, uint8_t *end)
286 {
287     struct hvb_buf buf;
288     struct hvb_sign_info *sign_info = &cert->signature_info;
289     size_t cp_size = hvb_offsetof(struct hvb_sign_info, pubk);
290 
291     if (!_decode_octets(&buf, cp_size, p, end)) {
292         hvb_print("error, dc sign info const.\n");
293         return HVB_ERROR_INVALID_CERT_FORMAT;
294     }
295     if (hvb_memcpy_s(&cert->signature_info, sizeof(cert->signature_info), buf.addr, cp_size) != 0) {
296         hvb_print("error, copy dc sign info const.\n");
297         return HVB_ERROR_OOM;
298     }
299 
300     if (!_decode_octets(&buf, sign_info->pubkey_len, p, end)) {
301         hvb_print("error, dc pubk.\n");
302         return HVB_ERROR_INVALID_CERT_FORMAT;
303     }
304     if (hvb_memcpy_s(&sign_info->pubk, sizeof(sign_info->pubk), &buf, sizeof(buf)) != 0) {
305         hvb_print("error, copy dc pubk.\n");
306         return HVB_ERROR_OOM;
307     }
308 
309     if (!_decode_octets(&buf, sign_info->signature_len, p, end)) {
310         hvb_print("error, dc sign.\n");
311         return HVB_ERROR_INVALID_CERT_FORMAT;
312     }
313     if (hvb_memcpy_s(&sign_info->sign, sizeof(sign_info->sign), &buf, sizeof(buf)) != 0) {
314         hvb_print("error, copy dc sign.\n");
315         return HVB_ERROR_OOM;
316     }
317 
318     return HVB_OK;
319 }
320 
_hvb_cert_signature_parser_v2(struct hvb_cert * cert,uint8_t ** p,uint8_t * end,uint8_t * header)321 static enum hvb_errno _hvb_cert_signature_parser_v2(struct hvb_cert *cert, uint8_t **p, uint8_t *end, uint8_t *header)
322 {
323     struct hvb_buf buf = {0};
324     struct hvb_sign_info *sign_info = &cert->signature_info;
325     size_t cp_size = hvb_offsetof(struct hvb_sign_info, pubk);
326     uint8_t *cur_header;
327 
328     if (!_decode_octets(&buf, cp_size, p, end)) {
329         hvb_print("error, dc sign info const.\n");
330         return HVB_ERROR_INVALID_CERT_FORMAT;
331     }
332     if (hvb_memcpy_s(&cert->signature_info, sizeof(cert->signature_info), buf.addr, cp_size) != 0) {
333         hvb_print("error, copy dc sign info const.\n");
334         return HVB_ERROR_OOM;
335     }
336 
337     if (header + sign_info->pubkey_offset > end || header + sign_info->pubkey_offset <= header) {
338         hvb_print("error, illegal pubkey offset.\n");
339         return HVB_ERROR_INVALID_CERT_FORMAT;
340     }
341     cur_header = header + sign_info->pubkey_offset;
342 
343     if (cur_header + sign_info->pubkey_len > end || cur_header + sign_info->pubkey_len <= cur_header) {
344         hvb_print("error, dc pubkey.\n");
345         return HVB_ERROR_INVALID_CERT_FORMAT;
346     }
347     sign_info->pubk.addr = cur_header;
348     sign_info->pubk.size = sign_info->pubkey_len;
349 
350     if (header + sign_info->signature_offset > end || header + sign_info->signature_offset <= header) {
351         hvb_print("error, illegal signature offset.\n");
352         return HVB_ERROR_INVALID_CERT_FORMAT;
353     }
354     cur_header = header + sign_info->signature_offset;
355 
356     if (cur_header + sign_info->signature_len > end || cur_header + sign_info->signature_len <= cur_header) {
357         hvb_print("error, dc sign.\n");
358         return HVB_ERROR_INVALID_CERT_FORMAT;
359     }
360     sign_info->sign.addr = cur_header;
361     sign_info->sign.size = sign_info->signature_len;
362 
363     /* only SM hash algo need user_id */
364     if (sign_info->algorithm == SM_ALGO) {
365         if (header + sign_info->user_id_offset > end || header + sign_info->user_id_offset <= header) {
366             hvb_print("error, illegal user_id offset.\n");
367             return HVB_ERROR_INVALID_CERT_FORMAT;
368         }
369         cur_header = header + sign_info->user_id_offset;
370 
371         if (cur_header + sign_info->user_id_len > end || cur_header + sign_info->user_id_len <= cur_header) {
372             hvb_print("error, dc user id.\n");
373             return HVB_ERROR_INVALID_CERT_FORMAT;
374         }
375         sign_info->user_id.addr = cur_header;
376         sign_info->user_id.size = sign_info->user_id_len;
377     }
378 
379     return HVB_OK;
380 }
381 
hvb_cert_parser(struct hvb_cert * cert,struct hvb_buf * cert_buf)382 enum hvb_errno hvb_cert_parser(struct hvb_cert *cert, struct hvb_buf *cert_buf)
383 {
384     hvb_return_hvb_err_if_null(cert);
385     hvb_return_hvb_err_if_null(cert_buf);
386     hvb_return_hvb_err_if_null(cert_buf->addr);
387 
388     if (cert_buf->size > HVB_CERT_MAX_SIZE) {
389         hvb_print("invalid cert size.\n");
390         return HVB_ERROR_INVALID_ARGUMENT;
391     }
392 
393     enum hvb_errno ret = HVB_OK;
394     struct hvb_buf buf;
395     uint8_t *p = cert_buf->addr;
396     uint8_t *end = p + cert_buf->size;
397     uint8_t *header = p;
398     size_t header_size = hvb_offsetof(struct hvb_cert, hash_payload);
399 
400     /* parse header */
401     if (!_decode_octets(&buf, header_size, &p, end)) {
402         hvb_print("error, dc cert const.\n");
403         return HVB_ERROR_INVALID_CERT_FORMAT;
404     }
405     if (hvb_memcpy_s(cert, sizeof(*cert), buf.addr, buf.size) != 0) {
406         hvb_print("error, copy dc cert const.\n");
407         return HVB_ERROR_OOM;
408     }
409 
410     if (cert->version_minor == 0) {
411         /* parse hash payload */
412         ret = _hvb_cert_payload_parser(cert, &p, end);
413         if (ret != HVB_OK) {
414             hvb_print("error, pr hash payload.\n");
415             return ret;
416         }
417 
418         /* parse signature info */
419         ret = _hvb_cert_signature_parser(cert, &p, end);
420         if (ret != HVB_OK) {
421             hvb_print("error, pr sign.\n");
422             return ret;
423         }
424     } else if (cert->version_minor == 1) {
425         /* parse hash payload v2 */
426         ret = _hvb_cert_payload_parser_v2(cert, &p, end, header);
427         if (ret != HVB_OK) {
428             hvb_print("error, pr hash payload.\n");
429             return ret;
430         }
431 
432         /* parse signature info v2 */
433         ret = _hvb_cert_signature_parser_v2(cert, &p, end, header);
434         if (ret != HVB_OK) {
435             hvb_print("error, pr sign.\n");
436             return ret;
437         }
438     } else {
439         hvb_print("error minor version\n");
440         return HVB_ERROR_INVALID_ARGUMENT;
441     }
442 
443     return HVB_OK;
444 }
445 
hvb_buftouint64(uint8_t * p)446 static uint64_t hvb_buftouint64(uint8_t *p)
447 {
448     uint32_t i;
449     uint64_t val = 0;
450 
451     for (i = 0; i < 8; i++, p++)
452         val |= ((uint64_t)(*p)) << (i * 8);
453 
454     return val;
455 }
456 
457 /*
458  * raw_pubk: |bit_length|n0|mod|p_rr|
459  */
hvb_cert_pubk_parser_rsa(struct hvb_rsa_pubkey * pubk,struct hvb_buf * raw_pubk)460 static enum hvb_errno hvb_cert_pubk_parser_rsa(struct hvb_rsa_pubkey *pubk, struct hvb_buf *raw_pubk)
461 {
462     uint64_t bit_length = 0;
463     uint64_t n0 = 0;
464     struct hvb_buf mod;
465     struct hvb_buf p_rr;
466     struct hvb_buf buf;
467 
468     uint8_t *p = raw_pubk->addr;
469     uint8_t *end = p + raw_pubk->size;
470 
471     if (!_decode_octets(&buf, sizeof(uint64_t), &p, end)) {
472         hvb_print("error, dc bit_length.\n");
473         return 1;
474     }
475     bit_length = hvb_buftouint64(buf.addr);
476     bit_length = hvb_be64toh(bit_length);
477 
478     if (!_decode_octets(&buf, sizeof(uint64_t), &p, end)) {
479         hvb_print("error, dc n0.\n");
480         return 1;
481     }
482     n0 = hvb_buftouint64(buf.addr);
483     n0 = hvb_be64toh(n0);
484 
485     if (!_decode_octets(&mod, bit_length / 8, &p, end)) {
486         hvb_print("error, dc mod.\n");
487         return 1;
488     }
489 
490     if (!_decode_octets(&p_rr, bit_length / 8, &p, end)) {
491         hvb_print("error, dc p_rr\n");
492         return 1;
493     }
494 
495     pubk->width = bit_length;
496     pubk->e = 65537;
497     pubk->pn = mod.addr;
498     pubk->nlen = mod.size;
499     pubk->p_rr = p_rr.addr;
500     pubk->rlen = p_rr.size;
501     pubk->n_n0_i = n0;
502 
503     return 0;
504 }
505 
hvb_cert_pubk_parser_sm(struct sm2_pubkey * pubk,struct hvb_buf * raw_pubk)506 static enum hvb_errno hvb_cert_pubk_parser_sm(struct sm2_pubkey *pubk, struct hvb_buf *raw_pubk)
507 {
508     if (pubk == NULL || raw_pubk == NULL || raw_pubk->size != SM2_KEY_X_LEN + SM2_KEY_Y_LEN) {
509         hvb_print("arguments are invalid in hvb_cert_pubk_parser_sm\n");
510         return HVB_ERROR_INVALID_ARGUMENT;
511     }
512 
513     if (hvb_memcpy_s(&pubk->x[0], sizeof(pubk->x), raw_pubk->addr, SM2_KEY_X_LEN) != 0 ||
514         hvb_memcpy_s(&pubk->y[0], sizeof(pubk->y), raw_pubk->addr + SM2_KEY_X_LEN, SM2_KEY_Y_LEN) != 0) {
515         hvb_print("error, copy raw pubkey.\n");
516         return HVB_ERROR_OOM;
517     }
518 
519     return HVB_OK;
520 }
521 
hvb_verify_cert_rsa(struct hvb_buf * tbs,struct hvb_sign_info * sign_info,uint32_t salt_size)522 static enum hvb_errno hvb_verify_cert_rsa(struct hvb_buf *tbs, struct hvb_sign_info *sign_info, uint32_t salt_size)
523 {
524     int ret = HVB_OK;
525     uint32_t hash_len;
526     struct hvb_buf temp_buf;
527     uint8_t *hash = NULL;
528     struct hvb_rsa_pubkey pubk;
529 
530     temp_buf = sign_info->pubk;
531     ret = hvb_cert_pubk_parser_rsa(&pubk, &temp_buf);
532     if (ret != HVB_OK) {
533         hvb_print("error, hvb cert pubk parser.\n");
534         return ret;
535     }
536     hash_len = get_hash_size(sign_info->algorithm);
537     hash = hvb_malloc(hash_len);
538     if (!hash) {
539         hvb_print("hash malloc error:");
540         return HVB_ERROR_OOM;
541     }
542 
543     ret = hash_sha256_single(tbs->addr, tbs->size, hash, hash_len);
544     if (ret != HASH_OK) {
545         hvb_print("Error computed hash.\n");
546         hvb_free(hash);
547         return HVB_ERROR_INVALID_ARGUMENT;
548     }
549 
550     ret = hvb_rsa_verify_pss(&pubk, hash, hash_len, sign_info->sign.addr, sign_info->sign.size, salt_size);
551     if (ret != VERIFY_OK) {
552         hvb_print("hvb_rsa_verify_pss result error, signature mismatch\n");
553         hvb_free(hash);
554         return HVB_ERROR_VERIFY_SIGN;
555     }
556 
557     hvb_free(hash);
558 
559     return HVB_OK;
560 }
561 
hvb_verify_cert_sm(struct hvb_buf * tbs,struct hvb_sign_info * sign_info)562 static enum hvb_errno hvb_verify_cert_sm(struct hvb_buf *tbs, struct hvb_sign_info *sign_info)
563 {
564     int ret = HVB_OK;
565     struct hvb_buf temp_buf = {0};
566     struct hvb_buf user_id = {0};
567     struct sm2_pubkey pubk = {0};
568 
569     if (tbs == NULL || sign_info == NULL) {
570         hvb_print("arguments are invalid in hvb_verify_cert_sm\n");
571         return HVB_ERROR_INVALID_ARGUMENT;
572     }
573 
574     temp_buf = sign_info->pubk;
575     ret = hvb_cert_pubk_parser_sm(&pubk, &temp_buf);
576     if (ret != HVB_OK) {
577         hvb_print("error, hvb cert pubk parser.\n");
578         return ret;
579     }
580 
581     user_id = sign_info->user_id;
582 
583     ret = hvb_sm2_verify(&pubk, user_id.addr, user_id.size, tbs->addr,
584                          tbs->size, sign_info->sign.addr, sign_info->sign.size);
585     if (ret != SM2_VERIFY_OK) {
586         hvb_print("hvb_sm2_verify result error, signature mismatch\n");
587         return HVB_ERROR_VERIFY_SIGN;
588     }
589 
590     return HVB_OK;
591 }
592 
hvb_verify_cert(struct hvb_buf * tbs,struct hvb_sign_info * sign_info,uint32_t salt_size)593 static enum hvb_errno hvb_verify_cert(struct hvb_buf *tbs, struct hvb_sign_info *sign_info, uint32_t salt_size)
594 {
595     switch (sign_info->algorithm) {
596         case 0: // SHA256_RSA3072
597         case 1: // SHA256_RSA4096
598         case 2: // SHA256_RSA2048
599             return hvb_verify_cert_rsa(tbs, sign_info, salt_size);
600         case 3: // sm2_sm3
601             return hvb_verify_cert_sm(tbs, sign_info);
602         default: {
603             hvb_print("hvb_verify_cert error: invalid algorithm\n");
604             return HVB_ERROR_INVALID_ARGUMENT;
605         }
606     }
607 }
608 
_check_rollback_index(struct hvb_ops * ops,struct hvb_cert * cert,struct hvb_verified_data * vd)609 static enum hvb_errno _check_rollback_index(struct hvb_ops *ops, struct hvb_cert *cert, struct hvb_verified_data *vd)
610 {
611     enum hvb_io_errno io_ret = HVB_IO_OK;
612     uint64_t stored_rollback_index = 0;
613     uint64_t cert_rollback_index = cert->rollback_index;
614     uint64_t rollback_location = cert->rollback_location;
615 
616     if (rollback_location >= HVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) {
617         hvb_print("error, rollback_location too big\n");
618         return HVB_ERROR_INVALID_CERT_FORMAT;
619     }
620 
621     io_ret = ops->read_rollback(ops, rollback_location, &stored_rollback_index);
622     if (io_ret != HVB_IO_OK) {
623         hvb_print("error, read rollback idnex\n");
624         return HVB_ERROR_IO;
625     }
626 
627     if (cert_rollback_index < stored_rollback_index) {
628         hvb_print("error, cert rollback index is less than the stored\n");
629         return HVB_ERROR_ROLLBACK_INDEX;
630     }
631 
632     vd->rollback_indexes[rollback_location] = cert_rollback_index;
633 
634     return HVB_OK;
635 }
636 
cert_init_desc(struct hvb_ops * ops,const char * ptn,struct hvb_buf * cert_buf,const char * const * hash_ptn_list,struct hvb_buf * out_pubk,struct hvb_verified_data * vd)637 enum hvb_errno cert_init_desc(struct hvb_ops *ops, const char *ptn, struct hvb_buf *cert_buf,
638                               const char *const *hash_ptn_list, struct hvb_buf *out_pubk,
639                               struct hvb_verified_data *vd)
640 {
641     hvb_return_hvb_err_if_null(ops);
642     hvb_return_hvb_err_if_null(ptn);
643     hvb_return_hvb_err_if_null(cert_buf);
644     hvb_return_hvb_err_if_null(cert_buf->addr);
645     hvb_return_hvb_err_if_null(out_pubk);
646     hvb_return_hvb_err_if_null(vd);
647 
648     enum hvb_errno ret = HVB_OK;
649     ret = check_hvb_ops(ops);
650     if (ret != HVB_OK) {
651         hvb_print("error, check ops\n");
652         return HVB_ERROR_INVALID_ARGUMENT;
653     }
654 
655     struct hvb_cert cert = {0};
656     struct hvb_buf tbs = {0};
657     struct hvb_sign_info *sign_info = &cert.signature_info;
658 
659     ret = hvb_cert_parser(&cert, cert_buf);
660     if (ret != HVB_OK) {
661         hvb_print("error, hvb cert parser.\n");
662         return ret;
663     }
664 
665     tbs.addr = cert_buf->addr;
666     tbs.size = sign_info->sign.addr - cert_buf->addr;
667     vd->algorithm = sign_info->algorithm;
668 
669     ret = hvb_verify_cert(&tbs, sign_info, cert.salt_size);
670     if (ret != HVB_OK) {
671         hvb_print("error, verify cert.\n");
672         return ret;
673     }
674 
675     ret = _check_rollback_index(ops, &cert, vd);
676     if (ret != HVB_OK) {
677         hvb_print("error, checkout index.\n");
678         return ret;
679     }
680 
681     ret = hash_image_init_desc(ops, ptn, &cert, hash_ptn_list, vd);
682     if (ret != HVB_OK) {
683         hvb_print("hash_image_init_desc result error\n");
684         return ret;
685     }
686 
687     *out_pubk = sign_info->pubk;
688 
689     return ret;
690 }
691