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
26 #define MAX_IPC_DATA_LEN 0x100
27
DslmIpcCallback(IOwner owner,int code,IpcIo * reply)28 static int DslmIpcCallback(IOwner owner, int code, IpcIo *reply)
29 {
30 if (owner == NULL) {
31 return ERR_INVALID_PARA;
32 }
33
34 uint32_t result, level;
35 struct DslmCallbackHolder *holder = (struct DslmCallbackHolder *)owner;
36
37 ReadUint32(reply, &result);
38 if (result == SUCCESS) {
39 ReadUint32(reply, &level);
40 SECURITY_LOG_INFO("[TID:0x%lx] Notify Remote result: %u, level: %u", pthread_self(), result, level);
41 } else {
42 level = 0;
43 SECURITY_LOG_ERROR("RequestDeviceSecurityLevelSendRequest result value error, ret is %d", result);
44 }
45
46 if (holder->callback != NULL) {
47 DeviceSecurityInfo *info = (DeviceSecurityInfo *)MALLOC(sizeof(DeviceSecurityInfo));
48 if (info == NULL) {
49 return ERR_NO_MEMORY;
50 }
51 info->magicNum = SECURITY_MAGIC;
52 info->result = result;
53 info->level = level;
54 SECURITY_LOG_INFO("calling user callback");
55 holder->callback(&holder->identity, info);
56 }
57
58 return SUCCESS;
59 }
60
DslmIpcAsyncCallImpl(IUnknown * iUnknown,const DeviceIdentify identify,const RequestOption option,uint32_t cookie,const DeviceSecurityInfoCallback callback)61 static BOOL DslmIpcAsyncCallImpl(IUnknown *iUnknown, const DeviceIdentify identify, const RequestOption option,
62 uint32_t cookie, const DeviceSecurityInfoCallback callback)
63 {
64 if (identify.length == 0 || identify.length > DEVICE_ID_MAX_LEN) {
65 SECURITY_LOG_ERROR("RequestDeviceSecurityLevel invalid para len.");
66 return ERR_INVALID_PARA;
67 }
68 struct DslmCallbackHolder owner = {identify, callback};
69 DslmClientProxy *proxy = (DslmClientProxy *)iUnknown;
70 IpcIo request;
71 char data[MAX_IPC_DATA_LEN];
72 IpcIoInit(&request, data, MAX_IPC_DATA_LEN, 0);
73 /* DeviceIdentify */
74 WriteUint32(&request, identify.length);
75 WriteBuffer(&request, identify.identity, DEVICE_ID_MAX_LEN);
76 /* option */
77 WriteUint64(&request, option.challenge);
78 WriteUint32(&request, option.timeout);
79 WriteUint32(&request, option.extra);
80 /* cookie */
81 WriteUint32(&request, cookie);
82
83 int ret = proxy->Invoke((IClientProxy *)proxy, CMD_SET_DEVICE_SECURITY_LEVEL, &request, &owner, DslmIpcCallback);
84 if (ret != EC_SUCCESS) {
85 SECURITY_LOG_ERROR("RequestDeviceSecurityLevelSendRequest send failed, ret is %d", ret);
86 return ret;
87 }
88
89 return SUCCESS;
90 }
91
DslmCreatClient(const char * service,const char * feature,uint32 size)92 void *DslmCreatClient(const char *service, const char *feature, uint32 size)
93 {
94 (void)service;
95 (void)feature;
96 uint32_t len = size + sizeof(DslmClientEntry);
97 uint8_t *client = (uint8_t *)MALLOC(len);
98 if (client == NULL) {
99 SECURITY_LOG_ERROR("malloc error");
100 return NULL;
101 }
102 (void)memset_s(client, len, 0, len);
103 DslmClientEntry *entry = (DslmClientEntry *)&client[size];
104 entry->ver = ((uint16_t)CLIENT_PROXY_VER | (uint16_t)DEFAULT_VERSION);
105 entry->ref = 1;
106 entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
107 entry->iUnknown.AddRef = IUNKNOWN_AddRef;
108 entry->iUnknown.Release = IUNKNOWN_Release;
109 entry->iUnknown.Invoke = NULL;
110 entry->iUnknown.DslmIpcAsyncCall = DslmIpcAsyncCallImpl;
111 return client;
112 }
113
DslmDestroyClient(const char * service,const char * feature,void * proxy)114 void DslmDestroyClient(const char *service, const char *feature, void *proxy)
115 {
116 (void)service;
117 (void)feature;
118 FREE(proxy);
119 }
120
GetClientProxy(void)121 DslmClientProxy *GetClientProxy(void)
122 {
123 SAMGR_RegisterFactory(DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE, DslmCreatClient, DslmDestroyClient);
124 DslmClientProxy *proxy = NULL;
125 SECURITY_LOG_INFO("[GetFeatureApi S:%s F:%s] begin", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
126 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
127 if (iUnknown == NULL) {
128 SECURITY_LOG_ERROR("[GetFeatureApi S:%s F:%s]: failed", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
129 return NULL;
130 }
131
132 int32_t ret = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&proxy);
133 if (ret != SUCCESS || proxy == NULL) {
134 SECURITY_LOG_ERROR("[QueryInterface CLIENT_PROXY_VER S:%s, F:%s] failed", DSLM_SAMGR_SERVICE,
135 DSLM_SAMGR_FEATURE);
136 return NULL;
137 }
138 SECURITY_LOG_INFO("[QueryInterface CLIENT_PROXY_VER S:%s, F:%s] success", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
139 return proxy;
140 }
141
ReleaseClientProxy(DslmClientProxy * clientProxy)142 void ReleaseClientProxy(DslmClientProxy *clientProxy)
143 {
144 if (clientProxy == NULL) {
145 return;
146 }
147
148 int32 ret = clientProxy->Release((IUnknown *)clientProxy);
149 SECURITY_LOG_INFO("[Release api S:%s, F:%s]: ret:%d", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE, ret);
150 }