aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-12-18 20:03:31 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:59:50 -0500
commit62da92fb75c346b503bca765fd1337e08771c9fe (patch)
tree86246464a61297e4df2e593c31b2e2dda325cf5c /net
parente8cbb4cbeb7642d179b01c35adf036ddb65f3dd0 (diff)
mac80211: support getting key sequence counters via cfg80211
This implements cfg80211's get_key() to allow retrieving the sequence counter for a TKIP or CCMP key from userspace. It also cleans up and documents the associated low-level driver interface. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c85
1 files changed, 84 insertions, 1 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index d49f7b58b05c..4c1ce353c662 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * mac80211 configuration hooks for cfg80211 2 * mac80211 configuration hooks for cfg80211
3 * 3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
5 * 5 *
6 * This file is GPLv2 as found in COPYING. 6 * This file is GPLv2 as found in COPYING.
7 */ 7 */
@@ -175,6 +175,88 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
175 return 0; 175 return 0;
176} 176}
177 177
178static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
179 u8 key_idx, u8 *mac_addr, void *cookie,
180 void (*callback)(void *cookie,
181 struct key_params *params))
182{
183 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
184 struct sta_info *sta = NULL;
185 u8 seq[6] = {0};
186 struct key_params params;
187 struct ieee80211_key *key;
188 u32 iv32;
189 u16 iv16;
190 int err = -ENOENT;
191
192 if (mac_addr) {
193 sta = sta_info_get(sdata->local, mac_addr);
194 if (!sta)
195 goto out;
196
197 key = sta->key;
198 } else
199 key = sdata->keys[key_idx];
200
201 if (!key)
202 goto out;
203
204 memset(&params, 0, sizeof(params));
205
206 switch (key->conf.alg) {
207 case ALG_TKIP:
208 params.cipher = WLAN_CIPHER_SUITE_TKIP;
209
210 iv32 = key->u.tkip.iv32;
211 iv16 = key->u.tkip.iv16;
212
213 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
214 sdata->local->ops->get_tkip_seq)
215 sdata->local->ops->get_tkip_seq(
216 local_to_hw(sdata->local),
217 key->conf.hw_key_idx,
218 &iv32, &iv16);
219
220 seq[0] = iv16 & 0xff;
221 seq[1] = (iv16 >> 8) & 0xff;
222 seq[2] = iv32 & 0xff;
223 seq[3] = (iv32 >> 8) & 0xff;
224 seq[4] = (iv32 >> 16) & 0xff;
225 seq[5] = (iv32 >> 24) & 0xff;
226 params.seq = seq;
227 params.seq_len = 6;
228 break;
229 case ALG_CCMP:
230 params.cipher = WLAN_CIPHER_SUITE_CCMP;
231 seq[0] = key->u.ccmp.tx_pn[5];
232 seq[1] = key->u.ccmp.tx_pn[4];
233 seq[2] = key->u.ccmp.tx_pn[3];
234 seq[3] = key->u.ccmp.tx_pn[2];
235 seq[4] = key->u.ccmp.tx_pn[1];
236 seq[5] = key->u.ccmp.tx_pn[0];
237 params.seq = seq;
238 params.seq_len = 6;
239 break;
240 case ALG_WEP:
241 if (key->conf.keylen == 5)
242 params.cipher = WLAN_CIPHER_SUITE_WEP40;
243 else
244 params.cipher = WLAN_CIPHER_SUITE_WEP104;
245 break;
246 }
247
248 params.key = key->conf.key;
249 params.key_len = key->conf.keylen;
250
251 callback(cookie, &params);
252 err = 0;
253
254 out:
255 if (sta)
256 sta_info_put(sta);
257 return err;
258}
259
178static int ieee80211_config_default_key(struct wiphy *wiphy, 260static int ieee80211_config_default_key(struct wiphy *wiphy,
179 struct net_device *dev, 261 struct net_device *dev,
180 u8 key_idx) 262 u8 key_idx)
@@ -193,5 +275,6 @@ struct cfg80211_ops mac80211_config_ops = {
193 .change_virtual_intf = ieee80211_change_iface, 275 .change_virtual_intf = ieee80211_change_iface,
194 .add_key = ieee80211_add_key, 276 .add_key = ieee80211_add_key,
195 .del_key = ieee80211_del_key, 277 .del_key = ieee80211_del_key,
278 .get_key = ieee80211_get_key,
196 .set_default_key = ieee80211_config_default_key, 279 .set_default_key = ieee80211_config_default_key,
197}; 280};