1 /******************************************************************************
2  *
3  *  Copyright (C) 2018 ST Microelectronics S.A.
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  ******************************************************************************/
19 #define LOG_TAG "StEse-SecureElement"
20 #include "SecureElement.h"
21 #include <android_logmsg.h>
22 #include <dlfcn.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 typedef int (*STAram_init)(void);
28 typedef int (*StAram_Transceive)(StEse_data*, StEse_data*);
29 static StAram_Transceive Aram_transceive = nullptr;
30 static int aram_channel = 0;
31 
32 extern bool ese_debug_enabled;
33 static bool OpenLogicalChannelProcessing = false;
34 static bool OpenBasicChannelProcessing = false;
35 
36 namespace android {
37 namespace hardware {
38 namespace secure_element {
39 namespace V1_0 {
40 namespace implementation {
41 
42 sp<V1_0::ISecureElementHalCallback> SecureElement::mCallbackV1_0 = nullptr;
43 
SecureElement()44 SecureElement::SecureElement()
45     : mOpenedchannelCount(0), mOpenedChannels{false, false, false, false} {}
46 
init(const sp<::android::hardware::secure_element::V1_0::ISecureElementHalCallback> & clientCallback)47 Return<void> SecureElement::init(
48     const sp<
49         ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
50         clientCallback) {
51   ESESTATUS status = ESESTATUS_SUCCESS;
52   aram_channel = 0;
53   STLOG_HAL_D("%s: Enter", __func__);
54   if (clientCallback == nullptr) {
55     return Void();
56   } else {
57     mCallbackV1_0 = clientCallback;
58     if (!mCallbackV1_0->linkToDeath(this, 0 /*cookie*/)) {
59       STLOG_HAL_E("%s: Failed to register death notification", __func__);
60     }
61   }
62 
63   if (isSeInitialized()) {
64     clientCallback->onStateChange(true);
65     return Void();
66   }
67 
68   // Ignore this dlopen if you don't have libstpreprocess.so
69 #if defined(ST_LIB_32)
70   void* stdll = dlopen("/vendor/lib/libstpreprocess.so", RTLD_NOW);
71 #else
72   void* stdll = dlopen("/vendor/lib64/libstpreprocess.so", RTLD_NOW);
73 #endif
74   if (stdll) {
75     STAram_init fn_init = (STAram_init)dlsym(stdll, "STAram_init");
76     if (fn_init) {
77       if (ESESTATUS_SUCCESS == fn_init()) {
78         STLOG_HAL_D("%s: Enter", __func__);
79         Aram_transceive = (StAram_Transceive)dlsym(stdll, "StAram_Transceive");
80       } else {
81         Aram_transceive = nullptr;
82         STLOG_HAL_E("%s: Error in loading StAram_Transceive", __func__);
83       }
84     }
85   }
86 
87   status = seHalInit();
88   if (status != ESESTATUS_SUCCESS) {
89     clientCallback->onStateChange(false);
90     return Void();
91   } else {
92     clientCallback->onStateChange(true);
93     return Void();
94   }
95 }
96 
getAtr(getAtr_cb _hidl_cb)97 Return<void> SecureElement::getAtr(getAtr_cb _hidl_cb) {
98   STLOG_HAL_D("%s: Enter", __func__);
99   hidl_vec<uint8_t> response;
100   uint8_t* ATR;
101   ATR = StEse_getAtr();
102   if (ATR != nullptr) {
103     uint8_t len = *ATR;
104     if (len) {
105       response.resize(len);
106       memcpy(&response[0], ATR, len);
107     }
108   }
109   _hidl_cb(response);
110   return Void();
111 }
112 
isCardPresent()113 Return<bool> SecureElement::isCardPresent() { return true; }
114 
transmit(const hidl_vec<uint8_t> & data,transmit_cb _hidl_cb)115 Return<void> SecureElement::transmit(const hidl_vec<uint8_t>& data,
116                                      transmit_cb _hidl_cb) {
117   ESESTATUS status = ESESTATUS_FAILED;
118   StEse_data cmdApdu;
119   StEse_data rspApdu;
120   memset(&cmdApdu, 0x00, sizeof(StEse_data));
121   memset(&rspApdu, 0x00, sizeof(StEse_data));
122 
123   STLOG_HAL_D("%s: Enter", __func__);
124   cmdApdu.len = data.size();
125   if (cmdApdu.len >= MIN_APDU_LENGTH) {
126     cmdApdu.p_data = (uint8_t*)malloc(data.size() * sizeof(uint8_t));
127     memcpy(cmdApdu.p_data, data.data(), cmdApdu.len);
128     /* Check aram_channel number after open logic channel */
129     if (aram_channel && (0x03 & cmdApdu.p_data[0]) == aram_channel &&
130         Aram_transceive) {
131       /* Replace responses for ARAM operations*/
132       status = (ESESTATUS)Aram_transceive(&cmdApdu, &rspApdu);
133     } else {
134       status = StEse_Transceive(&cmdApdu, &rspApdu);
135     }
136   }
137 
138   hidl_vec<uint8_t> result;
139   if (status != ESESTATUS_SUCCESS) {
140     STLOG_HAL_E("%s: transmit failed!!!", __func__);
141     seHalResetSe();
142   } else {
143     result.resize(rspApdu.len);
144     memcpy(&result[0], rspApdu.p_data, rspApdu.len);
145   }
146   _hidl_cb(result);
147   free(cmdApdu.p_data);
148   free(rspApdu.p_data);
149   return Void();
150 }
151 
openLogicalChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openLogicalChannel_cb _hidl_cb)152 Return<void> SecureElement::openLogicalChannel(const hidl_vec<uint8_t>& aid,
153                                                uint8_t p2,
154                                                openLogicalChannel_cb _hidl_cb) {
155   hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
156   hidl_vec<uint8_t> ARA_M_AID = {0xA0, 0x00, 0x00, 0x01, 0x51,
157                                  0x41, 0x43, 0x4C, 0x00};
158   OpenLogicalChannelProcessing = true;
159   LogicalChannelResponse resApduBuff;
160   resApduBuff.channelNumber = 0xff;
161   memset(&resApduBuff, 0x00, sizeof(resApduBuff));
162   STLOG_HAL_D("%s: Enter", __func__);
163 
164   if (aid.size() > 16) {
165     STLOG_HAL_E("%s: Invalid AID size: %u", __func__, (unsigned)aid.size());
166     _hidl_cb(resApduBuff, SecureElementStatus::FAILED);
167     OpenLogicalChannelProcessing = false;
168     return Void();
169   }
170 
171   if (!isSeInitialized()) {
172     STLOG_HAL_D("%s: Enter SeInitialized", __func__);
173     ESESTATUS status = seHalInit();
174     if (status != ESESTATUS_SUCCESS) {
175       STLOG_HAL_E("%s: seHalInit Failed!!!", __func__);
176       _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
177       OpenLogicalChannelProcessing = false;
178       return Void();
179     }
180   }
181 
182   SecureElementStatus sestatus = SecureElementStatus::FAILED;
183   ESESTATUS status = ESESTATUS_FAILED;
184   StEse_data cmdApdu;
185   StEse_data rspApdu;
186 
187   memset(&cmdApdu, 0x00, sizeof(StEse_data));
188   memset(&rspApdu, 0x00, sizeof(StEse_data));
189 
190   cmdApdu.len = manageChannelCommand.size();
191   cmdApdu.p_data =
192       (uint8_t*)malloc(manageChannelCommand.size() * sizeof(uint8_t));
193   if (cmdApdu.p_data != NULL) {
194     memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
195     status = StEse_Transceive(&cmdApdu, &rspApdu);
196   }
197   if (status != ESESTATUS_SUCCESS) {
198     /*Transceive failed*/
199     sestatus = SecureElementStatus::IOERROR;
200   } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
201              rspApdu.p_data[rspApdu.len - 1] == 0x00) {
202     /*ManageChannel successful*/
203     resApduBuff.channelNumber = rspApdu.p_data[0];
204     mOpenedchannelCount++;
205     mOpenedChannels[resApduBuff.channelNumber] = true;
206     sestatus = SecureElementStatus::SUCCESS;
207     if (ARA_M_AID == aid) {
208       STLOG_HAL_D("%s: ARAM AID match", __func__);
209       aram_channel = resApduBuff.channelNumber;
210     } else {
211       /* Clear aram_channel number */
212       if (aram_channel == resApduBuff.channelNumber) aram_channel = 0;
213     }
214   } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
215              rspApdu.p_data[rspApdu.len - 1] == 0x81) {
216     sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
217   } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
218               (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
219              rspApdu.p_data[rspApdu.len - 1] == 0x00) {
220     sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
221   }
222   /*Free the allocations*/
223   free(cmdApdu.p_data);
224   cmdApdu.p_data = NULL;
225   free(rspApdu.p_data);
226   rspApdu.p_data = NULL;
227   if (sestatus != SecureElementStatus::SUCCESS) {
228     /* if the SE is unresponsive, reset it */
229     if (sestatus == SecureElementStatus::IOERROR) {
230       seHalResetSe();
231     }
232 
233     /*If manageChannel is failed in any of above cases
234     send the callback and return*/
235     _hidl_cb(resApduBuff, sestatus);
236     STLOG_HAL_E("%s: Exit - manage channel failed!!", __func__);
237     OpenLogicalChannelProcessing = false;
238     return Void();
239   }
240 
241   STLOG_HAL_D("%s: Sending selectApdu", __func__);
242   /*Reset variables if manageChannel is success*/
243   sestatus = SecureElementStatus::FAILED;
244   status = ESESTATUS_FAILED;
245 
246   memset(&cmdApdu, 0x00, sizeof(StEse_data));
247   memset(&rspApdu, 0x00, sizeof(StEse_data));
248 
249   cmdApdu.len = (int32_t)(6 + aid.size());
250   cmdApdu.p_data = (uint8_t*)malloc(cmdApdu.len * sizeof(uint8_t));
251   if (cmdApdu.p_data != NULL) {
252     uint8_t xx = 0;
253     cmdApdu.p_data[xx++] = resApduBuff.channelNumber;
254     cmdApdu.p_data[xx++] = 0xA4;        // INS
255     cmdApdu.p_data[xx++] = 0x04;        // P1
256     cmdApdu.p_data[xx++] = p2;          // P2
257     cmdApdu.p_data[xx++] = aid.size();  // Lc
258     memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
259     cmdApdu.p_data[xx + aid.size()] = 0x00;  // Le
260 
261     if (Aram_transceive && (aram_channel == resApduBuff.channelNumber)) {
262       status = (ESESTATUS)Aram_transceive(&cmdApdu, &rspApdu);
263     } else {
264       status = StEse_Transceive(&cmdApdu, &rspApdu);
265     }
266   }
267 
268   if (status != ESESTATUS_SUCCESS) {
269     /*Transceive failed*/
270     sestatus = SecureElementStatus::IOERROR;
271   } else {
272     uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
273     uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
274     /*Return response on success, empty vector on failure*/
275     /*Status is success*/
276     if (sw1 == 0x90 && sw2 == 0x00) {
277       /*Copy the response including status word*/
278       resApduBuff.selectResponse.resize(rspApdu.len);
279       memcpy(&resApduBuff.selectResponse[0], rspApdu.p_data, rspApdu.len);
280       sestatus = SecureElementStatus::SUCCESS;
281     }
282     /*AID provided doesn't match any applet on the secure element*/
283     else if (sw1 == 0x6A && sw2 == 0x82) {
284       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
285     }
286     /*Operation provided by the P2 parameter is not permitted by the applet.*/
287     else if (sw1 == 0x6A && sw2 == 0x86) {
288       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
289     }
290   }
291 
292   if (sestatus != SecureElementStatus::SUCCESS) {
293     /* if the SE is unresponsive, reset it */
294     if (sestatus == SecureElementStatus::IOERROR) {
295       seHalResetSe();
296     } else {
297       STLOG_HAL_E("%s: Select APDU failed! Close channel..", __func__);
298       SecureElementStatus closeChannelStatus =
299           closeChannel(resApduBuff.channelNumber);
300       if (closeChannelStatus != SecureElementStatus::SUCCESS) {
301         STLOG_HAL_E("%s: closeChannel Failed", __func__);
302       } else {
303         resApduBuff.channelNumber = 0xff;
304       }
305     }
306   }
307   _hidl_cb(resApduBuff, sestatus);
308   free(cmdApdu.p_data);
309   free(rspApdu.p_data);
310   STLOG_HAL_V("%s: Exit", __func__);
311   OpenLogicalChannelProcessing = false;
312   return Void();
313 }
314 
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)315 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
316                                              uint8_t p2,
317                                              openBasicChannel_cb _hidl_cb) {
318   hidl_vec<uint8_t> result;
319   OpenBasicChannelProcessing = true;
320   STLOG_HAL_D("%s: Enter", __func__);
321 
322   if (aid.size() > 16) {
323     STLOG_HAL_E("%s: Invalid AID size: %u", __func__, (unsigned)aid.size());
324     _hidl_cb(result, SecureElementStatus::FAILED);
325     OpenBasicChannelProcessing = false;
326     return Void();
327   }
328 
329   if (!isSeInitialized()) {
330     ESESTATUS status = seHalInit();
331     if (status != ESESTATUS_SUCCESS) {
332       STLOG_HAL_E("%s: seHalInit Failed!!!", __func__);
333       _hidl_cb(result, SecureElementStatus::IOERROR);
334       OpenBasicChannelProcessing = false;
335       return Void();
336     }
337   }
338 
339   SecureElementStatus sestatus = SecureElementStatus::FAILED;
340   ESESTATUS status = ESESTATUS_FAILED;
341   StEse_data cmdApdu;
342   StEse_data rspApdu;
343 
344   memset(&cmdApdu, 0x00, sizeof(StEse_data));
345   memset(&rspApdu, 0x00, sizeof(StEse_data));
346 
347   cmdApdu.len = (int32_t)(6 + aid.size());
348   cmdApdu.p_data = (uint8_t*)malloc(cmdApdu.len * sizeof(uint8_t));
349   if (cmdApdu.p_data != NULL) {
350     uint8_t xx = 0;
351     cmdApdu.p_data[xx++] = 0x00;        // basic channel
352     cmdApdu.p_data[xx++] = 0xA4;        // INS
353     cmdApdu.p_data[xx++] = 0x04;        // P1
354     cmdApdu.p_data[xx++] = p2;          // P2
355     cmdApdu.p_data[xx++] = aid.size();  // Lc
356     memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
357     cmdApdu.p_data[xx + aid.size()] = 0x00;  // Le
358 
359     status = StEse_Transceive(&cmdApdu, &rspApdu);
360   }
361 
362   if (status != ESESTATUS_SUCCESS) {
363     /* Transceive failed */
364     sestatus = SecureElementStatus::IOERROR;
365   } else {
366     uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
367     uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
368     /*Return response on success, empty vector on failure*/
369     /*Status is success*/
370     if ((sw1 == 0x90) && (sw2 == 0x00)) {
371       /*Copy the response including status word*/
372       result.resize(rspApdu.len);
373       memcpy(&result[0], rspApdu.p_data, rspApdu.len);
374       /*Set basic channel reference if it is not set */
375       if (!mOpenedChannels[0]) {
376         mOpenedChannels[0] = true;
377         mOpenedchannelCount++;
378       }
379       sestatus = SecureElementStatus::SUCCESS;
380     }
381     /*AID provided doesn't match any applet on the secure element*/
382     else if (sw1 == 0x6A && sw2 == 0x82) {
383       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
384     }
385     /*Operation provided by the P2 parameter is not permitted by the applet.*/
386     else if (sw1 == 0x6A && sw2 == 0x86) {
387       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
388     }
389   }
390 
391   /* if the SE is unresponsive, reset it */
392   if (sestatus == SecureElementStatus::IOERROR) {
393     seHalResetSe();
394   }
395 
396   if ((sestatus != SecureElementStatus::SUCCESS) && mOpenedChannels[0]) {
397     SecureElementStatus closeChannelStatus =
398         closeChannel(DEFAULT_BASIC_CHANNEL);
399     if (closeChannelStatus != SecureElementStatus::SUCCESS) {
400       STLOG_HAL_E("%s: closeChannel Failed", __func__);
401     }
402   }
403   _hidl_cb(result, sestatus);
404   free(cmdApdu.p_data);
405   free(rspApdu.p_data);
406   STLOG_HAL_V("%s: Exit", __func__);
407   OpenBasicChannelProcessing = false;
408   return Void();
409 }
410 
411 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
closeChannel(uint8_t channelNumber)412 SecureElement::closeChannel(uint8_t channelNumber) {
413   ESESTATUS status = ESESTATUS_FAILED;
414   SecureElementStatus sestatus = SecureElementStatus::FAILED;
415 
416   StEse_data cmdApdu;
417   StEse_data rspApdu;
418 
419   STLOG_HAL_D("%s: Enter : %d", __func__, channelNumber);
420 
421   if ((channelNumber < DEFAULT_BASIC_CHANNEL) ||
422       (channelNumber >= MAX_LOGICAL_CHANNELS) ||
423       (mOpenedChannels[channelNumber] == false)) {
424     STLOG_HAL_E("%s: invalid channel!!!", __func__);
425     sestatus = SecureElementStatus::FAILED;
426   } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
427     /* Reset aram_channel to 0 */
428     if (channelNumber == aram_channel) aram_channel = 0;
429 
430     memset(&cmdApdu, 0x00, sizeof(StEse_data));
431     memset(&rspApdu, 0x00, sizeof(StEse_data));
432     cmdApdu.p_data = (uint8_t*)malloc(5 * sizeof(uint8_t));
433     if (cmdApdu.p_data != NULL) {
434       uint8_t xx = 0;
435 
436       cmdApdu.p_data[xx++] = channelNumber;
437       cmdApdu.p_data[xx++] = 0x70;           // INS
438       cmdApdu.p_data[xx++] = 0x80;           // P1
439       cmdApdu.p_data[xx++] = channelNumber;  // P2
440       cmdApdu.p_data[xx++] = 0x00;           // Lc
441       cmdApdu.len = xx;
442 
443       status = StEse_Transceive(&cmdApdu, &rspApdu);
444     }
445     if (status != ESESTATUS_SUCCESS) {
446       sestatus = SecureElementStatus::FAILED;
447     } else if ((rspApdu.p_data[rspApdu.len - 2] == 0x90) &&
448                (rspApdu.p_data[rspApdu.len - 1] == 0x00)) {
449       sestatus = SecureElementStatus::SUCCESS;
450     } else {
451       sestatus = SecureElementStatus::FAILED;
452     }
453     free(cmdApdu.p_data);
454     free(rspApdu.p_data);
455   }
456 
457   if ((channelNumber == DEFAULT_BASIC_CHANNEL) ||
458       (sestatus == SecureElementStatus::SUCCESS)) {
459     mOpenedChannels[channelNumber] = false;
460     mOpenedchannelCount--;
461     /*If there are no channels remaining close secureElement*/
462     if ((mOpenedchannelCount == 0) && !OpenLogicalChannelProcessing &&
463         !OpenBasicChannelProcessing) {
464       sestatus = seHalDeInit();
465     } else {
466       sestatus = SecureElementStatus::SUCCESS;
467     }
468   }
469 
470   STLOG_HAL_V("%s: Exit", __func__);
471   return sestatus;
472 }
473 
serviceDied(uint64_t,const wp<IBase> &)474 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
475   STLOG_HAL_E("%s: SecureElement serviceDied!!!", __func__);
476   /* Reset aram_channel to 0 */
477   aram_channel = 0;
478   SecureElementStatus sestatus = seHalDeInit();
479   if (sestatus != SecureElementStatus::SUCCESS) {
480     STLOG_HAL_E("%s: seHalDeInit Faliled!!!", __func__);
481   }
482   if (mCallbackV1_0 != nullptr) {
483     mCallbackV1_0->unlinkToDeath(this);
484   }
485 }
486 
isSeInitialized()487 bool SecureElement::isSeInitialized() { return StEseApi_isOpen(); }
488 
seHalInit()489 ESESTATUS SecureElement::seHalInit() {
490   ESESTATUS status = ESESTATUS_SUCCESS;
491 
492   STLOG_HAL_D("%s: Enter", __func__);
493   aram_channel = 0;
494   status = StEse_init();
495   if (status != ESESTATUS_SUCCESS) {
496     STLOG_HAL_E("%s: SecureElement open failed!!!", __func__);
497   }
498   STLOG_HAL_V("%s: Exit", __func__);
499   return status;
500 }
501 
seHalResetSe()502 void SecureElement::seHalResetSe() {
503   ESESTATUS status = ESESTATUS_SUCCESS;
504 
505   STLOG_HAL_D("%s: Enter", __func__);
506   if (!isSeInitialized()) {
507     ESESTATUS status = seHalInit();
508     if (status != ESESTATUS_SUCCESS) {
509       STLOG_HAL_E("%s: seHalInit Failed!!!", __func__);
510     }
511   }
512 
513   if (status == ESESTATUS_SUCCESS) {
514     mCallbackV1_0->onStateChange(false);
515 
516     status = StEse_Reset();
517     if (status != ESESTATUS_SUCCESS) {
518       STLOG_HAL_E("%s: SecureElement reset failed!!", __func__);
519     } else {
520       for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
521         mOpenedChannels[xx] = false;
522       }
523       mOpenedchannelCount = 0;
524       mCallbackV1_0->onStateChange(true);
525     }
526   }
527   STLOG_HAL_V("%s: Exit", __func__);
528 }
529 
530 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
seHalDeInit()531 SecureElement::seHalDeInit() {
532   STLOG_HAL_D("%s: Enter", __func__);
533   ESESTATUS status = ESESTATUS_SUCCESS;
534   SecureElementStatus sestatus = SecureElementStatus::FAILED;
535   status = StEse_close();
536   if (status != ESESTATUS_SUCCESS) {
537     sestatus = SecureElementStatus::FAILED;
538   } else {
539     sestatus = SecureElementStatus::SUCCESS;
540 
541     for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
542       mOpenedChannels[xx] = false;
543     }
544     mOpenedchannelCount = 0;
545   }
546   STLOG_HAL_V("%s: Exit", __func__);
547   return sestatus;
548 }
549 
550 }  // namespace implementation
551 }  // namespace V1_0
552 }  // namespace secure_element
553 }  // namespace hardware
554 }  // namespace android
555