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