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