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 (a << HDI_POS_FOURTH) | 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 (ciphers & HDI_CIPHER_CCMP_256) {
185 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sCCMP-256");
186 }
187 if (ciphers & HDI_CIPHER_GCMP_256) {
188 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sGCMP-256");
189 }
190 if (ciphers & HDI_CIPHER_CCMP) {
191 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sCCMP");
192 }
193 if (ciphers & HDI_CIPHER_GCMP) {
194 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sGCMP");
195 }
196 if (ciphers & HDI_CIPHER_TKIP) {
197 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sTKIP");
198 }
199 if (ciphers & HDI_CIPHER_AES_128_CMAC) {
200 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sAES-128-CMAC");
201 }
202 if (ciphers & HDI_CIPHER_BIP_GMAC_128) {
203 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sBIP-GMAC-128");
204 }
205 if (ciphers & HDI_CIPHER_BIP_GMAC_256) {
206 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sBIP-GMAC-256");
207 }
208 if (ciphers & HDI_CIPHER_BIP_CMAC_256) {
209 HDI_HANDLE_CIPHER_INFO(ret, start, end, delim, "%sBIP-CMAC-256");
210 }
211 if (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 return 0;
345 }
346
HdiGetIe(const uint8_t * ies,size_t len,uint8_t eid)347 const uint8_t* HdiGetIe(const uint8_t *ies, size_t len, uint8_t eid)
348 {
349 const struct HdiElem *elem;
350
351 if (!ies) {
352 return NULL;
353 }
354
355 HDI_CHECK_ELEMENT_BY_ID(elem, eid, ies, len)
356 return &elem->id;
357
358 return NULL;
359 }
360
HdiBssGetIe(const uint8_t * ies,size_t len,uint8_t ie)361 const uint8_t* HdiBssGetIe(const uint8_t *ies, size_t len, uint8_t ie)
362 {
363 return HdiGetIe(ies, len, ie);
364 }
365
HdiBssGetVendorIe(const uint8_t * ies,size_t len,uint32_t vendorType)366 const uint8_t *HdiBssGetVendorIe(const uint8_t *ies, size_t len, uint32_t vendorType)
367 {
368 const struct HdiElem *elem;
369 HDI_CHECK_ELEMENT_BY_ID(elem, HDI_EID_VENDOR_SPECIFIC, ies, len) {
370 if (elem->datalen >= HDI_POS_FOURTH && vendorType == HdiGetBe32(elem->data)) {
371 return &elem->id;
372 }
373 }
374
375 return NULL;
376 }
377
HdiBssGetVendorBeacon(const uint8_t * ies,size_t len,size_t beaconIeLen,uint32_t vendorType)378 const uint8_t* HdiBssGetVendorBeacon(const uint8_t *ies, size_t len, size_t beaconIeLen, uint32_t vendorType)
379 {
380 const struct HdiElem *elem;
381
382 if (beaconIeLen == 0) {
383 return NULL;
384 }
385
386 ies += len;
387
388 HDI_CHECK_ELEMENT_BY_ID(elem, HDI_EID_VENDOR_SPECIFIC, ies, beaconIeLen) {
389 if (elem->datalen >= HDI_POS_FOURTH && vendorType == HdiGetBe32(elem->data)) {
390 return &elem->id;
391 }
392 }
393
394 return NULL;
395 }
396
HdiCheckValidWise(int cipher)397 int HdiCheckValidWise(int cipher)
398 {
399 return cipher == HDI_CIPHER_CCMP_256 ||
400 cipher == HDI_CIPHER_GCMP_256 ||
401 cipher == HDI_CIPHER_CCMP ||
402 cipher == HDI_CIPHER_GCMP ||
403 cipher == HDI_CIPHER_TKIP;
404 }
405
HdiCheckValidGroup(int cipher)406 int HdiCheckValidGroup(int cipher)
407 {
408 return HdiCheckValidWise(cipher) ||
409 cipher == HDI_CIPHER_GTK_NOT_USED;
410 }
411
HdiConvertIe(const uint8_t * hdiIe,size_t wpaIeLen,struct HdiIeData * data)412 int HdiConvertIe(const uint8_t *hdiIe, size_t wpaIeLen,
413 struct HdiIeData *data)
414 {
415 const struct HdiIeHdr *hdr;
416 const uint8_t *pos;
417 int left;
418 int i, count;
419
420 (void)memset_s(data, sizeof(*data), 0, sizeof(*data));
421 data->proto = HDI_PROTO_DEFAULT;
422 data->pairwiseCipher = HDI_CIPHER_TKIP;
423 data->groupCipher = HDI_CIPHER_TKIP;
424 data->keyMgmt = HDI_KEY_MGMT;
425 data->capabilities = 0;
426 data->pmkid = NULL;
427 data->numPmkid = 0;
428 data->mgmtGroupCipher = 0;
429
430 if (wpaIeLen < sizeof(struct HdiIeHdr)) {
431 LOGI("ie len too short %{public}lu", (unsigned long) wpaIeLen);
432 return -1;
433 }
434
435 hdr = (const struct HdiIeHdr *) hdiIe;
436
437 if (hdr->elemId != HDI_EID_VENDOR_SPECIFIC ||
438 hdr->len != wpaIeLen - HDI_POS_SECOND ||
439 HDI_GET_RSN_ID(hdr->oui) != HDI_OUI_TYPE ||
440 HdiGetBe16(hdr->version) != HDI_VERSION) {
441 LOGI("malformed ie or unknown version");
442 return -1;
443 }
444
445 pos = (const uint8_t *) (hdr + 1);
446 left = (int)(wpaIeLen - sizeof(*hdr));
447
448 if (left >= HDI_SELECTOR_LEN) {
449 data->groupCipher = HdiRsnIdToCipher(pos);
450 pos += HDI_SELECTOR_LEN;
451 left -= HDI_SELECTOR_LEN;
452 } else if (left > 0) {
453 LOGI("ie length mismatch, %{public}u too much", left);
454 return -1;
455 }
456
457 if (left >= HDI_POS_SECOND) {
458 data->pairwiseCipher = 0;
459 count = HdiGetBe16(pos);
460 pos += HDI_POS_SECOND;
461 left -= HDI_POS_SECOND;
462 if (count == 0 || count > left / HDI_SELECTOR_LEN) {
463 LOGI("ie count botch (pairwise), count %{public}u left %{public}u", count, left);
464 return -1;
465 }
466 for (i = 0; i < count; i++) {
467 data->pairwiseCipher |= HdiRsnIdToCipher(pos);
468 pos += HDI_SELECTOR_LEN;
469 left -= HDI_SELECTOR_LEN;
470 }
471 } else if (left == 1) {
472 LOGI("ie too short (for key mgmt)");
473 return -1;
474 }
475
476 if (left >= HDI_POS_SECOND) {
477 data->keyMgmt = 0;
478 count = HdiGetBe16(pos);
479 pos += HDI_POS_SECOND;
480 left -= HDI_POS_SECOND;
481 if (count == 0 || count > left / HDI_SELECTOR_LEN) {
482 LOGI("ie count botch (key mgmt),count %{public}u left %{public}u", count, left);
483 return -1;
484 }
485 for (i = 0; i < count; i++) {
486 data->keyMgmt |= HdiKeyMgmtToAuthMgmt(pos);
487 pos += HDI_SELECTOR_LEN;
488 left -= HDI_SELECTOR_LEN;
489 }
490 } else if (left == 1) {
491 LOGI("ie too short (for capabilities)");
492 return -1;
493 }
494
495 if (left >= HDI_POS_SECOND) {
496 data->capabilities = HdiGetBe16(pos);
497 }
498 return 0;
499 }
500
HdiConvertIeRsn(const uint8_t * rsnIe,size_t rsnIeLen,struct HdiIeData * data)501 int HdiConvertIeRsn(const uint8_t *rsnIe, size_t rsnIeLen,
502 struct HdiIeData *data)
503 {
504 const uint8_t *pos;
505 int left;
506 int i, count;
507
508 (void)memset_s(data, sizeof(*data), 0, sizeof(*data));
509 data->proto = HDI_PROTO_ONE;
510 data->pairwiseCipher = HDI_CIPHER_CCMP;
511 data->groupCipher = HDI_CIPHER_CCMP;
512 data->keyMgmt = HDI_KEY_MGMT;
513 data->capabilities = 0;
514 data->pmkid = NULL;
515 data->numPmkid = 0;
516 data->mgmtGroupCipher = 0;
517
518 if (rsnIeLen == 0) {
519 return -1;
520 }
521
522 if (rsnIeLen < sizeof(struct HdiRsnIeHdr)) {
523 LOGI("ie len too short %{public}lu", (unsigned long) rsnIeLen);
524 return -1;
525 }
526
527 if (rsnIeLen >= HDI_POS_SIX && rsnIe[1] >= HDI_POS_FOURTH &&
528 rsnIe[1] == rsnIeLen - HDI_POS_SECOND &&
529 HdiGetBe32(&rsnIe[HDI_POS_SECOND]) == HDI_OSEN_IE_VENDOR_TYPE) {
530 pos = rsnIe + HDI_POS_SIX;
531 left = rsnIeLen - HDI_POS_SIX;
532
533 data->groupCipher = HDI_CIPHER_GTK_NOT_USED;
534 data->hasGroup = 1;
535 data->keyMgmt = HDI_KEY_MGMT_OSEN;
536 data->proto = HDI_PROTO_THREE;
537 } else {
538 const struct HdiRsnIeHdr *hdr;
539
540 hdr = (const struct HdiRsnIeHdr *) rsnIe;
541
542 if (hdr->elemId != HDI_EID_RSN ||
543 hdr->len != rsnIeLen - HDI_POS_SECOND ||
544 HdiGetBe16(hdr->version) != HDI_VERSION) {
545 LOGI("malformed ie or unknown version");
546 return -1;
547 }
548
549 pos = (const uint8_t *) (hdr + 1);
550 left = rsnIeLen - sizeof(*hdr);
551 }
552
553 if (left >= HDI_SELECTOR_LEN) {
554 data->groupCipher = HdiRsnIdToCipherSuite(pos);
555 data->hasGroup = 1;
556 if (!HdiCheckValidGroup(data->groupCipher)) {
557 LOGI("invalid group cipher 0x%{public}x (%08x)", data->groupCipher,
558 HdiGetBe32(pos));
559 return -1;
560 }
561 pos += HDI_SELECTOR_LEN;
562 left -= HDI_SELECTOR_LEN;
563 } else if (left > 0) {
564 LOGI("ie length mismatch, %u too much", left);
565 return -1;
566 }
567
568 if (left >= HDI_POS_SECOND) {
569 data->pairwiseCipher = 0;
570 count = HdiGetBe16(pos);
571 pos += HDI_POS_SECOND;
572 left -= HDI_POS_SECOND;
573 if (count == 0 || count > left / HDI_SELECTOR_LEN) {
574 LOGI("ie count botch (pairwise), count %{public}u left %{public}u", count, left);
575 return -1;
576 }
577 data->hasPairwise = 1;
578 for (i = 0; i < count; i++) {
579 data->pairwiseCipher |= HdiRsnIdToCipherSuite(pos);
580 pos += HDI_SELECTOR_LEN;
581 left -= HDI_SELECTOR_LEN;
582 }
583 } else if (left == 1) {
584 LOGI("ie too short (for key mgmt)");
585 return -1;
586 }
587
588 if (left >= HDI_POS_SECOND) {
589 data->keyMgmt = 0;
590 count = HdiGetBe16(pos);
591 pos += HDI_POS_SECOND;
592 left -= HDI_POS_SECOND;
593 if (count == 0 || count > left / HDI_SELECTOR_LEN) {
594 LOGI("ie count botch (key mgmt) count %{public}u left %{public}u", count, left);
595 return -1;
596 }
597 for (i = 0; i < count; i++) {
598 data->keyMgmt |= HdiRsnKeyMgmtToAuthMgmt(pos);
599 pos += HDI_SELECTOR_LEN;
600 left -= HDI_SELECTOR_LEN;
601 }
602 } else if (left == 1) {
603 LOGI("ie too short (for capabilities)");
604 return -1;
605 }
606
607 if (left >= HDI_POS_SECOND) {
608 data->capabilities = HdiGetBe16(pos);
609 pos += HDI_POS_SECOND;
610 left -= HDI_POS_SECOND;
611 }
612
613 if (left >= HDI_POS_SECOND) {
614 uint16_t numPmkid = HdiGetBe16(pos);
615 pos += HDI_POS_SECOND;
616 left -= HDI_POS_SECOND;
617 if (numPmkid > (unsigned int) left / HDI_PMKID_LEN) {
618 LOGI("PMKID underflow(numPmkid=%{public}u left=%{public}d)", numPmkid, left);
619 data->numPmkid = 0;
620 return -1;
621 } else {
622 data->numPmkid = numPmkid;
623 data->pmkid = pos;
624 }
625 }
626
627 return 0;
628 }
629
HdiParseIe(const uint8_t * hdiIe,size_t wpaIeLen,struct HdiIeData * data)630 int HdiParseIe(const uint8_t *hdiIe, size_t wpaIeLen,
631 struct HdiIeData *data)
632 {
633 if (wpaIeLen >= HDI_POS_FIRST && hdiIe[0] == HDI_EID_RSN) {
634 return HdiConvertIeRsn(hdiIe, wpaIeLen, data);
635 }
636 if (wpaIeLen >= HDI_POS_SIX && hdiIe[0] == HDI_EID_VENDOR_SPECIFIC &&
637 hdiIe[1] >= HDI_POS_FOURTH && HdiGetBe32(&hdiIe[HDI_POS_SECOND]) == HDI_OSEN_IE_VENDOR_TYPE) {
638 return HdiConvertIeRsn(hdiIe, wpaIeLen, data);
639 }
640 else {
641 return HdiConvertIe(hdiIe, wpaIeLen, data);
642 }
643 }
644
HdiGetIeTxt(char * pos,char * end,const char * proto,const uint8_t * ie,size_t ieLen)645 char* HdiGetIeTxt(char *pos, char *end, const char *proto,
646 const uint8_t *ie, size_t ieLen)
647 {
648 struct HdiIeData data;
649 char *start;
650 int ret;
651
652 ret = HdiTxtPrintf(pos, end - pos, "[%s-", proto);
653 if (HdiCheckError(end - pos, ret)) {
654 return pos;
655 }
656 pos += ret;
657
658 if (HdiParseIe(ie, ieLen, &data) < 0) {
659 ret = HdiTxtPrintf(pos, end - pos, "?]");
660 if (HdiCheckError(end - pos, ret)) {
661 return pos;
662 }
663 pos += ret;
664 return pos;
665 }
666
667 start = pos;
668
669 HDI_HANDLE_CIPHER_POS_INFO(data.keyMgmt & HDI_KEY_MGMT, ret, pos, end, "+", "%sEAP");
670 HDI_HANDLE_CIPHER_POS_INFO(data.keyMgmt & HDI_KEY_MGMT_PSK, ret, pos, end, "+", "%sPSK");
671 HDI_HANDLE_CIPHER_POS_INFO(data.keyMgmt & HDI_KEY_MGMT_HDI_NONE, ret, pos, end, "+", "%sNone");
672 HDI_HANDLE_CIPHER_POS_INFO(data.keyMgmt & HDI_KEY_MGMT_SAE, ret, pos, end, "+", "%sSAE");
673 HDI_HANDLE_CIPHER_POS_INFO(data.keyMgmt & HDI_KEY_MGMT_SUITE_B_192, ret, pos, end, "+", "%sEAP-SUITE-B-192");
674 HDI_HANDLE_CIPHER_POS_INFO(data.keyMgmt & HDI_KEY_MGMT_OSEN, ret, pos, end, "+", "%sOSEN");
675 HDI_HANDLE_CIPHER_POS_INFO(data.keyMgmt & HDI_KEY_MGMT_OWE, ret, pos, end, "+", "%sOWE");
676 HDI_HANDLE_CIPHER_POS_INFO(data.keyMgmt & HDI_KEY_MGMT_PSK_SHA256, ret, pos, end, "+", "%sPSK");
677 HDI_HANDLE_CIPHER_POS_INFO(data.keyMgmt & HDI_KEY_MGMT_FT_IEEE8021X, ret, pos, end, "+", "%sFT/EAP");
678 HDI_HANDLE_CIPHER_POS_INFO(data.keyMgmt & HDI_KEY_MGMT_FT_PSK, ret, pos, end, "+", "%sFT/PSK");
679 HDI_HANDLE_CIPHER_POS_INFO(data.keyMgmt & HDI_KEY_MGMT_FT_SAE, ret, pos, end, "+", "%sFT/SAE");
680
681 pos = HdiGetCipherTxt(pos, end, data.pairwiseCipher);
682
683 if ((unsigned int)data.capabilities & HDI_CAPABILITY_PREAUTH) {
684 ret = HdiTxtPrintf(pos, end - pos, "-preauth");
685 if (HdiCheckError(end - pos, ret)) {
686 return pos;
687 }
688 pos += ret;
689 }
690
691 ret = HdiTxtPrintf(pos, end - pos, "]");
692 if (HdiCheckError(end - pos, ret)) {
693 return pos;
694 }
695 pos += ret;
696
697 return pos;
698 }
699
HdiGetIeExt(const uint8_t * ies,size_t len,uint8_t ext)700 const uint8_t* HdiGetIeExt(const uint8_t *ies, size_t len, uint8_t ext)
701 {
702 const struct HdiElem *elem;
703
704 if (!ies) {
705 return NULL;
706 }
707 HDI_CHECK_ELEMENT_BY_EXTID(elem, ext, ies, len)
708 return &elem->id;
709
710 return NULL;
711 }
712
HdiBssGetIeExt(const uint8_t * ies,size_t len,uint8_t ext)713 const uint8_t* HdiBssGetIeExt(const uint8_t *ies, size_t len, uint8_t ext)
714 {
715 return HdiGetIeExt(ies, len, ext);
716 }
717
HdiBufEncode(char * txt,size_t maxlen,const uint8_t * data,size_t len)718 void HdiBufEncode(char *txt, size_t maxlen, const uint8_t *data, size_t len)
719 {
720 char *end = txt + maxlen;
721 size_t i;
722
723 for (i = 0; i < len; i++) {
724 if (txt + HDI_POS_FOURTH >= end) {
725 break;
726 }
727
728 switch (data[i]) {
729 case '\"':
730 *txt++ = '\\';
731 *txt++ = '\"';
732 break;
733 case '\\':
734 *txt++ = '\\';
735 *txt++ = '\\';
736 break;
737 case '\033':
738 *txt++ = '\\';
739 *txt++ = 'e';
740 break;
741 case '\n':
742 *txt++ = '\\';
743 *txt++ = 'n';
744 break;
745 case '\r':
746 *txt++ = '\\';
747 *txt++ = 'r';
748 break;
749 case '\t':
750 *txt++ = '\\';
751 *txt++ = 't';
752 break;
753 default:
754 if (data[i] >= HDI_POS_TT && data[i] <= HDI_POS_OTX) {
755 *txt++ = data[i];
756 } else {
757 txt += HdiTxtPrintf(txt, end - txt, "\\x%02x",
758 data[i]);
759 }
760 break;
761 }
762 }
763
764 *txt = '\0';
765 }
766
HdiSSid2Txt(const uint8_t * ssid,size_t ssidLen)767 const char* HdiSSid2Txt(const uint8_t *ssid, size_t ssidLen)
768 {
769 static char ssid_txt[SSID_MAX_LEN * HDI_POS_FOURTH + 1];
770 if (ssid == NULL) {
771 ssid_txt[0] = '\0';
772 return ssid_txt;
773 }
774
775 HdiBufEncode(ssid_txt, sizeof(ssid_txt), ssid, ssidLen);
776 return ssid_txt;
777 }
778
HdiGetWifiCategoryTxt(char * pos,char * end,const struct HdiElems * elems)779 char* HdiGetWifiCategoryTxt(char *pos, char* end, const struct HdiElems *elems)
780 {
781 int ret = 0;
782 if (elems->ehtCapabilities80211Be != NULL) {
783 ret = HdiTxtPrintf(pos, end - pos, "%s", "[11BE]");
784 } else if (elems->heCapabilities != NULL) {
785 ret = HdiTxtPrintf(pos, end - pos, "%s", "[11AX]");
786 }
787 if (HdiCheckError(end - pos, ret)) {
788 LOGE("HdiGetWifiCategoryTxt HdiCheckError fail");
789 return pos;
790 }
791 pos += ret;
792 return pos;
793 }
794
IsValidHexCharAndConvert(char c)795 int8_t IsValidHexCharAndConvert(char c)
796 {
797 if (c >= '0' && c <= '9') {
798 return c - '0';
799 }
800 if (c >= 'a' && c <= 'f') {
801 return c - 'a' + ('9' - '0' + 1);
802 }
803 if (c >= 'A' && c <= 'F') {
804 return c - 'A' + ('9' - '0' + 1);
805 }
806 return -1;
807 }
808
CheckMacIsValid(const char * macStr)809 int CheckMacIsValid(const char *macStr)
810 {
811 if (macStr == NULL || strlen(macStr) != MAC_STRING_SIZE) {
812 return -1;
813 }
814 for (int i = 0, j = 0; i < MAC_STRING_SIZE; ++i) {
815 if (j == 0 || j == 1) {
816 int v = IsValidHexCharAndConvert(macStr[i]);
817 if (v < 0) {
818 return -1;
819 }
820 ++j;
821 } else {
822 if (macStr[i] != ':') {
823 return -1;
824 }
825 j = 0;
826 }
827 }
828 return 0;
829 }
830
StrSafeCopy(char * dst,unsigned len,const char * src)831 void StrSafeCopy(char *dst, unsigned len, const char *src)
832 {
833 if (dst == NULL) {
834 return;
835 }
836 if (src == NULL) {
837 dst[0] = '\0';
838 return;
839 }
840 unsigned i = 0;
841 while (i + 1 < len && src[i] != '\0') {
842 dst[i] = src[i];
843 ++i;
844 }
845 dst[i] = '\0';
846 return;
847 }
848
HdiGetWapiTxt(char * pos,char * end,const uint8_t * ie)849 char* HdiGetWapiTxt(char *pos, char *end, const uint8_t *ie)
850 {
851 if (ie[HDI_POS_FIRST] < HDI_CAP_WAPI_BIT_OFFSET - HDI_POS_SECOND) {
852 return pos;
853 }
854
855 char *start;
856 int ret;
857
858 ret = HdiTxtPrintf(pos, end - pos, "[WAPI-");
859 if (HdiCheckError(end - pos, ret)) {
860 return pos;
861 }
862 pos += ret;
863
864 start = pos;
865 uint8_t akm = ie[HDI_CAP_WAPI_BIT_OFFSET];
866 HDI_HANDLE_CIPHER_POS_INFO(akm & HDI_KEY_MGMT_WAPI_CERT_AKM, ret, pos, end, "+", "%sCERT");
867 HDI_HANDLE_CIPHER_POS_INFO(akm & HDI_KEY_MGMT_WAPI_PSK_AKM, ret, pos, end, "+", "%sPSK");
868
869 ret = HdiTxtPrintf(pos, end - pos, "]");
870 if (HdiCheckError(end - pos, ret)) {
871 return pos;
872 }
873 pos += ret;
874
875 return pos;
876 }