[PATCH] rsn_supp: Don't encrypt EAPOL-Key 4/4.
Andreas Hartmann
andihartmann
Thu Feb 9 04:14:02 PST 2012
Nicolas Cavallari schrieb:
> On 09/02/2012 11:40, Andreas Hartmann wrote:
>> Nicolas Cavallari schrieb:
>>> On 08/02/2012 17:18, Andreas Hartmann wrote:
[...]
>>>> Correctly - PTK rekeying.
>>>>
>>>> I checked something more now: I disabled hw encryption on the AP and
>>>> inserted debug output in net/mac80211/wpa.c
>>>> (ieee80211_crypto_ccmp_decrypt()) to see, where and when the frames are
>>>> dropped during rekeying with payload.
>>>>
>>>> The dropping of the frames starts directly after 2/4 has been done and
>>>> 3/4 has been sent the first time (long before the first 4/4 timeout). I
>>>> could see, that the first few frames (mostly data frames I suppose) are
>>>> dropped here:
>>>>
>>>> if (!(status->flag & RX_FLAG_DECRYPTED)) {
>>>> u8 scratch[6 * AES_BLOCK_SIZE];
>>>> /* hardware didn't decrypt/verify MIC */
>>>> ccmp_special_blocks(skb, pn, scratch, 1);
>>>>
>>>> if (ieee80211_aes_ccm_decrypt(
>>>> key->u.ccmp.tfm, scratch,
>>>> skb->data + hdrlen + CCMP_HDR_LEN, data_len,
>>>> skb->data + skb->len - CCMP_MIC_LEN,
>>>> skb->data + hdrlen + CCMP_HDR_LEN)) {
>>>> printk(KERN_INFO "ieee80211_crypto_ccmp_decrypt 10 RX_DROP_UNUSABLE\n");
>>>> return RX_DROP_UNUSABLE;
>>>> }
>>>> }
>>>
>>> So the replay counter was acceptable but the key was wrong, strange
>>> indeed. I would proceed to debug the ieee80211_tx_h_select_key() on the
>>> supplicant, if it's possible.
>>
>> It looks like this:
>>
>> with patch
>>
>> Feb 9 09:46:59 notebook2 kernel: [18401.024008] ieee80211_tx_h_select_key DONT_ENCRYPT
>> Feb 9 09:46:59 notebook2 kernel: [18408.907037] ieee80211_tx_h_select_key DONT_ENCRYPT
>> Feb 9 09:46:59 notebook2 kernel: [18408.910235] ieee80211_tx_h_select_key 1
>> Feb 9 09:46:59 notebook2 kernel: [18408.925414] ieee80211_tx_h_select_key KEY is NULL
>>
>
> And there were no packet that were sent unencrypted ? If so, this is
> likely a driver bug...
Which version of compat-wireless / kernel do you use? I'm using kernel
3.1.9 with compat-wireless 3.2.1 and wpa_supplicant 1.0 rc2 from git.
> By the way, i just tested on my side with an ath9k station connecting to
> an ath9k ap, and with my patch, 4/4 is sent unencrypted. (and in my
> case, rekeying works), but i don't have any rt devices around me to test.
You tested with payload (a few times consecutively - for testing, I set
ptk rekeying timeout to 70s)?
It works for me too, without payload (idle) at the same time - even
without your patch.
The problem comes up with parallel payload.
> Also, i don't know what the DONT_ENCRYPT traces correspond to, but
> IEEE80211_TX_INTFL_DONT_ENCRYPT should only be set for management frames
> and the likes.
You got it right! Which category from below code snippet would be
correct - or which category do you see?
>
>>
>> without patch
>>
>> Feb 9 09:50:43 notebook2 kernel: [18624.839406] ieee80211_tx_h_select_key DONT_ENCRYPT
>> Feb 9 09:50:43 notebook2 kernel: [18632.619828] ieee80211_tx_h_select_key DONT_ENCRYPT
>> Feb 9 09:50:43 notebook2 kernel: [18632.622989] ieee80211_tx_h_select_key 1
>> Feb 9 09:50:43 notebook2 kernel: [18632.624980] ieee80211_tx_h_select_key 1
>>
>>
>> The patched source from compat-wireless (net/mac80211/tx.c):
>>
>>
>> if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) {
>> printk(KERN_DEBUG "ieee80211_tx_h_select_key DONT_ENCRYPT");
>> tx->key = NULL;
>> }
>> else if (tx->sta && (key = rcu_dereference(tx->sta->ptk))) {
>> printk(KERN_DEBUG "ieee80211_tx_h_select_key 1");
>> tx->key = key;
>> }
>> else if (ieee80211_is_mgmt(hdr->frame_control) &&
>> is_multicast_ether_addr(hdr->addr1) &&
>> ieee80211_is_robust_mgmt_frame(hdr) &&
>> (key = rcu_dereference(tx->sdata->default_mgmt_key))) {
>> printk(KERN_DEBUG "ieee80211_tx_h_select_key MGMT");
>> tx->key = key;
>> }
>> else if (is_multicast_ether_addr(hdr->addr1) &&
>> (key = rcu_dereference(tx->sdata->default_multicast_key))) {
>> printk(KERN_DEBUG "ieee80211_tx_h_select_key MULTICAST");
>> tx->key = key;
>> }
>> else if (!is_multicast_ether_addr(hdr->addr1) &&
>> (key = rcu_dereference(tx->sdata->default_unicast_key))) {
>> printk(KERN_DEBUG "ieee80211_tx_h_select_key UNICAST");
>> tx->key = key;
>> }
>> else if (tx->sdata->drop_unencrypted &&
>> (tx->skb->protocol != tx->sdata->control_port_protocol) &&
>> !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
>> (!ieee80211_is_robust_mgmt_frame(hdr) ||
>> (ieee80211_is_action(hdr->frame_control) &&
>> tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))) {
>> I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
>> printk(KERN_DEBUG "ieee80211_tx_h_select_key DROP_UNENCRYPTED");
>> return TX_DROP;
>> } else {
>> tx->key = NULL;
>> printk(KERN_DEBUG "ieee80211_tx_h_select_key KEY is NULL");
>> }
>>
>>
>>
>>
>> The 4/4 seen by wireshark by a external device looks like this:
>>
>> No. Time Source Destination Protocol Length Info
>> 1004 89.983445 src dst 802.11 179 QoS Data, SN=18, FN=0, Flags=.p.....TC
>>
>> Frame 1004: 179 bytes on wire (1432 bits), 179 bytes captured (1432 bits)
>> Radiotap Header v0, Length 26
>> IEEE 802.11 QoS Data, Flags: .p.....TC
>> Type/Subtype: QoS Data (0x28)
>> Frame Control: 0x4188 (Normal)
>> Version: 0
>> Type: Data frame (2)
>> Subtype: 8
>> Flags: 0x41
>> .... ..01 = DS status: Frame from STA to DS via an AP (To DS: 1 From DS: 0) (0x01)
>> .... .0.. = More Fragments: This is the last fragment
>> .... 0... = Retry: Frame is not being retransmitted
>> ...0 .... = PWR MGT: STA will stay up
>> ..0. .... = More Data: No data buffered
>> .1.. .... = Protected flag: Data is protected
>> 0... .... = Order flag: Not strictly ordered
>> Duration: 202
>> BSS Id: dst
>> Source address: src
>> Destination address: dst
>> Fragment number: 0
>> Sequence number: 18
>> Frame check sequence: 0x15b1958f [correct]
>> [Good: True]
>> [Bad: False]
>> QoS Control
>> TID: 0
>> Priority: 0 (Best Effort) (Best Effort)
>> ...0 .... = QoS bit 4: Bits 8-15 of QoS Control field are TXOP Duration Requested
>> Ack Policy: Normal Ack (0x00)
>> Payload Type: MSDU
>> TXOP Duration Requested: no TXOP requested (0)
>> CCMP parameters
>> CCMP Ext. Initialization Vector: 0x000000000009
>> Key Index: 0
>> Data (115 bytes)
>>
>> Data: ...........
>> [Length: 115]
>
> How do you know that this is 4/4 ?
Good question! I tested without any payload. Therefore, you can easily
see, which frame should be which step. One thing is sure: I didn't saw
any unencrypted frame ... . And PTK rekeying didn't work - it should
have worked, if it was unencrypted.
Regards,
Andreas
More information about the Hostap
mailing list