• 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_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 }