]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Extend internal entropy pool help for key/snonce derivation
authorJouni Malinen <jouni@qca.qualcomm.com>
Mon, 8 Sep 2014 09:54:18 +0000 (12:54 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 8 Sep 2014 09:54:18 +0000 (12:54 +0300)
The internal entropy pool was previously used to prevent 4-way handshake
in AP mode from completing before sufficient entropy was available to
allow secure keys to be generated. This commit extends that workaround
for boards that do not provide secure OS level PRNG (e.g., /dev/urandom
does not get enough entropy) for the most critical WPS operations by
rejecting AP-as-enrollee case (use of AP PIN to learn/modify AP
configuration) and new PSK/passphrase generation. This does not have any
effect on devices that have an appropriately working OS level PRNG
(e.g., /dev/random and /dev/urandom on Linux).

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/wps/wps_enrollee.c
src/wps/wps_registrar.c

index f7d41b4dee21f1e0a599c11524ddeda6014323ce..9f5a90ce928fc10927787c730f4a01d822ca645e 100644 (file)
@@ -175,6 +175,12 @@ static struct wpabuf * wps_build_m3(struct wps_data *wps)
        }
        wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
 
+       if (wps->wps->ap && random_pool_ready() != 1) {
+               wpa_printf(MSG_INFO,
+                          "WPS: Not enough entropy in random pool to proceed - do not allow AP PIN to be used");
+               return NULL;
+       }
+
        msg = wpabuf_alloc(1000);
        if (msg == NULL)
                return NULL;
@@ -268,8 +274,12 @@ static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
                char hex[65];
                u8 psk[32];
                /* Generate a random per-device PSK */
-               if (random_get_bytes(psk, sizeof(psk)) < 0)
+               if (random_pool_ready() != 1 ||
+                   random_get_bytes(psk, sizeof(psk)) < 0) {
+                       wpa_printf(MSG_INFO,
+                                  "WPS: Could not generate random PSK");
                        return -1;
+               }
                wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
                                psk, sizeof(psk));
                wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%u)",
index 00c8299ac0b8e9874d679ffddbddc85319d58f3a..b90cc25e412e661d5584330cc4cf2e9bfb765c9a 100644 (file)
@@ -1640,8 +1640,12 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
            !wps->wps->registrar->disable_auto_conf) {
                u8 r[16];
                /* Generate a random passphrase */
-               if (random_get_bytes(r, sizeof(r)) < 0)
+               if (random_pool_ready() != 1 ||
+                   random_get_bytes(r, sizeof(r)) < 0) {
+                       wpa_printf(MSG_INFO,
+                                  "WPS: Could not generate random PSK");
                        return -1;
+               }
                os_free(wps->new_psk);
                wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
                if (wps->new_psk == NULL)
@@ -1674,7 +1678,10 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
                wps->new_psk = os_malloc(wps->new_psk_len);
                if (wps->new_psk == NULL)
                        return -1;
-               if (random_get_bytes(wps->new_psk, wps->new_psk_len) < 0) {
+               if (random_pool_ready() != 1 ||
+                   random_get_bytes(wps->new_psk, wps->new_psk_len) < 0) {
+                       wpa_printf(MSG_INFO,
+                                  "WPS: Could not generate random PSK");
                        os_free(wps->new_psk);
                        wps->new_psk = NULL;
                        return -1;