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