1 /*
2 **
3 ** Copyright 2018, The Android Open Source Project
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  ** The original Work has been changed by NXP.
20  **
21  ** Licensed under the Apache License, Version 2.0 (the "License");
22  ** you may not use this file except in compliance with the License.
23  ** You may obtain a copy of the License at
24  **
25  ** http://www.apache.org/licenses/LICENSE-2.0
26  **
27  ** Unless required by applicable law or agreed to in writing, software
28  ** distributed under the License is distributed on an "AS IS" BASIS,
29  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30  ** See the License for the specific language governing permissions and
31  ** limitations under the License.
32  **
33  ** Copyright 2020-2021,2024 NXP
34  **
35  *********************************************************************************/
36 #define LOG_TAG "AppletConnection"
37 
38 #include <android-base/logging.h>
39 #include <android-base/stringprintf.h>
40 #include <android/binder_manager.h>
41 #include <signal.h>
42 #include <iomanip>
43 #include <mutex>
44 #include <string>
45 #include <vector>
46 
47 #include <AppletConnection.h>
48 #include <EseTransportUtils.h>
49 #include <SignalHandler.h>
50 
51 using aidl::android::hardware::secure_element::BnSecureElementCallback;
52 using aidl::android::hardware::secure_element::ISecureElement;
53 using aidl::android::hardware::secure_element::LogicalChannelResponse;
54 using android::base::StringPrintf;
55 using ndk::ScopedAStatus;
56 using ndk::SharedRefBase;
57 using ndk::SpAIBinder;
58 
59 namespace keymint::javacard {
60 
61 static bool isStrongBox = false; // true when linked with StrongBox HAL process
62 const std::vector<uint8_t> kStrongBoxAppletAID = {0xA0, 0x00, 0x00, 0x00, 0x62};
63 constexpr const char eseHalServiceName[] = "android.hardware.secure_element.ISecureElement/eSE1";
64 
65 class SecureElementCallback : public BnSecureElementCallback {
66   public:
onStateChange(bool state,const std::string & in_debugReason)67     ScopedAStatus onStateChange(bool state, const std::string& in_debugReason) override {
68         LOGD_OMAPI("connected =" << (state ? "true " : "false ") << "reason: " << in_debugReason);
69         mConnState = state;
70         return ScopedAStatus::ok();
71     };
isClientConnected()72     bool isClientConnected() { return mConnState; }
73 
74   private:
75     bool mConnState = false;
76 };
77 
BinderDiedCallback(void * cookie)78 void AppletConnection::BinderDiedCallback(void* cookie) {
79     LOG(ERROR) << "Received binder death ntf. SE HAL Service died";
80     auto thiz = static_cast<AppletConnection*>(cookie);
81     thiz->mSecureElementCallback->onStateChange(false, "SE HAL died");
82     thiz->mSecureElement = nullptr;
83 }
84 
AppletConnection(const std::vector<uint8_t> & aid)85 AppletConnection::AppletConnection(const std::vector<uint8_t>& aid)
86     : kAppletAID(aid), mSBAccessController(SBAccessController::getInstance()) {
87     if (kAppletAID == kStrongBoxAppletAID) {
88         isStrongBox = true;
89     }
90     mDeathRecipient =
91         ::ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback));
92 }
93 
connectToSEService()94 bool AppletConnection::connectToSEService() {
95     if (!SignalHandler::getInstance()->isHandlerRegistered()) {
96         LOG(DEBUG) << "register signal handler";
97         SignalHandler::getInstance()->installHandler(this);
98     }
99     if (mSecureElement != nullptr && mSecureElementCallback->isClientConnected()) {
100         LOG(INFO) <<"Already connected";
101         return true;
102     }
103     bool connected = false;
104     SpAIBinder binder = SpAIBinder(AServiceManager_waitForService(eseHalServiceName));
105     mSecureElement = ISecureElement::fromBinder(binder);
106     if (mSecureElement == nullptr) {
107         LOG(ERROR) << "Failed to connect to Secure element service";
108     } else {
109         mSecureElementCallback = SharedRefBase::make<SecureElementCallback>();
110         auto status = mSecureElement->init(mSecureElementCallback);
111         connected = status.isOk() && mSecureElementCallback->isClientConnected();
112         if (!connected) {
113             LOG(ERROR) << "Failed to initialize SE HAL service";
114         }
115     }
116     return connected;
117 }
118 
119 // AIDL Hal returns empty response for failure case
120 // so prepare response based on service specific errorcode
prepareServiceSpecificErrorRepsponse(std::vector<uint8_t> & resp,int32_t errorCode)121 void prepareServiceSpecificErrorRepsponse(std::vector<uint8_t>& resp, int32_t errorCode) {
122     resp.clear();
123     switch (errorCode) {
124         case ISecureElement::NO_SUCH_ELEMENT_ERROR:
125             resp.push_back(0x6A);
126             resp.push_back(0x82);
127             break;
128         case ISecureElement::CHANNEL_NOT_AVAILABLE:
129             resp.push_back(0x6A);
130             resp.push_back(0x81);
131             break;
132         case ISecureElement::UNSUPPORTED_OPERATION:
133             resp.push_back(0x6A);
134             resp.push_back(0x86);
135             break;
136         case ISecureElement::IOERROR:
137             resp.push_back(0x64);
138             resp.push_back(0xFF);
139             break;
140         default:
141             resp.push_back(0xFF);
142             resp.push_back(0xFF);
143     }
144 }
selectApplet(std::vector<uint8_t> & resp,uint8_t p2)145 bool AppletConnection::selectApplet(std::vector<uint8_t>& resp, uint8_t p2) {
146   bool stat = false;
147   resp.clear();
148   LogicalChannelResponse logical_channel_response;
149   auto status = mSecureElement->openLogicalChannel(kAppletAID, p2, &logical_channel_response);
150   if (status.isOk()) {
151       mOpenChannel = logical_channel_response.channelNumber;
152       resp = logical_channel_response.selectResponse;
153       stat = true;
154   } else {
155       mOpenChannel = -1;
156       resp = logical_channel_response.selectResponse;
157       LOG(ERROR) << "openLogicalChannel: Failed ";
158       // AIDL Hal returns empty response for failure case
159       // so prepare response based on service specific errorcode
160       prepareServiceSpecificErrorRepsponse(resp, status.getServiceSpecificError());
161   }
162   return stat;
163 }
prepareErrorRepsponse(std::vector<uint8_t> & resp)164 void prepareErrorRepsponse(std::vector<uint8_t>& resp){
165         resp.clear();
166         resp.push_back(0xFF);
167         resp.push_back(0xFF);
168 }
openChannelToApplet(std::vector<uint8_t> & resp)169 bool AppletConnection::openChannelToApplet(std::vector<uint8_t>& resp) {
170   bool ret = false;
171   uint8_t retry = 0;
172   if (isChannelOpen()) {
173     LOG(INFO) << "channel Already opened";
174     return true;
175   }
176   if (isStrongBox) {
177       if (!mSBAccessController.isSelectAllowed()) {
178           prepareErrorRepsponse(resp);
179           return false;
180       }
181       do {
182           if (selectApplet(resp, SELECT_P2_VALUE_0) || selectApplet(resp, SELECT_P2_VALUE_2)) {
183               ret = true;
184               break;
185           }
186           LOG(INFO) << " openChannelToApplet retry after 2 secs";
187           usleep(2 * ONE_SEC);
188       } while (++retry < MAX_RETRY_COUNT);
189   } else {
190       ret = selectApplet(resp, 0x0);
191   }
192   return ret;
193 }
194 
transmit(std::vector<uint8_t> & CommandApdu,std::vector<uint8_t> & output)195 bool AppletConnection::transmit(std::vector<uint8_t>& CommandApdu , std::vector<uint8_t>& output){
196     std::vector<uint8_t> cmd = CommandApdu;
197     cmd[0] |= mOpenChannel ;
198     LOGD_OMAPI("Channel number: " << static_cast<int>(mOpenChannel));
199 
200     if (mSecureElement == nullptr) return false;
201     if (isStrongBox) {
202         if (!mSBAccessController.isOperationAllowed(CommandApdu[APDU_INS_OFFSET])) {
203             std::vector<uint8_t> ins;
204             ins.push_back(CommandApdu[APDU_INS_OFFSET]);
205             LOG(ERROR) << "command Ins:" << ins << " not allowed";
206             prepareErrorRepsponse(output);
207             return false;
208         }
209     }
210     // block any fatal signal delivery
211     SignalHandler::getInstance()->blockSignals();
212     std::vector<uint8_t> response;
213     mSecureElement->transmit(cmd, &response);
214     output = response;
215     // un-block signal delivery
216     SignalHandler::getInstance()->unblockSignals();
217     return true;
218 }
219 
getSessionTimeout()220 int AppletConnection::getSessionTimeout() {
221     return mSBAccessController.getSessionTimeout();
222 }
223 
close()224 bool AppletConnection::close() {
225     std::lock_guard<std::mutex> lock(channel_mutex_);
226     if (mSecureElement == nullptr) {
227         LOG(ERROR) << "Channel couldn't be closed mSEClient handle is null";
228         return false;
229     }
230     if(mOpenChannel < 0){
231        LOG(INFO) << "Channel is already closed";
232        return true;
233     }
234     auto status = mSecureElement->closeChannel(mOpenChannel);
235     if (!status.isOk()) {
236         /*
237          * reason could be SE reset or HAL deinit triggered from other client
238          * which anyway closes all the opened channels
239          */
240         LOG(ERROR) << "closeChannel failed";
241         mOpenChannel = -1;
242         return true;
243     }
244     LOG(INFO) << "Channel closed";
245     mOpenChannel = -1;
246     return true;
247 }
248 
isServiceConnected()249 bool AppletConnection::isServiceConnected() {
250     std::lock_guard<std::mutex> lock(channel_mutex_);
251     if (mSecureElement == nullptr || !mSecureElementCallback->isClientConnected()) {
252         return false;
253     }
254     return true;
255 }
256 
isChannelOpen()257 bool AppletConnection::isChannelOpen() {
258     std::lock_guard<std::mutex> lock(channel_mutex_);
259     return mOpenChannel >= 0;
260 }
261 }  // namespace keymint::javacard
262