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
SetProtocolsToIdentityInfo(IdentityInfo * info)21 static int32_t SetProtocolsToIdentityInfo(IdentityInfo *info)
22 {
23 ProtocolEntity *ecSpekeEntity = (ProtocolEntity *)HcMalloc(sizeof(ProtocolEntity), 0);
24 if (ecSpekeEntity == NULL) {
25 LOGE("Failed to alloc memory for ec speke entity!");
26 return HC_ERR_ALLOC_MEMORY;
27 }
28 ecSpekeEntity->protocolType = ALG_EC_SPEKE;
29 ecSpekeEntity->expandProcessCmds = 0;
30 if (info->protocolVec.pushBack(&info->protocolVec, (const ProtocolEntity **)&ecSpekeEntity) == NULL) {
31 LOGE("Failed to push ecSpeke entity!");
32 HcFree(ecSpekeEntity);
33 return HC_ERR_ALLOC_MEMORY;
34 }
35
36 return HC_SUCCESS;
37 }
38
CombineQueryCredentialParams(const CJson * in,CJson * out)39 static int32_t CombineQueryCredentialParams(const CJson *in, CJson *out)
40 {
41 int32_t osAccountId = INVALID_OS_ACCOUNT;
42 if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
43 LOGE("Failed to get osAccountId from context!");
44 return HC_ERR_JSON_GET;
45 }
46 const char *peerConnDeviceId = GetStringFromJson(in, FIELD_PEER_CONN_DEVICE_ID);
47 if (peerConnDeviceId == NULL) {
48 LOGE("Failed to get peerConnDeviceId from context, need peerConnDeviceId!");
49 return HC_ERR_JSON_GET;
50 }
51 int32_t acquireType = ACQUIRE_TYPE_INVALID;
52 if (GetIntFromJson(in, FIELD_ACQURIED_TYPE, &acquireType) != HC_SUCCESS) {
53 LOGE("Failed to get acquireType from context!");
54 return HC_ERR_JSON_GET;
55 }
56 if (acquireType != P2P_BIND) {
57 LOGE("acquireType invalid! only P2P_BIND is allowed now!");
58 return HC_ERR_INVALID_PARAMS;
59 }
60 if (AddIntToJson(out, FIELD_OS_ACCOUNT_ID, osAccountId) != HC_SUCCESS) {
61 LOGE("add osAccountId to json error!");
62 return HC_ERR_JSON_ADD;
63 }
64 if (AddIntToJson(out, FIELD_ACQURIED_TYPE, acquireType) != HC_SUCCESS) {
65 LOGE("add acquireType to json error!");
66 return HC_ERR_JSON_ADD;
67 }
68 if (AddIntToJson(out, FIELD_CRED_OP_FLAG, RETURN_FLAG_DEFAULT) != HC_SUCCESS) {
69 LOGE("add flag to json error!");
70 return HC_ERR_JSON_ADD;
71 }
72 if (AddStringToJson(out, FIELD_DEVICE_ID, peerConnDeviceId) != HC_SUCCESS) {
73 LOGE("add device id to json error!");
74 return HC_ERR_JSON_ADD;
75 }
76 return HC_SUCCESS;
77 }
78
IsPeerDevicePublicKeyExist(const CJson * in)79 static int32_t IsPeerDevicePublicKeyExist(const CJson *in)
80 {
81 CJson *paramsJson = CreateJson();
82 if (paramsJson == NULL) {
83 LOGE("alloc memory error!");
84 return HC_ERR_ALLOC_MEMORY;
85 }
86 int32_t ret = CombineQueryCredentialParams(in, paramsJson);
87 if (ret != HC_SUCCESS) {
88 LOGE("Prepare query credential parmaters return error!");
89 FreeJson(paramsJson);
90 return ret;
91 }
92 const CredentialOperator *credOperator = GetCredentialOperator();
93 if (credOperator == NULL) {
94 LOGE("credOperator is null!");
95 FreeJson(paramsJson);
96 return HC_ERR_NOT_SUPPORT;
97 }
98 char *requestParams = PackJsonToString(paramsJson);
99 FreeJson(paramsJson);
100 if (requestParams == NULL) {
101 LOGE("Failed to pack query credentail params json to string!");
102 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
103 }
104 ret = credOperator->queryCredential(requestParams, NULL);
105 FreeJsonString(requestParams);
106 return ret;
107 }
108
CreateUrlStr(int32_t keyType,char ** urlStr)109 static int32_t CreateUrlStr(int32_t keyType, char **urlStr)
110 {
111 CJson *urlJson = CreateCredUrlJson(PRE_SHARED, keyType, TRUST_TYPE_P2P);
112 if (!urlJson) {
113 LOGE("Failed to create CredUrlJson info!");
114 return HC_ERR_ALLOC_MEMORY;
115 }
116 if (AddBoolToJson(urlJson, FIELD_IS_DIRECT_AUTH, true) != HC_SUCCESS) {
117 LOGE("Failed to add isDirectAuth to preshared url!");
118 FreeJson(urlJson);
119 return HC_ERR_JSON_ADD;
120 } else {
121 LOGI("add isDirectAuth:true into urlJson!");
122 }
123 char *str = PackJsonToString(urlJson);
124 FreeJson(urlJson);
125 if (str == NULL) {
126 LOGE("Failed to pack url json to string!");
127 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
128 }
129 *urlStr = str;
130 return HC_SUCCESS;
131 }
132
GetCredInfosByPeerIdentity(const CJson * in,IdentityInfoVec * vec)133 static int32_t GetCredInfosByPeerIdentity(const CJson *in, IdentityInfoVec *vec)
134 {
135 int32_t keyType = KEY_TYPE_ASYM;
136 (void)GetIntFromJson(in, FIELD_KEY_TYPE, &keyType);
137
138 int32_t ret = IsPeerDevicePublicKeyExist(in);
139 if (ret != HC_SUCCESS) {
140 LOGE("Failed to get peer device public key!");
141 return ret;
142 }
143
144 char *urlStr = NULL;
145 ret = CreateUrlStr(keyType, &urlStr);
146 if (ret != HC_SUCCESS) {
147 LOGE("Failed to create url string!");
148 return ret;
149 }
150 IdentityInfo *info = CreateIdentityInfo();
151 if (info == NULL) {
152 LOGE("Failed to create identity info!");
153 FreeJsonString(urlStr);
154 return HC_ERR_ALLOC_MEMORY;
155 }
156 ret = SetPreSharedUrlForProof(urlStr, &info->proof.preSharedUrl);
157 FreeJsonString(urlStr);
158 if (ret != HC_SUCCESS) {
159 LOGE("Failed to set preSharedUrl of proof!");
160 DestroyIdentityInfo(info);
161 return ret;
162 }
163 ret = SetProtocolsToIdentityInfo(info);
164 if (ret != HC_SUCCESS) {
165 LOGE("Failed to set protocols!");
166 DestroyIdentityInfo(info);
167 return ret;
168 }
169 info->proofType = PRE_SHARED;
170 info->IdInfoType = P2P_DIRECT_AUTH;
171 if (vec->pushBack(vec, (const IdentityInfo **)&info) == NULL) {
172 LOGE("Failed to push info!");
173 DestroyIdentityInfo(info);
174 return HC_ERR_ALLOC_MEMORY;
175 }
176 return HC_SUCCESS;
177 }
178
GetCredInfoByPeerUrl(const CJson * in,const Uint8Buff * presharedUrl,IdentityInfo ** returnInfo)179 static int32_t GetCredInfoByPeerUrl(const CJson *in, const Uint8Buff *presharedUrl, IdentityInfo **returnInfo)
180 {
181 if (in == NULL || presharedUrl == NULL || returnInfo == NULL) {
182 LOGE("Invalid input params!");
183 return HC_ERR_INVALID_PARAMS;
184 }
185 IdentityInfo *info = CreateIdentityInfo();
186 if (info == NULL) {
187 LOGE("Failed to create identity info!");
188 return HC_ERR_ALLOC_MEMORY;
189 }
190 int32_t ret = SetPreSharedUrlForProof((const char *)presharedUrl->val, &info->proof.preSharedUrl);
191 if (ret != HC_SUCCESS) {
192 LOGE("Failed to set preSharedUrl of proof!");
193 DestroyIdentityInfo(info);
194 return ret;
195 }
196 ret = SetProtocolsToIdentityInfo(info);
197 if (ret != HC_SUCCESS) {
198 LOGE("Failed to set protocols!");
199 DestroyIdentityInfo(info);
200 return ret;
201 }
202 info->proofType = PRE_SHARED;
203 info->IdInfoType = P2P_DIRECT_AUTH;
204 *returnInfo = info;
205 return HC_SUCCESS;
206 }
207
208 /**
209 * @brief compute shared key alias
210 *
211 * @param osAccountId
212 * @param selfAuthId self device udid
213 * @param peerAuthId peer device udid
214 * @param sharedKeyAlias
215 * @return int32_t
216 */
ComputeAndSaveDirectAuthPsk(int32_t osAccountId,const char * selfAuthId,const char * peerAuthId,const char * peerServiceType,const Uint8Buff * sharedKeyAlias)217 static int32_t ComputeAndSaveDirectAuthPsk(int32_t osAccountId, const char *selfAuthId, const char *peerAuthId,
218 const char *peerServiceType, const Uint8Buff *sharedKeyAlias)
219 {
220 Uint8Buff selfAuthIdBuff = { (uint8_t *)selfAuthId, HcStrlen(selfAuthId) };
221 Uint8Buff pkgNameBuff = { (uint8_t *)DEFAULT_PACKAGE_NAME, HcStrlen(DEFAULT_PACKAGE_NAME) };
222 Uint8Buff serviceTypeBuff = { (uint8_t *)DEFAULT_SERVICE_TYPE, HcStrlen(DEFAULT_SERVICE_TYPE) };
223 KeyAliasType keyType = KEY_ALIAS_P2P_AUTH;
224 uint8_t selfKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
225 Uint8Buff selfKeyAlias = { selfKeyAliasVal, PAKE_KEY_ALIAS_LEN };
226 int32_t ret = GenerateKeyAlias(&pkgNameBuff, &serviceTypeBuff, keyType, &selfAuthIdBuff, &selfKeyAlias);
227 if (ret != HC_SUCCESS) {
228 LOGE("Failed to generate self key alias!");
229 return ret;
230 }
231 LOGI("selfKeyAlias: %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x****.", selfKeyAlias.val[DEV_AUTH_ZERO],
232 selfKeyAlias.val[DEV_AUTH_ONE], selfKeyAlias.val[DEV_AUTH_TWO], selfKeyAlias.val[DEV_AUTH_THREE]);
233
234 Uint8Buff peerServiceTypeBuff = { (uint8_t *)peerServiceType, HcStrlen(peerServiceType) };
235 KeyAliasType keyTypePeer = KEY_ALIAS_P2P_AUTH;
236 Uint8Buff peerAuthIdBuff = { (uint8_t *)peerAuthId, HcStrlen(peerAuthId) };
237 uint8_t peerKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
238 Uint8Buff peerKeyAlias = { peerKeyAliasVal, PAKE_KEY_ALIAS_LEN };
239 ret = GenerateKeyAlias(&pkgNameBuff, &peerServiceTypeBuff, keyTypePeer, &peerAuthIdBuff, &peerKeyAlias);
240 if (ret != HC_SUCCESS) {
241 LOGE("Failed to generate peer key alias!");
242 return ret;
243 }
244 LOGI("peerKeyAlias: %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x****.", peerKeyAlias.val[DEV_AUTH_ZERO],
245 peerKeyAlias.val[DEV_AUTH_ONE], peerKeyAlias.val[DEV_AUTH_TWO], peerKeyAlias.val[DEV_AUTH_THREE]);
246
247 ret = GetLoaderInstance()->checkKeyExist(&selfKeyAlias, false, osAccountId);
248 if (ret != HC_SUCCESS) {
249 LOGE("self auth keyPair not exist!");
250 return ret;
251 }
252 ret = GetLoaderInstance()->checkKeyExist(&peerKeyAlias, false, osAccountId);
253 if (ret != HC_SUCCESS) {
254 LOGE("peer auth pubKey not exist!");
255 return ret;
256 }
257
258 KeyParams selfKeyParams = { { selfKeyAlias.val, selfKeyAlias.length, true }, false, osAccountId };
259 KeyBuff peerKeyBuff = { peerKeyAlias.val, peerKeyAlias.length, true };
260 return GetLoaderInstance()->agreeSharedSecretWithStorage(
261 &selfKeyParams, &peerKeyBuff, ED25519, PAKE_PSK_LEN, sharedKeyAlias);
262 }
263
GetDirectAuthPskAliasCreateIfNeeded(const CJson * in,Uint8Buff * pskKeyAlias)264 static int32_t GetDirectAuthPskAliasCreateIfNeeded(const CJson *in, Uint8Buff *pskKeyAlias)
265 {
266 int32_t osAccountId = INVALID_OS_ACCOUNT;
267 if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
268 LOGE("Failed to get osAccountId!");
269 return HC_ERR_JSON_GET;
270 }
271 const char *selfAuthId = GetStringFromJson(in, FIELD_AUTH_ID);
272 if (selfAuthId == NULL) {
273 LOGE("get authId from context fail.");
274 return HC_ERR_JSON_GET;
275 }
276 const char *peerAuthId = GetStringFromJson(in, FIELD_PEER_CONN_DEVICE_ID);
277 if (peerAuthId == NULL) {
278 LOGE("get peerConnDeviceId from json fail.");
279 return HC_ERR_JSON_GET;
280 }
281 const char *peerServieType = GetStringFromJson(in, FIELD_SERVICE_TYPE);
282 if (peerServieType == NULL) {
283 LOGI("get serviceType from json fail, replace by default");
284 peerServieType = DEFAULT_SERVICE_TYPE;
285 }
286 Uint8Buff pkgNameBuff = { (uint8_t *)DEFAULT_PACKAGE_NAME, HcStrlen(DEFAULT_PACKAGE_NAME) };
287 Uint8Buff serviceTypeBuff = { (uint8_t *)peerServieType, HcStrlen(peerServieType) };
288 Uint8Buff peerAuthIdBuff = { (uint8_t *)peerAuthId, HcStrlen(peerAuthId) };
289 int32_t ret = GenerateKeyAlias(&pkgNameBuff, &serviceTypeBuff, KEY_ALIAS_PSK, &peerAuthIdBuff, pskKeyAlias);
290 if (ret != HC_SUCCESS) {
291 LOGE("Failed to generate psk key alias!");
292 return ret;
293 }
294 LOGI("psk alias: %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x****.", pskKeyAlias->val[DEV_AUTH_ZERO],
295 pskKeyAlias->val[DEV_AUTH_ONE], pskKeyAlias->val[DEV_AUTH_TWO], pskKeyAlias->val[DEV_AUTH_THREE]);
296 ret = GetLoaderInstance()->checkKeyExist(pskKeyAlias, false, osAccountId);
297 if (ret != HC_SUCCESS) {
298 ret = ComputeAndSaveDirectAuthPsk(osAccountId, selfAuthId, peerAuthId, peerServieType, pskKeyAlias);
299 }
300 return ret;
301 }
302
GetSharedSecretByUrl(const CJson * in,const Uint8Buff * presharedUrl,ProtocolAlgType protocolType,Uint8Buff * sharedSecret)303 static int32_t GetSharedSecretByUrl(
304 const CJson *in, const Uint8Buff *presharedUrl, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
305 {
306 (void)protocolType;
307 if (in == NULL || presharedUrl == NULL || sharedSecret == NULL) {
308 LOGE("Invalid input params!");
309 return HC_ERR_INVALID_PARAMS;
310 }
311 int32_t osAccountId;
312 if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
313 LOGE("Failed to get osAccountId!");
314 return HC_ERR_JSON_GET;
315 }
316 uint8_t pskKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
317 Uint8Buff pskKeyAlias = { pskKeyAliasVal, PAKE_KEY_ALIAS_LEN };
318 int32_t ret = GetDirectAuthPskAliasCreateIfNeeded(in, &pskKeyAlias);
319 if (ret != HC_SUCCESS) {
320 LOGE("Failed to generate key alias for psk!");
321 return ret;
322 }
323 uint8_t nonceVal[PAKE_NONCE_LEN] = { 0 };
324 Uint8Buff nonceBuff = { nonceVal, PAKE_NONCE_LEN };
325 if (GetByteFromJson(in, FIELD_NONCE, nonceBuff.val, nonceBuff.length) != HC_SUCCESS) {
326 LOGE("Failed to get nonce!");
327 return HC_ERR_JSON_GET;
328 }
329 uint8_t pskVal[PAKE_PSK_LEN] = { 0 };
330 Uint8Buff pskBuff = { pskVal, PAKE_PSK_LEN };
331 Uint8Buff keyInfo = { (uint8_t *)TMP_AUTH_KEY_FACTOR, HcStrlen(TMP_AUTH_KEY_FACTOR) };
332 KeyParams keyAliasParams = { { pskKeyAlias.val, pskKeyAlias.length, true }, false, osAccountId };
333 ret = GetLoaderInstance()->computeHkdf(&keyAliasParams, &nonceBuff, &keyInfo, &pskBuff);
334 if (ret != HC_SUCCESS) {
335 LOGE("Failed to compute hkdf for psk!");
336 return ret;
337 }
338 ret = ConvertPsk(&pskBuff, sharedSecret);
339 if (ret != HC_SUCCESS) {
340 LOGE("Failed to convert psk!");
341 }
342 return ret;
343 }
344
GetCredInfoByPeerCert(const CJson * in,const CertInfo * certInfo,IdentityInfo ** returnInfo)345 static int32_t GetCredInfoByPeerCert(const CJson *in, const CertInfo *certInfo, IdentityInfo **returnInfo)
346 {
347 // NOT SUPPORT FOR P2P AUTH
348 (void)in;
349 (void)certInfo;
350 (void)returnInfo;
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 P2P AUTH
358 (void)in;
359 (void)peerCertInfo;
360 (void)protocolType;
361 (void)sharedSecret;
362 return HC_ERR_ALG_FAIL;
363 }
364
365 static const AuthIdentity g_authIdentity = {
366 .getCredInfosByPeerIdentity = GetCredInfosByPeerIdentity,
367 .getCredInfoByPeerUrl = GetCredInfoByPeerUrl,
368 .getSharedSecretByUrl = GetSharedSecretByUrl,
369 .getCredInfoByPeerCert = GetCredInfoByPeerCert,
370 .getSharedSecretByPeerCert = GetSharedSecretByPeerCert,
371 };
372
GetP2pAuthIdentity(void)373 const AuthIdentity *GetP2pAuthIdentity(void)
374 {
375 return &g_authIdentity;
376 }