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