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