Merge pi-qpr1-release PQ1A.181105.017.A1 to pi-platform-release
Change-Id: I098c224e8646e610dcfde3eb5ef018f651bc8e34
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
old mode 100644
new mode 100755
index 24fd3cd..e76951c
--- a/Android.bp
+++ b/Android.bp
@@ -71,17 +71,18 @@
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 @@
"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
old mode 100644
new mode 100755
index c2e9e01..01facdb
--- 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
old mode 100644
new mode 100755
index 44e77ab..b7f8329
--- a/ls_client/inc/LsLib.h
+++ b/ls_client/inc/LsLib.h
@@ -48,8 +48,16 @@
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 @@
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};
+static const uint8_t SelectLsc[] = {0xA4, 0x04, 0x00, 0x0E, 0xA0, 0x00,
+ 0x00, 0x03, 0x96, 0x54, 0x43, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00};
-/*LSC2*/
-#define NOOFAIDS 0x03
-#define LENOFAIDS 0x16
-
-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 @@
#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 @@
/*******************************************************************************
**
+** 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 @@
/*******************************************************************************
**
+** 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
old mode 100644
new mode 100755
index 8922f38..50ea3d1
--- 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 @@
**
*******************************************************************************/
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 @@
}
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+");
+ /*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);
+
+ /*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;
+ }
+
+ /*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__, lsUpdateBackupOutPath);
- phNxpEse_free(lsUpdateBuf);
- pthread_exit(NULL);
- cCallback->onStateChange(true);
- return NULL;
+ ALOGE("%s Failed to open file %s\n", __func__, outPath.c_str());
+ break;
}
+ fclose(fOut);
- 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;
- }
-
- 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);
+ /*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 @@
/*******************************************************************************
**
+** 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
old mode 100644
new mode 100755
index 0a43c7f..0e8f129
--- a/ls_client/src/LsLib.cpp
+++ b/ls_client/src/LsLib.cpp
@@ -39,7 +39,8 @@
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 @@
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 @@
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 @@
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];
+ /*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;
+
+ memcpy(&(cmdApdu.p_data[1]), SelectLsc, sizeof(SelectLsc));
+
+ ALOGD_IF(ese_debug_enabled,
+ "%s: Calling Secure Element Transceive with Loader service AID", fn);
+
+ ESESTATUS eseStat = phNxpEse_Transceive(&cmdApdu, &rspApdu);
+
+ 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);
}
-
- 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);
-
- ESESTATUS eseStat = phNxpEse_Transceive(&cmdApdu, &rspApdu);
-
- 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;
-
- FILE* fAidMem = fopen(AID_MEM_PATH, "w+");
-
- 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;
- }
+ } 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 @@
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 @@
(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 @@
}
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 @@
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;
+}