aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2019-08-03 14:00:39 (GMT)
committerJouni Malinen <j@w1.fi>2019-08-03 14:00:39 (GMT)
commitac734a342ed172a07714dbbf71bcac4b379a0b9b (patch)
treedd8551af4b7a6741d2ef7faf97dbe527b7397e31
parente57e3f12b4639ace1420bc3a921034ab31299fa8 (diff)
downloadhostap-ac734a342ed172a07714dbbf71bcac4b379a0b9b.zip
hostap-ac734a342ed172a07714dbbf71bcac4b379a0b9b.tar.gz
hostap-ac734a342ed172a07714dbbf71bcac4b379a0b9b.tar.bz2
SAE: Fix KCK, PMK, and PMKID derivation for groups 22, 23, 24
IEEE Std 802.11-2016 is not exactly clear on the encoding of the bit string that is needed for KCK, PMK, and PMKID derivation, but it seems to make most sense to encode the (commit-scalar + peer-commit-scalar) mod r part as a bit string by zero padding it from left to the length of the order (in full octets). The previous implementation used the length of the prime (in full octets). This would work for KCK/PMK, but this results in deriving all zero PMKIDs for the groups where the size of the order is smaller than the size of the prime. This is the case for groups 22, 23, and 24. However, those groups have been marked as being unsuitable for use with SAE, so this fix should not really have a practical impact anymore. Anyway, better fix it and document this clearly in the implementation taken into account the unclarity of the standard in this area. Signed-off-by: Jouni Malinen <j@w1.fi>
-rw-r--r--src/common/sae.c11
-rw-r--r--src/common/sae.h1
2 files changed, 10 insertions, 2 deletions
diff --git a/src/common/sae.c b/src/common/sae.c
index 2d52093..5614fe9 100644
--- a/src/common/sae.c
+++ b/src/common/sae.c
@@ -45,6 +45,7 @@ int sae_set_group(struct sae_data *sae, int group)
sae->group = group;
tmp->prime_len = crypto_ec_prime_len(tmp->ec);
tmp->prime = crypto_ec_get_prime(tmp->ec);
+ tmp->order_len = crypto_ec_order_len(tmp->ec);
tmp->order = crypto_ec_get_order(tmp->ec);
return 0;
}
@@ -709,10 +710,16 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k)
crypto_bignum_add(sae->tmp->own_commit_scalar, sae->peer_commit_scalar,
tmp);
crypto_bignum_mod(tmp, sae->tmp->order, tmp);
- crypto_bignum_to_bin(tmp, val, sizeof(val), sae->tmp->prime_len);
+ /* IEEE Std 802.11-2016 is not exactly clear on the encoding of the bit
+ * string that is needed for KCK, PMK, and PMKID derivation, but it
+ * seems to make most sense to encode the
+ * (commit-scalar + peer-commit-scalar) mod r part as a bit string by
+ * zero padding it from left to the length of the order (in full
+ * octets). */
+ crypto_bignum_to_bin(tmp, val, sizeof(val), sae->tmp->order_len);
wpa_hexdump(MSG_DEBUG, "SAE: PMKID", val, SAE_PMKID_LEN);
if (sha256_prf(keyseed, sizeof(keyseed), "SAE KCK and PMK",
- val, sae->tmp->prime_len, keys, sizeof(keys)) < 0)
+ val, sae->tmp->order_len, keys, sizeof(keys)) < 0)
goto fail;
os_memset(keyseed, 0, sizeof(keyseed));
os_memcpy(sae->tmp->kck, keys, SAE_KCK_LEN);
diff --git a/src/common/sae.h b/src/common/sae.h
index 3eb6e32..10f9302 100644
--- a/src/common/sae.h
+++ b/src/common/sae.h
@@ -33,6 +33,7 @@ struct sae_temporary_data {
struct crypto_bignum *sae_rand;
struct crypto_ec *ec;
int prime_len;
+ int order_len;
const struct dh_group *dh;
const struct crypto_bignum *prime;
const struct crypto_bignum *order;