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 "common.h"
|
||||
#include "common/defs.h"
|
||||
#include "common/wpa_common.h"
|
||||
#include "utils/const_time.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/sha256.h"
|
||||
|
@ -1520,10 +1522,11 @@ static int sae_derive_keys(struct sae_data *sae, const u8 *k)
|
|||
const u8 *salt;
|
||||
struct wpabuf *rejected_groups = NULL;
|
||||
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;
|
||||
int ret = -1;
|
||||
size_t hash_len, salt_len, prime_len = sae->tmp->prime_len;
|
||||
size_t pmk_len;
|
||||
const u8 *addr[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);
|
||||
else
|
||||
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 ||
|
||||
sae->tmp->peer_rejected_groups)) {
|
||||
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_kdf_hash(hash_len, keyseed, "SAE-PK keys",
|
||||
val, sae->tmp->order_len,
|
||||
keys, 2 * hash_len + SAE_PMK_LEN) < 0)
|
||||
keys, 2 * hash_len + pmk_len) < 0)
|
||||
goto fail;
|
||||
} else {
|
||||
if (sae_kdf_hash(hash_len, keyseed, "SAE KCK and PMK",
|
||||
val, sae->tmp->order_len,
|
||||
keys, hash_len + SAE_PMK_LEN) < 0)
|
||||
keys, hash_len + pmk_len) < 0)
|
||||
goto fail;
|
||||
}
|
||||
#else /* CONFIG_SAE_PK */
|
||||
if (sae_kdf_hash(hash_len, keyseed, "SAE KCK and PMK",
|
||||
val, sae->tmp->order_len,
|
||||
keys, hash_len + SAE_PMK_LEN) < 0)
|
||||
keys, hash_len + pmk_len) < 0)
|
||||
goto fail;
|
||||
#endif /* !CONFIG_SAE_PK */
|
||||
|
||||
forced_memzero(keyseed, sizeof(keyseed));
|
||||
os_memcpy(sae->tmp->kck, keys, hash_len);
|
||||
sae->tmp->kck_len = hash_len;
|
||||
os_memcpy(sae->pmk, keys + hash_len, SAE_PMK_LEN);
|
||||
sae->pmk_len = SAE_PMK_LEN;
|
||||
os_memcpy(sae->pmk, keys + hash_len, pmk_len);
|
||||
sae->pmk_len = pmk_len;
|
||||
os_memcpy(sae->pmkid, val, SAE_PMKID_LEN);
|
||||
#ifdef CONFIG_SAE_PK
|
||||
if (sae->pk) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#define SAE_KCK_LEN 32
|
||||
#define SAE_PMK_LEN 32
|
||||
#define SAE_PMK_LEN_MAX 64
|
||||
#define SAE_PMKID_LEN 16
|
||||
#define SAE_MAX_PRIME_LEN 512
|
||||
#define SAE_MAX_ECC_PRIME_LEN 66
|
||||
|
@ -104,7 +105,7 @@ enum sae_state {
|
|||
struct sae_data {
|
||||
enum sae_state state;
|
||||
u16 send_confirm;
|
||||
u8 pmk[SAE_PMK_LEN];
|
||||
u8 pmk[SAE_PMK_LEN_MAX];
|
||||
size_t pmk_len;
|
||||
int akmp; /* WPA_KEY_MGMT_* used in key derivation */
|
||||
u32 own_akm_suite_selector;
|
||||
|
|
Loading…
Reference in a new issue