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