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:
Jouni Malinen 2008-08-31 22:57:28 +03:00
parent 9b71728bba
commit 565861976d
28 changed files with 343 additions and 151 deletions

View file

@ -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;
/**

View file

@ -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 */

View file

@ -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,