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
16 #include <errno.h>
17 #include <fcntl.h>
18 #include <sys/stat.h>
19 #include <unistd.h>
20
21 #include "beget_ext.h"
22 #include "fs_dm.h"
23 #include "fs_hvb.h"
24 #include "securec.h"
25
26 #ifdef __cplusplus
27 #if __cplusplus
28 extern "C" {
29 #endif
30 #endif
31
32 #define PARTITION_PATH_PREFIX "/dev/block/by-name/"
33
GetImageSizeForHVB(const int fd,const char * image)34 static int64_t GetImageSizeForHVB(const int fd, const char* image)
35 {
36 if (fd < 0) {
37 BEGET_LOGE("param is error");
38 return -1;
39 }
40
41 return lseek64(fd, 0, SEEK_END);
42 }
43
HvbReadFromPartition(struct hvb_ops * ops,const char * partition,int64_t offset,uint64_t numBytes,void * buf,uint64_t * outNumRead)44 static enum hvb_io_errno HvbReadFromPartition(struct hvb_ops* ops,
45 const char* partition,
46 int64_t offset, uint64_t numBytes,
47 void* buf, uint64_t* outNumRead)
48 {
49 int rc;
50 int fd = -1;
51 char* path = NULL;
52 size_t pathLen = 0;
53 enum hvb_io_errno ret = HVB_IO_ERROR_IO;
54
55 if (partition == NULL) {
56 BEGET_LOGE("error, partition is NULL");
57 return HVB_IO_ERROR_IO;
58 }
59
60 if (buf == NULL) {
61 BEGET_LOGE("error, buf is NULL");
62 return HVB_IO_ERROR_IO;
63 }
64
65 pathLen = strlen(PARTITION_PATH_PREFIX) + strlen(partition);
66 path = calloc(1, pathLen + 1);
67 if (path == NULL) {
68 BEGET_LOGE("error, calloc fail");
69 return HVB_IO_ERROR_OOM;
70 }
71
72 rc = snprintf_s(path, pathLen + 1, pathLen, "%s%s", PARTITION_PATH_PREFIX,
73 partition);
74 if (rc < 0) {
75 BEGET_LOGE("error, snprintf_s fail, ret = %d", rc);
76 ret = HVB_IO_ERROR_IO;
77 goto exit;
78 }
79
80 fd = open(path, O_RDONLY | O_CLOEXEC);
81 if (fd < 0) {
82 BEGET_LOGE("error, Failed to open %s, errno = %d", path, errno);
83 fd = open("/dev/block/by-name/rvt_system", O_RDONLY | O_CLOEXEC);
84 BEGET_LOGE("open %s, fd=%d errno = %d", "/dev/block/by-name/rvt_system",
85 fd, errno);
86 if (fd >= 0) {
87 close(fd);
88 }
89 ret = HVB_IO_ERROR_IO;
90 goto exit;
91 }
92
93 if (offset < 0) {
94 int64_t total_size = GetImageSizeForHVB(fd, partition);
95 if (total_size == -1) {
96 BEGET_LOGE("Failed to get the size of the partition %s", partition);
97 ret = HVB_IO_ERROR_IO;
98 goto exit;
99 }
100 offset = total_size + offset;
101 }
102
103 lseek64(fd, offset, SEEK_SET);
104
105 ssize_t numRead = read(fd, buf, numBytes);
106 if (numRead < 0 || (size_t)numRead != numBytes) {
107 BEGET_LOGE("Failed to read %lld bytes from %s offset %lld", numBytes,
108 path, offset);
109 ret = HVB_IO_ERROR_IO;
110 goto exit;
111 }
112
113 if (outNumRead != NULL) {
114 *outNumRead = numRead;
115 }
116
117 ret = HVB_IO_OK;
118
119 exit:
120
121 if (path != NULL) {
122 free(path);
123 }
124
125 if (fd >= 0) {
126 close(fd);
127 }
128 return ret;
129 }
130
HvbWriteToPartition(struct hvb_ops * ops,const char * partition,int64_t offset,uint64_t numBytes,const void * buf)131 static enum hvb_io_errno HvbWriteToPartition(struct hvb_ops* ops,
132 const char* partition,
133 int64_t offset, uint64_t numBytes,
134 const void* buf)
135 {
136 return HVB_IO_OK;
137 }
138
HvbInvaldateKey(struct hvb_ops * ops,const uint8_t * publicKeyData,uint64_t publicKeyLength,const uint8_t * publicKeyMetadata,uint64_t publicKeyMetadataLength,bool * outIsTrusted)139 static enum hvb_io_errno HvbInvaldateKey(struct hvb_ops* ops,
140 const uint8_t* publicKeyData,
141 uint64_t publicKeyLength,
142 const uint8_t* publicKeyMetadata,
143 uint64_t publicKeyMetadataLength,
144 bool* outIsTrusted)
145 {
146 if (outIsTrusted == NULL) {
147 return HVB_IO_ERROR_IO;
148 }
149
150 *outIsTrusted = true;
151
152 return HVB_IO_OK;
153 }
154
HvbReadRollbackIdx(struct hvb_ops * ops,uint64_t rollBackIndexLocation,uint64_t * outRollbackIndex)155 static enum hvb_io_errno HvbReadRollbackIdx(struct hvb_ops* ops,
156 uint64_t rollBackIndexLocation,
157 uint64_t* outRollbackIndex)
158 {
159 if (outRollbackIndex == NULL) {
160 return HVB_IO_ERROR_IO;
161 }
162
163 // return 0 as we only need to set up HVB HASHTREE partitions
164 *outRollbackIndex = 0;
165
166 return HVB_IO_OK;
167 }
168
HvbWriteRollbackIdx(struct hvb_ops * ops,uint64_t rollBackIndexLocation,uint64_t rollbackIndex)169 static enum hvb_io_errno HvbWriteRollbackIdx(struct hvb_ops* ops,
170 uint64_t rollBackIndexLocation,
171 uint64_t rollbackIndex)
172 {
173 return HVB_IO_OK;
174 }
175
HvbReadLockState(struct hvb_ops * ops,bool * lock_state)176 static enum hvb_io_errno HvbReadLockState(struct hvb_ops* ops,
177 bool* lock_state)
178 {
179 return HVB_IO_OK;
180 }
181
HvbGetSizeOfPartition(struct hvb_ops * ops,const char * partition,uint64_t * size)182 static enum hvb_io_errno HvbGetSizeOfPartition(struct hvb_ops* ops,
183 const char* partition,
184 uint64_t* size)
185 {
186 if (size == NULL) {
187 return HVB_IO_ERROR_IO;
188 }
189
190 // The function is for bootloader to load entire content of HVB HASH
191 // partitions. In user-space, return 0 as we only need to set up HVB
192 // HASHTREE partitions.
193 *size = 0;
194 return HVB_IO_OK;
195 }
196
197 static struct hvb_ops g_hvb_ops = {
198 .user_data = &g_hvb_ops,
199 .read_partition = HvbReadFromPartition,
200 .write_partition = HvbWriteToPartition,
201 .valid_rvt_key = HvbInvaldateKey,
202 .read_rollback = HvbReadRollbackIdx,
203 .write_rollback = HvbWriteRollbackIdx,
204 .read_lock_state = HvbReadLockState,
205 .get_partiton_size = HvbGetSizeOfPartition,
206 };
207
FsHvbGetOps(void)208 struct hvb_ops* FsHvbGetOps(void)
209 {
210 return &g_hvb_ops;
211 }
212
213 #ifdef __cplusplus
214 #if __cplusplus
215 }
216 #endif
217 #endif
218