fix up hostapd for mac80211
[librecmc/librecmc.git] / package / mac80211 / patches / 019-mac80211-key-seq-nl80211.patch
1 Subject: mac80211: support getting key sequence counters via cfg80211
2
3 This implements cfg80211's get_key() to allow retrieving the sequence
4 counter for a TKIP or CCMP key from userspace. It also cleans up and
5 documents the associated low-level driver interface.
6
7 Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
8
9 ---
10  include/net/mac80211.h |   14 ++------
11  net/mac80211/cfg.c     |   85 ++++++++++++++++++++++++++++++++++++++++++++++++-
12  2 files changed, 89 insertions(+), 10 deletions(-)
13
14 Index: mac80211/net/mac80211/cfg.c
15 ===================================================================
16 --- mac80211.orig/net/mac80211/cfg.c    2007-11-11 15:46:41.497954646 +0100
17 +++ mac80211/net/mac80211/cfg.c 2007-11-11 15:46:51.346515884 +0100
18 @@ -1,7 +1,7 @@
19  /*
20   * mac80211 configuration hooks for cfg80211
21   *
22 - * Copyright 2006      Johannes Berg <johannes@sipsolutions.net>
23 + * Copyright 2006, 2007        Johannes Berg <johannes@sipsolutions.net>
24   *
25   * This file is GPLv2 as found in COPYING.
26   */
27 @@ -180,6 +180,88 @@
28         return 0;
29  }
30  
31 +static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
32 +                            u8 key_idx, u8 *mac_addr, void *cookie,
33 +                            void (*callback)(void *cookie,
34 +                                             struct key_params *params))
35 +{
36 +       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
37 +       struct sta_info *sta = NULL;
38 +       u8 seq[6] = {0};
39 +       struct key_params params;
40 +       struct ieee80211_key *key;
41 +       u32 iv32;
42 +       u16 iv16;
43 +       int err = -ENOENT;
44 +
45 +       if (mac_addr) {
46 +               sta = sta_info_get(sdata->local, mac_addr);
47 +               if (!sta)
48 +                       goto out;
49 +
50 +               key = sta->key;
51 +       } else
52 +               key = sdata->keys[key_idx];
53 +
54 +       if (!key)
55 +               goto out;
56 +
57 +       memset(&params, 0, sizeof(params));
58 +
59 +       switch (key->conf.alg) {
60 +       case ALG_TKIP:
61 +               params.cipher = WLAN_CIPHER_SUITE_TKIP;
62 +
63 +               iv32 = key->u.tkip.iv32;
64 +               iv16 = key->u.tkip.iv16;
65 +
66 +               if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
67 +                   sdata->local->ops->get_tkip_seq)
68 +                       sdata->local->ops->get_tkip_seq(
69 +                               local_to_hw(sdata->local),
70 +                               key->conf.hw_key_idx,
71 +                               &iv32, &iv16);
72 +
73 +               seq[0] = iv16 & 0xff;
74 +               seq[1] = (iv16 >> 8) & 0xff;
75 +               seq[2] = iv32 & 0xff;
76 +               seq[3] = (iv32 >> 8) & 0xff;
77 +               seq[4] = (iv32 >> 16) & 0xff;
78 +               seq[5] = (iv32 >> 24) & 0xff;
79 +               params.seq = seq;
80 +               params.seq_len = 6;
81 +               break;
82 +       case ALG_CCMP:
83 +               params.cipher = WLAN_CIPHER_SUITE_CCMP;
84 +               seq[0] = key->u.ccmp.tx_pn[5];
85 +               seq[1] = key->u.ccmp.tx_pn[4];
86 +               seq[2] = key->u.ccmp.tx_pn[3];
87 +               seq[3] = key->u.ccmp.tx_pn[2];
88 +               seq[4] = key->u.ccmp.tx_pn[1];
89 +               seq[5] = key->u.ccmp.tx_pn[0];
90 +               params.seq = seq;
91 +               params.seq_len = 6;
92 +               break;
93 +       case ALG_WEP:
94 +               if (key->conf.keylen == 5)
95 +                       params.cipher = WLAN_CIPHER_SUITE_WEP40;
96 +               else
97 +                       params.cipher = WLAN_CIPHER_SUITE_WEP104;
98 +               break;
99 +       }
100 +
101 +       params.key = key->conf.key;
102 +       params.key_len = key->conf.keylen;
103 +
104 +       callback(cookie, &params);
105 +       err = 0;
106 +
107 + out:
108 +       if (sta)
109 +               sta_info_put(sta);
110 +       return err;
111 +}
112 +
113  static int ieee80211_config_default_key(struct wiphy *wiphy,
114                                         struct net_device *dev,
115                                         u8 key_idx)
116 @@ -198,5 +280,6 @@
117         .change_virtual_intf = ieee80211_change_iface,
118         .add_key = ieee80211_add_key,
119         .del_key = ieee80211_del_key,
120 +       .get_key = ieee80211_get_key,
121         .set_default_key = ieee80211_config_default_key,
122  };
123 Index: mac80211/include/net/mac80211.h
124 ===================================================================
125 --- mac80211.orig/include/net/mac80211.h        2007-11-11 15:46:41.377947807 +0100
126 +++ mac80211/include/net/mac80211.h     2007-11-11 15:47:08.183475366 +0100
127 @@ -598,9 +598,6 @@
128         u8 key[0];
129  };
130  
131 -#define IEEE80211_SEQ_COUNTER_RX       0
132 -#define IEEE80211_SEQ_COUNTER_TX       1
133 -
134  /**
135   * enum set_key_cmd - key command
136   *
137 @@ -947,9 +944,9 @@
138   *
139   * @get_stats: return low-level statistics
140   *
141 - * @get_sequence_counter: For devices that have internal sequence counters this
142 - *     callback allows mac80211 to access the current value of a counter.
143 - *     This callback seems not well-defined, tell us if you need it.
144 + * @get_tkip_seq: If your device implements TKIP encryption in hardware this
145 + *     callback should be provided to read the TKIP transmit IVs (both IV32
146 + *     and IV16) for the given key from hardware.
147   *
148   * @set_rts_threshold: Configuration of RTS threshold (if device needs it)
149   *
150 @@ -1022,9 +1019,8 @@
151         int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len);
152         int (*get_stats)(struct ieee80211_hw *hw,
153                          struct ieee80211_low_level_stats *stats);
154 -       int (*get_sequence_counter)(struct ieee80211_hw *hw,
155 -                                   u8* addr, u8 keyidx, u8 txrx,
156 -                                   u32* iv32, u16* iv16);
157 +       void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx,
158 +                            u32 *iv32, u16 *iv16);
159         int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
160         int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value);
161         int (*set_retry_limit)(struct ieee80211_hw *hw,