diff --git a/hostapd/README-WPS b/hostapd/README-WPS index 2786c602e..e435a5655 100644 --- a/hostapd/README-WPS +++ b/hostapd/README-WPS @@ -94,6 +94,7 @@ eap_server=1 # WPS configuration (AP configured, do not allow external WPS Registrars) wps_state=2 ap_setup_locked=1 +# If UUID is not configured, it will be generated based on local MAC address. uuid=87654321-9abc-def0-1234-56789abc0000 wps_pin_requests=/var/run/hostapd.pin-req device_name=Wireless AP diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 973257350..c5d82e6ba 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -871,6 +871,7 @@ own_ip_addr=127.0.0.1 # Universally Unique IDentifier (UUID; see RFC 4122) of the device # This value is used as the UUID for the internal WPS Registrar. If the AP # is also using UPnP, this value should be set to the device's UPnP UUID. +# If not configured, UUID will be generated based on the local MAC address. #uuid=12345678-9abc-def0-1234-56789abcdef0 # Note: If wpa_psk_file is set, WPS is used to generate random, per-device PSKs diff --git a/hostapd/wps_hostapd.c b/hostapd/wps_hostapd.c index 4871d9c57..14966d941 100644 --- a/hostapd/wps_hostapd.c +++ b/hostapd/wps_hostapd.c @@ -383,7 +383,12 @@ int hostapd_init_wps(struct hostapd_data *hapd, os_memset(&cfg, 0, sizeof(cfg)); wps->wps_state = hapd->conf->wps_state; wps->ap_setup_locked = hapd->conf->ap_setup_locked; - os_memcpy(wps->uuid, hapd->conf->uuid, UUID_LEN); + if (is_nil_uuid(hapd->conf->uuid)) { + uuid_gen_mac_addr(hapd->own_addr, wps->uuid); + wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC address", + wps->uuid, UUID_LEN); + } else + os_memcpy(wps->uuid, hapd->conf->uuid, UUID_LEN); wps->ssid_len = hapd->conf->ssid.ssid_len; os_memcpy(wps->ssid, hapd->conf->ssid.ssid, wps->ssid_len); wps->ap = 1; diff --git a/src/utils/uuid.c b/src/utils/uuid.c index d8cc26754..620d3d610 100644 --- a/src/utils/uuid.c +++ b/src/utils/uuid.c @@ -15,6 +15,8 @@ #include "includes.h" #include "common.h" +#include "crypto.h" +#include "sha1.h" #include "uuid.h" int uuid_str2bin(const char *str, u8 *bin) @@ -75,3 +77,31 @@ int is_nil_uuid(const u8 *uuid) return 0; return 1; } + + +void uuid_gen_mac_addr(const u8 *mac_addr, u8 *uuid) +{ + const u8 *addr[2]; + size_t len[2]; + u8 hash[SHA1_MAC_LEN]; + u8 nsid[16] = { + 0x52, 0x64, 0x80, 0xf8, + 0xc9, 0x9b, + 0x4b, 0xe5, + 0xa6, 0x55, + 0x58, 0xed, 0x5f, 0x5d, 0x60, 0x84 + }; + + addr[0] = nsid; + len[0] = sizeof(nsid); + addr[1] = mac_addr; + len[1] = 6; + sha1_vector(2, addr, len, hash); + os_memcpy(uuid, hash, 16); + + /* Version: 5 = named-based version using SHA-1 */ + uuid[6] = (5 << 4) | (uuid[6] & 0x0f); + + /* Variant specified in RFC 4122 */ + uuid[8] = 0x80 | (uuid[8] & 0x3f); +} diff --git a/src/utils/uuid.h b/src/utils/uuid.h index 075916525..9fc2ba068 100644 --- a/src/utils/uuid.h +++ b/src/utils/uuid.h @@ -20,5 +20,6 @@ int uuid_str2bin(const char *str, u8 *bin); int uuid_bin2str(const u8 *bin, char *str, size_t max_len); int is_nil_uuid(const u8 *uuid); +void uuid_gen_mac_addr(const u8 *mac_addr, u8 *uuid); #endif /* UUID_H */ diff --git a/wpa_supplicant/README-WPS b/wpa_supplicant/README-WPS index b1aa0dcc1..284753ffb 100644 --- a/wpa_supplicant/README-WPS +++ b/wpa_supplicant/README-WPS @@ -67,7 +67,8 @@ CONFIG_WPS=y WPS needs the Universally Unique IDentifier (UUID; see RFC 4122) for the device. This is configured in the runtime configuration for -wpa_supplicant: +wpa_supplicant (if not set, UUID will be generated based on local MAC +address): # example UUID for WPS uuid=12345678-9abc-def0-1234-56789abcdef0 diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index c7b2dbdbd..a9f86ea95 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -181,7 +181,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) #ifdef CONFIG_WPS if (wps) { wps_ie = wps_build_probe_req_ie(wps == 2, &wpa_s->wps->dev, - wpa_s->conf->uuid, req_type); + wpa_s->wps->uuid, req_type); if (wps_ie) { extra_ie = wpabuf_head(wps_ie); extra_ie_len = wpabuf_len(wps_ie); diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index b92f43f07..cfcea8831 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -150,6 +150,7 @@ fast_reauth=1 # Wi-Fi Protected Setup (WPS) parameters # Universally Unique IDentifier (UUID; see RFC 4122) of the device +# If not configured, UUID will be generated based on the local MAC address. #uuid=12345678-9abc-def0-1234-56789abcdef0 # Device Name diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index eeee4969f..a538338a1 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -21,6 +21,7 @@ #include "eap_peer/eap.h" #include "wpa_supplicant_i.h" #include "eloop.h" +#include "uuid.h" #include "wpa_ctrl.h" #include "eap_common/eap_wsc_common.h" #include "wps/wps.h" @@ -442,7 +443,12 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s) wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version); wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ; /* TODO: config */ os_memcpy(wps->dev.mac_addr, wpa_s->own_addr, ETH_ALEN); - os_memcpy(wps->uuid, wpa_s->conf->uuid, 16); + if (is_nil_uuid(wpa_s->conf->uuid)) { + uuid_gen_mac_addr(wpa_s->own_addr, wps->uuid); + wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC address", + wps->uuid, WPS_UUID_LEN); + } else + os_memcpy(wps->uuid, wpa_s->conf->uuid, WPS_UUID_LEN); wpa_s->wps = wps;