1 /******************************************************************************
2 *
3 * Copyright 2018,2023 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 if (aid.size() > MAX_AID_LENGTH) {
171 ALOGE("%s: AID out of range!!!", __func__);
172 _hidl_cb(resApduBuff, SecureElementStatus::FAILED);
173 return Void();
174 }
175
176 if (!isSeInitialized()) {
177 ESESTATUS status = seHalInit();
178 if (status != ESESTATUS_SUCCESS) {
179 ALOGE("%s: seHalInit Failed!!!", __func__);
180 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
181 return Void();
182 }
183 }
184
185 SecureElementStatus sestatus = SecureElementStatus::IOERROR;
186 ESESTATUS status = ESESTATUS_FAILED;
187 phNxpEse_data cmdApdu;
188 phNxpEse_data rspApdu;
189
190 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
191 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
192
193 cmdApdu.len = manageChannelCommand.size();
194 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
195 sizeof(uint8_t));
196 if (cmdApdu.p_data != NULL) {
197 memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
198 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
199 }
200 if (status != ESESTATUS_SUCCESS) {
201 /*Transceive failed*/
202 sestatus = SecureElementStatus::IOERROR;
203 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
204 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
205 /*ManageChannel successful*/
206 resApduBuff.channelNumber = rspApdu.p_data[0];
207 mOpenedchannelCount++;
208 mOpenedChannels[resApduBuff.channelNumber] = true;
209 sestatus = SecureElementStatus::SUCCESS;
210 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
211 rspApdu.p_data[rspApdu.len - 1] == 0x81) {
212 sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
213 } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
214 (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
215 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
216 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
217 }
218
219 /*Free the allocations*/
220 phNxpEse_free(cmdApdu.p_data);
221 phNxpEse_free(rspApdu.p_data);
222
223 if (sestatus != SecureElementStatus::SUCCESS) {
224 /*If first logical channel open fails, DeInit SE*/
225 if (isSeInitialized() && (mOpenedchannelCount == 0)) {
226 SecureElementStatus deInitStatus = seHalDeInit();
227 if (deInitStatus != SecureElementStatus::SUCCESS) {
228 ALOGE("%s: seDeInit Failed", __func__);
229 }
230 }
231 /*If manageChanle is failed in any of above cases
232 send the callback and return*/
233 _hidl_cb(resApduBuff, sestatus);
234 return Void();
235 }
236
237 ALOGD_IF(ese_debug_enabled, "%s: Sending selectApdu", __func__);
238 /*Reset variables if manageChannel is success*/
239 sestatus = SecureElementStatus::IOERROR;
240 status = ESESTATUS_FAILED;
241
242 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
243 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
244
245 cmdApdu.len = (int32_t)(5 + aid.size());
246 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
247 if (cmdApdu.p_data != NULL) {
248 uint8_t xx = 0;
249 cmdApdu.p_data[xx++] = resApduBuff.channelNumber;
250 cmdApdu.p_data[xx++] = 0xA4; // INS
251 cmdApdu.p_data[xx++] = 0x04; // P1
252 cmdApdu.p_data[xx++] = p2; // P2
253 cmdApdu.p_data[xx++] = aid.size(); // Lc
254 memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
255
256 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
257 }
258
259 if (status != ESESTATUS_SUCCESS) {
260 /*Transceive failed*/
261 sestatus = SecureElementStatus::IOERROR;
262 } else {
263 uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
264 uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
265 /*Return response on success, empty vector on failure*/
266 /*Status is success*/
267 if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
268 /*Copy the response including status word*/
269 resApduBuff.selectResponse.resize(rspApdu.len);
270 memcpy(&resApduBuff.selectResponse[0], rspApdu.p_data, rspApdu.len);
271 sestatus = SecureElementStatus::SUCCESS;
272 }
273 /*AID provided doesn't match any applet on the secure element*/
274 else if ((sw1 == 0x6A && sw2 == 0x82) ||
275 (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
276 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
277 }
278 /*Operation provided by the P2 parameter is not permitted by the applet.*/
279 else if (sw1 == 0x6A && sw2 == 0x86) {
280 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
281 }
282 }
283
284 if (sestatus != SecureElementStatus::SUCCESS) {
285 SecureElementStatus closeChannelStatus =
286 closeChannel(resApduBuff.channelNumber);
287 if (closeChannelStatus != SecureElementStatus::SUCCESS) {
288 ALOGE("%s: closeChannel Failed", __func__);
289 } else {
290 resApduBuff.channelNumber = 0xff;
291 }
292 }
293 _hidl_cb(resApduBuff, sestatus);
294 phNxpEse_free(cmdApdu.p_data);
295 phNxpEse_free(rspApdu.p_data);
296
297 return Void();
298 }
299
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)300 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
301 uint8_t p2,
302 openBasicChannel_cb _hidl_cb) {
303 hidl_vec<uint8_t> result;
304 if (aid.size() > MAX_AID_LENGTH) {
305 ALOGE("%s: AID out of range!!!", __func__);
306 _hidl_cb(result, SecureElementStatus::FAILED);
307 return Void();
308 }
309
310 if (!isSeInitialized()) {
311 ESESTATUS status = seHalInit();
312 if (status != ESESTATUS_SUCCESS) {
313 ALOGE("%s: seHalInit Failed!!!", __func__);
314 _hidl_cb(result, SecureElementStatus::IOERROR);
315 return Void();
316 }
317 }
318
319 SecureElementStatus sestatus = SecureElementStatus::IOERROR;
320 ESESTATUS status = ESESTATUS_FAILED;
321 phNxpEse_data cmdApdu;
322 phNxpEse_data rspApdu;
323
324 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
325 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
326
327 cmdApdu.len = (int32_t)(5 + aid.size());
328 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
329 if (cmdApdu.p_data != NULL) {
330 uint8_t xx = 0;
331 cmdApdu.p_data[xx++] = 0x00; // basic channel
332 cmdApdu.p_data[xx++] = 0xA4; // INS
333 cmdApdu.p_data[xx++] = 0x04; // P1
334 cmdApdu.p_data[xx++] = p2; // P2
335 cmdApdu.p_data[xx++] = aid.size(); // Lc
336 memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
337
338 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
339 }
340
341 if (status != ESESTATUS_SUCCESS) {
342 /* Transceive failed */
343 sestatus = SecureElementStatus::IOERROR;
344 } else {
345 uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
346 uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
347 /*Return response on success, empty vector on failure*/
348 /*Status is success*/
349 if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
350 /*Copy the response including status word*/
351 result.resize(rspApdu.len);
352 memcpy(&result[0], rspApdu.p_data, rspApdu.len);
353 /*Set basic channel reference if it is not set */
354 if (!mOpenedChannels[0]) {
355 mOpenedChannels[0] = true;
356 mOpenedchannelCount++;
357 }
358 sestatus = SecureElementStatus::SUCCESS;
359 }
360 /*AID provided doesn't match any applet on the secure element*/
361 else if ((sw1 == 0x6A && sw2 == 0x82) ||
362 (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
363 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
364 }
365 /*Operation provided by the P2 parameter is not permitted by the applet.*/
366 else if (sw1 == 0x6A && sw2 == 0x86) {
367 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
368 }
369 }
370
371 if (sestatus != SecureElementStatus::SUCCESS) {
372 SecureElementStatus closeStatus = SecureElementStatus::IOERROR;
373 /*If first basic channel open fails, DeInit SE*/
374 if ((mOpenedChannels[DEFAULT_BASIC_CHANNEL] == false) &&
375 (mOpenedchannelCount == 0)) {
376 closeStatus = seHalDeInit();
377 } else {
378 closeStatus = closeChannel(DEFAULT_BASIC_CHANNEL);
379 }
380 if (closeStatus != SecureElementStatus::SUCCESS) {
381 ALOGE("%s: close Failed", __func__);
382 }
383 }
384 _hidl_cb(result, sestatus);
385 phNxpEse_free(cmdApdu.p_data);
386 phNxpEse_free(rspApdu.p_data);
387 return Void();
388 }
389
closeChannel(uint8_t channelNumber)390 Return<SecureElementStatus> SecureElement::closeChannel(uint8_t channelNumber) {
391 ESESTATUS status = ESESTATUS_FAILED;
392 SecureElementStatus sestatus = SecureElementStatus::FAILED;
393
394 phNxpEse_data cmdApdu;
395 phNxpEse_data rspApdu;
396
397 if ((channelNumber >= MAX_LOGICAL_CHANNELS) ||
398 (mOpenedChannels[channelNumber] == false)) {
399 ALOGE("%s: invalid channel!!!", __func__);
400 sestatus = SecureElementStatus::FAILED;
401 } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
402 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
403 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
404 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(5 * sizeof(uint8_t));
405 if (cmdApdu.p_data != NULL) {
406 uint8_t xx = 0;
407
408 cmdApdu.p_data[xx++] = channelNumber;
409 cmdApdu.p_data[xx++] = 0x70; // INS
410 cmdApdu.p_data[xx++] = 0x80; // P1
411 cmdApdu.p_data[xx++] = channelNumber; // P2
412 cmdApdu.p_data[xx++] = 0x00; // Lc
413 cmdApdu.len = xx;
414
415 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
416 }
417 if (status != ESESTATUS_SUCCESS) {
418 sestatus = SecureElementStatus::FAILED;
419 } else if ((rspApdu.p_data[rspApdu.len - 2] == 0x90) &&
420 (rspApdu.p_data[rspApdu.len - 1] == 0x00)) {
421 sestatus = SecureElementStatus::SUCCESS;
422 } else {
423 sestatus = SecureElementStatus::FAILED;
424 }
425 phNxpEse_free(cmdApdu.p_data);
426 phNxpEse_free(rspApdu.p_data);
427 }
428
429 if (mOpenedChannels[channelNumber] != false) mOpenedchannelCount--;
430 mOpenedChannels[channelNumber] = false;
431 /*If there are no channels remaining close secureElement*/
432 if (mOpenedchannelCount == 0) {
433 sestatus = seHalDeInit();
434 } else {
435 sestatus = SecureElementStatus::SUCCESS;
436 }
437 return sestatus;
438 }
439
serviceDied(uint64_t,const wp<IBase> &)440 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
441 ALOGE("%s: SecureElement serviceDied!!!", __func__);
442 SecureElementStatus sestatus = seHalDeInit();
443 if (sestatus != SecureElementStatus::SUCCESS) {
444 ALOGE("%s: seHalDeInit Faliled!!!", __func__);
445 }
446 if (mCallbackV1_0 != nullptr) {
447 mCallbackV1_0->unlinkToDeath(this);
448 mCallbackV1_0 = nullptr;
449 }
450 if (mCallbackV1_1 != nullptr) {
451 mCallbackV1_1->unlinkToDeath(this);
452 mCallbackV1_1 = nullptr;
453 }
454 }
455
isSeInitialized()456 bool SecureElement::isSeInitialized() { return phNxpEse_isOpen(); }
457
seHalInit()458 ESESTATUS SecureElement::seHalInit() {
459 ESESTATUS status = ESESTATUS_SUCCESS;
460 phNxpEse_initParams initParams;
461 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
462 initParams.initMode = ESE_MODE_NORMAL;
463
464 status = phNxpEse_open(initParams);
465 if (status != ESESTATUS_SUCCESS) {
466 ALOGE("%s: SecureElement open failed!!!", __func__);
467 } else {
468 status = phNxpEse_init(initParams);
469 if (status != ESESTATUS_SUCCESS) {
470 ALOGE("%s: SecureElement init failed!!!", __func__);
471 }
472 }
473 return status;
474 }
475
seHalDeInit()476 Return<SecureElementStatus> SecureElement::seHalDeInit() {
477 ESESTATUS status = ESESTATUS_SUCCESS;
478 SecureElementStatus sestatus = SecureElementStatus::FAILED;
479 status = phNxpEse_deInit();
480 if (status != ESESTATUS_SUCCESS) {
481 sestatus = SecureElementStatus::FAILED;
482 } else {
483 status = phNxpEse_close();
484 if (status != ESESTATUS_SUCCESS) {
485 sestatus = SecureElementStatus::FAILED;
486 } else {
487 sestatus = SecureElementStatus::SUCCESS;
488
489 for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
490 mOpenedChannels[xx] = false;
491 }
492 mOpenedchannelCount = 0;
493 }
494 }
495 return sestatus;
496 }
497
onStateChange(bool result,std::string reason)498 void SecureElement::onStateChange(bool result, std::string reason) {
499 ALOGD("%s: result: %d, reaon= %s", __func__, result, reason.c_str());
500 if (mCallbackV1_1 != nullptr) {
501 mCallbackV1_1->onStateChange_1_1(result, reason);
502 } else if (mCallbackV1_0 != nullptr) {
503 mCallbackV1_0->onStateChange(result);
504 }
505 }
506
507 } // namespace implementation
508 } // namespace V1_1
509 } // namespace secure_element
510 } // namespace hardware
511 } // namespace android
512