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