aboutsummaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2015-01-25 21:32:01 (GMT)
committerJouni Malinen <j@w1.fi>2015-01-26 23:43:52 (GMT)
commit5e3b5197cc37a7a85613f6ba5f7041342cd66511 (patch)
treefa00aeb63542b55a5a63a7007790aa5f0b6b0eaf /src/common
parent97ae35a8487cb696f4ca1bf6c51e8aebb805df1b (diff)
downloadhostap-5e3b5197cc37a7a85613f6ba5f7041342cd66511.zip
hostap-5e3b5197cc37a7a85613f6ba5f7041342cd66511.tar.gz
hostap-5e3b5197cc37a7a85613f6ba5f7041342cd66511.tar.bz2
Add Suite B 192-bit AKM
WPA-EAP-SUITE-B-192 can now be used to select 192-bit level Suite B into use as the key management method. Signed-off-by: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'src/common')
-rw-r--r--src/common/defs.h14
-rw-r--r--src/common/ieee802_11_defs.h3
-rw-r--r--src/common/wpa_common.c61
-rw-r--r--src/common/wpa_common.h36
4 files changed, 104 insertions, 10 deletions
diff --git a/src/common/defs.h b/src/common/defs.h
index 2efb985..b5f4f80 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -1,6 +1,6 @@
/*
* WPA Supplicant - Common definitions
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -50,6 +50,7 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean;
#define WPA_KEY_MGMT_CCKM BIT(14)
#define WPA_KEY_MGMT_OSEN BIT(15)
#define WPA_KEY_MGMT_IEEE8021X_SUITE_B BIT(16)
+#define WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 BIT(17)
static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
{
@@ -58,7 +59,8 @@ static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
WPA_KEY_MGMT_CCKM |
WPA_KEY_MGMT_OSEN |
WPA_KEY_MGMT_IEEE8021X_SHA256 |
- WPA_KEY_MGMT_IEEE8021X_SUITE_B));
+ WPA_KEY_MGMT_IEEE8021X_SUITE_B |
+ WPA_KEY_MGMT_IEEE8021X_SUITE_B_192));
}
static inline int wpa_key_mgmt_wpa_psk(int akm)
@@ -91,9 +93,15 @@ static inline int wpa_key_mgmt_sha256(int akm)
WPA_KEY_MGMT_IEEE8021X_SUITE_B));
}
+static inline int wpa_key_mgmt_sha384(int akm)
+{
+ return !!(akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192);
+}
+
static inline int wpa_key_mgmt_suite_b(int akm)
{
- return !!(akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B);
+ return !!(akm & (WPA_KEY_MGMT_IEEE8021X_SUITE_B |
+ WPA_KEY_MGMT_IEEE8021X_SUITE_B_192));
}
static inline int wpa_key_mgmt_wpa(int akm)
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 803b8cc..97a4537 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -1,6 +1,6 @@
/*
* IEEE 802.11 Frame type definitions
- * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
* Copyright (c) 2007-2008 Intel Corporation
*
* This software may be distributed under the terms of the BSD license.
@@ -1192,6 +1192,7 @@ enum plink_action_field {
#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
#define WLAN_AKM_SUITE_8021X_SUITE_B 0x000FAC11
+#define WLAN_AKM_SUITE_8021X_SUITE_B_192 0x000FAC12
#define WLAN_AKM_SUITE_CCKM 0x00409600
#define WLAN_AKM_SUITE_OSEN 0x506f9a01
diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
index d4a17a1..de81d53 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -12,6 +12,7 @@
#include "crypto/md5.h"
#include "crypto/sha1.h"
#include "crypto/sha256.h"
+#include "crypto/sha384.h"
#include "crypto/aes_wrap.h"
#include "crypto/crypto.h"
#include "ieee802_11_defs.h"
@@ -21,12 +22,24 @@
static unsigned int wpa_kck_len(int akmp)
{
+ if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
+ return 24;
return 16;
}
static unsigned int wpa_kek_len(int akmp)
{
+ if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
+ return 32;
+ return 16;
+}
+
+
+unsigned int wpa_mic_len(int akmp)
+{
+ if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
+ return 24;
return 16;
}
@@ -54,7 +67,7 @@ static unsigned int wpa_kek_len(int akmp)
int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
const u8 *buf, size_t len, u8 *mic)
{
- u8 hash[SHA256_MAC_LEN];
+ u8 hash[SHA384_MAC_LEN];
switch (ver) {
#ifndef CONFIG_FIPS
@@ -83,6 +96,13 @@ int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
os_memcpy(mic, hash, MD5_MAC_LEN);
break;
#endif /* CONFIG_SUITEB */
+#ifdef CONFIG_SUITEB192
+ case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
+ if (hmac_sha384(key, key_len, buf, len, hash))
+ return -1;
+ os_memcpy(mic, hash, 24);
+ break;
+#endif /* CONFIG_SUITEB192 */
default:
return -1;
}
@@ -452,6 +472,8 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
#endif /* CONFIG_SAE */
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B)
return WPA_KEY_MGMT_IEEE8021X_SUITE_B;
+ if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192)
+ return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
return 0;
}
@@ -1034,6 +1056,39 @@ int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
#endif /* CONFIG_SUITEB */
+#ifdef CONFIG_SUITEB192
+/**
+ * rsn_pmkid_suite_b_192 - Calculate PMK identifier for Suite B AKM
+ * @kck: Key confirmation key
+ * @kck_len: Length of kck in bytes
+ * @aa: Authenticator address
+ * @spa: Supplicant address
+ * @pmkid: Buffer for PMKID
+ * Returns: 0 on success, -1 on failure
+ *
+ * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
+ * PMKID = Truncate(HMAC-SHA-384(KCK, "PMK Name" || AA || SPA))
+ */
+int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
+ const u8 *spa, u8 *pmkid)
+{
+ char *title = "PMK Name";
+ const u8 *addr[3];
+ const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
+ unsigned char hash[SHA384_MAC_LEN];
+
+ addr[0] = (u8 *) title;
+ addr[1] = aa;
+ addr[2] = spa;
+
+ if (hmac_sha384_vector(kck, kck_len, 3, addr, len, hash) < 0)
+ return -1;
+ os_memcpy(pmkid, hash, PMKID_LEN);
+ return 0;
+}
+#endif /* CONFIG_SUITEB192 */
+
+
/**
* wpa_cipher_txt - Convert cipher suite to a text string
* @cipher: Cipher suite (WPA_CIPHER_* enum)
@@ -1113,6 +1168,8 @@ const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
return "OSEN";
case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
return "WPA2-EAP-SUITE-B";
+ case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
+ return "WPA2-EAP-SUITE-B-192";
default:
return "UNKNOWN";
}
@@ -1141,6 +1198,8 @@ u32 wpa_akm_to_suite(int akm)
return WLAN_AKM_SUITE_OSEN;
if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
return WLAN_AKM_SUITE_8021X_SUITE_B;
+ if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
+ return WLAN_AKM_SUITE_8021X_SUITE_B_192;
return 0;
}
diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
index ddb4a09..091e317 100644
--- a/src/common/wpa_common.h
+++ b/src/common/wpa_common.h
@@ -63,8 +63,8 @@ WPA_CIPHER_GTK_NOT_USED)
#define RSN_AUTH_KEY_MGMT_SAE RSN_SELECTOR(0x00, 0x0f, 0xac, 8)
#define RSN_AUTH_KEY_MGMT_FT_SAE RSN_SELECTOR(0x00, 0x0f, 0xac, 9)
#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B RSN_SELECTOR(0x00, 0x0f, 0xac, 11)
-#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_384 RSN_SELECTOR(0x00, 0x0f, 0xac, 12)
-#define RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_384 \
+#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192 RSN_SELECTOR(0x00, 0x0f, 0xac, 12)
+#define RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_192 \
RSN_SELECTOR(0x00, 0x0f, 0xac, 13)
#define RSN_AUTH_KEY_MGMT_CCKM RSN_SELECTOR(0x00, 0x40, 0x96, 0x00)
#define RSN_AUTH_KEY_MGMT_OSEN RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x01)
@@ -191,9 +191,24 @@ struct wpa_eapol_key {
/* followed by key_data_length bytes of key_data */
} STRUCT_PACKED;
-#define WPA_EAPOL_KEY_MIC_MAX_LEN 16
-#define WPA_KCK_MAX_LEN 16
-#define WPA_KEK_MAX_LEN 16
+struct wpa_eapol_key_192 {
+ u8 type;
+ /* Note: key_info, key_length, and key_data_length are unaligned */
+ u8 key_info[2]; /* big endian */
+ u8 key_length[2]; /* big endian */
+ u8 replay_counter[WPA_REPLAY_COUNTER_LEN];
+ u8 key_nonce[WPA_NONCE_LEN];
+ u8 key_iv[16];
+ u8 key_rsc[WPA_KEY_RSC_LEN];
+ u8 key_id[8]; /* Reserved in IEEE 802.11i/RSN */
+ u8 key_mic[24];
+ u8 key_data_length[2]; /* big endian */
+ /* followed by key_data_length bytes of key_data */
+} STRUCT_PACKED;
+
+#define WPA_EAPOL_KEY_MIC_MAX_LEN 24
+#define WPA_KCK_MAX_LEN 24
+#define WPA_KEK_MAX_LEN 32
#define WPA_TK_MAX_LEN 32
/**
@@ -386,6 +401,16 @@ static inline int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
return -1;
}
#endif /* CONFIG_SUITEB */
+#ifdef CONFIG_SUITEB192
+int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
+ const u8 *spa, u8 *pmkid);
+#else /* CONFIG_SUITEB192 */
+static inline int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len,
+ const u8 *aa, const u8 *spa, u8 *pmkid)
+{
+ return -1;
+}
+#endif /* CONFIG_SUITEB192 */
const char * wpa_cipher_txt(int cipher);
const char * wpa_key_mgmt_txt(int key_mgmt, int proto);
@@ -431,5 +456,6 @@ int wpa_pick_group_cipher(int ciphers);
int wpa_parse_cipher(const char *value);
int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim);
int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise);
+unsigned int wpa_mic_len(int akmp);
#endif /* WPA_COMMON_H */