EAP-pwd peer: Fix payload length validation for Commit and Confirm

The length of the received Commit and Confirm message payloads was not
checked before reading them. This could result in a buffer read
overflow when processing an invalid message.

Fix this by verifying that the payload is of expected length before
processing it. In addition, enforce correct state transition sequence to
make sure there is no unexpected behavior if receiving a Commit/Confirm
message before the previous exchanges have been completed.

Thanks to Kostya Kortchinsky of Google security team for discovering and
reporting this issue.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2015-05-01 16:37:45 +03:00
parent f79a5fa006
commit dd2f043c9c

View file

@ -355,6 +355,23 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
BIGNUM *mask = NULL, *x = NULL, *y = NULL, *cofactor = NULL;
u16 offset;
u8 *ptr, *scalar = NULL, *element = NULL;
size_t prime_len, order_len;
if (data->state != PWD_Commit_Req) {
ret->ignore = TRUE;
goto fin;
}
prime_len = BN_num_bytes(data->grp->prime);
order_len = BN_num_bytes(data->grp->order);
if (payload_len != 2 * prime_len + order_len) {
wpa_printf(MSG_INFO,
"EAP-pwd: Unexpected Commit payload length %u (expected %u)",
(unsigned int) payload_len,
(unsigned int) (2 * prime_len + order_len));
goto fin;
}
if (((data->private_value = BN_new()) == NULL) ||
((data->my_element = EC_POINT_new(data->grp->group)) == NULL) ||
@ -554,6 +571,18 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr;
int offset;
if (data->state != PWD_Confirm_Req) {
ret->ignore = TRUE;
goto fin;
}
if (payload_len != SHA256_MAC_LEN) {
wpa_printf(MSG_INFO,
"EAP-pwd: Unexpected Confirm payload length %u (expected %u)",
(unsigned int) payload_len, SHA256_MAC_LEN);
goto fin;
}
/*
* first build up the ciphersuite which is group | random_function |
* prf