• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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