1 /******************************************************************************
2  *
3  *  Copyright 2018-2020 NXP
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 #include "VirtualISO.h"
19 #include <android-base/logging.h>
20 #include "NxpEse.h"
21 #include "SecureElement.h"
22 #include "eSEClient.h"
23 #include "hal_nxpese.h"
24 #include "phNxpEse_Apdu_Api.h"
25 #include "phNxpEse_Api.h"
26 
27 namespace vendor {
28 namespace nxp {
29 namespace virtual_iso {
30 namespace V1_0 {
31 namespace implementation {
32 
33 #define LOG_TAG "nxpVIsoese@1.1-service"
34 
35 #define DEFAULT_BASIC_CHANNEL 0x00
36 
37 using ::android::hardware::secure_element::V1_1::ISecureElement;
38 using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
39 
40 typedef struct gsTransceiveBuffer {
41   phNxpEse_data cmdData;
42   phNxpEse_data rspData;
43   hidl_vec<uint8_t>* pRspDataBuff;
44 } sTransceiveBuffer_t;
45 
46 static sTransceiveBuffer_t gsTxRxBuffer;
47 static hidl_vec<uint8_t> gsRspDataBuff(256);
48 sp<::android::hardware::secure_element::V1_0::ISecureElementHalCallback>
49     VirtualISO::mCallbackV1_0 = nullptr;
50 sp<::android::hardware::secure_element::V1_1::ISecureElementHalCallback>
51     VirtualISO::mCallbackV1_1 = nullptr;
52 std::vector<bool> VirtualISO::mOpenedChannels;
53 
VirtualISO()54 VirtualISO::VirtualISO()
55     : mMaxChannelCount(0), mOpenedchannelCount(0), mIsEseInitialized(false) {}
56 
init(const sp<::android::hardware::secure_element::V1_0::ISecureElementHalCallback> & clientCallback)57 Return<void> VirtualISO::init(
58     const sp<
59         ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
60         clientCallback) {
61   ESESTATUS status = ESESTATUS_SUCCESS;
62   ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
63   bool mIsInitDone = false;
64   phNxpEse_initParams initParams;
65   LOG(INFO) << "Virtual ISO::init Enter";
66   gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
67   memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
68   initParams.initMode = ESE_MODE_NORMAL;
69   initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
70 
71   if (clientCallback == nullptr) {
72     return Void();
73   } else {
74     clientCallback->linkToDeath(this, 0 /*cookie*/);
75   }
76   if (ese_update != ESE_UPDATE_COMPLETED) {
77     mCallbackV1_0 = clientCallback;
78     clientCallback->onStateChange(false);
79     LOG(INFO) << "ESE JCOP Download in progress";
80     NxpEse::setVirtualISOCallBack(clientCallback);
81     return Void();
82     // Register
83   }
84   if (mIsEseInitialized) {
85     clientCallback->onStateChange(true);
86     return Void();
87   }
88   status = phNxpEse_open(initParams);
89   if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
90     if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
91         ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
92       if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
93         LOG(INFO) << "VISO init complete!!!";
94         mIsInitDone = true;
95       }
96       deInitStatus = phNxpEse_deInit();
97       if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
98     }
99     status = phNxpEse_close(deInitStatus);
100   }
101   if (status == ESESTATUS_SUCCESS && mIsInitDone) {
102     mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
103     mOpenedChannels.resize(mMaxChannelCount, false);
104     clientCallback->onStateChange(true);
105   } else {
106     LOG(ERROR) << "VISO-Hal Init failed";
107     clientCallback->onStateChange(false);
108   }
109   return Void();
110 }
111 
init_1_1(const sp<::android::hardware::secure_element::V1_1::ISecureElementHalCallback> & clientCallback)112 Return<void> VirtualISO::init_1_1(
113     const sp<
114         ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
115         clientCallback) {
116   ESESTATUS status = ESESTATUS_SUCCESS;
117   ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
118   bool mIsInitDone = false;
119   phNxpEse_initParams initParams;
120   LOG(INFO) << "Virtual ISO::init Enter";
121   gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
122   memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
123   initParams.initMode = ESE_MODE_NORMAL;
124   initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
125 
126   if (clientCallback == nullptr) {
127     return Void();
128   } else {
129     clientCallback->linkToDeath(this, 0 /*cookie*/);
130   }
131   if (ese_update != ESE_UPDATE_COMPLETED) {
132     mCallbackV1_1 = clientCallback;
133     clientCallback->onStateChange_1_1(false, "NXP SE update going on");
134     LOG(INFO) << "ESE JCOP Download in progress";
135     NxpEse::setVirtualISOCallBack_1_1(clientCallback);
136     return Void();
137     // Register
138   }
139   if (mIsEseInitialized) {
140     clientCallback->onStateChange_1_1(true, "NXP VISIO HAL init ok");
141     return Void();
142   }
143   status = phNxpEse_open(initParams);
144   if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
145     if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
146         ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
147       if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
148         LOG(INFO) << "VISO init complete!!!";
149         mIsInitDone = true;
150       }
151       deInitStatus = phNxpEse_deInit();
152       if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
153     }
154     status = phNxpEse_close(deInitStatus);
155   }
156   if (status == ESESTATUS_SUCCESS && mIsInitDone) {
157     mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
158     mOpenedChannels.resize(mMaxChannelCount, false);
159     clientCallback->onStateChange_1_1(true, "NXP VISIO HAL init ok");
160   } else {
161     LOG(ERROR) << "VISO-Hal Init failed";
162     clientCallback->onStateChange_1_1(false, "NXP VISIO HAL init failed");
163   }
164   return Void();
165 }
166 
getAtr(getAtr_cb _hidl_cb)167 Return<void> VirtualISO::getAtr(getAtr_cb _hidl_cb) {
168   hidl_vec<uint8_t> response;
169   _hidl_cb(response);
170   return Void();
171 }
172 
isCardPresent()173 Return<bool> VirtualISO::isCardPresent() { return true; }
174 
transmit(const hidl_vec<uint8_t> & data,transmit_cb _hidl_cb)175 Return<void> VirtualISO::transmit(const hidl_vec<uint8_t>& data,
176                                   transmit_cb _hidl_cb) {
177   ESESTATUS status = ESESTATUS_FAILED;
178   hidl_vec<uint8_t> result;
179   phNxpEse_memset(&gsTxRxBuffer.cmdData, 0x00, sizeof(phNxpEse_data));
180   phNxpEse_memset(&gsTxRxBuffer.rspData, 0x00, sizeof(phNxpEse_data));
181   gsTxRxBuffer.cmdData.len = data.size();
182   gsTxRxBuffer.cmdData.p_data =
183       (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
184   if (NULL == gsTxRxBuffer.cmdData.p_data) {
185     LOG(ERROR) << "transmit failed to allocate the Memory!!!";
186     /*Return empty hidl_vec*/
187     _hidl_cb(result);
188     return Void();
189   }
190   memcpy(gsTxRxBuffer.cmdData.p_data, data.data(), gsTxRxBuffer.cmdData.len);
191   LOG(ERROR) << "Acquired the lock in VISO ";
192   status = phNxpEse_SetEndPoint_Cntxt(1);
193   if (status != ESESTATUS_SUCCESS) {
194     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
195   }
196   status = phNxpEse_Transceive(&gsTxRxBuffer.cmdData, &gsTxRxBuffer.rspData);
197 
198   if (status != ESESTATUS_SUCCESS) {
199     LOG(ERROR) << "transmit failed!!!";
200   } else {
201     result.resize(gsTxRxBuffer.rspData.len);
202     memcpy(&result[0], gsTxRxBuffer.rspData.p_data, gsTxRxBuffer.rspData.len);
203   }
204   status = phNxpEse_ResetEndPoint_Cntxt(1);
205   if (status != ESESTATUS_SUCCESS) {
206     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
207   }
208 
209   _hidl_cb(result);
210   if (NULL != gsTxRxBuffer.cmdData.p_data) {
211     phNxpEse_free(gsTxRxBuffer.cmdData.p_data);
212     gsTxRxBuffer.cmdData.p_data = NULL;
213   }
214   if (NULL != gsTxRxBuffer.rspData.p_data) {
215     phNxpEse_free(gsTxRxBuffer.rspData.p_data);
216     gsTxRxBuffer.rspData.p_data = NULL;
217   }
218 
219   return Void();
220 }
221 
openLogicalChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openLogicalChannel_cb _hidl_cb)222 Return<void> VirtualISO::openLogicalChannel(const hidl_vec<uint8_t>& aid,
223                                             uint8_t p2,
224                                             openLogicalChannel_cb _hidl_cb) {
225   hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
226 
227   LogicalChannelResponse resApduBuff;
228 
229   LOG(INFO) << "Acquired the lock in VISO openLogicalChannel";
230 
231   resApduBuff.channelNumber = 0xff;
232   memset(&resApduBuff, 0x00, sizeof(resApduBuff));
233   if (!mIsEseInitialized) {
234     ESESTATUS status = seHalInit();
235     if (status != ESESTATUS_SUCCESS) {
236       LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
237       _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
238       return Void();
239     }
240   }
241 
242   SecureElementStatus sestatus = SecureElementStatus::IOERROR;
243   ESESTATUS status = ESESTATUS_FAILED;
244   phNxpEse_data cmdApdu;
245   phNxpEse_data rspApdu;
246 
247   phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
248   phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
249 
250   cmdApdu.len = manageChannelCommand.size();
251   cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
252                                                sizeof(uint8_t));
253   memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
254 
255   memset(&sestatus, 0x00, sizeof(sestatus));
256 
257   status = phNxpEse_SetEndPoint_Cntxt(1);
258   if (status != ESESTATUS_SUCCESS) {
259     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
260   }
261   status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
262   if (status != ESESTATUS_SUCCESS) {
263     resApduBuff.channelNumber = 0xff;
264     if (NULL != rspApdu.p_data && rspApdu.len > 0) {
265       if ((rspApdu.p_data[0] == 0x64 && rspApdu.p_data[1] == 0xFF)) {
266         sestatus = SecureElementStatus::IOERROR;
267       }
268     }
269     if (SecureElementStatus::IOERROR != sestatus) {
270       sestatus = SecureElementStatus::FAILED;
271     }
272   } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
273              rspApdu.p_data[rspApdu.len - 1] == 0x81) {
274     resApduBuff.channelNumber = 0xff;
275     sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
276   } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
277              rspApdu.p_data[rspApdu.len - 1] == 0x00) {
278     resApduBuff.channelNumber = rspApdu.p_data[0];
279     mOpenedchannelCount++;
280     mOpenedChannels[resApduBuff.channelNumber] = true;
281     sestatus = SecureElementStatus::SUCCESS;
282   } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
283               (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
284              rspApdu.p_data[rspApdu.len - 1] == 0x00) {
285     sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
286   }
287 
288   /*Free the allocations*/
289   phNxpEse_free(cmdApdu.p_data);
290   phNxpEse_free(rspApdu.p_data);
291 
292   if (sestatus != SecureElementStatus::SUCCESS) {
293     if (mOpenedchannelCount == 0) {
294       sestatus = seHalDeInit();
295       if (sestatus != SecureElementStatus::SUCCESS) {
296         LOG(INFO) << "seDeInit Failed";
297       }
298     }
299     /*If manageChanle is failed in any of above cases
300     send the callback and return*/
301     status = phNxpEse_ResetEndPoint_Cntxt(1);
302     if (status != ESESTATUS_SUCCESS) {
303       LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
304     }
305     _hidl_cb(resApduBuff, sestatus);
306     return Void();
307   }
308   LOG(INFO) << "openLogicalChannel Sending selectApdu";
309   sestatus = SecureElementStatus::IOERROR;
310   status = ESESTATUS_FAILED;
311 
312   phNxpEse_7816_cpdu_t cpdu;
313   phNxpEse_7816_rpdu_t rpdu;
314   phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
315   phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
316 
317   if ((resApduBuff.channelNumber > 0x03) &&
318       (resApduBuff.channelNumber < 0x14)) {
319     /* update CLA byte accoridng to GP spec Table 11-12*/
320     cpdu.cla =
321         0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
322   } else if ((resApduBuff.channelNumber > 0x00) &&
323              (resApduBuff.channelNumber < 0x04)) {
324     /* update CLA byte accoridng to GP spec Table 11-11*/
325     cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
326   } else {
327     LOG(ERROR) << StringPrintf("%s: Invalid Channel no: %02x", __func__,
328                                resApduBuff.channelNumber);
329     resApduBuff.channelNumber = 0xff;
330     _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
331     return Void();
332   }
333   cpdu.ins = 0xA4; /* Instruction code */
334   cpdu.p1 = 0x04;  /* Instruction parameter 1 */
335   cpdu.p2 = p2;    /* Instruction parameter 2 */
336   cpdu.lc = aid.size();
337   cpdu.le_type = 0x01;
338   cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
339   memcpy(cpdu.pdata, aid.data(), cpdu.lc);
340   cpdu.le = 256;
341 
342   rpdu.len = 0x02;
343   rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
344 
345   status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
346   if (status != ESESTATUS_SUCCESS) {
347     /*Transceive failed*/
348     if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
349       sestatus = SecureElementStatus::IOERROR;
350     } else {
351       sestatus = SecureElementStatus::FAILED;
352     }
353   } else {
354     /*Status word to be passed as part of response
355     So include additional length*/
356     uint16_t responseLen = rpdu.len + 2;
357     resApduBuff.selectResponse.resize(responseLen);
358     memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
359     resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
360     resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
361 
362     /*Status is success*/
363     if (rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) {
364       sestatus = SecureElementStatus::SUCCESS;
365     }
366     /*AID provided doesn't match any applet on the secure element*/
367     else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) {
368       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
369     }
370     /*Operation provided by the P2 parameter is not permitted by the applet.*/
371     else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
372       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
373     } else {
374       sestatus = SecureElementStatus::FAILED;
375     }
376   }
377   if (sestatus != SecureElementStatus::SUCCESS) {
378     SecureElementStatus closeChannelStatus =
379         internalCloseChannel(resApduBuff.channelNumber);
380     if (closeChannelStatus != SecureElementStatus::SUCCESS) {
381       LOG(ERROR) << "%s: closeChannel Failed" << __func__;
382     } else {
383       resApduBuff.channelNumber = 0xff;
384     }
385   }
386   status = phNxpEse_ResetEndPoint_Cntxt(1);
387   if (status != ESESTATUS_SUCCESS) {
388     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
389   }
390   _hidl_cb(resApduBuff, sestatus);
391   phNxpEse_free(cpdu.pdata);
392   phNxpEse_free(rpdu.pdata);
393 
394   return Void();
395 }
396 
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)397 Return<void> VirtualISO::openBasicChannel(const hidl_vec<uint8_t>& aid,
398                                           uint8_t p2,
399                                           openBasicChannel_cb _hidl_cb) {
400   ESESTATUS status = ESESTATUS_SUCCESS;
401   phNxpEse_7816_cpdu_t cpdu;
402   phNxpEse_7816_rpdu_t rpdu;
403   hidl_vec<uint8_t> result;
404 
405   LOG(INFO) << "Acquired the lock in VISO openBasicChannel";
406 
407   if (!mIsEseInitialized) {
408     ESESTATUS status = seHalInit();
409     if (status != ESESTATUS_SUCCESS) {
410       LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
411       _hidl_cb(result, SecureElementStatus::IOERROR);
412       return Void();
413     }
414   }
415 
416   phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
417   phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
418 
419   cpdu.cla = 0x00; /* Class of instruction */
420   cpdu.ins = 0xA4; /* Instruction code */
421   cpdu.p1 = 0x04;  /* Instruction parameter 1 */
422   cpdu.p2 = p2;    /* Instruction parameter 2 */
423   cpdu.lc = aid.size();
424   cpdu.le_type = 0x01;
425   cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
426   memcpy(cpdu.pdata, aid.data(), cpdu.lc);
427   cpdu.le = 256;
428 
429   rpdu.len = 0x02;
430   rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
431 
432   status = phNxpEse_SetEndPoint_Cntxt(1);
433   status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
434 
435   SecureElementStatus sestatus;
436   memset(&sestatus, 0x00, sizeof(sestatus));
437 
438   if (status != ESESTATUS_SUCCESS) {
439     /* Transceive failed */
440     if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
441       sestatus = SecureElementStatus::IOERROR;
442     } else {
443       sestatus = SecureElementStatus::FAILED;
444     }
445   } else {
446     /*Status word to be passed as part of response
447     So include additional length*/
448     uint16_t responseLen = rpdu.len + 2;
449     result.resize(responseLen);
450     memcpy(&result[0], rpdu.pdata, rpdu.len);
451     result[responseLen - 1] = rpdu.sw2;
452     result[responseLen - 2] = rpdu.sw1;
453 
454     /*Status is success*/
455     if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
456       /*Set basic channel reference if it is not set */
457       if (!mOpenedChannels[0]) {
458         mOpenedChannels[0] = true;
459         mOpenedchannelCount++;
460       }
461 
462       sestatus = SecureElementStatus::SUCCESS;
463     }
464     /*AID provided doesn't match any applet on the secure element*/
465     else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) {
466       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
467     }
468     /*Operation provided by the P2 parameter is not permitted by the applet.*/
469     else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
470       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
471     } else {
472       sestatus = SecureElementStatus::FAILED;
473     }
474   }
475   status = phNxpEse_ResetEndPoint_Cntxt(1);
476   if (status != ESESTATUS_SUCCESS) {
477     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
478   }
479   if (sestatus != SecureElementStatus::SUCCESS) {
480     SecureElementStatus closeChannelStatus =
481         internalCloseChannel(DEFAULT_BASIC_CHANNEL);
482     if (closeChannelStatus != SecureElementStatus::SUCCESS) {
483       LOG(ERROR) << "%s: closeChannel Failed" << __func__;
484     }
485   }
486   _hidl_cb(result, sestatus);
487   phNxpEse_free(cpdu.pdata);
488   phNxpEse_free(rpdu.pdata);
489   return Void();
490 }
491 
492 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
internalCloseChannel(uint8_t channelNumber)493 VirtualISO::internalCloseChannel(uint8_t channelNumber) {
494   ESESTATUS status = ESESTATUS_SUCCESS;
495   SecureElementStatus sestatus = SecureElementStatus::FAILED;
496   phNxpEse_7816_cpdu_t cpdu;
497   phNxpEse_7816_rpdu_t rpdu;
498 
499   LOG(ERROR) << "internalCloseChannel Enter";
500   LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d",
501                             mMaxChannelCount, channelNumber);
502   if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL ||
503       channelNumber >= mMaxChannelCount) {
504     LOG(ERROR) << StringPrintf("invalid channel!!! %d", channelNumber);
505   } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
506     phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
507     phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
508     cpdu.cla = channelNumber; /* Class of instruction */
509     cpdu.ins = 0x70;          /* Instruction code */
510     cpdu.p1 = 0x80;           /* Instruction parameter 1 */
511     cpdu.p2 = channelNumber;  /* Instruction parameter 2 */
512     cpdu.lc = 0x00;
513     cpdu.le = 0x9000;
514     status = phNxpEse_SetEndPoint_Cntxt(1);
515     if (status != ESESTATUS_SUCCESS) {
516       LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
517     }
518     status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
519 
520     if (status == ESESTATUS_SUCCESS) {
521       if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
522         sestatus = SecureElementStatus::SUCCESS;
523       }
524     }
525     status = phNxpEse_ResetEndPoint_Cntxt(1);
526     if (status != ESESTATUS_SUCCESS) {
527       LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
528     }
529     if (mOpenedChannels[channelNumber]) {
530       mOpenedChannels[channelNumber] = false;
531       mOpenedchannelCount--;
532     }
533   }
534   /*If there are no channels remaining close secureElement*/
535   if (mOpenedchannelCount == 0) {
536     sestatus = seHalDeInit();
537   } else {
538     sestatus = SecureElementStatus::SUCCESS;
539   }
540   return sestatus;
541 }
542 
543 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
closeChannel(uint8_t channelNumber)544 VirtualISO::closeChannel(uint8_t channelNumber) {
545   ESESTATUS status = ESESTATUS_SUCCESS;
546   SecureElementStatus sestatus = SecureElementStatus::FAILED;
547   phNxpEse_7816_cpdu_t cpdu;
548   phNxpEse_7816_rpdu_t rpdu;
549 
550   LOG(INFO) << "Acquired the lock in VISO closeChannel";
551   if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL ||
552       channelNumber >= mMaxChannelCount) {
553     LOG(ERROR) << StringPrintf("invalid channel!!! %d", channelNumber);
554   } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
555     phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
556     phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
557     cpdu.cla = channelNumber; /* Class of instruction */
558     cpdu.ins = 0x70;          /* Instruction code */
559     cpdu.p1 = 0x80;           /* Instruction parameter 1 */
560     cpdu.p2 = channelNumber;  /* Instruction parameter 2 */
561     cpdu.lc = 0x00;
562     cpdu.le = 0x9000;
563     status = phNxpEse_SetEndPoint_Cntxt(1);
564     if (status != ESESTATUS_SUCCESS) {
565       LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
566     }
567     status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
568 
569     if (status == ESESTATUS_SUCCESS) {
570       if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
571         sestatus = SecureElementStatus::SUCCESS;
572       }
573     }
574     status = phNxpEse_ResetEndPoint_Cntxt(1);
575     if (status != ESESTATUS_SUCCESS) {
576       LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
577     }
578     if (mOpenedChannels[channelNumber]) {
579       mOpenedChannels[channelNumber] = false;
580       mOpenedchannelCount--;
581     }
582   }
583 
584   /*If there are no channels remaining close secureElement*/
585   if (mOpenedchannelCount == 0) {
586     sestatus = seHalDeInit();
587   } else {
588     sestatus = SecureElementStatus::SUCCESS;
589   }
590   return sestatus;
591 }
seHalInit()592 ESESTATUS VirtualISO::seHalInit() {
593   ESESTATUS status = ESESTATUS_SUCCESS;
594   ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
595   phNxpEse_initParams initParams;
596   memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
597   initParams.initMode = ESE_MODE_NORMAL;
598   initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
599 
600   status = phNxpEse_open(initParams);
601   if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
602     if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
603         ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
604       if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
605         mIsEseInitialized = true;
606         LOG(INFO) << "VISO init complete!!!";
607         return ESESTATUS_SUCCESS;
608       }
609       deInitStatus = phNxpEse_deInit();
610     }
611     phNxpEse_close(deInitStatus);
612     mIsEseInitialized = false;
613   }
614   return status;
615 }
616 
617 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
seHalDeInit()618 VirtualISO::seHalDeInit() {
619   ESESTATUS status = ESESTATUS_SUCCESS;
620   ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
621   bool mIsDeInitDone = true;
622   SecureElementStatus sestatus = SecureElementStatus::FAILED;
623   status = phNxpEse_SetEndPoint_Cntxt(1);
624   if (status != ESESTATUS_SUCCESS) {
625     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
626     mIsDeInitDone = false;
627   }
628   deInitStatus = phNxpEse_deInit();
629   if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
630   status = phNxpEse_ResetEndPoint_Cntxt(1);
631   if (status != ESESTATUS_SUCCESS) {
632     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
633     mIsDeInitDone = false;
634   }
635   status = phNxpEse_close(deInitStatus);
636   if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
637     sestatus = SecureElementStatus::SUCCESS;
638     ;
639   } else {
640     LOG(ERROR) << "seHalDeInit: Failed";
641   }
642   // Clear all the flags as SPI driver is closed.
643   mIsEseInitialized = false;
644   for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
645     mOpenedChannels[xx] = false;
646   }
647   mOpenedchannelCount = 0;
648   return sestatus;
649 }
650 
651 }  // namespace implementation
652 }  // namespace V1_0
653 }  // namespace virtual_iso
654 }  // namespace nxp
655 }  // namespace vendor
656