• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *******************************************************************************/
LSC_Start(const char * name,const char * dest,uint8_t * pdata,uint16_t len,uint8_t * respSW)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 *******************************************************************************/
LSC_doDownload(const android::sp<ISecureElementHalCallback> & clientCallback)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 *******************************************************************************/
performLSDownload_thread(void * data)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 *******************************************************************************/
datahex(char c)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