diff options
| author | Bill Yi <byi@google.com> | 2018-11-28 18:34:30 -0800 |
|---|---|---|
| committer | Bill Yi <byi@google.com> | 2018-11-28 18:34:30 -0800 |
| commit | cec735a56f472890bd2fd5cceddc1f5b136e4ad3 (patch) | |
| tree | d92e91a73021d0beb1202ef5a13c07ad57cfd084 | |
| parent | e737b7d63275fe81bcedd3b745abff7dfda1c088 (diff) | |
| parent | b25f0f974988e57cba44855193919d3182b42cab (diff) | |
| download | platform_hardware_nxp_secure_element-pie-cuttlefish-testing.tar.gz platform_hardware_nxp_secure_element-pie-cuttlefish-testing.tar.bz2 platform_hardware_nxp_secure_element-pie-cuttlefish-testing.zip | |
Merge pi-qpr1-release PQ1A.181105.017.A1 to pi-platform-releasepie-platform-releasepie-cuttlefish-testing
Change-Id: I098c224e8646e610dcfde3eb5ef018f651bc8e34
| -rw-r--r-- | 1.0/android.hardware.secure_element@1.0-service-disabled.rc | 5 | ||||
| -rw-r--r-- | 1.0/android.hardware.secure_element@1.0-service.rc | 1 | ||||
| -rwxr-xr-x[-rw-r--r--] | Android.bp | 19 | ||||
| -rwxr-xr-x[-rw-r--r--] | ls_client/inc/LsClient.h | 4 | ||||
| -rwxr-xr-x[-rw-r--r--] | ls_client/inc/LsLib.h | 87 | ||||
| -rwxr-xr-x[-rw-r--r--] | ls_client/src/LsClient.cpp | 210 | ||||
| -rwxr-xr-x[-rw-r--r--] | ls_client/src/LsLib.cpp | 429 |
7 files changed, 564 insertions, 191 deletions
diff --git a/1.0/android.hardware.secure_element@1.0-service-disabled.rc b/1.0/android.hardware.secure_element@1.0-service-disabled.rc new file mode 100644 index 0000000..bb6ea2f --- /dev/null +++ b/1.0/android.hardware.secure_element@1.0-service-disabled.rc @@ -0,0 +1,5 @@ +service secure_element_hal_service /vendor/bin/hw/android.hardware.secure_element@1.0-service-disabled + disabled + interface android.hardware.secure_element@1.0::ISecureElement eSE1 + user secure_element + group secure_element diff --git a/1.0/android.hardware.secure_element@1.0-service.rc b/1.0/android.hardware.secure_element@1.0-service.rc index e446ada..f1e0966 100644 --- a/1.0/android.hardware.secure_element@1.0-service.rc +++ b/1.0/android.hardware.secure_element@1.0-service.rc @@ -1,4 +1,5 @@ service secure_element_hal_service /vendor/bin/hw/android.hardware.secure_element@1.0-service class hal + interface android.hardware.secure_element@1.0::ISecureElement eSE1 user secure_element group secure_element diff --git a/Android.bp b/Android.bp index 24fd3cd..e76951c 100644..100755 --- a/Android.bp +++ b/Android.bp @@ -71,17 +71,18 @@ cc_library_shared { shared_libs: [ "ese_spi_nxp", "android.hardware.secure_element@1.0", + "libcutils", "liblog", "libhidlbase", "liblog", "libutils", + "libcrypto" ], } -cc_binary { - name: "android.hardware.secure_element@1.0-service", +cc_defaults { + name: "android.hardware.secure_element@1.0_defaults", relative_install_path: "hw", - init_rc: ["1.0/android.hardware.secure_element@1.0-service.rc"], proprietary: true, defaults: ["hidl_defaults"], srcs: [ @@ -106,3 +107,15 @@ cc_binary { "vendor.nxp.nxpnfc@1.0", ], } + +cc_binary { + name: "android.hardware.secure_element@1.0-service", + init_rc: ["1.0/android.hardware.secure_element@1.0-service.rc"], + defaults: ["android.hardware.secure_element@1.0_defaults"], +} + +cc_binary { + name: "android.hardware.secure_element@1.0-service-disabled", + init_rc: ["1.0/android.hardware.secure_element@1.0-service-disabled.rc"], + defaults: ["android.hardware.secure_element@1.0_defaults"], +} diff --git a/ls_client/inc/LsClient.h b/ls_client/inc/LsClient.h index c2e9e01..01facdb 100644..100755 --- a/ls_client/inc/LsClient.h +++ b/ls_client/inc/LsClient.h @@ -24,7 +24,9 @@ typedef enum { LSCSTATUS_SUCCESS = (0x0000), LSCSTATUS_FAILED = (0x0003), - LSCSTATUS_FILE_NOT_FOUND = (0x0005) + LSCSTATUS_SELF_UPDATE_DONE = (0x0005), + LSCSTATUS_HASH_SLOT_EMPTY = (0x0006), + LSCSTATUS_HASH_SLOT_INVALID = (0x0007) } LSCSTATUS; using ::android::hardware::secure_element::V1_0::ISecureElementHalCallback; diff --git a/ls_client/inc/LsLib.h b/ls_client/inc/LsLib.h index 44e77ab..b7f8329 100644..100755 --- a/ls_client/inc/LsLib.h +++ b/ls_client/inc/LsLib.h @@ -48,8 +48,16 @@ typedef struct Lsc_ImageInfo { int bytes_wrote; Lsc_ChannelInfo_t Channel_Info[10]; uint8_t channel_cnt; + uint8_t initChannelNum; } Lsc_ImageInfo_t; +typedef struct Lsc_HashInfo { + uint16_t readHashLen; + uint8_t* lsRawScriptBuf = nullptr; + uint8_t* lsScriptHash = nullptr; + uint8_t* readBuffHash = nullptr; +} Lsc_HashInfo_t; + typedef enum { LS_Default = 0x00, LS_Cert = 0x7F21, @@ -60,21 +68,13 @@ typedef enum { static uint8_t OpenChannel[] = {0x00, 0x70, 0x00, 0x00, 0x01}; static uint8_t GetData[] = {0x80, 0xCA, 0x00, 0x46, 0x00}; -static uint8_t SelectLsc[] = {0x00, 0xA4, 0x04, 0x00, 0x0F, 0xA0, 0x00, - 0x00, 0x03, 0x96, 0x54, 0x43, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x0B, 0x00, 0x01}; - -/*LSC2*/ -#define NOOFAIDS 0x03 -#define LENOFAIDS 0x16 +static const uint8_t SelectLsc[] = {0xA4, 0x04, 0x00, 0x0E, 0xA0, 0x00, + 0x00, 0x03, 0x96, 0x54, 0x43, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00}; -static uint8_t ArrayOfAIDs[NOOFAIDS][LENOFAIDS] = { - {0x14, 0x00, 0xA4, 0x04, 0x00, 0x0F, 0xA0, 0x00, 0x00, 0x03, 0x96, - 0x54, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x02, 0x00}, - {0x14, 0x00, 0xA4, 0x04, 0x00, 0x0F, 0xA0, 0x00, 0x00, 0x03, 0x96, - 0x54, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x01, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; +static uint8_t SelectLscSlotHash[] = {0x00, 0xA4, 0x04, 0x00, 0x10, 0xA0, 0x00, + 0x00, 0x03, 0x96, 0x54, 0x53, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, 0x00}; #define TAG_CERTIFICATE 0x7F21 #define TAG_LSES_RESP 0x4E @@ -97,7 +97,6 @@ static uint8_t ArrayOfAIDs[NOOFAIDS][LENOFAIDS] = { #define LS_ABORT_SW1 0x69 #define LS_ABORT_SW2 0x87 -#define AID_MEM_PATH "/data/vendor/secure_element/AID_MEM.txt" #define LS_STATUS_PATH "/data/vendor/secure_element/LS_Status.txt" #define LS_SRC_BACKUP "/data/vendor/secure_element/LS_Src_Backup.txt" #define LS_DST_BACKUP "/data/vendor/secure_element/LS_Dst_Backup.txt" @@ -162,6 +161,19 @@ static LSCSTATUS LSC_OpenChannel(Lsc_ImageInfo_t* pContext, LSCSTATUS status, /******************************************************************************* ** +** Function: LSC_ResetChannel +** +** Description: Reset(Open & Close) next available logical channel +** +** Returns: Success if ok. +** +*******************************************************************************/ +static LSCSTATUS LSC_ResetChannel(Lsc_ImageInfo_t* pContext, LSCSTATUS status, + Lsc_TranscieveInfo_t* pInfo) + __attribute__((unused)); + +/******************************************************************************* +** ** Function: LSC_SelectLsc ** ** Description: Creates the logical channel with lsc @@ -451,6 +463,51 @@ LSCSTATUS Process_SelectRsp(uint8_t* Recv_data, int32_t Recv_len); /******************************************************************************* ** +** Function: LSC_CloseAllLogicalChannels +** +** Description: Close all opened logical channels +** +** Returns: SUCCESS/FAILURE +** +*******************************************************************************/ +LSCSTATUS LSC_CloseAllLogicalChannels(Lsc_ImageInfo_t* Os_info); + +/******************************************************************************* +** +** Function: LSC_SelectLsHash +** +** Description: Selects LS Hash applet +** +** Returns: SUCCESS/FAILURE +** +*******************************************************************************/ + +LSCSTATUS LSC_SelectLsHash(); + +/******************************************************************************* +** +** Function: LSC_ReadLsHash +** +** Description: Read the LS SHA1 for the intended slot +** +** Returns: SUCCESS/FAILURE +** +*******************************************************************************/ +LSCSTATUS LSC_ReadLsHash(uint8_t* hash, uint16_t* readHashLen, uint8_t slotId); + +/******************************************************************************* +** +** Function: LSC_UpdateLsHash +** +** Description: Updates SHA1 of LS script to the respective Slot ID +** +** Returns: Update status +** +*******************************************************************************/ +LSCSTATUS LSC_UpdateLsHash(uint8_t* hash, long hashLen, uint8_t slotId); + +/******************************************************************************* +** ** Function: Numof_lengthbytes ** ** Description: Checks the number of length bytes and assigns diff --git a/ls_client/src/LsClient.cpp b/ls_client/src/LsClient.cpp index 8922f38..50ea3d1 100644..100755 --- a/ls_client/src/LsClient.cpp +++ b/ls_client/src/LsClient.cpp @@ -17,16 +17,54 @@ ******************************************************************************/ #define LOG_TAG "LSClient" #include "LsClient.h" +#include <cutils/properties.h> #include <dirent.h> #include <log/log.h> +#include <openssl/evp.h> #include <pthread.h> #include <stdlib.h> +#include <string> #include "LsLib.h" uint8_t datahex(char c); +unsigned char* getHASH(uint8_t* buffer, size_t buffSize); extern bool ese_debug_enabled; + +#define ls_script_source_prefix "/vendor/etc/loaderservice_updater_" +#define ls_script_source_suffix ".lss" +#define ls_script_output_prefix \ + "/data/vendor/secure_element/loaderservice_updater_out_" +#define ls_script_output_suffix ".txt" +const size_t HASH_DATA_LENGTH = 21; +const uint16_t HASH_STATUS_INDEX = 20; +const uint8_t LS_MAX_COUNT = 10; +const uint8_t LS_DOWNLOAD_SUCCESS = 0x00; +const uint8_t LS_DOWNLOAD_FAILED = 0x01; + static android::sp<ISecureElementHalCallback> cCallback; void* performLSDownload_thread(void* data); +static void getLSScriptSourcePrefix(std::string& prefix); + +void getLSScriptSourcePrefix(std::string& prefix) { + char source_path[PROPERTY_VALUE_MAX] = {0}; + int len = property_get("vendor.ese.loader_script_path", source_path, ""); + if (len > 0) { + FILE* fd = fopen(source_path, "rb"); + if (fd != NULL) { + char c; + while (!feof(fd) && fread(&c, 1, 1, fd) == 1) { + if (c == ' ' || c == '\n' || c == '\r' || c == 0x00) break; + prefix.push_back(c); + } + } else { + ALOGD("%s Cannot open file %s\n", __func__, source_path); + } + } + if (prefix.empty()) { + prefix.assign(ls_script_source_prefix); + } +} + /******************************************************************************* ** ** Function: LSC_Start @@ -88,13 +126,7 @@ LSCSTATUS LSC_doDownload( ** *******************************************************************************/ void* performLSDownload_thread(__attribute__((unused)) void* data) { - ALOGD_IF(ese_debug_enabled, "%s enter: ", __func__); - - const char* lsUpdateBackupPath = - "/data/vendor/secure_element/loaderservice_updater.txt"; - const char* lsUpdateBackupOutPath = - "/data/vendor/secure_element/loaderservice_updater_out.txt"; - + ALOGD_IF(ese_debug_enabled, "%s enter ", __func__); /*generated SHA-1 string for secureElementLS This will remain constant as handled in secureElement HAL*/ char sha1[] = "6d583e84f2710e6b0f06beebc1a12a1083591373"; @@ -106,64 +138,122 @@ void* performLSDownload_thread(__attribute__((unused)) void* data) { } uint8_t resSW[4] = {0x4e, 0x02, 0x69, 0x87}; - FILE* fIn = fopen(lsUpdateBackupPath, "rb"); - if (fIn == NULL) { - ALOGE("%s Cannot open LS script file %s\n", __func__, lsUpdateBackupPath); - ALOGE("%s Error : %s", __func__, strerror(errno)); - cCallback->onStateChange(true); - } else { + + std::string sourcePath; + std::string sourcePrefix; + std::string outPath; + int index = 1; + LSCSTATUS status = LSCSTATUS_SUCCESS; + Lsc_HashInfo_t lsHashInfo; + + getLSScriptSourcePrefix(sourcePrefix); + do { + /*Open the script file from specified location and name*/ + sourcePath.assign(sourcePrefix); + sourcePath += ('0' + index); + sourcePath += ls_script_source_suffix; + FILE* fIn = fopen(sourcePath.c_str(), "rb"); + if (fIn == NULL) { + ALOGE("%s Cannot open LS script file %s\n", __func__, sourcePath.c_str()); + ALOGE("%s Error : %s", __func__, strerror(errno)); + break; + } ALOGD_IF(ese_debug_enabled, "%s File opened %s\n", __func__, - lsUpdateBackupPath); + sourcePath.c_str()); + + /*Read the script content to a local buffer*/ fseek(fIn, 0, SEEK_END); - long fsize = ftell(fIn); + long lsBufSize = ftell(fIn); rewind(fIn); + if (lsHashInfo.lsRawScriptBuf == nullptr) { + lsHashInfo.lsRawScriptBuf = (uint8_t*)phNxpEse_memalloc(lsBufSize + 1); + } + memset(lsHashInfo.lsRawScriptBuf, 0x00, (lsBufSize + 1)); + fread(lsHashInfo.lsRawScriptBuf, lsBufSize, 1, fIn); - char* lsUpdateBuf = (char*)phNxpEse_memalloc(fsize + 1); - fread(lsUpdateBuf, fsize, 1, fIn); + LSCSTATUS lsHashStatus = LSCSTATUS_FAILED; - FILE* fOut = fopen(lsUpdateBackupOutPath, "wb+"); - if (fOut == NULL) { - ALOGE("%s Failed to open file %s\n", __func__, lsUpdateBackupOutPath); - phNxpEse_free(lsUpdateBuf); - pthread_exit(NULL); - cCallback->onStateChange(true); - return NULL; + /*Get 20bye SHA1 of the script*/ + lsHashInfo.lsScriptHash = + getHASH(lsHashInfo.lsRawScriptBuf, (size_t)lsBufSize); + phNxpEse_free(lsHashInfo.lsRawScriptBuf); + lsHashInfo.lsRawScriptBuf = nullptr; + if (lsHashInfo.lsScriptHash == nullptr) break; + + if (lsHashInfo.readBuffHash == nullptr) { + lsHashInfo.readBuffHash = (uint8_t*)phNxpEse_memalloc(HASH_DATA_LENGTH); } + memset(lsHashInfo.readBuffHash, 0x00, HASH_DATA_LENGTH); - long size = fwrite(lsUpdateBuf, 1, fsize, fOut); - if (size != fsize) { - ALOGE("%s ERROR - Failed to write %ld bytes to file\n", __func__, fsize); - phNxpEse_free(lsUpdateBuf); - pthread_exit(NULL); - cCallback->onStateChange(true); - return NULL; + /*Read the hash from applet for specified slot*/ + lsHashStatus = + LSC_ReadLsHash(lsHashInfo.readBuffHash, &lsHashInfo.readHashLen, index); + + /*Check if previously script is successfully installed. + if yes, continue reading next script else try update wit current script*/ + if ((lsHashStatus == LSCSTATUS_SUCCESS) && + (lsHashInfo.readHashLen == HASH_DATA_LENGTH) && + (0 == memcmp(lsHashInfo.lsScriptHash, lsHashInfo.readBuffHash, + HASH_DATA_LENGTH)) && + (lsHashInfo.readBuffHash[HASH_STATUS_INDEX] == LS_DOWNLOAD_SUCCESS)) { + ALOGD_IF(ese_debug_enabled, "%s LS Loader sript is already installed \n", + __func__); + continue; } - LSCSTATUS status = LSC_Start(lsUpdateBackupPath, lsUpdateBackupOutPath, - (uint8_t*)hash, (uint16_t)sizeof(hash), resSW); - ALOGD_IF(ese_debug_enabled, "%s LSC_Start completed\n", __func__); - if (status == LSCSTATUS_SUCCESS) { - if (remove(lsUpdateBackupPath) == 0) { - ALOGD_IF(ese_debug_enabled, "%s : %s file deleted successfully\n", - __func__, lsUpdateBackupPath); - } else { - ALOGD_IF(ese_debug_enabled, "%s : %s file deletion failed!!!\n", - __func__, lsUpdateBackupPath); + /*Create output file to write response data*/ + outPath.assign(ls_script_output_prefix); + outPath += ('0' + index); + outPath += ls_script_output_suffix; + + FILE* fOut = fopen(outPath.c_str(), "wb+"); + if (fOut == NULL) { + ALOGE("%s Failed to open file %s\n", __func__, outPath.c_str()); + break; + } + fclose(fOut); + + /*Uptdates current script*/ + status = LSC_Start(sourcePath.c_str(), outPath.c_str(), (uint8_t*)hash, + (uint16_t)sizeof(hash), resSW); + ALOGD_IF(ese_debug_enabled, "%s script %s perform done, result = %d\n", + __func__, sourcePath.c_str(), status); + if (status != LSCSTATUS_SUCCESS) { + lsHashInfo.lsScriptHash[HASH_STATUS_INDEX] = LS_DOWNLOAD_FAILED; + /*If current script updation fails, update the status with hash to the + * applet then clean and exit*/ + lsHashStatus = + LSC_UpdateLsHash(lsHashInfo.lsScriptHash, HASH_DATA_LENGTH, index); + if (lsHashStatus != LSCSTATUS_SUCCESS) { + ALOGD_IF(ese_debug_enabled, "%s LSC_UpdateLsHash Failed\n", __func__); } - cCallback->onStateChange(true); - } else { - ESESTATUS status = phNxpEse_deInit(); - if (status == ESESTATUS_SUCCESS) { - status = phNxpEse_close(); - if (status == ESESTATUS_SUCCESS) { + ESESTATUS estatus = phNxpEse_deInit(); + if (estatus == ESESTATUS_SUCCESS) { + estatus = phNxpEse_close(); + if (estatus == ESESTATUS_SUCCESS) { ALOGD_IF(ese_debug_enabled, "%s: Ese_close success\n", __func__); } } else { ALOGE("%s: Ese_deInit failed", __func__); } cCallback->onStateChange(false); + break; + } else { + /*If current script execution is succes, update the status along with the + * hash to the applet*/ + lsHashInfo.lsScriptHash[HASH_STATUS_INDEX] = LS_DOWNLOAD_SUCCESS; + lsHashStatus = + LSC_UpdateLsHash(lsHashInfo.lsScriptHash, HASH_DATA_LENGTH, index); + if (lsHashStatus != LSCSTATUS_SUCCESS) { + ALOGD_IF(ese_debug_enabled, "%s LSC_UpdateLsHash Failed\n", __func__); + } } - phNxpEse_free(lsUpdateBuf); + } while (++index <= LS_MAX_COUNT); + + phNxpEse_free(lsHashInfo.readBuffHash); + + if (status == LSCSTATUS_SUCCESS) { + cCallback->onStateChange(true); } pthread_exit(NULL); ALOGD_IF(ese_debug_enabled, "%s pthread_exit\n", __func__); @@ -172,6 +262,30 @@ void* performLSDownload_thread(__attribute__((unused)) void* data) { /******************************************************************************* ** +** Function: getHASH +** +** Description: generates SHA1 of given buffer +** +** Returns: 20 bytes of SHA1 +** +*******************************************************************************/ +unsigned char* getHASH(uint8_t* buffer, size_t buffSize) { + static uint8_t outHash[HASH_DATA_LENGTH] = {0}; + unsigned int md_len = -1; + const EVP_MD* md = EVP_get_digestbyname("SHA1"); + if (NULL != md) { + EVP_MD_CTX mdctx; + EVP_MD_CTX_init(&mdctx); + EVP_DigestInit_ex(&mdctx, md, NULL); + EVP_DigestUpdate(&mdctx, buffer, buffSize); + EVP_DigestFinal_ex(&mdctx, outHash, &md_len); + EVP_MD_CTX_cleanup(&mdctx); + } + return outHash; +} + +/******************************************************************************* +** ** Function: datahex ** ** Description: Converts char to uint8_t diff --git a/ls_client/src/LsLib.cpp b/ls_client/src/LsLib.cpp index 0a43c7f..0e8f129 100644..100755 --- a/ls_client/src/LsLib.cpp +++ b/ls_client/src/LsLib.cpp @@ -39,7 +39,8 @@ static int32_t gsResp_len = 0; LSCSTATUS(*Applet_load_seqhandler[]) (Lsc_ImageInfo_t* pContext, LSCSTATUS status, Lsc_TranscieveInfo_t* pInfo) = { - LSC_OpenChannel, LSC_SelectLsc, LSC_StoreData, LSC_loadapplet, NULL}; + LSC_OpenChannel, LSC_ResetChannel, LSC_SelectLsc, + LSC_StoreData, LSC_loadapplet, NULL}; /******************************************************************************* ** @@ -119,6 +120,12 @@ LSCSTATUS LSC_update_seq_handler( ALOGE("%s: exiting; status=0x0%X", fn, status); break; } + + if ((seq_counter == 0x00) && + update_info.Channel_Info[update_info.channel_cnt - 1].isOpend) { + update_info.initChannelNum = + update_info.Channel_Info[update_info.channel_cnt - 1].channel_id; + } seq_counter++; } @@ -179,6 +186,69 @@ LSCSTATUS LSC_OpenChannel(Lsc_ImageInfo_t* Os_info, LSCSTATUS status, ALOGD_IF(ese_debug_enabled, "%s: exit; status=0x%x", fn, status); return status; } +/******************************************************************************* +** +** Function: LSC_ResetChannel +** +** Description: Reset(Open & Close) next available logical channel +** +** Returns: Success if ok. +** +*******************************************************************************/ +LSCSTATUS LSC_ResetChannel(Lsc_ImageInfo_t* Os_info, LSCSTATUS status, + Lsc_TranscieveInfo_t* pTranscv_Info) { + static const char fn[] = "LSC_ResetChannel"; + + ALOGD_IF(ese_debug_enabled, "%s: enter", fn); + if (Os_info == NULL || pTranscv_Info == NULL) { + ALOGE("%s: Invalid parameter", fn); + return LSCSTATUS_FAILED; + } + + ESESTATUS eseStat = ESESTATUS_FAILED; + bool bResetCompleted = false; + phNxpEse_data cmdApdu; + phNxpEse_data rspApdu; + phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data)); + phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data)); + cmdApdu.len = (int32_t)sizeof(OpenChannel); + cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t)); + memcpy(cmdApdu.p_data, OpenChannel, cmdApdu.len); + + do { + ALOGD_IF(ese_debug_enabled, "%s: Calling Secure Element Transceive", fn); + eseStat = phNxpEse_Transceive(&cmdApdu, &rspApdu); + if (eseStat != ESESTATUS_SUCCESS && (rspApdu.len < 0x03)) { + status = LSCSTATUS_FAILED; + ALOGE("%s: SE transceive failed status = 0x%X", fn, status); + } else if (((rspApdu.p_data[rspApdu.len - 2] != 0x90) && + (rspApdu.p_data[rspApdu.len - 1] != 0x00))) { + status = LSCSTATUS_FAILED; + ALOGE("%s: invalid response = 0x%X", fn, status); + } else if (!bResetCompleted) { + /*close the previously opened channel*/ + uint8_t xx = 0; + cmdApdu.p_data[xx++] = rspApdu.p_data[rspApdu.len - 3]; /*channel id*/ + cmdApdu.p_data[xx++] = 0x70; + cmdApdu.p_data[xx++] = 0x80; + cmdApdu.p_data[xx++] = rspApdu.p_data[rspApdu.len - 3]; + cmdApdu.p_data[xx++] = 0x00; + cmdApdu.len = 5; + bResetCompleted = true; + phNxpEse_free(rspApdu.p_data); + status = LSCSTATUS_SUCCESS; + } else { + ALOGD_IF(ese_debug_enabled, "%s: Channel reset success", fn); + status = LSCSTATUS_SUCCESS; + break; + } + } while (status == LSCSTATUS_SUCCESS); + + phNxpEse_free(cmdApdu.p_data); + phNxpEse_free(rspApdu.p_data); + ALOGD_IF(ese_debug_enabled, "%s: exit; status=0x%x", fn, status); + return status; +} /******************************************************************************* ** @@ -207,73 +277,33 @@ LSCSTATUS LSC_SelectLsc(Lsc_ImageInfo_t* Os_info, LSCSTATUS status, phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data)); phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data)); - uint8_t selectCnt = 3; - while ((selectCnt--) > 0) { - if (selectCnt == 2) { - cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc( - ((ArrayOfAIDs[selectCnt - 1][0]) - 1) * sizeof(uint8_t)); - cmdApdu.len = (int32_t)ArrayOfAIDs[selectCnt - 1][0]; - } else { - cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc( - ((ArrayOfAIDs[selectCnt][0]) - 1) * sizeof(uint8_t)); - cmdApdu.len = (int32_t)ArrayOfAIDs[selectCnt][0]; - } - - cmdApdu.p_data[0] = Os_info->Channel_Info[0].channel_id; - - memcpy(&(cmdApdu.p_data[1]), &ArrayOfAIDs[selectCnt][2], - ((ArrayOfAIDs[selectCnt][0]) - 1)); - - /*If NFC/SPI Deinitialize requested*/ - ALOGD_IF(ese_debug_enabled, - "%s: Calling Secure Element Transceive with Loader service AID", - fn); + /*p_data will have channel_id (1 byte) + SelectLsc APDU*/ + cmdApdu.len = (int32_t)(sizeof(SelectLsc) + 1); + cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t)); + cmdApdu.p_data[0] = Os_info->Channel_Info[0].channel_id; - ESESTATUS eseStat = phNxpEse_Transceive(&cmdApdu, &rspApdu); + memcpy(&(cmdApdu.p_data[1]), SelectLsc, sizeof(SelectLsc)); - if (eseStat != ESESTATUS_SUCCESS && (rspApdu.len == 0x00)) { - status = LSCSTATUS_FAILED; - ALOGE("%s: SE transceive failed status = 0x%X", fn, status); - break; - } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x90) && - (rspApdu.p_data[rspApdu.len - 1] == 0x00))) { - status = Process_SelectRsp(rspApdu.p_data, (rspApdu.len - 2)); - if (status != LSCSTATUS_SUCCESS) { - ALOGE("%s: Select Lsc Rsp doesnt have a valid key; status = 0x%X", fn, - status); - } - /*If AID is found which is successfully selected break while loop*/ - if (status == LSCSTATUS_SUCCESS) { - uint8_t totalLen = ArrayOfAIDs[selectCnt][0]; - uint8_t cnt = 0; - int32_t wStatus = 0; - status = LSCSTATUS_FAILED; + ALOGD_IF(ese_debug_enabled, + "%s: Calling Secure Element Transceive with Loader service AID", fn); - FILE* fAidMem = fopen(AID_MEM_PATH, "w+"); + ESESTATUS eseStat = phNxpEse_Transceive(&cmdApdu, &rspApdu); - if (fAidMem == NULL) { - ALOGE("Error opening AID data file for writing: %s", strerror(errno)); - phNxpEse_free(cmdApdu.p_data); - return status; - } - while (cnt <= totalLen) { - wStatus = fprintf(fAidMem, "%02x", ArrayOfAIDs[selectCnt][cnt++]); - if (wStatus != 2) { - ALOGE("%s: Error writing AID data to AID_MEM file: %s", fn, - strerror(errno)); - break; - } - } - if (wStatus == 2) status = LSCSTATUS_SUCCESS; - fclose(fAidMem); - break; - } - } else if (((rspApdu.p_data[rspApdu.len - 2] != 0x90))) { - /*Copy the response SW in failure case*/ - memcpy(&gsLsExecuteResp[2], &(rspApdu.p_data[rspApdu.len - 2]), 2); - } else { - status = LSCSTATUS_FAILED; + if (eseStat != ESESTATUS_SUCCESS && (rspApdu.len == 0x00)) { + status = LSCSTATUS_FAILED; + ALOGE("%s: SE transceive failed status = 0x%X", fn, status); + } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x90) && + (rspApdu.p_data[rspApdu.len - 1] == 0x00))) { + status = Process_SelectRsp(rspApdu.p_data, (rspApdu.len - 2)); + if (status != LSCSTATUS_SUCCESS) { + ALOGE("%s: Select Lsc Rsp doesnt have a valid key; status = 0x%X", fn, + status); } + } else if (((rspApdu.p_data[rspApdu.len - 2] != 0x90))) { + /*Copy the response SW in failure case*/ + memcpy(&gsLsExecuteResp[2], &(rspApdu.p_data[rspApdu.len - 2]), 2); + } else { + status = LSCSTATUS_FAILED; } phNxpEse_free(cmdApdu.p_data); phNxpEse_free(rspApdu.p_data); @@ -439,35 +469,13 @@ LSCSTATUS LSC_loadapplet(Lsc_ImageInfo_t* Os_info, LSCSTATUS status, status = LSC_SendtoLsc(Os_info, status, pTranscv_Info, LS_Comm); if (status != LSCSTATUS_SUCCESS) { /*When the switching of LS 6320 case*/ - if (status == LSCSTATUS_FILE_NOT_FOUND) { - /*When 6320 occurs close the existing channels*/ - LSC_CloseChannel(Os_info, status, pTranscv_Info); - - status = LSCSTATUS_FAILED; - status = LSC_OpenChannel(Os_info, status, pTranscv_Info); - if (status == LSCSTATUS_SUCCESS) { - ALOGD_IF(ese_debug_enabled, - "%s: SUCCESS:Post Switching LS open channel", fn); - status = LSCSTATUS_FAILED; - status = LSC_SelectLsc(Os_info, status, pTranscv_Info); - if (status == LSCSTATUS_SUCCESS) { - ALOGD_IF(ese_debug_enabled, - "%s: SUCCESS:Post Switching LS select", fn); - status = LSCSTATUS_FAILED; - status = LSC_StoreData(Os_info, status, pTranscv_Info); - if (status == LSCSTATUS_SUCCESS) { - /*Enable certificate and signature verification*/ - tag40_found = LSCSTATUS_SUCCESS; - gsLsExecuteResp[2] = 0x90; - gsLsExecuteResp[3] = 0x00; - reachEOFCheck = true; - continue; - } - ALOGE("%s: Post Switching LS store data failure", fn); - } - ALOGE("%s: Post Switching LS select failure", fn); + if (status == LSCSTATUS_SELF_UPDATE_DONE) { + status = LSC_CloseAllLogicalChannels(Os_info); + if (status != LSCSTATUS_SUCCESS) { + ALOGE("%s: CleanupLsUpdaterChannels failed", fn); } - ALOGE("%s: Post Switching LS failure", fn); + status = LSCSTATUS_SUCCESS; + goto exit; } ALOGE("%s: Sending packet to lsc failed", fn); goto exit; @@ -934,6 +942,9 @@ LSCSTATUS LSC_CloseChannel(Lsc_ImageInfo_t* Os_info, LSCSTATUS status, (rspApdu.p_data[rspApdu.len - 1] == 0x00)) { ALOGD_IF(ese_debug_enabled, "%s: Close channel id = 0x0%x success", fn, Os_info->Channel_Info[cnt].channel_id); + if (Os_info->Channel_Info[cnt].channel_id == Os_info->initChannelNum) { + Os_info->initChannelNum = 0x00; + } status = LSCSTATUS_SUCCESS; } else { ALOGD_IF(ese_debug_enabled, "%s: Close channel id = 0x0%x failed", fn, @@ -1002,39 +1013,9 @@ LSCSTATUS LSC_ProcessResp(Lsc_ImageInfo_t* image_info, int32_t recvlen, } status = LSC_SendtoEse(image_info, status, trans_info); } else if ((recvlen > 0x02) && (sw[0] == 0x63) && (sw[1] == 0x20)) { - uint8_t aid_array[22]; - aid_array[0] = recvlen + 3; - aid_array[1] = 00; - aid_array[2] = 0xA4; - aid_array[3] = 0x04; - aid_array[4] = 0x00; - aid_array[5] = recvlen - 2; - memcpy(&aid_array[6], &RecvData[0], recvlen - 2); - memcpy(&ArrayOfAIDs[2][0], &aid_array[0], recvlen + 4); - - FILE* fAidMem = fopen(AID_MEM_PATH, "w"); - - if (fAidMem == NULL) { - ALOGE("%s: Error opening AID data for writing: %s", fn, strerror(errno)); - return LSCSTATUS_FAILED; - } - - /*Updating the AID_MEM with new value into AID file*/ - uint8_t respLen = 0; - int32_t wStatus = 0; - while (respLen <= (recvlen + 4)) { - wStatus = fprintf(fAidMem, "%2x", aid_array[respLen++]); - if (wStatus != 2) { - ALOGE("%s: Invalid Response during fprintf; status=0x%x", fn, wStatus); - fclose(fAidMem); - break; - } - } - if (wStatus == 2) { - status = LSCSTATUS_FILE_NOT_FOUND; - } else { - status = LSCSTATUS_FAILED; - } + /*In case of self update, status 0x6320 indicates script execution success + and response data has new AID*/ + status = LSCSTATUS_SELF_UPDATE_DONE; } else if ((recvlen >= 0x02) && ((sw[0] != 0x90) && (sw[0] != 0x63) && (sw[0] != 0x61))) { Write_Response_To_OutFile(image_info, RecvData, recvlen, tType); @@ -1945,3 +1926,203 @@ LSCSTATUS Get_LsStatus(uint8_t* pStatus) { fclose(fLsStatus); return LSCSTATUS_SUCCESS; } + +/******************************************************************************* +** +** Function: LSC_CloseAllLogicalChannels +** +** Description: Close all opened logical channels +** +** Returns: SUCCESS/FAILURE +** +*******************************************************************************/ +LSCSTATUS LSC_CloseAllLogicalChannels(Lsc_ImageInfo_t* Os_info) { + ESESTATUS status = ESESTATUS_FAILED; + LSCSTATUS lsStatus = LSCSTATUS_FAILED; + phNxpEse_data cmdApdu; + phNxpEse_data rspApdu; + + ALOGD_IF(ese_debug_enabled, "%s: Enter", __func__); + for (uint8_t channelNumber = 0x01; channelNumber < 0x04; channelNumber++) { + if (channelNumber == Os_info->initChannelNum) continue; + phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data)); + phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data)); + cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(5 * sizeof(uint8_t)); + if (cmdApdu.p_data != NULL) { + uint8_t xx = 0; + + cmdApdu.p_data[xx++] = channelNumber; + cmdApdu.p_data[xx++] = 0x70; // INS + cmdApdu.p_data[xx++] = 0x80; // P1 + cmdApdu.p_data[xx++] = channelNumber; // P2 + cmdApdu.p_data[xx++] = 0x00; // Lc + cmdApdu.len = xx; + + status = phNxpEse_Transceive(&cmdApdu, &rspApdu); + } + if (status != ESESTATUS_SUCCESS) { + lsStatus = LSCSTATUS_FAILED; + } else if ((rspApdu.p_data[rspApdu.len - 2] == 0x90) && + (rspApdu.p_data[rspApdu.len - 1] == 0x00)) { + lsStatus = LSCSTATUS_SUCCESS; + } else { + lsStatus = LSCSTATUS_FAILED; + } + + phNxpEse_free(cmdApdu.p_data); + phNxpEse_free(rspApdu.p_data); + } + return lsStatus; +} + +/******************************************************************************* +** +** Function: LSC_SelectLsHash +** +** Description: Selects LS Hash applet +** +** Returns: SUCCESS/FAILURE +** +*******************************************************************************/ +LSCSTATUS LSC_SelectLsHash() { + phNxpEse_data cmdApdu; + phNxpEse_data rspApdu; + LSCSTATUS lsStatus = LSCSTATUS_FAILED; + ALOGD_IF(ese_debug_enabled, "%s: Enter ", __func__); + phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data)); + phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data)); + + cmdApdu.len = (int32_t)(sizeof(SelectLscSlotHash)); + cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t)); + memcpy(cmdApdu.p_data, SelectLscSlotHash, sizeof(SelectLscSlotHash)); + + ESESTATUS eseStat = phNxpEse_Transceive(&cmdApdu, &rspApdu); + + if ((eseStat != ESESTATUS_SUCCESS) || + ((rspApdu.p_data[rspApdu.len - 2] != 0x90) && + (rspApdu.p_data[rspApdu.len - 1] != 0x00))) { + lsStatus = LSCSTATUS_FAILED; + } else { + lsStatus = LSCSTATUS_SUCCESS; + } + + phNxpEse_free(cmdApdu.p_data); + phNxpEse_free(rspApdu.p_data); + return lsStatus; +} +/******************************************************************************* +** +** Function: LSC_ReadLsHash +** +** Description: Read the LS SHA1 for the intended slot +** +** Returns: SUCCESS/FAILURE +** +*******************************************************************************/ +LSCSTATUS LSC_ReadLsHash(uint8_t* hash, uint16_t* readHashLen, uint8_t slotId) { + phNxpEse_data cmdApdu; + phNxpEse_data rspApdu; + LSCSTATUS lsStatus = LSCSTATUS_FAILED; + + lsStatus = LSC_SelectLsHash(); + if (lsStatus != LSCSTATUS_SUCCESS) { + return lsStatus; + } + + phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data)); + phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data)); + cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(5 * sizeof(uint8_t)); + + if (cmdApdu.p_data != NULL) { + uint8_t xx = 0; + cmdApdu.p_data[xx++] = 0x80; // CLA + cmdApdu.p_data[xx++] = 0x02; // INS + cmdApdu.p_data[xx++] = slotId; // P1 + cmdApdu.p_data[xx++] = 0x00; // P2 + cmdApdu.len = xx; + + ESESTATUS eseStat = phNxpEse_Transceive(&cmdApdu, &rspApdu); + + if ((eseStat == ESESTATUS_SUCCESS) && + ((rspApdu.p_data[rspApdu.len - 2] == 0x90) && + (rspApdu.p_data[rspApdu.len - 1] == 0x00))) { + ALOGD_IF(ese_debug_enabled, "%s: rspApdu.len : %u", __func__, + rspApdu.len); + *readHashLen = rspApdu.len - 2; + memcpy(hash, rspApdu.p_data, rspApdu.len); + + lsStatus = LSCSTATUS_SUCCESS; + } else { + if ((rspApdu.p_data[rspApdu.len - 2] == 0x6A) && + (rspApdu.p_data[rspApdu.len - 1] == 0x86)) { + ALOGD_IF(ese_debug_enabled, "%s: slot id is invalid", __func__); + lsStatus = LSCSTATUS_HASH_SLOT_INVALID; + } else if ((rspApdu.p_data[rspApdu.len - 2] == 0x6A) && + (rspApdu.p_data[rspApdu.len - 1] == 0x83)) { + ALOGD_IF(ese_debug_enabled, "%s: slot is empty", __func__); + lsStatus = LSCSTATUS_HASH_SLOT_EMPTY; + } else { + lsStatus = LSCSTATUS_FAILED; + } + } + phNxpEse_free(cmdApdu.p_data); + phNxpEse_free(rspApdu.p_data); + } + return lsStatus; +} + +/******************************************************************************* +** +** Function: LSC_UpdateLsHash +** +** Description: Updates the SHA1 for the intended slot +** +** Returns: SUCCESS/FAILURE +** +*******************************************************************************/ +LSCSTATUS LSC_UpdateLsHash(uint8_t* hash, long hashLen, uint8_t slotId) { + phNxpEse_data cmdApdu; + phNxpEse_data rspApdu; + LSCSTATUS lsStatus = LSCSTATUS_FAILED; + ALOGD_IF(ese_debug_enabled, "%s: Enter ", __func__); + + lsStatus = LSC_SelectLsHash(); + if (lsStatus != LSCSTATUS_SUCCESS) { + return lsStatus; + } + + phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data)); + phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data)); + + cmdApdu.len = (int32_t)(5 + hashLen); + cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t)); + + if (cmdApdu.p_data != NULL) { + uint8_t xx = 0; + cmdApdu.p_data[xx++] = 0x80; + cmdApdu.p_data[xx++] = 0x01; // INS + cmdApdu.p_data[xx++] = slotId; // P1 + cmdApdu.p_data[xx++] = 0x00; // P2 + cmdApdu.p_data[xx++] = hashLen; // Lc + memcpy(&cmdApdu.p_data[xx], hash, hashLen); + + ESESTATUS eseStat = phNxpEse_Transceive(&cmdApdu, &rspApdu); + + if ((eseStat == ESESTATUS_SUCCESS) && + ((rspApdu.p_data[rspApdu.len - 2] == 0x90) && + (rspApdu.p_data[rspApdu.len - 1] == 0x00))) { + lsStatus = LSCSTATUS_SUCCESS; + } else { + if ((rspApdu.p_data[rspApdu.len - 2] == 0x6A) && + (rspApdu.p_data[rspApdu.len - 1] == 0x86)) { + ALOGD_IF(ese_debug_enabled, "%s: if slot id is invalid", __func__); + } + lsStatus = LSCSTATUS_FAILED; + } + } + + ALOGD_IF(ese_debug_enabled, "%s: Exit ", __func__); + phNxpEse_free(cmdApdu.p_data); + phNxpEse_free(rspApdu.p_data); + return lsStatus; +} |
