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, &params->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, &params->randPeer) != HC_SUCCESS) {
339         LOGE("copy randC fail.");
340         return HC_ERR_ALLOC_MEMORY;
341     }
342     if (DeepCopyUint8Buff(&authIdC, &params->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, &params->randPeer) != HC_SUCCESS) {
452         LOGE("copy randS fail.");
453         return HC_ERR_ALLOC_MEMORY;
454     }
455     if (DeepCopyUint8Buff(&authIdS, &params->authIdPeer) != HC_SUCCESS) {
456         LOGE("copy authIdS fail.");
457         return HC_ERR_ALLOC_MEMORY;
458     }
459     if (DeepCopyUint8Buff(&tokenS, &params->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, &params->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, &params->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(&params->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(&params->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