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 }