xref: /base/startup/hvb/libhvb/src/rvt/hvb_rvt.c (revision 7310c0d0)
17310c0d0Sopenharmony_ci/*
27310c0d0Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
37310c0d0Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
47310c0d0Sopenharmony_ci * you may not use this file except in compliance with the License.
57310c0d0Sopenharmony_ci * You may obtain a copy of the License at
67310c0d0Sopenharmony_ci *
77310c0d0Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
87310c0d0Sopenharmony_ci *
97310c0d0Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
107310c0d0Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
117310c0d0Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127310c0d0Sopenharmony_ci * See the License for the specific language governing permissions and
137310c0d0Sopenharmony_ci * limitations under the License.
147310c0d0Sopenharmony_ci */
157310c0d0Sopenharmony_ci#include "hvb_rvt.h"
167310c0d0Sopenharmony_ci#include "hvb_ops.h"
177310c0d0Sopenharmony_ci#include "hvb_cert.h"
187310c0d0Sopenharmony_ci#include "hvb_util.h"
197310c0d0Sopenharmony_ci
207310c0d0Sopenharmony_cienum hvb_errno hvb_calculate_certs_digest(struct hvb_verified_data *vd, uint8_t *out_digest)
217310c0d0Sopenharmony_ci{
227310c0d0Sopenharmony_ci    uint64_t n;
237310c0d0Sopenharmony_ci    int ret = -1;
247310c0d0Sopenharmony_ci    struct hash_ctx_t ctx;
257310c0d0Sopenharmony_ci
267310c0d0Sopenharmony_ci    ret = hash_ctx_init(&ctx, HASH_ALG_SHA256);
277310c0d0Sopenharmony_ci    if (ret != HASH_OK) {
287310c0d0Sopenharmony_ci        hvb_print("error, hash_ctx_init.\n");
297310c0d0Sopenharmony_ci        return HVB_ERROR_INVALID_ARGUMENT;
307310c0d0Sopenharmony_ci    }
317310c0d0Sopenharmony_ci
327310c0d0Sopenharmony_ci    for (n = 0; n < vd->num_loaded_certs; n++) {
337310c0d0Sopenharmony_ci        ret = hash_calc_update(&ctx, vd->certs[n].data.addr, vd->certs[n].data.size);
347310c0d0Sopenharmony_ci        if (ret != HASH_OK) {
357310c0d0Sopenharmony_ci            hvb_print("error, hash_calc_update.\n");
367310c0d0Sopenharmony_ci            return HVB_ERROR_INVALID_ARGUMENT;
377310c0d0Sopenharmony_ci        }
387310c0d0Sopenharmony_ci    }
397310c0d0Sopenharmony_ci
407310c0d0Sopenharmony_ci    ret = hash_calc_do_final(&ctx, NULL, 0, out_digest, HVB_SHA256_DIGEST_BYTES);
417310c0d0Sopenharmony_ci    if (ret != HASH_OK) {
427310c0d0Sopenharmony_ci        hvb_print("error, hash_calc_do_final.\n");
437310c0d0Sopenharmony_ci        return HVB_ERROR_INVALID_ARGUMENT;
447310c0d0Sopenharmony_ci    }
457310c0d0Sopenharmony_ci
467310c0d0Sopenharmony_ci    return HVB_OK;
477310c0d0Sopenharmony_ci}
487310c0d0Sopenharmony_ci
497310c0d0Sopenharmony_cienum hvb_errno hvb_rvt_head_parser(const struct hvb_buf *rvt, struct rvt_image_header *header, uint64_t desc_size)
507310c0d0Sopenharmony_ci{
517310c0d0Sopenharmony_ci    uint64_t rvt_real_size;
527310c0d0Sopenharmony_ci
537310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(rvt);
547310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(rvt->addr);
557310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(header);
567310c0d0Sopenharmony_ci
577310c0d0Sopenharmony_ci    if (rvt->size < sizeof(*header)) {
587310c0d0Sopenharmony_ci        hvb_print("error, rvt->size is too small.\n");
597310c0d0Sopenharmony_ci        return HVB_ERROR_INVALID_ARGUMENT;
607310c0d0Sopenharmony_ci    }
617310c0d0Sopenharmony_ci    if (hvb_memcpy_s(header, sizeof(*header), rvt->addr, sizeof(*header)) != 0) {
627310c0d0Sopenharmony_ci        hvb_print("error, copy rvt header.\n");
637310c0d0Sopenharmony_ci        return HVB_ERROR_OOM;
647310c0d0Sopenharmony_ci    }
657310c0d0Sopenharmony_ci
667310c0d0Sopenharmony_ci    rvt_real_size = sizeof(*header) + header->verity_num * desc_size;
677310c0d0Sopenharmony_ci    if (rvt_real_size > rvt->size || rvt_real_size < sizeof(*header)) {
687310c0d0Sopenharmony_ci        hvb_print("error, rvt_real_size is invalid.\n");
697310c0d0Sopenharmony_ci        return HVB_ERROR_INVALID_ARGUMENT;
707310c0d0Sopenharmony_ci    }
717310c0d0Sopenharmony_ci
727310c0d0Sopenharmony_ci    return HVB_OK;
737310c0d0Sopenharmony_ci}
747310c0d0Sopenharmony_ci
757310c0d0Sopenharmony_cienum hvb_errno hvb_rvt_get_pubk_desc(const struct hvb_buf *rvt, struct hvb_buf *pubk_desc)
767310c0d0Sopenharmony_ci{
777310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(rvt);
787310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(rvt->addr);
797310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(pubk_desc);
807310c0d0Sopenharmony_ci
817310c0d0Sopenharmony_ci    if (rvt->size < sizeof(*pubk_desc)) {
827310c0d0Sopenharmony_ci        hvb_print("error, rvt->size is too small.\n");
837310c0d0Sopenharmony_ci        return HVB_ERROR_INVALID_ARGUMENT;
847310c0d0Sopenharmony_ci    }
857310c0d0Sopenharmony_ci
867310c0d0Sopenharmony_ci    pubk_desc->addr = rvt->addr + sizeof(struct rvt_image_header);
877310c0d0Sopenharmony_ci    pubk_desc->size = rvt->size - sizeof(struct rvt_image_header);
887310c0d0Sopenharmony_ci
897310c0d0Sopenharmony_ci    if (pubk_desc->size > rvt->size) {
907310c0d0Sopenharmony_ci        hvb_print("error, pubk_desc->size is invalid.\n");
917310c0d0Sopenharmony_ci        return HVB_ERROR_INVALID_ARGUMENT;
927310c0d0Sopenharmony_ci    }
937310c0d0Sopenharmony_ci
947310c0d0Sopenharmony_ci    return HVB_OK;
957310c0d0Sopenharmony_ci}
967310c0d0Sopenharmony_ci
977310c0d0Sopenharmony_cienum hvb_errno hvb_rvt_pubk_desc_parser(const struct hvb_buf *pubk, struct rvt_pubk_desc *desc, uint64_t desc_size)
987310c0d0Sopenharmony_ci{
997310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(pubk);
1007310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(pubk->addr);
1017310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(desc);
1027310c0d0Sopenharmony_ci
1037310c0d0Sopenharmony_ci    if (pubk->size < desc_size) {
1047310c0d0Sopenharmony_ci        hvb_print("error, pubk->size is too small.\n");
1057310c0d0Sopenharmony_ci        return HVB_ERROR_INVALID_ARGUMENT;
1067310c0d0Sopenharmony_ci    }
1077310c0d0Sopenharmony_ci    if (hvb_memcpy_s(desc, sizeof(*desc), pubk->addr, desc_size) != 0) {
1087310c0d0Sopenharmony_ci        hvb_print("error, copy desc.\n");
1097310c0d0Sopenharmony_ci        return HVB_ERROR_OOM;
1107310c0d0Sopenharmony_ci    }
1117310c0d0Sopenharmony_ci
1127310c0d0Sopenharmony_ci    return HVB_OK;
1137310c0d0Sopenharmony_ci}
1147310c0d0Sopenharmony_ci
1157310c0d0Sopenharmony_cienum hvb_errno hvb_rvt_get_pubk_buf(struct hvb_buf *key_buf, const struct hvb_buf *rvt, struct rvt_pubk_desc *desc)
1167310c0d0Sopenharmony_ci{
1177310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(key_buf);
1187310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(rvt);
1197310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(rvt->addr);
1207310c0d0Sopenharmony_ci    hvb_return_hvb_err_if_null(desc);
1217310c0d0Sopenharmony_ci
1227310c0d0Sopenharmony_ci    key_buf->addr = rvt->addr + desc->pubkey_offset;
1237310c0d0Sopenharmony_ci    key_buf->size = desc->pubkey_len;
1247310c0d0Sopenharmony_ci
1257310c0d0Sopenharmony_ci    return HVB_OK;
1267310c0d0Sopenharmony_ci}
127