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 "dev_slinfo_adpt.h"
17 #include <dlfcn.h>
18 #include "securec.h"
19 #include "dev_slinfo_list.h"
20 #include "dev_slinfo_log.h"
21 #include "dev_slinfo_mgr.h"
22
23 #define MAX_LIST_LENGTH 128
24
25 void *g_deviceSecLevelHandle = NULL;
26 DeviceSecEnv g_deviceSecEnv;
27 static struct DATASLListParams *g_callbackList = NULL;
28
DestroyDeviceSecEnv(void)29 static void DestroyDeviceSecEnv(void)
30 {
31 if (g_deviceSecLevelHandle != NULL) {
32 (void)memset_s(&g_deviceSecEnv, sizeof(g_deviceSecEnv), 0, sizeof(g_deviceSecEnv));
33 dlclose(g_deviceSecLevelHandle);
34 g_deviceSecLevelHandle = NULL;
35 }
36 if (g_callbackList != NULL) {
37 ClearList(g_callbackList);
38 g_callbackList = NULL;
39 }
40 return;
41 }
42
DlopenSDK(void)43 static int32_t DlopenSDK(void)
44 {
45 g_deviceSecLevelHandle = dlopen("libdslm_sdk.z.so", RTLD_LAZY | RTLD_NODELETE);
46 if (g_deviceSecLevelHandle == NULL) {
47 DATA_SEC_LOG_ERROR("failed to load libdevicesecmgrsdktmp: %s", dlerror());
48 return DEVSL_ERROR;
49 }
50
51 return DEVSL_SUCCESS;
52 }
53
InitDeviceSecEnv(void)54 static int32_t InitDeviceSecEnv(void)
55 {
56 if (g_deviceSecLevelHandle != NULL) {
57 DATA_SEC_LOG_WARN("libdevicesecmgrsdk already loaded");
58 return DEVSL_SUCCESS;
59 }
60 int32_t ret = DlopenSDK();
61 if (ret != DEVSL_SUCCESS) {
62 return ret;
63 }
64 RequestDeviceSecurityInfoFunction requestDeviceSecurityInfo = (RequestDeviceSecurityInfoFunction)dlsym(
65 g_deviceSecLevelHandle, "RequestDeviceSecurityInfo");
66 if (requestDeviceSecurityInfo == NULL) {
67 dlclose(g_deviceSecLevelHandle);
68 g_deviceSecLevelHandle = NULL;
69 DATA_SEC_LOG_ERROR("failed to find symbol: %s", dlerror());
70 return DEVSL_ERROR;
71 }
72 FreeDeviceSecurityInfoFunction freeDeviceSecurityInfo = (FreeDeviceSecurityInfoFunction)dlsym(
73 g_deviceSecLevelHandle, "FreeDeviceSecurityInfo");
74 if (freeDeviceSecurityInfo == NULL) {
75 dlclose(g_deviceSecLevelHandle);
76 g_deviceSecLevelHandle = NULL;
77 DATA_SEC_LOG_ERROR("failed to find symbol: %s", dlerror());
78 return DEVSL_ERROR;
79 }
80 GetDeviceSecurityLevelValueFunction getDeviceSecurityLevelValue = (GetDeviceSecurityLevelValueFunction)dlsym(
81 g_deviceSecLevelHandle, "GetDeviceSecurityLevelValue");
82 if (getDeviceSecurityLevelValue == NULL) {
83 dlclose(g_deviceSecLevelHandle);
84 g_deviceSecLevelHandle = NULL;
85 DATA_SEC_LOG_ERROR("failed to find symbol: %s", dlerror());
86 return DEVSL_ERROR;
87 }
88 RequestDeviceSecurityInfoAsyncFunction requestDeviceSecurityInfoAsync =
89 (RequestDeviceSecurityInfoAsyncFunction)dlsym(g_deviceSecLevelHandle, "RequestDeviceSecurityInfoAsync");
90 if (requestDeviceSecurityInfoAsync == NULL) {
91 dlclose(g_deviceSecLevelHandle);
92 g_deviceSecLevelHandle = NULL;
93 DATA_SEC_LOG_ERROR("failed to find symbol: %s", dlerror());
94 return DEVSL_ERROR;
95 }
96 (void)memset_s(&g_deviceSecEnv, sizeof(g_deviceSecEnv), 0, sizeof(g_deviceSecEnv));
97 g_deviceSecEnv.requestDeviceSecurityInfo = requestDeviceSecurityInfo;
98 g_deviceSecEnv.freeDeviceSecurityInfo = freeDeviceSecurityInfo;
99 g_deviceSecEnv.getDeviceSecurityLevelValue = getDeviceSecurityLevelValue;
100 g_deviceSecEnv.requestDeviceSecurityInfoAsync = requestDeviceSecurityInfoAsync;
101 return DEVSL_SUCCESS;
102 }
103
StartDevslEnv(void)104 int32_t StartDevslEnv(void)
105 {
106 DATA_SEC_LOG_INFO("Enter InitDeviceSecEnv...");
107 int32_t ret = InitDeviceSecEnv();
108 DATA_SEC_LOG_INFO("InitDeviceSecEnv done!");
109 if (ret != DEVSL_SUCCESS) {
110 return DEVSL_ERR_DEVICE_SEC_SDK_INIT;
111 }
112
113 if (g_callbackList == NULL) {
114 ret = InitPthreadMutex();
115 if (ret != DEVSL_SUCCESS) {
116 return DEVSL_ERR_MUTEX_LOCK_INIT;
117 }
118 g_callbackList = InitList();
119 }
120
121 if (g_callbackList == NULL) {
122 return DEVSL_ERR_OUT_OF_MEMORY;
123 }
124 return DEVSL_SUCCESS;
125 }
126
FinishDevslEnv(void)127 void FinishDevslEnv(void)
128 {
129 DestroyDeviceSecEnv();
130 DestroyPthreadMutex();
131 return;
132 }
133
GetDeviceSecLevelByUdid(const uint8_t * udid,uint32_t udidLen,int32_t * devLevel)134 int32_t GetDeviceSecLevelByUdid(const uint8_t *udid, uint32_t udidLen, int32_t *devLevel)
135 {
136 DATA_SEC_LOG_INFO("Enter GetDeviceSecLevelByUdid...");
137 if (g_deviceSecEnv.requestDeviceSecurityInfo == NULL) {
138 DATA_SEC_LOG_ERROR("GetDeviceSecLevelByUdid: requestDeviceSecurityInfo is invalid");
139 return DEVSL_ERROR;
140 }
141
142 if (g_deviceSecEnv.freeDeviceSecurityInfo == NULL) {
143 DATA_SEC_LOG_ERROR("GetDeviceSecLevelByUdid: freeDeviceSecurityInfo is invalid");
144 return DEVSL_ERROR;
145 }
146
147 if (g_deviceSecEnv.getDeviceSecurityLevelValue == NULL) {
148 DATA_SEC_LOG_ERROR("GetDeviceSecByUdid: getDeviceSecurityLevelValue is invalid");
149 return DEVSL_ERROR;
150 }
151
152 int32_t ret;
153 struct DeviceSecurityInfo *info = NULL;
154
155 struct DeviceIdentify devId;
156 (void)memset_s(&devId, sizeof(devId), 0, sizeof(devId));
157
158 ret = memcpy_s(devId.identity, MAX_UDID_LENGTH, udid, udidLen);
159 if (ret != EOK) {
160 DATA_SEC_LOG_ERROR("GetDeviceSecLevelByUdid: udid memcpy failed, ret is %d", ret);
161 return DEVSL_ERR_OUT_OF_MEMORY;
162 }
163 devId.length = udidLen;
164
165 ret = g_deviceSecEnv.requestDeviceSecurityInfo(&devId, NULL, &info);
166 if (ret != SUCCESS) {
167 DATA_SEC_LOG_ERROR("GetDeviceSecLevelByUdid: request device Security info failed, %d", ret);
168 g_deviceSecEnv.freeDeviceSecurityInfo(info);
169 return ret;
170 }
171
172 ret = g_deviceSecEnv.getDeviceSecurityLevelValue(info, devLevel);
173 if (ret != SUCCESS) {
174 DATA_SEC_LOG_ERROR("GetDeviceSecLevelByUdid: get device Security value failed, %d", ret);
175 g_deviceSecEnv.freeDeviceSecurityInfo(info);
176 return ret;
177 }
178
179 g_deviceSecEnv.freeDeviceSecurityInfo(info);
180 DATA_SEC_LOG_INFO("GetDeviceSecLevelByUdid done!");
181 return DEVSL_SUCCESS;
182 }
183
OnApiDeviceSecInfoCallback(const DeviceIdentify * identify,struct DeviceSecurityInfo * info)184 void OnApiDeviceSecInfoCallback(const DeviceIdentify *identify, struct DeviceSecurityInfo *info)
185 {
186 DATA_SEC_LOG_INFO("Enter OnApiDeviceSecInfoCallback...");
187 if (identify == NULL) {
188 DATA_SEC_LOG_INFO("OnApiDeviceSecInfoCallback: DeviceIdentify is null");
189 return;
190 }
191 int32_t ret = DEVSL_SUCCESS;
192
193 if (info == NULL) {
194 DATA_SEC_LOG_INFO("OnApiDeviceSecInfoCallback: DeviceSecurityInfo is null");
195 ret = DEVSL_ERROR;
196 }
197 if (g_deviceSecEnv.getDeviceSecurityLevelValue == NULL) {
198 DATA_SEC_LOG_ERROR("OnApiDeviceSecInfoCallback: getDeviceSecurityLevelValue is invalid");
199 ret = DEVSL_ERROR;
200 }
201
202 if (g_deviceSecEnv.freeDeviceSecurityInfo == NULL) {
203 DATA_SEC_LOG_ERROR("OnApiDeviceSecInfoCallback: freeDeviceSecurityInfo is invalid");
204 ret = DEVSL_ERROR;
205 }
206
207 int32_t devLevel = DEFAULT_DEV_SEC_LEVEL;
208 uint32_t levelInfo = DATA_SEC_LEVEL0;
209
210 if (ret == DEVSL_SUCCESS) {
211 ret = g_deviceSecEnv.getDeviceSecurityLevelValue(info, &devLevel);
212 if (ret != SUCCESS) {
213 DATA_SEC_LOG_ERROR("OnApiDeviceSecInfoCallback: get device security level value, %d", ret);
214 } else {
215 levelInfo = GetDataSecLevelByDevSecLevel(devLevel);
216 }
217 g_deviceSecEnv.freeDeviceSecurityInfo(info);
218 }
219
220 DEVSLQueryParams queryParams;
221 (void)memset_s(&queryParams, sizeof(queryParams), 0, sizeof(queryParams));
222
223 if (memcpy_s(queryParams.udid, MAX_UDID_LENGTH, identify->identity, identify->length) != EOK) {
224 DATA_SEC_LOG_ERROR("OnApiDeviceSecInfoCallback: udid memcpy failed");
225 return;
226 }
227 queryParams.udidLen = identify->length;
228
229 if (g_callbackList != NULL) {
230 LookupCallback(g_callbackList, &queryParams, ret, levelInfo);
231 }
232 DATA_SEC_LOG_INFO("OnApiDeviceSecInfoCallback done!");
233 }
234
GetDeviceSecLevelByUdidAsync(const uint8_t * udid,uint32_t udidLen)235 int32_t GetDeviceSecLevelByUdidAsync(const uint8_t *udid, uint32_t udidLen)
236 {
237 DATA_SEC_LOG_INFO("Enter GetDeviceSecLevelByUdidAsync...");
238 if (g_deviceSecEnv.requestDeviceSecurityInfoAsync == NULL) {
239 DATA_SEC_LOG_ERROR("GetDeviceSecLevelByUdidAsync: requestDeviceSecurityInfoAsync is invalid");
240 return DEVSL_ERROR;
241 }
242
243 int32_t ret;
244 DeviceIdentify devId;
245 (void)memset_s(&devId, sizeof(devId), 0, sizeof(devId));
246
247 ret = memcpy_s(devId.identity, MAX_UDID_LENGTH, udid, udidLen);
248 if (ret != EOK) {
249 DATA_SEC_LOG_ERROR("GetDeviceSecLevelByUdidAsync: memcpy udid failed, ret is %d", ret);
250 return DEVSL_ERR_OUT_OF_MEMORY;
251 }
252 devId.length = udidLen;
253 ret = g_deviceSecEnv.requestDeviceSecurityInfoAsync(&devId, NULL, OnApiDeviceSecInfoCallback);
254 if (ret != SUCCESS) {
255 DATA_SEC_LOG_ERROR("GetDeviceSecLevelByUdidAsync: request device security Info for Async failed, %d", ret);
256 return ret;
257 }
258
259 DATA_SEC_LOG_INFO("GetDeviceSecLevelByUdidAsync done!");
260 return ret;
261 }
262
CompareUdid(DEVSLQueryParams * queryParamsL,DEVSLQueryParams * queryParamsR)263 int32_t CompareUdid(DEVSLQueryParams *queryParamsL, DEVSLQueryParams *queryParamsR)
264 {
265 DATA_SEC_LOG_INFO("Enter CompareUdid...");
266 uint32_t i;
267
268 if (queryParamsL->udidLen != queryParamsR->udidLen) {
269 return DEVSL_ERROR;
270 }
271 for (i = 0; i < queryParamsL->udidLen; i++) {
272 if (queryParamsL->udid[i] != queryParamsR->udid[i]) {
273 return DEVSL_ERROR;
274 }
275 }
276 DATA_SEC_LOG_INFO("CompareUdid done!");
277 return DEVSL_SUCCESS;
278 }
279
GetDataSecLevelByDevSecLevel(int32_t devLevel)280 uint32_t GetDataSecLevelByDevSecLevel(int32_t devLevel)
281 {
282 int32_t i;
283 int32_t n;
284 struct {
285 int32_t devSecLevel;
286 uint32_t dataSecLevel;
287 } devTypeMap[] = {
288 { DEV_SEC_LEVEL1, DATA_SEC_LEVEL1 },
289 { DEV_SEC_LEVEL2, DATA_SEC_LEVEL2 },
290 { DEV_SEC_LEVEL3, DATA_SEC_LEVEL3 },
291 { DEV_SEC_LEVEL4, DATA_SEC_LEVEL4 },
292 { DEV_SEC_LEVEL5, DATA_SEC_LEVEL4 },
293 };
294
295 n = (int32_t)(sizeof(devTypeMap) / sizeof(devTypeMap[0]));
296 for (i = 0; i < n; i++) {
297 if (devTypeMap[i].devSecLevel == devLevel) {
298 return devTypeMap[i].dataSecLevel;
299 }
300 }
301 if (i >= n) {
302 DATA_SEC_LOG_WARN("GetDataSecLevelBySecLevel, unknown device level tag: %d", devLevel);
303 }
304 return DATA_SEC_LEVEL0;
305 }
306
UpdateCallbackListParams(DEVSLQueryParams * queryParams,HigestSecInfoCallback * callback)307 int32_t UpdateCallbackListParams(DEVSLQueryParams *queryParams, HigestSecInfoCallback *callback)
308 {
309 DATA_SEC_LOG_INFO("Enter UpdateCallbackListParams...");
310 int32_t ret;
311 int32_t result = DEVSL_ERR_REQUEST_DEVICE_EXCEED_LIMIT;
312 uint32_t levelInfo = DEFAULT_DEV_SEC_LEVEL;
313
314 struct DATASLCallbackParams *newListNode =
315 (struct DATASLCallbackParams*)malloc(sizeof(struct DATASLCallbackParams));
316 if (newListNode == NULL) {
317 return DEVSL_ERR_OUT_OF_MEMORY;
318 }
319
320 ret = memcpy_s(newListNode->queryParams.udid, MAX_UDID_LENGTH, queryParams->udid, queryParams->udidLen);
321 if (ret != EOK) {
322 DATA_SEC_LOG_ERROR("UpdateCallbackListParams: memcpy udid failed, ret is %d", ret);
323 free(newListNode);
324 return DEVSL_ERR_OUT_OF_MEMORY;
325 }
326 newListNode->queryParams.udidLen = queryParams->udidLen;
327 newListNode->callback = callback;
328
329 ret = GetListLength(g_callbackList);
330 if (ret == MAX_LIST_LENGTH) {
331 g_callbackList->next->callbackParams->callback(queryParams, result, levelInfo);
332 RemoveListNode(g_callbackList, g_callbackList->next->callbackParams);
333 }
334
335 ret = PushListNode(g_callbackList, newListNode);
336 DATA_SEC_LOG_INFO("UpdateCallbackListParams done!");
337 return ret;
338 }