1 /******************************************************************************
2  *
3  *  Copyright 2018-2020, 2023 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 
19 #ifdef NXP_BOOTTIME_UPDATE
20 #include "eSEClient.h"
21 
22 #include <IChannel.h>
23 #include <JcDnld.h>
24 #include <LsClient.h>
25 #include <aidl/vendor/nxp/nxpnfc_aidl/INxpNfc.h>
26 #include <dirent.h>
27 #include <ese_config.h>
28 #include <log/log.h>
29 #include <pthread.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <vendor/nxp/nxpnfc/2.0/INxpNfc.h>
35 
36 #include "NfcAdaptation.h"
37 #include "NxpEse.h"
38 #include "hal_nxpese.h"
39 #include "phNxpEse_Apdu_Api.h"
40 #include "phNxpEse_Spm.h"
41 
42 using android::sp;
43 using android::hardware::hidl_vec;
44 using android::hardware::Void;
45 using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
46 using INxpNfc = vendor::nxp::nxpnfc::V2_0::INxpNfc;
47 using INxpNfcAidl = ::aidl::vendor::nxp::nxpnfc_aidl::INxpNfc;
48 
49 std::string NXPNFC_AIDL_HAL_SERVICE_NAME =
50     "vendor.nxp.nxpnfc_aidl.INxpNfc/default";
51 
52 sp<INxpNfc> mHalNxpNfc = nullptr;
53 std::shared_ptr<INxpNfcAidl> mAidlHalNxpNfc = nullptr;
54 
55 void seteSEClientState(uint8_t state);
56 
57 IChannel_t Ch;
58 se_extns_entry se_intf;
59 void* eSEClientUpdate_ThreadHandler(void* data);
60 void* eSEClientUpdate_Thread(void* data);
61 void* eSEUpdate_SE_SeqHandler(void* data);
62 void eSEClientUpdate_Thread();
63 SESTATUS ESE_ChannelInit(IChannel* ch);
64 SESTATUS handleJcopOsDownload();
65 void* LSUpdate_Thread(void* data);
66 uint8_t performLSUpdate();
67 SESTATUS initializeEse(phNxpEse_initMode mode, SEDomainID Id);
68 ese_update_state_t ese_update = ESE_UPDATE_COMPLETED;
69 SESTATUS eSEUpdate_SeqHandler();
SE_Open()70 int16_t SE_Open() { return SESTATUS_SUCCESS; }
71 
SE_Reset()72 void SE_Reset() { phNxpEse_coldReset(); }
73 
SE_Transmit(uint8_t * xmitBuffer,int32_t xmitBufferSize,uint8_t * recvBuffer,int32_t recvBufferMaxSize,int32_t & recvBufferActualSize,int32_t timeoutMillisec)74 bool SE_Transmit(uint8_t* xmitBuffer, int32_t xmitBufferSize,
75                  uint8_t* recvBuffer, int32_t recvBufferMaxSize,
76                  int32_t& recvBufferActualSize, int32_t timeoutMillisec) {
77   phNxpEse_data cmdData;
78   phNxpEse_data rspData;
79 
80   cmdData.len = xmitBufferSize;
81   cmdData.p_data = xmitBuffer;
82 
83   recvBufferMaxSize++;
84   timeoutMillisec++;
85   if (phNxpEse_Transceive(&cmdData, &rspData) != ESESTATUS_SUCCESS) {
86     ALOGE("%s: Ese Transceive failed", __FUNCTION__);
87   }
88   recvBufferActualSize = rspData.len;
89 
90   if (rspData.p_data != NULL && rspData.len) {
91     memcpy(&recvBuffer[0], rspData.p_data, rspData.len);
92   }
93 
94   ALOGE("%s: size = 0x%x ", __FUNCTION__, recvBufferActualSize);
95   return true;
96 }
97 
SE_JcopDownLoadReset()98 void SE_JcopDownLoadReset() { phNxpEse_resetJcopUpdate(); }
99 
SE_Close(int16_t mHandle)100 bool SE_Close(int16_t mHandle) {
101   if (mHandle != 0)
102     return true;
103   else
104     return false;
105 }
SE_getInterfaceInfo()106 uint8_t SE_getInterfaceInfo() { return INTF_SE; }
107 
108 /***************************************************************************
109 **
110 ** Function:        checkEseClientUpdate
111 **
112 ** Description:     Check the initial condition
113                     and interface for eSE Client update for LS and JCOP download
114 **
115 ** Returns:         SUCCESS of ok
116 **
117 *******************************************************************************/
checkEseClientUpdate()118 void checkEseClientUpdate() {
119   ALOGD("%s enter:  ", __func__);
120   checkeSEClientRequired(ESE_INTF_SPI);
121   se_intf.isJcopUpdateRequired = getJcopUpdateRequired();
122   se_intf.isLSUpdateRequired = getLsUpdateRequired();
123   se_intf.sJcopUpdateIntferface = getJcopUpdateIntf();
124   se_intf.sLsUpdateIntferface = getLsUpdateIntf();
125   if ((se_intf.isJcopUpdateRequired && se_intf.sJcopUpdateIntferface) ||
126       (se_intf.isLSUpdateRequired && se_intf.sLsUpdateIntferface))
127     seteSEClientState(ESE_UPDATE_STARTED);
128 }
129 
130 /***************************************************************************
131 **
132 ** Function:        perform_eSEClientUpdate
133 **
134 ** Description:     Perform LS and JCOP download during hal service init
135 **
136 ** Returns:         SUCCESS / SESTATUS_FAILED
137 **
138 *******************************************************************************/
perform_eSEClientUpdate()139 SESTATUS perform_eSEClientUpdate() {
140   ALOGD("%s enter:  ", __func__);
141 
142   eSEClientUpdate_Thread();
143   return SESTATUS_SUCCESS;
144 }
145 
ESE_ChannelInit(IChannel * ch)146 SESTATUS ESE_ChannelInit(IChannel* ch) {
147   ch->open = SE_Open;
148   ch->close = SE_Close;
149   ch->transceive = SE_Transmit;
150   ch->transceiveRaw = SE_Transmit;
151   ch->doeSE_Reset = SE_Reset;
152   ch->doeSE_JcopDownLoadReset = SE_JcopDownLoadReset;
153   ch->getInterfaceInfo = SE_getInterfaceInfo;
154   return SESTATUS_SUCCESS;
155 }
156 
157 /*******************************************************************************
158 **
159 ** Function:        eSEClientUpdate_Thread
160 **
161 ** Description:     Perform eSE update
162 **
163 ** Returns:         SUCCESS of ok
164 **
165 *******************************************************************************/
eSEClientUpdate_Thread()166 void eSEClientUpdate_Thread() {
167   pthread_t thread;
168   pthread_attr_t attr;
169   pthread_attr_init(&attr);
170   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
171   if (pthread_create(&thread, &attr, &eSEClientUpdate_ThreadHandler, NULL) !=
172       0) {
173     ALOGD("Thread creation failed");
174   } else {
175     ALOGD("Thread creation success");
176   }
177   pthread_attr_destroy(&attr);
178 }
179 /*******************************************************************************
180 **
181 ** Function:        eSEClientUpdate_Thread
182 **
183 ** Description:     Perform eSE update
184 **
185 ** Returns:         SUCCESS of ok
186 **
187 *******************************************************************************/
eSEClientUpdate_SE_Thread()188 void eSEClientUpdate_SE_Thread() {
189   pthread_t thread;
190   pthread_attr_t attr;
191   pthread_attr_init(&attr);
192   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
193   if (pthread_create(&thread, &attr, &eSEUpdate_SE_SeqHandler, NULL) != 0) {
194     ALOGD("Thread creation failed");
195   } else {
196     ALOGD("Thread creation success");
197   }
198   pthread_attr_destroy(&attr);
199 }
200 /*******************************************************************************
201 **
202 ** Function:        eSEClientUpdate_ThreadHandler
203 **
204 ** Description:     Perform JCOP Download
205 **
206 ** Returns:         SUCCESS of ok
207 **
208 *******************************************************************************/
eSEUpdate_SE_SeqHandler(void * data)209 void* eSEUpdate_SE_SeqHandler(void* data) {
210   (void)data;
211   ALOGD("%s Enter\n", __func__);
212   eSEUpdate_SeqHandler();
213   ALOGD("%s Exit eSEUpdate_SE_SeqHandler\n", __func__);
214   return NULL;
215 }
216 /*******************************************************************************
217 **
218 ** Function:        eSEClientUpdate_ThreadHandler
219 **
220 ** Description:     Perform JCOP Download
221 **
222 ** Returns:         SUCCESS of ok
223 **
224 *******************************************************************************/
eSEClientUpdate_ThreadHandler(void * data)225 void* eSEClientUpdate_ThreadHandler(void* data) {
226   (void)data;
227   int cnt = 0;
228 
229   ALOGD("%s Enter\n", __func__);
230   if (mAidlHalNxpNfc == nullptr) {
231     do {
232       ::ndk::SpAIBinder binder(
233           AServiceManager_checkService(NXPNFC_AIDL_HAL_SERVICE_NAME.c_str()));
234       mAidlHalNxpNfc = INxpNfcAidl::fromBinder(binder);
235       if (!mAidlHalNxpNfc) {
236         usleep(100 * 1000);
237         cnt++;
238       }
239     } while (((mAidlHalNxpNfc == nullptr) && (cnt < 3)));
240   }
241 
242   if (mAidlHalNxpNfc) {
243     ALOGD("Boot Time Update not supported for mAidlHalNxpNfc.");
244     ALOGD("%s Exit\n", __func__);
245     pthread_exit(NULL);
246     return NULL;
247   } else {
248     mHalNxpNfc = INxpNfc::tryGetService();
249     if (mHalNxpNfc == nullptr) ALOGD(": Failed to retrieve the NXP NFC HAL!");
250     if (mHalNxpNfc != nullptr) {
251       ALOGD("INxpNfc::getService() returned %p (%s)", mHalNxpNfc.get(),
252             (mHalNxpNfc->isRemote() ? "remote" : "local"));
253     }
254 
255     if (mHalNxpNfc != nullptr) {
256       if (!se_intf.isJcopUpdateRequired && mHalNxpNfc->isJcopUpdateRequired()) {
257         se_intf.isJcopUpdateRequired = true;
258         ALOGD(" se_intf.isJcopUpdateRequired = %d",
259               se_intf.isJcopUpdateRequired);
260       }
261       if (!se_intf.isLSUpdateRequired && mHalNxpNfc->isLsUpdateRequired()) {
262         se_intf.isLSUpdateRequired = true;
263         ALOGD("se_intf.isLSUpdateRequired = %d", se_intf.isLSUpdateRequired);
264       }
265     }
266   }
267 
268   if (se_intf.isJcopUpdateRequired) {
269     if (se_intf.sJcopUpdateIntferface == ESE_INTF_NFC) {
270       seteSEClientState(ESE_JCOP_UPDATE_REQUIRED);
271       return NULL;
272     } else if (se_intf.sJcopUpdateIntferface == ESE_INTF_SPI) {
273       seteSEClientState(ESE_JCOP_UPDATE_REQUIRED);
274     }
275   }
276 
277   if ((ESE_JCOP_UPDATE_REQUIRED != ese_update) &&
278       (se_intf.isLSUpdateRequired)) {
279     if (se_intf.sLsUpdateIntferface == ESE_INTF_NFC) {
280       seteSEClientState(ESE_LS_UPDATE_REQUIRED);
281       return NULL;
282     } else if (se_intf.sLsUpdateIntferface == ESE_INTF_SPI) {
283       seteSEClientState(ESE_LS_UPDATE_REQUIRED);
284     }
285   }
286 
287   if ((ese_update == ESE_JCOP_UPDATE_REQUIRED) ||
288       (ese_update == ESE_LS_UPDATE_REQUIRED))
289     eSEUpdate_SeqHandler();
290 
291   ALOGD("%s Exit eSEClientUpdate_Thread\n", __func__);
292   return NULL;
293 }
294 
295 /*******************************************************************************
296 **
297 ** Function:        handleJcopOsDownload
298 **
299 ** Description:     Perform JCOP update
300 **
301 ** Returns:         SUCCESS of ok
302 **
303 *******************************************************************************/
handleJcopOsDownload()304 SESTATUS handleJcopOsDownload() {
305   SESTATUS status = SESTATUS_FAILED;
306   uint8_t retstat;
307   status = initializeEse(ESE_MODE_OSU, ESE);
308   if (status == SESTATUS_SUCCESS) {
309     retstat = JCDNLD_Init(&Ch);
310     if (retstat != STATUS_SUCCESS) {
311       ALOGE("%s: JCDND initialization failed", __FUNCTION__);
312       if (phNxpEse_ResetEndPoint_Cntxt(0) != ESESTATUS_SUCCESS) {
313         ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
314       }
315       phNxpEse_close(ESESTATUS_SUCCESS);
316       return status;
317     } else {
318       retstat = JCDNLD_StartDownload();
319       if (retstat != SESTATUS_SUCCESS) {
320         ALOGE("%s: JCDNLD_StartDownload failed", __FUNCTION__);
321       }
322     }
323     JCDNLD_DeInit();
324     if (phNxpEse_ResetEndPoint_Cntxt(0) != ESESTATUS_SUCCESS) {
325       ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
326     }
327     phNxpEse_close(ESESTATUS_SUCCESS);
328   }
329   status = SESTATUS_SUCCESS;
330   return status;
331 }
332 
333 /*******************************************************************************
334 **
335 ** Function:        performLSUpdate
336 **
337 ** Description:     Perform LS update
338 **
339 ** Returns:         SUCCESS of ok
340 **
341 *******************************************************************************/
performLSUpdate()342 uint8_t performLSUpdate() {
343   const char* SEterminal = "eSEx";
344   bool ret = false;
345   char terminalID[5];
346   uint8_t status = SESTATUS_FAILED;
347   bool isSEPresent = false;
348   bool isVISOPresent = false;
349   ret = geteSETerminalId(terminalID);
350   ALOGI("performLSUpdate Terminal val = %s", terminalID);
351   if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
352     isSEPresent = true;
353   }
354   ret = geteUICCTerminalId(terminalID);
355   if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
356     isVISOPresent = true;
357   }
358   seteSEClientState(ESE_UPDATE_STARTED);
359   if (isSEPresent) {
360     ALOGE("%s:On eSE domain ", __FUNCTION__);
361     status = initializeEse(ESE_MODE_NORMAL, ESE);
362     ALOGE("%s:On eSE domain ", __FUNCTION__);
363     if (status == SESTATUS_SUCCESS) {
364       status = performLSDownload(&Ch);
365       if (phNxpEse_ResetEndPoint_Cntxt(ESE) != ESESTATUS_SUCCESS) {
366         ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
367       }
368     }
369     phNxpEse_close(ESESTATUS_SUCCESS);
370   }
371   if (isVISOPresent) {
372     ALOGE("%s:On eUICC domain ", __FUNCTION__);
373     status = initializeEse(ESE_MODE_NORMAL, EUICC);
374     if (status == SESTATUS_SUCCESS) {
375       status = performLSDownload(&Ch);
376       if (phNxpEse_ResetEndPoint_Cntxt(EUICC) != ESESTATUS_SUCCESS) {
377         ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
378       }
379     }
380     phNxpEse_close(ESESTATUS_SUCCESS);
381   }
382   return status;
383 }
384 
385 /*******************************************************************************
386 **
387 ** Function:        initializeEse
388 **
389 ** Description:     Open & Initialize libese
390 **
391 ** Returns:         SUCCESS of ok
392 **
393 *******************************************************************************/
initializeEse(phNxpEse_initMode mode,SEDomainID Id)394 SESTATUS initializeEse(phNxpEse_initMode mode, SEDomainID Id) {
395   uint8_t retstat;
396   SESTATUS status = SESTATUS_FAILED;
397   phNxpEse_initParams initParams;
398   memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
399 
400   initParams.initMode = mode;
401   ALOGE("%s: Mode = %d", __FUNCTION__, mode);
402   retstat = phNxpEse_open(initParams);
403   if (retstat != ESESTATUS_SUCCESS) {
404     return status;
405   }
406   retstat = phNxpEse_SetEndPoint_Cntxt(Id);
407   if (retstat != ESESTATUS_SUCCESS) {
408     ALOGE("%s: Set SE EndPoint failed", __FUNCTION__);
409   }
410   retstat = phNxpEse_init(initParams);
411   if (retstat != ESESTATUS_SUCCESS) {
412     if (phNxpEse_ResetEndPoint_Cntxt(Id) != ESESTATUS_SUCCESS) {
413       ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
414     }
415     phNxpEse_close(ESESTATUS_SUCCESS);
416     return status;
417   }
418   ESE_ChannelInit(&Ch);
419   status = SESTATUS_SUCCESS;
420   return status;
421 }
422 
423 /*******************************************************************************
424 **
425 ** Function:        seteSEClientState
426 **
427 ** Description:     Function to set the eSEUpdate state
428 **
429 ** Returns:         SUCCESS of ok
430 **
431 *******************************************************************************/
seteSEClientState(uint8_t state)432 void seteSEClientState(uint8_t state) {
433   ALOGE("%s: State = %d", __FUNCTION__, state);
434   ese_update = (ese_update_state_t)state;
435 }
436 
437 /*******************************************************************************
438 **
439 ** Function:        sendeSEUpdateState
440 **
441 ** Description:     Notify NFC HAL LS / JCOP download state
442 **
443 ** Returns:         SUCCESS of ok
444 **
445 *******************************************************************************/
sendeSEUpdateState(uint8_t state)446 void sendeSEUpdateState(uint8_t state) {
447   ALOGE("%s: State = %d", __FUNCTION__, state);
448   phNxpEse_SPM_SetEseClientUpdateState(state);
449 }
450 
451 /*******************************************************************************
452 **
453 ** Function:        eSEUpdate_SeqHandler
454 **
455 ** Description:     ESE client update handler
456 **
457 ** Returns:         SUCCESS of ok
458 **
459 *******************************************************************************/
eSEUpdate_SeqHandler()460 SESTATUS eSEUpdate_SeqHandler() {
461   switch (ese_update) {
462     case ESE_UPDATE_STARTED:
463       break;
464     case ESE_JCOP_UPDATE_REQUIRED:
465       ALOGE("%s: ESE_JCOP_UPDATE_REQUIRED", __FUNCTION__);
466       if (se_intf.isJcopUpdateRequired) {
467         if (se_intf.sJcopUpdateIntferface == ESE_INTF_SPI) {
468           handleJcopOsDownload();
469           sendeSEUpdateState(ESE_JCOP_UPDATE_COMPLETED);
470           setJcopUpdateRequired(false);
471         } else if (se_intf.sJcopUpdateIntferface == ESE_INTF_NFC) {
472           return SESTATUS_SUCCESS;
473         }
474       }
475       [[fallthrough]];
476     case ESE_JCOP_UPDATE_COMPLETED:
477       ALOGE("%s: ESE_JCOP_UPDATE_COMPLETED", __FUNCTION__);
478       [[fallthrough]];
479     case ESE_LS_UPDATE_REQUIRED:
480       if (se_intf.isLSUpdateRequired) {
481         if (se_intf.sLsUpdateIntferface == ESE_INTF_SPI) {
482           performLSUpdate();
483           sendeSEUpdateState(ESE_LS_UPDATE_COMPLETED);
484           setLsUpdateRequired(false);
485         } else if (se_intf.sLsUpdateIntferface == ESE_INTF_NFC) {
486           seteSEClientState(ESE_LS_UPDATE_REQUIRED);
487           return SESTATUS_SUCCESS;
488         }
489       }
490       ALOGE("%s: ESE_LS_UPDATE_REQUIRED", __FUNCTION__);
491       [[fallthrough]];
492     case ESE_LS_UPDATE_COMPLETED:
493       ALOGE("%s: ESE_LS_UPDATE_COMPLETED", __FUNCTION__);
494       [[fallthrough]];
495     case ESE_UPDATE_COMPLETED:
496       seteSEClientState(ESE_UPDATE_COMPLETED);
497       sendeSEUpdateState(ESE_UPDATE_COMPLETED);
498       NxpEse::initSEService();
499       NxpEse::initVIrtualISOService();
500       ALOGE("%s: ESE_UPDATE_COMPLETED", __FUNCTION__);
501       break;
502   }
503   return SESTATUS_SUCCESS;
504 }
505 #endif /* NXP_BOOTTIME_UPDATE */