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