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