Commit 3cfcf6ac6d69dc290e96416731eea5c88ac7d426

Authored by Jouni Malinen
Committed by John W. Linville
1 parent 765cb46a3f

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>

Showing 14 changed files with 317 additions and 21 deletions Side-by-side Diff

drivers/net/wireless/ath5k/pcu.c
... ... @@ -1026,6 +1026,9 @@
1026 1026 return AR5K_KEYTABLE_TYPE_40;
1027 1027 else if (key->keylen == LEN_WEP104)
1028 1028 return AR5K_KEYTABLE_TYPE_104;
  1029 + return -EINVAL;
  1030 + default:
  1031 + return -EINVAL;
1029 1032 }
1030 1033 return -EINVAL;
1031 1034 }
include/linux/ieee80211.h
... ... @@ -1139,6 +1139,7 @@
1139 1139 /* reserved: 0x000FAC03 */
1140 1140 #define WLAN_CIPHER_SUITE_CCMP 0x000FAC04
1141 1141 #define WLAN_CIPHER_SUITE_WEP104 0x000FAC05
  1142 +#define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06
1142 1143  
1143 1144 #define WLAN_MAX_KEY_LEN 32
1144 1145  
include/linux/nl80211.h
... ... @@ -72,8 +72,8 @@
72 72 *
73 73 * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified
74 74 * by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC.
75   - * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT or
76   - * %NL80211_ATTR_KEY_THRESHOLD.
  75 + * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,
  76 + * %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.
77 77 * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
78 78 * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC and %NL80211_ATTR_KEY_CIPHER
79 79 * attributes.
... ... @@ -345,6 +345,8 @@
345 345 NL80211_ATTR_WIPHY_TXQ_PARAMS,
346 346 NL80211_ATTR_WIPHY_FREQ,
347 347 NL80211_ATTR_WIPHY_CHANNEL_TYPE,
  348 +
  349 + NL80211_ATTR_KEY_DEFAULT_MGMT,
348 350  
349 351 /* add attributes here, update the policy in nl80211.c */
350 352  
include/net/cfg80211.h
... ... @@ -473,6 +473,8 @@
473 473 *
474 474 * @set_default_key: set the default key on an interface
475 475 *
  476 + * @set_default_mgmt_key: set the default management frame key on an interface
  477 + *
476 478 * @add_beacon: Add a beacon with given parameters, @head, @interval
477 479 * and @dtim_period will be valid, @tail is optional.
478 480 * @set_beacon: Change the beacon parameters for an access point mode
... ... @@ -520,6 +522,9 @@
520 522 int (*set_default_key)(struct wiphy *wiphy,
521 523 struct net_device *netdev,
522 524 u8 key_index);
  525 + int (*set_default_mgmt_key)(struct wiphy *wiphy,
  526 + struct net_device *netdev,
  527 + u8 key_index);
523 528  
524 529 int (*add_beacon)(struct wiphy *wiphy, struct net_device *dev,
525 530 struct beacon_parameters *info);
include/net/mac80211.h
... ... @@ -651,11 +651,13 @@
651 651 * @ALG_WEP: WEP40 or WEP104
652 652 * @ALG_TKIP: TKIP
653 653 * @ALG_CCMP: CCMP (AES)
  654 + * @ALG_AES_CMAC: AES-128-CMAC
654 655 */
655 656 enum ieee80211_key_alg {
656 657 ALG_WEP,
657 658 ALG_TKIP,
658 659 ALG_CCMP,
  660 + ALG_AES_CMAC,
659 661 };
660 662  
661 663 /**
... ... @@ -133,6 +133,9 @@
133 133 case WLAN_CIPHER_SUITE_CCMP:
134 134 alg = ALG_CCMP;
135 135 break;
  136 + case WLAN_CIPHER_SUITE_AES_CMAC:
  137 + alg = ALG_AES_CMAC;
  138 + break;
136 139 default:
137 140 return -EINVAL;
138 141 }
... ... @@ -275,6 +278,17 @@
275 278 else
276 279 params.cipher = WLAN_CIPHER_SUITE_WEP104;
277 280 break;
  281 + case ALG_AES_CMAC:
  282 + params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
  283 + seq[0] = key->u.aes_cmac.tx_pn[5];
  284 + seq[1] = key->u.aes_cmac.tx_pn[4];
  285 + seq[2] = key->u.aes_cmac.tx_pn[3];
  286 + seq[3] = key->u.aes_cmac.tx_pn[2];
  287 + seq[4] = key->u.aes_cmac.tx_pn[1];
  288 + seq[5] = key->u.aes_cmac.tx_pn[0];
  289 + params.seq = seq;
  290 + params.seq_len = 6;
  291 + break;
278 292 }
279 293  
280 294 params.key = key->conf.key;
... ... @@ -304,6 +318,22 @@
304 318 return 0;
305 319 }
306 320  
  321 +static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
  322 + struct net_device *dev,
  323 + u8 key_idx)
  324 +{
  325 + struct ieee80211_sub_if_data *sdata;
  326 +
  327 + rcu_read_lock();
  328 +
  329 + sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  330 + ieee80211_set_default_mgmt_key(sdata, key_idx);
  331 +
  332 + rcu_read_unlock();
  333 +
  334 + return 0;
  335 +}
  336 +
307 337 static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
308 338 {
309 339 struct ieee80211_sub_if_data *sdata = sta->sdata;
... ... @@ -1153,6 +1183,7 @@
1153 1183 .del_key = ieee80211_del_key,
1154 1184 .get_key = ieee80211_get_key,
1155 1185 .set_default_key = ieee80211_config_default_key,
  1186 + .set_default_mgmt_key = ieee80211_config_default_mgmt_key,
1156 1187 .add_beacon = ieee80211_add_beacon,
1157 1188 .set_beacon = ieee80211_set_beacon,
1158 1189 .del_beacon = ieee80211_del_beacon,
net/mac80211/debugfs_key.c
... ... @@ -76,6 +76,9 @@
76 76 case ALG_CCMP:
77 77 alg = "CCMP\n";
78 78 break;
  79 + case ALG_AES_CMAC:
  80 + alg = "AES-128-CMAC\n";
  81 + break;
79 82 default:
80 83 return 0;
81 84 }
... ... @@ -105,6 +108,12 @@
105 108 len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
106 109 tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]);
107 110 break;
  111 + case ALG_AES_CMAC:
  112 + tpn = key->u.aes_cmac.tx_pn;
  113 + len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
  114 + tpn[0], tpn[1], tpn[2], tpn[3], tpn[4],
  115 + tpn[5]);
  116 + break;
108 117 default:
109 118 return 0;
110 119 }
... ... @@ -142,6 +151,14 @@
142 151 }
143 152 len = p - buf;
144 153 break;
  154 + case ALG_AES_CMAC:
  155 + rpn = key->u.aes_cmac.rx_pn;
  156 + p += scnprintf(p, sizeof(buf)+buf-p,
  157 + "%02x%02x%02x%02x%02x%02x\n",
  158 + rpn[0], rpn[1], rpn[2],
  159 + rpn[3], rpn[4], rpn[5]);
  160 + len = p - buf;
  161 + break;
145 162 default:
146 163 return 0;
147 164 }
148 165  
149 166  
... ... @@ -156,13 +173,40 @@
156 173 char buf[20];
157 174 int len;
158 175  
159   - if (key->conf.alg != ALG_CCMP)
  176 + switch (key->conf.alg) {
  177 + case ALG_CCMP:
  178 + len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
  179 + break;
  180 + case ALG_AES_CMAC:
  181 + len = scnprintf(buf, sizeof(buf), "%u\n",
  182 + key->u.aes_cmac.replays);
  183 + break;
  184 + default:
160 185 return 0;
161   - len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
  186 + }
162 187 return simple_read_from_buffer(userbuf, count, ppos, buf, len);
163 188 }
164 189 KEY_OPS(replays);
165 190  
  191 +static ssize_t key_icverrors_read(struct file *file, char __user *userbuf,
  192 + size_t count, loff_t *ppos)
  193 +{
  194 + struct ieee80211_key *key = file->private_data;
  195 + char buf[20];
  196 + int len;
  197 +
  198 + switch (key->conf.alg) {
  199 + case ALG_AES_CMAC:
  200 + len = scnprintf(buf, sizeof(buf), "%u\n",
  201 + key->u.aes_cmac.icverrors);
  202 + break;
  203 + default:
  204 + return 0;
  205 + }
  206 + return simple_read_from_buffer(userbuf, count, ppos, buf, len);
  207 +}
  208 +KEY_OPS(icverrors);
  209 +
166 210 static ssize_t key_key_read(struct file *file, char __user *userbuf,
167 211 size_t count, loff_t *ppos)
168 212 {
... ... @@ -222,6 +266,7 @@
222 266 DEBUGFS_ADD(tx_spec);
223 267 DEBUGFS_ADD(rx_spec);
224 268 DEBUGFS_ADD(replays);
  269 + DEBUGFS_ADD(icverrors);
225 270 DEBUGFS_ADD(key);
226 271 DEBUGFS_ADD(ifindex);
227 272 };
... ... @@ -243,6 +288,7 @@
243 288 DEBUGFS_DEL(tx_spec);
244 289 DEBUGFS_DEL(rx_spec);
245 290 DEBUGFS_DEL(replays);
  291 + DEBUGFS_DEL(icverrors);
246 292 DEBUGFS_DEL(key);
247 293 DEBUGFS_DEL(ifindex);
248 294  
... ... @@ -278,6 +324,35 @@
278 324  
279 325 debugfs_remove(sdata->common_debugfs.default_key);
280 326 sdata->common_debugfs.default_key = NULL;
  327 +}
  328 +
  329 +void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
  330 +{
  331 + char buf[50];
  332 + struct ieee80211_key *key;
  333 +
  334 + if (!sdata->debugfsdir)
  335 + return;
  336 +
  337 + /* this is running under the key lock */
  338 +
  339 + key = sdata->default_mgmt_key;
  340 + if (key) {
  341 + sprintf(buf, "../keys/%d", key->debugfs.cnt);
  342 + sdata->common_debugfs.default_mgmt_key =
  343 + debugfs_create_symlink("default_mgmt_key",
  344 + sdata->debugfsdir, buf);
  345 + } else
  346 + ieee80211_debugfs_key_remove_mgmt_default(sdata);
  347 +}
  348 +
  349 +void ieee80211_debugfs_key_remove_mgmt_default(struct ieee80211_sub_if_data *sdata)
  350 +{
  351 + if (!sdata)
  352 + return;
  353 +
  354 + debugfs_remove(sdata->common_debugfs.default_mgmt_key);
  355 + sdata->common_debugfs.default_mgmt_key = NULL;
281 356 }
282 357  
283 358 void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
net/mac80211/debugfs_key.h
... ... @@ -6,6 +6,10 @@
6 6 void ieee80211_debugfs_key_remove(struct ieee80211_key *key);
7 7 void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata);
8 8 void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata);
  9 +void ieee80211_debugfs_key_add_mgmt_default(
  10 + struct ieee80211_sub_if_data *sdata);
  11 +void ieee80211_debugfs_key_remove_mgmt_default(
  12 + struct ieee80211_sub_if_data *sdata);
9 13 void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
10 14 struct sta_info *sta);
11 15 #else
... ... @@ -17,6 +21,12 @@
17 21 struct ieee80211_sub_if_data *sdata)
18 22 {}
19 23 static inline void ieee80211_debugfs_key_remove_default(
  24 + struct ieee80211_sub_if_data *sdata)
  25 +{}
  26 +static inline void ieee80211_debugfs_key_add_mgmt_default(
  27 + struct ieee80211_sub_if_data *sdata)
  28 +{}
  29 +static inline void ieee80211_debugfs_key_remove_mgmt_default(
20 30 struct ieee80211_sub_if_data *sdata)
21 31 {}
22 32 static inline void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
net/mac80211/ieee80211_i.h
... ... @@ -409,8 +409,10 @@
409 409 unsigned int fragment_next;
410 410  
411 411 #define NUM_DEFAULT_KEYS 4
412   - struct ieee80211_key *keys[NUM_DEFAULT_KEYS];
  412 +#define NUM_DEFAULT_MGMT_KEYS 2
  413 + struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
413 414 struct ieee80211_key *default_key;
  415 + struct ieee80211_key *default_mgmt_key;
414 416  
415 417 u16 sequence_number;
416 418  
... ... @@ -482,6 +484,7 @@
482 484 } debugfs;
483 485 struct {
484 486 struct dentry *default_key;
  487 + struct dentry *default_mgmt_key;
485 488 } common_debugfs;
486 489  
487 490 #ifdef CONFIG_MAC80211_MESH
... ... @@ -18,6 +18,7 @@
18 18 #include "ieee80211_i.h"
19 19 #include "debugfs_key.h"
20 20 #include "aes_ccm.h"
  21 +#include "aes_cmac.h"
21 22  
22 23  
23 24 /**
24 25  
25 26  
... ... @@ -215,13 +216,38 @@
215 216 spin_unlock_irqrestore(&sdata->local->key_lock, flags);
216 217 }
217 218  
  219 +static void
  220 +__ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
  221 +{
  222 + struct ieee80211_key *key = NULL;
218 223  
  224 + if (idx >= NUM_DEFAULT_KEYS &&
  225 + idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
  226 + key = sdata->keys[idx];
  227 +
  228 + rcu_assign_pointer(sdata->default_mgmt_key, key);
  229 +
  230 + if (key)
  231 + add_todo(key, KEY_FLAG_TODO_DEFMGMTKEY);
  232 +}
  233 +
  234 +void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
  235 + int idx)
  236 +{
  237 + unsigned long flags;
  238 +
  239 + spin_lock_irqsave(&sdata->local->key_lock, flags);
  240 + __ieee80211_set_default_mgmt_key(sdata, idx);
  241 + spin_unlock_irqrestore(&sdata->local->key_lock, flags);
  242 +}
  243 +
  244 +
219 245 static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
220 246 struct sta_info *sta,
221 247 struct ieee80211_key *old,
222 248 struct ieee80211_key *new)
223 249 {
224   - int idx, defkey;
  250 + int idx, defkey, defmgmtkey;
225 251  
226 252 if (new)
227 253 list_add(&new->list, &sdata->key_list);
228 254  
229 255  
... ... @@ -237,13 +263,19 @@
237 263 idx = new->conf.keyidx;
238 264  
239 265 defkey = old && sdata->default_key == old;
  266 + defmgmtkey = old && sdata->default_mgmt_key == old;
240 267  
241 268 if (defkey && !new)
242 269 __ieee80211_set_default_key(sdata, -1);
  270 + if (defmgmtkey && !new)
  271 + __ieee80211_set_default_mgmt_key(sdata, -1);
243 272  
244 273 rcu_assign_pointer(sdata->keys[idx], new);
245 274 if (defkey && new)
246 275 __ieee80211_set_default_key(sdata, new->conf.keyidx);
  276 + if (defmgmtkey && new)
  277 + __ieee80211_set_default_mgmt_key(sdata,
  278 + new->conf.keyidx);
247 279 }
248 280  
249 281 if (old) {
... ... @@ -262,7 +294,7 @@
262 294 {
263 295 struct ieee80211_key *key;
264 296  
265   - BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS);
  297 + BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
266 298  
267 299 key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL);
268 300 if (!key)
... ... @@ -291,6 +323,10 @@
291 323 key->conf.iv_len = CCMP_HDR_LEN;
292 324 key->conf.icv_len = CCMP_MIC_LEN;
293 325 break;
  326 + case ALG_AES_CMAC:
  327 + key->conf.iv_len = 0;
  328 + key->conf.icv_len = sizeof(struct ieee80211_mmie);
  329 + break;
294 330 }
295 331 memcpy(key->conf.key, key_data, key_len);
296 332 INIT_LIST_HEAD(&key->list);
... ... @@ -308,6 +344,19 @@
308 344 }
309 345 }
310 346  
  347 + if (alg == ALG_AES_CMAC) {
  348 + /*
  349 + * Initialize AES key state here as an optimization so that
  350 + * it does not need to be initialized for every packet.
  351 + */
  352 + key->u.aes_cmac.tfm =
  353 + ieee80211_aes_cmac_key_setup(key_data);
  354 + if (!key->u.aes_cmac.tfm) {
  355 + kfree(key);
  356 + return NULL;
  357 + }
  358 + }
  359 +
311 360 return key;
312 361 }
313 362  
... ... @@ -461,6 +510,8 @@
461 510  
462 511 if (key->conf.alg == ALG_CCMP)
463 512 ieee80211_aes_key_free(key->u.ccmp.tfm);
  513 + if (key->conf.alg == ALG_AES_CMAC)
  514 + ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
464 515 ieee80211_debugfs_key_remove(key);
465 516  
466 517 kfree(key);
... ... @@ -483,6 +534,7 @@
483 534 list_del_init(&key->todo);
484 535 todoflags = key->flags & (KEY_FLAG_TODO_ADD_DEBUGFS |
485 536 KEY_FLAG_TODO_DEFKEY |
  537 + KEY_FLAG_TODO_DEFMGMTKEY |
486 538 KEY_FLAG_TODO_HWACCEL_ADD |
487 539 KEY_FLAG_TODO_HWACCEL_REMOVE |
488 540 KEY_FLAG_TODO_DELETE);
... ... @@ -500,6 +552,11 @@
500 552 ieee80211_debugfs_key_add_default(key->sdata);
501 553 work_done = true;
502 554 }
  555 + if (todoflags & KEY_FLAG_TODO_DEFMGMTKEY) {
  556 + ieee80211_debugfs_key_remove_mgmt_default(key->sdata);
  557 + ieee80211_debugfs_key_add_mgmt_default(key->sdata);
  558 + work_done = true;
  559 + }
503 560 if (todoflags & KEY_FLAG_TODO_HWACCEL_ADD) {
504 561 ieee80211_key_enable_hw_accel(key);
505 562 work_done = true;
... ... @@ -535,6 +592,7 @@
535 592 ieee80211_key_lock();
536 593  
537 594 ieee80211_debugfs_key_remove_default(sdata);
  595 + ieee80211_debugfs_key_remove_mgmt_default(sdata);
538 596  
539 597 spin_lock_irqsave(&sdata->local->key_lock, flags);
540 598 list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
... ... @@ -46,6 +46,8 @@
46 46 * acceleration.
47 47 * @KEY_FLAG_TODO_DEFKEY: Key is default key and debugfs needs to be updated.
48 48 * @KEY_FLAG_TODO_ADD_DEBUGFS: Key needs to be added to debugfs.
  49 + * @KEY_FLAG_TODO_DEFMGMTKEY: Key is default management key and debugfs needs
  50 + * to be updated.
49 51 */
50 52 enum ieee80211_internal_key_flags {
51 53 KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0),
... ... @@ -54,6 +56,7 @@
54 56 KEY_FLAG_TODO_HWACCEL_REMOVE = BIT(3),
55 57 KEY_FLAG_TODO_DEFKEY = BIT(4),
56 58 KEY_FLAG_TODO_ADD_DEBUGFS = BIT(5),
  59 + KEY_FLAG_TODO_DEFMGMTKEY = BIT(6),
57 60 };
58 61  
59 62 struct tkip_ctx {
... ... @@ -124,6 +127,7 @@
124 127 struct dentry *tx_spec;
125 128 struct dentry *rx_spec;
126 129 struct dentry *replays;
  130 + struct dentry *icverrors;
127 131 struct dentry *key;
128 132 struct dentry *ifindex;
129 133 int cnt;
... ... @@ -150,6 +154,8 @@
150 154 struct sta_info *sta);
151 155 void ieee80211_key_free(struct ieee80211_key *key);
152 156 void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx);
  157 +void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
  158 + int idx);
153 159 void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
154 160 void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
155 161 void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata);
... ... @@ -446,6 +446,52 @@
446 446 return RX_CONTINUE;
447 447 }
448 448  
  449 +
  450 +static 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 +
  461 +static 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 */
  473 +static 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 +
449 495 static ieee80211_rx_result
450 496 ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
451 497 {
452 498  
453 499  
454 500  
... ... @@ -561,21 +607,23 @@
561 607 int hdrlen;
562 608 ieee80211_rx_result result = RX_DROP_UNUSABLE;
563 609 struct ieee80211_key *stakey = NULL;
  610 + int mmie_keyidx = -1;
564 611  
565 612 /*
566 613 * Key selection 101
567 614 *
568   - * There are three types of keys:
  615 + * There are four types of keys:
569 616 * - GTK (group keys)
  617 + * - IGTK (group keys for management frames)
570 618 * - PTK (pairwise keys)
571 619 * - STK (station-to-station pairwise keys)
572 620 *
573 621 * When selecting a key, we have to distinguish between multicast
574 622 * (including broadcast) and unicast frames, the latter can only
575   - * use PTKs and STKs while the former always use GTKs. Unless, of
576   - * course, actual WEP keys ("pre-RSNA") are used, then unicast
577   - * frames can also use key indizes like GTKs. Hence, if we don't
578   - * have a PTK/STK we check the key index for a WEP key.
  623 + * use PTKs and STKs while the former always use GTKs and IGTKs.
  624 + * Unless, of course, actual WEP keys ("pre-RSNA") are used, then
  625 + * unicast frames can also use key indices like GTKs. Hence, if we
  626 + * don't have a PTK/STK we check the key index for a WEP key.
579 627 *
580 628 * Note that in a regular BSS, multicast frames are sent by the
581 629 * AP only, associated stations unicast the frame to the AP first
... ... @@ -588,8 +636,14 @@
588 636 * possible.
589 637 */
590 638  
591   - if (!ieee80211_has_protected(hdr->frame_control))
592   - return RX_CONTINUE;
  639 + if (!ieee80211_has_protected(hdr->frame_control)) {
  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 649 * No point in finding a key and decrypting if the frame is neither
... ... @@ -603,6 +657,16 @@
603 657  
604 658 if (!is_multicast_ether_addr(hdr->addr1) && stakey) {
605 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 670 } else {
607 671 /*
608 672 * The device doesn't give us the IV so we won't be
... ... @@ -665,6 +729,9 @@
665 729 case ALG_CCMP:
666 730 result = ieee80211_crypto_ccmp_decrypt(rx);
667 731 break;
  732 + case ALG_AES_CMAC:
  733 + result = ieee80211_crypto_aes_cmac_decrypt(rx);
  734 + break;
668 735 }
669 736  
670 737 /* either the frame has been decrypted or will be dropped */
... ... @@ -1112,6 +1179,15 @@
1112 1179 /* Drop unencrypted frames if key is set. */
1113 1180 if (unlikely(!ieee80211_has_protected(fc) &&
1114 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 1191 (rx->key || rx->sdata->drop_unencrypted)))
1116 1192 return -EACCES;
1117 1193  
... ... @@ -425,6 +425,9 @@
425 425 tx->key = NULL;
426 426 else if (tx->sta && (key = rcu_dereference(tx->sta->key)))
427 427 tx->key = key;
  428 + else if (ieee80211_is_mgmt(hdr->frame_control) &&
  429 + (key = rcu_dereference(tx->sdata->default_mgmt_key)))
  430 + tx->key = key;
428 431 else if ((key = rcu_dereference(tx->sdata->default_key)))
429 432 tx->key = key;
430 433 else if (tx->sdata->drop_unencrypted &&
... ... @@ -453,6 +456,10 @@
453 456 tx->skb))
454 457 tx->key = NULL;
455 458 break;
  459 + case ALG_AES_CMAC:
  460 + if (!ieee80211_is_mgmt(hdr->frame_control))
  461 + tx->key = NULL;
  462 + break;
456 463 }
457 464 }
458 465  
... ... @@ -808,6 +815,8 @@
808 815 return ieee80211_crypto_tkip_encrypt(tx);
809 816 case ALG_CCMP:
810 817 return ieee80211_crypto_ccmp_encrypt(tx);
  818 + case ALG_AES_CMAC:
  819 + return ieee80211_crypto_aes_cmac_encrypt(tx);
811 820 }
812 821  
813 822 /* not reached */
net/wireless/nl80211.c
... ... @@ -738,7 +738,7 @@
738 738 if (info->attrs[NL80211_ATTR_KEY_IDX])
739 739 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
740 740  
741   - if (key_idx > 3)
  741 + if (key_idx > 5)
742 742 return -EINVAL;
743 743  
744 744 if (info->attrs[NL80211_ATTR_MAC])
745 745  
746 746  
747 747  
748 748  
... ... @@ -804,30 +804,41 @@
804 804 int err;
805 805 struct net_device *dev;
806 806 u8 key_idx;
  807 + int (*func)(struct wiphy *wiphy, struct net_device *netdev,
  808 + u8 key_index);
807 809  
808 810 if (!info->attrs[NL80211_ATTR_KEY_IDX])
809 811 return -EINVAL;
810 812  
811 813 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
812 814  
813   - if (key_idx > 3)
  815 + if (info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]) {
  816 + if (key_idx < 4 || key_idx > 5)
  817 + return -EINVAL;
  818 + } else if (key_idx > 3)
814 819 return -EINVAL;
815 820  
816 821 /* currently only support setting default key */
817   - if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
  822 + if (!info->attrs[NL80211_ATTR_KEY_DEFAULT] &&
  823 + !info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT])
818 824 return -EINVAL;
819 825  
820 826 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
821 827 if (err)
822 828 return err;
823 829  
824   - if (!drv->ops->set_default_key) {
  830 + if (info->attrs[NL80211_ATTR_KEY_DEFAULT])
  831 + func = drv->ops->set_default_key;
  832 + else
  833 + func = drv->ops->set_default_mgmt_key;
  834 +
  835 + if (!func) {
825 836 err = -EOPNOTSUPP;
826 837 goto out;
827 838 }
828 839  
829 840 rtnl_lock();
830   - err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx);
  841 + err = func(&drv->wiphy, dev, key_idx);
831 842 rtnl_unlock();
832 843  
833 844 out:
... ... @@ -863,7 +874,7 @@
863 874 if (info->attrs[NL80211_ATTR_MAC])
864 875 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
865 876  
866   - if (key_idx > 3)
  877 + if (key_idx > 5)
867 878 return -EINVAL;
868 879  
869 880 /*
... ... @@ -894,6 +905,10 @@
894 905 if (params.key_len != 13)
895 906 return -EINVAL;
896 907 break;
  908 + case WLAN_CIPHER_SUITE_AES_CMAC:
  909 + if (params.key_len != 16)
  910 + return -EINVAL;
  911 + break;
897 912 default:
898 913 return -EINVAL;
899 914 }
... ... @@ -928,7 +943,7 @@
928 943 if (info->attrs[NL80211_ATTR_KEY_IDX])
929 944 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
930 945  
931   - if (key_idx > 3)
  946 + if (key_idx > 5)
932 947 return -EINVAL;
933 948  
934 949 if (info->attrs[NL80211_ATTR_MAC])