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