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