1 /******************************************************************************
2  *
3  *  Copyright 2018,2023 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 #define LOG_TAG "NxpEseHal"
19 #include <log/log.h>
20 
21 #include "LsClient.h"
22 #include "SecureElement.h"
23 #include "phNxpEse_Api.h"
24 
25 extern bool ese_debug_enabled;
26 
27 namespace android {
28 namespace hardware {
29 namespace secure_element {
30 namespace V1_1 {
31 namespace implementation {
32 
33 sp<V1_0::ISecureElementHalCallback> SecureElement::mCallbackV1_0 = nullptr;
34 sp<V1_1::ISecureElementHalCallback> SecureElement::mCallbackV1_1 = nullptr;
35 
onLSCompleted(bool result,std::string reason,void * arg)36 static void onLSCompleted(bool result, std::string reason, void* arg) {
37   ((SecureElement*)arg)->onStateChange(result, reason);
38 }
39 
SecureElement()40 SecureElement::SecureElement()
41     : mOpenedchannelCount(0), mOpenedChannels{false, false, false, false} {}
42 
init(const sp<V1_0::ISecureElementHalCallback> & clientCallback)43 Return<void> SecureElement::init(
44     const sp<V1_0::ISecureElementHalCallback>& clientCallback) {
45   ESESTATUS status = ESESTATUS_SUCCESS;
46 
47   if (clientCallback == nullptr) {
48     return Void();
49   } else {
50     mCallbackV1_0 = clientCallback;
51     mCallbackV1_1 = nullptr;
52     if (!mCallbackV1_0->linkToDeath(this, 0 /*cookie*/)) {
53       ALOGE("%s: Failed to register death notification", __func__);
54     }
55   }
56   if (isSeInitialized()) {
57     clientCallback->onStateChange(true);
58     return Void();
59   }
60 
61   status = seHalInit();
62   if (status != ESESTATUS_SUCCESS) {
63     clientCallback->onStateChange(false);
64     return Void();
65   }
66 
67   LSCSTATUS lsStatus = LSC_doDownload(onLSCompleted, (void*)this);
68   /*
69    * LSC_doDownload returns LSCSTATUS_FAILED in case thread creation fails.
70    * So return callback as false.
71    * Otherwise callback will be called in LSDownload module.
72    */
73   if (lsStatus != LSCSTATUS_SUCCESS) {
74     ALOGE("%s: LSDownload thread creation failed!!!", __func__);
75     SecureElementStatus sestatus = seHalDeInit();
76     if (sestatus != SecureElementStatus::SUCCESS) {
77       ALOGE("%s: seHalDeInit failed!!!", __func__);
78     }
79     clientCallback->onStateChange(false);
80   }
81   return Void();
82 }
83 
init_1_1(const sp<V1_1::ISecureElementHalCallback> & clientCallback)84 Return<void> SecureElement::init_1_1(
85     const sp<V1_1::ISecureElementHalCallback>& clientCallback) {
86   ESESTATUS status = ESESTATUS_SUCCESS;
87 
88   if (clientCallback == nullptr) {
89     return Void();
90   } else {
91     mCallbackV1_1 = clientCallback;
92     mCallbackV1_0 = nullptr;
93     if (!mCallbackV1_1->linkToDeath(this, 0 /*cookie*/)) {
94       ALOGE("%s: Failed to register death notification", __func__);
95     }
96   }
97   if (isSeInitialized()) {
98     clientCallback->onStateChange_1_1(true, "NXP SE HAL init ok");
99     return Void();
100   }
101 
102   status = seHalInit();
103   if (status != ESESTATUS_SUCCESS) {
104     clientCallback->onStateChange_1_1(false, "NXP SE HAL init failed");
105     return Void();
106   }
107 
108   LSCSTATUS lsStatus = LSC_doDownload(onLSCompleted, (void*)this);
109   /*
110    * LSC_doDownload returns LSCSTATUS_FAILED in case thread creation fails.
111    * So return callback as false.
112    * Otherwise callback will be called in LSDownload module.
113    */
114   if (lsStatus != LSCSTATUS_SUCCESS) {
115     ALOGE("%s: LSDownload thread creation failed!!!", __func__);
116     SecureElementStatus sestatus = seHalDeInit();
117     if (sestatus != SecureElementStatus::SUCCESS) {
118       ALOGE("%s: seHalDeInit failed!!!", __func__);
119     }
120     clientCallback->onStateChange_1_1(false,
121                                       "Failed to create LS download thread");
122   }
123   return Void();
124 }
125 
getAtr(getAtr_cb _hidl_cb)126 Return<void> SecureElement::getAtr(getAtr_cb _hidl_cb) {
127   hidl_vec<uint8_t> response;
128   _hidl_cb(response);
129   return Void();
130 }
131 
isCardPresent()132 Return<bool> SecureElement::isCardPresent() { return true; }
133 
transmit(const hidl_vec<uint8_t> & data,transmit_cb _hidl_cb)134 Return<void> SecureElement::transmit(const hidl_vec<uint8_t>& data,
135                                      transmit_cb _hidl_cb) {
136   ESESTATUS status = ESESTATUS_FAILED;
137   phNxpEse_data cmdApdu;
138   phNxpEse_data rspApdu;
139   phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
140   phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
141 
142   cmdApdu.len = data.size();
143   if (cmdApdu.len >= MIN_APDU_LENGTH) {
144     cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
145     memcpy(cmdApdu.p_data, data.data(), cmdApdu.len);
146     status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
147   }
148 
149   hidl_vec<uint8_t> result;
150   if (status != ESESTATUS_SUCCESS) {
151     ALOGE("%s: transmit failed!!!", __func__);
152   } else {
153     result.resize(rspApdu.len);
154     memcpy(&result[0], rspApdu.p_data, rspApdu.len);
155   }
156   _hidl_cb(result);
157   phNxpEse_free(cmdApdu.p_data);
158   phNxpEse_free(rspApdu.p_data);
159   return Void();
160 }
161 
openLogicalChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openLogicalChannel_cb _hidl_cb)162 Return<void> SecureElement::openLogicalChannel(const hidl_vec<uint8_t>& aid,
163                                                uint8_t p2,
164                                                openLogicalChannel_cb _hidl_cb) {
165   hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
166 
167   LogicalChannelResponse resApduBuff;
168   resApduBuff.channelNumber = 0xff;
169   memset(&resApduBuff, 0x00, sizeof(resApduBuff));
170   if (aid.size() > MAX_AID_LENGTH) {
171     ALOGE("%s: AID out of range!!!", __func__);
172     _hidl_cb(resApduBuff, SecureElementStatus::FAILED);
173     return Void();
174   }
175 
176   if (!isSeInitialized()) {
177     ESESTATUS status = seHalInit();
178     if (status != ESESTATUS_SUCCESS) {
179       ALOGE("%s: seHalInit Failed!!!", __func__);
180       _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
181       return Void();
182     }
183   }
184 
185   SecureElementStatus sestatus = SecureElementStatus::IOERROR;
186   ESESTATUS status = ESESTATUS_FAILED;
187   phNxpEse_data cmdApdu;
188   phNxpEse_data rspApdu;
189 
190   phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
191   phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
192 
193   cmdApdu.len = manageChannelCommand.size();
194   cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
195                                                sizeof(uint8_t));
196   if (cmdApdu.p_data != NULL) {
197     memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
198     status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
199   }
200   if (status != ESESTATUS_SUCCESS) {
201     /*Transceive failed*/
202     sestatus = SecureElementStatus::IOERROR;
203   } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
204              rspApdu.p_data[rspApdu.len - 1] == 0x00) {
205     /*ManageChannel successful*/
206     resApduBuff.channelNumber = rspApdu.p_data[0];
207     mOpenedchannelCount++;
208     mOpenedChannels[resApduBuff.channelNumber] = true;
209     sestatus = SecureElementStatus::SUCCESS;
210   } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
211              rspApdu.p_data[rspApdu.len - 1] == 0x81) {
212     sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
213   } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
214               (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
215              rspApdu.p_data[rspApdu.len - 1] == 0x00) {
216     sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
217   }
218 
219   /*Free the allocations*/
220   phNxpEse_free(cmdApdu.p_data);
221   phNxpEse_free(rspApdu.p_data);
222 
223   if (sestatus != SecureElementStatus::SUCCESS) {
224     /*If first logical channel open fails, DeInit SE*/
225     if (isSeInitialized() && (mOpenedchannelCount == 0)) {
226       SecureElementStatus deInitStatus = seHalDeInit();
227       if (deInitStatus != SecureElementStatus::SUCCESS) {
228         ALOGE("%s: seDeInit Failed", __func__);
229       }
230     }
231     /*If manageChanle is failed in any of above cases
232     send the callback and return*/
233     _hidl_cb(resApduBuff, sestatus);
234     return Void();
235   }
236 
237   ALOGD_IF(ese_debug_enabled, "%s: Sending selectApdu", __func__);
238   /*Reset variables if manageChannel is success*/
239   sestatus = SecureElementStatus::IOERROR;
240   status = ESESTATUS_FAILED;
241 
242   phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
243   phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
244 
245   cmdApdu.len = (int32_t)(5 + aid.size());
246   cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
247   if (cmdApdu.p_data != NULL) {
248     uint8_t xx = 0;
249     cmdApdu.p_data[xx++] = resApduBuff.channelNumber;
250     cmdApdu.p_data[xx++] = 0xA4;        // INS
251     cmdApdu.p_data[xx++] = 0x04;        // P1
252     cmdApdu.p_data[xx++] = p2;          // P2
253     cmdApdu.p_data[xx++] = aid.size();  // Lc
254     memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
255 
256     status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
257   }
258 
259   if (status != ESESTATUS_SUCCESS) {
260     /*Transceive failed*/
261     sestatus = SecureElementStatus::IOERROR;
262   } else {
263     uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
264     uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
265     /*Return response on success, empty vector on failure*/
266     /*Status is success*/
267     if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
268       /*Copy the response including status word*/
269       resApduBuff.selectResponse.resize(rspApdu.len);
270       memcpy(&resApduBuff.selectResponse[0], rspApdu.p_data, rspApdu.len);
271       sestatus = SecureElementStatus::SUCCESS;
272     }
273     /*AID provided doesn't match any applet on the secure element*/
274     else if ((sw1 == 0x6A && sw2 == 0x82) ||
275              (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
276       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
277     }
278     /*Operation provided by the P2 parameter is not permitted by the applet.*/
279     else if (sw1 == 0x6A && sw2 == 0x86) {
280       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
281     }
282   }
283 
284   if (sestatus != SecureElementStatus::SUCCESS) {
285     SecureElementStatus closeChannelStatus =
286         closeChannel(resApduBuff.channelNumber);
287     if (closeChannelStatus != SecureElementStatus::SUCCESS) {
288       ALOGE("%s: closeChannel Failed", __func__);
289     } else {
290       resApduBuff.channelNumber = 0xff;
291     }
292   }
293   _hidl_cb(resApduBuff, sestatus);
294   phNxpEse_free(cmdApdu.p_data);
295   phNxpEse_free(rspApdu.p_data);
296 
297   return Void();
298 }
299 
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)300 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
301                                              uint8_t p2,
302                                              openBasicChannel_cb _hidl_cb) {
303   hidl_vec<uint8_t> result;
304   if (aid.size() > MAX_AID_LENGTH) {
305     ALOGE("%s: AID out of range!!!", __func__);
306     _hidl_cb(result, SecureElementStatus::FAILED);
307     return Void();
308   }
309 
310   if (!isSeInitialized()) {
311     ESESTATUS status = seHalInit();
312     if (status != ESESTATUS_SUCCESS) {
313       ALOGE("%s: seHalInit Failed!!!", __func__);
314       _hidl_cb(result, SecureElementStatus::IOERROR);
315       return Void();
316     }
317   }
318 
319   SecureElementStatus sestatus = SecureElementStatus::IOERROR;
320   ESESTATUS status = ESESTATUS_FAILED;
321   phNxpEse_data cmdApdu;
322   phNxpEse_data rspApdu;
323 
324   phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
325   phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
326 
327   cmdApdu.len = (int32_t)(5 + aid.size());
328   cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
329   if (cmdApdu.p_data != NULL) {
330     uint8_t xx = 0;
331     cmdApdu.p_data[xx++] = 0x00;        // basic channel
332     cmdApdu.p_data[xx++] = 0xA4;        // INS
333     cmdApdu.p_data[xx++] = 0x04;        // P1
334     cmdApdu.p_data[xx++] = p2;          // P2
335     cmdApdu.p_data[xx++] = aid.size();  // Lc
336     memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
337 
338     status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
339   }
340 
341   if (status != ESESTATUS_SUCCESS) {
342     /* Transceive failed */
343     sestatus = SecureElementStatus::IOERROR;
344   } else {
345     uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
346     uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
347     /*Return response on success, empty vector on failure*/
348     /*Status is success*/
349     if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
350       /*Copy the response including status word*/
351       result.resize(rspApdu.len);
352       memcpy(&result[0], rspApdu.p_data, rspApdu.len);
353       /*Set basic channel reference if it is not set */
354       if (!mOpenedChannels[0]) {
355         mOpenedChannels[0] = true;
356         mOpenedchannelCount++;
357       }
358       sestatus = SecureElementStatus::SUCCESS;
359     }
360     /*AID provided doesn't match any applet on the secure element*/
361     else if ((sw1 == 0x6A && sw2 == 0x82) ||
362              (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
363       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
364     }
365     /*Operation provided by the P2 parameter is not permitted by the applet.*/
366     else if (sw1 == 0x6A && sw2 == 0x86) {
367       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
368     }
369   }
370 
371   if (sestatus != SecureElementStatus::SUCCESS) {
372     SecureElementStatus closeStatus = SecureElementStatus::IOERROR;
373     /*If first basic channel open fails, DeInit SE*/
374     if ((mOpenedChannels[DEFAULT_BASIC_CHANNEL] == false) &&
375         (mOpenedchannelCount == 0)) {
376       closeStatus = seHalDeInit();
377     } else {
378       closeStatus = closeChannel(DEFAULT_BASIC_CHANNEL);
379     }
380     if (closeStatus != SecureElementStatus::SUCCESS) {
381       ALOGE("%s: close Failed", __func__);
382     }
383   }
384   _hidl_cb(result, sestatus);
385   phNxpEse_free(cmdApdu.p_data);
386   phNxpEse_free(rspApdu.p_data);
387   return Void();
388 }
389 
closeChannel(uint8_t channelNumber)390 Return<SecureElementStatus> SecureElement::closeChannel(uint8_t channelNumber) {
391   ESESTATUS status = ESESTATUS_FAILED;
392   SecureElementStatus sestatus = SecureElementStatus::FAILED;
393 
394   phNxpEse_data cmdApdu;
395   phNxpEse_data rspApdu;
396 
397   if ((channelNumber >= MAX_LOGICAL_CHANNELS) ||
398       (mOpenedChannels[channelNumber] == false)) {
399     ALOGE("%s: invalid channel!!!", __func__);
400     sestatus = SecureElementStatus::FAILED;
401   } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
402     phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
403     phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
404     cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(5 * sizeof(uint8_t));
405     if (cmdApdu.p_data != NULL) {
406       uint8_t xx = 0;
407 
408       cmdApdu.p_data[xx++] = channelNumber;
409       cmdApdu.p_data[xx++] = 0x70;           // INS
410       cmdApdu.p_data[xx++] = 0x80;           // P1
411       cmdApdu.p_data[xx++] = channelNumber;  // P2
412       cmdApdu.p_data[xx++] = 0x00;           // Lc
413       cmdApdu.len = xx;
414 
415       status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
416     }
417     if (status != ESESTATUS_SUCCESS) {
418       sestatus = SecureElementStatus::FAILED;
419     } else if ((rspApdu.p_data[rspApdu.len - 2] == 0x90) &&
420                (rspApdu.p_data[rspApdu.len - 1] == 0x00)) {
421       sestatus = SecureElementStatus::SUCCESS;
422     } else {
423       sestatus = SecureElementStatus::FAILED;
424     }
425     phNxpEse_free(cmdApdu.p_data);
426     phNxpEse_free(rspApdu.p_data);
427   }
428 
429   if (mOpenedChannels[channelNumber] != false) mOpenedchannelCount--;
430   mOpenedChannels[channelNumber] = false;
431   /*If there are no channels remaining close secureElement*/
432   if (mOpenedchannelCount == 0) {
433     sestatus = seHalDeInit();
434   } else {
435     sestatus = SecureElementStatus::SUCCESS;
436   }
437   return sestatus;
438 }
439 
serviceDied(uint64_t,const wp<IBase> &)440 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
441   ALOGE("%s: SecureElement serviceDied!!!", __func__);
442   SecureElementStatus sestatus = seHalDeInit();
443   if (sestatus != SecureElementStatus::SUCCESS) {
444     ALOGE("%s: seHalDeInit Faliled!!!", __func__);
445   }
446   if (mCallbackV1_0 != nullptr) {
447     mCallbackV1_0->unlinkToDeath(this);
448     mCallbackV1_0 = nullptr;
449   }
450   if (mCallbackV1_1 != nullptr) {
451     mCallbackV1_1->unlinkToDeath(this);
452     mCallbackV1_1 = nullptr;
453   }
454 }
455 
isSeInitialized()456 bool SecureElement::isSeInitialized() { return phNxpEse_isOpen(); }
457 
seHalInit()458 ESESTATUS SecureElement::seHalInit() {
459   ESESTATUS status = ESESTATUS_SUCCESS;
460   phNxpEse_initParams initParams;
461   memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
462   initParams.initMode = ESE_MODE_NORMAL;
463 
464   status = phNxpEse_open(initParams);
465   if (status != ESESTATUS_SUCCESS) {
466     ALOGE("%s: SecureElement open failed!!!", __func__);
467   } else {
468     status = phNxpEse_init(initParams);
469     if (status != ESESTATUS_SUCCESS) {
470       ALOGE("%s: SecureElement init failed!!!", __func__);
471     }
472   }
473   return status;
474 }
475 
seHalDeInit()476 Return<SecureElementStatus> SecureElement::seHalDeInit() {
477   ESESTATUS status = ESESTATUS_SUCCESS;
478   SecureElementStatus sestatus = SecureElementStatus::FAILED;
479   status = phNxpEse_deInit();
480   if (status != ESESTATUS_SUCCESS) {
481     sestatus = SecureElementStatus::FAILED;
482   } else {
483     status = phNxpEse_close();
484     if (status != ESESTATUS_SUCCESS) {
485       sestatus = SecureElementStatus::FAILED;
486     } else {
487       sestatus = SecureElementStatus::SUCCESS;
488 
489       for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
490         mOpenedChannels[xx] = false;
491       }
492       mOpenedchannelCount = 0;
493     }
494   }
495   return sestatus;
496 }
497 
onStateChange(bool result,std::string reason)498 void SecureElement::onStateChange(bool result, std::string reason) {
499   ALOGD("%s: result: %d, reaon= %s", __func__, result, reason.c_str());
500   if (mCallbackV1_1 != nullptr) {
501     mCallbackV1_1->onStateChange_1_1(result, reason);
502   } else if (mCallbackV1_0 != nullptr) {
503     mCallbackV1_0->onStateChange(result);
504   }
505 }
506 
507 }  // namespace implementation
508 }  // namespace V1_1
509 }  // namespace secure_element
510 }  // namespace hardware
511 }  // namespace android
512