aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2009-01-08 06:32:02 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-29 16:00:03 -0500
commit3cfcf6ac6d69dc290e96416731eea5c88ac7d426 (patch)
tree35bc626e2e3f7c37a7eb50c1f057adb4830eccc6 /net/mac80211/rx.c
parent765cb46a3fc856245ea68a7c961ac87c77e4ae2d (diff)
mac80211: 802.11w - Use BIP (AES-128-CMAC)
Add mechanism for managing BIP keys (IGTK) and integrate BIP into the TX/RX paths. Signed-off-by: Jouni Malinen <j@w1.fi> Acked-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c90
1 files changed, 83 insertions, 7 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b68e082e99ce..abc3aa583ca6 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -446,6 +446,52 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
446 return RX_CONTINUE; 446 return RX_CONTINUE;
447} 447}
448 448
449
450static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb)
451{
452 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
453
454 if (skb->len < 24 || is_multicast_ether_addr(hdr->addr1))
455 return 0;
456
457 return ieee80211_is_robust_mgmt_frame(hdr);
458}
459
460
461static int ieee80211_is_multicast_robust_mgmt_frame(struct sk_buff *skb)
462{
463 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
464
465 if (skb->len < 24 || !is_multicast_ether_addr(hdr->addr1))
466 return 0;
467
468 return ieee80211_is_robust_mgmt_frame(hdr);
469}
470
471
472/* Get the BIP key index from MMIE; return -1 if this is not a BIP frame */
473static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
474{
475 struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data;
476 struct ieee80211_mmie *mmie;
477
478 if (skb->len < 24 + sizeof(*mmie) ||
479 !is_multicast_ether_addr(hdr->da))
480 return -1;
481
482 if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) hdr))
483 return -1; /* not a robust management frame */
484
485 mmie = (struct ieee80211_mmie *)
486 (skb->data + skb->len - sizeof(*mmie));
487 if (mmie->element_id != WLAN_EID_MMIE ||
488 mmie->length != sizeof(*mmie) - 2)
489 return -1;
490
491 return le16_to_cpu(mmie->key_id);
492}
493
494
449static ieee80211_rx_result 495static ieee80211_rx_result
450ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) 496ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
451{ 497{
@@ -561,21 +607,23 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
561 int hdrlen; 607 int hdrlen;
562 ieee80211_rx_result result = RX_DROP_UNUSABLE; 608 ieee80211_rx_result result = RX_DROP_UNUSABLE;
563 struct ieee80211_key *stakey = NULL; 609 struct ieee80211_key *stakey = NULL;
610 int mmie_keyidx = -1;
564 611
565 /* 612 /*
566 * Key selection 101 613 * Key selection 101
567 * 614 *
568 * There are three types of keys: 615 * There are four types of keys:
569 * - GTK (group keys) 616 * - GTK (group keys)
617 * - IGTK (group keys for management frames)
570 * - PTK (pairwise keys) 618 * - PTK (pairwise keys)
571 * - STK (station-to-station pairwise keys) 619 * - STK (station-to-station pairwise keys)
572 * 620 *
573 * When selecting a key, we have to distinguish between multicast 621 * When selecting a key, we have to distinguish between multicast
574 * (including broadcast) and unicast frames, the latter can only 622 * (including broadcast) and unicast frames, the latter can only
575 * use PTKs and STKs while the former always use GTKs. Unless, of 623 * use PTKs and STKs while the former always use GTKs and IGTKs.
576 * course, actual WEP keys ("pre-RSNA") are used, then unicast 624 * Unless, of course, actual WEP keys ("pre-RSNA") are used, then
577 * frames can also use key indizes like GTKs. Hence, if we don't 625 * unicast frames can also use key indices like GTKs. Hence, if we
578 * have a PTK/STK we check the key index for a WEP key. 626 * don't have a PTK/STK we check the key index for a WEP key.
579 * 627 *
580 * Note that in a regular BSS, multicast frames are sent by the 628 * Note that in a regular BSS, multicast frames are sent by the
581 * AP only, associated stations unicast the frame to the AP first 629 * AP only, associated stations unicast the frame to the AP first
@@ -588,8 +636,14 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
588 * possible. 636 * possible.
589 */ 637 */
590 638
591 if (!ieee80211_has_protected(hdr->frame_control)) 639 if (!ieee80211_has_protected(hdr->frame_control)) {
592 return RX_CONTINUE; 640 if (!ieee80211_is_mgmt(hdr->frame_control) ||
641 rx->sta == NULL || !test_sta_flags(rx->sta, WLAN_STA_MFP))
642 return RX_CONTINUE;
643 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
644 if (mmie_keyidx < 0)
645 return RX_CONTINUE;
646 }
593 647
594 /* 648 /*
595 * No point in finding a key and decrypting if the frame is neither 649 * No point in finding a key and decrypting if the frame is neither
@@ -603,6 +657,16 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
603 657
604 if (!is_multicast_ether_addr(hdr->addr1) && stakey) { 658 if (!is_multicast_ether_addr(hdr->addr1) && stakey) {
605 rx->key = stakey; 659 rx->key = stakey;
660 } else if (mmie_keyidx >= 0) {
661 /* Broadcast/multicast robust management frame / BIP */
662 if ((rx->status->flag & RX_FLAG_DECRYPTED) &&
663 (rx->status->flag & RX_FLAG_IV_STRIPPED))
664 return RX_CONTINUE;
665
666 if (mmie_keyidx < NUM_DEFAULT_KEYS ||
667 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
668 return RX_DROP_MONITOR; /* unexpected BIP keyidx */
669 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
606 } else { 670 } else {
607 /* 671 /*
608 * The device doesn't give us the IV so we won't be 672 * The device doesn't give us the IV so we won't be
@@ -665,6 +729,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
665 case ALG_CCMP: 729 case ALG_CCMP:
666 result = ieee80211_crypto_ccmp_decrypt(rx); 730 result = ieee80211_crypto_ccmp_decrypt(rx);
667 break; 731 break;
732 case ALG_AES_CMAC:
733 result = ieee80211_crypto_aes_cmac_decrypt(rx);
734 break;
668 } 735 }
669 736
670 /* either the frame has been decrypted or will be dropped */ 737 /* either the frame has been decrypted or will be dropped */
@@ -1112,6 +1179,15 @@ ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
1112 /* Drop unencrypted frames if key is set. */ 1179 /* Drop unencrypted frames if key is set. */
1113 if (unlikely(!ieee80211_has_protected(fc) && 1180 if (unlikely(!ieee80211_has_protected(fc) &&
1114 !ieee80211_is_nullfunc(fc) && 1181 !ieee80211_is_nullfunc(fc) &&
1182 (!ieee80211_is_mgmt(fc) ||
1183 (ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
1184 rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP))) &&
1185 (rx->key || rx->sdata->drop_unencrypted)))
1186 return -EACCES;
1187 /* BIP does not use Protected field, so need to check MMIE */
1188 if (unlikely(rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP) &&
1189 ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
1190 ieee80211_get_mmie_keyidx(rx->skb) < 0 &&
1115 (rx->key || rx->sdata->drop_unencrypted))) 1191 (rx->key || rx->sdata->drop_unencrypted)))
1116 return -EACCES; 1192 return -EACCES;
1117 1193