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