1 /*
2 * Copyright (c) 2021 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 "auth_sessionkey.h"
17
18 #include <securec.h>
19
20 #include "auth_common.h"
21 #include "softbus_adapter_mem.h"
22 #include "softbus_errcode.h"
23 #include "softbus_log.h"
24
25 static ListNode g_sessionKeyListHead;
26
AuthSessionKeyListInit(void)27 void AuthSessionKeyListInit(void)
28 {
29 ListInit(&g_sessionKeyListHead);
30 }
31
AuthSetLocalSessionKey(const NecessaryDevInfo * devInfo,const char * peerUdid,const uint8_t * sessionKey,uint32_t sessionKeyLen)32 void AuthSetLocalSessionKey(const NecessaryDevInfo *devInfo, const char *peerUdid,
33 const uint8_t *sessionKey, uint32_t sessionKeyLen)
34 {
35 uint32_t listSize = 0;
36 ListNode *item = NULL;
37 SessionKeyList *sessionKeyList = NULL;
38 SessionKeyList *sessionKeyListTail = NULL;
39 if (devInfo == NULL || peerUdid == NULL || sessionKey == NULL) {
40 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid parameter");
41 return;
42 }
43 sessionKeyList = (SessionKeyList *)SoftBusCalloc(sizeof(SessionKeyList));
44 if (sessionKeyList == NULL) {
45 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "SoftBusCalloc failed");
46 return;
47 }
48 sessionKeyList->type = devInfo->type;
49 sessionKeyList->side = devInfo->side;
50 sessionKeyList->seq = devInfo->seq;
51 if (memcpy_s(sessionKeyList->peerUdid, UDID_BUF_LEN, peerUdid, strlen(peerUdid)) != EOK) {
52 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "memcpy_s failed");
53 SoftBusFree(sessionKeyList);
54 return;
55 }
56 if (memcpy_s(sessionKeyList->deviceKey, MAX_DEVICE_KEY_LEN, devInfo->deviceKey, devInfo->deviceKeyLen) != EOK) {
57 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "memcpy_s failed");
58 SoftBusFree(sessionKeyList);
59 return;
60 }
61 sessionKeyList->deviceKeyLen = devInfo->deviceKeyLen;
62 if (memcpy_s(sessionKeyList->sessionKey, SESSION_KEY_LENGTH, sessionKey, sessionKeyLen) != EOK) {
63 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "memcpy_s failed");
64 SoftBusFree(sessionKeyList);
65 return;
66 }
67 sessionKeyList->sessionKeyLen = sessionKeyLen;
68 ListNodeInsert(&g_sessionKeyListHead, &sessionKeyList->node);
69 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "auth add sessionkey, seq is:%d", sessionKeyList->seq);
70
71 LIST_FOR_EACH(item, &g_sessionKeyListHead) {
72 listSize++;
73 }
74 if (listSize == MAX_KEY_LIST_SIZE) {
75 item = GET_LIST_TAIL(&g_sessionKeyListHead);
76 sessionKeyListTail = LIST_ENTRY(item, SessionKeyList, node);
77 (void)memset_s(sessionKeyListTail->sessionKey, SESSION_KEY_LENGTH, 0, SESSION_KEY_LENGTH);
78 ListDelete(&sessionKeyListTail->node);
79 SoftBusFree(sessionKeyListTail);
80 sessionKeyListTail = NULL;
81 }
82 }
83
AuthIsDeviceVerified(uint32_t type,const char * deviceKey,uint32_t deviceKeyLen)84 bool AuthIsDeviceVerified(uint32_t type, const char *deviceKey, uint32_t deviceKeyLen)
85 {
86 if (deviceKey == NULL) {
87 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid parameter");
88 return false;
89 }
90 SessionKeyList *sessionKeyList = NULL;
91 if (IsListEmpty(&g_sessionKeyListHead) == true) {
92 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_WARN, "no session key in memory, need to verify device");
93 return false;
94 }
95 ListNode *item = NULL;
96 LIST_FOR_EACH(item, &g_sessionKeyListHead) {
97 sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
98 if (sessionKeyList->type == type && strncmp(sessionKeyList->deviceKey, deviceKey, deviceKeyLen) == 0) {
99 return true;
100 }
101 }
102 return false;
103 }
104
AuthIsSeqInKeyList(int32_t seq)105 bool AuthIsSeqInKeyList(int32_t seq)
106 {
107 SessionKeyList *sessionKeyList = NULL;
108 if (IsListEmpty(&g_sessionKeyListHead) == true) {
109 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_WARN, "auth is seq in key list, no session key in memory");
110 return false;
111 }
112 ListNode *item = NULL;
113 LIST_FOR_EACH(item, &g_sessionKeyListHead) {
114 sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
115 if (sessionKeyList->seq == seq) {
116 return true;
117 }
118 }
119 return false;
120 }
121
AuthGetSessionKey(const NecessaryDevInfo * devInfo)122 static SessionKeyList *AuthGetSessionKey(const NecessaryDevInfo *devInfo)
123 {
124 if (devInfo == NULL) {
125 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid parameter");
126 return NULL;
127 }
128 SessionKeyList *sessionKeyList = NULL;
129 if (IsListEmpty(&g_sessionKeyListHead) == true) {
130 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "auth get last session key, no session key in memory");
131 return NULL;
132 }
133 ListNode *item = NULL;
134 LIST_FOR_EACH(item, &g_sessionKeyListHead) {
135 sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
136 if (devInfo->side != AUTH_SIDE_ANY) {
137 if (sessionKeyList->side == devInfo->side && sessionKeyList->type == devInfo->type &&
138 strncmp(sessionKeyList->deviceKey, devInfo->deviceKey, devInfo->deviceKeyLen) == 0) {
139 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO,
140 "auth get session key succ, seq is:%d, side is %d", sessionKeyList->seq, devInfo->side);
141 return sessionKeyList;
142 }
143 } else {
144 if (sessionKeyList->type == devInfo->type &&
145 strncmp(sessionKeyList->deviceKey, devInfo->deviceKey, devInfo->deviceKeyLen) == 0) {
146 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO,
147 "auth get last session key succ, seq is:%d", sessionKeyList->seq);
148 return sessionKeyList;
149 }
150 }
151 }
152 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "auth get session key failed");
153 return NULL;
154 }
155
GetSessionKeyByDevinfo(const NecessaryDevInfo * devInfo)156 static SessionKeyList *GetSessionKeyByDevinfo(const NecessaryDevInfo *devInfo)
157 {
158 if (devInfo == NULL) {
159 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid parameter");
160 return NULL;
161 }
162 SessionKeyList *sessionKeyList = NULL;
163 if (IsListEmpty(&g_sessionKeyListHead) == true) {
164 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR,
165 "auth get session key by device info, no session key in memory");
166 return NULL;
167 }
168 ListNode *item = NULL;
169 LIST_FOR_EACH(item, &g_sessionKeyListHead) {
170 sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
171 if (sessionKeyList->type == devInfo->type &&
172 sessionKeyList->seq == devInfo->seq &&
173 strncmp(sessionKeyList->deviceKey, devInfo->deviceKey, devInfo->deviceKeyLen) == 0) {
174 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO,
175 "auth get session key by dev info succ, seq is:%d", sessionKeyList->seq);
176 return sessionKeyList;
177 }
178 }
179 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "auth cannot find session key by dev info");
180 return NULL;
181 }
182
AuthGetSessionKeyBySeq(int32_t seq)183 static SessionKeyList *AuthGetSessionKeyBySeq(int32_t seq)
184 {
185 SessionKeyList *sessionKeyList = NULL;
186 if (IsListEmpty(&g_sessionKeyListHead) == true) {
187 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "auth get session key by seq, no session key in memory");
188 return NULL;
189 }
190 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "auth get session key by seq %d", seq);
191 ListNode *item = NULL;
192 ListNode *tmp = NULL;
193 LIST_FOR_EACH_SAFE(item, tmp, &g_sessionKeyListHead) {
194 sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
195 if (sessionKeyList->seq == seq) {
196 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "auth get session key by seq seccessfully.");
197 return sessionKeyList;
198 }
199 }
200 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "auth get session key by seq failed");
201 return NULL;
202 }
203
AuthEncryptBySeq(int32_t seq,AuthSideFlag * side,uint8_t * data,uint32_t len,OutBuf * outBuf)204 int32_t AuthEncryptBySeq(int32_t seq, AuthSideFlag *side, uint8_t *data, uint32_t len, OutBuf *outBuf)
205 {
206 if (data == NULL || outBuf == NULL || outBuf->bufLen < (len + ENCRYPT_OVER_HEAD_LEN)) {
207 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid parameter");
208 return SOFTBUS_INVALID_PARAM;
209 }
210 SessionKeyList *sessionKeyList = NULL;
211 uint32_t outLen;
212
213 sessionKeyList = AuthGetSessionKeyBySeq(seq);
214 if (sessionKeyList == NULL) {
215 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "Auth Get SessionKey by seq failed");
216 return SOFTBUS_ENCRYPT_ERR;
217 }
218 *side = sessionKeyList->side;
219 // add seq first
220 if (memcpy_s(outBuf->buf, sizeof(int32_t), &sessionKeyList->seq, sizeof(int32_t)) != EOK) {
221 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "memcpy_s failed");
222 return SOFTBUS_ENCRYPT_ERR;
223 }
224 AesGcmCipherKey cipherKey = {0};
225 cipherKey.keyLen = sessionKeyList->sessionKeyLen;
226 if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKeyList->sessionKey, sessionKeyList->sessionKeyLen) != EOK) {
227 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "memcpy_s failed");
228 return SOFTBUS_ENCRYPT_ERR;
229 }
230 if (SoftBusEncryptDataWithSeq(&cipherKey, data, len, outBuf->buf + MESSAGE_INDEX_LEN,
231 &outLen, sessionKeyList->seq) != SOFTBUS_OK) {
232 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "SoftBusEncryptDataWithSeq failed");
233 return SOFTBUS_ENCRYPT_ERR;
234 }
235 outBuf->outLen = outLen + MESSAGE_INDEX_LEN;
236 return SOFTBUS_OK;
237 }
238
AuthEncrypt(const ConnectOption * option,AuthSideFlag * side,uint8_t * data,uint32_t len,OutBuf * outBuf)239 int32_t AuthEncrypt(const ConnectOption *option, AuthSideFlag *side, uint8_t *data, uint32_t len, OutBuf *outBuf)
240 {
241 if (option == NULL || side == NULL || data == NULL ||
242 outBuf == NULL || outBuf->bufLen < (len + ENCRYPT_OVER_HEAD_LEN)) {
243 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid parameter");
244 return SOFTBUS_INVALID_PARAM;
245 }
246 SessionKeyList *sessionKeyList = NULL;
247 NecessaryDevInfo devInfo = {0};
248 uint32_t outLen;
249
250 devInfo.type = option->type;
251 int32_t ret = AuthGetDeviceKey(devInfo.deviceKey, MAX_DEVICE_KEY_LEN, &(devInfo.deviceKeyLen), option);
252 if (ret != SOFTBUS_OK) {
253 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "AuthGetDeviceKey failed");
254 return SOFTBUS_ENCRYPT_ERR;
255 }
256 devInfo.side = *side;
257 sessionKeyList = AuthGetSessionKey(&devInfo);
258 if (sessionKeyList == NULL) {
259 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "AuthGetSessionKey failed");
260 return SOFTBUS_ENCRYPT_ERR;
261 }
262 *side = sessionKeyList->side;
263 // add seq first
264 if (memcpy_s(outBuf->buf, sizeof(int32_t), &sessionKeyList->seq, sizeof(int32_t)) != EOK) {
265 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "memcpy_s failed");
266 return SOFTBUS_ENCRYPT_ERR;
267 }
268 AesGcmCipherKey cipherKey = {0};
269 cipherKey.keyLen = sessionKeyList->sessionKeyLen;
270 if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKeyList->sessionKey, sessionKeyList->sessionKeyLen) != EOK) {
271 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "memcpy_s failed");
272 return SOFTBUS_ENCRYPT_ERR;
273 }
274 if (SoftBusEncryptDataWithSeq(&cipherKey, data, len, outBuf->buf + MESSAGE_INDEX_LEN,
275 &outLen, sessionKeyList->seq) != SOFTBUS_OK) {
276 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "SoftBusEncryptDataWithSeq failed");
277 return SOFTBUS_ENCRYPT_ERR;
278 }
279 outBuf->outLen = outLen + MESSAGE_INDEX_LEN;
280 return SOFTBUS_OK;
281 }
282
AuthDecrypt(const ConnectOption * option,AuthSideFlag side,uint8_t * data,uint32_t len,OutBuf * outBuf)283 int32_t AuthDecrypt(const ConnectOption *option, AuthSideFlag side, uint8_t *data, uint32_t len, OutBuf *outBuf)
284 {
285 if (option == NULL || data == NULL || outBuf == NULL || outBuf->bufLen < (len - ENCRYPT_OVER_HEAD_LEN)) {
286 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid parameter");
287 return SOFTBUS_INVALID_PARAM;
288 }
289 SessionKeyList *sessionKeyList = NULL;
290 NecessaryDevInfo devInfo = {0};
291 devInfo.type = option->type;
292
293 int32_t ret = AuthGetDeviceKey(devInfo.deviceKey, MAX_DEVICE_KEY_LEN, &(devInfo.deviceKeyLen), option);
294 if (ret != SOFTBUS_OK) {
295 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "AuthGetDeviceKey failed");
296 return SOFTBUS_ENCRYPT_ERR;
297 }
298 int32_t seq;
299 if (memcpy_s(&seq, sizeof(int32_t), data, sizeof(int32_t)) != EOK) {
300 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "memcpy_s failed");
301 return SOFTBUS_ENCRYPT_ERR;
302 }
303 devInfo.seq = seq;
304 data += sizeof(int32_t);
305 len -= sizeof(int32_t);
306 devInfo.side = side;
307 sessionKeyList = GetSessionKeyByDevinfo(&devInfo);
308 if (sessionKeyList == NULL) {
309 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "GetSessionKeyByDevinfo failed");
310 return SOFTBUS_ENCRYPT_ERR;
311 }
312
313 AesGcmCipherKey cipherKey = {0};
314 cipherKey.keyLen = sessionKeyList->sessionKeyLen;
315 if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKeyList->sessionKey, sessionKeyList->sessionKeyLen) != EOK) {
316 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "memcpy_s failed");
317 return SOFTBUS_ENCRYPT_ERR;
318 }
319 if (SoftBusDecryptDataWithSeq(&cipherKey, data, len, outBuf->buf,
320 &outBuf->outLen, sessionKeyList->seq) != SOFTBUS_OK) {
321 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "SoftBusDecryptDataWithSeq failed");
322 return SOFTBUS_ENCRYPT_ERR;
323 }
324 return SOFTBUS_OK;
325 }
326
AuthGetEncryptHeadLen(void)327 uint32_t AuthGetEncryptHeadLen(void)
328 {
329 return ENCRYPT_OVER_HEAD_LEN;
330 }
331
AuthClearSessionKeyBySeq(int32_t seq)332 void AuthClearSessionKeyBySeq(int32_t seq)
333 {
334 SessionKeyList *sessionKeyList = NULL;
335 if (IsListEmpty(&g_sessionKeyListHead) == true) {
336 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "auth clear session key by seq, no session key in memory");
337 return;
338 }
339 ListNode *item = NULL;
340 ListNode *tmp = NULL;
341 LIST_FOR_EACH_SAFE(item, tmp, &g_sessionKeyListHead) {
342 sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
343 if (sessionKeyList->seq == seq) {
344 (void)memset_s(sessionKeyList->sessionKey, SESSION_KEY_LENGTH, 0, SESSION_KEY_LENGTH);
345 ListDelete(&sessionKeyList->node);
346 SoftBusFree(sessionKeyList);
347 sessionKeyList = NULL;
348 }
349 }
350 }
351
AuthClearAllSessionKey(void)352 void AuthClearAllSessionKey(void)
353 {
354 SessionKeyList *sessionKeyList = NULL;
355 if (IsListEmpty(&g_sessionKeyListHead) == true) {
356 return;
357 }
358 ListNode *item = NULL;
359 ListNode *tmp = NULL;
360 LIST_FOR_EACH_SAFE(item, tmp, &g_sessionKeyListHead) {
361 sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
362 (void)memset_s(sessionKeyList->sessionKey, SESSION_KEY_LENGTH, 0, SESSION_KEY_LENGTH);
363 ListDelete(&sessionKeyList->node);
364 SoftBusFree(sessionKeyList);
365 sessionKeyList = NULL;
366 }
367 ListInit(&g_sessionKeyListHead);
368 }
369