summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_wpi.c
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2008-04-16 18:32:16 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2008-04-16 18:32:16 +0000
commit792a7af405f1bcd074df2d192736f0ff71180ce6 (patch)
treed1c8127338d31609e63b5a8c220604e11d416fa8 /sys/dev/pci/if_wpi.c
parentc257d1252aa088da82103c7952e3c42933d743da (diff)
Kernel implementation of the 4-way handshake and group-key
handshake protocols (both supplicant and authenticator state machines) as defined in the IEEE 802.11i standard. Software implementation of the TKIP (Temporal Key Integrity Protocol) and CCMP (CTR with CBC-MAC Protocol) protocols. This diff doesn't implement any of the 802.1X authentication protocols and thus only PSK authentication (using pre-shared keys) is currently supported. In concrete terms, this adds support for WPA-PSK and WPA2-PSK protocols, both in station and hostap modes. The following drivers are marked as WPA-capable and should work: bwi(4), malo(4), ral(4), iwn(4), wpi(4), ural(4), rum(4), upgt(4), and zyd(4) The following options have been added to ifconfig(8): wpa, wpapsk, wpaprotos, wpaakms, wpaciphers, wpagroupcipher wpa-psk(8) can be used to generate keys from passphrases. tested by many@ ok deraadt@
Diffstat (limited to 'sys/dev/pci/if_wpi.c')
-rw-r--r--sys/dev/pci/if_wpi.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c
index f0cd31a8a1e..0549b16de86 100644
--- a/sys/dev/pci/if_wpi.c
+++ b/sys/dev/pci/if_wpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wpi.c,v 1.59 2008/03/08 16:24:45 espie Exp $ */
+/* $OpenBSD: if_wpi.c,v 1.60 2008/04/16 18:32:15 damien Exp $ */
/*-
* Copyright (c) 2006, 2007
@@ -130,7 +130,7 @@ int wpi_ioctl(struct ifnet *, u_long, caddr_t);
int wpi_cmd(struct wpi_softc *, int, const void *, int, int);
int wpi_mrr_setup(struct wpi_softc *);
int wpi_set_key(struct ieee80211com *, struct ieee80211_node *,
- const struct ieee80211_key *);
+ struct ieee80211_key *);
void wpi_updateedca(struct ieee80211com *);
void wpi_set_led(struct wpi_softc *, uint8_t, uint8_t, uint8_t);
void wpi_enable_tsf(struct wpi_softc *, struct ieee80211_node *);
@@ -270,6 +270,7 @@ wpi_attach(struct device *parent, struct device *self, void *aux)
/* set device capabilities */
ic->ic_caps =
IEEE80211_C_WEP | /* s/w WEP */
+ IEEE80211_C_RSN | /* WPA/RSN */
IEEE80211_C_MONITOR | /* monitor mode supported */
IEEE80211_C_TXPMGT | /* tx power management */
IEEE80211_C_SHSLOT | /* short slot time supported */
@@ -299,7 +300,9 @@ wpi_attach(struct device *parent, struct device *self, void *aux)
ieee80211_ifattach(ifp);
ic->ic_node_alloc = wpi_node_alloc;
ic->ic_newassoc = wpi_newassoc;
+#ifdef notyet
ic->ic_set_key = wpi_set_key;
+#endif
ic->ic_updateedca = wpi_updateedca;
/* override state transition machine */
@@ -1569,9 +1572,10 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
struct wpi_tx_cmd *cmd;
struct wpi_cmd_data *tx;
struct ieee80211_frame *wh;
+ struct ieee80211_key *k;
struct mbuf *mnew;
u_int hdrlen;
- int i, rate, error, ovhd = 0;
+ int i, rate, error;
desc = &ring->desc[ring->cur];
data = &ring->data[ring->cur];
@@ -1626,18 +1630,13 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
tx->flags = 0;
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
- const struct ieee80211_key *key =
- &ic->ic_nw_keys[ic->ic_wep_txkey];
- if (key->k_cipher == IEEE80211_CIPHER_WEP40)
- tx->security = WPI_CIPHER_WEP40;
- else
- tx->security = WPI_CIPHER_WEP104;
- tx->security |= ic->ic_wep_txkey << 6;
- memcpy(&tx->key[3], key->k_key, key->k_len);
- /* compute crypto overhead */
- ovhd = IEEE80211_WEP_TOTLEN;
- } else
- tx->security = 0;
+ k = ieee80211_get_txkey(ic, wh, ni);
+
+ if ((m0 = ieee80211_encrypt(ic, m0, k)) == NULL)
+ return ENOBUFS;
+
+ wh = mtod(m0, struct ieee80211_frame *);
+ }
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
tx->id = WPI_ID_BSS;
@@ -1648,7 +1647,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
/* check if RTS/CTS or CTS-to-self protection must be used */
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
/* multicast frames are not sent at OFDM rates in 802.11b/g */
- if (m0->m_pkthdr.len + ovhd + IEEE80211_CRC_LEN >
+ if (m0->m_pkthdr.len + IEEE80211_CRC_LEN >
ic->ic_rtsthreshold) {
tx->flags |= htole32(WPI_TX_NEED_RTS |
WPI_TX_FULL_TXOP);
@@ -2118,7 +2117,7 @@ wpi_mrr_setup(struct wpi_softc *sc)
*/
int
wpi_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
- const struct ieee80211_key *k)
+ struct ieee80211_key *k)
{
struct wpi_softc *sc = ic->ic_softc;
struct wpi_node_info node;