• 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_manager.h"
22 #include "auth_session_fsm.h"
23 #include "softbus_adapter_mem.h"
24 #include "softbus_adapter_socket.h"
25 #include "softbus_errcode.h"
26 #include "softbus_log.h"
27 
28 #define SESSION_KEY_MAX_NUM 10
29 #define LAST_USE_THRESHOLD_MS (30 * 1000L) /* 30s */
30 
31 typedef struct {
32     int32_t index;
33     SessionKey key;
34     uint64_t lastUseTime;
35     ListNode node;
36 } SessionKeyItem;
37 
RemoveOldKey(SessionKeyList * list)38 static void RemoveOldKey(SessionKeyList *list)
39 {
40     uint32_t num = 0;
41     SessionKeyItem *item = NULL;
42     LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
43         num++;
44     }
45     if (num <= SESSION_KEY_MAX_NUM) {
46         return;
47     }
48     item = LIST_ENTRY(GET_LIST_HEAD(list), SessionKeyItem, node);
49     ListDelete(&item->node);
50     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO,
51         "session key num reach max, remove the oldest, index=%d", item->index);
52     (void)memset_s(&item->key, sizeof(SessionKey), 0, sizeof(SessionKey));
53     SoftBusFree(item);
54 }
55 
InitSessionKeyList(SessionKeyList * list)56 void InitSessionKeyList(SessionKeyList *list)
57 {
58     CHECK_NULL_PTR_RETURN_VOID(list);
59     ListInit(list);
60 }
61 
DupSessionKeyList(const SessionKeyList * srcList,SessionKeyList * dstList)62 int32_t DupSessionKeyList(const SessionKeyList *srcList, SessionKeyList *dstList)
63 {
64     CHECK_NULL_PTR_RETURN_VALUE(srcList, SOFTBUS_INVALID_PARAM);
65     CHECK_NULL_PTR_RETURN_VALUE(dstList, SOFTBUS_INVALID_PARAM);
66     SessionKeyItem *item = NULL;
67     SessionKeyItem *newItem = NULL;
68     LIST_FOR_EACH_ENTRY(item, srcList, SessionKeyItem, node) {
69         newItem = (SessionKeyItem *)DupMemBuffer((uint8_t *)item, sizeof(SessionKeyItem));
70         if (newItem == NULL) {
71             DestroySessionKeyList(dstList);
72             return SOFTBUS_MALLOC_ERR;
73         }
74         ListTailInsert(dstList, &newItem->node);
75     }
76     return SOFTBUS_OK;
77 }
78 
DestroySessionKeyList(SessionKeyList * list)79 void DestroySessionKeyList(SessionKeyList *list)
80 {
81     CHECK_NULL_PTR_RETURN_VOID(list);
82     SessionKeyItem *item = NULL;
83     SessionKeyItem *next = NULL;
84     LIST_FOR_EACH_ENTRY_SAFE(item, next, list, SessionKeyItem, node) {
85         ListDelete(&item->node);
86         (void)memset_s(&item->key, sizeof(SessionKey), 0, sizeof(SessionKey));
87         SoftBusFree(item);
88     }
89 }
90 
HasSessionKey(const SessionKeyList * list)91 bool HasSessionKey(const SessionKeyList *list)
92 {
93     CHECK_NULL_PTR_RETURN_VALUE(list, false);
94     return !IsListEmpty(list);
95 }
96 
AddSessionKey(SessionKeyList * list,int32_t index,const SessionKey * key)97 int32_t AddSessionKey(SessionKeyList *list, int32_t index, const SessionKey *key)
98 {
99     CHECK_NULL_PTR_RETURN_VALUE(key, SOFTBUS_INVALID_PARAM);
100     CHECK_NULL_PTR_RETURN_VALUE(list, SOFTBUS_INVALID_PARAM);
101     SessionKeyItem *item = SoftBusMalloc(sizeof(SessionKeyItem));
102     if (item == NULL) {
103         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "malloc SessionKeyItem fail.");
104         return SOFTBUS_MALLOC_ERR;
105     }
106     item->index = index;
107     item->lastUseTime = GetCurrentTimeMs();
108     if (memcpy_s(&item->key, sizeof(item->key), key, sizeof(SessionKey)) != EOK) {
109         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "add session key fail.");
110         SoftBusFree(item);
111         return SOFTBUS_MEM_ERR;
112     }
113     ListTailInsert((ListNode *)list, &item->node);
114     RemoveOldKey(list);
115     return SOFTBUS_OK;
116 }
117 
GetLatestSessionKey(const SessionKeyList * list,int32_t * index,SessionKey * key)118 int32_t GetLatestSessionKey(const SessionKeyList *list, int32_t *index, SessionKey *key)
119 {
120     CHECK_NULL_PTR_RETURN_VALUE(list, SOFTBUS_INVALID_PARAM);
121     CHECK_NULL_PTR_RETURN_VALUE(index, SOFTBUS_INVALID_PARAM);
122     CHECK_NULL_PTR_RETURN_VALUE(key, SOFTBUS_INVALID_PARAM);
123     if (IsListEmpty((const ListNode *)list)) {
124         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "session key list is empty.");
125         return SOFTBUS_ERR;
126     }
127     SessionKeyItem *item = LIST_ENTRY(GET_LIST_TAIL((const ListNode *)list), SessionKeyItem, node);
128     if (item == NULL) {
129         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid session key item.");
130         return SOFTBUS_ERR;
131     }
132     if (memcpy_s(key, sizeof(SessionKey), &item->key, sizeof(item->key)) != EOK) {
133         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "copy session key fail.");
134         return SOFTBUS_MEM_ERR;
135     }
136     item->lastUseTime = GetCurrentTimeMs();
137     *index = item->index;
138     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "get session key succ, index=%d.", item->index);
139     return SOFTBUS_OK;
140 }
141 
GetSessionKeyByIndex(const SessionKeyList * list,int32_t index,SessionKey * key)142 int32_t GetSessionKeyByIndex(const SessionKeyList *list, int32_t index, SessionKey *key)
143 {
144     CHECK_NULL_PTR_RETURN_VALUE(list, SOFTBUS_INVALID_PARAM);
145     CHECK_NULL_PTR_RETURN_VALUE(key, SOFTBUS_INVALID_PARAM);
146     SessionKeyItem *item = NULL;
147     LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
148         if (item->index != index) {
149             continue;
150         }
151         if (memcpy_s(key, sizeof(SessionKey), &item->key, sizeof(item->key)) != EOK) {
152             SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "get session key fail, index=%d.", index);
153             return SOFTBUS_MEM_ERR;
154         }
155         item->lastUseTime = GetCurrentTimeMs();
156         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "get session key succ, index=%d.", index);
157         return SOFTBUS_OK;
158     }
159     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "session key not found, index=%d.", index);
160     return SOFTBUS_ERR;
161 }
162 
EncryptData(const SessionKeyList * list,const uint8_t * inData,uint32_t inLen,uint8_t * outData,uint32_t * outLen)163 int32_t EncryptData(const SessionKeyList *list, const uint8_t *inData, uint32_t inLen,
164     uint8_t *outData, uint32_t *outLen)
165 {
166     if (list == NULL || inData == NULL || inLen == 0 || outData == NULL ||
167         *outLen < (inLen + ENCRYPT_OVER_HEAD_LEN)) {
168         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid param.");
169         return SOFTBUS_INVALID_PARAM;
170     }
171     int32_t index = 0;
172     SessionKey sessionKey;
173     if (GetLatestSessionKey(list, &index, &sessionKey) != SOFTBUS_OK) {
174         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "get key fail.");
175         return SOFTBUS_ENCRYPT_ERR;
176     }
177     /* pack key index */
178     *(uint32_t *)outData = SoftBusHtoLl((uint32_t)index);
179     AesGcmCipherKey cipherKey = {.keyLen = sessionKey.len};
180     if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey.value, sessionKey.len) != EOK) {
181         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "set key fail.");
182         (void)memset_s(&sessionKey, sizeof(SessionKey), 0, sizeof(SessionKey));
183         return SOFTBUS_MEM_ERR;
184     }
185     (void)memset_s(&sessionKey, sizeof(SessionKey), 0, sizeof(SessionKey));
186     int32_t ret = SoftBusEncryptDataWithSeq(&cipherKey, inData, inLen, outData + ENCRYPT_INDEX_LEN, outLen, index);
187     (void)memset_s(&cipherKey, sizeof(AesGcmCipherKey), 0, sizeof(AesGcmCipherKey));
188     if (ret != SOFTBUS_OK) {
189         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "SoftBusEncryptDataWithSeq fail(=%d).", ret);
190         return SOFTBUS_ENCRYPT_ERR;
191     }
192     *outLen += ENCRYPT_INDEX_LEN;
193     return SOFTBUS_OK;
194 }
195 
DecryptData(const SessionKeyList * list,const uint8_t * inData,uint32_t inLen,uint8_t * outData,uint32_t * outLen)196 int32_t DecryptData(const SessionKeyList *list, const uint8_t *inData, uint32_t inLen,
197     uint8_t *outData, uint32_t *outLen)
198 {
199     if (list == NULL || inData == NULL || outData == NULL || inLen <= ENCRYPT_OVER_HEAD_LEN ||
200         *outLen < (inLen - ENCRYPT_OVER_HEAD_LEN)) {
201         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid param.");
202         return SOFTBUS_INVALID_PARAM;
203     }
204     /* unpack key index */
205     int32_t index = (int32_t)SoftBusLtoHl(*(uint32_t *)inData);
206     SessionKey sessionKey;
207     if (GetSessionKeyByIndex(list, index, &sessionKey) != SOFTBUS_OK) {
208         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "get key fail.");
209         return SOFTBUS_DECRYPT_ERR;
210     }
211     AesGcmCipherKey cipherKey = {.keyLen = sessionKey.len};
212     if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey.value, sessionKey.len) != EOK) {
213         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "set key fail.");
214         (void)memset_s(&sessionKey, sizeof(SessionKey), 0, sizeof(SessionKey));
215         return SOFTBUS_MEM_ERR;
216     }
217     (void)memset_s(&sessionKey, sizeof(SessionKey), 0, sizeof(SessionKey));
218     int32_t ret = SoftBusDecryptDataWithSeq(&cipherKey, inData + ENCRYPT_INDEX_LEN, inLen - ENCRYPT_INDEX_LEN,
219         outData, outLen, index);
220     (void)memset_s(&cipherKey, sizeof(AesGcmCipherKey), 0, sizeof(AesGcmCipherKey));
221     if (ret != SOFTBUS_OK) {
222         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "SoftBusDecryptDataWithSeq fail(=%d).", ret);
223         return SOFTBUS_DECRYPT_ERR;
224     }
225     return SOFTBUS_OK;
226 }
227 
EncryptInner(const SessionKeyList * list,const uint8_t * inData,uint32_t inLen,uint8_t ** outData,uint32_t * outLen)228 int32_t EncryptInner(const SessionKeyList *list, const uint8_t *inData, uint32_t inLen,
229     uint8_t **outData, uint32_t *outLen)
230 {
231     if (list == NULL || inData == NULL || inLen == 0 || outData == NULL || outLen == NULL) {
232         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid param.");
233         return SOFTBUS_INVALID_PARAM;
234     }
235     uint32_t encDataLen = inLen + ENCRYPT_OVER_HEAD_LEN;
236     uint8_t *encData = (uint8_t *)SoftBusCalloc(encDataLen);
237     if (encData == NULL) {
238         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "malloc encrypt data fail.");
239         return SOFTBUS_MALLOC_ERR;
240     }
241     if (EncryptData(list, inData, inLen, encData, &encDataLen) != SOFTBUS_OK) {
242         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "encrypt data fail.");
243         SoftBusFree(encData);
244         return SOFTBUS_ENCRYPT_ERR;
245     }
246     *outData = encData;
247     *outLen = encDataLen;
248     return SOFTBUS_OK;
249 }
250 
DecryptInner(const SessionKeyList * list,const uint8_t * inData,uint32_t inLen,uint8_t ** outData,uint32_t * outLen)251 int32_t DecryptInner(const SessionKeyList *list, const uint8_t *inData, uint32_t inLen,
252     uint8_t **outData, uint32_t *outLen)
253 {
254     if (list == NULL || inData == NULL || inLen <= ENCRYPT_OVER_HEAD_LEN || outData == NULL || outLen == NULL) {
255         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid param.");
256         return SOFTBUS_INVALID_PARAM;
257     }
258     uint32_t decDataLen = inLen - ENCRYPT_OVER_HEAD_LEN + 1; /* for '\0' */
259     uint8_t *decData = (uint8_t *)SoftBusCalloc(decDataLen);
260     if (decData == NULL) {
261         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "malloc decrypt data fail.");
262         return SOFTBUS_MALLOC_ERR;
263     }
264     if (DecryptData(list, inData, inLen, decData, &decDataLen) != SOFTBUS_OK) {
265         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "decrypt data fail.");
266         SoftBusFree(decData);
267         return SOFTBUS_DECRYPT_ERR;
268     }
269     *outData = decData;
270     *outLen = decDataLen;
271     return SOFTBUS_OK;
272 }
273 
274 /* For Debug */
DumpSessionkeyList(const SessionKeyList * list)275 void DumpSessionkeyList(const SessionKeyList *list)
276 {
277     CHECK_NULL_PTR_RETURN_VOID(list);
278     uint32_t keyNum = 0;
279     SessionKeyItem *item = NULL;
280     LIST_FOR_EACH_ENTRY(item, (const ListNode *)list, SessionKeyItem, node) {
281         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_DBG,
282             "[Dump] SessionKey[%d]: {index=%d, key: {len=%u, key=XX}, lastUseTime=%"PRIu64"}",
283             keyNum, item->index, item->key.len, item->lastUseTime);
284         keyNum++;
285     }
286     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_DBG, "[Dump] SessionKey total num: %u", keyNum);
287 }
288 
HandleUpdateSessionKeyEvent(const void * obj)289 static void HandleUpdateSessionKeyEvent(const void *obj)
290 {
291     CHECK_NULL_PTR_RETURN_VOID(obj);
292     int64_t authId = *(int64_t *)(obj);
293     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO,
294         "update session key begin, authId=%" PRId64, authId);
295     AuthManager *auth = GetAuthManagerByAuthId(authId);
296     if (auth == NULL) {
297         return;
298     }
299     if (AuthSessionStartAuth(GenSeq(false), AuthGenRequestId(),
300         auth->connId, &auth->connInfo, false) != SOFTBUS_OK) {
301         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR,
302             "start auth session to update session key fail, authId=%" PRId64, authId);
303     }
304     DelAuthManager(auth, false);
305 }
306 
RmoveUpdateSessionKeyFunc(const void * obj,void * para)307 static int32_t RmoveUpdateSessionKeyFunc(const void *obj, void *para)
308 {
309     CHECK_NULL_PTR_RETURN_VALUE(obj, SOFTBUS_ERR);
310     CHECK_NULL_PTR_RETURN_VALUE(para, SOFTBUS_ERR);
311     int64_t authId = *(int64_t *)(obj);
312     if (authId == *(int64_t *)(para)) {
313         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO,
314             "remove update session key event, authId=%" PRId64, authId);
315         return SOFTBUS_OK;
316     }
317     return SOFTBUS_ERR;
318 }
319 
ScheduleUpdateSessionKey(int64_t authId,uint64_t delayMs)320 void ScheduleUpdateSessionKey(int64_t authId, uint64_t delayMs)
321 {
322     RemoveAuthEvent(EVENT_UPDATE_SESSION_KEY, RmoveUpdateSessionKeyFunc, (void *)(&authId));
323     PostAuthEvent(EVENT_UPDATE_SESSION_KEY, HandleUpdateSessionKeyEvent, &authId, sizeof(authId), delayMs);
324 }
325