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