• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &params->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, &params->randPeer) != HC_SUCCESS) {
338         LOGE("copy randC fail.");
339         return HC_ERR_ALLOC_MEMORY;
340     }
341     if (DeepCopyUint8Buff(&authIdC, &params->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, &params->randPeer) != HC_SUCCESS) {
451         LOGE("copy randS fail.");
452         return HC_ERR_ALLOC_MEMORY;
453     }
454     if (DeepCopyUint8Buff(&authIdS, &params->authIdPeer) != HC_SUCCESS) {
455         LOGE("copy authIdS fail.");
456         return HC_ERR_ALLOC_MEMORY;
457     }
458     if (DeepCopyUint8Buff(&tokenS, &params->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, &params->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, &params->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(&params->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(&params->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