• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ", %{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], item->useTime[AUTH_LINK_TYPE_SLE]);
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     DeviceKeyId deviceKeyId = {
569         .hasDeviceKeyId = false, .localDeviceKeyId = AUTH_INVALID_DEVICEKEY_ID,
570         .remoteDeviceKeyId = AUTH_INVALID_DEVICEKEY_ID,
571     };
572     if (AuthSessionStartAuth(&authInfo, &auth->connInfo[authHandle.type], &deviceKeyId) != SOFTBUS_OK) {
573         AUTH_LOGI(
574             AUTH_FSM, "start auth session to update session key fail, authId=%{public}" PRId64, authHandle.authId);
575     }
576     DelDupAuthManager(auth);
577 }
578 
RemoveUpdateSessionKeyFunc(const void * obj,void * para)579 static int32_t RemoveUpdateSessionKeyFunc(const void *obj, void *para)
580 {
581     AUTH_CHECK_AND_RETURN_RET_LOGE(obj != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "obj is NULL");
582     AUTH_CHECK_AND_RETURN_RET_LOGE(para != NULL, SOFTBUS_INVALID_PARAM, AUTH_FSM, "para is NULL");
583     int64_t authId = *(int64_t *)(obj);
584     if (authId == *(int64_t *)(para)) {
585         AUTH_LOGI(AUTH_FSM, "remove update session key event, authId=%{public}" PRId64, authId);
586         return SOFTBUS_OK;
587     }
588     return SOFTBUS_INVALID_PARAM;
589 }
590 
ScheduleUpdateSessionKey(AuthHandle authHandle,uint64_t delayMs)591 void ScheduleUpdateSessionKey(AuthHandle authHandle, uint64_t delayMs)
592 {
593     if (authHandle.type < AUTH_LINK_TYPE_WIFI || authHandle.type >= AUTH_LINK_TYPE_MAX) {
594         AUTH_LOGE(AUTH_FSM, "authHandle type error");
595         return;
596     }
597     RemoveAuthEvent(EVENT_UPDATE_SESSION_KEY, RemoveUpdateSessionKeyFunc, (void *)(&authHandle.authId));
598     PostAuthEvent(EVENT_UPDATE_SESSION_KEY, HandleUpdateSessionKeyEvent, &authHandle, sizeof(AuthHandle), delayMs);
599 }
600 
CancelUpdateSessionKey(int64_t authId)601 void CancelUpdateSessionKey(int64_t authId)
602 {
603     RemoveAuthEvent(EVENT_UPDATE_SESSION_KEY, RemoveUpdateSessionKeyFunc, (void *)(&authId));
604 }