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