]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Add option for using random UUID
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 13 Apr 2017 10:22:56 +0000 (13:22 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 13 Apr 2017 14:38:55 +0000 (17:38 +0300)
If the uuid configuration parameter is not set, wpa_supplicant generates
an UUID automatically to allow WPS operations to proceed. This was
previously always using an UUID generated from the MAC address. This
commit adds an option to use a random UUID instead. The type of the
automatically generated UUID is set with the auto_uuid parameter: 0 =
based on MAC address (default; old behavior), 1 = random UUID.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/utils/uuid.c
src/utils/uuid.h
wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/config_file.c
wpa_supplicant/config_winreg.c
wpa_supplicant/wpa_supplicant.conf
wpa_supplicant/wps_supplicant.c

index 0f224f976b803727bce969731eac6b119d74ad09..98e43d02f68b5132be5f1261e79cc2d2765760f9 100644 (file)
@@ -9,6 +9,7 @@
 #include "includes.h"
 
 #include "common.h"
+#include "crypto/sha256.h"
 #include "uuid.h"
 
 int uuid_str2bin(const char *str, u8 *bin)
@@ -69,3 +70,27 @@ int is_nil_uuid(const u8 *uuid)
                        return 0;
        return 1;
 }
+
+
+int uuid_random(u8 *uuid)
+{
+       struct os_time t;
+       u8 hash[SHA256_MAC_LEN];
+
+       /* Use HMAC-SHA256 and timestamp as context to avoid exposing direct
+        * os_get_random() output in the UUID field. */
+       os_get_time(&t);
+       if (os_get_random(uuid, UUID_LEN) < 0 ||
+           hmac_sha256(uuid, UUID_LEN, (const u8 *) &t, sizeof(t), hash) < 0)
+               return -1;
+
+       os_memcpy(uuid, hash, UUID_LEN);
+
+       /* Version: 4 = random */
+       uuid[6] = (4 << 4) | (uuid[6] & 0x0f);
+
+       /* Variant specified in RFC 4122 */
+       uuid[8] = 0x80 | (uuid[8] & 0x3f);
+
+       return 0;
+}
index 5e860cbc5936615c19146357245a888f9fba2f0a..6e20210f99b9c79b464b48a8a19d35c7550cfd7a 100644 (file)
@@ -14,5 +14,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);
+int uuid_random(u8 *uuid);
 
 #endif /* UUID_H */
index 9e54f6cadcfe233f059df0e248edfacd2deb362e..9ef11d86d88f3f2eadea3f5826c5f1aa1254213e 100644 (file)
@@ -4408,6 +4408,7 @@ static const struct global_parse_data global_fields[] = {
        { FUNC_NO_VAR(load_dynamic_eap), 0 },
 #ifdef CONFIG_WPS
        { FUNC(uuid), CFG_CHANGED_UUID },
+       { INT_RANGE(auto_uuid, 0, 1), 0 },
        { STR_RANGE(device_name, 0, WPS_DEV_NAME_MAX_LEN),
          CFG_CHANGED_DEVICE_NAME },
        { STR_RANGE(manufacturer, 0, 64), CFG_CHANGED_WPS_STRING },
index a7b043561a6061f2733d11beb8c4fb9946725a0c..c883c18c3845fbe26da6cc33738dcb5af5039e2e 100644 (file)
@@ -625,6 +625,13 @@ struct wpa_config {
         */
        u8 uuid[16];
 
+       /**
+        * auto_uuid - Automatic UUID behavior
+        * 0 = generate static value based on the local MAC address (default)
+        * 1 = generate a random UUID every time wpa_supplicant starts
+        */
+       int auto_uuid;
+
        /**
         * device_name - Device Name (WPS)
         * User-friendly description of device; up to 32 octets encoded in
index e8f11493e55978c934ddb36fbd90e384adfd5e23..3a44c8a0df766041757333d5d1a4eed57b80e5a5 100644 (file)
@@ -1088,6 +1088,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
                uuid_bin2str(config->uuid, buf, sizeof(buf));
                fprintf(f, "uuid=%s\n", buf);
        }
+       if (config->auto_uuid)
+               fprintf(f, "auto_uuid=%d\n", config->auto_uuid);
        if (config->device_name)
                fprintf(f, "device_name=%s\n", config->device_name);
        if (config->manufacturer)
index 6bea597600a3abc68ba10224467ab8a798ed0189..b22ed5c669859b0eb5a432bd52fd99421be46ec5 100644 (file)
@@ -233,6 +233,7 @@ static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
 #ifdef CONFIG_WPS
        if (wpa_config_read_global_uuid(config, hk))
                errors++;
+       wpa_config_read_reg_dword(hk, TEXT("auto_uuid"), &config->auto_uuid);
        config->device_name = wpa_config_read_reg_string(
                hk, TEXT("device_name"));
        config->manufacturer = wpa_config_read_reg_string(
@@ -579,6 +580,8 @@ static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
                uuid_bin2str(config->uuid, buf, sizeof(buf));
                wpa_config_write_reg_string(hk, "uuid", buf);
        }
+       wpa_config_write_reg_dword(hk, TEXT("auto_uuid"), config->auto_uuid,
+                                  0);
        wpa_config_write_reg_string(hk, "device_name", config->device_name);
        wpa_config_write_reg_string(hk, "manufacturer", config->manufacturer);
        wpa_config_write_reg_string(hk, "model_name", config->model_name);
index 6dac20e2029270beb8ea68ea21d504b5c66f7c5e..c07badbde07feadbd96a49144692f6bfeab12f87 100644 (file)
@@ -218,9 +218,15 @@ 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.
+# If not configured, UUID will be generated based on the mechanism selected with
+# the auto_uuid parameter.
 #uuid=12345678-9abc-def0-1234-56789abcdef0
 
+# Automatic UUID behavior
+# 0 = generate static value based on the local MAC address (default)
+# 1 = generate a random UUID every time wpa_supplicant starts
+#auto_uuid=0
+
 # Device Name
 # User-friendly description of device; up to 32 octets encoded in UTF-8
 #device_name=Wireless Client
index 2117b009f70a33eed9f0d2ea9b6ba3943b71af13..3b12c8f3cea588a6d183da589388abf9ce0acb55 100644 (file)
@@ -1481,6 +1481,9 @@ static void wpas_wps_set_uuid(struct wpa_supplicant *wpa_s,
                                          wpa_s->global->ifaces->wps->uuid,
                                          WPS_UUID_LEN);
                        src = "from the first interface";
+               } else if (wpa_s->conf->auto_uuid == 1) {
+                       uuid_random(wps->uuid);
+                       src = "based on random data";
                } else {
                        uuid_gen_mac_addr(wpa_s->own_addr, wps->uuid);
                        src = "based on MAC address";