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