((const u8 *) mgmt) + len -
mgmt->u.auth.variable, &token,
&token_len, hapd->conf->sae_groups);
+ if (resp == SAE_SILENTLY_DISCARD) {
+ wpa_printf(MSG_DEBUG,
+ "SAE: Drop commit message from " MACSTR " due to reflection attack",
+ MAC2STR(sta->addr));
+ return;
+ }
if (token && check_sae_token(hapd, sta->addr, token, token_len)
< 0) {
wpa_printf(MSG_DEBUG, "SAE: Drop commit message with "
return res;
/* commit-element */
- return sae_parse_commit_element(sae, pos, end);
+ res = sae_parse_commit_element(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.
+ */
+ if (!sae->tmp->own_commit_scalar ||
+ crypto_bignum_cmp(sae->tmp->own_commit_scalar,
+ sae->peer_commit_scalar) != 0 ||
+ (sae->tmp->dh &&
+ (!sae->tmp->own_commit_element_ffc ||
+ crypto_bignum_cmp(sae->tmp->own_commit_element_ffc,
+ sae->tmp->peer_commit_element_ffc) != 0)) ||
+ (sae->tmp->ec &&
+ (!sae->tmp->own_commit_element_ecc ||
+ crypto_ec_point_cmp(sae->tmp->ec,
+ sae->tmp->own_commit_element_ecc,
+ sae->tmp->peer_commit_element_ecc) != 0)))
+ return WLAN_STATUS_SUCCESS; /* scalars/elements are different */
+
+ /*
+ * This is a reflection attack - return special value to trigger caller
+ * to silently discard the frame instead of replying with a specific
+ * status code.
+ */
+ return SAE_SILENTLY_DISCARD;
}
#define SAE_COMMIT_MAX_LEN (2 + 3 * SAE_MAX_PRIME_LEN)
#define SAE_CONFIRM_MAX_LEN (2 + SAE_MAX_PRIME_LEN)
+/* Special value returned by sae_parse_commit() */
+#define SAE_SILENTLY_DISCARD 65535
+
struct sae_temporary_data {
u8 kck[SAE_KCK_LEN];
struct crypto_bignum *own_commit_scalar;
return -1;
if (auth_transaction == 1) {
+ u16 res;
+
groups = wpa_s->conf->sae_groups;
wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit");
return -1;
if (groups && groups[0] <= 0)
groups = NULL;
- if (sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
- groups) != WLAN_STATUS_SUCCESS)
+ res = sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
+ groups);
+ if (res == SAE_SILENTLY_DISCARD) {
+ wpa_printf(MSG_DEBUG,
+ "SAE: Drop commit message due to reflection attack");
+ return 0;
+ }
+ if (res != WLAN_STATUS_SUCCESS)
return -1;
if (sae_process_commit(&wpa_s->sme.sae) < 0) {