• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) || (resLen < MIN_RES_LEN)) {
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     status = getStatusBySW(res[resLen - SW1_OFFSET], res[resLen - SW2_OFFSET]);
138     if ((ret == SECURE_ELEMENT_CA_RET_OK) && (channelCreated < MAX_CHANNEL_NUM - 1) &&
139         !g_openedChannels[channelCreated] && (status == SecureElementStatus::SE_SUCCESS)) {
140         g_openedChannels[channelCreated] = true;
141         g_openedChannelCount++;
142     } else if (g_openedChannelCount == 0) { // If there are no channels remaining close secureElement
143         HDF_LOGI("openLogicalChannel: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
144         SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
145     }
146 
147     if (channelCreated <= MAX_CHANNEL_SIZE) {
148         channelNumber = static_cast<uint8_t>(channelCreated);
149     } else {
150         HDF_LOGE("openLogicalChannel err, channelCreated = %{public}d", channelCreated);
151     }
152     HDF_LOGI("openLogicalChannel [%{public}d] status:[%{public}d], now has %{public}d channel inuse",
153         channelNumber, static_cast<uint8_t>(status), g_openedChannelCount);
154 #endif
155     return HDF_SUCCESS;
156 }
157 
openBasicChannel(const std::vector<uint8_t> & aid,uint8_t p2,std::vector<uint8_t> & response,SecureElementStatus & status)158 int32_t SeVendorAdaptions::openBasicChannel(const std::vector<uint8_t>& aid, uint8_t p2, std::vector<uint8_t>& response,
159     SecureElementStatus& status)
160 {
161     HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
162     std::lock_guard<std::mutex> lock(g_mutex);
163     if (aid.empty()) {
164         HDF_LOGE("aid is null");
165         status = SecureElementStatus::SE_ILLEGAL_PARAMETER_ERROR;
166         return HDF_ERR_INVALID_PARAM;
167     }
168 #ifdef SE_VENDOR_ADAPTION_USE_CA
169     uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
170     uint32_t resLen = RES_BUFFER_MAX_LENGTH;
171     int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaOpenBasicChannel(
172         (uint8_t *)&aid[0], aid.size(), res, &resLen);
173     for (uint32_t i = 0; i < resLen; i++) {
174         response.push_back(res[i]);
175     }
176     if ((ret != SECURE_ELEMENT_CA_RET_OK) || (resLen < MIN_RES_LEN)) {
177         HDF_LOGE("openBasicChannel failed ret %{public}u", ret);
178         status = SecureElementStatus::SE_GENERAL_ERROR;
179         if (g_openedChannelCount == 0) {
180             HDF_LOGI("openBasicChannel failed: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
181             SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
182         }
183         return HDF_SUCCESS;
184     }
185     status = getStatusBySW(res[resLen - SW1_OFFSET], res[resLen - SW2_OFFSET]);
186     if ((ret == SECURE_ELEMENT_CA_RET_OK) && !g_openedChannels[0] && (status == SecureElementStatus::SE_SUCCESS)) {
187         g_openedChannels[0] = true;
188         g_openedChannelCount++;
189     } else if (g_openedChannelCount == 0) {
190         HDF_LOGI("openBasicChannel failed: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
191         SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
192     }
193     HDF_LOGI("openBasicChannel [0] status:[%{public}d], now has %{public}d channel inuse",
194         static_cast<uint8_t>(status),
195         g_openedChannelCount);
196 #endif
197     return HDF_SUCCESS;
198 }
199 
closeChannel(uint8_t channelNumber,SecureElementStatus & status)200 int32_t SeVendorAdaptions::closeChannel(uint8_t channelNumber, SecureElementStatus& status)
201 {
202     HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
203     std::lock_guard<std::mutex> lock(g_mutex);
204 #ifdef SE_VENDOR_ADAPTION_USE_CA
205     int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaCloseChannel(channelNumber);
206     if (ret != SECURE_ELEMENT_CA_RET_OK) {
207         status = SecureElementStatus::SE_GENERAL_ERROR;
208         HDF_LOGE("closeChannel failed ret %{public}u", ret);
209         return HDF_SUCCESS;
210     }
211     HDF_LOGI("closeChannel: channelNumber = %{public}d", channelNumber);
212     if (channelNumber < MAX_CHANNEL_NUM - 1 && g_openedChannels[channelNumber]) {
213         g_openedChannels[channelNumber] = false;
214         g_openedChannelCount--;
215     }
216     if (g_openedChannelCount == 0) {
217         HDF_LOGI("closeChannel: g_openedChannelCount = %{public}d, Uninit", g_openedChannelCount);
218         SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
219     }
220     HDF_LOGI("closeChannel [%{public}d] succ, now has %{public}d channel inuse",
221         channelNumber, g_openedChannelCount);
222 #endif
223     status = SecureElementStatus::SE_SUCCESS;
224     return HDF_SUCCESS;
225 }
226 
transmit(const std::vector<uint8_t> & command,std::vector<uint8_t> & response,SecureElementStatus & status)227 int32_t SeVendorAdaptions::transmit(const std::vector<uint8_t>& command, std::vector<uint8_t>& response,
228     SecureElementStatus& status)
229 {
230     HDF_LOGD("SeVendorAdaptions:%{public}s!", __func__);
231     std::lock_guard<std::mutex> lock(g_mutex);
232 #ifdef SE_VENDOR_ADAPTION_USE_CA
233     uint8_t res[RES_BUFFER_MAX_LENGTH] = {0};
234     uint32_t resLen = RES_BUFFER_MAX_LENGTH;
235     int ret = SecureElementCaProxy::GetInstance().VendorSecureElementCaTransmit(
236         (uint8_t *)&command[0], command.size(), res, &resLen);
237     for (uint32_t i = 0; i < resLen; i++) {
238         response.push_back(res[i]);
239     }
240     if (ret != SECURE_ELEMENT_CA_RET_OK) {
241         HDF_LOGE("transmit failed ret %{public}u", ret);
242         status = SecureElementStatus::SE_GENERAL_ERROR;
243         return HDF_SUCCESS;
244     }
245     if (resLen >= MIN_RES_LEN) {
246         status = getStatusBySW(res[resLen - SW1_OFFSET], res[resLen - SW2_OFFSET]);
247         return HDF_SUCCESS;
248     }
249     HDF_LOGE("transmit failed resLen %{public}d", resLen);
250 #endif
251     return HDF_SUCCESS;
252 }
253 
reset(SecureElementStatus & status)254 int32_t SeVendorAdaptions::reset(SecureElementStatus& status)
255 {
256     HDF_LOGI("SeVendorAdaptions:%{public}s!", __func__);
257     HDF_LOGE("reset is not support");
258     status = SecureElementStatus::SE_SUCCESS;
259     return HDF_SUCCESS;
260 }
261 
getStatusBySW(uint8_t sw1,uint8_t sw2) const262 SecureElementStatus SeVendorAdaptions::getStatusBySW(uint8_t sw1, uint8_t sw2) const
263 {
264     /* 0x9000, 0x62XX, 0x63XX Status is success */
265     if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x62) || (sw1 == 0x63)) {
266         return SecureElementStatus::SE_SUCCESS;
267     }
268     /* 0x6A82, 0x6999, 0x6985 AID provided doesn't match any applet on the secure element */
269     if ((sw1 == 0x6A && sw2 == 0x82) || (sw1 == 0x69 && (sw2 == 0x99 || sw2 == 0x85))) {
270         return SecureElementStatus::SE_NO_SUCH_ELEMENT_ERROR;
271     }
272     /* 0x6A86 Operation provided by the P2 parameter is not permitted by the applet. */
273     if (sw1 == 0x6A && sw2 == 0x86) {
274         return SecureElementStatus::SE_OPERATION_NOT_SUPPORTED_ERROR;
275     }
276     HDF_LOGE("getStatusBySW fail, SW:0x%{public}02x%{public}02x", sw1, sw2);
277     return SecureElementStatus::SE_GENERAL_ERROR;
278 }
279 
OnRemoteDied(const wptr<IRemoteObject> & object)280 void SeVendorAdaptions::OnRemoteDied(const wptr<IRemoteObject> &object)
281 {
282     HDF_LOGI("OnRemoteDied");
283     // don't lock here, lock in closeChannel
284 #ifdef SE_VENDOR_ADAPTION_USE_CA
285     SecureElementStatus status = SecureElementStatus::SE_GENERAL_ERROR;
286     for (size_t i = 0; i < MAX_CHANNEL_NUM; i++) {
287         if (g_openedChannels[i]) {
288             closeChannel(i, status);
289             HDF_LOGI("OnRemoteDied, close channel [%{public}zu], status = %{public}d", i, status);
290         }
291     }
292     SecureElementCaProxy::GetInstance().VendorSecureElementCaUninit();
293 #endif
294     std::lock_guard<std::mutex> lock(g_mutex);
295     g_callbackV1_0 = nullptr;
296 }
297 
AddSecureElementDeathRecipient(const sptr<ISecureElementCallback> & callbackObj)298 int32_t SeVendorAdaptions::AddSecureElementDeathRecipient(const sptr<ISecureElementCallback> &callbackObj)
299 {
300     if (callbackObj == nullptr) {
301         HDF_LOGE("SeVendorAdaptions AddSecureElementDeathRecipient callbackObj is nullptr");
302         return HDF_FAILURE;
303     }
304     const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ISecureElementCallback>(callbackObj);
305     bool result = remote->AddDeathRecipient(remoteDeathRecipient_);
306     if (!result) {
307         HDF_LOGE("SeVendorAdaptions AddDeathRecipient failed!");
308         return HDF_FAILURE;
309     }
310     return HDF_SUCCESS;
311 }
312 
RemoveSecureElementDeathRecipient(const sptr<ISecureElementCallback> & callbackObj)313 int32_t SeVendorAdaptions::RemoveSecureElementDeathRecipient(const sptr<ISecureElementCallback> &callbackObj)
314 {
315     if (callbackObj == nullptr) {
316         HDF_LOGE("SeVendorAdaptions callbackObj is nullptr!");
317         return HDF_FAILURE;
318     }
319     const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ISecureElementCallback>(callbackObj);
320     bool result = remote->RemoveDeathRecipient(remoteDeathRecipient_);
321     if (!result) {
322         HDF_LOGE("SeVendorAdaptions RemoveDeathRecipient failed!");
323         return HDF_FAILURE;
324     }
325     return HDF_SUCCESS;
326 }
327 } // SecureElement
328 } // HDI
329 } // OHOS