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