diff options
author | Jouni Malinen <j@w1.fi> | 2019-08-03 14:00:39 (GMT) |
---|---|---|
committer | Jouni Malinen <j@w1.fi> | 2019-08-03 14:00:39 (GMT) |
commit | ac734a342ed172a07714dbbf71bcac4b379a0b9b (patch) | |
tree | dd8551af4b7a6741d2ef7faf97dbe527b7397e31 | |
parent | e57e3f12b4639ace1420bc3a921034ab31299fa8 (diff) | |
download | hostap-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.c | 11 | ||||
-rw-r--r-- | src/common/sae.h | 1 |
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; |