• 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) {
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       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
230     }
231     /*Operation provided by the P2 parameter is not permitted by the applet.*/
232     else if (sw1 == 0x6A && sw2 == 0x86) {
233       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
234     }
235   }
236 
237   if (sestatus != SecureElementStatus::SUCCESS) {
238     SecureElementStatus closeChannelStatus =
239         closeChannel(resApduBuff.channelNumber);
240     if (closeChannelStatus != SecureElementStatus::SUCCESS) {
241       ALOGE("%s: closeChannel Failed", __func__);
242     } else {
243       resApduBuff.channelNumber = 0xff;
244     }
245   }
246   _hidl_cb(resApduBuff, sestatus);
247   phNxpEse_free(cmdApdu.p_data);
248   phNxpEse_free(rspApdu.p_data);
249 
250   return Void();
251 }
252 
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)253 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
254                                              uint8_t p2,
255                                              openBasicChannel_cb _hidl_cb) {
256   hidl_vec<uint8_t> result;
257 
258   if (!isSeInitialized()) {
259     ESESTATUS status = seHalInit();
260     if (status != ESESTATUS_SUCCESS) {
261       ALOGE("%s: seHalInit Failed!!!", __func__);
262       _hidl_cb(result, SecureElementStatus::IOERROR);
263       return Void();
264     }
265   }
266 
267   SecureElementStatus sestatus = SecureElementStatus::IOERROR;
268   ESESTATUS status = ESESTATUS_FAILED;
269   phNxpEse_data cmdApdu;
270   phNxpEse_data rspApdu;
271 
272   phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
273   phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
274 
275   cmdApdu.len = (int32_t)(5 + aid.size());
276   cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
277   if (cmdApdu.p_data != NULL) {
278     uint8_t xx = 0;
279     cmdApdu.p_data[xx++] = 0x00;        // basic channel
280     cmdApdu.p_data[xx++] = 0xA4;        // INS
281     cmdApdu.p_data[xx++] = 0x04;        // P1
282     cmdApdu.p_data[xx++] = p2;          // P2
283     cmdApdu.p_data[xx++] = aid.size();  // Lc
284     memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
285 
286     status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
287   }
288 
289   if (status != ESESTATUS_SUCCESS) {
290     /* Transceive failed */
291     sestatus = SecureElementStatus::IOERROR;
292   } else {
293     uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
294     uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
295     /*Return response on success, empty vector on failure*/
296     /*Status is success*/
297     if ((sw1 == 0x90) && (sw2 == 0x00)) {
298       /*Copy the response including status word*/
299       result.resize(rspApdu.len);
300       memcpy(&result[0], rspApdu.p_data, rspApdu.len);
301       /*Set basic channel reference if it is not set */
302       if (!mOpenedChannels[0]) {
303         mOpenedChannels[0] = true;
304         mOpenedchannelCount++;
305       }
306       sestatus = SecureElementStatus::SUCCESS;
307     }
308     /*AID provided doesn't match any applet on the secure element*/
309     else if (sw1 == 0x6A && sw2 == 0x82) {
310       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
311     }
312     /*Operation provided by the P2 parameter is not permitted by the applet.*/
313     else if (sw1 == 0x6A && sw2 == 0x86) {
314       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
315     }
316   }
317 
318   if (sestatus != SecureElementStatus::SUCCESS) {
319     SecureElementStatus closeStatus = SecureElementStatus::IOERROR;
320     /*If first basic channel open fails, DeInit SE*/
321     if ((mOpenedChannels[DEFAULT_BASIC_CHANNEL] == false) &&
322         (mOpenedchannelCount == 0)) {
323       closeStatus = seHalDeInit();
324     } else {
325       closeStatus = closeChannel(DEFAULT_BASIC_CHANNEL);
326     }
327     if (closeStatus != SecureElementStatus::SUCCESS) {
328       ALOGE("%s: close Failed", __func__);
329     }
330   }
331   _hidl_cb(result, sestatus);
332   phNxpEse_free(cmdApdu.p_data);
333   phNxpEse_free(rspApdu.p_data);
334   return Void();
335 }
336 
337 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
closeChannel(uint8_t channelNumber)338 SecureElement::closeChannel(uint8_t channelNumber) {
339   ESESTATUS status = ESESTATUS_FAILED;
340   SecureElementStatus sestatus = SecureElementStatus::FAILED;
341 
342   phNxpEse_data cmdApdu;
343   phNxpEse_data rspApdu;
344 
345   if ((channelNumber < DEFAULT_BASIC_CHANNEL) ||
346       (channelNumber >= MAX_LOGICAL_CHANNELS) ||
347       (mOpenedChannels[channelNumber] == false)) {
348     ALOGE("%s: invalid channel!!!", __func__);
349     sestatus = SecureElementStatus::FAILED;
350   } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
351     phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
352     phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
353     cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(5 * sizeof(uint8_t));
354     if (cmdApdu.p_data != NULL) {
355       uint8_t xx = 0;
356 
357       cmdApdu.p_data[xx++] = channelNumber;
358       cmdApdu.p_data[xx++] = 0x70;           // INS
359       cmdApdu.p_data[xx++] = 0x80;           // P1
360       cmdApdu.p_data[xx++] = channelNumber;  // P2
361       cmdApdu.p_data[xx++] = 0x00;           // Lc
362       cmdApdu.len = xx;
363 
364       status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
365     }
366     if (status != ESESTATUS_SUCCESS) {
367       sestatus = SecureElementStatus::FAILED;
368     } else if ((rspApdu.p_data[rspApdu.len - 2] == 0x90) &&
369                (rspApdu.p_data[rspApdu.len - 1] == 0x00)) {
370       sestatus = SecureElementStatus::SUCCESS;
371     } else {
372       sestatus = SecureElementStatus::FAILED;
373     }
374     phNxpEse_free(cmdApdu.p_data);
375     phNxpEse_free(rspApdu.p_data);
376   }
377 
378   if ((channelNumber == DEFAULT_BASIC_CHANNEL) ||
379       (sestatus == SecureElementStatus::SUCCESS)) {
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   }
389   return sestatus;
390 }
391 
serviceDied(uint64_t,const wp<IBase> &)392 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
393   ALOGE("%s: SecureElement serviceDied!!!", __func__);
394   SecureElementStatus sestatus = seHalDeInit();
395   if (sestatus != SecureElementStatus::SUCCESS) {
396     ALOGE("%s: seHalDeInit Faliled!!!", __func__);
397   }
398   if (mCallbackV1_0 != nullptr) {
399     mCallbackV1_0->unlinkToDeath(this);
400   }
401 }
402 
isSeInitialized()403 bool SecureElement::isSeInitialized() { return phNxpEse_isOpen(); }
404 
seHalInit()405 ESESTATUS SecureElement::seHalInit() {
406   ESESTATUS status = ESESTATUS_SUCCESS;
407   phNxpEse_initParams initParams;
408   memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
409   initParams.initMode = ESE_MODE_NORMAL;
410 
411   status = phNxpEse_open(initParams);
412   if (status != ESESTATUS_SUCCESS) {
413     ALOGE("%s: SecureElement open failed!!!", __func__);
414   } else {
415     status = phNxpEse_init(initParams);
416     if (status != ESESTATUS_SUCCESS) {
417       ALOGE("%s: SecureElement init failed!!!", __func__);
418     }
419   }
420   return status;
421 }
422 
423 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
seHalDeInit()424 SecureElement::seHalDeInit() {
425   ESESTATUS status = ESESTATUS_SUCCESS;
426   SecureElementStatus sestatus = SecureElementStatus::FAILED;
427   status = phNxpEse_deInit();
428   if (status != ESESTATUS_SUCCESS) {
429     sestatus = SecureElementStatus::FAILED;
430   } else {
431     status = phNxpEse_close();
432     if (status != ESESTATUS_SUCCESS) {
433       sestatus = SecureElementStatus::FAILED;
434     } else {
435       sestatus = SecureElementStatus::SUCCESS;
436 
437       for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
438         mOpenedChannels[xx] = false;
439       }
440       mOpenedchannelCount = 0;
441     }
442   }
443   return sestatus;
444 }
445 
onStateChange(bool result,std::string reason)446 void SecureElement::onStateChange(bool result, std::string reason) {
447   ALOGD("%s: result: %d, reaon= %s", __func__, result, reason.c_str());
448   mCallbackV1_0->onStateChange(result);
449 }
450 
451 }  // namespace implementation
452 }  // namespace V1_0
453 }  // namespace secure_element
454 }  // namespace hardware
455 }  // namespace android
456