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