1 /******************************************************************************
2 *
3 * Copyright 2018-2022 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) << "Endpoint set 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) << "Endpoint set 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_SetEndPoint_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
324 LOG(INFO) << "Acquired the lock from SPI openLogicalChannel";
325
326 if (!mIsEseInitialized) {
327 ESESTATUS status = seHalInit();
328 if (status != ESESTATUS_SUCCESS) {
329 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
330 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
331 return Void();
332 }
333 }
334
335 SecureElementStatus sestatus = SecureElementStatus::IOERROR;
336 ESESTATUS status = ESESTATUS_FAILED;
337 phNxpEse_data cmdApdu;
338 phNxpEse_data rspApdu;
339
340 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
341
342 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
343
344 cmdApdu.len = (uint32_t)manageChannelCommand.size();
345 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
346 sizeof(uint8_t));
347 memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
348
349 status = phNxpEse_SetEndPoint_Cntxt(0);
350 if (status != ESESTATUS_SUCCESS) {
351 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
352 }
353 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
354 if (status != ESESTATUS_SUCCESS) {
355 resApduBuff.channelNumber = 0xff;
356 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
357 rspApdu.p_data[rspApdu.len - 1] == 0x81) {
358 resApduBuff.channelNumber = 0xff;
359 sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
360 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
361 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
362 resApduBuff.channelNumber = rspApdu.p_data[0];
363 mOpenedchannelCount++;
364 mOpenedChannels[resApduBuff.channelNumber] = true;
365 sestatus = SecureElementStatus::SUCCESS;
366 } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
367 (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
368 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
369 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
370 }
371 /*Free the allocations*/
372 phNxpEse_free(cmdApdu.p_data);
373 phNxpEse_free(rspApdu.p_data);
374
375 if (sestatus != SecureElementStatus::SUCCESS) {
376 if (mOpenedchannelCount == 0) {
377 SecureElementStatus deInitStatus = seHalDeInit();
378 if (deInitStatus != SecureElementStatus::SUCCESS) {
379 LOG(INFO) << "seDeInit Failed";
380 }
381 }
382 /*If manageChannel is failed in any of above cases
383 send the callback and return*/
384 status = phNxpEse_ResetEndPoint_Cntxt(0);
385 if (status != ESESTATUS_SUCCESS) {
386 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
387 }
388 _hidl_cb(resApduBuff, sestatus);
389 return Void();
390 }
391 LOG(INFO) << "openLogicalChannel Sending selectApdu";
392 sestatus = SecureElementStatus::IOERROR;
393 status = ESESTATUS_FAILED;
394
395 phNxpEse_7816_cpdu_t cpdu;
396 phNxpEse_7816_rpdu_t rpdu;
397 phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
398 phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
399
400 if ((resApduBuff.channelNumber > 0x03) &&
401 (resApduBuff.channelNumber < 0x14)) {
402 /* update CLA byte according to GP spec Table 11-12*/
403 cpdu.cla =
404 0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
405 } else if ((resApduBuff.channelNumber > 0x00) &&
406 (resApduBuff.channelNumber < 0x04)) {
407 /* update CLA byte according to GP spec Table 11-11*/
408 cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
409 } else {
410 LOG(ERROR) << StringPrintf("%s: Invalid Channel no: %02x", __func__,
411 resApduBuff.channelNumber);
412 resApduBuff.channelNumber = 0xff;
413 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
414 return Void();
415 }
416 cpdu.ins = 0xA4; /* Instruction code */
417 cpdu.p1 = 0x04; /* Instruction parameter 1 */
418 cpdu.p2 = p2; /* Instruction parameter 2 */
419 cpdu.lc = (uint16_t)aid.size();
420 cpdu.le_type = 0x01;
421 cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
422 memcpy(cpdu.pdata, aid.data(), cpdu.lc);
423 cpdu.le = 256;
424
425 rpdu.len = 0x02;
426 rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
427
428 status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
429
430 if (status != ESESTATUS_SUCCESS) {
431 /*Transceive failed*/
432 if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
433 sestatus = SecureElementStatus::IOERROR;
434 } else {
435 sestatus = SecureElementStatus::FAILED;
436 }
437 } else {
438 /*Status word to be passed as part of response
439 So include additional length*/
440 uint16_t responseLen = rpdu.len + 2;
441 resApduBuff.selectResponse.resize(responseLen);
442 memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
443 resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
444 resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
445
446 /*Status is success*/
447 if ((rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) || (rpdu.sw1 == 0x62) ||
448 (rpdu.sw1 == 0x63)) {
449 sestatus = SecureElementStatus::SUCCESS;
450 }
451 /*AID provided doesn't match any applet on the secure element*/
452 else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
453 (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
454 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
455 }
456 /*Operation provided by the P2 parameter is not permitted by the applet.*/
457 else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
458 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
459 } else {
460 sestatus = SecureElementStatus::FAILED;
461 }
462 }
463 if (sestatus != SecureElementStatus::SUCCESS) {
464 SecureElementStatus closeChannelStatus =
465 internalCloseChannel(resApduBuff.channelNumber);
466 if (closeChannelStatus != SecureElementStatus::SUCCESS) {
467 LOG(ERROR) << "%s: closeChannel Failed" << __func__;
468 } else {
469 resApduBuff.channelNumber = 0xff;
470 }
471 }
472 status = phNxpEse_ResetEndPoint_Cntxt(0);
473 if (status != ESESTATUS_SUCCESS) {
474 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
475 }
476 _hidl_cb(resApduBuff, sestatus);
477 phNxpEse_free(cpdu.pdata);
478 phNxpEse_free(rpdu.pdata);
479
480 return Void();
481 }
482
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)483 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
484 uint8_t p2,
485 openBasicChannel_cb _hidl_cb) {
486 AutoMutex guard(seHalLock);
487 ESESTATUS status = ESESTATUS_SUCCESS;
488 phNxpEse_7816_cpdu_t cpdu;
489 phNxpEse_7816_rpdu_t rpdu;
490 hidl_vec<uint8_t> result;
491 hidl_vec<uint8_t> ls_aid = {0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C,
492 0x41, 0x01, 0x43, 0x4F, 0x52, 0x01};
493
494 LOG(ERROR) << "Acquired the lock in SPI openBasicChannel";
495
496 if (!mIsEseInitialized) {
497 ESESTATUS status = seHalInit();
498 if (status != ESESTATUS_SUCCESS) {
499 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
500 _hidl_cb(result, SecureElementStatus::IOERROR);
501 return Void();
502 }
503 }
504 phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
505 phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
506
507 cpdu.cla = 0x00; /* Class of instruction */
508 cpdu.ins = 0xA4; /* Instruction code */
509 cpdu.p1 = 0x04; /* Instruction parameter 1 */
510 cpdu.p2 = p2; /* Instruction parameter 2 */
511 cpdu.lc = (uint16_t)aid.size();
512 cpdu.le_type = 0x01;
513 cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
514 memcpy(cpdu.pdata, aid.data(), cpdu.lc);
515 cpdu.le = 256;
516
517 rpdu.len = 0x02;
518 rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
519
520 status = phNxpEse_SetEndPoint_Cntxt(0);
521 if (status != ESESTATUS_SUCCESS) {
522 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
523 }
524 status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
525 SecureElementStatus sestatus;
526 memset(&sestatus, 0x00, sizeof(sestatus));
527
528 if (status != ESESTATUS_SUCCESS) {
529 /* Transceive failed */
530 if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
531 sestatus = SecureElementStatus::IOERROR;
532 } else {
533 sestatus = SecureElementStatus::FAILED;
534 }
535 } else {
536 /*Status word to be passed as part of response
537 So include additional length*/
538 uint16_t responseLen = rpdu.len + 2;
539 result.resize(responseLen);
540 memcpy(&result[0], rpdu.pdata, rpdu.len);
541 result[responseLen - 1] = rpdu.sw2;
542 result[responseLen - 2] = rpdu.sw1;
543
544 /*Status is success*/
545 if (((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) || (rpdu.sw1 == 0x62) ||
546 (rpdu.sw1 == 0x63)) {
547 /*Set basic channel reference if it is not set */
548 if (!mOpenedChannels[0]) {
549 mOpenedChannels[0] = true;
550 mOpenedchannelCount++;
551 }
552
553 sestatus = SecureElementStatus::SUCCESS;
554 }
555 /*AID provided doesn't match any applet on the secure element*/
556 else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
557 (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
558 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
559 }
560 /*Operation provided by the P2 parameter is not permitted by the applet.*/
561 else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
562 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
563 } else {
564 sestatus = SecureElementStatus::FAILED;
565 }
566 }
567 status = phNxpEse_ResetEndPoint_Cntxt(0);
568 if (status != ESESTATUS_SUCCESS) {
569 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
570 }
571 if (sestatus != SecureElementStatus::SUCCESS) {
572 SecureElementStatus closeChannelStatus =
573 internalCloseChannel(DEFAULT_BASIC_CHANNEL);
574 if (closeChannelStatus != SecureElementStatus::SUCCESS) {
575 LOG(ERROR) << "%s: closeChannel Failed" << __func__;
576 }
577 }
578 _hidl_cb(result, sestatus);
579 phNxpEse_free(cpdu.pdata);
580 phNxpEse_free(rpdu.pdata);
581 return Void();
582 }
583
internalCloseChannel(uint8_t channelNumber)584 Return<SecureElementStatus> SecureElement::internalCloseChannel(
585 uint8_t channelNumber) {
586 ESESTATUS status = ESESTATUS_SUCCESS;
587 SecureElementStatus sestatus = SecureElementStatus::FAILED;
588 phNxpEse_7816_cpdu_t cpdu;
589 phNxpEse_7816_rpdu_t rpdu;
590
591 LOG(ERROR) << "Acquired the lock in SPI internalCloseChannel";
592 LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d",
593 mMaxChannelCount, channelNumber);
594 if (channelNumber >= mMaxChannelCount) {
595 LOG(ERROR) << StringPrintf("invalid channel!!! %d", channelNumber);
596 } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
597 phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
598 phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
599 cpdu.cla = channelNumber; /* Class of instruction */
600 // For Supplementary Channel update CLA byte according to GP
601 if ((channelNumber > 0x03) && (channelNumber < 0x14)) {
602 /* update CLA byte according to GP spec Table 11-12*/
603 cpdu.cla = 0x40 + (channelNumber - 4); /* Class of instruction */
604 }
605 cpdu.ins = 0x70; /* Instruction code */
606 cpdu.p1 = 0x80; /* Instruction parameter 1 */
607 cpdu.p2 = channelNumber; /* Instruction parameter 2 */
608 cpdu.lc = 0x00;
609 cpdu.le = 0x9000;
610 status = phNxpEse_SetEndPoint_Cntxt(0);
611 if (status != ESESTATUS_SUCCESS) {
612 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
613 }
614 status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
615 if (status == ESESTATUS_SUCCESS) {
616 if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
617 sestatus = SecureElementStatus::SUCCESS;
618 }
619 }
620 status = phNxpEse_ResetEndPoint_Cntxt(0);
621 if (status != ESESTATUS_SUCCESS) {
622 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
623 }
624 }
625 if (channelNumber < mMaxChannelCount) {
626 if (mOpenedChannels[channelNumber]) {
627 mOpenedChannels[channelNumber] = false;
628 mOpenedchannelCount--;
629 }
630 }
631 /*If there are no channels remaining close secureElement*/
632 if (mOpenedchannelCount == 0) {
633 sestatus = seHalDeInit();
634 } else {
635 sestatus = SecureElementStatus::SUCCESS;
636 }
637 return sestatus;
638 }
639
closeChannel(uint8_t channelNumber)640 Return<SecureElementStatus> SecureElement::closeChannel(uint8_t channelNumber) {
641 AutoMutex guard(seHalLock);
642 return internalCloseChannel(channelNumber);
643 }
644
serviceDied(uint64_t,const wp<IBase> &)645 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
646 LOG(ERROR) << " SecureElement serviceDied!!!";
647 mIsEseInitialized = false;
648 if (seHalDeInit() != SecureElementStatus::SUCCESS) {
649 LOG(ERROR) << "SE Deinit not successful";
650 }
651 }
seHalInit()652 ESESTATUS SecureElement::seHalInit() {
653 ESESTATUS status = ESESTATUS_SUCCESS;
654 phNxpEse_initParams initParams;
655 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
656 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
657 initParams.initMode = ESE_MODE_NORMAL;
658 initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
659 initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
660
661 status = phNxpEse_open(initParams);
662 if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
663 if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
664 ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
665 if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
666 mIsEseInitialized = true;
667 LOG(INFO) << "ESE SPI init complete!!!";
668 return ESESTATUS_SUCCESS;
669 }
670 deInitStatus = phNxpEse_deInit();
671 } else {
672 LOG(INFO) << "ESE SPI init NOT successful";
673 status = ESESTATUS_FAILED;
674 }
675 if (phNxpEse_close(deInitStatus) != ESESTATUS_SUCCESS) {
676 LOG(INFO) << "ESE close not successful";
677 status = ESESTATUS_FAILED;
678 }
679 mIsEseInitialized = false;
680 }
681 return status;
682 }
683
seHalDeInit()684 Return<SecureElementStatus> SecureElement::seHalDeInit() {
685 ESESTATUS status = ESESTATUS_SUCCESS;
686 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
687 bool mIsDeInitDone = true;
688 SecureElementStatus sestatus = SecureElementStatus::FAILED;
689 status = phNxpEse_SetEndPoint_Cntxt(0);
690 if (status != ESESTATUS_SUCCESS) {
691 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
692 mIsDeInitDone = false;
693 }
694 deInitStatus = phNxpEse_deInit();
695 if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
696 status = phNxpEse_ResetEndPoint_Cntxt(0);
697 if (status != ESESTATUS_SUCCESS) {
698 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
699 mIsDeInitDone = false;
700 }
701 status = phNxpEse_close(deInitStatus);
702 if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
703 sestatus = SecureElementStatus::SUCCESS;
704 ;
705 } else {
706 LOG(ERROR) << "seHalDeInit: Failed";
707 }
708 mIsEseInitialized = false;
709 for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
710 mOpenedChannels[xx] = false;
711 }
712 mOpenedchannelCount = 0;
713
714 return sestatus;
715 }
716
717 } // namespace implementation
718 } // namespace V1_1
719 } // namespace secure_element
720 } // namespace hardware
721 } // namespace android
722