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