• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "fbex.h"
17 
18 #include <cerrno>
19 #include <cstdio>
20 #include <fcntl.h>
21 #include <securec.h>
22 #include <string>
23 #include <sys/ioctl.h>
24 #include <unistd.h>
25 
26 #include "file_ex.h"
27 #include "storage_service_log.h"
28 
29 namespace {
30 constexpr const char *FBEX_UFS_INLINE_SUPPORT_PREFIX = "/sys/devices/platform/";
31 constexpr const char *FBEX_UFS_INLINE_SUPPORT_END = "/ufs_inline_stat";
32 constexpr const char *FBEX_UFS_INLINE_BASE_ADDR = "/proc/bootdevice/name";
33 constexpr const char *FBEX_INLINE_CRYPTO_V3 = "3\n";
34 
35 constexpr const char *FBEX_CMD_PATH = "/dev/fbex_cmd";
36 
37 const uint8_t FBEX_IOC_MAGIC = 'f';
38 const uint8_t FBEX_ADD_IV = 0x1;
39 const uint8_t FBEX_DEL_IV = 0x2;
40 const uint8_t FBEX_LOCK_SCREEN = 0x3;
41 const uint8_t FBEX_UNLOCK_SCREEN = 0x4;
42 const uint8_t FBEX_USER_LOGOUT = 0x8;
43 const uint8_t FBEX_STATUS_REPORT = 0xC;
44 
45 struct FbeOptStr {
46     uint32_t user = 0;
47     uint32_t type = 0;
48     uint32_t len = 0;
49     uint8_t iv[OHOS::StorageDaemon::FBEX_IV_SIZE] = {0};
50     uint8_t flag = 0;
51 };
52 using FbeOpts = FbeOptStr;
53 
54 #define FBEX_IOC_ADD_IV _IOWR(FBEX_IOC_MAGIC, FBEX_ADD_IV, FbeOpts)
55 #define FBEX_IOC_DEL_IV _IOW(FBEX_IOC_MAGIC, FBEX_DEL_IV, FbeOpts)
56 #define FBEX_IOC_LOCK_SCREEN _IOW(FBEX_IOC_MAGIC, FBEX_LOCK_SCREEN, FbeOpts)
57 #define FBEX_IOC_UNLOCK_SCREEN _IOWR(FBEX_IOC_MAGIC, FBEX_UNLOCK_SCREEN, FbeOpts)
58 #define FBEX_IOC_USER_LOGOUT _IOW(FBEX_IOC_MAGIC, FBEX_USER_LOGOUT, FbeOpts)
59 #define FBEX_IOC_STATUS_REPORT _IOW(FBEX_IOC_MAGIC, FBEX_STATUS_REPORT, FbeOpts)
60 } // namespace
61 
62 namespace OHOS {
63 namespace StorageDaemon {
IsFBEXSupported()64 bool FBEX::IsFBEXSupported()
65 {
66     std::string baseAddr;
67     if (!OHOS::LoadStringFromFile(FBEX_UFS_INLINE_BASE_ADDR, baseAddr)) {
68         LOGE("Read baseAddr failed, errno: %{public}d", errno);
69         return false;
70     }
71 
72     std::string path = FBEX_UFS_INLINE_SUPPORT_PREFIX + baseAddr + FBEX_UFS_INLINE_SUPPORT_END;
73     std::string rpath(PATH_MAX + 1, '\0');
74 
75     if ((path.length() > PATH_MAX) || (realpath(path.c_str(), rpath.data()) == nullptr)) {
76         LOGE("realpath of %{public}s failed, errno: %{public}d", path.c_str(), errno);
77         return false;
78     }
79     if (rpath.rfind(FBEX_UFS_INLINE_SUPPORT_PREFIX) != 0) {
80         LOGE("rpath %{public}s is invalid", rpath.c_str());
81         return false;
82     }
83 
84     std::string versionNum;
85     if (!OHOS::LoadStringFromFile(rpath, versionNum)) {
86         LOGE("read ufs_inline_stat failed, errno: %{public}d", errno);
87         return false;
88     }
89     return versionNum.compare(FBEX_INLINE_CRYPTO_V3) == 0;
90 }
91 
CheckIvValid(const uint8_t * iv,uint32_t size)92 static inline bool CheckIvValid(const uint8_t *iv, uint32_t size)
93 {
94     return (iv != nullptr) && (size == FBEX_IV_SIZE);
95 }
96 
InstallKeyToKernel(uint32_t userId,uint32_t type,uint8_t * iv,uint32_t size,uint8_t flag)97 int FBEX::InstallKeyToKernel(uint32_t userId, uint32_t type, uint8_t *iv, uint32_t size, uint8_t flag)
98 {
99     LOGD("enter, userId: %{public}d, type: %{public}u, flag: %{public}u", userId, type, flag);
100     if (!CheckIvValid(iv, size)) {
101         LOGE("install key param invalid");
102         return -EINVAL;
103     }
104 
105     int fd = open(FBEX_CMD_PATH, O_RDWR);
106     if (fd < 0) {
107         LOGE("open fbex_cmd failed, errno: %{public}d", errno);
108         return -errno;
109     }
110 
111     FbeOpts ops{.user = userId, .type = type, .len = size, .flag = flag};
112     (void)memcpy_s(ops.iv, sizeof(ops.iv), iv, size);
113     int ret = ioctl(fd, FBEX_IOC_ADD_IV, &ops);
114     if (ret != 0) {
115         LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", ret, errno);
116         close(fd);
117         return ret;
118     }
119     close(fd);
120 
121     (void)memcpy_s(iv, size, ops.iv, sizeof(ops.iv));
122     LOGD("success");
123     return ret;
124 }
125 
UninstallOrLockUserKeyToKernel(uint32_t userId,uint32_t type,uint8_t * iv,uint32_t size,bool destroy)126 int FBEX::UninstallOrLockUserKeyToKernel(uint32_t userId, uint32_t type, uint8_t *iv, uint32_t size, bool destroy)
127 {
128     LOGD("enter, userId: %{public}d, type: %{public}u, flag: %{public}d", userId, type, destroy);
129     if (!CheckIvValid(iv, size)) {
130         LOGE("uninstall key param invalid");
131         return -EINVAL;
132     }
133 
134     int fd = open(FBEX_CMD_PATH, O_RDWR);
135     if (fd < 0) {
136         LOGE("open fbex_cmd failed, errno: %{public}d", errno);
137         return -errno;
138     }
139 
140     FbeOpts ops{.user = userId, .type = type, .len = size};
141     (void)memcpy_s(ops.iv, sizeof(ops.iv), iv, size);
142     int ret = ioctl(fd, destroy ? FBEX_IOC_DEL_IV : FBEX_IOC_USER_LOGOUT, &ops);
143     if (ret != 0) {
144         LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", ret, errno);
145     }
146     close(fd);
147     return ret;
148 }
149 
150 // for el3 & el4
LockScreenToKernel(uint32_t userId)151 int FBEX::LockScreenToKernel(uint32_t userId)
152 {
153     LOGD("enter, userId: %{public}d", userId);
154 
155     int fd = open(FBEX_CMD_PATH, O_RDWR);
156     if (fd < 0) {
157         LOGE("open fbex_cmd failed, errno: %{public}d", errno);
158         return -errno;
159     }
160 
161     FbeOpts ops{.user = userId};
162     int ret = ioctl(fd, FBEX_IOC_LOCK_SCREEN, &ops);
163     if (ret != 0) {
164         LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", ret, errno);
165     }
166     close(fd);
167     return ret;
168 }
169 
UnlockScreenToKernel(uint32_t userId,uint32_t type,uint8_t * iv,uint32_t size)170 int FBEX::UnlockScreenToKernel(uint32_t userId, uint32_t type, uint8_t *iv, uint32_t size)
171 {
172     LOGD("enter, userId: %{public}d, type: %{public}u", userId, type);
173     if (!CheckIvValid(iv, size)) {
174         LOGE("install key param invalid");
175         return -EINVAL;
176     }
177 
178     int fd = open(FBEX_CMD_PATH, O_RDWR);
179     if (fd < 0) {
180         LOGE("open fbex_cmd failed, errno: %{public}d", errno);
181         return -errno;
182     }
183 
184     FbeOpts ops{.user = userId, .type = type, .len = size};
185     (void)memcpy_s(ops.iv, sizeof(ops.iv), iv, size);
186     int ret = ioctl(fd, FBEX_IOC_UNLOCK_SCREEN, &ops);
187     if (ret != 0) {
188         LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", ret, errno);
189         close(fd);
190         return ret;
191     }
192     close(fd);
193 
194     (void)memcpy_s(iv, size, ops.iv, sizeof(ops.iv));
195     LOGD("success");
196     return ret;
197 }
198 
IsMspReady()199 bool FBEX::IsMspReady()
200 {
201     std::string status;
202     (void)OHOS::LoadStringFromFile(FBEX_CMD_PATH, status);
203     return status == "true";
204 }
205 
GetStatus()206 int FBEX::GetStatus()
207 {
208     int fd = open(FBEX_CMD_PATH, O_RDWR);
209     if (fd < 0) {
210         LOGE("open fbex_cmd failed, errno: %{public}d", errno);
211         return -errno;
212     }
213 
214     FbeOpts ops;
215     int ret = ioctl(fd, FBEX_IOC_STATUS_REPORT, &ops);
216     close(fd);
217     return ret;
218 }
219 } // namespace StorageDaemon
220 } // namespace OHOS
221