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