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