Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright 2018 NXP
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 #define LOG_TAG "LSClient"
     19 #include "LsClient.h"
     20 #include <dirent.h>
     21 #include <log/log.h>
     22 #include <pthread.h>
     23 #include <stdlib.h>
     24 #include "LsLib.h"
     25 
     26 uint8_t datahex(char c);
     27 extern bool ese_debug_enabled;
     28 static android::sp<ISecureElementHalCallback> cCallback;
     29 void* performLSDownload_thread(void* data);
     30 /*******************************************************************************
     31 **
     32 ** Function:        LSC_Start
     33 **
     34 ** Description:     Starts the LSC update with encrypted data privided in the
     35                     updater file
     36 **
     37 ** Returns:         SUCCESS if ok.
     38 **
     39 *******************************************************************************/
     40 LSCSTATUS LSC_Start(const char* name, const char* dest, uint8_t* pdata,
     41                     uint16_t len, uint8_t* respSW) {
     42   static const char fn[] = "LSC_Start";
     43   LSCSTATUS status = LSCSTATUS_FAILED;
     44   if (name != NULL) {
     45     status = Perform_LSC(name, dest, pdata, len, respSW);
     46   } else {
     47     ALOGE("%s: LS script file is missing", fn);
     48   }
     49   ALOGD_IF(ese_debug_enabled, "%s: Exit; status=0x0%X", fn, status);
     50   return status;
     51 }
     52 
     53 /*******************************************************************************
     54 **
     55 ** Function:        LSC_doDownload
     56 **
     57 ** Description:     Start LS download process by creating thread
     58 **
     59 ** Returns:         SUCCESS of ok
     60 **
     61 *******************************************************************************/
     62 LSCSTATUS LSC_doDownload(
     63     const android::sp<ISecureElementHalCallback>& clientCallback) {
     64   static const char fn[] = "LSC_doDownload";
     65   LSCSTATUS status;
     66   pthread_t thread;
     67   pthread_attr_t attr;
     68   pthread_attr_init(&attr);
     69   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
     70   cCallback = clientCallback;
     71   if (pthread_create(&thread, &attr, &performLSDownload_thread, NULL) < 0) {
     72     ALOGE("%s: Thread creation failed", fn);
     73     status = LSCSTATUS_FAILED;
     74   } else {
     75     status = LSCSTATUS_SUCCESS;
     76   }
     77   pthread_attr_destroy(&attr);
     78   return status;
     79 }
     80 
     81 /*******************************************************************************
     82 **
     83 ** Function:        performLSDownload_thread
     84 **
     85 ** Description:     Perform LS during hal init
     86 **
     87 ** Returns:         None
     88 **
     89 *******************************************************************************/
     90 void* performLSDownload_thread(__attribute__((unused)) void* data) {
     91   ALOGD_IF(ese_debug_enabled, "%s enter:  ", __func__);
     92 
     93   const char* lsUpdateBackupPath =
     94       "/data/vendor/secure_element/loaderservice_updater.txt";
     95   const char* lsUpdateBackupOutPath =
     96       "/data/vendor/secure_element/loaderservice_updater_out.txt";
     97 
     98   /*generated SHA-1 string for secureElementLS
     99   This will remain constant as handled in secureElement HAL*/
    100   char sha1[] = "6d583e84f2710e6b0f06beebc1a12a1083591373";
    101   uint8_t hash[20] = {0};
    102 
    103   for (int i = 0; i < 40; i = i + 2) {
    104     hash[i / 2] =
    105         (((datahex(sha1[i]) & 0x0F) << 4) | (datahex(sha1[i + 1]) & 0x0F));
    106   }
    107 
    108   uint8_t resSW[4] = {0x4e, 0x02, 0x69, 0x87};
    109   FILE* fIn = fopen(lsUpdateBackupPath, "rb");
    110   if (fIn == NULL) {
    111     ALOGE("%s Cannot open LS script file %s\n", __func__, lsUpdateBackupPath);
    112     ALOGE("%s Error : %s", __func__, strerror(errno));
    113     cCallback->onStateChange(true);
    114   } else {
    115     ALOGD_IF(ese_debug_enabled, "%s File opened %s\n", __func__,
    116              lsUpdateBackupPath);
    117     fseek(fIn, 0, SEEK_END);
    118     long fsize = ftell(fIn);
    119     rewind(fIn);
    120 
    121     char* lsUpdateBuf = (char*)phNxpEse_memalloc(fsize + 1);
    122     fread(lsUpdateBuf, fsize, 1, fIn);
    123 
    124     FILE* fOut = fopen(lsUpdateBackupOutPath, "wb+");
    125     if (fOut == NULL) {
    126       ALOGE("%s Failed to open file %s\n", __func__, lsUpdateBackupOutPath);
    127       phNxpEse_free(lsUpdateBuf);
    128       pthread_exit(NULL);
    129       cCallback->onStateChange(true);
    130       return NULL;
    131     }
    132 
    133     long size = fwrite(lsUpdateBuf, 1, fsize, fOut);
    134     if (size != fsize) {
    135       ALOGE("%s ERROR - Failed to write %ld bytes to file\n", __func__, fsize);
    136       phNxpEse_free(lsUpdateBuf);
    137       pthread_exit(NULL);
    138       cCallback->onStateChange(true);
    139       return NULL;
    140     }
    141 
    142     LSCSTATUS status = LSC_Start(lsUpdateBackupPath, lsUpdateBackupOutPath,
    143                                  (uint8_t*)hash, (uint16_t)sizeof(hash), resSW);
    144     ALOGD_IF(ese_debug_enabled, "%s LSC_Start completed\n", __func__);
    145     if (status == LSCSTATUS_SUCCESS) {
    146       if (remove(lsUpdateBackupPath) == 0) {
    147         ALOGD_IF(ese_debug_enabled, "%s  : %s file deleted successfully\n",
    148                  __func__, lsUpdateBackupPath);
    149       } else {
    150         ALOGD_IF(ese_debug_enabled, "%s  : %s file deletion failed!!!\n",
    151                  __func__, lsUpdateBackupPath);
    152       }
    153       cCallback->onStateChange(true);
    154     } else {
    155       ESESTATUS status = phNxpEse_deInit();
    156       if (status == ESESTATUS_SUCCESS) {
    157         status = phNxpEse_close();
    158         if (status == ESESTATUS_SUCCESS) {
    159           ALOGD_IF(ese_debug_enabled, "%s: Ese_close success\n", __func__);
    160         }
    161       } else {
    162         ALOGE("%s: Ese_deInit failed", __func__);
    163       }
    164       cCallback->onStateChange(false);
    165     }
    166     phNxpEse_free(lsUpdateBuf);
    167   }
    168   pthread_exit(NULL);
    169   ALOGD_IF(ese_debug_enabled, "%s pthread_exit\n", __func__);
    170   return NULL;
    171 }
    172 
    173 /*******************************************************************************
    174 **
    175 ** Function:        datahex
    176 **
    177 ** Description:     Converts char to uint8_t
    178 **
    179 ** Returns:         uint8_t variable
    180 **
    181 *******************************************************************************/
    182 uint8_t datahex(char c) {
    183   uint8_t value = 0;
    184   if (c >= '0' && c <= '9')
    185     value = (c - '0');
    186   else if (c >= 'A' && c <= 'F')
    187     value = (10 + (c - 'A'));
    188   else if (c >= 'a' && c <= 'f')
    189     value = (10 + (c - 'a'));
    190   return value;
    191 }
    192