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 #define LOG_TAG "NxpEseHal"
19 #include <log/log.h>
20
21 #include "LsClient.h"
22 #include "SecureElement.h"
23 #include "phNxpEse_Api.h"
24
25 extern bool ese_debug_enabled;
26
27 namespace android {
28 namespace hardware {
29 namespace secure_element {
30 namespace V1_0 {
31 namespace implementation {
32
33 sp<V1_0::ISecureElementHalCallback> SecureElement::mCallbackV1_0 = nullptr;
34
onLSCompleted(bool result,std::string reason,void * arg)35 static void onLSCompleted(bool result, std::string reason, void* arg) {
36 ((SecureElement*)arg)->onStateChange(result, reason);
37 }
38
SecureElement()39 SecureElement::SecureElement()
40 : mOpenedchannelCount(0), mOpenedChannels{false, false, false, false} {}
41
init(const sp<::android::hardware::secure_element::V1_0::ISecureElementHalCallback> & clientCallback)42 Return<void> SecureElement::init(
43 const sp<
44 ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
45 clientCallback) {
46 ESESTATUS status = ESESTATUS_SUCCESS;
47
48 if (clientCallback == nullptr) {
49 return Void();
50 } else {
51 mCallbackV1_0 = clientCallback;
52 if (!mCallbackV1_0->linkToDeath(this, 0 /*cookie*/)) {
53 ALOGE("%s: Failed to register death notification", __func__);
54 }
55 }
56 if (isSeInitialized()) {
57 clientCallback->onStateChange(true);
58 return Void();
59 }
60
61 status = seHalInit();
62 if (status != ESESTATUS_SUCCESS) {
63 clientCallback->onStateChange(false);
64 return Void();
65 }
66
67 LSCSTATUS lsStatus = LSC_doDownload(onLSCompleted, (void*)this);
68 /*
69 * LSC_doDownload returns LSCSTATUS_FAILED in case thread creation fails.
70 * So return callback as false.
71 * Otherwise callback will be called in LSDownload module.
72 */
73 if (lsStatus != LSCSTATUS_SUCCESS) {
74 ALOGE("%s: LSDownload thread creation failed!!!", __func__);
75 SecureElementStatus sestatus = seHalDeInit();
76 if (sestatus != SecureElementStatus::SUCCESS) {
77 ALOGE("%s: seHalDeInit failed!!!", __func__);
78 }
79 clientCallback->onStateChange(false);
80 }
81 return Void();
82 }
83
getAtr(getAtr_cb _hidl_cb)84 Return<void> SecureElement::getAtr(getAtr_cb _hidl_cb) {
85 hidl_vec<uint8_t> response;
86 _hidl_cb(response);
87 return Void();
88 }
89
isCardPresent()90 Return<bool> SecureElement::isCardPresent() { return true; }
91
transmit(const hidl_vec<uint8_t> & data,transmit_cb _hidl_cb)92 Return<void> SecureElement::transmit(const hidl_vec<uint8_t>& data,
93 transmit_cb _hidl_cb) {
94 ESESTATUS status = ESESTATUS_FAILED;
95 phNxpEse_data cmdApdu;
96 phNxpEse_data rspApdu;
97 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
98 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
99
100 cmdApdu.len = data.size();
101 if (cmdApdu.len >= MIN_APDU_LENGTH) {
102 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
103 memcpy(cmdApdu.p_data, data.data(), cmdApdu.len);
104 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
105 }
106
107 hidl_vec<uint8_t> result;
108 if (status != ESESTATUS_SUCCESS) {
109 ALOGE("%s: transmit failed!!!", __func__);
110 } else {
111 result.resize(rspApdu.len);
112 memcpy(&result[0], rspApdu.p_data, rspApdu.len);
113 }
114 _hidl_cb(result);
115 phNxpEse_free(cmdApdu.p_data);
116 phNxpEse_free(rspApdu.p_data);
117 return Void();
118 }
119
openLogicalChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openLogicalChannel_cb _hidl_cb)120 Return<void> SecureElement::openLogicalChannel(const hidl_vec<uint8_t>& aid,
121 uint8_t p2,
122 openLogicalChannel_cb _hidl_cb) {
123 hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
124
125 LogicalChannelResponse resApduBuff;
126 resApduBuff.channelNumber = 0xff;
127 memset(&resApduBuff, 0x00, sizeof(resApduBuff));
128 if (aid.size() > MAX_AID_LENGTH) {
129 ALOGE("%s: AID out of range!!!", __func__);
130 _hidl_cb(resApduBuff, SecureElementStatus::FAILED);
131 return Void();
132 }
133
134 if (!isSeInitialized()) {
135 ESESTATUS status = seHalInit();
136 if (status != ESESTATUS_SUCCESS) {
137 ALOGE("%s: seHalInit Failed!!!", __func__);
138 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
139 return Void();
140 }
141 }
142
143 SecureElementStatus sestatus = SecureElementStatus::IOERROR;
144 ESESTATUS status = ESESTATUS_FAILED;
145 phNxpEse_data cmdApdu;
146 phNxpEse_data rspApdu;
147
148 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
149 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
150
151 cmdApdu.len = manageChannelCommand.size();
152 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
153 sizeof(uint8_t));
154 if (cmdApdu.p_data != NULL) {
155 memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
156 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
157 }
158 if (status != ESESTATUS_SUCCESS) {
159 /*Transceive failed*/
160 sestatus = SecureElementStatus::IOERROR;
161 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
162 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
163 /*ManageChannel successful*/
164 resApduBuff.channelNumber = rspApdu.p_data[0];
165 mOpenedchannelCount++;
166 mOpenedChannels[resApduBuff.channelNumber] = true;
167 sestatus = SecureElementStatus::SUCCESS;
168 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
169 rspApdu.p_data[rspApdu.len - 1] == 0x81) {
170 sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
171 } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
172 (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
173 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
174 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
175 }
176
177 /*Free the allocations*/
178 phNxpEse_free(cmdApdu.p_data);
179 phNxpEse_free(rspApdu.p_data);
180
181 if (sestatus != SecureElementStatus::SUCCESS) {
182 /*If first logical channel open fails, DeInit SE*/
183 if (isSeInitialized() && (mOpenedchannelCount == 0)) {
184 SecureElementStatus deInitStatus = seHalDeInit();
185 if (deInitStatus != SecureElementStatus::SUCCESS) {
186 ALOGE("%s: seDeInit Failed", __func__);
187 }
188 }
189 /*If manageChanle is failed in any of above cases
190 send the callback and return*/
191 _hidl_cb(resApduBuff, sestatus);
192 return Void();
193 }
194
195 ALOGD_IF(ese_debug_enabled, "%s: Sending selectApdu", __func__);
196 /*Reset variables if manageChannel is success*/
197 sestatus = SecureElementStatus::IOERROR;
198 status = ESESTATUS_FAILED;
199
200 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
201 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
202
203 cmdApdu.len = (int32_t)(5 + aid.size());
204 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
205 if (cmdApdu.p_data != NULL) {
206 uint8_t xx = 0;
207 cmdApdu.p_data[xx++] = resApduBuff.channelNumber;
208 cmdApdu.p_data[xx++] = 0xA4; // INS
209 cmdApdu.p_data[xx++] = 0x04; // P1
210 cmdApdu.p_data[xx++] = p2; // P2
211 cmdApdu.p_data[xx++] = aid.size(); // Lc
212 memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
213
214 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
215 }
216
217 if (status != ESESTATUS_SUCCESS) {
218 /*Transceive failed*/
219 sestatus = SecureElementStatus::IOERROR;
220 } else {
221 uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
222 uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
223 /*Return response on success, empty vector on failure*/
224 /*Status is success*/
225 if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
226 /*Copy the response including status word*/
227 resApduBuff.selectResponse.resize(rspApdu.len);
228 memcpy(&resApduBuff.selectResponse[0], rspApdu.p_data, rspApdu.len);
229 sestatus = SecureElementStatus::SUCCESS;
230 }
231 /*AID provided doesn't match any applet on the secure element*/
232 else if ((sw1 == 0x6A && sw2 == 0x82) ||
233 (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
234 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
235 }
236 /*Operation provided by the P2 parameter is not permitted by the applet.*/
237 else if (sw1 == 0x6A && sw2 == 0x86) {
238 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
239 }
240 }
241
242 if (sestatus != SecureElementStatus::SUCCESS) {
243 SecureElementStatus closeChannelStatus =
244 closeChannel(resApduBuff.channelNumber);
245 if (closeChannelStatus != SecureElementStatus::SUCCESS) {
246 ALOGE("%s: closeChannel Failed", __func__);
247 } else {
248 resApduBuff.channelNumber = 0xff;
249 }
250 }
251 _hidl_cb(resApduBuff, sestatus);
252 phNxpEse_free(cmdApdu.p_data);
253 phNxpEse_free(rspApdu.p_data);
254
255 return Void();
256 }
257
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)258 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
259 uint8_t p2,
260 openBasicChannel_cb _hidl_cb) {
261 hidl_vec<uint8_t> result;
262 if (aid.size() > MAX_AID_LENGTH) {
263 ALOGE("%s: AID out of range!!!", __func__);
264 _hidl_cb(result, SecureElementStatus::FAILED);
265 return Void();
266 }
267
268 if (!isSeInitialized()) {
269 ESESTATUS status = seHalInit();
270 if (status != ESESTATUS_SUCCESS) {
271 ALOGE("%s: seHalInit Failed!!!", __func__);
272 _hidl_cb(result, SecureElementStatus::IOERROR);
273 return Void();
274 }
275 }
276
277 SecureElementStatus sestatus = SecureElementStatus::IOERROR;
278 ESESTATUS status = ESESTATUS_FAILED;
279 phNxpEse_data cmdApdu;
280 phNxpEse_data rspApdu;
281
282 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
283 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
284
285 cmdApdu.len = (int32_t)(5 + aid.size());
286 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
287 if (cmdApdu.p_data != NULL) {
288 uint8_t xx = 0;
289 cmdApdu.p_data[xx++] = 0x00; // basic channel
290 cmdApdu.p_data[xx++] = 0xA4; // INS
291 cmdApdu.p_data[xx++] = 0x04; // P1
292 cmdApdu.p_data[xx++] = p2; // P2
293 cmdApdu.p_data[xx++] = aid.size(); // Lc
294 memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
295
296 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
297 }
298
299 if (status != ESESTATUS_SUCCESS) {
300 /* Transceive failed */
301 sestatus = SecureElementStatus::IOERROR;
302 } else {
303 uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
304 uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
305 /*Return response on success, empty vector on failure*/
306 /*Status is success*/
307 if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
308 /*Copy the response including status word*/
309 result.resize(rspApdu.len);
310 memcpy(&result[0], rspApdu.p_data, rspApdu.len);
311 /*Set basic channel reference if it is not set */
312 if (!mOpenedChannels[0]) {
313 mOpenedChannels[0] = true;
314 mOpenedchannelCount++;
315 }
316 sestatus = SecureElementStatus::SUCCESS;
317 }
318 /*AID provided doesn't match any applet on the secure element*/
319 else if ((sw1 == 0x6A && sw2 == 0x82) ||
320 (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
321 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
322 }
323 /*Operation provided by the P2 parameter is not permitted by the applet.*/
324 else if (sw1 == 0x6A && sw2 == 0x86) {
325 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
326 }
327 }
328
329 if (sestatus != SecureElementStatus::SUCCESS) {
330 SecureElementStatus closeStatus = SecureElementStatus::IOERROR;
331 /*If first basic channel open fails, DeInit SE*/
332 if ((mOpenedChannels[DEFAULT_BASIC_CHANNEL] == false) &&
333 (mOpenedchannelCount == 0)) {
334 closeStatus = seHalDeInit();
335 } else {
336 closeStatus = closeChannel(DEFAULT_BASIC_CHANNEL);
337 }
338 if (closeStatus != SecureElementStatus::SUCCESS) {
339 ALOGE("%s: close Failed", __func__);
340 }
341 }
342 _hidl_cb(result, sestatus);
343 phNxpEse_free(cmdApdu.p_data);
344 phNxpEse_free(rspApdu.p_data);
345 return Void();
346 }
347
348 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
closeChannel(uint8_t channelNumber)349 SecureElement::closeChannel(uint8_t channelNumber) {
350 ESESTATUS status = ESESTATUS_FAILED;
351 SecureElementStatus sestatus = SecureElementStatus::FAILED;
352
353 phNxpEse_data cmdApdu;
354 phNxpEse_data rspApdu;
355
356 if ((channelNumber >= MAX_LOGICAL_CHANNELS) ||
357 (mOpenedChannels[channelNumber] == false)) {
358 ALOGE("%s: invalid channel!!!", __func__);
359 sestatus = SecureElementStatus::FAILED;
360 } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
361 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
362 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
363 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(5 * sizeof(uint8_t));
364 if (cmdApdu.p_data != NULL) {
365 uint8_t xx = 0;
366
367 cmdApdu.p_data[xx++] = channelNumber;
368 cmdApdu.p_data[xx++] = 0x70; // INS
369 cmdApdu.p_data[xx++] = 0x80; // P1
370 cmdApdu.p_data[xx++] = channelNumber; // P2
371 cmdApdu.p_data[xx++] = 0x00; // Lc
372 cmdApdu.len = xx;
373
374 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
375 }
376 if (status != ESESTATUS_SUCCESS) {
377 sestatus = SecureElementStatus::FAILED;
378 } else if ((rspApdu.p_data[rspApdu.len - 2] == 0x90) &&
379 (rspApdu.p_data[rspApdu.len - 1] == 0x00)) {
380 sestatus = SecureElementStatus::SUCCESS;
381 } else {
382 sestatus = SecureElementStatus::FAILED;
383 }
384 phNxpEse_free(cmdApdu.p_data);
385 phNxpEse_free(rspApdu.p_data);
386 }
387
388 if (mOpenedChannels[channelNumber] != false) mOpenedchannelCount--;
389 mOpenedChannels[channelNumber] = false;
390 /*If there are no channels remaining close secureElement*/
391 if (mOpenedchannelCount == 0) {
392 sestatus = seHalDeInit();
393 } else {
394 sestatus = SecureElementStatus::SUCCESS;
395 }
396 return sestatus;
397 }
398
serviceDied(uint64_t,const wp<IBase> &)399 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
400 ALOGE("%s: SecureElement serviceDied!!!", __func__);
401 SecureElementStatus sestatus = seHalDeInit();
402 if (sestatus != SecureElementStatus::SUCCESS) {
403 ALOGE("%s: seHalDeInit Faliled!!!", __func__);
404 }
405 if (mCallbackV1_0 != nullptr) {
406 mCallbackV1_0->unlinkToDeath(this);
407 }
408 }
409
isSeInitialized()410 bool SecureElement::isSeInitialized() { return phNxpEse_isOpen(); }
411
seHalInit()412 ESESTATUS SecureElement::seHalInit() {
413 ESESTATUS status = ESESTATUS_SUCCESS;
414 phNxpEse_initParams initParams;
415 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
416 initParams.initMode = ESE_MODE_NORMAL;
417
418 status = phNxpEse_open(initParams);
419 if (status != ESESTATUS_SUCCESS) {
420 ALOGE("%s: SecureElement open failed!!!", __func__);
421 } else {
422 status = phNxpEse_init(initParams);
423 if (status != ESESTATUS_SUCCESS) {
424 ALOGE("%s: SecureElement init failed!!!", __func__);
425 }
426 }
427 return status;
428 }
429
430 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
seHalDeInit()431 SecureElement::seHalDeInit() {
432 ESESTATUS status = ESESTATUS_SUCCESS;
433 SecureElementStatus sestatus = SecureElementStatus::FAILED;
434 status = phNxpEse_deInit();
435 if (status != ESESTATUS_SUCCESS) {
436 sestatus = SecureElementStatus::FAILED;
437 } else {
438 status = phNxpEse_close();
439 if (status != ESESTATUS_SUCCESS) {
440 sestatus = SecureElementStatus::FAILED;
441 } else {
442 sestatus = SecureElementStatus::SUCCESS;
443
444 for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
445 mOpenedChannels[xx] = false;
446 }
447 mOpenedchannelCount = 0;
448 }
449 }
450 return sestatus;
451 }
452
onStateChange(bool result,std::string reason)453 void SecureElement::onStateChange(bool result, std::string reason) {
454 ALOGD("%s: result: %d, reaon= %s", __func__, result, reason.c_str());
455 mCallbackV1_0->onStateChange(result);
456 }
457
458 } // namespace implementation
459 } // namespace V1_0
460 } // namespace secure_element
461 } // namespace hardware
462 } // namespace android
463