1 /*
2 * Copyright (c) 2023 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_base.h>
17 #include <hdf_device_desc.h>
18 #include <hdf_log.h>
19 #include <hdf_sbuf_ipc.h>
20 #include "v1_0/secure_element_interface_stub.h"
21
22 #ifdef SE_DRIVER_USE_CA
23 #include "secure_element_ca_proxy.h"
24 #endif
25
26 #define HDF_LOG_TAG hdf_se
27
28 #ifdef LOG_DOMAIN
29 #undef LOG_DOMAIN
30 #endif
31
32 #define LOG_DOMAIN 0xD000305
33
34 using OHOS::HDI::SecureElement::V1_0::ISecureElementInterface;
35
36 struct HdfSeInterfaceHost {
37 struct IDeviceIoService ioservice;
38 OHOS::sptr<OHOS::IRemoteObject> stub;
39 };
40
SeInterfaceDriverDispatch(struct HdfDeviceIoClient * client,int cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)41 static int32_t SeInterfaceDriverDispatch(struct HdfDeviceIoClient* client, int cmdId, struct HdfSBuf* data,
42 struct HdfSBuf* reply)
43 {
44 auto* hdfSeInterfaceHost =
45 CONTAINER_OF(client->device->service, struct HdfSeInterfaceHost, ioservice);
46
47 OHOS::MessageParcel* dataParcel = nullptr;
48 OHOS::MessageParcel* replyParcel = nullptr;
49 OHOS::MessageOption option;
50
51 if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {
52 HDF_LOGE("%{public}s:invalid data sbuf object to dispatch", __func__);
53 return HDF_ERR_INVALID_PARAM;
54 }
55 if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) {
56 HDF_LOGE("%{public}s:invalid reply sbuf object to dispatch", __func__);
57 return HDF_ERR_INVALID_PARAM;
58 }
59
60 return hdfSeInterfaceHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option);
61 }
62
HdfSeInterfaceDriverInit(struct HdfDeviceObject * deviceObject)63 static int HdfSeInterfaceDriverInit(struct HdfDeviceObject* deviceObject)
64 {
65 HDF_LOGE("%{public}s: Enter", __func__);
66 #ifdef SE_DRIVER_USE_CA
67 int ret = OHOS::HDI::SecureElement::SecureElementCaProxy::GetInstance().VendorSecureElementCaOnStart();
68 if (ret != SECURE_ELEMENT_CA_RET_OK) {
69 HDF_LOGE("%{public}s: Failed", __func__);
70 return HDF_ERR_INVALID_PARAM;
71 }
72 #endif
73 return HDF_SUCCESS;
74 }
75
HdfSeInterfaceDriverBind(struct HdfDeviceObject * deviceObject)76 static int HdfSeInterfaceDriverBind(struct HdfDeviceObject* deviceObject)
77 {
78 auto* hdfSeInterfaceHost = new (std::nothrow) HdfSeInterfaceHost;
79 if (hdfSeInterfaceHost == nullptr) {
80 HDF_LOGE("%{public}s: failed to create HdfSeInterfaceDriverBind Object!", __func__);
81 return HDF_FAILURE;
82 }
83
84 hdfSeInterfaceHost->ioservice.Dispatch = SeInterfaceDriverDispatch;
85 hdfSeInterfaceHost->ioservice.Open = nullptr;
86 hdfSeInterfaceHost->ioservice.Release = nullptr;
87
88 auto serviceImpl = ISecureElementInterface::Get(true);
89 if (serviceImpl == nullptr) {
90 HDF_LOGE("%{public}s: failed to get of implement service", __func__);
91 delete hdfSeInterfaceHost;
92 return HDF_FAILURE;
93 }
94
95 hdfSeInterfaceHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
96 ISecureElementInterface::GetDescriptor());
97 if (hdfSeInterfaceHost->stub == nullptr) {
98 HDF_LOGE("%{public}s: failed to get stub object", __func__);
99 delete hdfSeInterfaceHost;
100 return HDF_FAILURE;
101 }
102
103 deviceObject->service = &hdfSeInterfaceHost->ioservice;
104 return HDF_SUCCESS;
105 }
106
HdfSeInterfaceDriverRelease(struct HdfDeviceObject * deviceObject)107 static void HdfSeInterfaceDriverRelease(struct HdfDeviceObject* deviceObject)
108 {
109 if (deviceObject->service == nullptr) {
110 HDF_LOGE("HdfSeInterfaceDriverRelease not initted");
111 return;
112 }
113
114 auto* hdfSeInterfaceHost =
115 CONTAINER_OF(deviceObject->service, struct HdfSeInterfaceHost, ioservice);
116 delete hdfSeInterfaceHost;
117 }
118
119 static struct HdfDriverEntry g_seInterfaceDriverEntry = {
120 .moduleVersion = 1,
121 .moduleName = "secure_element_service",
122 .Bind = HdfSeInterfaceDriverBind,
123 .Init = HdfSeInterfaceDriverInit,
124 .Release = HdfSeInterfaceDriverRelease,
125 };
126
127 #ifdef __cplusplus
128 extern "C" {
129 #endif /* __cplusplus */
130 HDF_INIT(g_seInterfaceDriverEntry);
131 #ifdef __cplusplus
132 }
133 #endif /* __cplusplus */
134