• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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