1 /*
2 * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifdef ESP_SUPPLICANT
8
9 #include "utils/includes.h"
10 #include "utils/common.h"
11 #include "common/eapol_common.h"
12 #include "rsn_supp/wpa.h"
13 #include "rsn_supp/pmksa_cache.h"
14 #include "esp_wpas_glue.h"
15 #include "esp_private/wifi.h"
16
wpa_alloc_eapol(void * sm,u8 type,const void * data,u16 data_len,size_t * msg_len,void ** data_pos)17 u8 *wpa_alloc_eapol(void *sm, u8 type,
18 const void *data, u16 data_len,
19 size_t *msg_len, void **data_pos)
20 {
21 void *buffer;
22 struct ieee802_1x_hdr *hdr;
23
24 *msg_len = sizeof(struct ieee802_1x_hdr) + data_len;
25
26 buffer = os_malloc(*msg_len + sizeof(struct l2_ethhdr));
27
28 if (buffer == NULL) {
29 return NULL;
30 }
31
32 /* XXX: reserve l2_ethhdr is enough */
33 hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr));
34
35 hdr->version = DEFAULT_EAPOL_VERSION;
36 hdr->type = type;
37 hdr->length = host_to_be16(data_len);
38
39 if (data) {
40 memcpy(hdr + 1, data, data_len);
41 } else {
42 memset(hdr + 1, 0, data_len);
43 }
44
45 if (data_pos) {
46 *data_pos = hdr + 1;
47 }
48
49 return (u8 *) hdr;
50 }
51
wpa_free_eapol(u8 * buffer)52 void wpa_free_eapol(u8 *buffer)
53 {
54 if (!buffer) {
55 return;
56 }
57 buffer = buffer - sizeof(struct l2_ethhdr);
58 os_free(buffer);
59 }
60
wpa_ether_send(void * ctx,const u8 * dest,u16 proto,const u8 * data,size_t data_len)61 int wpa_ether_send(void *ctx, const u8 *dest, u16 proto,
62 const u8 *data, size_t data_len)
63 {
64 void *buffer = (void *)(data - sizeof(struct l2_ethhdr));
65 struct l2_ethhdr *eth = (struct l2_ethhdr *)buffer;
66
67 os_memcpy(eth->h_dest, dest, ETH_ALEN);
68 os_memcpy(eth->h_source, gWpaSm.own_addr, ETH_ALEN);
69 eth->h_proto = host_to_be16(proto);
70
71 return esp_wifi_internal_tx(WIFI_IF_STA, buffer, sizeof(struct l2_ethhdr) + data_len);
72 }
73
hostapd_send_eapol(const u8 * source,const u8 * sta_addr,const u8 * data,size_t data_len)74 int hostapd_send_eapol(const u8 *source, const u8 *sta_addr,
75 const u8 *data, size_t data_len)
76 {
77 void *buffer = os_malloc(data_len + sizeof(struct l2_ethhdr));
78 struct l2_ethhdr *eth = buffer;
79
80 if (!buffer){
81 wpa_printf( MSG_DEBUG, "send_eapol, buffer=%p", buffer);
82 return -1;
83 }
84
85 memcpy(eth->h_dest, sta_addr, ETH_ALEN);
86 memcpy(eth->h_source, source, ETH_ALEN);
87 eth->h_proto = host_to_be16(ETH_P_EAPOL);
88
89 memcpy((char *)buffer + sizeof(struct l2_ethhdr), data, data_len);
90 esp_wifi_internal_tx(WIFI_IF_AP, buffer, sizeof(struct l2_ethhdr) + data_len);
91 os_free(buffer);
92 return 0;
93
94 }
95
disable_wpa_wpa2(void)96 static void disable_wpa_wpa2(void)
97 {
98 esp_wifi_sta_disable_wpa2_authmode_internal();
99 }
100
wpa_supplicant_transition_disable(struct wpa_sm * sm,u8 bitmap)101 void wpa_supplicant_transition_disable(struct wpa_sm *sm, u8 bitmap)
102 {
103 wpa_printf(MSG_DEBUG, "TRANSITION_DISABLE %02x", bitmap);
104
105 if ((bitmap & TRANSITION_DISABLE_WPA3_PERSONAL) &&
106 wpa_key_mgmt_sae(sm->key_mgmt)) {
107 disable_wpa_wpa2();
108 }
109
110 if ((bitmap & TRANSITION_DISABLE_SAE_PK) &&
111 wpa_key_mgmt_sae(sm->key_mgmt)) {
112 wpa_printf(MSG_INFO,
113 "SAE-PK: SAE authentication without PK disabled based on AP notification");
114 disable_wpa_wpa2();
115 esp_wifi_enable_sae_pk_only_mode_internal();
116 }
117
118 if ((bitmap & TRANSITION_DISABLE_WPA3_ENTERPRISE) &&
119 wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) {
120 disable_wpa_wpa2();
121 }
122
123 if ((bitmap & TRANSITION_DISABLE_ENHANCED_OPEN) &&
124 wpa_key_mgmt_owe(sm->key_mgmt)) {
125 esp_wifi_sta_disable_owe_trans_internal();
126 }
127 }
128
wpa_sm_alloc_eapol(struct wpa_sm * sm,u8 type,const void * data,u16 data_len,size_t * msg_len,void ** data_pos)129 u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
130 const void *data, u16 data_len,
131 size_t *msg_len, void **data_pos)
132 {
133 return wpa_alloc_eapol(sm, type, data, data_len, msg_len, data_pos);
134 }
135
wpa_sm_free_eapol(u8 * buffer)136 void wpa_sm_free_eapol(u8 *buffer)
137 {
138 return wpa_free_eapol(buffer);
139 }
140
wpa_sm_deauthenticate(struct wpa_sm * sm,u8 reason_code)141 void wpa_sm_deauthenticate(struct wpa_sm *sm, u8 reason_code)
142 {
143 /*only need send deauth frame when associated*/
144 if (WPA_SM_STATE(sm) >= WPA_ASSOCIATED) {
145 pmksa_cache_clear_current(sm);
146 wpa_deauthenticate(reason_code);
147 }
148 }
149
150 /**
151 * mlme_setprotection - MLME-SETPROTECTION.request primitive
152 * @priv: Private driver interface data
153 * @addr: Address of the station for which to set protection (may be
154 * %NULL for group keys)
155 * @protect_type: MLME_SETPROTECTION_PROTECT_TYPE_*
156 * @key_type: MLME_SETPROTECTION_KEY_TYPE_*
157 * Returns: 0 on success, -1 on failure
158 *
159 * This is an optional function that can be used to set the driver to
160 * require protection for Tx and/or Rx frames. This uses the layer
161 * interface defined in IEEE 802.11i-2004 clause 10.3.22.1
162 * (MLME-SETPROTECTION.request). Many drivers do not use explicit
163 * set protection operation; instead, they set protection implicitly
164 * based on configured keys.
165 */
wpa_sm_mlme_setprotection(struct wpa_sm * sm,const u8 * addr,int protect_type,int key_type)166 int wpa_sm_mlme_setprotection(struct wpa_sm *sm, const u8 *addr,
167 int protect_type, int key_type)
168 {
169 return 0;
170 }
171
172 /*
173 *use above two functions to get wpa_ie and rsn_ie, then don't need wpa_sm_get_beacon_ie function
174 */
wpa_sm_get_beacon_ie(struct wpa_sm * sm)175 int wpa_sm_get_beacon_ie(struct wpa_sm *sm)
176 {
177 return 0;
178 }
179
180 /**
181 * wpa_supplicant_disassociate - Disassociate the current connection
182 * @wpa_s: Pointer to wpa_supplicant data
183 * @reason_code: IEEE 802.11 reason code for the disassociate frame
184 *
185 * This function is used to request %wpa_supplicant to disassociate with the
186 * current AP.
187 */
wpa_sm_disassociate(struct wpa_sm * sm,int reason_code)188 void wpa_sm_disassociate(struct wpa_sm *sm, int reason_code)
189 {
190 /*check if need clear internal state and data value*/
191 }
192 #endif
193