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 "common_standard_unbind_exchange.h"
17 #include "das_task_common.h"
18 #include "hc_log.h"
19 #include "hc_types.h"
20 #include "protocol_common.h"
21 #include "securec.h"
22
InitStandardUnbindExchangeParams(StandardUnbindExchangeParams * params)23 int32_t InitStandardUnbindExchangeParams(StandardUnbindExchangeParams *params)
24 {
25 if (params == NULL) {
26 return HC_ERR_INVALID_PARAMS;
27 }
28
29 int32_t res;
30
31 params->nonce.length = STANDARD_UNBIND_EXCHANGE_NONCE_LEN;
32 params->nonce.val = (uint8_t *)HcMalloc(params->nonce.length, 0);
33 if (params->nonce.val == NULL) {
34 res = HC_ERR_ALLOC_MEMORY;
35 goto ERR;
36 }
37
38 params->rmvInfo.length = 0;
39 params->rmvInfo.val = NULL;
40 params->exRmvCipher.length = 0;
41 params->exRmvCipher.val = NULL;
42 params->resultCipher.length = 0;
43 params->resultCipher.val = NULL;
44
45 return HC_SUCCESS;
46 ERR:
47 DestroyStandardUnbindExchangeParams(params);
48 return res;
49 }
50
DestroyStandardUnbindExchangeParams(StandardUnbindExchangeParams * params)51 void DestroyStandardUnbindExchangeParams(StandardUnbindExchangeParams *params)
52 {
53 if (params == NULL) {
54 return;
55 }
56 if (params->rmvInfo.val != NULL) {
57 HcFree(params->rmvInfo.val);
58 params->rmvInfo.val = NULL;
59 }
60 if (params->exRmvCipher.val != NULL) {
61 HcFree(params->exRmvCipher.val);
62 params->exRmvCipher.val = NULL;
63 }
64 if (params->resultCipher.val != NULL) {
65 HcFree(params->resultCipher.val);
66 params->resultCipher.val = NULL;
67 }
68 if (params->nonce.val != NULL) {
69 HcFree(params->nonce.val);
70 params->nonce.val = NULL;
71 }
72 }
73
PackageRmvInfo(const PakeParams * pakeParams,StandardUnbindExchangeParams * exchangeParams)74 static int32_t PackageRmvInfo(const PakeParams *pakeParams, StandardUnbindExchangeParams *exchangeParams)
75 {
76 int32_t res = HC_SUCCESS;
77 CJson *rmvInfoJson = CreateJson();
78 char *rmvInfoStr = NULL;
79 GOTO_ERR_AND_SET_RET(AddByteToJson(rmvInfoJson, FIELD_RMV_ID, pakeParams->baseParams.idSelf.val,
80 pakeParams->baseParams.idSelf.length), res);
81 GOTO_ERR_AND_SET_RET(AddIntToJson(rmvInfoJson, FIELD_RMV_TYPE, pakeParams->userType), res);
82 rmvInfoStr = PackJsonToString(rmvInfoJson);
83 if (rmvInfoStr == NULL) {
84 LOGE("rmvInfoStr PackJsonToString failed");
85 res = HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
86 goto ERR;
87 }
88
89 res = InitSingleParam(&exchangeParams->rmvInfo, strlen(rmvInfoStr));
90 if (res != HC_SUCCESS) {
91 LOGE("InitSingleParam rmvInfo failed.");
92 goto ERR;
93 }
94
95 if (memcpy_s(exchangeParams->rmvInfo.val, exchangeParams->rmvInfo.length, rmvInfoStr, strlen(rmvInfoStr)) != EOK) {
96 LOGE("Memcpy rmvInfo failed.");
97 res = HC_ERR_MEMORY_COPY;
98 goto ERR;
99 }
100 ERR:
101 FreeJson(rmvInfoJson);
102 FreeJsonString(rmvInfoStr);
103 return res;
104 }
105
EncryptRmvInfo(const PakeParams * pakeParams,StandardUnbindExchangeParams * exchangeParams)106 static int32_t EncryptRmvInfo(const PakeParams *pakeParams, StandardUnbindExchangeParams *exchangeParams)
107 {
108 int32_t res = InitSingleParam(&(exchangeParams->exRmvCipher), exchangeParams->rmvInfo.length + AE_TAG_LEN);
109 if (res != HC_SUCCESS) {
110 LOGE("InitRmvInfoCipher failed");
111 return res;
112 }
113
114 // encrypt
115 res = pakeParams->baseParams.loader->generateRandom(&(exchangeParams->nonce));
116 if (res != HC_SUCCESS) {
117 LOGE("generateRandom failed");
118 return res;
119 }
120
121 GcmParam encryptInfo = {
122 .aad = (uint8_t *)HICHAIN_REMOVE_INFO_REQUEST,
123 .aadLen = strlen(HICHAIN_REMOVE_INFO_REQUEST),
124 .nonce = exchangeParams->nonce.val,
125 .nonceLen = exchangeParams->nonce.length
126 };
127 res = pakeParams->baseParams.loader->aesGcmEncrypt(&(pakeParams->baseParams.sessionKey), &(exchangeParams->rmvInfo),
128 &encryptInfo, false, &(exchangeParams->exRmvCipher));
129 if (res != HC_SUCCESS) {
130 LOGE("aesGcmEncrypt failed");
131 return res;
132 }
133
134 return HC_SUCCESS;
135 }
136
DecryptRmvInfo(PakeParams * pakeParams,StandardUnbindExchangeParams * exchangeParams)137 static int32_t DecryptRmvInfo(PakeParams *pakeParams, StandardUnbindExchangeParams *exchangeParams)
138 {
139 int32_t res = InitSingleParam(&exchangeParams->rmvInfo, exchangeParams->exRmvCipher.length - AE_TAG_LEN);
140 if (res != HC_SUCCESS) {
141 LOGE("InitSingleParam rmvInfo failed.");
142 return res;
143 }
144
145 GcmParam decryptInfo = {
146 .aad = (uint8_t *)HICHAIN_REMOVE_INFO_REQUEST,
147 .aadLen = strlen(HICHAIN_REMOVE_INFO_REQUEST),
148 .nonce = exchangeParams->nonce.val,
149 .nonceLen = exchangeParams->nonce.length
150 };
151
152 res = pakeParams->baseParams.loader->aesGcmDecrypt(&(pakeParams->baseParams.sessionKey),
153 &(exchangeParams->exRmvCipher), &decryptInfo, false, &(exchangeParams->rmvInfo));
154 if (res != HC_SUCCESS) {
155 LOGE("aesGcmDecrypt failed");
156 return res;
157 }
158
159 return res;
160 }
161
ParseRmvInfo(PakeParams * pakeParams,StandardUnbindExchangeParams * exchangeParams)162 static int32_t ParseRmvInfo(PakeParams *pakeParams, StandardUnbindExchangeParams *exchangeParams)
163 {
164 int32_t res;
165 CJson *rmvInfoJson = CreateJsonFromString((char *)exchangeParams->rmvInfo.val);
166 if (rmvInfoJson == NULL) {
167 LOGE("Create rmvInfoJson failed.");
168 return HC_ERR_JSON_CREATE;
169 }
170 GOTO_ERR_AND_SET_RET(GetIntFromJson(rmvInfoJson, FIELD_RMV_TYPE, &(pakeParams->userTypePeer)), res);
171 res = GetIdPeer(rmvInfoJson, FIELD_RMV_ID, &pakeParams->baseParams.idSelf, &pakeParams->baseParams.idPeer);
172 if (res != HC_SUCCESS) {
173 LOGE("GetIdPeer failed, res: %d.", res);
174 goto ERR;
175 }
176 ERR:
177 FreeJson(rmvInfoJson);
178 return res;
179 }
180
DeleteAuthInfo(PakeParams * pakeParams)181 static int32_t DeleteAuthInfo(PakeParams *pakeParams)
182 {
183 uint8_t keyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
184 Uint8Buff keyAlias = { keyAliasVal, PAKE_KEY_ALIAS_LEN };
185 KeyAliasType keyType = pakeParams->userTypePeer;
186 Uint8Buff packageName = { (uint8_t *)pakeParams->packageName, strlen(pakeParams->packageName) };
187 Uint8Buff serviceType = { (uint8_t *)pakeParams->serviceType, strlen(pakeParams->serviceType) };
188 int32_t res = GenerateKeyAlias(&packageName, &serviceType, keyType, &(pakeParams->baseParams.idPeer), &keyAlias);
189 if (res != HC_SUCCESS) {
190 LOGE("generate pubKey alias failed");
191 return res;
192 }
193 LOGI("PubKey alias: %x%x%x%x****.", keyAliasVal[0], keyAliasVal[1], keyAliasVal[2], keyAliasVal[3]);
194 res = pakeParams->baseParams.loader->deleteKey(&keyAlias);
195 if (res != HC_SUCCESS) {
196 LOGE("deleteKey failed");
197 return res;
198 }
199 LOGI("delete peer pubKey success.");
200 res = GenerateKeyAlias(&packageName, &serviceType, KEY_ALIAS_PSK, &(pakeParams->baseParams.idPeer),
201 &keyAlias);
202 if (res != HC_SUCCESS) {
203 LOGE("generate pskKey alias failed");
204 return res;
205 }
206 LOGI("Psk alias: %x%x%x%x****.", keyAliasVal[0], keyAliasVal[1], keyAliasVal[2], keyAliasVal[3]);
207 res = pakeParams->baseParams.loader->deleteKey(&keyAlias);
208 if (res != HC_SUCCESS) {
209 LOGE("delete pskKey failed");
210 return res;
211 }
212 LOGI("delete pskKey success.");
213 return HC_SUCCESS;
214 }
215
BuildRmvResult(PakeParams * pakeParams,StandardUnbindExchangeParams * exchangeParams)216 static int32_t BuildRmvResult(PakeParams *pakeParams, StandardUnbindExchangeParams *exchangeParams)
217 {
218 uint8_t resultVal[sizeof(int32_t)] = { 0 };
219 Uint8Buff result = { resultVal, sizeof(int32_t) };
220 int32_t res = InitSingleParam(&(exchangeParams->resultCipher), result.length + AE_TAG_LEN);
221 if (res != HC_SUCCESS) {
222 LOGE("InitResultInfoCipher failed");
223 return res;
224 }
225
226 // encrypt
227 res = pakeParams->baseParams.loader->generateRandom(&(exchangeParams->nonce));
228 if (res != HC_SUCCESS) {
229 LOGE("generateRandom failed");
230 return res;
231 }
232
233 GcmParam encryptInfo = {
234 .aad = (uint8_t *)HICHAIN_REMOVE_INFO_RESPONSE,
235 .aadLen = strlen(HICHAIN_REMOVE_INFO_RESPONSE),
236 .nonce = exchangeParams->nonce.val,
237 .nonceLen = exchangeParams->nonce.length
238 };
239
240 res = pakeParams->baseParams.loader->aesGcmEncrypt(&(pakeParams->baseParams.sessionKey),
241 &result, &encryptInfo, false, &(exchangeParams->resultCipher));
242 if (res != HC_SUCCESS) {
243 LOGE("aesGcmEncrypt failed");
244 return res;
245 }
246
247 return HC_SUCCESS;
248 }
249
ConfirmRmvResult(PakeParams * pakeParams,StandardUnbindExchangeParams * exchangeParams)250 static int32_t ConfirmRmvResult(PakeParams *pakeParams, StandardUnbindExchangeParams *exchangeParams)
251 {
252 uint8_t resultVal[sizeof(int32_t)] = { 0 };
253 Uint8Buff result = { resultVal, sizeof(int32_t) };
254
255 // decrypt
256 GcmParam decryptInfo = {
257 .aad = (uint8_t *)HICHAIN_REMOVE_INFO_RESPONSE,
258 .aadLen = strlen(HICHAIN_REMOVE_INFO_RESPONSE),
259 .nonce = exchangeParams->nonce.val,
260 .nonceLen = exchangeParams->nonce.length
261 };
262
263 int32_t res = pakeParams->baseParams.loader->aesGcmDecrypt(&(pakeParams->baseParams.sessionKey),
264 &(exchangeParams->resultCipher), &decryptInfo, false, &result);
265 if (res != HC_SUCCESS) {
266 LOGE("aesGcmDecrypt failed");
267 return res;
268 }
269
270 uint8_t resultSuccess[sizeof(int32_t)] = { 0 };
271 if (memcmp(result.val, resultSuccess, sizeof(int32_t)) != 0) {
272 LOGE("RemoveAuthStartRequest failed, ret: %d", res);
273 int32_t *resultTmp = (int32_t *)result.val;
274 return *resultTmp;
275 }
276
277 return HC_SUCCESS;
278 }
279
ClientRequestStandardUnbindExchange(const PakeParams * pakeParams,StandardUnbindExchangeParams * exchangeParams)280 int32_t ClientRequestStandardUnbindExchange(const PakeParams *pakeParams, StandardUnbindExchangeParams *exchangeParams)
281 {
282 int32_t res = PackageRmvInfo(pakeParams, exchangeParams);
283 if (res != HC_SUCCESS) {
284 LOGE("PackageRmvInfo failed");
285 return res;
286 }
287
288 res = EncryptRmvInfo(pakeParams, exchangeParams);
289 if (res != HC_SUCCESS) {
290 LOGE("EncryptRmvInfo failed");
291 return res;
292 }
293
294 return res;
295 }
296
ServerResponseStandardUnbindExchange(PakeParams * pakeParams,StandardUnbindExchangeParams * exchangeParams)297 int32_t ServerResponseStandardUnbindExchange(PakeParams *pakeParams, StandardUnbindExchangeParams *exchangeParams)
298 {
299 int32_t res = DecryptRmvInfo(pakeParams, exchangeParams);
300 if (res != HC_SUCCESS) {
301 LOGE("DecryptRmvInfo failed");
302 return res;
303 }
304
305 res = ParseRmvInfo(pakeParams, exchangeParams);
306 if (res != HC_SUCCESS) {
307 LOGE("ParseRmvInfo failed");
308 return res;
309 }
310
311 res = DeleteAuthInfo(pakeParams);
312 if (res != HC_SUCCESS) {
313 LOGE("DeleteAuthInfo failed");
314 return res;
315 }
316
317 res = BuildRmvResult(pakeParams, exchangeParams);
318 if (res != HC_SUCCESS) {
319 LOGE("BuildRmvResult failed");
320 return res;
321 }
322
323 return HC_SUCCESS;
324 }
325
ClientConfirmStandardUnbindExchange(PakeParams * pakeParams,StandardUnbindExchangeParams * exchangeParams)326 int32_t ClientConfirmStandardUnbindExchange(PakeParams *pakeParams, StandardUnbindExchangeParams *exchangeParams)
327 {
328 int32_t res = ConfirmRmvResult(pakeParams, exchangeParams);
329 if (res != HC_SUCCESS) {
330 LOGE("ConfirmRmvResult failed");
331 return res;
332 }
333
334 res = DeleteAuthInfo(pakeParams);
335 if (res != HC_SUCCESS) {
336 LOGE("DeleteAuthInfo failed");
337 return res;
338 }
339
340 return HC_SUCCESS;
341 }