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
25extern bool ese_debug_enabled;
26
27namespace android {
28namespace hardware {
29namespace secure_element {
30namespace V1_0 {
31namespace implementation {
32
33sp<V1_0::ISecureElementHalCallback> SecureElement::mCallbackV1_0 = nullptr;
34
35SecureElement::SecureElement()
36    : mOpenedchannelCount(0),
37      mOpenedChannels{false, false, false, false} {}
38
39Return<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
81Return<void> SecureElement::getAtr(getAtr_cb _hidl_cb) {
82  hidl_vec<uint8_t> response;
83  _hidl_cb(response);
84  return Void();
85}
86
87Return<bool> SecureElement::isCardPresent() { return true; }
88
89Return<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
117Return<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
242Return<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
320Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
321SecureElement::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
375void 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
386bool SecureElement::isSeInitialized() { return phNxpEse_isOpen(); }
387
388ESESTATUS 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
406Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
407SecureElement::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