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