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), 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
129 if (!isSeInitialized()) {
130 ESESTATUS status = seHalInit();
131 if (status != ESESTATUS_SUCCESS) {
132 ALOGE("%s: seHalInit Failed!!!", __func__);
133 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
134 return Void();
135 }
136 }
137
138 SecureElementStatus sestatus = SecureElementStatus::IOERROR;
139 ESESTATUS status = ESESTATUS_FAILED;
140 phNxpEse_data cmdApdu;
141 phNxpEse_data rspApdu;
142
143 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
144 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
145
146 cmdApdu.len = manageChannelCommand.size();
147 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
148 sizeof(uint8_t));
149 if (cmdApdu.p_data != NULL) {
150 memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
151 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
152 }
153 if (status != ESESTATUS_SUCCESS) {
154 /*Transceive failed*/
155 sestatus = SecureElementStatus::IOERROR;
156 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
157 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
158 /*ManageChannel successful*/
159 resApduBuff.channelNumber = rspApdu.p_data[0];
160 mOpenedchannelCount++;
161 mOpenedChannels[resApduBuff.channelNumber] = true;
162 sestatus = SecureElementStatus::SUCCESS;
163 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
164 rspApdu.p_data[rspApdu.len - 1] == 0x81) {
165 sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
166 } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
167 (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
168 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
169 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
170 }
171
172 /*Free the allocations*/
173 phNxpEse_free(cmdApdu.p_data);
174 phNxpEse_free(rspApdu.p_data);
175
176 if (sestatus != SecureElementStatus::SUCCESS) {
177 /*If first logical channel open fails, DeInit SE*/
178 if (isSeInitialized() && (mOpenedchannelCount == 0)) {
179 SecureElementStatus deInitStatus = seHalDeInit();
180 if (deInitStatus != SecureElementStatus::SUCCESS) {
181 ALOGE("%s: seDeInit Failed", __func__);
182 }
183 }
184 /*If manageChanle is failed in any of above cases
185 send the callback and return*/
186 _hidl_cb(resApduBuff, sestatus);
187 return Void();
188 }
189
190 ALOGD_IF(ese_debug_enabled, "%s: Sending selectApdu", __func__);
191 /*Reset variables if manageChannel is success*/
192 sestatus = SecureElementStatus::IOERROR;
193 status = ESESTATUS_FAILED;
194
195 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
196 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
197
198 cmdApdu.len = (int32_t)(5 + aid.size());
199 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
200 if (cmdApdu.p_data != NULL) {
201 uint8_t xx = 0;
202 cmdApdu.p_data[xx++] = resApduBuff.channelNumber;
203 cmdApdu.p_data[xx++] = 0xA4; // INS
204 cmdApdu.p_data[xx++] = 0x04; // P1
205 cmdApdu.p_data[xx++] = p2; // P2
206 cmdApdu.p_data[xx++] = aid.size(); // Lc
207 memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
208
209 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
210 }
211
212 if (status != ESESTATUS_SUCCESS) {
213 /*Transceive failed*/
214 sestatus = SecureElementStatus::IOERROR;
215 } else {
216 uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
217 uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
218 /*Return response on success, empty vector on failure*/
219 /*Status is success*/
220 if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
221 /*Copy the response including status word*/
222 resApduBuff.selectResponse.resize(rspApdu.len);
223 memcpy(&resApduBuff.selectResponse[0], rspApdu.p_data, rspApdu.len);
224 sestatus = SecureElementStatus::SUCCESS;
225 }
226 /*AID provided doesn't match any applet on the secure element*/
227 else if ((sw1 == 0x6A && sw2 == 0x82) ||
228 (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
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) || (sw1 == 0x62) || (sw1 == 0x63)) {
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 (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
311 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
312 }
313 /*Operation provided by the P2 parameter is not permitted by the applet.*/
314 else if (sw1 == 0x6A && sw2 == 0x86) {
315 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
316 }
317 }
318
319 if (sestatus != SecureElementStatus::SUCCESS) {
320 SecureElementStatus closeStatus = SecureElementStatus::IOERROR;
321 /*If first basic channel open fails, DeInit SE*/
322 if ((mOpenedChannels[DEFAULT_BASIC_CHANNEL] == false) &&
323 (mOpenedchannelCount == 0)) {
324 closeStatus = seHalDeInit();
325 } else {
326 closeStatus = closeChannel(DEFAULT_BASIC_CHANNEL);
327 }
328 if (closeStatus != SecureElementStatus::SUCCESS) {
329 ALOGE("%s: close Failed", __func__);
330 }
331 }
332 _hidl_cb(result, sestatus);
333 phNxpEse_free(cmdApdu.p_data);
334 phNxpEse_free(rspApdu.p_data);
335 return Void();
336 }
337
338 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
closeChannel(uint8_t channelNumber)339 SecureElement::closeChannel(uint8_t channelNumber) {
340 ESESTATUS status = ESESTATUS_FAILED;
341 SecureElementStatus sestatus = SecureElementStatus::FAILED;
342
343 phNxpEse_data cmdApdu;
344 phNxpEse_data rspApdu;
345
346 if ((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 (mOpenedChannels[channelNumber] != false) mOpenedchannelCount--;
379 mOpenedChannels[channelNumber] = false;
380 /*If there are no channels remaining close secureElement*/
381 if (mOpenedchannelCount == 0) {
382 sestatus = seHalDeInit();
383 } else {
384 sestatus = SecureElementStatus::SUCCESS;
385 }
386 return sestatus;
387 }
388
serviceDied(uint64_t,const wp<IBase> &)389 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
390 ALOGE("%s: SecureElement serviceDied!!!", __func__);
391 SecureElementStatus sestatus = seHalDeInit();
392 if (sestatus != SecureElementStatus::SUCCESS) {
393 ALOGE("%s: seHalDeInit Faliled!!!", __func__);
394 }
395 if (mCallbackV1_0 != nullptr) {
396 mCallbackV1_0->unlinkToDeath(this);
397 }
398 }
399
isSeInitialized()400 bool SecureElement::isSeInitialized() { return phNxpEse_isOpen(); }
401
seHalInit()402 ESESTATUS SecureElement::seHalInit() {
403 ESESTATUS status = ESESTATUS_SUCCESS;
404 phNxpEse_initParams initParams;
405 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
406 initParams.initMode = ESE_MODE_NORMAL;
407
408 status = phNxpEse_open(initParams);
409 if (status != ESESTATUS_SUCCESS) {
410 ALOGE("%s: SecureElement open failed!!!", __func__);
411 } else {
412 status = phNxpEse_init(initParams);
413 if (status != ESESTATUS_SUCCESS) {
414 ALOGE("%s: SecureElement init failed!!!", __func__);
415 }
416 }
417 return status;
418 }
419
420 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
seHalDeInit()421 SecureElement::seHalDeInit() {
422 ESESTATUS status = ESESTATUS_SUCCESS;
423 SecureElementStatus sestatus = SecureElementStatus::FAILED;
424 status = phNxpEse_deInit();
425 if (status != ESESTATUS_SUCCESS) {
426 sestatus = SecureElementStatus::FAILED;
427 } else {
428 status = phNxpEse_close();
429 if (status != ESESTATUS_SUCCESS) {
430 sestatus = SecureElementStatus::FAILED;
431 } else {
432 sestatus = SecureElementStatus::SUCCESS;
433
434 for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
435 mOpenedChannels[xx] = false;
436 }
437 mOpenedchannelCount = 0;
438 }
439 }
440 return sestatus;
441 }
442
onStateChange(bool result,std::string reason)443 void SecureElement::onStateChange(bool result, std::string reason) {
444 ALOGD("%s: result: %d, reaon= %s", __func__, result, reason.c_str());
445 mCallbackV1_0->onStateChange(result);
446 }
447
448 } // namespace implementation
449 } // namespace V1_0
450 } // namespace secure_element
451 } // namespace hardware
452 } // namespace android
453