From 8511a0f67b6ade371264a3c18ea4301c605a02aa Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 8 Sep 2014 12:54:18 +0300 Subject: [PATCH] WPS: Extend internal entropy pool help for key/snonce derivation 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 --- src/wps/wps_enrollee.c | 12 +++++++++++- src/wps/wps_registrar.c | 11 +++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c index f7d41b4de..9f5a90ce9 100644 --- a/src/wps/wps_enrollee.c +++ b/src/wps/wps_enrollee.c @@ -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)", diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index 00c8299ac..b90cc25e4 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -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;