1 /*
2  * Copyright (C) 2023 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 "ec_speke_protocol.h"
17 
18 #include "alg_loader.h"
19 #include "device_auth_defines.h"
20 #include "hc_log.h"
21 
22 #define EC_SPEKE_AUTH_ID_MAX_LEN 256
23 #define EC_SPEKE_SALT_LEN 16
24 #define EC_SPEKE_KCF_CODE_LEN 1
25 #define EC_SPEKE_SECRET_LEN 32
26 #define EC_SPEKE_EC_KEY_LEN 32
27 #define EC_SPEKE_SESSION_KEY_LEN 32
28 #define HICHAIN_SPEKE_BASE_INFO "hichain_speke_base_info"
29 #define SHARED_SECRET_DERIVED_FACTOR "hichain_speke_shared_secret_info"
30 #define HICHAIN_SPEKE_SESSIONKEY_INFO "hichain_speke_sessionkey_info"
31 
32 // X25519 define
33 #define EC_SPEKE_PRIVATE_KEY_AND_MASK_HIGH 0xF8
34 #define EC_SPEKE_PRIVATE_KEY_AND_MASK_LOW  0x7F
35 #define EC_SPEKE_PRIVATE_KEY_OR_MASK_LOW   0x40
36 
37 // event field define
38 #define FIELD_PROTOCOL_TYPE "protocolType"
39 #define FIELD_EVENT "event"
40 #define FIELD_PROTOCOL_DATA "protocolData"
41 #define FIELD_ERR_CODE "errCode"
42 #define FIELD_ERR_MSG "errMsg"
43 
44 // protocol data field define
45 #define FIELD_SALT "salt"
46 #define FIELD_AUTH_ID_CLIENT "authIdC"
47 #define FIELD_AUTH_ID_SERVER "authIdS"
48 #define FIELD_EPK_CLIENT "epkC"
49 #define FIELD_EPK_SERVER "epkS"
50 #define FIELD_KCF_DATA_CLIENT "kcfDataC"
51 #define FIELD_KCF_DATA_SERVER "kcfDataS"
52 
53 static const uint8_t KCF_CODE_CLIENT[EC_SPEKE_KCF_CODE_LEN] = { 0x04 };
54 static const uint8_t KCF_CODE_SERVER[EC_SPEKE_KCF_CODE_LEN] = { 0x03 };
55 
56 typedef struct {
57     EcSpekeCurveType curveType;
58     Uint8Buff psk;
59     Uint8Buff salt;
60     Uint8Buff base;
61     Uint8Buff eskSelf;
62     Uint8Buff epkSelf;
63     Uint8Buff epkPeer;
64     Uint8Buff authIdSelf;
65     Uint8Buff authIdPeer;
66     Uint8Buff kcfDataSelf;
67     Uint8Buff kcfDataPeer;
68     Uint8Buff sharedSecret;
69     int32_t osAccountId;
70 } EcSpekeParams;
71 
72 typedef struct {
73     BaseProtocol base;
74     EcSpekeParams params;
75 } EcSpekeProtocol;
76 
77 typedef struct {
78     int32_t curState;
79     int32_t eventType;
80     int32_t (*stateProcessFunc)(EcSpekeProtocol *impl, const CJson *inputEvent, CJson **outputEvent);
81     void (*exceptionHandleFunc)(int32_t errorCode, CJson **outputEvent);
82     int32_t nextState;
83 } ProtocolStateNode;
84 
EcSpekeClientStartReqBuildEvent(const EcSpekeParams * params,CJson ** outputEvent)85 static int32_t EcSpekeClientStartReqBuildEvent(const EcSpekeParams *params, CJson **outputEvent)
86 {
87     CJson *json = CreateJson();
88     if (json == NULL) {
89         LOGE("create json failed.");
90         return HC_ERR_JSON_CREATE;
91     }
92     if (AddIntToJson(json, FIELD_EVENT, CLEINT_START_REQ_EVENT) != HC_SUCCESS) {
93         LOGE("add eventName to json fail.");
94         FreeJson(json);
95         return HC_ERR_JSON_ADD;
96     }
97     if (AddByteToJson(json, FIELD_AUTH_ID_CLIENT, params->authIdSelf.val,
98         params->authIdSelf.length) != HC_SUCCESS) {
99         LOGE("add authIdC to json fail.");
100         FreeJson(json);
101         return HC_ERR_JSON_ADD;
102     }
103     *outputEvent = json;
104     return HC_SUCCESS;
105 }
106 
GetAuthIdPeerFromInput(const CJson * inputEvent,EcSpekeParams * params,bool isClient)107 static int32_t GetAuthIdPeerFromInput(const CJson *inputEvent, EcSpekeParams *params, bool isClient)
108 {
109     const char *authIdPeerStr = isClient ? GetStringFromJson(inputEvent, FIELD_AUTH_ID_SERVER) :
110         GetStringFromJson(inputEvent, FIELD_AUTH_ID_CLIENT);
111     if (authIdPeerStr == NULL) {
112         LOGE("get authIdPeerStr from inputEvent fail.");
113         return HC_ERR_JSON_GET;
114     }
115     uint32_t authIdPeerStrLen = HcStrlen(authIdPeerStr) / BYTE_TO_HEX_OPER_LENGTH;
116     if (authIdPeerStrLen == 0 || authIdPeerStrLen > EC_SPEKE_AUTH_ID_MAX_LEN) {
117         LOGE("Invalid authIdPeerStrLen: %u.", authIdPeerStrLen);
118         return HC_ERR_CONVERT_FAILED;
119     }
120     if (InitUint8Buff(&params->authIdPeer, authIdPeerStrLen) != HC_SUCCESS) {
121         LOGE("allocate authIdPeer memory fail.");
122         return HC_ERR_ALLOC_MEMORY;
123     }
124     if (HexStringToByte(authIdPeerStr, params->authIdPeer.val, params->authIdPeer.length) != HC_SUCCESS) {
125         LOGE("HexStringToByte for authIdPeerStr failed.");
126         return HC_ERR_CONVERT_FAILED;
127     }
128     return HC_SUCCESS;
129 }
130 
GetSaltFromInput(const CJson * inputEvent,EcSpekeParams * params)131 static int32_t GetSaltFromInput(const CJson *inputEvent, EcSpekeParams *params)
132 {
133     if (InitUint8Buff(&params->salt, EC_SPEKE_SALT_LEN) != HC_SUCCESS) {
134         LOGE("allocate salt memory fail.");
135         return HC_ERR_ALLOC_MEMORY;
136     }
137     if (GetByteFromJson(inputEvent, FIELD_SALT, params->salt.val, params->salt.length) != HC_SUCCESS) {
138         LOGE("get salt from inputEvent fail.");
139         return HC_ERR_JSON_GET;
140     }
141     return HC_SUCCESS;
142 }
143 
GetEpkPeerFromInput(const CJson * inputEvent,EcSpekeParams * params,bool isClient)144 static int32_t GetEpkPeerFromInput(const CJson *inputEvent, EcSpekeParams *params, bool isClient)
145 {
146     const char *epkPeerStr = isClient ? GetStringFromJson(inputEvent, FIELD_EPK_SERVER) :
147         GetStringFromJson(inputEvent, FIELD_EPK_CLIENT);
148     if (epkPeerStr == NULL) {
149         LOGE("get epkPeerStr from inputEvent fail.");
150         return HC_ERR_JSON_GET;
151     }
152     if (InitUint8Buff(&params->epkPeer, HcStrlen(epkPeerStr) / BYTE_TO_HEX_OPER_LENGTH) != HC_SUCCESS) {
153         LOGE("allocate epkPeerStr memory fail.");
154         return HC_ERR_ALLOC_MEMORY;
155     }
156     if (HexStringToByte(epkPeerStr, params->epkPeer.val, params->epkPeer.length) != HC_SUCCESS) {
157         LOGE("HexStringToByte for epkPeerStr failed.");
158         return HC_ERR_CONVERT_FAILED;
159     }
160     return HC_SUCCESS;
161 }
162 
GetKcfDataPeerFromInput(const CJson * inputEvent,EcSpekeParams * params,bool isClient)163 static int32_t GetKcfDataPeerFromInput(const CJson *inputEvent, EcSpekeParams *params, bool isClient)
164 {
165     if (InitUint8Buff(&params->kcfDataPeer, SHA256_LEN) != HC_SUCCESS) {
166         LOGE("allocate kcfDataPeer fail.");
167         return HC_ERR_ALLOC_MEMORY;
168     }
169     if (GetByteFromJson(inputEvent, (isClient ? FIELD_KCF_DATA_SERVER : FIELD_KCF_DATA_CLIENT),
170         params->kcfDataPeer.val, params->kcfDataPeer.length) != HC_SUCCESS) {
171         LOGE("get kcfDataPeer from inputEvent fail.");
172         return HC_ERR_JSON_GET;
173     }
174     return HC_SUCCESS;
175 }
176 
EcSpekeClientStartReq(EcSpekeProtocol * impl,const CJson * inputEvent,CJson ** outputEvent)177 static int32_t EcSpekeClientStartReq(EcSpekeProtocol *impl, const CJson *inputEvent, CJson **outputEvent)
178 {
179     (void)inputEvent;
180     return EcSpekeClientStartReqBuildEvent(&impl->params, outputEvent);
181 }
182 
EcSpekeServerStartRspParseEvent(const CJson * inputEvent,EcSpekeParams * params)183 static int32_t EcSpekeServerStartRspParseEvent(const CJson *inputEvent, EcSpekeParams *params)
184 {
185     return GetAuthIdPeerFromInput(inputEvent, params, false);
186 }
187 
CalSalt(EcSpekeParams * params)188 static int32_t CalSalt(EcSpekeParams *params)
189 {
190     if (InitUint8Buff(&params->salt, EC_SPEKE_SALT_LEN) != HC_SUCCESS) {
191         LOGE("allocate salt memory fail.");
192         return HC_ERR_ALLOC_MEMORY;
193     }
194     int32_t res = GetLoaderInstance()->generateRandom(&params->salt);
195     if (res != HC_SUCCESS) {
196         LOGE("Generate salt failed, res: %x.", res);
197         return res;
198     }
199     return HC_SUCCESS;
200 }
201 
CalSecret(EcSpekeParams * params,Uint8Buff * secret)202 static int32_t CalSecret(EcSpekeParams *params, Uint8Buff *secret)
203 {
204     Uint8Buff keyInfo = { (uint8_t *)HICHAIN_SPEKE_BASE_INFO, HcStrlen(HICHAIN_SPEKE_BASE_INFO) };
205     KeyParams keyParams = { { params->psk.val, params->psk.length, false }, false, params->osAccountId };
206     int32_t res = GetLoaderInstance()->computeHkdf(&keyParams, &(params->salt), &keyInfo, secret);
207     if (res != HC_SUCCESS) {
208         LOGE("Derive secret from psk failed, res: %x.", res);
209         return res;
210     }
211     ClearFreeUint8Buff(&params->psk);
212     return HC_SUCCESS;
213 }
214 
EcSpekeCalBase(EcSpekeParams * params,Uint8Buff * secret)215 static int32_t EcSpekeCalBase(EcSpekeParams *params, Uint8Buff *secret)
216 {
217     Algorithm algo;
218     int32_t res;
219     if (params->curveType == CURVE_TYPE_256) {
220         algo = P256;
221         /* P256 requires buffer for both X and Y coordinates. */
222         res = InitUint8Buff(&params->base, 2 * EC_SPEKE_EC_KEY_LEN);
223     } else if (params->curveType == CURVE_TYPE_25519) {
224         algo = X25519;
225         res = InitUint8Buff(&params->base, EC_SPEKE_EC_KEY_LEN);
226     } else {
227         LOGE("Unsupported curve type: %d", params->curveType);
228         return HC_ERR_UNSUPPORTED_VERSION;
229     }
230     if (res != HC_SUCCESS) {
231         LOGE("allocate base memory fail.");
232         return HC_ERR_ALLOC_MEMORY;
233     }
234     res = GetLoaderInstance()->hashToPoint(secret, algo, &params->base);
235     if (res != HC_SUCCESS) {
236         LOGE("HashToPoint from secret to base failed, res: %x", res);
237         return res;
238     }
239     return HC_SUCCESS;
240 }
241 
EcSpekeCalEskSelf(EcSpekeParams * params)242 static int32_t EcSpekeCalEskSelf(EcSpekeParams *params)
243 {
244     if (InitUint8Buff(&params->eskSelf, EC_SPEKE_EC_KEY_LEN) != HC_SUCCESS) {
245         LOGE("allocate eskSelf memory fail.");
246         return HC_ERR_ALLOC_MEMORY;
247     }
248     int32_t res;
249     if (params->curveType == CURVE_TYPE_256) {
250         res = GetLoaderInstance()->generateRandom(&(params->eskSelf));
251         if (res != HC_SUCCESS) {
252             LOGE("GenerateRandom for eskSelf failed, res: %x", res);
253             return res;
254         }
255     } else if (params->curveType == CURVE_TYPE_25519) {
256         res = GetLoaderInstance()->generateRandom(&(params->eskSelf));
257         if (res != HC_SUCCESS) {
258             LOGE("GenerateRandom for eskSelf failed, res: %x", res);
259             return res;
260         }
261         params->eskSelf.val[EC_SPEKE_EC_KEY_LEN - 1] &= EC_SPEKE_PRIVATE_KEY_AND_MASK_HIGH;
262         params->eskSelf.val[0] &= EC_SPEKE_PRIVATE_KEY_AND_MASK_LOW;
263         params->eskSelf.val[0] |= EC_SPEKE_PRIVATE_KEY_OR_MASK_LOW;
264     } else {
265         LOGE("Unsupported curve type: %d", params->curveType);
266         return HC_ERR_UNSUPPORTED_VERSION;
267     }
268     return HC_SUCCESS;
269 }
270 
EcSpekeCalEpkSelf(EcSpekeParams * params)271 static int32_t EcSpekeCalEpkSelf(EcSpekeParams *params)
272 {
273     int32_t res;
274     Algorithm algo;
275     if (params->curveType == CURVE_TYPE_256) {
276         algo = P256;
277         /* P256 requires buffer for both X and Y coordinates. */
278         res = InitUint8Buff(&params->epkSelf, 2 * EC_SPEKE_EC_KEY_LEN);
279     } else if (params->curveType == CURVE_TYPE_25519) {
280         algo = X25519;
281         res = InitUint8Buff(&params->epkSelf, EC_SPEKE_EC_KEY_LEN);
282     } else {
283         LOGE("Unsupported curve type: %d", params->curveType);
284         return HC_ERR_UNSUPPORTED_VERSION;
285     }
286     if (res != HC_SUCCESS) {
287         LOGE("allocate epkSelf memory fail.");
288         return HC_ERR_ALLOC_MEMORY;
289     }
290     KeyParams eskSelfParams = { { params->eskSelf.val, params->eskSelf.length, false }, false, params->osAccountId };
291     KeyBuff baseBuff = { params->base.val, params->base.length, false };
292     res = GetLoaderInstance()->agreeSharedSecret(&eskSelfParams, &baseBuff, algo, &params->epkSelf);
293     if (res != HC_SUCCESS) {
294         LOGE("AgreeSharedSecret for epkSelf failed, res: %x", res);
295         return res;
296     }
297     return HC_SUCCESS;
298 }
299 
CheckEpkPeerValid(EcSpekeParams * params)300 static int32_t CheckEpkPeerValid(EcSpekeParams *params)
301 {
302     /* P256 requires buffer for both X and Y coordinates. */
303     uint32_t epkPeerValidLen = (params->curveType == CURVE_TYPE_256) ?
304         (2 * EC_SPEKE_EC_KEY_LEN) : EC_SPEKE_EC_KEY_LEN;
305     if (params->epkPeer.length != epkPeerValidLen) {
306         LOGE("Invalid epkPeer length: %u", params->epkPeer.length);
307         return HC_ERR_BAD_MESSAGE;
308     }
309     Algorithm algo = (params->curveType == CURVE_TYPE_256) ? P256 : X25519;
310     if (!GetLoaderInstance()->checkEcPublicKey(&params->epkPeer, algo)) {
311         LOGE("Check EC_SPEKE publicKey fail.");
312         return HC_ERR_BAD_MESSAGE;
313     }
314     return HC_SUCCESS;
315 }
316 
CalP(EcSpekeParams * params,Uint8Buff * p)317 static int32_t CalP(EcSpekeParams *params, Uint8Buff *p)
318 {
319     KeyParams eskSelfParams = { { params->eskSelf.val, params->eskSelf.length, false }, false, params->osAccountId };
320     KeyBuff epkPeerBuff = { params->epkPeer.val, params->epkPeer.length, false };
321     Algorithm algo = (params->curveType == CURVE_TYPE_256) ? P256 : X25519;
322     int32_t res = GetLoaderInstance()->agreeSharedSecret(&eskSelfParams, &epkPeerBuff, algo, p);
323     ClearFreeUint8Buff(&params->eskSelf);
324     if (res != HC_SUCCESS) {
325         LOGE("AgreeSharedSecret for p failed, res: %x", res);
326         return res;
327     }
328     return HC_SUCCESS;
329 }
330 
CalSidSelf(EcSpekeParams * params,Uint8Buff * sidSelf)331 static int32_t CalSidSelf(EcSpekeParams *params, Uint8Buff *sidSelf)
332 {
333     uint32_t sidSelfMsgLen = params->authIdSelf.length + EC_SPEKE_EC_KEY_LEN;
334     Uint8Buff sidSelfMsg = { NULL, 0 };
335     if (InitUint8Buff(&sidSelfMsg, sidSelfMsgLen) != HC_SUCCESS) {
336         LOGE("allocate sidSelfMsg memory fail.");
337         return HC_ERR_ALLOC_MEMORY;
338     }
339     if (memcpy_s(sidSelfMsg.val, sidSelfMsg.length, params->authIdSelf.val, params->authIdSelf.length) != EOK) {
340         LOGE("Memcpy for authIdSelf failed.");
341         ClearFreeUint8Buff(&sidSelfMsg);
342         return HC_ERR_MEMORY_COPY;
343     }
344     if (memcpy_s(sidSelfMsg.val + params->authIdSelf.length, sidSelfMsg.length - params->authIdSelf.length,
345         params->epkSelf.val, EC_SPEKE_EC_KEY_LEN) != EOK) { // only need x-coordinate
346         LOGE("Memcpy for epkSelf_X failed.");
347         ClearFreeUint8Buff(&sidSelfMsg);
348         return HC_ERR_MEMORY_COPY;
349     }
350     int32_t res = GetLoaderInstance()->sha256(&sidSelfMsg, sidSelf);
351     ClearFreeUint8Buff(&sidSelfMsg);
352     if (res != HC_SUCCESS) {
353         LOGE("Sha256 for sidSelf failed, res: %x", res);
354         return res;
355     }
356     return HC_SUCCESS;
357 }
358 
CalSidPeer(EcSpekeParams * params,Uint8Buff * sidPeer)359 static int32_t CalSidPeer(EcSpekeParams *params, Uint8Buff *sidPeer)
360 {
361     uint32_t sidPeerMsgLen = params->authIdPeer.length + EC_SPEKE_EC_KEY_LEN;
362     Uint8Buff sidPeerMsg = { NULL, 0 };
363     if (InitUint8Buff(&sidPeerMsg, sidPeerMsgLen) != HC_SUCCESS) {
364         LOGE("allocate sidPeerMsg memory fail.");
365         return HC_ERR_ALLOC_MEMORY;
366     }
367     if (memcpy_s(sidPeerMsg.val, sidPeerMsg.length, params->authIdPeer.val, params->authIdPeer.length) != EOK) {
368         LOGE("Memcpy for authIdPeer failed.");
369         ClearFreeUint8Buff(&sidPeerMsg);
370         return HC_ERR_MEMORY_COPY;
371     }
372     if (memcpy_s(sidPeerMsg.val + params->authIdPeer.length, sidPeerMsg.length - params->authIdPeer.length,
373         params->epkPeer.val, EC_SPEKE_EC_KEY_LEN) != EOK) { // only need x-coordinate
374         LOGE("Memcpy for epkPeer_X failed.");
375         ClearFreeUint8Buff(&sidPeerMsg);
376         return HC_ERR_MEMORY_COPY;
377     }
378     int32_t res = GetLoaderInstance()->sha256(&sidPeerMsg, sidPeer);
379     ClearFreeUint8Buff(&sidPeerMsg);
380     if (res != HC_SUCCESS) {
381         LOGE("Sha256 for sidPeer failed, res: %x", res);
382         return res;
383     }
384     return HC_SUCCESS;
385 }
386 
CalSid(EcSpekeParams * params,Uint8Buff * sid)387 static int32_t CalSid(EcSpekeParams *params, Uint8Buff *sid)
388 {
389     uint8_t sidSelfVal[SHA256_LEN] = { 0 };
390     uint8_t sidPeerVal[SHA256_LEN] = { 0 };
391     Uint8Buff sidSelf = { sidSelfVal, SHA256_LEN };
392     Uint8Buff sidPeer = { sidPeerVal, SHA256_LEN };
393     int32_t res = CalSidSelf(params, &sidSelf);
394     if (res != HC_SUCCESS) {
395         return res;
396     }
397     res = CalSidPeer(params, &sidPeer);
398     if (res != HC_SUCCESS) {
399         return res;
400     }
401     Uint8Buff *maxSid = &sidSelf;
402     Uint8Buff *minSid = &sidPeer;
403     if (GetLoaderInstance()->bigNumCompare(&sidSelf, &sidPeer) > 0) {
404         maxSid = &sidPeer;
405         minSid = &sidSelf;
406     }
407     if (memcpy_s(sid->val, sid->length, maxSid->val, maxSid->length) != EOK) {
408         LOGE("Memcpy for maxSid failed.");
409         return HC_ERR_MEMORY_COPY;
410     }
411     if (memcpy_s(sid->val + maxSid->length, sid->length - maxSid->length, minSid->val, minSid->length) != EOK) {
412         LOGE("Memcpy for minSid failed.");
413         return HC_ERR_MEMORY_COPY;
414     }
415     return HC_SUCCESS;
416 }
417 
CombineSharedSecretMsg(const Uint8Buff * p,const Uint8Buff * sid,Uint8Buff * sharedSecretMsg)418 static int32_t CombineSharedSecretMsg(const Uint8Buff *p, const Uint8Buff *sid, Uint8Buff *sharedSecretMsg)
419 {
420     uint32_t usedLen = 0;
421     if (memcpy_s(sharedSecretMsg->val, sharedSecretMsg->length, sid->val, sid->length) != EOK) {
422         LOGE("Memcpy for sidHex failed.");
423         return HC_ERR_MEMORY_COPY;
424     }
425     usedLen += sid->length;
426     // Only need x-coordinate
427     if (memcpy_s(sharedSecretMsg->val + usedLen, sharedSecretMsg->length - usedLen,
428         p->val, EC_SPEKE_EC_KEY_LEN) != EOK) {
429         LOGE("Memcpy for tmpSharedSecret failed.");
430         return HC_ERR_MEMORY_COPY;
431     }
432     usedLen += EC_SPEKE_EC_KEY_LEN;
433     if (memcpy_s(sharedSecretMsg->val + usedLen, sharedSecretMsg->length - usedLen,
434         SHARED_SECRET_DERIVED_FACTOR, HcStrlen(SHARED_SECRET_DERIVED_FACTOR)) != EOK) {
435         LOGE("Memcpy for sharedSecret derived factor failed.");
436         return HC_ERR_MEMORY_COPY;
437     }
438     return HC_SUCCESS;
439 }
440 
GenerateSharedSecretMsg(EcSpekeParams * params,Uint8Buff * sharedSecretMsg)441 static int32_t GenerateSharedSecretMsg(EcSpekeParams *params, Uint8Buff *sharedSecretMsg)
442 {
443     uint32_t pLen = (params->curveType == CURVE_TYPE_256) ? (2 * EC_SPEKE_EC_KEY_LEN) : EC_SPEKE_EC_KEY_LEN;
444     Uint8Buff p = { NULL, 0 };
445     if (InitUint8Buff(&p, pLen) != HC_SUCCESS) {
446         LOGE("allocate p memory fail.");
447         return HC_ERR_ALLOC_MEMORY;
448     }
449     int32_t res = CalP(params, &p);
450     if (res != HC_SUCCESS) {
451         ClearFreeUint8Buff(&p);
452         return res;
453     }
454     // sid is composed of client sid and server sid, so need twice SHA256_LEN
455     uint8_t sidVal[SHA256_LEN * 2] = { 0 };
456     Uint8Buff sid = { sidVal, SHA256_LEN * 2 };
457     res = CalSid(params, &sid);
458     if (res != HC_SUCCESS) {
459         ClearFreeUint8Buff(&p);
460         return res;
461     }
462     res = CombineSharedSecretMsg(&p, &sid, sharedSecretMsg);
463     (void)memset_s(sid.val, sid.length, 0, sid.length);
464     ClearFreeUint8Buff(&p);
465     return res;
466 }
467 
468 /*
469  * '|' means joint
470  * P = eskSelf . epkPeer
471  *
472  * sidSelf = hash(idSelf | epkSelf_X)
473  * sidPeer = hash(idPeer | epkPeer_X)
474  * sid = MAX(sidSelf, sidPeer) | MIN(sidSelf, sidPeer)
475  *
476  * derivedFactor = "hichain_speke_shared_secret_info"
477  * hash = sha256
478  * sharedSecret = hash(hex(sid) | P_X | derivedFactor)
479  */
CalSharedSecret(EcSpekeParams * params)480 static int32_t CalSharedSecret(EcSpekeParams *params)
481 {
482     uint32_t sharedSecretMsgLen = SHA256_LEN * 2 + EC_SPEKE_EC_KEY_LEN + HcStrlen(SHARED_SECRET_DERIVED_FACTOR);
483     Uint8Buff sharedSecretMsg = { NULL, 0 };
484     if (InitUint8Buff(&sharedSecretMsg, sharedSecretMsgLen) != HC_SUCCESS) {
485         LOGE("allocate sharedSecretMsg memory fail.");
486         return HC_ERR_ALLOC_MEMORY;
487     }
488     int32_t res = GenerateSharedSecretMsg(params, &sharedSecretMsg);
489     if (res != HC_SUCCESS) {
490         ClearFreeUint8Buff(&sharedSecretMsg);
491         return res;
492     }
493     if (InitUint8Buff(&params->sharedSecret, SHA256_LEN)) {
494         LOGE("allocate sharedSecret memory fail.");
495         ClearFreeUint8Buff(&sharedSecretMsg);
496         return HC_ERR_ALLOC_MEMORY;
497     }
498     res = GetLoaderInstance()->sha256(&sharedSecretMsg, &params->sharedSecret);
499     ClearFreeUint8Buff(&sharedSecretMsg);
500     if (res != HC_SUCCESS) {
501         LOGE("Sha256 for sharedSecret failed, res: %x", res);
502         return res;
503     }
504     return HC_SUCCESS;
505 }
506 
CombineProtectedMsg(EcSpekeProtocol * impl,bool isVerify,Uint8Buff * kcfDataMsg,uint32_t usedLen)507 static int32_t CombineProtectedMsg(EcSpekeProtocol *impl, bool isVerify, Uint8Buff *kcfDataMsg, uint32_t usedLen)
508 {
509     Uint8Buff *firstProtectedMsg = isVerify ? &(impl->base.protectedMsg.peerMsg) : &(impl->base.protectedMsg.selfMsg);
510     Uint8Buff *secondProtectedMsg = isVerify ? &(impl->base.protectedMsg.selfMsg) : &(impl->base.protectedMsg.peerMsg);
511     if (IsUint8BuffValid(firstProtectedMsg, PROTECTED_MSG_MAX_LEN)) {
512         if (memcpy_s(kcfDataMsg->val + usedLen, kcfDataMsg->length - usedLen,
513             firstProtectedMsg->val, firstProtectedMsg->length) != EOK) {
514             LOGE("Memcpy firstProtectedMsg failed.");
515             return HC_ERR_MEMORY_COPY;
516         }
517         usedLen += firstProtectedMsg->length;
518     }
519     if (IsUint8BuffValid(secondProtectedMsg, PROTECTED_MSG_MAX_LEN)) {
520         if (memcpy_s(kcfDataMsg->val + usedLen, kcfDataMsg->length - usedLen,
521             secondProtectedMsg->val, secondProtectedMsg->length) != EOK) {
522             LOGE("Memcpy secondProtectedMsg failed.");
523             return HC_ERR_MEMORY_COPY;
524         }
525     }
526     return HC_SUCCESS;
527 }
528 
GenerateKcfDataMsg(EcSpekeProtocol * impl,bool isClient,bool isVerify,Uint8Buff * kcfDataMsg)529 static int32_t GenerateKcfDataMsg(EcSpekeProtocol *impl, bool isClient, bool isVerify, Uint8Buff *kcfDataMsg)
530 {
531     EcSpekeParams *params = &impl->params;
532     const uint8_t *kcfCode = ((isClient && !isVerify) || (!isClient && isVerify)) ? KCF_CODE_CLIENT : KCF_CODE_SERVER;
533     if (memcpy_s(kcfDataMsg->val, kcfDataMsg->length, kcfCode, EC_SPEKE_KCF_CODE_LEN) != HC_SUCCESS) {
534         LOGE("Memcpy for kcfCode failed.");
535         return HC_ERR_MEMORY_COPY;
536     }
537     uint32_t usedLen = EC_SPEKE_KCF_CODE_LEN;
538     Uint8Buff *epkClient = isClient ? &params->epkSelf : &params->epkPeer;
539     Uint8Buff *epkServer = isClient ? &params->epkPeer : &params->epkSelf;
540     if (memcpy_s(kcfDataMsg->val + usedLen, kcfDataMsg->length - usedLen,
541         epkClient->val, EC_SPEKE_EC_KEY_LEN) != EOK) { // Only the x-coordinate of epk is required
542         LOGE("Memcpy for epkClient failed.");
543         return HC_ERR_MEMORY_COPY;
544     }
545     usedLen += EC_SPEKE_EC_KEY_LEN;
546     if (memcpy_s(kcfDataMsg->val + usedLen, kcfDataMsg->length - usedLen,
547         epkServer->val, EC_SPEKE_EC_KEY_LEN) != EOK) { // Only the x-coordinate of epk is required
548         LOGE("Memcpy for epkServer failed.");
549         return HC_ERR_MEMORY_COPY;
550     }
551     usedLen += EC_SPEKE_EC_KEY_LEN;
552     if (memcpy_s(kcfDataMsg->val + usedLen, kcfDataMsg->length - usedLen,
553         params->sharedSecret.val, params->sharedSecret.length) != EOK) {
554         LOGE("Memcpy for sharedSecret failed.");
555         return HC_ERR_MEMORY_COPY;
556     }
557     usedLen += params->sharedSecret.length;
558     if (memcpy_s(kcfDataMsg->val + usedLen, kcfDataMsg->length - usedLen,
559         params->base.val, EC_SPEKE_EC_KEY_LEN) != EOK) { // Only the x-coordinate of base is required
560         LOGE("Memcpy for base_X failed.");
561         return HC_ERR_MEMORY_COPY;
562     }
563     usedLen += EC_SPEKE_EC_KEY_LEN;
564     return CombineProtectedMsg(impl, isVerify, kcfDataMsg, usedLen);
565 }
566 
567 /*
568  * kcfdataClient = SHA256(byte(0x04), PK_CLIENT_X, PK_SERVER_X, sharedSecret, base_X)
569  * kcfdataServer = SHA256(byte(0x03), PK_CLIENT_X, PK_SERVER_X, sharedSecret, base_X)
570  */
CalKcfDataSelf(EcSpekeProtocol * impl,bool isClient)571 static int32_t CalKcfDataSelf(EcSpekeProtocol *impl, bool isClient)
572 {
573     uint32_t kcfDataMsgLen = EC_SPEKE_KCF_CODE_LEN + EC_SPEKE_EC_KEY_LEN + EC_SPEKE_EC_KEY_LEN +
574         SHA256_LEN + EC_SPEKE_EC_KEY_LEN + impl->base.protectedMsg.selfMsg.length +
575         impl->base.protectedMsg.peerMsg.length;
576     Uint8Buff kcfDataMsg = { NULL, 0 };
577     if (InitUint8Buff(&kcfDataMsg, kcfDataMsgLen) != HC_SUCCESS) {
578         LOGE("allocate kcfDataMsg memory fail.");
579         return HC_ERR_ALLOC_MEMORY;
580     }
581     int32_t res = GenerateKcfDataMsg(impl, isClient, false, &kcfDataMsg);
582     if (res != HC_SUCCESS) {
583         ClearFreeUint8Buff(&kcfDataMsg);
584         return res;
585     }
586     if (InitUint8Buff(&impl->params.kcfDataSelf, SHA256_LEN) != HC_SUCCESS) {
587         LOGE("allocate kcfDataSelf memory fail.");
588         ClearFreeUint8Buff(&kcfDataMsg);
589         return HC_ERR_ALLOC_MEMORY;
590     }
591     res = GetLoaderInstance()->sha256(&kcfDataMsg, &impl->params.kcfDataSelf);
592     ClearFreeUint8Buff(&kcfDataMsg);
593     if (res != HC_SUCCESS) {
594         LOGE("Sha256 for kcfDataSelf failed, res: %x", res);
595         return res;
596     }
597     return HC_SUCCESS;
598 }
599 
600 /*
601  * kcfdataClient = SHA256(byte(0x04), PK_CLIENT_X, PK_SERVER_X, sharedSecret, base_X)
602  * kcfdataServer = SHA256(byte(0x03), PK_CLIENT_X, PK_SERVER_X, sharedSecret, base_X)
603  */
VerifyKcfDataPeer(EcSpekeProtocol * impl,bool isClient)604 static int32_t VerifyKcfDataPeer(EcSpekeProtocol *impl, bool isClient)
605 {
606     uint32_t kcfDataMsgLen = EC_SPEKE_KCF_CODE_LEN + EC_SPEKE_EC_KEY_LEN + EC_SPEKE_EC_KEY_LEN +
607         SHA256_LEN + EC_SPEKE_EC_KEY_LEN + impl->base.protectedMsg.selfMsg.length +
608         impl->base.protectedMsg.peerMsg.length;
609     Uint8Buff kcfDataMsg = { NULL, 0 };
610     if (InitUint8Buff(&kcfDataMsg, kcfDataMsgLen) != HC_SUCCESS) {
611         LOGE("allocate kcfDataMsg memory fail.");
612         return HC_ERR_ALLOC_MEMORY;
613     }
614     int32_t res = GenerateKcfDataMsg(impl, isClient, true, &kcfDataMsg);
615     if (res != HC_SUCCESS) {
616         ClearFreeUint8Buff(&kcfDataMsg);
617         return res;
618     }
619     uint8_t kcfDataPeerVal[SHA256_LEN] = { 0 };
620     Uint8Buff kcfDataPeer = { kcfDataPeerVal, SHA256_LEN };
621     res = GetLoaderInstance()->sha256(&kcfDataMsg, &kcfDataPeer);
622     ClearFreeUint8Buff(&kcfDataMsg);
623     if (res != HC_SUCCESS) {
624         LOGE("Sha256 for kcfDataPeer failed, res: %x", res);
625         return res;
626     }
627     if (memcmp(kcfDataPeer.val, impl->params.kcfDataPeer.val, kcfDataPeer.length) != 0) {
628         LOGE("verify kcfData fail.");
629         (void)memset_s(kcfDataPeer.val, kcfDataPeer.length, 0, kcfDataPeer.length);
630         return PROOF_MISMATCH;
631     }
632     return HC_SUCCESS;
633 }
634 
CalSessionKey(EcSpekeProtocol * impl)635 static int32_t CalSessionKey(EcSpekeProtocol *impl)
636 {
637     if (InitUint8Buff(&impl->base.sessionKey, EC_SPEKE_SESSION_KEY_LEN) != HC_SUCCESS) {
638         LOGE("allocate sessionKey memory fail.");
639         return HC_ERR_ALLOC_MEMORY;
640     }
641     Uint8Buff keyInfo = { (uint8_t *)HICHAIN_SPEKE_SESSIONKEY_INFO, HcStrlen(HICHAIN_SPEKE_SESSIONKEY_INFO) };
642     KeyParams keyParams = {
643         { impl->params.sharedSecret.val, impl->params.sharedSecret.length, false },
644         false,
645         impl->params.osAccountId
646     };
647     int32_t res = GetLoaderInstance()->computeHkdf(&keyParams, &impl->params.salt, &keyInfo,
648         &impl->base.sessionKey);
649     ClearFreeUint8Buff(&impl->params.salt);
650     ClearFreeUint8Buff(&impl->params.sharedSecret);
651     if (res != HC_SUCCESS) {
652         LOGE("ComputeHkdf for sessionKey failed, res: %x", res);
653         return res;
654     }
655     return HC_SUCCESS;
656 }
657 
EcSpekeServerStartRspProcEvent(EcSpekeProtocol * impl)658 static int32_t EcSpekeServerStartRspProcEvent(EcSpekeProtocol *impl)
659 {
660     int32_t res = CalSalt(&impl->params);
661     if (res != HC_SUCCESS) {
662         return res;
663     }
664     uint8_t secretVal[EC_SPEKE_SECRET_LEN] = { 0 };
665     Uint8Buff secret = { secretVal, EC_SPEKE_SECRET_LEN };
666     res = CalSecret(&impl->params, &secret);
667     if (res != HC_SUCCESS) {
668         return res;
669     }
670     res = EcSpekeCalBase(&impl->params, &secret);
671     if (res != HC_SUCCESS) {
672         return res;
673     }
674     res = EcSpekeCalEskSelf(&impl->params);
675     if (res != HC_SUCCESS) {
676         return res;
677     }
678     return EcSpekeCalEpkSelf(&impl->params);
679 }
680 
EcSpekeServerStartRspBuildEvent(const EcSpekeParams * params,CJson ** outputEvent)681 static int32_t EcSpekeServerStartRspBuildEvent(const EcSpekeParams *params, CJson **outputEvent)
682 {
683     CJson *json = CreateJson();
684     if (json == NULL) {
685         LOGE("create json failed.");
686         return HC_ERR_JSON_CREATE;
687     }
688     if (AddIntToJson(json, FIELD_EVENT, SERVER_START_RSP_EVENT) != HC_SUCCESS) {
689         LOGE("add eventName to json fail.");
690         FreeJson(json);
691         return HC_ERR_JSON_ADD;
692     }
693     if (AddByteToJson(json, FIELD_SALT, params->salt.val, params->salt.length) != HC_SUCCESS) {
694         LOGE("add salt to json fail.");
695         FreeJson(json);
696         return HC_ERR_JSON_ADD;
697     }
698     if (AddByteToJson(json, FIELD_EPK_SERVER, params->epkSelf.val, params->epkSelf.length) != HC_SUCCESS) {
699         LOGE("add epkS to json fail.");
700         FreeJson(json);
701         return HC_ERR_JSON_ADD;
702     }
703     if (AddByteToJson(json, FIELD_AUTH_ID_SERVER, params->authIdSelf.val,
704         params->authIdSelf.length) != HC_SUCCESS) {
705         LOGE("add authIdS to json fail.");
706         FreeJson(json);
707         return HC_ERR_JSON_ADD;
708     }
709     *outputEvent = json;
710     return HC_SUCCESS;
711 }
712 
EcSpekeServerStartRsp(EcSpekeProtocol * impl,const CJson * inputEvent,CJson ** outputEvent)713 static int32_t EcSpekeServerStartRsp(EcSpekeProtocol *impl, const CJson *inputEvent, CJson **outputEvent)
714 {
715     int32_t res = EcSpekeServerStartRspParseEvent(inputEvent, &impl->params);
716     if (res != HC_SUCCESS) {
717         return res;
718     }
719     res = EcSpekeServerStartRspProcEvent(impl);
720     if (res != HC_SUCCESS) {
721         return res;
722     }
723     return EcSpekeServerStartRspBuildEvent(&impl->params, outputEvent);
724 }
725 
EcSpekeClientFinishReqParseEvent(const CJson * inputEvent,EcSpekeParams * params)726 static int32_t EcSpekeClientFinishReqParseEvent(const CJson *inputEvent, EcSpekeParams *params)
727 {
728     int32_t res = GetSaltFromInput(inputEvent, params);
729     if (res != HC_SUCCESS) {
730         return res;
731     }
732     res = GetEpkPeerFromInput(inputEvent, params, true);
733     if (res != HC_SUCCESS) {
734         return res;
735     }
736     return GetAuthIdPeerFromInput(inputEvent, params, true);
737 }
738 
EcSpekeClientFinishReqProcEvent(EcSpekeProtocol * impl)739 static int32_t EcSpekeClientFinishReqProcEvent(EcSpekeProtocol *impl)
740 {
741     uint8_t secretVal[EC_SPEKE_SECRET_LEN] = { 0 };
742     Uint8Buff secret = { secretVal, EC_SPEKE_SECRET_LEN };
743     int32_t res = CalSecret(&impl->params, &secret);
744     if (res != HC_SUCCESS) {
745         return res;
746     }
747     res = EcSpekeCalBase(&impl->params, &secret);
748     (void)memset_s(secret.val, secret.length, 0, secret.length);
749     if (res != HC_SUCCESS) {
750         return res;
751     }
752     res = EcSpekeCalEskSelf(&impl->params);
753     if (res != HC_SUCCESS) {
754         return res;
755     }
756     res = EcSpekeCalEpkSelf(&impl->params);
757     if (res != HC_SUCCESS) {
758         return res;
759     }
760     res = CheckEpkPeerValid(&impl->params);
761     if (res != HC_SUCCESS) {
762         return res;
763     }
764     res = CalSharedSecret(&impl->params);
765     if (res != HC_SUCCESS) {
766         return res;
767     }
768     return CalKcfDataSelf(impl, true);
769 }
770 
EcSpekeClientFinishReqBuildEvent(EcSpekeParams * params,CJson ** outputEvent)771 static int32_t EcSpekeClientFinishReqBuildEvent(EcSpekeParams *params, CJson **outputEvent)
772 {
773     CJson *json = CreateJson();
774     if (json == NULL) {
775         LOGE("create json failed.");
776         return HC_ERR_JSON_CREATE;
777     }
778     if (AddIntToJson(json, FIELD_EVENT, CLEINT_FINISH_REQ_EVENT) != HC_SUCCESS) {
779         LOGE("add eventName to json fail.");
780         FreeJson(json);
781         return HC_ERR_JSON_ADD;
782     }
783     if (AddByteToJson(json, FIELD_EPK_CLIENT, params->epkSelf.val, params->epkSelf.length) != HC_SUCCESS) {
784         LOGE("add epkC to json fail.");
785         FreeJson(json);
786         return HC_ERR_JSON_ADD;
787     }
788     if (AddByteToJson(json, FIELD_KCF_DATA_CLIENT, params->kcfDataSelf.val,
789         params->kcfDataSelf.length) != HC_SUCCESS) {
790         LOGE("add kcfDataC to json fail.");
791         FreeJson(json);
792         return HC_ERR_JSON_ADD;
793     }
794     *outputEvent = json;
795     return HC_SUCCESS;
796 }
797 
EcSpekeClientFinishReq(EcSpekeProtocol * impl,const CJson * inputEvent,CJson ** outputEvent)798 static int32_t EcSpekeClientFinishReq(EcSpekeProtocol *impl, const CJson *inputEvent, CJson **outputEvent)
799 {
800     int32_t res = EcSpekeClientFinishReqParseEvent(inputEvent, &impl->params);
801     if (res != HC_SUCCESS) {
802         return res;
803     }
804     res = EcSpekeClientFinishReqProcEvent(impl);
805     if (res != HC_SUCCESS) {
806         return res;
807     }
808     return EcSpekeClientFinishReqBuildEvent(&impl->params, outputEvent);
809 }
810 
EcSpekeServerFinishRspParseEvent(const CJson * inputEvent,EcSpekeParams * params)811 static int32_t EcSpekeServerFinishRspParseEvent(const CJson *inputEvent, EcSpekeParams *params)
812 {
813     int32_t res = GetEpkPeerFromInput(inputEvent, params, false);
814     if (res != HC_SUCCESS) {
815         return res;
816     }
817     return GetKcfDataPeerFromInput(inputEvent, params, false);
818 }
819 
EcSpekeServerFinishRspProcEvent(EcSpekeProtocol * impl)820 static int32_t EcSpekeServerFinishRspProcEvent(EcSpekeProtocol *impl)
821 {
822     int32_t res = CheckEpkPeerValid(&impl->params);
823     if (res != HC_SUCCESS) {
824         return res;
825     }
826     res = CalSharedSecret(&impl->params);
827     if (res != HC_SUCCESS) {
828         return res;
829     }
830     res = VerifyKcfDataPeer(impl, false);
831     if (res != HC_SUCCESS) {
832         return res;
833     }
834     res = CalKcfDataSelf(impl, false);
835     if (res != HC_SUCCESS) {
836         return res;
837     }
838     return CalSessionKey(impl);
839 }
840 
EcSpekeServerFinishRspBuildEvent(EcSpekeParams * params,CJson ** outputEvent)841 static int32_t EcSpekeServerFinishRspBuildEvent(EcSpekeParams *params, CJson **outputEvent)
842 {
843     CJson *json = CreateJson();
844     if (json == NULL) {
845         LOGE("create json failed.");
846         return HC_ERR_JSON_CREATE;
847     }
848     if (AddIntToJson(json, FIELD_EVENT, SERVER_FINISH_RSP_EVENT) != HC_SUCCESS) {
849         LOGE("add eventName to json fail.");
850         FreeJson(json);
851         return HC_ERR_JSON_ADD;
852     }
853     if (AddByteToJson(json, FIELD_KCF_DATA_SERVER, params->kcfDataSelf.val,
854         params->kcfDataSelf.length) != HC_SUCCESS) {
855         LOGE("add kcfDataS to json fail.");
856         FreeJson(json);
857         return HC_ERR_JSON_ADD;
858     }
859     *outputEvent = json;
860     return HC_SUCCESS;
861 }
862 
EcSpekeServerFinishRsp(EcSpekeProtocol * impl,const CJson * inputEvent,CJson ** outputEvent)863 static int32_t EcSpekeServerFinishRsp(EcSpekeProtocol *impl, const CJson *inputEvent, CJson **outputEvent)
864 {
865     int32_t res = EcSpekeServerFinishRspParseEvent(inputEvent, &impl->params);
866     if (res != HC_SUCCESS) {
867         return res;
868     }
869     res = EcSpekeServerFinishRspProcEvent(impl);
870     if (res != HC_SUCCESS) {
871         return res;
872     }
873     return EcSpekeServerFinishRspBuildEvent(&impl->params, outputEvent);
874 }
875 
EcSpekeClientFinishParseEvent(const CJson * inputEvent,EcSpekeParams * params)876 static int32_t EcSpekeClientFinishParseEvent(const CJson *inputEvent, EcSpekeParams *params)
877 {
878     return GetKcfDataPeerFromInput(inputEvent, params, true);
879 }
880 
EcSpekeClientFinishProcEvent(EcSpekeProtocol * impl)881 static int32_t EcSpekeClientFinishProcEvent(EcSpekeProtocol *impl)
882 {
883     int32_t res = VerifyKcfDataPeer(impl, true);
884     if (res != HC_SUCCESS) {
885         return res;
886     }
887     return CalSessionKey(impl);
888 }
889 
EcSpekeClientFinish(EcSpekeProtocol * impl,const CJson * inputEvent,CJson ** outputEvent)890 static int32_t EcSpekeClientFinish(EcSpekeProtocol *impl, const CJson *inputEvent, CJson **outputEvent)
891 {
892     (void)outputEvent;
893     int32_t res = EcSpekeClientFinishParseEvent(inputEvent, &impl->params);
894     if (res != HC_SUCCESS) {
895         return res;
896     }
897     return EcSpekeClientFinishProcEvent(impl);
898 }
899 
ReturnError(int32_t errorCode,CJson ** outputEvent)900 static void ReturnError(int32_t errorCode, CJson **outputEvent)
901 {
902     (void)errorCode;
903     (void)outputEvent;
904     return;
905 }
906 
NotifyPeerError(int32_t errorCode,CJson ** outputEvent)907 static void NotifyPeerError(int32_t errorCode, CJson **outputEvent)
908 {
909     CJson *json = CreateJson();
910     if (json == NULL) {
911         LOGE("create json failed.");
912         return;
913     }
914     if (AddIntToJson(json, FIELD_EVENT, FAIL_EVENT) != HC_SUCCESS) {
915         LOGE("add eventName to json fail.");
916         FreeJson(json);
917         return;
918     }
919     if (AddIntToJson(json, FIELD_ERR_CODE, errorCode) != HC_SUCCESS) {
920         LOGE("add errorCode to json fail.");
921         FreeJson(json);
922         return;
923     }
924     *outputEvent = json;
925     return;
926 }
927 
ThrowException(EcSpekeProtocol * impl,const CJson * inputEvent,CJson ** outputEvent)928 static int32_t ThrowException(EcSpekeProtocol *impl, const CJson *inputEvent, CJson **outputEvent)
929 {
930     (void)impl;
931     (void)outputEvent;
932     int32_t peerErrorCode = HC_ERR_PEER_ERROR;
933     (void)GetIntFromJson(inputEvent, FIELD_ERR_CODE, &peerErrorCode);
934     LOGE("An exception occurred in the peer protocol. [Code]: %d", peerErrorCode);
935     return peerErrorCode;
936 }
937 
938 static const ProtocolStateNode STATE_MACHINE[] = {
939     { CREATE_AS_CLIENT_STATE, START_AUTH_EVENT, EcSpekeClientStartReq, ReturnError, CLIENT_REQ_STATE },
940     { CREATE_AS_SERVER_STATE, CLEINT_START_REQ_EVENT, EcSpekeServerStartRsp, NotifyPeerError, SERVER_RSP_STATE },
941     { CLIENT_REQ_STATE, SERVER_START_RSP_EVENT, EcSpekeClientFinishReq, NotifyPeerError, CLIENT_FINISH_REQ_STATE },
942     { CLIENT_REQ_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
943     { SERVER_RSP_STATE, CLEINT_FINISH_REQ_EVENT, EcSpekeServerFinishRsp, NotifyPeerError, SERVER_FINISH_STATE },
944     { SERVER_RSP_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
945     { CLIENT_FINISH_REQ_STATE, SERVER_FINISH_RSP_EVENT, EcSpekeClientFinish, NotifyPeerError, CLIENT_FINISH_STATE },
946     { CLIENT_FINISH_REQ_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
947 };
948 
DecodeEvent(const CJson * receviedMsg)949 static int32_t DecodeEvent(const CJson *receviedMsg)
950 {
951     if (receviedMsg == NULL) {
952         return START_AUTH_EVENT;
953     }
954     int32_t event;
955     if (GetIntFromJson(receviedMsg, FIELD_EVENT, &event) != HC_SUCCESS) {
956         LOGE("get event from receviedMsg fail.");
957         return UNKNOWN_EVENT;
958     }
959     if (START_AUTH_EVENT <= event && event <= UNKNOWN_EVENT) {
960         return event;
961     }
962     LOGE("unknown event.");
963     return UNKNOWN_EVENT;
964 }
965 
EcSpekeProtocolSwitchState(BaseProtocol * self,const CJson * receviedMsg,CJson ** returnSendMsg)966 static int32_t EcSpekeProtocolSwitchState(BaseProtocol *self, const CJson *receviedMsg, CJson **returnSendMsg)
967 {
968     int32_t eventType = DecodeEvent(receviedMsg);
969     for (uint32_t i = 0; i < sizeof(STATE_MACHINE) / sizeof(STATE_MACHINE[0]); i++) {
970         if ((STATE_MACHINE[i].curState == self->curState) && (STATE_MACHINE[i].eventType == eventType)) {
971             int32_t res = STATE_MACHINE[i].stateProcessFunc((EcSpekeProtocol *)self, receviedMsg, returnSendMsg);
972             if (res != HC_SUCCESS) {
973                 STATE_MACHINE[i].exceptionHandleFunc(res, returnSendMsg);
974                 self->curState = self->failState;
975                 return res;
976             }
977             LOGI("event: %d, curState: %d, nextState: %d", eventType, self->curState, STATE_MACHINE[i].nextState);
978             self->curState = STATE_MACHINE[i].nextState;
979             return HC_SUCCESS;
980         }
981     }
982     LOGI("Unsupported event type. Ignore process. [Event]: %d, [CurState]: %d", eventType, self->curState);
983     return HC_SUCCESS;
984 }
985 
StartEcSpekeProtocol(BaseProtocol * self,CJson ** returnSendMsg)986 static int32_t StartEcSpekeProtocol(BaseProtocol *self, CJson **returnSendMsg)
987 {
988     if ((self == NULL) || (returnSendMsg == NULL)) {
989         LOGE("invalid params.");
990         return HC_ERR_INVALID_PARAMS;
991     }
992     if ((self->curState == self->finishState) || (self->curState == self->failState)) {
993         LOGE("The protocol has ended, and the state switch cannot continue!");
994         return HC_ERR_UNSUPPORTED_OPCODE;
995     }
996     return EcSpekeProtocolSwitchState(self, NULL, returnSendMsg);
997 }
998 
ProcessEcSpekeProtocol(BaseProtocol * self,const CJson * receviedMsg,CJson ** returnSendMsg)999 static int32_t ProcessEcSpekeProtocol(BaseProtocol *self, const CJson *receviedMsg, CJson **returnSendMsg)
1000 {
1001     if ((self == NULL) || (receviedMsg == NULL) || (returnSendMsg == NULL)) {
1002         LOGE("invalid params.");
1003         return HC_ERR_INVALID_PARAMS;
1004     }
1005     if ((self->curState == self->finishState) || (self->curState == self->failState)) {
1006         LOGE("The protocol has ended, and the state switch cannot continue!");
1007         return HC_ERR_UNSUPPORTED_OPCODE;
1008     }
1009     return EcSpekeProtocolSwitchState(self, receviedMsg, returnSendMsg);
1010 }
1011 
SetEcSpekePsk(BaseProtocol * self,const Uint8Buff * psk)1012 static int32_t SetEcSpekePsk(BaseProtocol *self, const Uint8Buff *psk)
1013 {
1014     if ((self == NULL) || (psk == NULL) || (psk->val == NULL) || (psk->length == 0)) {
1015         LOGE("invalid params.");
1016         return HC_ERR_INVALID_PARAMS;
1017     }
1018     EcSpekeProtocol *impl = (EcSpekeProtocol *)self;
1019     if (DeepCopyUint8Buff(psk, &impl->params.psk) != HC_SUCCESS) {
1020         LOGE("copy psk fail.");
1021         return HC_ERR_ALLOC_MEMORY;
1022     }
1023     LOGI("set psk success.");
1024     return HC_SUCCESS;
1025 }
1026 
SetEcSpekeSelfProtectedMsg(BaseProtocol * self,const Uint8Buff * selfMsg)1027 static int32_t SetEcSpekeSelfProtectedMsg(BaseProtocol *self, const Uint8Buff *selfMsg)
1028 {
1029     if ((self == NULL) || !IsUint8BuffValid(selfMsg, PROTECTED_MSG_MAX_LEN)) {
1030         LOGE("invalid params.");
1031         return HC_ERR_INVALID_PARAMS;
1032     }
1033     if (DeepCopyUint8Buff(selfMsg, &self->protectedMsg.selfMsg) != HC_SUCCESS) {
1034         LOGE("copy protected self msg fail.");
1035         return HC_ERR_ALLOC_MEMORY;
1036     }
1037     return HC_SUCCESS;
1038 }
1039 
SetEcSpekePeerProtectedMsg(BaseProtocol * self,const Uint8Buff * peerMsg)1040 static int32_t SetEcSpekePeerProtectedMsg(BaseProtocol *self, const Uint8Buff *peerMsg)
1041 {
1042     if ((self == NULL) || !IsUint8BuffValid(peerMsg, PROTECTED_MSG_MAX_LEN)) {
1043         LOGE("invalid params.");
1044         return HC_ERR_INVALID_PARAMS;
1045     }
1046     if (DeepCopyUint8Buff(peerMsg, &self->protectedMsg.peerMsg) != HC_SUCCESS) {
1047         LOGE("copy protected peer msg fail.");
1048         return HC_ERR_ALLOC_MEMORY;
1049     }
1050     return HC_SUCCESS;
1051 }
1052 
GetEcSpekeSessionKey(BaseProtocol * self,Uint8Buff * returnSessionKey)1053 static int32_t GetEcSpekeSessionKey(BaseProtocol *self, Uint8Buff *returnSessionKey)
1054 {
1055     if ((self == NULL) || (returnSessionKey == NULL)) {
1056         LOGE("invalid params.");
1057         return HC_ERR_INVALID_PARAMS;
1058     }
1059     if (self->curState != self->finishState) {
1060         LOGE("The protocol has not been completed, unable to obtain the protocol result!");
1061         return HC_ERR_UNSUPPORTED_OPCODE;
1062     }
1063     return DeepCopyUint8Buff(&self->sessionKey, returnSessionKey);
1064 }
1065 
DestroyEcSpekeProtocol(BaseProtocol * self)1066 static void DestroyEcSpekeProtocol(BaseProtocol *self)
1067 {
1068     if (self == NULL) {
1069         LOGD("self is null.");
1070         return;
1071     }
1072     EcSpekeProtocol *impl = (EcSpekeProtocol *)self;
1073     ClearFreeUint8Buff(&impl->base.protectedMsg.selfMsg);
1074     ClearFreeUint8Buff(&impl->base.protectedMsg.peerMsg);
1075     ClearFreeUint8Buff(&impl->base.sessionKey);
1076     ClearFreeUint8Buff(&impl->params.psk);
1077     ClearFreeUint8Buff(&impl->params.salt);
1078     ClearFreeUint8Buff(&impl->params.base);
1079     ClearFreeUint8Buff(&impl->params.eskSelf);
1080     ClearFreeUint8Buff(&impl->params.epkSelf);
1081     ClearFreeUint8Buff(&impl->params.epkPeer);
1082     ClearFreeUint8Buff(&impl->params.authIdSelf);
1083     ClearFreeUint8Buff(&impl->params.authIdPeer);
1084     ClearFreeUint8Buff(&impl->params.kcfDataSelf);
1085     ClearFreeUint8Buff(&impl->params.kcfDataPeer);
1086     ClearFreeUint8Buff(&impl->params.sharedSecret);
1087     HcFree(impl);
1088 }
1089 
BuildEcSpekeProtocolObj(const EcSpekeInitParams * params,bool isClient,EcSpekeProtocol * instance)1090 static int32_t BuildEcSpekeProtocolObj(const EcSpekeInitParams *params, bool isClient, EcSpekeProtocol *instance)
1091 {
1092     if (DeepCopyUint8Buff(&params->authId, &instance->params.authIdSelf) != HC_SUCCESS) {
1093         return HC_ERR_ALLOC_MEMORY;
1094     }
1095     instance->params.osAccountId = params->osAccountId;
1096     instance->base.name = PROTOCOL_TYPE_EC_SPEKE;
1097     instance->base.beginState = isClient ? CREATE_AS_CLIENT_STATE : CREATE_AS_SERVER_STATE;
1098     instance->base.finishState = isClient ? CLIENT_FINISH_STATE : SERVER_FINISH_STATE;
1099     instance->base.failState = FAIL_STATE;
1100     instance->base.curState = instance->base.beginState;
1101     instance->base.start = StartEcSpekeProtocol;
1102     instance->base.process = ProcessEcSpekeProtocol;
1103     instance->base.setPsk = SetEcSpekePsk;
1104     instance->base.setSelfProtectedMsg = SetEcSpekeSelfProtectedMsg;
1105     instance->base.setPeerProtectedMsg = SetEcSpekePeerProtectedMsg;
1106     instance->base.getSessionKey = GetEcSpekeSessionKey;
1107     instance->base.destroy = DestroyEcSpekeProtocol;
1108     instance->params.curveType = params->curveType;
1109     return HC_SUCCESS;
1110 }
1111 
IsCurveTypeValid(int32_t curveType)1112 static bool IsCurveTypeValid(int32_t curveType)
1113 {
1114     return (curveType == CURVE_TYPE_256 || curveType == CURVE_TYPE_25519);
1115 }
1116 
CreateEcSpekeProtocol(const void * baseParams,bool isClient,BaseProtocol ** returnObj)1117 int32_t CreateEcSpekeProtocol(const void *baseParams, bool isClient, BaseProtocol **returnObj)
1118 {
1119     const EcSpekeInitParams *params = (const EcSpekeInitParams *)baseParams;
1120     if ((params == NULL) || (returnObj == NULL) ||
1121         !IsUint8BuffValid(&params->authId, EC_SPEKE_AUTH_ID_MAX_LEN)) {
1122         LOGE("invalid params.");
1123         return HC_ERR_INVALID_PARAMS;
1124     }
1125     if (!IsCurveTypeValid(params->curveType)) {
1126         LOGE("invalid curve type. [CurveType]: %d", params->curveType);
1127         return HC_ERR_INVALID_PARAMS;
1128     }
1129     EcSpekeProtocol *instance = (EcSpekeProtocol *)HcMalloc(sizeof(EcSpekeProtocol), 0);
1130     if (instance == NULL) {
1131         LOGE("allocate instance memory fail.");
1132         return HC_ERR_ALLOC_MEMORY;
1133     }
1134     int32_t res = BuildEcSpekeProtocolObj(params, isClient, instance);
1135     if (res != HC_SUCCESS) {
1136         DestroyEcSpekeProtocol((BaseProtocol *)instance);
1137         return res;
1138     }
1139     *returnObj = (BaseProtocol *)instance;
1140     return HC_SUCCESS;
1141 }
1142