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