Michael MIC verification uses non-constant-time memcmp (defense-in-depth)
| Field | Value |
|---|---|
| ID | DF-0595 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N |
| CWE | CWE-208 Observable Timing Discrepancy; CWE-697 Incorrect Comparison |
| File | sys/netproto/802_11/wlan_tkip/ieee80211_crypto_tkip.c |
| Lines | 359-361 |
| Area | netproto/802_11 (TKIP crypto) |
| Confidence | certain |
| Discovered | 2026-07-02 |
| Reported | pending |
Summary
tkip_demic compares the computed Michael MIC against the received MIC
using libc memcmp, which short-circuits on the first differing byte. This
is the canonical enabling side-channel for byte-by-byte MIC-forcing attacks
(Erik Tews' "chopchop" family) on TKIP. The practical bar is high โ the
timing difference is sub-microsecond while WiFi RTT and the hostap_input
softirq path dominate โ but the fix is trivial and the spec-recommended
practice is to compare tags in constant time.
Root cause
sys/netproto/802_11/wlan_tkip/ieee80211_crypto_tkip.c:361:
359: m_copydata(m, m->m_pkthdr.len - tkip.ic_miclen,
360: tkip.ic_miclen, mic0);
361: if (memcmp(mic, mic0, tkip.ic_miclen)) {
memcmp returns as soon as any byte differs; the branch and memory-access
pattern are attacker-observable in principle. The same pattern exists in
sys/netproto/802_11/wlan_ccmp/ieee80211_crypto_ccmp.c:642, so this is a
tree-wide habit rather than TKIP-specific. There is no kmemcmp /
timingsafe_bcmp use anywhere in netproto/802_11.
Threat model & preconditions
- Attacker position: remote adjacent-network attacker within RF range.
- Privileges gained or impact: in principle, byte-by-byte MIC recovery via timing; in practice, heavily throttled by 802.11 MIC countermeasures (at most 2 MIC failures per 60 s before the link is shut down). Useful only as a defense-in-depth hardening item.
- Required config or capabilities: attacker within RF range of a TKIP-protected BSS, capable of injecting many forged frames and measuring per-frame processing time finely.
- Reachability: requires the SW-MIC path
(
k->wk_flags & IEEE80211_KEY_SWDEMIC).
Proof of concept
Pure hardening; not exploited here. The methodology (Beck-Tews) would be:
keep TSC advancing (one QoS TID per attempt to avoid replay), submit a
frame whose last MIC byte is each of 0..255, time the AP's response. Wrong
byte โ early memcmp return (statistically faster); right byte โ
full-length compare (slightly slower). Repeat for the preceding byte using
the recovered one. Not provided because (1) it is well-known, (2)
countermeasures throttle it to ~1 byte/min in practice, and (3) the goal
of this finding is the trivial constant-time fix, not a new attack.
Impact
- Blast radius: any DragonFlyBSD system using the SW TKIP MIC path.
- Severity rationale: Info โ hardening opportunity, defense-in-depth. No demonstrated impact; the timing channel is real in principle but dominated by channel jitter and throttled by MIC countermeasures in practice.
- Reliability: not currently exploited.
Recommended fix
Replace the memcmp with a constant-time comparison:
--- a/sys/netproto/802_11/wlan_tkip/ieee80211_crypto_tkip.c
+++ b/sys/netproto/802_11/wlan_tkip/ieee80211_crypto_tkip.c
@@ -358,7 +358,12 @@ tkip_demic(struct ieee80211_key *k, struct mbuf *m, int force)
m_copydata(m, m->m_pkthdr.len - tkip.ic_miclen,
tkip.ic_miclen, mic0);
- if (memcmp(mic, mic0, tkip.ic_miclen)) {
+ {
+ u_int _i;
+ u8 _d = 0;
+ for (_i = 0; _i < tkip.ic_miclen; _i++)
+ _d |= mic[_i] ^ mic0[_i];
+ if (_d != 0) {
/* NB: 802.11 layer handles statistic and debug msg */
ieee80211_notify_michael_failure(vap, wh,
k->wk_rxkeyix != IEEE80211_KEYIX_NONE ?
k->wk_rxkeyix : k->wk_keyix);
+ }
}
tkip.ic_miclen is fixed at compile time (= IEEE80211_WEP_MICLEN = 8),
so the loop is fully unrollable. The same treatment should be applied to
sys/netproto/802_11/wlan_ccmp/ieee80211_crypto_ccmp.c:642.
References
- Beck-Tews chopchop attack on TKIP โ historical context for the timing channel.
memcmp(3)semantics: short-circuit on first differing byte.- DragonFlyBSD
bcmp(9)/ constant-time-compare idioms elsewhere in the kernel (e.g. crypto subsystem).
Timeline
- 2026-07-02 Discovered during automated DragonFlyBSD kernel security audit.
- 2026-07-02 Reported to DragonFlyBSD security contact (pending) as a defense-in-depth hardening item.