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