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