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 "hvb_rvt.h"
16 #include "hvb_ops.h"
17 #include "hvb_cert.h"
18 #include "hvb_util.h"
19
hvb_calculate_certs_digest(struct hvb_verified_data * vd,uint8_t * out_digest)20 enum hvb_errno hvb_calculate_certs_digest(struct hvb_verified_data *vd, uint8_t *out_digest)
21 {
22 uint64_t n;
23 int ret = -1;
24 struct hash_ctx_t ctx;
25
26 ret = hash_ctx_init(&ctx, HASH_ALG_SHA256);
27 if (ret != HASH_OK) {
28 hvb_print("error, hash_ctx_init.\n");
29 return HVB_ERROR_INVALID_ARGUMENT;
30 }
31
32 for (n = 0; n < vd->num_loaded_certs; n++) {
33 ret = hash_calc_update(&ctx, vd->certs[n].data.addr, vd->certs[n].data.size);
34 if (ret != HASH_OK) {
35 hvb_print("error, hash_calc_update.\n");
36 return HVB_ERROR_INVALID_ARGUMENT;
37 }
38 }
39
40 ret = hash_calc_do_final(&ctx, NULL, 0, out_digest, HVB_SHA256_DIGEST_BYTES);
41 if (ret != HASH_OK) {
42 hvb_print("error, hash_calc_do_final.\n");
43 return HVB_ERROR_INVALID_ARGUMENT;
44 }
45
46 return HVB_OK;
47 }
48
hvb_rvt_head_parser(const struct hvb_buf * rvt,struct rvt_image_header * header)49 enum hvb_errno hvb_rvt_head_parser(const struct hvb_buf *rvt, struct rvt_image_header *header)
50 {
51 uint64_t rvt_real_size;
52
53 hvb_return_hvb_err_if_null(rvt);
54 hvb_return_hvb_err_if_null(rvt->addr);
55 hvb_return_hvb_err_if_null(header);
56
57 if (rvt->size < sizeof(*header)) {
58 hvb_print("error, rvt->size is too small.\n");
59 return HVB_ERROR_INVALID_ARGUMENT;
60 }
61
62 hvb_memcpy(header, rvt->addr, sizeof(*header));
63
64 rvt_real_size = sizeof(*header) + header->verity_num * sizeof(struct rvt_pubk_desc);
65 if (rvt_real_size > rvt->size || rvt_real_size < sizeof(*header)) {
66 hvb_print("error, rvt_real_size is invalid.\n");
67 return HVB_ERROR_INVALID_ARGUMENT;
68 }
69
70 return HVB_OK;
71 }
72
hvb_rvt_get_pubk_desc(const struct hvb_buf * rvt,struct hvb_buf * pubk_desc)73 enum hvb_errno hvb_rvt_get_pubk_desc(const struct hvb_buf *rvt, struct hvb_buf *pubk_desc)
74 {
75 hvb_return_hvb_err_if_null(rvt);
76 hvb_return_hvb_err_if_null(rvt->addr);
77 hvb_return_hvb_err_if_null(pubk_desc);
78
79 if (rvt->size < sizeof(*pubk_desc)) {
80 hvb_print("error, rvt->size is too small.\n");
81 return HVB_ERROR_INVALID_ARGUMENT;
82 }
83
84 pubk_desc->addr = rvt->addr + sizeof(struct rvt_image_header);
85 pubk_desc->size = rvt->size - sizeof(struct rvt_image_header);
86
87 if (pubk_desc->size > rvt->size) {
88 hvb_print("error, pubk_desc->size is invalid.\n");
89 return HVB_ERROR_INVALID_ARGUMENT;
90 }
91
92 return HVB_OK;
93 }
94
hvb_rvt_pubk_desc_parser(const struct hvb_buf * pubk,struct rvt_pubk_desc * desc)95 enum hvb_errno hvb_rvt_pubk_desc_parser(const struct hvb_buf *pubk, struct rvt_pubk_desc *desc)
96 {
97 hvb_return_hvb_err_if_null(pubk);
98 hvb_return_hvb_err_if_null(pubk->addr);
99 hvb_return_hvb_err_if_null(desc);
100
101 if (pubk->size < sizeof(*desc)) {
102 hvb_print("error, pubk->size is too small.\n");
103 return HVB_ERROR_INVALID_ARGUMENT;
104 }
105
106 hvb_memcpy(desc, pubk->addr, sizeof(*desc));
107
108 return HVB_OK;
109 }
110
hvb_rvt_get_pubk_buf(struct hvb_buf * key_buf,const struct hvb_buf * rvt,struct rvt_pubk_desc * desc)111 enum hvb_errno hvb_rvt_get_pubk_buf(struct hvb_buf *key_buf, const struct hvb_buf *rvt, struct rvt_pubk_desc *desc)
112 {
113 hvb_return_hvb_err_if_null(key_buf);
114 hvb_return_hvb_err_if_null(rvt);
115 hvb_return_hvb_err_if_null(rvt->addr);
116 hvb_return_hvb_err_if_null(desc);
117
118 key_buf->addr = rvt->addr + desc->pubkey_offset;
119 key_buf->size = desc->pubkey_len;
120
121 return HVB_OK;
122 }
123