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 "secure_element_ca_proxy.h"
17 
18 #define HDF_LOG_TAG hdf_se
19 
20 #ifdef LOG_DOMAIN
21 #undef LOG_DOMAIN
22 #endif
23 
24 #define LOG_DOMAIN 0xD000305
25 
26 namespace OHOS {
27 namespace HDI {
28 namespace SecureElement {
SecureElementCaProxy()29 SecureElementCaProxy::SecureElementCaProxy()
30 {
31     InitFunc();
32 }
33 
DynamicLoad(const std::string & lib)34 SecureElementCaProxy::DynamicLoad::DynamicLoad(const std::string &lib) : libPath_(lib) {}
35 
~DynamicLoad()36 SecureElementCaProxy::DynamicLoad::~DynamicLoad()
37 {
38     (void)CloseLib();
39 }
40 
LoadLib()41 bool SecureElementCaProxy::DynamicLoad::LoadLib()
42 {
43     if (libPath_.empty() || handle_) {
44         return false;
45     }
46     handle_ = dlopen(libPath_.c_str(), RTLD_LAZY | RTLD_LOCAL);
47     if (!handle_) {
48         HDF_LOGE("load %{public}s fail, %{public}s", libPath_.c_str(), dlerror());
49         return false;
50     }
51     HDF_LOGI("load %{public}s success", libPath_.c_str());
52     return true;
53 }
54 
CloseLib()55 bool SecureElementCaProxy::DynamicLoad::CloseLib()
56 {
57     if (handle_) {
58         if (dlclose(handle_) != 0) {
59             handle_ = nullptr;
60             HDF_LOGE("close %{public}s fail, %{public}s", libPath_.c_str(), dlerror());
61             return false;
62         }
63         handle_ = nullptr;
64     }
65     HDF_LOGI("close %{public}s success", libPath_.c_str());
66     return true;
67 }
68 
InitFunc()69 void SecureElementCaProxy::InitFunc()
70 {
71     if (!loader_) {
72         loader_ = std::make_unique<DynamicLoad>(LIB_NAME);
73         if (!loader_->LoadLib()) {
74             return;
75         }
76     }
77     vendorSecureElementCaOnStartFunc_ = loader_->FindTheFunc<VendorSecureElementCaOnStartT>(CA_ON_START_SYMBOL);
78     vendorSecureElementCaInitFunc_ = loader_->FindTheFunc<VendorSecureElementCaInitT>(CA_INIT_SYMBOL);
79     vendorSecureElementCaUninitFunc_ = loader_->FindTheFunc<VendorSecureElementCaUninitT>(CA_UNINIT_SYMBOL);
80     vendorSecureElementCaGetAtrFunc_ = loader_->FindTheFunc<VendorSecureElementCaGetAtrT>(CA_GET_ATR_SYMBOL);
81     vendorSecureElementCaOpenLogicalChannelFunc_ =
82         loader_->FindTheFunc<VendorSecureElementCaOpenLogicalChannelT>(CA_OPEN_LOGICAL_SYMBOL);
83     vendorSecureElementCaOpenBasicChannelFunc_ =
84         loader_->FindTheFunc<VendorSecureElementCaOpenBasicChannelT>(CA_OPEN_BASIC_SYMBOL);
85     vendorSecureElementCaCloseChannelFunc_ =
86         loader_->FindTheFunc<VendorSecureElementCaCloseChannelT>(CA_CLOSE_SYMBOL);
87     vendorSecureElementCaTransmitFunc_ = loader_->FindTheFunc<VendorSecureElementCaTransmitT>(CA_TRANS_SYMBOL);
88 }
89 
90 #define CA_FUNCTION_INVOKE_RETURN(func, ...) \
91     if (func) {                              \
92         return func(__VA_ARGS__);            \
93     }                                        \
94     HDF_LOGE("func is null!");               \
95     return SECURE_ELEMENT_CA_RET_LOAD_FAIL
96 
VendorSecureElementCaOnStart() const97 int SecureElementCaProxy::VendorSecureElementCaOnStart() const
98 {
99     CA_FUNCTION_INVOKE_RETURN(vendorSecureElementCaOnStartFunc_);
100 }
101 
VendorSecureElementCaInit() const102 int SecureElementCaProxy::VendorSecureElementCaInit() const
103 {
104     CA_FUNCTION_INVOKE_RETURN(vendorSecureElementCaInitFunc_);
105 }
106 
VendorSecureElementCaUninit() const107 int SecureElementCaProxy::VendorSecureElementCaUninit() const
108 {
109     CA_FUNCTION_INVOKE_RETURN(vendorSecureElementCaUninitFunc_);
110 }
111 
VendorSecureElementCaGetAtr(uint8_t * rsp,uint32_t * rspLen) const112 int SecureElementCaProxy::VendorSecureElementCaGetAtr(uint8_t *rsp, uint32_t *rspLen) const
113 {
114     CA_FUNCTION_INVOKE_RETURN(vendorSecureElementCaGetAtrFunc_, rsp, rspLen);
115 }
116 
VendorSecureElementCaOpenLogicalChannel(uint8_t * aid,uint32_t len,uint8_t p2,uint8_t * rsp,uint32_t * rspLen,uint32_t * channelNum) const117 int SecureElementCaProxy::VendorSecureElementCaOpenLogicalChannel(
118     uint8_t *aid, uint32_t len, uint8_t p2, uint8_t *rsp, uint32_t *rspLen, uint32_t *channelNum) const
119 {
120     CA_FUNCTION_INVOKE_RETURN(vendorSecureElementCaOpenLogicalChannelFunc_, aid, len, p2, rsp, rspLen, channelNum);
121 }
122 
VendorSecureElementCaOpenBasicChannel(uint8_t * aid,uint32_t len,uint8_t * rsp,uint32_t * rspLen) const123 int SecureElementCaProxy::VendorSecureElementCaOpenBasicChannel(
124     uint8_t *aid, uint32_t len, uint8_t *rsp, uint32_t *rspLen) const
125 {
126     CA_FUNCTION_INVOKE_RETURN(vendorSecureElementCaOpenBasicChannelFunc_, aid, len, rsp, rspLen);
127 }
128 
VendorSecureElementCaCloseChannel(uint32_t channelNum) const129 int SecureElementCaProxy::VendorSecureElementCaCloseChannel(uint32_t channelNum) const
130 {
131     CA_FUNCTION_INVOKE_RETURN(vendorSecureElementCaCloseChannelFunc_, channelNum);
132 }
133 
VendorSecureElementCaTransmit(uint8_t * cmd,uint32_t cmdLen,uint8_t * rsp,uint32_t * rspLen) const134 int SecureElementCaProxy::VendorSecureElementCaTransmit(
135     uint8_t *cmd, uint32_t cmdLen, uint8_t *rsp, uint32_t *rspLen) const
136 {
137     CA_FUNCTION_INVOKE_RETURN(vendorSecureElementCaTransmitFunc_, cmd, cmdLen, rsp, rspLen);
138 }
139 
140 }  // SecureElement
141 }  // HDI
142 }  // OHOS