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