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 if (info->protocolVec.pushBack(&info->protocolVec, (const ProtocolEntity **)&ecSpekeEntity) == NULL) {
129 LOGE("Failed to push ecspeke entity!");
130 HcFree(ecSpekeEntity);
131 return HC_ERR_ALLOC_MEMORY;
132 }
133 #else
134 #endif
135
136 return HC_SUCCESS;
137 }
138
GetCredInfosByPeerIdentity(const CJson *in, IdentityInfoVec *vec)139 static int32_t GetCredInfosByPeerIdentity(const CJson *in, IdentityInfoVec *vec)
140 {
141 IdentityInfo *info = CreateIdentityInfo();
142 if (info == NULL) {
143 LOGE("Failed to create identity info!");
144 return HC_ERR_ALLOC_MEMORY;
145 }
146 CJson *urlJson = CreateCredUrlJson(PRE_SHARED, KEY_TYPE_SYM, TRUST_TYPE_PIN);
147 if (!urlJson) {
148 LOGE("Failed to create CredUrlJson info!");
149 DestroyIdentityInfo(info);
150 return HC_ERR_ALLOC_MEMORY;
151 }
152 if (IsDirectAuth(in) && AddBoolToJson(urlJson, FIELD_IS_DIRECT_AUTH, true) != HC_SUCCESS) {
153 LOGE("Failed to isDirectAuth to preshared url!");
154 FreeJson(urlJson);
155 DestroyIdentityInfo(info);
156 return HC_ERR_JSON_ADD;
157 }
158 char *urlStr = PackJsonToString(urlJson);
159 FreeJson(urlJson);
160 if (urlStr == NULL) {
161 LOGE("Failed to pack url json to string!");
162 DestroyIdentityInfo(info);
163 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
164 }
165 int32_t ret = SetPreSharedUrlForProof(urlStr, &info->proof.preSharedUrl);
166 FreeJsonString(urlStr);
167 if (ret != HC_SUCCESS) {
168 LOGE("Failed to set preSharedUrl of proof!");
169 DestroyIdentityInfo(info);
170 return ret;
171 }
172 if (IsDirectAuth(in)) {
173 ret = SetProtocolsForDirectAuth(info);
174 info->IdInfoType = P2P_DIRECT_AUTH;
175 } else {
176 ret = SetProtocolsForPinType(in, info);
177 }
178 if (ret != HC_SUCCESS) {
179 LOGE("Failed to set protocols!");
180 DestroyIdentityInfo(info);
181 return ret;
182 }
183 info->proofType = PRE_SHARED;
184 vec->pushBack(vec, (const IdentityInfo **)&info);
185 return HC_SUCCESS;
186 }
187
GetCredInfoByPeerUrl(const CJson *in, const Uint8Buff *presharedUrl, IdentityInfo **returnInfo)188 static int32_t GetCredInfoByPeerUrl(const CJson *in, const Uint8Buff *presharedUrl, IdentityInfo **returnInfo)
189 {
190 if (in == NULL || presharedUrl == NULL || returnInfo == NULL) {
191 LOGE("Invalid input params!");
192 return HC_ERR_INVALID_PARAMS;
193 }
194 IdentityInfo *info = CreateIdentityInfo();
195 if (info == NULL) {
196 LOGE("Failed to create identity info!");
197 return HC_ERR_ALLOC_MEMORY;
198 }
199 CJson *urlJson = CreateJsonFromString((const char *)presharedUrl->val);
200 if (urlJson == NULL) {
201 LOGE("Failed to create url json!");
202 DestroyIdentityInfo(info);
203 return HC_ERR_JSON_CREATE;
204 }
205 int32_t credentialType = PRE_SHARED;
206 if (GetIntFromJson(urlJson, PRESHARED_URL_CREDENTIAL_TYPE, &credentialType) != HC_SUCCESS) {
207 LOGE("Failed to get credential type!");
208 DestroyIdentityInfo(info);
209 FreeJson(urlJson);
210 return HC_ERR_JSON_GET;
211 }
212 FreeJson(urlJson);
213 int32_t ret = SetPreSharedUrlForProof((const char *)presharedUrl->val, &info->proof.preSharedUrl);
214 if (ret != HC_SUCCESS) {
215 LOGE("Failed to set preSharedUrl of proof!");
216 DestroyIdentityInfo(info);
217 return ret;
218 }
219 if (IsDirectAuth(in)) {
220 ret = SetProtocolsForDirectAuth(info);
221 info->IdInfoType = P2P_DIRECT_AUTH;
222 } else {
223 ret = SetProtocolsForPinType(in, info);
224 }
225 if (ret != HC_SUCCESS) {
226 LOGE("Failed to set protocols!");
227 DestroyIdentityInfo(info);
228 return ret;
229 }
230 info->proofType = credentialType;
231 *returnInfo = info;
232 return HC_SUCCESS;
233 }
234
AuthGeneratePskUsePin(const CJson *in, const Uint8Buff *seed, const char *pinCode, Uint8Buff *sharedSecret)235 static int32_t AuthGeneratePskUsePin(const CJson *in, const Uint8Buff *seed, const char *pinCode,
236 Uint8Buff *sharedSecret)
237 {
238 int32_t osAccountId;
239 if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
240 LOGE("Failed to get osAccountId!");
241 return HC_ERR_JSON_GET;
242 }
243 Uint8Buff messageBuf = { (uint8_t *)pinCode, (uint32_t)HcStrlen(pinCode) };
244 uint8_t hash[SHA256_LEN] = { 0 };
245 Uint8Buff hashBuf = { hash, sizeof(hash) };
246 int ret = GetLoaderInstance()->sha256(&messageBuf, &hashBuf);
247 if (ret != HC_SUCCESS) {
248 LOGE("sha256 failed, ret:%d", ret);
249 return ret;
250 }
251 KeyParams keyParams = { { hashBuf.val, hashBuf.length, false }, false, osAccountId };
252 return GetLoaderInstance()->computeHmac(&keyParams, seed, sharedSecret);
253 }
254
255 #ifdef ENABLE_P2P_BIND_LITE_PROTOCOL_CHECK
CheckPinLenForStandardIso(const CJson *in, const char *pinCode)256 static bool CheckPinLenForStandardIso(const CJson *in, const char *pinCode)
257 {
258 int32_t protocolExpandVal = INVALID_PROTOCOL_EXPAND_VALUE;
259 (void)GetIntFromJson(in, FIELD_PROTOCOL_EXPAND, &protocolExpandVal);
260 if (protocolExpandVal != LITE_PROTOCOL_STANDARD_MODE) {
261 LOGI("not standard iso, no need to check.");
262 return true;
263 }
264 return HcStrlen(pinCode) >= PIN_CODE_LEN_LONG;
265 }
266 #endif
267
GetSharedSecretForPinInIso(const CJson *in, Uint8Buff *sharedSecret)268 static int32_t GetSharedSecretForPinInIso(const CJson *in, Uint8Buff *sharedSecret)
269 {
270 const char *pinCode = GetStringFromJson(in, FIELD_PIN_CODE);
271 if (pinCode == NULL) {
272 LOGE("Failed to get pinCode!");
273 return HC_ERR_JSON_GET;
274 }
275 if (HcStrlen(pinCode) < PIN_CODE_LEN_SHORT) {
276 LOGE("Pin code is too short!");
277 return HC_ERR_INVALID_LEN;
278 }
279 #ifdef ENABLE_P2P_BIND_LITE_PROTOCOL_CHECK
280 if (!CheckPinLenForStandardIso(in, pinCode)) {
281 LOGE("Invalid pin code len!");
282 return HC_ERR_INVALID_LEN;
283 }
284 #endif
285 uint8_t *seedVal = (uint8_t *)HcMalloc(SEED_LEN, 0);
286 if (seedVal == NULL) {
287 LOGE("Failed to alloc seed memory!");
288 return HC_ERR_ALLOC_MEMORY;
289 }
290 Uint8Buff seedBuff = { seedVal, SEED_LEN };
291 int32_t ret = GetByteFromJson(in, FIELD_SEED, seedBuff.val, seedBuff.length);
292 if (ret != HC_SUCCESS) {
293 LOGE("Failed to get seed!");
294 HcFree(seedVal);
295 return HC_ERR_JSON_GET;
296 }
297 uint8_t *pskVal = (uint8_t *)HcMalloc(ISO_PSK_LEN, 0);
298 if (pskVal == NULL) {
299 LOGE("Failed to alloc psk memory!");
300 HcFree(seedVal);
301 return HC_ERR_ALLOC_MEMORY;
302 }
303 sharedSecret->val = pskVal;
304 sharedSecret->length = ISO_PSK_LEN;
305 ret = AuthGeneratePskUsePin(in, &seedBuff, pinCode, sharedSecret);
306 HcFree(seedVal);
307 if (ret != HC_SUCCESS) {
308 LOGE("Failed to generate psk use pin!");
309 FreeBuffData(sharedSecret);
310 }
311 return ret;
312 }
313
GetSharedSecretForPinInPake(const CJson *in, Uint8Buff *sharedSecret)314 static int32_t GetSharedSecretForPinInPake(const CJson *in, Uint8Buff *sharedSecret)
315 {
316 const char *pinCode = GetStringFromJson(in, FIELD_PIN_CODE);
317 if (pinCode == NULL) {
318 LOGE("Failed to get pinCode!");
319 return HC_ERR_JSON_GET;
320 }
321 uint32_t pinLen = HcStrlen(pinCode);
322 if (pinLen < PIN_CODE_LEN_SHORT) {
323 LOGE("Invalid pin code len!");
324 return HC_ERR_INVALID_LEN;
325 }
326 sharedSecret->val = (uint8_t *)HcMalloc(pinLen, 0);
327 if (sharedSecret->val == NULL) {
328 LOGE("Failed to alloc sharedSecret memory!");
329 return HC_ERR_ALLOC_MEMORY;
330 }
331 if (memcpy_s(sharedSecret->val, pinLen, pinCode, pinLen) != HC_SUCCESS) {
332 LOGE("Failed to memcpy pinCode!");
333 FreeBuffData(sharedSecret);
334 return HC_ERR_MEMORY_COPY;
335 }
336 sharedSecret->length = pinLen;
337 return HC_SUCCESS;
338 }
339
GetSharedSecretByUrl( const CJson *in, const Uint8Buff *presharedUrl, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)340 static int32_t GetSharedSecretByUrl(
341 const CJson *in, const Uint8Buff *presharedUrl, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
342 {
343 if (in == NULL || presharedUrl == NULL || sharedSecret == NULL) {
344 LOGE("Invalid input params!");
345 return HC_ERR_INVALID_PARAMS;
346 }
347 int32_t ret;
348 if (protocolType == ALG_ISO) {
349 ret = GetSharedSecretForPinInIso(in, sharedSecret);
350 LOGI("get shared secret for pin in iso result: %d", ret);
351 } else {
352 ret = GetSharedSecretForPinInPake(in, sharedSecret);
353 LOGI("get shared secret for pin in pake result: %d", ret);
354 }
355
356 return ret;
357 }
358
GetCredInfoByPeerCert(const CJson *in, const CertInfo *certInfo, IdentityInfo **returnInfo)359 static int32_t GetCredInfoByPeerCert(const CJson *in, const CertInfo *certInfo, IdentityInfo **returnInfo)
360 {
361 // NOT SUPPORT FOR PIN
362 (void)in;
363 (void)certInfo;
364 (void)returnInfo;
365 return HC_ERR_ALG_FAIL;
366 }
367
GetSharedSecretByPeerCert( const CJson *in, const CertInfo *peerCertInfo, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)368 static int32_t GetSharedSecretByPeerCert(
369 const CJson *in, const CertInfo *peerCertInfo, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
370 {
371 // NOT SUPPORT FOR PIN
372 (void)in;
373 (void)peerCertInfo;
374 (void)protocolType;
375 (void)sharedSecret;
376 return HC_ERR_ALG_FAIL;
377 }
378
379 static const AuthIdentity g_authIdentity = {
380 .getCredInfosByPeerIdentity = GetCredInfosByPeerIdentity,
381 .getCredInfoByPeerUrl = GetCredInfoByPeerUrl,
382 .getSharedSecretByUrl = GetSharedSecretByUrl,
383 .getCredInfoByPeerCert = GetCredInfoByPeerCert,
384 .getSharedSecretByPeerCert = GetSharedSecretByPeerCert,
385 };
386
GetPinAuthIdentity(void)387 const AuthIdentity *GetPinAuthIdentity(void)
388 {
389 return &g_authIdentity;
390 }