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