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 #include "hvb_sm3.h"
20
hvb_calculate_certs_digest_rsa(struct hvb_verified_data * vd,uint8_t * out_digest)21 static enum hvb_errno hvb_calculate_certs_digest_rsa(struct hvb_verified_data *vd, uint8_t *out_digest)
22 {
23 uint64_t n;
24 int ret;
25 struct hash_ctx_t ctx;
26
27 ret = hash_ctx_init(&ctx, HASH_ALG_SHA256);
28 if (ret != HASH_OK) {
29 hvb_print("error, hash_ctx_init.\n");
30 return HVB_ERROR_INVALID_ARGUMENT;
31 }
32
33 for (n = 0; n < vd->num_loaded_certs; n++) {
34 ret = hash_calc_update(&ctx, vd->certs[n].data.addr, vd->certs[n].data.size);
35 if (ret != HASH_OK) {
36 hvb_print("error, hash_calc_update.\n");
37 return HVB_ERROR_INVALID_ARGUMENT;
38 }
39 }
40
41 ret = hash_calc_do_final(&ctx, NULL, 0, out_digest, HVB_SHA256_DIGEST_BYTES);
42 if (ret != HASH_OK) {
43 hvb_print("error, hash_calc_do_final.\n");
44 return HVB_ERROR_INVALID_ARGUMENT;
45 }
46
47 return HVB_OK;
48 }
49
hvb_calculate_certs_digest_sm(struct hvb_verified_data * vd,uint8_t * out_digest)50 static enum hvb_errno hvb_calculate_certs_digest_sm(struct hvb_verified_data *vd, uint8_t *out_digest)
51 {
52 uint64_t n;
53 uint32_t out_len = HVB_SM3_DIGEST_BYTES;
54 int ret;
55 struct sm3_ctx_t ctx;
56
57 if (vd == NULL || out_digest == NULL) {
58 hvb_print("arguments are invalid in hvb_calculate_certs_digest_sm\n");
59 return HVB_ERROR_INVALID_ARGUMENT;
60 }
61
62 ret = hvb_sm3_init(&ctx);
63 if (ret != SM3_OK) {
64 hvb_print("error, hash_ctx_init.\n");
65 return HVB_ERROR_INVALID_ARGUMENT;
66 }
67
68 for (n = 0; n < vd->num_loaded_certs; n++) {
69 ret = hvb_sm3_update(&ctx, vd->certs[n].data.addr, vd->certs[n].data.size);
70 if (ret != SM3_OK) {
71 hvb_print("error, hash_calc_update.\n");
72 return HVB_ERROR_INVALID_ARGUMENT;
73 }
74 }
75
76 ret = hvb_sm3_final(&ctx, out_digest, &out_len);
77 if (ret != SM3_OK) {
78 hvb_print("error, hash_calc_do_final.\n");
79 return HVB_ERROR_INVALID_ARGUMENT;
80 }
81
82 return HVB_OK;
83 }
84
hvb_calculate_certs_digest(struct hvb_verified_data * vd,uint8_t * out_digest)85 enum hvb_errno hvb_calculate_certs_digest(struct hvb_verified_data *vd, uint8_t *out_digest)
86 {
87 switch (vd->algorithm) {
88 case 0: // SHA256_RSA3072
89 case 1: // SHA256_RSA4096
90 case 2: // SHA256_RSA2048
91 return hvb_calculate_certs_digest_rsa(vd, out_digest);
92 case 3: // sm2_sm3
93 return hvb_calculate_certs_digest_sm(vd, out_digest);
94 default: {
95 hvb_print("hvb_calculate_certs_digest error: invalid algorithm\n");
96 return HVB_ERROR_INVALID_ARGUMENT;
97 }
98 }
99 }
100
hvb_rvt_head_parser(const struct hvb_buf * rvt,struct rvt_image_header * header)101 enum hvb_errno hvb_rvt_head_parser(const struct hvb_buf *rvt, struct rvt_image_header *header)
102 {
103 hvb_return_hvb_err_if_null(rvt);
104 hvb_return_hvb_err_if_null(rvt->addr);
105 hvb_return_hvb_err_if_null(header);
106
107 if (rvt->size < sizeof(*header)) {
108 hvb_print("error, rvt->size is too small.\n");
109 return HVB_ERROR_INVALID_ARGUMENT;
110 }
111
112 /* copy desc const part */
113 if (hvb_memcpy_s(header, sizeof(*header), rvt->addr, sizeof(*header)) != 0) {
114 hvb_print("error, copy rvt header.\n");
115 return HVB_ERROR_OOM;
116 }
117
118 if (header->pubkey_num_per_ptn > RVT_MAX_VALID_KEY_NUM) {
119 hvb_print("error, invalid pubkey_num_per_ptn.\n");
120 return HVB_ERROR_OOM;
121 }
122
123 if (header->verity_num >= MAX_NUMBER_OF_RVT_IMAGES) {
124 hvb_print("error, verity_num.\n");
125 return HVB_ERROR_OOM;
126 }
127
128 return HVB_OK;
129 }
130
hvb_rvt_get_pubk_desc(const struct hvb_buf * rvt,struct hvb_buf * pubk_desc)131 enum hvb_errno hvb_rvt_get_pubk_desc(const struct hvb_buf *rvt, struct hvb_buf *pubk_desc)
132 {
133 hvb_return_hvb_err_if_null(rvt);
134 hvb_return_hvb_err_if_null(rvt->addr);
135 hvb_return_hvb_err_if_null(pubk_desc);
136
137 if (rvt->size < sizeof(*pubk_desc)) {
138 hvb_print("error, rvt->size is too small.\n");
139 return HVB_ERROR_INVALID_ARGUMENT;
140 }
141
142 pubk_desc->addr = rvt->addr + sizeof(struct rvt_image_header);
143 pubk_desc->size = rvt->size - sizeof(struct rvt_image_header);
144
145 if (pubk_desc->size > rvt->size) {
146 hvb_print("error, pubk_desc->size is invalid.\n");
147 return HVB_ERROR_INVALID_ARGUMENT;
148 }
149
150 return HVB_OK;
151 }
152
hvb_rvt_pubk_desc_parser(const struct hvb_buf * pubk,struct rvt_pubk_desc * desc)153 enum hvb_errno hvb_rvt_pubk_desc_parser(const struct hvb_buf *pubk, struct rvt_pubk_desc *desc)
154 {
155 size_t pubk_desc_const_size = hvb_offsetof(struct rvt_pubk_desc, pubkey_payload);
156 hvb_return_hvb_err_if_null(pubk);
157 hvb_return_hvb_err_if_null(pubk->addr);
158 hvb_return_hvb_err_if_null(desc);
159
160 if (pubk->size < pubk_desc_const_size) {
161 hvb_print("error, pubk->size is too small.\n");
162 return HVB_ERROR_INVALID_ARGUMENT;
163 }
164 if (hvb_memcpy_s(desc, sizeof(*desc), pubk->addr, pubk_desc_const_size) != 0) {
165 hvb_print("error, copy desc.\n");
166 return HVB_ERROR_OOM;
167 }
168
169 return HVB_OK;
170 }
171
hvb_rvt_get_pubk_buf(struct hvb_buf * key_buf,const struct hvb_buf * rvt,uint32_t pubkey_offset,uint32_t pubkey_len)172 enum hvb_errno hvb_rvt_get_pubk_buf(struct hvb_buf *key_buf, const struct hvb_buf *rvt,
173 uint32_t pubkey_offset, uint32_t pubkey_len)
174 {
175 hvb_return_hvb_err_if_null(key_buf);
176 hvb_return_hvb_err_if_null(rvt);
177 hvb_return_hvb_err_if_null(rvt->addr);
178
179 key_buf->addr = rvt->addr + pubkey_offset;
180 key_buf->size = pubkey_len;
181
182 return HVB_OK;
183 }
184