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