DPP: Fix config exchange with gas_rand_mac_addr

Do not use a random MAC address for the GAS exchange that is used as
part of the DPP protocol exchange since that would break DPP.
Configurator expects the same MAC address to be used for DPP
Authentication exchange and DPP Configuration exchange (GAS).

Since the DPP Authentication exchange has already used the MAC address
configured on the interface, use of a random address for the GAS
exchange would not provide any additional privacy protection. If a
random MAC address needs to be used for this type of an exchange, that
random address would need to be first configured on the interface before
starting DPP exchange.

This does not change GAS query behavior for any other use case, i.e.,
the gas_rand_mac_addr configuration continues to apply to all the
Interworking/Hotspot 2.0 uses.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2020-04-22 17:04:43 +03:00 committed by Jouni Malinen
parent de3f8d9fd1
commit 0c5edededa
6 changed files with 34 additions and 9 deletions

View File

@ -1428,7 +1428,7 @@ static void wpas_dpp_start_gas_client(struct wpa_supplicant *wpa_s)
MAC2STR(auth->peer_mac_addr), auth->curr_freq); MAC2STR(auth->peer_mac_addr), auth->curr_freq);
res = gas_query_req(wpa_s->gas, auth->peer_mac_addr, auth->curr_freq, res = gas_query_req(wpa_s->gas, auth->peer_mac_addr, auth->curr_freq,
1, buf, wpas_dpp_gas_resp_cb, wpa_s); 1, 1, buf, wpas_dpp_gas_resp_cb, wpa_s);
if (res < 0) { if (res < 0) {
wpa_msg(wpa_s, MSG_DEBUG, "GAS: Failed to send Query Request"); wpa_msg(wpa_s, MSG_DEBUG, "GAS: Failed to send Query Request");
wpabuf_free(buf); wpabuf_free(buf);

View File

@ -43,6 +43,7 @@ struct gas_query_pending {
unsigned int offchannel_tx_started:1; unsigned int offchannel_tx_started:1;
unsigned int retry:1; unsigned int retry:1;
unsigned int wildcard_bssid:1; unsigned int wildcard_bssid:1;
unsigned int maintain_addr:1;
int freq; int freq;
u16 status_code; u16 status_code;
struct wpabuf *req; struct wpabuf *req;
@ -693,7 +694,8 @@ static void gas_query_start_cb(struct wpa_radio_work *work, int deinit)
return; return;
} }
if (wpas_update_random_addr_disassoc(wpa_s) < 0) { if (!query->maintain_addr &&
wpas_update_random_addr_disassoc(wpa_s) < 0) {
wpa_msg(wpa_s, MSG_INFO, wpa_msg(wpa_s, MSG_INFO,
"Failed to assign random MAC address for GAS"); "Failed to assign random MAC address for GAS");
gas_query_free(query, 1); gas_query_free(query, 1);
@ -749,12 +751,23 @@ static int gas_query_set_sa(struct gas_query *gas,
struct wpa_supplicant *wpa_s = gas->wpa_s; struct wpa_supplicant *wpa_s = gas->wpa_s;
struct os_reltime now; struct os_reltime now;
if (!wpa_s->conf->gas_rand_mac_addr || if (query->maintain_addr ||
!wpa_s->conf->gas_rand_mac_addr ||
!(wpa_s->current_bss ? !(wpa_s->current_bss ?
(wpa_s->drv_flags & (wpa_s->drv_flags &
WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED) : WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED) :
(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA))) { (wpa_s->drv_flags & WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA))) {
/* Use own MAC address as the transmitter address */ /* Use own MAC address as the transmitter address */
wpa_printf(MSG_DEBUG,
"GAS: Use own MAC address as the transmitter address%s%s%s",
query->maintain_addr ? " (maintain_addr)" : "",
!wpa_s->conf->gas_rand_mac_addr ? " (no gas_rand_mac_adr set)" : "",
!(wpa_s->current_bss ?
(wpa_s->drv_flags &
WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED) :
(wpa_s->drv_flags &
WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA)) ?
" (no driver rand capa" : "");
os_memcpy(query->sa, wpa_s->own_addr, ETH_ALEN); os_memcpy(query->sa, wpa_s->own_addr, ETH_ALEN);
return 0; return 0;
} }
@ -800,6 +813,9 @@ static int gas_query_set_sa(struct gas_query *gas,
* @gas: GAS query data from gas_query_init() * @gas: GAS query data from gas_query_init()
* @dst: Destination MAC address for the query * @dst: Destination MAC address for the query
* @freq: Frequency (in MHz) for the channel on which to send the query * @freq: Frequency (in MHz) for the channel on which to send the query
* @wildcard_bssid: Force use of wildcard BSSID value
* @maintain_addr: Maintain own MAC address for exchange (i.e., ignore MAC
* address randomization rules)
* @req: GAS query payload (to be freed by gas_query module in case of success * @req: GAS query payload (to be freed by gas_query module in case of success
* return) * return)
* @cb: Callback function for reporting GAS query result and response * @cb: Callback function for reporting GAS query result and response
@ -807,7 +823,7 @@ static int gas_query_set_sa(struct gas_query *gas,
* Returns: dialog token (>= 0) on success or -1 on failure * Returns: dialog token (>= 0) on success or -1 on failure
*/ */
int gas_query_req(struct gas_query *gas, const u8 *dst, int freq, int gas_query_req(struct gas_query *gas, const u8 *dst, int freq,
int wildcard_bssid, struct wpabuf *req, int wildcard_bssid, int maintain_addr, struct wpabuf *req,
void (*cb)(void *ctx, const u8 *dst, u8 dialog_token, void (*cb)(void *ctx, const u8 *dst, u8 dialog_token,
enum gas_query_result result, enum gas_query_result result,
const struct wpabuf *adv_proto, const struct wpabuf *adv_proto,
@ -829,6 +845,7 @@ int gas_query_req(struct gas_query *gas, const u8 *dst, int freq,
return -1; return -1;
query->gas = gas; query->gas = gas;
query->maintain_addr = !!maintain_addr;
if (gas_query_set_sa(gas, query)) { if (gas_query_set_sa(gas, query)) {
os_free(query); os_free(query);
return -1; return -1;

View File

@ -35,7 +35,7 @@ enum gas_query_result {
}; };
int gas_query_req(struct gas_query *gas, const u8 *dst, int freq, int gas_query_req(struct gas_query *gas, const u8 *dst, int freq,
int wildcard_bssid, struct wpabuf *req, int wildcard_bssid, int maintain_addr, struct wpabuf *req,
void (*cb)(void *ctx, const u8 *dst, u8 dialog_token, void (*cb)(void *ctx, const u8 *dst, u8 dialog_token,
enum gas_query_result result, enum gas_query_result result,
const struct wpabuf *adv_proto, const struct wpabuf *adv_proto,

View File

@ -288,7 +288,8 @@ int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes,
if (buf == NULL) if (buf == NULL)
return -1; return -1;
res = gas_query_req(wpa_s->gas, dst, freq, 0, buf, anqp_resp_cb, wpa_s); res = gas_query_req(wpa_s->gas, dst, freq, 0, 0, buf, anqp_resp_cb,
wpa_s);
if (res < 0) { if (res < 0) {
wpa_printf(MSG_DEBUG, "ANQP: Failed to send Query Request"); wpa_printf(MSG_DEBUG, "ANQP: Failed to send Query Request");
wpabuf_free(buf); wpabuf_free(buf);

View File

@ -316,7 +316,7 @@ static int interworking_anqp_send_req(struct wpa_supplicant *wpa_s,
if (buf == NULL) if (buf == NULL)
return -1; return -1;
res = gas_query_req(wpa_s->gas, bss->bssid, bss->freq, 0, buf, res = gas_query_req(wpa_s->gas, bss->bssid, bss->freq, 0, 0, buf,
interworking_anqp_resp_cb, wpa_s); interworking_anqp_resp_cb, wpa_s);
if (res < 0) { if (res < 0) {
wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Failed to send Query Request"); wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Failed to send Query Request");
@ -2804,7 +2804,8 @@ int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
if (buf == NULL) if (buf == NULL)
return -1; return -1;
res = gas_query_req(wpa_s->gas, dst, freq, 0, buf, anqp_resp_cb, wpa_s); res = gas_query_req(wpa_s->gas, dst, freq, 0, 0, buf, anqp_resp_cb,
wpa_s);
if (res < 0) { if (res < 0) {
wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Failed to send Query Request"); wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Failed to send Query Request");
wpabuf_free(buf); wpabuf_free(buf);
@ -3243,7 +3244,8 @@ int gas_send_request(struct wpa_supplicant *wpa_s, const u8 *dst,
} else } else
wpabuf_put_le16(buf, 0); wpabuf_put_le16(buf, 0);
res = gas_query_req(wpa_s->gas, dst, freq, 0, buf, gas_resp_cb, wpa_s); res = gas_query_req(wpa_s->gas, dst, freq, 0, 0, buf, gas_resp_cb,
wpa_s);
if (res < 0) { if (res < 0) {
wpa_msg(wpa_s, MSG_DEBUG, "GAS: Failed to send Query Request"); wpa_msg(wpa_s, MSG_DEBUG, "GAS: Failed to send Query Request");
wpabuf_free(buf); wpabuf_free(buf);

View File

@ -481,6 +481,11 @@ fast_reauth=1
# 0 = use permanent MAC address # 0 = use permanent MAC address
# 1 = use random MAC address # 1 = use random MAC address
# 2 = like 1, but maintain OUI (with local admin bit set) # 2 = like 1, but maintain OUI (with local admin bit set)
# Note that this setting is ignored when a specific MAC address is needed for
# a full protocol exchange that includes GAS, e.g., when going through a DPP
# exchange that exposes the configured interface address as part of the DP
# Public Action frame exchanges before using GAS. That same address is then used
# during the GAS exchange as well to avoid breaking the protocol expectations.
#gas_rand_mac_addr=0 #gas_rand_mac_addr=0
# Lifetime of GAS random MAC address in seconds (default: 60) # Lifetime of GAS random MAC address in seconds (default: 60)