• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "alg_defs.h"
17 #include "alg_loader.h"
18 #include "hc_log.h"
19 #include "identity_manager.h"
20 
SetDlSpekeProtocol(IdentityInfo * info)21 static int32_t SetDlSpekeProtocol(IdentityInfo *info)
22 {
23 #ifdef ENABLE_P2P_BIND_DL_SPEKE
24     ProtocolEntity *dlSpekeEntity = (ProtocolEntity *)HcMalloc(sizeof(ProtocolEntity), 0);
25     if (dlSpekeEntity == NULL) {
26         LOGE("Failed to alloc memory for dl speke entity!");
27         return HC_ERR_ALLOC_MEMORY;
28     }
29     dlSpekeEntity->protocolType = ALG_DL_SPEKE;
30     dlSpekeEntity->expandProcessCmds = CMD_IMPORT_AUTH_CODE | CMD_ADD_TRUST_DEVICE;
31     if (info->protocolVec.pushBack(&info->protocolVec, (const ProtocolEntity **)&dlSpekeEntity) == NULL) {
32         LOGE("Failed to push dl speke entity!");
33         HcFree(dlSpekeEntity);
34         return HC_ERR_ALLOC_MEMORY;
35     }
36     return HC_SUCCESS;
37 #else
38     (void)info;
39     return HC_SUCCESS;
40 #endif
41 }
42 
SetIsoProtocol(const CJson * in,IdentityInfo * info)43 static int32_t SetIsoProtocol(const CJson *in, IdentityInfo *info)
44 {
45 #ifdef ENABLE_P2P_BIND_ISO
46     ProtocolEntity *isoEntity = (ProtocolEntity *)HcMalloc(sizeof(ProtocolEntity), 0);
47     if (isoEntity == NULL) {
48         LOGE("Failed to alloc memory for iso entity!");
49         return HC_ERR_ALLOC_MEMORY;
50     }
51     isoEntity->protocolType = ALG_ISO;
52     bool isCredAuth = false;
53     (void)GetBoolFromJson(in, FIELD_IS_CRED_AUTH, &isCredAuth);
54     isoEntity->expandProcessCmds = isCredAuth ? 0 : CMD_IMPORT_AUTH_CODE | CMD_ADD_TRUST_DEVICE;
55     if (info->protocolVec.pushBack(&info->protocolVec, (const ProtocolEntity **)&isoEntity) == NULL) {
56         LOGE("Failed to push iso entity!");
57         HcFree(isoEntity);
58         return HC_ERR_ALLOC_MEMORY;
59     }
60     return HC_SUCCESS;
61 #else
62     (void)info;
63     return HC_SUCCESS;
64 #endif
65 }
66 
SetLiteProtocols(const CJson * in,IdentityInfo * info)67 static int32_t SetLiteProtocols(const CJson *in, IdentityInfo *info)
68 {
69     int32_t res = SetDlSpekeProtocol(info);
70     if (res != HC_SUCCESS) {
71         return res;
72     }
73     return SetIsoProtocol(in, info);
74 }
75 
SetLiteProtocolsForPinType(const CJson * in,IdentityInfo * info)76 static int32_t SetLiteProtocolsForPinType(const CJson *in, IdentityInfo *info)
77 {
78 #ifndef ENABLE_P2P_BIND_LITE_PROTOCOL_CHECK
79     (void)in;
80     return SetLiteProtocols(in, info);
81 #else
82     int32_t protocolExpandVal = INVALID_PROTOCOL_EXPAND_VALUE;
83     (void)GetIntFromJson(in, FIELD_PROTOCOL_EXPAND, &protocolExpandVal);
84     int32_t res = HC_SUCCESS;
85     if (protocolExpandVal == LITE_PROTOCOL_STANDARD_MODE ||
86         protocolExpandVal == LITE_PROTOCOL_COMPATIBILITY_MODE) {
87         res = SetLiteProtocols(in, info);
88     }
89     return res;
90 #endif
91 }
92 
SetProtocolsForPinType(const CJson * in,IdentityInfo * info)93 static int32_t SetProtocolsForPinType(const CJson *in, IdentityInfo *info)
94 {
95 #ifdef ENABLE_P2P_BIND_EC_SPEKE
96     ProtocolEntity *ecSpekeEntity = (ProtocolEntity *)HcMalloc(sizeof(ProtocolEntity), 0);
97     if (ecSpekeEntity == NULL) {
98         LOGE("Failed to alloc memory for ec speke entity!");
99         return HC_ERR_ALLOC_MEMORY;
100     }
101     ecSpekeEntity->protocolType = ALG_EC_SPEKE;
102     bool isCredAuth = false;
103     (void)GetBoolFromJson(in, FIELD_IS_CRED_AUTH, &isCredAuth);
104     ecSpekeEntity->expandProcessCmds = isCredAuth ? 0 : CMD_EXCHANGE_PK | CMD_ADD_TRUST_DEVICE;
105     if (info->protocolVec.pushBack(&info->protocolVec, (const ProtocolEntity **)&ecSpekeEntity) == NULL) {
106         LOGE("Failed to push ec speke entity!");
107         HcFree(ecSpekeEntity);
108         return HC_ERR_ALLOC_MEMORY;
109     }
110 #endif
111 
112     return SetLiteProtocolsForPinType(in, info);
113 }
114 
IsDirectAuth(const CJson * context)115 static bool IsDirectAuth(const CJson *context)
116 {
117     bool isDirectAuth = false;
118     (void)GetBoolFromJson(context, FIELD_IS_DIRECT_AUTH, &isDirectAuth);
119     return isDirectAuth;
120 }
121 
SetProtocolsForDirectAuth(IdentityInfo * info)122 static int32_t SetProtocolsForDirectAuth(IdentityInfo *info)
123 {
124 #ifdef ENABLE_P2P_AUTH_EC_SPEKE
125     ProtocolEntity *ecSpekeEntity = (ProtocolEntity *)HcMalloc(sizeof(ProtocolEntity), 0);
126     if (ecSpekeEntity == NULL) {
127         LOGE("Failed to alloc memory for ec speke entity!");
128         return HC_ERR_ALLOC_MEMORY;
129     }
130     ecSpekeEntity->protocolType = ALG_EC_SPEKE;
131     ecSpekeEntity->expandProcessCmds = 0;
132     if (info->protocolVec.pushBack(&info->protocolVec, (const ProtocolEntity **)&ecSpekeEntity) == NULL) {
133         LOGE("Failed to push ecspeke entity!");
134         HcFree(ecSpekeEntity);
135         return HC_ERR_ALLOC_MEMORY;
136     }
137 #else
138 #endif
139 
140     return HC_SUCCESS;
141 }
142 
CreateUrlStr(const CJson * in,char ** urlStr)143 static int32_t CreateUrlStr(const CJson *in, char **urlStr)
144 {
145     CJson *urlJson = CreateCredUrlJson(PRE_SHARED, KEY_TYPE_SYM, TRUST_TYPE_PIN);
146     if (!urlJson) {
147         LOGE("Failed to create cred url json info!");
148         return HC_ERR_ALLOC_MEMORY;
149     }
150     if (IsDirectAuth(in) && AddBoolToJson(urlJson, FIELD_IS_DIRECT_AUTH, true) != HC_SUCCESS) {
151         LOGE("Failed to isDirectAuth to preshared url!");
152         FreeJson(urlJson);
153         return HC_ERR_JSON_ADD;
154     }
155     char *str = PackJsonToString(urlJson);
156     FreeJson(urlJson);
157     if (str == NULL) {
158         LOGE("Failed to pack json to str!");
159         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
160     }
161     *urlStr = str;
162     return HC_SUCCESS;
163 }
164 
GetCredInfosByPeerIdentity(const CJson * in,IdentityInfoVec * vec)165 static int32_t GetCredInfosByPeerIdentity(const CJson *in, IdentityInfoVec *vec)
166 {
167     IdentityInfo *info = CreateIdentityInfo();
168     if (info == NULL) {
169         LOGE("Failed to create identity info!");
170         return HC_ERR_ALLOC_MEMORY;
171     }
172     char *urlStr = NULL;
173     int32_t ret = CreateUrlStr(in, &urlStr);
174     if (ret != HC_SUCCESS) {
175         LOGE("Failed to create url string!");
176         DestroyIdentityInfo(info);
177         return ret;
178     }
179     ret = SetPreSharedUrlForProof(urlStr, &info->proof.preSharedUrl);
180     FreeJsonString(urlStr);
181     if (ret != HC_SUCCESS) {
182         LOGE("Failed to set preSharedUrl of proof!");
183         DestroyIdentityInfo(info);
184         return ret;
185     }
186     if (IsDirectAuth(in)) {
187         ret = SetProtocolsForDirectAuth(info);
188         info->IdInfoType = P2P_DIRECT_AUTH;
189     } else {
190         ret = SetProtocolsForPinType(in, info);
191     }
192     if (ret != HC_SUCCESS) {
193         LOGE("Failed to set protocols!");
194         DestroyIdentityInfo(info);
195         return ret;
196     }
197     info->proofType = PRE_SHARED;
198     if (vec->pushBack(vec, (const IdentityInfo **)&info) == NULL) {
199         LOGE("Failed to push info!");
200         DestroyIdentityInfo(info);
201         return HC_ERR_ALLOC_MEMORY;
202     }
203     return HC_SUCCESS;
204 }
205 
GetCredInfoByPeerUrl(const CJson * in,const Uint8Buff * presharedUrl,IdentityInfo ** returnInfo)206 static int32_t GetCredInfoByPeerUrl(const CJson *in, const Uint8Buff *presharedUrl, IdentityInfo **returnInfo)
207 {
208     if (in == NULL || presharedUrl == NULL || returnInfo == NULL) {
209         LOGE("Invalid input params!");
210         return HC_ERR_INVALID_PARAMS;
211     }
212     IdentityInfo *info = CreateIdentityInfo();
213     if (info == NULL) {
214         LOGE("Failed to create identity info!");
215         return HC_ERR_ALLOC_MEMORY;
216     }
217     CJson *urlJson = CreateJsonFromString((const char *)presharedUrl->val);
218     if (urlJson == NULL) {
219         LOGE("Failed to create url json!");
220         DestroyIdentityInfo(info);
221         return HC_ERR_JSON_CREATE;
222     }
223     int32_t credentialType = PRE_SHARED;
224     if (GetIntFromJson(urlJson, PRESHARED_URL_CREDENTIAL_TYPE, &credentialType) != HC_SUCCESS) {
225         LOGE("Failed to get credential type!");
226         DestroyIdentityInfo(info);
227         FreeJson(urlJson);
228         return HC_ERR_JSON_GET;
229     }
230     FreeJson(urlJson);
231     int32_t ret = SetPreSharedUrlForProof((const char *)presharedUrl->val, &info->proof.preSharedUrl);
232     if (ret != HC_SUCCESS) {
233         LOGE("Set preSharedUrl of proof failed!");
234         DestroyIdentityInfo(info);
235         return ret;
236     }
237     if (IsDirectAuth(in)) {
238         ret = SetProtocolsForDirectAuth(info);
239         info->IdInfoType = P2P_DIRECT_AUTH;
240     } else {
241         ret = SetProtocolsForPinType(in, info);
242     }
243     if (ret != HC_SUCCESS) {
244         LOGE("Error occurs, Failed to set protocols!");
245         DestroyIdentityInfo(info);
246         return ret;
247     }
248     info->proofType = credentialType;
249     *returnInfo = info;
250     return HC_SUCCESS;
251 }
252 
AuthGeneratePskUsePin(const CJson * in,const Uint8Buff * seed,const char * pinCode,Uint8Buff * sharedSecret)253 static int32_t AuthGeneratePskUsePin(const CJson *in, const Uint8Buff *seed, const char *pinCode,
254     Uint8Buff *sharedSecret)
255 {
256     int32_t osAccountId;
257     if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
258         LOGE("Failed to get osAccountId!");
259         return HC_ERR_JSON_GET;
260     }
261     Uint8Buff messageBuf = { (uint8_t *)pinCode, (uint32_t)HcStrlen(pinCode) };
262     uint8_t hash[SHA256_LEN] = { 0 };
263     Uint8Buff hashBuf = { hash, sizeof(hash) };
264     int ret = GetLoaderInstance()->sha256(&messageBuf, &hashBuf);
265     if (ret != HC_SUCCESS) {
266         LOGE("sha256 failed, ret:%" LOG_PUB "d", ret);
267         return ret;
268     }
269     KeyParams keyParams = { { hashBuf.val, hashBuf.length, false }, false, osAccountId };
270     return GetLoaderInstance()->computeHmac(&keyParams, seed, sharedSecret);
271 }
272 
273 #ifdef ENABLE_P2P_BIND_LITE_PROTOCOL_CHECK
CheckPinLenForStandardIso(const CJson * in,const char * pinCode)274 static bool CheckPinLenForStandardIso(const CJson *in, const char *pinCode)
275 {
276     int32_t protocolExpandVal = INVALID_PROTOCOL_EXPAND_VALUE;
277     (void)GetIntFromJson(in, FIELD_PROTOCOL_EXPAND, &protocolExpandVal);
278     if (protocolExpandVal != LITE_PROTOCOL_STANDARD_MODE) {
279         LOGI("not standard iso, not need to check.");
280         return true;
281     }
282     return HcStrlen(pinCode) >= PIN_CODE_LEN_LONG;
283 }
284 #endif
285 
GetSharedSecretForPinInIso(const CJson * in,Uint8Buff * sharedSecret)286 static int32_t GetSharedSecretForPinInIso(const CJson *in, Uint8Buff *sharedSecret)
287 {
288     const char *pinCode = GetStringFromJson(in, FIELD_PIN_CODE);
289     if (pinCode == NULL) {
290         LOGE("Failed to get pinCode!");
291         return HC_ERR_JSON_GET;
292     }
293     if (HcStrlen(pinCode) < PIN_CODE_LEN_SHORT) {
294         LOGE("Pin code is too short!");
295         return HC_ERR_INVALID_LEN;
296     }
297 #ifdef ENABLE_P2P_BIND_LITE_PROTOCOL_CHECK
298     if (!CheckPinLenForStandardIso(in, pinCode)) {
299         LOGE("Invalid pin code len!");
300         return HC_ERR_INVALID_LEN;
301     }
302 #endif
303     uint8_t *seedVal = (uint8_t *)HcMalloc(SEED_LEN, 0);
304     if (seedVal == NULL) {
305         LOGE("Failed to alloc seed memory!");
306         return HC_ERR_ALLOC_MEMORY;
307     }
308     Uint8Buff seedBuff = { seedVal, SEED_LEN };
309     int32_t ret = GetByteFromJson(in, FIELD_SEED, seedBuff.val, seedBuff.length);
310     if (ret != HC_SUCCESS) {
311         LOGE("Failed to get seed from json!");
312         HcFree(seedVal);
313         return HC_ERR_JSON_GET;
314     }
315     uint8_t *pskVal = (uint8_t *)HcMalloc(ISO_PSK_LEN, 0);
316     if (pskVal == NULL) {
317         LOGE("Failed to alloc psk memory!");
318         HcFree(seedVal);
319         return HC_ERR_ALLOC_MEMORY;
320     }
321     sharedSecret->val = pskVal;
322     sharedSecret->length = ISO_PSK_LEN;
323     ret = AuthGeneratePskUsePin(in, &seedBuff, pinCode, sharedSecret);
324     HcFree(seedVal);
325     if (ret != HC_SUCCESS) {
326         LOGE("Failed to generate psk use pin!");
327         FreeBuffData(sharedSecret);
328     }
329     return ret;
330 }
331 
GetSharedSecretForPinInPake(const CJson * in,Uint8Buff * sharedSecret)332 static int32_t GetSharedSecretForPinInPake(const CJson *in, Uint8Buff *sharedSecret)
333 {
334     const char *pinCode = GetStringFromJson(in, FIELD_PIN_CODE);
335     if (pinCode == NULL) {
336         LOGE("Failed to get pinCode!");
337         return HC_ERR_JSON_GET;
338     }
339     uint32_t pinLen = HcStrlen(pinCode);
340     if (pinLen < PIN_CODE_LEN_SHORT) {
341         LOGE("Invalid pin code len!");
342         return HC_ERR_INVALID_LEN;
343     }
344     sharedSecret->val = (uint8_t *)HcMalloc(pinLen, 0);
345     if (sharedSecret->val == NULL) {
346         LOGE("Failed to alloc sharedSecret memory!");
347         return HC_ERR_ALLOC_MEMORY;
348     }
349     if (memcpy_s(sharedSecret->val, pinLen, pinCode, pinLen) != HC_SUCCESS) {
350         LOGE("Failed to memcpy pinCode!");
351         FreeBuffData(sharedSecret);
352         return HC_ERR_MEMORY_COPY;
353     }
354     sharedSecret->length = pinLen;
355     return HC_SUCCESS;
356 }
357 
GetSharedSecretByUrl(const CJson * in,const Uint8Buff * presharedUrl,ProtocolAlgType protocolType,Uint8Buff * sharedSecret)358 static int32_t GetSharedSecretByUrl(
359     const CJson *in, const Uint8Buff *presharedUrl, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
360 {
361     if (in == NULL || presharedUrl == NULL || sharedSecret == NULL) {
362         LOGE("Invalid input params!");
363         return HC_ERR_INVALID_PARAMS;
364     }
365     int32_t ret;
366     if (protocolType == ALG_ISO) {
367         ret = GetSharedSecretForPinInIso(in, sharedSecret);
368         LOGI("get shared secret for pin in iso result: %" LOG_PUB "d", ret);
369     } else {
370         ret = GetSharedSecretForPinInPake(in, sharedSecret);
371         LOGI("get shared secret for pin in pake result: %" LOG_PUB "d", ret);
372     }
373     return ret;
374 }
375 
GetCredInfoByPeerCert(const CJson * in,const CertInfo * certInfo,IdentityInfo ** returnInfo)376 static int32_t GetCredInfoByPeerCert(const CJson *in, const CertInfo *certInfo, IdentityInfo **returnInfo)
377 {
378     // NOT SUPPORT FOR PIN
379     (void)returnInfo;
380     (void)certInfo;
381     (void)in;
382     return HC_ERR_ALG_FAIL;
383 }
384 
GetSharedSecretByPeerCert(const CJson * in,const CertInfo * peerCertInfo,ProtocolAlgType protocolType,Uint8Buff * sharedSecret)385 static int32_t GetSharedSecretByPeerCert(
386     const CJson *in, const CertInfo *peerCertInfo, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
387 {
388     // NOT SUPPORT FOR PIN
389     (void)sharedSecret;
390     (void)protocolType;
391     (void)peerCertInfo;
392     (void)in;
393     return HC_ERR_ALG_FAIL;
394 }
395 
396 static const AuthIdentity g_authIdentity = {
397     .getCredInfosByPeerIdentity = GetCredInfosByPeerIdentity,
398     .getCredInfoByPeerUrl = GetCredInfoByPeerUrl,
399     .getSharedSecretByUrl = GetSharedSecretByUrl,
400     .getCredInfoByPeerCert = GetCredInfoByPeerCert,
401     .getSharedSecretByPeerCert = GetSharedSecretByPeerCert,
402 };
403 
GetPinAuthIdentity(void)404 const AuthIdentity *GetPinAuthIdentity(void)
405 {
406     return &g_authIdentity;
407 }