1 /*
2 * Copyright (c) 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 "module_hvb_ops.h"
17
18 #include <cerrno>
19 #include <fcntl.h>
20
21 #include "directory_ex.h"
22 #include "log/log.h"
23 #include "module_constants.h"
24 #include "module_file.h"
25 #include "module_utils.h"
26 #include "unique_fd.h"
27
28 #ifdef __cplusplus
29 #if __cplusplus
30 extern "C" {
31 #endif
32 #endif
33
34 using namespace OHOS::SysInstaller;
35 using namespace Updater;
36
ParseReadParam(const std::string & path,const int64_t offset,const uint64_t numBytes,off_t & outOffset,size_t & outCount)37 static bool ParseReadParam(const std::string &path, const int64_t offset, const uint64_t numBytes, off_t &outOffset,
38 size_t &outCount)
39 {
40 std::string modulePath = OHOS::ExtractFilePath(path) + HMP_INFO_NAME;
41 std::unique_ptr<ModuleFile> file = ModuleFile::Open(modulePath);
42 if (file == nullptr) {
43 LOG(ERROR) << "failed to parse file " << modulePath;
44 return false;
45 }
46 if (!file->GetImageStat().has_value()) {
47 LOG(ERROR) << modulePath << " has no image";
48 return false;
49 }
50 int64_t imageOffset = static_cast<int64_t>(file->GetImageStat().value().imageOffset);
51 int64_t imageSize = static_cast<int64_t>(file->GetImageStat().value().imageSize);
52 outOffset = offset + imageOffset;
53 if (offset < 0) {
54 outOffset += imageSize;
55 }
56 if (outOffset < imageOffset) {
57 LOG(ERROR) << "invalid offset " << offset;
58 return false;
59 }
60 outCount = imageOffset + imageSize - outOffset;
61 if (outCount > numBytes) {
62 outCount = numBytes;
63 }
64 return true;
65 }
66
HvbReadFromPartition(struct hvb_ops * ops,const char * partition,int64_t offset,uint64_t numBytes,void * buf,uint64_t * outNumRead)67 static enum hvb_io_errno HvbReadFromPartition(
68 struct hvb_ops *ops, const char *partition, int64_t offset, uint64_t numBytes, void *buf, uint64_t *outNumRead)
69 {
70 if (partition == nullptr) {
71 LOG(ERROR) << "partition is null";
72 return HVB_IO_ERROR_IO;
73 }
74 if (buf == nullptr) {
75 LOG(ERROR) << "buf is null";
76 return HVB_IO_ERROR_IO;
77 }
78
79 std::string path = std::string(partition);
80 std::string realPath = GetRealPath(path);
81 if (realPath.empty()) {
82 LOG(ERROR) << "invalid path " << path;
83 return HVB_IO_ERROR_IO;
84 }
85 off_t realOffset = 0;
86 size_t count = 0;
87 if (!ParseReadParam(path, offset, numBytes, realOffset, count)) {
88 return HVB_IO_ERROR_IO;
89 }
90
91 OHOS::UniqueFd fd(open(realPath.c_str(), O_RDONLY | O_CLOEXEC));
92 if (fd.Get() == -1) {
93 LOG(ERROR) << "failed to open file " << realPath << " err=" << errno;
94 return HVB_IO_ERROR_IO;
95 }
96 if (!ReadFullyAtOffset(fd.Get(), reinterpret_cast<uint8_t *>(buf), count, realOffset)) {
97 LOG(ERROR) << "failed to read file " << realPath;
98 return HVB_IO_ERROR_IO;
99 }
100 if (outNumRead != nullptr) {
101 *outNumRead = count;
102 }
103
104 return HVB_IO_OK;
105 }
106
HvbWriteToPartition(struct hvb_ops * ops,const char * partition,int64_t offset,uint64_t numBytes,const void * buf)107 static enum hvb_io_errno HvbWriteToPartition(
108 struct hvb_ops *ops, const char *partition, int64_t offset, uint64_t numBytes, const void *buf)
109 {
110 return HVB_IO_OK;
111 }
112
HvbInvalidateKey(struct hvb_ops * ops,const uint8_t * publicKeyData,uint64_t publicKeyLength,const uint8_t * publicKeyMetadata,uint64_t publicKeyMetadataLength,bool * outIsTrusted)113 static enum hvb_io_errno HvbInvalidateKey(struct hvb_ops *ops, const uint8_t *publicKeyData, uint64_t publicKeyLength,
114 const uint8_t *publicKeyMetadata, uint64_t publicKeyMetadataLength, bool *outIsTrusted)
115 {
116 if (outIsTrusted == nullptr) {
117 return HVB_IO_ERROR_IO;
118 }
119
120 *outIsTrusted = true;
121
122 return HVB_IO_OK;
123 }
124
HvbReadRollbackIdx(struct hvb_ops * ops,uint64_t rollBackIndexLocation,uint64_t * outRollbackIndex)125 static enum hvb_io_errno HvbReadRollbackIdx(
126 struct hvb_ops *ops, uint64_t rollBackIndexLocation, uint64_t *outRollbackIndex)
127 {
128 if (outRollbackIndex == nullptr) {
129 return HVB_IO_ERROR_IO;
130 }
131
132 // return 0 as we only need to set up HVB HASHTREE partition
133 *outRollbackIndex = 0;
134
135 return HVB_IO_OK;
136 }
137
HvbWriteRollbackIdx(struct hvb_ops * ops,uint64_t rollBackIndexLocation,uint64_t rollbackIndex)138 static enum hvb_io_errno HvbWriteRollbackIdx(
139 struct hvb_ops *ops, uint64_t rollBackIndexLocation, uint64_t rollbackIndex)
140 {
141 return HVB_IO_OK;
142 }
143
HvbReadLockState(struct hvb_ops * ops,bool * lock_state)144 static enum hvb_io_errno HvbReadLockState(struct hvb_ops *ops, bool *lock_state)
145 {
146 return HVB_IO_OK;
147 }
148
HvbGetSizeOfPartition(struct hvb_ops * ops,const char * partition,uint64_t * size)149 static enum hvb_io_errno HvbGetSizeOfPartition(struct hvb_ops *ops, const char *partition, uint64_t *size)
150 {
151 if (size == nullptr) {
152 return HVB_IO_ERROR_IO;
153 }
154
155 // The function is for bootloader to load entire content of HVB HASH
156 // partition. In user-space, return 0 as we only need to set up HVB
157 // HASHTREE partitions.
158 *size = 0;
159 return HVB_IO_OK;
160 }
161
162 static struct hvb_ops g_hvb_ops = {
163 .user_data = &g_hvb_ops,
164 .read_partition = HvbReadFromPartition,
165 .write_partition = HvbWriteToPartition,
166 .valid_rvt_key = HvbInvalidateKey,
167 .read_rollback = HvbReadRollbackIdx,
168 .write_rollback = HvbWriteRollbackIdx,
169 .read_lock_state = HvbReadLockState,
170 .get_partiton_size = HvbGetSizeOfPartition,
171 };
172
ModuleHvbGetOps(void)173 struct hvb_ops *ModuleHvbGetOps(void)
174 {
175 return &g_hvb_ops;
176 }
177
178 #ifdef __cplusplus
179 #if __cplusplus
180 }
181 #endif
182 #endif