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 <stdlib.h>
167310c0d0Sopenharmony_ci#include <string.h>
177310c0d0Sopenharmony_ci#include <sys/ioctl.h>
187310c0d0Sopenharmony_ci#include <sys/stat.h>
197310c0d0Sopenharmony_ci#include <sys/types.h>
207310c0d0Sopenharmony_ci#include <unistd.h>
217310c0d0Sopenharmony_ci#include <stdio.h>
227310c0d0Sopenharmony_ci#include <linux/fs.h>
237310c0d0Sopenharmony_ci
247310c0d0Sopenharmony_ci#include <errno.h>
257310c0d0Sopenharmony_ci#include <fcntl.h>
267310c0d0Sopenharmony_ci
277310c0d0Sopenharmony_ci#include "hvb_ops.h"
287310c0d0Sopenharmony_ci#include "hvb.h"
297310c0d0Sopenharmony_ci
307310c0d0Sopenharmony_cistatic struct struct hvb_ops *g_hvb_ops;
317310c0d0Sopenharmony_ci
327310c0d0Sopenharmony_cistatic enum hvb_io_errno hvb_read_partition(struct hvb_ops *ops,
337310c0d0Sopenharmony_ci                                            const char *partition,
347310c0d0Sopenharmony_ci                                            int64_t offset,
357310c0d0Sopenharmony_ci                                            uint64_t num_bytes,
367310c0d0Sopenharmony_ci                                            void *buffer,
377310c0d0Sopenharmony_ci                                            uint64_t *out_num_read)
387310c0d0Sopenharmony_ci{
397310c0d0Sopenharmony_ci    int fd;
407310c0d0Sopenharmony_ci    off_t where;
417310c0d0Sopenharmony_ci    suint64_t num_read;
427310c0d0Sopenharmony_ci    enum hvb_io_errno ret = HVB_IO_OK;
437310c0d0Sopenharmony_ci
447310c0d0Sopenharmony_ci    fd = open(partition, O_RDONLY);
457310c0d0Sopenharmony_ci    if (fd == -1) {
467310c0d0Sopenharmony_ci        printf("Error open %s partition.\n", partition);
477310c0d0Sopenharmony_ci        ret = HVB_IO_ERROR_NO_SUCH_PARTITION;
487310c0d0Sopenharmony_ci        goto out;
497310c0d0Sopenharmony_ci    }
507310c0d0Sopenharmony_ci
517310c0d0Sopenharmony_ci    if (offset < 0) {
527310c0d0Sopenharmony_ci        uint64_t partition_size;
537310c0d0Sopenharmony_ci        if (ioctl(fd, BLKGETSIZE64, &partition_size) != 0) {
547310c0d0Sopenharmony_ci            printf("Error getting size of %s partition.\n", partition);
557310c0d0Sopenharmony_ci            ret = HVB_IO_ERROR_IO;
567310c0d0Sopenharmony_ci            goto out;
577310c0d0Sopenharmony_ci        }
587310c0d0Sopenharmony_ci        offset = partition_size - (-offset);
597310c0d0Sopenharmony_ci    }
607310c0d0Sopenharmony_ci
617310c0d0Sopenharmony_ci    where = lseek(fd, offset, SEEK_SET);
627310c0d0Sopenharmony_ci    if (where == -1) {
637310c0d0Sopenharmony_ci        printf("Error seeking to offset.\n");
647310c0d0Sopenharmony_ci        ret = HVB_IO_ERROR_IO;
657310c0d0Sopenharmony_ci        goto out;
667310c0d0Sopenharmony_ci    } else if (where != offset) {
677310c0d0Sopenharmony_ci        printf("Error seeking to offset.\n");
687310c0d0Sopenharmony_ci        ret = HVB_IO_ERROR_RANGE_OUTSIDE_PARTITION;
697310c0d0Sopenharmony_ci        goto out;
707310c0d0Sopenharmony_ci    }
717310c0d0Sopenharmony_ci
727310c0d0Sopenharmony_ci    num_read = read(fd, buffer, num_bytes);
737310c0d0Sopenharmony_ci    if (num_read == -1) {
747310c0d0Sopenharmony_ci        printf("Error reading data.\n");
757310c0d0Sopenharmony_ci        ret = HVB_IO_ERROR_IO;
767310c0d0Sopenharmony_ci        goto out;
777310c0d0Sopenharmony_ci    }
787310c0d0Sopenharmony_ci
797310c0d0Sopenharmony_ci    if (out_num_read != NULL) {
807310c0d0Sopenharmony_ci        *out_num_read = num_read;
817310c0d0Sopenharmony_ci    }
827310c0d0Sopenharmony_ci
837310c0d0Sopenharmony_ciout:
847310c0d0Sopenharmony_ci    if (fd != -1) {
857310c0d0Sopenharmony_ci        if (close(fd) != 0) {
867310c0d0Sopenharmony_ci            printf("Error closing file descriptor.\n");
877310c0d0Sopenharmony_ci        }
887310c0d0Sopenharmony_ci    }
897310c0d0Sopenharmony_ci
907310c0d0Sopenharmony_ci    return ret;
917310c0d0Sopenharmony_ci}
927310c0d0Sopenharmony_ci
937310c0d0Sopenharmony_cistatic enum hvb_io_errno hvb_write_partition(struct hvb_ops *ops,
947310c0d0Sopenharmony_ci                                             const char *partition,
957310c0d0Sopenharmony_ci                                             int64_t offset,
967310c0d0Sopenharmony_ci                                             uint64_t num_bytes,
977310c0d0Sopenharmony_ci                                             const void *buffer)
987310c0d0Sopenharmony_ci{
997310c0d0Sopenharmony_ci    int fd;
1007310c0d0Sopenharmony_ci    off_t where;
1017310c0d0Sopenharmony_ci    suint64_t num_written;
1027310c0d0Sopenharmony_ci    enum hvb_io_errno ret = HVB_IO_OK;
1037310c0d0Sopenharmony_ci
1047310c0d0Sopenharmony_ci    fd = open(partition, O_WRONLY);
1057310c0d0Sopenharmony_ci    if (fd == -1) {
1067310c0d0Sopenharmony_ci        printf("Error opening %s partition.\n", partition);
1077310c0d0Sopenharmony_ci        ret = HVB_IO_ERROR_IO;
1087310c0d0Sopenharmony_ci        goto out;
1097310c0d0Sopenharmony_ci    }
1107310c0d0Sopenharmony_ci
1117310c0d0Sopenharmony_ci    where = lseek(fd, offset, SEEK_SET);
1127310c0d0Sopenharmony_ci    if (where == -1) {
1137310c0d0Sopenharmony_ci        printf("Error seeking to offset.\n");
1147310c0d0Sopenharmony_ci        ret = HVB_IO_ERROR_IO;
1157310c0d0Sopenharmony_ci        goto out;
1167310c0d0Sopenharmony_ci    } else if (where != offset) {
1177310c0d0Sopenharmony_ci        printf("Error seeking to offset.\n");
1187310c0d0Sopenharmony_ci        ret = HVB_IO_ERROR_RANGE_OUTSIDE_PARTITION;
1197310c0d0Sopenharmony_ci        goto out;
1207310c0d0Sopenharmony_ci    }
1217310c0d0Sopenharmony_ci
1227310c0d0Sopenharmony_ci    /* On Linux, we never get partial writes on block devices. */
1237310c0d0Sopenharmony_ci    num_written = write(fd, buffer, num_bytes);
1247310c0d0Sopenharmony_ci    if (num_written == -1) {
1257310c0d0Sopenharmony_ci        printf("Error writing data.\n");
1267310c0d0Sopenharmony_ci        ret = HVB_IO_ERROR_IO;
1277310c0d0Sopenharmony_ci        goto out;
1287310c0d0Sopenharmony_ci    }
1297310c0d0Sopenharmony_ci
1307310c0d0Sopenharmony_ciout:
1317310c0d0Sopenharmony_ci    if (fd != -1) {
1327310c0d0Sopenharmony_ci        if (close(fd) != 0) {
1337310c0d0Sopenharmony_ci            printf("Error closing file descriptor.\n");
1347310c0d0Sopenharmony_ci        }
1357310c0d0Sopenharmony_ci    }
1367310c0d0Sopenharmony_ci
1377310c0d0Sopenharmony_ci    return ret;
1387310c0d0Sopenharmony_ci}
1397310c0d0Sopenharmony_ci
1407310c0d0Sopenharmony_cistatic enum hvb_io_errno hvb_read_rollback(struct hvb_ops *ops,
1417310c0d0Sopenharmony_ci                                           uint64_t rollback_index_location,
1427310c0d0Sopenharmony_ci                                           uint64_t *out_rollback_index)
1437310c0d0Sopenharmony_ci{
1447310c0d0Sopenharmony_ci    if (out_rollback_index != NULL) {
1457310c0d0Sopenharmony_ci        *out_rollback_index = 0;
1467310c0d0Sopenharmony_ci    }
1477310c0d0Sopenharmony_ci
1487310c0d0Sopenharmony_ci    return HVB_IO_OK;
1497310c0d0Sopenharmony_ci}
1507310c0d0Sopenharmony_ci
1517310c0d0Sopenharmony_cistatic enum hvb_io_errno hvb_write_rollback(struct hvb_ops *ops,
1527310c0d0Sopenharmony_ci                                            uint64_t rollback_index_location,
1537310c0d0Sopenharmony_ci                                            uint64_t rollback_index)
1547310c0d0Sopenharmony_ci{
1557310c0d0Sopenharmony_ci    return HVB_IO_OK;
1567310c0d0Sopenharmony_ci}
1577310c0d0Sopenharmony_ci
1587310c0d0Sopenharmony_cistatic enum hvb_io_errno hvb_get_partiton_uuid(struct hvb_ops *ops,
1597310c0d0Sopenharmony_ci                                               const char *partition,
1607310c0d0Sopenharmony_ci                                               char *uuid_buf,
1617310c0d0Sopenharmony_ci                                               uint64_t uuid_buf_size)
1627310c0d0Sopenharmony_ci{
1637310c0d0Sopenharmony_ci    if (uuid_buf != NULL && uuid_buf_size > 0) {
1647310c0d0Sopenharmony_ci        uuid_buf[0] = '\0';
1657310c0d0Sopenharmony_ci    }
1667310c0d0Sopenharmony_ci
1677310c0d0Sopenharmony_ci    return HVB_IO_OK;
1687310c0d0Sopenharmony_ci}
1697310c0d0Sopenharmony_ci
1707310c0d0Sopenharmony_cistatic enum hvb_io_errno hvb_get_partiton_size(struct hvb_ops *ops,
1717310c0d0Sopenharmony_ci                                               const char *partition,
1727310c0d0Sopenharmony_ci                                               uint64_t *out_size_in_bytes)
1737310c0d0Sopenharmony_ci{
1747310c0d0Sopenharmony_ci    int fd;
1757310c0d0Sopenharmony_ci    enum hvb_io_errno ret = HVB_IO_OK;
1767310c0d0Sopenharmony_ci
1777310c0d0Sopenharmony_ci    fd = open(partition, O_WRONLY);
1787310c0d0Sopenharmony_ci    if (fd == -1) {
1797310c0d0Sopenharmony_ci        printf("Error opening %s partition.\n", partition);
1807310c0d0Sopenharmony_ci        ret = HVB_IO_ERROR_IO;
1817310c0d0Sopenharmony_ci        goto out;
1827310c0d0Sopenharmony_ci    }
1837310c0d0Sopenharmony_ci
1847310c0d0Sopenharmony_ci    if (out_size_in_bytes != NULL) {
1857310c0d0Sopenharmony_ci        if (ioctl(fd, BLKGETSIZE64, out_size_in_bytes) != 0) {
1867310c0d0Sopenharmony_ci            printf("Error getting size of %s partition.\n", partition);
1877310c0d0Sopenharmony_ci            ret = HVB_IO_ERROR_IO;
1887310c0d0Sopenharmony_ci            goto out;
1897310c0d0Sopenharmony_ci        }
1907310c0d0Sopenharmony_ci    }
1917310c0d0Sopenharmony_ci
1927310c0d0Sopenharmony_ciout:
1937310c0d0Sopenharmony_ci    if (fd != -1) {
1947310c0d0Sopenharmony_ci        if (close(fd) != 0) {
1957310c0d0Sopenharmony_ci            printf("Error closing file descriptor.\n");
1967310c0d0Sopenharmony_ci        }
1977310c0d0Sopenharmony_ci    }
1987310c0d0Sopenharmony_ci
1997310c0d0Sopenharmony_ci    return ret;
2007310c0d0Sopenharmony_ci}
2017310c0d0Sopenharmony_ci
2027310c0d0Sopenharmony_cistatic struct hvb_ops *hvb_ops_user(void)
2037310c0d0Sopenharmony_ci{
2047310c0d0Sopenharmony_ci    struct hvb_ops *hvb_ops;
2057310c0d0Sopenharmony_ci
2067310c0d0Sopenharmony_ci    hvb_ops = (struct hvb_ops *)hvb_malloc(sizeof(struct hvb_ops));
2077310c0d0Sopenharmony_ci    if (!hvb_ops) {
2087310c0d0Sopenharmony_ci        printf("Error malloc for hvb_ops.\n");
2097310c0d0Sopenharmony_ci        return NULL;
2107310c0d0Sopenharmony_ci    }
2117310c0d0Sopenharmony_ci
2127310c0d0Sopenharmony_ci    hvb_ops->user_data = hvb_ops;
2137310c0d0Sopenharmony_ci    hvb_ops->read_partition = hvb_read_partition;
2147310c0d0Sopenharmony_ci    hvb_ops->write_partition = hvb_write_partition;
2157310c0d0Sopenharmony_ci    hvb_ops->read_rollback = hvb_read_rollback;
2167310c0d0Sopenharmony_ci    hvb_ops->write_rollback = hvb_write_rollback;
2177310c0d0Sopenharmony_ci    hvb_ops->get_partiton_uuid = hvb_get_partiton_uuid;
2187310c0d0Sopenharmony_ci    hvb_ops->get_partiton_size = hvb_get_partiton_size;
2197310c0d0Sopenharmony_ci
2207310c0d0Sopenharmony_ci    return hvb_ops;
2217310c0d0Sopenharmony_ci}
2227310c0d0Sopenharmony_ci
2237310c0d0Sopenharmony_ciint main(void)
2247310c0d0Sopenharmony_ci{
2257310c0d0Sopenharmony_ci    int ret = -1;
2267310c0d0Sopenharmony_ci    enum hvb_errno sub_ret = HVB_OK;
2277310c0d0Sopenharmony_ci    struct hvb_verified_data *verified_data = NULL;
2287310c0d0Sopenharmony_ci
2297310c0d0Sopenharmony_ci    printf("hvb main function start.\n");
2307310c0d0Sopenharmony_ci    g_hvb_ops = hvb_ops_user();
2317310c0d0Sopenharmony_ci    if (!g_hvb_ops) {
2327310c0d0Sopenharmony_ci        printf("failed to get hvb_ops_user.\n");
2337310c0d0Sopenharmony_ci        goto out;
2347310c0d0Sopenharmony_ci    }
2357310c0d0Sopenharmony_ci
2367310c0d0Sopenharmony_ci    sub_ret = hvb_chain_verify(g_hvb_ops, "rvt", &verified_data);
2377310c0d0Sopenharmony_ci    if (sub_ret != HVB_OK) {
2387310c0d0Sopenharmony_ci        printf("hvb verity error.\n");
2397310c0d0Sopenharmony_ci        goto out;
2407310c0d0Sopenharmony_ci    }
2417310c0d0Sopenharmony_ci    printf("hvb main end.\n");
2427310c0d0Sopenharmony_ci
2437310c0d0Sopenharmony_ciout:
2447310c0d0Sopenharmony_ci    if (g_hvb_ops != NULL) {
2457310c0d0Sopenharmony_ci        hvb_free(g_hvb_ops);
2467310c0d0Sopenharmony_ci    }
2477310c0d0Sopenharmony_ci
2487310c0d0Sopenharmony_ci    return ret;
2497310c0d0Sopenharmony_ci}
250