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