1 /*
2 * Copyright (C) 2021 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 "das_task_common.h"
17 #include "alg_defs.h"
18 #include "alg_loader.h"
19 #include "device_auth_defines.h"
20 #include "hc_log.h"
21 #include "hc_types.h"
22 #include "protocol_common.h"
23 #include "string_util.h"
24
25 #define MESSAGE_RETURN 0x8000
26 #define MESSAGE_PREFIX 0x0010
27
DasSendErrorToOut(CJson * out,int errCode)28 void DasSendErrorToOut(CJson *out, int errCode)
29 {
30 CJson *sendToSelf = CreateJson();
31 if (sendToSelf == NULL) {
32 LOGE("Create sendToSelf json failed.");
33 return;
34 }
35 CJson *sendToPeer = CreateJson();
36 if (sendToPeer == NULL) {
37 LOGE("Create sendToPeer json failed.");
38 FreeJson(sendToSelf);
39 return;
40 }
41 CJson *payload = CreateJson();
42 if (payload == NULL) {
43 LOGE("Create payload json failed.");
44 goto ERR;
45 }
46 int res;
47 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToSelf, FIELD_AUTH_FORM, AUTH_FORM_ACCOUNT_UNRELATED), res);
48 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToSelf, FIELD_ERROR_CODE, errCode), res);
49
50 GOTO_ERR_AND_SET_RET(AddIntToJson(payload, FIELD_ERROR_CODE, errCode), res);
51 GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_PAYLOAD, payload), res);
52 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_MESSAGE, ERR_MESSAGE), res);
53
54 GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), res);
55 GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf), res);
56 ERR:
57 FreeJson(sendToPeer);
58 FreeJson(sendToSelf);
59 FreeJson(payload);
60 }
61
DasSendErrMsgToSelf(CJson * out,int errCode)62 void DasSendErrMsgToSelf(CJson *out, int errCode)
63 {
64 CJson *sendToSelf = CreateJson();
65 if (sendToSelf == NULL) {
66 LOGE("Create sendToSelf json failed.");
67 return;
68 }
69
70 if (AddIntToJson(sendToSelf, FIELD_AUTH_FORM, AUTH_FORM_ACCOUNT_UNRELATED) != 0) {
71 FreeJson(sendToSelf);
72 LOGE("Add authForm failed.");
73 return;
74 }
75 if (AddIntToJson(sendToSelf, FIELD_ERROR_CODE, errCode) != 0) {
76 FreeJson(sendToSelf);
77 LOGE("Add errCode failed.");
78 return;
79 }
80 if (AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf) != 0) {
81 FreeJson(sendToSelf);
82 LOGE("Add sendToSelf failed.");
83 return;
84 }
85 FreeJson(sendToSelf);
86 }
87
ProtocolMessageIn(const CJson * in)88 uint32_t ProtocolMessageIn(const CJson *in)
89 {
90 int32_t message = 0;
91 if (GetIntFromJson(in, FIELD_MESSAGE, &message) != 0) {
92 return INVALID_MESSAGE;
93 }
94 if (message == ERR_MESSAGE) {
95 return ERR_MESSAGE;
96 }
97 return message & 0x000F; /* get lower 8 bit */
98 }
99
ClientProtocolMessageOut(CJson * out,int opCode,uint32_t step)100 int ClientProtocolMessageOut(CJson *out, int opCode, uint32_t step)
101 {
102 CJson *sendToPeer = GetObjFromJson(out, FIELD_SEND_TO_PEER);
103 if (sendToPeer == NULL) {
104 LOGD("No need to send to peer");
105 return HC_SUCCESS;
106 }
107 int res;
108 switch (opCode) {
109 case OP_BIND:
110 case AUTH_KEY_AGREEMENT:
111 res = AddIntToJson(sendToPeer, FIELD_MESSAGE, step);
112 break;
113 case AUTHENTICATE:
114 case OP_UNBIND:
115 step = step | MESSAGE_PREFIX;
116 res = AddIntToJson(sendToPeer, FIELD_MESSAGE, step);
117 break;
118 default:
119 LOGE("Unsupported opCode: %d.", opCode);
120 return HC_ERR_NOT_SUPPORT;
121 }
122 return (res == 0) ? HC_SUCCESS : HC_ERR_JSON_ADD;
123 }
124
ServerProtocolMessageOut(CJson * out,int opCode,uint32_t step)125 int ServerProtocolMessageOut(CJson *out, int opCode, uint32_t step)
126 {
127 int res;
128 CJson *sendToPeer = GetObjFromJson(out, FIELD_SEND_TO_PEER);
129 if (sendToPeer == NULL) {
130 LOGD("No need to send to peer");
131 return HC_SUCCESS;
132 }
133 switch (opCode) {
134 case OP_BIND:
135 case AUTH_KEY_AGREEMENT:
136 step = step | MESSAGE_RETURN;
137 res = AddIntToJson(sendToPeer, FIELD_MESSAGE, step);
138 break;
139 case AUTHENTICATE:
140 case OP_UNBIND:
141 step = step | MESSAGE_RETURN;
142 step = step | MESSAGE_PREFIX;
143 res = AddIntToJson(sendToPeer, FIELD_MESSAGE, step);
144 break;
145 default:
146 LOGE("Unsupported opCode: %d.", opCode);
147 return HC_ERR_NOT_SUPPORT;
148 }
149 return (res == 0) ? HC_SUCCESS : HC_ERR_JSON_ADD;
150 }
151
CombineServiceId(const Uint8Buff * pkgName,const Uint8Buff * serviceType,Uint8Buff * serviceId)152 static int32_t CombineServiceId(const Uint8Buff *pkgName, const Uint8Buff *serviceType, Uint8Buff *serviceId)
153 {
154 int32_t res = HC_SUCCESS;
155 Uint8Buff serviceIdPlain = { NULL, 0 };
156 serviceIdPlain.length = pkgName->length + serviceType->length;
157 serviceIdPlain.val = (uint8_t *)HcMalloc(serviceIdPlain.length, 0);
158 if (serviceIdPlain.val == NULL) {
159 LOGE("malloc serviceIdPlain.val failed.");
160 res = HC_ERR_ALLOC_MEMORY;
161 goto ERR;
162 }
163
164 if (memcpy_s(serviceIdPlain.val, serviceIdPlain.length, pkgName->val, pkgName->length) != EOK) {
165 LOGE("Copy service id: pkgName failed.");
166 res = HC_ERR_MEMORY_COPY;
167 goto ERR;
168 }
169 if (memcpy_s(serviceIdPlain.val + pkgName->length, serviceIdPlain.length - pkgName->length,
170 serviceType->val, serviceType->length) != EOK) {
171 LOGE("Copy service id: serviceType failed.");
172 res = HC_ERR_MEMORY_COPY;
173 goto ERR;
174 }
175
176 res = GetLoaderInstance()->sha256(&serviceIdPlain, serviceId);
177 if (res != HC_SUCCESS) {
178 LOGE("Service id Sha256 failed.");
179 goto ERR;
180 }
181 ERR:
182 HcFree(serviceIdPlain.val);
183 return res;
184 }
185
CombineKeyAlias(const Uint8Buff * serviceId,const Uint8Buff * keyType,const Uint8Buff * authId,Uint8Buff * keyAliasHash)186 static int32_t CombineKeyAlias(const Uint8Buff *serviceId, const Uint8Buff *keyType,
187 const Uint8Buff *authId, Uint8Buff *keyAliasHash)
188 {
189 int32_t res = HC_SUCCESS;
190 Uint8Buff keyAliasBuff = { NULL, 0 };
191 keyAliasBuff.length = serviceId->length + authId->length + keyType->length;
192 keyAliasBuff.val = (uint8_t *)HcMalloc(keyAliasBuff.length, 0);
193 if (keyAliasBuff.val == NULL) {
194 LOGE("Malloc mem failed.");
195 return HC_ERR_ALLOC_MEMORY;
196 }
197
198 uint32_t totalLen = keyAliasBuff.length;
199 uint32_t usedLen = 0;
200 if (memcpy_s(keyAliasBuff.val, totalLen, serviceId->val, serviceId->length) != EOK) {
201 LOGE("Copy serviceId failed.");
202 res = HC_ERR_MEMORY_COPY;
203 goto ERR;
204 }
205 usedLen = usedLen + serviceId->length;
206
207 if (memcpy_s(keyAliasBuff.val + usedLen, totalLen - usedLen, keyType->val, keyType->length) != EOK) {
208 LOGE("Copy keyType failed.");
209 res = HC_ERR_MEMORY_COPY;
210 goto ERR;
211 }
212 usedLen = usedLen + keyType->length;
213
214 if (memcpy_s(keyAliasBuff.val + usedLen, totalLen - usedLen, authId->val, authId->length) != EOK) {
215 LOGE("Copy authId failed.");
216 res = HC_ERR_MEMORY_COPY;
217 goto ERR;
218 }
219
220 res = GetLoaderInstance()->sha256(&keyAliasBuff, keyAliasHash);
221 if (res != HC_SUCCESS) {
222 LOGE("Sha256 failed.");
223 goto ERR;
224 }
225 ERR:
226 HcFree(keyAliasBuff.val);
227 return res;
228 }
229
CombineKeyAliasForIso(const Uint8Buff * serviceId,const Uint8Buff * keyType,const Uint8Buff * authId,Uint8Buff * outKeyAlias)230 static int32_t CombineKeyAliasForIso(const Uint8Buff *serviceId, const Uint8Buff *keyType,
231 const Uint8Buff *authId, Uint8Buff *outKeyAlias)
232 {
233 if (outKeyAlias->length != SHA256_LEN) {
234 return HC_ERR_INVALID_LEN;
235 }
236 int32_t res = CombineKeyAlias(serviceId, keyType, authId, outKeyAlias);
237 if (res != HC_SUCCESS) {
238 LOGE("CombineKeyAlias failed.");
239 return res;
240 }
241 return res;
242 }
243
CombineKeyAliasForPake(const Uint8Buff * serviceId,const Uint8Buff * keyType,const Uint8Buff * authId,Uint8Buff * outKeyAlias)244 static int32_t CombineKeyAliasForPake(const Uint8Buff *serviceId, const Uint8Buff *keyType,
245 const Uint8Buff *authId, Uint8Buff *outKeyAlias)
246 {
247 int32_t res;
248 Uint8Buff keyAliasHash = { NULL, SHA256_LEN };
249 char *outKeyAliasHex = NULL;
250 if (outKeyAlias->length != SHA256_LEN * BYTE_TO_HEX_OPER_LENGTH) {
251 res = HC_ERR_INVALID_LEN;
252 goto ERR;
253 }
254 keyAliasHash.val = (uint8_t *)HcMalloc(keyAliasHash.length, 0);
255 if (keyAliasHash.val == NULL) {
256 LOGE("Malloc keyAliasHash failed");
257 res = HC_ERR_ALLOC_MEMORY;
258 goto ERR;
259 }
260 res = CombineKeyAlias(serviceId, keyType, authId, &keyAliasHash);
261 if (res != HC_SUCCESS) {
262 LOGE("CombineKeyAlias failed.");
263 goto ERR;
264 }
265 uint32_t outKeyAliasHexLen = keyAliasHash.length * BYTE_TO_HEX_OPER_LENGTH + 1;
266 outKeyAliasHex = (char *)HcMalloc(outKeyAliasHexLen, 0);
267 res = ByteToHexString(keyAliasHash.val, keyAliasHash.length, outKeyAliasHex, outKeyAliasHexLen);
268 if (res != HC_SUCCESS) {
269 LOGE("ByteToHexString failed");
270 goto ERR;
271 }
272 if (memcpy_s(outKeyAlias->val, outKeyAlias->length, outKeyAliasHex, strlen(outKeyAliasHex)) != EOK) {
273 LOGE("memcpy outkeyalias failed.");
274 res = HC_ERR_MEMORY_COPY;
275 goto ERR;
276 }
277 ERR:
278 HcFree(keyAliasHash.val);
279 HcFree(outKeyAliasHex);
280 return res;
281 }
282
GenerateKeyAlias(const Uint8Buff * pkgName,const Uint8Buff * serviceType,const KeyAliasType keyType,const Uint8Buff * authId,Uint8Buff * outKeyAlias)283 int32_t GenerateKeyAlias(const Uint8Buff *pkgName, const Uint8Buff *serviceType,
284 const KeyAliasType keyType, const Uint8Buff *authId, Uint8Buff *outKeyAlias)
285 {
286 CHECK_PTR_RETURN_ERROR_CODE(pkgName, "pkgName");
287 CHECK_PTR_RETURN_ERROR_CODE(pkgName->val, "pkgName->val");
288 CHECK_PTR_RETURN_ERROR_CODE(serviceType, "serviceType");
289 CHECK_PTR_RETURN_ERROR_CODE(serviceType->val, "serviceType->val");
290 CHECK_PTR_RETURN_ERROR_CODE(authId, "authId");
291 CHECK_PTR_RETURN_ERROR_CODE(authId->val, "authId->val");
292 CHECK_PTR_RETURN_ERROR_CODE(outKeyAlias, "outKeyAlias");
293 CHECK_PTR_RETURN_ERROR_CODE(outKeyAlias->val, "outKeyAlias->val");
294 if (pkgName->length == 0 || serviceType->length == 0 || authId->length == 0 || outKeyAlias->length == 0) {
295 LOGE("Invalid zero length params exist.");
296 return HC_ERR_INVALID_LEN;
297 }
298 if (pkgName->length > PACKAGE_NAME_MAX_LEN || serviceType->length > SERVICE_TYPE_MAX_LEN ||
299 authId->length > AUTH_ID_MAX_LEN || keyType >= KEY_ALIAS_TYPE_END) {
300 LOGE("Out of length params exist.");
301 return HC_ERR_INVALID_LEN;
302 }
303
304 int32_t res;
305 Uint8Buff serviceId = { NULL, SHA256_LEN };
306 serviceId.val = (uint8_t *)HcMalloc(serviceId.length, 0);
307 if (serviceId.val == NULL) {
308 LOGE("Malloc for serviceId failed.");
309 res = HC_ERR_ALLOC_MEMORY;
310 goto ERR;
311 }
312 res = CombineServiceId(pkgName, serviceType, &serviceId);
313 if (res != HC_SUCCESS) {
314 LOGE("CombineServiceId failed, res: %x.", res);
315 goto ERR;
316 }
317 Uint8Buff keyTypeBuff = { GetKeyTypePair(keyType), KEY_TYPE_PAIR_LEN };
318 if (keyType == KEY_ALIAS_AUTH_TOKEN) {
319 res = CombineKeyAliasForIso(&serviceId, &keyTypeBuff, authId, outKeyAlias);
320 } else {
321 res = CombineKeyAliasForPake(&serviceId, &keyTypeBuff, authId, outKeyAlias);
322 }
323 if (res != HC_SUCCESS) {
324 LOGE("CombineKeyAlias failed, keyType: %d, res: %d", keyType, res);
325 }
326 ERR:
327 HcFree(serviceId.val);
328 return res;
329 }
330
GetIdPeer(const CJson * in,const char * peerIdKey,const Uint8Buff * authIdSelf,Uint8Buff * authIdPeer)331 int32_t GetIdPeer(const CJson *in, const char *peerIdKey, const Uint8Buff *authIdSelf, Uint8Buff *authIdPeer)
332 {
333 const char *authIdStr = GetStringFromJson(in, peerIdKey);
334 if (authIdStr == NULL) {
335 LOGE("Get peer id from json failed.");
336 return HC_ERR_JSON_GET;
337 }
338 uint32_t authIdLen = HcStrlen(authIdStr) / BYTE_TO_HEX_OPER_LENGTH;
339 if (authIdLen == 0 || authIdLen > MAX_AUTH_ID_LEN) {
340 LOGE("Invalid authIdPeerLen: %u.", authIdLen);
341 return HC_ERR_INVALID_LEN;
342 }
343 int32_t res = InitSingleParam(authIdPeer, authIdLen);
344 if (res != HC_SUCCESS) {
345 LOGE("InitSingleParam for peer authId failed, res: %d.", res);
346 return res;
347 }
348 if (HexStringToByte(authIdStr, authIdPeer->val, authIdPeer->length) != HC_SUCCESS) {
349 LOGE("HexStringToByte for authIdPeer failed.");
350 return HC_ERR_CONVERT_FAILED;
351 }
352 if ((authIdSelf->length == authIdPeer->length) &&
353 memcmp(authIdSelf->val, authIdPeer->val, authIdSelf->length) == 0) {
354 LOGE("Peer id can not be equal to self id.");
355 return HC_ERR_INVALID_PARAMS;
356 }
357 return HC_SUCCESS;
358 }
359
GetAndCheckAuthIdPeer(const CJson * in,const Uint8Buff * authIdSelf,const Uint8Buff * authIdPeer)360 int32_t GetAndCheckAuthIdPeer(const CJson *in, const Uint8Buff *authIdSelf, const Uint8Buff *authIdPeer)
361 {
362 const CJson *payload = GetObjFromJson(in, FIELD_PAYLOAD);
363 if (payload == NULL) {
364 LOGE("Get payload failed.");
365 return HC_ERR_JSON_GET;
366 }
367 const char *authIdStr = GetStringFromJson(payload, FIELD_PEER_AUTH_ID);
368 if (authIdStr == NULL) {
369 LOGE("Get peer authId from payload failed.");
370 return HC_ERR_JSON_GET;
371 }
372 uint32_t authIdPeerLen = HcStrlen(authIdStr) / BYTE_TO_HEX_OPER_LENGTH;
373 if (authIdPeerLen == 0 || authIdPeerLen > MAX_AUTH_ID_LEN) {
374 LOGE("Invalid peer authId length.");
375 return HC_ERR_INVALID_LEN;
376 }
377 uint8_t *authIdPeerTmp = (uint8_t *)HcMalloc(authIdPeerLen, 0);
378 if (authIdPeerTmp == NULL) {
379 LOGE("Malloc for authIdPeerTmp failed.");
380 return HC_ERR_ALLOC_MEMORY;
381 }
382 if (HexStringToByte(authIdStr, authIdPeerTmp, authIdPeerLen) != HC_SUCCESS) {
383 LOGE("Convert peer authId from hex string to byte failed.");
384 HcFree(authIdPeerTmp);
385 return HC_ERR_CONVERT_FAILED;
386 }
387 if ((authIdSelf->length == authIdPeer->length) &&
388 memcmp(authIdSelf->val, authIdPeer->val, authIdSelf->length) == EOK) {
389 LOGE("Peer id can not be equal to self id.");
390 HcFree(authIdPeerTmp);
391 return HC_ERR_INVALID_PARAMS;
392 }
393 if (memcmp(authIdPeer->val, authIdPeerTmp, authIdPeer->length) != EOK) {
394 LOGE("Peer authId does not match.");
395 HcFree(authIdPeerTmp);
396 return HC_ERR_INVALID_PARAMS;
397 }
398 HcFree(authIdPeerTmp);
399 return HC_SUCCESS;
400 }
401
GetAuthIdPeerFromPayload(const CJson * in,const Uint8Buff * authIdSelf,Uint8Buff * authIdPeer)402 int32_t GetAuthIdPeerFromPayload(const CJson *in, const Uint8Buff *authIdSelf, Uint8Buff *authIdPeer)
403 {
404 const CJson *payload = GetObjFromJson(in, FIELD_PAYLOAD);
405 if (payload == NULL) {
406 LOGE("Not have payload.");
407 return HC_ERR_JSON_GET;
408 }
409 int res = GetIdPeer(payload, FIELD_PEER_AUTH_ID, authIdSelf, authIdPeer);
410 if (res != HC_SUCCESS) {
411 LOGE("GetIdPeer failed, res: %d.", res);
412 }
413 return res;
414 }
415
GetAndCheckKeyLenOnServer(const CJson * in,uint32_t keyLen)416 int32_t GetAndCheckKeyLenOnServer(const CJson *in, uint32_t keyLen)
417 {
418 const CJson *payload = GetObjFromJson(in, FIELD_PAYLOAD);
419 if (payload == NULL) {
420 LOGE("Get payload failed.");
421 return HC_ERR_JSON_GET;
422 }
423 uint32_t tmpKeyLen = 0;
424 if (GetIntFromJson(payload, FIELD_KEY_LENGTH, (int32_t *)&tmpKeyLen) != HC_SUCCESS) {
425 LOGE("Get tmpKeyLen from payload failed.");
426 return HC_ERR_JSON_GET;
427 }
428
429 if (keyLen != tmpKeyLen) {
430 LOGE("Key length is not equal.");
431 return HC_ERR_INVALID_PARAMS;
432 }
433 return HC_SUCCESS;
434 }
435