xref: /base/startup/hvb/test/hvb_main.c (revision 7310c0d0)
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
30static struct struct hvb_ops *g_hvb_ops;
31
32static 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
83out:
84    if (fd != -1) {
85        if (close(fd) != 0) {
86            printf("Error closing file descriptor.\n");
87        }
88    }
89
90    return ret;
91}
92
93static 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
130out:
131    if (fd != -1) {
132        if (close(fd) != 0) {
133            printf("Error closing file descriptor.\n");
134        }
135    }
136
137    return ret;
138}
139
140static 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
151static 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
158static 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
170static 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
192out:
193    if (fd != -1) {
194        if (close(fd) != 0) {
195            printf("Error closing file descriptor.\n");
196        }
197    }
198
199    return ret;
200}
201
202static 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
223int 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
243out:
244    if (g_hvb_ops != NULL) {
245        hvb_free(g_hvb_ops);
246    }
247
248    return ret;
249}
250