[PATCH] rsn_supp: Don't encrypt EAPOL-Key 4/4.
Andreas Hartmann
andihartmann
Thu Feb 9 02:40:08 PST 2012
Nicolas Cavallari schrieb:
> On 08/02/2012 17:18, Andreas Hartmann wrote:
>> Nicolas Cavallari schrieb:
>>> On 08/02/2012 12:31, Andreas Hartmann wrote:
>>>> Nicolas Cavallari schrieb:
>>>>> On 06/02/2012 21:05, Jouni Malinen wrote:
>>>>>> On Mon, Feb 06, 2012 at 06:39:02PM +0100, Nicolas Cavallari wrote:
>>>>>>> This is just a proposed solution to a problem that i'm having. I don't
>>>>>>> think it is the best nor it does not break something else, so i'm asking
>>>>>>> what would be the right approach here. I was also thinking about
>>>>>>> reusing hostapd's eapol_send.
>>>>>>
>>>>>> Well, the proper approach would be to implement setprotection rather
>>>>>> than this workaround..
>>>>>
>>>>> If i implement setprotection, there are still drivers that won't or
>>>>> can't support it... that mean different code path depending on if the
>>>>> driver support it or not, because if the driver does not support it but
>>>>> we assume it does, we would set a key for rx and tx ... before sending
>>>>> 4/4. I already fell into that trap ;)
>>>>> I'll start experimenting a setprotection implementation anyway...
>>>>>
>>>>>>> I'm currently experimenting with a IBSS RSN network of 4 station, but
>>>>>>> while testing, there are always two or more handshakes that fails,
>>>>>>> because of a lost EAPOL-Key 4/4 frame. In IBSS mode, the two station
>>>>>>> will not retry association, so the network will not recover and will
>>>>>>> eventually split.
>>>>>>>
>>>>>>> Also, between the time where 3/4 was received by the supplicant and 4/4
>>>>>>> was received by the authenticator, the opposite four way handshake is
>>>>>>> stalled for the same reason.
>>>>>>
>>>>>> These are bit problematic to fix in any other way than by adding support
>>>>>> for unidirectional (RX only) key operations, i.e., MLME-SETPROTECTION
>>>>>> primitives. The AP (or well, Authenticator to include IBSS case) side
>>>>>> may start transmitting encrypted frames immediately after receiving
>>>>>> EAPOL-Key 4/4 and trying to remove/add keys on the STA/Supplicant side
>>>>>> is opening a race condition here.
>>>>>>
>>>>>
>>>>> This race condition already exists; the supplicant currently set the key
>>>>> after sending 4/4, this patch does not change anything about that. The
>>>>> same race also exist in the authenticator case, after receiving 4/4, and
>>>>> we can't do much to protect against that one. Both are
>>>>> equally feasible in IBSS mode, because the opposite four way hs is
>>>>> occurring at the same time.
>>>>
>>>> Please, may I ask you a question?
>>>>
>>>> I do encounter here a similar (?) problem since ages. hostapd sends 3/4
>>>> to supplicant, supplicant sends 4/4 and is ready and all is fine.
>>>>
>>>> But there is one problem: it only works, as long as there is no data
>>>> stream (payload) active between supplicant and hostapd.
>>>> If there is payload at the same time (e.g. created with netperf), 4/4 is
>>>> sent by supplicant (can be seen in wireshark), but isn't seen by
>>>> hostapd. hostapd therefore retries 3/4, but supplicant doesn't see these
>>>> packages any more: connection is broken, because hostapd closes the
>>>> connection because of missing 4/4!
>>>
>>> Which driver(s) do you use ?
>>
>> I'm using rt2800pci as AP and rt5572sta as STA (or rt2800usb or ath9k
>> - the latter even as AP, too).
>>
>>> It could be the same problem or a different one. Do you have a trace
>>> made from a separate interface in monitor mode ? that way we could see
>>> which packets are encrypted or not, and which are acked... logs from the
>>> both side might be useful too.
>>
>> I could provide them if you really need them, but I fear, they are
>> incomplete.
>>
>>
>> Rekeying behaviour without payload:
>> I compared the 4 packets of the original and the patched wpa_supplicant
>> (gathered on the supplicant itself with wireshark) but couldn't see any
>> difference between them.
>>
>> If I trace it with an external interface, all of the 4 packets are
>> encrypted and shown as "QoS Data". IEEE 802.11 QoS Data / Frame
>> Control / Flags / Protected flag is set (Data is protected). Each of
>> the frame is acked.
>>
>> I expected that the 4/4 frame should have been unencrypted with your
>> patch. But this seems not to be.
>
> Then my patch does not work... Or the kernel/driver does something
> completely strange. I should check my patch more in infrastructure mode
> to see if my 4/4 are encrypted ...
>
>>
>> BTW: the first 4 way handshake, directly after the initialisation of the
>> connection, is always sent completely unencrypted.
>>
>>
>>> But the fact that the supplicant cannot receive the duplicated 3/4 frame
>>> might indicate something. You are seeing this at key renegotiation time,
>>> right ?
>>
>> 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
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]
The same 4/4 with the internal supplicant of ralink (which just works
fine):
No. Time Source Destination Protocol Length Info
1271 142.821706 src dst EAPOL 163 Key (msg 4/4)
Frame 1271: 163 bytes on wire (1304 bits), 163 bytes captured (1304 bits)
Radiotap Header v0, Length 26
IEEE 802.11 QoS Data, Flags: .......TC
Type/Subtype: QoS Data (0x28)
Frame Control: 0x0188 (Normal)
Version: 0
Type: Data frame (2)
Subtype: 8
Flags: 0x1
.... ..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
.0.. .... = Protected flag: Data is not protected
0... .... = Order flag: Not strictly ordered
Duration: 202
BSS Id: dst
Source address: src
Destination address: dst
Fragment number: 0
Sequence number: 3
Frame check sequence: 0xeda1aa68 [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)
Logical-Link Control
DSAP: SNAP (0xaa)
IG Bit: Individual
SSAP: SNAP (0xaa)
CR Bit: Command
Control field: U, func=UI (0x03)
000. 00.. = Command: Unnumbered Information (0x00)
.... ..11 = Frame type: Unnumbered frame (0x03)
Organization Code: Encapsulated Ethernet (0x000000)
Type: 802.1X Authentication (0x888e)
802.1X Authentication
Version: 1
Type: Key (3)
Length: 95
Descriptor Type: EAPOL RSN key (2)
Key Information: 0x030a
.... .... .... .010 = Key Descriptor Version: HMAC-SHA1 for MIC and AES key wrap for encryption (2)
.... .... .... 1... = Key Type: Pairwise key
.... .... ..00 .... = Key Index: 0
.... .... .0.. .... = Install flag: Not set
.... .... 0... .... = Key Ack flag: Not set
.... ...1 .... .... = Key MIC flag: Set
.... ..1. .... .... = Secure flag: Set
.... .0.. .... .... = Error flag: Not set
.... 0... .... .... = Request flag: Not set
...0 .... .... .... = Encrypted Key Data flag: Not set
Key Length: 0
Replay Counter: 4
Nonce: 000000000000000000000000000000000000000000000000...
Key IV: 00000000000000000000000000000000
WPA Key RSC: 0000000000000000
WPA Key ID: 0000000000000000
WPA Key MIC: f7435c2290b845547d14e6deae810b1b
WPA Key Length: 0
Kind regards,
Andreas
More information about the Hostap
mailing list