From b20ea5e67f32f4700f54550161e5fa92f85b9428 Mon Sep 17 00:00:00 2001 From: "anil.hiranniah" Date: Wed, 15 Dec 2021 21:33:02 +0530 Subject: update NXP se hal for SNxxx Test: CTS, VTS, command exchange from Host to eSE Bug: 210582278 Change-Id: Id73b80ac6e8ba73865d62ea915d3add5a36d23a3 --- snxxx/1.0/NxpEseService.cpp | 14 +-- snxxx/1.0/SecureElement.cpp | 10 ++- snxxx/1.0/SecureElement.h | 1 + snxxx/1.0/VirtualISO.cpp | 9 +- snxxx/1.0/VirtualISO.h | 2 +- snxxx/1.1/NxpEseService.cpp | 7 +- snxxx/1.1/SecureElement.cpp | 12 ++- snxxx/1.1/SecureElement.h | 1 + snxxx/1.1/VirtualISO.cpp | 9 +- snxxx/1.1/VirtualISO.h | 2 +- snxxx/1.2/NxpEseService.cpp | 40 +++++++-- snxxx/1.2/OsuHal/inc/OsuHalExtn.h | 7 +- snxxx/1.2/OsuHal/src/OsuHalExtn.cpp | 42 +++++---- snxxx/1.2/SecureElement.cpp | 109 ++++++++++++++++++++--- snxxx/1.2/VirtualISO.cpp | 15 +++- snxxx/1.2/VirtualISO.h | 2 +- snxxx/Android.bp | 5 +- snxxx/ese-clients/inc/eSEClient.h | 1 + snxxx/ese-clients/src/eSEClient.cpp | 2 + snxxx/extns/impl/NxpEse.cpp | 7 +- snxxx/libese-spi/Android.bp | 8 +- snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp | 5 +- snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h | 16 ++-- snxxx/libese-spi/p73/lib/phNxpEse_Api.cpp | 11 +-- snxxx/libese-spi/src/include/NfcAdaptation.h | 4 +- 25 files changed, 257 insertions(+), 84 deletions(-) diff --git a/snxxx/1.0/NxpEseService.cpp b/snxxx/1.0/NxpEseService.cpp index c27b781..52b47a7 100644 --- a/snxxx/1.0/NxpEseService.cpp +++ b/snxxx/1.0/NxpEseService.cpp @@ -19,13 +19,13 @@ #include #include #include -#include -#include "VirtualISO.h" - #include #include +#include + #include "NxpEse.h" #include "SecureElement.h" +#include "VirtualISO.h" #include "eSEClient.h" // Generated HIDL files @@ -84,15 +84,15 @@ int main() { nxp_se_service = new NxpEse(); if (nxp_se_service == nullptr) { LOG(ERROR) << StringPrintf( - "Can not create an instance of NXP Secure Element Extn " - "Iface,exiting."); + "Can not create an instance of NXP Secure " + "Element Extn Iface,exiting."); goto shutdown; } status = nxp_se_service->registerAsService(); if (status != OK) { LOG(ERROR) << StringPrintf( - "Could not register service for Power Secure Element Extn Iface " - "(%d).", + "Could not register service for Power Secure " + "Element Extn Iface (%d).", status); goto shutdown; } diff --git a/snxxx/1.0/SecureElement.cpp b/snxxx/1.0/SecureElement.cpp index 61f1e7f..18c5176 100755 --- a/snxxx/1.0/SecureElement.cpp +++ b/snxxx/1.0/SecureElement.cpp @@ -16,8 +16,10 @@ * ******************************************************************************/ #include "SecureElement.h" + #include #include + #include "NxpEse.h" #include "eSEClient.h" #include "hal_nxpese.h" @@ -502,8 +504,7 @@ SecureElement::internalCloseChannel(uint8_t channelNumber) { LOG(ERROR) << "Acquired the lock in SPI internalCloseChannel"; LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d", mMaxChannelCount, channelNumber); - if (channelNumber < DEFAULT_BASIC_CHANNEL || - channelNumber >= mMaxChannelCount) { + if (channelNumber >= mMaxChannelCount) { LOG(ERROR) << StringPrintf("invalid channel!!! %d for %d", channelNumber, mOpenedChannels[channelNumber]); sestatus = SecureElementStatus::FAILED; @@ -511,6 +512,11 @@ SecureElement::internalCloseChannel(uint8_t channelNumber) { 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 Suplementary Channel update CLA byte according to GP + if ((channelNumber > 0x03) && (channelNumber < 0x14)) { + /* update CLA byte accoridng 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 */ diff --git a/snxxx/1.0/SecureElement.h b/snxxx/1.0/SecureElement.h index f46b666..44d7e7b 100644 --- a/snxxx/1.0/SecureElement.h +++ b/snxxx/1.0/SecureElement.h @@ -24,6 +24,7 @@ #include #include #include + #include "phNxpEse_Api.h" class ThreadMutex { diff --git a/snxxx/1.0/VirtualISO.cpp b/snxxx/1.0/VirtualISO.cpp index e92bce8..0b3a383 100644 --- a/snxxx/1.0/VirtualISO.cpp +++ b/snxxx/1.0/VirtualISO.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright 2018-2020 NXP + * Copyright 2018-2021 NXP * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,9 @@ * ******************************************************************************/ #include "VirtualISO.h" + #include + #include "NxpEse.h" #include "SecureElement.h" #include "eSEClient.h" @@ -446,6 +448,11 @@ VirtualISO::internalCloseChannel(uint8_t channelNumber) { 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 Suplementary Channel update CLA byte according to GP + if ((channelNumber > 0x03) && (channelNumber < 0x14)) { + /* update CLA byte accoridng 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 */ diff --git a/snxxx/1.0/VirtualISO.h b/snxxx/1.0/VirtualISO.h index 9d7438f..322dc6b 100644 --- a/snxxx/1.0/VirtualISO.h +++ b/snxxx/1.0/VirtualISO.h @@ -23,6 +23,7 @@ #include #include #include + #include "phNxpEse_Api.h" namespace vendor { @@ -72,7 +73,6 @@ struct VirtualISO : public ISecureElement, public hidl_death_recipient { // T=1 stack // close(0); } - private: uint8_t mMaxChannelCount; uint8_t mOpenedchannelCount = 0; diff --git a/snxxx/1.1/NxpEseService.cpp b/snxxx/1.1/NxpEseService.cpp index dcb1541..3d23bb4 100755 --- a/snxxx/1.1/NxpEseService.cpp +++ b/snxxx/1.1/NxpEseService.cpp @@ -17,15 +17,16 @@ ******************************************************************************/ #define LOG_TAG "nxpese@1.1-service" #include +#include #include +#include #include -#include "VirtualISO.h" -#include -#include #include + #include "NxpEse.h" #include "SecureElement.h" +#include "VirtualISO.h" #include "eSEClient.h" // Generated HIDL files diff --git a/snxxx/1.1/SecureElement.cpp b/snxxx/1.1/SecureElement.cpp index 409811f..3a2834c 100755 --- a/snxxx/1.1/SecureElement.cpp +++ b/snxxx/1.1/SecureElement.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright 2018-2020 NXP + * Copyright 2018-2021 NXP * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,10 @@ * ******************************************************************************/ #include "SecureElement.h" + #include #include + #include "NxpEse.h" #include "eSEClient.h" #include "hal_nxpese.h" @@ -565,13 +567,17 @@ Return SecureElement::internalCloseChannel( LOG(ERROR) << "Acquired the lock in SPI internalCloseChannel"; LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d", mMaxChannelCount, channelNumber); - if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL || - channelNumber >= mMaxChannelCount) { + if (channelNumber >= mMaxChannelCount) { LOG(ERROR) << StringPrintf("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 Suplementary Channel update CLA byte according to GP + if ((channelNumber > 0x03) && (channelNumber < 0x14)) { + /* update CLA byte accoridng 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 */ diff --git a/snxxx/1.1/SecureElement.h b/snxxx/1.1/SecureElement.h index 5c15da1..4ed0b8f 100755 --- a/snxxx/1.1/SecureElement.h +++ b/snxxx/1.1/SecureElement.h @@ -26,6 +26,7 @@ #include #include #include + #include "phNxpEse_Api.h" class ThreadMutex { diff --git a/snxxx/1.1/VirtualISO.cpp b/snxxx/1.1/VirtualISO.cpp index aa0355e..432de16 100755 --- a/snxxx/1.1/VirtualISO.cpp +++ b/snxxx/1.1/VirtualISO.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright 2018-2020 NXP + * Copyright 2018-2021 NXP * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,9 @@ * ******************************************************************************/ #include "VirtualISO.h" + #include + #include "NxpEse.h" #include "SecureElement.h" #include "eSEClient.h" @@ -506,6 +508,11 @@ VirtualISO::internalCloseChannel(uint8_t channelNumber) { 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 Suplementary Channel update CLA byte according to GP + if ((channelNumber > 0x03) && (channelNumber < 0x14)) { + /* update CLA byte accoridng 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 */ diff --git a/snxxx/1.1/VirtualISO.h b/snxxx/1.1/VirtualISO.h index 504a535..fa38783 100755 --- a/snxxx/1.1/VirtualISO.h +++ b/snxxx/1.1/VirtualISO.h @@ -24,6 +24,7 @@ #include #include #include + #include "phNxpEse_Api.h" namespace vendor { @@ -79,7 +80,6 @@ struct VirtualISO : public ISecureElement, public hidl_death_recipient { // T=1 stack // close(0); } - private: uint8_t mMaxChannelCount; uint8_t mOpenedchannelCount = 0; diff --git a/snxxx/1.2/NxpEseService.cpp b/snxxx/1.2/NxpEseService.cpp index 7e9559a..eba57e0 100755 --- a/snxxx/1.2/NxpEseService.cpp +++ b/snxxx/1.2/NxpEseService.cpp @@ -16,20 +16,25 @@ * ******************************************************************************/ #define LOG_TAG "nxpese@1.2-service" +#include #include +#include #include +#include #include -#include "VirtualISO.h" -#include -#include #include + #include "NxpEse.h" #include "SecureElement.h" +#include "VirtualISO.h" #ifdef NXP_BOOTTIME_UPDATE #include "eSEClient.h" #endif +#define MAX_NFC_GET_RETRY 30 +#define NFC_GET_SERVICE_DELAY_MS 100 + // Generated HIDL files using android::OK; using android::base::StringPrintf; @@ -37,6 +42,7 @@ using android::hardware::configureRpcThreadpool; using android::hardware::defaultPassthroughServiceImplementation; using android::hardware::joinRpcThreadpool; using android::hardware::registerPassthroughServiceImplementation; +using android::hardware::nfc::V1_2::INfc; using android::hardware::secure_element::V1_2::ISecureElement; using android::hardware::secure_element::V1_2::implementation::SecureElement; using vendor::nxp::nxpese::V1_0::INxpEse; @@ -47,6 +53,25 @@ using android::OK; using android::sp; using android::status_t; +static inline void waitForNFCHAL() { + int retry = 0; + android::sp nfc_service = nullptr; + + ALOGI("Waiting for NFC HAL .. "); + do { + nfc_service = INfc::tryGetService(); + if (nfc_service != nullptr) { + ALOGI("NFC HAL service is registered"); + break; + } + /* Wait for 100 MS for HAL RETRY*/ + usleep(NFC_GET_SERVICE_DELAY_MS * 1000); + } while (retry++ < MAX_NFC_GET_RETRY); + if (nfc_service == nullptr) { + ALOGE("Failed to get NFC HAL Service"); + } +} + int main() { status_t status; @@ -58,8 +83,9 @@ int main() { android::sp nxp_se_service = nullptr; android::sp virtual_iso_service = nullptr; - ALOGI("Secure Element HAL Service 1.2 is starting."); try { + waitForNFCHAL(); + ALOGI("Secure Element HAL Service 1.2 is starting."); se_service = new SecureElement(); if (se_service == nullptr) { ALOGE("Can not create an instance of Secure Element HAL Iface, exiting."); @@ -104,6 +130,7 @@ int main() { ALOGI("Secure Element Service is ready"); } +#ifdef NXP_VISO_ENABLE ALOGI("Virtual ISO HAL Service 1.0 is starting."); virtual_iso_service = new VirtualISO(); if (virtual_iso_service == nullptr) { @@ -121,11 +148,12 @@ int main() { if (status != OK) { ALOGE("Could not register service for Virtual ISO HAL Iface (%d).", status); - } else { - ALOGI("Virtual ISO: Secure Element Service is ready"); + goto shutdown; } } + ALOGI("Virtual ISO: Secure Element Service is ready"); +#endif #ifdef NXP_BOOTTIME_UPDATE perform_eSEClientUpdate(); #endif diff --git a/snxxx/1.2/OsuHal/inc/OsuHalExtn.h b/snxxx/1.2/OsuHal/inc/OsuHalExtn.h index 6630d7a..3fb8a72 100644 --- a/snxxx/1.2/OsuHal/inc/OsuHalExtn.h +++ b/snxxx/1.2/OsuHal/inc/OsuHalExtn.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright 2020 NXP + * Copyright 2020-2021 NXP * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,9 +56,9 @@ class OsuHalExtn { INIT, OPENBASIC, OPENLOGICAL, + GETATR, TRANSMIT, CLOSE, - RESET, } SecureElementAPI; static OsuHalExtn& getInstance(); @@ -75,6 +75,7 @@ class OsuHalExtn { bool isAppOSUMode; bool isJcopOSUMode; static const hidl_vec osu_aid[10]; - OsuApduMode checkTransmit(uint8_t* input, size_t length, uint32_t* outLength); + OsuApduMode checkTransmit(uint8_t* input, uint32_t* outLength, + const hidl_vec& data); bool isOsuMode(); }; diff --git a/snxxx/1.2/OsuHal/src/OsuHalExtn.cpp b/snxxx/1.2/OsuHal/src/OsuHalExtn.cpp index 8fcffb7..0411c16 100644 --- a/snxxx/1.2/OsuHal/src/OsuHalExtn.cpp +++ b/snxxx/1.2/OsuHal/src/OsuHalExtn.cpp @@ -60,16 +60,21 @@ OsuHalExtn::OsuApduMode OsuHalExtn::isOsuMode(const hidl_vec& evt, } break; case TRANSMIT: - memcpy(pCmdData->p_data, evt.data(), evt.size()); - if (isOsuMode()) { - /* - * Process transmit request(unwrap APDU, proprietary actions) in OSU - * mode - */ - osuSubState = - checkTransmit(pCmdData->p_data, evt.size(), &pCmdData->len); + // Validate input data before processing + if (pCmdData != NULL && pCmdData->p_data != NULL) { + memcpy(pCmdData->p_data, evt.data(), evt.size()); + if (isOsuMode()) { + /* + * Process transmit request(unwrap APDU, proprietary actions) in OSU + * mode + */ + osuSubState = checkTransmit(pCmdData->p_data, &pCmdData->len, evt); + } else { + pCmdData->len = evt.size(); + osuSubState = NON_OSU_MODE; + } } else { - pCmdData->len = evt.size(); + if (pCmdData != NULL) pCmdData->len = evt.size(); osuSubState = NON_OSU_MODE; } break; @@ -95,6 +100,9 @@ bool OsuHalExtn::isOsuMode(uint8_t type, uint8_t channel) { case OPENLOGICAL: // No action, only return current mode break; + case GETATR: + // No action, only return current mode + break; case CLOSE: /* * If in OSU mode close basic channel is called @@ -188,10 +196,15 @@ bool OsuHalExtn::isOsuMode() { return (isAppOSUMode || isJcopOSUMode); } ** Returns: OsuApduMode ** *******************************************************************************/ -OsuHalExtn::OsuApduMode OsuHalExtn::checkTransmit(uint8_t* input, size_t length, - uint32_t* outLength) { +OsuHalExtn::OsuApduMode OsuHalExtn::checkTransmit( + uint8_t* input, uint32_t* outLength, const hidl_vec& data) { OsuHalExtn::OsuApduMode halMode = NON_OSU_MODE; + size_t length = data.size(); + // Validate input buffer processing + if (input == NULL) { + return halMode; + } /* * 1) Transmit request on logical channels(ISO7816_CLA_CHN_MASK)shall be * blocked in OSU mode @@ -215,8 +228,7 @@ OsuHalExtn::OsuApduMode OsuHalExtn::checkTransmit(uint8_t* input, size_t length, if (*(input + ISO7816_LC_OFFSET) != 0) { if (length > ISO7816_SHORT_APDU_HEADER) { *outLength = length - ISO7816_SHORT_APDU_HEADER; - memcpy(input, input + ISO7816_SHORT_APDU_HEADER, - length - ISO7816_SHORT_APDU_HEADER); + std::copy(data.begin() + ISO7816_SHORT_APDU_HEADER, data.end(), input); } else { *outLength = 0; ALOGE("checkTransmit input data length is incorrect"); @@ -224,8 +236,8 @@ OsuHalExtn::OsuApduMode OsuHalExtn::checkTransmit(uint8_t* input, size_t length, } else { if (length > ISO7816_EXTENDED_APDU_HEADER) { *outLength = length - ISO7816_EXTENDED_APDU_HEADER; - memcpy(input, input + ISO7816_EXTENDED_APDU_HEADER, - length - ISO7816_EXTENDED_APDU_HEADER); + std::copy(data.begin() + ISO7816_EXTENDED_APDU_HEADER, data.end(), + input); } else { *outLength = 0; ALOGE("checkTransmit input data length is incorrect"); diff --git a/snxxx/1.2/SecureElement.cpp b/snxxx/1.2/SecureElement.cpp index 4c6756d..520d545 100755 --- a/snxxx/1.2/SecureElement.cpp +++ b/snxxx/1.2/SecureElement.cpp @@ -16,15 +16,17 @@ * ******************************************************************************/ #include "SecureElement.h" + +#include "NxpEse.h" +#ifdef NXP_BOOTTIME_UPDATE +#include "eSEClient.h" +#endif #include #include -#include "NxpEse.h" + #include "hal_nxpese.h" #include "phNxpEse_Apdu_Api.h" #include "phNxpEse_Api.h" -#ifdef NXP_BOOTTIME_UPDATE -#include "eSEClient.h" -#endif /* Mutex to synchronize multiple transceive */ namespace android { @@ -37,6 +39,7 @@ namespace implementation { #define DEFAULT_BASIC_CHANNEL 0x00 #define INVALID_LEN_SW1 0x64 #define INVALID_LEN_SW2 0xFF +#define SW1_BYTES_REMAINING 0x61 typedef struct gsTransceiveBuffer { phNxpEse_data cmdData; @@ -44,6 +47,9 @@ typedef struct gsTransceiveBuffer { hidl_vec* pRspDataBuff; } sTransceiveBuffer_t; +static Return<::android::hardware::secure_element::V1_0::SecureElementStatus> +getResponseInternal(uint8_t cla, phNxpEse_7816_rpdu_t& rpdu, + hidl_vec& result); static sTransceiveBuffer_t gsTxRxBuffer; static hidl_vec gsRspDataBuff(256); sp SecureElement::mCallbackV1_0 = nullptr; @@ -198,8 +204,8 @@ Return SecureElement::getAtr(getAtr_cb _hidl_cb) { ESESTATUS status = ESESTATUS_FAILED; bool mIsSeHalInitDone = false; - if (IS_OSU_MODE(OsuHalExtn::getInstance().OPENLOGICAL) >= - OsuHalExtn::getInstance().OSU_PROP_MODE) { + // In dedicated mode getATR not allowed + if (IS_OSU_MODE(OsuHalExtn::getInstance().GETATR)) { LOG(ERROR) << "%s: Not allowed in dedicated mode!!!" << __func__; _hidl_cb(response); return Void(); @@ -336,8 +342,8 @@ Return SecureElement::openLogicalChannel(const hidl_vec& aid, LOG(INFO) << "Acquired the lock from SPI openLogicalChannel"; - if (IS_OSU_MODE(OsuHalExtn::getInstance().OPENLOGICAL) >= - OsuHalExtn::getInstance().OSU_PROP_MODE) { + // In dedicated mode openLogical not allowed + if (IS_OSU_MODE(OsuHalExtn::getInstance().OPENLOGICAL)) { LOG(ERROR) << "%s: Not allowed in dedicated mode!!!" << __func__; _hidl_cb(resApduBuff, SecureElementStatus::IOERROR); return Void(); @@ -467,6 +473,14 @@ Return SecureElement::openLogicalChannel(const hidl_vec& aid, resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2; resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1; + if (rpdu.sw1 == SW1_BYTES_REMAINING) { + sestatus = + getResponseInternal(cpdu.cla, rpdu, resApduBuff.selectResponse); + if (sestatus != SecureElementStatus::SUCCESS) { + LOG(ERROR) << "%s: getResponseInternal Failed" << __func__; + } + } + /*Status is success*/ if ((rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) || (rpdu.sw1 == 0x62) || (rpdu.sw1 == 0x63)) { @@ -609,6 +623,12 @@ Return SecureElement::openBasicChannel(const hidl_vec& aid, memcpy(&result[0], rpdu.pdata, rpdu.len); result[responseLen - 1] = rpdu.sw2; result[responseLen - 2] = rpdu.sw1; + if (rpdu.sw1 == SW1_BYTES_REMAINING) { + sestatus = getResponseInternal(cpdu.cla, rpdu, result); + if (sestatus != SecureElementStatus::SUCCESS) { + LOG(ERROR) << "%s: getResponseInternal Failed " << __func__; + } + } /*Status is success*/ if (((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) || (rpdu.sw1 == 0x62) || @@ -660,13 +680,17 @@ Return SecureElement::internalCloseChannel( LOG(ERROR) << "Acquired the lock in SPI internalCloseChannel"; LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d", mMaxChannelCount, channelNumber); - if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL || - channelNumber >= mMaxChannelCount) { + if (channelNumber >= mMaxChannelCount) { LOG(ERROR) << StringPrintf("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 Suplementary Channel update CLA byte according to GP + if ((channelNumber > 0x03) && (channelNumber < 0x14)) { + /* update CLA byte accoridng 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 */ @@ -704,8 +728,8 @@ Return SecureElement::internalCloseChannel( Return SecureElement::closeChannel(uint8_t channelNumber) { AutoMutex guard(seHalLock); - if (IS_OSU_MODE(OsuHalExtn::getInstance().CLOSE, channelNumber) == - OsuHalExtn::getInstance().NON_OSU_MODE) { + // Close internal allowed when not in dedicated Mode + if (!IS_OSU_MODE(OsuHalExtn::getInstance().CLOSE, channelNumber)) { return internalCloseChannel(channelNumber); } else { /*Decrement channel count opened to @@ -825,6 +849,67 @@ SecureElement::reset() { return sestatus; } +static Return<::android::hardware::secure_element::V1_0::SecureElementStatus> +getResponseInternal(uint8_t cla, phNxpEse_7816_rpdu_t& rpdu, + hidl_vec& result) { + SecureElementStatus sestatus = SecureElementStatus::SUCCESS; + ESESTATUS status = ESESTATUS_SUCCESS; + phNxpEse_data cmdApdu; + phNxpEse_data rspApdu; + uint16_t responseLen = rpdu.len; // Response already copied + uint8_t getRespLe = rpdu.sw2; // Response pending to receive + uint8_t getResponse[5] = {0x00, 0xC0, 0x00, 0x00, 0x00}; + + getResponse[0] = cla; + + phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data)); + + cmdApdu.len = (uint32_t)sizeof(getResponse); + cmdApdu.p_data = getResponse; + + do { + // update GET response 61 xx(Le) + getResponse[4] = getRespLe; + + phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data)); + + status = phNxpEse_Transceive(&cmdApdu, &rspApdu); + if (status != ESESTATUS_SUCCESS) { + /*Transceive failed*/ + if (rspApdu.len > 0 && (rspApdu.p_data[rspApdu.len - 2] == 0x64 && + rspApdu.p_data[rspApdu.len - 1] == 0xFF)) { + sestatus = SecureElementStatus::IOERROR; + } else { + sestatus = SecureElementStatus::FAILED; + } + break; + } else { + uint32_t respLen = rspApdu.len; + + // skip 2 bytes in case of 61xx SW again + if (rspApdu.p_data[respLen - 2] == SW1_BYTES_REMAINING) { + respLen -= 2; + getRespLe = rspApdu.p_data[respLen - 1]; + } + // copy response chunk received + result.resize(responseLen + respLen); + memcpy(&result[responseLen], rspApdu.p_data, respLen); + responseLen += respLen; + } + } while (rspApdu.p_data[rspApdu.len - 2] == SW1_BYTES_REMAINING); + + // Propagate SW as it is received from card + if (sestatus == SecureElementStatus::SUCCESS) { + rpdu.sw1 = rspApdu.p_data[rspApdu.len - 2]; + rpdu.sw2 = rspApdu.p_data[rspApdu.len - 1]; + } else { // Other Failure cases update failure SW:64FF + rpdu.sw1 = INVALID_LEN_SW1; + rpdu.sw2 = INVALID_LEN_SW2; + } + + return sestatus; +} + } // namespace implementation } // namespace V1_2 } // namespace secure_element diff --git a/snxxx/1.2/VirtualISO.cpp b/snxxx/1.2/VirtualISO.cpp index 4550605..44ece57 100755 --- a/snxxx/1.2/VirtualISO.cpp +++ b/snxxx/1.2/VirtualISO.cpp @@ -16,15 +16,17 @@ * ******************************************************************************/ #include "VirtualISO.h" -#include + +#include "NxpEse.h" #include "SecureElement.h" -#include "phNxpEse_Apdu_Api.h" -#include "phNxpEse_Api.h" #ifdef NXP_BOOTTIME_UPDATE #include "eSEClient.h" #endif -#include "NxpEse.h" +#include + #include "hal_nxpese.h" +#include "phNxpEse_Apdu_Api.h" +#include "phNxpEse_Api.h" namespace vendor { namespace nxp { @@ -522,6 +524,11 @@ VirtualISO::internalCloseChannel(uint8_t channelNumber) { 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 Suplementary Channel update CLA byte according to GP + if ((channelNumber > 0x03) && (channelNumber < 0x14)) { + /* update CLA byte accoridng 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 */ diff --git a/snxxx/1.2/VirtualISO.h b/snxxx/1.2/VirtualISO.h index b664fa0..af8b641 100755 --- a/snxxx/1.2/VirtualISO.h +++ b/snxxx/1.2/VirtualISO.h @@ -24,6 +24,7 @@ #include #include #include + #include "phNxpEse_Api.h" namespace vendor { @@ -77,7 +78,6 @@ struct VirtualISO : public ISecureElement, public hidl_death_recipient { // T=1 stack // close(0); } - private: uint8_t mMaxChannelCount; uint8_t mOpenedchannelCount = 0; diff --git a/snxxx/Android.bp b/snxxx/Android.bp index 6e7cbd6..1713d67 100755 --- a/snxxx/Android.bp +++ b/snxxx/Android.bp @@ -39,6 +39,7 @@ cc_binary { "vendor.nxp.nxpnfc@2.0", "android.hardware.nfc@1.0", "android.hardware.nfc@1.1", + "android.hardware.nfc@1.2", ], local_include_dirs: [ @@ -52,9 +53,11 @@ cc_binary { "libese-spi/p73/spm", "libese-spi/src/include", "1.2/OsuHal/inc", - "extns/impl", ], + include_dirs: [ + "hardware/nxp/secure_element/snxxx/extns/impl", + ], cflags: [ "-DANDROID", "-DJCOP_VER_3_1=1", diff --git a/snxxx/ese-clients/inc/eSEClient.h b/snxxx/ese-clients/inc/eSEClient.h index 425cada..f8752f3 100644 --- a/snxxx/ese-clients/inc/eSEClient.h +++ b/snxxx/ese-clients/inc/eSEClient.h @@ -17,6 +17,7 @@ ******************************************************************************/ #include + #include "../../../secure_element_extns/inc/eSEClientIntf.h" #include "phNxpEse_Api.h" diff --git a/snxxx/ese-clients/src/eSEClient.cpp b/snxxx/ese-clients/src/eSEClient.cpp index f87e80c..1ee1e8c 100644 --- a/snxxx/ese-clients/src/eSEClient.cpp +++ b/snxxx/ese-clients/src/eSEClient.cpp @@ -17,6 +17,7 @@ ******************************************************************************/ #include "eSEClient.h" + #include #include #include @@ -29,6 +30,7 @@ #include #include #include + #include "NfcAdaptation.h" #include "NxpEse.h" #include "hal_nxpese.h" diff --git a/snxxx/extns/impl/NxpEse.cpp b/snxxx/extns/impl/NxpEse.cpp index c72d162..370ce51 100755 --- a/snxxx/extns/impl/NxpEse.cpp +++ b/snxxx/extns/impl/NxpEse.cpp @@ -16,12 +16,13 @@ * ******************************************************************************/ #include "NxpEse.h" -#include -#include -#include "phNxpEse_Api.h" #ifdef NXP_BOOTTIME_UPDATE #include "eSEClient.h" #endif +#include +#include + +#include "phNxpEse_Api.h" namespace vendor { namespace nxp { diff --git a/snxxx/libese-spi/Android.bp b/snxxx/libese-spi/Android.bp index 1fb7ebf..4563037 100755 --- a/snxxx/libese-spi/Android.bp +++ b/snxxx/libese-spi/Android.bp @@ -31,13 +31,15 @@ cc_library_shared { ], local_include_dirs: [ + "p73/lib", + "p73/pal/spi", + "p73/utils", + ], + export_include_dirs: [ "common/include", "p73/common", "p73/inc", - "p73/lib", "p73/pal", - "p73/pal/spi", - "p73/utils", "src/include", ], include_dirs: [ diff --git a/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp b/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp index bf1aad2..d6df6da 100755 --- a/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp +++ b/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp @@ -189,7 +189,7 @@ static ESESTATUS TransceiveProcess(void); * \ingroup ISO7816-3_protocol_lib * \brief This internal function is used to * 1. Send propreitary S-Frame command for resynch - *T=1 sequence at client + *T=1 sequence at worker * */ static ESESTATUS phNxpEseProto7816_RSync(void); @@ -1226,8 +1226,9 @@ static ESESTATUS phNxpEseProto7816_DecodeFrame(uint8_t* p_data, phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = SFRAME; if (frameType != WTX_REQ) { phNxpEseProto7816_CheckAndNotifyWtx(WTX_END); + phNxpEseProto7816_ResetRecovery(); } - phNxpEseProto7816_ResetRecovery(); + switch (frameType) { case RESYNCH_REQ: phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType = diff --git a/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h b/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h index 8a22daa..70f4617 100755 --- a/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h +++ b/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h @@ -193,14 +193,14 @@ typedef struct phNxpEseProto7816_ATR_Info { uint8_t numChannels; /*!< ATR: Number of logical connections supported */ uint8_t maxIFSC[2]; /*!< ATR: Maximum size of IFS supported */ uint8_t capabilities[2]; /*!< ATR: Bitmap to indicate various features - supported by SE Bit-1: SE Data Available Line - supported. Bit-2: SE Data available polarity. 1 - Data - available GPIO will be pulled HIGH when SE response is - ready Bit 3: SE chip reset S-blk command supported - Bit-4: Extended frame length feature supported Bit-5: - Support for more than one logical channel Bit 6 to 16: - Reserved for future use - */ + supported by SE Bit-1: SE Data Available Line supported. + Bit-2: SE Data available polarity. 1 - Data available + GPIO will be pulled HIGH when SE response is ready Bit + 3: SE chip reset S-blk command supported Bit-4: Extended + frame length feature supported Bit-5: Support for more + than one logical channel Bit 6 to 16: Reserved for + future use + */ } phNxpEseProto7816_ATR_Info_t; typedef struct phNxpEseProto7816_ATR_Info2 { diff --git a/snxxx/libese-spi/p73/lib/phNxpEse_Api.cpp b/snxxx/libese-spi/p73/lib/phNxpEse_Api.cpp index a5b63d7..da6a0e1 100755 --- a/snxxx/libese-spi/p73/lib/phNxpEse_Api.cpp +++ b/snxxx/libese-spi/p73/lib/phNxpEse_Api.cpp @@ -133,10 +133,10 @@ void phNxpLog_InitializeLogLevel() { * * Description This function is called by Jni/phNxpEse_open during the * initialization of the ESE. It initializes protocol stack - *instance variable + * instance variable * * Returns This function return ESESTATUS_SUCCESS (0) in case of - *success In case of failure returns other failure value. + * success In case of failure returns other failure value. * ******************************************************************************/ ESESTATUS phNxpEse_init(phNxpEse_initParams initParams) { @@ -278,6 +278,7 @@ ESESTATUS phNxpEse_init(phNxpEse_initParams initParams) { * thread for operation. * Returns This function return ESESTATUS_SUCCESS (0) in case of * success. In case of failure returns other failure values. + * ******************************************************************************/ ESESTATUS phNxpEse_open(phNxpEse_initParams initParams) { phPalEse_Config_t tPalConfig; @@ -1381,7 +1382,7 @@ static int phNxpEse_readPacket(void* pDevHandle, uint8_t* pBuffer, /*For I-Frame Only*/ if (0 == pcb_bits.msb) { if (pBuffer[2] != EXTENDED_FRAME_MARKER) { - nNbBytesToRead = pBuffer[2]; + nNbBytesToRead = (pBuffer[2] & 0x000000FF); headerIndex = 3; } else { ret = phPalEse_read(pDevHandle, &pBuffer[3], 2); @@ -1406,7 +1407,7 @@ static int phNxpEse_readPacket(void* pDevHandle, uint8_t* pBuffer, } } else { /*For Non-IFrame*/ - nNbBytesToRead = (int)pBuffer[2]; + nNbBytesToRead = (pBuffer[2] & 0x000000FF); headerIndex = 3; } if (!flushData) { @@ -1535,7 +1536,7 @@ static int phNxpEse_readPacket_legacy(void* pDevHandle, uint8_t* pBuffer, poll_sof_chained_delay); } total_count = 3; - nNbBytesToRead = (int)pBuffer[2]; + nNbBytesToRead = (pBuffer[2] & 0x000000FF); /* Read the Complete data + one byte CRC*/ ret = phPalEse_read(pDevHandle, &pBuffer[3], (nNbBytesToRead + 1)); if (ret < 0) { diff --git a/snxxx/libese-spi/src/include/NfcAdaptation.h b/snxxx/libese-spi/src/include/NfcAdaptation.h index 18720f6..10c0545 100644 --- a/snxxx/libese-spi/src/include/NfcAdaptation.h +++ b/snxxx/libese-spi/src/include/NfcAdaptation.h @@ -16,13 +16,13 @@ * ******************************************************************************/ #pragma once -#include - #include #include #include +#include #include #include + #include "hal_nxpese.h" using vendor::nxp::nxpnfc::V2_0::INxpNfc; -- cgit v1.2.3