• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 2018-2022 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) << "Endpoint set 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) << "Endpoint set 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_SetEndPoint_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 
324   LOG(INFO) << "Acquired the lock from SPI openLogicalChannel";
325 
326   if (!mIsEseInitialized) {
327     ESESTATUS status = seHalInit();
328     if (status != ESESTATUS_SUCCESS) {
329       LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
330       _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
331       return Void();
332     }
333   }
334 
335   SecureElementStatus sestatus = SecureElementStatus::IOERROR;
336   ESESTATUS status = ESESTATUS_FAILED;
337   phNxpEse_data cmdApdu;
338   phNxpEse_data rspApdu;
339 
340   phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
341 
342   phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
343 
344   cmdApdu.len = (uint32_t)manageChannelCommand.size();
345   cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
346                                                sizeof(uint8_t));
347   memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
348 
349   status = phNxpEse_SetEndPoint_Cntxt(0);
350   if (status != ESESTATUS_SUCCESS) {
351     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
352   }
353   status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
354   if (status != ESESTATUS_SUCCESS) {
355     resApduBuff.channelNumber = 0xff;
356   } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
357              rspApdu.p_data[rspApdu.len - 1] == 0x81) {
358     resApduBuff.channelNumber = 0xff;
359     sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
360   } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
361              rspApdu.p_data[rspApdu.len - 1] == 0x00) {
362     resApduBuff.channelNumber = rspApdu.p_data[0];
363     mOpenedchannelCount++;
364     mOpenedChannels[resApduBuff.channelNumber] = true;
365     sestatus = SecureElementStatus::SUCCESS;
366   } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
367               (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
368              rspApdu.p_data[rspApdu.len - 1] == 0x00) {
369     sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
370   }
371   /*Free the allocations*/
372   phNxpEse_free(cmdApdu.p_data);
373   phNxpEse_free(rspApdu.p_data);
374 
375   if (sestatus != SecureElementStatus::SUCCESS) {
376     if (mOpenedchannelCount == 0) {
377       SecureElementStatus deInitStatus = seHalDeInit();
378       if (deInitStatus != SecureElementStatus::SUCCESS) {
379         LOG(INFO) << "seDeInit Failed";
380       }
381     }
382     /*If manageChannel is failed in any of above cases
383     send the callback and return*/
384     status = phNxpEse_ResetEndPoint_Cntxt(0);
385     if (status != ESESTATUS_SUCCESS) {
386       LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
387     }
388     _hidl_cb(resApduBuff, sestatus);
389     return Void();
390   }
391   LOG(INFO) << "openLogicalChannel Sending selectApdu";
392   sestatus = SecureElementStatus::IOERROR;
393   status = ESESTATUS_FAILED;
394 
395   phNxpEse_7816_cpdu_t cpdu;
396   phNxpEse_7816_rpdu_t rpdu;
397   phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
398   phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
399 
400   if ((resApduBuff.channelNumber > 0x03) &&
401       (resApduBuff.channelNumber < 0x14)) {
402     /* update CLA byte according to GP spec Table 11-12*/
403     cpdu.cla =
404         0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
405   } else if ((resApduBuff.channelNumber > 0x00) &&
406              (resApduBuff.channelNumber < 0x04)) {
407     /* update CLA byte according to GP spec Table 11-11*/
408     cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
409   } else {
410     LOG(ERROR) << StringPrintf("%s: Invalid Channel no: %02x", __func__,
411                                resApduBuff.channelNumber);
412     resApduBuff.channelNumber = 0xff;
413     _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
414     return Void();
415   }
416   cpdu.ins = 0xA4; /* Instruction code */
417   cpdu.p1 = 0x04;  /* Instruction parameter 1 */
418   cpdu.p2 = p2;    /* Instruction parameter 2 */
419   cpdu.lc = (uint16_t)aid.size();
420   cpdu.le_type = 0x01;
421   cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
422   memcpy(cpdu.pdata, aid.data(), cpdu.lc);
423   cpdu.le = 256;
424 
425   rpdu.len = 0x02;
426   rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
427 
428   status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
429 
430   if (status != ESESTATUS_SUCCESS) {
431     /*Transceive failed*/
432     if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
433       sestatus = SecureElementStatus::IOERROR;
434     } else {
435       sestatus = SecureElementStatus::FAILED;
436     }
437   } else {
438     /*Status word to be passed as part of response
439     So include additional length*/
440     uint16_t responseLen = rpdu.len + 2;
441     resApduBuff.selectResponse.resize(responseLen);
442     memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
443     resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
444     resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
445 
446     /*Status is success*/
447     if ((rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) || (rpdu.sw1 == 0x62) ||
448         (rpdu.sw1 == 0x63)) {
449       sestatus = SecureElementStatus::SUCCESS;
450     }
451     /*AID provided doesn't match any applet on the secure element*/
452     else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
453              (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
454       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
455     }
456     /*Operation provided by the P2 parameter is not permitted by the applet.*/
457     else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
458       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
459     } else {
460       sestatus = SecureElementStatus::FAILED;
461     }
462   }
463   if (sestatus != SecureElementStatus::SUCCESS) {
464     SecureElementStatus closeChannelStatus =
465         internalCloseChannel(resApduBuff.channelNumber);
466     if (closeChannelStatus != SecureElementStatus::SUCCESS) {
467       LOG(ERROR) << "%s: closeChannel Failed" << __func__;
468     } else {
469       resApduBuff.channelNumber = 0xff;
470     }
471   }
472   status = phNxpEse_ResetEndPoint_Cntxt(0);
473   if (status != ESESTATUS_SUCCESS) {
474     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
475   }
476   _hidl_cb(resApduBuff, sestatus);
477   phNxpEse_free(cpdu.pdata);
478   phNxpEse_free(rpdu.pdata);
479 
480   return Void();
481 }
482 
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)483 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
484                                              uint8_t p2,
485                                              openBasicChannel_cb _hidl_cb) {
486   AutoMutex guard(seHalLock);
487   ESESTATUS status = ESESTATUS_SUCCESS;
488   phNxpEse_7816_cpdu_t cpdu;
489   phNxpEse_7816_rpdu_t rpdu;
490   hidl_vec<uint8_t> result;
491   hidl_vec<uint8_t> ls_aid = {0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C,
492                               0x41, 0x01, 0x43, 0x4F, 0x52, 0x01};
493 
494   LOG(ERROR) << "Acquired the lock in SPI openBasicChannel";
495 
496   if (!mIsEseInitialized) {
497     ESESTATUS status = seHalInit();
498     if (status != ESESTATUS_SUCCESS) {
499       LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
500       _hidl_cb(result, SecureElementStatus::IOERROR);
501       return Void();
502     }
503   }
504   phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
505   phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
506 
507   cpdu.cla = 0x00; /* Class of instruction */
508   cpdu.ins = 0xA4; /* Instruction code */
509   cpdu.p1 = 0x04;  /* Instruction parameter 1 */
510   cpdu.p2 = p2;    /* Instruction parameter 2 */
511   cpdu.lc = (uint16_t)aid.size();
512   cpdu.le_type = 0x01;
513   cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
514   memcpy(cpdu.pdata, aid.data(), cpdu.lc);
515   cpdu.le = 256;
516 
517   rpdu.len = 0x02;
518   rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
519 
520   status = phNxpEse_SetEndPoint_Cntxt(0);
521   if (status != ESESTATUS_SUCCESS) {
522     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
523   }
524   status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
525   SecureElementStatus sestatus;
526   memset(&sestatus, 0x00, sizeof(sestatus));
527 
528   if (status != ESESTATUS_SUCCESS) {
529     /* Transceive failed */
530     if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
531       sestatus = SecureElementStatus::IOERROR;
532     } else {
533       sestatus = SecureElementStatus::FAILED;
534     }
535   } else {
536     /*Status word to be passed as part of response
537     So include additional length*/
538     uint16_t responseLen = rpdu.len + 2;
539     result.resize(responseLen);
540     memcpy(&result[0], rpdu.pdata, rpdu.len);
541     result[responseLen - 1] = rpdu.sw2;
542     result[responseLen - 2] = rpdu.sw1;
543 
544     /*Status is success*/
545     if (((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) || (rpdu.sw1 == 0x62) ||
546         (rpdu.sw1 == 0x63)) {
547       /*Set basic channel reference if it is not set */
548       if (!mOpenedChannels[0]) {
549         mOpenedChannels[0] = true;
550         mOpenedchannelCount++;
551       }
552 
553       sestatus = SecureElementStatus::SUCCESS;
554     }
555     /*AID provided doesn't match any applet on the secure element*/
556     else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
557              (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
558       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
559     }
560     /*Operation provided by the P2 parameter is not permitted by the applet.*/
561     else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
562       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
563     } else {
564       sestatus = SecureElementStatus::FAILED;
565     }
566   }
567   status = phNxpEse_ResetEndPoint_Cntxt(0);
568   if (status != ESESTATUS_SUCCESS) {
569     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
570   }
571   if (sestatus != SecureElementStatus::SUCCESS) {
572     SecureElementStatus closeChannelStatus =
573         internalCloseChannel(DEFAULT_BASIC_CHANNEL);
574     if (closeChannelStatus != SecureElementStatus::SUCCESS) {
575       LOG(ERROR) << "%s: closeChannel Failed" << __func__;
576     }
577   }
578   _hidl_cb(result, sestatus);
579   phNxpEse_free(cpdu.pdata);
580   phNxpEse_free(rpdu.pdata);
581   return Void();
582 }
583 
internalCloseChannel(uint8_t channelNumber)584 Return<SecureElementStatus> SecureElement::internalCloseChannel(
585     uint8_t channelNumber) {
586   ESESTATUS status = ESESTATUS_SUCCESS;
587   SecureElementStatus sestatus = SecureElementStatus::FAILED;
588   phNxpEse_7816_cpdu_t cpdu;
589   phNxpEse_7816_rpdu_t rpdu;
590 
591   LOG(ERROR) << "Acquired the lock in SPI internalCloseChannel";
592   LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d",
593                             mMaxChannelCount, channelNumber);
594   if (channelNumber >= mMaxChannelCount) {
595     LOG(ERROR) << StringPrintf("invalid channel!!! %d", channelNumber);
596   } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
597     phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
598     phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
599     cpdu.cla = channelNumber; /* Class of instruction */
600     // For Supplementary Channel update CLA byte according to GP
601     if ((channelNumber > 0x03) && (channelNumber < 0x14)) {
602       /* update CLA byte according to GP spec Table 11-12*/
603       cpdu.cla = 0x40 + (channelNumber - 4); /* Class of instruction */
604     }
605     cpdu.ins = 0x70;          /* Instruction code */
606     cpdu.p1 = 0x80;           /* Instruction parameter 1 */
607     cpdu.p2 = channelNumber;  /* Instruction parameter 2 */
608     cpdu.lc = 0x00;
609     cpdu.le = 0x9000;
610     status = phNxpEse_SetEndPoint_Cntxt(0);
611     if (status != ESESTATUS_SUCCESS) {
612       LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
613     }
614     status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
615     if (status == ESESTATUS_SUCCESS) {
616       if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
617         sestatus = SecureElementStatus::SUCCESS;
618       }
619     }
620     status = phNxpEse_ResetEndPoint_Cntxt(0);
621     if (status != ESESTATUS_SUCCESS) {
622       LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
623     }
624   }
625   if (channelNumber < mMaxChannelCount) {
626     if (mOpenedChannels[channelNumber]) {
627       mOpenedChannels[channelNumber] = false;
628       mOpenedchannelCount--;
629     }
630   }
631   /*If there are no channels remaining close secureElement*/
632   if (mOpenedchannelCount == 0) {
633     sestatus = seHalDeInit();
634   } else {
635     sestatus = SecureElementStatus::SUCCESS;
636   }
637   return sestatus;
638 }
639 
closeChannel(uint8_t channelNumber)640 Return<SecureElementStatus> SecureElement::closeChannel(uint8_t channelNumber) {
641   AutoMutex guard(seHalLock);
642   return internalCloseChannel(channelNumber);
643 }
644 
serviceDied(uint64_t,const wp<IBase> &)645 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
646   LOG(ERROR) << " SecureElement serviceDied!!!";
647   mIsEseInitialized = false;
648   if (seHalDeInit() != SecureElementStatus::SUCCESS) {
649     LOG(ERROR) << "SE Deinit not successful";
650   }
651 }
seHalInit()652 ESESTATUS SecureElement::seHalInit() {
653   ESESTATUS status = ESESTATUS_SUCCESS;
654   phNxpEse_initParams initParams;
655   ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
656   memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
657   initParams.initMode = ESE_MODE_NORMAL;
658   initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
659   initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
660 
661   status = phNxpEse_open(initParams);
662   if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
663     if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
664         ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
665       if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
666         mIsEseInitialized = true;
667         LOG(INFO) << "ESE SPI init complete!!!";
668         return ESESTATUS_SUCCESS;
669       }
670       deInitStatus = phNxpEse_deInit();
671     } else {
672       LOG(INFO) << "ESE SPI init NOT successful";
673       status = ESESTATUS_FAILED;
674     }
675     if (phNxpEse_close(deInitStatus) != ESESTATUS_SUCCESS) {
676       LOG(INFO) << "ESE close not successful";
677       status = ESESTATUS_FAILED;
678     }
679     mIsEseInitialized = false;
680   }
681   return status;
682 }
683 
seHalDeInit()684 Return<SecureElementStatus> SecureElement::seHalDeInit() {
685   ESESTATUS status = ESESTATUS_SUCCESS;
686   ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
687   bool mIsDeInitDone = true;
688   SecureElementStatus sestatus = SecureElementStatus::FAILED;
689   status = phNxpEse_SetEndPoint_Cntxt(0);
690   if (status != ESESTATUS_SUCCESS) {
691     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
692     mIsDeInitDone = false;
693   }
694   deInitStatus = phNxpEse_deInit();
695   if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
696   status = phNxpEse_ResetEndPoint_Cntxt(0);
697   if (status != ESESTATUS_SUCCESS) {
698     LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
699     mIsDeInitDone = false;
700   }
701   status = phNxpEse_close(deInitStatus);
702   if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
703     sestatus = SecureElementStatus::SUCCESS;
704     ;
705   } else {
706     LOG(ERROR) << "seHalDeInit: Failed";
707   }
708   mIsEseInitialized = false;
709   for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
710     mOpenedChannels[xx] = false;
711   }
712   mOpenedchannelCount = 0;
713 
714   return sestatus;
715 }
716 
717 }  // namespace implementation
718 }  // namespace V1_1
719 }  // namespace secure_element
720 }  // namespace hardware
721 }  // namespace android
722