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_core_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 FILE *fp = fopen(path, "w");
160 if (fp == NULL) {
161 HDF_LOGE("open %{public}s failed, errno is %{public}d", HDF_SECURE_PATH, errno);
162 return HDF_FAILURE;
163 }
164 int32_t fd = fileno(fp);
165 if (fd < 0) {
166 HDF_LOGE("fileno %{public}s failed, errno is %{public}d", HDF_SECURE_PATH, errno);
167 (void)fclose(fp);
168 return HDF_FAILURE;
169 }
170
171 if (isSetCurrentSecId == 0) {
172 ret = ioctl(fd, HDF_SECURE_SET_INFO, &secInfo);
173 } else if (isSetCurrentSecId == 1) {
174 ret = ioctl(fd, HDF_SECURE_SET_CURRENT_ID, &secInfo);
175 } else {
176 ret = ioctl(fd, HDF_SECURE_DELETE_INFO, &secInfo);
177 }
178
179 (void)fclose(fp);
180 fd = -1;
181 if (ret != 0) {
182 HDF_LOGE("%{public}s ioctl error, ret is %{public}d", __FUNCTION__, ret);
183 return HDF_FAILURE;
184 }
185 return HDF_SUCCESS;
186 }
187
HdfRegisterSecurityId(const char * id,const uint64_t perm)188 static int32_t HdfRegisterSecurityId(const char *id, const uint64_t perm)
189 {
190 return HdfUpdateSecurityId(id, perm, HDF_SECURE_SET_ALL_ID);
191 }
192
HdfRegisterAllDevSecId(const struct DeviceResourceNode * hostRoot)193 int32_t HdfRegisterAllDevSecId(const struct DeviceResourceNode *hostRoot)
194 {
195 if (hostRoot == NULL) {
196 HDF_LOGE("device_node linked list completed");
197 return HDF_FAILURE;
198 }
199
200 uint64_t random = 0;
201 int32_t ret = HdfGetRandom(MAX_RANDOM_BYTE_LEN, (uint8_t *)&random);
202 if (ret != HDF_SUCCESS) {
203 HDF_LOGE("%{public}s HdfGetRandom failed", __FUNCTION__);
204 return HDF_FAILURE;
205 }
206
207 InitStrToIndexMap();
208
209 struct DeviceResourceNode *driverRoot = hostRoot->child;
210 const char *permStr = NULL;
211 volatile uint64_t perms = HDF_SECURE_INVALID_PERM;
212 while (driverRoot != NULL) {
213 const struct DeviceResourceNode *deviceRoot = driverRoot->child;
214 while (deviceRoot != NULL) {
215 int32_t permNums = HcsGetElemNum(deviceRoot, HDF_SEC_PERM_ELEM_NAME);
216 HDF_LOGD("name is %{public}s, permNums is %{public}d", deviceRoot->name, permNums);
217 for (int i = 0; i < permNums; ++i) {
218 HcsGetStringArrayElem(deviceRoot, HDF_SEC_PERM_ELEM_NAME, i, &permStr, NULL);
219 HdfCalculatePerms(permStr, &perms);
220 }
221 deviceRoot = deviceRoot->sibling;
222 }
223 driverRoot = driverRoot->sibling;
224 }
225 if (perms != HDF_SECURE_INVALID_PERM) {
226 const char *hostName = NULL;
227 HcsGetString(hostRoot, HDF_SEC_HOST_NAME, &hostName, NULL);
228 ret = HdfRegisterSecurityId(hostName, perms);
229 if (ret != HDF_SUCCESS) {
230 HDF_LOGE("HdfCreateSecurityId failed for %{public}s", hostRoot->name);
231 }
232 perms = HDF_SECURE_INVALID_PERM;
233 }
234 return HDF_SUCCESS;
235 }
236
HdfSetCurrentHostSecurity(const char * hostName,int32_t procId)237 int32_t HdfSetCurrentHostSecurity(const char *hostName, int32_t procId)
238 {
239 return HdfUpdateSecurityId(hostName, (uint64_t)procId, HDF_SECURE_SET_CUR_ID);
240 }
241
HdfDelSecurity(const char * hostName)242 void HdfDelSecurity(const char *hostName)
243 {
244 if (hostName == NULL) {
245 return;
246 }
247 int32_t ret = HdfUpdateSecurityId(hostName, 0, HDF_SECURE_DEL_CUR_ID);
248 if (ret != HDF_SUCCESS) {
249 HDF_LOGE("%{public}s delete %{public}s security failed", __func__, hostName);
250 }
251 }
252