• 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), 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 
129   if (!isSeInitialized()) {
130     ESESTATUS status = seHalInit();
131     if (status != ESESTATUS_SUCCESS) {
132       ALOGE("%s: seHalInit Failed!!!", __func__);
133       _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
134       return Void();
135     }
136   }
137 
138   SecureElementStatus sestatus = SecureElementStatus::IOERROR;
139   ESESTATUS status = ESESTATUS_FAILED;
140   phNxpEse_data cmdApdu;
141   phNxpEse_data rspApdu;
142 
143   phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
144   phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
145 
146   cmdApdu.len = manageChannelCommand.size();
147   cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
148                                                sizeof(uint8_t));
149   if (cmdApdu.p_data != NULL) {
150     memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
151     status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
152   }
153   if (status != ESESTATUS_SUCCESS) {
154     /*Transceive failed*/
155     sestatus = SecureElementStatus::IOERROR;
156   } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
157              rspApdu.p_data[rspApdu.len - 1] == 0x00) {
158     /*ManageChannel successful*/
159     resApduBuff.channelNumber = rspApdu.p_data[0];
160     mOpenedchannelCount++;
161     mOpenedChannels[resApduBuff.channelNumber] = true;
162     sestatus = SecureElementStatus::SUCCESS;
163   } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
164              rspApdu.p_data[rspApdu.len - 1] == 0x81) {
165     sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
166   } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
167               (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
168              rspApdu.p_data[rspApdu.len - 1] == 0x00) {
169     sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
170   }
171 
172   /*Free the allocations*/
173   phNxpEse_free(cmdApdu.p_data);
174   phNxpEse_free(rspApdu.p_data);
175 
176   if (sestatus != SecureElementStatus::SUCCESS) {
177     /*If first logical channel open fails, DeInit SE*/
178     if (isSeInitialized() && (mOpenedchannelCount == 0)) {
179       SecureElementStatus deInitStatus = seHalDeInit();
180       if (deInitStatus != SecureElementStatus::SUCCESS) {
181         ALOGE("%s: seDeInit Failed", __func__);
182       }
183     }
184     /*If manageChanle is failed in any of above cases
185     send the callback and return*/
186     _hidl_cb(resApduBuff, sestatus);
187     return Void();
188   }
189 
190   ALOGD_IF(ese_debug_enabled, "%s: Sending selectApdu", __func__);
191   /*Reset variables if manageChannel is success*/
192   sestatus = SecureElementStatus::IOERROR;
193   status = ESESTATUS_FAILED;
194 
195   phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
196   phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
197 
198   cmdApdu.len = (int32_t)(5 + aid.size());
199   cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
200   if (cmdApdu.p_data != NULL) {
201     uint8_t xx = 0;
202     cmdApdu.p_data[xx++] = resApduBuff.channelNumber;
203     cmdApdu.p_data[xx++] = 0xA4;        // INS
204     cmdApdu.p_data[xx++] = 0x04;        // P1
205     cmdApdu.p_data[xx++] = p2;          // P2
206     cmdApdu.p_data[xx++] = aid.size();  // Lc
207     memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
208 
209     status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
210   }
211 
212   if (status != ESESTATUS_SUCCESS) {
213     /*Transceive failed*/
214     sestatus = SecureElementStatus::IOERROR;
215   } else {
216     uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
217     uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
218     /*Return response on success, empty vector on failure*/
219     /*Status is success*/
220     if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
221       /*Copy the response including status word*/
222       resApduBuff.selectResponse.resize(rspApdu.len);
223       memcpy(&resApduBuff.selectResponse[0], rspApdu.p_data, rspApdu.len);
224       sestatus = SecureElementStatus::SUCCESS;
225     }
226     /*AID provided doesn't match any applet on the secure element*/
227     else if ((sw1 == 0x6A && sw2 == 0x82) ||
228              (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
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) || (sw1 == 0x62) || (sw1 == 0x63)) {
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              (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
311       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
312     }
313     /*Operation provided by the P2 parameter is not permitted by the applet.*/
314     else if (sw1 == 0x6A && sw2 == 0x86) {
315       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
316     }
317   }
318 
319   if (sestatus != SecureElementStatus::SUCCESS) {
320     SecureElementStatus closeStatus = SecureElementStatus::IOERROR;
321     /*If first basic channel open fails, DeInit SE*/
322     if ((mOpenedChannels[DEFAULT_BASIC_CHANNEL] == false) &&
323         (mOpenedchannelCount == 0)) {
324       closeStatus = seHalDeInit();
325     } else {
326       closeStatus = closeChannel(DEFAULT_BASIC_CHANNEL);
327     }
328     if (closeStatus != SecureElementStatus::SUCCESS) {
329       ALOGE("%s: close Failed", __func__);
330     }
331   }
332   _hidl_cb(result, sestatus);
333   phNxpEse_free(cmdApdu.p_data);
334   phNxpEse_free(rspApdu.p_data);
335   return Void();
336 }
337 
338 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
closeChannel(uint8_t channelNumber)339 SecureElement::closeChannel(uint8_t channelNumber) {
340   ESESTATUS status = ESESTATUS_FAILED;
341   SecureElementStatus sestatus = SecureElementStatus::FAILED;
342 
343   phNxpEse_data cmdApdu;
344   phNxpEse_data rspApdu;
345 
346   if ((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 (mOpenedChannels[channelNumber] != false) mOpenedchannelCount--;
379   mOpenedChannels[channelNumber] = false;
380   /*If there are no channels remaining close secureElement*/
381   if (mOpenedchannelCount == 0) {
382     sestatus = seHalDeInit();
383   } else {
384     sestatus = SecureElementStatus::SUCCESS;
385   }
386   return sestatus;
387 }
388 
serviceDied(uint64_t,const wp<IBase> &)389 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
390   ALOGE("%s: SecureElement serviceDied!!!", __func__);
391   SecureElementStatus sestatus = seHalDeInit();
392   if (sestatus != SecureElementStatus::SUCCESS) {
393     ALOGE("%s: seHalDeInit Faliled!!!", __func__);
394   }
395   if (mCallbackV1_0 != nullptr) {
396     mCallbackV1_0->unlinkToDeath(this);
397   }
398 }
399 
isSeInitialized()400 bool SecureElement::isSeInitialized() { return phNxpEse_isOpen(); }
401 
seHalInit()402 ESESTATUS SecureElement::seHalInit() {
403   ESESTATUS status = ESESTATUS_SUCCESS;
404   phNxpEse_initParams initParams;
405   memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
406   initParams.initMode = ESE_MODE_NORMAL;
407 
408   status = phNxpEse_open(initParams);
409   if (status != ESESTATUS_SUCCESS) {
410     ALOGE("%s: SecureElement open failed!!!", __func__);
411   } else {
412     status = phNxpEse_init(initParams);
413     if (status != ESESTATUS_SUCCESS) {
414       ALOGE("%s: SecureElement init failed!!!", __func__);
415     }
416   }
417   return status;
418 }
419 
420 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
seHalDeInit()421 SecureElement::seHalDeInit() {
422   ESESTATUS status = ESESTATUS_SUCCESS;
423   SecureElementStatus sestatus = SecureElementStatus::FAILED;
424   status = phNxpEse_deInit();
425   if (status != ESESTATUS_SUCCESS) {
426     sestatus = SecureElementStatus::FAILED;
427   } else {
428     status = phNxpEse_close();
429     if (status != ESESTATUS_SUCCESS) {
430       sestatus = SecureElementStatus::FAILED;
431     } else {
432       sestatus = SecureElementStatus::SUCCESS;
433 
434       for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
435         mOpenedChannels[xx] = false;
436       }
437       mOpenedchannelCount = 0;
438     }
439   }
440   return sestatus;
441 }
442 
onStateChange(bool result,std::string reason)443 void SecureElement::onStateChange(bool result, std::string reason) {
444   ALOGD("%s: result: %d, reaon= %s", __func__, result, reason.c_str());
445   mCallbackV1_0->onStateChange(result);
446 }
447 
448 }  // namespace implementation
449 }  // namespace V1_0
450 }  // namespace secure_element
451 }  // namespace hardware
452 }  // namespace android
453