[PATCH] rsn_supp: Don't encrypt EAPOL-Key 4/4.
Nicolas Cavallari
Nicolas.Cavallari
Wed Feb 8 09:33:37 PST 2012
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.
>
>
> All other frames are even dropped before:
>
> if (memcmp(pn, key->u.ccmp.rx_pn[queue], CCMP_PN_LEN) <= 0) {
> key->u.ccmp.replays++;
> printk(KERN_INFO "ieee80211_crypto_ccmp_decrypt 9 RX_DROP_UNUSABLE\n");
> return RX_DROP_UNUSABLE;
> }
During my test, when either side changes the key, it resets the replay
counter to 0, so if one has still the old key, it detects the frame as a
replay, but really is a key conflict.
More information about the Hostap
mailing list