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