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.randSelf.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: %" LOG_PUB "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:%" LOG_PUB "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:%" LOG_PUB "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:%" LOG_PUB "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): %" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x****.",
304 keyAliasBuff.val[DEV_AUTH_ZERO], keyAliasBuff.val[DEV_AUTH_ONE],
305 keyAliasBuff.val[DEV_AUTH_TWO], keyAliasBuff.val[DEV_AUTH_THREE]);
306 res = params->baseParams.loader->deleteKey(&keyAliasBuff, params->isPeerFromUpgrade,
307 params->baseParams.osAccountId);
308 if (res != HC_SUCCESS) {
309 LOGE("Failed to delete auth code!");
310 }
311 }
312
DestroyIsoParams(IsoParams * params)313 void DestroyIsoParams(IsoParams *params)
314 {
315 if (params == NULL) {
316 return;
317 }
318
319 DestroyIsoBaseParams(¶ms->baseParams);
320
321 if (params->packageName != NULL) {
322 HcFree(params->packageName);
323 params->packageName = NULL;
324 }
325 if (params->serviceType != NULL) {
326 HcFree(params->serviceType);
327 params->serviceType = NULL;
328 }
329 if (params->seed.val != NULL) {
330 HcFree(params->seed.val);
331 params->seed.val = NULL;
332 }
333 if (params->pinCodeString != NULL) {
334 (void)memset_s(params->pinCodeString, HcStrlen(params->pinCodeString), 0, HcStrlen(params->pinCodeString));
335 HcFree(params->pinCodeString);
336 params->pinCodeString = NULL;
337 }
338 (void)memset_s(params, sizeof(IsoParams), 0, sizeof(IsoParams));
339 }
340
FillAuthId(IsoParams * params,const CJson * in)341 static int FillAuthId(IsoParams *params, const CJson *in)
342 {
343 const char *authId = GetStringFromJson(in, FIELD_SELF_AUTH_ID);
344 if (authId == NULL) {
345 LOGE("get self authId failed");
346 return HC_ERROR;
347 }
348 uint32_t authIdLen = HcStrlen(authId);
349 if (authIdLen == 0 || authIdLen > MAX_AUTH_ID_LEN) {
350 LOGE("Invalid authIdSelfLen: %" LOG_PUB "d.", authIdLen);
351 return HC_ERR_INVALID_PARAMS;
352 }
353 params->baseParams.authIdSelf.length = authIdLen;
354 params->baseParams.authIdSelf.val = (uint8_t *)HcMalloc(params->baseParams.authIdSelf.length, 0);
355 if (params->baseParams.authIdSelf.val == NULL) {
356 LOGE("malloc authIdSelf failed");
357 return HC_ERROR;
358 }
359 if (memcpy_s(params->baseParams.authIdSelf.val, params->baseParams.authIdSelf.length,
360 authId, HcStrlen(authId)) != EOK) {
361 LOGE("Memcpy authIdSelf failed.");
362 return HC_ERR_MEMORY_COPY;
363 }
364
365 if (params->opCode == OP_BIND) {
366 params->baseParams.authIdPeer.length = 0;
367 params->baseParams.authIdPeer.val = NULL;
368 } else {
369 authId = GetStringFromJson(in, FIELD_PEER_AUTH_ID);
370 if (authId == NULL) {
371 LOGE("get peer authId failed");
372 return HC_ERROR;
373 }
374 authIdLen = HcStrlen(authId);
375 if (authIdLen == 0 || authIdLen > MAX_AUTH_ID_LEN) {
376 LOGE("Invalid authIdPeerLen %" LOG_PUB "d.", authIdLen);
377 return HC_ERR_INVALID_PARAMS;
378 }
379 params->baseParams.authIdPeer.length = authIdLen;
380 params->baseParams.authIdPeer.val = (uint8_t *)HcMalloc(params->baseParams.authIdPeer.length, 0);
381 if (params->baseParams.authIdPeer.val == NULL) {
382 LOGE("malloc authIdPeer failed");
383 return HC_ERROR;
384 }
385 if (memcpy_s(params->baseParams.authIdPeer.val, params->baseParams.authIdPeer.length,
386 authId, HcStrlen(authId)) != EOK) {
387 LOGE("Memcpy authIdPeer failed.");
388 return HC_ERR_MEMORY_COPY;
389 }
390 }
391
392 return HC_SUCCESS;
393 }
394
FillPkgNameAndServiceType(IsoParams * params,const CJson * in)395 static int FillPkgNameAndServiceType(IsoParams *params, const CJson *in)
396 {
397 const char *serviceType = GetStringFromJson(in, FIELD_SERVICE_TYPE);
398 if (serviceType == NULL) {
399 LOGE("get serviceType failed");
400 return HC_ERROR;
401 }
402 params->serviceType = (char *)HcMalloc((uint32_t)(HcStrlen(serviceType) + 1), 0);
403 if (params->serviceType == NULL) {
404 LOGE("malloc serviceType failed");
405 return HC_ERR_ALLOC_MEMORY;
406 }
407 if (memcpy_s(params->serviceType, HcStrlen(serviceType) + 1, serviceType, HcStrlen(serviceType)) != EOK) {
408 LOGE("memcpy serviceType failed.");
409 return HC_ERR_MEMORY_COPY;
410 }
411 const char *packageName = GetStringFromJson(in, FIELD_PKG_NAME);
412 if (packageName == NULL) {
413 LOGE("get packageName failed");
414 return HC_ERROR;
415 }
416 params->packageName = (char *)HcMalloc((uint32_t)(HcStrlen(packageName) + 1), 0);
417 if (params->packageName == NULL) {
418 LOGE("malloc packageName failed");
419 return HC_ERROR;
420 }
421 if (memcpy_s(params->packageName, HcStrlen(packageName) + 1, packageName, HcStrlen(packageName)) != EOK) {
422 LOGE("memcpy packageName failed.");
423 return HC_ERR_MEMORY_COPY;
424 }
425 return HC_SUCCESS;
426 }
427
428 #ifdef ENABLE_P2P_BIND_LITE_PROTOCOL_CHECK
CheckPinLenForStandardIso(const CJson * in,const char * pinCode)429 static bool CheckPinLenForStandardIso(const CJson *in, const char *pinCode)
430 {
431 int32_t protocolExpandVal = INVALID_PROTOCOL_EXPAND_VALUE;
432 (void)GetIntFromJson(in, FIELD_PROTOCOL_EXPAND, &protocolExpandVal);
433 if (protocolExpandVal != LITE_PROTOCOL_STANDARD_MODE) {
434 LOGI("not standard iso, no need to check.");
435 return true;
436 }
437 return HcStrlen(pinCode) >= PIN_CODE_LEN_LONG;
438 }
439 #endif
440
FillPin(IsoParams * params,const CJson * in)441 static int FillPin(IsoParams *params, const CJson *in)
442 {
443 if (params->opCode == OP_BIND) {
444 const char *pinString = GetStringFromJson(in, FIELD_PIN_CODE);
445 if (pinString == NULL) {
446 LOGE("Get pin failed.");
447 return HC_ERROR;
448 }
449 if (HcStrlen(pinString) < MIN_PIN_LEN || HcStrlen(pinString) > MAX_PIN_LEN) {
450 LOGE("Pin is too short.");
451 return HC_ERR_INVALID_PARAMS;
452 }
453 #ifdef ENABLE_P2P_BIND_LITE_PROTOCOL_CHECK
454 if (!CheckPinLenForStandardIso(in, pinString)) {
455 LOGE("Invalid pin code len!");
456 return HC_ERR_INVALID_LEN;
457 }
458 #endif
459 params->pinCodeString = (char *)HcMalloc(HcStrlen(pinString) + 1, 0);
460 if (params->pinCodeString == NULL) {
461 LOGE("malloc pinCode failed.");
462 return HC_ERR_ALLOC_MEMORY;
463 }
464 if (memcpy_s(params->pinCodeString, HcStrlen(pinString) + 1, pinString, HcStrlen(pinString)) != EOK) {
465 LOGE("memcpy pinCodeString failed.");
466 (void)memset_s(params->pinCodeString, HcStrlen(pinString) + 1, 0, HcStrlen(pinString) + 1);
467 return HC_ERR_MEMORY_COPY;
468 }
469 }
470 return HC_SUCCESS;
471 }
472
AllocSeed(IsoParams * params)473 static int AllocSeed(IsoParams *params)
474 {
475 params->seed.val = (uint8_t *)HcMalloc(SEED_LEN, 0);
476 if (params->seed.val == NULL) {
477 LOGE("Malloc for seed failed.");
478 return HC_ERR_ALLOC_MEMORY;
479 }
480 params->seed.length = SEED_LEN;
481 return HC_SUCCESS;
482 }
483
GetUserType(IsoParams * params,const CJson * in)484 static int GetUserType(IsoParams *params, const CJson *in)
485 {
486 int res = GetIntFromJson(in, FIELD_SELF_TYPE, &(params->selfUserType));
487 if (res != 0) {
488 LOGE("get userType failed: %" LOG_PUB "d", res);
489 return res;
490 }
491
492 res = GetIntFromJson(in, FIELD_PEER_USER_TYPE, &(params->peerUserType));
493 if (res != 0) {
494 LOGD("get peer Type failed use default, res: %" LOG_PUB "d", res);
495 params->peerUserType = 0; /* fill default value */
496 res = HC_SUCCESS;
497 }
498 return res;
499 }
500
GetUpgradeFlagAndKeyLength(IsoParams * params,const CJson * in)501 static int32_t GetUpgradeFlagAndKeyLength(IsoParams *params, const CJson *in)
502 {
503 (void)GetBoolFromJson(in, FIELD_IS_PEER_FROM_UPGRADE, ¶ms->isPeerFromUpgrade);
504 if (params->opCode == OP_UNBIND || params->opCode == OP_BIND) {
505 params->keyLen = 0;
506 return HC_SUCCESS;
507 }
508
509 if (GetIntFromJson(in, FIELD_KEY_LENGTH, (int32_t *)&(params->keyLen)) != 0) {
510 LOGD("Get key length failed, use default.");
511 params->keyLen = DEFAULT_RETURN_KEY_LENGTH;
512 }
513 if (params->keyLen < MIN_OUTPUT_KEY_LEN || params->keyLen > MAX_OUTPUT_KEY_LEN) {
514 LOGE("Output key length is invalid, keyLen: %" LOG_PUB "d.", params->keyLen);
515 return HC_ERR_INVALID_LEN;
516 }
517 return HC_SUCCESS;
518 }
519
InitIsoParams(IsoParams * params,const CJson * in)520 int InitIsoParams(IsoParams *params, const CJson *in)
521 {
522 int res;
523 if (GetIntFromJson(in, FIELD_OPERATION_CODE, &(params->opCode)) != 0) {
524 LOGD("Get opCode failed, use default.");
525 params->opCode = AUTHENTICATE;
526 }
527 if (params->opCode != OP_BIND && params->opCode != OP_UNBIND && params->opCode != AUTHENTICATE) {
528 LOGE("Unsupported opCode: %" LOG_PUB "d.", params->opCode);
529 res = HC_ERR_NOT_SUPPORT;
530 goto ERR;
531 }
532 if (GetBoolFromJson(in, FIELD_IS_CLIENT, &(params->isClient)) != 0) {
533 LOGE("get isClient failed");
534 res = HC_ERR_JSON_GET;
535 goto ERR;
536 }
537 res = InitIsoBaseParams(in, ¶ms->baseParams);
538 if (res != HC_SUCCESS) {
539 LOGE("InitIsoBaseParams failed, res: %" LOG_PUB "x.", res);
540 goto ERR;
541 }
542 res = GetUpgradeFlagAndKeyLength(params, in);
543 if (res != HC_SUCCESS) {
544 goto ERR;
545 }
546 res = GetUserType(params, in);
547 if (res != HC_SUCCESS) {
548 goto ERR;
549 }
550 res = FillAuthId(params, in);
551 if (res != HC_SUCCESS) {
552 goto ERR;
553 }
554 res = FillPkgNameAndServiceType(params, in);
555 if (res != HC_SUCCESS) {
556 goto ERR;
557 }
558 res = FillPin(params, in);
559 if (res != HC_SUCCESS) {
560 goto ERR;
561 }
562 res = AllocSeed(params);
563 if (res != HC_SUCCESS) {
564 goto ERR;
565 }
566 return HC_SUCCESS;
567 ERR:
568 DestroyIsoParams(params);
569 return res;
570 }
571
AuthGeneratePsk(const Uint8Buff * seed,IsoParams * params)572 static int AuthGeneratePsk(const Uint8Buff *seed, IsoParams *params)
573 {
574 uint8_t keyAliasVal[ISO_KEY_ALIAS_LEN] = { 0 };
575 uint8_t upgradeKeyAliasVal[ISO_UPGRADE_KEY_ALIAS_LEN] = { 0 };
576 Uint8Buff keyAlias = { keyAliasVal, ISO_KEY_ALIAS_LEN };
577 if (params->isPeerFromUpgrade) {
578 keyAlias.val = upgradeKeyAliasVal;
579 keyAlias.length = ISO_UPGRADE_KEY_ALIAS_LEN;
580 }
581 int32_t res = GenerateKeyAliasForIso(params, &keyAlias);
582 if (res != HC_SUCCESS) {
583 LOGE("Failed to generate iso key alias!");
584 return res;
585 }
586
587 LOGI("AuthCode alias(HEX): %" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x****.", keyAlias.val[DEV_AUTH_ZERO],
588 keyAlias.val[DEV_AUTH_ONE], keyAlias.val[DEV_AUTH_TWO], keyAlias.val[DEV_AUTH_THREE]);
589 Uint8Buff pskBuf = { params->baseParams.psk, sizeof(params->baseParams.psk) };
590 if (params->isPeerFromUpgrade) {
591 KeyParams keyAliasParams = { { keyAlias.val, keyAlias.length, true }, true, params->baseParams.osAccountId };
592 return params->baseParams.loader->computeHmacWithThreeStage(&keyAliasParams, seed, &pskBuf);
593 } else {
594 KeyParams keyAliasParams = { { keyAlias.val, keyAlias.length, true }, false, params->baseParams.osAccountId };
595 return params->baseParams.loader->computeHmac(&keyAliasParams, seed, &pskBuf);
596 }
597 }
598
AuthGeneratePskUsePin(const Uint8Buff * seed,IsoParams * params,const char * pinString)599 static int AuthGeneratePskUsePin(const Uint8Buff *seed, IsoParams *params, const char *pinString)
600 {
601 Uint8Buff messageBuf = { (uint8_t *)pinString, (uint32_t)HcStrlen(pinString) };
602 Uint8Buff pskBuf = { params->baseParams.psk, sizeof(params->baseParams.psk) };
603 uint8_t hash[SHA256_LEN] = { 0 };
604 Uint8Buff hashBuf = { hash, sizeof(hash) };
605 int res = params->baseParams.loader->sha256(&messageBuf, &hashBuf);
606 if (res != 0) {
607 LOGE("sha256 failed, res:%" LOG_PUB "d", res);
608 return res;
609 }
610 KeyParams keyParams = { { hashBuf.val, hashBuf.length, false }, false, params->baseParams.osAccountId };
611 return params->baseParams.loader->computeHmac(&keyParams, seed, &pskBuf);
612 }
613
GenerateKeyAliasInIso(const IsoParams * params,uint8_t * keyAlias,uint32_t keyAliasLen,bool useOpposite)614 int GenerateKeyAliasInIso(const IsoParams *params, uint8_t *keyAlias, uint32_t keyAliasLen, bool useOpposite)
615 {
616 if (params == NULL || keyAlias == NULL || keyAliasLen == 0) {
617 return HC_ERR_INVALID_PARAMS;
618 }
619 Uint8Buff pkgName = { (uint8_t *)params->packageName, (uint32_t)HcStrlen(params->packageName) };
620 Uint8Buff serviceType = { (uint8_t *)params->serviceType, (uint32_t)HcStrlen(params->serviceType) };
621 Uint8Buff authId = { NULL, 0 };
622 if (useOpposite) {
623 authId.val = params->baseParams.authIdPeer.val;
624 authId.length = params->baseParams.authIdPeer.length;
625 } else {
626 authId.val = params->baseParams.authIdSelf.val;
627 authId.length = params->baseParams.authIdSelf.length;
628 }
629 Uint8Buff outKeyAlias = { keyAlias, keyAliasLen };
630 return GenerateKeyAlias(&pkgName, &serviceType, KEY_ALIAS_AUTH_TOKEN, &authId,
631 &outKeyAlias);
632 }
633
GeneratePsk(const CJson * in,IsoParams * params)634 int GeneratePsk(const CJson *in, IsoParams *params)
635 {
636 if (!params->isClient) {
637 if (GetByteFromJson(in, FIELD_SEED, params->seed.val, params->seed.length) != 0) {
638 LOGE("Get seed failed.");
639 return HC_ERR_JSON_GET;
640 }
641 }
642 int res;
643 if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND) {
644 res = AuthGeneratePsk(¶ms->seed, params);
645 } else {
646 res = AuthGeneratePskUsePin(¶ms->seed, params, params->pinCodeString);
647 if (params->pinCodeString != NULL) {
648 (void)memset_s(params->pinCodeString, HcStrlen(params->pinCodeString), 0, HcStrlen(params->pinCodeString));
649 }
650 }
651 if (res != HC_SUCCESS) {
652 LOGE("Generate psk failed, res: %" LOG_PUB "x.", res);
653 goto ERR;
654 }
655 return res;
656 ERR:
657 (void)memset_s(params->baseParams.psk, sizeof(params->baseParams.psk), 0, sizeof(params->baseParams.psk));
658 return res;
659 }
660
GenerateSeed(IsoParams * params)661 int GenerateSeed(IsoParams *params)
662 {
663 uint8_t *random = (uint8_t *)HcMalloc(SEED_LEN, 0);
664 if (random == NULL) {
665 LOGE("malloc random failed");
666 return HC_ERR_ALLOC_MEMORY;
667 }
668 Uint8Buff randomBuf = { random, SEED_LEN };
669 int res = params->baseParams.loader->generateRandom(&randomBuf);
670 if (res != 0) {
671 LOGE("generate random failed, res:%" LOG_PUB "d", res);
672 HcFree(random);
673 return res;
674 }
675 clock_t times = 0;
676 uint8_t *input = (uint8_t *)HcMalloc(SEED_LEN + sizeof(clock_t), 0);
677 if (input == NULL) {
678 LOGE("malloc failed");
679 HcFree(random);
680 return HC_ERR_ALLOC_MEMORY;
681 }
682 if (memcpy_s(input, SEED_LEN + sizeof(clock_t), random, SEED_LEN) != EOK) {
683 LOGE("memcpy seed failed.");
684 res = HC_ERR_MEMORY_COPY;
685 goto ERR;
686 }
687 if (memcpy_s(input + SEED_LEN, sizeof(clock_t), ×, sizeof(clock_t)) != EOK) {
688 LOGE("memcpy times failed.");
689 res = HC_ERR_MEMORY_COPY;
690 goto ERR;
691 }
692 Uint8Buff inputBuf = { input, SEED_LEN + sizeof(clock_t) };
693 res = params->baseParams.loader->sha256(&inputBuf, ¶ms->seed);
694 if (res != HC_SUCCESS) {
695 LOGE("sha256 failed.");
696 goto ERR;
697 }
698 ERR:
699 HcFree(random);
700 HcFree(input);
701 return res;
702 }
703