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