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