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