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