1 /* 2 * Copyright 2002-2005, Instant802 Networks, Inc. 3 * Copyright 2005-2006, Devicescape Software, Inc. 4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 5 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12 #include <linux/if_ether.h> 13 #include <linux/etherdevice.h> 14 #include <linux/list.h> 15 #include <linux/rcupdate.h> 16 #include <net/mac80211.h> 17 #include "ieee80211_i.h" 18 #include "debugfs_key.h" 19 #include "aes_ccm.h" 20 21 22 /* 23 * Key handling basics 24 * 25 * Key handling in mac80211 is done based on per-interface (sub_if_data) 26 * keys and per-station keys. Since each station belongs to an interface, 27 * each station key also belongs to that interface. 28 * 29 * Hardware acceleration is done on a best-effort basis, for each key 30 * that is eligible the hardware is asked to enable that key but if 31 * it cannot do that they key is simply kept for software encryption. 32 * There is currently no way of knowing this except by looking into 33 * debugfs. 34 * 35 * All operations here are called under RTNL so no extra locking is 36 * required. 37 */ 38 39 static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 40 static const u8 zero_addr[ETH_ALEN]; 41 42 static const u8 *get_mac_for_key(struct ieee80211_key *key) 43 { 44 const u8 *addr = bcast_addr; 45 46 /* 47 * If we're an AP we won't ever receive frames with a non-WEP 48 * group key so we tell the driver that by using the zero MAC 49 * address to indicate a transmit-only key. 50 */ 51 if (key->conf.alg != ALG_WEP && 52 (key->sdata->type == IEEE80211_IF_TYPE_AP || 53 key->sdata->type == IEEE80211_IF_TYPE_VLAN)) 54 addr = zero_addr; 55 56 if (key->sta) 57 addr = key->sta->addr; 58 59 return addr; 60 } 61 62 static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) 63 { 64 const u8 *addr; 65 int ret; 66 DECLARE_MAC_BUF(mac); 67 68 if (!key->local->ops->set_key) 69 return; 70 71 addr = get_mac_for_key(key); 72 73 ret = key->local->ops->set_key(local_to_hw(key->local), SET_KEY, 74 key->sdata->dev->dev_addr, addr, 75 &key->conf); 76 77 if (!ret) 78 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; 79 80 if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP) 81 printk(KERN_ERR "mac80211-%s: failed to set key " 82 "(%d, %s) to hardware (%d)\n", 83 wiphy_name(key->local->hw.wiphy), 84 key->conf.keyidx, print_mac(mac, addr), ret); 85 } 86 87 static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) 88 { 89 const u8 *addr; 90 int ret; 91 DECLARE_MAC_BUF(mac); 92 93 if (!key->local->ops->set_key) 94 return; 95 96 if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) 97 return; 98 99 addr = get_mac_for_key(key); 100 101 ret = key->local->ops->set_key(local_to_hw(key->local), DISABLE_KEY, 102 key->sdata->dev->dev_addr, addr, 103 &key->conf); 104 105 if (ret) 106 printk(KERN_ERR "mac80211-%s: failed to remove key " 107 "(%d, %s) from hardware (%d)\n", 108 wiphy_name(key->local->hw.wiphy), 109 key->conf.keyidx, print_mac(mac, addr), ret); 110 111 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; 112 } 113 114 struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata, 115 struct sta_info *sta, 116 enum ieee80211_key_alg alg, 117 int idx, 118 size_t key_len, 119 const u8 *key_data) 120 { 121 struct ieee80211_key *key; 122 123 BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS); 124 125 key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL); 126 if (!key) 127 return NULL; 128 129 /* 130 * Default to software encryption; we'll later upload the 131 * key to the hardware if possible. 132 */ 133 key->conf.flags = 0; 134 key->flags = 0; 135 136 key->conf.alg = alg; 137 key->conf.keyidx = idx; 138 key->conf.keylen = key_len; 139 memcpy(key->conf.key, key_data, key_len); 140 141 key->local = sdata->local; 142 key->sdata = sdata; 143 key->sta = sta; 144 145 if (alg == ALG_CCMP) { 146 /* 147 * Initialize AES key state here as an optimization so that 148 * it does not need to be initialized for every packet. 149 */ 150 key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data); 151 if (!key->u.ccmp.tfm) { 152 ieee80211_key_free(key); 153 return NULL; 154 } 155 } 156 157 ieee80211_debugfs_key_add(key->local, key); 158 159 /* remove key first */ 160 if (sta) 161 ieee80211_key_free(sta->key); 162 else 163 ieee80211_key_free(sdata->keys[idx]); 164 165 if (sta) { 166 ieee80211_debugfs_key_sta_link(key, sta); 167 168 /* 169 * some hardware cannot handle TKIP with QoS, so 170 * we indicate whether QoS could be in use. 171 */ 172 if (sta->flags & WLAN_STA_WME) 173 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; 174 } else { 175 if (sdata->type == IEEE80211_IF_TYPE_STA) { 176 struct sta_info *ap; 177 178 /* same here, the AP could be using QoS */ 179 ap = sta_info_get(key->local, key->sdata->u.sta.bssid); 180 if (ap) { 181 if (ap->flags & WLAN_STA_WME) 182 key->conf.flags |= 183 IEEE80211_KEY_FLAG_WMM_STA; 184 sta_info_put(ap); 185 } 186 } 187 } 188 189 /* enable hwaccel if appropriate */ 190 if (netif_running(key->sdata->dev)) 191 ieee80211_key_enable_hw_accel(key); 192 193 if (sta) 194 rcu_assign_pointer(sta->key, key); 195 else 196 rcu_assign_pointer(sdata->keys[idx], key); 197 198 list_add(&key->list, &sdata->key_list); 199 200 return key; 201 } 202 203 void ieee80211_key_free(struct ieee80211_key *key) 204 { 205 if (!key) 206 return; 207 208 if (key->sta) { 209 rcu_assign_pointer(key->sta->key, NULL); 210 } else { 211 if (key->sdata->default_key == key) 212 ieee80211_set_default_key(key->sdata, -1); 213 if (key->conf.keyidx >= 0 && 214 key->conf.keyidx < NUM_DEFAULT_KEYS) 215 rcu_assign_pointer(key->sdata->keys[key->conf.keyidx], 216 NULL); 217 else 218 WARN_ON(1); 219 } 220 221 /* wait for all key users to complete */ 222 synchronize_rcu(); 223 224 /* remove from hwaccel if appropriate */ 225 ieee80211_key_disable_hw_accel(key); 226 227 if (key->conf.alg == ALG_CCMP) 228 ieee80211_aes_key_free(key->u.ccmp.tfm); 229 ieee80211_debugfs_key_remove(key); 230 231 list_del(&key->list); 232 233 kfree(key); 234 } 235 236 void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx) 237 { 238 struct ieee80211_key *key = NULL; 239 240 if (idx >= 0 && idx < NUM_DEFAULT_KEYS) 241 key = sdata->keys[idx]; 242 243 if (sdata->default_key != key) { 244 ieee80211_debugfs_key_remove_default(sdata); 245 246 rcu_assign_pointer(sdata->default_key, key); 247 248 if (sdata->default_key) 249 ieee80211_debugfs_key_add_default(sdata); 250 } 251 } 252 253 void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) 254 { 255 struct ieee80211_key *key, *tmp; 256 257 list_for_each_entry_safe(key, tmp, &sdata->key_list, list) 258 ieee80211_key_free(key); 259 } 260 261 void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) 262 { 263 struct ieee80211_key *key; 264 265 WARN_ON(!netif_running(sdata->dev)); 266 if (!netif_running(sdata->dev)) 267 return; 268 269 list_for_each_entry(key, &sdata->key_list, list) 270 ieee80211_key_enable_hw_accel(key); 271 } 272 273 void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata) 274 { 275 struct ieee80211_key *key; 276 277 list_for_each_entry(key, &sdata->key_list, list) 278 ieee80211_key_disable_hw_accel(key); 279 } 280