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