• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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