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 CJson * in,const Uint8Buff * seed,const char * pinCode,Uint8Buff * sharedSecret)231 static int32_t AuthGeneratePskUsePin(const CJson *in, const Uint8Buff *seed, const char *pinCode,
232 Uint8Buff *sharedSecret)
233 {
234 int32_t osAccountId;
235 if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
236 LOGE("Failed to get osAccountId!");
237 return HC_ERR_JSON_GET;
238 }
239 Uint8Buff messageBuf = { (uint8_t *)pinCode, (uint32_t)HcStrlen(pinCode) };
240 uint8_t hash[SHA256_LEN] = { 0 };
241 Uint8Buff hashBuf = { hash, sizeof(hash) };
242 int ret = GetLoaderInstance()->sha256(&messageBuf, &hashBuf);
243 if (ret != HC_SUCCESS) {
244 LOGE("sha256 failed, ret:%d", ret);
245 return ret;
246 }
247 KeyParams keyParams = { { hashBuf.val, hashBuf.length, false }, false, osAccountId };
248 return GetLoaderInstance()->computeHmac(&keyParams, seed, sharedSecret);
249 }
250
251 #ifdef ENABLE_P2P_BIND_LITE_PROTOCOL_CHECK
CheckPinLenForStandardIso(const CJson * in,const char * pinCode)252 static bool CheckPinLenForStandardIso(const CJson *in, const char *pinCode)
253 {
254 int32_t protocolExpandVal = INVALID_PROTOCOL_EXPAND_VALUE;
255 (void)GetIntFromJson(in, FIELD_PROTOCOL_EXPAND, &protocolExpandVal);
256 if (protocolExpandVal != LITE_PROTOCOL_STANDARD_MODE) {
257 LOGI("not standard iso, no need to check.");
258 return true;
259 }
260 return HcStrlen(pinCode) >= PIN_CODE_LEN_LONG;
261 }
262 #endif
263
GetSharedSecretForPinInIso(const CJson * in,Uint8Buff * sharedSecret)264 static int32_t GetSharedSecretForPinInIso(const CJson *in, Uint8Buff *sharedSecret)
265 {
266 const char *pinCode = GetStringFromJson(in, FIELD_PIN_CODE);
267 if (pinCode == NULL) {
268 LOGE("Failed to get pinCode!");
269 return HC_ERR_JSON_GET;
270 }
271 if (HcStrlen(pinCode) < PIN_CODE_LEN_SHORT) {
272 LOGE("Pin code is too short!");
273 return HC_ERR_INVALID_LEN;
274 }
275 #ifdef ENABLE_P2P_BIND_LITE_PROTOCOL_CHECK
276 if (!CheckPinLenForStandardIso(in, pinCode)) {
277 LOGE("Invalid pin code len!");
278 return HC_ERR_INVALID_LEN;
279 }
280 #endif
281 uint8_t *seedVal = (uint8_t *)HcMalloc(SEED_LEN, 0);
282 if (seedVal == NULL) {
283 LOGE("Failed to alloc seed memory!");
284 return HC_ERR_ALLOC_MEMORY;
285 }
286 Uint8Buff seedBuff = { seedVal, SEED_LEN };
287 int32_t ret = GetByteFromJson(in, FIELD_SEED, seedBuff.val, seedBuff.length);
288 if (ret != HC_SUCCESS) {
289 LOGE("Failed to get seed!");
290 HcFree(seedVal);
291 return HC_ERR_JSON_GET;
292 }
293 uint8_t *pskVal = (uint8_t *)HcMalloc(ISO_PSK_LEN, 0);
294 if (pskVal == NULL) {
295 LOGE("Failed to alloc psk memory!");
296 HcFree(seedVal);
297 return HC_ERR_ALLOC_MEMORY;
298 }
299 sharedSecret->val = pskVal;
300 sharedSecret->length = ISO_PSK_LEN;
301 ret = AuthGeneratePskUsePin(in, &seedBuff, pinCode, sharedSecret);
302 HcFree(seedVal);
303 if (ret != HC_SUCCESS) {
304 LOGE("Failed to generate psk use pin!");
305 FreeBuffData(sharedSecret);
306 }
307 return ret;
308 }
309
GetSharedSecretForPinInPake(const CJson * in,Uint8Buff * sharedSecret)310 static int32_t GetSharedSecretForPinInPake(const CJson *in, Uint8Buff *sharedSecret)
311 {
312 const char *pinCode = GetStringFromJson(in, FIELD_PIN_CODE);
313 if (pinCode == NULL) {
314 LOGE("Failed to get pinCode!");
315 return HC_ERR_JSON_GET;
316 }
317 uint32_t pinLen = HcStrlen(pinCode);
318 if (pinLen < PIN_CODE_LEN_SHORT) {
319 LOGE("Invalid pin code len!");
320 return HC_ERR_INVALID_LEN;
321 }
322 sharedSecret->val = (uint8_t *)HcMalloc(pinLen, 0);
323 if (sharedSecret->val == NULL) {
324 LOGE("Failed to alloc sharedSecret memory!");
325 return HC_ERR_ALLOC_MEMORY;
326 }
327 if (memcpy_s(sharedSecret->val, pinLen, pinCode, pinLen) != HC_SUCCESS) {
328 LOGE("Failed to memcpy pinCode!");
329 FreeBuffData(sharedSecret);
330 return HC_ERR_MEMORY_COPY;
331 }
332 sharedSecret->length = pinLen;
333 return HC_SUCCESS;
334 }
335
GetSharedSecretByUrl(const CJson * in,const Uint8Buff * presharedUrl,ProtocolAlgType protocolType,Uint8Buff * sharedSecret)336 static int32_t GetSharedSecretByUrl(
337 const CJson *in, const Uint8Buff *presharedUrl, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
338 {
339 if (in == NULL || presharedUrl == NULL || sharedSecret == NULL) {
340 LOGE("Invalid input params!");
341 return HC_ERR_INVALID_PARAMS;
342 }
343 int32_t ret;
344 if (protocolType == ALG_ISO) {
345 ret = GetSharedSecretForPinInIso(in, sharedSecret);
346 LOGI("get shared secret for pin in iso result: %d", ret);
347 } else {
348 ret = GetSharedSecretForPinInPake(in, sharedSecret);
349 LOGI("get shared secret for pin in pake result: %d", ret);
350 }
351
352 return ret;
353 }
354
GetCredInfoByPeerCert(const CJson * in,const CertInfo * certInfo,IdentityInfo ** returnInfo)355 static int32_t GetCredInfoByPeerCert(const CJson *in, const CertInfo *certInfo, IdentityInfo **returnInfo)
356 {
357 // NOT SUPPORT FOR PIN
358 (void)in;
359 (void)certInfo;
360 (void)returnInfo;
361 return HC_ERR_ALG_FAIL;
362 }
363
GetSharedSecretByPeerCert(const CJson * in,const CertInfo * peerCertInfo,ProtocolAlgType protocolType,Uint8Buff * sharedSecret)364 static int32_t GetSharedSecretByPeerCert(
365 const CJson *in, const CertInfo *peerCertInfo, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
366 {
367 // NOT SUPPORT FOR PIN
368 (void)in;
369 (void)peerCertInfo;
370 (void)protocolType;
371 (void)sharedSecret;
372 return HC_ERR_ALG_FAIL;
373 }
374
375 static const AuthIdentity g_authIdentity = {
376 .getCredInfosByPeerIdentity = GetCredInfosByPeerIdentity,
377 .getCredInfoByPeerUrl = GetCredInfoByPeerUrl,
378 .getSharedSecretByUrl = GetSharedSecretByUrl,
379 .getCredInfoByPeerCert = GetCredInfoByPeerCert,
380 .getSharedSecretByPeerCert = GetSharedSecretByPeerCert,
381 };
382
GetPinAuthIdentity(void)383 const AuthIdentity *GetPinAuthIdentity(void)
384 {
385 return &g_authIdentity;
386 }