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(&params->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, &params->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(&params->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(&params->epkSelf, &params->epkPeer, params->innerKeyLen, proofMsg, &usedLen);
467     } else {
468         res = CombineEpk(&params->epkPeer, &params->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, &params->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, &params->salt, &keyInfo, &params->sessionKey);
575     if (res != HC_SUCCESS) {
576         LOGE("ComputeHkdf for sessionKey failed, res: %x.", res);
577         CleanPakeSensitiveKeys(params);
578     }
579     FreeAndCleanKey(&params->base);
580     FreeAndCleanKey(&params->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