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 <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2014-09-08 12:54:18 +03:00 committed by Jouni Malinen
parent abc05534aa
commit 8511a0f67b
2 changed files with 20 additions and 3 deletions

View 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)",

View 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;