2 * Copyright 2002-2004, Instant802 Networks, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
9 #include <linux/netdevice.h>
10 #include <linux/types.h>
11 #include <linux/slab.h>
12 #include <linux/skbuff.h>
13 #include <linux/compiler.h>
14 #include <net/mac80211.h>
16 #include "ieee80211_i.h"
22 static int ieee80211_get_hdr_info(const struct sk_buff
*skb
, u8
**sa
, u8
**da
,
23 u8
*qos_tid
, u8
**data
, size_t *data_len
)
25 struct ieee80211_hdr
*hdr
;
31 hdr
= (struct ieee80211_hdr
*) skb
->data
;
32 fc
= le16_to_cpu(hdr
->frame_control
);
35 if ((fc
& (IEEE80211_FCTL_FROMDS
| IEEE80211_FCTL_TODS
)) ==
36 (IEEE80211_FCTL_FROMDS
| IEEE80211_FCTL_TODS
)) {
40 } else if (fc
& IEEE80211_FCTL_FROMDS
) {
43 } else if (fc
& IEEE80211_FCTL_TODS
) {
54 *data
= skb
->data
+ hdrlen
;
55 *data_len
= skb
->len
- hdrlen
;
57 a4_included
= (fc
& (IEEE80211_FCTL_TODS
| IEEE80211_FCTL_FROMDS
)) ==
58 (IEEE80211_FCTL_TODS
| IEEE80211_FCTL_FROMDS
);
59 if ((fc
& IEEE80211_FCTL_FTYPE
) == IEEE80211_FTYPE_DATA
&&
60 fc
& IEEE80211_STYPE_QOS_DATA
) {
61 pos
= (u8
*) &hdr
->addr4
;
64 *qos_tid
= pos
[0] & 0x0f;
65 *qos_tid
|= 0x80; /* qos_included flag */
69 return skb
->len
< hdrlen
? -1 : 0;
74 ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data
*tx
)
76 u8
*data
, *sa
, *da
, *key
, *mic
, qos_tid
;
79 struct sk_buff
*skb
= tx
->skb
;
85 if (!tx
->key
|| tx
->key
->conf
.alg
!= ALG_TKIP
|| skb
->len
< 24 ||
86 !WLAN_FC_DATA_PRESENT(fc
))
89 if (ieee80211_get_hdr_info(skb
, &sa
, &da
, &qos_tid
, &data
, &data_len
))
92 if ((tx
->key
->flags
& KEY_FLAG_UPLOADED_TO_HARDWARE
) &&
93 !(tx
->flags
& IEEE80211_TXRXD_FRAGMENTED
) &&
94 !(tx
->key
->conf
.flags
& IEEE80211_KEY_FLAG_GENERATE_MMIC
) &&
96 /* hwaccel - with no need for preallocated room for Michael MIC
101 if (skb_tailroom(skb
) < MICHAEL_MIC_LEN
) {
102 I802_DEBUG_INC(tx
->local
->tx_expand_skb_head
);
103 if (unlikely(pskb_expand_head(skb
, TKIP_IV_LEN
,
104 MICHAEL_MIC_LEN
+ TKIP_ICV_LEN
,
106 printk(KERN_DEBUG
"%s: failed to allocate more memory "
107 "for Michael MIC\n", tx
->dev
->name
);
113 authenticator
= fc
& IEEE80211_FCTL_FROMDS
; /* FIX */
117 key
= &tx
->key
->conf
.key
[authenticator
? ALG_TKIP_TEMP_AUTH_TX_MIC_KEY
:
118 ALG_TKIP_TEMP_AUTH_RX_MIC_KEY
];
119 mic
= skb_put(skb
, MICHAEL_MIC_LEN
);
120 michael_mic(key
, da
, sa
, qos_tid
& 0x0f, data
, data_len
, mic
);
122 return TXRX_CONTINUE
;
126 ieee80211_txrx_result
127 ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data
*rx
)
129 u8
*data
, *sa
, *da
, *key
= NULL
, qos_tid
;
132 u8 mic
[MICHAEL_MIC_LEN
];
133 struct sk_buff
*skb
= rx
->skb
;
134 int authenticator
= 1, wpa_test
= 0;
135 DECLARE_MAC_BUF(mac
);
140 * No way to verify the MIC if the hardware stripped it
142 if (rx
->u
.rx
.status
->flag
& RX_FLAG_MMIC_STRIPPED
)
143 return TXRX_CONTINUE
;
145 if (!rx
->key
|| rx
->key
->conf
.alg
!= ALG_TKIP
||
146 !(rx
->fc
& IEEE80211_FCTL_PROTECTED
) || !WLAN_FC_DATA_PRESENT(fc
))
147 return TXRX_CONTINUE
;
149 if (ieee80211_get_hdr_info(skb
, &sa
, &da
, &qos_tid
, &data
, &data_len
)
150 || data_len
< MICHAEL_MIC_LEN
)
153 data_len
-= MICHAEL_MIC_LEN
;
156 authenticator
= fc
& IEEE80211_FCTL_TODS
; /* FIX */
160 key
= &rx
->key
->conf
.key
[authenticator
? ALG_TKIP_TEMP_AUTH_RX_MIC_KEY
:
161 ALG_TKIP_TEMP_AUTH_TX_MIC_KEY
];
162 michael_mic(key
, da
, sa
, qos_tid
& 0x0f, data
, data_len
, mic
);
163 if (memcmp(mic
, data
+ data_len
, MICHAEL_MIC_LEN
) != 0 || wpa_test
) {
164 if (!(rx
->flags
& IEEE80211_TXRXD_RXRA_MATCH
))
167 printk(KERN_DEBUG
"%s: invalid Michael MIC in data frame from "
168 "%s\n", rx
->dev
->name
, print_mac(mac
, sa
));
170 mac80211_ev_michael_mic_failure(rx
->dev
, rx
->key
->conf
.keyidx
,
175 /* remove Michael MIC from payload */
176 skb_trim(skb
, skb
->len
- MICHAEL_MIC_LEN
);
178 /* update IV in key information to be able to detect replays */
179 rx
->key
->u
.tkip
.iv32_rx
[rx
->u
.rx
.queue
] = rx
->u
.rx
.tkip_iv32
;
180 rx
->key
->u
.tkip
.iv16_rx
[rx
->u
.rx
.queue
] = rx
->u
.rx
.tkip_iv16
;
182 return TXRX_CONTINUE
;
186 static int tkip_encrypt_skb(struct ieee80211_txrx_data
*tx
,
187 struct sk_buff
*skb
, int test
)
189 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) skb
->data
;
190 struct ieee80211_key
*key
= tx
->key
;
191 int hdrlen
, len
, tailneed
;
195 fc
= le16_to_cpu(hdr
->frame_control
);
196 hdrlen
= ieee80211_get_hdrlen(fc
);
197 len
= skb
->len
- hdrlen
;
199 if (tx
->key
->flags
& KEY_FLAG_UPLOADED_TO_HARDWARE
)
202 tailneed
= TKIP_ICV_LEN
;
204 if ((skb_headroom(skb
) < TKIP_IV_LEN
||
205 skb_tailroom(skb
) < tailneed
)) {
206 I802_DEBUG_INC(tx
->local
->tx_expand_skb_head
);
207 if (unlikely(pskb_expand_head(skb
, TKIP_IV_LEN
, tailneed
,
212 pos
= skb_push(skb
, TKIP_IV_LEN
);
213 memmove(pos
, pos
+ TKIP_IV_LEN
, hdrlen
);
216 /* Increase IV for the frame */
218 if (key
->u
.tkip
.iv16
== 0)
221 if (tx
->key
->flags
& KEY_FLAG_UPLOADED_TO_HARDWARE
) {
222 hdr
= (struct ieee80211_hdr
*)skb
->data
;
224 /* hwaccel - with preallocated room for IV */
225 ieee80211_tkip_add_iv(pos
, key
,
226 (u8
) (key
->u
.tkip
.iv16
>> 8),
227 (u8
) (((key
->u
.tkip
.iv16
>> 8) | 0x20) &
229 (u8
) key
->u
.tkip
.iv16
);
231 tx
->u
.tx
.control
->key_idx
= tx
->key
->conf
.hw_key_idx
;
235 /* Add room for ICV */
236 skb_put(skb
, TKIP_ICV_LEN
);
238 hdr
= (struct ieee80211_hdr
*) skb
->data
;
239 ieee80211_tkip_encrypt_data(tx
->local
->wep_tx_tfm
,
240 key
, pos
, len
, hdr
->addr2
);
245 ieee80211_txrx_result
246 ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data
*tx
)
248 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) tx
->skb
->data
;
250 struct sk_buff
*skb
= tx
->skb
;
251 int wpa_test
= 0, test
= 0;
253 fc
= le16_to_cpu(hdr
->frame_control
);
255 if (!WLAN_FC_DATA_PRESENT(fc
))
256 return TXRX_CONTINUE
;
258 tx
->u
.tx
.control
->icv_len
= TKIP_ICV_LEN
;
259 tx
->u
.tx
.control
->iv_len
= TKIP_IV_LEN
;
260 ieee80211_tx_set_iswep(tx
);
262 if ((tx
->key
->flags
& KEY_FLAG_UPLOADED_TO_HARDWARE
) &&
263 !(tx
->key
->conf
.flags
& IEEE80211_KEY_FLAG_GENERATE_IV
) &&
265 /* hwaccel - with no need for preallocated room for IV/ICV */
266 tx
->u
.tx
.control
->key_idx
= tx
->key
->conf
.hw_key_idx
;
267 return TXRX_CONTINUE
;
270 if (tkip_encrypt_skb(tx
, skb
, test
) < 0)
273 if (tx
->u
.tx
.extra_frag
) {
275 for (i
= 0; i
< tx
->u
.tx
.num_extra_frag
; i
++) {
276 if (tkip_encrypt_skb(tx
, tx
->u
.tx
.extra_frag
[i
], test
)
282 return TXRX_CONTINUE
;
286 ieee80211_txrx_result
287 ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data
*rx
)
289 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) rx
->skb
->data
;
291 int hdrlen
, res
, hwaccel
= 0, wpa_test
= 0;
292 struct ieee80211_key
*key
= rx
->key
;
293 struct sk_buff
*skb
= rx
->skb
;
294 DECLARE_MAC_BUF(mac
);
296 fc
= le16_to_cpu(hdr
->frame_control
);
297 hdrlen
= ieee80211_get_hdrlen(fc
);
299 if ((rx
->fc
& IEEE80211_FCTL_FTYPE
) != IEEE80211_FTYPE_DATA
)
300 return TXRX_CONTINUE
;
302 if (!rx
->sta
|| skb
->len
- hdrlen
< 12)
305 if (rx
->u
.rx
.status
->flag
& RX_FLAG_DECRYPTED
) {
306 if (rx
->u
.rx
.status
->flag
& RX_FLAG_IV_STRIPPED
) {
308 * Hardware took care of all processing, including
309 * replay protection, and stripped the ICV/IV so
310 * we cannot do any checks here.
312 return TXRX_CONTINUE
;
315 /* let TKIP code verify IV, but skip decryption */
319 res
= ieee80211_tkip_decrypt_data(rx
->local
->wep_rx_tfm
,
320 key
, skb
->data
+ hdrlen
,
321 skb
->len
- hdrlen
, rx
->sta
->addr
,
322 hwaccel
, rx
->u
.rx
.queue
,
324 &rx
->u
.rx
.tkip_iv16
);
325 if (res
!= TKIP_DECRYPT_OK
|| wpa_test
) {
326 #ifdef CONFIG_MAC80211_DEBUG
328 printk(KERN_DEBUG
"%s: TKIP decrypt failed for RX "
329 "frame from %s (res=%d)\n", rx
->dev
->name
,
330 print_mac(mac
, rx
->sta
->addr
), res
);
331 #endif /* CONFIG_MAC80211_DEBUG */
336 skb_trim(skb
, skb
->len
- TKIP_ICV_LEN
);
339 memmove(skb
->data
+ TKIP_IV_LEN
, skb
->data
, hdrlen
);
340 skb_pull(skb
, TKIP_IV_LEN
);
342 return TXRX_CONTINUE
;
346 static void ccmp_special_blocks(struct sk_buff
*skb
, u8
*pn
, u8
*b_0
, u8
*aad
,
350 int a4_included
, qos_included
;
351 u8 qos_tid
, *fc_pos
, *data
, *sa
, *da
;
354 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) skb
->data
;
356 fc_pos
= (u8
*) &hdr
->frame_control
;
357 fc
= fc_pos
[0] ^ (fc_pos
[1] << 8);
358 a4_included
= (fc
& (IEEE80211_FCTL_TODS
| IEEE80211_FCTL_FROMDS
)) ==
359 (IEEE80211_FCTL_TODS
| IEEE80211_FCTL_FROMDS
);
361 ieee80211_get_hdr_info(skb
, &sa
, &da
, &qos_tid
, &data
, &data_len
);
362 data_len
-= CCMP_HDR_LEN
+ (encrypted
? CCMP_MIC_LEN
: 0);
363 if (qos_tid
& 0x80) {
368 /* First block, b_0 */
370 b_0
[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
371 /* Nonce: QoS Priority | A2 | PN */
373 memcpy(&b_0
[2], hdr
->addr2
, 6);
374 memcpy(&b_0
[8], pn
, CCMP_PN_LEN
);
376 b_0
[14] = (data_len
>> 8) & 0xff;
377 b_0
[15] = data_len
& 0xff;
380 /* AAD (extra authenticate-only data) / masked 802.11 header
381 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
383 len_a
= a4_included
? 28 : 22;
387 aad
[0] = 0; /* (len_a >> 8) & 0xff; */
388 aad
[1] = len_a
& 0xff;
389 /* Mask FC: zero subtype b4 b5 b6 */
390 aad
[2] = fc_pos
[0] & ~(BIT(4) | BIT(5) | BIT(6));
391 /* Retry, PwrMgt, MoreData; set Protected */
392 aad
[3] = (fc_pos
[1] & ~(BIT(3) | BIT(4) | BIT(5))) | BIT(6);
393 memcpy(&aad
[4], &hdr
->addr1
, 18);
395 /* Mask Seq#, leave Frag# */
396 aad
[22] = *((u8
*) &hdr
->seq_ctrl
) & 0x0f;
399 memcpy(&aad
[24], hdr
->addr4
, 6);
403 memset(&aad
[24], 0, 8);
405 u8
*dpos
= &aad
[a4_included
? 30 : 24];
407 /* Mask QoS Control field */
414 static inline void ccmp_pn2hdr(u8
*hdr
, u8
*pn
, int key_id
)
419 hdr
[3] = 0x20 | (key_id
<< 6);
427 static inline int ccmp_hdr2pn(u8
*pn
, u8
*hdr
)
435 return (hdr
[3] >> 6) & 0x03;
439 static int ccmp_encrypt_skb(struct ieee80211_txrx_data
*tx
,
440 struct sk_buff
*skb
, int test
)
442 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) skb
->data
;
443 struct ieee80211_key
*key
= tx
->key
;
444 int hdrlen
, len
, tailneed
;
446 u8
*pos
, *pn
, *b_0
, *aad
, *scratch
;
449 scratch
= key
->u
.ccmp
.tx_crypto_buf
;
450 b_0
= scratch
+ 3 * AES_BLOCK_LEN
;
451 aad
= scratch
+ 4 * AES_BLOCK_LEN
;
453 fc
= le16_to_cpu(hdr
->frame_control
);
454 hdrlen
= ieee80211_get_hdrlen(fc
);
455 len
= skb
->len
- hdrlen
;
457 if (key
->flags
& KEY_FLAG_UPLOADED_TO_HARDWARE
)
460 tailneed
= CCMP_MIC_LEN
;
462 if ((skb_headroom(skb
) < CCMP_HDR_LEN
||
463 skb_tailroom(skb
) < tailneed
)) {
464 I802_DEBUG_INC(tx
->local
->tx_expand_skb_head
);
465 if (unlikely(pskb_expand_head(skb
, CCMP_HDR_LEN
, tailneed
,
470 pos
= skb_push(skb
, CCMP_HDR_LEN
);
471 memmove(pos
, pos
+ CCMP_HDR_LEN
, hdrlen
);
472 hdr
= (struct ieee80211_hdr
*) pos
;
476 pn
= key
->u
.ccmp
.tx_pn
;
478 for (i
= CCMP_PN_LEN
- 1; i
>= 0; i
--) {
484 ccmp_pn2hdr(pos
, pn
, key
->conf
.keyidx
);
486 if (key
->flags
& KEY_FLAG_UPLOADED_TO_HARDWARE
) {
487 /* hwaccel - with preallocated room for CCMP header */
488 tx
->u
.tx
.control
->key_idx
= key
->conf
.hw_key_idx
;
493 ccmp_special_blocks(skb
, pn
, b_0
, aad
, 0);
494 ieee80211_aes_ccm_encrypt(key
->u
.ccmp
.tfm
, scratch
, b_0
, aad
, pos
, len
,
495 pos
, skb_put(skb
, CCMP_MIC_LEN
));
501 ieee80211_txrx_result
502 ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data
*tx
)
504 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) tx
->skb
->data
;
506 struct sk_buff
*skb
= tx
->skb
;
509 fc
= le16_to_cpu(hdr
->frame_control
);
511 if (!WLAN_FC_DATA_PRESENT(fc
))
512 return TXRX_CONTINUE
;
514 tx
->u
.tx
.control
->icv_len
= CCMP_MIC_LEN
;
515 tx
->u
.tx
.control
->iv_len
= CCMP_HDR_LEN
;
516 ieee80211_tx_set_iswep(tx
);
518 if ((tx
->key
->flags
& KEY_FLAG_UPLOADED_TO_HARDWARE
) &&
519 !(tx
->key
->conf
.flags
& IEEE80211_KEY_FLAG_GENERATE_IV
)) {
520 /* hwaccel - with no need for preallocated room for CCMP "
521 * header or MIC fields */
522 tx
->u
.tx
.control
->key_idx
= tx
->key
->conf
.hw_key_idx
;
523 return TXRX_CONTINUE
;
526 if (ccmp_encrypt_skb(tx
, skb
, test
) < 0)
529 if (tx
->u
.tx
.extra_frag
) {
531 for (i
= 0; i
< tx
->u
.tx
.num_extra_frag
; i
++) {
532 if (ccmp_encrypt_skb(tx
, tx
->u
.tx
.extra_frag
[i
], test
)
538 return TXRX_CONTINUE
;
542 ieee80211_txrx_result
543 ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data
*rx
)
545 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) rx
->skb
->data
;
548 struct ieee80211_key
*key
= rx
->key
;
549 struct sk_buff
*skb
= rx
->skb
;
552 DECLARE_MAC_BUF(mac
);
554 fc
= le16_to_cpu(hdr
->frame_control
);
555 hdrlen
= ieee80211_get_hdrlen(fc
);
557 if ((rx
->fc
& IEEE80211_FCTL_FTYPE
) != IEEE80211_FTYPE_DATA
)
558 return TXRX_CONTINUE
;
560 data_len
= skb
->len
- hdrlen
- CCMP_HDR_LEN
- CCMP_MIC_LEN
;
561 if (!rx
->sta
|| data_len
< 0)
564 if ((rx
->u
.rx
.status
->flag
& RX_FLAG_DECRYPTED
) &&
565 (rx
->u
.rx
.status
->flag
& RX_FLAG_IV_STRIPPED
))
566 return TXRX_CONTINUE
;
568 (void) ccmp_hdr2pn(pn
, skb
->data
+ hdrlen
);
570 if (memcmp(pn
, key
->u
.ccmp
.rx_pn
[rx
->u
.rx
.queue
], CCMP_PN_LEN
) <= 0) {
571 #ifdef CONFIG_MAC80211_DEBUG
572 u8
*ppn
= key
->u
.ccmp
.rx_pn
[rx
->u
.rx
.queue
];
574 printk(KERN_DEBUG
"%s: CCMP replay detected for RX frame from "
575 "%s (RX PN %02x%02x%02x%02x%02x%02x <= prev. PN "
576 "%02x%02x%02x%02x%02x%02x)\n", rx
->dev
->name
,
577 print_mac(mac
, rx
->sta
->addr
),
578 pn
[0], pn
[1], pn
[2], pn
[3], pn
[4], pn
[5],
579 ppn
[0], ppn
[1], ppn
[2], ppn
[3], ppn
[4], ppn
[5]);
580 #endif /* CONFIG_MAC80211_DEBUG */
581 key
->u
.ccmp
.replays
++;
585 if (!(rx
->u
.rx
.status
->flag
& RX_FLAG_DECRYPTED
)) {
586 /* hardware didn't decrypt/verify MIC */
587 u8
*scratch
, *b_0
, *aad
;
589 scratch
= key
->u
.ccmp
.rx_crypto_buf
;
590 b_0
= scratch
+ 3 * AES_BLOCK_LEN
;
591 aad
= scratch
+ 4 * AES_BLOCK_LEN
;
593 ccmp_special_blocks(skb
, pn
, b_0
, aad
, 1);
595 if (ieee80211_aes_ccm_decrypt(
596 key
->u
.ccmp
.tfm
, scratch
, b_0
, aad
,
597 skb
->data
+ hdrlen
+ CCMP_HDR_LEN
, data_len
,
598 skb
->data
+ skb
->len
- CCMP_MIC_LEN
,
599 skb
->data
+ hdrlen
+ CCMP_HDR_LEN
)) {
600 #ifdef CONFIG_MAC80211_DEBUG
602 printk(KERN_DEBUG
"%s: CCMP decrypt failed "
603 "for RX frame from %s\n", rx
->dev
->name
,
604 print_mac(mac
, rx
->sta
->addr
));
605 #endif /* CONFIG_MAC80211_DEBUG */
610 memcpy(key
->u
.ccmp
.rx_pn
[rx
->u
.rx
.queue
], pn
, CCMP_PN_LEN
);
612 /* Remove CCMP header and MIC */
613 skb_trim(skb
, skb
->len
- CCMP_MIC_LEN
);
614 memmove(skb
->data
+ CCMP_HDR_LEN
, skb
->data
, hdrlen
);
615 skb_pull(skb
, CCMP_HDR_LEN
);
617 return TXRX_CONTINUE
;