• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "iso_server_bind_exchange_task.h"
17 #include "das_task_common.h"
18 #include "das_module_defines.h"
19 #include "hc_log.h"
20 #include "hc_types.h"
21 #include "iso_protocol_common.h"
22 #include "iso_task_common.h"
23 #include "protocol_common.h"
24 
25 enum {
26     TASK_TYPE_BEGIN = 1,
27     TASK_TYPE_FINAL,
28 };
29 
GetTaskType(void)30 static CurTaskType GetTaskType(void)
31 {
32     return TASK_TYPE_BIND_LITE_EXCHANGE;
33 }
34 
DestroyServerBindExchangeTask(struct SymBaseCurTaskT * task)35 void DestroyServerBindExchangeTask(struct SymBaseCurTaskT *task)
36 {
37     HcFree(task);
38 }
39 
Process(struct SymBaseCurTaskT * task,IsoParams * params,const CJson * in,CJson * out,int32_t * status)40 static int Process(struct SymBaseCurTaskT *task, IsoParams *params, const CJson *in, CJson *out, int32_t *status)
41 {
42     IsoServerBindExchangeTask *realTask = (IsoServerBindExchangeTask *)task;
43     if (realTask->taskBase.taskStatus < TASK_TYPE_BEGIN) {
44         LOGE("task status failed");
45         return HC_ERR_BAD_MESSAGE;
46     }
47 
48     if (realTask->taskBase.taskStatus > TASK_TYPE_BEGIN) {
49         LOGI("The message is repeated, ignore it, status: %d", realTask->taskBase.taskStatus);
50         *status = IGNORE_MSG;
51         return HC_SUCCESS;
52     }
53     int res;
54     int32_t message = 0;
55     res = GetIntFromJson(in, FIELD_MESSAGE, &message);
56     if (res != 0 || message != ISO_CLIENT_BIND_EXCHANGE_CONFIRM) {
57         return HC_ERR_BAD_MESSAGE;
58     }
59     res = CheckEncResult(params, in, RESULT_AAD);
60     if (res != 0) {
61         LOGE("CheckEncResult failed, res:%d", res);
62         DeleteAuthCode(params);
63         return res;
64     }
65     res = SendResultToFinalSelf(params, out, false);
66     if (res != 0) {
67         LOGE("SendResultToFinalSelf failed, res:%d", res);
68         DeleteAuthCode(params);
69         return res;
70     }
71     realTask->taskBase.taskStatus = TASK_TYPE_FINAL;
72     *status = FINISH;
73     return res;
74 }
75 
DecryptChallenge(const IsoParams * params,const CJson * in,uint8_t * challenge,uint32_t challengeLen)76 static int DecryptChallenge(const IsoParams *params, const CJson *in, uint8_t *challenge, uint32_t challengeLen)
77 {
78     (void)challengeLen;
79     int res;
80     uint8_t *encData = NULL;
81     uint8_t *nonce = NULL;
82 
83     encData = (uint8_t *)HcMalloc(ENC_CHALLENGE_LEN, 0);
84     if (encData == NULL) {
85         res = HC_ERR_ALLOC_MEMORY;
86         goto ERR;
87     }
88     GOTO_ERR_AND_SET_RET(GetByteFromJson(in, FIELD_ENC_DATA, encData, ENC_CHALLENGE_LEN), res);
89     nonce = (uint8_t *)HcMalloc(NONCE_SIZE, 0);
90     if (nonce == NULL) {
91         res = HC_ERR_ALLOC_MEMORY;
92         goto ERR;
93     }
94     GOTO_ERR_AND_SET_RET(GetByteFromJson(in, FIELD_NONCE, nonce, NONCE_SIZE), res);
95     Uint8Buff encDataBuf = { encData, ENC_CHALLENGE_LEN };
96     GcmParam gcmParam;
97     gcmParam.aad = (uint8_t *)EXCHANGE_AAD;
98     gcmParam.aadLen = (uint32_t)strlen(EXCHANGE_AAD);
99     gcmParam.nonce = nonce;
100     gcmParam.nonceLen = NONCE_SIZE;
101     Uint8Buff challengeBuf = { challenge, CHALLENGE_SIZE };
102     res = params->baseParams.loader->aesGcmDecrypt(&params->baseParams.sessionKey, &encDataBuf, &gcmParam, false,
103         &challengeBuf);
104     if (res != 0) {
105         LOGE("decrypt challenge failed, res:%d", res);
106         goto ERR;
107     }
108 ERR:
109     HcFree(encData);
110     HcFree(nonce);
111     return res;
112 }
113 
GenAndEncAuthCode(const IsoParams * params,Uint8Buff * nonceBuf,const Uint8Buff * challengeBuf,Uint8Buff * encAuthCodeBuf)114 static int GenAndEncAuthCode(const IsoParams *params, Uint8Buff *nonceBuf, const Uint8Buff *challengeBuf,
115     Uint8Buff *encAuthCodeBuf)
116 {
117     int res;
118     uint8_t *keyAlias = NULL;
119     uint8_t *authCode = (uint8_t *)HcMalloc(AUTH_CODE_LEN, 0);
120     if (authCode == NULL) {
121         res = HC_ERR_ALLOC_MEMORY;
122         goto ERR;
123     }
124     Uint8Buff authCodeBuf = { authCode, AUTH_CODE_LEN };
125     res = params->baseParams.loader->generateRandom(&authCodeBuf);
126     if (res != 0) {
127         LOGE("generate auth code failed, res:%d", res);
128         goto ERR;
129     }
130 
131     res = params->baseParams.loader->generateRandom(nonceBuf);
132     if (res != 0) {
133         LOGE("generate nonce failed, res:%d", res);
134         goto ERR;
135     }
136     GcmParam gcmParam = { nonceBuf->val, nonceBuf->length, challengeBuf->val, challengeBuf->length };
137     res = params->baseParams.loader->aesGcmEncrypt(&params->baseParams.sessionKey, &authCodeBuf, &gcmParam, false,
138         encAuthCodeBuf);
139     if (res != 0) {
140         LOGE("encrypt auth code failed, res:%d", res);
141         goto ERR;
142     }
143 
144     keyAlias = (uint8_t *)HcMalloc(ISO_KEY_ALIAS_LEN, 0);
145     if (keyAlias == NULL) {
146         res = HC_ERR_ALLOC_MEMORY;
147         goto ERR;
148     }
149     res = GenerateKeyAliasInIso(params, keyAlias, ISO_KEY_ALIAS_LEN, true);
150     if (res != 0) {
151         LOGE("GenerateKeyAliasInIso failed, res:%d", res);
152         goto ERR;
153     }
154 
155     LOGI("AuthCode alias: %x%x%x%x****.", keyAlias[0], keyAlias[1], keyAlias[2], keyAlias[3]);
156     Uint8Buff keyAliasBuf = { keyAlias, ISO_KEY_ALIAS_LEN };
157     ExtraInfo exInfo = { { params->baseParams.authIdPeer.val, params->baseParams.authIdPeer.length },
158         params->peerUserType, PAIR_TYPE_BIND };
159     res = params->baseParams.loader->importSymmetricKey(&keyAliasBuf, &authCodeBuf, KEY_PURPOSE_MAC, &exInfo);
160     if (res != 0) {
161         LOGE("ImportSymmetricKey failed, res: %x.", res);
162         goto ERR;
163     }
164 ERR:
165     HcFree(keyAlias);
166     FreeAndCleanKey(&authCodeBuf);
167     return res;
168 }
169 
GenerateAuthCodeAndImport(const IsoParams * params,CJson * out,uint8_t * challenge,uint32_t challengeLen)170 static int GenerateAuthCodeAndImport(const IsoParams *params, CJson *out, uint8_t *challenge, uint32_t challengeLen)
171 {
172     int res;
173     uint8_t *nonce = NULL;
174     uint8_t *encAuthCode = NULL;
175     CJson *payload = NULL;
176     CJson *sendToPeer = NULL;
177 
178     nonce = (uint8_t *)HcMalloc(NONCE_SIZE, 0);
179     if (nonce == NULL) {
180         res = HC_ERR_ALLOC_MEMORY;
181         goto ERR;
182     }
183     encAuthCode = (uint8_t *)HcMalloc(AUTH_CODE_LEN + TAG_LEN, 0);
184     if (encAuthCode == NULL) {
185         res = HC_ERR_ALLOC_MEMORY;
186         goto ERR;
187     }
188     Uint8Buff encAuthCodeBuf = { encAuthCode, AUTH_CODE_LEN + TAG_LEN };
189     Uint8Buff nonceBuf = { nonce, NONCE_SIZE };
190     Uint8Buff challengeBuf = { challenge, challengeLen };
191 
192     res = GenAndEncAuthCode(params, &nonceBuf, &challengeBuf, &encAuthCodeBuf);
193     if (res != 0) {
194         LOGE("GenAndEncAuthCode failed, res:%d", res);
195         goto ERR;
196     }
197     payload = CreateJson();
198     if (payload == NULL) {
199         res = HC_ERR_ALLOC_MEMORY;
200         goto ERR;
201     }
202     sendToPeer = CreateJson();
203     if (sendToPeer == NULL) {
204         res = HC_ERR_ALLOC_MEMORY;
205         goto ERR;
206     }
207     GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_MESSAGE, ISO_SERVER_BIND_EXCHANGE_RET), res);
208     GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_ENC_AUTH_TOKEN, encAuthCodeBuf.val, encAuthCodeBuf.length), res);
209     GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_NONCE, nonceBuf.val, nonceBuf.length), res);
210     GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_PAYLOAD, payload), res);
211     GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), res);
212 
213 ERR:
214     HcFree(nonce);
215     HcFree(encAuthCode);
216     FreeJson(payload);
217     FreeJson(sendToPeer);
218     return res;
219 }
220 
ServerBindExchangeStart(const IsoParams * params,IsoServerBindExchangeTask * task,const CJson * in,CJson * out,int32_t * status)221 static int ServerBindExchangeStart(const IsoParams *params, IsoServerBindExchangeTask *task,
222     const CJson *in, CJson *out, int32_t *status)
223 {
224     int res;
225     uint8_t *challenge = (uint8_t *)HcMalloc(CHALLENGE_SIZE, 0);
226     if (challenge == NULL) {
227         res = HC_ERR_ALLOC_MEMORY;
228         goto ERR;
229     }
230     res = DecryptChallenge(params, in, challenge, CHALLENGE_SIZE);
231     if (res != 0) {
232         LOGE("decrypt challenge failed, res:%d", res);
233         goto ERR;
234     }
235     res = GenerateAuthCodeAndImport(params, out, challenge, CHALLENGE_SIZE);
236     if (res != 0) {
237         LOGE("GenerateAuthCodeAndImport failed, res:%d", res);
238         goto ERR;
239     }
240     task->taskBase.taskStatus = TASK_TYPE_BEGIN;
241     *status = CONTINUE;
242 ERR:
243     HcFree(challenge);
244     return res;
245 }
246 
CreateServerBindExchangeTask(IsoParams * params,const CJson * in,CJson * out,int32_t * status)247 SymBaseCurTask *CreateServerBindExchangeTask(IsoParams *params, const CJson *in, CJson *out, int32_t *status)
248 {
249     IsoServerBindExchangeTask *task = (IsoServerBindExchangeTask *)HcMalloc(sizeof(IsoServerBindExchangeTask), 0);
250     if (task == NULL) {
251         return NULL;
252     }
253     task->taskBase.destroyTask = DestroyServerBindExchangeTask;
254     task->taskBase.process = Process;
255     task->taskBase.getCurTaskType = GetTaskType;
256     int res = ServerBindExchangeStart(params, task, in, out, status);
257     if (res != 0) {
258         DestroyServerBindExchangeTask((struct SymBaseCurTaskT *)task);
259         return NULL;
260     }
261     return (SymBaseCurTask *)task;
262 }
263