blob: 58082381c698afe4cfad445b8068efd3f7868f7e [file] [log] [blame]
/******************************************************************************
*
* Copyright 2023 NXP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#include "VirtualISO.h"
#include "SecureElement.h"
// Undefined LOG_TAG as it is also defined in log.h
#undef LOG_TAG
#include <memunreachable/memunreachable.h>
// #include "hal_nxpese.h"
#include "phNxpEse_Apdu_Api.h"
#include "phNxpEse_Api.h"
namespace aidl {
namespace vendor {
namespace nxp {
namespace virtual_iso {
#define LOG_TAG "nxpVIsoese_aidl-service"
#define DEFAULT_BASIC_CHANNEL 0x00
typedef struct gsTransceiveBuffer {
phNxpEse_data cmdData;
phNxpEse_data rspData;
std::vector<uint8_t>* pRspDataBuff;
} sTransceiveBuffer_t;
static sTransceiveBuffer_t gsTxRxBuffer;
static std::vector<uint8_t> gsRspDataBuff(256);
std::shared_ptr<ISecureElementCallback> VirtualISO::mCallback = nullptr;
AIBinder_DeathRecipient* clientDeathRecipient = nullptr;
std::vector<bool> VirtualISO::mOpenedChannels;
VirtualISO::VirtualISO()
: mMaxChannelCount(0), mOpenedchannelCount(0), mIsEseInitialized(false) {}
void OnDeath(void* cookie) {
(void)cookie;
// TODO: Implement graceful closure, to close ongoing tx-rx and deinit
// T=1 stack
// close(0);
}
ScopedAStatus VirtualISO::init(
const std::shared_ptr<ISecureElementCallback>& clientCallback) {
ESESTATUS status = ESESTATUS_SUCCESS;
ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
bool mIsInitDone = false;
phNxpEse_initParams initParams;
LOG(INFO) << "Virtual ISO::init Enter";
gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
initParams.initMode = ESE_MODE_NORMAL;
initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
if (clientCallback == nullptr) {
return ScopedAStatus::ok();
} else {
clientDeathRecipient = AIBinder_DeathRecipient_new(OnDeath);
auto linkRet =
AIBinder_linkToDeath(clientCallback->asBinder().get(),
clientDeathRecipient, this /* cookie */);
if (linkRet != STATUS_OK) {
LOG(ERROR) << __func__ << ": linkToDeath failed: " << linkRet;
// Just ignore the error.
}
}
if (mIsEseInitialized) {
clientCallback->onStateChange(true, "NXP VISIO HAL init ok");
return ScopedAStatus::ok();
}
status = phNxpEse_open(initParams);
if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
LOG(INFO) << "VISO init complete!!!";
mIsInitDone = true;
}
deInitStatus = phNxpEse_deInit();
if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
}
status = phNxpEse_close(deInitStatus);
}
if (status == ESESTATUS_SUCCESS && mIsInitDone) {
mMaxChannelCount = (GET_CHIP_OS_VERSION() > OS_VERSION_6_2) ? 0x0C : 0x04;
mOpenedChannels.resize(mMaxChannelCount, false);
clientCallback->onStateChange(true, "NXP VISIO HAL init ok");
} else {
LOG(ERROR) << "VISO-Hal Init failed";
clientCallback->onStateChange(false, "NXP VISIO HAL init failed");
}
return ScopedAStatus::ok();
}
ScopedAStatus VirtualISO::getAtr(std::vector<uint8_t>* _aidl_return) {
std::vector<uint8_t> response;
*_aidl_return = std::move(response);
return ScopedAStatus::ok();
}
ScopedAStatus VirtualISO::isCardPresent(bool* _aidl_return) {
LOG(INFO) << __func__;
*_aidl_return = true;
return ScopedAStatus::ok();
}
ScopedAStatus VirtualISO::transmit(const std::vector<uint8_t>& data,
std::vector<uint8_t>* _aidl_return) {
ESESTATUS status = ESESTATUS_FAILED;
std::vector<uint8_t> result;
phNxpEse_memset(&gsTxRxBuffer.cmdData, 0x00, sizeof(phNxpEse_data));
phNxpEse_memset(&gsTxRxBuffer.rspData, 0x00, sizeof(phNxpEse_data));
gsTxRxBuffer.cmdData.len = data.size();
gsTxRxBuffer.cmdData.p_data =
(uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
if (NULL == gsTxRxBuffer.cmdData.p_data) {
LOG(ERROR) << "transmit failed to allocate the Memory!!!";
/*Return empty vec*/
*_aidl_return = result;
return ScopedAStatus::ok();
}
memcpy(gsTxRxBuffer.cmdData.p_data, data.data(), gsTxRxBuffer.cmdData.len);
LOG(ERROR) << "Acquired the lock in VISO ";
status = phNxpEse_SetEndPoint_Cntxt(1);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
}
status = phNxpEse_Transceive(&gsTxRxBuffer.cmdData, &gsTxRxBuffer.rspData);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "transmit failed!!!";
} else {
result.resize(gsTxRxBuffer.rspData.len);
memcpy(&result[0], gsTxRxBuffer.rspData.p_data, gsTxRxBuffer.rspData.len);
}
status = phNxpEse_ResetEndPoint_Cntxt(1);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
}
*_aidl_return = std::move(result);
if (NULL != gsTxRxBuffer.cmdData.p_data) {
phNxpEse_free(gsTxRxBuffer.cmdData.p_data);
gsTxRxBuffer.cmdData.p_data = NULL;
}
if (NULL != gsTxRxBuffer.rspData.p_data) {
phNxpEse_free(gsTxRxBuffer.rspData.p_data);
gsTxRxBuffer.rspData.p_data = NULL;
}
return ScopedAStatus::ok();
}
ScopedAStatus VirtualISO::openLogicalChannel(
const std::vector<uint8_t>& aid, int8_t p2,
::aidl::android::hardware::secure_element::LogicalChannelResponse*
_aidl_return) {
std::vector<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
LogicalChannelResponse resApduBuff;
if (GET_CHIP_OS_VERSION() <= OS_VERSION_6_2) {
uint8_t maxLogicalChannelSupported = mMaxChannelCount - 1;
uint8_t openedLogicalChannelCount = mOpenedchannelCount;
if (mOpenedChannels[0]) openedLogicalChannelCount--;
if (openedLogicalChannelCount >= maxLogicalChannelSupported) {
LOG(ERROR) << "%s: Reached Max supported Logical Channel" << __func__;
*_aidl_return = resApduBuff;
return ScopedAStatus::fromServiceSpecificError(CHANNEL_NOT_AVAILABLE);
}
}
LOG(INFO) << "Acquired the lock in VISO openLogicalChannel";
resApduBuff.channelNumber = 0xff;
memset(&resApduBuff, 0x00, sizeof(resApduBuff));
if (!mIsEseInitialized) {
ESESTATUS status = seHalInit();
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
*_aidl_return = resApduBuff;
return ScopedAStatus::fromServiceSpecificError(IOERROR);
}
}
if (mOpenedChannels.size() == 0x00) {
mMaxChannelCount = (GET_CHIP_OS_VERSION() > OS_VERSION_6_2) ? 0x0C : 0x04;
mOpenedChannels.resize(mMaxChannelCount, false);
}
int sestatus = ISecureElement::IOERROR;
ESESTATUS status = ESESTATUS_FAILED;
phNxpEse_data cmdApdu;
phNxpEse_data rspApdu;
phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
cmdApdu.len = manageChannelCommand.size();
cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
sizeof(uint8_t));
memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
sestatus = SESTATUS_SUCCESS;
status = phNxpEse_SetEndPoint_Cntxt(1);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
}
status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
if (status != ESESTATUS_SUCCESS) {
resApduBuff.channelNumber = 0xff;
if (NULL != rspApdu.p_data && rspApdu.len > 0) {
if ((rspApdu.p_data[0] == 0x64 && rspApdu.p_data[1] == 0xFF)) {
sestatus = ISecureElement::IOERROR;
}
}
if (sestatus != ISecureElement::IOERROR) {
sestatus = ISecureElement::FAILED;
}
} else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
rspApdu.p_data[rspApdu.len - 1] == 0x81) {
resApduBuff.channelNumber = 0xff;
sestatus = ISecureElement::CHANNEL_NOT_AVAILABLE;
} else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
rspApdu.p_data[rspApdu.len - 1] == 0x00) {
resApduBuff.channelNumber = rspApdu.p_data[0];
mOpenedchannelCount++;
mOpenedChannels[resApduBuff.channelNumber] = true;
sestatus = SESTATUS_SUCCESS;
} else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
(rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
rspApdu.p_data[rspApdu.len - 1] == 0x00) {
sestatus = ISecureElement::UNSUPPORTED_OPERATION;
}
/*Free the allocations*/
phNxpEse_free(cmdApdu.p_data);
phNxpEse_free(rspApdu.p_data);
if (sestatus != SESTATUS_SUCCESS) {
if (mOpenedchannelCount == 0) {
sestatus = seHalDeInit();
if (sestatus != SESTATUS_SUCCESS) {
LOG(INFO) << "seDeInit Failed";
}
}
/*If manageChannel is failed in any of above cases
send the callback and return*/
status = phNxpEse_ResetEndPoint_Cntxt(1);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
}
*_aidl_return = resApduBuff;
return ScopedAStatus::fromServiceSpecificError(sestatus);
}
LOG(INFO) << "openLogicalChannel Sending selectApdu";
sestatus = ISecureElement::IOERROR;
status = ESESTATUS_FAILED;
phNxpEse_7816_cpdu_t cpdu;
phNxpEse_7816_rpdu_t rpdu;
phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
if ((resApduBuff.channelNumber > 0x03) &&
(resApduBuff.channelNumber < 0x14)) {
/* update CLA byte according to GP spec Table 11-12*/
cpdu.cla =
0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
} else if ((resApduBuff.channelNumber > 0x00) &&
(resApduBuff.channelNumber < 0x04)) {
/* update CLA byte according to GP spec Table 11-11*/
cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
} else {
ALOGE("%s: Invalid Channel no: %02x", __func__, resApduBuff.channelNumber);
resApduBuff.channelNumber = 0xff;
*_aidl_return = resApduBuff;
return ScopedAStatus::fromServiceSpecificError(IOERROR);
}
cpdu.ins = 0xA4; /* Instruction code */
cpdu.p1 = 0x04; /* Instruction parameter 1 */
cpdu.p2 = p2; /* Instruction parameter 2 */
cpdu.lc = aid.size();
cpdu.le_type = 0x01;
cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
memcpy(cpdu.pdata, aid.data(), cpdu.lc);
cpdu.le = 256;
rpdu.len = 0x02;
rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
if (status != ESESTATUS_SUCCESS) {
/*Transceive failed*/
if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
sestatus = ISecureElement::IOERROR;
} else {
sestatus = ISecureElement::FAILED;
}
} else {
/*Status word to be passed as part of response
So include additional length*/
uint16_t responseLen = rpdu.len + 2;
resApduBuff.selectResponse.resize(responseLen);
memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
/*Status is success*/
if (rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) {
sestatus = SESTATUS_SUCCESS;
}
/*AID provided doesn't match any applet on the secure element*/
else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) {
sestatus = ISecureElement::NO_SUCH_ELEMENT_ERROR;
}
/*Operation provided by the P2 parameter is not permitted by the applet.*/
else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
sestatus = ISecureElement::UNSUPPORTED_OPERATION;
} else {
sestatus = ISecureElement::FAILED;
}
}
if (sestatus != SESTATUS_SUCCESS) {
int closeChannelStatus = internalCloseChannel(resApduBuff.channelNumber);
if (closeChannelStatus != SESTATUS_SUCCESS) {
LOG(ERROR) << "%s: closeChannel Failed" << __func__;
} else {
resApduBuff.channelNumber = 0xff;
}
}
status = phNxpEse_ResetEndPoint_Cntxt(1);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
}
*_aidl_return = std::move(resApduBuff);
phNxpEse_free(cpdu.pdata);
phNxpEse_free(rpdu.pdata);
return sestatus == SESTATUS_SUCCESS
? ndk::ScopedAStatus::ok()
: ndk::ScopedAStatus::fromServiceSpecificError(sestatus);
}
ScopedAStatus VirtualISO::openBasicChannel(const std::vector<uint8_t>& aid,
int8_t p2,
std::vector<uint8_t>* _aidl_return) {
ESESTATUS status = ESESTATUS_SUCCESS;
phNxpEse_7816_cpdu_t cpdu;
phNxpEse_7816_rpdu_t rpdu;
std::vector<uint8_t> result;
LOG(INFO) << "Acquired the lock in VISO openBasicChannel";
if (!mIsEseInitialized) {
ESESTATUS status = seHalInit();
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
*_aidl_return = result;
return ScopedAStatus::fromServiceSpecificError(IOERROR);
}
}
if (mOpenedChannels.size() == 0x00) {
mMaxChannelCount = (GET_CHIP_OS_VERSION() > OS_VERSION_6_2) ? 0x0C : 0x04;
mOpenedChannels.resize(mMaxChannelCount, false);
}
phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
cpdu.cla = 0x00; /* Class of instruction */
cpdu.ins = 0xA4; /* Instruction code */
cpdu.p1 = 0x04; /* Instruction parameter 1 */
cpdu.p2 = p2; /* Instruction parameter 2 */
cpdu.lc = aid.size();
cpdu.le_type = 0x01;
cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
memcpy(cpdu.pdata, aid.data(), cpdu.lc);
cpdu.le = 256;
rpdu.len = 0x02;
rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
status = phNxpEse_SetEndPoint_Cntxt(1);
status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
int sestatus;
sestatus = SESTATUS_SUCCESS;
if (status != ESESTATUS_SUCCESS) {
/* Transceive failed */
if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
sestatus = ISecureElement::IOERROR;
} else {
sestatus = ISecureElement::FAILED;
}
} else {
/*Status word to be passed as part of response
So include additional length*/
uint16_t responseLen = rpdu.len + 2;
result.resize(responseLen);
memcpy(&result[0], rpdu.pdata, rpdu.len);
result[responseLen - 1] = rpdu.sw2;
result[responseLen - 2] = rpdu.sw1;
/*Status is success*/
if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
/*Set basic channel reference if it is not set */
if (!mOpenedChannels[0]) {
mOpenedChannels[0] = true;
mOpenedchannelCount++;
}
sestatus = SESTATUS_SUCCESS;
}
/*AID provided doesn't match any applet on the secure element*/
else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) {
sestatus = ISecureElement::NO_SUCH_ELEMENT_ERROR;
}
/*Operation provided by the P2 parameter is not permitted by the applet.*/
else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
sestatus = ISecureElement::UNSUPPORTED_OPERATION;
} else {
sestatus = ISecureElement::FAILED;
}
}
status = phNxpEse_ResetEndPoint_Cntxt(1);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
}
if (sestatus != SESTATUS_SUCCESS) {
int closeChannelStatus = internalCloseChannel(DEFAULT_BASIC_CHANNEL);
if (closeChannelStatus != SESTATUS_SUCCESS) {
LOG(ERROR) << "%s: closeChannel Failed" << __func__;
}
}
*_aidl_return = std::move(result);
phNxpEse_free(cpdu.pdata);
phNxpEse_free(rpdu.pdata);
return sestatus == SESTATUS_SUCCESS
? ndk::ScopedAStatus::ok()
: ndk::ScopedAStatus::fromServiceSpecificError(sestatus);
}
int VirtualISO::internalCloseChannel(uint8_t channelNumber) {
ESESTATUS status = ESESTATUS_SUCCESS;
int sestatus = ISecureElement::FAILED;
phNxpEse_7816_cpdu_t cpdu;
phNxpEse_7816_rpdu_t rpdu;
ALOGE("internalCloseChannel Enter");
ALOGI("mMaxChannelCount = %d, Closing Channel = %d", mMaxChannelCount,
channelNumber);
if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL ||
channelNumber >= mMaxChannelCount) {
ALOGE("invalid channel!!! %d", channelNumber);
} else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
cpdu.cla = channelNumber; /* Class of instruction */
// For Supplementary Channel update CLA byte according to GP
if ((channelNumber > 0x03) && (channelNumber < 0x14)) {
/* update CLA byte according to GP spec Table 11-12*/
cpdu.cla = 0x40 + (channelNumber - 4); /* Class of instruction */
}
cpdu.ins = 0x70; /* Instruction code */
cpdu.p1 = 0x80; /* Instruction parameter 1 */
cpdu.p2 = channelNumber; /* Instruction parameter 2 */
cpdu.lc = 0x00;
cpdu.le = 0x9000;
status = phNxpEse_SetEndPoint_Cntxt(1);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
}
status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
if (status == ESESTATUS_SUCCESS) {
if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
sestatus = SESTATUS_SUCCESS;
}
}
status = phNxpEse_ResetEndPoint_Cntxt(1);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
}
if (mOpenedChannels[channelNumber]) {
mOpenedChannels[channelNumber] = false;
mOpenedchannelCount--;
}
}
/*If there are no channels remaining close secureElement*/
if (mOpenedchannelCount == 0) {
sestatus = seHalDeInit();
} else {
sestatus = SESTATUS_SUCCESS;
}
return sestatus;
}
ScopedAStatus VirtualISO::closeChannel(int8_t channelNumber) {
ESESTATUS status = ESESTATUS_SUCCESS;
int sestatus = ISecureElement::FAILED;
phNxpEse_7816_cpdu_t cpdu;
phNxpEse_7816_rpdu_t rpdu;
LOG(INFO) << "Acquired the lock in VISO closeChannel";
if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL ||
channelNumber >= mMaxChannelCount) {
ALOGE("invalid channel!!! %d", channelNumber);
} else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
cpdu.cla = channelNumber; /* Class of instruction */
cpdu.ins = 0x70; /* Instruction code */
cpdu.p1 = 0x80; /* Instruction parameter 1 */
cpdu.p2 = channelNumber; /* Instruction parameter 2 */
cpdu.lc = 0x00;
cpdu.le = 0x9000;
status = phNxpEse_SetEndPoint_Cntxt(1);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
}
status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
if (status == ESESTATUS_SUCCESS) {
if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
sestatus = SESTATUS_SUCCESS;
}
}
status = phNxpEse_ResetEndPoint_Cntxt(1);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
}
if (mOpenedChannels[channelNumber]) {
mOpenedChannels[channelNumber] = false;
mOpenedchannelCount--;
}
}
/*If there are no channels remaining close secureElement*/
if (mOpenedchannelCount == 0) {
sestatus = seHalDeInit();
} else {
sestatus = SESTATUS_SUCCESS;
}
return sestatus == SESTATUS_SUCCESS
? ndk::ScopedAStatus::ok()
: ndk::ScopedAStatus::fromServiceSpecificError(sestatus);
}
ESESTATUS VirtualISO::seHalInit() {
ESESTATUS status = ESESTATUS_SUCCESS;
ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
phNxpEse_initParams initParams;
memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
initParams.initMode = ESE_MODE_NORMAL;
initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
status = phNxpEse_open(initParams);
if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
mIsEseInitialized = true;
LOG(INFO) << "VISO init complete!!!";
return ESESTATUS_SUCCESS;
}
deInitStatus = phNxpEse_deInit();
}
if (phNxpEse_close(deInitStatus) != ESESTATUS_SUCCESS) {
LOG(INFO) << "VISO close is not successful";
}
mIsEseInitialized = false;
}
return status;
}
int VirtualISO::seHalDeInit() {
ESESTATUS status = ESESTATUS_SUCCESS;
ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
bool mIsDeInitDone = true;
int sestatus = ISecureElement::FAILED;
status = phNxpEse_SetEndPoint_Cntxt(1);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
mIsDeInitDone = false;
}
deInitStatus = phNxpEse_deInit();
if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
status = phNxpEse_ResetEndPoint_Cntxt(1);
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
mIsDeInitDone = false;
}
status = phNxpEse_close(deInitStatus);
if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
sestatus = SESTATUS_SUCCESS;
} else {
LOG(ERROR) << "seHalDeInit: Failed";
}
// Clear all the flags as SPI driver is closed.
mIsEseInitialized = false;
for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
mOpenedChannels[xx] = false;
}
mOpenedchannelCount = 0;
return sestatus;
}
ScopedAStatus VirtualISO::reset() {
ESESTATUS status = ESESTATUS_SUCCESS;
int sestatus = ISecureElement::FAILED;
LOG(ERROR) << "%s: Enter" << __func__;
if (!mIsEseInitialized) {
ESESTATUS status = seHalInit();
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
}
}
if (status == ESESTATUS_SUCCESS) {
mCallback->onStateChange(false, "reset the SE");
status = phNxpEse_reset();
if (status != ESESTATUS_SUCCESS) {
LOG(ERROR) << "%s: SecureElement reset failed!!" << __func__;
} else {
sestatus = SESTATUS_SUCCESS;
if (mOpenedChannels.size() == 0x00) {
mMaxChannelCount =
(GET_CHIP_OS_VERSION() > OS_VERSION_6_2) ? 0x0C : 0x04;
mOpenedChannels.resize(mMaxChannelCount, false);
}
for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
mOpenedChannels[xx] = false;
}
mOpenedchannelCount = 0;
mCallback->onStateChange(true, "SE initialized");
}
}
LOG(ERROR) << "%s: Exit" << __func__;
return sestatus == SESTATUS_SUCCESS
? ndk::ScopedAStatus::ok()
: ndk::ScopedAStatus::fromServiceSpecificError(sestatus);
}
} // namespace virtual_iso
} // namespace nxp
} // namespace vendor
} // namespace aidl