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