diff options
-rw-r--r-- | include/net/mac80211.h | 37 | ||||
-rw-r--r-- | net/mac80211/rx.c | 113 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 7 |
3 files changed, 103 insertions, 54 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 000b8e3133ba..6a2a0c3e7255 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -1,7 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Low-level hardware driver -- IEEE 802.11 driver (80211.o) interface | 2 | * mac80211 <-> driver interface |
3 | * | ||
3 | * Copyright 2002-2005, Devicescape Software, Inc. | 4 | * Copyright 2002-2005, Devicescape Software, Inc. |
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 5 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
6 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | ||
5 | * | 7 | * |
6 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -472,10 +474,16 @@ struct ieee80211_hw { | |||
472 | */ | 474 | */ |
473 | #define IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE (1<<1) | 475 | #define IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE (1<<1) |
474 | 476 | ||
475 | /* Some devices handle decryption internally and do not | 477 | /* |
478 | * Some devices handle decryption internally and do not | ||
476 | * indicate whether the frame was encrypted (unencrypted frames | 479 | * indicate whether the frame was encrypted (unencrypted frames |
477 | * will be dropped by the hardware, unless specifically allowed | 480 | * will be dropped by the hardware, unless specifically allowed |
478 | * through) */ | 481 | * through.) |
482 | * It is permissible to not handle all encrypted frames and fall | ||
483 | * back to software encryption; however, if this flag is set | ||
484 | * unencrypted frames must be dropped unless the driver is told | ||
485 | * otherwise via the set_ieee8021x() callback. | ||
486 | */ | ||
479 | #define IEEE80211_HW_DEVICE_HIDES_WEP (1<<2) | 487 | #define IEEE80211_HW_DEVICE_HIDES_WEP (1<<2) |
480 | 488 | ||
481 | /* Whether RX frames passed to ieee80211_rx() include FCS in the end */ | 489 | /* Whether RX frames passed to ieee80211_rx() include FCS in the end */ |
@@ -489,6 +497,18 @@ struct ieee80211_hw { | |||
489 | * can fetch them with ieee80211_get_buffered_bc(). */ | 497 | * can fetch them with ieee80211_get_buffered_bc(). */ |
490 | #define IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING (1<<4) | 498 | #define IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING (1<<4) |
491 | 499 | ||
500 | /* | ||
501 | * This flag is only relevant if hardware encryption is used. | ||
502 | * If set, it has two meanings: | ||
503 | * 1) the IV and ICV are present in received frames that have | ||
504 | * been decrypted (unless IEEE80211_HW_DEVICE_HIDES_WEP is | ||
505 | * also set) | ||
506 | * 2) on transmission, the IV should be generated in software. | ||
507 | * | ||
508 | * Please let us know if you *don't* use this flag, the stack would | ||
509 | * really like to be able to get the IV to keep key statistics | ||
510 | * accurate. | ||
511 | */ | ||
492 | #define IEEE80211_HW_WEP_INCLUDE_IV (1<<5) | 512 | #define IEEE80211_HW_WEP_INCLUDE_IV (1<<5) |
493 | 513 | ||
494 | /* hole at 6 */ | 514 | /* hole at 6 */ |
@@ -496,11 +516,12 @@ struct ieee80211_hw { | |||
496 | /* Force software encryption for TKIP packets if WMM is enabled. */ | 516 | /* Force software encryption for TKIP packets if WMM is enabled. */ |
497 | #define IEEE80211_HW_NO_TKIP_WMM_HWACCEL (1<<7) | 517 | #define IEEE80211_HW_NO_TKIP_WMM_HWACCEL (1<<7) |
498 | 518 | ||
499 | /* Some devices handle Michael MIC internally and do not include MIC in | 519 | /* |
500 | * the received packets passed up. device_strips_mic must be set | 520 | * Some devices handle Michael MIC internally and do not include MIC in |
501 | * for such devices. The 'encryption' frame control bit is expected to | 521 | * the received packets passed up. This flag must be set for such |
502 | * be still set in the IEEE 802.11 header with this option unlike with | 522 | * devices. The 'encryption' frame control bit is expected to be still |
503 | * the device_hides_wep configuration option. | 523 | * set in the IEEE 802.11 header with this option unlike with the |
524 | * IEEE80211_HW_DEVICE_HIDES_WEP flag. | ||
504 | */ | 525 | */ |
505 | #define IEEE80211_HW_DEVICE_STRIPS_MIC (1<<8) | 526 | #define IEEE80211_HW_DEVICE_STRIPS_MIC (1<<8) |
506 | 527 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b0959c249869..08ca066246b9 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -310,52 +310,77 @@ static ieee80211_txrx_result | |||
310 | ieee80211_rx_h_load_key(struct ieee80211_txrx_data *rx) | 310 | ieee80211_rx_h_load_key(struct ieee80211_txrx_data *rx) |
311 | { | 311 | { |
312 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 312 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
313 | int always_sta_key; | 313 | int keyidx; |
314 | int hdrlen; | ||
314 | 315 | ||
315 | if (rx->sdata->type == IEEE80211_IF_TYPE_STA) | 316 | /* |
316 | always_sta_key = 0; | 317 | * Key selection 101 |
317 | else | 318 | * |
318 | always_sta_key = 1; | 319 | * There are three types of keys: |
320 | * - GTK (group keys) | ||
321 | * - PTK (pairwise keys) | ||
322 | * - STK (station-to-station pairwise keys) | ||
323 | * | ||
324 | * When selecting a key, we have to distinguish between multicast | ||
325 | * (including broadcast) and unicast frames, the latter can only | ||
326 | * use PTKs and STKs while the former always use GTKs. Unless, of | ||
327 | * course, actual WEP keys ("pre-RSNA") are used, then unicast | ||
328 | * frames can also use key indizes like GTKs. Hence, if we don't | ||
329 | * have a PTK/STK we check the key index for a WEP key. | ||
330 | * | ||
331 | * There is also a slight problem in IBSS mode: GTKs are negotiated | ||
332 | * with each station, that is something we don't currently handle. | ||
333 | */ | ||
334 | |||
335 | if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) | ||
336 | return TXRX_CONTINUE; | ||
319 | 337 | ||
320 | if (rx->sta && rx->sta->key && always_sta_key) { | 338 | /* |
339 | * No point in finding a key if the frame is neither | ||
340 | * addressed to us nor a multicast frame. | ||
341 | */ | ||
342 | if (!rx->u.rx.ra_match) | ||
343 | return TXRX_CONTINUE; | ||
344 | |||
345 | if (!is_multicast_ether_addr(hdr->addr1) && rx->sta && rx->sta->key) { | ||
321 | rx->key = rx->sta->key; | 346 | rx->key = rx->sta->key; |
322 | } else { | 347 | } else { |
323 | if (rx->sta && rx->sta->key) | 348 | /* |
324 | rx->key = rx->sta->key; | 349 | * The device doesn't give us the IV so we won't be |
325 | else | 350 | * able to look up the key. That's ok though, we |
326 | rx->key = rx->sdata->default_key; | 351 | * don't need to decrypt the frame, we just won't |
352 | * be able to keep statistics accurate. | ||
353 | * Except for key threshold notifications, should | ||
354 | * we somehow allow the driver to tell us which key | ||
355 | * the hardware used if this flag is set? | ||
356 | */ | ||
357 | if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) | ||
358 | return TXRX_CONTINUE; | ||
327 | 359 | ||
328 | if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) && | 360 | hdrlen = ieee80211_get_hdrlen(rx->fc); |
329 | rx->fc & IEEE80211_FCTL_PROTECTED) { | ||
330 | int keyidx = ieee80211_wep_get_keyidx(rx->skb); | ||
331 | 361 | ||
332 | if (keyidx >= 0 && keyidx < NUM_DEFAULT_KEYS && | 362 | if (rx->skb->len < 8 + hdrlen) |
333 | (!rx->sta || !rx->sta->key || keyidx > 0)) | 363 | return TXRX_DROP; /* TODO: count this? */ |
334 | rx->key = rx->sdata->keys[keyidx]; | ||
335 | 364 | ||
336 | if (!rx->key) { | 365 | /* |
337 | if (!rx->u.rx.ra_match) | 366 | * no need to call ieee80211_wep_get_keyidx, |
338 | return TXRX_DROP; | 367 | * it verifies a bunch of things we've done already |
339 | if (net_ratelimit()) | 368 | */ |
340 | printk(KERN_DEBUG "%s: RX WEP frame " | 369 | keyidx = rx->skb->data[hdrlen + 3] >> 6; |
341 | "with unknown keyidx %d " | 370 | |
342 | "(A1=" MAC_FMT | 371 | rx->key = rx->sdata->keys[keyidx]; |
343 | " A2=" MAC_FMT | 372 | |
344 | " A3=" MAC_FMT ")\n", | 373 | /* |
345 | rx->dev->name, keyidx, | 374 | * RSNA-protected unicast frames should always be sent with |
346 | MAC_ARG(hdr->addr1), | 375 | * pairwise or station-to-station keys, but for WEP we allow |
347 | MAC_ARG(hdr->addr2), | 376 | * using a key index as well. |
348 | MAC_ARG(hdr->addr3)); | 377 | */ |
349 | /* | 378 | if (rx->key && rx->key->alg != ALG_WEP && |
350 | * TODO: notify userspace about this | 379 | !is_multicast_ether_addr(hdr->addr1)) |
351 | * via cfg/nl80211 | 380 | rx->key = NULL; |
352 | */ | ||
353 | return TXRX_DROP; | ||
354 | } | ||
355 | } | ||
356 | } | 381 | } |
357 | 382 | ||
358 | if (rx->fc & IEEE80211_FCTL_PROTECTED && rx->key && rx->u.rx.ra_match) { | 383 | if (rx->key) { |
359 | rx->key->tx_rx_count++; | 384 | rx->key->tx_rx_count++; |
360 | if (unlikely(rx->local->key_tx_rx_threshold && | 385 | if (unlikely(rx->local->key_tx_rx_threshold && |
361 | rx->key->tx_rx_count > | 386 | rx->key->tx_rx_count > |
@@ -516,10 +541,6 @@ ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx) | |||
516 | static ieee80211_txrx_result | 541 | static ieee80211_txrx_result |
517 | ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx) | 542 | ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx) |
518 | { | 543 | { |
519 | /* If the device handles decryption totally, skip this test */ | ||
520 | if (rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) | ||
521 | return TXRX_CONTINUE; | ||
522 | |||
523 | if ((rx->key && rx->key->alg != ALG_WEP) || | 544 | if ((rx->key && rx->key->alg != ALG_WEP) || |
524 | !(rx->fc & IEEE80211_FCTL_PROTECTED) || | 545 | !(rx->fc & IEEE80211_FCTL_PROTECTED) || |
525 | ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && | 546 | ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && |
@@ -871,8 +892,14 @@ ieee80211_rx_h_802_1x_pae(struct ieee80211_txrx_data *rx) | |||
871 | static ieee80211_txrx_result | 892 | static ieee80211_txrx_result |
872 | ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx) | 893 | ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx) |
873 | { | 894 | { |
874 | /* If the device handles decryption totally, skip this test */ | 895 | /* |
875 | if (rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) | 896 | * Pass through unencrypted frames if the hardware might have |
897 | * decrypted them already without telling us, but that can only | ||
898 | * be true if we either didn't find a key or the found key is | ||
899 | * uploaded to the hardware. | ||
900 | */ | ||
901 | if ((rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) && | ||
902 | (!rx->key || !rx->key->force_sw_encrypt)) | ||
876 | return TXRX_CONTINUE; | 903 | return TXRX_CONTINUE; |
877 | 904 | ||
878 | /* Drop unencrypted frames if key is set. */ | 905 | /* Drop unencrypted frames if key is set. */ |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 783af32c6911..f5723ea15aae 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -137,9 +137,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) | |||
137 | 137 | ||
138 | fc = rx->fc; | 138 | fc = rx->fc; |
139 | 139 | ||
140 | /* If device handles decryption totally, skip this check */ | 140 | /* |
141 | if ((rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) || | 141 | * No way to verify the MIC if the hardware stripped it |
142 | (rx->local->hw.flags & IEEE80211_HW_DEVICE_STRIPS_MIC)) | 142 | */ |
143 | if (rx->local->hw.flags & IEEE80211_HW_DEVICE_STRIPS_MIC) | ||
143 | return TXRX_CONTINUE; | 144 | return TXRX_CONTINUE; |
144 | 145 | ||
145 | if (!rx->key || rx->key->alg != ALG_TKIP || | 146 | if (!rx->key || rx->key->alg != ALG_TKIP || |