aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2013-07-23 18:24:05 (GMT)
committerJouni Malinen <j@w1.fi>2014-02-25 23:24:23 (GMT)
commitdf0f01d91f56fc55fedfd78a81a1fcca031af537 (patch)
tree82e0c13651bda598698e22ef95eafcecb81bf7ad /src
parenta5d75636f91fc547d44448bfb76eea3df57da4a9 (diff)
downloadhostap-df0f01d91f56fc55fedfd78a81a1fcca031af537.zip
hostap-df0f01d91f56fc55fedfd78a81a1fcca031af537.tar.gz
hostap-df0f01d91f56fc55fedfd78a81a1fcca031af537.tar.bz2
HS 2.0R2: Add OSEN client implementation
Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'src')
-rw-r--r--src/rsn_supp/wpa.c22
-rw-r--r--src/rsn_supp/wpa_ie.c65
2 files changed, 83 insertions, 4 deletions
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 4474c3b..0a6f0d8 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -89,7 +89,10 @@ void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
int key_info, ver;
u8 bssid[ETH_ALEN], *rbuf;
- if (wpa_key_mgmt_ft(sm->key_mgmt) || wpa_key_mgmt_sha256(sm->key_mgmt))
+ if (sm->key_mgmt == WPA_KEY_MGMT_OSEN)
+ ver = WPA_KEY_INFO_TYPE_AKM_DEFINED;
+ else if (wpa_key_mgmt_ft(sm->key_mgmt) ||
+ wpa_key_mgmt_sha256(sm->key_mgmt))
ver = WPA_KEY_INFO_TYPE_AES_128_CMAC;
else if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
@@ -1480,7 +1483,8 @@ static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
return -1;
}
} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
- ver == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
+ ver == WPA_KEY_INFO_TYPE_AES_128_CMAC ||
+ sm->key_mgmt == WPA_KEY_MGMT_OSEN) {
u8 *buf;
if (keydatalen % 8) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
@@ -1662,13 +1666,22 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
#endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
- ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
+ ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
+ sm->key_mgmt != WPA_KEY_MGMT_OSEN) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"WPA: Unsupported EAPOL-Key descriptor version %d",
ver);
goto out;
}
+ if (sm->key_mgmt == WPA_KEY_MGMT_OSEN &&
+ ver != WPA_KEY_INFO_TYPE_AKM_DEFINED) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "OSEN: Unsupported EAPOL-Key descriptor version %d",
+ ver);
+ goto out;
+ }
+
#ifdef CONFIG_IEEE80211R
if (wpa_key_mgmt_ft(sm->key_mgmt)) {
/* IEEE 802.11r uses a new key_info type (AES-128-CMAC). */
@@ -1681,7 +1694,8 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_IEEE80211W
if (wpa_key_mgmt_sha256(sm->key_mgmt)) {
- if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
+ if (ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
+ sm->key_mgmt != WPA_KEY_MGMT_OSEN) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"WPA: AP did not use the "
"negotiated AES-128-CMAC");
diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c
index e58bdc4..9c11183 100644
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
@@ -222,6 +222,64 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
}
+#ifdef CONFIG_HS20
+static int wpa_gen_wpa_ie_osen(u8 *wpa_ie, size_t wpa_ie_len,
+ int pairwise_cipher, int group_cipher,
+ int key_mgmt)
+{
+ u8 *pos, *len;
+ u32 suite;
+
+ if (wpa_ie_len < 2 + 4 + RSN_SELECTOR_LEN +
+ 2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN)
+ return -1;
+
+ pos = wpa_ie;
+ *pos++ = WLAN_EID_VENDOR_SPECIFIC;
+ len = pos++; /* to be filled */
+ WPA_PUT_BE24(pos, OUI_WFA);
+ pos += 3;
+ *pos++ = HS20_OSEN_OUI_TYPE;
+
+ /* Group Data Cipher Suite */
+ suite = wpa_cipher_to_suite(WPA_PROTO_RSN, group_cipher);
+ if (suite == 0) {
+ wpa_printf(MSG_WARNING, "Invalid group cipher (%d).",
+ group_cipher);
+ return -1;
+ }
+ RSN_SELECTOR_PUT(pos, suite);
+ pos += RSN_SELECTOR_LEN;
+
+ /* Pairwise Cipher Suite Count and List */
+ WPA_PUT_LE16(pos, 1);
+ pos += 2;
+ suite = wpa_cipher_to_suite(WPA_PROTO_RSN, pairwise_cipher);
+ if (suite == 0 ||
+ (!wpa_cipher_valid_pairwise(pairwise_cipher) &&
+ pairwise_cipher != WPA_CIPHER_NONE)) {
+ wpa_printf(MSG_WARNING, "Invalid pairwise cipher (%d).",
+ pairwise_cipher);
+ return -1;
+ }
+ RSN_SELECTOR_PUT(pos, suite);
+ pos += RSN_SELECTOR_LEN;
+
+ /* AKM Suite Count and List */
+ WPA_PUT_LE16(pos, 1);
+ pos += 2;
+ RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_OSEN);
+ pos += RSN_SELECTOR_LEN;
+
+ *len = pos - len - 1;
+
+ WPA_ASSERT((size_t) (pos - wpa_ie) <= wpa_ie_len);
+
+ return pos - wpa_ie;
+}
+#endif /* CONFIG_HS20 */
+
+
/**
* wpa_gen_wpa_ie - Generate WPA/RSN IE based on current security policy
* @sm: Pointer to WPA state machine data from wpa_sm_init()
@@ -237,6 +295,13 @@ int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len)
sm->group_cipher,
sm->key_mgmt, sm->mgmt_group_cipher,
sm);
+#ifdef CONFIG_HS20
+ else if (sm->proto == WPA_PROTO_OSEN)
+ return wpa_gen_wpa_ie_osen(wpa_ie, wpa_ie_len,
+ sm->pairwise_cipher,
+ sm->group_cipher,
+ sm->key_mgmt);
+#endif /* CONFIG_HS20 */
else
return wpa_gen_wpa_ie_wpa(wpa_ie, wpa_ie_len,
sm->pairwise_cipher,