• 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(PakeBaseParams * params)149 int32_t InitPakeV1BaseParams(PakeBaseParams *params)
150 {
151     if (params == NULL) {
152         LOGE("Params is null.");
153         return HC_ERR_NULL_PTR;
154     }
155 
156     int32_t res = AllocDefaultParams(params);
157     if (res != HC_SUCCESS) {
158         goto CLEAN_UP;
159     }
160 
161     FillDefaultValue(params);
162 
163     params->loader = GetLoaderInstance();
164     if (params->loader == NULL) {
165         res = HC_ERROR;
166         goto CLEAN_UP;
167     }
168 
169     return HC_SUCCESS;
170 CLEAN_UP:
171     DestroyPakeV1BaseParams(params);
172     return res;
173 }
174 
GeneratePakeParams(PakeBaseParams * params)175 static int32_t GeneratePakeParams(PakeBaseParams *params)
176 {
177     int32_t res;
178     uint8_t secretVal[PAKE_SECRET_LEN] = { 0 };
179     Uint8Buff secret = { secretVal, PAKE_SECRET_LEN };
180     if (!params->isClient) {
181         res = params->loader->generateRandom(&(params->salt));
182         if (res != HC_SUCCESS) {
183             LOGE("Generate salt failed, res: %x.", res);
184             goto CLEAN_UP;
185         }
186     }
187 
188     res = params->loader->generateRandom(&(params->challengeSelf));
189     if (res != HC_SUCCESS) {
190         LOGE("Generate challengeSelf failed, res: %x.", res);
191         goto CLEAN_UP;
192     }
193 
194     Uint8Buff keyInfo = { (uint8_t *)HICHAIN_SPEKE_BASE_INFO, HcStrlen(HICHAIN_SPEKE_BASE_INFO) };
195     res = params->loader->computeHkdf(&(params->psk), &(params->salt), &keyInfo, &secret, false);
196     if (res != HC_SUCCESS) {
197         LOGE("Derive secret from psk failed, res: %x.", res);
198         goto CLEAN_UP;
199     }
200     FreeAndCleanKey(&params->psk);
201 
202     if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_EC) != 0) {
203         res = GenerateEcPakeParams(params, &secret);
204     } else if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_DL) != 0) {
205         res = GenerateDlPakeParams(params, &secret);
206     } else {
207         res = HC_ERR_INVALID_ALG;
208     }
209     if (res != HC_SUCCESS) {
210         LOGE("GeneratePakeParams failed, pakeAlgType: 0x%x, res: %x.", params->supportedPakeAlg, res);
211         goto CLEAN_UP;
212     }
213     FreeAndCleanKey(&params->base);
214     (void)memset_s(secret.val, secret.length, 0, secret.length);
215     return res;
216 CLEAN_UP:
217     (void)memset_s(secret.val, secret.length, 0, secret.length);
218     CleanPakeSensitiveKeys(params);
219     return res;
220 }
221 
DeriveKeyFromSharedSecret(PakeBaseParams * params)222 static int32_t DeriveKeyFromSharedSecret(PakeBaseParams *params)
223 {
224     int32_t res;
225     Uint8Buff unionKey = { NULL, 0 };
226     Uint8Buff keyInfo = { (uint8_t *)HICHAIN_SPEKE_SESSIONKEY_INFO, HcStrlen(HICHAIN_SPEKE_SESSIONKEY_INFO) };
227     unionKey.length = params->sessionKey.length + params->hmacKey.length;
228     unionKey.val = (uint8_t *)HcMalloc(unionKey.length, 0);
229     if (unionKey.val == NULL) {
230         LOGE("Malloc for unionKey failed.");
231         res = HC_ERR_ALLOC_MEMORY;
232         goto CLEAN_UP;
233     }
234 
235     res = params->loader->computeHkdf(&(params->sharedSecret), &(params->salt), &keyInfo, &unionKey, false);
236     if (res != HC_SUCCESS) {
237         LOGE("ComputeHkdf for unionKey failed, res: %x.", res);
238         goto CLEAN_UP;
239     }
240     FreeAndCleanKey(&params->sharedSecret);
241     if (memcpy_s(params->sessionKey.val, params->sessionKey.length, unionKey.val, params->sessionKey.length) != EOK) {
242         LOGE("Memcpy for sessionKey failed.");
243         res = HC_ERR_ALLOC_MEMORY;
244         goto CLEAN_UP;
245     }
246     if (memcpy_s(params->hmacKey.val, params->hmacKey.length,
247         unionKey.val + params->sessionKey.length, params->hmacKey.length) != EOK) {
248         LOGE("Memcpy for hmacKey failed.");
249         res = HC_ERR_ALLOC_MEMORY;
250         goto CLEAN_UP;
251     }
252 CLEAN_UP:
253     FreeAndCleanKey(&unionKey);
254     return res;
255 }
256 
GenerateSessionKey(PakeBaseParams * params)257 static int32_t GenerateSessionKey(PakeBaseParams *params)
258 {
259     int32_t res = InitSingleParam(&params->sharedSecret, params->innerKeyLen);
260     if (res != HC_SUCCESS) {
261         LOGE("InitSingleParam for sharedSecret failed, res: %x.", res);
262         goto CLEAN_UP;
263     }
264 
265     if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_EC) != 0) {
266         res = AgreeEcSharedSecret(params, &params->sharedSecret);
267     } else if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_DL) != 0) {
268         res = AgreeDlSharedSecret(params, &params->sharedSecret);
269     } else {
270         res = HC_ERR_INVALID_ALG;
271     }
272     if (res != HC_SUCCESS) {
273         LOGE("AgreeDlSharedSecret failed, pakeAlgType: 0x%x, res: %x.", params->supportedPakeAlg, res);
274         goto CLEAN_UP;
275     }
276     FreeAndCleanKey(&params->eskSelf);
277 
278     res = DeriveKeyFromSharedSecret(params);
279     if (res != HC_SUCCESS) {
280         LOGE("DeriveKeyFromSharedSecret failed, res: %x.", res);
281         goto CLEAN_UP;
282     }
283     return res;
284 CLEAN_UP:
285     CleanPakeSensitiveKeys(params);
286     return res;
287 }
288 
GenerateProof(PakeBaseParams * params)289 static int32_t GenerateProof(PakeBaseParams *params)
290 {
291     int res;
292     uint8_t challengeVal[PAKE_CHALLENGE_LEN + PAKE_CHALLENGE_LEN] = { 0 };
293     Uint8Buff challenge = { challengeVal, PAKE_CHALLENGE_LEN + PAKE_CHALLENGE_LEN };
294     if (memcpy_s(challenge.val, challenge.length, params->challengeSelf.val, params->challengeSelf.length) != EOK) {
295         LOGE("Memcpy challengeSelf failed.");
296         res = HC_ERR_MEMORY_COPY;
297         goto CLEAN_UP;
298     }
299     if (memcpy_s(challenge.val + params->challengeSelf.length, challenge.length - params->challengeSelf.length,
300         params->challengePeer.val, params->challengePeer.length) != EOK) {
301         LOGE("Memcpy challengePeer failed.");
302         res = HC_ERR_MEMORY_COPY;
303         goto CLEAN_UP;
304     }
305 
306     res = params->loader->computeHmac(&(params->hmacKey), &challenge, &(params->kcfData), false);
307     if (res != HC_SUCCESS) {
308         LOGE("Compute hmac for kcfData failed, res: %x.", res);
309         goto CLEAN_UP;
310     }
311     return res;
312 CLEAN_UP:
313     CleanPakeSensitiveKeys(params);
314     return res;
315 }
316 
VerifyProof(PakeBaseParams * params)317 static int32_t VerifyProof(PakeBaseParams *params)
318 {
319     uint8_t challengeVal[PAKE_CHALLENGE_LEN + PAKE_CHALLENGE_LEN] = { 0 };
320     Uint8Buff challenge = { challengeVal, PAKE_CHALLENGE_LEN + PAKE_CHALLENGE_LEN };
321     int res;
322     if (memcpy_s(challenge.val, challenge.length, params->challengePeer.val, params->challengePeer.length) != EOK) {
323         LOGE("Memcpy for challengePeer failed.");
324         res = HC_ERR_MEMORY_COPY;
325         goto CLEAN_UP;
326     }
327     if (memcpy_s(challenge.val + params->challengePeer.length, challenge.length - params->challengePeer.length,
328         params->challengeSelf.val, params->challengeSelf.length) != EOK) {
329         LOGE("Memcpy for challengeSelf failed.");
330         res = HC_ERR_MEMORY_COPY;
331         goto CLEAN_UP;
332     }
333 
334     uint8_t verifyProofVal[HMAC_LEN] = { 0 };
335     Uint8Buff verifyProof = { verifyProofVal, HMAC_LEN };
336     res = params->loader->computeHmac(&(params->hmacKey), &challenge, &verifyProof, false);
337     if (res != HC_SUCCESS) {
338         LOGE("Compute hmac for kcfData failed, res: %x.", res);
339         goto CLEAN_UP;
340     }
341 
342     if (memcmp(verifyProof.val, params->kcfDataPeer.val, verifyProof.length) != 0) {
343         LOGE("Compare kcfDataPeer failed.");
344         res = HC_ERR_PROOF_NOT_MATCH;
345         goto CLEAN_UP;
346     }
347     return res;
348 CLEAN_UP:
349     CleanPakeSensitiveKeys(params);
350     return res;
351 }
352 
ClientConfirmPakeV1Protocol(PakeBaseParams * params)353 int32_t ClientConfirmPakeV1Protocol(PakeBaseParams *params)
354 {
355     if (params == NULL) {
356         LOGE("Params is null.");
357         return HC_ERR_NULL_PTR;
358     }
359     int32_t res = GeneratePakeParams(params);
360     if (res != HC_SUCCESS) {
361         LOGE("GeneratePakeParams failed, res: %x.", res);
362         goto CLEAN_UP;
363     }
364 
365     res = GenerateSessionKey(params);
366     if (res != HC_SUCCESS) {
367         LOGE("GenerateSessionKey failed, res: %x.", res);
368         goto CLEAN_UP;
369     }
370 
371     res = GenerateProof(params);
372     if (res != HC_SUCCESS) {
373         LOGE("GenerateProof failed, res: %x.", res);
374         goto CLEAN_UP;
375     }
376     return res;
377 CLEAN_UP:
378     CleanPakeSensitiveKeys(params);
379     return res;
380 }
381 
ClientVerifyConfirmPakeV1Protocol(PakeBaseParams * params)382 int32_t ClientVerifyConfirmPakeV1Protocol(PakeBaseParams *params)
383 {
384     if (params == NULL) {
385         LOGE("Params is null.");
386         return HC_ERR_NULL_PTR;
387     }
388     int32_t res = VerifyProof(params);
389     if (res != HC_SUCCESS) {
390         LOGE("VerifyProof failed, res: %x.", res);
391         CleanPakeSensitiveKeys(params);
392     }
393     return res;
394 }
395 
ServerResponsePakeV1Protocol(PakeBaseParams * params)396 int32_t ServerResponsePakeV1Protocol(PakeBaseParams *params)
397 {
398     if (params == NULL) {
399         LOGE("Params is null.");
400         return HC_ERR_NULL_PTR;
401     }
402     int32_t res = GeneratePakeParams(params);
403     if (res != HC_SUCCESS) {
404         LOGE("GeneratePakeParams failed, res: %x.", res);
405         CleanPakeSensitiveKeys(params);
406     }
407     return res;
408 }
409 
ServerConfirmPakeV1Protocol(PakeBaseParams * params)410 int32_t ServerConfirmPakeV1Protocol(PakeBaseParams *params)
411 {
412     if (params == NULL) {
413         LOGE("Params is null.");
414         return HC_ERR_NULL_PTR;
415     }
416     int32_t res = GenerateSessionKey(params);
417     if (res != HC_SUCCESS) {
418         LOGE("GenerateSessionKey failed, res: %x.", res);
419         goto CLEAN_UP;
420     }
421 
422     res = VerifyProof(params);
423     if (res != HC_SUCCESS) {
424         LOGE("VerifyProof failed, res: %x.", res);
425         goto CLEAN_UP;
426     }
427 
428     res = GenerateProof(params);
429     if (res != HC_SUCCESS) {
430         LOGE("GenerateProof failed, res: %x.", res);
431         goto CLEAN_UP;
432     }
433 
434     return res;
435 CLEAN_UP:
436     CleanPakeSensitiveKeys(params);
437     return res;
438 }
439