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