1 /*
2 * Copyright (C) 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_protocol.h"
17
18 #include "alg_loader.h"
19 #include "device_auth_defines.h"
20 #include "hc_log.h"
21
22 #define RAND_BYTE_LEN 16
23 #define ISO_TOKEN_LEN 32
24 #define ISO_AUTH_ID_MAX_LEN 256
25 #define ISO_SESSION_KEY_LEN 32
26
27 #define GENERATE_SESSION_KEY_STR "hichain_iso_session_key"
28
29 #define START_AUTH_EVENT_NAME "StartAuth"
30 #define CLEINT_START_REQ_EVENT_NAME "StartReq"
31 #define SERVER_START_RSP_EVENT_NAME "StartRsp"
32 #define CLEINT_FINISH_REQ_EVENT_NAME "FinishReq"
33 #define SERVER_FINISH_RSP_EVENT_NAME "FinishRsp"
34 #define FAIL_EVENT_NAME "AuthFail"
35
36 #define FIELD_RAND_CLIENT "randC"
37 #define FIELD_RAND_SERVER "randS"
38 #define FIELD_AUTH_ID_CLIENT "authIdC"
39 #define FIELD_AUTH_ID_SERVER "authIdS"
40 #define FIELD_TOKEN_CLIENT "tokenC"
41 #define FIELD_TOKEN_SERVER "tokenS"
42 #define FIELD_AUTH_RESULT_MAC "authResultMac"
43
44 #define FIELD_PROTOCOL_TYPE "protocolType"
45 #define FIELD_EVENT "event"
46 #define FIELD_PROTOCOL_DATA "protocolData"
47 #define FIELD_ERR_CODE "errCode"
48 #define FIELD_ERR_MSG "errMsg"
49
50 typedef struct {
51 Uint8Buff psk;
52 Uint8Buff randSelf;
53 Uint8Buff randPeer;
54 Uint8Buff authIdSelf;
55 Uint8Buff authIdPeer;
56 Uint8Buff tokenSelf;
57 Uint8Buff tokenPeer;
58 Uint8Buff authResultMac;
59 int32_t osAccountId;
60 } IsoParams;
61
62 typedef struct {
63 BaseProtocol base;
64 IsoParams params;
65 } IsoProtocol;
66
67 typedef struct {
68 int32_t curState;
69 int32_t eventType;
70 int32_t (*stateProcessFunc)(IsoProtocol *impl, const CJson *inputEvent, CJson **outputEvent);
71 void (*exceptionHandleFunc)(int32_t errorCode, CJson **outputEvent);
72 int32_t nextState;
73 } ProtocolStateNode;
74
BuildSelfTokenMessage(uint8_t * message,int32_t messageLen,const IsoParams * params,const ProtectedMsg * msg)75 static int32_t BuildSelfTokenMessage(uint8_t *message, int32_t messageLen,
76 const IsoParams *params, const ProtectedMsg *msg)
77 {
78 int32_t usedLen = 0;
79 if (memcpy_s(message, messageLen, params->randSelf.val, params->randSelf.length) != EOK) {
80 LOGE("Memcpy randSelf failed.");
81 return HC_ERR_MEMORY_COPY;
82 }
83 usedLen += params->randSelf.length;
84 if (memcpy_s(message + usedLen, messageLen - usedLen, params->randPeer.val, params->randPeer.length) != EOK) {
85 LOGE("Memcpy randPeer failed.");
86 return HC_ERR_MEMORY_COPY;
87 }
88 usedLen += params->randPeer.length;
89 if (memcpy_s(message + usedLen, messageLen - usedLen, params->authIdPeer.val, params->authIdPeer.length) != EOK) {
90 LOGE("Memcpy authIdPeer failed.");
91 return HC_ERR_MEMORY_COPY;
92 }
93 usedLen += params->authIdPeer.length;
94 if (memcpy_s(message + usedLen, messageLen - usedLen, params->authIdSelf.val, params->authIdSelf.length) != EOK) {
95 LOGE("Memcpy authIdSelf failed.");
96 return HC_ERR_MEMORY_COPY;
97 }
98 usedLen += params->authIdSelf.length;
99 if (msg->selfMsg.length > 0 && msg->selfMsg.val != NULL) {
100 if (memcpy_s(message + usedLen, messageLen - usedLen, msg->selfMsg.val, msg->selfMsg.length) != EOK) {
101 LOGE("Memcpy selfMsg failed.");
102 return HC_ERR_MEMORY_COPY;
103 }
104 usedLen += msg->selfMsg.length;
105 }
106 if (msg->peerMsg.length > 0 && msg->peerMsg.val != NULL) {
107 if (memcpy_s(message + usedLen, messageLen - usedLen, msg->peerMsg.val, msg->peerMsg.length) != EOK) {
108 LOGE("Memcpy peerMsg failed.");
109 return HC_ERR_MEMORY_COPY;
110 }
111 }
112 return HC_SUCCESS;
113 }
114
BuildPeerTokenMessage(uint8_t * message,int32_t messageLen,const IsoParams * params,const ProtectedMsg * msg)115 static int32_t BuildPeerTokenMessage(uint8_t *message, int32_t messageLen,
116 const IsoParams *params, const ProtectedMsg *msg)
117 {
118 int32_t usedLen = 0;
119 if (memcpy_s(message, messageLen, params->randPeer.val, params->randPeer.length) != EOK) {
120 LOGE("Memcpy randPeer failed.");
121 return HC_ERR_MEMORY_COPY;
122 }
123 usedLen += params->randPeer.length;
124 if (memcpy_s(message + usedLen, messageLen - usedLen, params->randSelf.val, params->randSelf.length) != EOK) {
125 LOGE("Memcpy randSelf failed.");
126 return HC_ERR_MEMORY_COPY;
127 }
128 usedLen += params->randSelf.length;
129 if (memcpy_s(message + usedLen, messageLen - usedLen, params->authIdSelf.val, params->authIdSelf.length) != EOK) {
130 LOGE("Memcpy authIdSelf failed.");
131 return HC_ERR_MEMORY_COPY;
132 }
133 usedLen += params->authIdSelf.length;
134 if (memcpy_s(message + usedLen, messageLen - usedLen, params->authIdPeer.val, params->authIdPeer.length) != EOK) {
135 LOGE("Memcpy authIdPeer failed.");
136 return HC_ERR_MEMORY_COPY;
137 }
138 usedLen += params->authIdPeer.length;
139 if (msg->peerMsg.length > 0 && msg->peerMsg.val != NULL) {
140 if (memcpy_s(message + usedLen, messageLen - usedLen, msg->peerMsg.val, msg->peerMsg.length) != EOK) {
141 LOGE("Memcpy peerMsg failed.");
142 return HC_ERR_MEMORY_COPY;
143 }
144 usedLen += msg->peerMsg.length;
145 }
146 if (msg->selfMsg.length > 0 && msg->selfMsg.val != NULL) {
147 if (memcpy_s(message + usedLen, messageLen - usedLen, msg->selfMsg.val, msg->selfMsg.length) != EOK) {
148 LOGE("Memcpy selfMsg failed.");
149 return HC_ERR_MEMORY_COPY;
150 }
151 }
152 return HC_SUCCESS;
153 }
154
IsoCalToken(const IsoProtocol * protocol,Uint8Buff * token,bool isSelf)155 static int32_t IsoCalToken(const IsoProtocol *protocol, Uint8Buff *token, bool isSelf)
156 {
157 const IsoParams *params = &(protocol->params);
158 const ProtectedMsg *msg = &(protocol->base.protectedMsg);
159 int32_t length = params->randSelf.length + params->randPeer.length +
160 params->authIdSelf.length + params->authIdPeer.length +
161 msg->selfMsg.length + msg->peerMsg.length;
162 uint8_t *message = (uint8_t *)HcMalloc(length, 0);
163 if (message == NULL) {
164 LOGE("Malloc for message failed.");
165 return HC_ERR_ALLOC_MEMORY;
166 }
167 int32_t res = isSelf ? BuildSelfTokenMessage(message, length, params, msg) :
168 BuildPeerTokenMessage(message, length, params, msg);
169 if (res != HC_SUCCESS) {
170 HcFree(message);
171 return res;
172 }
173 Uint8Buff messageBuf = { message, length };
174 KeyParams keyParams = { { params->psk.val, params->psk.length, false }, false, params->osAccountId };
175 res = GetLoaderInstance()->computeHmac(&keyParams, &messageBuf, token);
176 HcFree(message);
177 if (res != HC_SUCCESS) {
178 LOGE("ComputeHmac for token failed, res: %x.", res);
179 return res;
180 }
181 return HC_SUCCESS;
182 }
183
IsoCombineHkdfSalt(IsoParams * params,Uint8Buff * hkdfSaltBuf,bool isClient)184 static int32_t IsoCombineHkdfSalt(IsoParams *params, Uint8Buff *hkdfSaltBuf, bool isClient)
185 {
186 if (isClient) {
187 if (memcpy_s(hkdfSaltBuf->val, hkdfSaltBuf->length, params->randSelf.val, params->randSelf.length) != EOK) {
188 LOGE("Memcpy randSelf failed.");
189 return HC_ERR_MEMORY_COPY;
190 }
191 if (memcpy_s(hkdfSaltBuf->val + params->randSelf.length, hkdfSaltBuf->length - params->randSelf.length,
192 params->randPeer.val, params->randPeer.length) != EOK) {
193 LOGE("Memcpy randPeer failed.");
194 return HC_ERR_MEMORY_COPY;
195 }
196 } else {
197 if (memcpy_s(hkdfSaltBuf->val, hkdfSaltBuf->length, params->randPeer.val, params->randPeer.length) != EOK) {
198 LOGE("Memcpy randPeer failed.");
199 return HC_ERR_MEMORY_COPY;
200 }
201 if (memcpy_s(hkdfSaltBuf->val + params->randPeer.length, hkdfSaltBuf->length - params->randPeer.length,
202 params->randSelf.val, params->randSelf.length) != EOK) {
203 LOGE("Memcpy randSelf failed.");
204 return HC_ERR_MEMORY_COPY;
205 }
206 }
207 return HC_SUCCESS;
208 }
209
IsoGenSessionKey(IsoProtocol * impl,bool isClient)210 static int32_t IsoGenSessionKey(IsoProtocol *impl, bool isClient)
211 {
212 uint32_t hkdfSaltLen = impl->params.randPeer.length + impl->params.randSelf.length;
213 uint8_t *hkdfSalt = (uint8_t *)HcMalloc(hkdfSaltLen, 0);
214 if (hkdfSalt == NULL) {
215 LOGE("Malloc for hkdfSalt failed.");
216 return HC_ERR_ALLOC_MEMORY;
217 }
218 Uint8Buff hkdfSaltBuf = { hkdfSalt, hkdfSaltLen };
219 int32_t res = IsoCombineHkdfSalt(&impl->params, &hkdfSaltBuf, isClient);
220 if (res != HC_SUCCESS) {
221 LOGE("IsoCombineHkdfSalt failed, res: %d", res);
222 HcFree(hkdfSalt);
223 return res;
224 }
225 Uint8Buff keyInfoBuf = { (uint8_t *)GENERATE_SESSION_KEY_STR, HcStrlen(GENERATE_SESSION_KEY_STR) };
226 uint8_t sessionKeyVal[ISO_SESSION_KEY_LEN] = { 0 };
227 Uint8Buff sessionKey = { sessionKeyVal, ISO_SESSION_KEY_LEN };
228 KeyParams keyParams = {
229 .keyBuff = { impl->params.psk.val, impl->params.psk.length, false },
230 .isDeStorage = false,
231 .osAccountId = impl->params.osAccountId
232 };
233 res = GetLoaderInstance()->computeHkdf(&keyParams, &hkdfSaltBuf, &keyInfoBuf, &sessionKey);
234 HcFree(hkdfSalt);
235 if (res != HC_SUCCESS) {
236 LOGE("ComputeHkdf for sessionKey failed, res: %d", res);
237 return res;
238 }
239 if (DeepCopyUint8Buff(&sessionKey, &impl->base.sessionKey) != HC_SUCCESS) {
240 LOGE("copy sessionkey fail.");
241 (void)memset_s(sessionKeyVal, ISO_SESSION_KEY_LEN, 0, ISO_SESSION_KEY_LEN);
242 return HC_ERR_ALLOC_MEMORY;
243 }
244 (void)memset_s(sessionKeyVal, ISO_SESSION_KEY_LEN, 0, ISO_SESSION_KEY_LEN);
245 return HC_SUCCESS;
246 }
247
IsoGenAuthResultMac(const IsoParams * params,Uint8Buff * authResultMac)248 static int32_t IsoGenAuthResultMac(const IsoParams *params, Uint8Buff *authResultMac)
249 {
250 int32_t returnCode = 0;
251 Uint8Buff messageBuf = { (uint8_t *)&returnCode, sizeof(int32_t) };
252 KeyParams keyParams = { { params->psk.val, params->psk.length, false }, false, params->osAccountId };
253 int32_t res = GetLoaderInstance()->computeHmac(&keyParams, &messageBuf, authResultMac);
254 if (res != HC_SUCCESS) {
255 LOGE("Compute authResultMac failed, res: %x.", res);
256 return res;
257 }
258 return HC_SUCCESS;
259 }
260
ClientGenRandomProcEvent(IsoParams * params)261 static int32_t ClientGenRandomProcEvent(IsoParams *params)
262 {
263 uint8_t randCVal[RAND_BYTE_LEN] = { 0 };
264 Uint8Buff randC = { randCVal, RAND_BYTE_LEN };
265 int32_t res = GetLoaderInstance()->generateRandom(&randC);
266 if (res != HC_SUCCESS) {
267 LOGE("Generate randSelf failed, res: %x.", res);
268 return res;
269 }
270 if (DeepCopyUint8Buff(&randC, ¶ms->randSelf) != HC_SUCCESS) {
271 LOGE("copy randC fail.");
272 return HC_ERR_ALLOC_MEMORY;
273 }
274 return HC_SUCCESS;
275 }
276
ClientGenRandomBuildEvent(const IsoParams * params,CJson ** outputEvent)277 static int32_t ClientGenRandomBuildEvent(const IsoParams *params, CJson **outputEvent)
278 {
279 CJson *json = CreateJson();
280 if (json == NULL) {
281 LOGE("create json failed.");
282 return HC_ERR_JSON_CREATE;
283 }
284 if (AddIntToJson(json, FIELD_EVENT, CLEINT_START_REQ_EVENT) != HC_SUCCESS) {
285 LOGE("add eventName to json fail.");
286 FreeJson(json);
287 return HC_ERR_JSON_ADD;
288 }
289 if (AddByteToJson(json, FIELD_RAND_CLIENT, params->randSelf.val, params->randSelf.length) != HC_SUCCESS) {
290 LOGE("add randC to json fail.");
291 FreeJson(json);
292 return HC_ERR_JSON_ADD;
293 }
294 if (AddByteToJson(json, FIELD_AUTH_ID_CLIENT, params->authIdSelf.val,
295 params->authIdSelf.length) != HC_SUCCESS) {
296 LOGE("add authIdC to json fail.");
297 FreeJson(json);
298 return HC_ERR_JSON_ADD;
299 }
300 *outputEvent = json;
301 return HC_SUCCESS;
302 }
303
ClientGenRandom(IsoProtocol * impl,const CJson * inputEvent,CJson ** outputEvent)304 static int32_t ClientGenRandom(IsoProtocol *impl, const CJson *inputEvent, CJson **outputEvent)
305 {
306 (void)inputEvent;
307 int32_t res = ClientGenRandomProcEvent(&impl->params);
308 if (res != HC_SUCCESS) {
309 return res;
310 }
311 return ClientGenRandomBuildEvent(&impl->params, outputEvent);
312 }
313
ServerGenTokenParseEvent(const CJson * inputEvent,IsoParams * params)314 static int32_t ServerGenTokenParseEvent(const CJson *inputEvent, IsoParams *params)
315 {
316 uint8_t randCVal[RAND_BYTE_LEN] = { 0 };
317 Uint8Buff randC = { randCVal, RAND_BYTE_LEN };
318 if (GetByteFromJson(inputEvent, FIELD_RAND_CLIENT, randC.val, randC.length) != HC_SUCCESS) {
319 LOGE("get randC from receviedMsg fail.");
320 return HC_ERR_JSON_GET;
321 }
322 const char *authIdCStr = GetStringFromJson(inputEvent, FIELD_AUTH_ID_CLIENT);
323 if (authIdCStr == NULL) {
324 LOGE("get authIdCStr from receviedMsg fail.");
325 return HC_ERR_JSON_GET;
326 }
327 uint32_t authIdCLen = HcStrlen(authIdCStr) / BYTE_TO_HEX_OPER_LENGTH;
328 if (authIdCLen == 0 || authIdCLen > ISO_AUTH_ID_MAX_LEN) {
329 LOGE("Invalid authIdCLen: %u.", authIdCLen);
330 return HC_ERR_CONVERT_FAILED;
331 }
332 uint8_t authIdCVal[ISO_AUTH_ID_MAX_LEN] = { 0 };
333 Uint8Buff authIdC = { authIdCVal, authIdCLen };
334 if (HexStringToByte(authIdCStr, authIdC.val, authIdC.length) != HC_SUCCESS) {
335 LOGE("HexStringToByte for authIdC failed.");
336 return HC_ERR_CONVERT_FAILED;
337 }
338 if (DeepCopyUint8Buff(&randC, ¶ms->randPeer) != HC_SUCCESS) {
339 LOGE("copy randC fail.");
340 return HC_ERR_ALLOC_MEMORY;
341 }
342 if (DeepCopyUint8Buff(&authIdC, ¶ms->authIdPeer) != HC_SUCCESS) {
343 LOGE("copy randC fail.");
344 return HC_ERR_ALLOC_MEMORY;
345 }
346 return HC_SUCCESS;
347 }
348
ServerGenTokenProcEvent(IsoProtocol * impl)349 static int32_t ServerGenTokenProcEvent(IsoProtocol *impl)
350 {
351 uint8_t randSVal[RAND_BYTE_LEN] = { 0 };
352 Uint8Buff randS = { randSVal, RAND_BYTE_LEN };
353 int32_t res = GetLoaderInstance()->generateRandom(&randS);
354 if (res != HC_SUCCESS) {
355 LOGE("Generate randSelf failed, res: %x.", res);
356 return res;
357 }
358 if (DeepCopyUint8Buff(&randS, &impl->params.randSelf) != HC_SUCCESS) {
359 LOGE("copy randS fail.");
360 return HC_ERR_ALLOC_MEMORY;
361 }
362 uint8_t tokenValS[SHA256_LEN] = { 0 };
363 Uint8Buff tokenS = { tokenValS, SHA256_LEN };
364 res = IsoCalToken(impl, &tokenS, true);
365 if (res != HC_SUCCESS) {
366 LOGE("IsoCalServerToken failed, res: %x.", res);
367 return res;
368 }
369 if (DeepCopyUint8Buff(&tokenS, &impl->params.tokenSelf) != HC_SUCCESS) {
370 LOGE("copy tokenS fail.");
371 return HC_ERR_ALLOC_MEMORY;
372 }
373 return HC_SUCCESS;
374 }
375
ServerGenTokenBuildEvent(const IsoParams * params,CJson ** outputEvent)376 static int32_t ServerGenTokenBuildEvent(const IsoParams *params, CJson **outputEvent)
377 {
378 CJson *json = CreateJson();
379 if (json == NULL) {
380 LOGE("create json failed.");
381 return HC_ERR_JSON_CREATE;
382 }
383 if (AddIntToJson(json, FIELD_EVENT, SERVER_START_RSP_EVENT) != HC_SUCCESS) {
384 LOGE("add eventName to json fail.");
385 FreeJson(json);
386 return HC_ERR_JSON_ADD;
387 }
388 if (AddByteToJson(json, FIELD_RAND_SERVER, params->randSelf.val, params->randSelf.length) != HC_SUCCESS) {
389 LOGE("add randS to json fail.");
390 FreeJson(json);
391 return HC_ERR_JSON_ADD;
392 }
393 if (AddByteToJson(json, FIELD_AUTH_ID_SERVER, params->authIdSelf.val,
394 params->authIdSelf.length) != HC_SUCCESS) {
395 LOGE("add authIdS to json fail.");
396 FreeJson(json);
397 return HC_ERR_JSON_ADD;
398 }
399 if (AddByteToJson(json, FIELD_TOKEN_SERVER, params->tokenSelf.val, params->tokenSelf.length) != HC_SUCCESS) {
400 LOGE("add tokenS to json fail.");
401 FreeJson(json);
402 return HC_ERR_JSON_ADD;
403 }
404 *outputEvent = json;
405 return HC_SUCCESS;
406 }
407
ServerGenToken(IsoProtocol * impl,const CJson * inputEvent,CJson ** outputEvent)408 static int32_t ServerGenToken(IsoProtocol *impl, const CJson *inputEvent, CJson **outputEvent)
409 {
410 int32_t res = ServerGenTokenParseEvent(inputEvent, &impl->params);
411 if (res != HC_SUCCESS) {
412 return res;
413 }
414 res = ServerGenTokenProcEvent(impl);
415 if (res != HC_SUCCESS) {
416 return res;
417 }
418 return ServerGenTokenBuildEvent(&impl->params, outputEvent);
419 }
420
ClientGenTokenParseEvent(const CJson * inputEvent,IsoParams * params)421 static int32_t ClientGenTokenParseEvent(const CJson *inputEvent, IsoParams *params)
422 {
423 uint8_t randSVal[RAND_BYTE_LEN] = { 0 };
424 Uint8Buff randS = { randSVal, RAND_BYTE_LEN };
425 if (GetByteFromJson(inputEvent, FIELD_RAND_SERVER, randS.val, randS.length) != HC_SUCCESS) {
426 LOGE("get randS from inputEvent fail.");
427 return HC_ERR_JSON_GET;
428 }
429 const char *authIdSStr = GetStringFromJson(inputEvent, FIELD_AUTH_ID_SERVER);
430 if (authIdSStr == NULL) {
431 LOGE("get authIdSStr from inputEvent fail.");
432 return HC_ERR_JSON_GET;
433 }
434 uint32_t authIdSLen = HcStrlen(authIdSStr) / BYTE_TO_HEX_OPER_LENGTH;
435 if (authIdSLen == 0 || authIdSLen > ISO_AUTH_ID_MAX_LEN) {
436 LOGE("Invalid authIdSLen: %u.", authIdSLen);
437 return HC_ERR_CONVERT_FAILED;
438 }
439 uint8_t authIdSVal[ISO_AUTH_ID_MAX_LEN] = { 0 };
440 Uint8Buff authIdS = { authIdSVal, authIdSLen };
441 if (HexStringToByte(authIdSStr, authIdS.val, authIdS.length) != HC_SUCCESS) {
442 LOGE("HexStringToByte for authIdS failed.");
443 return HC_ERR_CONVERT_FAILED;
444 }
445 uint8_t tokenSVal[ISO_TOKEN_LEN] = { 0 };
446 Uint8Buff tokenS = { tokenSVal, ISO_TOKEN_LEN };
447 if (GetByteFromJson(inputEvent, FIELD_TOKEN_SERVER, tokenS.val, tokenS.length) != HC_SUCCESS) {
448 LOGE("get tokenS from receviedMsg fail.");
449 return HC_ERR_JSON_GET;
450 }
451 if (DeepCopyUint8Buff(&randS, ¶ms->randPeer) != HC_SUCCESS) {
452 LOGE("copy randS fail.");
453 return HC_ERR_ALLOC_MEMORY;
454 }
455 if (DeepCopyUint8Buff(&authIdS, ¶ms->authIdPeer) != HC_SUCCESS) {
456 LOGE("copy authIdS fail.");
457 return HC_ERR_ALLOC_MEMORY;
458 }
459 if (DeepCopyUint8Buff(&tokenS, ¶ms->tokenPeer) != HC_SUCCESS) {
460 LOGE("copy tokenS fail.");
461 return HC_ERR_ALLOC_MEMORY;
462 }
463 return HC_SUCCESS;
464 }
465
ClientGenTokenProcEvent(IsoProtocol * impl)466 static int32_t ClientGenTokenProcEvent(IsoProtocol *impl)
467 {
468 uint8_t tokenValS[SHA256_LEN] = { 0 };
469 Uint8Buff tokenS = { tokenValS, SHA256_LEN };
470 int32_t res = IsoCalToken(impl, &tokenS, false);
471 if (res != HC_SUCCESS) {
472 LOGE("IsoCalServerToken failed, res: %d", res);
473 return res;
474 }
475 if ((impl->params.tokenPeer.length != tokenS.length) ||
476 (memcmp(impl->params.tokenPeer.val, tokenS.val, tokenS.length) != 0)) {
477 LOGE("The server token is inconsistent!");
478 return PROOF_MISMATCH;
479 }
480 uint8_t tokenValC[SHA256_LEN] = { 0 };
481 Uint8Buff tokenC = { tokenValC, SHA256_LEN };
482 res = IsoCalToken(impl, &tokenC, true);
483 if (res != HC_SUCCESS) {
484 LOGE("IsoCalClientToken failed, res: %d", res);
485 return res;
486 }
487 if (DeepCopyUint8Buff(&tokenC, &impl->params.tokenSelf) != HC_SUCCESS) {
488 LOGE("copy tokenS fail.");
489 return HC_ERR_ALLOC_MEMORY;
490 }
491 return HC_SUCCESS;
492 }
493
ClientGenTokenBuildEvent(const IsoParams * params,CJson ** outputEvent)494 static int32_t ClientGenTokenBuildEvent(const IsoParams *params, CJson **outputEvent)
495 {
496 CJson *json = CreateJson();
497 if (json == NULL) {
498 LOGE("create json failed.");
499 return HC_ERR_JSON_CREATE;
500 }
501 if (AddIntToJson(json, FIELD_EVENT, CLEINT_FINISH_REQ_EVENT) != HC_SUCCESS) {
502 LOGE("add eventName to json fail.");
503 FreeJson(json);
504 return HC_ERR_JSON_ADD;
505 }
506 if (AddByteToJson(json, FIELD_TOKEN_CLIENT, params->tokenSelf.val, params->tokenSelf.length) != HC_SUCCESS) {
507 LOGE("add tokenC to json fail.");
508 FreeJson(json);
509 return HC_ERR_JSON_ADD;
510 }
511 *outputEvent = json;
512 return HC_SUCCESS;
513 }
514
ClientGenToken(IsoProtocol * impl,const CJson * inputEvent,CJson ** outputEvent)515 static int32_t ClientGenToken(IsoProtocol *impl, const CJson *inputEvent, CJson **outputEvent)
516 {
517 int32_t res = ClientGenTokenParseEvent(inputEvent, &impl->params);
518 if (res != HC_SUCCESS) {
519 return res;
520 }
521 res = ClientGenTokenProcEvent(impl);
522 if (res != HC_SUCCESS) {
523 return res;
524 }
525 return ClientGenTokenBuildEvent(&impl->params, outputEvent);
526 }
527
ServerGenSessKeyParseEvent(const CJson * inputEvent,IsoParams * params)528 static int32_t ServerGenSessKeyParseEvent(const CJson *inputEvent, IsoParams *params)
529 {
530 uint8_t tokenCVal[ISO_TOKEN_LEN] = { 0 };
531 Uint8Buff tokenC = { tokenCVal, ISO_TOKEN_LEN };
532 if (GetByteFromJson(inputEvent, FIELD_TOKEN_CLIENT, tokenC.val, tokenC.length) != HC_SUCCESS) {
533 LOGE("get tokenC from receviedMsg fail.");
534 return HC_ERR_JSON_GET;
535 }
536 if (DeepCopyUint8Buff(&tokenC, ¶ms->tokenPeer) != HC_SUCCESS) {
537 LOGE("copy tokenC fail.");
538 return HC_ERR_ALLOC_MEMORY;
539 }
540 return HC_SUCCESS;
541 }
542
ServerGenSessKeyProcEvent(IsoProtocol * impl)543 static int32_t ServerGenSessKeyProcEvent(IsoProtocol *impl)
544 {
545 uint8_t tokenValC[SHA256_LEN] = { 0 };
546 Uint8Buff tokenC = { tokenValC, SHA256_LEN };
547 int32_t res = IsoCalToken(impl, &tokenC, false);
548 if (res != HC_SUCCESS) {
549 LOGE("IsoCalClientToken failed, res: %d", res);
550 return res;
551 }
552 if ((impl->params.tokenPeer.length != tokenC.length) ||
553 (memcmp(impl->params.tokenPeer.val, tokenC.val, tokenC.length) != 0)) {
554 LOGE("The client token is inconsistent!");
555 return PROOF_MISMATCH;
556 }
557 uint8_t authResultMacVal[SHA256_LEN] = { 0 };
558 Uint8Buff authResultMac = { authResultMacVal, SHA256_LEN };
559 res = IsoGenAuthResultMac(&impl->params, &authResultMac);
560 if (res != HC_SUCCESS) {
561 return res;
562 }
563 if (DeepCopyUint8Buff(&authResultMac, &impl->params.authResultMac) != HC_SUCCESS) {
564 LOGE("copy authResultMac fail.");
565 return HC_ERR_ALLOC_MEMORY;
566 }
567 res = IsoGenSessionKey(impl, false);
568 if (res != HC_SUCCESS) {
569 LOGE("IsoGenSessionKey failed, res: %d", res);
570 return res;
571 }
572 return HC_SUCCESS;
573 }
574
ServerGenSessKeyBuildEvent(const IsoParams * params,CJson ** outputEvent)575 static int32_t ServerGenSessKeyBuildEvent(const IsoParams *params, CJson **outputEvent)
576 {
577 CJson *json = CreateJson();
578 if (json == NULL) {
579 LOGE("create json failed.");
580 return HC_ERR_JSON_CREATE;
581 }
582 if (AddIntToJson(json, FIELD_EVENT, SERVER_FINISH_RSP_EVENT) != HC_SUCCESS) {
583 LOGE("add eventName to json fail.");
584 FreeJson(json);
585 return HC_ERR_JSON_ADD;
586 }
587 if (AddByteToJson(json, FIELD_AUTH_RESULT_MAC, params->authResultMac.val,
588 params->authResultMac.length) != HC_SUCCESS) {
589 LOGE("add authResultMac to json fail.");
590 FreeJson(json);
591 return HC_ERR_JSON_ADD;
592 }
593 *outputEvent = json;
594 return HC_SUCCESS;
595 }
596
ServerGenSessKey(IsoProtocol * impl,const CJson * inputEvent,CJson ** outputEvent)597 static int32_t ServerGenSessKey(IsoProtocol *impl, const CJson *inputEvent, CJson **outputEvent)
598 {
599 int32_t res = ServerGenSessKeyParseEvent(inputEvent, &impl->params);
600 if (res != HC_SUCCESS) {
601 return res;
602 }
603 res = ServerGenSessKeyProcEvent(impl);
604 if (res != HC_SUCCESS) {
605 return res;
606 }
607 return ServerGenSessKeyBuildEvent(&impl->params, outputEvent);
608 }
609
ClientGenSessKeyParseEvent(const CJson * inputEvent,IsoParams * params)610 static int32_t ClientGenSessKeyParseEvent(const CJson *inputEvent, IsoParams *params)
611 {
612 uint8_t authResultMacVal[HMAC_LEN] = { 0 };
613 Uint8Buff authResultMac = { authResultMacVal, HMAC_LEN };
614 if (GetByteFromJson(inputEvent, FIELD_AUTH_RESULT_MAC, authResultMac.val,
615 authResultMac.length) != HC_SUCCESS) {
616 LOGE("get authResultMac from inputEvent fail.");
617 return HC_ERR_JSON_GET;
618 }
619 if (DeepCopyUint8Buff(&authResultMac, ¶ms->authResultMac) != HC_SUCCESS) {
620 LOGE("copy authResultMac fail.");
621 return HC_ERR_ALLOC_MEMORY;
622 }
623 return HC_SUCCESS;
624 }
625
ClientGenSessKeyProcEvent(IsoProtocol * impl)626 static int32_t ClientGenSessKeyProcEvent(IsoProtocol *impl)
627 {
628 uint8_t authResultMacVal[SHA256_LEN] = { 0 };
629 Uint8Buff authResultMac = { authResultMacVal, SHA256_LEN };
630 int32_t res = IsoGenAuthResultMac(&impl->params, &authResultMac);
631 if (res != HC_SUCCESS) {
632 return res;
633 }
634 if (memcmp(impl->params.authResultMac.val, authResultMac.val, SHA256_LEN) != 0) {
635 LOGE("The authResultMac is isconsistent!");
636 return HC_ERR_PEER_ERROR;
637 }
638 res = IsoGenSessionKey(impl, true);
639 if (res != HC_SUCCESS) {
640 LOGE("IsoGenSessionKey failed, res: %x.", res);
641 return res;
642 }
643 return HC_SUCCESS;
644 }
645
ClientGenSessKey(IsoProtocol * impl,const CJson * inputEvent,CJson ** outputEvent)646 static int32_t ClientGenSessKey(IsoProtocol *impl, const CJson *inputEvent, CJson **outputEvent)
647 {
648 (void)outputEvent;
649 int32_t res = ClientGenSessKeyParseEvent(inputEvent, &impl->params);
650 if (res != HC_SUCCESS) {
651 return res;
652 }
653 return ClientGenSessKeyProcEvent(impl);
654 }
655
ReturnError(int32_t errorCode,CJson ** outputEvent)656 static void ReturnError(int32_t errorCode, CJson **outputEvent)
657 {
658 (void)errorCode;
659 (void)outputEvent;
660 return;
661 }
662
NotifyPeerError(int32_t errorCode,CJson ** outputEvent)663 static void NotifyPeerError(int32_t errorCode, CJson **outputEvent)
664 {
665 CJson *json = CreateJson();
666 if (json == NULL) {
667 LOGE("create json failed.");
668 return;
669 }
670 if (AddIntToJson(json, FIELD_EVENT, FAIL_EVENT) != HC_SUCCESS) {
671 LOGE("add eventName to json fail.");
672 FreeJson(json);
673 return;
674 }
675 if (AddIntToJson(json, FIELD_ERR_CODE, errorCode) != HC_SUCCESS) {
676 LOGE("add errorCode to json fail.");
677 FreeJson(json);
678 return;
679 }
680 *outputEvent = json;
681 return;
682 }
683
ThrowException(IsoProtocol * impl,const CJson * inputEvent,CJson ** outputEvent)684 static int32_t ThrowException(IsoProtocol *impl, const CJson *inputEvent, CJson **outputEvent)
685 {
686 (void)impl;
687 (void)outputEvent;
688 int32_t peerErrorCode = HC_ERR_PEER_ERROR;
689 (void)GetIntFromJson(inputEvent, FIELD_ERR_CODE, &peerErrorCode);
690 LOGE("An exception occurred in the peer protocol. [Code]: %d", peerErrorCode);
691 return peerErrorCode;
692 }
693
694 static const ProtocolStateNode STATE_MACHINE[] = {
695 { CREATE_AS_CLIENT_STATE, START_AUTH_EVENT, ClientGenRandom, ReturnError, CLIENT_REQ_STATE },
696 { CREATE_AS_SERVER_STATE, CLEINT_START_REQ_EVENT, ServerGenToken, NotifyPeerError, SERVER_RSP_STATE },
697 { CLIENT_REQ_STATE, SERVER_START_RSP_EVENT, ClientGenToken, NotifyPeerError, CLIENT_FINISH_REQ_STATE },
698 { CLIENT_REQ_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
699 { SERVER_RSP_STATE, CLEINT_FINISH_REQ_EVENT, ServerGenSessKey, NotifyPeerError, SERVER_FINISH_STATE },
700 { SERVER_RSP_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
701 { CLIENT_FINISH_REQ_STATE, SERVER_FINISH_RSP_EVENT, ClientGenSessKey, NotifyPeerError, CLIENT_FINISH_STATE },
702 { CLIENT_FINISH_REQ_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
703 };
704
DecodeEvent(const CJson * receviedMsg)705 static int32_t DecodeEvent(const CJson *receviedMsg)
706 {
707 if (receviedMsg == NULL) {
708 return START_AUTH_EVENT;
709 }
710 int32_t event;
711 if (GetIntFromJson(receviedMsg, FIELD_EVENT, &event) != HC_SUCCESS) {
712 LOGE("get event from receviedMsg fail.");
713 return UNKNOWN_EVENT;
714 }
715 if (START_AUTH_EVENT <= event && event <= UNKNOWN_EVENT) {
716 return event;
717 }
718 LOGE("unknown event.");
719 return UNKNOWN_EVENT;
720 }
721
IsoProtocolSwitchState(BaseProtocol * self,const CJson * receviedMsg,CJson ** returnSendMsg)722 static int32_t IsoProtocolSwitchState(BaseProtocol *self, const CJson *receviedMsg, CJson **returnSendMsg)
723 {
724 int32_t eventType = DecodeEvent(receviedMsg);
725 for (uint32_t i = 0; i < sizeof(STATE_MACHINE) / sizeof(STATE_MACHINE[0]); i++) {
726 if ((STATE_MACHINE[i].curState == self->curState) && (STATE_MACHINE[i].eventType == eventType)) {
727 int32_t res = STATE_MACHINE[i].stateProcessFunc((IsoProtocol *)self, receviedMsg, returnSendMsg);
728 if (res != HC_SUCCESS) {
729 STATE_MACHINE[i].exceptionHandleFunc(res, returnSendMsg);
730 self->curState = self->failState;
731 return res;
732 }
733 LOGI("event: %d, curState: %d, nextState: %d", eventType, self->curState, STATE_MACHINE[i].nextState);
734 self->curState = STATE_MACHINE[i].nextState;
735 return HC_SUCCESS;
736 }
737 }
738 LOGI("Unsupported event type. Ignore process. [Event]: %d, [CurState]: %d", eventType, self->curState);
739 return HC_SUCCESS;
740 }
741
StartIsoProtocol(BaseProtocol * self,CJson ** returnSendMsg)742 static int32_t StartIsoProtocol(BaseProtocol *self, CJson **returnSendMsg)
743 {
744 if ((self == NULL) || (returnSendMsg == NULL)) {
745 LOGE("invalid params.");
746 return HC_ERR_INVALID_PARAMS;
747 }
748 if ((self->curState == self->finishState) || (self->curState == self->failState)) {
749 LOGE("The protocol has ended, and the state switch cannot continue!");
750 return HC_ERR_UNSUPPORTED_OPCODE;
751 }
752 return IsoProtocolSwitchState(self, NULL, returnSendMsg);
753 }
754
ProcessIsoProtocol(BaseProtocol * self,const CJson * receviedMsg,CJson ** returnSendMsg)755 static int32_t ProcessIsoProtocol(BaseProtocol *self, const CJson *receviedMsg, CJson **returnSendMsg)
756 {
757 if ((self == NULL) || (receviedMsg == NULL) || (returnSendMsg == NULL)) {
758 LOGE("invalid params.");
759 return HC_ERR_INVALID_PARAMS;
760 }
761 if ((self->curState == self->finishState) || (self->curState == self->failState)) {
762 LOGE("The protocol has ended, and the state switch cannot continue!");
763 return HC_ERR_UNSUPPORTED_OPCODE;
764 }
765 return IsoProtocolSwitchState(self, receviedMsg, returnSendMsg);
766 }
767
SetIsoPsk(BaseProtocol * self,const Uint8Buff * psk)768 static int32_t SetIsoPsk(BaseProtocol *self, const Uint8Buff *psk)
769 {
770 if ((self == NULL) || (psk == NULL) || (psk->val == NULL) || (psk->length == 0)) {
771 LOGE("invalid params.");
772 return HC_ERR_INVALID_PARAMS;
773 }
774 IsoProtocol *impl = (IsoProtocol *)self;
775 if (DeepCopyUint8Buff(psk, &impl->params.psk) != HC_SUCCESS) {
776 LOGE("copy psk fail.");
777 return HC_ERR_ALLOC_MEMORY;
778 }
779 LOGI("set psk success.");
780 return HC_SUCCESS;
781 }
782
SetIsoSelfProtectedMsg(BaseProtocol * self,const Uint8Buff * selfMsg)783 static int32_t SetIsoSelfProtectedMsg(BaseProtocol *self, const Uint8Buff *selfMsg)
784 {
785 if ((self == NULL) || !IsUint8BuffValid(selfMsg, PROTECTED_MSG_MAX_LEN)) {
786 LOGE("invalid params.");
787 return HC_ERR_INVALID_PARAMS;
788 }
789 if (DeepCopyUint8Buff(selfMsg, &self->protectedMsg.selfMsg) != HC_SUCCESS) {
790 LOGE("copy protected self msg fail.");
791 return HC_ERR_ALLOC_MEMORY;
792 }
793 return HC_SUCCESS;
794 }
795
SetIsoPeerProtectedMsg(BaseProtocol * self,const Uint8Buff * peerMsg)796 static int32_t SetIsoPeerProtectedMsg(BaseProtocol *self, const Uint8Buff *peerMsg)
797 {
798 if ((self == NULL) || !IsUint8BuffValid(peerMsg, PROTECTED_MSG_MAX_LEN)) {
799 LOGE("invalid params.");
800 return HC_ERR_INVALID_PARAMS;
801 }
802 if (DeepCopyUint8Buff(peerMsg, &self->protectedMsg.peerMsg) != HC_SUCCESS) {
803 LOGE("copy protected peer msg fail.");
804 return HC_ERR_ALLOC_MEMORY;
805 }
806 return HC_SUCCESS;
807 }
808
GetIsoSessionKey(BaseProtocol * self,Uint8Buff * returnSessionKey)809 static int32_t GetIsoSessionKey(BaseProtocol *self, Uint8Buff *returnSessionKey)
810 {
811 if ((self == NULL) || (returnSessionKey == NULL)) {
812 LOGE("invalid params.");
813 return HC_ERR_INVALID_PARAMS;
814 }
815 if (self->curState != self->finishState) {
816 LOGE("The protocol has not been completed, unable to obtain the protocol result!");
817 return HC_ERR_UNSUPPORTED_OPCODE;
818 }
819 return DeepCopyUint8Buff(&self->sessionKey, returnSessionKey);
820 }
821
DestroyIsoProtocol(BaseProtocol * self)822 static void DestroyIsoProtocol(BaseProtocol *self)
823 {
824 if (self == NULL) {
825 LOGD("self is null.");
826 return;
827 }
828 IsoProtocol *impl = (IsoProtocol *)self;
829 ClearFreeUint8Buff(&impl->base.protectedMsg.selfMsg);
830 ClearFreeUint8Buff(&impl->base.protectedMsg.peerMsg);
831 ClearFreeUint8Buff(&impl->base.sessionKey);
832 ClearFreeUint8Buff(&impl->params.psk);
833 ClearFreeUint8Buff(&impl->params.randSelf);
834 ClearFreeUint8Buff(&impl->params.randPeer);
835 ClearFreeUint8Buff(&impl->params.authIdSelf);
836 ClearFreeUint8Buff(&impl->params.authIdPeer);
837 ClearFreeUint8Buff(&impl->params.tokenSelf);
838 ClearFreeUint8Buff(&impl->params.tokenPeer);
839 ClearFreeUint8Buff(&impl->params.authResultMac);
840 HcFree(impl);
841 }
842
CreateIsoProtocol(const void * baseParams,bool isClient,BaseProtocol ** returnObj)843 int32_t CreateIsoProtocol(const void *baseParams, bool isClient, BaseProtocol **returnObj)
844 {
845 const IsoInitParams *params = (const IsoInitParams *)baseParams;
846 if ((params == NULL) || (returnObj == NULL) ||
847 !IsUint8BuffValid(¶ms->authId, ISO_AUTH_ID_MAX_LEN)) {
848 LOGE("invalid params.");
849 return HC_ERR_INVALID_PARAMS;
850 }
851 IsoProtocol *instance = (IsoProtocol *)HcMalloc(sizeof(IsoProtocol), 0);
852 if (instance == NULL) {
853 LOGE("allocate instance memory fail.");
854 return HC_ERR_ALLOC_MEMORY;
855 }
856 if (DeepCopyUint8Buff(¶ms->authId, &instance->params.authIdSelf) != HC_SUCCESS) {
857 HcFree(instance);
858 return HC_ERR_ALLOC_MEMORY;
859 }
860 instance->params.osAccountId = params->osAccountId;
861 instance->base.name = PROTOCOL_TYPE_ISO;
862 instance->base.beginState = isClient ? CREATE_AS_CLIENT_STATE : CREATE_AS_SERVER_STATE;
863 instance->base.finishState = isClient ? CLIENT_FINISH_STATE : SERVER_FINISH_STATE;
864 instance->base.failState = FAIL_STATE;
865 instance->base.curState = instance->base.beginState;
866 instance->base.start = StartIsoProtocol;
867 instance->base.process = ProcessIsoProtocol;
868 instance->base.setPsk = SetIsoPsk;
869 instance->base.setSelfProtectedMsg = SetIsoSelfProtectedMsg;
870 instance->base.setPeerProtectedMsg = SetIsoPeerProtectedMsg;
871 instance->base.getSessionKey = GetIsoSessionKey;
872 instance->base.destroy = DestroyIsoProtocol;
873 *returnObj = (BaseProtocol *)instance;
874 return HC_SUCCESS;
875 }
876