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
17 #include <unistd.h>
18 #include <net/if.h>
19 #include <sys/ioctl.h>
20 #include <sys/socket.h>
21 #include <pthread.h>
22
23 #include "securec.h"
24 #include "wifi_hdi_common.h"
25
26 #ifndef UT_TEST
27 #include "wifi_log.h"
28 #else
29 #define static
30 #define LOGI(...)
31 #define LOGE(...)
32 #endif
33
34 #undef LOG_TAG
35 #define LOG_TAG "WifiHdiCommon"
36
hex2num(char c)37 static int hex2num(char c)
38 {
39 if (c >= '0' && c <= '9') {
40 return c - '0';
41 }
42 if (c >= 'a' && c <= 'f') {
43 return c - 'a' + HDI_POS_TEN;
44 }
45 if (c >= 'A' && c <= 'F') {
46 return c - 'A' + HDI_POS_TEN;
47 }
48 return -1;
49 }
50
hex2byte(const char * hex)51 int hex2byte(const char *hex)
52 {
53 int a, b;
54 a = hex2num(*hex++);
55 if (a < 0) {
56 return -1;
57 }
58 b = hex2num(*hex++);
59 if (b < 0) {
60 return -1;
61 }
62 return (int)(((unsigned int)a << HDI_POS_FOURTH) | (unsigned int)b);
63 }
64
DealDigital(u8 * buf,const char ** pos,size_t * len)65 static void DealDigital(u8 *buf, const char **pos, size_t *len)
66 {
67 int val;
68 switch (**pos) {
69 case '0':
70 case '1':
71 case '2':
72 case '3':
73 case '4':
74 case '5':
75 case '6':
76 case '7':
77 val = **pos++ - '0';
78 if (**pos >= '0' && **pos <= '7') {
79 val = val * HDI_POS_EIGHT + (**pos++ - '0');
80 }
81 if (**pos >= '0' && **pos <= '7') {
82 val = val * HDI_POS_EIGHT + (**pos++ - '0');
83 }
84 buf[(*len)++] = val;
85 return;
86 default:
87 return;
88 }
89 }
90
DealSymbol(u8 * buf,const char ** pos,size_t * len)91 static void DealSymbol(u8 *buf, const char **pos, size_t *len)
92 {
93 int val;
94 switch (**pos) {
95 case '\\':
96 buf[(*len)++] = '\\';
97 (*pos)++;
98 return;
99 case '"':
100 buf[(*len)++] = '"';
101 (*pos)++;
102 return;
103 case 'n':
104 buf[(*len)++] = '\n';
105 (*pos)++;
106 return;
107 case 'r':
108 buf[(*len)++] = '\r';
109 (*pos)++;
110 return;
111 case 't':
112 buf[(*len)++] = '\t';
113 (*pos)++;
114 return;
115 case 'e':
116 buf[(*len)++] = '\033';
117 (*pos)++;
118 return;
119 case 'x':
120 (*pos)++;
121 val = hex2byte(*pos);
122 if (val < 0) {
123 val = hex2num(**pos);
124 if (val < 0) {
125 return;
126 }
127 buf[(*len)++] = val;
128 (*pos)++;
129 } else {
130 buf[(*len)++] = val;
131 (*pos) += HDI_POS_SECOND;
132 }
133 return;
134 default:
135 DealDigital(buf, pos, len);
136 return;
137 }
138 }
139
PrintfDecode(u8 * buf,size_t maxlen,const char * str)140 size_t PrintfDecode(u8 *buf, size_t maxlen, const char *str)
141 {
142 const char *pos = str;
143 size_t len = 0;
144
145 while (*pos) {
146 if (len + 1 >= maxlen) {
147 break;
148 }
149 switch (*pos) {
150 case '\\':
151 pos++;
152 DealSymbol(buf, &pos, &len);
153 break;
154 default:
155 buf[len++] = *pos++;
156 break;
157 }
158 }
159 if (maxlen > len) {
160 buf[len] = '\0';
161 }
162 return len;
163 }
164
HdiTxtPrintf(char * str,size_t size,const char * format,...)165 int HdiTxtPrintf(char *str, size_t size, const char *format, ...)
166 {
167 va_list ap;
168 int ret;
169
170 va_start(ap, format);
171 ret = vsnprintf_s(str, size, size - 1, format, ap);
172 va_end(ap);
173 if (size > 0) {
174 str[size - 1] = '\0';
175 }
176 return ret;
177 }
178
HdiGetCipherInfo(char * start,char * end,int ciphers,const char * delim)179 int HdiGetCipherInfo(char *start, char *end, int ciphers, const char *delim)
180 {
181 char *pos = start;
182 int ret;
183
184 if ((unsigned int)ciphers & HDI_CIPHER_CCMP_256) {
185 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sCCMP-256");
186 }
187 if ((unsigned int)ciphers & HDI_CIPHER_GCMP_256) {
188 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sGCMP-256");
189 }
190 if ((unsigned int)ciphers & HDI_CIPHER_CCMP) {
191 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sCCMP");
192 }
193 if ((unsigned int)ciphers & HDI_CIPHER_GCMP) {
194 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sGCMP");
195 }
196 if ((unsigned int)ciphers & HDI_CIPHER_TKIP) {
197 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sTKIP");
198 }
199 if ((unsigned int)ciphers & HDI_CIPHER_AES_128_CMAC) {
200 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sAES-128-CMAC");
201 }
202 if ((unsigned int)ciphers & HDI_CIPHER_BIP_GMAC_128) {
203 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sBIP-GMAC-128");
204 }
205 if ((unsigned int)ciphers & HDI_CIPHER_BIP_GMAC_256) {
206 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sBIP-GMAC-256");
207 }
208 if ((unsigned int)ciphers & HDI_CIPHER_BIP_CMAC_256) {
209 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sBIP-CMAC-256");
210 }
211 if ((unsigned int)ciphers & HDI_CIPHER_NONE) {
212 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sNONE");
213 }
214
215 return pos - start;
216 }
217
HdiGetCipherTxt(char * pos,char * end,int cipher)218 static char* HdiGetCipherTxt(char *pos, char *end, int cipher)
219 {
220 int ret;
221 ret = HdiTxtPrintf(pos, end - pos, "-");
222 if (HdiCheckError(end - pos, ret)) {
223 return pos;
224 }
225 pos += ret;
226 ret = HdiGetCipherInfo(pos, end, cipher, "+");
227 if (ret < 0) {
228 return pos;
229 }
230 pos += ret;
231 return pos;
232 }
233
HdiRsnIdToCipher(const uint8_t * s)234 static int HdiRsnIdToCipher(const uint8_t *s)
235 {
236 if (HDI_GET_RSN_ID(s) == HDI_CIPHER_SUITE_NONE) {
237 return HDI_CIPHER_NONE;
238 }
239 if (HDI_GET_RSN_ID(s) == HDI_CIPHER_SUITE_TKIP) {
240 return HDI_CIPHER_TKIP;
241 }
242 if (HDI_GET_RSN_ID(s) == HDI_CIPHER_SUITE_CCMP) {
243 return HDI_CIPHER_CCMP;
244 }
245 return 0;
246 }
247
HdiRsnIdToCipherSuite(const uint8_t * s)248 static int HdiRsnIdToCipherSuite(const uint8_t *s)
249 {
250 if (HDI_GET_RSN_ID(s) == HDI_RSN_CIPHER_SUITE_NONE) {
251 return HDI_CIPHER_NONE;
252 }
253 if (HDI_GET_RSN_ID(s) == HDI_RSN_CIPHER_SUITE_TKIP) {
254 return HDI_CIPHER_TKIP;
255 }
256 if (HDI_GET_RSN_ID(s) == HDI_RSN_CIPHER_SUITE_CCMP) {
257 return HDI_CIPHER_CCMP;
258 }
259 if (HDI_GET_RSN_ID(s) == HDI_RSN_CIPHER_SUITE_GCMP) {
260 return HDI_CIPHER_GCMP;
261 }
262 if (HDI_GET_RSN_ID(s) == HDI_RSN_CIPHER_SUITE_CCMP_256) {
263 return HDI_CIPHER_CCMP_256;
264 }
265 if (HDI_GET_RSN_ID(s) == HDI_RSN_CIPHER_SUITE_GCMP_256) {
266 return HDI_CIPHER_GCMP_256;
267 }
268 if (HDI_GET_RSN_ID(s) == HDI_RSN_CIPHER_SUITE_BIP_GMAC_128) {
269 return HDI_CIPHER_BIP_GMAC_128;
270 }
271 if (HDI_GET_RSN_ID(s) == HDI_RSN_CIPHER_SUITE_BIP_GMAC_256) {
272 return HDI_CIPHER_BIP_GMAC_256;
273 }
274 if (HDI_GET_RSN_ID(s) == HDI_RSN_CIPHER_SUITE_BIP_CMAC_256) {
275 return HDI_CIPHER_BIP_CMAC_256;
276 }
277 if (HDI_GET_RSN_ID(s) == HDI_RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED) {
278 return HDI_CIPHER_GTK_NOT_USED;
279 }
280 return 0;
281 }
282
HdiKeyMgmtToAuthMgmt(const uint8_t * s)283 static int HdiKeyMgmtToAuthMgmt(const uint8_t *s)
284 {
285 if (HDI_GET_RSN_ID(s) == HDI_AUTH_KEY_MGMT_UNSPEC) {
286 return HDI_KEY_MGMT;
287 }
288 if (HDI_GET_RSN_ID(s) == HDI_AUTH_KEY_MGMT_PSK_OVER) {
289 return HDI_KEY_MGMT_PSK;
290 }
291 if (HDI_GET_RSN_ID(s) == HDI_AUTH_KEY_MGMT_NONE) {
292 return HDI_KEY_MGMT_HDI_NONE;
293 }
294 return 0;
295 }
296
HdiRsnKeyMgmtToAuthMgmt(const uint8_t * s)297 static int HdiRsnKeyMgmtToAuthMgmt(const uint8_t *s)
298 {
299 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_UNSPEC) {
300 return HDI_KEY_MGMT;
301 }
302 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_SAE) {
303 return HDI_KEY_MGMT_SAE;
304 }
305 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_PSK_OVER) {
306 return HDI_KEY_MGMT_PSK;
307 }
308 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_SUITE_B) {
309 return HDI_KEY_MGMT_SUITE_B;
310 }
311 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_SUITE_B_192) {
312 return HDI_KEY_MGMT_SUITE_B_192;
313 }
314 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_FILS_SHA256) {
315 return HDI_KEY_MGMT_FILS_SHA256;
316 }
317 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_FILS_SHA384) {
318 return HDI_KEY_MGMT_FILS_SHA384;
319 }
320 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_FT_FILS_SHA256) {
321 return HDI_KEY_MGMT_FT_FILS_SHA256;
322 }
323 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_FT_FILS_SHA384) {
324 return HDI_KEY_MGMT_FT_FILS_SHA384;
325 }
326 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_OSEN) {
327 return HDI_KEY_MGMT_OSEN;
328 }
329 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_OWE) {
330 return HDI_KEY_MGMT_OWE;
331 }
332 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_PSK_SHA256) {
333 return HDI_KEY_MGMT_PSK_SHA256;
334 }
335 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_FT) {
336 return HDI_KEY_MGMT_FT_IEEE8021X;
337 }
338 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_FT_PSK) {
339 return HDI_KEY_MGMT_FT_PSK;
340 }
341 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_FT_SAE) {
342 return HDI_KEY_MGMT_FT_SAE;
343 }
344 if (HDI_GET_RSN_ID(s) == HDI_RSN_AUTH_KEY_MGMT_SHA256) {
345 return HDI_KEY_MGMT_IEEE8021X_SHA256;
346 }
347 return 0;
348 }
349
HdiGetIe(const uint8_t * ies,size_t len,uint8_t eid)350 const uint8_t* HdiGetIe(const uint8_t *ies, size_t len, uint8_t eid)
351 {
352 const struct HdiElem *elem;
353
354 if (!ies) {
355 return NULL;
356 }
357
358 HDI_CHECK_ELEMENT_BY_ID(elem, eid, ies, len)
359 return &elem->id;
360
361 return NULL;
362 }
363
HdiBssGetIe(const uint8_t * ies,size_t len,uint8_t ie)364 const uint8_t* HdiBssGetIe(const uint8_t *ies, size_t len, uint8_t ie)
365 {
366 return HdiGetIe(ies, len, ie);
367 }
368
HdiBssGetVendorIe(const uint8_t * ies,size_t len,uint32_t vendorType)369 const uint8_t *HdiBssGetVendorIe(const uint8_t *ies, size_t len, uint32_t vendorType)
370 {
371 const struct HdiElem *elem;
372 HDI_CHECK_ELEMENT_BY_ID(elem, HDI_EID_VENDOR_SPECIFIC, ies, len) {
373 if (elem->datalen >= HDI_POS_FOURTH && vendorType == HdiGetBe32(elem->data)) {
374 return &elem->id;
375 }
376 }
377
378 return NULL;
379 }
380
HdiBssGetVendorBeacon(const uint8_t * ies,size_t len,size_t beaconIeLen,uint32_t vendorType)381 const uint8_t* HdiBssGetVendorBeacon(const uint8_t *ies, size_t len, size_t beaconIeLen, uint32_t vendorType)
382 {
383 const struct HdiElem *elem;
384
385 if (beaconIeLen == 0) {
386 return NULL;
387 }
388
389 ies += len;
390
391 HDI_CHECK_ELEMENT_BY_ID(elem, HDI_EID_VENDOR_SPECIFIC, ies, beaconIeLen) {
392 if (elem->datalen >= HDI_POS_FOURTH && vendorType == HdiGetBe32(elem->data)) {
393 return &elem->id;
394 }
395 }
396
397 return NULL;
398 }
399
HdiCheckValidWise(int cipher)400 int HdiCheckValidWise(int cipher)
401 {
402 return cipher == HDI_CIPHER_CCMP_256 ||
403 cipher == HDI_CIPHER_GCMP_256 ||
404 cipher == HDI_CIPHER_CCMP ||
405 cipher == HDI_CIPHER_GCMP ||
406 cipher == HDI_CIPHER_TKIP;
407 }
408
HdiCheckValidGroup(int cipher)409 int HdiCheckValidGroup(int cipher)
410 {
411 return HdiCheckValidWise(cipher) ||
412 cipher == HDI_CIPHER_GTK_NOT_USED;
413 }
414
HdiConvertIe(const uint8_t * hdiIe,size_t wpaIeLen,struct HdiIeData * data)415 int HdiConvertIe(const uint8_t *hdiIe, size_t wpaIeLen,
416 struct HdiIeData *data)
417 {
418 const struct HdiIeHdr *hdr;
419 const uint8_t *pos;
420 int left;
421 int i, count;
422
423 if (memset_s(data, sizeof(*data), 0, sizeof(*data)) != EOK) {
424 LOGE("HdiConvertIe memset_s is failed");
425 return -1;
426 }
427 data->proto = HDI_PROTO_DEFAULT;
428 data->pairwiseCipher = HDI_CIPHER_TKIP;
429 data->groupCipher = HDI_CIPHER_TKIP;
430 data->keyMgmt = HDI_KEY_MGMT;
431 data->capabilities = 0;
432 data->pmkid = NULL;
433 data->numPmkid = 0;
434 data->mgmtGroupCipher = 0;
435
436 if (wpaIeLen < sizeof(struct HdiIeHdr)) {
437 LOGI("ie len too short %{public}lu", (unsigned long) wpaIeLen);
438 return -1;
439 }
440
441 hdr = (const struct HdiIeHdr *) hdiIe;
442
443 if (hdr->elemId != HDI_EID_VENDOR_SPECIFIC ||
444 hdr->len != wpaIeLen - HDI_POS_SECOND ||
445 HDI_GET_RSN_ID(hdr->oui) != HDI_OUI_TYPE ||
446 HdiGetBe16(hdr->version) != HDI_VERSION) {
447 LOGI("malformed ie or unknown version");
448 return -1;
449 }
450
451 pos = (const uint8_t *) (hdr + 1);
452 left = (int)(wpaIeLen - sizeof(*hdr));
453
454 if (left >= HDI_SELECTOR_LEN) {
455 data->groupCipher = HdiRsnIdToCipher(pos);
456 pos += HDI_SELECTOR_LEN;
457 left -= HDI_SELECTOR_LEN;
458 } else if (left > 0) {
459 LOGI("ie length mismatch, %{public}u too much", left);
460 return -1;
461 }
462
463 if (left >= HDI_POS_SECOND) {
464 data->pairwiseCipher = 0;
465 count = HdiGetBe16(pos);
466 pos += HDI_POS_SECOND;
467 left -= HDI_POS_SECOND;
468 if (count == 0 || count > left / HDI_SELECTOR_LEN) {
469 LOGI("ie count botch (pairwise), count %{public}u left %{public}u", count, left);
470 return -1;
471 }
472 for (i = 0; i < count; i++) {
473 data->pairwiseCipher = (int)((unsigned int)(data->pairwiseCipher) | (unsigned int)HdiRsnIdToCipher(pos));
474 pos += HDI_SELECTOR_LEN;
475 left -= HDI_SELECTOR_LEN;
476 }
477 } else if (left == 1) {
478 LOGI("ie too short (for key mgmt)");
479 return -1;
480 }
481
482 if (left >= HDI_POS_SECOND) {
483 data->keyMgmt = 0;
484 count = HdiGetBe16(pos);
485 pos += HDI_POS_SECOND;
486 left -= HDI_POS_SECOND;
487 if (count == 0 || count > left / HDI_SELECTOR_LEN) {
488 LOGI("ie count botch (key mgmt),count %{public}u left %{public}u", count, left);
489 return -1;
490 }
491 for (i = 0; i < count; i++) {
492 data->keyMgmt = (int)((unsigned int)(data->keyMgmt) | (unsigned int)HdiKeyMgmtToAuthMgmt(pos));
493 pos += HDI_SELECTOR_LEN;
494 left -= HDI_SELECTOR_LEN;
495 }
496 } else if (left == 1) {
497 LOGI("ie too short (for capabilities)");
498 return -1;
499 }
500
501 if (left >= HDI_POS_SECOND) {
502 data->capabilities = HdiGetBe16(pos);
503 }
504 return 0;
505 }
506
HdiConvertIeRsn(const uint8_t * rsnIe,size_t rsnIeLen,struct HdiIeData * data)507 int HdiConvertIeRsn(const uint8_t *rsnIe, size_t rsnIeLen,
508 struct HdiIeData *data)
509 {
510 const uint8_t *pos;
511 int left;
512 int i, count;
513
514 if (memset_s(data, sizeof(*data), 0, sizeof(*data)) != EOK) {
515 LOGE("HdiConvertIeRsn memset_s is failed");
516 return -1;
517 }
518 data->proto = HDI_PROTO_ONE;
519 data->pairwiseCipher = HDI_CIPHER_CCMP;
520 data->groupCipher = HDI_CIPHER_CCMP;
521 data->keyMgmt = HDI_KEY_MGMT;
522 data->capabilities = 0;
523 data->pmkid = NULL;
524 data->numPmkid = 0;
525 data->mgmtGroupCipher = 0;
526
527 if (rsnIeLen == 0) {
528 return -1;
529 }
530
531 if (rsnIeLen < sizeof(struct HdiRsnIeHdr)) {
532 LOGI("ie len too short %{public}lu", (unsigned long) rsnIeLen);
533 return -1;
534 }
535
536 if (rsnIeLen >= HDI_POS_SIX && rsnIe[1] >= HDI_POS_FOURTH &&
537 rsnIe[1] == rsnIeLen - HDI_POS_SECOND &&
538 HdiGetBe32(&rsnIe[HDI_POS_SECOND]) == HDI_OSEN_IE_VENDOR_TYPE) {
539 pos = rsnIe + HDI_POS_SIX;
540 left = (int)(rsnIeLen - HDI_POS_SIX);
541
542 data->groupCipher = HDI_CIPHER_GTK_NOT_USED;
543 data->hasGroup = 1;
544 data->keyMgmt = HDI_KEY_MGMT_OSEN;
545 data->proto = HDI_PROTO_THREE;
546 } else {
547 const struct HdiRsnIeHdr *hdr;
548
549 hdr = (const struct HdiRsnIeHdr *) rsnIe;
550
551 if (hdr->elemId != HDI_EID_RSN ||
552 hdr->len != rsnIeLen - HDI_POS_SECOND ||
553 HdiGetBe16(hdr->version) != HDI_VERSION) {
554 LOGI("malformed ie or unknown version");
555 return -1;
556 }
557
558 pos = (const uint8_t *) (hdr + 1);
559 left = (int)(rsnIeLen - sizeof(*hdr));
560 }
561
562 if (left >= HDI_SELECTOR_LEN) {
563 data->groupCipher = HdiRsnIdToCipherSuite(pos);
564 data->hasGroup = 1;
565 if (!HdiCheckValidGroup(data->groupCipher)) {
566 LOGI("invalid group cipher 0x%{public}x (%08x)", data->groupCipher,
567 HdiGetBe32(pos));
568 return -1;
569 }
570 pos += HDI_SELECTOR_LEN;
571 left -= HDI_SELECTOR_LEN;
572 } else if (left > 0) {
573 LOGI("ie length mismatch, %u too much", left);
574 return -1;
575 }
576
577 if (left >= HDI_POS_SECOND) {
578 data->pairwiseCipher = 0;
579 count = HdiGetBe16(pos);
580 pos += HDI_POS_SECOND;
581 left -= HDI_POS_SECOND;
582 if (count == 0 || count > left / HDI_SELECTOR_LEN) {
583 LOGI("ie count botch (pairwise), count %{public}u left %{public}u", count, left);
584 return -1;
585 }
586 data->hasPairwise = 1;
587 for (i = 0; i < count; i++) {
588 data->pairwiseCipher = (int)((unsigned int)(data->pairwiseCipher) |
589 (unsigned int)HdiRsnIdToCipherSuite(pos));
590 pos += HDI_SELECTOR_LEN;
591 left -= HDI_SELECTOR_LEN;
592 }
593 } else if (left == 1) {
594 LOGI("ie too short (for key mgmt)");
595 return -1;
596 }
597
598 if (left >= HDI_POS_SECOND) {
599 data->keyMgmt = 0;
600 count = HdiGetBe16(pos);
601 pos += HDI_POS_SECOND;
602 left -= HDI_POS_SECOND;
603 if (count == 0 || count > left / HDI_SELECTOR_LEN) {
604 LOGI("ie count botch (key mgmt) count %{public}u left %{public}u", count, left);
605 return -1;
606 }
607 for (i = 0; i < count; i++) {
608 data->keyMgmt = (int)((unsigned int)(data->keyMgmt) | (unsigned int)HdiRsnKeyMgmtToAuthMgmt(pos));
609 pos += HDI_SELECTOR_LEN;
610 left -= HDI_SELECTOR_LEN;
611 }
612 } else if (left == 1) {
613 LOGI("ie too short (for capabilities)");
614 return -1;
615 }
616
617 if (left >= HDI_POS_SECOND) {
618 data->capabilities = HdiGetBe16(pos);
619 pos += HDI_POS_SECOND;
620 left -= HDI_POS_SECOND;
621 }
622
623 if (left >= HDI_POS_SECOND) {
624 uint16_t numPmkid = HdiGetBe16(pos);
625 pos += HDI_POS_SECOND;
626 left -= HDI_POS_SECOND;
627 if (numPmkid > (unsigned int) left / HDI_PMKID_LEN) {
628 LOGI("PMKID underflow(numPmkid=%{public}u left=%{public}d)", numPmkid, left);
629 data->numPmkid = 0;
630 return -1;
631 } else {
632 data->numPmkid = numPmkid;
633 data->pmkid = pos;
634 }
635 }
636
637 return 0;
638 }
639
HdiParseIe(const uint8_t * hdiIe,size_t wpaIeLen,struct HdiIeData * data)640 int HdiParseIe(const uint8_t *hdiIe, size_t wpaIeLen,
641 struct HdiIeData *data)
642 {
643 if (wpaIeLen >= HDI_POS_FIRST && hdiIe[0] == HDI_EID_RSN) {
644 return HdiConvertIeRsn(hdiIe, wpaIeLen, data);
645 }
646 if (wpaIeLen >= HDI_POS_SIX && hdiIe[0] == HDI_EID_VENDOR_SPECIFIC &&
647 hdiIe[1] >= HDI_POS_FOURTH && HdiGetBe32(&hdiIe[HDI_POS_SECOND]) == HDI_OSEN_IE_VENDOR_TYPE) {
648 return HdiConvertIeRsn(hdiIe, wpaIeLen, data);
649 }
650 else {
651 return HdiConvertIe(hdiIe, wpaIeLen, data);
652 }
653 }
654
HdiGetIeTxt(char * pos,char * end,const char * proto,const uint8_t * ie,size_t ieLen)655 char* HdiGetIeTxt(char *pos, char *end, const char *proto,
656 const uint8_t *ie, size_t ieLen)
657 {
658 struct HdiIeData data;
659 char *start;
660 int ret;
661
662 ret = HdiTxtPrintf(pos, end - pos, "[%s-", proto);
663 if (HdiCheckError(end - pos, ret)) {
664 return pos;
665 }
666 pos += ret;
667
668 if (HdiParseIe(ie, ieLen, &data) < 0) {
669 ret = HdiTxtPrintf(pos, end - pos, "?]");
670 if (HdiCheckError(end - pos, ret)) {
671 return pos;
672 }
673 pos += ret;
674 return pos;
675 }
676
677 start = pos;
678
679 HDI_HANDLE_CIPHER_POS_INFO((unsigned int)(data.keyMgmt) & HDI_KEY_MGMT, ret, pos, end, "+", "%sEAP");
680 HDI_HANDLE_CIPHER_POS_INFO((unsigned int)(data.keyMgmt) & HDI_KEY_MGMT_PSK, ret, pos, end, "+", "%sPSK");
681 HDI_HANDLE_CIPHER_POS_INFO((unsigned int)(data.keyMgmt) & HDI_KEY_MGMT_HDI_NONE, ret, pos, end, "+", "%sNone");
682 HDI_HANDLE_CIPHER_POS_INFO((unsigned int)(data.keyMgmt) & HDI_KEY_MGMT_SAE, ret, pos, end, "+", "%sSAE");
683 HDI_HANDLE_CIPHER_POS_INFO((unsigned int)(data.keyMgmt) & HDI_KEY_MGMT_SUITE_B_192,
684 ret, pos, end, "+", "%sEAP-SUITE-B-192");
685 HDI_HANDLE_CIPHER_POS_INFO((unsigned int)(data.keyMgmt) & HDI_KEY_MGMT_OSEN, ret, pos, end, "+", "%sOSEN");
686 HDI_HANDLE_CIPHER_POS_INFO((unsigned int)(data.keyMgmt) & HDI_KEY_MGMT_OWE, ret, pos, end, "+", "%sOWE");
687 HDI_HANDLE_CIPHER_POS_INFO((unsigned int)(data.keyMgmt) & HDI_KEY_MGMT_PSK_SHA256, ret, pos, end, "+", "%sPSK");
688 HDI_HANDLE_CIPHER_POS_INFO((unsigned int)(data.keyMgmt) & HDI_KEY_MGMT_FT_IEEE8021X,
689 ret, pos, end, "+", "%sFT/EAP");
690 HDI_HANDLE_CIPHER_POS_INFO((unsigned int)(data.keyMgmt) & HDI_KEY_MGMT_FT_PSK, ret, pos, end, "+", "%sFT/PSK");
691 HDI_HANDLE_CIPHER_POS_INFO((unsigned int)(data.keyMgmt) & HDI_KEY_MGMT_FT_SAE, ret, pos, end, "+", "%sFT/SAE");
692 HDI_HANDLE_CIPHER_POS_INFO((unsigned int)(data.keyMgmt) & HDI_KEY_MGMT_IEEE8021X_SHA256,
693 ret, pos, end, "+", "%sEAP");
694
695 pos = HdiGetCipherTxt(pos, end, data.pairwiseCipher);
696
697 if ((unsigned int)data.capabilities & HDI_CAPABILITY_PREAUTH) {
698 ret = HdiTxtPrintf(pos, end - pos, "-preauth");
699 if (HdiCheckError(end - pos, ret)) {
700 return pos;
701 }
702 pos += ret;
703 }
704
705 ret = HdiTxtPrintf(pos, end - pos, "]");
706 if (HdiCheckError(end - pos, ret)) {
707 return pos;
708 }
709 pos += ret;
710
711 return pos;
712 }
713
HdiGetIeExt(const uint8_t * ies,size_t len,uint8_t ext)714 const uint8_t* HdiGetIeExt(const uint8_t *ies, size_t len, uint8_t ext)
715 {
716 const struct HdiElem *elem;
717
718 if (!ies) {
719 return NULL;
720 }
721 HDI_CHECK_ELEMENT_BY_EXTID(elem, ext, ies, len)
722 return &elem->id;
723
724 return NULL;
725 }
726
HdiBssGetIeExt(const uint8_t * ies,size_t len,uint8_t ext)727 const uint8_t* HdiBssGetIeExt(const uint8_t *ies, size_t len, uint8_t ext)
728 {
729 return HdiGetIeExt(ies, len, ext);
730 }
731
HdiBufEncode(char * txt,size_t maxlen,const uint8_t * data,size_t len)732 void HdiBufEncode(char *txt, size_t maxlen, const uint8_t *data, size_t len)
733 {
734 char *end = txt + maxlen;
735 size_t i;
736
737 for (i = 0; i < len; i++) {
738 if (txt + HDI_POS_FOURTH >= end) {
739 break;
740 }
741
742 switch (data[i]) {
743 case '\"':
744 *txt++ = '\\';
745 *txt++ = '\"';
746 break;
747 case '\\':
748 *txt++ = '\\';
749 *txt++ = '\\';
750 break;
751 case '\033':
752 *txt++ = '\\';
753 *txt++ = 'e';
754 break;
755 case '\n':
756 *txt++ = '\\';
757 *txt++ = 'n';
758 break;
759 case '\r':
760 *txt++ = '\\';
761 *txt++ = 'r';
762 break;
763 case '\t':
764 *txt++ = '\\';
765 *txt++ = 't';
766 break;
767 default:
768 if (data[i] >= HDI_POS_TT && data[i] <= HDI_POS_OTX) {
769 *txt++ = data[i];
770 } else {
771 txt += HdiTxtPrintf(txt, end - txt, "\\x%02x",
772 data[i]);
773 }
774 break;
775 }
776 }
777
778 *txt = '\0';
779 }
780
HdiSSid2Txt(const uint8_t * ssid,size_t ssidLen)781 const char* HdiSSid2Txt(const uint8_t *ssid, size_t ssidLen)
782 {
783 static char ssid_txt[SSID_MAX_LEN * HDI_POS_FOURTH + 1];
784 if (ssid == NULL) {
785 ssid_txt[0] = '\0';
786 return ssid_txt;
787 }
788
789 HdiBufEncode(ssid_txt, sizeof(ssid_txt), ssid, ssidLen);
790 return ssid_txt;
791 }
792
HdiGetWifiCategoryTxt(char * pos,char * end,const struct HdiElems * elems)793 char* HdiGetWifiCategoryTxt(char *pos, char* end, const struct HdiElems *elems)
794 {
795 int ret = 0;
796 if (elems->ehtCapabilities80211Be != NULL) {
797 ret = HdiTxtPrintf(pos, end - pos, "%s", "[11BE]");
798 } else if (elems->heCapabilities != NULL) {
799 ret = HdiTxtPrintf(pos, end - pos, "%s", "[11AX]");
800 }
801 if (HdiCheckError(end - pos, ret)) {
802 LOGE("HdiGetWifiCategoryTxt HdiCheckError fail");
803 return pos;
804 }
805 pos += ret;
806 return pos;
807 }
808
IsValidHexCharAndConvert(char c)809 int8_t IsValidHexCharAndConvert(char c)
810 {
811 if (c >= '0' && c <= '9') {
812 return c - '0';
813 }
814 if (c >= 'a' && c <= 'f') {
815 return c - 'a' + ('9' - '0' + 1);
816 }
817 if (c >= 'A' && c <= 'F') {
818 return c - 'A' + ('9' - '0' + 1);
819 }
820 return -1;
821 }
822
CheckMacIsValid(const char * macStr)823 int CheckMacIsValid(const char *macStr)
824 {
825 if (macStr == NULL || strlen(macStr) != MAC_STRING_SIZE) {
826 return -1;
827 }
828 for (int i = 0, j = 0; i < MAC_STRING_SIZE; ++i) {
829 if (j == 0 || j == 1) {
830 int v = IsValidHexCharAndConvert(macStr[i]);
831 if (v < 0) {
832 return -1;
833 }
834 ++j;
835 } else {
836 if (macStr[i] != ':') {
837 return -1;
838 }
839 j = 0;
840 }
841 }
842 return 0;
843 }
844
StrSafeCopy(char * dst,unsigned len,const char * src)845 void StrSafeCopy(char *dst, unsigned len, const char *src)
846 {
847 if (dst == NULL) {
848 return;
849 }
850 if (src == NULL) {
851 dst[0] = '\0';
852 return;
853 }
854 unsigned i = 0;
855 while (i + 1 < len && src[i] != '\0') {
856 dst[i] = src[i];
857 ++i;
858 }
859 dst[i] = '\0';
860 return;
861 }
862
HdiGetWapiTxt(char * pos,char * end,const uint8_t * ie)863 char* HdiGetWapiTxt(char *pos, char *end, const uint8_t *ie)
864 {
865 if (ie[HDI_POS_FIRST] < HDI_CAP_WAPI_BIT_OFFSET - HDI_POS_SECOND) {
866 return pos;
867 }
868
869 char *start;
870 int ret;
871
872 ret = HdiTxtPrintf(pos, end - pos, "[WAPI-");
873 if (HdiCheckError(end - pos, ret)) {
874 return pos;
875 }
876 pos += ret;
877
878 start = pos;
879 uint8_t akm = ie[HDI_CAP_WAPI_BIT_OFFSET];
880 HDI_HANDLE_CIPHER_POS_INFO(akm & HDI_KEY_MGMT_WAPI_CERT_AKM, ret, pos, end, "+", "%sCERT");
881 HDI_HANDLE_CIPHER_POS_INFO(akm & HDI_KEY_MGMT_WAPI_PSK_AKM, ret, pos, end, "+", "%sPSK");
882
883 ret = HdiTxtPrintf(pos, end - pos, "]");
884 if (HdiCheckError(end - pos, ret)) {
885 return pos;
886 }
887 pos += ret;
888
889 return pos;
890 }