1 /******************************************************************************
2 *
3 * Copyright 2018-2023 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
20 #ifdef NXP_BOOTTIME_UPDATE
21 #include "NxpEse.h"
22 #include "eSEClient.h"
23 #endif
24 #include <android-base/logging.h>
25 #include <android-base/stringprintf.h>
26 #include <hidl/HidlTransportSupport.h>
27
28 #include "hal_nxpese.h"
29 #include "phNxpEse_Apdu_Api.h"
30 #include "phNxpEse_Api.h"
31 /* Mutex to synchronize multiple transceive */
32 #include <memunreachable/memunreachable.h>
33 namespace android {
34 namespace hardware {
35 namespace secure_element {
36 namespace V1_2 {
37 namespace implementation {
38
39 #define DEFAULT_BASIC_CHANNEL 0x00
40 #define INVALID_LEN_SW1 0x64
41 #define INVALID_LEN_SW2 0xFF
42 #define SW1_BYTES_REMAINING 0x61
43 #define NUM_OF_CH4 0x04
44 #define NUM_OF_CH5 0x05
45 typedef struct gsTransceiveBuffer {
46 phNxpEse_data cmdData;
47 phNxpEse_data rspData;
48 hidl_vec<uint8_t>* pRspDataBuff;
49 } sTransceiveBuffer_t;
50
51 static Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
52 getResponseInternal(uint8_t cla, phNxpEse_7816_rpdu_t& rpdu,
53 hidl_vec<uint8_t>& result);
54 static sTransceiveBuffer_t gsTxRxBuffer;
55 static hidl_vec<uint8_t> gsRspDataBuff(256);
56 sp<V1_0::ISecureElementHalCallback> SecureElement::mCallbackV1_0 = nullptr;
57 std::vector<bool> SecureElement::mOpenedChannels;
58 #ifdef NXP_BOOTTIME_UPDATE
59 using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
60 #endif
SecureElement()61 SecureElement::SecureElement()
62 : mMaxChannelCount(0), mOpenedchannelCount(0), mIsEseInitialized(false) {}
63
NotifySeWaitExtension(phNxpEse_wtxState state)64 void SecureElement::NotifySeWaitExtension(phNxpEse_wtxState state) {
65 if (state == WTX_ONGOING) {
66 LOG(INFO) << "SecureElement::WTX ongoing";
67 } else if (state == WTX_END) {
68 LOG(INFO) << "SecureElement::WTX ended";
69 }
70 }
71
init(const sp<::android::hardware::secure_element::V1_0::ISecureElementHalCallback> & clientCallback)72 Return<void> SecureElement::init(
73 const sp<
74 ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
75 clientCallback) {
76 ESESTATUS status = ESESTATUS_SUCCESS;
77 bool mIsInitDone = false;
78 phNxpEse_initParams initParams;
79 gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
80 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
81 initParams.initMode = ESE_MODE_NORMAL;
82 initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
83 initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
84
85 if (clientCallback == nullptr) {
86 return Void();
87 } else {
88 clientCallback->linkToDeath(this, 0 /*cookie*/);
89 }
90 LOG(INFO) << "SecureElement::init called here";
91 #ifdef NXP_BOOTTIME_UPDATE
92 if (ese_update != ESE_UPDATE_COMPLETED) {
93 mCallbackV1_0 = clientCallback;
94 clientCallback->onStateChange(false);
95 LOG(INFO) << "ESE JCOP Download in progress";
96 NxpEse::setSeCallBack(clientCallback);
97 return Void();
98 // Register
99 }
100 #endif
101 if (mIsEseInitialized) {
102 clientCallback->onStateChange(true);
103 return Void();
104 }
105
106 phNxpEse_setWtxCountLimit(OsuHalExtn::getInstance().getOSUMaxWtxCount());
107 status = phNxpEse_open(initParams);
108 if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
109 ESESTATUS initStatus = ESESTATUS_SUCCESS;
110 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
111 if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0)) {
112 initStatus = phNxpEse_init(initParams);
113 if (ESESTATUS_SUCCESS == initStatus) {
114 if (GET_CHIP_OS_VERSION() < OS_VERSION_8_9) {
115 /*update OS mode during first init*/
116 IS_OSU_MODE(OsuHalExtn::getInstance().INIT, 0);
117 }
118
119 if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
120 LOG(INFO) << "ESE SPI init complete!!!";
121 mIsInitDone = true;
122 }
123 deInitStatus = phNxpEse_deInit();
124 if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
125 }
126 }
127 status = phNxpEse_close(deInitStatus);
128 /*Enable terminal post recovery(i.e. close success) from transmit failure */
129 if (status == ESESTATUS_SUCCESS &&
130 (initStatus == ESESTATUS_TRANSCEIVE_FAILED ||
131 initStatus == ESESTATUS_FAILED)) {
132 if (GET_CHIP_OS_VERSION() < OS_VERSION_8_9)
133 IS_OSU_MODE(OsuHalExtn::getInstance().INIT, 0);
134 mIsInitDone = true;
135 }
136 }
137 phNxpEse_setWtxCountLimit(RESET_APP_WTX_COUNT);
138 if (status == ESESTATUS_SUCCESS && mIsInitDone) {
139 mHasPriorityAccess = phNxpEse_isPriorityAccessEnabled();
140 mMaxChannelCount = getMaxChannelCnt();
141 mOpenedChannels.resize(mMaxChannelCount, false);
142 clientCallback->onStateChange(true);
143 mCallbackV1_0 = clientCallback;
144 } else {
145 LOG(ERROR) << "eSE-Hal Init failed";
146 clientCallback->onStateChange(false);
147 }
148 return Void();
149 }
registerCallback(const sp<V1_1::ISecureElementHalCallback> & callback)150 void SecureElement::registerCallback(
151 const sp<V1_1::ISecureElementHalCallback>& callback) {
152 if (callback == nullptr) {
153 return;
154 }
155 mCallbacks.push_back(callback);
156
157 LOG(INFO) << __func__ << " New client " << callback.get()
158 << " registered . total clients = " << mCallbacks.size();
159
160 auto linkRet = callback->linkToDeath(this, 0u /* cookie */);
161 if (!linkRet.withDefault(false)) {
162 LOG(WARNING) << __func__ << " Cannot link to death: "
163 << (linkRet.isOk() ? "linkToDeath returns false"
164 : linkRet.description());
165 }
166 }
167
unregisterCallback(const sp<IBase> & callback)168 void SecureElement::unregisterCallback(const sp<IBase>& callback) {
169 if (callback == nullptr) return;
170 bool removed = false;
171
172 for (auto it = mCallbacks.begin(); it != mCallbacks.end();) {
173 if (interfacesEqual(*it, callback)) {
174 it = mCallbacks.erase(it);
175 removed = true;
176 } else {
177 ++it;
178 }
179 }
180 callback->unlinkToDeath(this).isOk(); // ignore errors
181
182 if (removed)
183 LOG(INFO) << __func__ << " client " << callback.get()
184 << " removed. Total clients = " << mCallbacks.size();
185 else
186 LOG(WARNING) << __func__ << " Failed to remove client. total clients = "
187 << mCallbacks.size();
188 }
init_1_1(const sp<::android::hardware::secure_element::V1_1::ISecureElementHalCallback> & clientCallback)189 Return<void> SecureElement::init_1_1(
190 const sp<
191 ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
192 clientCallback) {
193 ESESTATUS status = ESESTATUS_SUCCESS;
194 bool mIsInitDone = false;
195 phNxpEse_initParams initParams;
196 gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
197 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
198 initParams.initMode = ESE_MODE_NORMAL;
199 initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
200 initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
201
202 if (clientCallback == nullptr) return Void();
203
204 LOG(INFO) << "SecureElement::init called here";
205 #ifdef NXP_BOOTTIME_UPDATE
206 if (ese_update != ESE_UPDATE_COMPLETED) {
207 clientCallback->onStateChange_1_1(false, "NXP SE update going on");
208 LOG(INFO) << "ESE JCOP Download in progress";
209 NxpEse::setSeCallBack_1_1(clientCallback);
210 return Void();
211 }
212 #endif
213 registerCallback(clientCallback);
214 if (mIsEseInitialized) {
215 clientCallback->onStateChange_1_1(true, "NXP SE HAL init ok");
216 return Void();
217 }
218
219 phNxpEse_setWtxCountLimit(OsuHalExtn::getInstance().getOSUMaxWtxCount());
220 status = phNxpEse_open(initParams);
221 if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
222 ESESTATUS initStatus = ESESTATUS_SUCCESS;
223 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
224 if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0)) {
225 initStatus = phNxpEse_init(initParams);
226 if (initStatus == ESESTATUS_SUCCESS) {
227 /*update OS mode during first init*/
228 if (GET_CHIP_OS_VERSION() < OS_VERSION_8_9)
229 IS_OSU_MODE(OsuHalExtn::getInstance().INIT, 0);
230
231 if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
232 LOG(INFO) << "ESE SPI init complete!!!";
233 mIsInitDone = true;
234 }
235 deInitStatus = phNxpEse_deInit();
236 if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
237 }
238 }
239 status = phNxpEse_close(deInitStatus);
240 /*Enable terminal post recovery(i.e. close success) from transmit failure */
241 if (status == ESESTATUS_SUCCESS &&
242 (initStatus == ESESTATUS_TRANSCEIVE_FAILED ||
243 initStatus == ESESTATUS_FAILED)) {
244 if (GET_CHIP_OS_VERSION() < OS_VERSION_8_9)
245 IS_OSU_MODE(OsuHalExtn::getInstance().INIT, 0);
246 mIsInitDone = true;
247 }
248 }
249 phNxpEse_setWtxCountLimit(RESET_APP_WTX_COUNT);
250 if (status == ESESTATUS_SUCCESS && mIsInitDone) {
251 mHasPriorityAccess = phNxpEse_isPriorityAccessEnabled();
252 mMaxChannelCount = getMaxChannelCnt();
253 mOpenedChannels.resize(mMaxChannelCount, false);
254 clientCallback->onStateChange_1_1(true, "NXP SE HAL init ok");
255 } else {
256 LOG(ERROR) << "eSE-Hal Init failed";
257 clientCallback->onStateChange_1_1(false, "NXP SE HAL init failed");
258 // remove it from the list of registered callbacks
259 // Client anyway has to call the init again
260 unregisterCallback(clientCallback);
261 }
262 return Void();
263 }
264
getAtr(getAtr_cb _hidl_cb)265 Return<void> SecureElement::getAtr(getAtr_cb _hidl_cb) {
266 AutoMutex guard(seHalLock);
267 LOG(ERROR) << "Processing ATR.....";
268 phNxpEse_data atrData;
269 hidl_vec<uint8_t> response;
270 ESESTATUS status = ESESTATUS_FAILED;
271 bool mIsSeHalInitDone = false;
272
273 // In dedicated mode getATR not allowed
274 if ((GET_CHIP_OS_VERSION() < OS_VERSION_8_9) &&
275 (IS_OSU_MODE(OsuHalExtn::getInstance().GETATR))) {
276 LOG(ERROR) << "%s: Not allowed in dedicated mode!!!" << __func__;
277 _hidl_cb(response);
278 return Void();
279 }
280
281 if (!mIsEseInitialized) {
282 ESESTATUS status = seHalInit();
283 if (status != ESESTATUS_SUCCESS) {
284 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
285 _hidl_cb(response); /*Return with empty Vector*/
286 return Void();
287 } else {
288 mIsSeHalInitDone = true;
289 }
290 }
291 status = phNxpEse_SetEndPoint_Cntxt(0);
292 if (status != ESESTATUS_SUCCESS) {
293 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed";
294 }
295 status = phNxpEse_getAtr(&atrData);
296 if (status != ESESTATUS_SUCCESS) {
297 LOG(ERROR) << "phNxpEse_getAtr failed";
298 _hidl_cb(response); /*Return with empty Vector*/
299 return Void();
300 } else {
301 response.resize(atrData.len);
302 memcpy(&response[0], atrData.p_data, atrData.len);
303 }
304
305 status = phNxpEse_ResetEndPoint_Cntxt(0);
306 if (status != ESESTATUS_SUCCESS) {
307 LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed";
308 }
309
310 if (status != ESESTATUS_SUCCESS) {
311 LOG(INFO) << StringPrintf("ATR Data[BytebyByte]=Look below for %d bytes",
312 atrData.len);
313 for (auto i = response.begin(); i != response.end(); ++i)
314 LOG(INFO) << StringPrintf("0x%x\t", *i);
315 }
316
317 _hidl_cb(response);
318 if (atrData.p_data != NULL) {
319 phNxpEse_free(atrData.p_data);
320 }
321 if (mIsSeHalInitDone) {
322 if (SecureElementStatus::SUCCESS != seHalDeInit())
323 LOG(ERROR) << "phNxpEse_getAtr seHalDeInit failed";
324 mIsEseInitialized = false;
325 mIsSeHalInitDone = false;
326 }
327 return Void();
328 }
329
isCardPresent()330 Return<bool> SecureElement::isCardPresent() { return true; }
331
transmit(const hidl_vec<uint8_t> & data,transmit_cb _hidl_cb)332 Return<void> SecureElement::transmit(const hidl_vec<uint8_t>& data,
333 transmit_cb _hidl_cb) {
334 AutoMutex guard(seHalLock);
335 ESESTATUS status = ESESTATUS_FAILED;
336 hidl_vec<uint8_t> result;
337 phNxpEse_memset(&gsTxRxBuffer.cmdData, 0x00, sizeof(phNxpEse_data));
338 phNxpEse_memset(&gsTxRxBuffer.rspData, 0x00, sizeof(phNxpEse_data));
339 gsTxRxBuffer.cmdData.len = (uint32_t)data.size();
340 gsTxRxBuffer.cmdData.p_data =
341 (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
342 if (NULL == gsTxRxBuffer.cmdData.p_data) {
343 LOG(ERROR) << "transmit failed to allocate the Memory!!!";
344 /*Return empty hidl_vec*/
345 _hidl_cb(result);
346 return Void();
347 }
348 if (GET_CHIP_OS_VERSION() < OS_VERSION_8_9) {
349 OsuHalExtn::OsuApduMode mode = IS_OSU_MODE(
350 data, OsuHalExtn::getInstance().TRANSMIT, &gsTxRxBuffer.cmdData);
351 if (mode == OsuHalExtn::getInstance().OSU_BLOCKED_MODE) {
352 LOG(ERROR) << "Not allowed in dedicated mode!!!";
353 /*Return empty hidl_vec*/
354 _hidl_cb(result);
355 return Void();
356 } else if (mode == OsuHalExtn::getInstance().OSU_RST_MODE) {
357 uint8_t sw[2] = {0x90, 0x00};
358 result.resize(sizeof(sw));
359 memcpy(&result[0], sw, sizeof(sw));
360 _hidl_cb(result);
361 return Void();
362 }
363 } else {
364 memcpy(gsTxRxBuffer.cmdData.p_data, data.data(), gsTxRxBuffer.cmdData.len);
365 }
366 LOG(INFO) << "Acquired lock for SPI";
367 status = phNxpEse_SetEndPoint_Cntxt(0);
368 if (status != ESESTATUS_SUCCESS) {
369 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
370 }
371 status = phNxpEse_Transceive(&gsTxRxBuffer.cmdData, &gsTxRxBuffer.rspData);
372
373 if (status == ESESTATUS_SUCCESS) {
374 result.resize(gsTxRxBuffer.rspData.len);
375 memcpy(&result[0], gsTxRxBuffer.rspData.p_data, gsTxRxBuffer.rspData.len);
376 } else if (status == ESESTATUS_INVALID_RECEIVE_LENGTH) {
377 uint8_t respBuf[] = {INVALID_LEN_SW1, INVALID_LEN_SW2};
378 result.resize(sizeof(respBuf));
379 memcpy(&result[0], respBuf, sizeof(respBuf));
380 } else {
381 LOG(ERROR) << "transmit failed!!!";
382 }
383 status = phNxpEse_ResetEndPoint_Cntxt(0);
384 if (status != ESESTATUS_SUCCESS) {
385 LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
386 }
387
388 _hidl_cb(result);
389 if (NULL != gsTxRxBuffer.cmdData.p_data) {
390 phNxpEse_free(gsTxRxBuffer.cmdData.p_data);
391 gsTxRxBuffer.cmdData.p_data = NULL;
392 }
393 if (NULL != gsTxRxBuffer.rspData.p_data) {
394 phNxpEse_free(gsTxRxBuffer.rspData.p_data);
395 gsTxRxBuffer.rspData.p_data = NULL;
396 }
397
398 return Void();
399 }
400
openLogicalChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openLogicalChannel_cb _hidl_cb)401 Return<void> SecureElement::openLogicalChannel(const hidl_vec<uint8_t>& aid,
402 uint8_t p2,
403 openLogicalChannel_cb _hidl_cb) {
404 AutoMutex guard(seHalLock);
405 hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
406
407 LogicalChannelResponse resApduBuff;
408 resApduBuff.channelNumber = 0xff;
409 memset(&resApduBuff, 0x00, sizeof(resApduBuff));
410 if (aid.size() > MAX_AID_LENGTH) {
411 LOG(ERROR) << "%s: AID out of range!!!" << __func__;
412 _hidl_cb(resApduBuff, SecureElementStatus::FAILED);
413 return Void();
414 }
415
416 /*
417 * Basic channel & reserved channel if any is removed
418 * from count
419 */
420 uint8_t maxLogicalChannelSupported =
421 mMaxChannelCount - getReserveChannelCnt(aid) - 1;
422
423 uint8_t openedLogicalChannelCount = mOpenedchannelCount;
424 if (mOpenedChannels[0]) openedLogicalChannelCount--;
425
426 if (openedLogicalChannelCount >= maxLogicalChannelSupported) {
427 LOG(ERROR) << StringPrintf("%s: Reached Max supported(%d) Logical Channel",
428 __func__, openedLogicalChannelCount);
429 _hidl_cb(resApduBuff, SecureElementStatus::CHANNEL_NOT_AVAILABLE);
430 return Void();
431 }
432
433 LOG(INFO) << "Acquired the lock from SPI openLogicalChannel";
434
435 // In dedicated mode openLogical not allowed
436 if ((GET_CHIP_OS_VERSION() < OS_VERSION_6_2) &&
437 (IS_OSU_MODE(OsuHalExtn::getInstance().OPENLOGICAL))) {
438 LOG(ERROR) << "%s: Not allowed in dedicated mode!!!" << __func__;
439 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
440 return Void();
441 }
442 if (!mIsEseInitialized) {
443 ESESTATUS status = seHalInit();
444 if (status != ESESTATUS_SUCCESS) {
445 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
446 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
447 return Void();
448 }
449 }
450
451 if (mOpenedChannels.size() == 0x00) {
452 mMaxChannelCount = getMaxChannelCnt();
453 mOpenedChannels.resize(mMaxChannelCount, false);
454 }
455
456 SecureElementStatus sestatus = SecureElementStatus::IOERROR;
457 ESESTATUS status = ESESTATUS_FAILED;
458 phNxpEse_data cmdApdu;
459 phNxpEse_data rspApdu;
460
461 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
462
463 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
464
465 cmdApdu.len = (uint32_t)manageChannelCommand.size();
466 cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
467 sizeof(uint8_t));
468 memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
469
470 status = phNxpEse_SetEndPoint_Cntxt(0);
471 if (status != ESESTATUS_SUCCESS) {
472 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
473 }
474 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
475 if (status != ESESTATUS_SUCCESS) {
476 resApduBuff.channelNumber = 0xff;
477 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
478 rspApdu.p_data[rspApdu.len - 1] == 0x81) {
479 resApduBuff.channelNumber = 0xff;
480 sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
481 } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
482 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
483 resApduBuff.channelNumber = rspApdu.p_data[0];
484 mOpenedchannelCount++;
485 mOpenedChannels[resApduBuff.channelNumber] = true;
486 sestatus = SecureElementStatus::SUCCESS;
487 } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
488 (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
489 rspApdu.p_data[rspApdu.len - 1] == 0x00) {
490 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
491 }
492 /*Free the allocations*/
493 phNxpEse_free(cmdApdu.p_data);
494 phNxpEse_free(rspApdu.p_data);
495
496 if (sestatus != SecureElementStatus::SUCCESS) {
497 if (mOpenedchannelCount == 0) {
498 SecureElementStatus deInitStatus = seHalDeInit();
499 if (deInitStatus != SecureElementStatus::SUCCESS) {
500 LOG(INFO) << "seDeInit Failed";
501 }
502 }
503 /*If manageChanle is failed in any of above cases
504 send the callback and return*/
505 status = phNxpEse_ResetEndPoint_Cntxt(0);
506 if (status != ESESTATUS_SUCCESS) {
507 LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
508 }
509 _hidl_cb(resApduBuff, sestatus);
510 return Void();
511 }
512 LOG(INFO) << "openLogicalChannel Sending selectApdu";
513 sestatus = SecureElementStatus::IOERROR;
514 status = ESESTATUS_FAILED;
515
516 phNxpEse_7816_cpdu_t cpdu;
517 phNxpEse_7816_rpdu_t rpdu;
518 phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
519 phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
520
521 if ((resApduBuff.channelNumber > 0x03) &&
522 (resApduBuff.channelNumber < 0x14)) {
523 /* update CLA byte accoridng to GP spec Table 11-12*/
524 cpdu.cla =
525 0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
526 } else if ((resApduBuff.channelNumber > 0x00) &&
527 (resApduBuff.channelNumber < 0x04)) {
528 /* update CLA byte accoridng to GP spec Table 11-11*/
529 cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
530 } else {
531 LOG(ERROR) << StringPrintf("%s: Invalid Channel no: %02x", __func__,
532 resApduBuff.channelNumber);
533 resApduBuff.channelNumber = 0xff;
534 _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
535 return Void();
536 }
537 cpdu.ins = 0xA4; /* Instruction code */
538 cpdu.p1 = 0x04; /* Instruction parameter 1 */
539 cpdu.p2 = p2; /* Instruction parameter 2 */
540 cpdu.lc = (uint16_t)aid.size();
541 cpdu.le_type = 0x01;
542 cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
543 memcpy(cpdu.pdata, aid.data(), cpdu.lc);
544 cpdu.le = 256;
545
546 rpdu.len = 0x02;
547 rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
548
549 status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
550
551 if (status != ESESTATUS_SUCCESS) {
552 /*Transceive failed*/
553 if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
554 sestatus = SecureElementStatus::IOERROR;
555 } else {
556 sestatus = SecureElementStatus::FAILED;
557 }
558 } else {
559 /*Status word to be passed as part of response
560 So include additional length*/
561 uint16_t responseLen = rpdu.len + 2;
562 resApduBuff.selectResponse.resize(responseLen);
563 memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
564 resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
565 resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
566
567 if (rpdu.sw1 == SW1_BYTES_REMAINING) {
568 sestatus =
569 getResponseInternal(cpdu.cla, rpdu, resApduBuff.selectResponse);
570 if (sestatus != SecureElementStatus::SUCCESS) {
571 LOG(ERROR) << "%s: getResponseInternal Failed" << __func__;
572 }
573 }
574
575 /*Status is success*/
576 if ((rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) || (rpdu.sw1 == 0x62) ||
577 (rpdu.sw1 == 0x63)) {
578 sestatus = SecureElementStatus::SUCCESS;
579 }
580 /*AID provided doesn't match any applet on the secure element*/
581 else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
582 (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
583 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
584 }
585 /*Operation provided by the P2 parameter is not permitted by the applet.*/
586 else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
587 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
588 } else {
589 sestatus = SecureElementStatus::FAILED;
590 }
591 }
592 if (sestatus != SecureElementStatus::SUCCESS) {
593 SecureElementStatus closeChannelStatus =
594 internalCloseChannel(resApduBuff.channelNumber);
595 if (closeChannelStatus != SecureElementStatus::SUCCESS) {
596 LOG(ERROR) << "%s: closeChannel Failed" << __func__;
597 } else {
598 resApduBuff.channelNumber = 0xff;
599 }
600 }
601 status = phNxpEse_ResetEndPoint_Cntxt(0);
602 if (status != ESESTATUS_SUCCESS) {
603 LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
604 }
605 _hidl_cb(resApduBuff, sestatus);
606 phNxpEse_free(cpdu.pdata);
607 phNxpEse_free(rpdu.pdata);
608
609 return Void();
610 }
611
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)612 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
613 uint8_t p2,
614 openBasicChannel_cb _hidl_cb) {
615 hidl_vec<uint8_t> result;
616 if (aid.size() > MAX_AID_LENGTH) {
617 LOG(ERROR) << "%s: AID out of range!!!" << __func__;
618 _hidl_cb(result, SecureElementStatus::FAILED);
619 return Void();
620 }
621 AutoMutex guard(seHalLock);
622 ESESTATUS status = ESESTATUS_SUCCESS;
623 phNxpEse_7816_cpdu_t cpdu;
624 phNxpEse_7816_rpdu_t rpdu;
625 hidl_vec<uint8_t> ls_aid = {0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C,
626 0x41, 0x01, 0x43, 0x4F, 0x52, 0x01};
627
628 LOG(ERROR) << "Acquired the lock in SPI openBasicChannel";
629 if ((GET_CHIP_OS_VERSION() < OS_VERSION_8_9) &&
630 IS_OSU_MODE(aid, OsuHalExtn::getInstance().OPENBASIC) ==
631 OsuHalExtn::OSU_PROP_MODE) {
632 uint8_t sw[2] = {0x90, 0x00};
633 result.resize(sizeof(sw));
634 memcpy(&result[0], sw, 2);
635 if (mIsEseInitialized) {
636 /*Close existing sessions if any to start dedicated OSU Mode
637 * with OSU specific settings in TZ/TEE*/
638 if (seHalDeInit() != SecureElementStatus::SUCCESS) {
639 LOG(INFO) << "seDeInit Failed";
640 _hidl_cb(result, SecureElementStatus::IOERROR);
641 return Void();
642 }
643 }
644 phNxpEse_setWtxCountLimit(OsuHalExtn::getInstance().getOSUMaxWtxCount());
645 ESESTATUS status = ESESTATUS_FAILED;
646 uint8_t retry = 0;
647 do {
648 /*For Reset Recovery*/
649 status = seHalInit();
650 } while (status != ESESTATUS_SUCCESS && retry++ < 1);
651 if (status != ESESTATUS_SUCCESS) {
652 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
653 phNxpEse_setWtxCountLimit(RESET_APP_WTX_COUNT);
654 _hidl_cb(result, SecureElementStatus::IOERROR);
655 return Void();
656 }
657 if (phNxpEse_doResetProtection(true) != ESESTATUS_SUCCESS) {
658 LOG(ERROR) << "%s: Enable Reset Protection Failed!!!" << __func__;
659 _hidl_cb(result, SecureElementStatus::FAILED);
660 } else {
661 _hidl_cb(result, SecureElementStatus::SUCCESS);
662 }
663 return Void();
664 }
665
666 if (!mIsEseInitialized) {
667 ESESTATUS status = seHalInit();
668 if (status != ESESTATUS_SUCCESS) {
669 LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
670 _hidl_cb(result, SecureElementStatus::IOERROR);
671 return Void();
672 }
673 }
674
675 if (GET_CHIP_OS_VERSION() < OS_VERSION_8_9) {
676 phNxpEse_data atrData;
677 if (phNxpEse_getAtr(&atrData) != ESESTATUS_SUCCESS) {
678 LOG(ERROR) << "phNxpEse_getAtr failed";
679 }
680 if (atrData.p_data != NULL) {
681 phNxpEse_free(atrData.p_data);
682 }
683
684 if (phNxpEse_GetOsMode() == OSU_MODE) {
685 if (mOpenedchannelCount == 0) {
686 if (seHalDeInit() != SecureElementStatus::SUCCESS) {
687 LOG(INFO) << "seDeInit Failed";
688 }
689 }
690 _hidl_cb(result, SecureElementStatus::IOERROR);
691 return Void();
692 }
693 }
694
695 if (mOpenedChannels.size() == 0x00) {
696 mMaxChannelCount = getMaxChannelCnt();
697 mOpenedChannels.resize(mMaxChannelCount, false);
698 }
699 phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
700 phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
701
702 cpdu.cla = 0x00; /* Class of instruction */
703 cpdu.ins = 0xA4; /* Instruction code */
704 cpdu.p1 = 0x04; /* Instruction parameter 1 */
705 cpdu.p2 = p2; /* Instruction parameter 2 */
706 cpdu.lc = (uint16_t)aid.size();
707 cpdu.le_type = 0x01;
708 cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
709 memcpy(cpdu.pdata, aid.data(), cpdu.lc);
710 cpdu.le = 256;
711
712 rpdu.len = 0x02;
713 rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
714
715 status = phNxpEse_SetEndPoint_Cntxt(0);
716 if (status != ESESTATUS_SUCCESS) {
717 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
718 }
719 status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
720 SecureElementStatus sestatus;
721 memset(&sestatus, 0x00, sizeof(sestatus));
722
723 if (status != ESESTATUS_SUCCESS) {
724 /* Transceive failed */
725 if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
726 sestatus = SecureElementStatus::IOERROR;
727 } else {
728 sestatus = SecureElementStatus::FAILED;
729 }
730 } else {
731 /*Status word to be passed as part of response
732 So include additional length*/
733 uint16_t responseLen = rpdu.len + 2;
734 result.resize(responseLen);
735 memcpy(&result[0], rpdu.pdata, rpdu.len);
736 result[responseLen - 1] = rpdu.sw2;
737 result[responseLen - 2] = rpdu.sw1;
738 if (rpdu.sw1 == SW1_BYTES_REMAINING) {
739 sestatus = getResponseInternal(cpdu.cla, rpdu, result);
740 if (sestatus != SecureElementStatus::SUCCESS) {
741 LOG(ERROR) << "%s: getResponseInternal Failed " << __func__;
742 }
743 }
744
745 /*Status is success*/
746 if (((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) || (rpdu.sw1 == 0x62) ||
747 (rpdu.sw1 == 0x63)) {
748 /*Set basic channel reference if it is not set */
749 if (!mOpenedChannels[0]) {
750 mOpenedChannels[0] = true;
751 mOpenedchannelCount++;
752 }
753
754 sestatus = SecureElementStatus::SUCCESS;
755 }
756 /*AID provided doesn't match any applet on the secure element*/
757 else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
758 (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
759 sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
760 }
761 /*Operation provided by the P2 parameter is not permitted by the applet.*/
762 else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
763 sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
764 } else {
765 sestatus = SecureElementStatus::FAILED;
766 }
767 }
768 status = phNxpEse_ResetEndPoint_Cntxt(0);
769 if (status != ESESTATUS_SUCCESS) {
770 LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
771 }
772 if (sestatus != SecureElementStatus::SUCCESS) {
773 SecureElementStatus closeChannelStatus =
774 internalCloseChannel(DEFAULT_BASIC_CHANNEL);
775 if (closeChannelStatus != SecureElementStatus::SUCCESS) {
776 LOG(ERROR) << "%s: closeChannel Failed" << __func__;
777 }
778 }
779 _hidl_cb(result, sestatus);
780 phNxpEse_free(cpdu.pdata);
781 phNxpEse_free(rpdu.pdata);
782 return Void();
783 }
784
internalCloseChannel(uint8_t channelNumber)785 Return<SecureElementStatus> SecureElement::internalCloseChannel(
786 uint8_t channelNumber) {
787 ESESTATUS status = ESESTATUS_SUCCESS;
788 SecureElementStatus sestatus = SecureElementStatus::FAILED;
789 phNxpEse_7816_cpdu_t cpdu;
790 phNxpEse_7816_rpdu_t rpdu;
791
792 LOG(ERROR) << "Acquired the lock in SPI internalCloseChannel";
793 LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d",
794 mMaxChannelCount, channelNumber);
795 if (channelNumber >= mMaxChannelCount) {
796 LOG(ERROR) << StringPrintf("invalid channel!!! %d", channelNumber);
797 } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
798 phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
799 phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
800 cpdu.cla = channelNumber; /* Class of instruction */
801 // For Suplementary Channel update CLA byte according to GP
802 if ((channelNumber > 0x03) && (channelNumber < 0x14)) {
803 /* update CLA byte accoridng to GP spec Table 11-12*/
804 cpdu.cla = 0x40 + (channelNumber - 4); /* Class of instruction */
805 }
806 cpdu.ins = 0x70; /* Instruction code */
807 cpdu.p1 = 0x80; /* Instruction parameter 1 */
808 cpdu.p2 = channelNumber; /* Instruction parameter 2 */
809 cpdu.lc = 0x00;
810 cpdu.le = 0x9000;
811 status = phNxpEse_SetEndPoint_Cntxt(0);
812 if (status != ESESTATUS_SUCCESS) {
813 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
814 }
815 status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
816 if (status == ESESTATUS_SUCCESS) {
817 if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
818 sestatus = SecureElementStatus::SUCCESS;
819 }
820 }
821 status = phNxpEse_ResetEndPoint_Cntxt(0);
822 if (status != ESESTATUS_SUCCESS) {
823 LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
824 }
825 }
826 if (channelNumber < mMaxChannelCount) {
827 if (mOpenedChannels[channelNumber]) {
828 mOpenedChannels[channelNumber] = false;
829 mOpenedchannelCount--;
830 }
831 }
832 /*If there are no channels remaining close secureElement*/
833 if (mOpenedchannelCount == 0) {
834 sestatus = seHalDeInit();
835 } else {
836 sestatus = SecureElementStatus::SUCCESS;
837 }
838 return sestatus;
839 }
840
closeChannel(uint8_t channelNumber)841 Return<SecureElementStatus> SecureElement::closeChannel(uint8_t channelNumber) {
842 AutoMutex guard(seHalLock);
843 // Close internal allowed when not in dedicated Mode
844 if ((GET_CHIP_OS_VERSION() >= OS_VERSION_8_9) ||
845 (!IS_OSU_MODE(OsuHalExtn::getInstance().CLOSE, channelNumber))) {
846 return internalCloseChannel(channelNumber);
847 } else {
848 /*Decrement channel count opened to
849 * keep in sync with service */
850 if (channelNumber < mMaxChannelCount) {
851 if (mOpenedChannels[channelNumber]) {
852 mOpenedChannels[channelNumber] = false;
853 mOpenedchannelCount--;
854 }
855 }
856 return SecureElementStatus::SUCCESS;
857 }
858 }
859
serviceDied(uint64_t,const wp<IBase> & who)860 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& who) {
861 LOG(ERROR) << "Remote client Died!!!";
862 unregisterCallback(who.promote());
863 if (mCallbacks.empty()) {
864 LOG(ERROR) << "No alive registered client, resetting the state";
865 mIsEseInitialized = false;
866 if (seHalDeInit() != SecureElementStatus::SUCCESS) {
867 LOG(ERROR) << "SE Deinit not successful";
868 }
869 } else {
870 LOG(INFO) << "There are " << mCallbacks.size()
871 << " alive registered clients left";
872 }
873 }
seHalInit()874 ESESTATUS SecureElement::seHalInit() {
875 ESESTATUS status = ESESTATUS_SUCCESS;
876 phNxpEse_initParams initParams;
877 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
878 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
879 initParams.initMode = ESE_MODE_NORMAL;
880 initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
881 initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
882
883 status = phNxpEse_open(initParams);
884 if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
885 if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
886 ESESTATUS_SUCCESS == (status = phNxpEse_init(initParams))) {
887 if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
888 mIsEseInitialized = true;
889 LOG(INFO) << "ESE SPI init complete!!!";
890 return ESESTATUS_SUCCESS;
891 }
892 } else {
893 LOG(INFO) << "ESE SPI init NOT successful";
894 status = ESESTATUS_FAILED;
895 }
896 deInitStatus = phNxpEse_deInit();
897 if (phNxpEse_close(deInitStatus) != ESESTATUS_SUCCESS) {
898 LOG(INFO) << "ESE close not successful";
899 status = ESESTATUS_FAILED;
900 }
901 mIsEseInitialized = false;
902 }
903 return status;
904 }
905
seHalDeInit()906 Return<SecureElementStatus> SecureElement::seHalDeInit() {
907 ESESTATUS status = ESESTATUS_SUCCESS;
908 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
909 bool mIsDeInitDone = true;
910 SecureElementStatus sestatus = SecureElementStatus::FAILED;
911 status = phNxpEse_SetEndPoint_Cntxt(0);
912 if (status != ESESTATUS_SUCCESS) {
913 LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
914 mIsDeInitDone = false;
915 }
916 deInitStatus = phNxpEse_deInit();
917 if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
918 status = phNxpEse_ResetEndPoint_Cntxt(0);
919 if (status != ESESTATUS_SUCCESS) {
920 LOG(ERROR) << "phNxpEse_ResetEndPoint_Cntxt failed!!!";
921 mIsDeInitDone = false;
922 }
923 status = phNxpEse_close(deInitStatus);
924 if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
925 sestatus = SecureElementStatus::SUCCESS;
926 } else {
927 LOG(ERROR) << "seHalDeInit: Failed";
928 }
929 mIsEseInitialized = false;
930 for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
931 mOpenedChannels[xx] = false;
932 }
933 mOpenedchannelCount = 0;
934
935 return sestatus;
936 }
notifyClients(bool connected,std::string reason)937 void SecureElement::notifyClients(bool connected, std::string reason) {
938 LOG(INFO) << "Notifying current state to all " << mCallbacks.size()
939 << " clients";
940
941 for (auto it = mCallbacks.begin(); it != mCallbacks.end();) {
942 auto ret = (*it)->onStateChange_1_1(connected, reason);
943 if (!ret.isOk() && ret.isDeadObject()) {
944 LOG(WARNING) << "client is dead";
945 it = mCallbacks.erase(it);
946 } else {
947 ++it;
948 }
949 }
950 }
951 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
reset()952 SecureElement::reset() {
953 ESESTATUS status = ESESTATUS_SUCCESS;
954 SecureElementStatus sestatus = SecureElementStatus::FAILED;
955 LOG(INFO) << __func__ << " Enter";
956 if (!mIsEseInitialized) {
957 ESESTATUS status = seHalInit();
958 if (status != ESESTATUS_SUCCESS) {
959 LOG(ERROR) << __func__ << " seHalInit Failed!!!";
960 }
961 }
962 if (status == ESESTATUS_SUCCESS) {
963 notifyClients(false, "reset the SE");
964 status = phNxpEse_reset();
965 if (status != ESESTATUS_SUCCESS) {
966 LOG(ERROR) << __func__ << " SecureElement reset failed!!";
967 } else {
968 sestatus = SecureElementStatus::SUCCESS;
969 if (mOpenedChannels.size() == 0x00) {
970 mMaxChannelCount = getMaxChannelCnt();
971 mOpenedChannels.resize(mMaxChannelCount, false);
972 }
973 for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
974 mOpenedChannels[xx] = false;
975 }
976 mOpenedchannelCount = 0;
977 notifyClients(true, "SE initialized");
978 }
979 }
980 LOG(ERROR) << __func__ << ": Exit";
981 return sestatus;
982 }
983
984 static Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
getResponseInternal(uint8_t cla,phNxpEse_7816_rpdu_t & rpdu,hidl_vec<uint8_t> & result)985 getResponseInternal(uint8_t cla, phNxpEse_7816_rpdu_t& rpdu,
986 hidl_vec<uint8_t>& result) {
987 SecureElementStatus sestatus = SecureElementStatus::SUCCESS;
988 ESESTATUS status = ESESTATUS_SUCCESS;
989 phNxpEse_data cmdApdu;
990 phNxpEse_data rspApdu;
991 uint16_t responseLen = rpdu.len; // Response already copied
992 uint8_t getRespLe = rpdu.sw2; // Response pending to receive
993 uint8_t getResponse[5] = {0x00, 0xC0, 0x00, 0x00, 0x00};
994
995 getResponse[0] = cla;
996
997 phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
998
999 cmdApdu.len = (uint32_t)sizeof(getResponse);
1000 cmdApdu.p_data = getResponse;
1001
1002 do {
1003 // update GET response 61 xx(Le)
1004 getResponse[4] = getRespLe;
1005
1006 phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
1007
1008 status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
1009 if (status != ESESTATUS_SUCCESS) {
1010 /*Transceive failed*/
1011 if (rspApdu.len > 0 && (rspApdu.p_data[rspApdu.len - 2] == 0x64 &&
1012 rspApdu.p_data[rspApdu.len - 1] == 0xFF)) {
1013 sestatus = SecureElementStatus::IOERROR;
1014 } else {
1015 sestatus = SecureElementStatus::FAILED;
1016 }
1017 break;
1018 } else {
1019 uint32_t respLen = rspApdu.len;
1020
1021 // skip 2 bytes in case of 61xx SW again
1022 if (rspApdu.p_data[respLen - 2] == SW1_BYTES_REMAINING) {
1023 respLen -= 2;
1024 getRespLe = rspApdu.p_data[respLen - 1];
1025 }
1026 // copy response chunk received
1027 result.resize(responseLen + respLen);
1028 memcpy(&result[responseLen], rspApdu.p_data, respLen);
1029 responseLen += respLen;
1030 }
1031 } while (rspApdu.p_data[rspApdu.len - 2] == SW1_BYTES_REMAINING);
1032
1033 // Propagate SW as it is received from card
1034 if (sestatus == SecureElementStatus::SUCCESS) {
1035 rpdu.sw1 = rspApdu.p_data[rspApdu.len - 2];
1036 rpdu.sw2 = rspApdu.p_data[rspApdu.len - 1];
1037 } else { // Other Failure cases update failure SW:64FF
1038 rpdu.sw1 = INVALID_LEN_SW1;
1039 rpdu.sw2 = INVALID_LEN_SW2;
1040 }
1041
1042 return sestatus;
1043 }
1044
getReserveChannelCnt(const hidl_vec<uint8_t> & aid)1045 uint8_t SecureElement::getReserveChannelCnt(const hidl_vec<uint8_t>& aid) {
1046 const hidl_vec<uint8_t> weaverAid = {0xA0, 0x00, 0x00, 0x03,
1047 0x96, 0x10, 0x10};
1048 const hidl_vec<uint8_t> araAid = {0xA0, 0x00, 0x00, 0x01, 0x51,
1049 0x41, 0x43, 0x4C, 0x00};
1050 uint8_t reserveChannel = 0;
1051 // Check priority access enabled then only reserve channel
1052 if (mHasPriorityAccess && aid != weaverAid && aid != araAid) {
1053 // Exclude basic channel
1054 reserveChannel = 1;
1055 }
1056 return reserveChannel;
1057 }
1058
getMaxChannelCnt()1059 uint8_t SecureElement::getMaxChannelCnt() {
1060 /*
1061 * 1) SN1xx max channel supported 4.
1062 * 2) SN220 up to v2 max channel supported 5 (If priority access)
1063 * otherwise 4 channel.
1064 * 3) SN220 v3 and higher shall be updated accordingly.
1065 */
1066 uint8_t cnt = 0;
1067 if (GET_CHIP_OS_VERSION() < OS_VERSION_6_2)
1068 cnt = NUM_OF_CH4;
1069 else if (GET_CHIP_OS_VERSION() == OS_VERSION_6_2)
1070 cnt = (mHasPriorityAccess ? NUM_OF_CH5 : NUM_OF_CH4);
1071 else
1072 cnt = NUM_OF_CH5;
1073
1074 return cnt;
1075 }
1076
debug(const hidl_handle &,const hidl_vec<hidl_string> &)1077 Return<void> SecureElement::debug(const hidl_handle& /* fd */,
1078 const hidl_vec<hidl_string>& /* options */) {
1079 LOG(INFO) << "\n SecureElement-SecureElement HAL MemoryLeak Info = \n"
1080 << ::android::GetUnreachableMemoryString(true, 10000).c_str();
1081 return Void();
1082 }
1083
1084 } // namespace implementation
1085 } // namespace V1_2
1086 } // namespace secure_element
1087 } // namespace hardware
1088 } // namespace android
1089