• 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 
24 
hvb_need_verify_hash(const char * const * hash_ptn_list,const char * ptn)25 static bool hvb_need_verify_hash(const char *const *hash_ptn_list, const char *ptn)
26 {
27     size_t n;
28     size_t ptn_len = hvb_strlen(ptn);
29 
30     if (hash_ptn_list == NULL)
31         return false;
32 
33     for (n = 0; hash_ptn_list[n] != NULL; n++) {
34         if (hvb_strlen(hash_ptn_list[n]) == ptn_len &&
35             hvb_memcmp(hash_ptn_list[n], ptn, ptn_len) == 0)
36             return true;
37     }
38 
39     return false;
40 }
41 
get_hash_size(uint32_t algo)42 static uint64_t get_hash_size(uint32_t algo)
43 {
44     switch (algo) {
45         case 0: // SHA256_RSA3072
46         case 1: // SHA256_RSA4096
47         case 2: // SHA256_RSA2048
48             return 32;
49         default:
50             return 0;
51     }
52 
53     return 0;
54 }
55 
hvb_compare_hash(struct hvb_buf * digest_buf,struct hvb_buf * msg_buf,struct hvb_buf * salt_buf,uint32_t hash_algo)56 static enum hvb_errno hvb_compare_hash(struct hvb_buf *digest_buf, struct hvb_buf *msg_buf,
57                                        struct hvb_buf *salt_buf, uint32_t hash_algo)
58 {
59     int hash_err;
60     struct hash_ctx_t ctx = {0};
61     uint8_t computed_hash[HVB_HASH_MAX_BYTES] = {0};
62 
63     uint32_t computed_hash_size = get_hash_size(hash_algo);
64     if (computed_hash_size != digest_buf->size) {
65         hvb_print("computed_hash_size error\n");
66         return HVB_ERROR_INVALID_ARGUMENT;
67     }
68 
69     hash_err = hash_ctx_init(&ctx, hash_algo);
70     if (hash_err != HASH_OK) {
71         hvb_print("hash init error\n");
72         return HVB_ERROR_VERIFY_HASH;
73     }
74 
75     hash_err = hash_calc_update(&ctx, salt_buf->addr, salt_buf->size);
76     if (hash_err != HASH_OK) {
77         hvb_print("hash updata salt error\n");
78         return HVB_ERROR_VERIFY_HASH;
79     }
80 
81     hash_err = hash_calc_do_final(&ctx, msg_buf->addr, msg_buf->size, &computed_hash[0], digest_buf->size);
82     if (hash_err != HASH_OK) {
83         hvb_print("hash updata msg error\n");
84         return HVB_ERROR_VERIFY_HASH;
85     }
86 
87     if (hvb_memcmp(&computed_hash[0], digest_buf->addr, computed_hash_size) != 0) {
88         hvb_print("compare fail\n");
89         return HVB_ERROR_VERIFY_HASH;
90     }
91 
92     return HVB_OK;
93 }
94 
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)95 static enum hvb_errno hash_image_init_desc(struct hvb_ops *ops, const char *ptn,
96                                            struct hvb_cert *cert, const char *const *hash_ptn_list,
97                                            struct hvb_verified_data *vd)
98 {
99     enum hvb_io_errno io_ret = HVB_IO_OK;
100     enum hvb_errno ret = HVB_OK;
101     struct hvb_buf image_buf = {NULL, 0};
102     struct hvb_buf salt_buf = {cert->hash_payload.salt, cert->salt_size};
103     struct hvb_buf digest_buf = {cert->hash_payload.digest, cert->digest_size};
104     uint64_t read_bytes = 0;
105     struct hvb_image_data *image = NULL;
106     enum hvb_image_type image_type = (enum hvb_image_type)cert->verity_type;
107 
108     if (image_type != HVB_IMAGE_TYPE_HASH || !hvb_need_verify_hash(hash_ptn_list, ptn)) {
109         hvb_printv(ptn, ": no need verify hash image.\n", NULL);
110         return HVB_OK;
111     }
112 
113     image_buf.size = cert->image_original_len;
114     image_buf.addr = hvb_malloc(image_buf.size);
115     if (image_buf.addr == NULL) {
116         hvb_print("malloc image_buf fail\n");
117         return HVB_ERROR_OOM;
118     }
119 
120     io_ret = ops->read_partition(ops, ptn, 0, image_buf.size, image_buf.addr, &read_bytes);
121     if (io_ret != HVB_IO_OK) {
122         hvb_printv(ptn, ": Error loading data.\n", NULL);
123         ret = HVB_ERROR_IO;
124         goto out;
125     }
126     if (read_bytes != image_buf.size) {
127         hvb_printv(ptn, ": Read incorrect number of bytes from.\n", NULL);
128         ret = HVB_ERROR_IO;
129         goto out;
130     }
131 
132     ret = hvb_compare_hash(&digest_buf, &image_buf, &salt_buf, cert->hash_algo);
133     if (ret != HVB_OK) {
134         hvb_printv(ptn, ": compare hash error.\n", NULL);
135         goto out;
136     }
137 
138     if (vd->num_loaded_images >= HVB_MAX_NUMBER_OF_LOADED_IMAGES) {
139         hvb_print("error, too many images\n");
140         ret = HVB_ERROR_OOM;
141         goto out;
142     }
143 
144     image = &vd->images[vd->num_loaded_images++];
145     image->partition_name = hvb_strdup(ptn);
146     image->data = image_buf;
147     image->preloaded = true;
148 
149     return HVB_OK;
150 
151 out:
152     if (image_buf.addr != NULL)
153         hvb_free(image_buf.addr);
154 
155     return ret;
156 }
157 
_decode_octets(struct hvb_buf * buf,size_t size,uint8_t ** p,uint8_t * end)158 static bool _decode_octets(struct hvb_buf *buf, size_t size, uint8_t **p, uint8_t *end)
159 {
160     /* check range */
161     if (*p + size > end || *p + size < *p)
162         return false;
163 
164     buf->addr = *p;
165     buf->size = size;
166 
167     /* forward move */
168     *p += size;
169 
170     return true;
171 }
172 
_hvb_cert_payload_parser(struct hvb_cert * cert,uint8_t ** p,uint8_t * end)173 static enum hvb_errno _hvb_cert_payload_parser(struct hvb_cert *cert, uint8_t **p, uint8_t *end)
174 {
175     struct hvb_buf buf;
176     struct hash_payload *payload = &cert->hash_payload;
177 
178     if (!_decode_octets(&buf, cert->salt_size, p, end)) {
179         hvb_print("error, dc salt.\n");
180         return HVB_ERROR_INVALID_CERT_FORMAT;
181     }
182     payload->salt = buf.addr;
183 
184     if (!_decode_octets(&buf, cert->digest_size, p, end)) {
185         hvb_print("error, dc digest.\n");
186         return HVB_ERROR_INVALID_CERT_FORMAT;
187     }
188     payload->digest = buf.addr;
189 
190     return HVB_OK;
191 }
192 
_hvb_cert_signature_parser(struct hvb_cert * cert,uint8_t ** p,uint8_t * end)193 static enum hvb_errno _hvb_cert_signature_parser(struct hvb_cert *cert, uint8_t **p, uint8_t *end)
194 {
195     struct hvb_buf buf;
196     struct hvb_sign_info *sign_info = &cert->signature_info;
197     size_t cp_size = hvb_offsetof(struct hvb_sign_info, pubk);
198 
199     if (!_decode_octets(&buf, cp_size, p, end)) {
200         hvb_print("error, dc sign info const.\n");
201         return HVB_ERROR_INVALID_CERT_FORMAT;
202     }
203     hvb_memcpy(&cert->signature_info, buf.addr, cp_size);
204 
205     if (!_decode_octets(&buf, sign_info->pubkey_len, p, end)) {
206         hvb_print("error, dc pubk.\n");
207         return HVB_ERROR_INVALID_CERT_FORMAT;
208     }
209 
210     hvb_memcpy(&sign_info->pubk, &buf, sizeof(buf));
211 
212     if (!_decode_octets(&buf, sign_info->signature_len, p, end)) {
213         hvb_print("error, dc sign.\n");
214         return HVB_ERROR_INVALID_CERT_FORMAT;
215     }
216 
217     hvb_memcpy(&sign_info->sign, &buf, sizeof(buf));
218 
219     return HVB_OK;
220 }
221 
hvb_cert_parser(struct hvb_cert * cert,struct hvb_buf * cert_buf)222 enum hvb_errno hvb_cert_parser(struct hvb_cert *cert, struct hvb_buf *cert_buf)
223 {
224     enum hvb_errno ret = HVB_OK;
225     struct hvb_buf buf;
226     uint8_t *p = cert_buf->addr;
227     uint8_t *end = p + cert_buf->size;
228     size_t header_size = hvb_offsetof(struct hvb_cert, hash_payload);
229 
230     /* parse header */
231     if (!_decode_octets(&buf, header_size, &p, end)) {
232         hvb_print("error, dc cert const.\n");
233         return HVB_ERROR_INVALID_CERT_FORMAT;
234     }
235 
236     hvb_memcpy(cert, buf.addr, buf.size);
237 
238     /* parse hash payload */
239     ret = _hvb_cert_payload_parser(cert, &p, end);
240     if (ret != HVB_OK) {
241         hvb_print("error, pr hash payload.\n");
242         return ret;
243     }
244 
245     /* parse signature info */
246     ret = _hvb_cert_signature_parser(cert, &p, end);
247     if (ret != HVB_OK) {
248         hvb_print("error, pr sign.\n");
249         return ret;
250     }
251 
252     return HVB_OK;
253 }
254 
hvb_buftouint64(uint8_t * p)255 static uint64_t hvb_buftouint64(uint8_t *p)
256 {
257     uint32_t i;
258     uint64_t val = 0;
259 
260     for (i = 0; i < 8; i++, p++) {
261         val |= (((uint64_t)(*p)) << (i * 8));
262     }
263 
264     return val;
265 }
266 
267 /*
268  * raw_pubk: |bit_length|n0|mod|p_rr|
269  */
hvb_cert_pubk_parser(struct hvb_rsa_pubkey * pubk,struct hvb_buf * raw_pubk)270 static enum hvb_errno hvb_cert_pubk_parser(struct hvb_rsa_pubkey *pubk, struct hvb_buf *raw_pubk)
271 {
272     uint64_t bit_length = 0;
273     uint64_t n0 = 0;
274     struct hvb_buf mod;
275     struct hvb_buf p_rr;
276     struct hvb_buf buf;
277 
278     uint8_t *p = raw_pubk->addr;
279     uint8_t *end = p + raw_pubk->size;
280 
281     if (!_decode_octets(&buf, sizeof(uint64_t), &p, end)) {
282         hvb_print("error, dc bit_length.\n");
283         return 1;
284     }
285     bit_length = hvb_buftouint64(buf.addr);
286     bit_length = hvb_be64toh(bit_length);
287 
288     if (!_decode_octets(&buf, sizeof(uint64_t), &p, end)) {
289         hvb_print("error, dc n0.\n");
290         return 1;
291     }
292     n0 = hvb_buftouint64(buf.addr);
293     n0 = hvb_be64toh(n0);
294 
295     if (!_decode_octets(&mod, bit_length / 8, &p, end)) {
296         hvb_print("error, dc mod.\n");
297         return 1;
298     }
299 
300     if (!_decode_octets(&p_rr, bit_length / 8, &p, end)) {
301         hvb_print("error, dc p_rr\n");
302         return 1;
303     }
304 
305     pubk->width = bit_length;
306     pubk->e = 65537;
307     pubk->pn = mod.addr;
308     pubk->nlen = mod.size;
309     pubk->p_rr = p_rr.addr;
310     pubk->rlen = p_rr.size;
311     pubk->n_n0_i = n0;
312 
313     return 0;
314 }
315 
hvb_verify_cert(struct hvb_buf * tbs,struct hvb_sign_info * sign_info,uint32_t salt_size)316 static enum hvb_errno hvb_verify_cert(struct hvb_buf *tbs, struct hvb_sign_info *sign_info, uint32_t salt_size)
317 {
318     int cry_err;
319     enum hvb_errno ret = HVB_OK;
320     uint32_t hash_len;
321     struct hvb_buf temp_buf;
322     uint8_t *hash = NULL;
323     struct hvb_rsa_pubkey pubk;
324 
325     temp_buf = sign_info->pubk;
326     ret = hvb_cert_pubk_parser(&pubk, &temp_buf);
327     if (ret != HVB_OK) {
328         hvb_print("error, hvb cert pubk parser.\n");
329         return ret;
330     }
331 
332     hash_len = get_hash_size(sign_info->algorithm);
333     hash = hvb_malloc(hash_len);
334     if (!hash) {
335         hvb_print("hash malloc error:");
336         return HVB_ERROR_OOM;
337     }
338 
339     cry_err = hash_sha256_single(tbs->addr, tbs->size, hash, hash_len);
340     if (cry_err != 0) {
341         hvb_print("Error computed hash.\n");
342         return HVB_ERROR_INVALID_ARGUMENT;
343     }
344 
345     cry_err = hvb_rsa_verify_pss(&pubk, hash, hash_len, sign_info->sign.addr, sign_info->sign.size, salt_size);
346     if (cry_err != VERIFY_OK) {
347         hvb_print("hvb_rsa_verify_pss result error, signature mismatch\n");
348         return HVB_ERROR_VERIFY_SIGN;
349     }
350 
351     return HVB_OK;
352 }
353 
_check_rollback_index(struct hvb_ops * ops,struct hvb_cert * cert,struct hvb_verified_data * vd)354 static enum hvb_errno _check_rollback_index(struct hvb_ops *ops, struct hvb_cert *cert, struct hvb_verified_data *vd)
355 {
356     enum hvb_io_errno io_ret = HVB_IO_OK;
357     uint64_t stored_rollback_index = 0;
358     uint64_t cert_rollback_index = cert->rollback_index;
359     uint64_t rollback_location = cert->rollback_location;
360 
361     if (rollback_location >= HVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) {
362         hvb_print("error, rollback_location too big\n");
363         return HVB_ERROR_INVALID_CERT_FORMAT;
364     }
365 
366     io_ret = ops->read_rollback(ops, rollback_location, &stored_rollback_index);
367     if (io_ret != HVB_IO_OK) {
368         hvb_print("error, read rollback idnex\n");
369         return HVB_ERROR_IO;
370     }
371 
372     if (cert_rollback_index < stored_rollback_index) {
373         hvb_print("error, cert rollback index is less than the stored\n");
374         return HVB_ERROR_ROLLBACK_INDEX;
375     }
376 
377     vd->rollback_indexes[rollback_location] = cert_rollback_index;
378 
379     return HVB_OK;
380 }
381 
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)382 enum hvb_errno cert_init_desc(struct hvb_ops *ops, const char *ptn, struct hvb_buf *cert_buf,
383                               const char *const *hash_ptn_list, struct hvb_buf *out_pubk,
384                               struct hvb_verified_data *vd)
385 {
386     enum hvb_errno ret = HVB_OK;
387     struct hvb_cert cert = {0};
388     struct hvb_buf tbs = {0};
389     struct hvb_sign_info *sign_info = &cert.signature_info;
390 
391     ret = hvb_cert_parser(&cert, cert_buf);
392     if (ret != HVB_OK) {
393         hvb_print("error, hvb cert parser.\n");
394         return ret;
395     }
396 
397     tbs.addr = cert_buf->addr;
398     tbs.size = sign_info->sign.addr - cert_buf->addr;
399     ret = hvb_verify_cert(&tbs, sign_info, cert.salt_size);
400     if (ret != HVB_OK) {
401         hvb_print("error, verify cert.\n");
402         return ret;
403     }
404 
405     ret = _check_rollback_index(ops, &cert, vd);
406     if (ret != HVB_OK) {
407         hvb_print("error, checkout index.\n");
408         return ret;
409     }
410 
411     ret = hash_image_init_desc(ops, ptn, &cert, hash_ptn_list, vd);
412     if (ret != HVB_OK) {
413         hvb_print("hash_image_init_desc result error\n");
414         return ret;
415     }
416 
417     *out_pubk = sign_info->pubk;
418 
419     return ret;
420 }
421