[PATCH] rsn_supp: Don't encrypt EAPOL-Key 4/4.
Nicolas Cavallari
Nicolas.Cavallari
Thu Feb 9 07:27:39 PST 2012
On 09/02/2012 13:14, Andreas Hartmann wrote:
> 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.
I was testing with multicast payload ... silly me. I reproducted the
problem with unicast payload.
i'm going to dissect and test more...
>
>> 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
> _______________________________________________
> HostAP mailing list
> HostAP at lists.shmoo.com
> http://lists.shmoo.com/mailman/listinfo/hostap
More information about the Hostap
mailing list