1 /*
2 * Copyright (C) 2021 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 "pake_v2_protocol_common.h"
17 #include "alg_loader.h"
18 #include "device_auth_defines.h"
19 #include "hc_log.h"
20 #include "hc_types.h"
21 #include "pake_defs.h"
22 #include "pake_protocol_dl_common.h"
23 #include "pake_protocol_ec_common.h"
24 #include "protocol_common.h"
25 #include "string_util.h"
26
27 #define KCF_CODE_LEN 1
28 #define PAKE_SESSION_KEY_LEN 32
29
30 static const uint8_t KCF_CODE_CLIENT[KCF_CODE_LEN] = { 0x04 };
31 static const uint8_t KCF_CODE_SERVER[KCF_CODE_LEN] = { 0x03 };
32
DestroyPakeV2BaseParams(PakeBaseParams * params)33 void DestroyPakeV2BaseParams(PakeBaseParams *params)
34 {
35 if (params == NULL) {
36 return;
37 }
38
39 CleanPakeSensitiveKeys(params);
40
41 HcFree(params->salt.val);
42 params->salt.val = NULL;
43
44 HcFree(params->challengeSelf.val);
45 params->challengeSelf.val = NULL;
46
47 HcFree(params->challengePeer.val);
48 params->challengePeer.val = NULL;
49
50 HcFree(params->epkSelf.val);
51 params->epkSelf.val = NULL;
52
53 HcFree(params->epkPeer.val);
54 params->epkPeer.val = NULL;
55
56 HcFree(params->idSelf.val);
57 params->idSelf.val = NULL;
58
59 HcFree(params->idPeer.val);
60 params->idPeer.val = NULL;
61
62 HcFree(params->kcfData.val);
63 params->kcfData.val = NULL;
64
65 HcFree(params->kcfDataPeer.val);
66 params->kcfDataPeer.val = NULL;
67
68 HcFree(params->extraData.val);
69 params->extraData.val = NULL;
70 }
71
AllocDefaultParams(PakeBaseParams * params)72 static int32_t AllocDefaultParams(PakeBaseParams *params)
73 {
74 params->salt.length = PAKE_SALT_LEN;
75 params->salt.val = (uint8_t *)HcMalloc(params->salt.length, 0);
76 if (params->salt.val == NULL) {
77 LOGE("Malloc for salt failed.");
78 return HC_ERR_ALLOC_MEMORY;
79 }
80
81 params->sharedSecret.length = SHA256_LEN;
82 params->sharedSecret.val = (uint8_t *)HcMalloc(params->sharedSecret.length, 0);
83 if (params->sharedSecret.val == NULL) {
84 LOGE("Malloc for sharedSecret failed.");
85 return HC_ERR_ALLOC_MEMORY;
86 }
87
88 params->sessionKey.length = PAKE_SESSION_KEY_LEN;
89 params->sessionKey.val = (uint8_t *)HcMalloc(params->sessionKey.length, 0);
90 if (params->sessionKey.val == NULL) {
91 LOGE("Malloc for sessionKey failed.");
92 return HC_ERR_ALLOC_MEMORY;
93 }
94
95 params->kcfData.length = HMAC_LEN;
96 params->kcfData.val = (uint8_t *)HcMalloc(params->kcfData.length, 0);
97 if (params->kcfData.val == NULL) {
98 LOGE("Malloc for kcfData failed.");
99 return HC_ERR_ALLOC_MEMORY;
100 }
101
102 params->kcfDataPeer.length = HMAC_LEN;
103 params->kcfDataPeer.val = (uint8_t *)HcMalloc(params->kcfDataPeer.length, 0);
104 if (params->kcfDataPeer.val == NULL) {
105 LOGE("Malloc for kcfDataPeer failed.");
106 return HC_ERR_ALLOC_MEMORY;
107 }
108 return HC_SUCCESS;
109 }
110
FillDefaultValue(PakeBaseParams * params)111 static void FillDefaultValue(PakeBaseParams *params)
112 {
113 params->psk.val = NULL;
114 params->psk.length = 0;
115 params->challengeSelf.val = NULL;
116 params->challengeSelf.length = 0;
117 params->challengePeer.val = NULL;
118 params->challengePeer.length = 0;
119 params->eskSelf.val = NULL;
120 params->eskSelf.length = 0;
121 params->epkSelf.val = NULL;
122 params->epkSelf.length = 0;
123 params->epkPeer.val = NULL;
124 params->epkPeer.length = 0;
125 params->base.val = NULL;
126 params->base.length = 0;
127 params->idSelf.val = NULL;
128 params->idSelf.length = 0;
129 params->idPeer.val = NULL;
130 params->idPeer.length = 0;
131 params->hmacKey.val = NULL;
132 params->hmacKey.length = 0;
133 params->extraData.val = NULL;
134 params->extraData.length = 0;
135 params->supportedDlPrimeMod = DL_PRIME_MOD_NONE;
136 params->largePrimeNumHex = NULL;
137 params->innerKeyLen = 0;
138 params->supportedPakeAlg = PAKE_ALG_NONE;
139 params->curveType = CURVE_NONE;
140 params->isClient = true;
141 }
142
InitPakeV2BaseParams(int32_t osAccountId,PakeBaseParams * params)143 int32_t InitPakeV2BaseParams(int32_t osAccountId, PakeBaseParams *params)
144 {
145 if (params == NULL) {
146 LOGE("Params is null.");
147 return HC_ERR_NULL_PTR;
148 }
149 params->osAccountId = osAccountId;
150
151 int32_t res = AllocDefaultParams(params);
152 if (res != HC_SUCCESS) {
153 goto CLEAN_UP;
154 }
155
156 FillDefaultValue(params);
157
158 params->loader = GetLoaderInstance();
159 if (params->loader == NULL) {
160 res = HC_ERROR;
161 goto CLEAN_UP;
162 }
163
164 return HC_SUCCESS;
165 CLEAN_UP:
166 DestroyPakeV2BaseParams(params);
167 return res;
168 }
169
GeneratePakeParams(PakeBaseParams * params)170 static int32_t GeneratePakeParams(PakeBaseParams *params)
171 {
172 int32_t res;
173 uint8_t secretVal[PAKE_SECRET_LEN] = { 0 };
174 Uint8Buff secret = { secretVal, PAKE_SECRET_LEN };
175 if (!params->isClient) {
176 res = params->loader->generateRandom(&(params->salt));
177 if (res != HC_SUCCESS) {
178 LOGE("Generate salt failed, res: %x.", res);
179 goto CLEAN_UP;
180 }
181 }
182
183 Uint8Buff keyInfo = { (uint8_t *)HICHAIN_SPEKE_BASE_INFO, HcStrlen(HICHAIN_SPEKE_BASE_INFO) };
184 KeyParams keyParams = { { params->psk.val, params->psk.length, false }, false, params->osAccountId };
185 res = params->loader->computeHkdf(&keyParams, &(params->salt), &keyInfo, &secret);
186 if (res != HC_SUCCESS) {
187 LOGE("Derive secret from psk failed, res: %x.", res);
188 goto CLEAN_UP;
189 }
190 FreeAndCleanKey(¶ms->psk);
191
192 if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_EC) != 0) {
193 res = GenerateEcPakeParams(params, &secret);
194 } else if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_DL) != 0) {
195 res = GenerateDlPakeParams(params, &secret);
196 } else {
197 res = HC_ERR_INVALID_ALG;
198 }
199 if (res != HC_SUCCESS) {
200 LOGE("GeneratePakeParams failed, pakeAlgType: 0x%x, res: 0x%x.", params->supportedPakeAlg, res);
201 goto CLEAN_UP;
202 }
203 (void)memset_s(secret.val, secret.length, 0, secret.length);
204 return res;
205 CLEAN_UP:
206 (void)memset_s(secret.val, secret.length, 0, secret.length);
207 CleanPakeSensitiveKeys(params);
208 return res;
209 }
210
ComputeSidSelf(const PakeBaseParams * params,Uint8Buff * sidSelf)211 static int32_t ComputeSidSelf(const PakeBaseParams *params, Uint8Buff *sidSelf)
212 {
213 int res;
214 Uint8Buff idSelfMsg = { NULL, params->idSelf.length + params->innerKeyLen };
215 idSelfMsg.val = (uint8_t *)HcMalloc(idSelfMsg.length, 0);
216 if (idSelfMsg.val == NULL) {
217 LOGE("Malloc for idSelfMsg failed.");
218 res = HC_ERR_ALLOC_MEMORY;
219 goto CLEAN_UP;
220 }
221
222 if (memcpy_s(idSelfMsg.val, idSelfMsg.length, params->idSelf.val, params->idSelf.length) != EOK) {
223 LOGE("Memcpy for idSelf failed.");
224 res = HC_ERR_MEMORY_COPY;
225 goto CLEAN_UP;
226 }
227 if (memcpy_s(idSelfMsg.val + params->idSelf.length, idSelfMsg.length - params->idSelf.length,
228 params->epkSelf.val, params->innerKeyLen) != EOK) { // only need x-coordinate
229 LOGE("Memcpy for epkSelf failed.");
230 res = HC_ERR_MEMORY_COPY;
231 goto CLEAN_UP;
232 }
233 res = params->loader->sha256(&idSelfMsg, sidSelf);
234 if (res != HC_SUCCESS) {
235 LOGE("Sha256 for idSelfMsg failed, res: %x.", res);
236 goto CLEAN_UP;
237 }
238 CLEAN_UP:
239 HcFree(idSelfMsg.val);
240 return res;
241 }
242
ComputeSidPeer(const PakeBaseParams * params,Uint8Buff * sidPeer)243 static int32_t ComputeSidPeer(const PakeBaseParams *params, Uint8Buff *sidPeer)
244 {
245 int res;
246 Uint8Buff idPeerMsg = { NULL, params->idPeer.length + params->innerKeyLen };
247 idPeerMsg.val = (uint8_t *)HcMalloc(idPeerMsg.length, 0);
248 if (idPeerMsg.val == NULL) {
249 LOGE("Malloc for idPeerMsg failed.");
250 res = HC_ERR_ALLOC_MEMORY;
251 goto CLEAN_UP;
252 }
253
254 if (memcpy_s(idPeerMsg.val, idPeerMsg.length, params->idPeer.val, params->idPeer.length) != EOK) {
255 LOGE("Memcpy for idPeer failed.");
256 res = HC_ERR_MEMORY_COPY;
257 goto CLEAN_UP;
258 }
259 if (memcpy_s(idPeerMsg.val + params->idPeer.length, idPeerMsg.length - params->idPeer.length,
260 params->epkPeer.val, params->innerKeyLen) != EOK) { // only need x-coordinate
261 LOGE("Memcpy for epkPeer failed.");
262 res = HC_ERR_MEMORY_COPY;
263 goto CLEAN_UP;
264 }
265 res = params->loader->sha256(&idPeerMsg, sidPeer);
266 if (res != HC_SUCCESS) {
267 LOGE("Sha256 for idPeerMsg failed, res: %x.", res);
268 goto CLEAN_UP;
269 }
270 CLEAN_UP:
271 HcFree(idPeerMsg.val);
272 return res;
273 }
274
ComputeSid(const PakeBaseParams * params,Uint8Buff * sid)275 static int32_t ComputeSid(const PakeBaseParams *params, Uint8Buff *sid)
276 {
277 int32_t res = HC_ERR_ALLOC_MEMORY;
278 Uint8Buff sidSelf = { NULL, SHA256_LEN };
279 Uint8Buff sidPeer = { NULL, SHA256_LEN };
280
281 sidSelf.val = (uint8_t *)HcMalloc(sidSelf.length, 0);
282 if (sidSelf.val == NULL) {
283 LOGE("Malloc for sidSelf failed.");
284 goto CLEAN_UP;
285 }
286 sidPeer.val = (uint8_t *)HcMalloc(sidPeer.length, 0);
287 if (sidPeer.val == NULL) {
288 LOGE("Malloc for sidPeer failed.");
289 goto CLEAN_UP;
290 }
291
292 res = ComputeSidSelf(params, &sidSelf);
293 if (res != HC_SUCCESS) {
294 LOGE("ComputeSidSelf failed, res: %x", res);
295 goto CLEAN_UP;
296 }
297
298 res = ComputeSidPeer(params, &sidPeer);
299 if (res != HC_SUCCESS) {
300 LOGE("ComputeSidPeer failed, res: %x", res);
301 goto CLEAN_UP;
302 }
303
304 Uint8Buff *maxId = NULL;
305 Uint8Buff *minId = NULL;
306 int result = params->loader->bigNumCompare(&sidSelf, &sidPeer);
307 if (result <= 0) {
308 maxId = &sidSelf;
309 minId = &sidPeer;
310 } else {
311 maxId = &sidPeer;
312 minId = &sidSelf;
313 }
314
315 if (memcpy_s(sid->val, sid->length, maxId->val, maxId->length) != EOK) {
316 LOGE("Memcpy for maxId failed.");
317 res = HC_ERR_MEMORY_COPY;
318 goto CLEAN_UP;
319 }
320 if (memcpy_s(sid->val + maxId->length, sid->length - maxId->length, minId->val, minId->length) != EOK) {
321 LOGE("Memcpy for minId failed.");
322 res = HC_ERR_MEMORY_COPY;
323 goto CLEAN_UP;
324 }
325 CLEAN_UP:
326 HcFree(sidSelf.val);
327 HcFree(sidPeer.val);
328 return res;
329 }
330
ComputeSharedSecret(PakeBaseParams * params,const Uint8Buff * sid,const Uint8Buff * tmpSharedSecret)331 static int32_t ComputeSharedSecret(PakeBaseParams *params, const Uint8Buff *sid, const Uint8Buff *tmpSharedSecret)
332 {
333 int32_t res;
334 Uint8Buff sharedSecretMsg = { NULL, 0 };
335 sharedSecretMsg.length = sid->length + params->innerKeyLen + HcStrlen(SHARED_SECRET_DERIVED_FACTOR);
336 sharedSecretMsg.val = (uint8_t *)HcMalloc(sharedSecretMsg.length, 0);
337 if (sharedSecretMsg.val == NULL) {
338 LOGE("Malloc for sharedSecretMsg failed.");
339 return HC_ERR_ALLOC_MEMORY;
340 }
341
342 uint32_t usedLen = 0;
343 if (memcpy_s(sharedSecretMsg.val, sharedSecretMsg.length, sid->val, sid->length) != EOK) {
344 LOGE("Memcpy for sidHex failed.");
345 res = HC_ERR_MEMORY_COPY;
346 goto CLEAN_UP;
347 }
348 usedLen += sid->length;
349 if (memcpy_s(sharedSecretMsg.val + usedLen, sharedSecretMsg.length - usedLen,
350 tmpSharedSecret->val, params->innerKeyLen) != EOK) { // Only need x-coordinate
351 LOGE("Memcpy for tmpSharedSecret failed.");
352 res = HC_ERR_MEMORY_COPY;
353 goto CLEAN_UP;
354 }
355 usedLen += params->innerKeyLen;
356 if (memcpy_s(sharedSecretMsg.val + usedLen, sharedSecretMsg.length - usedLen,
357 SHARED_SECRET_DERIVED_FACTOR, HcStrlen(SHARED_SECRET_DERIVED_FACTOR)) != EOK) {
358 LOGE("Memcpy for sharedSecret derived factor failed.");
359 res = HC_ERR_MEMORY_COPY;
360 goto CLEAN_UP;
361 }
362
363 res = params->loader->sha256(&sharedSecretMsg, ¶ms->sharedSecret);
364 if (res != HC_SUCCESS) {
365 LOGE("Sha256 for sharedSecretMsg failed, res: %x.", res);
366 goto CLEAN_UP;
367 }
368 CLEAN_UP:
369 FreeAndCleanKey(&sharedSecretMsg);
370 return res;
371 }
372
373 /*
374 * '|' means joint
375 * Z = epkB . eskA
376 * A = hash(idA | epkA_X)
377 * B = hash(idB | epkB_X)
378 * sid = MAX(A, B) | MIN(A, B)
379 * sharedSecret = hash(hex(sid) | Z_X | derivedFactor)
380 */
GenerateSharedSecret(PakeBaseParams * params)381 static int32_t GenerateSharedSecret(PakeBaseParams *params)
382 {
383 int32_t res;
384 Uint8Buff tmpSharedSecret = { NULL, 0 };
385 Uint8Buff sid = { NULL, SHA256_LEN * 2 }; // sid is composed of client sid and server sid, so need twice SHA256_LEN
386 /* The key of P256 requires both X and Y coordinates values to represent it. */
387 tmpSharedSecret.length = (params->curveType == CURVE_256) ? (params->innerKeyLen * 2) : (params->innerKeyLen);
388 tmpSharedSecret.val = (uint8_t *)HcMalloc(tmpSharedSecret.length, 0);
389 if (tmpSharedSecret.val == NULL) {
390 LOGE("Malloc for tmpSharedSecret failed.");
391 res = HC_ERR_ALLOC_MEMORY;
392 goto CLEAN_UP;
393 }
394 if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_EC) != 0) {
395 res = AgreeEcSharedSecret(params, &tmpSharedSecret);
396 } else if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_DL) != 0) {
397 res = AgreeDlSharedSecret(params, &tmpSharedSecret);
398 } else {
399 res = HC_ERR_INVALID_ALG;
400 }
401 if (res != HC_SUCCESS) {
402 LOGE("Agree intermediate sharedSecret failed, pakeAlgType: 0x%x, res: %x.", params->supportedPakeAlg, res);
403 goto CLEAN_UP;
404 }
405 FreeAndCleanKey(¶ms->eskSelf);
406 sid.val = (uint8_t *)HcMalloc(sid.length, 0);
407 if (sid.val == NULL) {
408 LOGE("Malloc for sid failed.");
409 res = HC_ERR_ALLOC_MEMORY;
410 goto CLEAN_UP;
411 }
412 res = ComputeSid(params, &sid);
413 if (res != HC_SUCCESS) {
414 LOGE("Compute sid failed, res: %x.", res);
415 goto CLEAN_UP;
416 }
417 res = ComputeSharedSecret(params, &sid, &tmpSharedSecret);
418 if (res != HC_SUCCESS) {
419 LOGE("ComputeSharedSecret failed, res: %x.", res);
420 goto CLEAN_UP;
421 }
422 goto OUT;
423 CLEAN_UP:
424 CleanPakeSensitiveKeys(params);
425 OUT:
426 FreeAndCleanKey(&sid);
427 FreeAndCleanKey(&tmpSharedSecret);
428 return res;
429 }
430
CombineEpk(const Uint8Buff * epkClient,const Uint8Buff * epkServer,uint32_t epkLenX,Uint8Buff * proofMsg,uint32_t * usedLen)431 static int32_t CombineEpk(const Uint8Buff *epkClient, const Uint8Buff *epkServer, uint32_t epkLenX,
432 Uint8Buff *proofMsg, uint32_t *usedLen)
433 {
434 if (memcpy_s(proofMsg->val + *usedLen, proofMsg->length - *usedLen,
435 epkClient->val, epkLenX) != EOK) { // Only the x-coordinate of epk is required
436 LOGE("Memcpy for epkClient failed.");
437 return HC_ERR_MEMORY_COPY;
438 }
439 *usedLen += epkLenX;
440 if (memcpy_s(proofMsg->val + *usedLen, proofMsg->length - *usedLen,
441 epkServer->val, epkLenX) != EOK) { // Only the x-coordinate of epk is required
442 LOGE("Memcpy for epkServer failed.");
443 return HC_ERR_MEMORY_COPY;
444 }
445 *usedLen += epkLenX;
446 return HC_SUCCESS;
447 }
448
CombineProofMsg(const PakeBaseParams * params,Uint8Buff * proofMsg,bool isVerify)449 static int32_t CombineProofMsg(const PakeBaseParams *params, Uint8Buff *proofMsg, bool isVerify)
450 {
451 int32_t res;
452 uint32_t usedLen = 0;
453 const uint8_t *kcfCode = NULL;
454
455 if ((params->isClient && !isVerify) || (!params->isClient && isVerify)) {
456 kcfCode = KCF_CODE_CLIENT;
457 } else {
458 kcfCode = KCF_CODE_SERVER;
459 }
460 if (memcpy_s(proofMsg->val, proofMsg->length, kcfCode, KCF_CODE_LEN) != HC_SUCCESS) {
461 LOGE("Memcpy for g_kcfCode failed.");
462 return HC_ERR_MEMORY_COPY;
463 }
464 usedLen += KCF_CODE_LEN;
465 if (params->isClient) {
466 res = CombineEpk(¶ms->epkSelf, ¶ms->epkPeer, params->innerKeyLen, proofMsg, &usedLen);
467 } else {
468 res = CombineEpk(¶ms->epkPeer, ¶ms->epkSelf, params->innerKeyLen, proofMsg, &usedLen);
469 }
470 if (res != HC_SUCCESS) {
471 LOGE("CombineEpk failed, res: %x.", res);
472 return res;
473 }
474 if (memcpy_s(proofMsg->val + usedLen, proofMsg->length - usedLen,
475 params->sharedSecret.val, params->sharedSecret.length) != EOK) {
476 LOGE("Memcpy for sharedSecret failed.");
477 return HC_ERR_MEMORY_COPY;
478 }
479 usedLen += params->sharedSecret.length;
480 /* base only need x-coordinate */
481 if (memcpy_s(proofMsg->val + usedLen, proofMsg->length - usedLen, params->base.val, params->innerKeyLen) != EOK) {
482 LOGE("Memcpy for base failed.");
483 return HC_ERR_MEMORY_COPY;
484 }
485 usedLen += params->innerKeyLen;
486 if ((params->extraData.val != NULL) && (memcpy_s(proofMsg->val + usedLen, proofMsg->length - usedLen,
487 params->extraData.val, params->extraData.length) != EOK)) {
488 LOGE("Memcpy for extraData failed.");
489 return HC_ERR_MEMORY_COPY;
490 }
491 return HC_SUCCESS;
492 }
493
494 /*
495 * msg = challenge_self + challenge_peer
496 * kcfdata = SHA256(byte(code), PK_CLIENT_X, PK_SERVER_X, sharedSecret, base_X)
497 */
GenerateProof(PakeBaseParams * params)498 static int32_t GenerateProof(PakeBaseParams *params)
499 {
500 int res;
501 Uint8Buff proofMsg = { NULL, 0 };
502 proofMsg.length = KCF_CODE_LEN + params->innerKeyLen + params->innerKeyLen +
503 params->sharedSecret.length + params->innerKeyLen + params->extraData.length;
504 proofMsg.val = (uint8_t *)HcMalloc(proofMsg.length, 0);
505 if (proofMsg.val == NULL) {
506 LOGE("Malloc for proofMsg failed.");
507 res = HC_ERR_ALLOC_MEMORY;
508 goto CLEAN_UP;
509 }
510 res = CombineProofMsg(params, &proofMsg, false);
511 if (res != HC_SUCCESS) {
512 LOGE("CombineProofMsg failed, res: %x.", res);
513 goto CLEAN_UP;
514 }
515 res = params->loader->sha256(&proofMsg, ¶ms->kcfData);
516 if (res != HC_SUCCESS) {
517 LOGE("Sha256 for proofMsg failed, res: %x.", res);
518 goto CLEAN_UP;
519 }
520 goto OUT;
521 CLEAN_UP:
522 CleanPakeSensitiveKeys(params);
523 OUT:
524 FreeAndCleanKey(&proofMsg);
525 return res;
526 }
527
VerifyProof(PakeBaseParams * params)528 static int32_t VerifyProof(PakeBaseParams *params)
529 {
530 int res;
531 Uint8Buff proofMsg = { NULL, 0 };
532 proofMsg.length = KCF_CODE_LEN + params->innerKeyLen + params->innerKeyLen +
533 params->sharedSecret.length + params->innerKeyLen + params->extraData.length;
534 proofMsg.val = (uint8_t *)HcMalloc(proofMsg.length, 0);
535 if (proofMsg.val == NULL) {
536 LOGE("Malloc for proofMsg failed.");
537 res = HC_ERR_ALLOC_MEMORY;
538 goto CLEAN_UP;
539 }
540 res = CombineProofMsg(params, &proofMsg, true);
541 if (res != HC_SUCCESS) {
542 LOGE("CombineProofMsg failed, res: %x.", res);
543 goto CLEAN_UP;
544 }
545
546 uint8_t tmpKcfDataVal[SHA256_LEN] = { 0 };
547 Uint8Buff tmpKcfData = { tmpKcfDataVal, SHA256_LEN };
548 res = params->loader->sha256(&proofMsg, &tmpKcfData);
549 if (res != HC_SUCCESS) {
550 LOGE("Sha256 for proofMsg failed, res: %x.", res);
551 goto CLEAN_UP;
552 }
553 if (memcmp(tmpKcfData.val, params->kcfDataPeer.val, tmpKcfData.length) != EOK) {
554 LOGE("Compare kcfData failed.");
555 res = PROOF_MISMATCH;
556 goto CLEAN_UP;
557 }
558 goto OUT;
559 CLEAN_UP:
560 CleanPakeSensitiveKeys(params);
561 OUT:
562 FreeAndCleanKey(&proofMsg);
563 return res;
564 }
565
GenerateSessionKey(PakeBaseParams * params)566 static int32_t GenerateSessionKey(PakeBaseParams *params)
567 {
568 Uint8Buff keyInfo = { (uint8_t *)HICHAIN_SPEKE_SESSIONKEY_INFO, HcStrlen(HICHAIN_SPEKE_SESSIONKEY_INFO) };
569 KeyParams keyParams = {
570 .keyBuff = { params->sharedSecret.val, params->sharedSecret.length, false },
571 .isDeStorage = false,
572 .osAccountId = params->osAccountId
573 };
574 int res = params->loader->computeHkdf(&keyParams, ¶ms->salt, &keyInfo, ¶ms->sessionKey);
575 if (res != HC_SUCCESS) {
576 LOGE("ComputeHkdf for sessionKey failed, res: %x.", res);
577 CleanPakeSensitiveKeys(params);
578 }
579 FreeAndCleanKey(¶ms->base);
580 FreeAndCleanKey(¶ms->sharedSecret);
581 return res;
582 }
583
ClientConfirmPakeV2Protocol(PakeBaseParams * params)584 int32_t ClientConfirmPakeV2Protocol(PakeBaseParams *params)
585 {
586 if (params == NULL) {
587 LOGE("Params is null.");
588 return HC_ERR_NULL_PTR;
589 }
590 int32_t res = GeneratePakeParams(params);
591 if (res != HC_SUCCESS) {
592 LOGE("GeneratePakeParams failed, res: %x.", res);
593 goto CLEAN_UP;
594 }
595 res = GenerateSharedSecret(params);
596 if (res != HC_SUCCESS) {
597 LOGE("GenerateSharedSecret failed, res: %x.", res);
598 goto CLEAN_UP;
599 }
600 res = GenerateProof(params);
601 if (res != HC_SUCCESS) {
602 LOGE("GenerateProof failed, res: %x.", res);
603 goto CLEAN_UP;
604 }
605 return res;
606 CLEAN_UP:
607 CleanPakeSensitiveKeys(params);
608 return res;
609 }
610
ClientVerifyConfirmPakeV2Protocol(PakeBaseParams * params)611 int32_t ClientVerifyConfirmPakeV2Protocol(PakeBaseParams *params)
612 {
613 if (params == NULL) {
614 LOGE("Params is null.");
615 return HC_ERR_NULL_PTR;
616 }
617 int32_t res = VerifyProof(params);
618 if (res != HC_SUCCESS) {
619 LOGE("VerifyProof failed, res: %x.", res);
620 goto CLEAN_UP;
621 }
622
623 res = GenerateSessionKey(params);
624 if (res != HC_SUCCESS) {
625 LOGE("GenerateSessionKey failed, res: %x.", res);
626 goto CLEAN_UP;
627 }
628 return res;
629 CLEAN_UP:
630 CleanPakeSensitiveKeys(params);
631 return res;
632 }
633
ServerResponsePakeV2Protocol(PakeBaseParams * params)634 int32_t ServerResponsePakeV2Protocol(PakeBaseParams *params)
635 {
636 if (params == NULL) {
637 LOGE("Params is null.");
638 return HC_ERR_NULL_PTR;
639 }
640 int32_t res = GeneratePakeParams(params);
641 if (res != HC_SUCCESS) {
642 LOGE("GeneratePakeParams failed, res: %x.", res);
643 CleanPakeSensitiveKeys(params);
644 }
645 return res;
646 }
647
ServerConfirmPakeV2Protocol(PakeBaseParams * params)648 int32_t ServerConfirmPakeV2Protocol(PakeBaseParams *params)
649 {
650 if (params == NULL) {
651 LOGE("Params is null.");
652 return HC_ERR_NULL_PTR;
653 }
654 int32_t res = GenerateSharedSecret(params);
655 if (res != HC_SUCCESS) {
656 LOGE("GenerateSharedSecret failed, res: %x.", res);
657 goto CLEAN_UP;
658 }
659 res = VerifyProof(params);
660 if (res != HC_SUCCESS) {
661 LOGE("VerifyProof failed, res: %x.", res);
662 goto CLEAN_UP;
663 }
664 res = GenerateProof(params);
665 if (res != HC_SUCCESS) {
666 LOGE("GenerateProof failed, res: %x.", res);
667 goto CLEAN_UP;
668 }
669 res = GenerateSessionKey(params);
670 if (res != HC_SUCCESS) {
671 LOGE("GenerateSessionKey failed, res: %x.", res);
672 goto CLEAN_UP;
673 }
674 return res;
675 CLEAN_UP:
676 CleanPakeSensitiveKeys(params);
677 return res;
678 }
679