xref: /base/startup/hvb/libhvb/src/rvt/hvb_rvt.c (revision 7310c0d0)
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
20enum 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
49enum hvb_errno hvb_rvt_head_parser(const struct hvb_buf *rvt, struct rvt_image_header *header, uint64_t desc_size)
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    if (hvb_memcpy_s(header, sizeof(*header), rvt->addr, sizeof(*header)) != 0) {
62        hvb_print("error, copy rvt header.\n");
63        return HVB_ERROR_OOM;
64    }
65
66    rvt_real_size = sizeof(*header) + header->verity_num * desc_size;
67    if (rvt_real_size > rvt->size || rvt_real_size < sizeof(*header)) {
68        hvb_print("error, rvt_real_size is invalid.\n");
69        return HVB_ERROR_INVALID_ARGUMENT;
70    }
71
72    return HVB_OK;
73}
74
75enum hvb_errno hvb_rvt_get_pubk_desc(const struct hvb_buf *rvt, struct hvb_buf *pubk_desc)
76{
77    hvb_return_hvb_err_if_null(rvt);
78    hvb_return_hvb_err_if_null(rvt->addr);
79    hvb_return_hvb_err_if_null(pubk_desc);
80
81    if (rvt->size < sizeof(*pubk_desc)) {
82        hvb_print("error, rvt->size is too small.\n");
83        return HVB_ERROR_INVALID_ARGUMENT;
84    }
85
86    pubk_desc->addr = rvt->addr + sizeof(struct rvt_image_header);
87    pubk_desc->size = rvt->size - sizeof(struct rvt_image_header);
88
89    if (pubk_desc->size > rvt->size) {
90        hvb_print("error, pubk_desc->size is invalid.\n");
91        return HVB_ERROR_INVALID_ARGUMENT;
92    }
93
94    return HVB_OK;
95}
96
97enum hvb_errno hvb_rvt_pubk_desc_parser(const struct hvb_buf *pubk, struct rvt_pubk_desc *desc, uint64_t desc_size)
98{
99    hvb_return_hvb_err_if_null(pubk);
100    hvb_return_hvb_err_if_null(pubk->addr);
101    hvb_return_hvb_err_if_null(desc);
102
103    if (pubk->size < desc_size) {
104        hvb_print("error, pubk->size is too small.\n");
105        return HVB_ERROR_INVALID_ARGUMENT;
106    }
107    if (hvb_memcpy_s(desc, sizeof(*desc), pubk->addr, desc_size) != 0) {
108        hvb_print("error, copy desc.\n");
109        return HVB_ERROR_OOM;
110    }
111
112    return HVB_OK;
113}
114
115enum hvb_errno hvb_rvt_get_pubk_buf(struct hvb_buf *key_buf, const struct hvb_buf *rvt, struct rvt_pubk_desc *desc)
116{
117    hvb_return_hvb_err_if_null(key_buf);
118    hvb_return_hvb_err_if_null(rvt);
119    hvb_return_hvb_err_if_null(rvt->addr);
120    hvb_return_hvb_err_if_null(desc);
121
122    key_buf->addr = rvt->addr + desc->pubkey_offset;
123    key_buf->size = desc->pubkey_len;
124
125    return HVB_OK;
126}
127