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