• 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_protocol_common.h"
17 #include "alg_loader.h"
18 #include "device_auth_defines.h"
19 #include "hc_log.h"
20 #include "hc_types.h"
21 #include "protocol_common.h"
22 
InitIsoBaseParams(IsoBaseParams * params)23 int32_t InitIsoBaseParams(IsoBaseParams *params)
24 {
25     if (params == NULL) {
26         LOGE("Params is null.");
27         return HC_ERR_NULL_PTR;
28     }
29 
30     int32_t res;
31     params->randSelf.length = RAND_BYTE_LEN;
32     params->randSelf.val = (uint8_t *)HcMalloc(params->randSelf.length, 0);
33     if (params->randSelf.val == NULL) {
34         LOGE("Malloc randSelf failed.");
35         res = HC_ERR_ALLOC_MEMORY;
36         goto CLEAN_UP;
37     }
38     params->randPeer.length = RAND_BYTE_LEN;
39     params->randPeer.val = (uint8_t *)HcMalloc(params->randPeer.length, 0);
40     if (params->randPeer.val == NULL) {
41         LOGE("Malloc randPeer failed.");
42         res = HC_ERR_ALLOC_MEMORY;
43         goto CLEAN_UP;
44     }
45 
46     params->sessionKey.length = ISO_SESSION_KEY_LEN;
47     params->sessionKey.val = (uint8_t *)HcMalloc(params->sessionKey.length, 0);
48     if (params->sessionKey.val == NULL) {
49         LOGE("Malloc sessionKey failed.");
50         res = HC_ERR_ALLOC_MEMORY;
51         goto CLEAN_UP;
52     }
53 
54     params->loader = GetLoaderInstance();
55     if (params->loader == NULL) {
56         res = HC_ERROR;
57         goto CLEAN_UP;
58     }
59 
60     return HC_SUCCESS;
61 CLEAN_UP:
62     DestroyIsoBaseParams(params);
63     return res;
64 }
65 
DestroyIsoBaseParams(IsoBaseParams * params)66 void DestroyIsoBaseParams(IsoBaseParams *params)
67 {
68     if (params == NULL) {
69         return;
70     }
71 
72     FreeAndCleanKey(&params->sessionKey);
73     (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
74 
75     HcFree(params->randSelf.val);
76     params->randSelf.val = NULL;
77 
78     HcFree(params->randPeer.val);
79     params->randPeer.val = NULL;
80 
81     HcFree(params->authIdSelf.val);
82     params->authIdSelf.val = NULL;
83 
84     HcFree(params->authIdPeer.val);
85     params->authIdPeer.val = NULL;
86 }
87 
IsoCalSelfToken(const IsoBaseParams * params,Uint8Buff * outHmac)88 static int IsoCalSelfToken(const IsoBaseParams *params, Uint8Buff *outHmac)
89 {
90     int res;
91     int length = params->randSelf.length + params->randPeer.length + params->authIdSelf.length +
92         params->authIdPeer.length;
93     uint8_t *messagePeer = (uint8_t *)HcMalloc(length, 0);
94     if (messagePeer == NULL) {
95         LOGE("Malloc for messagePeer failed.");
96         return HC_ERR_ALLOC_MEMORY;
97     }
98     int usedLen = 0;
99     if (memcpy_s(messagePeer, length, params->randPeer.val, params->randPeer.length) != EOK) {
100         LOGE("Memcpy randPeer failed.");
101         res = HC_ERR_MEMORY_COPY;
102         goto CLEAN_UP;
103     }
104     usedLen += params->randPeer.length;
105     if (memcpy_s(messagePeer + usedLen, length - usedLen, params->randSelf.val, params->randSelf.length) != EOK) {
106         LOGE("Memcpy randSelf failed.");
107         res = HC_ERR_MEMORY_COPY;
108         goto CLEAN_UP;
109     }
110     usedLen += params->randSelf.length;
111     if (memcpy_s(messagePeer + usedLen, length - usedLen, params->authIdSelf.val, params->authIdSelf.length) != EOK) {
112         LOGE("Memcpy authIdSelf failed.");
113         res = HC_ERR_MEMORY_COPY;
114         goto CLEAN_UP;
115     }
116     usedLen += params->authIdSelf.length;
117     if (memcpy_s(messagePeer + usedLen, length - usedLen, params->authIdPeer.val, params->authIdPeer.length) != EOK) {
118         LOGE("Memcpy authIdPeer failed.");
119         res = HC_ERR_MEMORY_COPY;
120         goto CLEAN_UP;
121     }
122     Uint8Buff messageBuf = { messagePeer, length };
123     Uint8Buff pskBuf = { (uint8_t *)params->psk, sizeof(params->psk) };
124     res = params->loader->computeHmac(&pskBuf, &messageBuf, outHmac, false);
125     if (res != HC_SUCCESS) {
126         LOGE("ComputeHmac failed, res: %x.", res);
127         goto CLEAN_UP;
128     }
129 CLEAN_UP:
130     HcFree(messagePeer);
131     return res;
132 }
133 
IsoCalPeerToken(const IsoBaseParams * params,Uint8Buff * selfToken)134 static int IsoCalPeerToken(const IsoBaseParams *params, Uint8Buff *selfToken)
135 {
136     int length = params->randSelf.length + params->randPeer.length + params->authIdPeer.length +
137         params->authIdSelf.length;
138     uint8_t *messageSelf = (uint8_t *)HcMalloc(length, 0);
139     if (messageSelf == NULL) {
140         LOGE("Malloc for messageSelf failed.");
141         return HC_ERR_ALLOC_MEMORY;
142     }
143     int res;
144     int usedLen = 0;
145     if (memcpy_s(messageSelf, length, params->randSelf.val, params->randSelf.length) != EOK) {
146         LOGE("Memcpy randSelf failed.");
147         res = HC_ERR_MEMORY_COPY;
148         goto CLEAN_UP;
149     }
150     usedLen += params->randSelf.length;
151     if (memcpy_s(messageSelf + usedLen, length - usedLen, params->randPeer.val, params->randPeer.length) != EOK) {
152         LOGE("Memcpy randPeer failed.");
153         res = HC_ERR_MEMORY_COPY;
154         goto CLEAN_UP;
155     }
156     usedLen += params->randPeer.length;
157     if (memcpy_s(messageSelf + usedLen, length - usedLen, params->authIdPeer.val, params->authIdPeer.length) != EOK) {
158         LOGE("Memcpy authIdPeer failed.");
159         res = HC_ERR_MEMORY_COPY;
160         goto CLEAN_UP;
161     }
162     usedLen += params->authIdPeer.length;
163     if (memcpy_s(messageSelf + usedLen, length - usedLen, params->authIdSelf.val, params->authIdSelf.length) != EOK) {
164         LOGE("Memcpy authIdSelf failed.");
165         res = HC_ERR_MEMORY_COPY;
166         goto CLEAN_UP;
167     }
168     Uint8Buff messageBufSelf = { messageSelf, length };
169     Uint8Buff pskBuf = { (uint8_t *)params->psk, sizeof(params->psk) };
170     res = params->loader->computeHmac(&pskBuf, &messageBufSelf, selfToken, false);
171     if (res != HC_SUCCESS) {
172         LOGE("ComputeHmac for selfToken failed, res: %x.", res);
173         goto CLEAN_UP;
174     }
175 CLEAN_UP:
176     HcFree(messageSelf);
177     return res;
178 }
179 
IsoCombineHkdfSalt(IsoBaseParams * params,Uint8Buff * hkdfSaltBuf,bool isClient)180 static int IsoCombineHkdfSalt(IsoBaseParams *params, Uint8Buff *hkdfSaltBuf, bool isClient)
181 {
182     if (isClient) {
183         if (memcpy_s(hkdfSaltBuf->val, hkdfSaltBuf->length, params->randSelf.val, params->randSelf.length) != EOK) {
184             LOGE("Memcpy randSelf failed.");
185             return HC_ERR_MEMORY_COPY;
186         }
187         if (memcpy_s(hkdfSaltBuf->val + params->randSelf.length, hkdfSaltBuf->length - params->randSelf.length,
188             params->randPeer.val, params->randPeer.length) != EOK) {
189             LOGE("Memcpy randPeer failed.");
190             return HC_ERR_MEMORY_COPY;
191         }
192     } else {
193         if (memcpy_s(hkdfSaltBuf->val, hkdfSaltBuf->length, params->randPeer.val, params->randPeer.length) != EOK) {
194             LOGE("Memcpy randPeer failed.");
195             return HC_ERR_MEMORY_COPY;
196         }
197         if (memcpy_s(hkdfSaltBuf->val + params->randPeer.length, hkdfSaltBuf->length - params->randPeer.length,
198             params->randSelf.val, params->randSelf.length) != EOK) {
199             LOGE("Memcpy randSelf failed.");
200             return HC_ERR_MEMORY_COPY;
201         }
202     }
203     return HC_SUCCESS;
204 }
205 
IsoGenSessionKey(IsoBaseParams * params,Uint8Buff * pskBuf,bool isClient)206 static int IsoGenSessionKey(IsoBaseParams *params, Uint8Buff *pskBuf, bool isClient)
207 {
208     int hkdfSaltLen = params->randPeer.length + params->randSelf.length;
209     uint8_t *hkdfSalt = (uint8_t *)HcMalloc(hkdfSaltLen, 0);
210     if (hkdfSalt == NULL) {
211         LOGE("Malloc for hkdfSalt failed.");
212         return HC_ERR_ALLOC_MEMORY;
213     }
214     Uint8Buff hkdfSaltBuf = { hkdfSalt, hkdfSaltLen };
215     int res = IsoCombineHkdfSalt(params, &hkdfSaltBuf, isClient);
216     if (res != HC_SUCCESS) {
217         LOGE("IsoCombineHkdfSalt failed, res: %x.", res);
218         HcFree(hkdfSalt);
219         return res;
220     }
221 
222     Uint8Buff keyInfoBuf = { (uint8_t *)GENERATE_SESSION_KEY_STR, HcStrlen(GENERATE_SESSION_KEY_STR) };
223     res = params->loader->computeHkdf(pskBuf, &hkdfSaltBuf, &keyInfoBuf, &params->sessionKey, false);
224     if (res != HC_SUCCESS) {
225         LOGE("ComputeHkdf for sessionKey failed, res: %x.", res);
226         FreeAndCleanKey(&params->sessionKey);
227     }
228     HcFree(hkdfSalt);
229     return res;
230 }
231 
IsoClientGenRandom(IsoBaseParams * params)232 int IsoClientGenRandom(IsoBaseParams *params)
233 {
234     if (params == NULL) {
235         LOGE("Params is null.");
236         return HC_ERR_NULL_PTR;
237     }
238     int32_t res = params->loader->generateRandom(&params->randSelf);
239     if (res != HC_SUCCESS) {
240         LOGE("Generate randSelf failed, res: %x.", res);
241         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
242     }
243     return res;
244 }
245 
IsoClientCheckAndGenToken(IsoBaseParams * params,const Uint8Buff * peerToken,Uint8Buff * selfToken)246 int IsoClientCheckAndGenToken(IsoBaseParams *params, const Uint8Buff *peerToken, Uint8Buff *selfToken)
247 {
248     if (params == NULL) {
249         LOGE("Params is null.");
250         return HC_ERR_NULL_PTR;
251     }
252     if (peerToken == NULL || selfToken == NULL) {
253         LOGE("Params is null.");
254         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
255         return HC_ERR_NULL_PTR;
256     }
257 
258     uint8_t hmacPeer[SHA256_LEN] = { 0 };
259     Uint8Buff outHmac = { hmacPeer, sizeof(hmacPeer) };
260     int res = IsoCalSelfToken(params, &outHmac);
261     if (res != HC_SUCCESS) {
262         LOGE("IsoCalSelfToken failed, res: %x.", res);
263         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
264         return res;
265     }
266     if (memcmp(peerToken->val, outHmac.val, outHmac.length) != 0) {
267         LOGE("Compare hmac token failed.");
268         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
269         return HC_ERR_PROOF_NOT_MATCH;
270     }
271     res = IsoCalPeerToken(params, selfToken);
272     if (res != HC_SUCCESS) {
273         LOGE("IsoCalPeerToken failed, res: %x.", res);
274         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
275     }
276     return res;
277 }
278 
IsoClientGenSessionKey(IsoBaseParams * params,int returnResult,const uint8_t * hmac,uint32_t hmacLen)279 int IsoClientGenSessionKey(IsoBaseParams *params, int returnResult, const uint8_t *hmac, uint32_t hmacLen)
280 {
281     if (params == NULL) {
282         LOGE("Params is null.");
283         return HC_ERR_NULL_PTR;
284     }
285     if (hmac == NULL) {
286         LOGE("Params is null.");
287         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
288         return HC_ERR_NULL_PTR;
289     }
290 
291     Uint8Buff pskBuf = { params->psk, sizeof(params->psk) };
292     Uint8Buff hmacMessage = { (uint8_t *)&returnResult, sizeof(int) };
293     uint8_t hmacSelf[SHA256_LEN] = { 0 };
294     Uint8Buff outHmacBuf = { hmacSelf, sizeof(hmacSelf) };
295     int res = params->loader->computeHmac(&pskBuf, &hmacMessage, &outHmacBuf, false);
296     if (res != HC_SUCCESS) {
297         LOGE("ComputeHmac for returnResult failed, res: %x.", res);
298         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
299         return res;
300     }
301     if (memcmp(outHmacBuf.val, hmac, hmacLen) != 0) {
302         LOGE("Compare hmac result failed.");
303         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
304         return HC_ERR_PROOF_NOT_MATCH;
305     }
306 
307     res = IsoGenSessionKey(params, &pskBuf, true);
308     if (res != HC_SUCCESS) {
309         LOGE("IsoGenSessionKey failed, res: %x.", res);
310         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
311     }
312 
313     return res;
314 }
315 
IsoServerGenRandomAndToken(IsoBaseParams * params,Uint8Buff * selfTokenBuf)316 int IsoServerGenRandomAndToken(IsoBaseParams *params, Uint8Buff *selfTokenBuf)
317 {
318     if (params == NULL) {
319         LOGE("Params is null.");
320         return HC_ERR_NULL_PTR;
321     }
322     if (selfTokenBuf == NULL) {
323         LOGE("Params is null.");
324         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
325         return HC_ERR_NULL_PTR;
326     }
327     int res = params->loader->generateRandom(&params->randSelf);
328     if (res != HC_SUCCESS) {
329         LOGE("Generate randSelf failed, res: %x.", res);
330         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
331         return res;
332     }
333     res = IsoCalPeerToken(params, selfTokenBuf);
334     if (res != HC_SUCCESS) {
335         LOGE("IsoCalPeerToken failed, res: %x.", res);
336         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
337     }
338     return res;
339 }
340 
IsoServerGenSessionKeyAndCalToken(IsoBaseParams * params,const Uint8Buff * tokenFromPeer,Uint8Buff * tokenToPeer)341 int IsoServerGenSessionKeyAndCalToken(IsoBaseParams *params, const Uint8Buff *tokenFromPeer, Uint8Buff *tokenToPeer)
342 {
343     if (params == NULL) {
344         LOGE("Params is null.");
345         return HC_ERR_NULL_PTR;
346     }
347     if (tokenFromPeer == NULL || tokenToPeer == NULL) {
348         LOGE("Params is null.");
349         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
350         return HC_ERR_NULL_PTR;
351     }
352 
353     uint8_t hmacPeer[SHA256_LEN] = { 0 };
354     Uint8Buff outHmac = { hmacPeer, sizeof(hmacPeer) };
355     int res = IsoCalSelfToken(params, &outHmac);
356     if (res != HC_SUCCESS) {
357         LOGE("IsoCalSelfToken failed, res: %x.", res);
358         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
359         return res;
360     }
361     if (memcmp(tokenFromPeer->val, outHmac.val, outHmac.length) != 0) {
362         LOGE("Compare hmac token failed.");
363         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
364         return HC_ERR_PROOF_NOT_MATCH;
365     }
366 
367     Uint8Buff pskBuf = { params->psk, sizeof(params->psk) };
368     res = IsoGenSessionKey(params, &pskBuf, false);
369     if (res != HC_SUCCESS) {
370         LOGE("IsoGenSessionKey failed, res: %x.", res);
371         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
372         return res;
373     }
374 
375     int returnCode = 0;
376     Uint8Buff messageBuf = { (uint8_t *)&returnCode, sizeof(int) };
377     res = params->loader->computeHmac(&pskBuf, &messageBuf, tokenToPeer, false);
378     if (res != HC_SUCCESS) {
379         LOGE("Compute hmac for returnCode failed, res: %x.", res);
380         (void)memset_s(params->psk, sizeof(params->psk), 0, PSK_LEN);
381         FreeAndCleanKey(&params->sessionKey);
382     }
383     return res;
384 }