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) || (sw1 == 0x62) || (sw1 == 0x63)) {
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 (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
271 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
272 }
273 /*Operation provided by the P2 parameter is not permitted by the applet.*/
274 else if (sw1 == 0x6A && sw2 == 0x86) {
275 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
276 }
277 }
278
279 if (sestatus != SecureElementStatus::SUCCESS) {
280 SecureElementStatus closeChannelStatus =
281 closeChannel(resApduBuff.channelNumber);
282 if (closeChannelStatus != SecureElementStatus::SUCCESS) {
283 ALOGE("%s: closeChannel Failed", __func__);
284 } else {
285 resApduBuff.channelNumber = 0xff;
286 }
287 }
288 _hidl_cb(resApduBuff, sestatus);
289 phNxpEse_free(cmdApdu.p_data);
290 phNxpEse_free(rspApdu.p_data);
291
292 return Void();
293 }
294
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)295 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
296 uint8_t p2,
297 openBasicChannel_cb _hidl_cb) {
298 hidl_vec<uint8_t> result;
299
300 if (!isSeInitialized()) {
301 ESESTATUS status = seHalInit();
302 if (status != ESESTATUS_SUCCESS) {
303 ALOGE("%s: seHalInit Failed!!!", __func__);
304 _hidl_cb(result, SecureElementStatus::IOERROR);
305 return Void();
306 }
307 }
308
309 SecureElementStatus sestatus = SecureElementStatus::IOERROR;
310 ESESTATUS status = ESESTATUS_FAILED;
311 phNxpEse_data cmdApdu;
312 phNxpEse_data rspApdu;
313
314 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
315 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
316
317 cmdApdu.len = (int32_t)(5 + aid.size());
318 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
319 if (cmdApdu.p_data != NULL) {
320 uint8_t xx = 0;
321 cmdApdu.p_data[xx++] = 0x00; // basic channel
322 cmdApdu.p_data[xx++] = 0xA4; // INS
323 cmdApdu.p_data[xx++] = 0x04; // P1
324 cmdApdu.p_data[xx++] = p2; // P2
325 cmdApdu.p_data[xx++] = aid.size(); // Lc
326 memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
327
328 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
329 }
330
331 if (status != ESESTATUS_SUCCESS) {
332 /* Transceive failed */
333 sestatus = SecureElementStatus::IOERROR;
334 } else {
335 uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
336 uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
337 /*Return response on success, empty vector on failure*/
338 /*Status is success*/
339 if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
340 /*Copy the response including status word*/
341 result.resize(rspApdu.len);
342 memcpy(&result[0], rspApdu.p_data, rspApdu.len);
343 /*Set basic channel reference if it is not set */
344 if (!mOpenedChannels[0]) {
345 mOpenedChannels[0] = true;
346 mOpenedchannelCount++;
347 }
348 sestatus = SecureElementStatus::SUCCESS;
349 }
350 /*AID provided doesn't match any applet on the secure element*/
351 else if ((sw1 == 0x6A && sw2 == 0x82) ||
352 (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
353 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
354 }
355 /*Operation provided by the P2 parameter is not permitted by the applet.*/
356 else if (sw1 == 0x6A && sw2 == 0x86) {
357 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
358 }
359 }
360
361 if (sestatus != SecureElementStatus::SUCCESS) {
362 SecureElementStatus closeStatus = SecureElementStatus::IOERROR;
363 /*If first basic channel open fails, DeInit SE*/
364 if ((mOpenedChannels[DEFAULT_BASIC_CHANNEL] == false) &&
365 (mOpenedchannelCount == 0)) {
366 closeStatus = seHalDeInit();
367 } else {
368 closeStatus = closeChannel(DEFAULT_BASIC_CHANNEL);
369 }
370 if (closeStatus != SecureElementStatus::SUCCESS) {
371 ALOGE("%s: close Failed", __func__);
372 }
373 }
374 _hidl_cb(result, sestatus);
375 phNxpEse_free(cmdApdu.p_data);
376 phNxpEse_free(rspApdu.p_data);
377 return Void();
378 }
379
closeChannel(uint8_t channelNumber)380 Return<SecureElementStatus> SecureElement::closeChannel(uint8_t channelNumber) {
381 ESESTATUS status = ESESTATUS_FAILED;
382 SecureElementStatus sestatus = SecureElementStatus::FAILED;
383
384 phNxpEse_data cmdApdu;
385 phNxpEse_data rspApdu;
386
387 if ((channelNumber < DEFAULT_BASIC_CHANNEL) ||
388 (channelNumber >= MAX_LOGICAL_CHANNELS) ||
389 (mOpenedChannels[channelNumber] == false)) {
390 ALOGE("%s: invalid channel!!!", __func__);
391 sestatus = SecureElementStatus::FAILED;
392 } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
393 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
394 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
395 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(5 * sizeof(uint8_t));
396 if (cmdApdu.p_data != NULL) {
397 uint8_t xx = 0;
398
399 cmdApdu.p_data[xx++] = channelNumber;
400 cmdApdu.p_data[xx++] = 0x70; // INS
401 cmdApdu.p_data[xx++] = 0x80; // P1
402 cmdApdu.p_data[xx++] = channelNumber; // P2
403 cmdApdu.p_data[xx++] = 0x00; // Lc
404 cmdApdu.len = xx;
405
406 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
407 }
408 if (status != ESESTATUS_SUCCESS) {
409 sestatus = SecureElementStatus::FAILED;
410 } else if ((rspApdu.p_data[rspApdu.len - 2] == 0x90) &&
411 (rspApdu.p_data[rspApdu.len - 1] == 0x00)) {
412 sestatus = SecureElementStatus::SUCCESS;
413 } else {
414 sestatus = SecureElementStatus::FAILED;
415 }
416 phNxpEse_free(cmdApdu.p_data);
417 phNxpEse_free(rspApdu.p_data);
418 }
419
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 return sestatus;
429 }
430
serviceDied(uint64_t,const wp<IBase> &)431 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
432 ALOGE("%s: SecureElement serviceDied!!!", __func__);
433 SecureElementStatus sestatus = seHalDeInit();
434 if (sestatus != SecureElementStatus::SUCCESS) {
435 ALOGE("%s: seHalDeInit Faliled!!!", __func__);
436 }
437 if (mCallbackV1_0 != nullptr) {
438 mCallbackV1_0->unlinkToDeath(this);
439 mCallbackV1_0 = nullptr;
440 }
441 if (mCallbackV1_1 != nullptr) {
442 mCallbackV1_1->unlinkToDeath(this);
443 mCallbackV1_1 = nullptr;
444 }
445 }
446
isSeInitialized()447 bool SecureElement::isSeInitialized() { return phNxpEse_isOpen(); }
448
seHalInit()449 ESESTATUS SecureElement::seHalInit() {
450 ESESTATUS status = ESESTATUS_SUCCESS;
451 phNxpEse_initParams initParams;
452 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
453 initParams.initMode = ESE_MODE_NORMAL;
454
455 status = phNxpEse_open(initParams);
456 if (status != ESESTATUS_SUCCESS) {
457 ALOGE("%s: SecureElement open failed!!!", __func__);
458 } else {
459 status = phNxpEse_init(initParams);
460 if (status != ESESTATUS_SUCCESS) {
461 ALOGE("%s: SecureElement init failed!!!", __func__);
462 }
463 }
464 return status;
465 }
466
seHalDeInit()467 Return<SecureElementStatus> SecureElement::seHalDeInit() {
468 ESESTATUS status = ESESTATUS_SUCCESS;
469 SecureElementStatus sestatus = SecureElementStatus::FAILED;
470 status = phNxpEse_deInit();
471 if (status != ESESTATUS_SUCCESS) {
472 sestatus = SecureElementStatus::FAILED;
473 } else {
474 status = phNxpEse_close();
475 if (status != ESESTATUS_SUCCESS) {
476 sestatus = SecureElementStatus::FAILED;
477 } else {
478 sestatus = SecureElementStatus::SUCCESS;
479
480 for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
481 mOpenedChannels[xx] = false;
482 }
483 mOpenedchannelCount = 0;
484 }
485 }
486 return sestatus;
487 }
488
onStateChange(bool result,std::string reason)489 void SecureElement::onStateChange(bool result, std::string reason) {
490 ALOGD("%s: result: %d, reaon= %s", __func__, result, reason.c_str());
491 if (mCallbackV1_1 != nullptr) {
492 mCallbackV1_1->onStateChange_1_1(result, reason);
493 } else if (mCallbackV1_0 != nullptr) {
494 mCallbackV1_0->onStateChange(result);
495 }
496 }
497
498 } // namespace implementation
499 } // namespace V1_1
500 } // namespace secure_element
501 } // namespace hardware
502 } // namespace android
503