• 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 
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