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