diff options
Diffstat (limited to 'net/mac80211/tkip.c')
-rw-r--r-- | net/mac80211/tkip.c | 86 |
1 files changed, 34 insertions, 52 deletions
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index a7c3febc5a45..a00cf1ea7719 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -6,7 +6,6 @@ | |||
6 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | */ | 8 | */ |
9 | |||
10 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
11 | #include <linux/bitops.h> | 10 | #include <linux/bitops.h> |
12 | #include <linux/types.h> | 11 | #include <linux/types.h> |
@@ -72,10 +71,12 @@ static u16 tkipS(u16 val) | |||
72 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) | 71 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) |
73 | * P1K: 80 bits | 72 | * P1K: 80 bits |
74 | */ | 73 | */ |
75 | static void tkip_mixing_phase1(const u8 *ta, const u8 *tk, u32 tsc_IV32, | 74 | static void tkip_mixing_phase1(struct ieee80211_key *key, const u8 *ta, |
76 | u16 *p1k) | 75 | struct tkip_ctx *ctx, u32 tsc_IV32) |
77 | { | 76 | { |
78 | int i, j; | 77 | int i, j; |
78 | const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; | ||
79 | u16 *p1k = ctx->p1k; | ||
79 | 80 | ||
80 | p1k[0] = tsc_IV32 & 0xFFFF; | 81 | p1k[0] = tsc_IV32 & 0xFFFF; |
81 | p1k[1] = tsc_IV32 >> 16; | 82 | p1k[1] = tsc_IV32 >> 16; |
@@ -91,12 +92,15 @@ static void tkip_mixing_phase1(const u8 *ta, const u8 *tk, u32 tsc_IV32, | |||
91 | p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j)); | 92 | p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j)); |
92 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; | 93 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; |
93 | } | 94 | } |
95 | ctx->initialized = 1; | ||
94 | } | 96 | } |
95 | 97 | ||
96 | static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, | 98 | static void tkip_mixing_phase2(struct ieee80211_key *key, struct tkip_ctx *ctx, |
97 | u8 *rc4key) | 99 | u16 tsc_IV16, u8 *rc4key) |
98 | { | 100 | { |
99 | u16 ppk[6]; | 101 | u16 ppk[6]; |
102 | const u16 *p1k = ctx->p1k; | ||
103 | const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; | ||
100 | int i; | 104 | int i; |
101 | 105 | ||
102 | ppk[0] = p1k[0]; | 106 | ppk[0] = p1k[0]; |
@@ -132,38 +136,25 @@ static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, | |||
132 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets | 136 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets |
133 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of | 137 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of |
134 | * the packet payload). */ | 138 | * the packet payload). */ |
135 | u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, | 139 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, |
136 | u8 iv0, u8 iv1, u8 iv2) | 140 | u8 iv0, u8 iv1, u8 iv2) |
137 | { | 141 | { |
138 | *pos++ = iv0; | 142 | *pos++ = iv0; |
139 | *pos++ = iv1; | 143 | *pos++ = iv1; |
140 | *pos++ = iv2; | 144 | *pos++ = iv2; |
141 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; | 145 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; |
142 | put_unaligned_le32(key->u.tkip.iv32, pos); | 146 | put_unaligned_le32(key->u.tkip.tx.iv32, pos); |
143 | return pos + 4; | 147 | return pos + 4; |
144 | } | 148 | } |
145 | 149 | ||
146 | void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta, | 150 | static void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta, |
147 | u16 *phase1key) | ||
148 | { | ||
149 | tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
150 | key->u.tkip.iv32, phase1key); | ||
151 | } | ||
152 | |||
153 | void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta, | ||
154 | u8 *rc4key) | 151 | u8 *rc4key) |
155 | { | 152 | { |
156 | /* Calculate per-packet key */ | 153 | /* Calculate per-packet key */ |
157 | if (key->u.tkip.iv16 == 0 || !key->u.tkip.tx_initialized) { | 154 | if (key->u.tkip.tx.iv16 == 0 || !key->u.tkip.tx.initialized) |
158 | /* IV16 wrapped around - perform TKIP phase 1 */ | 155 | tkip_mixing_phase1(key, ta, &key->u.tkip.tx, key->u.tkip.tx.iv32); |
159 | tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
160 | key->u.tkip.iv32, key->u.tkip.p1k); | ||
161 | key->u.tkip.tx_initialized = 1; | ||
162 | } | ||
163 | 156 | ||
164 | tkip_mixing_phase2(key->u.tkip.p1k, | 157 | tkip_mixing_phase2(key, &key->u.tkip.tx, key->u.tkip.tx.iv16, rc4key); |
165 | &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
166 | key->u.tkip.iv16, rc4key); | ||
167 | } | 158 | } |
168 | 159 | ||
169 | void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | 160 | void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, |
@@ -187,9 +178,9 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | |||
187 | printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", | 178 | printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", |
188 | iv16, iv32); | 179 | iv16, iv32); |
189 | 180 | ||
190 | if (iv32 != key->u.tkip.iv32) { | 181 | if (iv32 != key->u.tkip.tx.iv32) { |
191 | printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n", | 182 | printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n", |
192 | iv32, key->u.tkip.iv32); | 183 | iv32, key->u.tkip.tx.iv32); |
193 | printk(KERN_DEBUG "Wrap around of iv16 in the middle of a " | 184 | printk(KERN_DEBUG "Wrap around of iv16 in the middle of a " |
194 | "fragmented packet\n"); | 185 | "fragmented packet\n"); |
195 | } | 186 | } |
@@ -198,20 +189,15 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | |||
198 | /* Update the p1k only when the iv16 in the packet wraps around, this | 189 | /* Update the p1k only when the iv16 in the packet wraps around, this |
199 | * might occur after the wrap around of iv16 in the key in case of | 190 | * might occur after the wrap around of iv16 in the key in case of |
200 | * fragmented packets. */ | 191 | * fragmented packets. */ |
201 | if (iv16 == 0 || !key->u.tkip.tx_initialized) { | 192 | if (iv16 == 0 || !key->u.tkip.tx.initialized) |
202 | /* IV16 wrapped around - perform TKIP phase 1 */ | 193 | tkip_mixing_phase1(key, ta, &key->u.tkip.tx, iv32); |
203 | tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
204 | iv32, key->u.tkip.p1k); | ||
205 | key->u.tkip.tx_initialized = 1; | ||
206 | } | ||
207 | 194 | ||
208 | if (type == IEEE80211_TKIP_P1_KEY) { | 195 | if (type == IEEE80211_TKIP_P1_KEY) { |
209 | memcpy(outkey, key->u.tkip.p1k, sizeof(u16) * 5); | 196 | memcpy(outkey, key->u.tkip.tx.p1k, sizeof(u16) * 5); |
210 | return; | 197 | return; |
211 | } | 198 | } |
212 | 199 | ||
213 | tkip_mixing_phase2(key->u.tkip.p1k, | 200 | tkip_mixing_phase2(key, &key->u.tkip.tx, iv16, outkey); |
214 | &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], iv16, outkey); | ||
215 | } | 201 | } |
216 | EXPORT_SYMBOL(ieee80211_get_tkip_key); | 202 | EXPORT_SYMBOL(ieee80211_get_tkip_key); |
217 | 203 | ||
@@ -271,33 +257,31 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
271 | if ((keyid >> 6) != key->conf.keyidx) | 257 | if ((keyid >> 6) != key->conf.keyidx) |
272 | return TKIP_DECRYPT_INVALID_KEYIDX; | 258 | return TKIP_DECRYPT_INVALID_KEYIDX; |
273 | 259 | ||
274 | if (key->u.tkip.rx_initialized[queue] && | 260 | if (key->u.tkip.rx[queue].initialized && |
275 | (iv32 < key->u.tkip.iv32_rx[queue] || | 261 | (iv32 < key->u.tkip.rx[queue].iv32 || |
276 | (iv32 == key->u.tkip.iv32_rx[queue] && | 262 | (iv32 == key->u.tkip.rx[queue].iv32 && |
277 | iv16 <= key->u.tkip.iv16_rx[queue]))) { | 263 | iv16 <= key->u.tkip.rx[queue].iv16))) { |
278 | #ifdef CONFIG_TKIP_DEBUG | 264 | #ifdef CONFIG_TKIP_DEBUG |
279 | DECLARE_MAC_BUF(mac); | 265 | DECLARE_MAC_BUF(mac); |
280 | printk(KERN_DEBUG "TKIP replay detected for RX frame from " | 266 | printk(KERN_DEBUG "TKIP replay detected for RX frame from " |
281 | "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", | 267 | "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", |
282 | print_mac(mac, ta), | 268 | print_mac(mac, ta), |
283 | iv32, iv16, key->u.tkip.iv32_rx[queue], | 269 | iv32, iv16, key->u.tkip.rx[queue].iv32, |
284 | key->u.tkip.iv16_rx[queue]); | 270 | key->u.tkip.rx[queue].iv16); |
285 | #endif /* CONFIG_TKIP_DEBUG */ | 271 | #endif /* CONFIG_TKIP_DEBUG */ |
286 | return TKIP_DECRYPT_REPLAY; | 272 | return TKIP_DECRYPT_REPLAY; |
287 | } | 273 | } |
288 | 274 | ||
289 | if (only_iv) { | 275 | if (only_iv) { |
290 | res = TKIP_DECRYPT_OK; | 276 | res = TKIP_DECRYPT_OK; |
291 | key->u.tkip.rx_initialized[queue] = 1; | 277 | key->u.tkip.rx[queue].initialized = 1; |
292 | goto done; | 278 | goto done; |
293 | } | 279 | } |
294 | 280 | ||
295 | if (!key->u.tkip.rx_initialized[queue] || | 281 | if (!key->u.tkip.rx[queue].initialized || |
296 | key->u.tkip.iv32_rx[queue] != iv32) { | 282 | key->u.tkip.rx[queue].iv32 != iv32) { |
297 | key->u.tkip.rx_initialized[queue] = 1; | ||
298 | /* IV16 wrapped around - perform TKIP phase 1 */ | 283 | /* IV16 wrapped around - perform TKIP phase 1 */ |
299 | tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | 284 | tkip_mixing_phase1(key, ta, &key->u.tkip.rx[queue], iv32); |
300 | iv32, key->u.tkip.p1k_rx[queue]); | ||
301 | #ifdef CONFIG_TKIP_DEBUG | 285 | #ifdef CONFIG_TKIP_DEBUG |
302 | { | 286 | { |
303 | int i; | 287 | int i; |
@@ -311,7 +295,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
311 | printk("\n"); | 295 | printk("\n"); |
312 | printk(KERN_DEBUG "TKIP decrypt: P1K="); | 296 | printk(KERN_DEBUG "TKIP decrypt: P1K="); |
313 | for (i = 0; i < 5; i++) | 297 | for (i = 0; i < 5; i++) |
314 | printk("%04x ", key->u.tkip.p1k_rx[queue][i]); | 298 | printk("%04x ", key->u.tkip.rx[queue].p1k[i]); |
315 | printk("\n"); | 299 | printk("\n"); |
316 | } | 300 | } |
317 | #endif /* CONFIG_TKIP_DEBUG */ | 301 | #endif /* CONFIG_TKIP_DEBUG */ |
@@ -326,13 +310,11 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
326 | 310 | ||
327 | key->local->ops->update_tkip_key( | 311 | key->local->ops->update_tkip_key( |
328 | local_to_hw(key->local), &key->conf, | 312 | local_to_hw(key->local), &key->conf, |
329 | sta_addr, iv32, key->u.tkip.p1k_rx[queue]); | 313 | sta_addr, iv32, key->u.tkip.rx[queue].p1k); |
330 | } | 314 | } |
331 | } | 315 | } |
332 | 316 | ||
333 | tkip_mixing_phase2(key->u.tkip.p1k_rx[queue], | 317 | tkip_mixing_phase2(key, &key->u.tkip.rx[queue], iv16, rc4key); |
334 | &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
335 | iv16, rc4key); | ||
336 | #ifdef CONFIG_TKIP_DEBUG | 318 | #ifdef CONFIG_TKIP_DEBUG |
337 | { | 319 | { |
338 | int i; | 320 | int i; |