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(¶ms->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(¶ms->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(¶ms->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(¶ms->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(¶ms->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(¶ms->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(¶ms->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(¶ms->base, 2 * EC_SPEKE_EC_KEY_LEN);
227 } else if (params->curveType == CURVE_TYPE_25519) {
228 algo = X25519;
229 res = InitUint8Buff(¶ms->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, ¶ms->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(¶ms->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(¶ms->epkSelf, 2 * EC_SPEKE_EC_KEY_LEN);
285 } else if (params->curveType == CURVE_TYPE_25519) {
286 algo = X25519;
287 res = InitUint8Buff(¶ms->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, ¶ms->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(¶ms->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(¶ms->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(¶ms->sharedSecret, SHA256_LEN)) {
501 LOGE("allocate sharedSecret memory fail.");
502 ClearFreeUint8Buff(&sharedSecretMsg);
503 return HC_ERR_ALLOC_MEMORY;
504 }
505 res = GetLoaderInstance()->sha256(&sharedSecretMsg, ¶ms->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 ? ¶ms->epkSelf : ¶ms->epkPeer;
547 Uint8Buff *epkServer = isClient ? ¶ms->epkPeer : ¶ms->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(¶ms->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(¶ms->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