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