1 /******************************************************************************
2 *
3 * Copyright 2018-2020 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 #include "SecureElement.h"
19 #include <android-base/logging.h>
20 #include <android-base/stringprintf.h>
21 #include "NxpEse.h"
22 #include "eSEClient.h"
23 #include "hal_nxpese.h"
24 #include "phNxpEse_Apdu_Api.h"
25 #include "phNxpEse_Api.h"
26 /* Mutex to synchronize multiple transceive */
27
28 namespace android {
29 namespace hardware {
30 namespace secure_element {
31 namespace V1_1 {
32 namespace implementation {
33
34 #define LOG_TAG "nxpese@1.1-service"
35 #define DEFAULT_BASIC_CHANNEL 0x00
36 #define INVALID_LEN_SW1 0x64
37 #define INVALID_LEN_SW2 0xFF
38
39 typedef struct gsTransceiveBuffer {
40 phNxpEse_data cmdData;
41 phNxpEse_data rspData;
42 hidl_vec<uint8_t>* pRspDataBuff;
43 } sTransceiveBuffer_t;
44
45 static sTransceiveBuffer_t gsTxRxBuffer;
46 static hidl_vec<uint8_t> gsRspDataBuff(256);
47 sp<V1_0::ISecureElementHalCallback> SecureElement::mCallbackV1_0 = nullptr;
48 sp<V1_1::ISecureElementHalCallback> SecureElement::mCallbackV1_1 = nullptr;
49 std::vector<bool> SecureElement::mOpenedChannels;
50 using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
SecureElement()51 SecureElement::SecureElement()
52 : mMaxChannelCount(0), mOpenedchannelCount(0), mIsEseInitialized(false) {}
53
NotifySeWaitExtension(phNxpEse_wtxState state)54 void SecureElement::NotifySeWaitExtension(phNxpEse_wtxState state) {
55 if (state == WTX_ONGOING) {
56 LOG(INFO) << "SecureElement::WTX ongoing";
57 } else if (state == WTX_END) {
58 LOG(INFO) << "SecureElement::WTX ended";
59 }
60 }
61
init(const sp<::android::hardware::secure_element::V1_0::ISecureElementHalCallback> & clientCallback)62 Return<void> SecureElement::init(
63 const sp<
64 ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
65 clientCallback) {
66 ESESTATUS status = ESESTATUS_SUCCESS;
67 bool mIsInitDone = false;
68 phNxpEse_initParams initParams;
69 gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
70 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
71 initParams.initMode = ESE_MODE_NORMAL;
72 initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
73 initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
74
75 if (clientCallback == nullptr) {
76 return Void();
77 } else {
78 clientCallback->linkToDeath(this, 0 /*cookie*/);
79 }
80 LOG(INFO) << "SecureElement::init called here";
81 if (ese_update != ESE_UPDATE_COMPLETED) {
82 mCallbackV1_0 = clientCallback;
83 clientCallback->onStateChange(false);
84 LOG(INFO) << "ESE JCOP Download in progress";
85 NxpEse::setSeCallBack(clientCallback);
86 return Void();
87 // Register
88 }
89 if (mIsEseInitialized) {
90 clientCallback->onStateChange(true);
91 return Void();
92 }
93
94 status = phNxpEse_open(initParams);
95 if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
96 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
97 if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
98 ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
99 if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
100 LOG(INFO) << "ESE SPI init complete!!!";
101 mIsInitDone = true;
102 }
103 deInitStatus = phNxpEse_deInit();
104 if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
105 }
106 status = phNxpEse_close(deInitStatus);
107 }
108 if (status == ESESTATUS_SUCCESS && mIsInitDone) {
109 mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
110 mOpenedChannels.resize(mMaxChannelCount, false);
111 clientCallback->onStateChange(true);
112 mCallbackV1_0 = clientCallback;
113 } else {
114 LOG(ERROR) << "eSE-Hal Init failed";
115 clientCallback->onStateChange(false);
116 }
117 return Void();
118 }
119
init_1_1(const sp<::android::hardware::secure_element::V1_1::ISecureElementHalCallback> & clientCallback)120 Return<void> SecureElement::init_1_1(
121 const sp<
122 ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
123 clientCallback) {
124 ESESTATUS status = ESESTATUS_SUCCESS;
125 bool mIsInitDone = false;
126 phNxpEse_initParams initParams;
127 gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
128 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
129 initParams.initMode = ESE_MODE_NORMAL;
130 initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
131 initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
132 if (clientCallback == nullptr) {
133 return Void();
134 } else {
135 clientCallback->linkToDeath(this, 0 /*cookie*/);
136 }
137 LOG(INFO) << "SecureElement::init called here";
138 if (ese_update != ESE_UPDATE_COMPLETED) {
139 mCallbackV1_1 = clientCallback;
140 clientCallback->onStateChange_1_1(false, "NXP SE update going on");
141 LOG(INFO) << "ESE JCOP Download in progress";
142 NxpEse::setSeCallBack_1_1(clientCallback);
143 return Void();
144 // Register
145 }
146 if (mIsEseInitialized) {
147 clientCallback->onStateChange_1_1(true, "NXP SE HAL init ok");
148 return Void();
149 }
150
151 status = phNxpEse_open(initParams);
152 if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
153 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
154 if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
155 ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
156 if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
157 LOG(INFO) << "ESE SPI init complete!!!";
158 mIsInitDone = true;
159 }
160 deInitStatus = phNxpEse_deInit();
161 if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
162 }
163 status = phNxpEse_close(deInitStatus);
164 }
165 if (status == ESESTATUS_SUCCESS && mIsInitDone) {
166 mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
167 mOpenedChannels.resize(mMaxChannelCount, false);
168 clientCallback->onStateChange_1_1(true, "NXP SE HAL init ok");
169 mCallbackV1_1 = clientCallback;
170 } else {
171 LOG(ERROR) << "eSE-Hal Init failed";
172 clientCallback->onStateChange_1_1(false, "NXP SE HAL init failed");
173 }
174 return Void();
175 }
176
getAtr(getAtr_cb _hidl_cb)177 Return<void> SecureElement::getAtr(getAtr_cb _hidl_cb) {
178 AutoMutex guard(seHalLock);
179 LOG(ERROR) << "Processing ATR.....";
180 phNxpEse_data atrData;
181 hidl_vec<uint8_t> response;
182 ESESTATUS status = ESESTATUS_FAILED;
183 bool mIsSeHalInitDone = false;
184
185 if (!mIsEseInitialized) {
186 ESESTATUS status = seHalInit();
187 if (status != ESESTATUS_SUCCESS) {
188 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
189 _hidl_cb(response); /*Return with empty Vector*/
190 return Void();
191 } else {
192 mIsSeHalInitDone = true;
193 }
194 }
195 status = phNxpEse_SetEndPoint_Cntxt(0);
196 if (status != ESESTATUS_SUCCESS) {
197 LOG(ERROR) << "Endpoint set failed";
198 }
199 status = phNxpEse_getAtr(&atrData);
200 if (status != ESESTATUS_SUCCESS) {
201 LOG(ERROR) << "phNxpEse_getAtr failed";
202 _hidl_cb(response); /*Return with empty Vector*/
203 return Void();
204 } else {
205 response.resize(atrData.len);
206 memcpy(&response[0], atrData.p_data, atrData.len);
207 }
208
209 status = phNxpEse_ResetEndPoint_Cntxt(0);
210 if (status != ESESTATUS_SUCCESS) {
211 LOG(ERROR) << "Endpoint set failed";
212 }
213
214 if (status != ESESTATUS_SUCCESS) {
215 LOG(INFO) << StringPrintf("ATR Data[BytebyByte]=Look below for %d bytes",
216 atrData.len);
217 for (auto i = response.begin(); i != response.end(); ++i)
218 LOG(INFO) << StringPrintf("0x%x\t", *i);
219 }
220
221 _hidl_cb(response);
222 if (atrData.p_data != NULL) {
223 phNxpEse_free(atrData.p_data);
224 }
225 if (mIsSeHalInitDone) {
226 if (SecureElementStatus::SUCCESS != seHalDeInit())
227 LOG(ERROR) << "phNxpEse_getAtr seHalDeInit failed";
228 mIsEseInitialized = false;
229 mIsSeHalInitDone = false;
230 }
231 return Void();
232 }
233
isCardPresent()234 Return<bool> SecureElement::isCardPresent() { return true; }
235
transmit(const hidl_vec<uint8_t> & data,transmit_cb _hidl_cb)236 Return<void> SecureElement::transmit(const hidl_vec<uint8_t>& data,
237 transmit_cb _hidl_cb) {
238 AutoMutex guard(seHalLock);
239 ESESTATUS status = ESESTATUS_FAILED;
240 hidl_vec<uint8_t> result;
241 phNxpEse_memset(&gsTxRxBuffer.cmdData, 0x00, sizeof(phNxpEse_data));
242 phNxpEse_memset(&gsTxRxBuffer.rspData, 0x00, sizeof(phNxpEse_data));
243 gsTxRxBuffer.cmdData.len = (uint32_t)data.size();
244 gsTxRxBuffer.cmdData.p_data =
245 (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
246 if (NULL == gsTxRxBuffer.cmdData.p_data) {
247 LOG(ERROR) << "transmit failed to allocate the Memory!!!";
248 /*Return empty hidl_vec*/
249 _hidl_cb(result);
250 return Void();
251 }
252 memcpy(gsTxRxBuffer.cmdData.p_data, data.data(), gsTxRxBuffer.cmdData.len);
253 LOG(INFO) << "Acquired lock for SPI";
254 status = phNxpEse_SetEndPoint_Cntxt(0);
255 if (status != ESESTATUS_SUCCESS) {
256 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
257 }
258 status = phNxpEse_Transceive(&gsTxRxBuffer.cmdData, &gsTxRxBuffer.rspData);
259
260 if (status == ESESTATUS_SUCCESS) {
261 result.resize(gsTxRxBuffer.rspData.len);
262 memcpy(&result[0], gsTxRxBuffer.rspData.p_data, gsTxRxBuffer.rspData.len);
263 } else if (status == ESESTATUS_INVALID_RECEIVE_LENGTH) {
264 uint8_t respBuf[] = {INVALID_LEN_SW1, INVALID_LEN_SW2};
265 result.resize(sizeof(respBuf));
266 memcpy(&result[0], respBuf, sizeof(respBuf));
267 } else {
268 LOG(ERROR) << "transmit failed!!!";
269 }
270 status = phNxpEse_ResetEndPoint_Cntxt(0);
271 if (status != ESESTATUS_SUCCESS) {
272 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
273 }
274
275 _hidl_cb(result);
276 if (NULL != gsTxRxBuffer.cmdData.p_data) {
277 phNxpEse_free(gsTxRxBuffer.cmdData.p_data);
278 gsTxRxBuffer.cmdData.p_data = NULL;
279 }
280 if (NULL != gsTxRxBuffer.rspData.p_data) {
281 phNxpEse_free(gsTxRxBuffer.rspData.p_data);
282 gsTxRxBuffer.rspData.p_data = NULL;
283 }
284
285 return Void();
286 }
287
openLogicalChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openLogicalChannel_cb _hidl_cb)288 Return<void> SecureElement::openLogicalChannel(const hidl_vec<uint8_t>& aid,
289 uint8_t p2,
290 openLogicalChannel_cb _hidl_cb) {
291 AutoMutex guard(seHalLock);
292 hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
293
294 LogicalChannelResponse resApduBuff;
295 resApduBuff.channelNumber = 0xff;
296 memset(&resApduBuff, 0x00, sizeof(resApduBuff));
297
298 LOG(INFO) << "Acquired the lock from SPI openLogicalChannel";
299
300 if (!mIsEseInitialized) {
301 ESESTATUS status = seHalInit();
302 if (status != ESESTATUS_SUCCESS) {
303 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
304 _hidl_cb(resApduBuff, 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
316 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
317
318 cmdApdu.len = (uint32_t)manageChannelCommand.size();
319 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
320 sizeof(uint8_t));
321 memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
322
323 status = phNxpEse_SetEndPoint_Cntxt(0);
324 if (status != ESESTATUS_SUCCESS) {
325 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
326 }
327 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
328 if (status != ESESTATUS_SUCCESS) {
329 resApduBuff.channelNumber = 0xff;
330 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
331 rspApdu.p_data[rspApdu.len - 1] == 0x81) {
332 resApduBuff.channelNumber = 0xff;
333 sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
334 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
335 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
336 resApduBuff.channelNumber = rspApdu.p_data[0];
337 mOpenedchannelCount++;
338 mOpenedChannels[resApduBuff.channelNumber] = true;
339 sestatus = SecureElementStatus::SUCCESS;
340 } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
341 (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
342 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
343 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
344 }
345 /*Free the allocations*/
346 phNxpEse_free(cmdApdu.p_data);
347 phNxpEse_free(rspApdu.p_data);
348
349 if (sestatus != SecureElementStatus::SUCCESS) {
350 if (mOpenedchannelCount == 0) {
351 SecureElementStatus deInitStatus = seHalDeInit();
352 if (deInitStatus != SecureElementStatus::SUCCESS) {
353 LOG(INFO) << "seDeInit Failed";
354 }
355 }
356 /*If manageChanle is failed in any of above cases
357 send the callback and return*/
358 status = phNxpEse_ResetEndPoint_Cntxt(0);
359 if (status != ESESTATUS_SUCCESS) {
360 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
361 }
362 _hidl_cb(resApduBuff, sestatus);
363 return Void();
364 }
365 LOG(INFO) << "openLogicalChannel Sending selectApdu";
366 sestatus = SecureElementStatus::IOERROR;
367 status = ESESTATUS_FAILED;
368
369 phNxpEse_7816_cpdu_t cpdu;
370 phNxpEse_7816_rpdu_t rpdu;
371 phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
372 phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
373
374 if ((resApduBuff.channelNumber > 0x03) &&
375 (resApduBuff.channelNumber < 0x14)) {
376 /* update CLA byte accoridng to GP spec Table 11-12*/
377 cpdu.cla =
378 0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
379 } else if ((resApduBuff.channelNumber > 0x00) &&
380 (resApduBuff.channelNumber < 0x04)) {
381 /* update CLA byte accoridng to GP spec Table 11-11*/
382 cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
383 } else {
384 LOG(ERROR) << StringPrintf("%s: Invalid Channel no: %02x", __func__,
385 resApduBuff.channelNumber);
386 resApduBuff.channelNumber = 0xff;
387 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
388 return Void();
389 }
390 cpdu.ins = 0xA4; /* Instruction code */
391 cpdu.p1 = 0x04; /* Instruction parameter 1 */
392 cpdu.p2 = p2; /* Instruction parameter 2 */
393 cpdu.lc = (uint16_t)aid.size();
394 cpdu.le_type = 0x01;
395 cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
396 memcpy(cpdu.pdata, aid.data(), cpdu.lc);
397 cpdu.le = 256;
398
399 rpdu.len = 0x02;
400 rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
401
402 status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
403
404 if (status != ESESTATUS_SUCCESS) {
405 /*Transceive failed*/
406 if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
407 sestatus = SecureElementStatus::IOERROR;
408 } else {
409 sestatus = SecureElementStatus::FAILED;
410 }
411 } else {
412 /*Status word to be passed as part of response
413 So include additional length*/
414 uint16_t responseLen = rpdu.len + 2;
415 resApduBuff.selectResponse.resize(responseLen);
416 memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
417 resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
418 resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
419
420 /*Status is success*/
421 if ((rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) || (rpdu.sw1 == 0x62) ||
422 (rpdu.sw1 == 0x63)) {
423 sestatus = SecureElementStatus::SUCCESS;
424 }
425 /*AID provided doesn't match any applet on the secure element*/
426 else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
427 (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
428 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
429 }
430 /*Operation provided by the P2 parameter is not permitted by the applet.*/
431 else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
432 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
433 } else {
434 sestatus = SecureElementStatus::FAILED;
435 }
436 }
437 if (sestatus != SecureElementStatus::SUCCESS) {
438 SecureElementStatus closeChannelStatus =
439 internalCloseChannel(resApduBuff.channelNumber);
440 if (closeChannelStatus != SecureElementStatus::SUCCESS) {
441 LOG(ERROR) << "%s: closeChannel Failed" << __func__;
442 } else {
443 resApduBuff.channelNumber = 0xff;
444 }
445 }
446 status = phNxpEse_ResetEndPoint_Cntxt(0);
447 if (status != ESESTATUS_SUCCESS) {
448 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
449 }
450 _hidl_cb(resApduBuff, sestatus);
451 phNxpEse_free(cpdu.pdata);
452 phNxpEse_free(rpdu.pdata);
453
454 return Void();
455 }
456
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)457 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
458 uint8_t p2,
459 openBasicChannel_cb _hidl_cb) {
460 AutoMutex guard(seHalLock);
461 ESESTATUS status = ESESTATUS_SUCCESS;
462 phNxpEse_7816_cpdu_t cpdu;
463 phNxpEse_7816_rpdu_t rpdu;
464 hidl_vec<uint8_t> result;
465 hidl_vec<uint8_t> ls_aid = {0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C,
466 0x41, 0x01, 0x43, 0x4F, 0x52, 0x01};
467
468 LOG(ERROR) << "Acquired the lock in SPI openBasicChannel";
469
470 if (!mIsEseInitialized) {
471 ESESTATUS status = seHalInit();
472 if (status != ESESTATUS_SUCCESS) {
473 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
474 _hidl_cb(result, SecureElementStatus::IOERROR);
475 return Void();
476 }
477 }
478 phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
479 phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
480
481 cpdu.cla = 0x00; /* Class of instruction */
482 cpdu.ins = 0xA4; /* Instruction code */
483 cpdu.p1 = 0x04; /* Instruction parameter 1 */
484 cpdu.p2 = p2; /* Instruction parameter 2 */
485 cpdu.lc = (uint16_t)aid.size();
486 cpdu.le_type = 0x01;
487 cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
488 memcpy(cpdu.pdata, aid.data(), cpdu.lc);
489 cpdu.le = 256;
490
491 rpdu.len = 0x02;
492 rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
493
494 status = phNxpEse_SetEndPoint_Cntxt(0);
495 if (status != ESESTATUS_SUCCESS) {
496 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
497 }
498 status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
499 SecureElementStatus sestatus;
500 memset(&sestatus, 0x00, sizeof(sestatus));
501
502 if (status != ESESTATUS_SUCCESS) {
503 /* Transceive failed */
504 if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
505 sestatus = SecureElementStatus::IOERROR;
506 } else {
507 sestatus = SecureElementStatus::FAILED;
508 }
509 } else {
510 /*Status word to be passed as part of response
511 So include additional length*/
512 uint16_t responseLen = rpdu.len + 2;
513 result.resize(responseLen);
514 memcpy(&result[0], rpdu.pdata, rpdu.len);
515 result[responseLen - 1] = rpdu.sw2;
516 result[responseLen - 2] = rpdu.sw1;
517
518 /*Status is success*/
519 if (((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) || (rpdu.sw1 == 0x62) ||
520 (rpdu.sw1 == 0x63)) {
521 /*Set basic channel reference if it is not set */
522 if (!mOpenedChannels[0]) {
523 mOpenedChannels[0] = true;
524 mOpenedchannelCount++;
525 }
526
527 sestatus = SecureElementStatus::SUCCESS;
528 }
529 /*AID provided doesn't match any applet on the secure element*/
530 else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
531 (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
532 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
533 }
534 /*Operation provided by the P2 parameter is not permitted by the applet.*/
535 else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
536 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
537 } else {
538 sestatus = SecureElementStatus::FAILED;
539 }
540 }
541 status = phNxpEse_ResetEndPoint_Cntxt(0);
542 if (status != ESESTATUS_SUCCESS) {
543 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
544 }
545 if (sestatus != SecureElementStatus::SUCCESS) {
546 SecureElementStatus closeChannelStatus =
547 internalCloseChannel(DEFAULT_BASIC_CHANNEL);
548 if (closeChannelStatus != SecureElementStatus::SUCCESS) {
549 LOG(ERROR) << "%s: closeChannel Failed" << __func__;
550 }
551 }
552 _hidl_cb(result, sestatus);
553 phNxpEse_free(cpdu.pdata);
554 phNxpEse_free(rpdu.pdata);
555 return Void();
556 }
557
internalCloseChannel(uint8_t channelNumber)558 Return<SecureElementStatus> SecureElement::internalCloseChannel(
559 uint8_t channelNumber) {
560 ESESTATUS status = ESESTATUS_SUCCESS;
561 SecureElementStatus sestatus = SecureElementStatus::FAILED;
562 phNxpEse_7816_cpdu_t cpdu;
563 phNxpEse_7816_rpdu_t rpdu;
564
565 LOG(ERROR) << "Acquired the lock in SPI internalCloseChannel";
566 LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d",
567 mMaxChannelCount, channelNumber);
568 if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL ||
569 channelNumber >= mMaxChannelCount) {
570 LOG(ERROR) << StringPrintf("invalid channel!!! %d", channelNumber);
571 } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
572 phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
573 phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
574 cpdu.cla = channelNumber; /* Class of instruction */
575 cpdu.ins = 0x70; /* Instruction code */
576 cpdu.p1 = 0x80; /* Instruction parameter 1 */
577 cpdu.p2 = channelNumber; /* Instruction parameter 2 */
578 cpdu.lc = 0x00;
579 cpdu.le = 0x9000;
580 status = phNxpEse_SetEndPoint_Cntxt(0);
581 if (status != ESESTATUS_SUCCESS) {
582 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
583 }
584 status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
585 if (status == ESESTATUS_SUCCESS) {
586 if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
587 sestatus = SecureElementStatus::SUCCESS;
588 }
589 }
590 status = phNxpEse_ResetEndPoint_Cntxt(0);
591 if (status != ESESTATUS_SUCCESS) {
592 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
593 }
594 }
595 if (channelNumber < mMaxChannelCount) {
596 if (mOpenedChannels[channelNumber]) {
597 mOpenedChannels[channelNumber] = false;
598 mOpenedchannelCount--;
599 }
600 }
601 /*If there are no channels remaining close secureElement*/
602 if (mOpenedchannelCount == 0) {
603 sestatus = seHalDeInit();
604 } else {
605 sestatus = SecureElementStatus::SUCCESS;
606 }
607 return sestatus;
608 }
609
closeChannel(uint8_t channelNumber)610 Return<SecureElementStatus> SecureElement::closeChannel(uint8_t channelNumber) {
611 AutoMutex guard(seHalLock);
612 return internalCloseChannel(channelNumber);
613 }
614
serviceDied(uint64_t,const wp<IBase> &)615 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
616 LOG(ERROR) << " SecureElement serviceDied!!!";
617 mIsEseInitialized = false;
618 if (seHalDeInit() != SecureElementStatus::SUCCESS) {
619 LOG(ERROR) << "SE Deinit not successful";
620 }
621 }
seHalInit()622 ESESTATUS SecureElement::seHalInit() {
623 ESESTATUS status = ESESTATUS_SUCCESS;
624 phNxpEse_initParams initParams;
625 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
626 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
627 initParams.initMode = ESE_MODE_NORMAL;
628 initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
629 initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
630
631 status = phNxpEse_open(initParams);
632 if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
633 if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
634 ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
635 if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
636 mIsEseInitialized = true;
637 LOG(INFO) << "ESE SPI init complete!!!";
638 return ESESTATUS_SUCCESS;
639 }
640 deInitStatus = phNxpEse_deInit();
641 } else {
642 LOG(INFO) << "ESE SPI init NOT successful";
643 status = ESESTATUS_FAILED;
644 }
645 if (phNxpEse_close(deInitStatus) != ESESTATUS_SUCCESS) {
646 LOG(INFO) << "ESE close not successful";
647 status = ESESTATUS_FAILED;
648 }
649 mIsEseInitialized = false;
650 }
651 return status;
652 }
653
seHalDeInit()654 Return<SecureElementStatus> SecureElement::seHalDeInit() {
655 ESESTATUS status = ESESTATUS_SUCCESS;
656 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
657 bool mIsDeInitDone = true;
658 SecureElementStatus sestatus = SecureElementStatus::FAILED;
659 status = phNxpEse_SetEndPoint_Cntxt(0);
660 if (status != ESESTATUS_SUCCESS) {
661 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
662 mIsDeInitDone = false;
663 }
664 deInitStatus = phNxpEse_deInit();
665 if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
666 status = phNxpEse_ResetEndPoint_Cntxt(0);
667 if (status != ESESTATUS_SUCCESS) {
668 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
669 mIsDeInitDone = false;
670 }
671 status = phNxpEse_close(deInitStatus);
672 if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
673 sestatus = SecureElementStatus::SUCCESS;
674 ;
675 } else {
676 LOG(ERROR) << "seHalDeInit: Failed";
677 }
678 mIsEseInitialized = false;
679 for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
680 mOpenedChannels[xx] = false;
681 }
682 mOpenedchannelCount = 0;
683
684 return sestatus;
685 }
686
687 } // namespace implementation
688 } // namespace V1_1
689 } // namespace secure_element
690 } // namespace hardware
691 } // namespace android
692