1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "se_vendor_adaptions.h"
17 #include <hdf_base.h>
18 #include <hdf_log.h>
19 #include <vector>
20 #include <iproxy_broker.h>
21
22 #ifdef SE_VENDOR_ADAPTION_USE_CA
23 #include "secure_element_ca_proxy.h"
24 #endif
25
26 #define HDF_LOG_TAG hdf_se
27
28 #ifdef LOG_DOMAIN
29 #undef LOG_DOMAIN
30 #endif
31
32 #define LOG_DOMAIN 0xD000305
33
34 namespace OHOS {
35 namespace HDI {
36 namespace SecureElement {
37 static sptr<ISecureElementCallback> g_callbackV1_0 = nullptr;
38 static std::mutex g_mutex {};
39 #ifdef SE_VENDOR_ADAPTION_USE_CA
40 static const int RES_BUFFER_MAX_LENGTH = 512;
41 static const uint16_t SW1_OFFSET = 2;
42 static const uint16_t SW2_OFFSET = 1;
43 static const uint16_t MAX_CHANNEL_NUM = 4;
44 static const uint16_t MAX_CHANNEL_SIZE = 0xFF;
45 static const uint16_t MIN_RES_LEN = 2;
46 uint16_t g_openedChannelCount = 0;
47 bool g_openedChannels[MAX_CHANNEL_NUM] = {false, false, false, false};
48 #endif
49
SeVendorAdaptions()50 SeVendorAdaptions::SeVendorAdaptions()
51 {
52 remoteDeathRecipient_ =
53 new RemoteDeathRecipient(std::bind(&SeVendorAdaptions::OnRemoteDied, this, std::placeholders::_1));
54 }
55
~SeVendorAdaptions()56 SeVendorAdaptions::~SeVendorAdaptions()
57 {
58 RemoveSecureElementDeathRecipient(g_callbackV1_0);
59 }
60
init(const sptr<ISecureElementCallback> & clientCallback,SecureElementStatus & status)61 int32_t SeVendorAdaptions::init(const sptr<ISecureElementCallback>& clientCallback, SecureElementStatus& status)
62 {
63 HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
64 std::lock_guard<std::mutex> lock(g_mutex);
65 if (clientCallback == nullptr) {
66 HDF_LOGE("init failed, clientCallback is null");
67 status = SecureElementStatus::SE_NULL_POINTER_ERROR;
68 return HDF_ERR_INVALID_PARAM;
69 }
70 #ifdef SE_VENDOR_ADAPTION_USE_CA
71 g_openedChannelCount = 0;
72 int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaInit();
73 if (ret != SECURE_ELEMENT_CA_RET_OK) {
74 HDF_LOGE("VendorSecureElementCaInit failed ret %{public}u", ret);
75 status = SecureElementStatus::SE_GENERAL_ERROR;
76 return HDF_ERR_INVALID_PARAM;
77 }
78 #endif
79 g_callbackV1_0 = clientCallback;
80 g_callbackV1_0->OnSeStateChanged(true);
81 AddSecureElementDeathRecipient(g_callbackV1_0);
82 status = SecureElementStatus::SE_SUCCESS;
83 return HDF_SUCCESS;
84 }
85
getAtr(std::vector<uint8_t> & response)86 int32_t SeVendorAdaptions::getAtr(std::vector<uint8_t>& response)
87 {
88 HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
89 #ifdef SE_VENDOR_ADAPTION_USE_CA
90 uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
91 uint32_t resLen = RES_BUFFER_MAX_LENGTH;
92 int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaGetAtr(res, &resLen);
93 for (uint32_t i = 0; i < resLen; i++) {
94 response.push_back(res[i]);
95 }
96 if (ret != SECURE_ELEMENT_CA_RET_OK) {
97 HDF_LOGE("getAtr failed ret %{public}u", ret);
98 }
99 #endif
100 return HDF_SUCCESS;
101 }
102
isSecureElementPresent(bool & present)103 int32_t SeVendorAdaptions::isSecureElementPresent(bool& present)
104 {
105 HDF_LOGD("SeVendorAdaptDons:%{public}s!", __func__);
106 std::lock_guard<std::mutex> lock(g_mutex);
107 if (g_callbackV1_0 == nullptr) {
108 present = false;
109 } else {
110 present = true;
111 }
112 return HDF_SUCCESS;
113 }
114
openLogicalChannel(const std::vector<uint8_t> & aid,uint8_t p2,std::vector<uint8_t> & response,uint8_t & channelNumber,SecureElementStatus & status)115 int32_t SeVendorAdaptions::openLogicalChannel(const std::vector<uint8_t>& aid, uint8_t p2,
116 std::vector<uint8_t>& response, uint8_t& channelNumber, SecureElementStatus& status)
117 {
118 HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
119 std::lock_guard<std::mutex> lock(g_mutex);
120 if (aid.empty()) {
121 HDF_LOGE("aid is null");
122 status = SecureElementStatus::SE_ILLEGAL_PARAMETER_ERROR;
123 return HDF_ERR_INVALID_PARAM;
124 }
125 #ifdef SE_VENDOR_ADAPTION_USE_CA
126 uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
127 uint32_t resLen = RES_BUFFER_MAX_LENGTH;
128 uint32_t channelCreated = MAX_CHANNEL_SIZE + 1;
129 int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaOpenLogicalChannel(
130 (uint8_t *)&aid[0], aid.size(), p2, res, &resLen, &channelCreated);
131 for (uint32_t i = 0; i < resLen; i++) {
132 response.push_back(res[i]);
133 }
134 if ((ret != SECURE_ELEMENT_CA_RET_OK) || (resLen < MIN_RES_LEN)) {
135 HDF_LOGE("openLogicalChannel failed ret %{public}u", ret);
136 status = SecureElementStatus::SE_GENERAL_ERROR;
137 if (g_openedChannelCount == 0) {
138 HDF_LOGI("openLogicalChannel: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
139 SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
140 }
141 return HDF_SUCCESS;
142 }
143 status = getStatusBySW(res[resLen - SW1_OFFSET], res[resLen - SW2_OFFSET]);
144 if ((ret == SECURE_ELEMENT_CA_RET_OK) && (channelCreated < MAX_CHANNEL_NUM - 1) &&
145 !g_openedChannels[channelCreated] && (status == SecureElementStatus::SE_SUCCESS)) {
146 g_openedChannels[channelCreated] = true;
147 g_openedChannelCount++;
148 } else if (g_openedChannelCount == 0) { // If there are no channels remaining close secureElement
149 HDF_LOGI("openLogicalChannel: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
150 SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
151 }
152
153 if (channelCreated <= MAX_CHANNEL_SIZE) {
154 channelNumber = static_cast<uint8_t>(channelCreated);
155 } else {
156 HDF_LOGE("openLogicalChannel err, channelCreated = %{public}d", channelCreated);
157 }
158 HDF_LOGI("openLogicalChannel [%{public}d] status:[%{public}d], now has %{public}d channel inuse",
159 channelNumber, static_cast<uint8_t>(status), g_openedChannelCount);
160 #endif
161 return HDF_SUCCESS;
162 }
163
openBasicChannel(const std::vector<uint8_t> & aid,uint8_t p2,std::vector<uint8_t> & response,SecureElementStatus & status)164 int32_t SeVendorAdaptions::openBasicChannel(const std::vector<uint8_t>& aid, uint8_t p2, std::vector<uint8_t>& response,
165 SecureElementStatus& status)
166 {
167 HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
168 std::lock_guard<std::mutex> lock(g_mutex);
169 if (aid.empty()) {
170 HDF_LOGE("aid is null");
171 status = SecureElementStatus::SE_ILLEGAL_PARAMETER_ERROR;
172 return HDF_ERR_INVALID_PARAM;
173 }
174 #ifdef SE_VENDOR_ADAPTION_USE_CA
175 uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
176 uint32_t resLen = RES_BUFFER_MAX_LENGTH;
177 int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaOpenBasicChannel(
178 (uint8_t *)&aid[0], aid.size(), res, &resLen);
179 for (uint32_t i = 0; i < resLen; i++) {
180 response.push_back(res[i]);
181 }
182 if ((ret != SECURE_ELEMENT_CA_RET_OK) || (resLen < MIN_RES_LEN)) {
183 HDF_LOGE("openBasicChannel failed ret %{public}u", ret);
184 status = SecureElementStatus::SE_GENERAL_ERROR;
185 if (g_openedChannelCount == 0) {
186 HDF_LOGI("openBasicChannel failed: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
187 SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
188 }
189 return HDF_SUCCESS;
190 }
191 status = getStatusBySW(res[resLen - SW1_OFFSET], res[resLen - SW2_OFFSET]);
192 if ((ret == SECURE_ELEMENT_CA_RET_OK) && !g_openedChannels[0] && (status == SecureElementStatus::SE_SUCCESS)) {
193 g_openedChannels[0] = true;
194 g_openedChannelCount++;
195 } else if (g_openedChannelCount == 0) {
196 HDF_LOGI("openBasicChannel failed: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
197 SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
198 }
199 HDF_LOGI("openBasicChannel [0] status:[%{public}d], now has %{public}d channel inuse",
200 static_cast<uint8_t>(status),
201 g_openedChannelCount);
202 #endif
203 return HDF_SUCCESS;
204 }
205
closeChannel(uint8_t channelNumber,SecureElementStatus & status)206 int32_t SeVendorAdaptions::closeChannel(uint8_t channelNumber, SecureElementStatus& status)
207 {
208 HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
209 std::lock_guard<std::mutex> lock(g_mutex);
210 #ifdef SE_VENDOR_ADAPTION_USE_CA
211 int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaCloseChannel(channelNumber);
212 if (ret != SECURE_ELEMENT_CA_RET_OK) {
213 status = SecureElementStatus::SE_GENERAL_ERROR;
214 HDF_LOGE("closeChannel failed ret %{public}u", ret);
215 return HDF_SUCCESS;
216 }
217 HDF_LOGI("closeChannel: channelNumber = %{public}d", channelNumber);
218 if (channelNumber < MAX_CHANNEL_NUM - 1 && g_openedChannels[channelNumber]) {
219 g_openedChannels[channelNumber] = false;
220 g_openedChannelCount--;
221 }
222 if (g_openedChannelCount == 0) {
223 HDF_LOGI("closeChannel: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
224 SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
225 }
226 HDF_LOGI("closeChannel [%{public}d] succ, now has %{public}d channel inuse",
227 channelNumber, g_openedChannelCount);
228 #endif
229 status = SecureElementStatus::SE_SUCCESS;
230 return HDF_SUCCESS;
231 }
232
transmit(const std::vector<uint8_t> & command,std::vector<uint8_t> & response,SecureElementStatus & status)233 int32_t SeVendorAdaptions::transmit(const std::vector<uint8_t>& command, std::vector<uint8_t>& response,
234 SecureElementStatus& status)
235 {
236 HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
237 std::lock_guard<std::mutex> lock(g_mutex);
238 #ifdef SE_VENDOR_ADAPTION_USE_CA
239 uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
240 uint32_t resLen = RES_BUFFER_MAX_LENGTH;
241 int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaTransmit(
242 (uint8_t *)&command[0], command.size(), res, &resLen);
243 for (uint32_t i = 0; i < resLen; i++) {
244 response.push_back(res[i]);
245 }
246 if (ret != SECURE_ELEMENT_CA_RET_OK) {
247 HDF_LOGE("transmit failed ret %{public}u", ret);
248 status = SecureElementStatus::SE_GENERAL_ERROR;
249 return HDF_SUCCESS;
250 }
251 if (resLen >= MIN_RES_LEN) {
252 status = getStatusBySW(res[resLen - SW1_OFFSET], res[resLen - SW2_OFFSET]);
253 return HDF_SUCCESS;
254 }
255 HDF_LOGE("transmit failed resLen %{public}d", resLen);
256 #endif
257 return HDF_SUCCESS;
258 }
259
reset(SecureElementStatus & status)260 int32_t SeVendorAdaptions::reset(SecureElementStatus& status)
261 {
262 HDF_LOGI("SeVendorAdaptions:%{public}s!", __func__);
263 HDF_LOGE("reset is not support");
264 status = SecureElementStatus::SE_SUCCESS;
265 return HDF_SUCCESS;
266 }
267
getStatusBySW(uint8_t sw1,uint8_t sw2) const268 SecureElementStatus SeVendorAdaptions::getStatusBySW(uint8_t sw1, uint8_t sw2) const
269 {
270 /* 0x9000, 0x62XX, 0x63XX Status is success */
271 if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
272 return SecureElementStatus::SE_SUCCESS;
273 }
274 /* 0x6A82, 0x6999, 0x6985 AID provided doesn't match any applet on the secure element */
275 if ((sw1 == 0x6A && sw2 == 0x82) || (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
276 return SecureElementStatus::SE_NO_SUCH_ELEMENT_ERROR;
277 }
278 /* 0x6A86 Operation provided by the P2 parameter is not permitted by the applet. */
279 if (sw1 == 0x6A && sw2 == 0x86) {
280 return SecureElementStatus::SE_OPERATION_NOT_SUPPORTED_ERROR;
281 }
282 HDF_LOGE("getStatusBySW fail, SW:0x%{public}02x%{public}02x", sw1, sw2);
283 return SecureElementStatus::SE_GENERAL_ERROR;
284 }
285
OnRemoteDied(const wptr<IRemoteObject> & object)286 void SeVendorAdaptions::OnRemoteDied(const wptr<IRemoteObject> &object)
287 {
288 HDF_LOGI("OnRemoteDied");
289 // don't lock here, lock in closeChannel
290 #ifdef SE_VENDOR_ADAPTION_USE_CA
291 SecureElementStatus status = SecureElementStatus::SE_GENERAL_ERROR;
292 for (size_t i = 0; i < MAX_CHANNEL_NUM; i++) {
293 if (g_openedChannels[i]) {
294 closeChannel(i, status);
295 HDF_LOGI("OnRemoteDied, close channel [%{public}zu], status = %{public}d", i, status);
296 }
297 }
298 #endif
299 std::lock_guard<std::mutex> lock(g_mutex);
300 g_callbackV1_0 = nullptr;
301 }
302
AddSecureElementDeathRecipient(const sptr<ISecureElementCallback> & callbackObj)303 int32_t SeVendorAdaptions::AddSecureElementDeathRecipient(const sptr<ISecureElementCallback> &callbackObj)
304 {
305 if (callbackObj == nullptr) {
306 HDF_LOGE("SeVendorAdaptions AddSecureElementDeathRecipient callbackObj is nullptr");
307 return HDF_FAILURE;
308 }
309 const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ISecureElementCallback>(callbackObj);
310 bool result = remote->AddDeathRecipient(remoteDeathRecipient_);
311 if (!result) {
312 HDF_LOGE("SeVendorAdaptions AddDeathRecipient failed!");
313 return HDF_FAILURE;
314 }
315 return HDF_SUCCESS;
316 }
317
RemoveSecureElementDeathRecipient(const sptr<ISecureElementCallback> & callbackObj)318 int32_t SeVendorAdaptions::RemoveSecureElementDeathRecipient(const sptr<ISecureElementCallback> &callbackObj)
319 {
320 if (callbackObj == nullptr) {
321 HDF_LOGE("SeVendorAdaptions callbackObj is nullptr!");
322 return HDF_FAILURE;
323 }
324 const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ISecureElementCallback>(callbackObj);
325 bool result = remote->RemoveDeathRecipient(remoteDeathRecipient_);
326 if (!result) {
327 HDF_LOGE("SeVendorAdaptions RemoveDeathRecipient failed!");
328 return HDF_FAILURE;
329 }
330 return HDF_SUCCESS;
331 }
332 } // SecureElement
333 } // HDI
334 } // OHOS