1 /*
2 * Copyright (c) 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 "key_utils.h"
17
18 #include <cstdlib>
19 #include <dlfcn.h>
20 #include <fcntl.h>
21 #include <string>
22 #include <unistd.h>
23 #include <securec.h>
24
25 #include "log.h"
26 #include "parameter.h"
27
28 using namespace OHOS::Security::CodeSign;
29
30 enum DeviceMode {
31 NOT_INITIALIZE = 0,
32 DEVICE_MODE_RD,
33 DEVICE_MODE_NOT_RD
34 };
35
36 constexpr int32_t CMDLINE_MAX_BUF_LEN = 4096;
37 static const std::string PROC_CMDLINE_FILE_PATH = "/proc/cmdline";
38 static int32_t g_isRdDevice = NOT_INITIALIZE;
39
CheckDeviceMode(char * buf,ssize_t bunLen)40 static bool CheckDeviceMode(char *buf, ssize_t bunLen)
41 {
42 if (strstr(buf, "oemmode=rd")) {
43 LOG_DEBUG(LABEL, "Oemode is rd");
44 return true;
45 } else {
46 LOG_DEBUG(LABEL, "Not rd mode, cmdline = %{private}s", buf);
47 }
48 return false;
49 }
50
CheckEfuseStatus(char * buf,ssize_t bunLen)51 static int32_t CheckEfuseStatus(char *buf, ssize_t bunLen)
52 {
53 if (strstr(buf, "efuse_status=1")) {
54 LOG_DEBUG(LABEL, "device is not efused");
55 return true;
56 } else {
57 LOG_DEBUG(LABEL, "Not efused, cmdline = %{private}s", buf);
58 }
59 return false;
60 }
61
ParseCMDLine()62 static void ParseCMDLine()
63 {
64 int32_t fd = open(PROC_CMDLINE_FILE_PATH.c_str(), O_RDONLY);
65 if (fd < 0) {
66 g_isRdDevice = DEVICE_MODE_NOT_RD;
67 LOG_ERROR(LABEL, "open %{public}s failed, %{public}s",
68 PROC_CMDLINE_FILE_PATH.c_str(), strerror(errno));
69 return;
70 }
71 char *buf = nullptr;
72 int32_t status = DEVICE_MODE_NOT_RD;
73 do {
74 buf = static_cast<char *>(malloc(CMDLINE_MAX_BUF_LEN));
75 if (buf == nullptr) {
76 LOG_ERROR(LABEL, "Alloc buffer for reading cmdline failed.");
77 break;
78 }
79 (void) memset_s(buf, CMDLINE_MAX_BUF_LEN, 0, CMDLINE_MAX_BUF_LEN);
80 ssize_t bufLen = read(fd, buf, CMDLINE_MAX_BUF_LEN - 1);
81 if (bufLen < 0) {
82 LOG_ERROR(LABEL, "Read %{public}s failed, %{public}s.",
83 PROC_CMDLINE_FILE_PATH.c_str(), strerror(errno));
84 break;
85 }
86 if (CheckDeviceMode(buf, bufLen) || CheckEfuseStatus(buf, bufLen)) {
87 status = DEVICE_MODE_RD;
88 }
89 } while (0);
90 g_isRdDevice = status;
91 (void) close(fd);
92 free(buf);
93 }
94
IsRdDevice()95 bool IsRdDevice()
96 {
97 if (g_isRdDevice == NOT_INITIALIZE) {
98 ParseCMDLine();
99 }
100 return g_isRdDevice == DEVICE_MODE_RD;
101 }