1 /*
2 * Copyright (c) 2022-2024 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 <cstdio>
23 #include <dirent.h>
24 #include <string>
25 #include <sys/ioctl.h>
26 #include <unistd.h>
27
28 #include "file_ex.h"
29 #include "storage_service_log.h"
30 #include "openssl_crypto.h"
31
32 namespace {
33 constexpr const char *FBEX_UFS_INLINE_SUPPORT_PREFIX = "/sys/devices/platform/";
34 constexpr const char *FBEX_UFS_INLINE_SUPPORT_END = "/ufs_inline_stat";
35 constexpr const char *FBEX_NVME_INLINE_SUPPORT_PATH = "/sys/block/nvme_crypto";
36 constexpr const char *FBEX_EMMC_INLINE_SUPPORT_PATH = "/sys/block/emmc_crypto";
37 constexpr const char *FBEX_UFS_INLINE_BASE_ADDR = "/proc/bootdevice/name";
38 constexpr const char *FBEX_INLINE_CRYPTO_V3 = "3\n";
39
40 constexpr const char *FBEX_CMD_PATH = "/dev/fbex_cmd";
41 constexpr const char *FBEX_UECE_PATH = "/dev/fbex_uece";
42
43 const uint8_t FBEX_IOC_MAGIC = 'f';
44 const uint8_t FBEX_ADD_IV = 0x1;
45 const uint8_t FBEX_DEL_IV = 0x2;
46 const uint8_t FBEX_LOCK_SCREEN = 0x3;
47 const uint8_t FBEX_UNLOCK_SCREEN = 0x4;
48 const uint8_t FBEX_USER_LOGOUT = 0x8;
49 const uint8_t FBEX_STATUS_REPORT = 0xC;
50 const uint8_t FBEX_ADD_EL5 = 21;
51 const uint8_t FBEX_READ_EL5 = 22;
52 const uint8_t FBEX_WRITE_EL5 = 23;
53 const uint8_t FBEX_DEL_EL5_PINCODE = 24;
54 const uint8_t FBEX_GENERATE_APP_KEY = 25;
55 const uint8_t FBEX_CHANGE_PINCODE = 26;
56 const uint8_t FBEX_LOCK_EL5 = 27;
57 const uint32_t FILE_ENCRY_ERROR_UECE_ALREADY_CREATED = 0xFBE30031;
58 const uint32_t FILE_ENCRY_ERROR_NOT_FOUND_UECE = 0xFBE30033;
59
60 struct FbeOptStr {
61 uint32_t user = 0;
62 uint32_t type = 0;
63 uint32_t len = 0;
64 uint8_t iv[OHOS::StorageDaemon::FBEX_IV_SIZE] = {0};
65 uint8_t flag = 0;
66 };
67 using FbeOpts = FbeOptStr;
68
69 struct FbeOptStrE {
70 uint32_t userIdDouble = 0;
71 uint32_t userIdSingle = 0;
72 uint32_t status = 0;
73 uint32_t length = 0;
74 uint8_t eBuffer[OHOS::StorageDaemon::FBEX_E_BUFFER_SIZE] = {0};
75 };
76 using FbeOptsE = FbeOptStrE;
77
78 #define FBEX_IOC_ADD_IV _IOWR(FBEX_IOC_MAGIC, FBEX_ADD_IV, FbeOpts)
79 #define FBEX_IOC_DEL_IV _IOW(FBEX_IOC_MAGIC, FBEX_DEL_IV, FbeOpts)
80 #define FBEX_IOC_LOCK_SCREEN _IOW(FBEX_IOC_MAGIC, FBEX_LOCK_SCREEN, FbeOpts)
81 #define FBEX_IOC_UNLOCK_SCREEN _IOWR(FBEX_IOC_MAGIC, FBEX_UNLOCK_SCREEN, FbeOpts)
82 #define FBEX_IOC_USER_LOGOUT _IOW(FBEX_IOC_MAGIC, FBEX_USER_LOGOUT, FbeOpts)
83 #define FBEX_IOC_STATUS_REPORT _IOW(FBEX_IOC_MAGIC, FBEX_STATUS_REPORT, FbeOpts)
84 #define FBEX_READ_CLASS_E _IOWR(FBEX_IOC_MAGIC, FBEX_READ_EL5, FbeOptsE)
85 #define FBEX_WRITE_CLASS_E _IOWR(FBEX_IOC_MAGIC, FBEX_WRITE_EL5, FbeOptsE)
86 #define FBEX_ADD_CLASS_E _IOWR(FBEX_IOC_MAGIC, FBEX_ADD_EL5, FbeOptsE)
87 #define FBEX_DEL_USER_PINCODE _IOWR(FBEX_IOC_MAGIC, FBEX_DEL_EL5_PINCODE, FbeOptsE)
88 #define FBEX_ADD_APPKEY2 _IOWR(FBEX_IOC_MAGIC, FBEX_GENERATE_APP_KEY, FbeOptsE)
89 #define FBEX_CHANGE_PINCODE _IOWR(FBEX_IOC_MAGIC, FBEX_CHANGE_PINCODE, FbeOptsE)
90 #define FBEX_LOCK_UECE _IOWR(FBEX_IOC_MAGIC, FBEX_LOCK_EL5, FbeOptsE)
91
92 } // namespace
93
94 namespace OHOS {
95 namespace StorageDaemon {
IsFBEXSupported()96 bool FBEX::IsFBEXSupported()
97 {
98 std::string baseAddr;
99 if (!OHOS::LoadStringFromFile(FBEX_UFS_INLINE_BASE_ADDR, baseAddr)) {
100 LOGE("Read baseAddr failed, errno: %{public}d", errno);
101 return false;
102 }
103
104 std::string path = FBEX_UFS_INLINE_SUPPORT_PREFIX + baseAddr + FBEX_UFS_INLINE_SUPPORT_END;
105 std::string nvmePath = FBEX_NVME_INLINE_SUPPORT_PATH;
106 std::string emmcPath = FBEX_EMMC_INLINE_SUPPORT_PATH;
107 std::string rpath(PATH_MAX + 1, '\0');
108
109 if ((path.length() > PATH_MAX) || (realpath(path.c_str(), rpath.data()) == nullptr)) {
110 LOGE("realpath of %{public}s failed, errno: %{public}d", path.c_str(), errno);
111 return ((access(nvmePath.c_str(), F_OK) == 0) || (access(emmcPath.c_str(), F_OK) == 0));
112 }
113 if (rpath.rfind(FBEX_UFS_INLINE_SUPPORT_PREFIX) != 0) {
114 LOGE("rpath %{public}s is invalid", rpath.c_str());
115 return false;
116 }
117
118 std::string versionNum;
119 if (!OHOS::LoadStringFromFile(rpath, versionNum)) {
120 LOGE("read ufs_inline_stat failed, errno: %{public}d", errno);
121 return false;
122 }
123 return versionNum.compare(FBEX_INLINE_CRYPTO_V3) == 0;
124 }
125
CheckIvValid(const uint8_t *iv, uint32_t size)126 static inline bool CheckIvValid(const uint8_t *iv, uint32_t size)
127 {
128 return (iv != nullptr) && (size == FBEX_IV_SIZE);
129 }
130
CheckReadBuffValid(const uint8_t *eBuffer, uint32_t size, uint32_t status)131 static inline bool CheckReadBuffValid(const uint8_t *eBuffer, uint32_t size, uint32_t status)
132 {
133 if (status == UNLOCK_STATUS) {
134 return (eBuffer != nullptr) && (size == (GCM_NONCE_BYTES + AES_256_HASH_RANDOM_SIZE + GCM_MAC_BYTES));
135 }
136 return (eBuffer != nullptr) && (size == AES_256_HASH_RANDOM_SIZE);
137 }
138
CheckWriteBuffValid(const uint8_t *eBuffer, uint32_t size, uint32_t status)139 static inline bool CheckWriteBuffValid(const uint8_t *eBuffer, uint32_t size, uint32_t status)
140 {
141 if (status == UNLOCK_STATUS) {
142 return (eBuffer != nullptr) && (size == AES_256_HASH_RANDOM_SIZE);
143 }
144 return (eBuffer != nullptr) && (size == (GCM_NONCE_BYTES + AES_256_HASH_RANDOM_SIZE + GCM_MAC_BYTES));
145 }
146
InstallEL5KeyToKernel(uint32_t userIdSingle, uint32_t userIdDouble, uint8_t flag, bool &isSupport, bool &isNeedEncryptClassE)147 int FBEX::InstallEL5KeyToKernel(uint32_t userIdSingle, uint32_t userIdDouble, uint8_t flag,
148 bool &isSupport, bool &isNeedEncryptClassE)
149 {
150 LOGI("InstallEL5KeyToKernel enter, userId: %{public}d, flag: %{public}u", userIdDouble, flag);
151 FILE *f = fopen(FBEX_UECE_PATH, "r+");
152 if (f == nullptr) {
153 if (errno == ENOENT) {
154 LOGE("fbex_uece does not exist, fbe not support this command!");
155 isSupport = false;
156 return 0;
157 }
158 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
159 return -errno;
160 }
161 int fd = fileno(f);
162 if (fd < 0) {
163 if (errno == ENOENT) {
164 LOGE("fbex_uece does not exist, fbe not support this command!");
165 isSupport = false;
166 return 0;
167 }
168 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
169 return -errno;
170 }
171
172 FbeOptsE ops{ .userIdDouble = userIdDouble, .userIdSingle = userIdSingle };
173 auto fbeRet = ioctl(fd, FBEX_ADD_CLASS_E, &ops);
174 if (static_cast<uint32_t>(fbeRet) == FILE_ENCRY_ERROR_UECE_ALREADY_CREATED) {
175 LOGE("class uece has already create, ret: 0x%{public}x, errno: %{public}d", fbeRet, errno);
176 isNeedEncryptClassE = false;
177 (void)fclose(f);
178 return 0;
179 }
180 int ret = 0;
181 if (fbeRet != 0) {
182 LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", fbeRet, errno);
183 ret = -errno;
184 }
185 (void)fclose(f);
186 LOGI("InstallEL5KeyToKernel success");
187 return ret;
188 }
189
InstallKeyToKernel(uint32_t userId, uint32_t type, uint8_t *iv, uint32_t size, uint8_t flag)190 int FBEX::InstallKeyToKernel(uint32_t userId, uint32_t type, uint8_t *iv, uint32_t size, uint8_t flag)
191 {
192 LOGI("enter, userId: %{public}d, type: %{public}u, flag: %{public}u", userId, type, flag);
193 if (!CheckIvValid(iv, size)) {
194 LOGE("install key param invalid");
195 return -EINVAL;
196 }
197
198 FILE *f = fopen(FBEX_CMD_PATH, "r+");
199 if (f == nullptr) {
200 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
201 return -errno;
202 }
203 int fd = fileno(f);
204 if (fd < 0) {
205 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
206 return -errno;
207 }
208
209 FbeOpts ops{.user = userId, .type = type, .len = size, .flag = flag};
210 auto err = memcpy_s(ops.iv, sizeof(ops.iv), iv, size);
211 if (err != EOK) {
212 LOGE("memcpy failed %{public}d", err);
213 (void)fclose(f);
214 return 0;
215 }
216 int ret = ioctl(fd, FBEX_IOC_ADD_IV, &ops);
217 if (ret != 0) {
218 LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", ret, errno);
219 (void)fclose(f);
220 return ret;
221 }
222 (void)fclose(f);
223
224 auto errops = memcpy_s(iv, size, ops.iv, sizeof(ops.iv));
225 if (errops != EOK) {
226 LOGE("memcpy failed %{public}d", errops);
227 return 0;
228 }
229 (void)memset_s(&ops.iv, sizeof(ops.iv), 0, sizeof(ops.iv));
230 LOGI("InstallKeyToKernel success");
231 return ret;
232 }
233
UninstallOrLockUserKeyToKernel(uint32_t userId, uint32_t type, uint8_t *iv, uint32_t size, bool destroy)234 int FBEX::UninstallOrLockUserKeyToKernel(uint32_t userId, uint32_t type, uint8_t *iv, uint32_t size, bool destroy)
235 {
236 LOGI("enter, userId: %{public}d, type: %{public}u, flag: %{public}d", userId, type, destroy);
237 if (!CheckIvValid(iv, size)) {
238 LOGE("uninstall key param invalid");
239 return -EINVAL;
240 }
241
242 FILE *f = fopen(FBEX_CMD_PATH, "r+");
243 if (f == nullptr) {
244 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
245 return -errno;
246 }
247 int fd = fileno(f);
248 if (fd < 0) {
249 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
250 return -errno;
251 }
252
253 FbeOpts ops{.user = userId, .type = type, .len = size};
254 auto err = memcpy_s(ops.iv, sizeof(ops.iv), iv, size);
255 if (err != EOK) {
256 LOGE("memcpy failed %{public}d", err);
257 (void)fclose(f);
258 return 0;
259 }
260 int ret = ioctl(fd, destroy ? FBEX_IOC_DEL_IV : FBEX_IOC_USER_LOGOUT, &ops);
261 if (ret != 0 && static_cast<uint32_t>(ret) != FILE_ENCRY_ERROR_NOT_FOUND_UECE) {
262 LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", ret, errno);
263 (void)fclose(f);
264 return ret;
265 }
266 (void)fclose(f);
267 LOGI("success");
268 return 0;
269 }
270
DeleteClassEPinCode(uint32_t userIdSingle, uint32_t userIdDouble)271 int FBEX::DeleteClassEPinCode(uint32_t userIdSingle, uint32_t userIdDouble)
272 {
273 LOGI("enter, userId: %{public}d", userIdDouble);
274 FILE *f = fopen(FBEX_UECE_PATH, "r+");
275 if (f == nullptr) {
276 if (errno == ENOENT) {
277 LOGE("fbex_uece does not exist, fbe not support this command!");
278 return 0;
279 }
280 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
281 return -errno;
282 }
283 int fd = fileno(f);
284 if (fd < 0) {
285 if (errno == ENOENT) {
286 LOGE("fbex_uece does not exist, fbe not support this command!");
287 return 0;
288 }
289 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
290 return -errno;
291 }
292 FbeOptsE ops{ .userIdDouble = userIdDouble, .userIdSingle = userIdSingle };
293 auto fbeRet = ioctl(fd, FBEX_DEL_USER_PINCODE, &ops);
294 int ret = 0;
295 if (fbeRet != 0) {
296 LOGE("ioctl fbex_cmd failed, fbeRet: 0x%{public}x, errno: %{public}d", fbeRet, errno);
297 ret = -errno;
298 }
299 (void)fclose(f);
300 LOGI("success");
301 return ret;
302 }
303
ChangePinCodeClassE(uint32_t userIdSingle, uint32_t userIdDouble, bool &isFbeSupport)304 int FBEX::ChangePinCodeClassE(uint32_t userIdSingle, uint32_t userIdDouble, bool &isFbeSupport)
305 {
306 LOGI("enter, userId: %{public}d", userIdDouble);
307 FILE *f = fopen(FBEX_UECE_PATH, "r+");
308 if (f == nullptr) {
309 if (errno == ENOENT) {
310 LOGE("fbex_uece does not exist, fbe not support this command!");
311 isFbeSupport = false;
312 return 0;
313 }
314 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
315 return -errno;
316 }
317 int fd = fileno(f);
318 if (fd < 0) {
319 if (errno == ENOENT) {
320 LOGE("fbex_uece does not exist, fbe not support this command!");
321 isFbeSupport = false;
322 return 0;
323 }
324 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
325 return -errno;
326 }
327 FbeOptsE ops{ .userIdDouble = userIdDouble, .userIdSingle = userIdSingle };
328 int ret = ioctl(fd, FBEX_CHANGE_PINCODE, &ops);
329 if (ret != 0) {
330 LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", ret, errno);
331 ret = -errno;
332 }
333 (void)fclose(f);
334 LOGI("change pincode classE finish.");
335 return ret;
336 }
337
338 // for el3 & el4
LockScreenToKernel(uint32_t userId)339 int FBEX::LockScreenToKernel(uint32_t userId)
340 {
341 LOGI("enter, userId: %{public}d", userId);
342
343 FILE *f = fopen(FBEX_CMD_PATH, "r+");
344 if (f == nullptr) {
345 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
346 return -errno;
347 }
348 int fd = fileno(f);
349 if (fd < 0) {
350 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
351 return -errno;
352 }
353 FbeOpts ops;
354 (void)memset_s(&ops, sizeof(FbeOpts), 0, sizeof(FbeOpts));
355 ops.user = userId;
356 int ret = ioctl(fd, FBEX_IOC_LOCK_SCREEN, &ops);
357 if (ret != 0) {
358 LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", ret, errno);
359 }
360 (void)fclose(f);
361 LOGI("success");
362 return ret;
363 }
364
GenerateAppkey(UserIdToFbeStr &userIdToFbe, uint32_t hashId, std::unique_ptr<uint8_t[]> &appKey, uint32_t size)365 int FBEX::GenerateAppkey(UserIdToFbeStr &userIdToFbe, uint32_t hashId, std::unique_ptr<uint8_t[]> &appKey,
366 uint32_t size)
367 {
368 LOGI("GenerateAppkey enter");
369 FILE *f = fopen(FBEX_UECE_PATH, "r+");
370 if (f == nullptr) {
371 if (errno == ENOENT) {
372 LOGE("fbex_uece does not exist, fbe not support this command!");
373 appKey.reset(nullptr);
374 return 0;
375 }
376 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
377 return -errno;
378 }
379 int fd = fileno(f);
380 if (fd < 0) {
381 if (errno == ENOENT) {
382 LOGE("fbex_uece does not exist, fbe not support this command!");
383 appKey.reset(nullptr);
384 return 0;
385 }
386 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
387 return -errno;
388 }
389 FbeOptsE ops{ .userIdDouble = userIdToFbe.userIds[DOUBLE_ID_INDEX],
390 .userIdSingle = userIdToFbe.userIds[SINGLE_ID_INDEX],
391 .status = hashId, .length = size };
392 auto fbeRet = ioctl(fd, FBEX_ADD_APPKEY2, &ops);
393 if (fbeRet != 0) {
394 LOGE("ioctl fbex_cmd failed, fbeRet: 0x%{public}x, errno: %{public}d", fbeRet, errno);
395 (void)fclose(f);
396 return -errno;
397 }
398
399 auto err = memcpy_s(appKey.get(), size, ops.eBuffer, sizeof(ops.eBuffer));
400 if (err != EOK) {
401 LOGE("memcpy failed %{public}d", err);
402 return 0;
403 }
404 (void)fclose(f);
405 LOGI("success");
406 return 0;
407 }
408
409 // for el5
LockUece(uint32_t userIdSingle, uint32_t userIdDouble, bool &isFbeSupport)410 int FBEX::LockUece(uint32_t userIdSingle, uint32_t userIdDouble, bool &isFbeSupport)
411 {
412 LOGI("enter, userId: %{public}d", userIdDouble);
413
414 FILE *f = fopen(FBEX_UECE_PATH, "r+");
415 if (f == nullptr) {
416 if (errno == ENOENT) {
417 LOGE("fbex_uece does not exist, fbe not support this command!");
418 isFbeSupport = false;
419 return 0;
420 }
421 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
422 return -errno;
423 }
424 int fd = fileno(f);
425 if (fd < 0) {
426 if (errno == ENOENT) {
427 LOGE("fbex_uece does not exist, fbe not support this command!");
428 isFbeSupport = false;
429 return 0;
430 }
431 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
432 return -errno;
433 }
434 FbeOptsE ops{ .userIdDouble = userIdDouble, .userIdSingle = userIdSingle };
435 int ret = ioctl(fd, FBEX_LOCK_UECE, &ops);
436 if (ret != 0) {
437 LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", ret, errno);
438 }
439 (void)fclose(f);
440 LOGI("success");
441 return ret;
442 }
443
UnlockScreenToKernel(uint32_t userId, uint32_t type, uint8_t *iv, uint32_t size)444 int FBEX::UnlockScreenToKernel(uint32_t userId, uint32_t type, uint8_t *iv, uint32_t size)
445 {
446 LOGI("enter, userId: %{public}d, type: %{public}u", userId, type);
447 if (!CheckIvValid(iv, size)) {
448 LOGE("install key param invalid");
449 return -EINVAL;
450 }
451
452 FILE *f = fopen(FBEX_CMD_PATH, "r+");
453 if (f == nullptr) {
454 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
455 return -errno;
456 }
457 int fd = fileno(f);
458 if (fd < 0) {
459 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
460 return -errno;
461 }
462
463 FbeOpts ops{.user = userId, .type = type, .len = size};
464
465 auto err = memcpy_s(ops.iv, sizeof(ops.iv), iv, size);
466 if (err != EOK) {
467 LOGE("memcpy failed %{public}d", err);
468 (void)fclose(f);
469 return 0;
470 }
471 int ret = ioctl(fd, FBEX_IOC_UNLOCK_SCREEN, &ops);
472 if (ret != 0) {
473 LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", ret, errno);
474 (void)fclose(f);
475 return ret;
476 }
477 (void)fclose(f);
478
479 auto errops = memcpy_s(iv, size, ops.iv, sizeof(ops.iv));
480 if (errops != EOK) {
481 LOGE("memcpy failed %{public}d", errops);
482 return 0;
483 }
484 LOGI("UnlockScreenToKernel success");
485 return ret;
486 }
487
ReadESecretToKernel(UserIdToFbeStr &userIdToFbe, uint32_t status, std::unique_ptr<uint8_t[]> &eBuffer, uint32_t length, bool &isFbeSupport)488 int FBEX::ReadESecretToKernel(UserIdToFbeStr &userIdToFbe, uint32_t status, std::unique_ptr<uint8_t[]> &eBuffer,
489 uint32_t length, bool &isFbeSupport)
490 {
491 LOGI("enter, userId: %{public}d, status: %{public}u", userIdToFbe.userIds[DOUBLE_ID_INDEX], status);
492 if (!CheckReadBuffValid(eBuffer.get(), length, status)) {
493 LOGE("read e secret param invalid");
494 return -EINVAL;
495 }
496 FILE *f = fopen(FBEX_UECE_PATH, "r+");
497 if (f == nullptr) {
498 if (errno == ENOENT) {
499 isFbeSupport = false;
500 return 0;
501 }
502 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
503 return -errno;
504 }
505 int fd = fileno(f);
506 if (fd < 0) {
507 if (errno == ENOENT) {
508 isFbeSupport = false;
509 return 0;
510 }
511 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
512 return -errno;
513 }
514 uint32_t bufferSize = AES_256_HASH_RANDOM_SIZE + GCM_MAC_BYTES + GCM_NONCE_BYTES;
515 FbeOptsE ops{ .userIdDouble = userIdToFbe.userIds[DOUBLE_ID_INDEX],
516 .userIdSingle = userIdToFbe.userIds[SINGLE_ID_INDEX], .status = status, .length = bufferSize };
517 auto err = memcpy_s(ops.eBuffer, sizeof(ops.eBuffer), eBuffer.get(), length);
518 if (err != EOK) {
519 LOGE("memcpy failed %{public}d", err);
520 (void)fclose(f);
521 return 0;
522 }
523 auto ret = ioctl(fd, FBEX_READ_CLASS_E, &ops);
524 if (ret != 0) {
525 LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", ret, errno);
526 (void)fclose(f);
527 return -errno;
528 }
529 (void)fclose(f);
530 if (ops.length == 0) {
531 (void)memset_s(eBuffer.get(), sizeof(eBuffer.get()), 0, sizeof(eBuffer.get()));
532 eBuffer.reset(nullptr);
533 LOGE("ops length is 0, skip");
534 return 0;
535 }
536 UnlockSendSecret(status, bufferSize, length, eBuffer.get(), ops.eBuffer);
537 LOGI("ReadESecretToKernel success");
538 return 0;
539 }
540
UnlockSendSecret(uint32_t status, uint32_t bufferSize, uint32_t length, uint8_t *eBuffer, uint8_t *opseBuffer)541 int FBEX::UnlockSendSecret(uint32_t status, uint32_t bufferSize, uint32_t length, uint8_t *eBuffer, uint8_t *opseBuffer)
542 {
543 if (status == UNLOCK_STATUS) {
544 bufferSize = AES_256_HASH_RANDOM_SIZE + GCM_MAC_BYTES + GCM_NONCE_BYTES;
545 } else {
546 bufferSize = AES_256_HASH_RANDOM_SIZE;
547 }
548 auto errBuffer = memcpy_s(eBuffer, length, opseBuffer, bufferSize);
549 if (errBuffer != EOK) {
550 LOGE("memcpy failed %{public}d", errBuffer);
551 return 0;
552 }
553 return 0;
554 }
555
WriteESecretToKernel(UserIdToFbeStr &userIdToFbe, uint32_t status, uint8_t *eBuffer, uint32_t length)556 int FBEX::WriteESecretToKernel(UserIdToFbeStr &userIdToFbe, uint32_t status, uint8_t *eBuffer, uint32_t length)
557 {
558 LOGI("enter, userId: %{public}d, status: %{public}u", userIdToFbe.userIds[DOUBLE_ID_INDEX], status);
559 if (!CheckWriteBuffValid(eBuffer, length, status)) {
560 LOGE("write e secret param invalid");
561 return -EINVAL;
562 }
563
564 FILE *f = fopen(FBEX_UECE_PATH, "r+");
565 if (f == nullptr) {
566 if (errno == ENOENT) {
567 LOGE("fbex_uece does not exist, fbe not support this command!");
568 return 0;
569 }
570 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
571 return -errno;
572 }
573 int fd = fileno(f);
574 if (fd < 0) {
575 if (errno == ENOENT) {
576 LOGE("fbex_uece does not exist, fbe not support this command!");
577 return 0;
578 }
579 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
580 return -errno;
581 }
582 uint32_t bufferSize = AES_256_HASH_RANDOM_SIZE + GCM_MAC_BYTES + GCM_NONCE_BYTES;
583 FbeOptsE ops{ .userIdDouble = userIdToFbe.userIds[DOUBLE_ID_INDEX],
584 .userIdSingle = userIdToFbe.userIds[SINGLE_ID_INDEX],
585 .status = status, .length = bufferSize };
586 auto err = memcpy_s(ops.eBuffer, sizeof(ops.eBuffer), eBuffer, length);
587 if (err != EOK) {
588 LOGE("memcpy failed %{public}d", err);
589 (void)fclose(f);
590 return 0;
591 }
592 auto ret = ioctl(fd, FBEX_WRITE_CLASS_E, &ops);
593 if (ret != 0) {
594 LOGE("ioctl fbex_cmd failed, ret: 0x%{public}x, errno: %{public}d", ret, errno);
595 (void)fclose(f);
596 return -errno;
597 }
598 (void)fclose(f);
599 LOGI("success");
600 return 0;
601 }
602
IsMspReady()603 bool FBEX::IsMspReady()
604 {
605 std::string status;
606 (void)OHOS::LoadStringFromFile(FBEX_CMD_PATH, status);
607 return status == "true";
608 }
609
GetStatus()610 int FBEX::GetStatus()
611 {
612 FILE *f = fopen(FBEX_CMD_PATH, "r+");
613 if (f == nullptr) {
614 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
615 return -errno;
616 }
617 int fd = fileno(f);
618 if (fd < 0) {
619 LOGE("open fbex_cmd failed, errno: %{public}d", errno);
620 return -errno;
621 }
622
623 FbeOpts ops;
624 int ret = ioctl(fd, FBEX_IOC_STATUS_REPORT, &ops);
625 (void)fclose(f);
626 return ret;
627 }
628 } // namespace StorageDaemon
629 } // namespace OHOS
630