aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@codeaurora.org>2019-09-07 15:38:29 (GMT)
committerJouni Malinen <j@w1.fi>2019-10-14 16:38:41 (GMT)
commitecd71140728f4576692064d79559e0a48121907e (patch)
tree89bb42837b499ede505b28be2daf65a1065b4603
parent86f6084862cd218d04b5213e7ac9df2e66ec138e (diff)
downloadhostap-ecd71140728f4576692064d79559e0a48121907e.zip
hostap-ecd71140728f4576692064d79559e0a48121907e.tar.gz
hostap-ecd71140728f4576692064d79559e0a48121907e.tar.bz2
SAE: Parse Rejected Groups element from H2E SAE commit
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
-rw-r--r--src/common/sae.c78
-rw-r--r--src/common/sae.h1
2 files changed, 67 insertions, 12 deletions
diff --git a/src/common/sae.c b/src/common/sae.c
index 30a5e18..49b9e90 100644
--- a/src/common/sae.c
+++ b/src/common/sae.c
@@ -107,6 +107,7 @@ void sae_clear_temp_data(struct sae_data *sae)
crypto_ec_point_deinit(tmp->own_commit_element_ecc, 0);
crypto_ec_point_deinit(tmp->peer_commit_element_ecc, 0);
wpabuf_free(tmp->anti_clogging_token);
+ wpabuf_free(tmp->peer_rejected_groups);
os_free(tmp->pw_id);
bin_clear_free(tmp, sizeof(*tmp));
sae->tmp = NULL;
@@ -849,9 +850,19 @@ static int sae_is_password_id_elem(const u8 *pos, const u8 *end)
}
+static int sae_is_rejected_groups_elem(const u8 *pos, const u8 *end)
+{
+ return end - pos >= 3 &&
+ pos[0] == WLAN_EID_EXTENSION &&
+ pos[1] >= 2 &&
+ end - pos - 2 >= pos[1] &&
+ pos[2] == WLAN_EID_EXT_REJECTED_GROUPS;
+}
+
+
static void sae_parse_commit_token(struct sae_data *sae, const u8 **pos,
const u8 *end, const u8 **token,
- size_t *token_len)
+ size_t *token_len, int h2e)
{
size_t scalar_elem_len, tlen;
const u8 *elem;
@@ -872,6 +883,8 @@ static void sae_parse_commit_token(struct sae_data *sae, const u8 **pos,
* fields, so use that length as a requirement for the received
* token and check for the presence of possible Password
* Identifier element based on the element header information.
+ * When parsing H2E case, also consider the Rejected Groupd element
+ * similarly.
*/
tlen = end - (*pos + scalar_elem_len);
@@ -889,12 +902,27 @@ static void sae_parse_commit_token(struct sae_data *sae, const u8 **pos,
* this frame. */
return;
}
+ if (h2e && sae_is_rejected_groups_elem(elem, end)) {
+ /* Rejected Groups takes out all available extra octets, so
+ * there can be no Anti-Clogging token in this frame. */
+ return;
+ }
elem += SHA256_MAC_LEN;
if (sae_is_password_id_elem(elem, end)) {
/* Password Identifier element is included in the end, so
* remove its length from the Anti-Clogging token field. */
tlen -= 2 + elem[1];
+ elem += 2 + elem[1];
+ if (h2e && sae_is_rejected_groups_elem(elem, end)) {
+ /* Also remove Rejected Groups element from the
+ * Anti-Clogging token field length */
+ tlen -= 2 + elem[1];
+ }
+ } else if (h2e && sae_is_rejected_groups_elem(elem, end)) {
+ /* Rejected Groups element is included in the end, so
+ * remove its length from the Anti-Clogging token field. */
+ tlen -= 2 + elem[1];
}
wpa_hexdump(MSG_DEBUG, "SAE: Anti-Clogging Token", *pos, tlen);
@@ -1061,11 +1089,11 @@ static u16 sae_parse_commit_element(struct sae_data *sae, const u8 **pos,
static int sae_parse_password_identifier(struct sae_data *sae,
- const u8 *pos, const u8 *end)
+ const u8 **pos, const u8 *end)
{
wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame",
- pos, end - pos);
- if (!sae_is_password_id_elem(pos, end)) {
+ *pos, end - *pos);
+ if (!sae_is_password_id_elem(*pos, end)) {
if (sae->tmp->pw_id) {
wpa_printf(MSG_DEBUG,
"SAE: No Password Identifier included, but expected one (%s)",
@@ -1078,8 +1106,8 @@ static int sae_parse_password_identifier(struct sae_data *sae,
}
if (sae->tmp->pw_id &&
- (pos[1] - 1 != (int) os_strlen(sae->tmp->pw_id) ||
- os_memcmp(sae->tmp->pw_id, pos + 3, pos[1] - 1) != 0)) {
+ ((*pos)[1] - 1 != (int) os_strlen(sae->tmp->pw_id) ||
+ os_memcmp(sae->tmp->pw_id, (*pos) + 3, (*pos)[1] - 1) != 0)) {
wpa_printf(MSG_DEBUG,
"SAE: The included Password Identifier does not match the expected one (%s)",
sae->tmp->pw_id);
@@ -1087,13 +1115,32 @@ static int sae_parse_password_identifier(struct sae_data *sae,
}
os_free(sae->tmp->pw_id);
- sae->tmp->pw_id = os_malloc(pos[1]);
+ sae->tmp->pw_id = os_malloc((*pos)[1]);
if (!sae->tmp->pw_id)
return WLAN_STATUS_UNSPECIFIED_FAILURE;
- os_memcpy(sae->tmp->pw_id, pos + 3, pos[1] - 1);
- sae->tmp->pw_id[pos[1] - 1] = '\0';
+ os_memcpy(sae->tmp->pw_id, (*pos) + 3, (*pos)[1] - 1);
+ sae->tmp->pw_id[(*pos)[1] - 1] = '\0';
wpa_hexdump_ascii(MSG_DEBUG, "SAE: Received Password Identifier",
- sae->tmp->pw_id, pos[1] - 1);
+ sae->tmp->pw_id, (*pos)[1] - 1);
+ *pos = *pos + 2 + (*pos)[1];
+ return WLAN_STATUS_SUCCESS;
+}
+
+
+static int sae_parse_rejected_groups(struct sae_data *sae,
+ const u8 *pos, const u8 *end)
+{
+ wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame",
+ pos, end - pos);
+ if (!sae_is_rejected_groups_elem(pos, end))
+ return WLAN_STATUS_SUCCESS;
+ wpabuf_free(sae->tmp->peer_rejected_groups);
+ sae->tmp->peer_rejected_groups = wpabuf_alloc(pos[1] - 1);
+ if (!sae->tmp->peer_rejected_groups)
+ return WLAN_STATUS_UNSPECIFIED_FAILURE;
+ wpabuf_put_data(sae->tmp->peer_rejected_groups, pos + 3, pos[1] - 1);
+ wpa_hexdump_buf(MSG_DEBUG, "SAE: Received Rejected Groups list",
+ sae->tmp->peer_rejected_groups);
return WLAN_STATUS_SUCCESS;
}
@@ -1114,7 +1161,7 @@ u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
pos += 2;
/* Optional Anti-Clogging Token */
- sae_parse_commit_token(sae, &pos, end, token, token_len);
+ sae_parse_commit_token(sae, &pos, end, token, token_len, h2e);
/* commit-scalar */
res = sae_parse_commit_scalar(sae, &pos, end);
@@ -1127,10 +1174,17 @@ u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
return res;
/* Optional Password Identifier element */
- res = sae_parse_password_identifier(sae, pos, end);
+ res = sae_parse_password_identifier(sae, &pos, end);
if (res != WLAN_STATUS_SUCCESS)
return res;
+ /* Conditional Rejected Groups element */
+ if (h2e) {
+ res = sae_parse_rejected_groups(sae, pos, end);
+ if (res != WLAN_STATUS_SUCCESS)
+ return res;
+ }
+
/*
* Check whether peer-commit-scalar and PEER-COMMIT-ELEMENT are same as
* the values we sent which would be evidence of a reflection attack.
diff --git a/src/common/sae.h b/src/common/sae.h
index ef7cf91..fee0b19 100644
--- a/src/common/sae.h
+++ b/src/common/sae.h
@@ -43,6 +43,7 @@ struct sae_temporary_data {
char *pw_id;
int vlan_id;
u8 bssid[ETH_ALEN];
+ struct wpabuf *peer_rejected_groups;
};
enum sae_state {