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 <pthread.h>
17 #include <securec.h>
18
19 #include "device_security_level_defines.h"
20 #include "device_security_level_proxy.h"
21
22 #include "ohos_types.h"
23 #include "utils_log.h"
24 #include "utils_mem.h"
25 #include "utils_mutex.h"
26
27 #define MAX_IPC_DATA_LEN 0x100
28
GetMutex(void)29 static inline Mutex *GetMutex(void)
30 {
31 static Mutex mutex = INITED_MUTEX;
32 return &mutex;
33 }
34
DslmIpcCallback(IOwner owner,int code,IpcIo * reply)35 static int DslmIpcCallback(IOwner owner, int code, IpcIo *reply)
36 {
37 uint32_t result = ERR_DEFAULT;
38 uint32_t level = 0;
39
40 if (owner == NULL) {
41 return ERR_INVALID_PARA;
42 }
43
44 struct DslmCallbackHolder *holder = (struct DslmCallbackHolder *)owner;
45
46 ReadUint32(reply, &result);
47 if (result == SUCCESS) {
48 ReadUint32(reply, &level);
49 SECURITY_LOG_INFO("[TID:0x%lx] Notify Remote result: %u, level: %u", pthread_self(), result, level);
50 } else {
51 level = 0;
52 SECURITY_LOG_ERROR("RequestDeviceSecurityLevelSendRequest result value error, ret is %d", result);
53 }
54
55 if (holder->callback != NULL) {
56 DeviceSecurityInfo *info = (DeviceSecurityInfo *)MALLOC(sizeof(DeviceSecurityInfo));
57 if (info == NULL) {
58 return ERR_NO_MEMORY;
59 }
60 info->magicNum = SECURITY_MAGIC;
61 info->result = result;
62 info->level = level;
63 SECURITY_LOG_INFO("calling user callback");
64 holder->callback(&holder->identity, info);
65 }
66
67 return SUCCESS;
68 }
69
DslmIpcAsyncCallImpl(IUnknown * iUnknown,const DeviceIdentify identify,const RequestOption option,uint32_t cookie,const DeviceSecurityInfoCallback callback)70 static BOOL DslmIpcAsyncCallImpl(IUnknown *iUnknown, const DeviceIdentify identify, const RequestOption option,
71 uint32_t cookie, const DeviceSecurityInfoCallback callback)
72 {
73 if (identify.length == 0 || identify.length > DEVICE_ID_MAX_LEN) {
74 SECURITY_LOG_ERROR("RequestDeviceSecurityLevel invalid para len.");
75 return ERR_INVALID_PARA;
76 }
77 struct DslmCallbackHolder owner = {identify, callback};
78 DslmClientProxy *proxy = (DslmClientProxy *)iUnknown;
79 IpcIo request;
80 char data[MAX_IPC_DATA_LEN];
81 IpcIoInit(&request, data, MAX_IPC_DATA_LEN, 0);
82 /* DeviceIdentify */
83 WriteUint32(&request, identify.length);
84 WriteBuffer(&request, identify.identity, DEVICE_ID_MAX_LEN);
85 /* option */
86 WriteUint64(&request, option.challenge);
87 WriteUint32(&request, option.timeout);
88 WriteUint32(&request, option.extra);
89 /* cookie */
90 WriteUint32(&request, cookie);
91
92 int ret = proxy->Invoke((IClientProxy *)proxy, CMD_SET_DEVICE_SECURITY_LEVEL, &request, &owner, DslmIpcCallback);
93 if (ret != EC_SUCCESS) {
94 SECURITY_LOG_ERROR("RequestDeviceSecurityLevelSendRequest send failed, ret is %d", ret);
95 return ret;
96 }
97
98 return SUCCESS;
99 }
100
DslmCreatClient(const char * service,const char * feature,uint32 size)101 void *DslmCreatClient(const char *service, const char *feature, uint32 size)
102 {
103 (void)service;
104 (void)feature;
105 uint32_t len = size + sizeof(DslmClientEntry);
106 uint8_t *client = (uint8_t *)MALLOC(len);
107 if (client == NULL) {
108 SECURITY_LOG_ERROR("malloc error");
109 return NULL;
110 }
111 (void)memset_s(client, len, 0, len);
112 DslmClientEntry *entry = (DslmClientEntry *)&client[size];
113 entry->ver = ((uint16_t)CLIENT_PROXY_VER | (uint16_t)DEFAULT_VERSION);
114 entry->ref = 1;
115 entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
116 entry->iUnknown.AddRef = IUNKNOWN_AddRef;
117 entry->iUnknown.Release = IUNKNOWN_Release;
118 entry->iUnknown.Invoke = NULL;
119 entry->iUnknown.DslmIpcAsyncCall = DslmIpcAsyncCallImpl;
120 return client;
121 }
122
DslmDestroyClient(const char * service,const char * feature,void * proxy)123 void DslmDestroyClient(const char *service, const char *feature, void *proxy)
124 {
125 (void)service;
126 (void)feature;
127 FREE(proxy);
128 }
129
GetClientProxy(void)130 static DslmClientProxy *GetClientProxy(void)
131 {
132 SAMGR_RegisterFactory(DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE, DslmCreatClient, DslmDestroyClient);
133 DslmClientProxy *proxy = NULL;
134 SECURITY_LOG_INFO("[GetFeatureApi S:%s F:%s] begin", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
135 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
136 if (iUnknown == NULL) {
137 SECURITY_LOG_ERROR("[GetFeatureApi S:%s F:%s]: failed", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
138 return NULL;
139 }
140
141 int32_t ret = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&proxy);
142 if (ret != SUCCESS || proxy == NULL) {
143 SECURITY_LOG_ERROR("[QueryInterface CLIENT_PROXY_VER S:%s, F:%s] failed", DSLM_SAMGR_SERVICE,
144 DSLM_SAMGR_FEATURE);
145 return NULL;
146 }
147 SECURITY_LOG_INFO("[QueryInterface CLIENT_PROXY_VER S:%s, F:%s] success", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
148 return proxy;
149 }
150
ReleaseClientProxy(DslmClientProxy * clientProxy)151 static void ReleaseClientProxy(DslmClientProxy *clientProxy)
152 {
153 if (clientProxy == NULL) {
154 return;
155 }
156
157 int32 ret = clientProxy->Release((IUnknown *)clientProxy);
158 SECURITY_LOG_INFO("[Release api S:%s, F:%s]: ret:%d", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE, ret);
159 }
160
RequestDeviceSecurityInfoAsyncImpl(const DeviceIdentify * identify,const RequestOption * option,DeviceSecurityInfoCallback callback)161 int32_t RequestDeviceSecurityInfoAsyncImpl(const DeviceIdentify *identify, const RequestOption *option,
162 DeviceSecurityInfoCallback callback)
163 {
164 static uint32_t generated = 0;
165 if (identify == NULL || callback == NULL) {
166 SECURITY_LOG_ERROR("GetDeviceSecurityInfo input error");
167 return ERR_INVALID_PARA;
168 }
169
170 static RequestOption defaultOption = {0, DEFAULT_KEEP_LEN, 0};
171 if (option == NULL) {
172 option = &defaultOption;
173 }
174 if (option->timeout > MAX_KEEP_LEN) {
175 SECURITY_LOG_ERROR("GetDeviceSecurityInfo input error, timeout too long");
176 return ERR_INVALID_PARA;
177 }
178
179 LockMutex(GetMutex());
180 uint32_t cookie = ++generated;
181 UnlockMutex(GetMutex());
182 DslmClientProxy *proxy = GetClientProxy();
183 if (proxy == NULL) {
184 SECURITY_LOG_ERROR("[GetFeatureApi S:%s F:%s]: failed", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
185 return ERR_IPC_PROXY_ERR;
186 }
187
188 if (proxy->DslmIpcAsyncCall == NULL) {
189 SECURITY_LOG_ERROR("proxy has NULL api");
190 return ERR_IPC_PROXY_ERR;
191 }
192 BOOL result = proxy->DslmIpcAsyncCall((IUnknown *)proxy, *identify, *option, cookie, callback);
193 if (result != SUCCESS) {
194 SECURITY_LOG_ERROR("GetDeviceSecurityInfo RequestDeviceSecurityLevel error");
195 return result;
196 }
197 SECURITY_LOG_INFO("GetDeviceSecurityInfo RequestDeviceSecurityLevel success");
198 ReleaseClientProxy(proxy);
199 return SUCCESS;
200 }