diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2007-12-18 20:03:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:59:50 -0500 |
commit | 62da92fb75c346b503bca765fd1337e08771c9fe (patch) | |
tree | 86246464a61297e4df2e593c31b2e2dda325cf5c /net/mac80211/cfg.c | |
parent | e8cbb4cbeb7642d179b01c35adf036ddb65f3dd0 (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/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 85 |
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 | ||
178 | static 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(¶ms, 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, ¶ms); | ||
252 | err = 0; | ||
253 | |||
254 | out: | ||
255 | if (sta) | ||
256 | sta_info_put(sta); | ||
257 | return err; | ||
258 | } | ||
259 | |||
178 | static int ieee80211_config_default_key(struct wiphy *wiphy, | 260 | static 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 | }; |