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 #endif
73 g_callbackV1_0 = clientCallback;
74 g_callbackV1_0->OnSeStateChanged(true);
75 AddSecureElementDeathRecipient(g_callbackV1_0);
76 status = SecureElementStatus::SE_SUCCESS;
77 return HDF_SUCCESS;
78 }
79
getAtr(std::vector<uint8_t>& response)80 int32_t SeVendorAdaptions::getAtr(std::vector<uint8_t>& response)
81 {
82 HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
83 #ifdef SE_VENDOR_ADAPTION_USE_CA
84 uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
85 uint32_t resLen = RES_BUFFER_MAX_LENGTH;
86 int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaGetAtr(res, &resLen);
87 for (uint32_t i = 0; i < resLen; i++) {
88 response.push_back(res[i]);
89 }
90 if (ret != SECURE_ELEMENT_CA_RET_OK) {
91 HDF_LOGE("getAtr failed ret %{public}u", ret);
92 }
93 #endif
94 return HDF_SUCCESS;
95 }
96
isSecureElementPresent(bool& present)97 int32_t SeVendorAdaptions::isSecureElementPresent(bool& present)
98 {
99 HDF_LOGD("SeVendorAdaptDons:%{public}s!", __func__);
100 std::lock_guard<std::mutex> lock(g_mutex);
101 if (g_callbackV1_0 == nullptr) {
102 present = false;
103 } else {
104 present = true;
105 }
106 return HDF_SUCCESS;
107 }
108
openLogicalChannel(const std::vector<uint8_t>& aid, uint8_t p2, std::vector<uint8_t>& response, uint8_t& channelNumber, SecureElementStatus& status)109 int32_t SeVendorAdaptions::openLogicalChannel(const std::vector<uint8_t>& aid, uint8_t p2,
110 std::vector<uint8_t>& response, uint8_t& channelNumber, SecureElementStatus& status)
111 {
112 HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
113 std::lock_guard<std::mutex> lock(g_mutex);
114 if (aid.empty()) {
115 HDF_LOGE("aid is null");
116 status = SecureElementStatus::SE_ILLEGAL_PARAMETER_ERROR;
117 return HDF_ERR_INVALID_PARAM;
118 }
119 #ifdef SE_VENDOR_ADAPTION_USE_CA
120 uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
121 uint32_t resLen = RES_BUFFER_MAX_LENGTH;
122 uint32_t channelCreated = MAX_CHANNEL_SIZE + 1;
123 int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaOpenLogicalChannel(
124 (uint8_t *)&aid[0], aid.size(), p2, res, &resLen, &channelCreated);
125 for (uint32_t i = 0; i < resLen; i++) {
126 response.push_back(res[i]);
127 }
128 if (ret != SECURE_ELEMENT_CA_RET_OK) {
129 HDF_LOGE("openLogicalChannel failed ret %{public}u", ret);
130 status = SecureElementStatus::SE_GENERAL_ERROR;
131 if (g_openedChannelCount == 0) {
132 HDF_LOGI("openLogicalChannel: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
133 SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
134 }
135 return HDF_SUCCESS;
136 }
137 if (ret == SECURE_ELEMENT_CA_RET_OK && resLen >= MIN_RES_LEN) {
138 status = getStatusBySW(res[resLen - SW1_OFFSET], res[resLen - SW2_OFFSET]);
139 if (channelCreated < MAX_CHANNEL_NUM - 1 && !g_openedChannels[channelCreated] &&
140 status == SecureElementStatus::SE_SUCCESS) {
141 g_openedChannels[channelCreated] = true;
142 g_openedChannelCount++;
143 }
144 }
145 if (channelCreated <= MAX_CHANNEL_SIZE) {
146 channelNumber = static_cast<uint8_t>(channelCreated);
147 } else {
148 HDF_LOGE("openLogicalChannel err, channelCreated = %{public}d", channelCreated);
149 }
150 HDF_LOGI("openLogicalChannel [%{public}d] succ, now has %{public}d channel inuse",
151 channelNumber, g_openedChannelCount);
152 #endif
153 return HDF_SUCCESS;
154 }
155
openBasicChannel(const std::vector<uint8_t>& aid, uint8_t p2, std::vector<uint8_t>& response, SecureElementStatus& status)156 int32_t SeVendorAdaptions::openBasicChannel(const std::vector<uint8_t>& aid, uint8_t p2, std::vector<uint8_t>& response,
157 SecureElementStatus& status)
158 {
159 HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
160 std::lock_guard<std::mutex> lock(g_mutex);
161 if (aid.empty()) {
162 HDF_LOGE("aid is null");
163 status = SecureElementStatus::SE_ILLEGAL_PARAMETER_ERROR;
164 return HDF_ERR_INVALID_PARAM;
165 }
166 #ifdef SE_VENDOR_ADAPTION_USE_CA
167 uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
168 uint32_t resLen = RES_BUFFER_MAX_LENGTH;
169 int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaOpenBasicChannel(
170 (uint8_t *)&aid[0], aid.size(), res, &resLen);
171 for (uint32_t i = 0; i < resLen; i++) {
172 response.push_back(res[i]);
173 }
174 if (ret != SECURE_ELEMENT_CA_RET_OK) {
175 HDF_LOGE("openBasicChannel failed ret %{public}u", ret);
176 status = SecureElementStatus::SE_GENERAL_ERROR;
177 if (g_openedChannelCount == 0) {
178 HDF_LOGI("openBasicChannel failed: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
179 SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
180 }
181 return HDF_SUCCESS;
182 }
183 if (ret == SECURE_ELEMENT_CA_RET_OK && resLen >= MIN_RES_LEN) {
184 status = getStatusBySW(res[resLen - SW1_OFFSET], res[resLen - SW2_OFFSET]);
185 if (!g_openedChannels[0] && (response[resLen - SW1_OFFSET] == 0x90 && response[resLen - SW2_OFFSET] == 0x00)) {
186 g_openedChannels[0] = true;
187 g_openedChannelCount++;
188 }
189 }
190 HDF_LOGI("openBasicChannel [0] succ, now has %{public}d channel inuse", g_openedChannelCount);
191 #endif
192 return HDF_SUCCESS;
193 }
194
closeChannel(uint8_t channelNumber, SecureElementStatus& status)195 int32_t SeVendorAdaptions::closeChannel(uint8_t channelNumber, SecureElementStatus& status)
196 {
197 HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
198 std::lock_guard<std::mutex> lock(g_mutex);
199 #ifdef SE_VENDOR_ADAPTION_USE_CA
200 int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaCloseChannel(channelNumber);
201 if (ret != SECURE_ELEMENT_CA_RET_OK) {
202 status = SecureElementStatus::SE_GENERAL_ERROR;
203 HDF_LOGE("closeChannel failed ret %{public}u", ret);
204 return HDF_SUCCESS;
205 }
206 HDF_LOGI("closeChannel: channelNumber = %{public}d", channelNumber);
207 if (channelNumber < MAX_CHANNEL_NUM - 1 && g_openedChannels[channelNumber]) {
208 g_openedChannels[channelNumber] = false;
209 g_openedChannelCount--;
210 }
211 if (g_openedChannelCount == 0) {
212 HDF_LOGI("closeChannel: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
213 SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
214 }
215 HDF_LOGI("closeChannel [%{public}d] succ, now has %{public}d channel inuse",
216 channelNumber, g_openedChannelCount);
217 #endif
218 status = SecureElementStatus::SE_SUCCESS;
219 return HDF_SUCCESS;
220 }
221
transmit(const std::vector<uint8_t>& command, std::vector<uint8_t>& response, SecureElementStatus& status)222 int32_t SeVendorAdaptions::transmit(const std::vector<uint8_t>& command, std::vector<uint8_t>& response,
223 SecureElementStatus& status)
224 {
225 HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
226 std::lock_guard<std::mutex> lock(g_mutex);
227 #ifdef SE_VENDOR_ADAPTION_USE_CA
228 uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
229 uint32_t resLen = RES_BUFFER_MAX_LENGTH;
230 int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaTransmit(
231 (uint8_t *)&command[0], command.size(), res, &resLen);
232 for (uint32_t i = 0; i < resLen; i++) {
233 response.push_back(res[i]);
234 }
235 if (ret != SECURE_ELEMENT_CA_RET_OK) {
236 HDF_LOGE("transmit failed ret %{public}u", ret);
237 status = SecureElementStatus::SE_GENERAL_ERROR;
238 return HDF_SUCCESS;
239 }
240 if (resLen >= MIN_RES_LEN) {
241 status = getStatusBySW(res[resLen - SW1_OFFSET], res[resLen - SW2_OFFSET]);
242 return HDF_SUCCESS;
243 }
244 HDF_LOGE("transmit failed resLen %{public}d", resLen);
245 #endif
246 return HDF_SUCCESS;
247 }
248
reset(SecureElementStatus& status)249 int32_t SeVendorAdaptions::reset(SecureElementStatus& status)
250 {
251 HDF_LOGI("SeVendorAdaptions:%{public}s!", __func__);
252 HDF_LOGE("reset is not support");
253 status = SecureElementStatus::SE_SUCCESS;
254 return HDF_SUCCESS;
255 }
256
getStatusBySW(uint8_t sw1, uint8_t sw2) const257 SecureElementStatus SeVendorAdaptions::getStatusBySW(uint8_t sw1, uint8_t sw2) const
258 {
259 /* 0x9000, 0x62XX, 0x63XX Status is success */
260 if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
261 return SecureElementStatus::SE_SUCCESS;
262 }
263 /* 0x6A82, 0x6999, 0x6985 AID provided doesn't match any applet on the secure element */
264 if ((sw1 == 0x6A && sw2 == 0x82) || (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
265 return SecureElementStatus::SE_NO_SUCH_ELEMENT_ERROR;
266 }
267 /* 0x6A86 Operation provided by the P2 parameter is not permitted by the applet. */
268 if (sw1 == 0x6A && sw2 == 0x86) {
269 return SecureElementStatus::SE_OPERATION_NOT_SUPPORTED_ERROR;
270 }
271 HDF_LOGE("getStatusBySW fail, SW:0x%{public}02x%{public}02x", sw1, sw2);
272 return SecureElementStatus::SE_GENERAL_ERROR;
273 }
274
OnRemoteDied(const wptr<IRemoteObject> &object)275 void SeVendorAdaptions::OnRemoteDied(const wptr<IRemoteObject> &object)
276 {
277 HDF_LOGI("OnRemoteDied");
278 // don't lock here, lock in closeChannel
279 #ifdef SE_VENDOR_ADAPTION_USE_CA
280 SecureElementStatus status = SecureElementStatus::SE_GENERAL_ERROR;
281 for (size_t i = 0; i < MAX_CHANNEL_NUM; i++) {
282 if (g_openedChannels[i]) {
283 closeChannel(i, status);
284 HDF_LOGI("OnRemoteDied, close channel [%{public}zu], status = %{public}d", i, status);
285 }
286 }
287 SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
288 #endif
289 std::lock_guard<std::mutex> lock(g_mutex);
290 g_callbackV1_0 = nullptr;
291 }
292
AddSecureElementDeathRecipient(const sptr<ISecureElementCallback> &callbackObj)293 int32_t SeVendorAdaptions::AddSecureElementDeathRecipient(const sptr<ISecureElementCallback> &callbackObj)
294 {
295 if (callbackObj == nullptr) {
296 HDF_LOGE("SeVendorAdaptions AddSecureElementDeathRecipient callbackObj is nullptr");
297 return HDF_FAILURE;
298 }
299 const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ISecureElementCallback>(callbackObj);
300 bool result = remote->AddDeathRecipient(remoteDeathRecipient_);
301 if (!result) {
302 HDF_LOGE("SeVendorAdaptions AddDeathRecipient failed!");
303 return HDF_FAILURE;
304 }
305 return HDF_SUCCESS;
306 }
307
RemoveSecureElementDeathRecipient(const sptr<ISecureElementCallback> &callbackObj)308 int32_t SeVendorAdaptions::RemoveSecureElementDeathRecipient(const sptr<ISecureElementCallback> &callbackObj)
309 {
310 if (callbackObj == nullptr) {
311 HDF_LOGE("SeVendorAdaptions callbackObj is nullptr!");
312 return HDF_FAILURE;
313 }
314 const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ISecureElementCallback>(callbackObj);
315 bool result = remote->RemoveDeathRecipient(remoteDeathRecipient_);
316 if (!result) {
317 HDF_LOGE("SeVendorAdaptions RemoveDeathRecipient failed!");
318 return HDF_FAILURE;
319 }
320 return HDF_SUCCESS;
321 }
322 } // SecureElement
323 } // HDI
324 } // OHOS