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) || (sw1 == 0x62) || (sw1 == 0x63)) {
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 (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
230 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
231 }
232 /*Operation provided by the P2 parameter is not permitted by the applet.*/
233 else if (sw1 == 0x6A && sw2 == 0x86) {
234 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
235 }
236 }
237
238 if (sestatus != SecureElementStatus::SUCCESS) {
239 SecureElementStatus closeChannelStatus =
240 closeChannel(resApduBuff.channelNumber);
241 if (closeChannelStatus != SecureElementStatus::SUCCESS) {
242 ALOGE("%s: closeChannel Failed", __func__);
243 } else {
244 resApduBuff.channelNumber = 0xff;
245 }
246 }
247 _hidl_cb(resApduBuff, sestatus);
248 phNxpEse_free(cmdApdu.p_data);
249 phNxpEse_free(rspApdu.p_data);
250
251 return Void();
252 }
253
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)254 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
255 uint8_t p2,
256 openBasicChannel_cb _hidl_cb) {
257 hidl_vec<uint8_t> result;
258
259 if (!isSeInitialized()) {
260 ESESTATUS status = seHalInit();
261 if (status != ESESTATUS_SUCCESS) {
262 ALOGE("%s: seHalInit Failed!!!", __func__);
263 _hidl_cb(result, SecureElementStatus::IOERROR);
264 return Void();
265 }
266 }
267
268 SecureElementStatus sestatus = SecureElementStatus::IOERROR;
269 ESESTATUS status = ESESTATUS_FAILED;
270 phNxpEse_data cmdApdu;
271 phNxpEse_data rspApdu;
272
273 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
274 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
275
276 cmdApdu.len = (int32_t)(5 + aid.size());
277 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(cmdApdu.len * sizeof(uint8_t));
278 if (cmdApdu.p_data != NULL) {
279 uint8_t xx = 0;
280 cmdApdu.p_data[xx++] = 0x00; // basic channel
281 cmdApdu.p_data[xx++] = 0xA4; // INS
282 cmdApdu.p_data[xx++] = 0x04; // P1
283 cmdApdu.p_data[xx++] = p2; // P2
284 cmdApdu.p_data[xx++] = aid.size(); // Lc
285 memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
286
287 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
288 }
289
290 if (status != ESESTATUS_SUCCESS) {
291 /* Transceive failed */
292 sestatus = SecureElementStatus::IOERROR;
293 } else {
294 uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
295 uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
296 /*Return response on success, empty vector on failure*/
297 /*Status is success*/
298 if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
299 /*Copy the response including status word*/
300 result.resize(rspApdu.len);
301 memcpy(&result[0], rspApdu.p_data, rspApdu.len);
302 /*Set basic channel reference if it is not set */
303 if (!mOpenedChannels[0]) {
304 mOpenedChannels[0] = true;
305 mOpenedchannelCount++;
306 }
307 sestatus = SecureElementStatus::SUCCESS;
308 }
309 /*AID provided doesn't match any applet on the secure element*/
310 else if ((sw1 == 0x6A && sw2 == 0x82) ||
311 (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
312 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
313 }
314 /*Operation provided by the P2 parameter is not permitted by the applet.*/
315 else if (sw1 == 0x6A && sw2 == 0x86) {
316 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
317 }
318 }
319
320 if (sestatus != SecureElementStatus::SUCCESS) {
321 SecureElementStatus closeStatus = SecureElementStatus::IOERROR;
322 /*If first basic channel open fails, DeInit SE*/
323 if ((mOpenedChannels[DEFAULT_BASIC_CHANNEL] == false) &&
324 (mOpenedchannelCount == 0)) {
325 closeStatus = seHalDeInit();
326 } else {
327 closeStatus = closeChannel(DEFAULT_BASIC_CHANNEL);
328 }
329 if (closeStatus != SecureElementStatus::SUCCESS) {
330 ALOGE("%s: close Failed", __func__);
331 }
332 }
333 _hidl_cb(result, sestatus);
334 phNxpEse_free(cmdApdu.p_data);
335 phNxpEse_free(rspApdu.p_data);
336 return Void();
337 }
338
339 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
closeChannel(uint8_t channelNumber)340 SecureElement::closeChannel(uint8_t channelNumber) {
341 ESESTATUS status = ESESTATUS_FAILED;
342 SecureElementStatus sestatus = SecureElementStatus::FAILED;
343
344 phNxpEse_data cmdApdu;
345 phNxpEse_data rspApdu;
346
347 if ((channelNumber < DEFAULT_BASIC_CHANNEL) ||
348 (channelNumber >= MAX_LOGICAL_CHANNELS) ||
349 (mOpenedChannels[channelNumber] == false)) {
350 ALOGE("%s: invalid channel!!!", __func__);
351 sestatus = SecureElementStatus::FAILED;
352 } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
353 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
354 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
355 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(5 * sizeof(uint8_t));
356 if (cmdApdu.p_data != NULL) {
357 uint8_t xx = 0;
358
359 cmdApdu.p_data[xx++] = channelNumber;
360 cmdApdu.p_data[xx++] = 0x70; // INS
361 cmdApdu.p_data[xx++] = 0x80; // P1
362 cmdApdu.p_data[xx++] = channelNumber; // P2
363 cmdApdu.p_data[xx++] = 0x00; // Lc
364 cmdApdu.len = xx;
365
366 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
367 }
368 if (status != ESESTATUS_SUCCESS) {
369 sestatus = SecureElementStatus::FAILED;
370 } else if ((rspApdu.p_data[rspApdu.len - 2] == 0x90) &&
371 (rspApdu.p_data[rspApdu.len - 1] == 0x00)) {
372 sestatus = SecureElementStatus::SUCCESS;
373 } else {
374 sestatus = SecureElementStatus::FAILED;
375 }
376 phNxpEse_free(cmdApdu.p_data);
377 phNxpEse_free(rspApdu.p_data);
378 }
379
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 return sestatus;
389 }
390
serviceDied(uint64_t,const wp<IBase> &)391 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
392 ALOGE("%s: SecureElement serviceDied!!!", __func__);
393 SecureElementStatus sestatus = seHalDeInit();
394 if (sestatus != SecureElementStatus::SUCCESS) {
395 ALOGE("%s: seHalDeInit Faliled!!!", __func__);
396 }
397 if (mCallbackV1_0 != nullptr) {
398 mCallbackV1_0->unlinkToDeath(this);
399 }
400 }
401
isSeInitialized()402 bool SecureElement::isSeInitialized() { return phNxpEse_isOpen(); }
403
seHalInit()404 ESESTATUS SecureElement::seHalInit() {
405 ESESTATUS status = ESESTATUS_SUCCESS;
406 phNxpEse_initParams initParams;
407 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
408 initParams.initMode = ESE_MODE_NORMAL;
409
410 status = phNxpEse_open(initParams);
411 if (status != ESESTATUS_SUCCESS) {
412 ALOGE("%s: SecureElement open failed!!!", __func__);
413 } else {
414 status = phNxpEse_init(initParams);
415 if (status != ESESTATUS_SUCCESS) {
416 ALOGE("%s: SecureElement init failed!!!", __func__);
417 }
418 }
419 return status;
420 }
421
422 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
seHalDeInit()423 SecureElement::seHalDeInit() {
424 ESESTATUS status = ESESTATUS_SUCCESS;
425 SecureElementStatus sestatus = SecureElementStatus::FAILED;
426 status = phNxpEse_deInit();
427 if (status != ESESTATUS_SUCCESS) {
428 sestatus = SecureElementStatus::FAILED;
429 } else {
430 status = phNxpEse_close();
431 if (status != ESESTATUS_SUCCESS) {
432 sestatus = SecureElementStatus::FAILED;
433 } else {
434 sestatus = SecureElementStatus::SUCCESS;
435
436 for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
437 mOpenedChannels[xx] = false;
438 }
439 mOpenedchannelCount = 0;
440 }
441 }
442 return sestatus;
443 }
444
onStateChange(bool result,std::string reason)445 void SecureElement::onStateChange(bool result, std::string reason) {
446 ALOGD("%s: result: %d, reaon= %s", __func__, result, reason.c_str());
447 mCallbackV1_0->onStateChange(result);
448 }
449
450 } // namespace implementation
451 } // namespace V1_0
452 } // namespace secure_element
453 } // namespace hardware
454 } // namespace android
455