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