• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 (aid.size() > 16) {
167     STLOG_HAL_E("%s: Invalid AID size: %u", __func__, (unsigned)aid.size());
168     _hidl_cb(resApduBuff, SecureElementStatus::FAILED);
169     OpenLogicalChannelProcessing = false;
170     return Void();
171   }
172 
173   if (!isSeInitialized()) {
174     STLOG_HAL_D("%s: Enter SeInitialized", __func__);
175     ESESTATUS status = seHalInit();
176     if (status != ESESTATUS_SUCCESS) {
177       STLOG_HAL_E("%s: seHalInit Failed!!!", __func__);
178       _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
179       OpenLogicalChannelProcessing = false;
180       return Void();
181     }
182   }
183 
184   SecureElementStatus sestatus = SecureElementStatus::IOERROR;
185   ESESTATUS status = ESESTATUS_FAILED;
186   StEse_data cmdApdu;
187   StEse_data rspApdu;
188 
189   memset(&cmdApdu, 0x00, sizeof(StEse_data));
190   memset(&rspApdu, 0x00, sizeof(StEse_data));
191 
192   cmdApdu.len = manageChannelCommand.size();
193   cmdApdu.p_data =
194       (uint8_t*)malloc(manageChannelCommand.size() * sizeof(uint8_t));
195   if (cmdApdu.p_data != NULL) {
196     memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
197     status = StEse_Transceive(&cmdApdu, &rspApdu);
198   }
199   if (status != ESESTATUS_SUCCESS) {
200     /*Transceive failed*/
201     sestatus = SecureElementStatus::IOERROR;
202   } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
203              rspApdu.p_data[rspApdu.len - 1] == 0x00) {
204     /*ManageChannel successful*/
205     resApduBuff.channelNumber = rspApdu.p_data[0];
206     mOpenedchannelCount++;
207     mOpenedChannels[resApduBuff.channelNumber] = true;
208     sestatus = SecureElementStatus::SUCCESS;
209   } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
210              rspApdu.p_data[rspApdu.len - 1] == 0x81) {
211     sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
212   } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
213               (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
214              rspApdu.p_data[rspApdu.len - 1] == 0x00) {
215     sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
216   }
217   /*Free the allocations*/
218   free(cmdApdu.p_data);
219   cmdApdu.p_data = NULL;
220   free(rspApdu.p_data);
221   rspApdu.p_data = NULL;
222   if (sestatus != SecureElementStatus::SUCCESS) {
223     /* if the SE is unresponsive, reset it */
224     if (sestatus == SecureElementStatus::IOERROR) {
225       seHalResetSe();
226     }
227 
228     /*If manageChannel is failed in any of above cases
229     send the callback and return*/
230     _hidl_cb(resApduBuff, sestatus);
231     STLOG_HAL_E("%s: Exit - manage channel failed!!", __func__);
232     OpenLogicalChannelProcessing = false;
233     return Void();
234   }
235 
236   STLOG_HAL_D("%s: Sending selectApdu", __func__);
237   /*Reset variables if manageChannel is success*/
238   sestatus = SecureElementStatus::IOERROR;
239   status = ESESTATUS_FAILED;
240 
241   memset(&cmdApdu, 0x00, sizeof(StEse_data));
242   memset(&rspApdu, 0x00, sizeof(StEse_data));
243 
244   cmdApdu.len = (int32_t)(6 + aid.size());
245   cmdApdu.p_data = (uint8_t*)malloc(cmdApdu.len * sizeof(uint8_t));
246   if (cmdApdu.p_data != NULL) {
247     uint8_t xx = 0;
248     cmdApdu.p_data[xx++] = resApduBuff.channelNumber;
249     cmdApdu.p_data[xx++] = 0xA4;        // INS
250     cmdApdu.p_data[xx++] = 0x04;        // P1
251     cmdApdu.p_data[xx++] = p2;          // P2
252     cmdApdu.p_data[xx++] = aid.size();  // Lc
253     memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
254     cmdApdu.p_data[xx + aid.size()] = 0x00;  // Le
255     status = StEse_Transceive(&cmdApdu, &rspApdu);
256   }
257 
258   if (status != ESESTATUS_SUCCESS) {
259     /*Transceive failed*/
260     sestatus = SecureElementStatus::IOERROR;
261   } else {
262     uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
263     uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
264     /*Return response on success, empty vector on failure*/
265     /*Status is success*/
266     if (sw1 == 0x90 && sw2 == 0x00) {
267       /*Copy the response including status word*/
268       resApduBuff.selectResponse.resize(rspApdu.len);
269       memcpy(&resApduBuff.selectResponse[0], rspApdu.p_data, rspApdu.len);
270       sestatus = SecureElementStatus::SUCCESS;
271     }
272     /*AID provided doesn't match any applet on the secure element*/
273     else if (sw1 == 0x6A && sw2 == 0x82) {
274       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
275     }
276     /*Operation provided by the P2 parameter is not permitted by the applet.*/
277     else if (sw1 == 0x6A && sw2 == 0x86) {
278       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
279     }
280   }
281 
282   if (sestatus != SecureElementStatus::SUCCESS) {
283     /* if the SE is unresponsive, reset it */
284     if (sestatus == SecureElementStatus::IOERROR) {
285       seHalResetSe();
286     } else {
287       STLOG_HAL_E("%s: Select APDU failed! Close channel..", __func__);
288       SecureElementStatus closeChannelStatus =
289           closeChannel(resApduBuff.channelNumber);
290       if (closeChannelStatus != SecureElementStatus::SUCCESS) {
291         STLOG_HAL_E("%s: closeChannel Failed", __func__);
292       } else {
293         resApduBuff.channelNumber = 0xff;
294       }
295     }
296   }
297   _hidl_cb(resApduBuff, sestatus);
298   free(cmdApdu.p_data);
299   free(rspApdu.p_data);
300   STLOG_HAL_V("%s: Exit", __func__);
301   OpenLogicalChannelProcessing = false;
302   return Void();
303 }
304 
openBasicChannel(const hidl_vec<uint8_t> & aid,uint8_t p2,openBasicChannel_cb _hidl_cb)305 Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
306                                              uint8_t p2,
307                                              openBasicChannel_cb _hidl_cb) {
308   hidl_vec<uint8_t> result;
309   OpenBasicChannelProcessing = true;
310   STLOG_HAL_D("%s: Enter", __func__);
311 
312   if (aid.size() > 16) {
313     STLOG_HAL_E("%s: Invalid AID size: %u", __func__, (unsigned)aid.size());
314     _hidl_cb(result, SecureElementStatus::FAILED);
315     OpenBasicChannelProcessing = false;
316     return Void();
317   }
318 
319   if (!isSeInitialized()) {
320     ESESTATUS status = seHalInit();
321     if (status != ESESTATUS_SUCCESS) {
322       STLOG_HAL_E("%s: seHalInit Failed!!!", __func__);
323       _hidl_cb(result, SecureElementStatus::IOERROR);
324       OpenBasicChannelProcessing = false;
325       return Void();
326     }
327   }
328 
329   SecureElementStatus sestatus = SecureElementStatus::IOERROR;
330   ESESTATUS status = ESESTATUS_FAILED;
331   StEse_data cmdApdu;
332   StEse_data rspApdu;
333 
334   memset(&cmdApdu, 0x00, sizeof(StEse_data));
335   memset(&rspApdu, 0x00, sizeof(StEse_data));
336 
337   cmdApdu.len = (int32_t)(6 + aid.size());
338   cmdApdu.p_data = (uint8_t*)malloc(cmdApdu.len * sizeof(uint8_t));
339   if (cmdApdu.p_data != NULL) {
340     uint8_t xx = 0;
341     cmdApdu.p_data[xx++] = 0x00;        // basic channel
342     cmdApdu.p_data[xx++] = 0xA4;        // INS
343     cmdApdu.p_data[xx++] = 0x04;        // P1
344     cmdApdu.p_data[xx++] = p2;          // P2
345     cmdApdu.p_data[xx++] = aid.size();  // Lc
346     memcpy(&cmdApdu.p_data[xx], aid.data(), aid.size());
347     cmdApdu.p_data[xx + aid.size()] = 0x00;  // Le
348 
349     status = StEse_Transceive(&cmdApdu, &rspApdu);
350   }
351 
352   if (status != ESESTATUS_SUCCESS) {
353     /* Transceive failed */
354     sestatus = SecureElementStatus::IOERROR;
355   } else {
356     uint8_t sw1 = rspApdu.p_data[rspApdu.len - 2];
357     uint8_t sw2 = rspApdu.p_data[rspApdu.len - 1];
358     /*Return response on success, empty vector on failure*/
359     /*Status is success*/
360     if ((sw1 == 0x90) && (sw2 == 0x00)) {
361       /*Copy the response including status word*/
362       result.resize(rspApdu.len);
363       memcpy(&result[0], rspApdu.p_data, rspApdu.len);
364       /*Set basic channel reference if it is not set */
365       if (!mOpenedChannels[0]) {
366         mOpenedChannels[0] = true;
367         mOpenedchannelCount++;
368       }
369       sestatus = SecureElementStatus::SUCCESS;
370     }
371     /*AID provided doesn't match any applet on the secure element*/
372     else if (sw1 == 0x6A && sw2 == 0x82) {
373       sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
374     }
375     /*Operation provided by the P2 parameter is not permitted by the applet.*/
376     else if (sw1 == 0x6A && sw2 == 0x86) {
377       sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
378     }
379   }
380 
381   /* if the SE is unresponsive, reset it */
382   if (sestatus == SecureElementStatus::IOERROR) {
383     seHalResetSe();
384   }
385 
386   if ((sestatus != SecureElementStatus::SUCCESS) && mOpenedChannels[0]) {
387     SecureElementStatus closeChannelStatus =
388         closeChannel(DEFAULT_BASIC_CHANNEL);
389     if (closeChannelStatus != SecureElementStatus::SUCCESS) {
390       STLOG_HAL_E("%s: closeChannel Failed", __func__);
391     }
392   }
393   _hidl_cb(result, sestatus);
394   free(cmdApdu.p_data);
395   free(rspApdu.p_data);
396   STLOG_HAL_V("%s: Exit", __func__);
397   OpenBasicChannelProcessing = false;
398   return Void();
399 }
400 
401 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
closeChannel(uint8_t channelNumber)402 SecureElement::closeChannel(uint8_t channelNumber) {
403   ESESTATUS status = ESESTATUS_FAILED;
404   SecureElementStatus sestatus = SecureElementStatus::FAILED;
405 
406   StEse_data cmdApdu;
407   StEse_data rspApdu;
408 
409   STLOG_HAL_D("%s: Enter : %d", __func__, channelNumber);
410 
411   if ((channelNumber < DEFAULT_BASIC_CHANNEL) ||
412       (channelNumber >= MAX_LOGICAL_CHANNELS) ||
413       (mOpenedChannels[channelNumber] == false)) {
414     STLOG_HAL_E("%s: invalid channel!!!", __func__);
415     sestatus = SecureElementStatus::FAILED;
416   } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
417     memset(&cmdApdu, 0x00, sizeof(StEse_data));
418     memset(&rspApdu, 0x00, sizeof(StEse_data));
419     cmdApdu.p_data = (uint8_t*)malloc(5 * sizeof(uint8_t));
420     if (cmdApdu.p_data != NULL) {
421       uint8_t xx = 0;
422 
423       cmdApdu.p_data[xx++] = channelNumber;
424       cmdApdu.p_data[xx++] = 0x70;           // INS
425       cmdApdu.p_data[xx++] = 0x80;           // P1
426       cmdApdu.p_data[xx++] = channelNumber;  // P2
427       cmdApdu.p_data[xx++] = 0x00;           // Lc
428       cmdApdu.len = xx;
429 
430       status = StEse_Transceive(&cmdApdu, &rspApdu);
431     }
432     if (status != ESESTATUS_SUCCESS) {
433       sestatus = SecureElementStatus::FAILED;
434     } else if ((rspApdu.p_data[rspApdu.len - 2] == 0x90) &&
435                (rspApdu.p_data[rspApdu.len - 1] == 0x00)) {
436       sestatus = SecureElementStatus::SUCCESS;
437     } else {
438       sestatus = SecureElementStatus::FAILED;
439     }
440     free(cmdApdu.p_data);
441     free(rspApdu.p_data);
442   }
443 
444   if ((channelNumber == DEFAULT_BASIC_CHANNEL) ||
445       (sestatus == SecureElementStatus::SUCCESS)) {
446     STLOG_HAL_D("%s: Closing channel : %d is successful ", __func__,
447                 channelNumber);
448     mOpenedChannels[channelNumber] = false;
449     mOpenedchannelCount--;
450     /*If there are no channels remaining close secureElement*/
451     if ((mOpenedchannelCount == 0) && !OpenLogicalChannelProcessing &&
452         !OpenBasicChannelProcessing) {
453       sestatus = seHalDeInit();
454     } else {
455       sestatus = SecureElementStatus::SUCCESS;
456     }
457   }
458 
459   STLOG_HAL_V("%s: Exit", __func__);
460   return sestatus;
461 }
462 
serviceDied(uint64_t,const wp<IBase> &)463 void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
464   STLOG_HAL_E("%s: SecureElement serviceDied!!!", __func__);
465   SecureElementStatus sestatus = seHalDeInit();
466   if (sestatus != SecureElementStatus::SUCCESS) {
467     STLOG_HAL_E("%s: seHalDeInit Failed!!!", __func__);
468   }
469   if (mCallbackV1_1 != nullptr) {
470     mCallbackV1_1->unlinkToDeath(this);
471     mCallbackV1_1 = nullptr;
472   }
473 }
474 
isSeInitialized()475 bool SecureElement::isSeInitialized() { return StEseApi_isOpen(); }
476 
seHalInit()477 ESESTATUS SecureElement::seHalInit() {
478   ESESTATUS status = ESESTATUS_SUCCESS;
479 
480   STLOG_HAL_D("%s: Enter", __func__);
481   status = StEse_init();
482   if (status != ESESTATUS_SUCCESS) {
483     STLOG_HAL_E("%s: SecureElement open failed!!!", __func__);
484   }
485   STLOG_HAL_V("%s: Exit", __func__);
486   return status;
487 }
488 
seHalResetSe()489 void SecureElement::seHalResetSe() {
490   ESESTATUS status = ESESTATUS_SUCCESS;
491 
492   STLOG_HAL_D("%s: Enter", __func__);
493   if (!isSeInitialized()) {
494     ESESTATUS status = seHalInit();
495     if (status != ESESTATUS_SUCCESS) {
496       STLOG_HAL_E("%s: seHalInit Failed!!!", __func__);
497     }
498   }
499 
500   if (status == ESESTATUS_SUCCESS) {
501     mCallbackV1_1->onStateChange_1_1(false, "reset the SE");
502 
503     status = StEse_Reset();
504     if (status != ESESTATUS_SUCCESS) {
505       STLOG_HAL_E("%s: SecureElement reset failed!!", __func__);
506     } else {
507       for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
508         mOpenedChannels[xx] = false;
509       }
510       mOpenedchannelCount = 0;
511       mCallbackV1_1->onStateChange_1_1(true, "SE initialized");
512     }
513   }
514   STLOG_HAL_V("%s: Exit", __func__);
515 }
516 
517 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
seHalDeInit()518 SecureElement::seHalDeInit() {
519   STLOG_HAL_D("%s: Enter", __func__);
520   ESESTATUS status = ESESTATUS_SUCCESS;
521   SecureElementStatus sestatus = SecureElementStatus::FAILED;
522   status = StEse_close();
523   if (status != ESESTATUS_SUCCESS) {
524     sestatus = SecureElementStatus::FAILED;
525   } else {
526     sestatus = SecureElementStatus::SUCCESS;
527 
528     for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
529       mOpenedChannels[xx] = false;
530     }
531     mOpenedchannelCount = 0;
532   }
533   STLOG_HAL_V("%s: Exit", __func__);
534   return sestatus;
535 }
536 
537 Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
reset()538 SecureElement::reset() {
539   int ret = 0;
540   void* stdll = nullptr;
541   ESESTATUS status = ESESTATUS_SUCCESS;
542   SecureElementStatus sestatus = SecureElementStatus::FAILED;
543   std::string valueStr =
544       android::base::GetProperty("persist.vendor.se.streset", "");
545 
546   STLOG_HAL_D("%s: Enter", __func__);
547   if (!isSeInitialized()) {
548     ESESTATUS status = seHalInit();
549     if (status != ESESTATUS_SUCCESS) {
550       STLOG_HAL_E("%s: seHalInit Failed!!!", __func__);
551       if (valueStr.length() > 0) {
552         stdll = dlopen(valueStr.c_str(), RTLD_NOW);
553         if (!stdll) {
554           valueStr = VENDOR_LIB_PATH + valueStr + VENDOR_LIB_EXT;
555           stdll = dlopen(valueStr.c_str(), RTLD_NOW);
556         }
557         if (stdll) {
558           STEseReset fn = (STEseReset)dlsym(stdll, "direct_reset");
559           if (fn) {
560             STLOG_HAL_E("STReset direct reset");
561             ret = fn();
562             STLOG_HAL_E("STReset result=%d", ret);
563             if (ret == 0) {
564               STLOG_HAL_E("STReset pass, retry seHalInit()");
565               status = seHalInit();
566             }
567           }
568         } else {
569           STLOG_HAL_D("%s not found, do nothing.", valueStr.c_str());
570         }
571       }
572     }
573   }
574 
575   if (status == ESESTATUS_SUCCESS) {
576     mCallbackV1_1->onStateChange_1_1(false, "reset the SE");
577 
578     status = StEse_Reset();
579     if (status != ESESTATUS_SUCCESS) {
580       STLOG_HAL_E("%s: SecureElement reset failed!!", __func__);
581     } else {
582       sestatus = SecureElementStatus::SUCCESS;
583       for (uint8_t xx = 0; xx < MAX_LOGICAL_CHANNELS; xx++) {
584         mOpenedChannels[xx] = false;
585       }
586       mOpenedchannelCount = 0;
587       mCallbackV1_1->onStateChange_1_1(true, "SE initialized");
588     }
589   }
590   STLOG_HAL_V("%s: Exit", __func__);
591 
592   return sestatus;
593 }
594 
595 }  // namespace implementation
596 }  // namespace V1_2
597 }  // namespace secure_element
598 }  // namespace hardware
599 }  // namespace android
600