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