1 /*
2 * Copyright (c) 2021 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 "hdf_security.h"
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <inttypes.h>
20 #include <openssl/rand.h>
21 #include <openssl/sha.h>
22 #include <string.h>
23 #include <sys/ioctl.h>
24 #include <sys/time.h>
25 #include <unistd.h>
26 #include "hcs_tree_if.h"
27 #include "hdf_base.h"
28 #include "hdf_log.h"
29 #include "hdf_sec.h"
30 #include "pal_if.h"
31 #include "securec.h"
32
33 #define HDF_LOG_TAG hdf_security
34 #define HDF_SECURE_PATH "/dev/hdf_secure"
35 #define HDF_SEC_PERM_ELEM_NAME "permission"
36 #define HDF_SEC_HOST_NAME "hostName"
37 #define MAX_RANDOM_BYTE_LEN 8
38 #define RAND_OPS_SUCCESS 1
39 #define MAX_SEED_LEN 64
40 #define HDF_TRANSFORM_STEP 2
41 #define HDF_SECURE_INVALID_PERM 0
42 #define HDF_SECURE_SET_ALL_ID 0
43 #define HDF_SECURE_SET_CUR_ID 1
44 #define HDF_SECURE_DEL_CUR_ID 2
45
46 #define BITS_PER_LONG 64
47 #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
48 #define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
49
50 const static char *g_hdfSecStrArray[PAL_MAX_TYPE] = {
51 [PAL_I2C_TYPE] = "i2c",
52 [PAL_SPI_TYPE] = "spi",
53 [PAL_GPIO_TYPE] = "gpio",
54 [PAL_PINCTRL_TYPE] = "pinctl",
55 [PAL_CLOCK_TYPE] = "clock",
56 [PAL_REGULATOR_TYPE] = "regulator",
57 [PAL_MIPI_TYPE] = "mipi",
58 [PAL_UART_TYPE] = "uart",
59 [PAL_SDIO_TYPE] = "sdio",
60 [PAL_MDIO_TYPE] = "mdio",
61 [PAL_APB_TYPE] = "apb",
62 [PAL_PCIE_TYPE] = "pcie",
63 [PAL_PCM_TYPE] = "pcm",
64 [PAL_I2S_TYPE] = "i2s",
65 [PAL_PWM_TYPE] = "pwm",
66 [PAL_DMA_TYPE] = "dma",
67 [PAL_EFUSE_TYPE] = "efuse",
68 [PAL_FLASH_TYPE] = "flash",
69 [PAL_EMMC_TYPE] = "emmc",
70 [PAL_RTC_TYPE] = "rtc",
71 [PAL_ADC_TYPE] = "adc",
72 [PAL_WDT_TYPE] = "wdt",
73 [PAL_I3C_TYPE] = "i3c",
74 };
75
76 static Map g_indexMap;
77
HdfSecGetHashMap()78 Map *HdfSecGetHashMap()
79 {
80 static Map hdfHashMap = { 0 };
81 if (hdfHashMap.nodeSize == 0) {
82 HDF_LOGI("Init hdfHashMap");
83 MapInit(&hdfHashMap);
84 }
85 return &hdfHashMap;
86 }
87
InitStrToIndexMap(void)88 static void InitStrToIndexMap(void)
89 {
90 MapInit(&g_indexMap);
91 for (int i = 0; i < PAL_MAX_TYPE; ++i) {
92 MapSet(&g_indexMap, g_hdfSecStrArray[i], &i, sizeof(int *));
93 }
94 }
95
HdfSetBit(uint32_t nr,volatile uint64_t * addr)96 static void HdfSetBit(uint32_t nr, volatile uint64_t *addr)
97 {
98 unsigned long mask = BIT_MASK(nr);
99 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
100 *p |= mask;
101 }
102
HdfGetRandom(int numBytes,uint8_t * random)103 static int32_t HdfGetRandom(int numBytes, uint8_t *random)
104 {
105 if (RAND_bytes(random, numBytes) != RAND_OPS_SUCCESS) {
106 HDF_LOGE("%{public}s: RAND_bytes failed", __FUNCTION__);
107 return HDF_FAILURE;
108 }
109 return HDF_SUCCESS;
110 }
111
HdfCalculatePerms(const char * permStr,volatile uint64_t * perms)112 static void HdfCalculatePerms(const char *permStr, volatile uint64_t *perms)
113 {
114 uint32_t *result = NULL;
115 result = (uint32_t *)MapGet(&g_indexMap, permStr);
116 if (result == NULL) {
117 HDF_LOGE("%{public}s: %{public}s is not exist in map", __FUNCTION__, permStr);
118 return;
119 }
120 HdfSetBit(*result, perms);
121 }
122
HdfSecCheckParameters(const char * id)123 static int32_t HdfSecCheckParameters(const char *id)
124 {
125 if (id == NULL) {
126 HDF_LOGE("HdfSecCheckParameters failed, id is null");
127 return HDF_FAILURE;
128 }
129 uint32_t len = (uint32_t)strlen(id);
130 if (len >= (ID_MAX_SIZE - 1)) {
131 HDF_LOGE("HdfSecCheckParameters failed, id length is %{public}u", len);
132 return HDF_FAILURE;
133 }
134 return HDF_SUCCESS;
135 }
136
HdfUpdateSecurityId(const char * id,uint64_t perms,int32_t isSetCurrentSecId)137 static int32_t HdfUpdateSecurityId(const char *id, uint64_t perms, int32_t isSetCurrentSecId)
138 {
139 if (HdfSecCheckParameters(id) != HDF_SUCCESS) {
140 HDF_LOGE("%{public}s check id failed", __FUNCTION__);
141 return HDF_FAILURE;
142 }
143 struct SecInfo secInfo = {
144 .secId = { 0 },
145 .secMap = { 0 }
146 };
147 int32_t ret = strncpy_s(secInfo.secId, ID_MAX_SIZE, id, ID_MAX_SIZE - 1);
148 if (ret != EOK) {
149 HDF_LOGE("%{public}s strncpy_s id failed", __FUNCTION__);
150 return HDF_FAILURE;
151 }
152 secInfo.secMap[0] = perms;
153
154 char path[PATH_MAX + 1] = { 0 };
155 if (realpath(HDF_SECURE_PATH, path) == NULL) {
156 HDF_LOGE("file %{public}s is invalid", HDF_SECURE_PATH);
157 return HDF_FAILURE;
158 }
159 int32_t fd = open(path, O_WRONLY);
160 if (fd < 0) {
161 HDF_LOGE("open %{public}s failed, errno is %{public}d", HDF_SECURE_PATH, errno);
162 return HDF_FAILURE;
163 }
164
165 if (isSetCurrentSecId == 0) {
166 ret = ioctl(fd, HDF_SECURE_SET_INFO, &secInfo);
167 } else if (isSetCurrentSecId == 1) {
168 ret = ioctl(fd, HDF_SECURE_SET_CURRENT_ID, &secInfo);
169 } else {
170 ret = ioctl(fd, HDF_SECURE_DELETE_INFO, &secInfo);
171 }
172
173 close(fd);
174 fd = -1;
175 if (ret != 0) {
176 HDF_LOGE("%{public}s ioctl error, ret is %{public}d", __FUNCTION__, ret);
177 return HDF_FAILURE;
178 }
179 return HDF_SUCCESS;
180 }
181
HdfRegisterSecurityId(const char * id,const uint64_t perm)182 static int32_t HdfRegisterSecurityId(const char *id, const uint64_t perm)
183 {
184 return HdfUpdateSecurityId(id, perm, HDF_SECURE_SET_ALL_ID);
185 }
186
HdfRegisterAllDevSecId(const struct DeviceResourceNode * hostRoot)187 int32_t HdfRegisterAllDevSecId(const struct DeviceResourceNode *hostRoot)
188 {
189 if (hostRoot == NULL) {
190 HDF_LOGE("device_node linked list completed");
191 return HDF_FAILURE;
192 }
193
194 uint64_t random = 0;
195 int32_t ret = HdfGetRandom(MAX_RANDOM_BYTE_LEN, (uint8_t *)&random);
196 if (ret != HDF_SUCCESS) {
197 HDF_LOGE("%{public}s HdfGetRandom failed", __FUNCTION__);
198 return HDF_FAILURE;
199 }
200
201 InitStrToIndexMap();
202
203 struct DeviceResourceNode *driverRoot = hostRoot->child;
204 const char *permStr = NULL;
205 volatile uint64_t perms = HDF_SECURE_INVALID_PERM;
206 while (driverRoot != NULL) {
207 const struct DeviceResourceNode *deviceRoot = driverRoot->child;
208 while (deviceRoot != NULL) {
209 int32_t permNums = HcsGetElemNum(deviceRoot, HDF_SEC_PERM_ELEM_NAME);
210 HDF_LOGD("name is %{public}s, permNums is %{public}d", deviceRoot->name, permNums);
211 for (int i = 0; i < permNums; ++i) {
212 HcsGetStringArrayElem(deviceRoot, HDF_SEC_PERM_ELEM_NAME, i, &permStr, NULL);
213 HdfCalculatePerms(permStr, &perms);
214 }
215 deviceRoot = deviceRoot->sibling;
216 }
217 driverRoot = driverRoot->sibling;
218 }
219 if (perms != HDF_SECURE_INVALID_PERM) {
220 const char *hostName = NULL;
221 HcsGetString(hostRoot, HDF_SEC_HOST_NAME, &hostName, NULL);
222 ret = HdfRegisterSecurityId(hostName, perms);
223 if (ret != HDF_SUCCESS) {
224 HDF_LOGE("HdfCreateSecurityId failed for %{public}s", hostRoot->name);
225 }
226 perms = HDF_SECURE_INVALID_PERM;
227 }
228 return HDF_SUCCESS;
229 }
230
HdfSetCurrentHostSecurity(const char * hostName,int32_t procId)231 int32_t HdfSetCurrentHostSecurity(const char *hostName, int32_t procId)
232 {
233 return HdfUpdateSecurityId(hostName, (uint64_t)procId, HDF_SECURE_SET_CUR_ID);
234 }
235
HdfDelSecurity(const char * hostName)236 void HdfDelSecurity(const char *hostName)
237 {
238 if (hostName == NULL) {
239 return;
240 }
241 int32_t ret = HdfUpdateSecurityId(hostName, 0, HDF_SECURE_DEL_CUR_ID);
242 if (ret != HDF_SUCCESS) {
243 HDF_LOGE("%{public}s delete %{public}s security failed", __func__, hostName);
244 }
245 }
246