SAE: Derive a variable length PMK with the new AKM suites
Select the PMK length based on the used group (prime length) when using the new AKM suites for SAE. Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
parent
91010e6f67
commit
f70db167ab
2 changed files with 19 additions and 7 deletions
|
@ -9,6 +9,8 @@
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "common/defs.h"
|
||||||
|
#include "common/wpa_common.h"
|
||||||
#include "utils/const_time.h"
|
#include "utils/const_time.h"
|
||||||
#include "crypto/crypto.h"
|
#include "crypto/crypto.h"
|
||||||
#include "crypto/sha256.h"
|
#include "crypto/sha256.h"
|
||||||
|
@ -1520,10 +1522,11 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k)
|
||||||
const u8 *salt;
|
const u8 *salt;
|
||||||
struct wpabuf *rejected_groups = NULL;
|
struct wpabuf *rejected_groups = NULL;
|
||||||
u8 keyseed[SAE_MAX_HASH_LEN];
|
u8 keyseed[SAE_MAX_HASH_LEN];
|
||||||
u8 keys[2 * SAE_MAX_HASH_LEN + SAE_PMK_LEN];
|
u8 keys[2 * SAE_MAX_HASH_LEN + SAE_PMK_LEN_MAX];
|
||||||
struct crypto_bignum *tmp;
|
struct crypto_bignum *tmp;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
size_t hash_len, salt_len, prime_len = sae->tmp->prime_len;
|
size_t hash_len, salt_len, prime_len = sae->tmp->prime_len;
|
||||||
|
size_t pmk_len;
|
||||||
const u8 *addr[1];
|
const u8 *addr[1];
|
||||||
size_t len[1];
|
size_t len[1];
|
||||||
|
|
||||||
|
@ -1545,6 +1548,14 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k)
|
||||||
hash_len = sae_ffc_prime_len_2_hash_len(prime_len);
|
hash_len = sae_ffc_prime_len_2_hash_len(prime_len);
|
||||||
else
|
else
|
||||||
hash_len = sae_ecc_prime_len_2_hash_len(prime_len);
|
hash_len = sae_ecc_prime_len_2_hash_len(prime_len);
|
||||||
|
if (wpa_key_mgmt_sae_ext_key(sae->akmp))
|
||||||
|
pmk_len = hash_len;
|
||||||
|
else
|
||||||
|
pmk_len = SAE_PMK_LEN;
|
||||||
|
wpa_printf(MSG_DEBUG, "SAE: Derive keys - H2E=%d AKMP=0x%x = %08x (%s)",
|
||||||
|
sae->h2e, sae->akmp,
|
||||||
|
wpa_akm_to_suite(sae->akmp),
|
||||||
|
wpa_key_mgmt_txt(sae->akmp, WPA_PROTO_RSN));
|
||||||
if (sae->h2e && (sae->tmp->own_rejected_groups ||
|
if (sae->h2e && (sae->tmp->own_rejected_groups ||
|
||||||
sae->tmp->peer_rejected_groups)) {
|
sae->tmp->peer_rejected_groups)) {
|
||||||
struct wpabuf *own, *peer;
|
struct wpabuf *own, *peer;
|
||||||
|
@ -1602,26 +1613,26 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k)
|
||||||
if (sae->pk) {
|
if (sae->pk) {
|
||||||
if (sae_kdf_hash(hash_len, keyseed, "SAE-PK keys",
|
if (sae_kdf_hash(hash_len, keyseed, "SAE-PK keys",
|
||||||
val, sae->tmp->order_len,
|
val, sae->tmp->order_len,
|
||||||
keys, 2 * hash_len + SAE_PMK_LEN) < 0)
|
keys, 2 * hash_len + pmk_len) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
} else {
|
} else {
|
||||||
if (sae_kdf_hash(hash_len, keyseed, "SAE KCK and PMK",
|
if (sae_kdf_hash(hash_len, keyseed, "SAE KCK and PMK",
|
||||||
val, sae->tmp->order_len,
|
val, sae->tmp->order_len,
|
||||||
keys, hash_len + SAE_PMK_LEN) < 0)
|
keys, hash_len + pmk_len) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
#else /* CONFIG_SAE_PK */
|
#else /* CONFIG_SAE_PK */
|
||||||
if (sae_kdf_hash(hash_len, keyseed, "SAE KCK and PMK",
|
if (sae_kdf_hash(hash_len, keyseed, "SAE KCK and PMK",
|
||||||
val, sae->tmp->order_len,
|
val, sae->tmp->order_len,
|
||||||
keys, hash_len + SAE_PMK_LEN) < 0)
|
keys, hash_len + pmk_len) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
#endif /* !CONFIG_SAE_PK */
|
#endif /* !CONFIG_SAE_PK */
|
||||||
|
|
||||||
forced_memzero(keyseed, sizeof(keyseed));
|
forced_memzero(keyseed, sizeof(keyseed));
|
||||||
os_memcpy(sae->tmp->kck, keys, hash_len);
|
os_memcpy(sae->tmp->kck, keys, hash_len);
|
||||||
sae->tmp->kck_len = hash_len;
|
sae->tmp->kck_len = hash_len;
|
||||||
os_memcpy(sae->pmk, keys + hash_len, SAE_PMK_LEN);
|
os_memcpy(sae->pmk, keys + hash_len, pmk_len);
|
||||||
sae->pmk_len = SAE_PMK_LEN;
|
sae->pmk_len = pmk_len;
|
||||||
os_memcpy(sae->pmkid, val, SAE_PMKID_LEN);
|
os_memcpy(sae->pmkid, val, SAE_PMKID_LEN);
|
||||||
#ifdef CONFIG_SAE_PK
|
#ifdef CONFIG_SAE_PK
|
||||||
if (sae->pk) {
|
if (sae->pk) {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#define SAE_KCK_LEN 32
|
#define SAE_KCK_LEN 32
|
||||||
#define SAE_PMK_LEN 32
|
#define SAE_PMK_LEN 32
|
||||||
|
#define SAE_PMK_LEN_MAX 64
|
||||||
#define SAE_PMKID_LEN 16
|
#define SAE_PMKID_LEN 16
|
||||||
#define SAE_MAX_PRIME_LEN 512
|
#define SAE_MAX_PRIME_LEN 512
|
||||||
#define SAE_MAX_ECC_PRIME_LEN 66
|
#define SAE_MAX_ECC_PRIME_LEN 66
|
||||||
|
@ -104,7 +105,7 @@ enum sae_state {
|
||||||
struct sae_data {
|
struct sae_data {
|
||||||
enum sae_state state;
|
enum sae_state state;
|
||||||
u16 send_confirm;
|
u16 send_confirm;
|
||||||
u8 pmk[SAE_PMK_LEN];
|
u8 pmk[SAE_PMK_LEN_MAX];
|
||||||
size_t pmk_len;
|
size_t pmk_len;
|
||||||
int akmp; /* WPA_KEY_MGMT_* used in key derivation */
|
int akmp; /* WPA_KEY_MGMT_* used in key derivation */
|
||||||
u32 own_akm_suite_selector;
|
u32 own_akm_suite_selector;
|
||||||
|
|
Loading…
Add table
Reference in a new issue