• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }