1 /** @file wifi-wps.c
2 *
3 * @brief This file provides WPS IE and parser.
4 *
5 * Copyright 2008-2024 NXP
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10
11 #include <mlan_api.h>
12
13 #define SC_Device_Password_ID 0x1012
14
15 const t_u8 wps_oui[4] = {0x00, 0x50, 0xf2, 0x04};
16
17 typedef MLAN_PACK_START struct
18 {
19 t_u16 Type;
20 t_u16 Length;
21 } MLAN_PACK_END MrvlIEParamSet_t;
22
23 /**
24 * @brief Parsing Device Password ID
25 *
26 * @param message A pointer to buffer for parsing
27 * @param size Length of buffer
28 * @return Device Password ID
29 */
wps_parser(t_u8 * message,size_t size)30 static t_u16 wps_parser(t_u8 *message, size_t size)
31 {
32 t_u16 device_password_id = 0xffff;
33 MrvlIEParamSet_t *ptlv;
34 t_u8 *plast_byte, *data;
35 t_u16 len;
36
37 /* Beginning from Version, skip IE_ID/Length/SC_OUI field */
38 ptlv = (MrvlIEParamSet_t *)(message + 4);
39 data = (t_u8 *)ptlv;
40 plast_byte = (t_u8 *)(message + (t_u8)size);
41
42 while ((void *)ptlv < (void *)plast_byte)
43 {
44 /* Barriers are normally not required but do ensure the code is
45 * completely within the specified behaviour for the architecture. */
46 __asm volatile ( "dsb" ::: "memory" );
47 __asm volatile ( "isb" );
48
49 ptlv->Type = mlan_ntohs(ptlv->Type);
50 ptlv->Length = mlan_ntohs(ptlv->Length);
51
52 switch (ptlv->Type)
53 {
54 case SC_Device_Password_ID:
55 wifi_d("SC_Device_Password_ID :: ");
56 memcpy(&device_password_id, data, sizeof(t_u16));
57 device_password_id = mlan_ntohs(device_password_id);
58 wifi_d("device_password_id = 0x%x", device_password_id);
59 break;
60 default:
61 break;
62 }
63
64 len = ptlv->Length + sizeof(MrvlIEParamSet_t);
65
66 ptlv->Type = mlan_htons(ptlv->Type);
67 ptlv->Length = mlan_htons(ptlv->Length);
68
69 ptlv = (MrvlIEParamSet_t *)((t_u8 *)ptlv + len);
70
71 data = (t_u8 *)ptlv;
72 data += sizeof(MrvlIEParamSet_t);
73 } /* while */
74
75 return device_password_id;
76 }
77
check_for_wps_ie(const t_u8 * poui,t_u8 oui_type,bool * wps_IE_exist,t_u16 * wps_session,void * element_data,unsigned element_len)78 void check_for_wps_ie(
79 const t_u8 *poui, t_u8 oui_type, bool *wps_IE_exist, t_u16 *wps_session, void *element_data, unsigned element_len)
80 {
81 if (!memcmp(poui, &wps_oui, sizeof(wps_oui) - 1U) && oui_type == wps_oui[3])
82 {
83 /* WPS IE is present in probe response. */
84 wifi_d("WPS IE :: %x:%x:%x:%x", poui[0], poui[1], poui[2], oui_type);
85
86 *wps_IE_exist = true;
87 *wps_session = wps_parser(element_data, element_len);
88 }
89 else if (!(*wps_IE_exist))
90 {
91 *wps_IE_exist = false;
92 *wps_session = 0xffff;
93 }
94 }
95