• 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_v1_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 PAKE_SESSION_KEY_LEN 16
28 
DestroyPakeV1BaseParams(PakeBaseParams * params)29 void DestroyPakeV1BaseParams(PakeBaseParams *params)
30 {
31     if (params == NULL) {
32         LOGE("param is NULL!");
33         return;
34     }
35 
36     CleanPakeSensitiveKeys(params);
37 
38     HcFree(params->salt.val);
39     params->salt.val = NULL;
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->epkSelf.val);
48     params->epkSelf.val = NULL;
49 
50     HcFree(params->epkPeer.val);
51     params->epkPeer.val = NULL;
52 
53     HcFree(params->kcfData.val);
54     params->kcfData.val = NULL;
55 
56     HcFree(params->kcfDataPeer.val);
57     params->kcfDataPeer.val = NULL;
58 
59     HcFree(params->idSelf.val);
60     params->idSelf.val = NULL;
61 
62     HcFree(params->idPeer.val);
63     params->idPeer.val = NULL;
64 
65     HcFree(params->extraData.val);
66     params->extraData.val = NULL;
67 }
68 
AllocDefaultParams(PakeBaseParams * params)69 static int32_t AllocDefaultParams(PakeBaseParams *params)
70 {
71     params->salt.length = PAKE_SALT_LEN;
72     params->salt.val = (uint8_t *)HcMalloc(params->salt.length, 0);
73     if (params->salt.val == NULL) {
74         LOGE("Failed to malloc for salt!");
75         return HC_ERR_ALLOC_MEMORY;
76     }
77 
78     params->challengeSelf.length = PAKE_CHALLENGE_LEN;
79     params->challengeSelf.val = (uint8_t *)HcMalloc(params->challengeSelf.length, 0);
80     if (params->challengeSelf.val == NULL) {
81         LOGE("Malloc for challengeSelf failed.");
82         return HC_ERR_ALLOC_MEMORY;
83     }
84 
85     params->challengePeer.length = PAKE_CHALLENGE_LEN;
86     params->challengePeer.val = (uint8_t *)HcMalloc(params->challengePeer.length, 0);
87     if (params->challengePeer.val == NULL) {
88         LOGE("Malloc for challengePeer failed.");
89         return HC_ERR_ALLOC_MEMORY;
90     }
91 
92     params->sessionKey.length = PAKE_SESSION_KEY_LEN;
93     params->sessionKey.val = (uint8_t *)HcMalloc(params->sessionKey.length, 0);
94     if (params->sessionKey.val == NULL) {
95         LOGE("Malloc for sessionKey failed.");
96         return HC_ERR_ALLOC_MEMORY;
97     }
98 
99     params->hmacKey.length = PAKE_HMAC_KEY_LEN;
100     params->hmacKey.val = (uint8_t *)HcMalloc(params->hmacKey.length, 0);
101     if (params->hmacKey.val == NULL) {
102         LOGE("Malloc for hmacKey failed.");
103         return HC_ERR_ALLOC_MEMORY;
104     }
105 
106     params->kcfData.length = HMAC_LEN;
107     params->kcfData.val = (uint8_t *)HcMalloc(params->kcfData.length, 0);
108     if (params->kcfData.val == NULL) {
109         LOGE("Malloc for kcfData failed.");
110         return HC_ERR_ALLOC_MEMORY;
111     }
112 
113     params->kcfDataPeer.length = HMAC_LEN;
114     params->kcfDataPeer.val = (uint8_t *)HcMalloc(params->kcfDataPeer.length, 0);
115     if (params->kcfDataPeer.val == NULL) {
116         LOGE("Malloc for kcfDataPeer failed.");
117         return HC_ERR_ALLOC_MEMORY;
118     }
119     return HC_SUCCESS;
120 }
121 
FillDefaultValue(PakeBaseParams * params)122 static void FillDefaultValue(PakeBaseParams *params)
123 {
124     params->psk.val = NULL;
125     params->psk.length = 0;
126     params->eskSelf.val = NULL;
127     params->eskSelf.length = 0;
128     params->epkSelf.val = NULL;
129     params->epkSelf.length = 0;
130     params->epkPeer.val = NULL;
131     params->epkPeer.length = 0;
132     params->base.val = NULL;
133     params->base.length = 0;
134     params->sharedSecret.val = NULL;
135     params->sharedSecret.length = 0;
136     params->idSelf.val = NULL;
137     params->idSelf.length = 0;
138     params->idPeer.val = NULL;
139     params->idPeer.length = 0;
140     params->extraData.val = NULL;
141     params->extraData.length = 0;
142     params->supportedDlPrimeMod = DL_PRIME_MOD_NONE;
143     params->largePrimeNumHex = NULL;
144     params->innerKeyLen = 0;
145     params->supportedPakeAlg = PAKE_ALG_NONE;
146     params->curveType = CURVE_NONE;
147     params->isClient = true;
148 }
149 
InitPakeV1BaseParams(int32_t osAccountId,PakeBaseParams * params)150 int32_t InitPakeV1BaseParams(int32_t osAccountId, PakeBaseParams *params)
151 {
152     if (params == NULL) {
153         LOGE("Params is null.");
154         return HC_ERR_NULL_PTR;
155     }
156     params->osAccountId = osAccountId;
157 
158     int32_t res = AllocDefaultParams(params);
159     if (res != HC_SUCCESS) {
160         goto CLEAN_UP;
161     }
162 
163     FillDefaultValue(params);
164 
165     params->loader = GetLoaderInstance();
166     if (params->loader == NULL) {
167         res = HC_ERROR;
168         goto CLEAN_UP;
169     }
170 
171     return HC_SUCCESS;
172 CLEAN_UP:
173     DestroyPakeV1BaseParams(params);
174     return res;
175 }
176 
GeneratePakeParams(PakeBaseParams * params)177 static int32_t GeneratePakeParams(PakeBaseParams *params)
178 {
179     int32_t res;
180     uint8_t secretVal[PAKE_SECRET_LEN] = { 0 };
181     Uint8Buff secret = { secretVal, PAKE_SECRET_LEN };
182     if (!params->isClient) {
183         res = params->loader->generateRandom(&(params->salt));
184         if (res != HC_SUCCESS) {
185             LOGE("Generate salt failed, res: %" LOG_PUB "x.", res);
186             goto CLEAN_UP;
187         }
188     }
189     PRINT_DEBUG_MSG(params->salt.val, params->salt.length, "saltValue");
190 
191     res = params->loader->generateRandom(&(params->challengeSelf));
192     if (res != HC_SUCCESS) {
193         LOGE("Generate challengeSelf failed, res: %" LOG_PUB "x.", res);
194         goto CLEAN_UP;
195     }
196     PRINT_DEBUG_MSG(params->challengeSelf.val, params->challengeSelf.length, "challengeSelf");
197 
198     Uint8Buff keyInfo = { (uint8_t *)HICHAIN_SPEKE_BASE_INFO, HcStrlen(HICHAIN_SPEKE_BASE_INFO) };
199     KeyParams keyParams = { { params->psk.val, params->psk.length, false }, false, params->osAccountId };
200     res = params->loader->computeHkdf(&keyParams, &(params->salt), &keyInfo, &secret);
201     PRINT_SENSITIVE_DATA("pskValue", (char *)params->psk.val);
202     PRINT_DEBUG_MSG(secret.val, secret.length, "secretValue");
203     if (res != HC_SUCCESS) {
204         LOGE("Derive secret from psk failed, res: %" LOG_PUB "x.", res);
205         goto CLEAN_UP;
206     }
207     FreeAndCleanKey(&params->psk);
208 
209     if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_EC) != 0) {
210         res = GenerateEcPakeParams(params, &secret);
211     } else if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_DL) != 0) {
212         res = GenerateDlPakeParams(params, &secret);
213     } else {
214         res = HC_ERR_INVALID_ALG;
215     }
216     if (res != HC_SUCCESS) {
217         LOGE("GeneratePakeParams failed, pakeAlgType: 0x%" LOG_PUB "x, res: %" LOG_PUB "x.",
218             params->supportedPakeAlg, res);
219         goto CLEAN_UP;
220     }
221     FreeAndCleanKey(&params->base);
222     (void)memset_s(secret.val, secret.length, 0, secret.length);
223     return res;
224 CLEAN_UP:
225     (void)memset_s(secret.val, secret.length, 0, secret.length);
226     CleanPakeSensitiveKeys(params);
227     return res;
228 }
229 
DeriveKeyFromSharedSecret(PakeBaseParams * params)230 static int32_t DeriveKeyFromSharedSecret(PakeBaseParams *params)
231 {
232     int32_t res;
233     Uint8Buff unionKey = { NULL, 0 };
234     Uint8Buff keyInfo = { (uint8_t *)HICHAIN_SPEKE_SESSIONKEY_INFO, HcStrlen(HICHAIN_SPEKE_SESSIONKEY_INFO) };
235     unionKey.length = params->sessionKey.length + params->hmacKey.length;
236     unionKey.val = (uint8_t *)HcMalloc(unionKey.length, 0);
237     if (unionKey.val == NULL) {
238         LOGE("Malloc for unionKey failed.");
239         res = HC_ERR_ALLOC_MEMORY;
240         goto CLEAN_UP;
241     }
242 
243     KeyParams keyParams = {
244         .keyBuff = { params->sharedSecret.val, params->sharedSecret.length, false },
245         .isDeStorage = false,
246         .osAccountId = params->osAccountId
247     };
248     res = params->loader->computeHkdf(&keyParams, &(params->salt), &keyInfo, &unionKey);
249     if (res != HC_SUCCESS) {
250         LOGE("ComputeHkdf for unionKey failed, res: %" LOG_PUB "x.", res);
251         goto CLEAN_UP;
252     }
253     PRINT_DEBUG_MSG(unionKey.val, unionKey.length, "unionKey");
254     FreeAndCleanKey(&params->sharedSecret);
255     if (memcpy_s(params->sessionKey.val, params->sessionKey.length, unionKey.val, params->sessionKey.length) != EOK) {
256         LOGE("Memcpy for sessionKey failed.");
257         res = HC_ERR_ALLOC_MEMORY;
258         goto CLEAN_UP;
259     }
260     PRINT_DEBUG_MSG(params->sessionKey.val, params->sessionKey.length, "sessionKey");
261     if (memcpy_s(params->hmacKey.val, params->hmacKey.length,
262         unionKey.val + params->sessionKey.length, params->hmacKey.length) != EOK) {
263         LOGE("Memcpy for hmacKey failed.");
264         res = HC_ERR_ALLOC_MEMORY;
265         goto CLEAN_UP;
266     }
267     PRINT_DEBUG_MSG(params->hmacKey.val, params->hmacKey.length, "hmacKey");
268 CLEAN_UP:
269     FreeAndCleanKey(&unionKey);
270     return res;
271 }
272 
GenerateSessionKey(PakeBaseParams * params)273 static int32_t GenerateSessionKey(PakeBaseParams *params)
274 {
275     int32_t res = InitSingleParam(&params->sharedSecret, params->innerKeyLen);
276     if (res != HC_SUCCESS) {
277         LOGE("InitSingleParam for sharedSecret failed, res: %" LOG_PUB "x.", res);
278         goto CLEAN_UP;
279     }
280 
281     if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_EC) != 0) {
282         res = AgreeEcSharedSecret(params, &params->sharedSecret);
283     } else if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_DL) != 0) {
284         res = AgreeDlSharedSecret(params, &params->sharedSecret);
285     } else {
286         res = HC_ERR_INVALID_ALG;
287     }
288     if (res != HC_SUCCESS) {
289         LOGE("AgreeDlSharedSecret failed, pakeAlgType: 0x%" LOG_PUB "x, res: %" LOG_PUB "x.",
290             params->supportedPakeAlg, res);
291         goto CLEAN_UP;
292     }
293     FreeAndCleanKey(&params->eskSelf);
294 
295     res = DeriveKeyFromSharedSecret(params);
296     if (res != HC_SUCCESS) {
297         LOGE("DeriveKeyFromSharedSecret failed, res: %" LOG_PUB "x.", res);
298         goto CLEAN_UP;
299     }
300     return res;
301 CLEAN_UP:
302     CleanPakeSensitiveKeys(params);
303     return res;
304 }
305 
GenerateProof(PakeBaseParams * params)306 static int32_t GenerateProof(PakeBaseParams *params)
307 {
308     int res;
309     uint8_t challengeVal[PAKE_CHALLENGE_LEN + PAKE_CHALLENGE_LEN] = { 0 };
310     Uint8Buff challenge = { challengeVal, PAKE_CHALLENGE_LEN + PAKE_CHALLENGE_LEN };
311     if (memcpy_s(challenge.val, challenge.length, params->challengeSelf.val, params->challengeSelf.length) != EOK) {
312         LOGE("Memcpy challengeSelf failed.");
313         res = HC_ERR_MEMORY_COPY;
314         goto CLEAN_UP;
315     }
316     PRINT_DEBUG_MSG(params->challengePeer.val, params->challengePeer.length, "challengePeer");
317     if (memcpy_s(challenge.val + params->challengeSelf.length, challenge.length - params->challengeSelf.length,
318         params->challengePeer.val, params->challengePeer.length) != EOK) {
319         LOGE("Memcpy challengePeer failed.");
320         res = HC_ERR_MEMORY_COPY;
321         goto CLEAN_UP;
322     }
323     PRINT_DEBUG_MSG(challenge.val, challenge.length, "challenge");
324 
325     KeyParams keyParams = { { params->hmacKey.val, params->hmacKey.length, false }, false, params->osAccountId };
326     res = params->loader->computeHmac(&keyParams, &challenge, &(params->kcfData));
327     if (res != HC_SUCCESS) {
328         LOGE("Compute hmac for kcfData failed, res: %" LOG_PUB "x.", res);
329         goto CLEAN_UP;
330     }
331     PRINT_DEBUG_MSG(params->kcfData.val, params->kcfData.length, "kcfData");
332     return res;
333 CLEAN_UP:
334     CleanPakeSensitiveKeys(params);
335     return res;
336 }
337 
VerifyProof(PakeBaseParams * params)338 static int32_t VerifyProof(PakeBaseParams *params)
339 {
340     uint8_t challengeVal[PAKE_CHALLENGE_LEN + PAKE_CHALLENGE_LEN] = { 0 };
341     Uint8Buff challenge = { challengeVal, PAKE_CHALLENGE_LEN + PAKE_CHALLENGE_LEN };
342     int res;
343     if (memcpy_s(challenge.val, challenge.length, params->challengePeer.val, params->challengePeer.length) != EOK) {
344         LOGE("Memcpy for challengePeer failed.");
345         res = HC_ERR_MEMORY_COPY;
346         goto CLEAN_UP;
347     }
348     if (memcpy_s(challenge.val + params->challengePeer.length, challenge.length - params->challengePeer.length,
349         params->challengeSelf.val, params->challengeSelf.length) != EOK) {
350         LOGE("Memcpy for challengeSelf failed.");
351         res = HC_ERR_MEMORY_COPY;
352         goto CLEAN_UP;
353     }
354     PRINT_DEBUG_MSG(challenge.val, challenge.length, "challenge");
355 
356     uint8_t verifyProofVal[HMAC_LEN] = { 0 };
357     Uint8Buff verifyProof = { verifyProofVal, HMAC_LEN };
358     KeyParams keyParams = { { params->hmacKey.val, params->hmacKey.length, false }, false, params->osAccountId };
359     res = params->loader->computeHmac(&keyParams, &challenge, &verifyProof);
360     if (res != HC_SUCCESS) {
361         LOGE("Compute hmac for kcfData failed, res: %" LOG_PUB "x.", res);
362         goto CLEAN_UP;
363     }
364     PRINT_DEBUG_MSG(verifyProof.val, verifyProof.length, "verifyProof");
365 
366     if (memcmp(verifyProof.val, params->kcfDataPeer.val, verifyProof.length) != 0) {
367         LOGE("Compare kcfDataPeer failed.");
368         res = PROOF_MISMATCH;
369         goto CLEAN_UP;
370     }
371     return res;
372 CLEAN_UP:
373     CleanPakeSensitiveKeys(params);
374     return res;
375 }
376 
ClientConfirmPakeV1Protocol(PakeBaseParams * params)377 int32_t ClientConfirmPakeV1Protocol(PakeBaseParams *params)
378 {
379     if (params == NULL) {
380         LOGE("Params is NULL.");
381         return HC_ERR_NULL_PTR;
382     }
383     int32_t res = GeneratePakeParams(params);
384     if (res != HC_SUCCESS) {
385         LOGE("Generate v1 pake params failed, res: %" LOG_PUB "x.", res);
386         goto CLEAN_UP;
387     }
388 
389     res = GenerateSessionKey(params);
390     if (res != HC_SUCCESS) {
391         LOGE("Generate v1 session key failed, res: %" LOG_PUB "x.", res);
392         goto CLEAN_UP;
393     }
394 
395     res = GenerateProof(params);
396     if (res != HC_SUCCESS) {
397         LOGE("The operation of GenerateProof failed, res: %" LOG_PUB "x.", res);
398         goto CLEAN_UP;
399     }
400     return res;
401 CLEAN_UP:
402     CleanPakeSensitiveKeys(params);
403     return res;
404 }
405 
ClientVerifyConfirmPakeV1Protocol(PakeBaseParams * params)406 int32_t ClientVerifyConfirmPakeV1Protocol(PakeBaseParams *params)
407 {
408     if (params == NULL) {
409         LOGE("Params is null.");
410         return HC_ERR_NULL_PTR;
411     }
412     int32_t res = VerifyProof(params);
413     if (res != HC_SUCCESS) {
414         LOGE("VerifyProof failed, res: %" LOG_PUB "x.", res);
415         CleanPakeSensitiveKeys(params);
416     }
417     return res;
418 }
419 
ServerResponsePakeV1Protocol(PakeBaseParams * params)420 int32_t ServerResponsePakeV1Protocol(PakeBaseParams *params)
421 {
422     if (params == NULL) {
423         LOGE("Invalid params, params is null!");
424         return HC_ERR_NULL_PTR;
425     }
426     int32_t res = GeneratePakeParams(params);
427     if (res != HC_SUCCESS) {
428         LOGE("Generate v1 pake params failed, res: %" LOG_PUB "x.", res);
429         CleanPakeSensitiveKeys(params);
430     }
431     return res;
432 }
433 
ServerConfirmPakeV1Protocol(PakeBaseParams * params)434 int32_t ServerConfirmPakeV1Protocol(PakeBaseParams *params)
435 {
436     if (params == NULL) {
437         LOGE("Params is null.");
438         return HC_ERR_NULL_PTR;
439     }
440     int32_t res = GenerateSessionKey(params);
441     if (res != HC_SUCCESS) {
442         LOGE("GenerateSessionKey failed, res: %" LOG_PUB "x.", res);
443         goto CLEAN_UP;
444     }
445 
446     res = VerifyProof(params);
447     if (res != HC_SUCCESS) {
448         LOGE("Verify proof failed, res: %" LOG_PUB "x.", res);
449         goto CLEAN_UP;
450     }
451 
452     res = GenerateProof(params);
453     if (res != HC_SUCCESS) {
454         LOGE("Generate proof failed, res: %" LOG_PUB "x.", res);
455         goto CLEAN_UP;
456     }
457 
458     return res;
459 CLEAN_UP:
460     CleanPakeSensitiveKeys(params);
461     return res;
462 }
463