• 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 "key_agree_sdk.h"
17 
18 #include "hc_log.h"
19 #include "key_agree_session.h"
20 #include "key_agree_session_manager.h"
21 #include "protocol_common.h"
22 
23 #define MIN_SHARED_SECRET_LENGTH 6
24 #define MAX_SHARED_SECRET_LENGTH 64
25 #define MIN_DEVICE_ID_LENGTH 16
26 #define MAX_DEVICE_ID_LENGTH 256
27 #define MIN_MESSAGE_LENGTH 2048
28 #define MAX_MESSAGE_LENGTH 4096
29 #define MIN_SESSIONKEY_LENGTH 64
30 #define MAX_SESSIONKEY_LENGTH 1024
31 #define MAX_EXTRAS_LENGTH 4096
32 
CheckKeyAgreeStartSessionParams(const KeyAgreeBlob * sharedSecret,const KeyAgreeBlob * deviceId,const char * extras)33 static int32_t CheckKeyAgreeStartSessionParams(const KeyAgreeBlob *sharedSecret,
34     const KeyAgreeBlob *deviceId, const char *extras)
35 {
36     if ((sharedSecret->length < MIN_SHARED_SECRET_LENGTH) || (sharedSecret->length > MAX_SHARED_SECRET_LENGTH)) {
37         LOGE("Invalid length of sharedSecret!");
38         return HC_ERR_INVALID_PARAMS;
39     }
40     if (strnlen((const char *)(sharedSecret->data), sharedSecret->length) > sharedSecret->length + 1) {
41         LOGE("Length of sharedSecret check fail!");
42         return HC_ERR_INVALID_PARAMS;
43     }
44     if ((deviceId->length < MIN_DEVICE_ID_LENGTH) || (deviceId->length > MAX_DEVICE_ID_LENGTH)) {
45         LOGE("Invalid length of deviceId!");
46         return HC_ERR_INVALID_PARAMS;
47     }
48     if (strnlen((const char *)(deviceId->data), deviceId->length) > deviceId->length + 1) {
49         LOGE("Length of deviceId check fail!");
50         return HC_ERR_INVALID_PARAMS;
51     }
52     if (((extras != NULL) && (HcStrlen(extras) > MAX_EXTRAS_LENGTH))) {
53         LOGE("Invalid length of extras!");
54         return HC_ERR_INVALID_PARAMS;
55     }
56     return HC_SUCCESS;
57 }
58 
BuildErrorMessage(KeyAgreeResult errorCode,KeyAgreeBlob * out)59 static void BuildErrorMessage(KeyAgreeResult errorCode, KeyAgreeBlob *out)
60 {
61     CJson *outJson = CreateJson();
62     if (outJson == NULL) {
63         LOGE("Create json failed!");
64         return;
65     }
66     int32_t res = AddIntToJson(outJson, FIELD_SDK_ERROR_CODE, errorCode);
67     if (res != HC_SUCCESS) {
68         LOGE("Add errorCode failed, res: %d.", res);
69         FreeJson(outJson);
70         return;
71     }
72     char *returnStr = PackJsonToString(outJson);
73     FreeJson(outJson);
74     if (returnStr == NULL) {
75         LOGE("Pack json to string failed!");
76         return;
77     }
78     uint32_t returnStrLen = HcStrlen(returnStr);
79     if (memcpy_s(out->data, out->length, returnStr, returnStrLen + 1) != EOK) {
80         LOGE("Memcpy for out json failed.");
81     }
82     out->length = returnStrLen + 1;
83     FreeJsonString(returnStr);
84 }
85 
IsErrorMessage(const KeyAgreeBlob * in)86 static bool IsErrorMessage(const KeyAgreeBlob *in)
87 {
88     int32_t errorCode;
89     CJson *inJson = CreateJsonFromString((const char *)(in->data));
90     if (inJson == NULL) {
91         LOGE("Create json failed!");
92         return true;
93     }
94     if (GetIntFromJson(inJson, FIELD_SDK_ERROR_CODE, &errorCode) != HC_SUCCESS) {
95         LOGE("There is no field named errorCode!");
96         FreeJson(inJson);
97         return true;
98     }
99     FreeJson(inJson);
100     if (errorCode != KEYAGREE_SUCCESS) {
101         LOGE("Peer is onError, errorCode: %d.!", errorCode);
102         return true;
103     }
104     return false;
105 }
106 
InitKeyAgreeStartSessionParams(SpekeSession * spekeSession,const KeyAgreeBlob * sharedSecret,const KeyAgreeBlob * deviceId,const char * extras)107 static int32_t InitKeyAgreeStartSessionParams(SpekeSession *spekeSession, const KeyAgreeBlob *sharedSecret,
108     const KeyAgreeBlob *deviceId, const char *extras)
109 {
110     int32_t res = KEYAGREE_SUCCESS;
111     do {
112         if (InitSingleParam(&(spekeSession->sharedSecret), sharedSecret->length) != HC_SUCCESS) {
113             LOGE("Init sharedSecret failed!");
114             res = KEYAGREE_START_INIT_PARAMS_SHAREDSECRET_FAIL;
115             break;
116         }
117         if (memcpy_s(spekeSession->sharedSecret.val, spekeSession->sharedSecret.length,
118             sharedSecret->data, sharedSecret->length) != HC_SUCCESS) {
119             LOGE("Memcpy for sharedSecret code failed.");
120             res = KEYAGREE_START_MEMORY_COPY_SHAREDSECRET_FAIL;
121             break;
122         }
123         if (InitSingleParam(&(spekeSession->deviceId), deviceId->length) != HC_SUCCESS) {
124             LOGE("Init deviceId failed!");
125             res = KEYAGREE_START_MEMORY_COPY_DEVID_FAIL;
126             break;
127         }
128         if (memcpy_s(spekeSession->deviceId.val, spekeSession->deviceId.length,
129             deviceId->data, deviceId->length) != HC_SUCCESS) {
130             LOGE("Memcpy for deviceId failed.");
131             res = KEYAGREE_START_MEMORY_COPY_DEVID_FAIL;
132             break;
133         }
134         if (extras != NULL) {
135             LOGI("This field named extras is not used in this version!");
136         }
137     } while (0);
138     if (res != HC_SUCCESS) {
139         FreeAndCleanKey(&spekeSession->sharedSecret);
140         FreeAndCleanKey(&spekeSession->deviceId);
141         HcFree(spekeSession->extras);
142         spekeSession->extras = NULL;
143     }
144     return res;
145 }
146 
KeyAgreeInitSession(KeyAgreeSession * session,KeyAgreeProtocol protocol,KeyAgreeType type)147 KeyAgreeResult KeyAgreeInitSession(KeyAgreeSession *session, KeyAgreeProtocol protocol, KeyAgreeType type)
148 {
149     LOGI("Key agree init begin!");
150     if (session == NULL) {
151         LOGE("Invalid input params.");
152         return KEYAGREE_INIT_BAD_PARAMS;
153     }
154     SpekeSession *spekeSession = CreateSpekeSession();
155     if (spekeSession == NULL) {
156         LOGE("Init spekeSession fail!");
157         return KEYAGREE_INIT_CREATE_SESSION_FAIL;
158     }
159     if (spekeSession->checkAndInitProtocol(spekeSession, protocol) != HC_SUCCESS) {
160         LOGE("This protocol is not supported!");
161         DestroySpekeSession(spekeSession);
162         return KEYAGREE_INIT_NOT_SUPPORTED;
163     }
164     spekeSession->sessionId = session->sessionId;
165     spekeSession->protocol = protocol;
166     spekeSession->keyAgreeType = type;
167     if (protocol != KEYAGREE_PROTOCOL_ANY) {
168         spekeSession->versionInfo.versionStatus = VERSION_DECIDED;
169         if (spekeSession->initSpekeSession(spekeSession, protocol) != HC_SUCCESS) {
170             LOGE("Init protocol session fail!");
171             DestroySpekeSession(spekeSession);
172             return KEYAGREE_INIT_INIT_SESSION_FAIL;
173         }
174     } else {
175         if (type == KEYAGREE_TYPE_CLIENT) {
176             spekeSession->versionInfo.versionStatus = INITIAL;
177         } else {
178             spekeSession->versionInfo.versionStatus = VERSION_CONFIRM;
179         }
180     }
181     if (GetManagerInstance()->addSession(session, spekeSession) != HC_SUCCESS) {
182         LOGE("Add session fail!");
183         DestroySpekeSession(spekeSession);
184         return KEYAGREE_INIT_ADD_SESSION_FAIL;
185     }
186     LOGI("Init keyAgree session successfully!");
187     return KEYAGREE_SUCCESS;
188 }
189 
KeyAgreeStartSession(KeyAgreeSession * session,const KeyAgreeBlob * sharedSecret,const KeyAgreeBlob * deviceId,const char * extras)190 KeyAgreeResult KeyAgreeStartSession(KeyAgreeSession *session, const KeyAgreeBlob *sharedSecret,
191     const KeyAgreeBlob *deviceId, const char *extras)
192 {
193     LOGI("Key agree start session begin!");
194     if ((sharedSecret == NULL) || (deviceId == NULL) || (session == NULL)) {
195         LOGE("Invalid input params.");
196         return KEYAGREE_START_BAD_PARAMS;
197     }
198     if (CheckKeyAgreeStartSessionParams(sharedSecret, deviceId, extras) != HC_SUCCESS) {
199         LOGE("Invalid input length!");
200         return KEYAGREE_START_INVAILD_LEN;
201     }
202     SpekeSession *spekeSession = GetManagerInstance()->getSession(session);
203     if (spekeSession == NULL) {
204         LOGE("GetSession fail!");
205         return KEYAGREE_START_GET_SESSION_FAIL;
206     }
207     int32_t res = InitKeyAgreeStartSessionParams(spekeSession, sharedSecret, deviceId, extras);
208     if (res != HC_SUCCESS) {
209         LOGE("Init params fail!");
210         return res;
211     }
212     LOGI("KeyAgree start successfully!");
213     return res;
214 }
215 
KeyAgreeGenerateNextMessage(KeyAgreeSession * session,const KeyAgreeBlob * messageReceived,KeyAgreeBlob * messageToTransmit)216 KeyAgreeResult KeyAgreeGenerateNextMessage(KeyAgreeSession *session, const KeyAgreeBlob *messageReceived,
217     KeyAgreeBlob *messageToTransmit)
218 {
219     LOGI("Key agree generate next message begin!");
220     if ((session == NULL) || (messageToTransmit == NULL)) {
221         LOGE("Invalid session or messageToTransmit!");
222         return KEYAGREE_PROCESS_BAD_PARAMS;
223     }
224     if ((messageToTransmit->length < MIN_MESSAGE_LENGTH) || (messageToTransmit->length > MAX_MESSAGE_LENGTH)) {
225         LOGE("Invalid length of messageToTransmit!");
226         return KEYAGREE_PROCESS_INVAILD_LEN;
227     }
228     if (messageReceived != NULL && messageReceived->data != NULL &&
229         strnlen((const char *)(messageReceived->data), messageReceived->length) > messageReceived->length  + 1) {
230         LOGE("Length of messageToTransmit check fail!");
231         return KEYAGREE_PROCESS_INVAILD_LEN;
232     }
233     if (messageReceived != NULL && messageReceived->data != NULL && IsErrorMessage(messageReceived)) {
234         LOGE("Peer is onError!");
235         return KEYAGREE_PROCESS_PEER_IS_ONERROR;
236     }
237     SpekeSession *spekeSession = GetManagerInstance()->getSession(session);
238     if (spekeSession == NULL) {
239         LOGE("GetSession fail!");
240         return KEYAGREE_PROCESS_GET_SESSION_FAIL;
241     }
242     if ((messageReceived == NULL) && (spekeSession->step != STEP_INIT)) {
243         LOGE("This is not first step, messageReceived is null!");
244         return KEYAGREE_PROCESS_BAD_PARAMS;
245     }
246     if (spekeSession->versionInfo.versionStatus != VERSION_DECIDED) {
247         LOGI("Protocol is not decided, need protocol agree!");
248         if (spekeSession->processProtocolAgree(spekeSession, messageReceived, messageToTransmit) != HC_SUCCESS) {
249             LOGE("Protocol agree fail!");
250             BuildErrorMessage(KEYAGREE_FAIL, messageToTransmit);
251             return KEYAGREE_PROCESS_PROTOCOL_AGREE_FAIL;
252         }
253     } else {
254         LOGI("Protocol decided, process key agree!");
255         if (spekeSession->processSession(spekeSession, messageReceived, messageToTransmit) != HC_SUCCESS) {
256             LOGE("Protocol agree fail!");
257             BuildErrorMessage(KEYAGREE_FAIL, messageToTransmit);
258             return KEYAGREE_PROCESS_PROTOCOL_SESSION_FAIL;
259         }
260     }
261     LOGI("KeyAgree generate next message successfully!");
262     return KEYAGREE_SUCCESS;
263 }
264 
KeyAgreeIsFinish(KeyAgreeSession * session)265 KeyAgreeResult KeyAgreeIsFinish(KeyAgreeSession *session)
266 {
267     LOGI("Key agree is finish start!");
268     if (session == NULL) {
269         LOGE("Invalid input params.");
270         return KEYAGREE_IS_FINSIH_BAD_PARAMS;
271     }
272     KeyAgreeSessionManager *sessionManager = GetManagerInstance();
273     if (sessionManager == NULL) {
274         LOGE("Get session mgr fail!");
275         return KEYAGREE_IS_FINSIH_GET_SESSION_MGR_FAIL;
276     }
277     SpekeSession *spekeSession = sessionManager->getSession(session);
278     if (spekeSession == NULL) {
279         LOGE("GetSession fail!");
280         return KEYAGREE_IS_FINSIH_GET_SESSION_FAIL;
281     }
282     if (!spekeSession->isFinish) {
283         LOGE("Keg agree is not finish!");
284         return KEYAGREE_IS_FINSIH_NOT_FINSIH;
285     }
286     LOGI("Keg agree is finish!");
287     return KEYAGREE_SUCCESS;
288 }
289 
KeyAgreeGetResult(KeyAgreeSession * session,KeyAgreeBlob * sessionKey)290 KeyAgreeResult KeyAgreeGetResult(KeyAgreeSession *session, KeyAgreeBlob *sessionKey)
291 {
292     LOGI("Key agree get result start!");
293     if ((session == NULL) || (sessionKey == NULL)) {
294         LOGE("Invalid session or sessionKey!");
295         return KEYAGREE_GET_RESULT_BAD_PARAMS;
296     }
297     if ((sessionKey->length < MIN_SESSIONKEY_LENGTH) || (sessionKey->length > MAX_SESSIONKEY_LENGTH)) {
298         LOGE("Invalid length of sessionKey!");
299         return KEYAGREE_GET_RESULT_INVAILD_LEN;
300     }
301     KeyAgreeSessionManager *sessionManager = GetManagerInstance();
302     if (sessionManager == NULL) {
303         LOGE("Get session mgr fail!");
304         return KEYAGREE_GET_RESULT_GET_SESSION_MGR_FAIL;
305     }
306     SpekeSession *spekeSession = sessionManager->getSession(session);
307     if (spekeSession == NULL) {
308         LOGE("GetSession fail!");
309         return KEYAGREE_GET_RESULT_GET_SESSION_FAIL;
310     }
311     if (!spekeSession->isFinish) {
312         LOGE("Keg agree is not finish, sessionKey is not generate!");
313         return KEYAGREE_GET_RESULT_NOT_FINSIH;
314     }
315     if (memcpy_s(sessionKey->data, spekeSession->baseParam.sessionKey.length + 1,
316         spekeSession->baseParam.sessionKey.val, spekeSession->baseParam.sessionKey.length + 1) != EOK) {
317         LOGE("Memcpy for seesionKey failed.");
318         return KEYAGREE_GET_RESULT_MEMCPY_FAILED;
319     }
320     sessionKey->length = spekeSession->baseParam.sessionKey.length;
321     LOGI("Keg agree is finish, return seesionKey.");
322     return KEYAGREE_SUCCESS;
323 }
324 
KeyAgreeFreeSession(KeyAgreeSession * session)325 void KeyAgreeFreeSession(KeyAgreeSession *session)
326 {
327     LOGI("Key agree free session start!");
328     if (session == NULL) {
329         LOGE("Invalid params!");
330         return;
331     }
332     KeyAgreeSessionManager *sessionManager = GetManagerInstance();
333     if (sessionManager == NULL) {
334         LOGE("Get session mgr fail!");
335         return;
336     }
337     SpekeSession *spekeSession = sessionManager->getSession(session);
338     if (spekeSession == NULL) {
339         LOGE("GetSession fail!");
340         return;
341     }
342     if (sessionManager == NULL || sessionManager->deleteSession(session) != HC_SUCCESS) {
343         LOGE("Delete session fail!");
344         return;
345     }
346     DestroySpekeSession(spekeSession);
347 }