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