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