aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wpa.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-08-28 17:01:55 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:48:53 -0400
commit11a843b7e16062389c53ba393c7913956e034eb2 (patch)
tree7f557a55220a0de38f0eafe1a5147487ec39b790 /net/mac80211/wpa.c
parent3aefaa3294193c931b20a574f718efee6baf27d4 (diff)
[MAC80211]: rework key handling
This moves all the key handling code out from ieee80211_ioctl.c into key.c and also does the following changes including documentation updates in mac80211.h: 1) Turn off hardware acceleration for keys when the interface is down. This is necessary because otherwise monitor interfaces could be decrypting frames for other interfaces that are down at the moment. Also, it should go some way towards better suspend/resume support, in any case the routines used here could be used for that as well. Additionally, this makes the driver interface nicer, keys for a specific local MAC address are only ever present while an interface with that MAC address is enabled. 2) Change driver set_key() callback interface to allow only return values of -ENOSPC, -EOPNOTSUPP and 0, warn on all other return values. This allows debugging the stack when a driver notices it's handed a key while it is down. 3) Invert the flag meaning to KEY_FLAG_UPLOADED_TO_HARDWARE. 4) Remove REMOVE_ALL_KEYS command as it isn't used nor do we want to use it, we'll use DISABLE_KEY for each key. It is hard to use REMOVE_ALL_KEYS because we can handle multiple virtual interfaces with different key configuration, so we'd have to keep track of a lot of state for this and that isn't worth it. 5) Warn when disabling a key fails, it musn't. 6) Remove IEEE80211_HW_NO_TKIP_WMM_HWACCEL in favour of per-key IEEE80211_KEY_FLAG_WMM_STA to let driver sort it out itself. 7) Tell driver that a (non-WEP) key is used only for transmission by using an all-zeroes station MAC address when configuring. 8) Change the set_key() callback to have access to the local MAC address the key is being added for. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r--net/mac80211/wpa.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 4a2a9aa638b..b6cd66e0ee5 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -89,7 +89,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx)
89 if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)) 89 if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len))
90 return TXRX_DROP; 90 return TXRX_DROP;
91 91
92 if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) && 92 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
93 !(tx->flags & IEEE80211_TXRXD_FRAGMENTED) && 93 !(tx->flags & IEEE80211_TXRXD_FRAGMENTED) &&
94 !(tx->local->hw.flags & IEEE80211_HW_TKIP_INCLUDE_MMIC) && 94 !(tx->local->hw.flags & IEEE80211_HW_TKIP_INCLUDE_MMIC) &&
95 !wpa_test) { 95 !wpa_test) {
@@ -146,7 +146,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
146 return TXRX_CONTINUE; 146 return TXRX_CONTINUE;
147 147
148 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && 148 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
149 !(rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) { 149 (rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
150 if (rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) { 150 if (rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) {
151 if (skb->len < MICHAEL_MIC_LEN) 151 if (skb->len < MICHAEL_MIC_LEN)
152 return TXRX_DROP; 152 return TXRX_DROP;
@@ -205,10 +205,10 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
205 hdrlen = ieee80211_get_hdrlen(fc); 205 hdrlen = ieee80211_get_hdrlen(fc);
206 len = skb->len - hdrlen; 206 len = skb->len - hdrlen;
207 207
208 if (tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) 208 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
209 tailneed = TKIP_ICV_LEN;
210 else
211 tailneed = 0; 209 tailneed = 0;
210 else
211 tailneed = TKIP_ICV_LEN;
212 212
213 if ((skb_headroom(skb) < TKIP_IV_LEN || 213 if ((skb_headroom(skb) < TKIP_IV_LEN ||
214 skb_tailroom(skb) < tailneed)) { 214 skb_tailroom(skb) < tailneed)) {
@@ -227,7 +227,7 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
227 if (key->u.tkip.iv16 == 0) 227 if (key->u.tkip.iv16 == 0)
228 key->u.tkip.iv32++; 228 key->u.tkip.iv32++;
229 229
230 if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) { 230 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
231 u32 flags = tx->local->hw.flags; 231 u32 flags = tx->local->hw.flags;
232 hdr = (struct ieee80211_hdr *)skb->data; 232 hdr = (struct ieee80211_hdr *)skb->data;
233 233
@@ -286,7 +286,7 @@ ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx)
286 tx->u.tx.control->iv_len = TKIP_IV_LEN; 286 tx->u.tx.control->iv_len = TKIP_IV_LEN;
287 ieee80211_tx_set_iswep(tx); 287 ieee80211_tx_set_iswep(tx);
288 288
289 if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) && 289 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
290 !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) && 290 !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) &&
291 !wpa_test) { 291 !wpa_test) {
292 /* hwaccel - with no need for preallocated room for IV/ICV */ 292 /* hwaccel - with no need for preallocated room for IV/ICV */
@@ -331,7 +331,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
331 return TXRX_DROP; 331 return TXRX_DROP;
332 332
333 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && 333 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
334 !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) { 334 (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
335 if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) { 335 if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) {
336 /* Hardware takes care of all processing, including 336 /* Hardware takes care of all processing, including
337 * replay protection, so no need to continue here. */ 337 * replay protection, so no need to continue here. */
@@ -475,10 +475,10 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
475 hdrlen = ieee80211_get_hdrlen(fc); 475 hdrlen = ieee80211_get_hdrlen(fc);
476 len = skb->len - hdrlen; 476 len = skb->len - hdrlen;
477 477
478 if (key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) 478 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
479 tailneed = CCMP_MIC_LEN;
480 else
481 tailneed = 0; 479 tailneed = 0;
480 else
481 tailneed = CCMP_MIC_LEN;
482 482
483 if ((skb_headroom(skb) < CCMP_HDR_LEN || 483 if ((skb_headroom(skb) < CCMP_HDR_LEN ||
484 skb_tailroom(skb) < tailneed)) { 484 skb_tailroom(skb) < tailneed)) {
@@ -504,7 +504,7 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
504 504
505 ccmp_pn2hdr(pos, pn, key->conf.keyidx); 505 ccmp_pn2hdr(pos, pn, key->conf.keyidx);
506 506
507 if (!(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) { 507 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
508 /* hwaccel - with preallocated room for CCMP header */ 508 /* hwaccel - with preallocated room for CCMP header */
509 tx->u.tx.control->key_idx = key->conf.hw_key_idx; 509 tx->u.tx.control->key_idx = key->conf.hw_key_idx;
510 return 0; 510 return 0;
@@ -537,7 +537,7 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx)
537 tx->u.tx.control->iv_len = CCMP_HDR_LEN; 537 tx->u.tx.control->iv_len = CCMP_HDR_LEN;
538 ieee80211_tx_set_iswep(tx); 538 ieee80211_tx_set_iswep(tx);
539 539
540 if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) && 540 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
541 !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) { 541 !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) {
542 /* hwaccel - with no need for preallocated room for CCMP " 542 /* hwaccel - with no need for preallocated room for CCMP "
543 * header or MIC fields */ 543 * header or MIC fields */
@@ -586,7 +586,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
586 return TXRX_DROP; 586 return TXRX_DROP;
587 587
588 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && 588 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
589 !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) && 589 (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
590 !(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) 590 !(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV))
591 return TXRX_CONTINUE; 591 return TXRX_CONTINUE;
592 592
@@ -607,7 +607,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
607 } 607 }
608 608
609 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && 609 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
610 !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) { 610 (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
611 /* hwaccel has already decrypted frame and verified MIC */ 611 /* hwaccel has already decrypted frame and verified MIC */
612 } else { 612 } else {
613 u8 *scratch, *b_0, *aad; 613 u8 *scratch, *b_0, *aad;