1 /*
2 * Copyright (C) 2021-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 "iso_task_common.h"
17 #include <time.h>
18 #include "das_task_common.h"
19 #include "das_module_defines.h"
20 #include "hc_log.h"
21 #include "hc_types.h"
22 #include "iso_protocol_common.h"
23 #include "protocol_common.h"
24 #include "hisysevent_common.h"
25
ComputeHkdfByParams(const IsoParams * params,const Uint8Buff * hkdfSaltBuf,Uint8Buff * returnKeyBuf)26 static int32_t ComputeHkdfByParams(const IsoParams *params, const Uint8Buff *hkdfSaltBuf, Uint8Buff *returnKeyBuf)
27 {
28 Uint8Buff keyInfoBuf = { (uint8_t *)GENERATE_RETURN_KEY_STR, (uint32_t)HcStrlen(GENERATE_RETURN_KEY_STR) };
29 KeyParams keyParam = {
30 .keyBuff = { params->baseParams.sessionKey.val, params->baseParams.sessionKey.length, false },
31 .isDeStorage = false,
32 .osAccountId = params->baseParams.osAccountId
33 };
34 return params->baseParams.loader->computeHkdf(&keyParam, hkdfSaltBuf, &keyInfoBuf, returnKeyBuf);
35 }
36
GenerateReturnKey(IsoParams * params,uint8_t * returnKey,uint32_t returnKeyLen)37 static int GenerateReturnKey(IsoParams *params, uint8_t *returnKey, uint32_t returnKeyLen)
38 {
39 uint32_t hkdfSaltLen = params->baseParams.randPeer.length + params->baseParams.randSelf.length;
40 int res;
41 uint8_t *hkdfSalt = (uint8_t *)HcMalloc(hkdfSaltLen, 0);
42 if (hkdfSalt == NULL) {
43 return HC_ERR_ALLOC_MEMORY;
44 }
45 if (params->isClient) {
46 if (memcpy_s(hkdfSalt, hkdfSaltLen, params->baseParams.randSelf.val,
47 params->baseParams.randSelf.length) != EOK) {
48 LOGE("Copy randSelf failed.");
49 res = HC_ERR_MEMORY_COPY;
50 goto ERR;
51 }
52 if (memcpy_s(hkdfSalt + params->baseParams.randSelf.length, hkdfSaltLen - params->baseParams.randSelf.length,
53 params->baseParams.randPeer.val, params->baseParams.randPeer.length) != EOK) {
54 LOGE("Copy randPeer failed.");
55 res = HC_ERR_MEMORY_COPY;
56 goto ERR;
57 }
58 } else {
59 if (memcpy_s(hkdfSalt, hkdfSaltLen, params->baseParams.randPeer.val,
60 params->baseParams.randPeer.length) != EOK) {
61 LOGE("Copy randPeer failed.");
62 res = HC_ERR_MEMORY_COPY;
63 goto ERR;
64 }
65 if (memcpy_s(hkdfSalt + params->baseParams.randPeer.length, hkdfSaltLen - params->baseParams.randPeer.length,
66 params->baseParams.randSelf.val, params->baseParams.randSelf.length) != EOK) {
67 LOGE("Copy randSelf failed.");
68 res = HC_ERR_MEMORY_COPY;
69 goto ERR;
70 }
71 }
72 Uint8Buff hkdfSaltBuf = { hkdfSalt, hkdfSaltLen };
73 Uint8Buff returnKeyBuf = { returnKey, returnKeyLen };
74 res = ComputeHkdfByParams(params, &hkdfSaltBuf, &returnKeyBuf);
75 if (res != HC_SUCCESS) {
76 LOGE("computeHkdf for returnKey failed.");
77 goto ERR;
78 }
79 ERR:
80 FreeAndCleanKey(&(params->baseParams.sessionKey));
81 HcFree(hkdfSalt);
82 return res;
83 }
84
GenerateEncResult(const IsoParams * params,int message,CJson * sendToPeer,const char * aad)85 int GenerateEncResult(const IsoParams *params, int message, CJson *sendToPeer, const char *aad)
86 {
87 CJson *payload = NULL;
88 uint8_t *out = NULL;
89 uint8_t nonce[NONCE_SIZE] = { 0 };
90 Uint8Buff nonceBuf = { nonce, sizeof(nonce) };
91 int ret = params->baseParams.loader->generateRandom(&nonceBuf);
92 if (ret != 0) {
93 LOGE("Generate nonce failed, res: %" LOG_PUB "x.", ret);
94 return ret;
95 }
96
97 int result = 0;
98 Uint8Buff plainBuf = { (uint8_t *)&result, sizeof(int) };
99 GcmParam encryptInfo;
100 encryptInfo.nonce = nonce;
101 encryptInfo.nonceLen = NONCE_SIZE;
102 encryptInfo.aad = (uint8_t *)aad;
103 encryptInfo.aadLen = (uint32_t)HcStrlen(aad);
104 out = (uint8_t *)HcMalloc((sizeof(int) + TAG_LEN), 0);
105 if (out == NULL) {
106 ret = HC_ERR_ALLOC_MEMORY;
107 goto ERR;
108 }
109 Uint8Buff outBuf = { out, sizeof(int) + TAG_LEN };
110 KeyParams keyParams = {
111 { params->baseParams.sessionKey.val, params->baseParams.sessionKey.length, false },
112 false,
113 params->baseParams.osAccountId
114 };
115 ret = params->baseParams.loader->aesGcmEncrypt(&keyParams, &plainBuf, &encryptInfo, &outBuf);
116 if (ret != HC_SUCCESS) {
117 goto ERR;
118 }
119 payload = CreateJson();
120 if (payload == NULL) {
121 ret = HC_ERR_ALLOC_MEMORY;
122 goto ERR;
123 }
124 GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_NONCE, nonce, sizeof(nonce)), ret);
125 GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_ENC_RESULT, out, sizeof(int) + TAG_LEN), ret);
126 GOTO_ERR_AND_SET_RET(AddIntToJson(payload, FIELD_OPERATION_CODE, params->opCode), ret);
127 GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_PAYLOAD, payload), ret);
128 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_MESSAGE, message), ret);
129 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_AUTH_FORM, AUTH_FORM_ACCOUNT_UNRELATED), ret);
130 ERR:
131 FreeJson(payload);
132 HcFree(out);
133 return ret;
134 }
135
SendResultToFinalSelf(IsoParams * params,CJson * out,bool isNeedReturnKey)136 int SendResultToFinalSelf(IsoParams *params, CJson *out, bool isNeedReturnKey)
137 {
138 CJson *sendToSelf = CreateJson();
139 if (sendToSelf == NULL) {
140 LOGE("Create sendToSelf json failed.");
141 return HC_ERR_JSON_CREATE;
142 }
143 uint8_t *returnSessionKey = NULL;
144 int res = 0;
145 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToSelf, FIELD_OPERATION_CODE, OP_BIND), res);
146 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToSelf, FIELD_AUTH_FORM, AUTH_FORM_ACCOUNT_UNRELATED), res);
147 if (isNeedReturnKey) {
148 returnSessionKey = (uint8_t *)HcMalloc(params->keyLen, 0);
149 if (returnSessionKey == NULL) {
150 LOGE("Malloc for returnSessionKey failed.");
151 res = HC_ERR_ALLOC_MEMORY;
152 goto ERR;
153 }
154 res = GenerateReturnKey(params, returnSessionKey, params->keyLen);
155 if (res != 0) {
156 LOGE("gen return key failed, res:%" LOG_PUB "d", res);
157 goto ERR;
158 }
159 GOTO_ERR_AND_SET_RET(AddByteToJson(sendToSelf, FIELD_SESSION_KEY, returnSessionKey, params->keyLen), res);
160 }
161 GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf), res);
162 ERR:
163 ClearSensitiveStringInJson(sendToSelf, FIELD_SESSION_KEY);
164 FreeJson(sendToSelf);
165 if (returnSessionKey != NULL) {
166 (void)memset_s(returnSessionKey, params->keyLen, 0, params->keyLen);
167 }
168 HcFree(returnSessionKey);
169 return res;
170 }
171
GenEncResult(IsoParams * params,int message,CJson * out,const char * aad,bool isNeedReturnKey)172 int GenEncResult(IsoParams *params, int message, CJson *out, const char *aad, bool isNeedReturnKey)
173 {
174 CJson *sendToSelf = CreateJson();
175 if (sendToSelf == NULL) {
176 LOGE("Create sendToSelf json failed.");
177 return HC_ERR_JSON_CREATE;
178 }
179 CJson *sendToPeer = CreateJson();
180 if (sendToPeer == NULL) {
181 LOGE("Create sendToPeer json failed.");
182 FreeJson(sendToSelf);
183 return HC_ERR_JSON_CREATE;
184 }
185
186 uint8_t *returnKey = NULL;
187 int res = GenerateEncResult(params, message, sendToPeer, aad);
188 if (res != 0) {
189 goto ERR;
190 }
191 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToSelf, FIELD_AUTH_FORM, AUTH_FORM_ACCOUNT_UNRELATED), res);
192 if (isNeedReturnKey) {
193 returnKey = (uint8_t *)HcMalloc(params->keyLen, 0);
194 if (returnKey == NULL) {
195 res = HC_ERR_ALLOC_MEMORY;
196 goto ERR;
197 }
198 res = GenerateReturnKey(params, returnKey, params->keyLen);
199 if (res != 0) {
200 LOGE("gen return key failed, res:%" LOG_PUB "d", res);
201 goto ERR;
202 }
203 GOTO_ERR_AND_SET_RET(AddByteToJson(sendToSelf, FIELD_SESSION_KEY, returnKey,
204 params->keyLen), res);
205 }
206 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToSelf, FIELD_OPERATION_CODE, params->opCode), res);
207 GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), res);
208 GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf), res);
209 ERR:
210 ClearSensitiveStringInJson(sendToSelf, FIELD_SESSION_KEY);
211 FreeJson(sendToPeer);
212 FreeJson(sendToSelf);
213 if (returnKey != NULL) {
214 (void)memset_s(returnKey, params->keyLen, 0, params->keyLen);
215 }
216 HcFree(returnKey);
217 return res;
218 }
219
CheckEncResult(IsoParams * params,const CJson * in,const char * aad)220 int CheckEncResult(IsoParams *params, const CJson *in, const char *aad)
221 {
222 int result = 0;
223 int res;
224 uint8_t *nonce = NULL;
225 uint8_t *encResult = NULL;
226
227 nonce = (uint8_t *)HcMalloc(NONCE_SIZE, 0);
228 if (nonce == NULL) {
229 res = HC_ERR_ALLOC_MEMORY;
230 goto ERR;
231 }
232 GOTO_ERR_AND_SET_RET(GetByteFromJson(in, FIELD_NONCE, nonce, NONCE_SIZE), res);
233 encResult = (uint8_t *)HcMalloc(sizeof(int) + TAG_LEN, 0);
234 if (encResult == NULL) {
235 res = HC_ERR_ALLOC_MEMORY;
236 goto ERR;
237 }
238 GOTO_ERR_AND_SET_RET(GetByteFromJson(in, FIELD_ENC_RESULT, encResult, sizeof(int) + TAG_LEN), res);
239 Uint8Buff outBuf = { (uint8_t *)&result, sizeof(int) };
240 Uint8Buff encResultBuf = { encResult, sizeof(int) + TAG_LEN };
241 GcmParam gcmParam;
242 gcmParam.aad = (uint8_t *)aad;
243 gcmParam.aadLen = (uint32_t)HcStrlen(aad);
244 gcmParam.nonce = nonce;
245 gcmParam.nonceLen = NONCE_SIZE;
246
247 KeyParams keyParams = {
248 { params->baseParams.sessionKey.val, params->baseParams.sessionKey.length, false },
249 false,
250 params->baseParams.osAccountId
251 };
252 res = params->baseParams.loader->aesGcmDecrypt(&keyParams, &encResultBuf, &gcmParam, &outBuf);
253 if (res != 0) {
254 LOGE("decrypt result failed, res:%" LOG_PUB "d", res);
255 goto ERR;
256 }
257 ERR:
258 HcFree(nonce);
259 HcFree(encResult);
260 return res;
261 }
262
GenerateKeyAliasForIso(const IsoParams * params,Uint8Buff * keyAliasBuff)263 static int32_t GenerateKeyAliasForIso(const IsoParams *params, Uint8Buff *keyAliasBuff)
264 {
265 TokenManagerParams tokenParams = { 0 };
266 tokenParams.serviceType.val = (uint8_t *)params->serviceType;
267 tokenParams.serviceType.length = HcStrlen(params->serviceType);
268 tokenParams.authId = params->baseParams.authIdPeer;
269 if (params->isPeerFromUpgrade) {
270 tokenParams.pkgName.val = (uint8_t *)GROUP_MANAGER_PACKAGE_NAME;
271 tokenParams.pkgName.length = HcStrlen(GROUP_MANAGER_PACKAGE_NAME);
272 tokenParams.userType = params->peerUserType;
273 } else {
274 tokenParams.pkgName.val = (uint8_t *)params->packageName;
275 tokenParams.pkgName.length = HcStrlen(params->packageName);
276 tokenParams.userType = KEY_ALIAS_AUTH_TOKEN;
277 }
278 int32_t res = GenerateKeyAlias(&tokenParams, keyAliasBuff);
279 if (res != HC_SUCCESS) {
280 LOGE("Failed to generate iso key alias!");
281 return res;
282 }
283 if (params->isPeerFromUpgrade) {
284 res = ToLowerCase(keyAliasBuff);
285 if (res != HC_SUCCESS) {
286 LOGE("Failed to convert psk alias to lower case!");
287 return res;
288 }
289 }
290 return HC_SUCCESS;
291 }
292
DeleteAuthCode(const IsoParams * params)293 void DeleteAuthCode(const IsoParams *params)
294 {
295 uint8_t keyAlias[ISO_KEY_ALIAS_LEN] = { 0 };
296 uint8_t upgradeKeyAlias[ISO_UPGRADE_KEY_ALIAS_LEN] = { 0 };
297 Uint8Buff keyAliasBuff = { keyAlias, ISO_KEY_ALIAS_LEN };
298 if (params->isPeerFromUpgrade) {
299 keyAliasBuff.val = upgradeKeyAlias;
300 keyAliasBuff.length = ISO_UPGRADE_KEY_ALIAS_LEN;
301 }
302 int32_t res = GenerateKeyAliasForIso(params, &keyAliasBuff);
303 if (res != HC_SUCCESS) {
304 LOGE("Failed to generate iso key alias!");
305 return;
306 }
307 LOGI("AuthCode alias(HEX): %" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x****.",
308 keyAliasBuff.val[DEV_AUTH_ZERO], keyAliasBuff.val[DEV_AUTH_ONE],
309 keyAliasBuff.val[DEV_AUTH_TWO], keyAliasBuff.val[DEV_AUTH_THREE]);
310 res = params->baseParams.loader->deleteKey(&keyAliasBuff, params->isPeerFromUpgrade,
311 params->baseParams.osAccountId);
312 if (res != HC_SUCCESS) {
313 LOGE("Failed to delete auth code!");
314 }
315 }
316
DestroyIsoParams(IsoParams * params)317 void DestroyIsoParams(IsoParams *params)
318 {
319 if (params == NULL) {
320 return;
321 }
322
323 DestroyIsoBaseParams(¶ms->baseParams);
324
325 if (params->packageName != NULL) {
326 HcFree(params->packageName);
327 params->packageName = NULL;
328 }
329 if (params->serviceType != NULL) {
330 HcFree(params->serviceType);
331 params->serviceType = NULL;
332 }
333 if (params->seed.val != NULL) {
334 HcFree(params->seed.val);
335 params->seed.val = NULL;
336 }
337 if (params->pinCodeString != NULL) {
338 (void)memset_s(params->pinCodeString, HcStrlen(params->pinCodeString), 0, HcStrlen(params->pinCodeString));
339 HcFree(params->pinCodeString);
340 params->pinCodeString = NULL;
341 }
342 (void)memset_s(params, sizeof(IsoParams), 0, sizeof(IsoParams));
343 }
344
FillAuthId(IsoParams * params,const CJson * in)345 static int FillAuthId(IsoParams *params, const CJson *in)
346 {
347 const char *authId = GetStringFromJson(in, FIELD_SELF_AUTH_ID);
348 if (authId == NULL) {
349 LOGE("get self authId failed");
350 return HC_ERROR;
351 }
352 uint32_t authIdLen = HcStrlen(authId);
353 if (authIdLen == 0 || authIdLen > MAX_AUTH_ID_LEN) {
354 LOGE("Invalid authIdSelfLen: %" LOG_PUB "d.", authIdLen);
355 return HC_ERR_INVALID_PARAMS;
356 }
357 params->baseParams.authIdSelf.length = authIdLen;
358 params->baseParams.authIdSelf.val = (uint8_t *)HcMalloc(params->baseParams.authIdSelf.length, 0);
359 if (params->baseParams.authIdSelf.val == NULL) {
360 LOGE("malloc authIdSelf failed");
361 return HC_ERROR;
362 }
363 if (memcpy_s(params->baseParams.authIdSelf.val, params->baseParams.authIdSelf.length,
364 authId, HcStrlen(authId)) != EOK) {
365 LOGE("Memcpy authIdSelf failed.");
366 return HC_ERR_MEMORY_COPY;
367 }
368
369 if (params->opCode == OP_BIND) {
370 params->baseParams.authIdPeer.length = 0;
371 params->baseParams.authIdPeer.val = NULL;
372 } else {
373 authId = GetStringFromJson(in, FIELD_PEER_AUTH_ID);
374 if (authId == NULL) {
375 LOGE("get peer authId failed");
376 return HC_ERROR;
377 }
378 authIdLen = HcStrlen(authId);
379 if (authIdLen == 0 || authIdLen > MAX_AUTH_ID_LEN) {
380 LOGE("Invalid authIdPeerLen %" LOG_PUB "d.", authIdLen);
381 return HC_ERR_INVALID_PARAMS;
382 }
383 params->baseParams.authIdPeer.length = authIdLen;
384 params->baseParams.authIdPeer.val = (uint8_t *)HcMalloc(params->baseParams.authIdPeer.length, 0);
385 if (params->baseParams.authIdPeer.val == NULL) {
386 LOGE("malloc authIdPeer failed");
387 return HC_ERROR;
388 }
389 if (memcpy_s(params->baseParams.authIdPeer.val, params->baseParams.authIdPeer.length,
390 authId, HcStrlen(authId)) != EOK) {
391 LOGE("Memcpy authIdPeer failed.");
392 return HC_ERR_MEMORY_COPY;
393 }
394 }
395
396 return HC_SUCCESS;
397 }
398
FillPkgNameAndServiceType(IsoParams * params,const CJson * in)399 static int FillPkgNameAndServiceType(IsoParams *params, const CJson *in)
400 {
401 const char *serviceType = GetStringFromJson(in, FIELD_SERVICE_TYPE);
402 if (serviceType == NULL) {
403 LOGE("get serviceType failed");
404 return HC_ERROR;
405 }
406 params->serviceType = (char *)HcMalloc((uint32_t)(HcStrlen(serviceType) + 1), 0);
407 if (params->serviceType == NULL) {
408 LOGE("malloc serviceType failed");
409 return HC_ERR_ALLOC_MEMORY;
410 }
411 if (memcpy_s(params->serviceType, HcStrlen(serviceType) + 1, serviceType, HcStrlen(serviceType)) != EOK) {
412 LOGE("memcpy serviceType failed.");
413 return HC_ERR_MEMORY_COPY;
414 }
415 const char *packageName = GetStringFromJson(in, FIELD_PKG_NAME);
416 if (packageName == NULL) {
417 LOGE("get packageName failed");
418 return HC_ERROR;
419 }
420 params->packageName = (char *)HcMalloc((uint32_t)(HcStrlen(packageName) + 1), 0);
421 if (params->packageName == NULL) {
422 LOGE("malloc packageName failed");
423 return HC_ERROR;
424 }
425 if (memcpy_s(params->packageName, HcStrlen(packageName) + 1, packageName, HcStrlen(packageName)) != EOK) {
426 LOGE("memcpy packageName failed.");
427 return HC_ERR_MEMORY_COPY;
428 }
429 return HC_SUCCESS;
430 }
431
432 #ifdef ENABLE_P2P_BIND_LITE_PROTOCOL_CHECK
CheckPinLenForStandardIso(const CJson * in,const char * pinCode)433 static bool CheckPinLenForStandardIso(const CJson *in, const char *pinCode)
434 {
435 int32_t protocolExpandVal = INVALID_PROTOCOL_EXPAND_VALUE;
436 (void)GetIntFromJson(in, FIELD_PROTOCOL_EXPAND, &protocolExpandVal);
437 if (protocolExpandVal != LITE_PROTOCOL_STANDARD_MODE) {
438 LOGI("not standard iso, no need to check.");
439 return true;
440 }
441 return HcStrlen(pinCode) >= PIN_CODE_LEN_LONG;
442 }
443 #endif
444
FillPin(IsoParams * params,const CJson * in)445 static int FillPin(IsoParams *params, const CJson *in)
446 {
447 if (params->opCode == OP_BIND) {
448 const char *pinString = GetStringFromJson(in, FIELD_PIN_CODE);
449 if (pinString == NULL) {
450 LOGE("Get pin failed.");
451 return HC_ERROR;
452 }
453 if (HcStrlen(pinString) < MIN_PIN_LEN || HcStrlen(pinString) > MAX_PIN_LEN) {
454 LOGE("Pin is too short.");
455 return HC_ERR_INVALID_PARAMS;
456 }
457 #ifdef ENABLE_P2P_BIND_LITE_PROTOCOL_CHECK
458 if (!CheckPinLenForStandardIso(in, pinString)) {
459 LOGE("Invalid pin code len!");
460 return HC_ERR_INVALID_LEN;
461 }
462 #endif
463 params->pinCodeString = (char *)HcMalloc(HcStrlen(pinString) + 1, 0);
464 if (params->pinCodeString == NULL) {
465 LOGE("malloc pinCode failed.");
466 return HC_ERR_ALLOC_MEMORY;
467 }
468 if (memcpy_s(params->pinCodeString, HcStrlen(pinString) + 1, pinString, HcStrlen(pinString)) != EOK) {
469 LOGE("memcpy pinCodeString failed.");
470 (void)memset_s(params->pinCodeString, HcStrlen(pinString) + 1, 0, HcStrlen(pinString) + 1);
471 return HC_ERR_MEMORY_COPY;
472 }
473 }
474 return HC_SUCCESS;
475 }
476
AllocSeed(IsoParams * params)477 static int AllocSeed(IsoParams *params)
478 {
479 params->seed.val = (uint8_t *)HcMalloc(SEED_LEN, 0);
480 if (params->seed.val == NULL) {
481 LOGE("Malloc for seed failed.");
482 return HC_ERR_ALLOC_MEMORY;
483 }
484 params->seed.length = SEED_LEN;
485 return HC_SUCCESS;
486 }
487
GetUserType(IsoParams * params,const CJson * in)488 static int GetUserType(IsoParams *params, const CJson *in)
489 {
490 int res = GetIntFromJson(in, FIELD_SELF_TYPE, &(params->selfUserType));
491 if (res != 0) {
492 LOGE("get userType failed: %" LOG_PUB "d", res);
493 return res;
494 }
495
496 res = GetIntFromJson(in, FIELD_PEER_USER_TYPE, &(params->peerUserType));
497 if (res != 0) {
498 LOGD("get peer Type failed use default, res: %" LOG_PUB "d", res);
499 params->peerUserType = 0; /* fill default value */
500 res = HC_SUCCESS;
501 }
502 return res;
503 }
504
GetUpgradeFlagAndKeyLength(IsoParams * params,const CJson * in)505 static int32_t GetUpgradeFlagAndKeyLength(IsoParams *params, const CJson *in)
506 {
507 (void)GetBoolFromJson(in, FIELD_IS_PEER_FROM_UPGRADE, ¶ms->isPeerFromUpgrade);
508 if (params->opCode == OP_UNBIND || params->opCode == OP_BIND) {
509 params->keyLen = 0;
510 return HC_SUCCESS;
511 }
512
513 if (GetIntFromJson(in, FIELD_KEY_LENGTH, (int32_t *)&(params->keyLen)) != 0) {
514 LOGD("Get key length failed, use default.");
515 params->keyLen = DEFAULT_RETURN_KEY_LENGTH;
516 }
517 if (params->keyLen < MIN_OUTPUT_KEY_LEN || params->keyLen > MAX_OUTPUT_KEY_LEN) {
518 LOGE("Output key length is invalid, keyLen: %" LOG_PUB "d.", params->keyLen);
519 return HC_ERR_INVALID_LEN;
520 }
521 return HC_SUCCESS;
522 }
523
InitIsoParams(IsoParams * params,const CJson * in)524 int InitIsoParams(IsoParams *params, const CJson *in)
525 {
526 int res;
527 if (GetIntFromJson(in, FIELD_OPERATION_CODE, &(params->opCode)) != 0) {
528 LOGD("Get opCode failed, use default.");
529 params->opCode = AUTHENTICATE;
530 }
531 if (params->opCode != OP_BIND && params->opCode != OP_UNBIND && params->opCode != AUTHENTICATE) {
532 LOGE("Unsupported opCode: %" LOG_PUB "d.", params->opCode);
533 res = HC_ERR_NOT_SUPPORT;
534 goto ERR;
535 }
536 if (GetBoolFromJson(in, FIELD_IS_CLIENT, &(params->isClient)) != 0) {
537 LOGE("get isClient failed");
538 res = HC_ERR_JSON_GET;
539 goto ERR;
540 }
541 res = InitIsoBaseParams(in, ¶ms->baseParams);
542 if (res != HC_SUCCESS) {
543 LOGE("InitIsoBaseParams failed, res: %" LOG_PUB "x.", res);
544 goto ERR;
545 }
546 res = GetUpgradeFlagAndKeyLength(params, in);
547 if (res != HC_SUCCESS) {
548 goto ERR;
549 }
550 res = GetUserType(params, in);
551 if (res != HC_SUCCESS) {
552 goto ERR;
553 }
554 res = FillAuthId(params, in);
555 if (res != HC_SUCCESS) {
556 goto ERR;
557 }
558 res = FillPkgNameAndServiceType(params, in);
559 if (res != HC_SUCCESS) {
560 goto ERR;
561 }
562 res = FillPin(params, in);
563 if (res != HC_SUCCESS) {
564 goto ERR;
565 }
566 res = AllocSeed(params);
567 if (res != HC_SUCCESS) {
568 goto ERR;
569 }
570 return HC_SUCCESS;
571 ERR:
572 DestroyIsoParams(params);
573 return res;
574 }
575
AuthGeneratePsk(const Uint8Buff * seed,IsoParams * params)576 static int AuthGeneratePsk(const Uint8Buff *seed, IsoParams *params)
577 {
578 uint8_t keyAliasVal[ISO_KEY_ALIAS_LEN] = { 0 };
579 uint8_t upgradeKeyAliasVal[ISO_UPGRADE_KEY_ALIAS_LEN] = { 0 };
580 Uint8Buff keyAlias = { keyAliasVal, ISO_KEY_ALIAS_LEN };
581 if (params->isPeerFromUpgrade) {
582 keyAlias.val = upgradeKeyAliasVal;
583 keyAlias.length = ISO_UPGRADE_KEY_ALIAS_LEN;
584 }
585 int32_t res = GenerateKeyAliasForIso(params, &keyAlias);
586 if (res != HC_SUCCESS) {
587 LOGE("Failed to generate iso key alias!");
588 return res;
589 }
590
591 LOGI("AuthCode alias(HEX): %" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x****.", keyAlias.val[DEV_AUTH_ZERO],
592 keyAlias.val[DEV_AUTH_ONE], keyAlias.val[DEV_AUTH_TWO], keyAlias.val[DEV_AUTH_THREE]);
593 Uint8Buff pskBuf = { params->baseParams.psk, sizeof(params->baseParams.psk) };
594 if (params->isPeerFromUpgrade) {
595 KeyParams keyAliasParams = { { keyAlias.val, keyAlias.length, true }, true, params->baseParams.osAccountId };
596 res = params->baseParams.loader->computeHmacWithThreeStage(&keyAliasParams, seed, &pskBuf);
597 ReportRadarEvent(res);
598 return res;
599 } else {
600 KeyParams keyAliasParams = { { keyAlias.val, keyAlias.length, true }, false, params->baseParams.osAccountId };
601 return params->baseParams.loader->computeHmac(&keyAliasParams, seed, &pskBuf);
602 }
603 }
604
AuthGeneratePskUsePin(const Uint8Buff * seed,IsoParams * params,const char * pinString)605 static int AuthGeneratePskUsePin(const Uint8Buff *seed, IsoParams *params, const char *pinString)
606 {
607 Uint8Buff messageBuf = { (uint8_t *)pinString, (uint32_t)HcStrlen(pinString) };
608 Uint8Buff pskBuf = { params->baseParams.psk, sizeof(params->baseParams.psk) };
609 uint8_t hash[SHA256_LEN] = { 0 };
610 Uint8Buff hashBuf = { hash, sizeof(hash) };
611 int res = params->baseParams.loader->sha256(&messageBuf, &hashBuf);
612 if (res != 0) {
613 LOGE("sha256 failed, res:%" LOG_PUB "d", res);
614 return res;
615 }
616 KeyParams keyParams = { { hashBuf.val, hashBuf.length, false }, false, params->baseParams.osAccountId };
617 return params->baseParams.loader->computeHmac(&keyParams, seed, &pskBuf);
618 }
619
GenerateKeyAliasInIso(const IsoParams * params,uint8_t * keyAlias,uint32_t keyAliasLen,bool useOpposite)620 int GenerateKeyAliasInIso(const IsoParams *params, uint8_t *keyAlias, uint32_t keyAliasLen, bool useOpposite)
621 {
622 if (params == NULL || keyAlias == NULL || keyAliasLen == 0) {
623 return HC_ERR_INVALID_PARAMS;
624 }
625 TokenManagerParams tokenParams = { 0 };
626 tokenParams.pkgName.val = (uint8_t *)params->packageName;
627 tokenParams.pkgName.length = HcStrlen(params->packageName);
628 tokenParams.serviceType.val = (uint8_t *)params->serviceType;
629 tokenParams.serviceType.length = HcStrlen(params->serviceType);
630 tokenParams.userType = KEY_ALIAS_AUTH_TOKEN;
631 if (useOpposite) {
632 tokenParams.authId = params->baseParams.authIdPeer;
633 } else {
634 tokenParams.authId = params->baseParams.authIdSelf;
635 }
636 Uint8Buff outKeyAlias = { keyAlias, keyAliasLen };
637 return GenerateKeyAlias(&tokenParams, &outKeyAlias);
638 }
639
GeneratePsk(const CJson * in,IsoParams * params)640 int GeneratePsk(const CJson *in, IsoParams *params)
641 {
642 if (!params->isClient) {
643 if (GetByteFromJson(in, FIELD_SEED, params->seed.val, params->seed.length) != 0) {
644 LOGE("Get seed failed.");
645 return HC_ERR_JSON_GET;
646 }
647 }
648 int res;
649 if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND) {
650 res = AuthGeneratePsk(¶ms->seed, params);
651 } else {
652 res = AuthGeneratePskUsePin(¶ms->seed, params, params->pinCodeString);
653 if (params->pinCodeString != NULL) {
654 (void)memset_s(params->pinCodeString, HcStrlen(params->pinCodeString), 0, HcStrlen(params->pinCodeString));
655 }
656 }
657 if (res != HC_SUCCESS) {
658 LOGE("Generate psk failed, res: %" LOG_PUB "x.", res);
659 goto ERR;
660 }
661 return res;
662 ERR:
663 (void)memset_s(params->baseParams.psk, sizeof(params->baseParams.psk), 0, sizeof(params->baseParams.psk));
664 return res;
665 }
666
GenerateSeed(IsoParams * params)667 int GenerateSeed(IsoParams *params)
668 {
669 uint8_t *random = (uint8_t *)HcMalloc(SEED_LEN, 0);
670 if (random == NULL) {
671 LOGE("malloc random failed");
672 return HC_ERR_ALLOC_MEMORY;
673 }
674 Uint8Buff randomBuf = { random, SEED_LEN };
675 int res = params->baseParams.loader->generateRandom(&randomBuf);
676 if (res != 0) {
677 LOGE("generate random failed, res:%" LOG_PUB "d", res);
678 HcFree(random);
679 return res;
680 }
681 clock_t times = 0;
682 uint8_t *input = (uint8_t *)HcMalloc(SEED_LEN + sizeof(clock_t), 0);
683 if (input == NULL) {
684 LOGE("malloc failed");
685 HcFree(random);
686 return HC_ERR_ALLOC_MEMORY;
687 }
688 if (memcpy_s(input, SEED_LEN + sizeof(clock_t), random, SEED_LEN) != EOK) {
689 LOGE("memcpy seed failed.");
690 res = HC_ERR_MEMORY_COPY;
691 goto ERR;
692 }
693 if (memcpy_s(input + SEED_LEN, sizeof(clock_t), ×, sizeof(clock_t)) != EOK) {
694 LOGE("memcpy times failed.");
695 res = HC_ERR_MEMORY_COPY;
696 goto ERR;
697 }
698 Uint8Buff inputBuf = { input, SEED_LEN + sizeof(clock_t) };
699 res = params->baseParams.loader->sha256(&inputBuf, ¶ms->seed);
700 if (res != HC_SUCCESS) {
701 LOGE("sha256 failed.");
702 goto ERR;
703 }
704 ERR:
705 HcFree(random);
706 HcFree(input);
707 return res;
708 }
709