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