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