Message ID | 1328549942-10112-1-git-send-email-cavallar@lri.fr |
---|---|
State | Changes Requested |
Headers | show |
On Mon, Feb 06, 2012 at 06:39:02PM +0100, Nicolas Cavallari wrote: > When the 4/4 pairwise handshake is lost, the authenticator > will retry 3/4 and we would resent 4/4, but encrypted. > > 802.11 spec implies that EAPOL 4/4 should not be encrypted, but > because setprotection is not implemented by any (non-testing) driver, > clear the key before sending EAPOL-Key 4/4 and reset the key > just after. > 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.. > 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.
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.
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 ? 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. 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 ?
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.
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
On 09/02/2012 11:40, Andreas Hartmann wrote: > 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 > And there were no packet that were sent unencrypted ? If so, this is likely a driver bug... 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. 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. > > 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 ? > > > > 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 > > _______________________________________________ > HostAP mailing list > HostAP@lists.shmoo.com > http://lists.shmoo.com/mailman/listinfo/hostap
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
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@lists.shmoo.com > http://lists.shmoo.com/mailman/listinfo/hostap
On Tue, Feb 07, 2012 at 12:52:54PM +0100, Nicolas Cavallari wrote: > 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... Well, how many of drivers support RSN IBSS in the first place? For infrastructure BSS, re-association seems like a reasonable workaround for recovering from this. > 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. Fair enough. Though, this patch does break PTK rekeying since it clears the PTK in the middle of 4-way handshake that was supposed to be completed using encrypted EAPOL frames. IBSS cases can be somewhat complex. I haven't really went through all the details for them, but in general, setprotection mechanism is something that I've wanted to see for a long time (i.e., way before RSN IBSS supported was added). Even if you were to be able to work around some initial connection cases by forcing EAPOL frames to be unencrypted, rekeying is likely to have similar race conditions.
On 12/02/2012 15:39, Jouni Malinen wrote: > On Tue, Feb 07, 2012 at 12:52:54PM +0100, Nicolas Cavallari wrote: >> 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... > Well, how many of drivers support RSN IBSS in the first place? For > infrastructure BSS, re-association seems like a reasonable workaround > for recovering from this. carl9170, ath9k, ath5k, ath9k_htc, and all mac80211-based drivers with pure software crypto... > >> 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. > Fair enough. Though, this patch does break PTK rekeying since it clears > the PTK in the middle of 4-way handshake that was supposed to be > completed using encrypted EAPOL frames. It clears a key just before sending 4/4, and the new PTK will be set just after sending 4/4. So clearing the key or not will make no difference, apart from respecting the standard when we do (and when it works), because the standard actually use setprotection(rx) instead. It will likely not change the various races that exists when sending frames while changing keys that Andreas is likely experiencing. > IBSS cases can be somewhat complex. I haven't really went through all > the details for them, but in general, setprotection mechanism is > something that I've wanted to see for a long time (i.e., way before RSN > IBSS supported was added). In terms of PTK, IBSS isn't much different from the PTK releying case: there is just traffic going on during the negociation. The opposite four way handshake is just here to exchange a GTK. As for my current setprotection() call, it will likely only implement the Tx part (choosing between Rx only and Rx_Tx), and won't necessarily solve race conditions, so i'm not that much motivated to try it. > > Even if you were to be able to work around some initial connection > cases by forcing EAPOL frames to be unencrypted, rekeying is likely to > have similar race conditions. Yes : If a 4/4 is lost during rekeying, the retransmitted 3/4 cannot be interpreted by the supplicant anymore. The standard somewhat "authorize" stations to store more than one PTK for a TA/RA pair, but does not define how to use them...
On Sun, Feb 12, 2012 at 06:20:09PM +0100, Nicolas Cavallari wrote: > It clears a key just before sending 4/4, and the new PTK will be set > just after sending 4/4. > So clearing the key or not will make no difference, apart from > respecting the standard when we do (and when it works), because the > standard actually use setprotection(rx) instead. It will likely not > change the various races that exists when sending frames while changing > keys that Andreas is likely experiencing. It would not make difference for the initial 4-way handshake at the beginning of the association, but it breaks PTK rekeying, i.e., another 4-way handshake during the association. In that exchange, all EAPOL frames need to be encrypted with the old key. > Yes : If a 4/4 is lost during rekeying, the retransmitted 3/4 cannot be > interpreted by the supplicant anymore. The standard somewhat "authorize" > stations to store more than one PTK for a TA/RA pair, but does not > define how to use them... Yes, this is not exactly completely defined, but in theory, something that could be implemented.
On 12/02/2012 19:25, Jouni Malinen wrote: > On Sun, Feb 12, 2012 at 06:20:09PM +0100, Nicolas Cavallari wrote: >> It clears a key just before sending 4/4, and the new PTK will be set >> just after sending 4/4. >> So clearing the key or not will make no difference, apart from >> respecting the standard when we do (and when it works), because the >> standard actually use setprotection(rx) instead. It will likely not >> change the various races that exists when sending frames while changing >> keys that Andreas is likely experiencing. > It would not make difference for the initial 4-way handshake at the > beginning of the association, but it breaks PTK rekeying, i.e., another > 4-way handshake during the association. In that exchange, all EAPOL > frames need to be encrypted with the old key. Where is that specified ? My interpretation of the standard is that setprotection(rx) is called before sending 4/4, so Tx encryption should be disabled for 4/4 ... If you don't want to not encrypt 4/4, there is no need to implement setprotection(rx)...
On Sun, Feb 12, 2012 at 07:35:40PM +0100, Nicolas Cavallari wrote: > On 12/02/2012 19:25, Jouni Malinen wrote: > > It would not make difference for the initial 4-way handshake at the > > beginning of the association, but it breaks PTK rekeying, i.e., another > > 4-way handshake during the association. In that exchange, all EAPOL > > frames need to be encrypted with the old key. > Where is that specified ? My interpretation of the standard is that > setprotection(rx) is called before sending 4/4, so Tx encryption > should be disabled for 4/4 ... In the IEEE 802.11 standard obviously.. ,-) Though, it may be a bit difficult to find this and some reading between lines may also be needed. > If you don't want to not encrypt 4/4, there is no need to implement > setprotection(rx)... There is. The key point here is that the 4-way handshake (including retries) is expected to be completed with the PTK that was in use at the beginning of the handshake. In other words, all four EAPOL messages in the 4-way handshake at the beginning of the association are unprotected while all four EAPOL messages (including retries) in the PTK rekeying 4-way handshakes are encrypted using the old PTK.
On 12/02/2012 20:43, Jouni Malinen wrote: > On Sun, Feb 12, 2012 at 07:35:40PM +0100, Nicolas Cavallari wrote: >> On 12/02/2012 19:25, Jouni Malinen wrote: >>> It would not make difference for the initial 4-way handshake at the >>> beginning of the association, but it breaks PTK rekeying, i.e., another >>> 4-way handshake during the association. In that exchange, all EAPOL >>> frames need to be encrypted with the old key. >> Where is that specified ? My interpretation of the standard is that >> setprotection(rx) is called before sending 4/4, so Tx encryption >> should be disabled for 4/4 ... > In the IEEE 802.11 standard obviously.. ,-) Though, it may be a bit > difficult to find this and some reading between lines may also be > needed. I would be interested to know more about those between-lines-readings ... because i still don't understand how rsn is supposed to not break. >> If you don't want to not encrypt 4/4, there is no need to implement >> setprotection(rx)... > There is. The key point here is that the 4-way handshake (including > retries) is expected to be completed with the PTK that was in use at the > beginning of the handshake. In other words, all four EAPOL messages in > the 4-way handshake at the beginning of the association are unprotected > while all four EAPOL messages (including retries) in the PTK rekeying > 4-way handshakes are encrypted using the old PTK. Then ... what do you expect "setprotection(rx)" to actually do, if not instead of not crypting in the tx path ? Considering that the standard does not require supporting more than one PTK per station, and that the linux kernel does not support it either... Anyway, it won't solve Andreas' problem : the 4/4 frame is queued behind a handful of data frames, control is resumed to wpa_supplicant, which sets the key just after. When the kernel flush his queue, it already uses the new key, so sends 4/4 encrypted with the new PTK ... Solving this might require something more than just "setprotection".
On Sun, Feb 12, 2012 at 09:27:25PM +0100, Nicolas Cavallari wrote: > Then ... what do you expect "setprotection(rx)" to actually do, > if not instead of not crypting in the tx path ? Considering that the > standard does not require supporting more than one PTK per station, and > that the linux kernel does not support it either... Well, this is not really described in the MLME primitives, or well, not really in the standard in general, but the only way to implement this correctly seems to require support for two PTKs that can be in use for the small amount of time during rekeying. I'm not aware of any implementation doing this either. > Anyway, it won't solve Andreas' problem : the 4/4 frame is queued behind > a handful of data frames, control is resumed to wpa_supplicant, which > sets the key just after. When the kernel flush his queue, it already > uses the new key, so sends 4/4 encrypted with the new PTK ... Solving > this might require something more than just "setprotection". What were those other data frames? If this is during the initial 4-way handshake, the port (PAE) should be unauthorized and other data frames apart from EAPOL frames should be blocked. Sure, we may not yet support PAE in station mode, but in theory, that's the way it is supposed to work. As far as rekeying is concerned, this gets quite a bit more complex (until the newly defined non-zero key index PTK gets into use).
Jouni Malinen schrieb: > On Sun, Feb 12, 2012 at 09:27:25PM +0100, Nicolas Cavallari wrote: >> Then ... what do you expect "setprotection(rx)" to actually do, >> if not instead of not crypting in the tx path ? Considering that the >> standard does not require supporting more than one PTK per station, and >> that the linux kernel does not support it either... > > Well, this is not really described in the MLME primitives, or well, not > really in the standard in general, but the only way to implement this > correctly seems to require support for two PTKs that can be in use for > the small amount of time during rekeying. I'm not aware of any > implementation doing this either. > >> Anyway, it won't solve Andreas' problem : the 4/4 frame is queued behind >> a handful of data frames, control is resumed to wpa_supplicant, which >> sets the key just after. When the kernel flush his queue, it already >> uses the new key, so sends 4/4 encrypted with the new PTK ... Solving >> this might require something more than just "setprotection". > > What were those other data frames? If this is during the initial 4-way > handshake, the port (PAE) should be unauthorized and other data frames > apart from EAPOL frames should be blocked. Sure, we may not yet support > PAE in station mode, but in theory, that's the way it is supposed to > work. As far as rekeying is concerned, this gets quite a bit more > complex (until the newly defined non-zero key index PTK gets into use). The problem comes up always during PTK rekeying with parallel payload (use netperf to force it easily) - a totally normal and trivial daily use case (streaming, nfs, X11, some internet download, ...), which is handled by ralink supplicant e.g. without any problem. I traced the problem on AP side at this point: I disabled hw encryption and inserted debug output in net/mac80211/wpa.c (ieee80211_crypto_ccmp_decrypt() - compat-wireless) 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; } } 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; } One of the dropped frame is the 4/4 frame from wpa_supplicant. If the legacy ralink driver internal supplicant is used, the connection isn't interrupted, because ralink sends 4/4 unencrypted (the behavior of the data frames is the same as wrote above, but this is no problem, as they are just resent after a few millisecs and the connection doesn't break down). That's the 4/4 frame as it can be seen traced with an external third device sent by ralink: 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 As it is sent unencrypted (the same way as during initial rekeying), I hope that the sent data is already internally encrypted (or it is just useless for any attacker, even if he get them unencrypted), so it shouldn't be a problem, if the frame itself isn't encrypted. I think, Nicolas analysis of the breakage sounds correctly to me. That's why even his patch doesn't work. Why isn't it just possible to send one of thousands of frames unencrypted? Just tag it with "unencrypted", so the driver knows, that this frame musn't be encrypted at all - independently if there is a key for encryption present or not. Kind regards, Andreas
On Mon, Feb 13, 2012 at 08:20:53AM +0100, Andreas Hartmann wrote: > 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)) { > /* hardware didn't decrypt/verify MIC */ > if (ieee80211_aes_ccm_decrypt( > return RX_DROP_UNUSABLE; Huh.. The key should not have changed yet on either the AP or the station.. > One of the dropped frame is the 4/4 frame from wpa_supplicant. Just to make sure.. This happened even for the case where only a single 3/4 had been transmitted and the first attempt at sending 4/4 was dropped? > If the legacy ralink driver internal supplicant is used, the connection > isn't interrupted, because ralink sends 4/4 unencrypted (the behavior of > the data frames is the same as wrote above, but this is no problem, > as they are just resent after a few millisecs and the connection > doesn't break down). The AP behaves incorrectly, if it accepts unencrypted EAPOL frame during PTK rekeying. Sure, with that kind of AP behavior, it would be trivial to avoid the issue by not encrypting the frame, but this is not the way RSN is supposed to work. > As it is sent unencrypted (the same way as during initial rekeying), I > hope that the sent data is already internally encrypted (or it is just > useless for any attacker, even if he get them unencrypted), so it > shouldn't be a problem, if the frame itself isn't encrypted. There are no know security attacks even if the frame were sent unencrypted. However, the RX rules on the other device (AP in this case) should force the frame to be dropped because a TK was configured for the transmitting STA and the frame was not protected. > Why isn't it just possible to send one of thousands of frames > unencrypted? Just tag it with "unencrypted", so the driver knows, that > this frame musn't be encrypted at all - independently if there is a > key for encryption present or not. It is not that much of a problem of being able to do this, but the problem of this not being the correct way of handling this.. If that AP was indeed using mac80211, too, I think we need to fix the AP behavior to drop such a frame. I would like to better understand which key is used for each frame during PTK rekeying. I'd guess that wireless capture file here can get pretty huge, so it may be easier if I try to reproduce that myself. If you are interested in running it through an analysis, I would suggest using wlantest (in the wlantest directory of hostap.git). If you provide it the needed keys (e.g., passphrase for WPA2-Personal), it will go through a wireless capture file and decrypt all the frames and decrypt the keys from both the initial 4-way handshake and PTK rekeys. It will complain about incorrectly protected frames, so it would be interesting to see what it says about the rekeying 4-way handshake.
Jouni Malinen schrieb: > On Mon, Feb 13, 2012 at 08:20:53AM +0100, Andreas Hartmann wrote: >> 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)) { >> /* hardware didn't decrypt/verify MIC */ >> if (ieee80211_aes_ccm_decrypt( >> return RX_DROP_UNUSABLE; > > Huh.. The key should not have changed yet on either the AP or the > station.. > >> One of the dropped frame is the 4/4 frame from wpa_supplicant. > > Just to make sure.. This happened even for the case where only a single > 3/4 had been transmitted and the first attempt at sending 4/4 was > dropped? Yes. >> If the legacy ralink driver internal supplicant is used, the connection >> isn't interrupted, because ralink sends 4/4 unencrypted (the behavior of >> the data frames is the same as wrote above, but this is no problem, >> as they are just resent after a few millisecs and the connection >> doesn't break down). > > The AP behaves incorrectly, if it accepts unencrypted EAPOL frame during > PTK rekeying. Sure, with that kind of AP behavior, it would be trivial > to avoid the issue by not encrypting the frame, but this is not the way > RSN is supposed to work. It is hostap-d3f57d0, hostap-1rc behaves exactly the same. Driver is nl80211, 80211.n (g behaves exactly the same). I can see it with ath9k and rt2800pci (didn't test any more) on AP side. Same problem can be seen with Linksys WAP610N as AP. >> As it is sent unencrypted (the same way as during initial rekeying), I >> hope that the sent data is already internally encrypted (or it is just >> useless for any attacker, even if he get them unencrypted), so it >> shouldn't be a problem, if the frame itself isn't encrypted. > > There are no know security attacks even if the frame were sent > unencrypted. However, the RX rules on the other device (AP in this case) > should force the frame to be dropped because a TK was configured for the > transmitting STA and the frame was not protected. If it works the protected way - but what is with supplicants sending unencrypted frames (I believe windows does the same, as I didn't have this problem with windows stations, too). >> Why isn't it just possible to send one of thousands of frames >> unencrypted? Just tag it with "unencrypted", so the driver knows, that >> this frame musn't be encrypted at all - independently if there is a >> key for encryption present or not. > > It is not that much of a problem of being able to do this, but the > problem of this not being the correct way of handling this.. If that AP > was indeed using mac80211, too, I think we need to fix the AP behavior > to drop such a frame. I think this would be a bad idea, because it would break compatibility (see above) and it would be against the defined standard (according Nicolas). > I would like to better understand which key is used for each frame > during PTK rekeying. I'd guess that wireless capture file here can get > pretty huge, so it may be easier if I try to reproduce that myself. That's right - the files get really huge :-(. > If you are interested in running it through an analysis, I would suggest > using wlantest (in the wlantest directory of hostap.git). If you provide > it the needed keys (e.g., passphrase for WPA2-Personal), it will go I'm using eap-tls, but psk shows exactly the same problem. > through a wireless capture file and decrypt all the frames and decrypt > the keys from both the initial 4-way handshake and PTK rekeys. It will > complain about incorrectly protected frames, so it would be interesting > to see what it says about the rekeying 4-way handshake. I'll try my best. But it should be really easy for you to reproduce this problem yourself, as it comes up here in 99%. Kind regards, Andreas
>> Anyway, it won't solve Andreas' problem : the 4/4 frame is queued behind >> a handful of data frames, control is resumed to wpa_supplicant, which >> sets the key just after. When the kernel flush his queue, it already >> uses the new key, so sends 4/4 encrypted with the new PTK ... Solving >> this might require something more than just "setprotection". > > What were those other data frames? If this is during the initial 4-way > handshake, the port (PAE) should be unauthorized and other data frames > apart from EAPOL frames should be blocked. Only the specific port corresponding to that particular authenticator is blocked. Other ports from other authenticators may be open. This is not the case for Andreas, as he is in Infrastructure mode. But for me it is, in IBSS mode... > As far as rekeying is concerned, this gets quite a bit more > complex (until the newly defined non-zero key index PTK gets into use). Which standard is this ? I might want to implement this for my private IBSS network.
On Mon, Feb 13, 2012 at 11:25:02AM +0100, Andreas Hartmann wrote: > Jouni Malinen schrieb: > > It is not that much of a problem of being able to do this, but the > > problem of this not being the correct way of handling this.. If that AP > > was indeed using mac80211, too, I think we need to fix the AP behavior > > to drop such a frame. > > I think this would be a bad idea, because it would break compatibility > (see above) and it would be against the defined standard (according > Nicolas). Sure, the interoperability part needs to be researched more. However, as far as the standard is concerned, I would claim that the defined behavior is to encrypt EAPOL frames whenever a PTK is in configured and that is very much the case during the PTK rekeying. There has been number of poor WPA implementations that did not exactly follow the rules correctly, but as far as RSN (WPA2) is concerned, these frames should really be encrypted. > I'll try my best. But it should be really easy for you to reproduce this > problem yourself, as it comes up here in 99%. For some reason, I did not seem to hit this in my tests when I was testing some of the EAPOL retransmission timeouts with heavy background traffic some time ago. I'll try this again, but I'm not sure when I'll find the time for this.
On Mon, Feb 13, 2012 at 11:39:26AM +0100, Nicolas Cavallari wrote: > > What were those other data frames? If this is during the initial 4-way > > handshake, the port (PAE) should be unauthorized and other data frames > > apart from EAPOL frames should be blocked. > > Only the specific port corresponding to that particular authenticator is > blocked. Other ports from other authenticators may be open. This is not > the case for Andreas, as he is in Infrastructure mode. But for me it is, > in IBSS mode... Sure, though even in that case, the non-EAPOL Data frames that get through should be for other destinations. I'm not sure I've fully understood this specific part of the issue, though. > > As far as rekeying is concerned, this gets quite a bit more > > complex (until the newly defined non-zero key index PTK gets into use). > > Which standard is this ? I might want to implement this for my > private IBSS network. It was added in P802.11-REVmb/D3.0 and will be included in the IEEE Std 802.11-2012 that should get published in a couple of months (it is included in the latest draft: P802.11-REVmb/D12). These 802.11 submissions may be helpful in understanding the changes: https://mentor.ieee.org/802.11/dcn/10/11-10-0313-01-000m-rekeying-protocol-fix.ppt https://mentor.ieee.org/802.11/dcn/10/11-10-0314-00-000m-rekeying-protocol-fix-text.doc
Nicolas Cavallari wrote: > On 08/02/2012 17:18, Andreas Hartmann wrote: [...] >> 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 ... I retested your patch again using 802.11g and could see this behaviour: 1. test: network idle The 4/4 package is sent unencrypted as proposed. The rekeying did work (but works fine too, without your patch). 2. test: network with high payload (netperf) The 4/4 package couldn't be seen, but therefore 6(!) packages of payload going from supplicant -> AP *unencrypted* . The rekeying didn't work nevertheless. Therefore: Big fat warning: don't use this patch at all! Kind regards, Andreas
Jouni Malinen schrieb: > On Mon, Feb 13, 2012 at 11:39:26AM +0100, Nicolas Cavallari wrote: >>> What were those other data frames? If this is during the initial 4-way >>> handshake, the port (PAE) should be unauthorized and other data frames >>> apart from EAPOL frames should be blocked. >> >> Only the specific port corresponding to that particular authenticator is >> blocked. Other ports from other authenticators may be open. This is not >> the case for Andreas, as he is in Infrastructure mode. But for me it is, >> in IBSS mode... > > Sure, though even in that case, the non-EAPOL Data frames that get > through should be for other destinations. I'm not sure I've fully > understood this specific part of the issue, though. > >>> As far as rekeying is concerned, this gets quite a bit more >>> complex (until the newly defined non-zero key index PTK gets into use). >> >> Which standard is this ? I might want to implement this for my >> private IBSS network. > > It was added in P802.11-REVmb/D3.0 and will be included in the IEEE Std > 802.11-2012 that should get published in a couple of months (it is > included in the latest draft: P802.11-REVmb/D12). > > These 802.11 submissions may be helpful in understanding the changes: > > https://mentor.ieee.org/802.11/dcn/10/11-10-0313-01-000m-rekeying-protocol-fix.ppt > https://mentor.ieee.org/802.11/dcn/10/11-10-0314-00-000m-rekeying-protocol-fix-text.doc May I kindly ask if these protocol changes have already been implemented in wpa_supplicant / hostapd? The actual situation is really annoying :-(. Thanks, kind regards, Andreas Hartmann
On Sat, Sep 01, 2012 at 03:18:08PM +0200, Andreas Hartmann wrote: > Jouni Malinen schrieb: > > https://mentor.ieee.org/802.11/dcn/10/11-10-0313-01-000m-rekeying-protocol-fix.ppt > May I kindly ask if these protocol changes have already been implemented > in wpa_supplicant / hostapd? The actual situation is really annoying :-(. Not yet. Though, even if they were, you would also need to get a wireless LAN driver/firmware that supports non-zero Key ID for pairwise keys, so this this require some more work. For most use cases, CCMP is strong enough to be used for quite some time without any rekeying, so the easiest workaround for rekeying related issues is to increase the rekey interval. I would assume that the new Key ID mechanism for unicast frames will eventually get deployed, but it may take same time to get there.
Jouni Malinen wrote: > On Sat, Sep 01, 2012 at 03:18:08PM +0200, Andreas Hartmann wrote: >> Jouni Malinen schrieb: >>> https://mentor.ieee.org/802.11/dcn/10/11-10-0313-01-000m-rekeying-protocol-fix.ppt > >> May I kindly ask if these protocol changes have already been implemented >> in wpa_supplicant / hostapd? The actual situation is really annoying :-(. > > Not yet. Though, even if they were, you would also need to get a > wireless LAN driver/firmware that supports non-zero Key ID for pairwise > keys, so this this require some more work. Would the firmware change be necessary, too, if nl80211 is used w/o hardware but software encryption (for both AP and supplicant)? > For most use cases, CCMP is strong enough to be used for quite some time > without any rekeying, so the easiest workaround for rekeying related > issues is to increase the rekey interval. The recommended value for the eap reauth period is 3600 seconds. You wrote about increasing the period and "quite some time". What would be the risk of the increase? Or better: which kinds of (known) attacks are complicated by forcing a regularly reauth? Why are 3600 seconds recommended and not, e.g., 1800? What would be a higher but still risk less time of period when using eap-tls and ccmp (using freeradius)? If it was your own network, which higher value would you use? I would be glad to get some basic points to be able to estimate the potential risk. A link would be fine, too. Thanks, kind regards, Andreas
Le 01/09/2012 15:18, Andreas Hartmann a écrit : > Jouni Malinen schrieb: >> On Mon, Feb 13, 2012 at 11:39:26AM +0100, Nicolas Cavallari wrote: >>>> As far as rekeying is concerned, this gets quite a bit more >>>> complex (until the newly defined non-zero key index PTK gets into use). >>> Which standard is this ? I might want to implement this for my >>> private IBSS network. >> It was added in P802.11-REVmb/D3.0 and will be included in the IEEE Std >> 802.11-2012 that should get published in a couple of months (it is >> included in the latest draft: P802.11-REVmb/D12). >> >> These 802.11 submissions may be helpful in understanding the changes: >> >> https://mentor.ieee.org/802.11/dcn/10/11-10-0313-01-000m-rekeying-protocol-fix.ppt >> https://mentor.ieee.org/802.11/dcn/10/11-10-0314-00-000m-rekeying-protocol-fix-text.doc > May I kindly ask if these protocol changes have already been implemented > in wpa_supplicant / hostapd? The actual situation is really annoying :-(. The hard part is implementing this in drivers. It's not even guaranteed that it will work with your cards. And if it does, it's because someone invested some of his time to implement it in mac80211. I started working on this, but i found an acceptable hack^Walternative solution for my case, and forgot about this. But i might want to reconsider it.
On Sun, Sep 02, 2012 at 08:59:27AM +0200, Andreas Hartmann wrote: > Jouni Malinen wrote: > > Not yet. Though, even if they were, you would also need to get a > > wireless LAN driver/firmware that supports non-zero Key ID for pairwise > > keys, so this this require some more work. > > Would the firmware change be necessary, too, if nl80211 is used w/o > hardware but software encryption (for both AP and supplicant)? It may be needed depending on which WLAN hardware you are using, but maybe not for most cases where software encryption is used. > > For most use cases, CCMP is strong enough to be used for quite some time > > without any rekeying, so the easiest workaround for rekeying related > > issues is to increase the rekey interval. > > The recommended value for the eap reauth period is 3600 seconds. > > You wrote about increasing the period and "quite some time". > > What would be the risk of the increase? Or better: which kinds of > (known) attacks are complicated by forcing a regularly reauth? Why are > 3600 seconds recommended and not, e.g., 1800? What would be a higher but > still risk less time of period when using eap-tls and ccmp (using > freeradius)? > If it was your own network, which higher value would you use? If EAP-TLS is used with a strong cipher and the network is configured to use only CCMP, I don't think I would need EAP reauthentication or PTK rekeying at all for practical purposes. Sure, you would need to stop using the key if the CCM nonce wraps around, so rekeying would be needed at that point, but that needs 2^48 frames to reach so until you get to 802.11ac or 802.11ad networks, it is a bit difficult to hit that in practice. That said, there may be other reasons for forcing EAP reauthentication, e.g., to enforce some session limits or to allow removal of a station from the network in reasonable amount of time even if the AP network does not support RADIUS server initiated disconnection requests. Anyway, I would consider CCMP strong enough to not require rekeying before CCM nonce wraparound based on what's known and what kind of CPU resources are available today, so the reason for setting rekeying based on some time limit is coming from some other need than maintaining secure encryption keys in the network.
Jouni Malinen wrote: > On Sun, Sep 02, 2012 at 08:59:27AM +0200, Andreas Hartmann wrote: >> Jouni Malinen wrote: [...] >>> For most use cases, CCMP is strong enough to be used for quite some time >>> without any rekeying, so the easiest workaround for rekeying related >>> issues is to increase the rekey interval. >> >> The recommended value for the eap reauth period is 3600 seconds. >> >> You wrote about increasing the period and "quite some time". >> >> What would be the risk of the increase? Or better: which kinds of >> (known) attacks are complicated by forcing a regularly reauth? Why are >> 3600 seconds recommended and not, e.g., 1800? What would be a higher but >> still risk less time of period when using eap-tls and ccmp (using >> freeradius)? >> If it was your own network, which higher value would you use? > > If EAP-TLS is used with a strong cipher and the network is configured to > use only CCMP, I don't think I would need EAP reauthentication or PTK > rekeying at all for practical purposes. Sure, you would need to stop > using the key if the CCM nonce wraps around, so rekeying would be needed > at that point, but that needs 2^48 frames to reach so until you get to > 802.11ac or 802.11ad networks, it is a bit difficult to hit that in > practice. Thanks for your explanation! But: what's a strong cipher? If freeradius cipher_list (-> openssl) is set to DEFAULT, the suite TLS_DHE_RSA_WITH_AES_256_CBC_SHA is used. If set to high, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA is used. According nmap, both suites are considered strong :-). Which one is stronger or more safe? CPU resources are not relevant at all. I'm using now 12 hours for rekeying timeout. I think this is feasible for me. > That said, there may be other reasons for forcing EAP reauthentication, > e.g., to enforce some session limits or to allow removal of a station > from the network in reasonable amount of time even if the AP network > does not support RADIUS server initiated disconnection requests. Anyway, > I would consider CCMP strong enough to not require rekeying before CCM > nonce wraparound based on what's known and what kind of CPU resources > are available today, so the reason for setting rekeying based on some > time limit is coming from some other need than maintaining secure > encryption keys in the network. Thanks again for your considerations! They helped me a lot! Kind regards, Andreas Hartmann
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 225489e..b24cc53 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -1141,6 +1141,9 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm, break; } + // Reset the PTK just before sending, so we don't sent 4/4 encrypted. + wpa_sm_set_key(sm, WPA_ALG_NONE, sm->bssid, 0, 0, NULL, 0, NULL, 0); + if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info, NULL, 0, &sm->ptk)) { goto failed;