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