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