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 <stdlib.h>
16 #include <string.h>
17 #include <sys/ioctl.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21 #include <stdio.h>
22 #include <linux/fs.h>
23
24 #include <errno.h>
25 #include <fcntl.h>
26
27 #include "hvb_ops.h"
28 #include "hvb.h"
29
30 static struct struct hvb_ops *g_hvb_ops;
31
hvb_read_partition(struct hvb_ops * ops,const char * partition,int64_t offset,uint64_t num_bytes,void * buffer,uint64_t * out_num_read)32 static enum hvb_io_errno hvb_read_partition(struct hvb_ops *ops,
33 const char *partition,
34 int64_t offset,
35 uint64_t num_bytes,
36 void *buffer,
37 uint64_t *out_num_read)
38 {
39 int fd;
40 off_t where;
41 suint64_t num_read;
42 enum hvb_io_errno ret = HVB_IO_OK;
43
44 fd = open(partition, O_RDONLY);
45 if (fd == -1) {
46 printf("Error open %s partition.\n", partition);
47 ret = HVB_IO_ERROR_NO_SUCH_PARTITION;
48 goto out;
49 }
50
51 if (offset < 0) {
52 uint64_t partition_size;
53 if (ioctl(fd, BLKGETSIZE64, &partition_size) != 0) {
54 printf("Error getting size of %s partition.\n", partition);
55 ret = HVB_IO_ERROR_IO;
56 goto out;
57 }
58 offset = partition_size - (-offset);
59 }
60
61 where = lseek(fd, offset, SEEK_SET);
62 if (where == -1) {
63 printf("Error seeking to offset.\n");
64 ret = HVB_IO_ERROR_IO;
65 goto out;
66 } else if (where != offset) {
67 printf("Error seeking to offset.\n");
68 ret = HVB_IO_ERROR_RANGE_OUTSIDE_PARTITION;
69 goto out;
70 }
71
72 num_read = read(fd, buffer, num_bytes);
73 if (num_read == -1) {
74 printf("Error reading data.\n");
75 ret = HVB_IO_ERROR_IO;
76 goto out;
77 }
78
79 if (out_num_read != NULL) {
80 *out_num_read = num_read;
81 }
82
83 out:
84 if (fd != -1) {
85 if (close(fd) != 0) {
86 printf("Error closing file descriptor.\n");
87 }
88 }
89
90 return ret;
91 }
92
hvb_write_partition(struct hvb_ops * ops,const char * partition,int64_t offset,uint64_t num_bytes,const void * buffer)93 static enum hvb_io_errno hvb_write_partition(struct hvb_ops *ops,
94 const char *partition,
95 int64_t offset,
96 uint64_t num_bytes,
97 const void *buffer)
98 {
99 int fd;
100 off_t where;
101 suint64_t num_written;
102 enum hvb_io_errno ret = HVB_IO_OK;
103
104 fd = open(partition, O_WRONLY);
105 if (fd == -1) {
106 printf("Error opening %s partition.\n", partition);
107 ret = HVB_IO_ERROR_IO;
108 goto out;
109 }
110
111 where = lseek(fd, offset, SEEK_SET);
112 if (where == -1) {
113 printf("Error seeking to offset.\n");
114 ret = HVB_IO_ERROR_IO;
115 goto out;
116 } else if (where != offset) {
117 printf("Error seeking to offset.\n");
118 ret = HVB_IO_ERROR_RANGE_OUTSIDE_PARTITION;
119 goto out;
120 }
121
122 /* On Linux, we never get partial writes on block devices. */
123 num_written = write(fd, buffer, num_bytes);
124 if (num_written == -1) {
125 printf("Error writing data.\n");
126 ret = HVB_IO_ERROR_IO;
127 goto out;
128 }
129
130 out:
131 if (fd != -1) {
132 if (close(fd) != 0) {
133 printf("Error closing file descriptor.\n");
134 }
135 }
136
137 return ret;
138 }
139
hvb_read_rollback(struct hvb_ops * ops,uint64_t rollback_index_location,uint64_t * out_rollback_index)140 static enum hvb_io_errno hvb_read_rollback(struct hvb_ops *ops,
141 uint64_t rollback_index_location,
142 uint64_t *out_rollback_index)
143 {
144 if (out_rollback_index != NULL) {
145 *out_rollback_index = 0;
146 }
147
148 return HVB_IO_OK;
149 }
150
hvb_write_rollback(struct hvb_ops * ops,uint64_t rollback_index_location,uint64_t rollback_index)151 static enum hvb_io_errno hvb_write_rollback(struct hvb_ops *ops,
152 uint64_t rollback_index_location,
153 uint64_t rollback_index)
154 {
155 return HVB_IO_OK;
156 }
157
hvb_get_partiton_uuid(struct hvb_ops * ops,const char * partition,char * uuid_buf,uint64_t uuid_buf_size)158 static enum hvb_io_errno hvb_get_partiton_uuid(struct hvb_ops *ops,
159 const char *partition,
160 char *uuid_buf,
161 uint64_t uuid_buf_size)
162 {
163 if (uuid_buf != NULL && uuid_buf_size > 0) {
164 uuid_buf[0] = '\0';
165 }
166
167 return HVB_IO_OK;
168 }
169
hvb_get_partiton_size(struct hvb_ops * ops,const char * partition,uint64_t * out_size_in_bytes)170 static enum hvb_io_errno hvb_get_partiton_size(struct hvb_ops *ops,
171 const char *partition,
172 uint64_t *out_size_in_bytes)
173 {
174 int fd;
175 enum hvb_io_errno ret = HVB_IO_OK;
176
177 fd = open(partition, O_WRONLY);
178 if (fd == -1) {
179 printf("Error opening %s partition.\n", partition);
180 ret = HVB_IO_ERROR_IO;
181 goto out;
182 }
183
184 if (out_size_in_bytes != NULL) {
185 if (ioctl(fd, BLKGETSIZE64, out_size_in_bytes) != 0) {
186 printf("Error getting size of %s partition.\n", partition);
187 ret = HVB_IO_ERROR_IO;
188 goto out;
189 }
190 }
191
192 out:
193 if (fd != -1) {
194 if (close(fd) != 0) {
195 printf("Error closing file descriptor.\n");
196 }
197 }
198
199 return ret;
200 }
201
hvb_ops_user(void)202 static struct hvb_ops *hvb_ops_user(void)
203 {
204 struct hvb_ops *hvb_ops;
205
206 hvb_ops = (struct hvb_ops *)hvb_malloc(sizeof(struct hvb_ops));
207 if (!hvb_ops) {
208 printf("Error malloc for hvb_ops.\n");
209 return NULL;
210 }
211
212 hvb_ops->user_data = hvb_ops;
213 hvb_ops->read_partition = hvb_read_partition;
214 hvb_ops->write_partition = hvb_write_partition;
215 hvb_ops->read_rollback = hvb_read_rollback;
216 hvb_ops->write_rollback = hvb_write_rollback;
217 hvb_ops->get_partiton_uuid = hvb_get_partiton_uuid;
218 hvb_ops->get_partiton_size = hvb_get_partiton_size;
219
220 return hvb_ops;
221 }
222
main(void)223 int main(void)
224 {
225 int ret = -1;
226 enum hvb_errno sub_ret = HVB_OK;
227 struct hvb_verified_data *verified_data = NULL;
228
229 printf("hvb main function start.\n");
230 g_hvb_ops = hvb_ops_user();
231 if (!g_hvb_ops) {
232 printf("failed to get hvb_ops_user.\n");
233 goto out;
234 }
235
236 sub_ret = hvb_chain_verify(g_hvb_ops, "rvt", &verified_data);
237 if (sub_ret != HVB_OK) {
238 printf("hvb verity error.\n");
239 goto out;
240 }
241 printf("hvb main end.\n");
242
243 out:
244 if (g_hvb_ops != NULL) {
245 hvb_free(g_hvb_ops);
246 }
247
248 return ret;
249 }
250