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