Added support for using SHA256-based stronger key derivation for WPA2
IEEE 802.11w/D6.0 defines new AKMPs to indicate SHA256-based algorithms for key derivation (and AES-CMAC for EAPOL-Key MIC). Add support for using new AKMPs and clean up AKMP processing with helper functions in defs.h.
This commit is contained in:
parent
9b71728bba
commit
565861976d
28 changed files with 343 additions and 151 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* WPA Supplicant - Common definitions
|
||||
* Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -40,6 +40,35 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean;
|
|||
#define WPA_KEY_MGMT_WPA_NONE BIT(4)
|
||||
#define WPA_KEY_MGMT_FT_IEEE8021X BIT(5)
|
||||
#define WPA_KEY_MGMT_FT_PSK BIT(6)
|
||||
#define WPA_KEY_MGMT_IEEE8021X_SHA256 BIT(7)
|
||||
#define WPA_KEY_MGMT_PSK_SHA256 BIT(8)
|
||||
|
||||
static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
|
||||
{
|
||||
return akm == WPA_KEY_MGMT_IEEE8021X ||
|
||||
akm == WPA_KEY_MGMT_FT_IEEE8021X ||
|
||||
akm == WPA_KEY_MGMT_IEEE8021X_SHA256;
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_wpa_psk(int akm)
|
||||
{
|
||||
return akm == WPA_KEY_MGMT_PSK ||
|
||||
akm == WPA_KEY_MGMT_FT_PSK ||
|
||||
akm == WPA_KEY_MGMT_PSK_SHA256;
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_ft(int akm)
|
||||
{
|
||||
return akm == WPA_KEY_MGMT_FT_PSK ||
|
||||
akm == WPA_KEY_MGMT_FT_IEEE8021X;
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_sha256(int akm)
|
||||
{
|
||||
return akm == WPA_KEY_MGMT_PSK_SHA256 ||
|
||||
akm == WPA_KEY_MGMT_IEEE8021X_SHA256;
|
||||
}
|
||||
|
||||
|
||||
#define WPA_PROTO_WPA BIT(0)
|
||||
#define WPA_PROTO_RSN BIT(1)
|
||||
|
@ -55,7 +84,8 @@ typedef enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
|
|||
CIPHER_WEP104 } wpa_cipher;
|
||||
typedef enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
|
||||
KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE,
|
||||
KEY_MGMT_FT_802_1X, KEY_MGMT_FT_PSK
|
||||
KEY_MGMT_FT_802_1X, KEY_MGMT_FT_PSK,
|
||||
KEY_MGMT_802_1X_SHA256, KEY_MGMT_PSK_SHA256
|
||||
} wpa_key_mgmt;
|
||||
|
||||
/**
|
||||
|
|
|
@ -79,6 +79,7 @@ int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
|
|||
* @nonce2: SNonce or ANonce
|
||||
* @ptk: Buffer for pairwise transient key
|
||||
* @ptk_len: Length of PTK
|
||||
* @use_sha256: Whether to use SHA256-based KDF
|
||||
*
|
||||
* IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
|
||||
* PTK = PRF-X(PMK, "Pairwise key expansion",
|
||||
|
@ -92,7 +93,7 @@ int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
|
|||
void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
|
||||
const u8 *addr1, const u8 *addr2,
|
||||
const u8 *nonce1, const u8 *nonce2,
|
||||
u8 *ptk, size_t ptk_len)
|
||||
u8 *ptk, size_t ptk_len, int use_sha256)
|
||||
{
|
||||
u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN];
|
||||
|
||||
|
@ -114,7 +115,14 @@ void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
|
|||
WPA_NONCE_LEN);
|
||||
}
|
||||
|
||||
sha1_prf(pmk, pmk_len, label, data, sizeof(data), ptk, ptk_len);
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
if (use_sha256)
|
||||
sha256_prf(pmk, pmk_len, label, data, sizeof(data),
|
||||
ptk, ptk_len);
|
||||
else
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
sha1_prf(pmk, pmk_len, label, data, sizeof(data), ptk,
|
||||
ptk_len);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WPA: PTK derivation - A1=" MACSTR " A2=" MACSTR,
|
||||
MAC2STR(addr1), MAC2STR(addr2));
|
||||
|
@ -214,6 +222,12 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
|
|||
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK)
|
||||
return WPA_KEY_MGMT_FT_PSK;
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
|
||||
return WPA_KEY_MGMT_IEEE8021X_SHA256;
|
||||
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_SHA256)
|
||||
return WPA_KEY_MGMT_PSK_SHA256;
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_NO_WPA2 */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* WPA definitions shared between hostapd and wpa_supplicant
|
||||
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -294,7 +294,7 @@ int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
|
|||
void wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
|
||||
const u8 *addr1, const u8 *addr2,
|
||||
const u8 *nonce1, const u8 *nonce2,
|
||||
u8 *ptk, size_t ptk_len);
|
||||
u8 *ptk, size_t ptk_len, int use_sha256);
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
int wpa_ft_mic(const u8 *kck, const u8 *sta_addr, const u8 *ap_addr,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue