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