1 /******************************************************************************
2  *
3  *  Copyright 2018-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 #ifdef NXP_BOOTTIME_UPDATE
19 #include "NxpEse.h"
20 #include "eSEClient.h"
21 #include <android-base/logging.h>
22 #include <android-base/stringprintf.h>
23 #include <memunreachable/memunreachable.h>
24 
25 #include "phNxpEse_Api.h"
26 
27 namespace vendor {
28 namespace nxp {
29 namespace nxpese {
30 namespace V1_0 {
31 namespace implementation {
32 using android::base::StringPrintf;
33 // using android::hardware::secure_element::V1_0::implementation::SecureElement;
34 static android::sp<ISecureElementHalCallback> seCallback;
35 static android::sp<
36     ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>
37     seCallback_1_1;
38 static android::sp<ISecureElementHalCallback> virtualISOCallback;
39 static android::sp<
40     ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>
41     virtualISOCallback_1_1;
42 bool isSeHalV1_1 = false;
43 // Methods from ::vendor::nxp::nxpese::V1_0::INxpEse follow.
setSeCallBack(const android::sp<ISecureElementHalCallback> & clientCallback)44 Return<void> NxpEse::setSeCallBack(
45     const android::sp<ISecureElementHalCallback>& clientCallback) {
46   seCallback = clientCallback;
47   return Void();
48 }
49 
setSeCallBack_1_1(const sp<::android::hardware::secure_element::V1_1::ISecureElementHalCallback> & clientCallback)50 Return<void> NxpEse::setSeCallBack_1_1(
51     const sp<
52         ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
53         clientCallback) {
54   seCallback_1_1 = clientCallback;
55   isSeHalV1_1 = true;
56   return Void();
57 }
58 
setVirtualISOCallBack(const android::sp<ISecureElementHalCallback> & clientCallback)59 Return<void> NxpEse::setVirtualISOCallBack(
60     const android::sp<ISecureElementHalCallback>& clientCallback) {
61   virtualISOCallback = clientCallback;
62   return Void();
63 }
64 
setVirtualISOCallBack_1_1(const android::sp<::android::hardware::secure_element::V1_1::ISecureElementHalCallback> & clientCallback)65 Return<void> NxpEse::setVirtualISOCallBack_1_1(
66     const android::sp<
67         ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
68         clientCallback) {
69   virtualISOCallback_1_1 = clientCallback;
70   isSeHalV1_1 = true;
71   return Void();
72 }
initSEService()73 void NxpEse::initSEService() {
74   ESESTATUS status = ESESTATUS_SUCCESS;
75   ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
76   phNxpEse_initParams initParams;
77   memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
78   initParams.initMode = ESE_MODE_NORMAL;
79   initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
80 
81   if (!seCallback && !isSeHalV1_1) return;
82 
83   if (!seCallback_1_1 && isSeHalV1_1) return;
84 
85   status = phNxpEse_open(initParams);
86   if (status != ESESTATUS_SUCCESS) {
87     goto exit;
88   }
89 
90   status = phNxpEse_SetEndPoint_Cntxt(0);
91   if (status != ESESTATUS_SUCCESS) {
92     goto exit1;
93   }
94   status = phNxpEse_init(initParams);
95   if (status != ESESTATUS_SUCCESS) {
96     goto exit1;
97   }
98   status = phNxpEse_ResetEndPoint_Cntxt(0);
99   if (status != ESESTATUS_SUCCESS) {
100     goto exit2;
101   }
102 
103   LOG(INFO) << "ESE SPI init complete !!!";
104 exit2:
105   deInitStatus = phNxpEse_deInit();
106 exit1:
107   status = phNxpEse_close(deInitStatus);
108 exit:
109   if (status == ESESTATUS_SUCCESS) {
110     if (isSeHalV1_1)
111       seCallback_1_1->onStateChange_1_1(true, "NXP SE HAL init ok");
112     else
113       seCallback->onStateChange(true);
114   } else {
115     LOG(ERROR) << "eSE-Hal Init failed";
116     if (isSeHalV1_1)
117       seCallback_1_1->onStateChange_1_1(false, "NXP SE HAL init not ok");
118     else
119       seCallback->onStateChange(false);
120   }
121 }
122 
initVIrtualISOService()123 void NxpEse::initVIrtualISOService() {
124   ESESTATUS status = ESESTATUS_SUCCESS;
125   phNxpEse_initParams initParams;
126   ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
127   memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
128   initParams.initMode = ESE_MODE_NORMAL;
129   initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
130 
131   if (!virtualISOCallback && !isSeHalV1_1) return;
132 
133   if (!virtualISOCallback_1_1 && isSeHalV1_1) return;
134 
135   status = phNxpEse_SetEndPoint_Cntxt(1);
136   if (status != ESESTATUS_SUCCESS) {
137     goto exit1;
138   }
139   status = phNxpEse_init(initParams);
140   if (status != ESESTATUS_SUCCESS) {
141     goto exit1;
142   }
143   status = phNxpEse_ResetEndPoint_Cntxt(1);
144   if (status != ESESTATUS_SUCCESS) {
145     goto exit2;
146   }
147 
148   LOG(INFO) << "ESE SPI init complete !!!";
149 exit2:
150   deInitStatus = phNxpEse_deInit();
151 exit1:
152   status = phNxpEse_close(deInitStatus);
153 
154   if (status == ESESTATUS_SUCCESS) {
155     if (isSeHalV1_1)
156       virtualISOCallback_1_1->onStateChange_1_1(true, "NXP SE HAL init ok");
157     else
158       virtualISOCallback->onStateChange(true);
159   } else {
160     LOG(ERROR) << "eSE-Hal Init failed";
161     if (isSeHalV1_1)
162       virtualISOCallback_1_1->onStateChange_1_1(false,
163                                                 "NXP SE HAL init not ok");
164     else
165       virtualISOCallback->onStateChange(false);
166   }
167 }
ioctlHandler(uint64_t ioctlType,ese_nxp_IoctlInOutData_t & inpOutData)168 Return<void> NxpEse::ioctlHandler(uint64_t ioctlType,
169                                   ese_nxp_IoctlInOutData_t& inpOutData) {
170   switch (ioctlType) {
171     case HAL_ESE_IOCTL_NFC_JCOP_DWNLD: {
172       // nfc_nci_IoctlInOutData_t* inpOutData =
173       // (nfc_nci_IoctlInOutData_t*)inpOutData;
174       int update_state = inpOutData.inp.data.nxpCmd.p_cmd[0];
175       if (update_state == ESE_JCOP_UPDATE_COMPLETED ||
176           update_state == ESE_LS_UPDATE_COMPLETED) {
177         seteSEClientState(update_state);
178         eSEClientUpdate_SE_Thread();
179       }
180     } break;
181   }
182   return Void();
183 }
184 
ioctl(uint64_t ioctlType,const hidl_vec<uint8_t> & inOutData,ioctl_cb _hidl_cb)185 Return<void> NxpEse::ioctl(uint64_t ioctlType,
186                            const hidl_vec<uint8_t>& inOutData,
187                            ioctl_cb _hidl_cb) {
188   ese_nxp_IoctlInOutData_t inpOutData;
189   ese_nxp_IoctlInOutData_t* pInOutData =
190       (ese_nxp_IoctlInOutData_t*)&inOutData[0];
191 
192   /*data from proxy->stub is copied to local data which can be updated by
193    * underlying HAL implementation since it's an inout argument*/
194   memcpy(&inpOutData, pInOutData, sizeof(ese_nxp_IoctlInOutData_t));
195   ESESTATUS status = phNxpEse_spiIoctl(ioctlType, &inpOutData);
196   ioctlHandler(ioctlType, inpOutData);
197   /*copy data and additional fields indicating status of ioctl operation
198    * and context of the caller. Then invoke the corresponding proxy callback*/
199   inpOutData.out.ioctlType = ioctlType;
200   inpOutData.out.result = status;
201   if (ioctlType == HAL_ESE_IOCTL_GET_ESE_UPDATE_STATE) {
202     inpOutData.out.data.status =
203         (getJcopUpdateRequired() | (getLsUpdateRequired() << 8));
204   }
205   EseData outputData;
206   outputData.setToExternal((uint8_t*)&inpOutData.out,
207                            sizeof(ese_nxp_ExtnOutputData_t));
208   LOG(ERROR) << "GET ESE update state2 = " << inpOutData.out.data.status;
209   _hidl_cb(outputData);
210   return Void();
211 }
212 
213 // Methods from ::android::hidl::base::V1_0::IBase follow.
debug(const hidl_handle &,const hidl_vec<hidl_string> &)214 Return<void> NxpEse::debug(const hidl_handle& /* fd */,
215                            const hidl_vec<hidl_string>& /* options */) {
216   LOG(INFO) << "\n SecureElement-NxpEse HAL MemoryLeak Info = \n"
217             << ::android::GetUnreachableMemoryString(true, 10000).c_str();
218   return Void();
219 }
220 
221 }  // namespace implementation
222 }  // namespace V1_0
223 }  // namespace nxpese
224 }  // namespace nxp
225 }  // namespace vendor
226 #endif //NXP_BOOTTIME_UPDATE