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