1 /*
2  * Copyright (C) 2024 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 "se_vendor_adaptions.h"
17 #include <hdf_base.h>
18 #include <hdf_log.h>
19 #include <vector>
20 #include <iproxy_broker.h>
21 
22 #include "securec.h"
23 
24 #define HDF_LOG_TAG hdf_sim_se
25 
26 #ifdef LOG_DOMAIN
27 #undef LOG_DOMAIN
28 #endif
29 
30 #define LOG_DOMAIN 0xD000305
31 
32 namespace OHOS {
33 namespace HDI {
34 namespace SecureElement {
35 namespace SimSecureElement {
36 namespace V1_0 {
37 static sptr<ISecureElementCallback> g_callbackV1_0 = nullptr;
38 static const int RES_BUFFER_MAX_LENGTH = 512;
39 static const uint16_t SW1_OFFSET = 2;
40 static const uint16_t SW2_OFFSET = 1;
41 static const uint16_t MAX_CHANNEL_NUM = 4;
42 static const uint16_t MAX_CHANNEL_SIZE = 0xFF;
43 uint16_t g_openedChannelCount = 0;
44 bool g_openedChannels[MAX_CHANNEL_NUM] = {false, false, false, false};
45 bool g_initFuncFlag = false;
46 
SimSeVendorAdaptions()47 SimSeVendorAdaptions::SimSeVendorAdaptions()
48 {
49     HDF_LOGE("SimSeVendorAdaptions enter");
50     remoteDeathRecipient_ =
51         new RemoteDeathRecipient(std::bind(&SimSeVendorAdaptions::OnRemoteDied, this, std::placeholders::_1));
52     InitFunc();
53 }
54 
~SimSeVendorAdaptions()55 SimSeVendorAdaptions::~SimSeVendorAdaptions() {}
56 
DynamicLoad(const std::string & lib)57 SimSeVendorAdaptions::DynamicLoad::DynamicLoad(const std::string &lib) : libPath_(lib) {}
58 
~DynamicLoad()59 SimSeVendorAdaptions::DynamicLoad::~DynamicLoad()
60 {
61     (void)CloseLib();
62 }
63 
LoadLib()64 bool SimSeVendorAdaptions::DynamicLoad::LoadLib()
65 {
66     if (libPath_.empty() || handle_) {
67         return false;
68     }
69     handle_ = dlopen(libPath_.c_str(), RTLD_LAZY | RTLD_LOCAL);
70     if (!handle_) {
71         HDF_LOGE("load %{public}s fail, %{public}s", libPath_.c_str(), dlerror());
72         return false;
73     }
74     HDF_LOGI("load %{public}s success", libPath_.c_str());
75     return true;
76 }
77 
CloseLib()78 bool SimSeVendorAdaptions::DynamicLoad::CloseLib()
79 {
80     if (handle_) {
81         if (dlclose(handle_) != 0) {
82             handle_ = nullptr;
83             HDF_LOGE("close %{public}s fail, %{public}s", libPath_.c_str(), dlerror());
84             return false;
85         }
86         handle_ = nullptr;
87     }
88     HDF_LOGI("close %{public}s success", libPath_.c_str());
89     return true;
90 }
91 
InitFunc()92 void SimSeVendorAdaptions::InitFunc()
93 {
94     HDF_LOGE("SimSeVendorAdaptions::InitFunc enter!");
95     if (!loader_) {
96         loader_ = std::make_unique<DynamicLoad>(LIB_NAME);
97         HDF_LOGE("SimSeVendorAdaptions::InitFunc enter %{public}s!", LIB_NAME);
98         if (!loader_->LoadLib()) {
99             return;
100         }
101     }
102     vendorSimSecureElementInitFunc_ = loader_->FindTheFunc<VendorSimSecureElementInitT>(SIM_INIT_SYMBOL);
103     vendorSimSecureElementUninitFunc_ = loader_->FindTheFunc<VendorSimSecureElementUninitT>(SIM_UNINIT_SYMBOL);
104     vendorSimSecureElementIsCardPresentFunc_ = loader_->FindTheFunc<VendorSimSecureElementIsCardPresentT>(
105         SIM_IS_CARD_PRESENT_SYMBOL);
106     vendorSimSecureElementGetAtrFunc_ = loader_->FindTheFunc<VendorSimSecureElementGetAtrT>(SIM_GET_ATR_SYMBOL);
107     vendorSimSecureElementOpenLogicalChannelFunc_ =
108         loader_->FindTheFunc<VendorSimSecureElementOpenLogicalChannelT>(SIM_OPEN_LOGICAL_SYMBOL);
109     vendorSimSecureElementOpenBasicChannelFunc_ =
110         loader_->FindTheFunc<VendorSimSecureElementOpenBasicChannelT>(SIM_OPEN_BASIC_SYMBOL);
111     vendorSimSecureElementCloseChannelFunc_ =
112         loader_->FindTheFunc<VendorSimSecureElementCloseChannelT>(SIM_CLOSE_SYMBOL);
113     vendorSimSecureElementTransmitFunc_ = loader_->FindTheFunc<VendorSimSecureElementTransmitT>(SIM_TRANS_SYMBOL);
114     g_initFuncFlag = true;
115     HDF_LOGE("SimSeVendorAdaptions::InitFunc exit!");
116 }
117 
118 #define SIM_FUNCTION_INVOKE_RETURN(func, ...) \
119     if (g_initFuncFlag == false) {           \
120         InitFunc();                          \
121     }                                        \
122     if (func) {                              \
123         return func(__VA_ARGS__);            \
124     }                                        \
125     HDF_LOGE("func is null!");               \
126     return SIM_SECURE_ELEMENT_RET_LOAD_FAIL
127 
VendorSimSecureElementInit()128 int SimSeVendorAdaptions::VendorSimSecureElementInit()
129 {
130     HDF_LOGE("SimSeVendorAdaptions::VendorSimSecureElementInit %{public}x", g_initFuncFlag);
131     SIM_FUNCTION_INVOKE_RETURN(vendorSimSecureElementInitFunc_);
132 }
133 
VendorSimSecureElementUninit()134 int SimSeVendorAdaptions::VendorSimSecureElementUninit()
135 {
136     RemoveSecureElementDeathRecipient(g_callbackV1_0);
137     SIM_FUNCTION_INVOKE_RETURN(vendorSimSecureElementUninitFunc_);
138 }
139 
VendorSimSecureElementGetAtr(uint8_t * rsp,uint32_t * rspLen)140 int SimSeVendorAdaptions::VendorSimSecureElementGetAtr(uint8_t *rsp, uint32_t *rspLen)
141 {
142     SIM_FUNCTION_INVOKE_RETURN(vendorSimSecureElementGetAtrFunc_, rsp, rspLen);
143 }
144 
VendorSimSecureElementOpenLogicalChannel(const std::vector<uint8_t> & aid,uint8_t p2,std::vector<uint8_t> & response,uint32_t * channelNum,int * status)145 int SimSeVendorAdaptions::VendorSimSecureElementOpenLogicalChannel(
146     const std::vector<uint8_t>& aid, uint8_t p2, std::vector<uint8_t>& response, uint32_t *channelNum, int *status)
147 {
148     uint8_t arrAid[RES_BUFFER_MAX_LENGTH];
149     uint32_t aidLen = aid.size();
150     uint8_t rsp[RES_BUFFER_MAX_LENGTH];
151     uint32_t rspLen = 0;
152     uint32_t i;
153     int ret;
154     if (aidLen > RES_BUFFER_MAX_LENGTH) {
155         HDF_LOGE("SimSeVendorAdaptions::VendorSimSecureElementOpenLogicalChannel invalid param %{public}x",
156             aidLen);
157         return SIM_SECURE_ELEMENT_RET_CONTEXT_FAIL;
158     }
159     for (i = 0; i < aidLen; i++) {
160         arrAid[i] = aid[i];
161     }
162     if (g_initFuncFlag == false) {
163         InitFunc();
164     }
165     if (vendorSimSecureElementOpenLogicalChannelFunc_) {
166         ret = vendorSimSecureElementOpenLogicalChannelFunc_(arrAid, aidLen, p2, rsp, &rspLen, channelNum, status);
167         if (!ret && rspLen) {
168             response.resize(rspLen);
169             for (i = 0; i < rspLen; i++) {
170                 response.push_back(rsp[i]);
171             }
172         }
173         return ret;
174     }
175     return SIM_SECURE_ELEMENT_RET_LOAD_FAIL;
176 }
177 
VendorSimSecureElementOpenBasicChannel(uint8_t * aid,uint32_t len,uint8_t * rsp,uint32_t * rspLen,int * status)178 int SimSeVendorAdaptions::VendorSimSecureElementOpenBasicChannel(
179     uint8_t *aid, uint32_t len, uint8_t *rsp, uint32_t *rspLen, int *status)
180 {
181     SIM_FUNCTION_INVOKE_RETURN(vendorSimSecureElementOpenBasicChannelFunc_, aid, len, rsp, rspLen, status);
182 }
183 
VendorSimSecureElementCloseChannel(uint32_t channelNum,int * status)184 int SimSeVendorAdaptions::VendorSimSecureElementCloseChannel(uint32_t channelNum, int *status)
185 {
186     SIM_FUNCTION_INVOKE_RETURN(vendorSimSecureElementCloseChannelFunc_, channelNum, status);
187 }
188 
VendorSimSecureElementTransmit(uint8_t * cmd,uint32_t cmdLen,uint8_t * rsp,uint32_t * rspLen,int * status)189 int SimSeVendorAdaptions::VendorSimSecureElementTransmit(
190     uint8_t *cmd, uint32_t cmdLen, uint8_t *rsp, uint32_t *rspLen, int *status)
191 {
192     SIM_FUNCTION_INVOKE_RETURN(vendorSimSecureElementTransmitFunc_, cmd, cmdLen, rsp, rspLen, status);
193 }
194 
init(const sptr<OHOS::HDI::SecureElement::SimSecureElement::V1_0::ISecureElementCallback> & clientCallback,OHOS::HDI::SecureElement::SimSecureElement::V1_0::SecureElementStatus & status)195 int32_t SimSeVendorAdaptions::init(
196     const sptr<OHOS::HDI::SecureElement::SimSecureElement::V1_0::ISecureElementCallback>& clientCallback,
197     OHOS::HDI::SecureElement::SimSecureElement::V1_0::SecureElementStatus& status)
198 {
199     HDF_LOGI("SimSeVendorAdaptions:%{public}s!", __func__);
200     if (clientCallback == nullptr) {
201         HDF_LOGE("init failed, clientCallback is null");
202         status = SecureElementStatus::SE_NULL_POINTER_ERROR;
203         return HDF_ERR_INVALID_PARAM;
204     }
205     g_openedChannelCount = 0;
206     int ret = VendorSimSecureElementInit();
207     if (ret != SIM_SECURE_ELEMENT_RET_OK) {
208         HDF_LOGE("VendorSimSecureElementInit failed ret %{public}u", ret);
209         status = SecureElementStatus::SE_GENERAL_ERROR;
210         return HDF_ERR_INVALID_PARAM;
211     }
212     g_callbackV1_0 = clientCallback;
213     g_callbackV1_0->OnSeStateChanged(true);
214     AddSecureElementDeathRecipient(g_callbackV1_0);
215     status = SecureElementStatus::SE_SUCCESS;
216     return HDF_SUCCESS;
217 }
218 
getAtr(std::vector<uint8_t> & response)219 int32_t SimSeVendorAdaptions::getAtr(std::vector<uint8_t>& response)
220 {
221     HDF_LOGI("SimSeVendorAdaptions:%{public}s!", __func__);
222     uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
223     uint32_t resLen = RES_BUFFER_MAX_LENGTH;
224     int ret = VendorSimSecureElementGetAtr(res, &resLen);
225     if (ret != SIM_SECURE_ELEMENT_RET_OK) {
226         HDF_LOGE("getAtr failed ret %{public}u", ret);
227         return HDF_SUCCESS;
228     }
229     for (uint32_t i = 0; i < resLen; i++) {
230         response.push_back(res[i]);
231     }
232     return HDF_SUCCESS;
233 }
234 
isSecureElementPresent(bool & present)235 int32_t SimSeVendorAdaptions::isSecureElementPresent(bool& present)
236 {
237     HDF_LOGI("SimSeVendorAdaptions:%{public}s!", __func__);
238     present = vendorSimSecureElementIsCardPresentFunc_();
239     return HDF_SUCCESS;
240 }
241 
openLogicalChannel(const std::vector<uint8_t> & aid,uint8_t p2,std::vector<uint8_t> & response,uint8_t & channelNumber,SecureElementStatus & status)242 int32_t SimSeVendorAdaptions::openLogicalChannel(const std::vector<uint8_t>& aid, uint8_t p2,
243     std::vector<uint8_t>& response, uint8_t& channelNumber, SecureElementStatus& status)
244 {
245     int tmpStatus;
246     HDF_LOGI("SimSeVendorAdaptions:%{public}s!", __func__);
247     if (aid.empty()) {
248         HDF_LOGE("aid is null");
249         status = SecureElementStatus::SE_ILLEGAL_PARAMETER_ERROR;
250         return HDF_ERR_INVALID_PARAM;
251     }
252     uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
253     uint32_t resLen = RES_BUFFER_MAX_LENGTH;
254     uint32_t channelCreated = MAX_CHANNEL_SIZE + 1;
255     int ret = VendorSimSecureElementOpenLogicalChannel(aid, p2, response, &channelCreated, &tmpStatus);
256     HDF_LOGE("VendorSimSecureElementOpenLogicalChannel ret %{public}u, tmpStatus = %{public}d", ret, tmpStatus);
257     if (ret != SIM_SECURE_ELEMENT_RET_OK) {
258         HDF_LOGE("openLogicalChannel failed ret %{public}u, tmpStatus = %{public}d", ret, tmpStatus);
259         if (g_openedChannelCount == 0) {
260             HDF_LOGI("openLogicalChannel: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
261             VendorSimSecureElementUninit();
262         }
263         return HDF_SUCCESS;
264     }
265     status = (SecureElementStatus)tmpStatus;
266     resLen = response.size();
267     for (uint32_t i = 0; i < resLen; i++) {
268         response.push_back(res[i]);
269     }
270     if (ret == SIM_SECURE_ELEMENT_RET_OK && resLen >= SW1_OFFSET &&
271         channelCreated < MAX_CHANNEL_NUM - 1 && !g_openedChannels[channelCreated]) {
272         if ((response[resLen - SW1_OFFSET] == 0x90 && response[resLen - SW2_OFFSET] == 0x00)
273             || response[resLen - SW2_OFFSET] == 0x62 || response[resLen - SW2_OFFSET] == 0x63) {
274             g_openedChannels[channelCreated] = true;
275             g_openedChannelCount++;
276         }
277     }
278     if (channelCreated <= MAX_CHANNEL_SIZE) {
279         channelNumber = static_cast<uint8_t>(channelCreated);
280     } else {
281         HDF_LOGE("openLogicalChannel err, channelCreated = %{public}d", channelCreated);
282     }
283     return HDF_SUCCESS;
284 }
285 
openBasicChannel(const std::vector<uint8_t> & aid,uint8_t p2,std::vector<uint8_t> & response,SecureElementStatus & status)286 int32_t SimSeVendorAdaptions::openBasicChannel(const std::vector<uint8_t>& aid, uint8_t p2,
287     std::vector<uint8_t>& response, SecureElementStatus& status)
288 {
289     int tmpStatus;
290     HDF_LOGI("SimSeVendorAdaptions:%{public}s!", __func__);
291     if (aid.empty()) {
292         HDF_LOGE("aid is null");
293         status = SecureElementStatus::SE_ILLEGAL_PARAMETER_ERROR;
294         return HDF_ERR_INVALID_PARAM;
295     }
296     uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
297     uint32_t resLen = RES_BUFFER_MAX_LENGTH;
298     int ret = VendorSimSecureElementOpenBasicChannel(
299         (uint8_t *)&aid[0], aid.size(), res, &resLen, &tmpStatus);
300     if (ret != SIM_SECURE_ELEMENT_RET_OK) {
301         HDF_LOGE("openBasicChannel failed ret %{public}u, tmpStatus = %{public}d", ret, tmpStatus);
302         if (g_openedChannelCount == 0) {
303             HDF_LOGI("openBasicChannel failed: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
304             VendorSimSecureElementUninit();
305         }
306         return HDF_SUCCESS;
307     }
308     status = (SecureElementStatus)tmpStatus;
309     resLen = response.size();
310     for (uint32_t i = 0; i < resLen; i++) {
311         response.push_back(res[i]);
312     }
313     if (ret == SIM_SECURE_ELEMENT_RET_OK && resLen >= SW1_OFFSET && !g_openedChannels[0]) {
314         if (response[resLen - SW1_OFFSET] == 0x90 && response[resLen - SW2_OFFSET] == 0x00) {
315             g_openedChannels[0] = true;
316             g_openedChannelCount++;
317         }
318     }
319     return HDF_SUCCESS;
320 }
321 
closeChannel(uint8_t channelNumber,SecureElementStatus & status)322 int32_t SimSeVendorAdaptions::closeChannel(uint8_t channelNumber, SecureElementStatus& status)
323 {
324     int tmpStatus;
325     HDF_LOGI("SimSeVendorAdaptions:%{public}s!", __func__);
326     int ret = VendorSimSecureElementCloseChannel(channelNumber, &tmpStatus);
327     status = (SecureElementStatus)tmpStatus;
328     if (ret != SIM_SECURE_ELEMENT_RET_OK) {
329         HDF_LOGE("closeChannel failed ret %{public}u, tmpStatus = %{public}d", ret, tmpStatus);
330         return HDF_SUCCESS;
331     }
332     HDF_LOGI("closeChannel: channelNumber = %{public}d", channelNumber);
333     if (channelNumber < MAX_CHANNEL_NUM - 1 && g_openedChannels[channelNumber]) {
334         g_openedChannels[channelNumber] = false;
335         g_openedChannelCount--;
336     }
337     if (g_openedChannelCount == 0) {
338         HDF_LOGI("closeChannel: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
339         VendorSimSecureElementUninit();
340     }
341     return HDF_SUCCESS;
342 }
343 
transmit(const std::vector<uint8_t> & command,std::vector<uint8_t> & response,SecureElementStatus & status)344 int32_t SimSeVendorAdaptions::transmit(const std::vector<uint8_t>& command, std::vector<uint8_t>& response,
345     SecureElementStatus& status)
346 {
347     int tmpStatus;
348     HDF_LOGI("SimSeVendorAdaptions:%{public}s!", __func__);
349     uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
350     uint32_t resLen = RES_BUFFER_MAX_LENGTH;
351     int ret = VendorSimSecureElementTransmit(
352         (uint8_t *)&command[0], command.size(), res, &resLen, &tmpStatus);
353     if (ret != SIM_SECURE_ELEMENT_RET_OK) {
354         HDF_LOGE("transmit failed ret %{public}u, tmpStatus = %{public}d", ret, tmpStatus);
355         return HDF_SUCCESS;
356     }
357     status = (SecureElementStatus)tmpStatus;
358     for (uint32_t i = 0; i < resLen; i++) {
359         response.push_back(res[i]);
360     }
361     return HDF_SUCCESS;
362 }
363 
reset(SecureElementStatus & status)364 int32_t SimSeVendorAdaptions::reset(SecureElementStatus& status)
365 {
366     HDF_LOGI("SimSeVendorAdaptions:%{public}s!", __func__);
367     HDF_LOGE("reset is not support");
368     status = SecureElementStatus::SE_SUCCESS;
369     return HDF_SUCCESS;
370 }
371 
OnRemoteDied(const wptr<IRemoteObject> & object)372 void SimSeVendorAdaptions::OnRemoteDied(const wptr<IRemoteObject> &object)
373 {
374     HDF_LOGI("OnRemoteDied");
375     SecureElementStatus status = SecureElementStatus::SE_GENERAL_ERROR;
376     for (size_t i = 0; i < MAX_CHANNEL_NUM; i++) {
377         if (g_openedChannels[i]) {
378             closeChannel(i, status);
379             HDF_LOGI("OnRemoteDied, close channel [%{public}zu], status = %{public}d", i, status);
380         }
381     }
382     g_callbackV1_0 = nullptr;
383 }
384 
AddSecureElementDeathRecipient(const sptr<ISecureElementCallback> & callbackObj)385 int32_t SimSeVendorAdaptions::AddSecureElementDeathRecipient(const sptr<ISecureElementCallback> &callbackObj)
386 {
387     if (callbackObj == nullptr) {
388         HDF_LOGE("SimSeVendorAdaptions AddSecureElementDeathRecipient callbackObj is nullptr");
389         return HDF_FAILURE;
390     }
391     const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ISecureElementCallback>(callbackObj);
392     bool result = remote->AddDeathRecipient(remoteDeathRecipient_);
393     if (!result) {
394         HDF_LOGE("SimSeVendorAdaptions AddDeathRecipient failed!");
395         return HDF_FAILURE;
396     }
397     return HDF_SUCCESS;
398 }
399 
RemoveSecureElementDeathRecipient(const sptr<ISecureElementCallback> & callbackObj)400 int32_t SimSeVendorAdaptions::RemoveSecureElementDeathRecipient(const sptr<ISecureElementCallback> &callbackObj)
401 {
402     if (callbackObj == nullptr) {
403         HDF_LOGE("SimSeVendorAdaptions callbackObj is nullptr!");
404         return HDF_FAILURE;
405     }
406     const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ISecureElementCallback>(callbackObj);
407     bool result = remote->RemoveDeathRecipient(remoteDeathRecipient_);
408     if (!result) {
409         HDF_LOGE("SimSeVendorAdaptions RemoveDeathRecipient failed!");
410         return HDF_FAILURE;
411     }
412     return HDF_SUCCESS;
413 }
414 }
415 }
416 } // SecureElement
417 } // HDI
418 } // OHOS