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_session.h"
17
18 #include "hc_log.h"
19 #include "key_agree_sdk.h"
20 #include "pake_v2_protocol_common.h"
21 #include "protocol_common.h"
22
23 #define MAX_AUTH_ID_LEN 256
24 #define MAJOR_VERSION_NO 1
25 #define TMP_VERSION_STR_LEN 30
26 #define DEC 10
27 #define MIN_SHAREDSECRET_LEN 4
28 #define MAX_SHAREDSECRET_LEN 1024
29
30 typedef int32_t (*PackageExtraData)(const PakeBaseParams *baseParams, CJson *payload);
31
32 const static ProtocolPrimeMod g_protocolAlgorithm[] = {
33 EC_SPEKE_X25519,
34 EC_SPEKE_P256,
35 DL_SPEKE_MOD_384,
36 DL_SPEKE_MOD_256
37 };
38
39 const static KeyAgreeProtocol g_keyAgreeProtocol[] = {
40 KEYAGREE_PROTOCOL_EC_SPEKE_X25519,
41 KEYAGREE_PROTOCOL_EC_SPEKE_P256,
42 KEYAGREE_PROTOCOL_DL_SPEKE_384,
43 KEYAGREE_PROTOCOL_DL_SPEKE_256
44 };
45
46 VersionStruct g_defaultVersion = { 1, 0, 0 };
47
GetIdPeer(const CJson * in,const char * peerIdKey,const Uint8Buff * authIdSelf,Uint8Buff * authIdPeer)48 static int32_t GetIdPeer(const CJson *in, const char *peerIdKey, const Uint8Buff *authIdSelf, Uint8Buff *authIdPeer)
49 {
50 const char *authIdStr = GetStringFromJson(in, peerIdKey);
51 if (authIdStr == NULL) {
52 LOGE("Get peer id from json failed.");
53 return HC_ERR_JSON_GET;
54 }
55 uint32_t authIdLen = HcStrlen(authIdStr) / BYTE_TO_HEX_OPER_LENGTH;
56 if (authIdLen == 0 || authIdLen > MAX_AUTH_ID_LEN) {
57 LOGE("Invalid authIdPeerLen: %u.", authIdLen);
58 return HC_ERR_INVALID_LEN;
59 }
60 int32_t res = InitSingleParam(authIdPeer, authIdLen);
61 if (res != HC_SUCCESS) {
62 LOGE("InitSingleParam for peer authId failed, res: %d.", res);
63 return res;
64 }
65 if (HexStringToByte(authIdStr, authIdPeer->val, authIdPeer->length) != HC_SUCCESS) {
66 LOGE("HexStringToByte for authIdPeer failed.");
67 return HC_ERR_CONVERT_FAILED;
68 }
69 if ((authIdSelf->length == authIdPeer->length) &&
70 memcmp(authIdSelf->val, authIdPeer->val, authIdSelf->length) == 0) {
71 LOGE("Peer id can not be equal to self id.");
72 return HC_ERR_INVALID_PARAMS;
73 }
74 return HC_SUCCESS;
75 }
76
GetKeyAgreeSdkPakeAlgInProtocol()77 static uint64_t GetKeyAgreeSdkPakeAlgInProtocol()
78 {
79 uint64_t algInProtocol = SPEKE_MOD_NONE;
80 #ifdef P2P_PAKE_DL_PRIME_LEN_256
81 algInProtocol |= DL_SPEKE_MOD_256;
82 #endif
83 #ifdef P2P_PAKE_DL_PRIME_LEN_384
84 algInProtocol |= DL_SPEKE_MOD_384;
85 #endif
86 #ifdef P2P_PAKE_EC_PRIME_P256
87 algInProtocol |= EC_SPEKE_P256;
88 #endif
89 #ifdef P2P_PAKE_EC_PRIME_X25519
90 algInProtocol |= EC_SPEKE_X25519;
91 #endif
92 return algInProtocol;
93 }
94
GetSlice(char * str,char delim,int32_t * nextIdx)95 static const char *GetSlice(char *str, char delim, int32_t *nextIdx)
96 {
97 if (str == NULL) {
98 LOGE("Input str is NULL!");
99 return str;
100 }
101 uint32_t len = HcStrlen(str);
102 for (uint32_t i = 0; i < len; i++) {
103 if (str[i] == delim) {
104 *nextIdx = *nextIdx + i + 1;
105 str[i] = '\0';
106 return str;
107 }
108 }
109 return str;
110 }
111
IsVersionEqual(VersionStruct * src,VersionStruct * des)112 static bool IsVersionEqual(VersionStruct *src, VersionStruct *des)
113 {
114 if ((src->first == des->first) && (src->second == des->second) && (src->third == des->third)) {
115 return true;
116 }
117 return false;
118 }
119
StringToVersion(const char * verStr,VersionStruct * version)120 static int32_t StringToVersion(const char* verStr, VersionStruct* version)
121 {
122 CHECK_PTR_RETURN_ERROR_CODE(version, "version");
123 CHECK_PTR_RETURN_ERROR_CODE(verStr, "verStr");
124
125 const char *subVer = NULL;
126 int32_t nextIdx = 0;
127 uint64_t len = HcStrlen(verStr);
128 char *verStrTmp = (char *)HcMalloc(len + 1, 0);
129 if (verStrTmp == NULL) {
130 LOGE("Malloc for verStrTmp failed.");
131 return HC_ERR_ALLOC_MEMORY;
132 }
133 if (memcpy_s(verStrTmp, len + 1, verStr, len) != EOK) {
134 LOGE("Memcpy for verStrTmp failed.");
135 HcFree(verStrTmp);
136 return HC_ERR_MEMORY_COPY;
137 }
138 subVer = GetSlice(verStrTmp, '.', &nextIdx);
139 if (subVer == NULL) {
140 goto CLEAN_UP;
141 }
142 version->first = (uint64_t)strtoul(subVer, NULL, DEC);
143 subVer = GetSlice(verStrTmp + nextIdx, '.', &nextIdx);
144 if (subVer == NULL) {
145 goto CLEAN_UP;
146 }
147 version->second = (uint64_t)strtoul(subVer, NULL, DEC);
148 subVer = GetSlice(verStrTmp + nextIdx, '.', &nextIdx);
149 if (subVer == NULL) {
150 goto CLEAN_UP;
151 }
152 version->third = (uint64_t)strtoul(subVer, NULL, DEC);
153 HcFree(verStrTmp);
154 return HC_SUCCESS;
155 CLEAN_UP:
156 LOGE("GetSlice failed.");
157 HcFree(verStrTmp);
158 return HC_ERROR;
159 }
160
VersionToString(const VersionStruct * version,char * verStr,uint32_t len)161 static int32_t VersionToString(const VersionStruct *version, char *verStr, uint32_t len)
162 {
163 CHECK_PTR_RETURN_ERROR_CODE(version, "version");
164 CHECK_PTR_RETURN_ERROR_CODE(verStr, "verStr");
165
166 char tmpStr[TMP_VERSION_STR_LEN] = { 0 };
167 if (sprintf_s(tmpStr, TMP_VERSION_STR_LEN, "%lld.%lld.%lld",
168 version->first, version->second, version->third) <= 0) {
169 LOGE("Convert version struct to string failed.");
170 return HC_ERR_CONVERT_FAILED;
171 }
172 uint32_t tmpStrLen = HcStrlen(tmpStr);
173 if (len < tmpStrLen + 1) {
174 LOGE("The length of verStr is too short, len: %u.", len);
175 return HC_ERR_INVALID_LEN;
176 }
177 if (memcpy_s(verStr, len, tmpStr, tmpStrLen + 1) != 0) {
178 LOGE("Memcpy for verStr failed.");
179 return HC_ERR_MEMORY_COPY;
180 }
181 return HC_SUCCESS;
182 }
183
GetMaxVersion(uint64_t algInProtocol,VersionStruct * version)184 void GetMaxVersion(uint64_t algInProtocol, VersionStruct *version)
185 {
186 version->first = MAJOR_VERSION_NO;
187 version->second = algInProtocol;
188 version->third = 0;
189 }
190
AddVersionToJson(CJson * jsonObj,const VersionStruct * maxVer)191 int32_t AddVersionToJson(CJson *jsonObj, const VersionStruct *maxVer)
192 {
193 CHECK_PTR_RETURN_ERROR_CODE(jsonObj, "jsonObj");
194 CHECK_PTR_RETURN_ERROR_CODE(maxVer, "maxVer");
195
196 char maxStr[TMP_VERSION_STR_LEN] = { 0 };
197 int32_t maxRet = VersionToString(maxVer, maxStr, TMP_VERSION_STR_LEN);
198 if (maxRet != HC_SUCCESS) {
199 LOGE("MaxRet for version to string failed.");
200 return HC_ERROR;
201 }
202 CJson* version = CreateJson();
203 if (version == NULL) {
204 LOGE("CreateJson for version failed.");
205 return HC_ERR_JSON_CREATE;
206 }
207 if (AddStringToJson(version, FIELD_SDK_CURRENT_VERSION, maxStr) != HC_SUCCESS) {
208 LOGE("Add max version to json failed.");
209 FreeJson(version);
210 return HC_ERR_JSON_ADD;
211 }
212 if (AddObjToJson(jsonObj, FIELD_SDK_VERSION, version) != HC_SUCCESS) {
213 LOGE("Add version object to json failed.");
214 FreeJson(version);
215 return HC_ERR_JSON_ADD;
216 }
217 FreeJson(version);
218 return HC_SUCCESS;
219 }
220
GetVersionFromJson(const CJson * jsonObj,VersionStruct * maxVer)221 int32_t GetVersionFromJson(const CJson* jsonObj, VersionStruct *maxVer)
222 {
223 CHECK_PTR_RETURN_ERROR_CODE(jsonObj, "jsonObj");
224 CHECK_PTR_RETURN_ERROR_CODE(maxVer, "maxVer");
225
226 const char *maxStr = GetStringFromJson(jsonObj, FIELD_SDK_CURRENT_VERSION);
227 CHECK_PTR_RETURN_ERROR_CODE(maxStr, "maxStr");
228
229 int32_t maxRet = StringToVersion(maxStr, maxVer);
230 if (maxRet != HC_SUCCESS) {
231 LOGE("Convert version string to struct failed.ionInfo");
232 return HC_ERROR;
233 }
234 return HC_SUCCESS;
235 }
236
NegotiateVersion(VersionStruct * curVersionPeer,VersionStruct * curVersionSelf)237 int32_t NegotiateVersion(VersionStruct *curVersionPeer, VersionStruct *curVersionSelf)
238 {
239 if (IsVersionEqual(curVersionPeer, &g_defaultVersion)) {
240 curVersionSelf->first = g_defaultVersion.first;
241 curVersionSelf->second = g_defaultVersion.second;
242 curVersionSelf->third = g_defaultVersion.third;
243 return HC_SUCCESS;
244 }
245 curVersionSelf->second = curVersionSelf->second & curVersionPeer->second;
246 if (curVersionSelf->second == 0) {
247 LOGE("Unsupported version!");
248 return HC_ERR_UNSUPPORTED_VERSION;
249 }
250 return HC_SUCCESS;
251 }
252
InitVersionInfo(VersionInfo * versionInfo)253 void InitVersionInfo(VersionInfo *versionInfo)
254 {
255 uint64_t algInProtocol = GetKeyAgreeSdkPakeAlgInProtocol();
256 GetMaxVersion(algInProtocol, &(versionInfo->curVersion));
257 versionInfo->versionStatus = INITIAL;
258 }
259
GetAuthIdPeerFromPayload(const CJson * in,const Uint8Buff * authIdSelf,Uint8Buff * authIdPeer)260 int32_t GetAuthIdPeerFromPayload(const CJson *in, const Uint8Buff *authIdSelf, Uint8Buff *authIdPeer)
261 {
262 const CJson *payload = GetObjFromJson(in, FIELD_SDK_PAYLOAD);
263 if (payload == NULL) {
264 LOGE("Not have payload.");
265 return HC_ERR_JSON_GET;
266 }
267 int32_t res = GetIdPeer(payload, FIELD_PEER_AUTH_ID, authIdSelf, authIdPeer);
268 if (res != HC_SUCCESS) {
269 LOGE("GetIdPeer failed, res: %d.", res);
270 }
271 return res;
272 }
273
ParsePakeServerConfirmMessage(PakeBaseParams * baseParams,const CJson * in)274 static int32_t ParsePakeServerConfirmMessage(PakeBaseParams *baseParams, const CJson *in)
275 {
276 int32_t res = GetByteFromJson(in, FIELD_KCF_DATA, baseParams->kcfDataPeer.val,
277 baseParams->kcfDataPeer.length);
278 if (res != HC_SUCCESS) {
279 LOGE("Get kcfDataPeer failed, res: %d.", res);
280 return HC_ERR_JSON_GET;
281 }
282 return HC_SUCCESS;
283 }
284
PackagePakeServerConfirmData(const PakeBaseParams * baseParams,CJson * payload)285 static int32_t PackagePakeServerConfirmData(const PakeBaseParams *baseParams, CJson *payload)
286 {
287 int32_t res = AddByteToJson(payload, FIELD_KCF_DATA, baseParams->kcfData.val, baseParams->kcfData.length);
288 if (res != HC_SUCCESS) {
289 LOGE("Add kcfData failed, res: %d.", res);
290 return HC_ERR_JSON_ADD;
291 }
292 return HC_SUCCESS;
293 }
294
GetDasEpkPeerFromJson(PakeBaseParams * baseParams,const CJson * in)295 static int32_t GetDasEpkPeerFromJson(PakeBaseParams *baseParams, const CJson *in)
296 {
297 const char *epkPeerHex = GetStringFromJson(in, FIELD_EPK);
298 if (epkPeerHex == NULL) {
299 LOGE("Get epkPeerHex failed.");
300 return HC_ERR_JSON_GET;
301 }
302 int32_t res = InitSingleParam(&(baseParams->epkPeer), HcStrlen(epkPeerHex) / BYTE_TO_HEX_OPER_LENGTH);
303 if (res != HC_SUCCESS) {
304 LOGE("InitSingleParam for epkPeer failed, res: %d.", res);
305 return res;
306 }
307 res = HexStringToByte(epkPeerHex, baseParams->epkPeer.val, baseParams->epkPeer.length);
308 if (res != HC_SUCCESS) {
309 LOGE("Convert epkPeer from hex string to byte failed, res: %d.", res);
310 return HC_ERR_CONVERT_FAILED;
311 }
312 return HC_SUCCESS;
313 }
314
ParsePakeClientConfirmMessage(PakeBaseParams * baseParams,const CJson * in)315 static int32_t ParsePakeClientConfirmMessage(PakeBaseParams *baseParams, const CJson *in)
316 {
317 int32_t res = GetByteFromJson(in, FIELD_KCF_DATA, baseParams->kcfDataPeer.val, baseParams->kcfDataPeer.length);
318 if (res != HC_SUCCESS) {
319 LOGE("Get kcfDataPeer failed, res: %d.", res);
320 return HC_ERR_JSON_GET;
321 }
322 res = GetDasEpkPeerFromJson(baseParams, in);
323 if (res != HC_SUCCESS) {
324 LOGE("GetDasEpkPeerFromJson failed, res: %d.", res);
325 }
326 return res;
327 }
328
PackagePakeClientConfirmData(const PakeBaseParams * baseParams,CJson * payload)329 static int32_t PackagePakeClientConfirmData(const PakeBaseParams *baseParams, CJson *payload)
330 {
331 int32_t res = AddByteToJson(payload, FIELD_EPK, baseParams->epkSelf.val, baseParams->epkSelf.length);
332 if (res != HC_SUCCESS) {
333 LOGE("Add epkSelf failed, res: %d.", res);
334 return HC_ERR_JSON_ADD;
335 }
336 res = AddByteToJson(payload, FIELD_KCF_DATA, baseParams->kcfData.val, baseParams->kcfData.length);
337 if (res != HC_SUCCESS) {
338 LOGE("Add kcfData failed, res: %d.", res);
339 return HC_ERR_JSON_ADD;
340 }
341 res = AddByteToJson(payload, FIELD_PEER_AUTH_ID, baseParams->idSelf.val, baseParams->idSelf.length);
342 if (res != HC_SUCCESS) {
343 LOGE("Add idSelf failed, res: %d.", res);
344 return HC_ERR_JSON_ADD;
345 }
346 return HC_SUCCESS;
347 }
348
ParsePakeResponseMessage(PakeBaseParams * baseParams,const CJson * in)349 static int32_t ParsePakeResponseMessage(PakeBaseParams *baseParams, const CJson *in)
350 {
351 int32_t res = GetByteFromJson(in, FIELD_SALT, baseParams->salt.val, baseParams->salt.length);
352 if (res != HC_SUCCESS) {
353 LOGE("Get salt failed, res: %d.", res);
354 return HC_ERR_JSON_GET;
355 }
356 res = GetDasEpkPeerFromJson(baseParams, in);
357 if (res != HC_SUCCESS) {
358 LOGE("GetDasEpkPeerFromJson failed, res: %d.", res);
359 }
360 return res;
361 }
362
FillExtraData(SpekeSession * spekeSession,const CJson * jsonMessage)363 static int32_t FillExtraData(SpekeSession *spekeSession, const CJson *jsonMessage)
364 {
365 const CJson *version = GetObjFromJson(jsonMessage, FIELD_SDK_VERSION);
366 if (version == NULL) {
367 LOGE("Get version from json failed.");
368 return HC_ERR_JSON_GET;
369 }
370 char *versionStr = PackJsonToString(version);
371 if (versionStr == NULL) {
372 LOGE("Pack json to versionStr failed.");
373 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
374 }
375 uint32_t versionStrLength = HcStrlen(versionStr) + 1;
376 int32_t res = HC_SUCCESS;
377 do {
378 res = InitSingleParam(&(spekeSession->baseParam.extraData), versionStrLength);
379 if (res != HC_SUCCESS) {
380 LOGE("InitSingleParam for extraData failed, res: %d.", res);
381 break;
382 }
383 res = memcpy_s(spekeSession->baseParam.extraData.val, spekeSession->baseParam.extraData.length,
384 versionStr, versionStrLength);
385 if (res != HC_SUCCESS) {
386 LOGE("Memcpy for extraData failed.");
387 HcFree(spekeSession->baseParam.extraData.val);
388 spekeSession->baseParam.extraData.val = NULL;
389 break;
390 }
391 } while (0);
392 FreeJsonString(versionStr);
393 return res;
394 }
395
FillPskAndDeviceId(SpekeSession * spekeSession)396 static int32_t FillPskAndDeviceId(SpekeSession *spekeSession)
397 {
398 if (spekeSession->sharedSecret.length < MIN_SHAREDSECRET_LEN ||
399 spekeSession->sharedSecret.length > MAX_SHAREDSECRET_LEN) {
400 LOGE("sharedSecret len is invalid.");
401 return HC_ERR_INVALID_LEN;
402 }
403
404 int32_t res = InitSingleParam(&(spekeSession->baseParam.psk), spekeSession->sharedSecret.length);
405 if (res != HC_SUCCESS) {
406 LOGE("InitSingleParam for psk failed, res: %d.", res);
407 return res;
408 }
409 if (memcpy_s(spekeSession->baseParam.psk.val, spekeSession->baseParam.psk.length,
410 spekeSession->sharedSecret.val, spekeSession->sharedSecret.length) != HC_SUCCESS) {
411 LOGE("Memcpy for psk failed.");
412 FreeAndCleanKey(&spekeSession->baseParam.psk);
413 return HC_ERR_MEMORY_COPY;
414 }
415
416 res = InitSingleParam(&(spekeSession->baseParam.idSelf), spekeSession->deviceId.length);
417 if (res != HC_SUCCESS) {
418 LOGE("InitSingleParam for idSelf failed, res: %d.", res);
419 FreeAndCleanKey(&spekeSession->baseParam.psk);
420 return res;
421 }
422 if (memcpy_s(spekeSession->baseParam.idSelf.val, spekeSession->baseParam.idSelf.length,
423 spekeSession->deviceId.val, spekeSession->deviceId.length) != HC_SUCCESS) {
424 LOGE("Memcpy for idSelf failed.");
425 FreeAndCleanKey(&spekeSession->baseParam.psk);
426 FreeAndCleanKey(&spekeSession->baseParam.idSelf);
427 return HC_ERR_MEMORY_COPY;
428 }
429 return HC_SUCCESS;
430 }
431
ConstructOutJson(CJson * out)432 static int32_t ConstructOutJson(CJson *out)
433 {
434 int32_t res;
435 CJson *payload = NULL;
436 CJson *sendToPeer = NULL;
437 do {
438 payload = CreateJson();
439 if (payload == NULL) {
440 LOGE("Create payload json failed.");
441 res = HC_ERR_JSON_CREATE;
442 break;
443 }
444 sendToPeer = CreateJson();
445 if (sendToPeer == NULL) {
446 LOGE("Create sendToPeer json failed.");
447 res = HC_ERR_JSON_CREATE;
448 break;
449 }
450 res = AddObjToJson(sendToPeer, FIELD_SDK_PAYLOAD, payload);
451 if (res != HC_SUCCESS) {
452 LOGE("Add payload to sendToPeer failed, res: %d.", res);
453 break;
454 }
455 res = AddObjToJson(out, FIELD_SDK_SEND_TO_PEER, sendToPeer);
456 if (res != HC_SUCCESS) {
457 LOGE("Add sendToPeer to out failed, res: %d.", res);
458 break;
459 }
460 } while (0);
461 FreeJson(payload);
462 FreeJson(sendToPeer);
463 return res;
464 }
465
PackagePakeResponseData(const PakeBaseParams * baseParams,CJson * payload)466 static int32_t PackagePakeResponseData(const PakeBaseParams *baseParams, CJson *payload)
467 {
468 int32_t res = AddByteToJson(payload, FIELD_SALT, baseParams->salt.val, baseParams->salt.length);
469 if (res != HC_SUCCESS) {
470 LOGE("Add salt failed, res: %d.", res);
471 return HC_ERR_JSON_ADD;
472 }
473 res = AddByteToJson(payload, FIELD_EPK, baseParams->epkSelf.val, baseParams->epkSelf.length);
474 if (res != HC_SUCCESS) {
475 LOGE("Add epkSelf failed, res: %d.", res);
476 return HC_ERR_JSON_ADD;
477 }
478 res = AddByteToJson(payload, FIELD_PEER_AUTH_ID, baseParams->idSelf.val, baseParams->idSelf.length);
479 if (res != HC_SUCCESS) {
480 LOGE("Add idSelf failed, res: %d.", res);
481 return res;
482 }
483 return HC_SUCCESS;
484 }
485
PackageMsgForPakeResponse(SpekeSession * spekeSession,CJson * outJson,PackageExtraData packageExtraData)486 static int32_t PackageMsgForPakeResponse(SpekeSession *spekeSession, CJson *outJson, PackageExtraData packageExtraData)
487 {
488 int32_t res = ConstructOutJson(outJson);
489 if (res != HC_SUCCESS) {
490 LOGE("ConstructOutJson failed, res: %d.", res);
491 return res;
492 }
493 CJson *payload = GetObjFromJson(outJson, FIELD_SDK_PAYLOAD);
494 if (payload == NULL) {
495 LOGE("Get payload from json failed.");
496 return HC_ERR_JSON_GET;
497 }
498 res = (*packageExtraData)(&spekeSession->baseParam, payload);
499 if (res != HC_SUCCESS) {
500 LOGE("PackagePakeResponseData failed, res: %d.", res);
501 return res;
502 }
503 res = AddIntToJson(payload, FIELD_SDK_STEP, spekeSession->step);
504 if (res != HC_SUCCESS) {
505 LOGE("Add step failed, res: %d.", res);
506 return res;
507 }
508 res = AddIntToJson(outJson, FIELD_SDK_ERROR_CODE, KEYAGREE_SUCCESS);
509 if (res != HC_SUCCESS) {
510 LOGE("Add errorCode failed, res: %d.", res);
511 return res;
512 }
513 res = AddVersionToJson(outJson, &(spekeSession->versionInfo.curVersion));
514 if (res != HC_SUCCESS) {
515 LOGE("AddVersionToOut failed, res: %d.", res);
516 return res;
517 }
518 return res;
519 }
520
BuildAndPutOutMessage(SpekeSession * spekeSession,KeyAgreeBlob * out,PackageExtraData packageExtraData)521 static int32_t BuildAndPutOutMessage(SpekeSession *spekeSession, KeyAgreeBlob *out, PackageExtraData packageExtraData)
522 {
523 CJson *outJson = CreateJson();
524 if (outJson == NULL) {
525 LOGE("Create outJson failed.");
526 return HC_ERR_JSON_CREATE;
527 }
528 int32_t res = PackageMsgForPakeResponse(spekeSession, outJson, packageExtraData);
529 if (res != HC_SUCCESS) {
530 LOGE("PackageMsgForResponse failed, res: %d.", res);
531 FreeJson(outJson);
532 return res;
533 }
534 char *returnStr = PackJsonToString(outJson);
535 FreeJson(outJson);
536 if (returnStr == NULL) {
537 LOGE("Pack json to string failed.");
538 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
539 }
540 uint32_t returnStrLen = HcStrlen(returnStr);
541 if (memcpy_s(out->data, out->length, returnStr, returnStrLen + 1) != EOK) {
542 LOGE("Memcpy for out blob failed.");
543 FreeJsonString(returnStr);
544 return HC_ERR_MEMORY_COPY;
545 }
546 out->length = returnStrLen + 1;
547 FreeJsonString(returnStr);
548 return HC_SUCCESS;
549 }
550
PakeResponse(SpekeSession * spekeSession,KeyAgreeBlob * out)551 static int32_t PakeResponse(SpekeSession *spekeSession, KeyAgreeBlob *out)
552 {
553 spekeSession->baseParam.isClient = false;
554 int32_t res = FillPskAndDeviceId(spekeSession);
555 if (res != HC_SUCCESS) {
556 LOGE("FillPskAndDeviceId failed, res: %d.", res);
557 return res;
558 }
559 res = ServerResponsePakeV2Protocol(&spekeSession->baseParam);
560 if (res != HC_SUCCESS) {
561 LOGE("ServerResponsePakeV2Protocol failed, res:%d", res);
562 return res;
563 }
564 res = BuildAndPutOutMessage(spekeSession, out, PackagePakeResponseData);
565 if (res != HC_SUCCESS) {
566 LOGE("BuildAndPutOutMessage failed, res:%d", res);
567 return res;
568 }
569 return res;
570 }
571
CheckPeerProtocolVersion(SpekeSession * spekeSession,CJson * inParams)572 static int32_t CheckPeerProtocolVersion(SpekeSession *spekeSession, CJson *inParams)
573 {
574 VersionStruct curVersionPeer = { 0, 0, 0 };
575 int32_t res = GetVersionFromJson(inParams, &curVersionPeer);
576 if (res != HC_SUCCESS) {
577 LOGE("Get peer version info failed, res: %d.", res);
578 return res;
579 }
580 res = NegotiateVersion(&curVersionPeer, &(spekeSession->versionInfo.curVersion));
581 if (res != HC_SUCCESS) {
582 LOGE("NegotiateVersion failed, res: %d.", res);
583 return res;
584 }
585 return HC_SUCCESS;
586 }
587
PakeConfirm(SpekeSession * spekeSession,CJson * inParams,KeyAgreeBlob * out)588 static int32_t PakeConfirm(SpekeSession *spekeSession, CJson *inParams, KeyAgreeBlob *out)
589 {
590 int32_t res = CheckPeerProtocolVersion(spekeSession, inParams);
591 if (res != HC_SUCCESS) {
592 LOGE("Peer protocol is not supported!");
593 return res;
594 }
595 spekeSession->baseParam.isClient = true;
596 res = FillPskAndDeviceId(spekeSession);
597 if (res != HC_SUCCESS) {
598 LOGE("FillPskAndDeviceId failed, res: %d.", res);
599 return res;
600 }
601 res = GetAuthIdPeerFromPayload(inParams, &(spekeSession->baseParam.idSelf), &(spekeSession->baseParam.idPeer));
602 if (res != HC_SUCCESS) {
603 LOGE("Get peer authId failed, res: %d.", res);
604 return res;
605 }
606 res = ParsePakeResponseMessage(&(spekeSession->baseParam), inParams);
607 if (res != HC_SUCCESS) {
608 LOGE("ParsePakeResponseMessage failed, res: %d.", res);
609 return res;
610 }
611 res = ClientConfirmPakeV2Protocol(&(spekeSession->baseParam));
612 if (res != HC_SUCCESS) {
613 LOGE("ClientConfirmPakeV2Protocol failed, res:%d", res);
614 return res;
615 }
616 res = BuildAndPutOutMessage(spekeSession, out, PackagePakeClientConfirmData);
617 if (res != HC_SUCCESS) {
618 LOGE("BuildAndPutOutMessage failed, res:%d", res);
619 return res;
620 }
621 return res;
622 }
623
PakeServerConfirm(SpekeSession * spekeSession,CJson * inParams,KeyAgreeBlob * out)624 static int32_t PakeServerConfirm(SpekeSession *spekeSession, CJson *inParams, KeyAgreeBlob *out)
625 {
626 int32_t res = ParsePakeClientConfirmMessage(&(spekeSession->baseParam), inParams);
627 if (res != HC_SUCCESS) {
628 LOGE("ParsePakeClientConfirmMessage failed, res: %d", res);
629 return res;
630 }
631 res = GetAuthIdPeerFromPayload(inParams, &(spekeSession->baseParam.idSelf), &(spekeSession->baseParam.idPeer));
632 if (res != HC_SUCCESS) {
633 LOGE("Get peer authId failed, res: %d.", res);
634 return res;
635 }
636 res = ServerConfirmPakeV2Protocol(&(spekeSession->baseParam));
637 if (res != HC_SUCCESS) {
638 LOGE("ServerConfirmPakeV2Protocol failed, res:%d", res);
639 return res;
640 }
641 res = BuildAndPutOutMessage(spekeSession, out, PackagePakeServerConfirmData);
642 if (res != HC_SUCCESS) {
643 LOGE("BuildAndPutOutMessage failed, res:%d", res);
644 return res;
645 }
646 spekeSession->isFinish = true;
647 return res;
648 }
649
PakeClientVerifyConfirm(SpekeSession * spekeSession,CJson * inParams,KeyAgreeBlob * out)650 static int32_t PakeClientVerifyConfirm(SpekeSession *spekeSession, CJson *inParams, KeyAgreeBlob *out)
651 {
652 int32_t res = ParsePakeServerConfirmMessage(&(spekeSession->baseParam), inParams);
653 if (res != HC_SUCCESS) {
654 LOGE("ParsePakeServerConfirmMessage failed, res: %d.", res);
655 return res;
656 }
657 res = ClientVerifyConfirmPakeV2Protocol(&(spekeSession->baseParam));
658 if (res != HC_SUCCESS) {
659 LOGE("ClientVerifyConfirmPakeV2Protocol failed, res: %d.", res);
660 return res;
661 }
662 FreeAndCleanKey(&spekeSession->sharedSecret);
663 out->length = 0;
664 spekeSession->isFinish = true;
665 return res;
666 }
667
ProcessStep(ProtocolStep step,SpekeSession * spekeSession,CJson * inParams,KeyAgreeBlob * out)668 static int32_t ProcessStep(ProtocolStep step, SpekeSession *spekeSession, CJson *inParams, KeyAgreeBlob *out)
669 {
670 int32_t res = HC_SUCCESS;
671 LOGI("In key agree step: %d.", step);
672 switch (step) {
673 case STEP_ONE:
674 if (PakeResponse(spekeSession, out) != HC_SUCCESS) {
675 LOGE("PakeResponse fail!");
676 res = HC_ERROR;
677 }
678 break;
679 case STEP_TWO:
680 if (PakeConfirm(spekeSession, inParams, out) != HC_SUCCESS) {
681 LOGE("PakeConfirm fail!");
682 res = HC_ERROR;
683 }
684 break;
685 case STEP_THREE:
686 if (PakeServerConfirm(spekeSession, inParams, out) != HC_SUCCESS) {
687 LOGE("PakeServerConfirm fail!");
688 res = HC_ERROR;
689 }
690 break;
691 case STEP_FOUR:
692 if (PakeClientVerifyConfirm(spekeSession, inParams, out) != HC_SUCCESS) {
693 LOGE("PakeClientVerifyConfirm fail!");
694 res = HC_ERROR;
695 }
696 break;
697 default:
698 LOGI("Unkonw step, may key agree is finish!");
699 res = HC_ERR_BAD_MESSAGE;
700 break;
701 }
702 if (inParams != NULL) {
703 FreeJson(inParams);
704 inParams = NULL;
705 }
706 return res;
707 }
708
ProcessSpekeSession(SpekeSession * spekeSession,const KeyAgreeBlob * in,KeyAgreeBlob * out)709 static int32_t ProcessSpekeSession(SpekeSession *spekeSession, const KeyAgreeBlob *in, KeyAgreeBlob *out)
710 {
711 LOGI("Process session start!");
712 CJson *inParams = NULL;
713 int32_t step = 0;
714 if (spekeSession->step == STEP_INIT) {
715 LOGI("It is first message!");
716 spekeSession->step = STEP_ONE;
717 } else {
718 if ((in == NULL) || (in->data == NULL)) {
719 LOGE("Invalid params!");
720 return HC_ERR_INVALID_PARAMS;
721 }
722 inParams = CreateJsonFromString((const char *)(in->data));
723 if (inParams == NULL) {
724 LOGE("Create from json failed!");
725 return HC_ERROR;
726 }
727 if (GetIntFromJson(inParams, FIELD_SDK_STEP, &step) != HC_SUCCESS) {
728 LOGI("There is no field named step, it is first protocol!");
729 spekeSession->step = STEP_ONE;
730 } else {
731 spekeSession->step = step + 1;
732 }
733 }
734 return ProcessStep(spekeSession->step, spekeSession, inParams, out);
735 }
736
InitSpekeSession(SpekeSession * spekeSession,KeyAgreeProtocol protocol)737 static int32_t InitSpekeSession(SpekeSession *spekeSession, KeyAgreeProtocol protocol)
738 {
739 switch (protocol) {
740 case KEYAGREE_PROTOCOL_DL_SPEKE_256:
741 LOGI("Init protocol of dl speke 256");
742 spekeSession->baseParam.supportedPakeAlg = PAKE_ALG_DL;
743 spekeSession->baseParam.supportedDlPrimeMod =
744 spekeSession->baseParam.supportedDlPrimeMod | DL_PRIME_MOD_256;
745 break;
746 case KEYAGREE_PROTOCOL_DL_SPEKE_384:
747 LOGI("Init protocol of dl speke 384");
748 spekeSession->baseParam.supportedPakeAlg = PAKE_ALG_DL;
749 spekeSession->baseParam.supportedDlPrimeMod =
750 spekeSession->baseParam.supportedDlPrimeMod | DL_PRIME_MOD_384;
751 break;
752 case KEYAGREE_PROTOCOL_EC_SPEKE_P256:
753 LOGI("Init protocol of ec speke p256");
754 spekeSession->baseParam.supportedPakeAlg = PAKE_ALG_EC;
755 spekeSession->baseParam.curveType = CURVE_256;
756 break;
757 case KEYAGREE_PROTOCOL_EC_SPEKE_X25519:
758 LOGI("Init protocol of ec speke X25519");
759 spekeSession->baseParam.supportedPakeAlg = PAKE_ALG_EC;
760 spekeSession->baseParam.curveType = CURVE_25519;
761 break;
762 default:
763 LOGE("Invalid protocol type!");
764 return HC_ERROR;
765 break;
766 }
767 return HC_SUCCESS;
768 }
769
GetKegAgreeProtocolType(VersionStruct * curVersion)770 static KeyAgreeProtocol GetKegAgreeProtocolType(VersionStruct *curVersion)
771 {
772 for (uint32_t i = 0; i < sizeof(g_protocolAlgorithm); i++) {
773 if ((curVersion->second & g_protocolAlgorithm[i]) == g_protocolAlgorithm[i]) {
774 curVersion->second = g_protocolAlgorithm[i];
775 return g_keyAgreeProtocol[i];
776 }
777 }
778 LOGE("No protocol supported!");
779 return KEYAGREE_PROTOCOL_ANY;
780 }
781
ProcessProtocolInitial(SpekeSession * spekeSession,KeyAgreeBlob * out)782 static int32_t ProcessProtocolInitial(SpekeSession *spekeSession, KeyAgreeBlob *out)
783 {
784 CJson *outJsonMessage = CreateJson();
785 if (outJsonMessage == NULL) {
786 LOGE("CreateJson failed!");
787 return HC_ERR_JSON_CREATE;
788 }
789 int32_t res = AddVersionToJson(outJsonMessage, &(spekeSession->versionInfo.curVersion));
790 if (res != HC_SUCCESS) {
791 LOGE("AddVersionToOut failed, res: %d.", res);
792 FreeJson(outJsonMessage);
793 return HC_ERR_JSON_ADD;
794 }
795 res = AddIntToJson(outJsonMessage, FIELD_SDK_ERROR_CODE, KEYAGREE_SUCCESS);
796 if (res != HC_SUCCESS) {
797 LOGE("Add errorCode failed, res: %d.", res);
798 FreeJson(outJsonMessage);
799 return res;
800 }
801 res = FillExtraData(spekeSession, outJsonMessage);
802 if (res != HC_SUCCESS) {
803 LOGE("Fill extra data failed, res: %d.", res);
804 FreeJson(outJsonMessage);
805 return res;
806 }
807 char *returnStr = PackJsonToString(outJsonMessage);
808 FreeJson(outJsonMessage);
809 if (returnStr == NULL) {
810 LOGE("Pack json to string failed.");
811 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
812 }
813 uint32_t returnStrLen = HcStrlen(returnStr);
814 if (memcpy_s(out->data, out->length, returnStr, returnStrLen + 1) != EOK) {
815 LOGE("Memcpy for out blob failed.");
816 FreeJsonString(returnStr);
817 return HC_ERR_MEMORY_COPY;
818 }
819 out->length = returnStrLen + 1;
820 FreeJsonString(returnStr);
821 spekeSession->versionInfo.versionStatus = VERSION_CONFIRM;
822 spekeSession->step = STEP_ONE;
823 return HC_SUCCESS;
824 }
825
ProcessProtocolConfirm(SpekeSession * spekeSession,const KeyAgreeBlob * in,KeyAgreeBlob * out)826 static int32_t ProcessProtocolConfirm(SpekeSession *spekeSession, const KeyAgreeBlob *in, KeyAgreeBlob *out)
827 {
828 if (spekeSession == NULL || in == NULL || in->data == NULL || out == NULL) {
829 LOGE("Invalid params!");
830 return HC_ERR_INVALID_PARAMS;
831 }
832 CJson *inJsonMessage = CreateJsonFromString((const char *)(in->data));
833 if (inJsonMessage == NULL) {
834 LOGE("Create json failed!");
835 return HC_ERR_JSON_CREATE;
836 }
837 int32_t res;
838 if (spekeSession->keyAgreeType == KEYAGREE_TYPE_SERVER) {
839 res = FillExtraData(spekeSession, inJsonMessage);
840 if (res != HC_SUCCESS) {
841 LOGE("Fill extra data failed!");
842 FreeJson(inJsonMessage);
843 return res;
844 }
845 }
846 VersionStruct curVersionPeer = { 0, 0, 0 };
847 res = GetVersionFromJson(inJsonMessage, &curVersionPeer);
848 FreeJson(inJsonMessage);
849 if (res != HC_SUCCESS) {
850 LOGE("Get peer version info failed, res: %d.", res);
851 return res;
852 }
853 res = NegotiateVersion(&curVersionPeer, &(spekeSession->versionInfo.curVersion));
854 if (res != HC_SUCCESS) {
855 LOGE("NegotiateVersion failed, res: %d.", res);
856 return res;
857 }
858 KeyAgreeProtocol protocolType = GetKegAgreeProtocolType(&(spekeSession->versionInfo.curVersion));
859 if (protocolType == KEYAGREE_PROTOCOL_ANY) {
860 LOGE("GetKegAgreeProtocolType failed!, it is no protocol support!");
861 return HC_ERR_NOT_SUPPORT;
862 }
863 res = InitSpekeSession(spekeSession, protocolType);
864 if (res != HC_SUCCESS) {
865 LOGE("Init protocol session fail!");
866 return res;
867 }
868 res = spekeSession->processSession(spekeSession, in, out);
869 if (res != HC_SUCCESS) {
870 LOGE("ProcessProtocolAgree:protocol agree fail!");
871 return res;
872 }
873 spekeSession->versionInfo.versionStatus = VERSION_DECIDED;
874 return HC_SUCCESS;
875 }
876
ProcessProtocolAgree(SpekeSession * spekeSession,const KeyAgreeBlob * in,KeyAgreeBlob * out)877 static int32_t ProcessProtocolAgree(SpekeSession *spekeSession, const KeyAgreeBlob *in, KeyAgreeBlob *out)
878 {
879 int32_t res = HC_SUCCESS;
880 if (spekeSession->versionInfo.versionStatus == INITIAL) {
881 res = ProcessProtocolInitial(spekeSession, out);
882 } else if (spekeSession->versionInfo.versionStatus == VERSION_CONFIRM) {
883 res = ProcessProtocolConfirm(spekeSession, in, out);
884 } else {
885 LOGI("Version is decided, no need do protocol agree!");
886 }
887 if (res != HC_SUCCESS) {
888 LOGE("ProcessProtocolAgree failed, versionStatus is: %d, res: %d.",
889 spekeSession->versionInfo.versionStatus, res);
890 }
891 return res;
892 }
893
CheckAndInitProtocol(SpekeSession * spekeSession,KeyAgreeProtocol protocol)894 static int32_t CheckAndInitProtocol(SpekeSession *spekeSession, KeyAgreeProtocol protocol)
895 {
896 int32_t res = HC_ERR_NOT_SUPPORT;
897 uint64_t algInProtocol = SPEKE_MOD_NONE;
898 switch (protocol) {
899 case KEYAGREE_PROTOCOL_ANY:
900 InitVersionInfo(&(spekeSession->versionInfo));
901 return HC_SUCCESS;
902 case KEYAGREE_PROTOCOL_DL_SPEKE_256:
903 #ifdef P2P_PAKE_DL_PRIME_LEN_256
904 algInProtocol |= DL_SPEKE_MOD_256;
905 res = HC_SUCCESS;
906 #endif
907 break;
908 case KEYAGREE_PROTOCOL_DL_SPEKE_384:
909 #ifdef P2P_PAKE_DL_PRIME_LEN_384
910 algInProtocol |= DL_SPEKE_MOD_384;
911 res = HC_SUCCESS;
912 #endif
913 break;
914 case KEYAGREE_PROTOCOL_EC_SPEKE_P256:
915 #ifdef P2P_PAKE_EC_PRIME_P256
916 algInProtocol |= EC_SPEKE_P256;
917 res = HC_SUCCESS;
918 #endif
919 break;
920 case KEYAGREE_PROTOCOL_EC_SPEKE_X25519:
921 #ifdef P2P_PAKE_EC_PRIME_X25519
922 algInProtocol |= EC_SPEKE_X25519;
923 res = HC_SUCCESS;
924 #endif
925 break;
926 default:
927 break;
928 }
929 GetMaxVersion(algInProtocol, &(spekeSession->versionInfo.curVersion));
930 return res;
931 }
932
DestroySpekeSession(SpekeSession * spekeSession)933 void DestroySpekeSession(SpekeSession *spekeSession)
934 {
935 if (spekeSession == NULL) {
936 LOGE("Failed to destroy session, spekeSession is NULL!");
937 return;
938 }
939 DestroyPakeV2BaseParams(&(spekeSession->baseParam));
940 FreeAndCleanKey(&spekeSession->sharedSecret);
941 FreeAndCleanKey(&spekeSession->deviceId);
942 HcFree(spekeSession->extras);
943 HcFree(spekeSession);
944 }
945
CreateSpekeSession(void)946 SpekeSession *CreateSpekeSession(void)
947 {
948 SpekeSession *spekeSession = (SpekeSession *)HcMalloc(sizeof(SpekeSession), 0);
949 if (spekeSession == NULL) {
950 LOGE("Failed to allocate session memory!");
951 return spekeSession;
952 }
953 if (InitPakeV2BaseParams(&(spekeSession->baseParam)) != HC_SUCCESS) {
954 LOGE("InitPakeV2BaseParams failed!");
955 HcFree(spekeSession);
956 return NULL;
957 }
958 spekeSession->processProtocolAgree = ProcessProtocolAgree;
959 spekeSession->processSession = ProcessSpekeSession;
960 spekeSession->initSpekeSession = InitSpekeSession;
961 spekeSession->checkAndInitProtocol = CheckAndInitProtocol;
962 spekeSession->sharedSecret.val = NULL;
963 spekeSession->sharedSecret.length = 0;
964 spekeSession->deviceId.val = NULL;
965 spekeSession->deviceId.length = 0;
966 spekeSession->extras = NULL;
967 spekeSession->protocol = KEYAGREE_PROTOCOL_ANY;
968 spekeSession->isFinish = false;
969 spekeSession->step = STEP_INIT;
970 return spekeSession;
971 }