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