1 /*
2 * Copyright (c) 2022 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_session_key.h"
17
18 #include <securec.h>
19
20 #include "auth_common.h"
21 #include "auth_log.h"
22 #include "auth_manager.h"
23 #include "auth_session_fsm.h"
24 #include "softbus_adapter_mem.h"
25 #include "softbus_adapter_socket.h"
26 #include "softbus_def.h"
27 #include "softbus_error_code.h"
28
29 #define SESSION_KEY_MAX_NUM 10
30 #define LAST_USE_THRESHOLD_MS (30 * 1000L) /* 30s */
31
32 typedef struct {
33 int32_t index;
34 SessionKey key;
35 uint64_t lastUseTime;
36 bool isAvailable;
37 ListNode node;
38 uint32_t type;
39 uint64_t useTime[AUTH_LINK_TYPE_MAX];
40 bool isOldKey;
41 } SessionKeyItem;
42
RemoveOldKey(SessionKeyList * list)43 static void RemoveOldKey(SessionKeyList *list)
44 {
45 uint32_t num = 0;
46 SessionKeyItem *item = NULL;
47 LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
48 num++;
49 }
50 if (num <= SESSION_KEY_MAX_NUM) {
51 return;
52 }
53
54 SessionKeyItem *oldKey = NULL;
55 uint64_t oldKeyUseTime = UINT64_MAX;
56 LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
57 if (item->lastUseTime < oldKeyUseTime) {
58 oldKeyUseTime = item->lastUseTime;
59 oldKey = item;
60 }
61 }
62 if (oldKey == NULL) {
63 AUTH_LOGE(AUTH_FSM, "remove session key fail");
64 return;
65 }
66 ListDelete(&oldKey->node);
67 AUTH_LOGI(AUTH_FSM, "session key num reach max, remove the oldest, index=%{public}d, type=%{public}u",
68 oldKey->index, oldKey->type);
69 (void)memset_s(&oldKey->key, sizeof(SessionKey), 0, sizeof(SessionKey));
70 SoftBusFree(oldKey);
71 }
72
InitSessionKeyList(SessionKeyList * list)73 void InitSessionKeyList(SessionKeyList *list)
74 {
75 AUTH_CHECK_AND_RETURN_LOGE(list != NULL, AUTH_FSM, "list is NULL");
76 ListInit(list);
77 }
78
SessionKeyHasAuthLinkType(uint32_t authType,AuthLinkType type)79 static bool SessionKeyHasAuthLinkType(uint32_t authType, AuthLinkType type)
80 {
81 return (authType & (1 << (uint32_t)type)) != 0;
82 }
83
SetAuthLinkType(uint32_t * authType,AuthLinkType type)84 static void SetAuthLinkType(uint32_t *authType, AuthLinkType type)
85 {
86 *authType = (*authType) | (1 << (uint32_t)type);
87 }
88
ClearAuthLinkType(uint32_t * authType,AuthLinkType type)89 static void ClearAuthLinkType(uint32_t *authType, AuthLinkType type)
90 {
91 *authType = (*authType) & (~(1 << (uint32_t)type));
92 }
93
UpdateLatestUseTime(SessionKeyItem * item,AuthLinkType type)94 static void UpdateLatestUseTime(SessionKeyItem *item, AuthLinkType type)
95 {
96 if (item->lastUseTime != item->useTime[type]) {
97 item->useTime[type] = 0;
98 return;
99 }
100 item->useTime[type] = 0;
101 item->lastUseTime = 0;
102 for (uint32_t i = AUTH_LINK_TYPE_WIFI; i < AUTH_LINK_TYPE_MAX; i++) {
103 if (item->useTime[i] > item->lastUseTime) {
104 item->lastUseTime = item->useTime[i];
105 }
106 }
107 }
108
CheckSessionKeyListExistType(const SessionKeyList * list,AuthLinkType type)109 bool CheckSessionKeyListExistType(const SessionKeyList *list, AuthLinkType type)
110 {
111 CHECK_NULL_PTR_RETURN_VALUE(list, false);
112 SessionKeyItem *item = NULL;
113 LIST_FOR_EACH_ENTRY(item, list, SessionKeyItem, node) {
114 if (SessionKeyHasAuthLinkType(item->type, type)) {
115 return true;
116 }
117 }
118 return false;
119 }
120
CheckSessionKeyListHasOldKey(const SessionKeyList * list,AuthLinkType type)121 bool CheckSessionKeyListHasOldKey(const SessionKeyList *list, AuthLinkType type)
122 {
123 CHECK_NULL_PTR_RETURN_VALUE(list, false);
124 SessionKeyItem *item = NULL;
125 LIST_FOR_EACH_ENTRY(item, list, SessionKeyItem, node) {
126 if (SessionKeyHasAuthLinkType(item->type, type) && item->isOldKey) {
127 return true;
128 }
129 }
130 return false;
131 }
132
ClearOldKey(const SessionKeyList * list,AuthLinkType type)133 int32_t ClearOldKey(const SessionKeyList *list, AuthLinkType type)
134 {
135 CHECK_NULL_PTR_RETURN_VALUE(list, SOFTBUS_INVALID_PARAM);
136 SessionKeyItem *item = NULL;
137 LIST_FOR_EACH_ENTRY(item, list, SessionKeyItem, node) {
138 if (SessionKeyHasAuthLinkType(item->type, type) && item->isOldKey) {
139 item->isOldKey = false;
140 }
141 }
142 return SOFTBUS_OK;
143 }
144
DupSessionKeyList(const SessionKeyList * srcList,SessionKeyList * dstList)145 int32_t DupSessionKeyList(const SessionKeyList *srcList, SessionKeyList *dstList)
146 {
147 AUTH_CHECK_AND_RETURN_RET_LOGE(srcList != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "srcList is NULL");
148 AUTH_CHECK_AND_RETURN_RET_LOGE(dstList != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "dstList is NULL");
149 SessionKeyItem *item = NULL;
150 SessionKeyItem *newItem = NULL;
151 LIST_FOR_EACH_ENTRY(item, srcList, SessionKeyItem, node) {
152 newItem = (SessionKeyItem *)DupMemBuffer((uint8_t *)item, sizeof(SessionKeyItem));
153 if (newItem == NULL) {
154 AUTH_LOGE(AUTH_FSM, "malloc newItem fail");
155 DestroySessionKeyList(dstList);
156 return SOFTBUS_MALLOC_ERR;
157 }
158 ListNodeInsert(dstList, &newItem->node);
159 }
160 return SOFTBUS_OK;
161 }
162
DestroySessionKeyList(SessionKeyList * list)163 void DestroySessionKeyList(SessionKeyList *list)
164 {
165 AUTH_CHECK_AND_RETURN_LOGE(list != NULL, AUTH_FSM, "list is NULL");
166 SessionKeyItem *item = NULL;
167 SessionKeyItem *next = NULL;
168 LIST_FOR_EACH_ENTRY_SAFE(item, next, list, SessionKeyItem, node) {
169 ListDelete(&item->node);
170 (void)memset_s(&item->key, sizeof(SessionKey), 0, sizeof(SessionKey));
171 SoftBusFree(item);
172 }
173 }
174
HasSessionKey(const SessionKeyList * list)175 bool HasSessionKey(const SessionKeyList *list)
176 {
177 AUTH_CHECK_AND_RETURN_RET_LOGE(list != NULL, false, AUTH_FSM, "list is NULL");
178 return !IsListEmpty(list);
179 }
180
GetSessionKeyTypeByIndex(const SessionKeyList * list,int32_t index)181 AuthLinkType GetSessionKeyTypeByIndex(const SessionKeyList *list, int32_t index)
182 {
183 CHECK_NULL_PTR_RETURN_VALUE(list, AUTH_LINK_TYPE_MAX);
184 SessionKeyItem *item = NULL;
185 uint32_t type = 0;
186 LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
187 if (item->index == index) {
188 type = item->type;
189 break;
190 }
191 }
192 if (type == 0) {
193 return AUTH_LINK_TYPE_MAX;
194 }
195 for (uint32_t i = AUTH_LINK_TYPE_WIFI; i < AUTH_LINK_TYPE_MAX; i++) {
196 if (SessionKeyHasAuthLinkType(type, (AuthLinkType)i)) {
197 AUTH_LOGI(AUTH_FSM, "auth link type=%{public}d", i);
198 return (AuthLinkType)i;
199 }
200 }
201 return AUTH_LINK_TYPE_MAX;
202 }
203
GetLatestAvailableSessionKeyTime(const SessionKeyList * list,AuthLinkType type)204 uint64_t GetLatestAvailableSessionKeyTime(const SessionKeyList *list, AuthLinkType type)
205 {
206 CHECK_NULL_PTR_RETURN_VALUE(list, 0);
207 if (type < AUTH_LINK_TYPE_WIFI || type >= AUTH_LINK_TYPE_MAX) {
208 AUTH_LOGE(AUTH_FSM, "type error");
209 return 0;
210 }
211 SessionKeyItem *item = NULL;
212 SessionKeyItem *latestKey = NULL;
213 uint64_t latestTime = 0;
214 LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
215 if (!item->isAvailable) {
216 continue;
217 }
218 if (item->useTime[type] > latestTime) {
219 latestTime = item->useTime[type];
220 latestKey = item;
221 }
222 }
223 if (latestKey == NULL) {
224 DumpSessionkeyList(list);
225 return 0;
226 }
227 AUTH_LOGI(AUTH_FSM, "latestUseTime=%{public}" PRIu64 ", type=%{public}d, index=%{public}d, time=%{public}" PRIu64
228 ", all type=%{public}u", latestKey->lastUseTime, type, latestKey->index, latestTime, latestKey->type);
229 return latestTime;
230 }
231
SetSessionKeyAvailable(SessionKeyList * list,int32_t index)232 int32_t SetSessionKeyAvailable(SessionKeyList *list, int32_t index)
233 {
234 CHECK_NULL_PTR_RETURN_VALUE(list, SOFTBUS_INVALID_PARAM);
235 SessionKeyItem *item = NULL;
236 LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
237 if (item->index != index) {
238 continue;
239 }
240 if (!item->isAvailable) {
241 item->isAvailable = true;
242 AUTH_LOGI(AUTH_FSM, "index=%{public}d, set available", index);
243 }
244 return SOFTBUS_OK;
245 }
246 AUTH_LOGE(AUTH_FSM, "can't find sessionKey, index=%{public}d", index);
247 return SOFTBUS_AUTH_SESSION_KEY_NOT_FOUND;
248 }
249
AddSessionKey(SessionKeyList * list,int32_t index,const SessionKey * key,AuthLinkType type,bool isOldKey)250 int32_t AddSessionKey(SessionKeyList *list, int32_t index, const SessionKey *key, AuthLinkType type, bool isOldKey)
251 {
252 AUTH_CHECK_AND_RETURN_RET_LOGE(key != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "key is NULL");
253 AUTH_CHECK_AND_RETURN_RET_LOGE(list != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "list is NULL");
254 if (type < AUTH_LINK_TYPE_WIFI || type >= AUTH_LINK_TYPE_MAX) {
255 AUTH_LOGE(AUTH_FSM, "type error");
256 return SOFTBUS_INVALID_PARAM;
257 }
258 AUTH_LOGD(AUTH_FSM, "keyLen=%{public}d", key->len);
259 SessionKeyItem *item = (SessionKeyItem *)SoftBusCalloc(sizeof(SessionKeyItem));
260 if (item == NULL) {
261 AUTH_LOGE(AUTH_FSM, "malloc SessionKeyItem fail");
262 return SOFTBUS_MALLOC_ERR;
263 }
264 item->isAvailable = false;
265 item->index = index;
266 item->lastUseTime = GetCurrentTimeMs();
267 item->useTime[type] = item->lastUseTime;
268 item->isOldKey = isOldKey;
269 SetAuthLinkType(&item->type, type);
270 if (memcpy_s(&item->key, sizeof(item->key), key, sizeof(SessionKey)) != EOK) {
271 AUTH_LOGE(AUTH_FSM, "add session key fail");
272 SoftBusFree(item);
273 return SOFTBUS_MEM_ERR;
274 }
275 ListNodeInsert((ListNode *)list, &item->node);
276 RemoveOldKey(list);
277 return SOFTBUS_OK;
278 }
279
GetLatestSessionKey(const SessionKeyList * list,AuthLinkType type,int32_t * index,SessionKey * key)280 int32_t GetLatestSessionKey(const SessionKeyList *list, AuthLinkType type, int32_t *index, SessionKey *key)
281 {
282 AUTH_CHECK_AND_RETURN_RET_LOGE(list != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "list is NULL");
283 AUTH_CHECK_AND_RETURN_RET_LOGE(index != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "index is NULL");
284 AUTH_CHECK_AND_RETURN_RET_LOGE(key != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "key is NULL");
285 if (type < AUTH_LINK_TYPE_WIFI || type >= AUTH_LINK_TYPE_MAX) {
286 AUTH_LOGE(AUTH_FSM, "type error");
287 return SOFTBUS_INVALID_PARAM;
288 }
289 if (IsListEmpty((const ListNode *)list)) {
290 AUTH_LOGE(AUTH_FSM, "session key list is empty");
291 return SOFTBUS_LIST_EMPTY;
292 }
293 SessionKeyItem *item = NULL;
294 SessionKeyItem *latestKey = NULL;
295 uint64_t latestTime = 0;
296 LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
297 if (!item->isAvailable || !SessionKeyHasAuthLinkType(item->type, type)) {
298 continue;
299 }
300 if (item->lastUseTime > latestTime) {
301 latestTime = item->lastUseTime;
302 latestKey = item;
303 }
304 }
305 if (latestKey == NULL) {
306 AUTH_LOGE(AUTH_FSM, "invalid session key item, type=%{public}d", type);
307 DumpSessionkeyList(list);
308 return SOFTBUS_AUTH_SESSION_KEY_INVALID;
309 }
310 if (memcpy_s(key, sizeof(SessionKey), &latestKey->key, sizeof(latestKey->key)) != EOK) {
311 AUTH_LOGE(AUTH_FSM, "copy session key fail.");
312 return SOFTBUS_MEM_ERR;
313 }
314 latestKey->lastUseTime = GetCurrentTimeMs();
315 latestKey->useTime[type] = latestKey->lastUseTime;
316 *index = latestKey->index;
317 AUTH_LOGI(AUTH_FSM, "get session key succ, index=%{public}d, authtype=%{public}d, keytype=%{public}u, "
318 "time=%{public}" PRIu64, latestKey->index, type, latestKey->type, latestKey->lastUseTime);
319 return SOFTBUS_OK;
320 }
321
SetSessionKeyAuthLinkType(const SessionKeyList * list,int32_t index,AuthLinkType type)322 int32_t SetSessionKeyAuthLinkType(const SessionKeyList *list, int32_t index, AuthLinkType type)
323 {
324 CHECK_NULL_PTR_RETURN_VALUE(list, SOFTBUS_INVALID_PARAM);
325 if (type < AUTH_LINK_TYPE_WIFI || type >= AUTH_LINK_TYPE_MAX) {
326 AUTH_LOGE(AUTH_FSM, "type error");
327 return SOFTBUS_INVALID_PARAM;
328 }
329 SessionKeyItem *item = NULL;
330 LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
331 if (item->index != index) {
332 continue;
333 }
334 SetAuthLinkType(&item->type, type);
335 item->lastUseTime = GetCurrentTimeMs();
336 item->useTime[type] = item->lastUseTime;
337 AUTH_LOGI(AUTH_FSM, "sessionKey add type, index=%{public}d, newType=%{public}d, type=%{public}u", index, type,
338 item->type);
339 return SOFTBUS_OK;
340 }
341 AUTH_LOGI(AUTH_FSM, "not found sessionKey, index=%{public}d", index);
342 return SOFTBUS_AUTH_SESSION_KEY_NOT_FOUND;
343 }
344
GetSessionKeyByIndex(const SessionKeyList * list,int32_t index,AuthLinkType type,SessionKey * key)345 int32_t GetSessionKeyByIndex(const SessionKeyList *list, int32_t index, AuthLinkType type, SessionKey *key)
346 {
347 AUTH_CHECK_AND_RETURN_RET_LOGE(list != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "list is NULL");
348 AUTH_CHECK_AND_RETURN_RET_LOGE(key != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "key is NULL");
349 if (type < AUTH_LINK_TYPE_WIFI || type >= AUTH_LINK_TYPE_MAX) {
350 AUTH_LOGE(AUTH_FSM, "type error");
351 return SOFTBUS_INVALID_PARAM;
352 }
353 SessionKeyItem *item = NULL;
354 LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
355 if (item->index != index) {
356 continue;
357 }
358 if (memcpy_s(key, sizeof(SessionKey), &item->key, sizeof(item->key)) != EOK) {
359 AUTH_LOGE(AUTH_FSM, "get session key fail, index=%{public}d", index);
360 return SOFTBUS_MEM_ERR;
361 }
362 item->lastUseTime = GetCurrentTimeMs();
363 item->useTime[type] = item->lastUseTime;
364 AUTH_LOGI(AUTH_FSM, "get session key succ, index=%{public}d, time=%{public}" PRIu64, index, item->lastUseTime);
365 return SOFTBUS_OK;
366 }
367 AUTH_LOGE(AUTH_FSM, "session key not found, index=%{public}d", index);
368 return SOFTBUS_AUTH_NOT_FOUND;
369 }
370
RemoveSessionkeyByIndex(SessionKeyList * list,int32_t index,AuthLinkType type)371 void RemoveSessionkeyByIndex(SessionKeyList *list, int32_t index, AuthLinkType type)
372 {
373 AUTH_CHECK_AND_RETURN_LOGE(list != NULL, AUTH_FSM, "list is NULL");
374 bool isFind = false;
375 SessionKeyItem *item = NULL;
376 LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
377 if (item->index == index) {
378 isFind = true;
379 break;
380 }
381 }
382 if (isFind) {
383 ClearAuthLinkType(&item->type, type);
384 if (item->type == 0) {
385 AUTH_LOGI(AUTH_FSM, "Remove Session key, index=%{public}d", index);
386 ListDelete(&item->node);
387 SoftBusFree(item);
388 } else {
389 UpdateLatestUseTime(item, type);
390 AUTH_LOGI(AUTH_FSM, "Remove Session key type, index=%{public}d, type=%{public}u", index, item->type);
391 }
392 } else {
393 AUTH_LOGE(AUTH_FSM, "Remove Session key not found, index=%{public}d", index);
394 }
395 }
396
ClearSessionkeyByAuthLinkType(int64_t authId,SessionKeyList * list,AuthLinkType type)397 void ClearSessionkeyByAuthLinkType(int64_t authId, SessionKeyList *list, AuthLinkType type)
398 {
399 CHECK_NULL_PTR_RETURN_VOID(list);
400 SessionKeyItem *item = NULL;
401 SessionKeyItem *next = NULL;
402 LIST_FOR_EACH_ENTRY_SAFE(item, next, list, SessionKeyItem, node) {
403 if (!SessionKeyHasAuthLinkType(item->type, type)) {
404 continue;
405 }
406 ClearAuthLinkType(&item->type, type);
407 if (item->type == 0) {
408 AUTH_LOGI(AUTH_FSM, "remove sessionkey, type=%{public}d, index=%{public}d, authId=%{public}" PRId64, type,
409 item->index, authId);
410 ListDelete(&item->node);
411 SoftBusFree(item);
412 } else {
413 UpdateLatestUseTime(item, type);
414 }
415 }
416 }
417
EncryptData(const SessionKeyList * list,AuthLinkType type,const InDataInfo * inDataInfo,uint8_t * outData,uint32_t * outLen)418 int32_t EncryptData(
419 const SessionKeyList *list, AuthLinkType type, const InDataInfo *inDataInfo, uint8_t *outData, uint32_t *outLen)
420 {
421 if (list == NULL || inDataInfo == NULL || inDataInfo->inData == NULL || inDataInfo->inLen == 0 || outData == NULL ||
422 *outLen < (inDataInfo->inLen + ENCRYPT_OVER_HEAD_LEN)) {
423 AUTH_LOGE(AUTH_FSM, "invalid param");
424 return SOFTBUS_INVALID_PARAM;
425 }
426 int32_t index = 0;
427 SessionKey sessionKey;
428 if (GetLatestSessionKey(list, type, &index, &sessionKey) != SOFTBUS_OK) {
429 AUTH_LOGE(AUTH_FSM, "get key fail");
430 AUTH_LOGD(AUTH_FSM, "keyLen=%{public}d", sessionKey.len);
431 return SOFTBUS_ENCRYPT_ERR;
432 }
433 /* pack key index */
434 *(uint32_t *)outData = SoftBusHtoLl((uint32_t)index);
435 AesGcmCipherKey cipherKey = { .keyLen = sessionKey.len };
436 if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey.value, sessionKey.len) != EOK) {
437 AUTH_LOGE(AUTH_FSM, "set key fail");
438 (void)memset_s(&sessionKey, sizeof(SessionKey), 0, sizeof(SessionKey));
439 return SOFTBUS_MEM_ERR;
440 }
441 (void)memset_s(&sessionKey, sizeof(SessionKey), 0, sizeof(SessionKey));
442 int32_t ret = SoftBusEncryptDataWithSeq(
443 &cipherKey, inDataInfo->inData, inDataInfo->inLen, outData + ENCRYPT_INDEX_LEN, outLen, index);
444 (void)memset_s(&cipherKey, sizeof(AesGcmCipherKey), 0, sizeof(AesGcmCipherKey));
445 if (ret != SOFTBUS_OK) {
446 AUTH_LOGE(AUTH_FSM, "SoftBusEncryptDataWithSeq fail=%{public}d", ret);
447 return SOFTBUS_ENCRYPT_ERR;
448 }
449 *outLen += ENCRYPT_INDEX_LEN;
450 return SOFTBUS_OK;
451 }
452
DecryptData(const SessionKeyList * list,AuthLinkType type,const InDataInfo * inDataInfo,uint8_t * outData,uint32_t * outLen)453 int32_t DecryptData(
454 const SessionKeyList *list, AuthLinkType type, const InDataInfo *inDataInfo, uint8_t *outData, uint32_t *outLen)
455 {
456 if (list == NULL || inDataInfo == NULL || inDataInfo->inData == NULL || outData == NULL ||
457 inDataInfo->inLen <= ENCRYPT_OVER_HEAD_LEN || *outLen < (inDataInfo->inLen - ENCRYPT_OVER_HEAD_LEN)) {
458 AUTH_LOGE(AUTH_FSM, "invalid param");
459 return SOFTBUS_INVALID_PARAM;
460 }
461 /* unpack key index */
462 int32_t index = (int32_t)SoftBusLtoHl(*(uint32_t *)inDataInfo->inData);
463 SessionKey sessionKey;
464 if (GetSessionKeyByIndex(list, index, type, &sessionKey) != SOFTBUS_OK) {
465 AUTH_LOGE(AUTH_FSM, "get key fail");
466 return SOFTBUS_DECRYPT_ERR;
467 }
468 AesGcmCipherKey cipherKey = { .keyLen = sessionKey.len };
469 if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey.value, sessionKey.len) != EOK) {
470 AUTH_LOGE(AUTH_FSM, "set key fail");
471 (void)memset_s(&sessionKey, sizeof(SessionKey), 0, sizeof(SessionKey));
472 return SOFTBUS_MEM_ERR;
473 }
474 (void)memset_s(&sessionKey, sizeof(SessionKey), 0, sizeof(SessionKey));
475 int32_t ret = SoftBusDecryptDataWithSeq(&cipherKey, inDataInfo->inData + ENCRYPT_INDEX_LEN,
476 inDataInfo->inLen - ENCRYPT_INDEX_LEN, outData, outLen, index);
477 (void)memset_s(&cipherKey, sizeof(AesGcmCipherKey), 0, sizeof(AesGcmCipherKey));
478 if (ret != SOFTBUS_OK) {
479 AUTH_LOGE(AUTH_FSM, "SoftBusDecryptDataWithSeq fail=%{public}d", ret);
480 return SOFTBUS_DECRYPT_ERR;
481 }
482 return SOFTBUS_OK;
483 }
484
EncryptInner(const SessionKeyList * list,AuthLinkType type,const InDataInfo * inDataInfo,uint8_t ** outData,uint32_t * outLen)485 int32_t EncryptInner(
486 const SessionKeyList *list, AuthLinkType type, const InDataInfo *inDataInfo, uint8_t **outData, uint32_t *outLen)
487 {
488 if (list == NULL || inDataInfo == NULL || inDataInfo->inData == NULL || inDataInfo->inLen == 0 || outData == NULL ||
489 outLen == NULL) {
490 AUTH_LOGE(AUTH_FSM, "invalid param");
491 return SOFTBUS_INVALID_PARAM;
492 }
493 uint32_t encDataLen = inDataInfo->inLen + ENCRYPT_OVER_HEAD_LEN;
494 uint8_t *encData = (uint8_t *)SoftBusCalloc(encDataLen);
495 if (encData == NULL) {
496 AUTH_LOGE(AUTH_FSM, "malloc encrypt data fail");
497 return SOFTBUS_MALLOC_ERR;
498 }
499 if (EncryptData(list, type, inDataInfo, encData, &encDataLen) != SOFTBUS_OK) {
500 AUTH_LOGE(AUTH_FSM, "encrypt data fail");
501 SoftBusFree(encData);
502 return SOFTBUS_ENCRYPT_ERR;
503 }
504 *outData = encData;
505 *outLen = encDataLen;
506 return SOFTBUS_OK;
507 }
508
DecryptInner(const SessionKeyList * list,AuthLinkType type,const InDataInfo * inDataInfo,uint8_t ** outData,uint32_t * outLen)509 int32_t DecryptInner(
510 const SessionKeyList *list, AuthLinkType type, const InDataInfo *inDataInfo, uint8_t **outData, uint32_t *outLen)
511 {
512 if (list == NULL || inDataInfo == NULL || inDataInfo->inData == NULL ||
513 inDataInfo->inLen <= ENCRYPT_OVER_HEAD_LEN || outData == NULL || outLen == NULL) {
514 AUTH_LOGE(AUTH_FSM, "invalid param");
515 return SOFTBUS_INVALID_PARAM;
516 }
517 uint32_t decDataLen = inDataInfo->inLen - ENCRYPT_OVER_HEAD_LEN + 1; /* for '\0' */
518 uint8_t *decData = (uint8_t *)SoftBusCalloc(decDataLen);
519 if (decData == NULL) {
520 AUTH_LOGE(AUTH_FSM, "malloc decrypt data fail");
521 return SOFTBUS_MALLOC_ERR;
522 }
523 if (DecryptData(list, type, inDataInfo, decData, &decDataLen) != SOFTBUS_OK) {
524 AUTH_LOGE(AUTH_FSM, "decrypt data fail");
525 SoftBusFree(decData);
526 return SOFTBUS_DECRYPT_ERR;
527 }
528 *outData = decData;
529 *outLen = decDataLen;
530 return SOFTBUS_OK;
531 }
532
533 /* For Debug */
DumpSessionkeyList(const SessionKeyList * list)534 void DumpSessionkeyList(const SessionKeyList *list)
535 {
536 AUTH_CHECK_AND_RETURN_LOGE(list != NULL, AUTH_FSM, "list is NULL");
537 uint32_t keyNum = 0;
538 SessionKeyItem *item = NULL;
539 LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
540 AUTH_LOGI(AUTH_FSM,
541 "[Dump] SessionKey keyNum=%{public}d, index=%{public}d, keyLen=%{public}u, key=XX, "
542 "lastUseTime=%{public}" PRIu64 ", type=%{public}u, useTime=%{public}" PRIu64
543 ", %{public}" PRIu64 ", %{public}" PRIu64 ", %{public}" PRIu64 ", %{public}" PRIu64,
544 keyNum, item->index, item->key.len, item->lastUseTime, item->type, item->useTime[AUTH_LINK_TYPE_WIFI],
545 item->useTime[AUTH_LINK_TYPE_BR], item->useTime[AUTH_LINK_TYPE_BLE], item->useTime[AUTH_LINK_TYPE_P2P],
546 item->useTime[AUTH_LINK_TYPE_ENHANCED_P2P]);
547 keyNum++;
548 }
549 AUTH_LOGI(AUTH_FSM, "[Dump] SessionKey total num=%{public}u", keyNum);
550 }
551
HandleUpdateSessionKeyEvent(const void * obj)552 static void HandleUpdateSessionKeyEvent(const void *obj)
553 {
554 AUTH_CHECK_AND_RETURN_LOGE(obj != NULL, AUTH_FSM, "obj is NULL");
555 AuthHandle authHandle = *(AuthHandle *)(obj);
556 AUTH_LOGI(AUTH_FSM, "update session key begin, authId=%{public}" PRId64, authHandle.authId);
557 AuthManager *auth = GetAuthManagerByAuthId(authHandle.authId);
558 if (auth == NULL) {
559 return;
560 }
561 AuthParam authInfo = {
562 .authSeq = GenSeq(false),
563 .requestId = AuthGenRequestId(),
564 .connId = auth->connId[authHandle.type],
565 .isServer = false,
566 .isFastAuth = false,
567 };
568 if (AuthSessionStartAuth(&authInfo, &auth->connInfo[authHandle.type]) != SOFTBUS_OK) {
569 AUTH_LOGI(
570 AUTH_FSM, "start auth session to update session key fail, authId=%{public}" PRId64, authHandle.authId);
571 }
572 DelDupAuthManager(auth);
573 }
574
RemoveUpdateSessionKeyFunc(const void * obj,void * para)575 static int32_t RemoveUpdateSessionKeyFunc(const void *obj, void *para)
576 {
577 AUTH_CHECK_AND_RETURN_RET_LOGE(obj != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "obj is NULL");
578 AUTH_CHECK_AND_RETURN_RET_LOGE(para != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "para is NULL");
579 int64_t authId = *(int64_t *)(obj);
580 if (authId == *(int64_t *)(para)) {
581 AUTH_LOGI(AUTH_FSM, "remove update session key event, authId=%{public}" PRId64, authId);
582 return SOFTBUS_OK;
583 }
584 return SOFTBUS_INVALID_PARAM;
585 }
586
ScheduleUpdateSessionKey(AuthHandle authHandle,uint64_t delayMs)587 void ScheduleUpdateSessionKey(AuthHandle authHandle, uint64_t delayMs)
588 {
589 if (authHandle.type < AUTH_LINK_TYPE_WIFI || authHandle.type >= AUTH_LINK_TYPE_MAX) {
590 AUTH_LOGE(AUTH_FSM, "authHandle type error");
591 return;
592 }
593 RemoveAuthEvent(EVENT_UPDATE_SESSION_KEY, RemoveUpdateSessionKeyFunc, (void *)(&authHandle.authId));
594 PostAuthEvent(EVENT_UPDATE_SESSION_KEY, HandleUpdateSessionKeyEvent, &authHandle, sizeof(AuthHandle), delayMs);
595 }
596
CancelUpdateSessionKey(int64_t authId)597 void CancelUpdateSessionKey(int64_t authId)
598 {
599 RemoveAuthEvent(EVENT_UPDATE_SESSION_KEY, RemoveUpdateSessionKeyFunc, (void *)(&authId));
600 }