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 "pake_v1_protocol_task_common.h"
17 #include "das_standard_token_manager.h"
18 #include "das_task_common.h"
19 #include "hc_log.h"
20 #include "hc_types.h"
21 #include "protocol_common.h"
22 #include "pake_v1_protocol_common.h"
23 #include "pake_task_common.h"
24 #include "das_task_common.h"
25 #include "hisysevent_common.h"
26
27 #define ASCII_CASE_DIFFERENCE_VALUE 32
28
DestroyDasPakeV1Params(PakeParams * params)29 void DestroyDasPakeV1Params(PakeParams *params)
30 {
31 if (params == NULL) {
32 return;
33 }
34
35 DestroyPakeV1BaseParams(&(params->baseParams));
36
37 if (params->returnKey.val != NULL) {
38 (void)memset_s(params->returnKey.val, params->returnKey.length, 0, params->returnKey.length);
39 HcFree(params->returnKey.val);
40 params->returnKey.val = NULL;
41 }
42
43 if (params->pseudonymExtInfo.selfNextPseudonymId.val != NULL) {
44 HcFree(params->pseudonymExtInfo.selfNextPseudonymId.val);
45 params->pseudonymExtInfo.selfNextPseudonymId.val = NULL;
46 }
47
48 if (params->pseudonymExtInfo.selfNextPseudonymChallenge.val != NULL) {
49 HcFree(params->pseudonymExtInfo.selfNextPseudonymChallenge.val);
50 params->pseudonymExtInfo.selfNextPseudonymChallenge.val = NULL;
51 }
52
53 if (params->pseudonymExtInfo.peerNextPseudonymId.val != NULL) {
54 HcFree(params->pseudonymExtInfo.peerNextPseudonymId.val);
55 params->pseudonymExtInfo.peerNextPseudonymId.val = NULL;
56 }
57
58 HcFree(params->packageName);
59 params->packageName = NULL;
60
61 HcFree(params->serviceType);
62 params->serviceType = NULL;
63
64 HcFree(params->nonce.val);
65 params->nonce.val = NULL;
66 }
67
AllocReturnKey(PakeParams * params,const CJson * in)68 static int32_t AllocReturnKey(PakeParams *params, const CJson *in)
69 {
70 if (params->opCode == OP_UNBIND) {
71 params->returnKey.val = NULL;
72 params->returnKey.length = 0;
73 return HC_SUCCESS;
74 }
75 int32_t res = GetIntFromJson(in, FIELD_KEY_LENGTH, (int *)&(params->returnKey.length));
76 if (res != HC_SUCCESS) {
77 LOGD("Get key length failed, use default, res: %" LOG_PUB "d", res);
78 params->returnKey.length = DEFAULT_RETURN_KEY_LENGTH;
79 }
80 if (params->returnKey.length < MIN_OUTPUT_KEY_LEN || params->returnKey.length > MAX_OUTPUT_KEY_LEN) {
81 LOGE("Output key length is invalid.");
82 return HC_ERR_INVALID_LEN;
83 }
84 res = InitSingleParam(¶ms->returnKey, params->returnKey.length);
85 if (res != HC_SUCCESS) {
86 LOGE("InitSingleParam for returnKey failed, res: %" LOG_PUB "d.", res);
87 }
88 return res;
89 }
90
RemoveEscapeForExtInfo(const char * extInfoStr,char ** outExtInfoStr)91 static int32_t RemoveEscapeForExtInfo(const char *extInfoStr, char **outExtInfoStr)
92 {
93 uint32_t len = HcStrlen(extInfoStr);
94 *outExtInfoStr = (char *)HcMalloc(len + 1, 0);
95 if (*outExtInfoStr == NULL) {
96 LOGE("Failed to alloc memory for outExtInfoStr!");
97 return HC_ERR_ALLOC_MEMORY;
98 }
99 uint32_t j = 0;
100 for (uint32_t i = 0; i < len; i++) {
101 if (extInfoStr[i] == '\\') {
102 i++;
103 if (extInfoStr[i] == '\"') {
104 (*outExtInfoStr)[j++] = '\"';
105 }
106 } else {
107 (*outExtInfoStr)[j++] = extInfoStr[i];
108 }
109 }
110 return HC_SUCCESS;
111 }
112
GetInnerExtInfo(const Uint8Buff * extInfoBuff,Uint8Buff * innerExtInfo)113 static int32_t GetInnerExtInfo(const Uint8Buff *extInfoBuff, Uint8Buff *innerExtInfo)
114 {
115 CJson *extInfoJson = CreateJsonFromString((char *)extInfoBuff->val);
116 if (extInfoJson == NULL) {
117 LOGE("Failed to create extInfoJson!");
118 return HC_ERR_JSON_CREATE;
119 }
120 const char *innerExtInfoStr = GetStringFromJson(extInfoJson, "ExtInfo");
121 if (innerExtInfoStr == NULL) {
122 LOGE("Failed to get inner extInfo!");
123 FreeJson(extInfoJson);
124 return HC_ERR_JSON_GET;
125 }
126 char *outInnerExtStr = NULL;
127 int32_t res = RemoveEscapeForExtInfo(innerExtInfoStr, &outInnerExtStr);
128 FreeJson(extInfoJson);
129 if (res != HC_SUCCESS) {
130 LOGE("Failed to remove escape for extInfo!");
131 return res;
132 }
133 innerExtInfo->val = (uint8_t *)outInnerExtStr;
134 innerExtInfo->length = HcStrlen(outInnerExtStr) + 1;
135 return HC_SUCCESS;
136 }
137
LoadPseudonymFlagIfNeed(PakeParams * params)138 static int32_t LoadPseudonymFlagIfNeed(PakeParams *params)
139 {
140 uint8_t peerKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
141 Uint8Buff peerKeyAlias = { peerKeyAliasVal, PAKE_KEY_ALIAS_LEN };
142 TokenManagerParams tokenParams = { 0 };
143 tokenParams.pkgName.val = (uint8_t *)params->packageName;
144 tokenParams.pkgName.length = HcStrlen(params->packageName);
145 tokenParams.serviceType.val = (uint8_t *)params->serviceType;
146 tokenParams.serviceType.length = HcStrlen(params->serviceType);
147 tokenParams.userType = params->userTypePeer;
148 tokenParams.authId = params->baseParams.idPeer;
149 int32_t res = GenerateKeyAlias(&tokenParams, &peerKeyAlias);
150 if (res != HC_SUCCESS) {
151 LOGE("Failed to generate peer key alias!");
152 return res;
153 }
154 res = ToLowerCase(&peerKeyAlias);
155 if (res != HC_SUCCESS) {
156 LOGE("Failed to convert key alias to lower case!");
157 return res;
158 }
159 Uint8Buff extInfoBuff = { NULL, 0 };
160 KeyParams keyParams = { { peerKeyAlias.val, peerKeyAlias.length, true }, true, params->baseParams.osAccountId };
161 res = params->baseParams.loader->getKeyExtInfo(&keyParams, &extInfoBuff);
162 if (res != HC_SUCCESS) {
163 LOGE("Failed to get public key extInfo!");
164 return res;
165 }
166 Uint8Buff innerExtInfo = { NULL, 0 };
167 res = GetInnerExtInfo(&extInfoBuff, &innerExtInfo);
168 FreeUint8Buff(&extInfoBuff);
169 if (res != HC_SUCCESS) {
170 LOGE("Failed to get inner extInfo!");
171 return res;
172 }
173 CJson *innerExtInfoJson = CreateJsonFromString((char *)innerExtInfo.val);
174 FreeUint8Buff(&innerExtInfo);
175 if (innerExtInfoJson == NULL) {
176 LOGE("Failed to create inner extInfo json!");
177 return HC_ERR_JSON_CREATE;
178 }
179 if (GetBoolFromJson(innerExtInfoJson, FIELD_IS_PSEUDONYM_SUPPORTED, ¶ms->isPseudonym) != HC_SUCCESS) {
180 LOGE("Failed to get pseudonym flag from inner extInfo!");
181 FreeJson(innerExtInfoJson);
182 return HC_ERR_JSON_GET;
183 }
184 LOGI("peer support pseudonym: %" LOG_PUB "s", params->isPseudonym ? "true" : "false");
185 FreeJson(innerExtInfoJson);
186 return HC_SUCCESS;
187 }
188
InitDasPakeV1Params(PakeParams * params,const CJson * in)189 int32_t InitDasPakeV1Params(PakeParams *params, const CJson *in)
190 {
191 int32_t osAccountId;
192 if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
193 LOGE("Failed to get osAccountId!");
194 return HC_ERR_JSON_GET;
195 }
196 int32_t res = InitPakeV1BaseParams(osAccountId, &(params->baseParams));
197 if (res != HC_SUCCESS) {
198 LOGE("InitPakeV1BaseParams failed, res: %" LOG_PUB "d.", res);
199 goto ERR;
200 }
201
202 res = FillDasPakeParams(params, in);
203 if (res != HC_SUCCESS) {
204 LOGE("FillDasPakeParams failed, res: %" LOG_PUB "d.", res);
205 goto ERR;
206 }
207 (void)GetBoolFromJson(in, FIELD_IS_SELF_FROM_UPGRADE, ¶ms->isSelfFromUpgrade);
208 (void)GetBoolFromJson(in, FIELD_IS_PEER_FROM_UPGRADE, ¶ms->isPeerFromUpgrade);
209 if (params->isSelfFromUpgrade) {
210 LOGI("Self device is from upgrade!");
211 } else {
212 LOGI("Self device is not from upgrade!");
213 }
214 if (params->isPeerFromUpgrade) {
215 LOGI("peer device is from upgrade!");
216 } else {
217 LOGI("peer device is not from upgrade!");
218 }
219 if (params->opCode == AUTHENTICATE && params->isPeerFromUpgrade) {
220 (void)LoadPseudonymFlagIfNeed(params);
221 }
222
223 res = AllocReturnKey(params, in);
224 if (res != HC_SUCCESS) {
225 LOGE("AllocReturnKey failed, res: %" LOG_PUB "d.", res);
226 goto ERR;
227 }
228
229 return HC_SUCCESS;
230 ERR:
231 DestroyDasPakeV1Params(params);
232 return res;
233 }
234
UpperToLowercase(Uint8Buff * hex)235 static void UpperToLowercase(Uint8Buff *hex)
236 {
237 for (uint32_t i = 0; i < hex->length; i++) {
238 if (hex->val[i] >= 'A' && hex->val[i] <= 'F') {
239 hex->val[i] += ASCII_CASE_DIFFERENCE_VALUE;
240 }
241 }
242 }
243
ConvertPakeV1Psk(const Uint8Buff * srcPsk,PakeParams * params)244 static int32_t ConvertPakeV1Psk(const Uint8Buff *srcPsk, PakeParams *params)
245 {
246 int res = InitSingleParam(&(params->baseParams.psk), PAKE_PSK_LEN * BYTE_TO_HEX_OPER_LENGTH + 1);
247 if (res != HC_SUCCESS) {
248 LOGE("InitSingleParam for psk failed, res: %" LOG_PUB "d.", res);
249 return res;
250 }
251
252 if (ByteToHexString(srcPsk->val, srcPsk->length, (char *)params->baseParams.psk.val,
253 params->baseParams.psk.length) != HC_SUCCESS) {
254 LOGE("Convert psk from byte to hex string failed.");
255 return HC_ERR_CONVERT_FAILED;
256 }
257 params->baseParams.psk.length = params->baseParams.psk.length - 1; // do not need include '\0' when using psk
258 (void)UpperToLowercase(&(params->baseParams.psk));
259 PRINT_DEBUG_MSG(srcPsk->val, srcPsk->length, "pskValue");
260 PRINT_SENSITIVE_DATA("pskValue", (char *)params->baseParams.psk.val);
261 return res;
262 }
263
GeneratePskAlias(const PakeParams * params,Uint8Buff * pskKeyAlias)264 static int32_t GeneratePskAlias(const PakeParams *params, Uint8Buff *pskKeyAlias)
265 {
266 TokenManagerParams tokenParams = { 0 };
267 tokenParams.pkgName.val = (uint8_t *)params->packageName;
268 tokenParams.pkgName.length = HcStrlen(params->packageName);
269 tokenParams.serviceType.val = (uint8_t *)params->serviceType;
270 tokenParams.serviceType.length = HcStrlen(params->serviceType);
271 tokenParams.userType = KEY_ALIAS_PSK;
272 tokenParams.authId = params->baseParams.idPeer;
273 int32_t res = GenerateKeyAlias(&tokenParams, pskKeyAlias);
274 if (res != HC_SUCCESS) {
275 LOGE("GenerateKeyAlias for psk failed, res: %" LOG_PUB "d.", res);
276 return res;
277 }
278 if (params->isPeerFromUpgrade) {
279 res = ToLowerCase(pskKeyAlias);
280 if (res != HC_SUCCESS) {
281 LOGE("Failed to convert psk alias to lower case!");
282 return res;
283 }
284 }
285 return HC_SUCCESS;
286 }
287
FillPskWithDerivedKeyHex(PakeParams * params)288 int32_t FillPskWithDerivedKeyHex(PakeParams *params)
289 {
290 int32_t res;
291 if (!(params->baseParams.isClient)) {
292 res = params->baseParams.loader->generateRandom(&(params->nonce));
293 if (res != HC_SUCCESS) {
294 LOGE("Generate nonce failed, res: %" LOG_PUB "d.", res);
295 return res;
296 }
297 }
298 uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
299 Uint8Buff pskAlias = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
300 res = GeneratePskAlias(params, &pskAlias);
301 if (res != HC_SUCCESS) {
302 return res;
303 }
304
305 LOGI("Psk alias(HEX): %" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x****.", pskAliasVal[DEV_AUTH_ZERO],
306 pskAliasVal[DEV_AUTH_ONE], pskAliasVal[DEV_AUTH_TWO], pskAliasVal[DEV_AUTH_THREE]);
307 bool isDeStorage = params->isSelfFromUpgrade;
308 if (params->baseParams.loader->checkKeyExist(&pskAlias, isDeStorage, params->baseParams.osAccountId) !=
309 HC_SUCCESS) {
310 res = GetStandardTokenManagerInstance()->computeAndSavePsk(params);
311 if (res != HC_SUCCESS) {
312 LOGE("ComputeAndSavePsk failed, res: %" LOG_PUB "d.", res);
313 return res;
314 }
315 }
316
317 uint8_t pskVal[PAKE_PSK_LEN] = { 0 };
318 Uint8Buff pskByte = { pskVal, PAKE_PSK_LEN };
319 Uint8Buff keyInfo = { (uint8_t *)TMP_AUTH_KEY_FACTOR, HcStrlen(TMP_AUTH_KEY_FACTOR) };
320 KeyParams keyParams = { { pskAlias.val, pskAlias.length, true }, isDeStorage, params->baseParams.osAccountId };
321 PRINT_DEBUG_MSG(params->nonce.val, params->nonce.length, "nonceValue");
322 res = params->baseParams.loader->computeHkdf(&keyParams, &(params->nonce), &keyInfo, &pskByte);
323 if (res != HC_SUCCESS) {
324 LOGE("ComputeHkdf for psk failed, res: %" LOG_PUB "d.", res);
325 FreeAndCleanKey(&(params->baseParams.psk));
326 return res;
327 }
328
329 res = ConvertPakeV1Psk(&pskByte, params);
330 if (res != HC_SUCCESS) {
331 LOGE("ConvertPakeV1Psk failed, res: %" LOG_PUB "d.", res);
332 FreeAndCleanKey(&(params->baseParams.psk));
333 }
334 return res;
335 }
336
FillPseudonymPskExtInfo(PseudonymPskExtInfo * extInfo,const CJson * extInfoJson)337 static int32_t FillPseudonymPskExtInfo(PseudonymPskExtInfo *extInfo, const CJson *extInfoJson)
338 {
339 uint8_t *tmpSefNextIdVal = (uint8_t *)HcMalloc(PSEUDONYM_ID_LEN, 0);
340 if (tmpSefNextIdVal == NULL) {
341 LOGE("Failed to alloc memory for self next pseudonym id!");
342 return HC_ERR_ALLOC_MEMORY;
343 }
344 if (GetByteFromJson(extInfoJson, FIELD_SELF_NEXT_PSEUDONYM_ID, tmpSefNextIdVal, PSEUDONYM_ID_LEN) != HC_SUCCESS) {
345 LOGE("Failed to get self next pseudonym id!");
346 HcFree(tmpSefNextIdVal);
347 return HC_ERR_JSON_GET;
348 }
349 uint8_t *tmpSelfNextChallengeVal = (uint8_t *)HcMalloc(PSEUDONYM_CHALLENGE_LEN, 0);
350 if (tmpSelfNextChallengeVal == NULL) {
351 LOGE("Failed to alloc memory for self next pseudonym challenge!");
352 HcFree(tmpSefNextIdVal);
353 return HC_ERR_ALLOC_MEMORY;
354 }
355 if (GetByteFromJson(extInfoJson, FIELD_SELF_NEXT_PSEUDONYM_CHALLENGE, tmpSelfNextChallengeVal,
356 PSEUDONYM_CHALLENGE_LEN) != HC_SUCCESS) {
357 LOGE("Failed to get self next pseudonym challenge!");
358 HcFree(tmpSefNextIdVal);
359 HcFree(tmpSelfNextChallengeVal);
360 return HC_ERR_JSON_GET;
361 }
362 uint8_t *tmpPeerNextIdVal = (uint8_t *)HcMalloc(PSEUDONYM_ID_LEN, 0);
363 if (tmpPeerNextIdVal == NULL) {
364 LOGE("Failed to alloc memory for peer next pseudonym id!");
365 HcFree(tmpSefNextIdVal);
366 HcFree(tmpSelfNextChallengeVal);
367 return HC_ERR_ALLOC_MEMORY;
368 }
369 if (GetByteFromJson(extInfoJson, FIELD_PEER_NEXT_PSEUDONYM_ID, tmpPeerNextIdVal, PSEUDONYM_ID_LEN) != HC_SUCCESS) {
370 LOGE("Failed to get peer next pseudonym id!");
371 HcFree(tmpSefNextIdVal);
372 HcFree(tmpSelfNextChallengeVal);
373 HcFree(tmpPeerNextIdVal);
374 return HC_ERR_JSON_GET;
375 }
376 extInfo->selfNextPseudonymId.val = tmpSefNextIdVal;
377 extInfo->selfNextPseudonymId.length = PSEUDONYM_ID_LEN;
378 extInfo->selfNextPseudonymChallenge.val = tmpSelfNextChallengeVal;
379 extInfo->selfNextPseudonymChallenge.length = PSEUDONYM_CHALLENGE_LEN;
380 extInfo->peerNextPseudonymId.val = tmpPeerNextIdVal;
381 extInfo->peerNextPseudonymId.length = PSEUDONYM_ID_LEN;
382 return HC_SUCCESS;
383 }
384
LoadPseudonymExtInfoIfNeed(PakeParams * params)385 int32_t LoadPseudonymExtInfoIfNeed(PakeParams *params)
386 {
387 if (params == NULL) {
388 LOGE("Invalid params!");
389 return HC_ERR_INVALID_PARAMS;
390 }
391 Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
392 uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
393 Uint8Buff pskAliasBuff = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
394 int32_t res = GeneratePseudonymPskAlias(&serviceTypeBuff, &(params->baseParams.idPeer), &pskAliasBuff);
395 if (res != HC_SUCCESS) {
396 LOGE("Failed to generate pseudonym psk alias!");
397 return res;
398 }
399 res = ToLowerCase(&pskAliasBuff);
400 if (res != HC_SUCCESS) {
401 LOGE("Failed to convert key alias to lower case!");
402 return res;
403 }
404 Uint8Buff extInfoBuff = { NULL, 0 };
405 KeyParams keyParams = { { pskAliasBuff.val, pskAliasBuff.length, true }, true, params->baseParams.osAccountId };
406 res = params->baseParams.loader->getKeyExtInfo(&keyParams, &extInfoBuff);
407 if (res != HC_SUCCESS) {
408 LOGE("Failed to get pseudonym psk extInfo!");
409 return res;
410 }
411 Uint8Buff innerExtInfo = { NULL, 0 };
412 res = GetInnerExtInfo(&extInfoBuff, &innerExtInfo);
413 FreeUint8Buff(&extInfoBuff);
414 if (res != HC_SUCCESS) {
415 LOGE("Failed to get inner extInfo!");
416 return res;
417 }
418 CJson *innerExtInfoJson = CreateJsonFromString((char *)innerExtInfo.val);
419 FreeUint8Buff(&innerExtInfo);
420 if (innerExtInfoJson == NULL) {
421 LOGE("Failed to create inner extInfo json!");
422 return HC_ERR_JSON_CREATE;
423 }
424 res = FillPseudonymPskExtInfo(¶ms->pseudonymExtInfo, innerExtInfoJson);
425 FreeJson(innerExtInfoJson);
426 if (res != HC_SUCCESS) {
427 LOGE("Failed to fill pseudonym psk ext info!");
428 }
429 return res;
430 }
431
CombinePseudonymChallenge(Uint8Buff * combinedChallengeBuff,const Uint8Buff * pseudonymChallengeBuff,const Uint8Buff * nextPseudonymChallengeBuff)432 static int32_t CombinePseudonymChallenge(Uint8Buff *combinedChallengeBuff, const Uint8Buff *pseudonymChallengeBuff,
433 const Uint8Buff *nextPseudonymChallengeBuff)
434 {
435 uint32_t totalLen = combinedChallengeBuff->length;
436 uint32_t usedLen = 0;
437 if (memcpy_s(combinedChallengeBuff->val, totalLen, pseudonymChallengeBuff->val,
438 pseudonymChallengeBuff->length) != EOK) {
439 LOGE("Copy pseudonym challenge failed!");
440 return HC_ERR_MEMORY_COPY;
441 }
442 usedLen = usedLen + pseudonymChallengeBuff->length;
443
444 if (memcpy_s(combinedChallengeBuff->val + usedLen, totalLen - usedLen, nextPseudonymChallengeBuff->val,
445 nextPseudonymChallengeBuff->length) != EOK) {
446 LOGE("Copy next pseudonym challenge failed!");
447 return HC_ERR_MEMORY_COPY;
448 }
449 return HC_SUCCESS;
450 }
451
GeneratePseudonymPskIfNotExist(const PakeParams * params)452 static int32_t GeneratePseudonymPskIfNotExist(const PakeParams *params)
453 {
454 uint8_t baseKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
455 Uint8Buff baseKeyAlias = { baseKeyAliasVal, PAKE_KEY_ALIAS_LEN };
456 TokenManagerParams tokenParams = { 0 };
457 tokenParams.pkgName.val = (uint8_t *)params->packageName;
458 tokenParams.pkgName.length = HcStrlen(params->packageName);
459 tokenParams.serviceType.val = (uint8_t *)params->serviceType;
460 tokenParams.serviceType.length = HcStrlen(params->serviceType);
461 tokenParams.userType = KEY_ALIAS_PSK;
462 tokenParams.authId = params->baseParams.idPeer;
463 int32_t res = GenerateKeyAlias(&tokenParams, &baseKeyAlias);
464 if (res != HC_SUCCESS) {
465 LOGE("Failed to generate base key alias!");
466 return res;
467 }
468 res = ToLowerCase(&baseKeyAlias);
469 if (res != HC_SUCCESS) {
470 LOGE("Failed to convert psk alias to lower case!");
471 return res;
472 }
473 uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
474 Uint8Buff pskAliasBuff = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
475 Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
476 res = GeneratePseudonymPskAlias(&serviceTypeBuff, ¶ms->baseParams.idPeer, &pskAliasBuff);
477 if (res != HC_SUCCESS) {
478 LOGE("Failed to generate psk alias!");
479 return res;
480 }
481 res = ToLowerCase(&pskAliasBuff);
482 if (res != HC_SUCCESS) {
483 LOGE("Failed to convert pseudonym psk alias to lower case!");
484 return res;
485 }
486 if (params->baseParams.loader->checkKeyExist(&pskAliasBuff, true, params->baseParams.osAccountId) == HC_SUCCESS) {
487 LOGI("Pseudonym psk already exist.");
488 return HC_SUCCESS;
489 }
490 uint8_t outKeyVal[PAKE_PSK_LEN] = { 0 };
491 Uint8Buff outKeyBuff = { outKeyVal, PAKE_PSK_LEN };
492 KeyParams keyParams = { { baseKeyAlias.val, baseKeyAlias.length, true }, true, params->baseParams.osAccountId };
493 res = params->baseParams.loader->computePseudonymPsk(&keyParams, &pskAliasBuff, NULL, &outKeyBuff);
494 if (res != HC_SUCCESS) {
495 LOGE("Failed to compute pseudonym psk!");
496 }
497 return res;
498 }
499
AddPseudonymIdToPayload(CJson * payload,const Uint8Buff * pseudonymIdBuff)500 static int32_t AddPseudonymIdToPayload(CJson *payload, const Uint8Buff *pseudonymIdBuff)
501 {
502 uint32_t hexLen = pseudonymIdBuff->length * BYTE_TO_HEX_OPER_LENGTH + 1;
503 char *hexStr = (char *)HcMalloc(hexLen, 0);
504 if (hexStr == NULL) {
505 LOGE("Failed to alloc memory for pseudonym id hex!");
506 return HC_ERR_ALLOC_MEMORY;
507 }
508 int32_t res = ByteToHexString(pseudonymIdBuff->val, pseudonymIdBuff->length, hexStr, hexLen);
509 if (res != HC_SUCCESS) {
510 LOGE("Failed to convert pseudonym id from byte to hex!");
511 HcFree(hexStr);
512 return res;
513 }
514 Uint8Buff hexBuff = {
515 .val = (uint8_t *)hexStr,
516 .length = HcStrlen(hexStr)
517 };
518 res = ToLowerCase(&hexBuff);
519 if (res != HC_SUCCESS) {
520 LOGE("Failed to convert pseudonym id hex to lower case!");
521 HcFree(hexStr);
522 return res;
523 }
524 if (AddStringToJson(payload, FIELD_P2P_PSEUDONYM_ID, hexStr) != HC_SUCCESS) {
525 LOGE("Failed to add pseudonym id hex to payload!");
526 HcFree(hexStr);
527 return HC_ERR_JSON_ADD;
528 }
529 HcFree(hexStr);
530 return HC_SUCCESS;
531 }
532
AddPseudonymChallengeToPayload(CJson * payload,const Uint8Buff * pseudonymChlgBuff)533 static int32_t AddPseudonymChallengeToPayload(CJson *payload, const Uint8Buff *pseudonymChlgBuff)
534 {
535 uint32_t hexLen = pseudonymChlgBuff->length * BYTE_TO_HEX_OPER_LENGTH + 1;
536 char *hexStr = (char *)HcMalloc(hexLen, 0);
537 if (hexStr == NULL) {
538 LOGE("Failed to alloc memory for pseudonym challenge hex!");
539 return HC_ERR_ALLOC_MEMORY;
540 }
541 int32_t res = ByteToHexString(pseudonymChlgBuff->val, pseudonymChlgBuff->length, hexStr, hexLen);
542 if (res != HC_SUCCESS) {
543 LOGE("Failed to convert pseudonym challenge from byte to hex!");
544 HcFree(hexStr);
545 return res;
546 }
547 Uint8Buff hexBuff = {
548 .val = (uint8_t *)hexStr,
549 .length = HcStrlen(hexStr)
550 };
551 res = ToLowerCase(&hexBuff);
552 if (res != HC_SUCCESS) {
553 LOGE("Failed to convert pseudonym challenge hex to lower case!");
554 HcFree(hexStr);
555 return res;
556 }
557 if (AddStringToJson(payload, FIELD_PSEUDONYM_CHALLENGE, hexStr) != HC_SUCCESS) {
558 LOGE("Failed to add pseudonym challenge hex to payload!");
559 HcFree(hexStr);
560 return HC_ERR_JSON_ADD;
561 }
562 HcFree(hexStr);
563 return HC_SUCCESS;
564 }
565
GenerateSelfPseudonymChlgAndId(const PakeParams * params,Uint8Buff * pseudonymChlgBuff,Uint8Buff * pseudonymIdBuff)566 static int32_t GenerateSelfPseudonymChlgAndId(const PakeParams *params, Uint8Buff *pseudonymChlgBuff,
567 Uint8Buff *pseudonymIdBuff)
568 {
569 int32_t res = GeneratePseudonymPskIfNotExist(params);
570 if (res != HC_SUCCESS) {
571 return res;
572 }
573 res = params->baseParams.loader->generateRandom(pseudonymChlgBuff);
574 if (res != HC_SUCCESS) {
575 LOGE("Failed to generate pseudonym challenge!");
576 return res;
577 }
578 Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
579 uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
580 Uint8Buff pskAlias = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
581 res = GeneratePseudonymPskAlias(&serviceTypeBuff, &(params->baseParams.idPeer), &pskAlias);
582 if (res != HC_SUCCESS) {
583 LOGE("Failed to generate pseudonym psk alias!");
584 return res;
585 }
586 res = ToLowerCase(&pskAlias);
587 if (res != HC_SUCCESS) {
588 LOGE("Failed to convert pseudonym psk alias to lower case!");
589 return res;
590 }
591 KeyParams pskAliasParams = { { pskAlias.val, pskAlias.length, true }, true, params->baseParams.osAccountId };
592 res = params->baseParams.loader->computeHmacWithThreeStage(&pskAliasParams, pseudonymChlgBuff, pseudonymIdBuff);
593 if (res != HC_SUCCESS) {
594 LOGE("Failed to generate pseudonym id!");
595 ReportRadarEvent(res);
596 }
597 return res;
598 }
599
GetSelfPseudonymChlgAndIdByExtInfo(const PakeParams * params,Uint8Buff * pseudonymChallengeBuff,Uint8Buff * pseudonymIdBuff)600 static int32_t GetSelfPseudonymChlgAndIdByExtInfo(const PakeParams *params, Uint8Buff *pseudonymChallengeBuff,
601 Uint8Buff *pseudonymIdBuff)
602 {
603 if (memcpy_s(pseudonymChallengeBuff->val, pseudonymChallengeBuff->length,
604 params->pseudonymExtInfo.selfNextPseudonymChallenge.val,
605 params->pseudonymExtInfo.selfNextPseudonymChallenge.length) != EOK) {
606 LOGE("Failed to copy pseudonym challenge!");
607 return HC_ERR_MEMORY_COPY;
608 }
609 if (memcpy_s(pseudonymIdBuff->val, pseudonymIdBuff->length, params->pseudonymExtInfo.selfNextPseudonymId.val,
610 params->pseudonymExtInfo.selfNextPseudonymId.length) != EOK) {
611 LOGE("Failed to copy pseudonym id!");
612 return HC_ERR_MEMORY_COPY;
613 }
614 return HC_SUCCESS;
615 }
616
AddPseudonymIdAndChallenge(PakeParams * params,CJson * payload)617 int32_t AddPseudonymIdAndChallenge(PakeParams *params, CJson *payload)
618 {
619 if (params == NULL || payload == NULL) {
620 LOGE("Invalid params!");
621 return HC_ERR_INVALID_PARAMS;
622 }
623 uint8_t pseudonymChallenge[PSEUDONYM_CHALLENGE_LEN] = { 0 };
624 Uint8Buff pseudonymChallengeBuff = { pseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
625 uint8_t pseudonymId[PSEUDONYM_ID_LEN] = { 0 };
626 Uint8Buff pseudonymIdBuff = { pseudonymId, PSEUDONYM_ID_LEN };
627 int32_t res;
628 if (params->pseudonymExtInfo.selfNextPseudonymId.val == NULL ||
629 params->pseudonymExtInfo.selfNextPseudonymChallenge.val == NULL) {
630 LOGW("Saved next pseudonym id or challenge is null, generate it!");
631 res = GenerateSelfPseudonymChlgAndId(params, &pseudonymChallengeBuff, &pseudonymIdBuff);
632 } else {
633 LOGI("Saved next pseudonym id or challenge is not null, use it directly.");
634 res = GetSelfPseudonymChlgAndIdByExtInfo(params, &pseudonymChallengeBuff, &pseudonymIdBuff);
635 }
636 if (res != HC_SUCCESS) {
637 return res;
638 }
639 Uint8Buff nextPseudonymChallengeBuff = { params->selfNextPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
640 res = params->baseParams.loader->generateRandom(&nextPseudonymChallengeBuff);
641 if (res != HC_SUCCESS) {
642 LOGE("Failed to generate next pseudonym challenge!");
643 return res;
644 }
645 res = AddPseudonymIdToPayload(payload, &pseudonymIdBuff);
646 if (res != HC_SUCCESS) {
647 LOGE("Failed to add pdid to payload!");
648 return res;
649 }
650 uint8_t combinedChallenge[PSEUDONYM_COMBINE_CHALLENGE_LEN] = { 0 };
651 Uint8Buff combinedChallengeBuff = { combinedChallenge, PSEUDONYM_COMBINE_CHALLENGE_LEN };
652 res = CombinePseudonymChallenge(&combinedChallengeBuff, &pseudonymChallengeBuff, &nextPseudonymChallengeBuff);
653 if (res != HC_SUCCESS) {
654 LOGE("Failed to combine pseudonym challenge!");
655 return res;
656 }
657 res = AddPseudonymChallengeToPayload(payload, &combinedChallengeBuff);
658 if (res != HC_SUCCESS) {
659 LOGE("Failed to add pdChlg to payload!");
660 }
661 return res;
662 }
663
CheckPseudonymIdByCompute(const PakeParams * params,const Uint8Buff * peerPseudonymChallengeBuff,const Uint8Buff * peerPseudonymIdBuff,bool * isEqual)664 static int32_t CheckPseudonymIdByCompute(const PakeParams *params, const Uint8Buff *peerPseudonymChallengeBuff,
665 const Uint8Buff *peerPseudonymIdBuff, bool *isEqual)
666 {
667 int32_t res = GeneratePseudonymPskIfNotExist(params);
668 if (res != HC_SUCCESS) {
669 LOGE("Failed to generate pseudonym psk!");
670 return res;
671 }
672 Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
673 uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
674 Uint8Buff pskAlias = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
675 res = GeneratePseudonymPskAlias(&serviceTypeBuff, &(params->baseParams.idPeer), &pskAlias);
676 if (res != HC_SUCCESS) {
677 LOGE("Failed to generate pseudonym psk alias!");
678 return res;
679 }
680 res = ToLowerCase(&pskAlias);
681 if (res != HC_SUCCESS) {
682 LOGE("Failed to convert pseudonym psk alias to lower case!");
683 return res;
684 }
685 uint8_t computePeerPseudonymId[PSEUDONYM_ID_LEN] = { 0 };
686 Uint8Buff computePeerPseudonymIdBuff = { computePeerPseudonymId, PSEUDONYM_ID_LEN };
687 KeyParams pskAliasParams = { { pskAlias.val, pskAlias.length, true }, true, params->baseParams.osAccountId };
688 res = params->baseParams.loader->computeHmacWithThreeStage(&pskAliasParams, peerPseudonymChallengeBuff,
689 &computePeerPseudonymIdBuff);
690 if (res != HC_SUCCESS) {
691 LOGE("Failed to generate peer pseudonym id!");
692 ReportRadarEvent(res);
693 return res;
694 }
695 *isEqual = (memcmp(peerPseudonymIdBuff->val, computePeerPseudonymId, PSEUDONYM_ID_LEN) == 0);
696 return HC_SUCCESS;
697 }
698
GetPeerChallenge(const CJson * payload,Uint8Buff * peerPseudonymChallengeBuff,PakeParams * params)699 static int32_t GetPeerChallenge(const CJson *payload, Uint8Buff *peerPseudonymChallengeBuff, PakeParams *params)
700 {
701 uint8_t peerChallenge[PSEUDONYM_COMBINE_CHALLENGE_LEN] = { 0 };
702 if (GetByteFromJson(payload, FIELD_PSEUDONYM_CHALLENGE, peerChallenge,
703 PSEUDONYM_COMBINE_CHALLENGE_LEN) != HC_SUCCESS) {
704 LOGE("Failed to get peer challenge!");
705 return HC_ERR_JSON_GET;
706 }
707 if (memcpy_s(peerPseudonymChallengeBuff->val, PSEUDONYM_CHALLENGE_LEN, peerChallenge,
708 PSEUDONYM_CHALLENGE_LEN) != EOK) {
709 LOGE("Failed to copy peer pseudonym challenge!");
710 return HC_ERR_MEMORY_COPY;
711 }
712 if (memcpy_s(params->peerNextPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN,
713 peerChallenge + PSEUDONYM_CHALLENGE_LEN, PSEUDONYM_CHALLENGE_LEN) != EOK) {
714 LOGE("Failed to copy peer next pseudonym challenge!");
715 return HC_ERR_MEMORY_COPY;
716 }
717 return HC_SUCCESS;
718 }
719
CheckPseudonymId(PakeParams * params,const CJson * in)720 int32_t CheckPseudonymId(PakeParams *params, const CJson *in)
721 {
722 if (params == NULL || in == NULL) {
723 LOGE("Invalid params!");
724 return HC_ERR_INVALID_PARAMS;
725 }
726 const CJson *payload = GetObjFromJson(in, FIELD_PAYLOAD);
727 if (payload == NULL) {
728 LOGE("Failed to get payload!");
729 return HC_ERR_JSON_GET;
730 }
731 uint8_t peerPseudonymId[PSEUDONYM_ID_LEN] = { 0 };
732 if (GetByteFromJson(payload, FIELD_P2P_PSEUDONYM_ID, peerPseudonymId, PSEUDONYM_ID_LEN) != HC_SUCCESS) {
733 LOGE("Failed to get peer pseudonym id!");
734 return HC_ERR_JSON_GET;
735 }
736 uint8_t peerPseudonymChallenge[PSEUDONYM_CHALLENGE_LEN] = { 0 };
737 Uint8Buff peerPseudonymChallengeBuff = { peerPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
738 int32_t res = GetPeerChallenge(payload, &peerPseudonymChallengeBuff, params);
739 if (res != HC_SUCCESS) {
740 return res;
741 }
742 bool isEqual = false;
743 if (params->pseudonymExtInfo.peerNextPseudonymId.val != NULL) {
744 isEqual = (memcmp(peerPseudonymId, params->pseudonymExtInfo.peerNextPseudonymId.val, PSEUDONYM_ID_LEN) == 0);
745 }
746 if (!isEqual) {
747 Uint8Buff peerPseudonymIdBuff = { peerPseudonymId, PSEUDONYM_ID_LEN };
748 res = CheckPseudonymIdByCompute(params, &peerPseudonymChallengeBuff, &peerPseudonymIdBuff, &isEqual);
749 if (res != HC_SUCCESS) {
750 LOGE("Failed to check pseudonym id by compute!");
751 return res;
752 }
753 }
754 if (!isEqual) {
755 LOGE("Check pseudonym id failed!");
756 return HC_ERR_MEMORY_COMPARE;
757 }
758 LOGI("Check pseudonym id succeed.");
759 return HC_SUCCESS;
760 }
761
GeneratePseudonymPskExtInfo(const PakeParams * params,const Uint8Buff * selfNextPseudonymIdBuff,const Uint8Buff * peerNextPseudonymIdBuff,Uint8Buff * extInfoBuff)762 static int32_t GeneratePseudonymPskExtInfo(const PakeParams *params, const Uint8Buff *selfNextPseudonymIdBuff,
763 const Uint8Buff *peerNextPseudonymIdBuff, Uint8Buff *extInfoBuff)
764 {
765 CJson *extInfoJson = CreateJson();
766 if (extInfoJson == NULL) {
767 LOGE("Failed to create extInfo json!");
768 return HC_ERR_JSON_CREATE;
769 }
770 if (AddByteToJson(extInfoJson, FIELD_SELF_NEXT_PSEUDONYM_ID, selfNextPseudonymIdBuff->val,
771 PSEUDONYM_ID_LEN) != HC_SUCCESS) {
772 LOGE("Failed to add self next pseudonym id!");
773 FreeJson(extInfoJson);
774 return HC_ERR_JSON_ADD;
775 }
776 if (AddByteToJson(extInfoJson, FIELD_SELF_NEXT_PSEUDONYM_CHALLENGE, params->selfNextPseudonymChallenge,
777 PSEUDONYM_CHALLENGE_LEN) != HC_SUCCESS) {
778 LOGE("Failed to add self next pseudonym challenge!");
779 FreeJson(extInfoJson);
780 return HC_ERR_JSON_ADD;
781 }
782 if (AddByteToJson(extInfoJson, FIELD_PEER_NEXT_PSEUDONYM_ID, peerNextPseudonymIdBuff->val,
783 PSEUDONYM_ID_LEN) != HC_SUCCESS) {
784 LOGE("Failed to add peer next pseudonym id!");
785 FreeJson(extInfoJson);
786 return HC_ERR_JSON_ADD;
787 }
788 char *extInfoJsonStr = PackJsonToString(extInfoJson);
789 FreeJson(extInfoJson);
790 if (extInfoJsonStr == NULL) {
791 LOGE("Failed to pack extInfo json to string!");
792 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
793 }
794 extInfoBuff->val = (uint8_t *)extInfoJsonStr;
795 extInfoBuff->length = HcStrlen(extInfoJsonStr) + 1;
796 return HC_SUCCESS;
797 }
798
SaveExtInfoToPseudonymPsk(const PakeParams * params,const Uint8Buff * extInfoStrBuff,const Uint8Buff * pskAliasBuff)799 static int32_t SaveExtInfoToPseudonymPsk(const PakeParams *params, const Uint8Buff *extInfoStrBuff,
800 const Uint8Buff *pskAliasBuff)
801 {
802 uint8_t baseKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
803 Uint8Buff baseKeyAlias = { baseKeyAliasVal, PAKE_KEY_ALIAS_LEN };
804 TokenManagerParams tokenParams = { 0 };
805 tokenParams.pkgName.val = (uint8_t *)params->packageName;
806 tokenParams.pkgName.length = HcStrlen(params->packageName);
807 tokenParams.serviceType.val = (uint8_t *)params->serviceType;
808 tokenParams.serviceType.length = HcStrlen(params->serviceType);
809 tokenParams.userType = KEY_ALIAS_PSK;
810 tokenParams.authId = params->baseParams.idPeer;
811 int32_t res = GenerateKeyAlias(&tokenParams, &baseKeyAlias);
812 if (res != HC_SUCCESS) {
813 LOGE("Failed to generate psk alias!");
814 return res;
815 }
816 res = ToLowerCase(&baseKeyAlias);
817 if (res != HC_SUCCESS) {
818 LOGE("Failed to convert psk alias to lower case!");
819 return res;
820 }
821 uint8_t outKeyVal[PAKE_PSK_LEN] = { 0 };
822 Uint8Buff outKeyBuff = { outKeyVal, PAKE_PSK_LEN };
823 KeyParams keyParams = { { baseKeyAlias.val, baseKeyAlias.length, true }, true, params->baseParams.osAccountId };
824 res = params->baseParams.loader->computePseudonymPsk(&keyParams, pskAliasBuff, extInfoStrBuff,
825 &outKeyBuff);
826 if (res != HC_SUCCESS) {
827 LOGE("Failed to save extInfo to pseudonym psk!");
828 }
829 return res;
830 }
831
SaveNextPseudonymIdAndChallenge(PakeParams * params)832 int32_t SaveNextPseudonymIdAndChallenge(PakeParams *params)
833 {
834 int32_t res = GeneratePseudonymPskIfNotExist(params);
835 if (res != HC_SUCCESS) {
836 return res;
837 }
838 Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
839 uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
840 Uint8Buff pskAlias = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
841 res = GeneratePseudonymPskAlias(&serviceTypeBuff, &(params->baseParams.idPeer), &pskAlias);
842 if (res != HC_SUCCESS) {
843 LOGE("Failed to generate pseudonym psk alias!");
844 return res;
845 }
846 res = ToLowerCase(&pskAlias);
847 if (res != HC_SUCCESS) {
848 LOGE("Failed to convert pseudonym psk alias to lower case!");
849 return res;
850 }
851 uint8_t selfNextPseudonymId[PSEUDONYM_ID_LEN] = { 0 };
852 Uint8Buff selfNextPseudonymIdBuff = { selfNextPseudonymId, PSEUDONYM_ID_LEN };
853 Uint8Buff selfNextPseudonymChallengeBuff = { params->selfNextPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
854 KeyParams pskAliasParams = { { pskAlias.val, pskAlias.length, true }, true, params->baseParams.osAccountId };
855 res = params->baseParams.loader->computeHmacWithThreeStage(&pskAliasParams, &selfNextPseudonymChallengeBuff,
856 &selfNextPseudonymIdBuff);
857 if (res != HC_SUCCESS) {
858 LOGE("Failed to compute next self pseudonym id!");
859 ReportRadarEvent(res);
860 return res;
861 }
862 uint8_t peerNextPseudonymId[PSEUDONYM_ID_LEN] = { 0 };
863 Uint8Buff peerNextPseudonymIdBuff = { peerNextPseudonymId, PSEUDONYM_ID_LEN };
864 Uint8Buff peerNextPseudonymChallengeBuff = { params->peerNextPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
865 res = params->baseParams.loader->computeHmacWithThreeStage(&pskAliasParams, &peerNextPseudonymChallengeBuff,
866 &peerNextPseudonymIdBuff);
867 if (res != HC_SUCCESS) {
868 LOGE("Failed to compute next peer pseudonym id!");
869 ReportRadarEvent(res);
870 return res;
871 }
872 Uint8Buff extInfoStrBuff = { NULL, 0 };
873 res = GeneratePseudonymPskExtInfo(params, &selfNextPseudonymIdBuff, &peerNextPseudonymIdBuff, &extInfoStrBuff);
874 if (res != HC_SUCCESS) {
875 return res;
876 }
877 res = SaveExtInfoToPseudonymPsk(params, &extInfoStrBuff, &pskAlias);
878 FreeJsonString((char *)extInfoStrBuff.val);
879 return res;
880 }