1 /******************************************************************************
2 *
3 * Copyright 2018-2021 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 #include "SecureElement.h"
19 #include <android-base/logging.h>
20 #include <android-base/stringprintf.h>
21 #include "NxpEse.h"
22 #include "hal_nxpese.h"
23 #include "phNxpEse_Apdu_Api.h"
24 #include "phNxpEse_Api.h"
25 #ifdef NXP_BOOTTIME_UPDATE
26 #include "eSEClient.h"
27 #endif
28 /* Mutex to synchronize multiple transceive */
29
30 namespace android {
31 namespace hardware {
32 namespace secure_element {
33 namespace V1_2 {
34 namespace implementation {
35
36 #define LOG_TAG "nxpese@1.2-service"
37 #define DEFAULT_BASIC_CHANNEL 0x00
38 #define INVALID_LEN_SW1 0x64
39 #define INVALID_LEN_SW2 0xFF
40
41 typedef struct gsTransceiveBuffer {
42 phNxpEse_data cmdData;
43 phNxpEse_data rspData;
44 hidl_vec<uint8_t>* pRspDataBuff;
45 } sTransceiveBuffer_t;
46
47 static sTransceiveBuffer_t gsTxRxBuffer;
48 static hidl_vec<uint8_t> gsRspDataBuff(256);
49 sp<V1_0::ISecureElementHalCallback> SecureElement::mCallbackV1_0 = nullptr;
50 sp<V1_1::ISecureElementHalCallback> SecureElement::mCallbackV1_1 = nullptr;
51 std::vector<bool> SecureElement::mOpenedChannels;
52 using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
SecureElement()53 SecureElement::SecureElement()
54 : mMaxChannelCount(0), mOpenedchannelCount(0), mIsEseInitialized(false) {}
55
NotifySeWaitExtension(phNxpEse_wtxState state)56 void SecureElement::NotifySeWaitExtension(phNxpEse_wtxState state) {
57 if (state == WTX_ONGOING) {
58 LOG(INFO) << "SecureElement::WTX ongoing";
59 } else if (state == WTX_END) {
60 LOG(INFO) << "SecureElement::WTX ended";
61 }
62 }
63
init(const sp<::android::hardware::secure_element::V1_0::ISecureElementHalCallback> & clientCallback)64 Return<void> SecureElement::init(
65 const sp<
66 ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
67 clientCallback) {
68 ESESTATUS status = ESESTATUS_SUCCESS;
69 bool mIsInitDone = false;
70 phNxpEse_initParams initParams;
71 gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
72 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
73 initParams.initMode = ESE_MODE_NORMAL;
74 initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
75 initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
76
77 if (clientCallback == nullptr) {
78 return Void();
79 } else {
80 clientCallback->linkToDeath(this, 0 /*cookie*/);
81 }
82 LOG(INFO) << "SecureElement::init called here";
83 #ifdef NXP_BOOTTIME_UPDATE
84 if (ese_update != ESE_UPDATE_COMPLETED) {
85 mCallbackV1_0 = clientCallback;
86 clientCallback->onStateChange(false);
87 LOG(INFO) << "ESE JCOP Download in progress";
88 NxpEse::setSeCallBack(clientCallback);
89 return Void();
90 // Register
91 }
92 #endif
93 if (mIsEseInitialized) {
94 clientCallback->onStateChange(true);
95 return Void();
96 }
97
98 phNxpEse_setWtxCountLimit(OsuHalExtn::getInstance().getOSUMaxWtxCount());
99 status = phNxpEse_open(initParams);
100 if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
101 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
102 if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
103 ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
104 /*update OS mode during first init*/
105 IS_OSU_MODE(OsuHalExtn::getInstance().INIT, 0);
106
107 if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
108 LOG(INFO) << "ESE SPI init complete!!!";
109 mIsInitDone = true;
110 }
111 deInitStatus = phNxpEse_deInit();
112 if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
113 }
114 status = phNxpEse_close(deInitStatus);
115 }
116 phNxpEse_setWtxCountLimit(RESET_APP_WTX_COUNT);
117 if (status == ESESTATUS_SUCCESS && mIsInitDone) {
118 mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
119 mOpenedChannels.resize(mMaxChannelCount, false);
120 clientCallback->onStateChange(true);
121 mCallbackV1_0 = clientCallback;
122 } else {
123 LOG(ERROR) << "eSE-Hal Init failed";
124 clientCallback->onStateChange(false);
125 }
126 return Void();
127 }
128
init_1_1(const sp<::android::hardware::secure_element::V1_1::ISecureElementHalCallback> & clientCallback)129 Return<void> SecureElement::init_1_1(
130 const sp<
131 ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
132 clientCallback) {
133 ESESTATUS status = ESESTATUS_SUCCESS;
134 bool mIsInitDone = false;
135 phNxpEse_initParams initParams;
136 gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
137 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
138 initParams.initMode = ESE_MODE_NORMAL;
139 initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
140 initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
141 if (clientCallback == nullptr) {
142 return Void();
143 } else {
144 clientCallback->linkToDeath(this, 0 /*cookie*/);
145 }
146 LOG(INFO) << "SecureElement::init called here";
147 #ifdef NXP_BOOTTIME_UPDATE
148 if (ese_update != ESE_UPDATE_COMPLETED) {
149 mCallbackV1_1 = clientCallback;
150 clientCallback->onStateChange_1_1(false, "NXP SE update going on");
151 LOG(INFO) << "ESE JCOP Download in progress";
152 NxpEse::setSeCallBack_1_1(clientCallback);
153 return Void();
154 // Register
155 }
156 #endif
157 if (mIsEseInitialized) {
158 clientCallback->onStateChange_1_1(true, "NXP SE HAL init ok");
159 return Void();
160 }
161
162 phNxpEse_setWtxCountLimit(OsuHalExtn::getInstance().getOSUMaxWtxCount());
163 status = phNxpEse_open(initParams);
164 if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
165 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
166 if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
167 ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
168 /*update OS mode during first init*/
169 IS_OSU_MODE(OsuHalExtn::getInstance().INIT, 0);
170
171 if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
172 LOG(INFO) << "ESE SPI init complete!!!";
173 mIsInitDone = true;
174 }
175 deInitStatus = phNxpEse_deInit();
176 if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
177 }
178 status = phNxpEse_close(deInitStatus);
179 }
180 phNxpEse_setWtxCountLimit(RESET_APP_WTX_COUNT);
181 if (status == ESESTATUS_SUCCESS && mIsInitDone) {
182 mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
183 mOpenedChannels.resize(mMaxChannelCount, false);
184 clientCallback->onStateChange_1_1(true, "NXP SE HAL init ok");
185 mCallbackV1_1 = clientCallback;
186 } else {
187 LOG(ERROR) << "eSE-Hal Init failed";
188 clientCallback->onStateChange_1_1(false, "NXP SE HAL init failed");
189 }
190 return Void();
191 }
192
getAtr(getAtr_cb _hidl_cb)193 Return<void> SecureElement::getAtr(getAtr_cb _hidl_cb) {
194 AutoMutex guard(seHalLock);
195 LOG(ERROR) << "Processing ATR.....";
196 phNxpEse_data atrData;
197 hidl_vec<uint8_t> response;
198 ESESTATUS status = ESESTATUS_FAILED;
199 bool mIsSeHalInitDone = false;
200
201 if (IS_OSU_MODE(OsuHalExtn::getInstance().OPENLOGICAL) >=
202 OsuHalExtn::getInstance().OSU_PROP_MODE) {
203 LOG(ERROR) << "%s: Not allowed in dedicated mode!!!" << __func__;
204 _hidl_cb(response);
205 return Void();
206 }
207
208 if (!mIsEseInitialized) {
209 ESESTATUS status = seHalInit();
210 if (status != ESESTATUS_SUCCESS) {
211 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
212 _hidl_cb(response); /*Return with empty Vector*/
213 return Void();
214 } else {
215 mIsSeHalInitDone = true;
216 }
217 }
218 status = phNxpEse_SetEndPoint_Cntxt(0);
219 if (status != ESESTATUS_SUCCESS) {
220 LOG(ERROR) << "Endpoint set failed";
221 }
222 status = phNxpEse_getAtr(&atrData);
223 if (status != ESESTATUS_SUCCESS) {
224 LOG(ERROR) << "phNxpEse_getAtr failed";
225 _hidl_cb(response); /*Return with empty Vector*/
226 return Void();
227 } else {
228 response.resize(atrData.len);
229 memcpy(&response[0], atrData.p_data, atrData.len);
230 }
231
232 status = phNxpEse_ResetEndPoint_Cntxt(0);
233 if (status != ESESTATUS_SUCCESS) {
234 LOG(ERROR) << "Endpoint set failed";
235 }
236
237 if (status != ESESTATUS_SUCCESS) {
238 LOG(INFO) << StringPrintf("ATR Data[BytebyByte]=Look below for %d bytes",
239 atrData.len);
240 for (auto i = response.begin(); i != response.end(); ++i)
241 LOG(INFO) << StringPrintf("0x%x\t", *i);
242 }
243
244 _hidl_cb(response);
245 if (atrData.p_data != NULL) {
246 phNxpEse_free(atrData.p_data);
247 }
248 if (mIsSeHalInitDone) {
249 if (SecureElementStatus::SUCCESS != seHalDeInit())
250 LOG(ERROR) << "phNxpEse_getAtr seHalDeInit failed";
251 mIsEseInitialized = false;
252 mIsSeHalInitDone = false;
253 }
254 return Void();
255 }
256
isCardPresent()257 Return<bool> SecureElement::isCardPresent() { return true; }
258
transmit(const hidl_vec<uint8_t> & data,transmit_cb _hidl_cb)259 Return<void> SecureElement::transmit(const hidl_vec<uint8_t>& data,
260 transmit_cb _hidl_cb) {
261 AutoMutex guard(seHalLock);
262 ESESTATUS status = ESESTATUS_FAILED;
263 hidl_vec<uint8_t> result;
264 phNxpEse_memset(&gsTxRxBuffer.cmdData, 0x00, sizeof(phNxpEse_data));
265 phNxpEse_memset(&gsTxRxBuffer.rspData, 0x00, sizeof(phNxpEse_data));
266 gsTxRxBuffer.cmdData.len = (uint32_t)data.size();
267 gsTxRxBuffer.cmdData.p_data =
268 (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
269 if (NULL == gsTxRxBuffer.cmdData.p_data) {
270 LOG(ERROR) << "transmit failed to allocate the Memory!!!";
271 /*Return empty hidl_vec*/
272 _hidl_cb(result);
273 return Void();
274 }
275 OsuHalExtn::OsuApduMode mode = IS_OSU_MODE(
276 data, OsuHalExtn::getInstance().TRANSMIT, &gsTxRxBuffer.cmdData);
277 if (mode == OsuHalExtn::getInstance().OSU_BLOCKED_MODE) {
278 LOG(ERROR) << "Not allowed in dedicated mode!!!";
279 /*Return empty hidl_vec*/
280 _hidl_cb(result);
281 return Void();
282 } else if (mode == OsuHalExtn::getInstance().OSU_RST_MODE) {
283 uint8_t sw[2] = {0x90, 0x00};
284 result.resize(sizeof(sw));
285 memcpy(&result[0], sw, sizeof(sw));
286 _hidl_cb(result);
287 return Void();
288 } else {
289 // continue with normal processing
290 }
291 // memcpy(gsTxRxBuffer.cmdData.p_data, data.data(), gsTxRxBuffer.cmdData.len);
292 LOG(INFO) << "Acquired lock for SPI";
293 status = phNxpEse_SetEndPoint_Cntxt(0);
294 if (status != ESESTATUS_SUCCESS) {
295 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
296 }
297 status = phNxpEse_Transceive(&gsTxRxBuffer.cmdData, &gsTxRxBuffer.rspData);
298
299 if (status == ESESTATUS_SUCCESS) {
300 result.resize(gsTxRxBuffer.rspData.len);
301 memcpy(&result[0], gsTxRxBuffer.rspData.p_data, gsTxRxBuffer.rspData.len);
302 } else if (status == ESESTATUS_INVALID_RECEIVE_LENGTH) {
303 uint8_t respBuf[] = {INVALID_LEN_SW1, INVALID_LEN_SW2};
304 result.resize(sizeof(respBuf));
305 memcpy(&result[0], respBuf, sizeof(respBuf));
306 } else {
307 LOG(ERROR) << "transmit failed!!!";
308 }
309 status = phNxpEse_ResetEndPoint_Cntxt(0);
310 if (status != ESESTATUS_SUCCESS) {
311 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
312 }
313
314 _hidl_cb(result);
315 if (NULL != gsTxRxBuffer.cmdData.p_data) {
316 phNxpEse_free(gsTxRxBuffer.cmdData.p_data);
317 gsTxRxBuffer.cmdData.p_data = NULL;
318 }
319 if (NULL != gsTxRxBuffer.rspData.p_data) {
320 phNxpEse_free(gsTxRxBuffer.rspData.p_data);
321 gsTxRxBuffer.rspData.p_data = NULL;
322 }
323
324 return Void();
325 }
326
openLogicalChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openLogicalChannel_cb _hidl_cb)327 Return<void> SecureElement::openLogicalChannel(const hidl_vec<uint8_t>& aid,
328 uint8_t p2,
329 openLogicalChannel_cb _hidl_cb) {
330 AutoMutex guard(seHalLock);
331 hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
332
333 LogicalChannelResponse resApduBuff;
334 resApduBuff.channelNumber = 0xff;
335 memset(&resApduBuff, 0x00, sizeof(resApduBuff));
336
337 LOG(INFO) << "Acquired the lock from SPI openLogicalChannel";
338
339 if (IS_OSU_MODE(OsuHalExtn::getInstance().OPENLOGICAL) >=
340 OsuHalExtn::getInstance().OSU_PROP_MODE) {
341 LOG(ERROR) << "%s: Not allowed in dedicated mode!!!" << __func__;
342 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
343 return Void();
344 }
345 if (!mIsEseInitialized) {
346 ESESTATUS status = seHalInit();
347 if (status != ESESTATUS_SUCCESS) {
348 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
349 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
350 return Void();
351 }
352 }
353
354 if (mOpenedChannels.size() == 0x00) {
355 mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
356 mOpenedChannels.resize(mMaxChannelCount, false);
357 }
358
359 SecureElementStatus sestatus = SecureElementStatus::IOERROR;
360 ESESTATUS status = ESESTATUS_FAILED;
361 phNxpEse_data cmdApdu;
362 phNxpEse_data rspApdu;
363
364 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
365
366 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
367
368 cmdApdu.len = (uint32_t)manageChannelCommand.size();
369 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
370 sizeof(uint8_t));
371 memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
372
373 status = phNxpEse_SetEndPoint_Cntxt(0);
374 if (status != ESESTATUS_SUCCESS) {
375 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
376 }
377 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
378 if (status != ESESTATUS_SUCCESS) {
379 resApduBuff.channelNumber = 0xff;
380 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
381 rspApdu.p_data[rspApdu.len - 1] == 0x81) {
382 resApduBuff.channelNumber = 0xff;
383 sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
384 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
385 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
386 resApduBuff.channelNumber = rspApdu.p_data[0];
387 mOpenedchannelCount++;
388 mOpenedChannels[resApduBuff.channelNumber] = true;
389 sestatus = SecureElementStatus::SUCCESS;
390 } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
391 (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
392 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
393 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
394 }
395 /*Free the allocations*/
396 phNxpEse_free(cmdApdu.p_data);
397 phNxpEse_free(rspApdu.p_data);
398
399 if (sestatus != SecureElementStatus::SUCCESS) {
400 if (mOpenedchannelCount == 0) {
401 SecureElementStatus deInitStatus = seHalDeInit();
402 if (deInitStatus != SecureElementStatus::SUCCESS) {
403 LOG(INFO) << "seDeInit Failed";
404 }
405 }
406 /*If manageChanle is failed in any of above cases
407 send the callback and return*/
408 status = phNxpEse_ResetEndPoint_Cntxt(0);
409 if (status != ESESTATUS_SUCCESS) {
410 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
411 }
412 _hidl_cb(resApduBuff, sestatus);
413 return Void();
414 }
415 LOG(INFO) << "openLogicalChannel Sending selectApdu";
416 sestatus = SecureElementStatus::IOERROR;
417 status = ESESTATUS_FAILED;
418
419 phNxpEse_7816_cpdu_t cpdu;
420 phNxpEse_7816_rpdu_t rpdu;
421 phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
422 phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
423
424 if ((resApduBuff.channelNumber > 0x03) &&
425 (resApduBuff.channelNumber < 0x14)) {
426 /* update CLA byte accoridng to GP spec Table 11-12*/
427 cpdu.cla =
428 0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
429 } else if ((resApduBuff.channelNumber > 0x00) &&
430 (resApduBuff.channelNumber < 0x04)) {
431 /* update CLA byte accoridng to GP spec Table 11-11*/
432 cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
433 } else {
434 LOG(ERROR) << StringPrintf("%s: Invalid Channel no: %02x", __func__,
435 resApduBuff.channelNumber);
436 resApduBuff.channelNumber = 0xff;
437 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
438 return Void();
439 }
440 cpdu.ins = 0xA4; /* Instruction code */
441 cpdu.p1 = 0x04; /* Instruction parameter 1 */
442 cpdu.p2 = p2; /* Instruction parameter 2 */
443 cpdu.lc = (uint16_t)aid.size();
444 cpdu.le_type = 0x01;
445 cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
446 memcpy(cpdu.pdata, aid.data(), cpdu.lc);
447 cpdu.le = 256;
448
449 rpdu.len = 0x02;
450 rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
451
452 status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
453
454 if (status != ESESTATUS_SUCCESS) {
455 /*Transceive failed*/
456 if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
457 sestatus = SecureElementStatus::IOERROR;
458 } else {
459 sestatus = SecureElementStatus::FAILED;
460 }
461 } else {
462 /*Status word to be passed as part of response
463 So include additional length*/
464 uint16_t responseLen = rpdu.len + 2;
465 resApduBuff.selectResponse.resize(responseLen);
466 memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
467 resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
468 resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
469
470 /*Status is success*/
471 if ((rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) || (rpdu.sw1 == 0x62) ||
472 (rpdu.sw1 == 0x63)) {
473 sestatus = SecureElementStatus::SUCCESS;
474 }
475 /*AID provided doesn't match any applet on the secure element*/
476 else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
477 (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
478 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
479 }
480 /*Operation provided by the P2 parameter is not permitted by the applet.*/
481 else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
482 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
483 } else {
484 sestatus = SecureElementStatus::FAILED;
485 }
486 }
487 if (sestatus != SecureElementStatus::SUCCESS) {
488 SecureElementStatus closeChannelStatus =
489 internalCloseChannel(resApduBuff.channelNumber);
490 if (closeChannelStatus != SecureElementStatus::SUCCESS) {
491 LOG(ERROR) << "%s: closeChannel Failed" << __func__;
492 } else {
493 resApduBuff.channelNumber = 0xff;
494 }
495 }
496 status = phNxpEse_ResetEndPoint_Cntxt(0);
497 if (status != ESESTATUS_SUCCESS) {
498 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
499 }
500 _hidl_cb(resApduBuff, sestatus);
501 phNxpEse_free(cpdu.pdata);
502 phNxpEse_free(rpdu.pdata);
503
504 return Void();
505 }
506
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)507 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
508 uint8_t p2,
509 openBasicChannel_cb _hidl_cb) {
510 AutoMutex guard(seHalLock);
511 ESESTATUS status = ESESTATUS_SUCCESS;
512 phNxpEse_7816_cpdu_t cpdu;
513 phNxpEse_7816_rpdu_t rpdu;
514 hidl_vec<uint8_t> result;
515 hidl_vec<uint8_t> ls_aid = {0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C,
516 0x41, 0x01, 0x43, 0x4F, 0x52, 0x01};
517
518 LOG(ERROR) << "Acquired the lock in SPI openBasicChannel";
519 OsuHalExtn::OsuApduMode mode =
520 IS_OSU_MODE(aid, OsuHalExtn::getInstance().OPENBASIC);
521 if (mode == OsuHalExtn::OSU_PROP_MODE) {
522 uint8_t sw[2] = {0x90, 0x00};
523 result.resize(sizeof(sw));
524 memcpy(&result[0], sw, 2);
525 if (mIsEseInitialized) {
526 /*Close existing sessions if any to start dedicated OSU Mode
527 * with OSU specific settings in TZ/TEE*/
528 if (seHalDeInit() != SecureElementStatus::SUCCESS) {
529 LOG(INFO) << "seDeInit Failed";
530 _hidl_cb(result, SecureElementStatus::IOERROR);
531 return Void();
532 }
533 }
534 phNxpEse_setWtxCountLimit(OsuHalExtn::getInstance().getOSUMaxWtxCount());
535 ESESTATUS status = ESESTATUS_FAILED;
536 uint8_t retry = 0;
537 do {
538 /*For Reset Recovery*/
539 status = seHalInit();
540 } while (status != ESESTATUS_SUCCESS && retry++ < 1);
541 if (status != ESESTATUS_SUCCESS) {
542 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
543 phNxpEse_setWtxCountLimit(RESET_APP_WTX_COUNT);
544 _hidl_cb(result, SecureElementStatus::IOERROR);
545 return Void();
546 }
547 if (phNxpEse_doResetProtection(true) != ESESTATUS_SUCCESS) {
548 LOG(ERROR) << "%s: Enable Reset Protection Failed!!!" << __func__;
549 _hidl_cb(result, SecureElementStatus::FAILED);
550 } else {
551 _hidl_cb(result, SecureElementStatus::SUCCESS);
552 }
553 return Void();
554 } else if (mode == OsuHalExtn::OSU_BLOCKED_MODE) {
555 _hidl_cb(result, SecureElementStatus::IOERROR);
556 return Void();
557 } else {
558 }
559
560 if (!mIsEseInitialized) {
561 ESESTATUS status = seHalInit();
562 if (status != ESESTATUS_SUCCESS) {
563 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
564 _hidl_cb(result, SecureElementStatus::IOERROR);
565 return Void();
566 }
567 }
568
569 if (mOpenedChannels.size() == 0x00) {
570 mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
571 mOpenedChannels.resize(mMaxChannelCount, false);
572 }
573 phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
574 phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
575
576 cpdu.cla = 0x00; /* Class of instruction */
577 cpdu.ins = 0xA4; /* Instruction code */
578 cpdu.p1 = 0x04; /* Instruction parameter 1 */
579 cpdu.p2 = p2; /* Instruction parameter 2 */
580 cpdu.lc = (uint16_t)aid.size();
581 cpdu.le_type = 0x01;
582 cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
583 memcpy(cpdu.pdata, aid.data(), cpdu.lc);
584 cpdu.le = 256;
585
586 rpdu.len = 0x02;
587 rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
588
589 status = phNxpEse_SetEndPoint_Cntxt(0);
590 if (status != ESESTATUS_SUCCESS) {
591 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
592 }
593 status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
594 SecureElementStatus sestatus;
595 memset(&sestatus, 0x00, sizeof(sestatus));
596
597 if (status != ESESTATUS_SUCCESS) {
598 /* Transceive failed */
599 if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
600 sestatus = SecureElementStatus::IOERROR;
601 } else {
602 sestatus = SecureElementStatus::FAILED;
603 }
604 } else {
605 /*Status word to be passed as part of response
606 So include additional length*/
607 uint16_t responseLen = rpdu.len + 2;
608 result.resize(responseLen);
609 memcpy(&result[0], rpdu.pdata, rpdu.len);
610 result[responseLen - 1] = rpdu.sw2;
611 result[responseLen - 2] = rpdu.sw1;
612
613 /*Status is success*/
614 if (((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) || (rpdu.sw1 == 0x62) ||
615 (rpdu.sw1 == 0x63)) {
616 /*Set basic channel reference if it is not set */
617 if (!mOpenedChannels[0]) {
618 mOpenedChannels[0] = true;
619 mOpenedchannelCount++;
620 }
621
622 sestatus = SecureElementStatus::SUCCESS;
623 }
624 /*AID provided doesn't match any applet on the secure element*/
625 else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
626 (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
627 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
628 }
629 /*Operation provided by the P2 parameter is not permitted by the applet.*/
630 else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
631 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
632 } else {
633 sestatus = SecureElementStatus::FAILED;
634 }
635 }
636 status = phNxpEse_ResetEndPoint_Cntxt(0);
637 if (status != ESESTATUS_SUCCESS) {
638 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
639 }
640 if (sestatus != SecureElementStatus::SUCCESS) {
641 SecureElementStatus closeChannelStatus =
642 internalCloseChannel(DEFAULT_BASIC_CHANNEL);
643 if (closeChannelStatus != SecureElementStatus::SUCCESS) {
644 LOG(ERROR) << "%s: closeChannel Failed" << __func__;
645 }
646 }
647 _hidl_cb(result, sestatus);
648 phNxpEse_free(cpdu.pdata);
649 phNxpEse_free(rpdu.pdata);
650 return Void();
651 }
652
internalCloseChannel(uint8_t channelNumber)653 Return<SecureElementStatus> SecureElement::internalCloseChannel(
654 uint8_t channelNumber) {
655 ESESTATUS status = ESESTATUS_SUCCESS;
656 SecureElementStatus sestatus = SecureElementStatus::FAILED;
657 phNxpEse_7816_cpdu_t cpdu;
658 phNxpEse_7816_rpdu_t rpdu;
659
660 LOG(ERROR) << "Acquired the lock in SPI internalCloseChannel";
661 LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d",
662 mMaxChannelCount, channelNumber);
663 if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL ||
664 channelNumber >= mMaxChannelCount) {
665 LOG(ERROR) << StringPrintf("invalid channel!!! %d", channelNumber);
666 } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
667 phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
668 phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
669 cpdu.cla = channelNumber; /* Class of instruction */
670 cpdu.ins = 0x70; /* Instruction code */
671 cpdu.p1 = 0x80; /* Instruction parameter 1 */
672 cpdu.p2 = channelNumber; /* Instruction parameter 2 */
673 cpdu.lc = 0x00;
674 cpdu.le = 0x9000;
675 status = phNxpEse_SetEndPoint_Cntxt(0);
676 if (status != ESESTATUS_SUCCESS) {
677 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
678 }
679 status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
680 if (status == ESESTATUS_SUCCESS) {
681 if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
682 sestatus = SecureElementStatus::SUCCESS;
683 }
684 }
685 status = phNxpEse_ResetEndPoint_Cntxt(0);
686 if (status != ESESTATUS_SUCCESS) {
687 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
688 }
689 }
690 if (channelNumber < mMaxChannelCount) {
691 if (mOpenedChannels[channelNumber]) {
692 mOpenedChannels[channelNumber] = false;
693 mOpenedchannelCount--;
694 }
695 }
696 /*If there are no channels remaining close secureElement*/
697 if (mOpenedchannelCount == 0) {
698 sestatus = seHalDeInit();
699 } else {
700 sestatus = SecureElementStatus::SUCCESS;
701 }
702 return sestatus;
703 }
704
closeChannel(uint8_t channelNumber)705 Return<SecureElementStatus> SecureElement::closeChannel(uint8_t channelNumber) {
706 AutoMutex guard(seHalLock);
707 if (IS_OSU_MODE(OsuHalExtn::getInstance().CLOSE, channelNumber) ==
708 OsuHalExtn::getInstance().NON_OSU_MODE) {
709 return internalCloseChannel(channelNumber);
710 } else {
711 /*Decrement channel count opened to
712 * keep in sync with service */
713 if (channelNumber < mMaxChannelCount) {
714 if (mOpenedChannels[channelNumber]) {
715 mOpenedChannels[channelNumber] = false;
716 mOpenedchannelCount--;
717 }
718 }
719 return SecureElementStatus::SUCCESS;
720 }
721 }
722
serviceDied(uint64_t,const wp<IBase> &)723 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
724 LOG(ERROR) << " SecureElement serviceDied!!!";
725 mIsEseInitialized = false;
726 if (seHalDeInit() != SecureElementStatus::SUCCESS) {
727 LOG(ERROR) << "SE Deinit not successful";
728 }
729 }
seHalInit()730 ESESTATUS SecureElement::seHalInit() {
731 ESESTATUS status = ESESTATUS_SUCCESS;
732 phNxpEse_initParams initParams;
733 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
734 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
735 initParams.initMode = ESE_MODE_NORMAL;
736 initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
737 initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
738
739 status = phNxpEse_open(initParams);
740 if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
741 if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
742 ESESTATUS_SUCCESS == (status = phNxpEse_init(initParams))) {
743 if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
744 mIsEseInitialized = true;
745 LOG(INFO) << "ESE SPI init complete!!!";
746 return ESESTATUS_SUCCESS;
747 }
748 } else {
749 LOG(INFO) << "ESE SPI init NOT successful";
750 status = ESESTATUS_FAILED;
751 }
752 deInitStatus = phNxpEse_deInit();
753 if (phNxpEse_close(deInitStatus) != ESESTATUS_SUCCESS) {
754 LOG(INFO) << "ESE close not successful";
755 status = ESESTATUS_FAILED;
756 }
757 mIsEseInitialized = false;
758 }
759 return status;
760 }
761
seHalDeInit()762 Return<SecureElementStatus> SecureElement::seHalDeInit() {
763 ESESTATUS status = ESESTATUS_SUCCESS;
764 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
765 bool mIsDeInitDone = true;
766 SecureElementStatus sestatus = SecureElementStatus::FAILED;
767 status = phNxpEse_SetEndPoint_Cntxt(0);
768 if (status != ESESTATUS_SUCCESS) {
769 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
770 mIsDeInitDone = false;
771 }
772 deInitStatus = phNxpEse_deInit();
773 if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
774 status = phNxpEse_ResetEndPoint_Cntxt(0);
775 if (status != ESESTATUS_SUCCESS) {
776 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
777 mIsDeInitDone = false;
778 }
779 status = phNxpEse_close(deInitStatus);
780 if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
781 sestatus = SecureElementStatus::SUCCESS;
782 ;
783 } else {
784 LOG(ERROR) << "seHalDeInit: Failed";
785 }
786 mIsEseInitialized = false;
787 for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
788 mOpenedChannels[xx] = false;
789 }
790 mOpenedchannelCount = 0;
791
792 return sestatus;
793 }
794 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
reset()795 SecureElement::reset() {
796 ESESTATUS status = ESESTATUS_SUCCESS;
797 SecureElementStatus sestatus = SecureElementStatus::FAILED;
798 LOG(ERROR) << "%s: Enter" << __func__;
799 if (!mIsEseInitialized) {
800 ESESTATUS status = seHalInit();
801 if (status != ESESTATUS_SUCCESS) {
802 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
803 }
804 }
805 if (status == ESESTATUS_SUCCESS) {
806 mCallbackV1_1->onStateChange_1_1(false, "reset the SE");
807 status = phNxpEse_reset();
808 if (status != ESESTATUS_SUCCESS) {
809 LOG(ERROR) << "%s: SecureElement reset failed!!" << __func__;
810 } else {
811 sestatus = SecureElementStatus::SUCCESS;
812 if (mOpenedChannels.size() == 0x00) {
813 mMaxChannelCount =
814 (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
815 mOpenedChannels.resize(mMaxChannelCount, false);
816 }
817 for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
818 mOpenedChannels[xx] = false;
819 }
820 mOpenedchannelCount = 0;
821 mCallbackV1_1->onStateChange_1_1(true, "SE initialized");
822 }
823 }
824 LOG(ERROR) << "%s: Exit" << __func__;
825 return sestatus;
826 }
827
828 } // namespace implementation
829 } // namespace V1_2
830 } // namespace secure_element
831 } // namespace hardware
832 } // namespace android
833