History log of /openbsd-current/sys/net80211/ieee80211_crypto.c
Revision (<<< Hide revision tags) (Show revision tags >>>) Date Author Comments
# 1.79 14-Apr-2024 jsg

with empty body loops, put final semicolon on a new line for readability
ok bluhm@ jca@


Revision tags: OPENBSD_7_0_BASE OPENBSD_7_1_BASE OPENBSD_7_2_BASE OPENBSD_7_3_BASE OPENBSD_7_4_BASE OPENBSD_7_5_BASE
# 1.78 11-May-2021 stsp

During a "key unset for sw crypto" panic, display more meta-data
about the offending key. This will hopefully help with debugging.


Revision tags: OPENBSD_6_9_BASE
# 1.77 10-Dec-2020 stsp

ieee80211_decrypt must use m_freem() instead of m_free()

Patch by zxystd from the OpenIntelWireless project (drivers for macOS)

ok tobhe@


Revision tags: OPENBSD_6_8_BASE
# 1.76 15-May-2020 stsp

Fix CCMP replay check with 11n Rx aggregation and CCMP hardware offloading.

So far, drivers using hardware CCMP decryption were expected to keep the
most recently seen CCMP packet number (PN) up-to-date, and to discard frames
with lower PNs as replays.

A-MPDU subframes may legitimately arrive out of order, and the drivers skipped
CCMP replay checking for such frames. Re-ordering happens in ieee80211_inputm(),
after the driver is done with a frame. Drivers cannot tell replayed frames
apart from legitimate out-of-order retransmissions.

To fix this, update the PN value in ieee80211_inputm() after subframes have
been reordered into their proper sequence. Drivers still perform replay checks
but they no longer have to worry about updating the last seen PN value.

The 802.11 spec confirms that replay checking is supposed to happen after
A-MPDU re-ordering.

Tested by jmc@, benno@, solene@, and myself with the following drivers:
athn(4), iwn(4), iwm(4), wpi(4), urtwn(4)

ok solene@


Revision tags: OPENBSD_6_6_BASE OPENBSD_6_7_BASE
# 1.75 16-Aug-2019 procter

check that software de/encrypt is possible: under hardware
offload, it needn't be. the stack must otherwise rely on every
offloading driver correctly handling all frames governed by a
given key.
ok stsp@


Revision tags: OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.74 24-Sep-2018 stsp

Prevent ieee80211_get_txkey() from returning the integrity group temporal
key (IGTK) if a node doesn't have management frame protection (MFP) enabled.
The IGTK is not initialized if MFP is disabled, so using it triggers this
panic in ieee80211_encrypt(): panic("invalid key cipher 0x%x", k->k_cipher)

(As far as I can tell, at present, MFP is never enabled.)

Problem reported and fix tested by tj@ on athn(4) hostap


# 1.73 28-Apr-2018 stsp

Fix WEP key selection in ieee80211_get_txkey().

The WEP key index is stored in ic_def_txkey. The iGTK ("integrity group key")
index is specific to WPA. The previous code happened to always select WEP key
index 0 since the iGTK index is not yet used by any driver.

ok phessler@


# 1.72 28-Apr-2018 stsp

If ieee80211_encrypt() is passed a key with an unrecognized cipher
type then panic immediately instead of silently dropping packets.

ok phessler@


Revision tags: OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.71 18-Aug-2017 stsp

Clear WPA group keys from memory before initiating a key exchange
with an access point. Prevents false positive 'reused group key'
warnings in dmesg when re-associating to the same access point.
Problem reported by tb@
ok tb@


# 1.70 02-May-2017 mikeb

Switch 802.11 crypto over to the new AES

OK stsp@


Revision tags: OPENBSD_6_1_BASE
# 1.69 23-Mar-2017 tb

branches: 1.69.4;
Use explicit_bzero() to wipe out key material and add some sizes to free().

ok stsp


# 1.68 20-Dec-2016 stsp

Disable TKIP (WPA1) by default.

It is time for this legacy of WEP to die (remember WEP?).
The 802.11-2012 standard says:
The use of TKIP is deprecated. The TKIP algorithm is unsuitable for
the purposes of this standard.

TKIP has numerous problems. One of which is that TKIP allows a denial of
service attack which can be triggered by any client. Report 2 Michael MIC
failures to a TKIP AP to trigger "TKIP countermeasures". The AP is now
required by the 802.11 standard to lock everyone out for at least 60 seconds.
The network will remain unusable for as long as such MIC failure reports
are sent twice per minute.

TKIP remains available for interoperability purposes, for now.
It must be enabled manually with ifconfig(8).

Prompted by discussion with Mathy Vanhoef.
ok deraadt@ sthen@ reyk@


# 1.67 17-Dec-2016 stsp

Complete our half-done implementation of TKIP countermeasures in hostap mode.

The previous code would disable the AP until next reboot upon MIC failure.
Instead, disable the AP for 60 seconds, as required by the 802.11 standard.
I randomly added a bit of time (up to 120 seconds total) just because we can.

Problem reported by Mathy Vanhoef, thanks!
ok deraadt@
random input reyk@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.66 24-Nov-2015 mpi

branches: 1.66.4;
No need to include <net/if_arp.h>

This header is only needed because <netinet/if_ether.h> declares a
structure that needs it. But it turns out that <net/if.h> already
includes it as workaround.

A proper solution would be to stop declarting "struct ether_arp"
there. But no driver should need this header.


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.65 23-Dec-2014 tedu

unifdef some more INET. v4 4life.


# 1.64 18-Nov-2014 tedu

move arc4random prototype to systm.h. more appropriate for most code
to include that than rdnvar.h. ok deraadt dlg


# 1.63 14-Sep-2014 jsg

remove uneeded proc.h includes
ok mpi@ kspillner@


Revision tags: OPENBSD_5_6_BASE
# 1.62 12-Jul-2014 tedu

add a size argument to free. will be used soon, but for now default to 0.
after discussions with beck deraadt kettenis.


Revision tags: OPENBSD_5_5_BASE
# 1.61 21-Nov-2013 mpi

Remove unneeded include.

ok deraadt@


Revision tags: OPENBSD_4_9_BASE OPENBSD_5_0_BASE OPENBSD_5_1_BASE OPENBSD_5_2_BASE OPENBSD_5_3_BASE OPENBSD_5_4_BASE
# 1.60 11-Jan-2011 deraadt

for key material that is being being discarded, convert bzero() to
explicit_bzero() where required
ok markus mikeb


Revision tags: OPENBSD_4_8_BASE
# 1.59 20-Jul-2010 matthew

Switch some obvious network stack MAC comparisons from bcmp() to
timingsafe_bcmp().

ok deraadt@; committed over WPA.


Revision tags: OPENBSD_4_5_BASE OPENBSD_4_6_BASE OPENBSD_4_7_BASE
# 1.58 13-Feb-2009 damien

Change ifconfig wpaakms default setting to `psk' instead of `psk,802.1x'.
Some supplicants will autoselect 802.1X without giving users the
possibility to choose between PSK or 802.1X.

Similarly, no longer announce `PSK with SHA-256 based KDF' AKMP (defined
in Draft 802.11w) by default in the RSN IE of beacons and probe responses
as it confuses some broken supplicants. This kind of sacrifies security
for interoperability with shitty (but unfortunately widespread) clients
that do not follow the 802.11 standard properly.
This fixes associations from Intel PROSet on XP and also reportedly fixes
some Mac OS clients. I will likely make `psk-sha256' configurable through
ifconfig wpaakms after the 4.5 release.


# 1.57 26-Jan-2009 damien

Add some initial HT bits (not enabled yet) based on 802.11n Draft 7.01:
- implement A-MPDU frames buffering and reordering
- implement A-MSDU decapsulation
- process/send ADDBA Request, ADDBA Response and DELBA action frames
- process Block Ack Request control frames (including MTBAR)
- implement PBAC support (Protected Block Ack)
- add some incomplete HT Capabilities and HT Operation IEs parsing

Add more Management Frame Protection bits based on 802.11w Draft 7.0:
- implement SA Query procedure (both AP and STA)
- cleanup BIP

Fix some bugs:
- fix check for WEP key length that otherwise caused a stack smash in
ieee80211_wep_encrypt (pointed out by Xavier Santolaria on macppc)
- properly stop EAPOL timeout: fixes a panic that occured in HostAP mode
when turning the interface down while a 4-way handshake is in progress
(pointed out by Doughertys)

Did some code cleanup too.

The HT bits are currently not compiled in (IEEE80211_NO_HT is defined)
because they won't be ready until after the next release and I didn't
want to grow the kernel or to inadvertently introduce new bugs.
They are here such that other people can look at the code.
Notice that I had to add an extra parameter to ic_send_mgmt() for
action frames, that is why there are small changes in drivers defining
their own ic_send_mgmt() handler.

Sorry for the not very incremental diff but this has been sitting in
my tree for too long now.


# 1.56 27-Sep-2008 damien

Initial implementation of PMKSA caching and pre-authentication.
This will be required for future WPA-Enterprise support (802.1X).
Add ieee80211_needs_auth() function (not implemented yet) to
notify the userland 802.1X PACP machine when an 802.1X port
becomes enabled (that is after successfull 802.11 Open System
authentication).
Add SIOCS80211KEYRUN and SIOCS80211KEYAVAIL ioctls so that the
PACP state machine can kick the 802.11 key state machine and
install PMKs obtained from 802.1X (pre-)authentication.

Enable SHA-256 based AKMPs by default while I'm here (TGw).
This uses SHA-256 for key-derivation (instead of SHA1), AES-128-CMAC
for data integrity, and AES Key Wrap for data protection of EAPOL-Key
frames. An OpenBSD AP will always advertise this capability and an
OpenBSD STA will always prefer SHA-256 based AKMPs over SHA1 based
ones if both are supported by an AP.


# 1.55 27-Aug-2008 damien

introduce new IEEE80211_STA_ONLY kernel option that can be set to
remove IBSS and HostAP support from net80211 and 802.11 drivers.
it can be used to shrink RAMDISK kernels for instance (like what
was done for wi(4)).
it also has the benefit of highlighting what is specific to IBSS
and HostAP modes in the code.
the cost is that we now have two code paths to maintain.


# 1.54 14-Aug-2008 damien

ieee80211_derive_pmkid() is not used either


# 1.53 14-Aug-2008 damien

#ifdef notyet ieee80211_kdf() as it is not used yet (shrink kernel a bit)


# 1.52 12-Aug-2008 damien

add the code to encrypt/decrypt management frames, retrieve key id
from MMIE etc...
this code can't be triggered as no drivers claim MFP capability yet.


# 1.51 12-Aug-2008 damien

missing SHA-256 bits.


# 1.50 12-Aug-2008 damien

new SHA-256 based AKMPs.


# 1.49 12-Aug-2008 damien

add support for EAPOL-Key v3 descriptors (similar to v2 except that the
MIC is computed using AES-128-CMAC instead of HMAC-SHA1).
add a SHA-256 based key derivation function (not used yet).


# 1.48 12-Aug-2008 damien

the only integrity group cipher currently supported is AES-128-CMAC.


# 1.47 12-Aug-2008 damien

extend the ic_nw_keys[] array to 6 elements.
indices 0-3 will be used for group data keys while indices 4-5 will
be used for integrity group keys.
add a ic_rsngroupmgmtcipher field too.


# 1.46 12-Aug-2008 damien

get rid of the map_ptk()/map_gtk() functions, just inline them
which makes things easier to track.


# 1.45 12-Aug-2008 damien

simplify ieee80211_derive_ptk() prototype.
pass the AKMP so we can support other key derivation functions in the
future.


# 1.44 12-Aug-2008 damien

use HMAC-MD5, HMAC-SHA1 and AES Key Wrap sys/crypto/


Revision tags: OPENBSD_4_4_BASE
# 1.43 21-Jul-2008 damien

add ieee80211_priv.h file: contains definitions private to net80211.
this must not be included by drivers.


# 1.42 16-Jun-2008 damien

remove now useless casts since the rijndael_* protos have been
constified.


# 1.41 26-Apr-2008 damien

move things from ieee80211_ifattach() to ieee80211_crypto_attach().


# 1.40 21-Apr-2008 damien

- do not process ethernet PAE frames if RSN is not enabled
- add a ieee80211_recv_action() function (will be used later)
- some cleanup, remove unused prototypes, get rid of the
IEEE80211_VERIFY_* macros


# 1.39 18-Apr-2008 djm

extend the if_ethersubr.c crc functions to support updating a running
crc in addition to the existing "oneshot" mode and use them to replace
ieee80211_crc_update() with the new ether_crc32_le_update(). Saves 1k
kernel bss + some code.

Mark the new ether_crc32_[lb]e_update functions as __pure for a
~25x speedup (on my i386 at least).

feedback and ok damien@


# 1.38 17-Apr-2008 damien

call ieee80211_crc_init() only once, when the first 802.11 device
attaches instead of at every attach.

discussed with deraadt@


# 1.37 16-Apr-2008 damien

Kernel implementation of the 4-way handshake and group-key
handshake protocols (both supplicant and authenticator state
machines) as defined in the IEEE 802.11i standard.

Software implementation of the TKIP (Temporal Key Integrity
Protocol) and CCMP (CTR with CBC-MAC Protocol) protocols.

This diff doesn't implement any of the 802.1X authentication
protocols and thus only PSK authentication (using pre-shared
keys) is currently supported.

In concrete terms, this adds support for WPA-PSK and WPA2-PSK
protocols, both in station and hostap modes.

The following drivers are marked as WPA-capable and should
work: bwi(4), malo(4), ral(4), iwn(4), wpi(4), ural(4),
rum(4), upgt(4), and zyd(4)

The following options have been added to ifconfig(8):
wpa, wpapsk, wpaprotos, wpaakms, wpaciphers, wpagroupcipher

wpa-psk(8) can be used to generate keys from passphrases.

tested by many@
ok deraadt@


Revision tags: OPENBSD_4_3_BASE
# 1.36 11-Sep-2007 damien

remove horrid casts now that SHA1Update() has been constified.


# 1.35 29-Aug-2007 damien

- use ieee80211_get_hdrlen() where appropriate.
- discard all EAPOL-Key frames with an unknown descriptor version.
- when receiving message 3/4 of the 4-way handshake, do not install
the PTK if the INSTALL bit is not set. this fixes 4-way handshake
with APs using group keys only.
- similarly, do not mark the 802.1X port as valid if the SECURE bit
is not set (it will be marked as valid after group key handshake).


# 1.34 23-Aug-2007 damien

fix ieee80211_map_ptk() for TKIP.


# 1.33 22-Aug-2007 damien

add a ieee80211_get_txkey() function to determine the key to use for
transmitting a frame to a given node.
change ieee80211_encrypt() so that it now takes the key as parameter.
this change is required because drivers doing hardware crypto need to
know what key is being used.


# 1.32 22-Aug-2007 damien

- add k_rxmic and k_txmic fields to struct ieee80211_key to store the
Tx/Rx MIC for TKIP.
- add two functions to map a PTK and a GTK to an IEEE 802.11 key and
use them in ieee80211_input.c instead of duplicating the same code.
properly set Tx/Rx MIC in the IEEE 802.11 key in the case of TKIP.
- add ic_psk to struct ieee80211com to store the pre-shared key.
- fix setting of the SECURE bit in outgoing EAPOL-Key frames.
- when receiving msg 2 of the 4-way handshake, deauthenticate the
station if the RSN IE does not match that of the (Re)Association
request.
- before parsing an RSN or WPA IE, check that there's enough room for
the version field (2 bytes) which is mandatory.
- various tweaks while i'm here.


Revision tags: OPENBSD_4_2_BASE
# 1.31 03-Aug-2007 damien

add a ni_eapol_desc field to struct ieee80211_node to know whether
a station is using WPA1 or RSN descriptors.
make sure that a station that advertises WPA1 capability in an IE
uses the WPA1 EAPOL-Key descriptor type and not the RSN one.
fix construction of EAPOL-Key frames for WPA1.
i can now successfuly complete a 4-way and group-key handshake
with both a WPA1 and a WPA2 access point.
add some TKIP encapsulation code (no SW crypto yet).

ok deraadt@


# 1.30 01-Aug-2007 damien

add generic ieee80211_encrypt() and ieee80211_decrypt() functions that
can handle multiple ciphers (the key to use is determined automatically
by these functions based on the frame's destination address).
add ieee80211_ccmp_encrypt() and ieee80211_ccmp_decrypt().
those two functions only do encapsulation/decapsulation of CCMP frames
for now (they don't do SW crypto). they will help to test things with
drivers that can do HW crypto.
add a ni_pairwise_key field to struct ieee80211_node to actually install
the pairwise transient key.
install the GTK in ic_nw_keys[].


# 1.29 01-Aug-2007 damien

group key handshake message 1 is very different between RSN and WPA1.
RSN uses a GTK KDE while WPA1 stores the GTK in the EAPOL-Key frame
data field (encrypted) and uses some bits in the info field.
split ieee80211_recv_group_msg1() in two separate functions.


# 1.28 01-Aug-2007 damien

all WPA implementations i have tested use EAPOL-Key frames version 1,
so use that too and remove a check in ieee80211_recv_eapol().
WPA1 stores the group key id into bits 4-5 of the EAPOL-Key frame info
field and uses bit 6 to indicate if the key is Rx/Tx or Rx only.
remove a check in ieee80211_eapol_key_decrypt() because WPA1 encrypts
the payload of message 1 of the group-key handshake without setting the
encrypted bit in the info field.


# 1.27 01-Aug-2007 damien

the EAPOL-Key MIC must be computed with the MIC bit set.
this simplifies ieee80211_eapol_key_mic() and ieee80211_eapol_key_check_mic()
quite a bit.
set the EAPOL-Key body length before computing the MIC since the MIC is
computed with the 802.1X header too.
add a missing htons() while i'm here.


# 1.26 28-Jul-2007 damien

extend the ieee80211_key structure with a key identifier, a flags field
and a 64-bit receive sequence counter (for group keys).
add a ieee80211_cipher_keylen() function to retrieve the key length
in bytes used by a specific cipher.
account for 802.1X header size when computing the Key MIC.
some cleanup in comments and variable names while i'm here.


# 1.25 24-Jul-2007 damien

new function to check the MIC of a received EAPOL-Key frame.


# 1.24 24-Jul-2007 damien

use rc4_skip().
fix ieee80211_eapol_key_encrypt() so that we don't add more padding
bytes than necessary in the case of AES Key Wrap encryption.


# 1.23 24-Jul-2007 damien

remove some unused key derivation functions.
we won't support PeerKey handshake in a first time.


# 1.22 24-Jul-2007 damien

remove arc4_ compatibility macros.


# 1.21 24-Jul-2007 damien

add functions to compute EAPOL-Key Key MIC fields and to encrypt/decrypt
EAPOL-Key Data fields.


# 1.20 24-Jul-2007 damien

add ic_globalcnt to struct ieee80211com:
in an RSNA, each STA must maintain a 256-bit global key counter that
must be initialized to a random value (see 8.5.7).


# 1.19 18-Jul-2007 damien

modify ieee80211_aes_key_wrap() to support in-place encryption.
explicitly use ovbcopy() even if our kernel memcpy() supports
overlapping buffers.


# 1.18 18-Jul-2007 damien

add AES Key Wrap algorithm (see RFC 3394).
this will be used to encrypt/decrypt EAPOL-Key frames payload.


# 1.17 18-Jul-2007 damien

replace the ieee80211_wepkey structure with a more generic ieee80211_key
one that can be used with other ciphers than WEP.


# 1.16 14-Jul-2007 damien

s/uint8_t/u_int8_t/ for consistency.


# 1.15 14-Jul-2007 damien

update QoS Tx/Rx sequence numbers for each TID.
add a parameter to ieee80211_decap() to handle different 802.11
header sizes.
cleanup and clarify ieee80211_classify().


# 1.14 05-Jul-2007 damien

add myself to the copyright list.


# 1.13 05-Jul-2007 damien

add the pseudo-random function (PRF) and various key derivation
functions defined in 802.11i.


# 1.12 16-Jun-2007 damien

constify


# 1.11 16-Jun-2007 damien

de-static

ok jsg@


# 1.10 06-Jun-2007 damien

The license permits us to redistribute this code under the BSD or the GPLv2.
Choose the BSD license so that future enhancements will be BSD-only.

ok jsg@ reyk@ deraadt@


Revision tags: OPENBSD_4_1_BASE
# 1.9 29-Dec-2006 reyk

fix the key buffer size used for software wep, this could cause
problems with non-standard wep keys >= 104 bits.

thanks to Alexander Bluhm

ok mglocker@ jsg@


Revision tags: OPENBSD_4_0_BASE
# 1.8 18-Jun-2006 damien

Improve 802.11b/g interoperability and move toward better compliance
with IEEE Std 802.11g-2003 standard:

- add ERP Information Element in probe responses and beacons
- keep track of the number of associated non-ERP STAs and non-short slot
time capable STAs in the BSS
- enable use of RTS/CTS or CTS-to-self protection when required by the BSS
- add a ic_updateslot() callback to notify drivers of slot time changes
- cleanup computation of mgmt frames sizes in ieee80211_output.c
- nuke unnecessary <sys/cdefs.h> includes
- remove an unused macro (LOGICALLY_EQUAL) while i'm here

From {free,net}bsd, with additional fixes.

ok brad@, reyk@


Revision tags: OPENBSD_3_9_BASE
# 1.7 08-Sep-2005 reyk

mostly knf

ok jsg@


# 1.6 08-Sep-2005 jsg

Remove the last of the FreeBSD compatiblity goop.
ok reyk@


# 1.5 08-Sep-2005 jsg

Remove FreeBSD if_printf compat function from net80211.
ok reyk@


# 1.4 07-Sep-2005 jsg

Remove FreeBSD/NetBSD ifdef mess. We are not likely to be
doing a wholesale merge with them in future.
very enthusiastic ok from reyk@


Revision tags: OPENBSD_3_6_BASE OPENBSD_3_7_BASE OPENBSD_3_8_BASE
# 1.3 28-Jun-2004 millert

Don't restrict WEP keys to exactly 40 or 108 bits.


# 1.2 27-Jun-2004 millert

Hack to avoid panic in arc4maybeinit() due to rnd device not being
attached yet.


# 1.1 22-Jun-2004 millert

Import current NetBSD/FreeBSD 802.11 framework.
Based in part on a diff from Matthew Gream.


# 1.78 11-May-2021 stsp

During a "key unset for sw crypto" panic, display more meta-data
about the offending key. This will hopefully help with debugging.


Revision tags: OPENBSD_6_9_BASE
# 1.77 10-Dec-2020 stsp

ieee80211_decrypt must use m_freem() instead of m_free()

Patch by zxystd from the OpenIntelWireless project (drivers for macOS)

ok tobhe@


Revision tags: OPENBSD_6_8_BASE
# 1.76 15-May-2020 stsp

Fix CCMP replay check with 11n Rx aggregation and CCMP hardware offloading.

So far, drivers using hardware CCMP decryption were expected to keep the
most recently seen CCMP packet number (PN) up-to-date, and to discard frames
with lower PNs as replays.

A-MPDU subframes may legitimately arrive out of order, and the drivers skipped
CCMP replay checking for such frames. Re-ordering happens in ieee80211_inputm(),
after the driver is done with a frame. Drivers cannot tell replayed frames
apart from legitimate out-of-order retransmissions.

To fix this, update the PN value in ieee80211_inputm() after subframes have
been reordered into their proper sequence. Drivers still perform replay checks
but they no longer have to worry about updating the last seen PN value.

The 802.11 spec confirms that replay checking is supposed to happen after
A-MPDU re-ordering.

Tested by jmc@, benno@, solene@, and myself with the following drivers:
athn(4), iwn(4), iwm(4), wpi(4), urtwn(4)

ok solene@


Revision tags: OPENBSD_6_6_BASE OPENBSD_6_7_BASE
# 1.75 16-Aug-2019 procter

check that software de/encrypt is possible: under hardware
offload, it needn't be. the stack must otherwise rely on every
offloading driver correctly handling all frames governed by a
given key.
ok stsp@


Revision tags: OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.74 24-Sep-2018 stsp

Prevent ieee80211_get_txkey() from returning the integrity group temporal
key (IGTK) if a node doesn't have management frame protection (MFP) enabled.
The IGTK is not initialized if MFP is disabled, so using it triggers this
panic in ieee80211_encrypt(): panic("invalid key cipher 0x%x", k->k_cipher)

(As far as I can tell, at present, MFP is never enabled.)

Problem reported and fix tested by tj@ on athn(4) hostap


# 1.73 28-Apr-2018 stsp

Fix WEP key selection in ieee80211_get_txkey().

The WEP key index is stored in ic_def_txkey. The iGTK ("integrity group key")
index is specific to WPA. The previous code happened to always select WEP key
index 0 since the iGTK index is not yet used by any driver.

ok phessler@


# 1.72 28-Apr-2018 stsp

If ieee80211_encrypt() is passed a key with an unrecognized cipher
type then panic immediately instead of silently dropping packets.

ok phessler@


Revision tags: OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.71 18-Aug-2017 stsp

Clear WPA group keys from memory before initiating a key exchange
with an access point. Prevents false positive 'reused group key'
warnings in dmesg when re-associating to the same access point.
Problem reported by tb@
ok tb@


# 1.70 02-May-2017 mikeb

Switch 802.11 crypto over to the new AES

OK stsp@


Revision tags: OPENBSD_6_1_BASE
# 1.69 23-Mar-2017 tb

branches: 1.69.4;
Use explicit_bzero() to wipe out key material and add some sizes to free().

ok stsp


# 1.68 20-Dec-2016 stsp

Disable TKIP (WPA1) by default.

It is time for this legacy of WEP to die (remember WEP?).
The 802.11-2012 standard says:
The use of TKIP is deprecated. The TKIP algorithm is unsuitable for
the purposes of this standard.

TKIP has numerous problems. One of which is that TKIP allows a denial of
service attack which can be triggered by any client. Report 2 Michael MIC
failures to a TKIP AP to trigger "TKIP countermeasures". The AP is now
required by the 802.11 standard to lock everyone out for at least 60 seconds.
The network will remain unusable for as long as such MIC failure reports
are sent twice per minute.

TKIP remains available for interoperability purposes, for now.
It must be enabled manually with ifconfig(8).

Prompted by discussion with Mathy Vanhoef.
ok deraadt@ sthen@ reyk@


# 1.67 17-Dec-2016 stsp

Complete our half-done implementation of TKIP countermeasures in hostap mode.

The previous code would disable the AP until next reboot upon MIC failure.
Instead, disable the AP for 60 seconds, as required by the 802.11 standard.
I randomly added a bit of time (up to 120 seconds total) just because we can.

Problem reported by Mathy Vanhoef, thanks!
ok deraadt@
random input reyk@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.66 24-Nov-2015 mpi

branches: 1.66.4;
No need to include <net/if_arp.h>

This header is only needed because <netinet/if_ether.h> declares a
structure that needs it. But it turns out that <net/if.h> already
includes it as workaround.

A proper solution would be to stop declarting "struct ether_arp"
there. But no driver should need this header.


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.65 23-Dec-2014 tedu

unifdef some more INET. v4 4life.


# 1.64 18-Nov-2014 tedu

move arc4random prototype to systm.h. more appropriate for most code
to include that than rdnvar.h. ok deraadt dlg


# 1.63 14-Sep-2014 jsg

remove uneeded proc.h includes
ok mpi@ kspillner@


Revision tags: OPENBSD_5_6_BASE
# 1.62 12-Jul-2014 tedu

add a size argument to free. will be used soon, but for now default to 0.
after discussions with beck deraadt kettenis.


Revision tags: OPENBSD_5_5_BASE
# 1.61 21-Nov-2013 mpi

Remove unneeded include.

ok deraadt@


Revision tags: OPENBSD_4_9_BASE OPENBSD_5_0_BASE OPENBSD_5_1_BASE OPENBSD_5_2_BASE OPENBSD_5_3_BASE OPENBSD_5_4_BASE
# 1.60 11-Jan-2011 deraadt

for key material that is being being discarded, convert bzero() to
explicit_bzero() where required
ok markus mikeb


Revision tags: OPENBSD_4_8_BASE
# 1.59 20-Jul-2010 matthew

Switch some obvious network stack MAC comparisons from bcmp() to
timingsafe_bcmp().

ok deraadt@; committed over WPA.


Revision tags: OPENBSD_4_5_BASE OPENBSD_4_6_BASE OPENBSD_4_7_BASE
# 1.58 13-Feb-2009 damien

Change ifconfig wpaakms default setting to `psk' instead of `psk,802.1x'.
Some supplicants will autoselect 802.1X without giving users the
possibility to choose between PSK or 802.1X.

Similarly, no longer announce `PSK with SHA-256 based KDF' AKMP (defined
in Draft 802.11w) by default in the RSN IE of beacons and probe responses
as it confuses some broken supplicants. This kind of sacrifies security
for interoperability with shitty (but unfortunately widespread) clients
that do not follow the 802.11 standard properly.
This fixes associations from Intel PROSet on XP and also reportedly fixes
some Mac OS clients. I will likely make `psk-sha256' configurable through
ifconfig wpaakms after the 4.5 release.


# 1.57 26-Jan-2009 damien

Add some initial HT bits (not enabled yet) based on 802.11n Draft 7.01:
- implement A-MPDU frames buffering and reordering
- implement A-MSDU decapsulation
- process/send ADDBA Request, ADDBA Response and DELBA action frames
- process Block Ack Request control frames (including MTBAR)
- implement PBAC support (Protected Block Ack)
- add some incomplete HT Capabilities and HT Operation IEs parsing

Add more Management Frame Protection bits based on 802.11w Draft 7.0:
- implement SA Query procedure (both AP and STA)
- cleanup BIP

Fix some bugs:
- fix check for WEP key length that otherwise caused a stack smash in
ieee80211_wep_encrypt (pointed out by Xavier Santolaria on macppc)
- properly stop EAPOL timeout: fixes a panic that occured in HostAP mode
when turning the interface down while a 4-way handshake is in progress
(pointed out by Doughertys)

Did some code cleanup too.

The HT bits are currently not compiled in (IEEE80211_NO_HT is defined)
because they won't be ready until after the next release and I didn't
want to grow the kernel or to inadvertently introduce new bugs.
They are here such that other people can look at the code.
Notice that I had to add an extra parameter to ic_send_mgmt() for
action frames, that is why there are small changes in drivers defining
their own ic_send_mgmt() handler.

Sorry for the not very incremental diff but this has been sitting in
my tree for too long now.


# 1.56 27-Sep-2008 damien

Initial implementation of PMKSA caching and pre-authentication.
This will be required for future WPA-Enterprise support (802.1X).
Add ieee80211_needs_auth() function (not implemented yet) to
notify the userland 802.1X PACP machine when an 802.1X port
becomes enabled (that is after successfull 802.11 Open System
authentication).
Add SIOCS80211KEYRUN and SIOCS80211KEYAVAIL ioctls so that the
PACP state machine can kick the 802.11 key state machine and
install PMKs obtained from 802.1X (pre-)authentication.

Enable SHA-256 based AKMPs by default while I'm here (TGw).
This uses SHA-256 for key-derivation (instead of SHA1), AES-128-CMAC
for data integrity, and AES Key Wrap for data protection of EAPOL-Key
frames. An OpenBSD AP will always advertise this capability and an
OpenBSD STA will always prefer SHA-256 based AKMPs over SHA1 based
ones if both are supported by an AP.


# 1.55 27-Aug-2008 damien

introduce new IEEE80211_STA_ONLY kernel option that can be set to
remove IBSS and HostAP support from net80211 and 802.11 drivers.
it can be used to shrink RAMDISK kernels for instance (like what
was done for wi(4)).
it also has the benefit of highlighting what is specific to IBSS
and HostAP modes in the code.
the cost is that we now have two code paths to maintain.


# 1.54 14-Aug-2008 damien

ieee80211_derive_pmkid() is not used either


# 1.53 14-Aug-2008 damien

#ifdef notyet ieee80211_kdf() as it is not used yet (shrink kernel a bit)


# 1.52 12-Aug-2008 damien

add the code to encrypt/decrypt management frames, retrieve key id
from MMIE etc...
this code can't be triggered as no drivers claim MFP capability yet.


# 1.51 12-Aug-2008 damien

missing SHA-256 bits.


# 1.50 12-Aug-2008 damien

new SHA-256 based AKMPs.


# 1.49 12-Aug-2008 damien

add support for EAPOL-Key v3 descriptors (similar to v2 except that the
MIC is computed using AES-128-CMAC instead of HMAC-SHA1).
add a SHA-256 based key derivation function (not used yet).


# 1.48 12-Aug-2008 damien

the only integrity group cipher currently supported is AES-128-CMAC.


# 1.47 12-Aug-2008 damien

extend the ic_nw_keys[] array to 6 elements.
indices 0-3 will be used for group data keys while indices 4-5 will
be used for integrity group keys.
add a ic_rsngroupmgmtcipher field too.


# 1.46 12-Aug-2008 damien

get rid of the map_ptk()/map_gtk() functions, just inline them
which makes things easier to track.


# 1.45 12-Aug-2008 damien

simplify ieee80211_derive_ptk() prototype.
pass the AKMP so we can support other key derivation functions in the
future.


# 1.44 12-Aug-2008 damien

use HMAC-MD5, HMAC-SHA1 and AES Key Wrap sys/crypto/


Revision tags: OPENBSD_4_4_BASE
# 1.43 21-Jul-2008 damien

add ieee80211_priv.h file: contains definitions private to net80211.
this must not be included by drivers.


# 1.42 16-Jun-2008 damien

remove now useless casts since the rijndael_* protos have been
constified.


# 1.41 26-Apr-2008 damien

move things from ieee80211_ifattach() to ieee80211_crypto_attach().


# 1.40 21-Apr-2008 damien

- do not process ethernet PAE frames if RSN is not enabled
- add a ieee80211_recv_action() function (will be used later)
- some cleanup, remove unused prototypes, get rid of the
IEEE80211_VERIFY_* macros


# 1.39 18-Apr-2008 djm

extend the if_ethersubr.c crc functions to support updating a running
crc in addition to the existing "oneshot" mode and use them to replace
ieee80211_crc_update() with the new ether_crc32_le_update(). Saves 1k
kernel bss + some code.

Mark the new ether_crc32_[lb]e_update functions as __pure for a
~25x speedup (on my i386 at least).

feedback and ok damien@


# 1.38 17-Apr-2008 damien

call ieee80211_crc_init() only once, when the first 802.11 device
attaches instead of at every attach.

discussed with deraadt@


# 1.37 16-Apr-2008 damien

Kernel implementation of the 4-way handshake and group-key
handshake protocols (both supplicant and authenticator state
machines) as defined in the IEEE 802.11i standard.

Software implementation of the TKIP (Temporal Key Integrity
Protocol) and CCMP (CTR with CBC-MAC Protocol) protocols.

This diff doesn't implement any of the 802.1X authentication
protocols and thus only PSK authentication (using pre-shared
keys) is currently supported.

In concrete terms, this adds support for WPA-PSK and WPA2-PSK
protocols, both in station and hostap modes.

The following drivers are marked as WPA-capable and should
work: bwi(4), malo(4), ral(4), iwn(4), wpi(4), ural(4),
rum(4), upgt(4), and zyd(4)

The following options have been added to ifconfig(8):
wpa, wpapsk, wpaprotos, wpaakms, wpaciphers, wpagroupcipher

wpa-psk(8) can be used to generate keys from passphrases.

tested by many@
ok deraadt@


Revision tags: OPENBSD_4_3_BASE
# 1.36 11-Sep-2007 damien

remove horrid casts now that SHA1Update() has been constified.


# 1.35 29-Aug-2007 damien

- use ieee80211_get_hdrlen() where appropriate.
- discard all EAPOL-Key frames with an unknown descriptor version.
- when receiving message 3/4 of the 4-way handshake, do not install
the PTK if the INSTALL bit is not set. this fixes 4-way handshake
with APs using group keys only.
- similarly, do not mark the 802.1X port as valid if the SECURE bit
is not set (it will be marked as valid after group key handshake).


# 1.34 23-Aug-2007 damien

fix ieee80211_map_ptk() for TKIP.


# 1.33 22-Aug-2007 damien

add a ieee80211_get_txkey() function to determine the key to use for
transmitting a frame to a given node.
change ieee80211_encrypt() so that it now takes the key as parameter.
this change is required because drivers doing hardware crypto need to
know what key is being used.


# 1.32 22-Aug-2007 damien

- add k_rxmic and k_txmic fields to struct ieee80211_key to store the
Tx/Rx MIC for TKIP.
- add two functions to map a PTK and a GTK to an IEEE 802.11 key and
use them in ieee80211_input.c instead of duplicating the same code.
properly set Tx/Rx MIC in the IEEE 802.11 key in the case of TKIP.
- add ic_psk to struct ieee80211com to store the pre-shared key.
- fix setting of the SECURE bit in outgoing EAPOL-Key frames.
- when receiving msg 2 of the 4-way handshake, deauthenticate the
station if the RSN IE does not match that of the (Re)Association
request.
- before parsing an RSN or WPA IE, check that there's enough room for
the version field (2 bytes) which is mandatory.
- various tweaks while i'm here.


Revision tags: OPENBSD_4_2_BASE
# 1.31 03-Aug-2007 damien

add a ni_eapol_desc field to struct ieee80211_node to know whether
a station is using WPA1 or RSN descriptors.
make sure that a station that advertises WPA1 capability in an IE
uses the WPA1 EAPOL-Key descriptor type and not the RSN one.
fix construction of EAPOL-Key frames for WPA1.
i can now successfuly complete a 4-way and group-key handshake
with both a WPA1 and a WPA2 access point.
add some TKIP encapsulation code (no SW crypto yet).

ok deraadt@


# 1.30 01-Aug-2007 damien

add generic ieee80211_encrypt() and ieee80211_decrypt() functions that
can handle multiple ciphers (the key to use is determined automatically
by these functions based on the frame's destination address).
add ieee80211_ccmp_encrypt() and ieee80211_ccmp_decrypt().
those two functions only do encapsulation/decapsulation of CCMP frames
for now (they don't do SW crypto). they will help to test things with
drivers that can do HW crypto.
add a ni_pairwise_key field to struct ieee80211_node to actually install
the pairwise transient key.
install the GTK in ic_nw_keys[].


# 1.29 01-Aug-2007 damien

group key handshake message 1 is very different between RSN and WPA1.
RSN uses a GTK KDE while WPA1 stores the GTK in the EAPOL-Key frame
data field (encrypted) and uses some bits in the info field.
split ieee80211_recv_group_msg1() in two separate functions.


# 1.28 01-Aug-2007 damien

all WPA implementations i have tested use EAPOL-Key frames version 1,
so use that too and remove a check in ieee80211_recv_eapol().
WPA1 stores the group key id into bits 4-5 of the EAPOL-Key frame info
field and uses bit 6 to indicate if the key is Rx/Tx or Rx only.
remove a check in ieee80211_eapol_key_decrypt() because WPA1 encrypts
the payload of message 1 of the group-key handshake without setting the
encrypted bit in the info field.


# 1.27 01-Aug-2007 damien

the EAPOL-Key MIC must be computed with the MIC bit set.
this simplifies ieee80211_eapol_key_mic() and ieee80211_eapol_key_check_mic()
quite a bit.
set the EAPOL-Key body length before computing the MIC since the MIC is
computed with the 802.1X header too.
add a missing htons() while i'm here.


# 1.26 28-Jul-2007 damien

extend the ieee80211_key structure with a key identifier, a flags field
and a 64-bit receive sequence counter (for group keys).
add a ieee80211_cipher_keylen() function to retrieve the key length
in bytes used by a specific cipher.
account for 802.1X header size when computing the Key MIC.
some cleanup in comments and variable names while i'm here.


# 1.25 24-Jul-2007 damien

new function to check the MIC of a received EAPOL-Key frame.


# 1.24 24-Jul-2007 damien

use rc4_skip().
fix ieee80211_eapol_key_encrypt() so that we don't add more padding
bytes than necessary in the case of AES Key Wrap encryption.


# 1.23 24-Jul-2007 damien

remove some unused key derivation functions.
we won't support PeerKey handshake in a first time.


# 1.22 24-Jul-2007 damien

remove arc4_ compatibility macros.


# 1.21 24-Jul-2007 damien

add functions to compute EAPOL-Key Key MIC fields and to encrypt/decrypt
EAPOL-Key Data fields.


# 1.20 24-Jul-2007 damien

add ic_globalcnt to struct ieee80211com:
in an RSNA, each STA must maintain a 256-bit global key counter that
must be initialized to a random value (see 8.5.7).


# 1.19 18-Jul-2007 damien

modify ieee80211_aes_key_wrap() to support in-place encryption.
explicitly use ovbcopy() even if our kernel memcpy() supports
overlapping buffers.


# 1.18 18-Jul-2007 damien

add AES Key Wrap algorithm (see RFC 3394).
this will be used to encrypt/decrypt EAPOL-Key frames payload.


# 1.17 18-Jul-2007 damien

replace the ieee80211_wepkey structure with a more generic ieee80211_key
one that can be used with other ciphers than WEP.


# 1.16 14-Jul-2007 damien

s/uint8_t/u_int8_t/ for consistency.


# 1.15 14-Jul-2007 damien

update QoS Tx/Rx sequence numbers for each TID.
add a parameter to ieee80211_decap() to handle different 802.11
header sizes.
cleanup and clarify ieee80211_classify().


# 1.14 05-Jul-2007 damien

add myself to the copyright list.


# 1.13 05-Jul-2007 damien

add the pseudo-random function (PRF) and various key derivation
functions defined in 802.11i.


# 1.12 16-Jun-2007 damien

constify


# 1.11 16-Jun-2007 damien

de-static

ok jsg@


# 1.10 06-Jun-2007 damien

The license permits us to redistribute this code under the BSD or the GPLv2.
Choose the BSD license so that future enhancements will be BSD-only.

ok jsg@ reyk@ deraadt@


Revision tags: OPENBSD_4_1_BASE
# 1.9 29-Dec-2006 reyk

fix the key buffer size used for software wep, this could cause
problems with non-standard wep keys >= 104 bits.

thanks to Alexander Bluhm

ok mglocker@ jsg@


Revision tags: OPENBSD_4_0_BASE
# 1.8 18-Jun-2006 damien

Improve 802.11b/g interoperability and move toward better compliance
with IEEE Std 802.11g-2003 standard:

- add ERP Information Element in probe responses and beacons
- keep track of the number of associated non-ERP STAs and non-short slot
time capable STAs in the BSS
- enable use of RTS/CTS or CTS-to-self protection when required by the BSS
- add a ic_updateslot() callback to notify drivers of slot time changes
- cleanup computation of mgmt frames sizes in ieee80211_output.c
- nuke unnecessary <sys/cdefs.h> includes
- remove an unused macro (LOGICALLY_EQUAL) while i'm here

From {free,net}bsd, with additional fixes.

ok brad@, reyk@


Revision tags: OPENBSD_3_9_BASE
# 1.7 08-Sep-2005 reyk

mostly knf

ok jsg@


# 1.6 08-Sep-2005 jsg

Remove the last of the FreeBSD compatiblity goop.
ok reyk@


# 1.5 08-Sep-2005 jsg

Remove FreeBSD if_printf compat function from net80211.
ok reyk@


# 1.4 07-Sep-2005 jsg

Remove FreeBSD/NetBSD ifdef mess. We are not likely to be
doing a wholesale merge with them in future.
very enthusiastic ok from reyk@


Revision tags: OPENBSD_3_6_BASE OPENBSD_3_7_BASE OPENBSD_3_8_BASE
# 1.3 28-Jun-2004 millert

Don't restrict WEP keys to exactly 40 or 108 bits.


# 1.2 27-Jun-2004 millert

Hack to avoid panic in arc4maybeinit() due to rnd device not being
attached yet.


# 1.1 22-Jun-2004 millert

Import current NetBSD/FreeBSD 802.11 framework.
Based in part on a diff from Matthew Gream.


# 1.77 10-Dec-2020 stsp

ieee80211_decrypt must use m_freem() instead of m_free()

Patch by zxystd from the OpenIntelWireless project (drivers for macOS)

ok tobhe@


Revision tags: OPENBSD_6_8_BASE
# 1.76 15-May-2020 stsp

Fix CCMP replay check with 11n Rx aggregation and CCMP hardware offloading.

So far, drivers using hardware CCMP decryption were expected to keep the
most recently seen CCMP packet number (PN) up-to-date, and to discard frames
with lower PNs as replays.

A-MPDU subframes may legitimately arrive out of order, and the drivers skipped
CCMP replay checking for such frames. Re-ordering happens in ieee80211_inputm(),
after the driver is done with a frame. Drivers cannot tell replayed frames
apart from legitimate out-of-order retransmissions.

To fix this, update the PN value in ieee80211_inputm() after subframes have
been reordered into their proper sequence. Drivers still perform replay checks
but they no longer have to worry about updating the last seen PN value.

The 802.11 spec confirms that replay checking is supposed to happen after
A-MPDU re-ordering.

Tested by jmc@, benno@, solene@, and myself with the following drivers:
athn(4), iwn(4), iwm(4), wpi(4), urtwn(4)

ok solene@


Revision tags: OPENBSD_6_6_BASE OPENBSD_6_7_BASE
# 1.75 16-Aug-2019 procter

check that software de/encrypt is possible: under hardware
offload, it needn't be. the stack must otherwise rely on every
offloading driver correctly handling all frames governed by a
given key.
ok stsp@


Revision tags: OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.74 24-Sep-2018 stsp

Prevent ieee80211_get_txkey() from returning the integrity group temporal
key (IGTK) if a node doesn't have management frame protection (MFP) enabled.
The IGTK is not initialized if MFP is disabled, so using it triggers this
panic in ieee80211_encrypt(): panic("invalid key cipher 0x%x", k->k_cipher)

(As far as I can tell, at present, MFP is never enabled.)

Problem reported and fix tested by tj@ on athn(4) hostap


# 1.73 28-Apr-2018 stsp

Fix WEP key selection in ieee80211_get_txkey().

The WEP key index is stored in ic_def_txkey. The iGTK ("integrity group key")
index is specific to WPA. The previous code happened to always select WEP key
index 0 since the iGTK index is not yet used by any driver.

ok phessler@


# 1.72 28-Apr-2018 stsp

If ieee80211_encrypt() is passed a key with an unrecognized cipher
type then panic immediately instead of silently dropping packets.

ok phessler@


Revision tags: OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.71 18-Aug-2017 stsp

Clear WPA group keys from memory before initiating a key exchange
with an access point. Prevents false positive 'reused group key'
warnings in dmesg when re-associating to the same access point.
Problem reported by tb@
ok tb@


# 1.70 02-May-2017 mikeb

Switch 802.11 crypto over to the new AES

OK stsp@


Revision tags: OPENBSD_6_1_BASE
# 1.69 23-Mar-2017 tb

branches: 1.69.4;
Use explicit_bzero() to wipe out key material and add some sizes to free().

ok stsp


# 1.68 20-Dec-2016 stsp

Disable TKIP (WPA1) by default.

It is time for this legacy of WEP to die (remember WEP?).
The 802.11-2012 standard says:
The use of TKIP is deprecated. The TKIP algorithm is unsuitable for
the purposes of this standard.

TKIP has numerous problems. One of which is that TKIP allows a denial of
service attack which can be triggered by any client. Report 2 Michael MIC
failures to a TKIP AP to trigger "TKIP countermeasures". The AP is now
required by the 802.11 standard to lock everyone out for at least 60 seconds.
The network will remain unusable for as long as such MIC failure reports
are sent twice per minute.

TKIP remains available for interoperability purposes, for now.
It must be enabled manually with ifconfig(8).

Prompted by discussion with Mathy Vanhoef.
ok deraadt@ sthen@ reyk@


# 1.67 17-Dec-2016 stsp

Complete our half-done implementation of TKIP countermeasures in hostap mode.

The previous code would disable the AP until next reboot upon MIC failure.
Instead, disable the AP for 60 seconds, as required by the 802.11 standard.
I randomly added a bit of time (up to 120 seconds total) just because we can.

Problem reported by Mathy Vanhoef, thanks!
ok deraadt@
random input reyk@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.66 24-Nov-2015 mpi

branches: 1.66.4;
No need to include <net/if_arp.h>

This header is only needed because <netinet/if_ether.h> declares a
structure that needs it. But it turns out that <net/if.h> already
includes it as workaround.

A proper solution would be to stop declarting "struct ether_arp"
there. But no driver should need this header.


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.65 23-Dec-2014 tedu

unifdef some more INET. v4 4life.


# 1.64 18-Nov-2014 tedu

move arc4random prototype to systm.h. more appropriate for most code
to include that than rdnvar.h. ok deraadt dlg


# 1.63 14-Sep-2014 jsg

remove uneeded proc.h includes
ok mpi@ kspillner@


Revision tags: OPENBSD_5_6_BASE
# 1.62 12-Jul-2014 tedu

add a size argument to free. will be used soon, but for now default to 0.
after discussions with beck deraadt kettenis.


Revision tags: OPENBSD_5_5_BASE
# 1.61 21-Nov-2013 mpi

Remove unneeded include.

ok deraadt@


Revision tags: OPENBSD_4_9_BASE OPENBSD_5_0_BASE OPENBSD_5_1_BASE OPENBSD_5_2_BASE OPENBSD_5_3_BASE OPENBSD_5_4_BASE
# 1.60 11-Jan-2011 deraadt

for key material that is being being discarded, convert bzero() to
explicit_bzero() where required
ok markus mikeb


Revision tags: OPENBSD_4_8_BASE
# 1.59 20-Jul-2010 matthew

Switch some obvious network stack MAC comparisons from bcmp() to
timingsafe_bcmp().

ok deraadt@; committed over WPA.


Revision tags: OPENBSD_4_5_BASE OPENBSD_4_6_BASE OPENBSD_4_7_BASE
# 1.58 13-Feb-2009 damien

Change ifconfig wpaakms default setting to `psk' instead of `psk,802.1x'.
Some supplicants will autoselect 802.1X without giving users the
possibility to choose between PSK or 802.1X.

Similarly, no longer announce `PSK with SHA-256 based KDF' AKMP (defined
in Draft 802.11w) by default in the RSN IE of beacons and probe responses
as it confuses some broken supplicants. This kind of sacrifies security
for interoperability with shitty (but unfortunately widespread) clients
that do not follow the 802.11 standard properly.
This fixes associations from Intel PROSet on XP and also reportedly fixes
some Mac OS clients. I will likely make `psk-sha256' configurable through
ifconfig wpaakms after the 4.5 release.


# 1.57 26-Jan-2009 damien

Add some initial HT bits (not enabled yet) based on 802.11n Draft 7.01:
- implement A-MPDU frames buffering and reordering
- implement A-MSDU decapsulation
- process/send ADDBA Request, ADDBA Response and DELBA action frames
- process Block Ack Request control frames (including MTBAR)
- implement PBAC support (Protected Block Ack)
- add some incomplete HT Capabilities and HT Operation IEs parsing

Add more Management Frame Protection bits based on 802.11w Draft 7.0:
- implement SA Query procedure (both AP and STA)
- cleanup BIP

Fix some bugs:
- fix check for WEP key length that otherwise caused a stack smash in
ieee80211_wep_encrypt (pointed out by Xavier Santolaria on macppc)
- properly stop EAPOL timeout: fixes a panic that occured in HostAP mode
when turning the interface down while a 4-way handshake is in progress
(pointed out by Doughertys)

Did some code cleanup too.

The HT bits are currently not compiled in (IEEE80211_NO_HT is defined)
because they won't be ready until after the next release and I didn't
want to grow the kernel or to inadvertently introduce new bugs.
They are here such that other people can look at the code.
Notice that I had to add an extra parameter to ic_send_mgmt() for
action frames, that is why there are small changes in drivers defining
their own ic_send_mgmt() handler.

Sorry for the not very incremental diff but this has been sitting in
my tree for too long now.


# 1.56 27-Sep-2008 damien

Initial implementation of PMKSA caching and pre-authentication.
This will be required for future WPA-Enterprise support (802.1X).
Add ieee80211_needs_auth() function (not implemented yet) to
notify the userland 802.1X PACP machine when an 802.1X port
becomes enabled (that is after successfull 802.11 Open System
authentication).
Add SIOCS80211KEYRUN and SIOCS80211KEYAVAIL ioctls so that the
PACP state machine can kick the 802.11 key state machine and
install PMKs obtained from 802.1X (pre-)authentication.

Enable SHA-256 based AKMPs by default while I'm here (TGw).
This uses SHA-256 for key-derivation (instead of SHA1), AES-128-CMAC
for data integrity, and AES Key Wrap for data protection of EAPOL-Key
frames. An OpenBSD AP will always advertise this capability and an
OpenBSD STA will always prefer SHA-256 based AKMPs over SHA1 based
ones if both are supported by an AP.


# 1.55 27-Aug-2008 damien

introduce new IEEE80211_STA_ONLY kernel option that can be set to
remove IBSS and HostAP support from net80211 and 802.11 drivers.
it can be used to shrink RAMDISK kernels for instance (like what
was done for wi(4)).
it also has the benefit of highlighting what is specific to IBSS
and HostAP modes in the code.
the cost is that we now have two code paths to maintain.


# 1.54 14-Aug-2008 damien

ieee80211_derive_pmkid() is not used either


# 1.53 14-Aug-2008 damien

#ifdef notyet ieee80211_kdf() as it is not used yet (shrink kernel a bit)


# 1.52 12-Aug-2008 damien

add the code to encrypt/decrypt management frames, retrieve key id
from MMIE etc...
this code can't be triggered as no drivers claim MFP capability yet.


# 1.51 12-Aug-2008 damien

missing SHA-256 bits.


# 1.50 12-Aug-2008 damien

new SHA-256 based AKMPs.


# 1.49 12-Aug-2008 damien

add support for EAPOL-Key v3 descriptors (similar to v2 except that the
MIC is computed using AES-128-CMAC instead of HMAC-SHA1).
add a SHA-256 based key derivation function (not used yet).


# 1.48 12-Aug-2008 damien

the only integrity group cipher currently supported is AES-128-CMAC.


# 1.47 12-Aug-2008 damien

extend the ic_nw_keys[] array to 6 elements.
indices 0-3 will be used for group data keys while indices 4-5 will
be used for integrity group keys.
add a ic_rsngroupmgmtcipher field too.


# 1.46 12-Aug-2008 damien

get rid of the map_ptk()/map_gtk() functions, just inline them
which makes things easier to track.


# 1.45 12-Aug-2008 damien

simplify ieee80211_derive_ptk() prototype.
pass the AKMP so we can support other key derivation functions in the
future.


# 1.44 12-Aug-2008 damien

use HMAC-MD5, HMAC-SHA1 and AES Key Wrap sys/crypto/


Revision tags: OPENBSD_4_4_BASE
# 1.43 21-Jul-2008 damien

add ieee80211_priv.h file: contains definitions private to net80211.
this must not be included by drivers.


# 1.42 16-Jun-2008 damien

remove now useless casts since the rijndael_* protos have been
constified.


# 1.41 26-Apr-2008 damien

move things from ieee80211_ifattach() to ieee80211_crypto_attach().


# 1.40 21-Apr-2008 damien

- do not process ethernet PAE frames if RSN is not enabled
- add a ieee80211_recv_action() function (will be used later)
- some cleanup, remove unused prototypes, get rid of the
IEEE80211_VERIFY_* macros


# 1.39 18-Apr-2008 djm

extend the if_ethersubr.c crc functions to support updating a running
crc in addition to the existing "oneshot" mode and use them to replace
ieee80211_crc_update() with the new ether_crc32_le_update(). Saves 1k
kernel bss + some code.

Mark the new ether_crc32_[lb]e_update functions as __pure for a
~25x speedup (on my i386 at least).

feedback and ok damien@


# 1.38 17-Apr-2008 damien

call ieee80211_crc_init() only once, when the first 802.11 device
attaches instead of at every attach.

discussed with deraadt@


# 1.37 16-Apr-2008 damien

Kernel implementation of the 4-way handshake and group-key
handshake protocols (both supplicant and authenticator state
machines) as defined in the IEEE 802.11i standard.

Software implementation of the TKIP (Temporal Key Integrity
Protocol) and CCMP (CTR with CBC-MAC Protocol) protocols.

This diff doesn't implement any of the 802.1X authentication
protocols and thus only PSK authentication (using pre-shared
keys) is currently supported.

In concrete terms, this adds support for WPA-PSK and WPA2-PSK
protocols, both in station and hostap modes.

The following drivers are marked as WPA-capable and should
work: bwi(4), malo(4), ral(4), iwn(4), wpi(4), ural(4),
rum(4), upgt(4), and zyd(4)

The following options have been added to ifconfig(8):
wpa, wpapsk, wpaprotos, wpaakms, wpaciphers, wpagroupcipher

wpa-psk(8) can be used to generate keys from passphrases.

tested by many@
ok deraadt@


Revision tags: OPENBSD_4_3_BASE
# 1.36 11-Sep-2007 damien

remove horrid casts now that SHA1Update() has been constified.


# 1.35 29-Aug-2007 damien

- use ieee80211_get_hdrlen() where appropriate.
- discard all EAPOL-Key frames with an unknown descriptor version.
- when receiving message 3/4 of the 4-way handshake, do not install
the PTK if the INSTALL bit is not set. this fixes 4-way handshake
with APs using group keys only.
- similarly, do not mark the 802.1X port as valid if the SECURE bit
is not set (it will be marked as valid after group key handshake).


# 1.34 23-Aug-2007 damien

fix ieee80211_map_ptk() for TKIP.


# 1.33 22-Aug-2007 damien

add a ieee80211_get_txkey() function to determine the key to use for
transmitting a frame to a given node.
change ieee80211_encrypt() so that it now takes the key as parameter.
this change is required because drivers doing hardware crypto need to
know what key is being used.


# 1.32 22-Aug-2007 damien

- add k_rxmic and k_txmic fields to struct ieee80211_key to store the
Tx/Rx MIC for TKIP.
- add two functions to map a PTK and a GTK to an IEEE 802.11 key and
use them in ieee80211_input.c instead of duplicating the same code.
properly set Tx/Rx MIC in the IEEE 802.11 key in the case of TKIP.
- add ic_psk to struct ieee80211com to store the pre-shared key.
- fix setting of the SECURE bit in outgoing EAPOL-Key frames.
- when receiving msg 2 of the 4-way handshake, deauthenticate the
station if the RSN IE does not match that of the (Re)Association
request.
- before parsing an RSN or WPA IE, check that there's enough room for
the version field (2 bytes) which is mandatory.
- various tweaks while i'm here.


Revision tags: OPENBSD_4_2_BASE
# 1.31 03-Aug-2007 damien

add a ni_eapol_desc field to struct ieee80211_node to know whether
a station is using WPA1 or RSN descriptors.
make sure that a station that advertises WPA1 capability in an IE
uses the WPA1 EAPOL-Key descriptor type and not the RSN one.
fix construction of EAPOL-Key frames for WPA1.
i can now successfuly complete a 4-way and group-key handshake
with both a WPA1 and a WPA2 access point.
add some TKIP encapsulation code (no SW crypto yet).

ok deraadt@


# 1.30 01-Aug-2007 damien

add generic ieee80211_encrypt() and ieee80211_decrypt() functions that
can handle multiple ciphers (the key to use is determined automatically
by these functions based on the frame's destination address).
add ieee80211_ccmp_encrypt() and ieee80211_ccmp_decrypt().
those two functions only do encapsulation/decapsulation of CCMP frames
for now (they don't do SW crypto). they will help to test things with
drivers that can do HW crypto.
add a ni_pairwise_key field to struct ieee80211_node to actually install
the pairwise transient key.
install the GTK in ic_nw_keys[].


# 1.29 01-Aug-2007 damien

group key handshake message 1 is very different between RSN and WPA1.
RSN uses a GTK KDE while WPA1 stores the GTK in the EAPOL-Key frame
data field (encrypted) and uses some bits in the info field.
split ieee80211_recv_group_msg1() in two separate functions.


# 1.28 01-Aug-2007 damien

all WPA implementations i have tested use EAPOL-Key frames version 1,
so use that too and remove a check in ieee80211_recv_eapol().
WPA1 stores the group key id into bits 4-5 of the EAPOL-Key frame info
field and uses bit 6 to indicate if the key is Rx/Tx or Rx only.
remove a check in ieee80211_eapol_key_decrypt() because WPA1 encrypts
the payload of message 1 of the group-key handshake without setting the
encrypted bit in the info field.


# 1.27 01-Aug-2007 damien

the EAPOL-Key MIC must be computed with the MIC bit set.
this simplifies ieee80211_eapol_key_mic() and ieee80211_eapol_key_check_mic()
quite a bit.
set the EAPOL-Key body length before computing the MIC since the MIC is
computed with the 802.1X header too.
add a missing htons() while i'm here.


# 1.26 28-Jul-2007 damien

extend the ieee80211_key structure with a key identifier, a flags field
and a 64-bit receive sequence counter (for group keys).
add a ieee80211_cipher_keylen() function to retrieve the key length
in bytes used by a specific cipher.
account for 802.1X header size when computing the Key MIC.
some cleanup in comments and variable names while i'm here.


# 1.25 24-Jul-2007 damien

new function to check the MIC of a received EAPOL-Key frame.


# 1.24 24-Jul-2007 damien

use rc4_skip().
fix ieee80211_eapol_key_encrypt() so that we don't add more padding
bytes than necessary in the case of AES Key Wrap encryption.


# 1.23 24-Jul-2007 damien

remove some unused key derivation functions.
we won't support PeerKey handshake in a first time.


# 1.22 24-Jul-2007 damien

remove arc4_ compatibility macros.


# 1.21 24-Jul-2007 damien

add functions to compute EAPOL-Key Key MIC fields and to encrypt/decrypt
EAPOL-Key Data fields.


# 1.20 24-Jul-2007 damien

add ic_globalcnt to struct ieee80211com:
in an RSNA, each STA must maintain a 256-bit global key counter that
must be initialized to a random value (see 8.5.7).


# 1.19 18-Jul-2007 damien

modify ieee80211_aes_key_wrap() to support in-place encryption.
explicitly use ovbcopy() even if our kernel memcpy() supports
overlapping buffers.


# 1.18 18-Jul-2007 damien

add AES Key Wrap algorithm (see RFC 3394).
this will be used to encrypt/decrypt EAPOL-Key frames payload.


# 1.17 18-Jul-2007 damien

replace the ieee80211_wepkey structure with a more generic ieee80211_key
one that can be used with other ciphers than WEP.


# 1.16 14-Jul-2007 damien

s/uint8_t/u_int8_t/ for consistency.


# 1.15 14-Jul-2007 damien

update QoS Tx/Rx sequence numbers for each TID.
add a parameter to ieee80211_decap() to handle different 802.11
header sizes.
cleanup and clarify ieee80211_classify().


# 1.14 05-Jul-2007 damien

add myself to the copyright list.


# 1.13 05-Jul-2007 damien

add the pseudo-random function (PRF) and various key derivation
functions defined in 802.11i.


# 1.12 16-Jun-2007 damien

constify


# 1.11 16-Jun-2007 damien

de-static

ok jsg@


# 1.10 06-Jun-2007 damien

The license permits us to redistribute this code under the BSD or the GPLv2.
Choose the BSD license so that future enhancements will be BSD-only.

ok jsg@ reyk@ deraadt@


Revision tags: OPENBSD_4_1_BASE
# 1.9 29-Dec-2006 reyk

fix the key buffer size used for software wep, this could cause
problems with non-standard wep keys >= 104 bits.

thanks to Alexander Bluhm

ok mglocker@ jsg@


Revision tags: OPENBSD_4_0_BASE
# 1.8 18-Jun-2006 damien

Improve 802.11b/g interoperability and move toward better compliance
with IEEE Std 802.11g-2003 standard:

- add ERP Information Element in probe responses and beacons
- keep track of the number of associated non-ERP STAs and non-short slot
time capable STAs in the BSS
- enable use of RTS/CTS or CTS-to-self protection when required by the BSS
- add a ic_updateslot() callback to notify drivers of slot time changes
- cleanup computation of mgmt frames sizes in ieee80211_output.c
- nuke unnecessary <sys/cdefs.h> includes
- remove an unused macro (LOGICALLY_EQUAL) while i'm here

From {free,net}bsd, with additional fixes.

ok brad@, reyk@


Revision tags: OPENBSD_3_9_BASE
# 1.7 08-Sep-2005 reyk

mostly knf

ok jsg@


# 1.6 08-Sep-2005 jsg

Remove the last of the FreeBSD compatiblity goop.
ok reyk@


# 1.5 08-Sep-2005 jsg

Remove FreeBSD if_printf compat function from net80211.
ok reyk@


# 1.4 07-Sep-2005 jsg

Remove FreeBSD/NetBSD ifdef mess. We are not likely to be
doing a wholesale merge with them in future.
very enthusiastic ok from reyk@


Revision tags: OPENBSD_3_6_BASE OPENBSD_3_7_BASE OPENBSD_3_8_BASE
# 1.3 28-Jun-2004 millert

Don't restrict WEP keys to exactly 40 or 108 bits.


# 1.2 27-Jun-2004 millert

Hack to avoid panic in arc4maybeinit() due to rnd device not being
attached yet.


# 1.1 22-Jun-2004 millert

Import current NetBSD/FreeBSD 802.11 framework.
Based in part on a diff from Matthew Gream.


# 1.76 15-May-2020 stsp

Fix CCMP replay check with 11n Rx aggregation and CCMP hardware offloading.

So far, drivers using hardware CCMP decryption were expected to keep the
most recently seen CCMP packet number (PN) up-to-date, and to discard frames
with lower PNs as replays.

A-MPDU subframes may legitimately arrive out of order, and the drivers skipped
CCMP replay checking for such frames. Re-ordering happens in ieee80211_inputm(),
after the driver is done with a frame. Drivers cannot tell replayed frames
apart from legitimate out-of-order retransmissions.

To fix this, update the PN value in ieee80211_inputm() after subframes have
been reordered into their proper sequence. Drivers still perform replay checks
but they no longer have to worry about updating the last seen PN value.

The 802.11 spec confirms that replay checking is supposed to happen after
A-MPDU re-ordering.

Tested by jmc@, benno@, solene@, and myself with the following drivers:
athn(4), iwn(4), iwm(4), wpi(4), urtwn(4)

ok solene@


Revision tags: OPENBSD_6_6_BASE OPENBSD_6_7_BASE
# 1.75 16-Aug-2019 procter

check that software de/encrypt is possible: under hardware
offload, it needn't be. the stack must otherwise rely on every
offloading driver correctly handling all frames governed by a
given key.
ok stsp@


Revision tags: OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.74 24-Sep-2018 stsp

Prevent ieee80211_get_txkey() from returning the integrity group temporal
key (IGTK) if a node doesn't have management frame protection (MFP) enabled.
The IGTK is not initialized if MFP is disabled, so using it triggers this
panic in ieee80211_encrypt(): panic("invalid key cipher 0x%x", k->k_cipher)

(As far as I can tell, at present, MFP is never enabled.)

Problem reported and fix tested by tj@ on athn(4) hostap


# 1.73 28-Apr-2018 stsp

Fix WEP key selection in ieee80211_get_txkey().

The WEP key index is stored in ic_def_txkey. The iGTK ("integrity group key")
index is specific to WPA. The previous code happened to always select WEP key
index 0 since the iGTK index is not yet used by any driver.

ok phessler@


# 1.72 28-Apr-2018 stsp

If ieee80211_encrypt() is passed a key with an unrecognized cipher
type then panic immediately instead of silently dropping packets.

ok phessler@


Revision tags: OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.71 18-Aug-2017 stsp

Clear WPA group keys from memory before initiating a key exchange
with an access point. Prevents false positive 'reused group key'
warnings in dmesg when re-associating to the same access point.
Problem reported by tb@
ok tb@


# 1.70 02-May-2017 mikeb

Switch 802.11 crypto over to the new AES

OK stsp@


Revision tags: OPENBSD_6_1_BASE
# 1.69 23-Mar-2017 tb

branches: 1.69.4;
Use explicit_bzero() to wipe out key material and add some sizes to free().

ok stsp


# 1.68 20-Dec-2016 stsp

Disable TKIP (WPA1) by default.

It is time for this legacy of WEP to die (remember WEP?).
The 802.11-2012 standard says:
The use of TKIP is deprecated. The TKIP algorithm is unsuitable for
the purposes of this standard.

TKIP has numerous problems. One of which is that TKIP allows a denial of
service attack which can be triggered by any client. Report 2 Michael MIC
failures to a TKIP AP to trigger "TKIP countermeasures". The AP is now
required by the 802.11 standard to lock everyone out for at least 60 seconds.
The network will remain unusable for as long as such MIC failure reports
are sent twice per minute.

TKIP remains available for interoperability purposes, for now.
It must be enabled manually with ifconfig(8).

Prompted by discussion with Mathy Vanhoef.
ok deraadt@ sthen@ reyk@


# 1.67 17-Dec-2016 stsp

Complete our half-done implementation of TKIP countermeasures in hostap mode.

The previous code would disable the AP until next reboot upon MIC failure.
Instead, disable the AP for 60 seconds, as required by the 802.11 standard.
I randomly added a bit of time (up to 120 seconds total) just because we can.

Problem reported by Mathy Vanhoef, thanks!
ok deraadt@
random input reyk@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.66 24-Nov-2015 mpi

branches: 1.66.4;
No need to include <net/if_arp.h>

This header is only needed because <netinet/if_ether.h> declares a
structure that needs it. But it turns out that <net/if.h> already
includes it as workaround.

A proper solution would be to stop declarting "struct ether_arp"
there. But no driver should need this header.


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.65 23-Dec-2014 tedu

unifdef some more INET. v4 4life.


# 1.64 18-Nov-2014 tedu

move arc4random prototype to systm.h. more appropriate for most code
to include that than rdnvar.h. ok deraadt dlg


# 1.63 14-Sep-2014 jsg

remove uneeded proc.h includes
ok mpi@ kspillner@


Revision tags: OPENBSD_5_6_BASE
# 1.62 12-Jul-2014 tedu

add a size argument to free. will be used soon, but for now default to 0.
after discussions with beck deraadt kettenis.


Revision tags: OPENBSD_5_5_BASE
# 1.61 21-Nov-2013 mpi

Remove unneeded include.

ok deraadt@


Revision tags: OPENBSD_4_9_BASE OPENBSD_5_0_BASE OPENBSD_5_1_BASE OPENBSD_5_2_BASE OPENBSD_5_3_BASE OPENBSD_5_4_BASE
# 1.60 11-Jan-2011 deraadt

for key material that is being being discarded, convert bzero() to
explicit_bzero() where required
ok markus mikeb


Revision tags: OPENBSD_4_8_BASE
# 1.59 20-Jul-2010 matthew

Switch some obvious network stack MAC comparisons from bcmp() to
timingsafe_bcmp().

ok deraadt@; committed over WPA.


Revision tags: OPENBSD_4_5_BASE OPENBSD_4_6_BASE OPENBSD_4_7_BASE
# 1.58 13-Feb-2009 damien

Change ifconfig wpaakms default setting to `psk' instead of `psk,802.1x'.
Some supplicants will autoselect 802.1X without giving users the
possibility to choose between PSK or 802.1X.

Similarly, no longer announce `PSK with SHA-256 based KDF' AKMP (defined
in Draft 802.11w) by default in the RSN IE of beacons and probe responses
as it confuses some broken supplicants. This kind of sacrifies security
for interoperability with shitty (but unfortunately widespread) clients
that do not follow the 802.11 standard properly.
This fixes associations from Intel PROSet on XP and also reportedly fixes
some Mac OS clients. I will likely make `psk-sha256' configurable through
ifconfig wpaakms after the 4.5 release.


# 1.57 26-Jan-2009 damien

Add some initial HT bits (not enabled yet) based on 802.11n Draft 7.01:
- implement A-MPDU frames buffering and reordering
- implement A-MSDU decapsulation
- process/send ADDBA Request, ADDBA Response and DELBA action frames
- process Block Ack Request control frames (including MTBAR)
- implement PBAC support (Protected Block Ack)
- add some incomplete HT Capabilities and HT Operation IEs parsing

Add more Management Frame Protection bits based on 802.11w Draft 7.0:
- implement SA Query procedure (both AP and STA)
- cleanup BIP

Fix some bugs:
- fix check for WEP key length that otherwise caused a stack smash in
ieee80211_wep_encrypt (pointed out by Xavier Santolaria on macppc)
- properly stop EAPOL timeout: fixes a panic that occured in HostAP mode
when turning the interface down while a 4-way handshake is in progress
(pointed out by Doughertys)

Did some code cleanup too.

The HT bits are currently not compiled in (IEEE80211_NO_HT is defined)
because they won't be ready until after the next release and I didn't
want to grow the kernel or to inadvertently introduce new bugs.
They are here such that other people can look at the code.
Notice that I had to add an extra parameter to ic_send_mgmt() for
action frames, that is why there are small changes in drivers defining
their own ic_send_mgmt() handler.

Sorry for the not very incremental diff but this has been sitting in
my tree for too long now.


# 1.56 27-Sep-2008 damien

Initial implementation of PMKSA caching and pre-authentication.
This will be required for future WPA-Enterprise support (802.1X).
Add ieee80211_needs_auth() function (not implemented yet) to
notify the userland 802.1X PACP machine when an 802.1X port
becomes enabled (that is after successfull 802.11 Open System
authentication).
Add SIOCS80211KEYRUN and SIOCS80211KEYAVAIL ioctls so that the
PACP state machine can kick the 802.11 key state machine and
install PMKs obtained from 802.1X (pre-)authentication.

Enable SHA-256 based AKMPs by default while I'm here (TGw).
This uses SHA-256 for key-derivation (instead of SHA1), AES-128-CMAC
for data integrity, and AES Key Wrap for data protection of EAPOL-Key
frames. An OpenBSD AP will always advertise this capability and an
OpenBSD STA will always prefer SHA-256 based AKMPs over SHA1 based
ones if both are supported by an AP.


# 1.55 27-Aug-2008 damien

introduce new IEEE80211_STA_ONLY kernel option that can be set to
remove IBSS and HostAP support from net80211 and 802.11 drivers.
it can be used to shrink RAMDISK kernels for instance (like what
was done for wi(4)).
it also has the benefit of highlighting what is specific to IBSS
and HostAP modes in the code.
the cost is that we now have two code paths to maintain.


# 1.54 14-Aug-2008 damien

ieee80211_derive_pmkid() is not used either


# 1.53 14-Aug-2008 damien

#ifdef notyet ieee80211_kdf() as it is not used yet (shrink kernel a bit)


# 1.52 12-Aug-2008 damien

add the code to encrypt/decrypt management frames, retrieve key id
from MMIE etc...
this code can't be triggered as no drivers claim MFP capability yet.


# 1.51 12-Aug-2008 damien

missing SHA-256 bits.


# 1.50 12-Aug-2008 damien

new SHA-256 based AKMPs.


# 1.49 12-Aug-2008 damien

add support for EAPOL-Key v3 descriptors (similar to v2 except that the
MIC is computed using AES-128-CMAC instead of HMAC-SHA1).
add a SHA-256 based key derivation function (not used yet).


# 1.48 12-Aug-2008 damien

the only integrity group cipher currently supported is AES-128-CMAC.


# 1.47 12-Aug-2008 damien

extend the ic_nw_keys[] array to 6 elements.
indices 0-3 will be used for group data keys while indices 4-5 will
be used for integrity group keys.
add a ic_rsngroupmgmtcipher field too.


# 1.46 12-Aug-2008 damien

get rid of the map_ptk()/map_gtk() functions, just inline them
which makes things easier to track.


# 1.45 12-Aug-2008 damien

simplify ieee80211_derive_ptk() prototype.
pass the AKMP so we can support other key derivation functions in the
future.


# 1.44 12-Aug-2008 damien

use HMAC-MD5, HMAC-SHA1 and AES Key Wrap sys/crypto/


Revision tags: OPENBSD_4_4_BASE
# 1.43 21-Jul-2008 damien

add ieee80211_priv.h file: contains definitions private to net80211.
this must not be included by drivers.


# 1.42 16-Jun-2008 damien

remove now useless casts since the rijndael_* protos have been
constified.


# 1.41 26-Apr-2008 damien

move things from ieee80211_ifattach() to ieee80211_crypto_attach().


# 1.40 21-Apr-2008 damien

- do not process ethernet PAE frames if RSN is not enabled
- add a ieee80211_recv_action() function (will be used later)
- some cleanup, remove unused prototypes, get rid of the
IEEE80211_VERIFY_* macros


# 1.39 18-Apr-2008 djm

extend the if_ethersubr.c crc functions to support updating a running
crc in addition to the existing "oneshot" mode and use them to replace
ieee80211_crc_update() with the new ether_crc32_le_update(). Saves 1k
kernel bss + some code.

Mark the new ether_crc32_[lb]e_update functions as __pure for a
~25x speedup (on my i386 at least).

feedback and ok damien@


# 1.38 17-Apr-2008 damien

call ieee80211_crc_init() only once, when the first 802.11 device
attaches instead of at every attach.

discussed with deraadt@


# 1.37 16-Apr-2008 damien

Kernel implementation of the 4-way handshake and group-key
handshake protocols (both supplicant and authenticator state
machines) as defined in the IEEE 802.11i standard.

Software implementation of the TKIP (Temporal Key Integrity
Protocol) and CCMP (CTR with CBC-MAC Protocol) protocols.

This diff doesn't implement any of the 802.1X authentication
protocols and thus only PSK authentication (using pre-shared
keys) is currently supported.

In concrete terms, this adds support for WPA-PSK and WPA2-PSK
protocols, both in station and hostap modes.

The following drivers are marked as WPA-capable and should
work: bwi(4), malo(4), ral(4), iwn(4), wpi(4), ural(4),
rum(4), upgt(4), and zyd(4)

The following options have been added to ifconfig(8):
wpa, wpapsk, wpaprotos, wpaakms, wpaciphers, wpagroupcipher

wpa-psk(8) can be used to generate keys from passphrases.

tested by many@
ok deraadt@


Revision tags: OPENBSD_4_3_BASE
# 1.36 11-Sep-2007 damien

remove horrid casts now that SHA1Update() has been constified.


# 1.35 29-Aug-2007 damien

- use ieee80211_get_hdrlen() where appropriate.
- discard all EAPOL-Key frames with an unknown descriptor version.
- when receiving message 3/4 of the 4-way handshake, do not install
the PTK if the INSTALL bit is not set. this fixes 4-way handshake
with APs using group keys only.
- similarly, do not mark the 802.1X port as valid if the SECURE bit
is not set (it will be marked as valid after group key handshake).


# 1.34 23-Aug-2007 damien

fix ieee80211_map_ptk() for TKIP.


# 1.33 22-Aug-2007 damien

add a ieee80211_get_txkey() function to determine the key to use for
transmitting a frame to a given node.
change ieee80211_encrypt() so that it now takes the key as parameter.
this change is required because drivers doing hardware crypto need to
know what key is being used.


# 1.32 22-Aug-2007 damien

- add k_rxmic and k_txmic fields to struct ieee80211_key to store the
Tx/Rx MIC for TKIP.
- add two functions to map a PTK and a GTK to an IEEE 802.11 key and
use them in ieee80211_input.c instead of duplicating the same code.
properly set Tx/Rx MIC in the IEEE 802.11 key in the case of TKIP.
- add ic_psk to struct ieee80211com to store the pre-shared key.
- fix setting of the SECURE bit in outgoing EAPOL-Key frames.
- when receiving msg 2 of the 4-way handshake, deauthenticate the
station if the RSN IE does not match that of the (Re)Association
request.
- before parsing an RSN or WPA IE, check that there's enough room for
the version field (2 bytes) which is mandatory.
- various tweaks while i'm here.


Revision tags: OPENBSD_4_2_BASE
# 1.31 03-Aug-2007 damien

add a ni_eapol_desc field to struct ieee80211_node to know whether
a station is using WPA1 or RSN descriptors.
make sure that a station that advertises WPA1 capability in an IE
uses the WPA1 EAPOL-Key descriptor type and not the RSN one.
fix construction of EAPOL-Key frames for WPA1.
i can now successfuly complete a 4-way and group-key handshake
with both a WPA1 and a WPA2 access point.
add some TKIP encapsulation code (no SW crypto yet).

ok deraadt@


# 1.30 01-Aug-2007 damien

add generic ieee80211_encrypt() and ieee80211_decrypt() functions that
can handle multiple ciphers (the key to use is determined automatically
by these functions based on the frame's destination address).
add ieee80211_ccmp_encrypt() and ieee80211_ccmp_decrypt().
those two functions only do encapsulation/decapsulation of CCMP frames
for now (they don't do SW crypto). they will help to test things with
drivers that can do HW crypto.
add a ni_pairwise_key field to struct ieee80211_node to actually install
the pairwise transient key.
install the GTK in ic_nw_keys[].


# 1.29 01-Aug-2007 damien

group key handshake message 1 is very different between RSN and WPA1.
RSN uses a GTK KDE while WPA1 stores the GTK in the EAPOL-Key frame
data field (encrypted) and uses some bits in the info field.
split ieee80211_recv_group_msg1() in two separate functions.


# 1.28 01-Aug-2007 damien

all WPA implementations i have tested use EAPOL-Key frames version 1,
so use that too and remove a check in ieee80211_recv_eapol().
WPA1 stores the group key id into bits 4-5 of the EAPOL-Key frame info
field and uses bit 6 to indicate if the key is Rx/Tx or Rx only.
remove a check in ieee80211_eapol_key_decrypt() because WPA1 encrypts
the payload of message 1 of the group-key handshake without setting the
encrypted bit in the info field.


# 1.27 01-Aug-2007 damien

the EAPOL-Key MIC must be computed with the MIC bit set.
this simplifies ieee80211_eapol_key_mic() and ieee80211_eapol_key_check_mic()
quite a bit.
set the EAPOL-Key body length before computing the MIC since the MIC is
computed with the 802.1X header too.
add a missing htons() while i'm here.


# 1.26 28-Jul-2007 damien

extend the ieee80211_key structure with a key identifier, a flags field
and a 64-bit receive sequence counter (for group keys).
add a ieee80211_cipher_keylen() function to retrieve the key length
in bytes used by a specific cipher.
account for 802.1X header size when computing the Key MIC.
some cleanup in comments and variable names while i'm here.


# 1.25 24-Jul-2007 damien

new function to check the MIC of a received EAPOL-Key frame.


# 1.24 24-Jul-2007 damien

use rc4_skip().
fix ieee80211_eapol_key_encrypt() so that we don't add more padding
bytes than necessary in the case of AES Key Wrap encryption.


# 1.23 24-Jul-2007 damien

remove some unused key derivation functions.
we won't support PeerKey handshake in a first time.


# 1.22 24-Jul-2007 damien

remove arc4_ compatibility macros.


# 1.21 24-Jul-2007 damien

add functions to compute EAPOL-Key Key MIC fields and to encrypt/decrypt
EAPOL-Key Data fields.


# 1.20 24-Jul-2007 damien

add ic_globalcnt to struct ieee80211com:
in an RSNA, each STA must maintain a 256-bit global key counter that
must be initialized to a random value (see 8.5.7).


# 1.19 18-Jul-2007 damien

modify ieee80211_aes_key_wrap() to support in-place encryption.
explicitly use ovbcopy() even if our kernel memcpy() supports
overlapping buffers.


# 1.18 18-Jul-2007 damien

add AES Key Wrap algorithm (see RFC 3394).
this will be used to encrypt/decrypt EAPOL-Key frames payload.


# 1.17 18-Jul-2007 damien

replace the ieee80211_wepkey structure with a more generic ieee80211_key
one that can be used with other ciphers than WEP.


# 1.16 14-Jul-2007 damien

s/uint8_t/u_int8_t/ for consistency.


# 1.15 14-Jul-2007 damien

update QoS Tx/Rx sequence numbers for each TID.
add a parameter to ieee80211_decap() to handle different 802.11
header sizes.
cleanup and clarify ieee80211_classify().


# 1.14 05-Jul-2007 damien

add myself to the copyright list.


# 1.13 05-Jul-2007 damien

add the pseudo-random function (PRF) and various key derivation
functions defined in 802.11i.


# 1.12 16-Jun-2007 damien

constify


# 1.11 16-Jun-2007 damien

de-static

ok jsg@


# 1.10 06-Jun-2007 damien

The license permits us to redistribute this code under the BSD or the GPLv2.
Choose the BSD license so that future enhancements will be BSD-only.

ok jsg@ reyk@ deraadt@


Revision tags: OPENBSD_4_1_BASE
# 1.9 29-Dec-2006 reyk

fix the key buffer size used for software wep, this could cause
problems with non-standard wep keys >= 104 bits.

thanks to Alexander Bluhm

ok mglocker@ jsg@


Revision tags: OPENBSD_4_0_BASE
# 1.8 18-Jun-2006 damien

Improve 802.11b/g interoperability and move toward better compliance
with IEEE Std 802.11g-2003 standard:

- add ERP Information Element in probe responses and beacons
- keep track of the number of associated non-ERP STAs and non-short slot
time capable STAs in the BSS
- enable use of RTS/CTS or CTS-to-self protection when required by the BSS
- add a ic_updateslot() callback to notify drivers of slot time changes
- cleanup computation of mgmt frames sizes in ieee80211_output.c
- nuke unnecessary <sys/cdefs.h> includes
- remove an unused macro (LOGICALLY_EQUAL) while i'm here

From {free,net}bsd, with additional fixes.

ok brad@, reyk@


Revision tags: OPENBSD_3_9_BASE
# 1.7 08-Sep-2005 reyk

mostly knf

ok jsg@


# 1.6 08-Sep-2005 jsg

Remove the last of the FreeBSD compatiblity goop.
ok reyk@


# 1.5 08-Sep-2005 jsg

Remove FreeBSD if_printf compat function from net80211.
ok reyk@


# 1.4 07-Sep-2005 jsg

Remove FreeBSD/NetBSD ifdef mess. We are not likely to be
doing a wholesale merge with them in future.
very enthusiastic ok from reyk@


Revision tags: OPENBSD_3_6_BASE OPENBSD_3_7_BASE OPENBSD_3_8_BASE
# 1.3 28-Jun-2004 millert

Don't restrict WEP keys to exactly 40 or 108 bits.


# 1.2 27-Jun-2004 millert

Hack to avoid panic in arc4maybeinit() due to rnd device not being
attached yet.


# 1.1 22-Jun-2004 millert

Import current NetBSD/FreeBSD 802.11 framework.
Based in part on a diff from Matthew Gream.


# 1.75 16-Aug-2019 procter

check that software de/encrypt is possible: under hardware
offload, it needn't be. the stack must otherwise rely on every
offloading driver correctly handling all frames governed by a
given key.
ok stsp@


Revision tags: OPENBSD_6_4_BASE OPENBSD_6_5_BASE
# 1.74 24-Sep-2018 stsp

Prevent ieee80211_get_txkey() from returning the integrity group temporal
key (IGTK) if a node doesn't have management frame protection (MFP) enabled.
The IGTK is not initialized if MFP is disabled, so using it triggers this
panic in ieee80211_encrypt(): panic("invalid key cipher 0x%x", k->k_cipher)

(As far as I can tell, at present, MFP is never enabled.)

Problem reported and fix tested by tj@ on athn(4) hostap


# 1.73 28-Apr-2018 stsp

Fix WEP key selection in ieee80211_get_txkey().

The WEP key index is stored in ic_def_txkey. The iGTK ("integrity group key")
index is specific to WPA. The previous code happened to always select WEP key
index 0 since the iGTK index is not yet used by any driver.

ok phessler@


# 1.72 28-Apr-2018 stsp

If ieee80211_encrypt() is passed a key with an unrecognized cipher
type then panic immediately instead of silently dropping packets.

ok phessler@


Revision tags: OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.71 18-Aug-2017 stsp

Clear WPA group keys from memory before initiating a key exchange
with an access point. Prevents false positive 'reused group key'
warnings in dmesg when re-associating to the same access point.
Problem reported by tb@
ok tb@


# 1.70 02-May-2017 mikeb

Switch 802.11 crypto over to the new AES

OK stsp@


Revision tags: OPENBSD_6_1_BASE
# 1.69 23-Mar-2017 tb

branches: 1.69.4;
Use explicit_bzero() to wipe out key material and add some sizes to free().

ok stsp


# 1.68 20-Dec-2016 stsp

Disable TKIP (WPA1) by default.

It is time for this legacy of WEP to die (remember WEP?).
The 802.11-2012 standard says:
The use of TKIP is deprecated. The TKIP algorithm is unsuitable for
the purposes of this standard.

TKIP has numerous problems. One of which is that TKIP allows a denial of
service attack which can be triggered by any client. Report 2 Michael MIC
failures to a TKIP AP to trigger "TKIP countermeasures". The AP is now
required by the 802.11 standard to lock everyone out for at least 60 seconds.
The network will remain unusable for as long as such MIC failure reports
are sent twice per minute.

TKIP remains available for interoperability purposes, for now.
It must be enabled manually with ifconfig(8).

Prompted by discussion with Mathy Vanhoef.
ok deraadt@ sthen@ reyk@


# 1.67 17-Dec-2016 stsp

Complete our half-done implementation of TKIP countermeasures in hostap mode.

The previous code would disable the AP until next reboot upon MIC failure.
Instead, disable the AP for 60 seconds, as required by the 802.11 standard.
I randomly added a bit of time (up to 120 seconds total) just because we can.

Problem reported by Mathy Vanhoef, thanks!
ok deraadt@
random input reyk@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.66 24-Nov-2015 mpi

branches: 1.66.4;
No need to include <net/if_arp.h>

This header is only needed because <netinet/if_ether.h> declares a
structure that needs it. But it turns out that <net/if.h> already
includes it as workaround.

A proper solution would be to stop declarting "struct ether_arp"
there. But no driver should need this header.


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.65 23-Dec-2014 tedu

unifdef some more INET. v4 4life.


# 1.64 18-Nov-2014 tedu

move arc4random prototype to systm.h. more appropriate for most code
to include that than rdnvar.h. ok deraadt dlg


# 1.63 14-Sep-2014 jsg

remove uneeded proc.h includes
ok mpi@ kspillner@


Revision tags: OPENBSD_5_6_BASE
# 1.62 12-Jul-2014 tedu

add a size argument to free. will be used soon, but for now default to 0.
after discussions with beck deraadt kettenis.


Revision tags: OPENBSD_5_5_BASE
# 1.61 21-Nov-2013 mpi

Remove unneeded include.

ok deraadt@


Revision tags: OPENBSD_4_9_BASE OPENBSD_5_0_BASE OPENBSD_5_1_BASE OPENBSD_5_2_BASE OPENBSD_5_3_BASE OPENBSD_5_4_BASE
# 1.60 11-Jan-2011 deraadt

for key material that is being being discarded, convert bzero() to
explicit_bzero() where required
ok markus mikeb


Revision tags: OPENBSD_4_8_BASE
# 1.59 20-Jul-2010 matthew

Switch some obvious network stack MAC comparisons from bcmp() to
timingsafe_bcmp().

ok deraadt@; committed over WPA.


Revision tags: OPENBSD_4_5_BASE OPENBSD_4_6_BASE OPENBSD_4_7_BASE
# 1.58 13-Feb-2009 damien

Change ifconfig wpaakms default setting to `psk' instead of `psk,802.1x'.
Some supplicants will autoselect 802.1X without giving users the
possibility to choose between PSK or 802.1X.

Similarly, no longer announce `PSK with SHA-256 based KDF' AKMP (defined
in Draft 802.11w) by default in the RSN IE of beacons and probe responses
as it confuses some broken supplicants. This kind of sacrifies security
for interoperability with shitty (but unfortunately widespread) clients
that do not follow the 802.11 standard properly.
This fixes associations from Intel PROSet on XP and also reportedly fixes
some Mac OS clients. I will likely make `psk-sha256' configurable through
ifconfig wpaakms after the 4.5 release.


# 1.57 26-Jan-2009 damien

Add some initial HT bits (not enabled yet) based on 802.11n Draft 7.01:
- implement A-MPDU frames buffering and reordering
- implement A-MSDU decapsulation
- process/send ADDBA Request, ADDBA Response and DELBA action frames
- process Block Ack Request control frames (including MTBAR)
- implement PBAC support (Protected Block Ack)
- add some incomplete HT Capabilities and HT Operation IEs parsing

Add more Management Frame Protection bits based on 802.11w Draft 7.0:
- implement SA Query procedure (both AP and STA)
- cleanup BIP

Fix some bugs:
- fix check for WEP key length that otherwise caused a stack smash in
ieee80211_wep_encrypt (pointed out by Xavier Santolaria on macppc)
- properly stop EAPOL timeout: fixes a panic that occured in HostAP mode
when turning the interface down while a 4-way handshake is in progress
(pointed out by Doughertys)

Did some code cleanup too.

The HT bits are currently not compiled in (IEEE80211_NO_HT is defined)
because they won't be ready until after the next release and I didn't
want to grow the kernel or to inadvertently introduce new bugs.
They are here such that other people can look at the code.
Notice that I had to add an extra parameter to ic_send_mgmt() for
action frames, that is why there are small changes in drivers defining
their own ic_send_mgmt() handler.

Sorry for the not very incremental diff but this has been sitting in
my tree for too long now.


# 1.56 27-Sep-2008 damien

Initial implementation of PMKSA caching and pre-authentication.
This will be required for future WPA-Enterprise support (802.1X).
Add ieee80211_needs_auth() function (not implemented yet) to
notify the userland 802.1X PACP machine when an 802.1X port
becomes enabled (that is after successfull 802.11 Open System
authentication).
Add SIOCS80211KEYRUN and SIOCS80211KEYAVAIL ioctls so that the
PACP state machine can kick the 802.11 key state machine and
install PMKs obtained from 802.1X (pre-)authentication.

Enable SHA-256 based AKMPs by default while I'm here (TGw).
This uses SHA-256 for key-derivation (instead of SHA1), AES-128-CMAC
for data integrity, and AES Key Wrap for data protection of EAPOL-Key
frames. An OpenBSD AP will always advertise this capability and an
OpenBSD STA will always prefer SHA-256 based AKMPs over SHA1 based
ones if both are supported by an AP.


# 1.55 27-Aug-2008 damien

introduce new IEEE80211_STA_ONLY kernel option that can be set to
remove IBSS and HostAP support from net80211 and 802.11 drivers.
it can be used to shrink RAMDISK kernels for instance (like what
was done for wi(4)).
it also has the benefit of highlighting what is specific to IBSS
and HostAP modes in the code.
the cost is that we now have two code paths to maintain.


# 1.54 14-Aug-2008 damien

ieee80211_derive_pmkid() is not used either


# 1.53 14-Aug-2008 damien

#ifdef notyet ieee80211_kdf() as it is not used yet (shrink kernel a bit)


# 1.52 12-Aug-2008 damien

add the code to encrypt/decrypt management frames, retrieve key id
from MMIE etc...
this code can't be triggered as no drivers claim MFP capability yet.


# 1.51 12-Aug-2008 damien

missing SHA-256 bits.


# 1.50 12-Aug-2008 damien

new SHA-256 based AKMPs.


# 1.49 12-Aug-2008 damien

add support for EAPOL-Key v3 descriptors (similar to v2 except that the
MIC is computed using AES-128-CMAC instead of HMAC-SHA1).
add a SHA-256 based key derivation function (not used yet).


# 1.48 12-Aug-2008 damien

the only integrity group cipher currently supported is AES-128-CMAC.


# 1.47 12-Aug-2008 damien

extend the ic_nw_keys[] array to 6 elements.
indices 0-3 will be used for group data keys while indices 4-5 will
be used for integrity group keys.
add a ic_rsngroupmgmtcipher field too.


# 1.46 12-Aug-2008 damien

get rid of the map_ptk()/map_gtk() functions, just inline them
which makes things easier to track.


# 1.45 12-Aug-2008 damien

simplify ieee80211_derive_ptk() prototype.
pass the AKMP so we can support other key derivation functions in the
future.


# 1.44 12-Aug-2008 damien

use HMAC-MD5, HMAC-SHA1 and AES Key Wrap sys/crypto/


Revision tags: OPENBSD_4_4_BASE
# 1.43 21-Jul-2008 damien

add ieee80211_priv.h file: contains definitions private to net80211.
this must not be included by drivers.


# 1.42 16-Jun-2008 damien

remove now useless casts since the rijndael_* protos have been
constified.


# 1.41 26-Apr-2008 damien

move things from ieee80211_ifattach() to ieee80211_crypto_attach().


# 1.40 21-Apr-2008 damien

- do not process ethernet PAE frames if RSN is not enabled
- add a ieee80211_recv_action() function (will be used later)
- some cleanup, remove unused prototypes, get rid of the
IEEE80211_VERIFY_* macros


# 1.39 18-Apr-2008 djm

extend the if_ethersubr.c crc functions to support updating a running
crc in addition to the existing "oneshot" mode and use them to replace
ieee80211_crc_update() with the new ether_crc32_le_update(). Saves 1k
kernel bss + some code.

Mark the new ether_crc32_[lb]e_update functions as __pure for a
~25x speedup (on my i386 at least).

feedback and ok damien@


# 1.38 17-Apr-2008 damien

call ieee80211_crc_init() only once, when the first 802.11 device
attaches instead of at every attach.

discussed with deraadt@


# 1.37 16-Apr-2008 damien

Kernel implementation of the 4-way handshake and group-key
handshake protocols (both supplicant and authenticator state
machines) as defined in the IEEE 802.11i standard.

Software implementation of the TKIP (Temporal Key Integrity
Protocol) and CCMP (CTR with CBC-MAC Protocol) protocols.

This diff doesn't implement any of the 802.1X authentication
protocols and thus only PSK authentication (using pre-shared
keys) is currently supported.

In concrete terms, this adds support for WPA-PSK and WPA2-PSK
protocols, both in station and hostap modes.

The following drivers are marked as WPA-capable and should
work: bwi(4), malo(4), ral(4), iwn(4), wpi(4), ural(4),
rum(4), upgt(4), and zyd(4)

The following options have been added to ifconfig(8):
wpa, wpapsk, wpaprotos, wpaakms, wpaciphers, wpagroupcipher

wpa-psk(8) can be used to generate keys from passphrases.

tested by many@
ok deraadt@


Revision tags: OPENBSD_4_3_BASE
# 1.36 11-Sep-2007 damien

remove horrid casts now that SHA1Update() has been constified.


# 1.35 29-Aug-2007 damien

- use ieee80211_get_hdrlen() where appropriate.
- discard all EAPOL-Key frames with an unknown descriptor version.
- when receiving message 3/4 of the 4-way handshake, do not install
the PTK if the INSTALL bit is not set. this fixes 4-way handshake
with APs using group keys only.
- similarly, do not mark the 802.1X port as valid if the SECURE bit
is not set (it will be marked as valid after group key handshake).


# 1.34 23-Aug-2007 damien

fix ieee80211_map_ptk() for TKIP.


# 1.33 22-Aug-2007 damien

add a ieee80211_get_txkey() function to determine the key to use for
transmitting a frame to a given node.
change ieee80211_encrypt() so that it now takes the key as parameter.
this change is required because drivers doing hardware crypto need to
know what key is being used.


# 1.32 22-Aug-2007 damien

- add k_rxmic and k_txmic fields to struct ieee80211_key to store the
Tx/Rx MIC for TKIP.
- add two functions to map a PTK and a GTK to an IEEE 802.11 key and
use them in ieee80211_input.c instead of duplicating the same code.
properly set Tx/Rx MIC in the IEEE 802.11 key in the case of TKIP.
- add ic_psk to struct ieee80211com to store the pre-shared key.
- fix setting of the SECURE bit in outgoing EAPOL-Key frames.
- when receiving msg 2 of the 4-way handshake, deauthenticate the
station if the RSN IE does not match that of the (Re)Association
request.
- before parsing an RSN or WPA IE, check that there's enough room for
the version field (2 bytes) which is mandatory.
- various tweaks while i'm here.


Revision tags: OPENBSD_4_2_BASE
# 1.31 03-Aug-2007 damien

add a ni_eapol_desc field to struct ieee80211_node to know whether
a station is using WPA1 or RSN descriptors.
make sure that a station that advertises WPA1 capability in an IE
uses the WPA1 EAPOL-Key descriptor type and not the RSN one.
fix construction of EAPOL-Key frames for WPA1.
i can now successfuly complete a 4-way and group-key handshake
with both a WPA1 and a WPA2 access point.
add some TKIP encapsulation code (no SW crypto yet).

ok deraadt@


# 1.30 01-Aug-2007 damien

add generic ieee80211_encrypt() and ieee80211_decrypt() functions that
can handle multiple ciphers (the key to use is determined automatically
by these functions based on the frame's destination address).
add ieee80211_ccmp_encrypt() and ieee80211_ccmp_decrypt().
those two functions only do encapsulation/decapsulation of CCMP frames
for now (they don't do SW crypto). they will help to test things with
drivers that can do HW crypto.
add a ni_pairwise_key field to struct ieee80211_node to actually install
the pairwise transient key.
install the GTK in ic_nw_keys[].


# 1.29 01-Aug-2007 damien

group key handshake message 1 is very different between RSN and WPA1.
RSN uses a GTK KDE while WPA1 stores the GTK in the EAPOL-Key frame
data field (encrypted) and uses some bits in the info field.
split ieee80211_recv_group_msg1() in two separate functions.


# 1.28 01-Aug-2007 damien

all WPA implementations i have tested use EAPOL-Key frames version 1,
so use that too and remove a check in ieee80211_recv_eapol().
WPA1 stores the group key id into bits 4-5 of the EAPOL-Key frame info
field and uses bit 6 to indicate if the key is Rx/Tx or Rx only.
remove a check in ieee80211_eapol_key_decrypt() because WPA1 encrypts
the payload of message 1 of the group-key handshake without setting the
encrypted bit in the info field.


# 1.27 01-Aug-2007 damien

the EAPOL-Key MIC must be computed with the MIC bit set.
this simplifies ieee80211_eapol_key_mic() and ieee80211_eapol_key_check_mic()
quite a bit.
set the EAPOL-Key body length before computing the MIC since the MIC is
computed with the 802.1X header too.
add a missing htons() while i'm here.


# 1.26 28-Jul-2007 damien

extend the ieee80211_key structure with a key identifier, a flags field
and a 64-bit receive sequence counter (for group keys).
add a ieee80211_cipher_keylen() function to retrieve the key length
in bytes used by a specific cipher.
account for 802.1X header size when computing the Key MIC.
some cleanup in comments and variable names while i'm here.


# 1.25 24-Jul-2007 damien

new function to check the MIC of a received EAPOL-Key frame.


# 1.24 24-Jul-2007 damien

use rc4_skip().
fix ieee80211_eapol_key_encrypt() so that we don't add more padding
bytes than necessary in the case of AES Key Wrap encryption.


# 1.23 24-Jul-2007 damien

remove some unused key derivation functions.
we won't support PeerKey handshake in a first time.


# 1.22 24-Jul-2007 damien

remove arc4_ compatibility macros.


# 1.21 24-Jul-2007 damien

add functions to compute EAPOL-Key Key MIC fields and to encrypt/decrypt
EAPOL-Key Data fields.


# 1.20 24-Jul-2007 damien

add ic_globalcnt to struct ieee80211com:
in an RSNA, each STA must maintain a 256-bit global key counter that
must be initialized to a random value (see 8.5.7).


# 1.19 18-Jul-2007 damien

modify ieee80211_aes_key_wrap() to support in-place encryption.
explicitly use ovbcopy() even if our kernel memcpy() supports
overlapping buffers.


# 1.18 18-Jul-2007 damien

add AES Key Wrap algorithm (see RFC 3394).
this will be used to encrypt/decrypt EAPOL-Key frames payload.


# 1.17 18-Jul-2007 damien

replace the ieee80211_wepkey structure with a more generic ieee80211_key
one that can be used with other ciphers than WEP.


# 1.16 14-Jul-2007 damien

s/uint8_t/u_int8_t/ for consistency.


# 1.15 14-Jul-2007 damien

update QoS Tx/Rx sequence numbers for each TID.
add a parameter to ieee80211_decap() to handle different 802.11
header sizes.
cleanup and clarify ieee80211_classify().


# 1.14 05-Jul-2007 damien

add myself to the copyright list.


# 1.13 05-Jul-2007 damien

add the pseudo-random function (PRF) and various key derivation
functions defined in 802.11i.


# 1.12 16-Jun-2007 damien

constify


# 1.11 16-Jun-2007 damien

de-static

ok jsg@


# 1.10 06-Jun-2007 damien

The license permits us to redistribute this code under the BSD or the GPLv2.
Choose the BSD license so that future enhancements will be BSD-only.

ok jsg@ reyk@ deraadt@


Revision tags: OPENBSD_4_1_BASE
# 1.9 29-Dec-2006 reyk

fix the key buffer size used for software wep, this could cause
problems with non-standard wep keys >= 104 bits.

thanks to Alexander Bluhm

ok mglocker@ jsg@


Revision tags: OPENBSD_4_0_BASE
# 1.8 18-Jun-2006 damien

Improve 802.11b/g interoperability and move toward better compliance
with IEEE Std 802.11g-2003 standard:

- add ERP Information Element in probe responses and beacons
- keep track of the number of associated non-ERP STAs and non-short slot
time capable STAs in the BSS
- enable use of RTS/CTS or CTS-to-self protection when required by the BSS
- add a ic_updateslot() callback to notify drivers of slot time changes
- cleanup computation of mgmt frames sizes in ieee80211_output.c
- nuke unnecessary <sys/cdefs.h> includes
- remove an unused macro (LOGICALLY_EQUAL) while i'm here

From {free,net}bsd, with additional fixes.

ok brad@, reyk@


Revision tags: OPENBSD_3_9_BASE
# 1.7 08-Sep-2005 reyk

mostly knf

ok jsg@


# 1.6 08-Sep-2005 jsg

Remove the last of the FreeBSD compatiblity goop.
ok reyk@


# 1.5 08-Sep-2005 jsg

Remove FreeBSD if_printf compat function from net80211.
ok reyk@


# 1.4 07-Sep-2005 jsg

Remove FreeBSD/NetBSD ifdef mess. We are not likely to be
doing a wholesale merge with them in future.
very enthusiastic ok from reyk@


Revision tags: OPENBSD_3_6_BASE OPENBSD_3_7_BASE OPENBSD_3_8_BASE
# 1.3 28-Jun-2004 millert

Don't restrict WEP keys to exactly 40 or 108 bits.


# 1.2 27-Jun-2004 millert

Hack to avoid panic in arc4maybeinit() due to rnd device not being
attached yet.


# 1.1 22-Jun-2004 millert

Import current NetBSD/FreeBSD 802.11 framework.
Based in part on a diff from Matthew Gream.


# 1.74 24-Sep-2018 stsp

Prevent ieee80211_get_txkey() from returning the integrity group temporal
key (IGTK) if a node doesn't have management frame protection (MFP) enabled.
The IGTK is not initialized if MFP is disabled, so using it triggers this
panic in ieee80211_encrypt(): panic("invalid key cipher 0x%x", k->k_cipher)

(As far as I can tell, at present, MFP is never enabled.)

Problem reported and fix tested by tj@ on athn(4) hostap


# 1.73 28-Apr-2018 stsp

Fix WEP key selection in ieee80211_get_txkey().

The WEP key index is stored in ic_def_txkey. The iGTK ("integrity group key")
index is specific to WPA. The previous code happened to always select WEP key
index 0 since the iGTK index is not yet used by any driver.

ok phessler@


# 1.72 28-Apr-2018 stsp

If ieee80211_encrypt() is passed a key with an unrecognized cipher
type then panic immediately instead of silently dropping packets.

ok phessler@


Revision tags: OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.71 18-Aug-2017 stsp

Clear WPA group keys from memory before initiating a key exchange
with an access point. Prevents false positive 'reused group key'
warnings in dmesg when re-associating to the same access point.
Problem reported by tb@
ok tb@


# 1.70 02-May-2017 mikeb

Switch 802.11 crypto over to the new AES

OK stsp@


Revision tags: OPENBSD_6_1_BASE
# 1.69 23-Mar-2017 tb

branches: 1.69.4;
Use explicit_bzero() to wipe out key material and add some sizes to free().

ok stsp


# 1.68 20-Dec-2016 stsp

Disable TKIP (WPA1) by default.

It is time for this legacy of WEP to die (remember WEP?).
The 802.11-2012 standard says:
The use of TKIP is deprecated. The TKIP algorithm is unsuitable for
the purposes of this standard.

TKIP has numerous problems. One of which is that TKIP allows a denial of
service attack which can be triggered by any client. Report 2 Michael MIC
failures to a TKIP AP to trigger "TKIP countermeasures". The AP is now
required by the 802.11 standard to lock everyone out for at least 60 seconds.
The network will remain unusable for as long as such MIC failure reports
are sent twice per minute.

TKIP remains available for interoperability purposes, for now.
It must be enabled manually with ifconfig(8).

Prompted by discussion with Mathy Vanhoef.
ok deraadt@ sthen@ reyk@


# 1.67 17-Dec-2016 stsp

Complete our half-done implementation of TKIP countermeasures in hostap mode.

The previous code would disable the AP until next reboot upon MIC failure.
Instead, disable the AP for 60 seconds, as required by the 802.11 standard.
I randomly added a bit of time (up to 120 seconds total) just because we can.

Problem reported by Mathy Vanhoef, thanks!
ok deraadt@
random input reyk@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.66 24-Nov-2015 mpi

branches: 1.66.4;
No need to include <net/if_arp.h>

This header is only needed because <netinet/if_ether.h> declares a
structure that needs it. But it turns out that <net/if.h> already
includes it as workaround.

A proper solution would be to stop declarting "struct ether_arp"
there. But no driver should need this header.


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.65 23-Dec-2014 tedu

unifdef some more INET. v4 4life.


# 1.64 18-Nov-2014 tedu

move arc4random prototype to systm.h. more appropriate for most code
to include that than rdnvar.h. ok deraadt dlg


# 1.63 14-Sep-2014 jsg

remove uneeded proc.h includes
ok mpi@ kspillner@


Revision tags: OPENBSD_5_6_BASE
# 1.62 12-Jul-2014 tedu

add a size argument to free. will be used soon, but for now default to 0.
after discussions with beck deraadt kettenis.


Revision tags: OPENBSD_5_5_BASE
# 1.61 21-Nov-2013 mpi

Remove unneeded include.

ok deraadt@


Revision tags: OPENBSD_4_9_BASE OPENBSD_5_0_BASE OPENBSD_5_1_BASE OPENBSD_5_2_BASE OPENBSD_5_3_BASE OPENBSD_5_4_BASE
# 1.60 11-Jan-2011 deraadt

for key material that is being being discarded, convert bzero() to
explicit_bzero() where required
ok markus mikeb


Revision tags: OPENBSD_4_8_BASE
# 1.59 20-Jul-2010 matthew

Switch some obvious network stack MAC comparisons from bcmp() to
timingsafe_bcmp().

ok deraadt@; committed over WPA.


Revision tags: OPENBSD_4_5_BASE OPENBSD_4_6_BASE OPENBSD_4_7_BASE
# 1.58 13-Feb-2009 damien

Change ifconfig wpaakms default setting to `psk' instead of `psk,802.1x'.
Some supplicants will autoselect 802.1X without giving users the
possibility to choose between PSK or 802.1X.

Similarly, no longer announce `PSK with SHA-256 based KDF' AKMP (defined
in Draft 802.11w) by default in the RSN IE of beacons and probe responses
as it confuses some broken supplicants. This kind of sacrifies security
for interoperability with shitty (but unfortunately widespread) clients
that do not follow the 802.11 standard properly.
This fixes associations from Intel PROSet on XP and also reportedly fixes
some Mac OS clients. I will likely make `psk-sha256' configurable through
ifconfig wpaakms after the 4.5 release.


# 1.57 26-Jan-2009 damien

Add some initial HT bits (not enabled yet) based on 802.11n Draft 7.01:
- implement A-MPDU frames buffering and reordering
- implement A-MSDU decapsulation
- process/send ADDBA Request, ADDBA Response and DELBA action frames
- process Block Ack Request control frames (including MTBAR)
- implement PBAC support (Protected Block Ack)
- add some incomplete HT Capabilities and HT Operation IEs parsing

Add more Management Frame Protection bits based on 802.11w Draft 7.0:
- implement SA Query procedure (both AP and STA)
- cleanup BIP

Fix some bugs:
- fix check for WEP key length that otherwise caused a stack smash in
ieee80211_wep_encrypt (pointed out by Xavier Santolaria on macppc)
- properly stop EAPOL timeout: fixes a panic that occured in HostAP mode
when turning the interface down while a 4-way handshake is in progress
(pointed out by Doughertys)

Did some code cleanup too.

The HT bits are currently not compiled in (IEEE80211_NO_HT is defined)
because they won't be ready until after the next release and I didn't
want to grow the kernel or to inadvertently introduce new bugs.
They are here such that other people can look at the code.
Notice that I had to add an extra parameter to ic_send_mgmt() for
action frames, that is why there are small changes in drivers defining
their own ic_send_mgmt() handler.

Sorry for the not very incremental diff but this has been sitting in
my tree for too long now.


# 1.56 27-Sep-2008 damien

Initial implementation of PMKSA caching and pre-authentication.
This will be required for future WPA-Enterprise support (802.1X).
Add ieee80211_needs_auth() function (not implemented yet) to
notify the userland 802.1X PACP machine when an 802.1X port
becomes enabled (that is after successfull 802.11 Open System
authentication).
Add SIOCS80211KEYRUN and SIOCS80211KEYAVAIL ioctls so that the
PACP state machine can kick the 802.11 key state machine and
install PMKs obtained from 802.1X (pre-)authentication.

Enable SHA-256 based AKMPs by default while I'm here (TGw).
This uses SHA-256 for key-derivation (instead of SHA1), AES-128-CMAC
for data integrity, and AES Key Wrap for data protection of EAPOL-Key
frames. An OpenBSD AP will always advertise this capability and an
OpenBSD STA will always prefer SHA-256 based AKMPs over SHA1 based
ones if both are supported by an AP.


# 1.55 27-Aug-2008 damien

introduce new IEEE80211_STA_ONLY kernel option that can be set to
remove IBSS and HostAP support from net80211 and 802.11 drivers.
it can be used to shrink RAMDISK kernels for instance (like what
was done for wi(4)).
it also has the benefit of highlighting what is specific to IBSS
and HostAP modes in the code.
the cost is that we now have two code paths to maintain.


# 1.54 14-Aug-2008 damien

ieee80211_derive_pmkid() is not used either


# 1.53 14-Aug-2008 damien

#ifdef notyet ieee80211_kdf() as it is not used yet (shrink kernel a bit)


# 1.52 12-Aug-2008 damien

add the code to encrypt/decrypt management frames, retrieve key id
from MMIE etc...
this code can't be triggered as no drivers claim MFP capability yet.


# 1.51 12-Aug-2008 damien

missing SHA-256 bits.


# 1.50 12-Aug-2008 damien

new SHA-256 based AKMPs.


# 1.49 12-Aug-2008 damien

add support for EAPOL-Key v3 descriptors (similar to v2 except that the
MIC is computed using AES-128-CMAC instead of HMAC-SHA1).
add a SHA-256 based key derivation function (not used yet).


# 1.48 12-Aug-2008 damien

the only integrity group cipher currently supported is AES-128-CMAC.


# 1.47 12-Aug-2008 damien

extend the ic_nw_keys[] array to 6 elements.
indices 0-3 will be used for group data keys while indices 4-5 will
be used for integrity group keys.
add a ic_rsngroupmgmtcipher field too.


# 1.46 12-Aug-2008 damien

get rid of the map_ptk()/map_gtk() functions, just inline them
which makes things easier to track.


# 1.45 12-Aug-2008 damien

simplify ieee80211_derive_ptk() prototype.
pass the AKMP so we can support other key derivation functions in the
future.


# 1.44 12-Aug-2008 damien

use HMAC-MD5, HMAC-SHA1 and AES Key Wrap sys/crypto/


Revision tags: OPENBSD_4_4_BASE
# 1.43 21-Jul-2008 damien

add ieee80211_priv.h file: contains definitions private to net80211.
this must not be included by drivers.


# 1.42 16-Jun-2008 damien

remove now useless casts since the rijndael_* protos have been
constified.


# 1.41 26-Apr-2008 damien

move things from ieee80211_ifattach() to ieee80211_crypto_attach().


# 1.40 21-Apr-2008 damien

- do not process ethernet PAE frames if RSN is not enabled
- add a ieee80211_recv_action() function (will be used later)
- some cleanup, remove unused prototypes, get rid of the
IEEE80211_VERIFY_* macros


# 1.39 18-Apr-2008 djm

extend the if_ethersubr.c crc functions to support updating a running
crc in addition to the existing "oneshot" mode and use them to replace
ieee80211_crc_update() with the new ether_crc32_le_update(). Saves 1k
kernel bss + some code.

Mark the new ether_crc32_[lb]e_update functions as __pure for a
~25x speedup (on my i386 at least).

feedback and ok damien@


# 1.38 17-Apr-2008 damien

call ieee80211_crc_init() only once, when the first 802.11 device
attaches instead of at every attach.

discussed with deraadt@


# 1.37 16-Apr-2008 damien

Kernel implementation of the 4-way handshake and group-key
handshake protocols (both supplicant and authenticator state
machines) as defined in the IEEE 802.11i standard.

Software implementation of the TKIP (Temporal Key Integrity
Protocol) and CCMP (CTR with CBC-MAC Protocol) protocols.

This diff doesn't implement any of the 802.1X authentication
protocols and thus only PSK authentication (using pre-shared
keys) is currently supported.

In concrete terms, this adds support for WPA-PSK and WPA2-PSK
protocols, both in station and hostap modes.

The following drivers are marked as WPA-capable and should
work: bwi(4), malo(4), ral(4), iwn(4), wpi(4), ural(4),
rum(4), upgt(4), and zyd(4)

The following options have been added to ifconfig(8):
wpa, wpapsk, wpaprotos, wpaakms, wpaciphers, wpagroupcipher

wpa-psk(8) can be used to generate keys from passphrases.

tested by many@
ok deraadt@


Revision tags: OPENBSD_4_3_BASE
# 1.36 11-Sep-2007 damien

remove horrid casts now that SHA1Update() has been constified.


# 1.35 29-Aug-2007 damien

- use ieee80211_get_hdrlen() where appropriate.
- discard all EAPOL-Key frames with an unknown descriptor version.
- when receiving message 3/4 of the 4-way handshake, do not install
the PTK if the INSTALL bit is not set. this fixes 4-way handshake
with APs using group keys only.
- similarly, do not mark the 802.1X port as valid if the SECURE bit
is not set (it will be marked as valid after group key handshake).


# 1.34 23-Aug-2007 damien

fix ieee80211_map_ptk() for TKIP.


# 1.33 22-Aug-2007 damien

add a ieee80211_get_txkey() function to determine the key to use for
transmitting a frame to a given node.
change ieee80211_encrypt() so that it now takes the key as parameter.
this change is required because drivers doing hardware crypto need to
know what key is being used.


# 1.32 22-Aug-2007 damien

- add k_rxmic and k_txmic fields to struct ieee80211_key to store the
Tx/Rx MIC for TKIP.
- add two functions to map a PTK and a GTK to an IEEE 802.11 key and
use them in ieee80211_input.c instead of duplicating the same code.
properly set Tx/Rx MIC in the IEEE 802.11 key in the case of TKIP.
- add ic_psk to struct ieee80211com to store the pre-shared key.
- fix setting of the SECURE bit in outgoing EAPOL-Key frames.
- when receiving msg 2 of the 4-way handshake, deauthenticate the
station if the RSN IE does not match that of the (Re)Association
request.
- before parsing an RSN or WPA IE, check that there's enough room for
the version field (2 bytes) which is mandatory.
- various tweaks while i'm here.


Revision tags: OPENBSD_4_2_BASE
# 1.31 03-Aug-2007 damien

add a ni_eapol_desc field to struct ieee80211_node to know whether
a station is using WPA1 or RSN descriptors.
make sure that a station that advertises WPA1 capability in an IE
uses the WPA1 EAPOL-Key descriptor type and not the RSN one.
fix construction of EAPOL-Key frames for WPA1.
i can now successfuly complete a 4-way and group-key handshake
with both a WPA1 and a WPA2 access point.
add some TKIP encapsulation code (no SW crypto yet).

ok deraadt@


# 1.30 01-Aug-2007 damien

add generic ieee80211_encrypt() and ieee80211_decrypt() functions that
can handle multiple ciphers (the key to use is determined automatically
by these functions based on the frame's destination address).
add ieee80211_ccmp_encrypt() and ieee80211_ccmp_decrypt().
those two functions only do encapsulation/decapsulation of CCMP frames
for now (they don't do SW crypto). they will help to test things with
drivers that can do HW crypto.
add a ni_pairwise_key field to struct ieee80211_node to actually install
the pairwise transient key.
install the GTK in ic_nw_keys[].


# 1.29 01-Aug-2007 damien

group key handshake message 1 is very different between RSN and WPA1.
RSN uses a GTK KDE while WPA1 stores the GTK in the EAPOL-Key frame
data field (encrypted) and uses some bits in the info field.
split ieee80211_recv_group_msg1() in two separate functions.


# 1.28 01-Aug-2007 damien

all WPA implementations i have tested use EAPOL-Key frames version 1,
so use that too and remove a check in ieee80211_recv_eapol().
WPA1 stores the group key id into bits 4-5 of the EAPOL-Key frame info
field and uses bit 6 to indicate if the key is Rx/Tx or Rx only.
remove a check in ieee80211_eapol_key_decrypt() because WPA1 encrypts
the payload of message 1 of the group-key handshake without setting the
encrypted bit in the info field.


# 1.27 01-Aug-2007 damien

the EAPOL-Key MIC must be computed with the MIC bit set.
this simplifies ieee80211_eapol_key_mic() and ieee80211_eapol_key_check_mic()
quite a bit.
set the EAPOL-Key body length before computing the MIC since the MIC is
computed with the 802.1X header too.
add a missing htons() while i'm here.


# 1.26 28-Jul-2007 damien

extend the ieee80211_key structure with a key identifier, a flags field
and a 64-bit receive sequence counter (for group keys).
add a ieee80211_cipher_keylen() function to retrieve the key length
in bytes used by a specific cipher.
account for 802.1X header size when computing the Key MIC.
some cleanup in comments and variable names while i'm here.


# 1.25 24-Jul-2007 damien

new function to check the MIC of a received EAPOL-Key frame.


# 1.24 24-Jul-2007 damien

use rc4_skip().
fix ieee80211_eapol_key_encrypt() so that we don't add more padding
bytes than necessary in the case of AES Key Wrap encryption.


# 1.23 24-Jul-2007 damien

remove some unused key derivation functions.
we won't support PeerKey handshake in a first time.


# 1.22 24-Jul-2007 damien

remove arc4_ compatibility macros.


# 1.21 24-Jul-2007 damien

add functions to compute EAPOL-Key Key MIC fields and to encrypt/decrypt
EAPOL-Key Data fields.


# 1.20 24-Jul-2007 damien

add ic_globalcnt to struct ieee80211com:
in an RSNA, each STA must maintain a 256-bit global key counter that
must be initialized to a random value (see 8.5.7).


# 1.19 18-Jul-2007 damien

modify ieee80211_aes_key_wrap() to support in-place encryption.
explicitly use ovbcopy() even if our kernel memcpy() supports
overlapping buffers.


# 1.18 18-Jul-2007 damien

add AES Key Wrap algorithm (see RFC 3394).
this will be used to encrypt/decrypt EAPOL-Key frames payload.


# 1.17 18-Jul-2007 damien

replace the ieee80211_wepkey structure with a more generic ieee80211_key
one that can be used with other ciphers than WEP.


# 1.16 14-Jul-2007 damien

s/uint8_t/u_int8_t/ for consistency.


# 1.15 14-Jul-2007 damien

update QoS Tx/Rx sequence numbers for each TID.
add a parameter to ieee80211_decap() to handle different 802.11
header sizes.
cleanup and clarify ieee80211_classify().


# 1.14 05-Jul-2007 damien

add myself to the copyright list.


# 1.13 05-Jul-2007 damien

add the pseudo-random function (PRF) and various key derivation
functions defined in 802.11i.


# 1.12 16-Jun-2007 damien

constify


# 1.11 16-Jun-2007 damien

de-static

ok jsg@


# 1.10 06-Jun-2007 damien

The license permits us to redistribute this code under the BSD or the GPLv2.
Choose the BSD license so that future enhancements will be BSD-only.

ok jsg@ reyk@ deraadt@


Revision tags: OPENBSD_4_1_BASE
# 1.9 29-Dec-2006 reyk

fix the key buffer size used for software wep, this could cause
problems with non-standard wep keys >= 104 bits.

thanks to Alexander Bluhm

ok mglocker@ jsg@


Revision tags: OPENBSD_4_0_BASE
# 1.8 18-Jun-2006 damien

Improve 802.11b/g interoperability and move toward better compliance
with IEEE Std 802.11g-2003 standard:

- add ERP Information Element in probe responses and beacons
- keep track of the number of associated non-ERP STAs and non-short slot
time capable STAs in the BSS
- enable use of RTS/CTS or CTS-to-self protection when required by the BSS
- add a ic_updateslot() callback to notify drivers of slot time changes
- cleanup computation of mgmt frames sizes in ieee80211_output.c
- nuke unnecessary <sys/cdefs.h> includes
- remove an unused macro (LOGICALLY_EQUAL) while i'm here

From {free,net}bsd, with additional fixes.

ok brad@, reyk@


Revision tags: OPENBSD_3_9_BASE
# 1.7 08-Sep-2005 reyk

mostly knf

ok jsg@


# 1.6 08-Sep-2005 jsg

Remove the last of the FreeBSD compatiblity goop.
ok reyk@


# 1.5 08-Sep-2005 jsg

Remove FreeBSD if_printf compat function from net80211.
ok reyk@


# 1.4 07-Sep-2005 jsg

Remove FreeBSD/NetBSD ifdef mess. We are not likely to be
doing a wholesale merge with them in future.
very enthusiastic ok from reyk@


Revision tags: OPENBSD_3_6_BASE OPENBSD_3_7_BASE OPENBSD_3_8_BASE
# 1.3 28-Jun-2004 millert

Don't restrict WEP keys to exactly 40 or 108 bits.


# 1.2 27-Jun-2004 millert

Hack to avoid panic in arc4maybeinit() due to rnd device not being
attached yet.


# 1.1 22-Jun-2004 millert

Import current NetBSD/FreeBSD 802.11 framework.
Based in part on a diff from Matthew Gream.


# 1.73 28-Apr-2018 stsp

Fix WEP key selection in ieee80211_get_txkey().

The WEP key index is stored in ic_def_txkey. The iGTK ("integrity group key")
index is specific to WPA. The previous code happened to always select WEP key
index 0 since the iGTK index is not yet used by any driver.

ok phessler@


# 1.72 28-Apr-2018 stsp

If ieee80211_encrypt() is passed a key with an unrecognized cipher
type then panic immediately instead of silently dropping packets.

ok phessler@


Revision tags: OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.71 18-Aug-2017 stsp

Clear WPA group keys from memory before initiating a key exchange
with an access point. Prevents false positive 'reused group key'
warnings in dmesg when re-associating to the same access point.
Problem reported by tb@
ok tb@


# 1.70 02-May-2017 mikeb

Switch 802.11 crypto over to the new AES

OK stsp@


Revision tags: OPENBSD_6_1_BASE
# 1.69 23-Mar-2017 tb

branches: 1.69.4;
Use explicit_bzero() to wipe out key material and add some sizes to free().

ok stsp


# 1.68 20-Dec-2016 stsp

Disable TKIP (WPA1) by default.

It is time for this legacy of WEP to die (remember WEP?).
The 802.11-2012 standard says:
The use of TKIP is deprecated. The TKIP algorithm is unsuitable for
the purposes of this standard.

TKIP has numerous problems. One of which is that TKIP allows a denial of
service attack which can be triggered by any client. Report 2 Michael MIC
failures to a TKIP AP to trigger "TKIP countermeasures". The AP is now
required by the 802.11 standard to lock everyone out for at least 60 seconds.
The network will remain unusable for as long as such MIC failure reports
are sent twice per minute.

TKIP remains available for interoperability purposes, for now.
It must be enabled manually with ifconfig(8).

Prompted by discussion with Mathy Vanhoef.
ok deraadt@ sthen@ reyk@


# 1.67 17-Dec-2016 stsp

Complete our half-done implementation of TKIP countermeasures in hostap mode.

The previous code would disable the AP until next reboot upon MIC failure.
Instead, disable the AP for 60 seconds, as required by the 802.11 standard.
I randomly added a bit of time (up to 120 seconds total) just because we can.

Problem reported by Mathy Vanhoef, thanks!
ok deraadt@
random input reyk@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.66 24-Nov-2015 mpi

branches: 1.66.4;
No need to include <net/if_arp.h>

This header is only needed because <netinet/if_ether.h> declares a
structure that needs it. But it turns out that <net/if.h> already
includes it as workaround.

A proper solution would be to stop declarting "struct ether_arp"
there. But no driver should need this header.


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.65 23-Dec-2014 tedu

unifdef some more INET. v4 4life.


# 1.64 18-Nov-2014 tedu

move arc4random prototype to systm.h. more appropriate for most code
to include that than rdnvar.h. ok deraadt dlg


# 1.63 14-Sep-2014 jsg

remove uneeded proc.h includes
ok mpi@ kspillner@


Revision tags: OPENBSD_5_6_BASE
# 1.62 12-Jul-2014 tedu

add a size argument to free. will be used soon, but for now default to 0.
after discussions with beck deraadt kettenis.


Revision tags: OPENBSD_5_5_BASE
# 1.61 21-Nov-2013 mpi

Remove unneeded include.

ok deraadt@


Revision tags: OPENBSD_4_9_BASE OPENBSD_5_0_BASE OPENBSD_5_1_BASE OPENBSD_5_2_BASE OPENBSD_5_3_BASE OPENBSD_5_4_BASE
# 1.60 11-Jan-2011 deraadt

for key material that is being being discarded, convert bzero() to
explicit_bzero() where required
ok markus mikeb


Revision tags: OPENBSD_4_8_BASE
# 1.59 20-Jul-2010 matthew

Switch some obvious network stack MAC comparisons from bcmp() to
timingsafe_bcmp().

ok deraadt@; committed over WPA.


Revision tags: OPENBSD_4_5_BASE OPENBSD_4_6_BASE OPENBSD_4_7_BASE
# 1.58 13-Feb-2009 damien

Change ifconfig wpaakms default setting to `psk' instead of `psk,802.1x'.
Some supplicants will autoselect 802.1X without giving users the
possibility to choose between PSK or 802.1X.

Similarly, no longer announce `PSK with SHA-256 based KDF' AKMP (defined
in Draft 802.11w) by default in the RSN IE of beacons and probe responses
as it confuses some broken supplicants. This kind of sacrifies security
for interoperability with shitty (but unfortunately widespread) clients
that do not follow the 802.11 standard properly.
This fixes associations from Intel PROSet on XP and also reportedly fixes
some Mac OS clients. I will likely make `psk-sha256' configurable through
ifconfig wpaakms after the 4.5 release.


# 1.57 26-Jan-2009 damien

Add some initial HT bits (not enabled yet) based on 802.11n Draft 7.01:
- implement A-MPDU frames buffering and reordering
- implement A-MSDU decapsulation
- process/send ADDBA Request, ADDBA Response and DELBA action frames
- process Block Ack Request control frames (including MTBAR)
- implement PBAC support (Protected Block Ack)
- add some incomplete HT Capabilities and HT Operation IEs parsing

Add more Management Frame Protection bits based on 802.11w Draft 7.0:
- implement SA Query procedure (both AP and STA)
- cleanup BIP

Fix some bugs:
- fix check for WEP key length that otherwise caused a stack smash in
ieee80211_wep_encrypt (pointed out by Xavier Santolaria on macppc)
- properly stop EAPOL timeout: fixes a panic that occured in HostAP mode
when turning the interface down while a 4-way handshake is in progress
(pointed out by Doughertys)

Did some code cleanup too.

The HT bits are currently not compiled in (IEEE80211_NO_HT is defined)
because they won't be ready until after the next release and I didn't
want to grow the kernel or to inadvertently introduce new bugs.
They are here such that other people can look at the code.
Notice that I had to add an extra parameter to ic_send_mgmt() for
action frames, that is why there are small changes in drivers defining
their own ic_send_mgmt() handler.

Sorry for the not very incremental diff but this has been sitting in
my tree for too long now.


# 1.56 27-Sep-2008 damien

Initial implementation of PMKSA caching and pre-authentication.
This will be required for future WPA-Enterprise support (802.1X).
Add ieee80211_needs_auth() function (not implemented yet) to
notify the userland 802.1X PACP machine when an 802.1X port
becomes enabled (that is after successfull 802.11 Open System
authentication).
Add SIOCS80211KEYRUN and SIOCS80211KEYAVAIL ioctls so that the
PACP state machine can kick the 802.11 key state machine and
install PMKs obtained from 802.1X (pre-)authentication.

Enable SHA-256 based AKMPs by default while I'm here (TGw).
This uses SHA-256 for key-derivation (instead of SHA1), AES-128-CMAC
for data integrity, and AES Key Wrap for data protection of EAPOL-Key
frames. An OpenBSD AP will always advertise this capability and an
OpenBSD STA will always prefer SHA-256 based AKMPs over SHA1 based
ones if both are supported by an AP.


# 1.55 27-Aug-2008 damien

introduce new IEEE80211_STA_ONLY kernel option that can be set to
remove IBSS and HostAP support from net80211 and 802.11 drivers.
it can be used to shrink RAMDISK kernels for instance (like what
was done for wi(4)).
it also has the benefit of highlighting what is specific to IBSS
and HostAP modes in the code.
the cost is that we now have two code paths to maintain.


# 1.54 14-Aug-2008 damien

ieee80211_derive_pmkid() is not used either


# 1.53 14-Aug-2008 damien

#ifdef notyet ieee80211_kdf() as it is not used yet (shrink kernel a bit)


# 1.52 12-Aug-2008 damien

add the code to encrypt/decrypt management frames, retrieve key id
from MMIE etc...
this code can't be triggered as no drivers claim MFP capability yet.


# 1.51 12-Aug-2008 damien

missing SHA-256 bits.


# 1.50 12-Aug-2008 damien

new SHA-256 based AKMPs.


# 1.49 12-Aug-2008 damien

add support for EAPOL-Key v3 descriptors (similar to v2 except that the
MIC is computed using AES-128-CMAC instead of HMAC-SHA1).
add a SHA-256 based key derivation function (not used yet).


# 1.48 12-Aug-2008 damien

the only integrity group cipher currently supported is AES-128-CMAC.


# 1.47 12-Aug-2008 damien

extend the ic_nw_keys[] array to 6 elements.
indices 0-3 will be used for group data keys while indices 4-5 will
be used for integrity group keys.
add a ic_rsngroupmgmtcipher field too.


# 1.46 12-Aug-2008 damien

get rid of the map_ptk()/map_gtk() functions, just inline them
which makes things easier to track.


# 1.45 12-Aug-2008 damien

simplify ieee80211_derive_ptk() prototype.
pass the AKMP so we can support other key derivation functions in the
future.


# 1.44 12-Aug-2008 damien

use HMAC-MD5, HMAC-SHA1 and AES Key Wrap sys/crypto/


Revision tags: OPENBSD_4_4_BASE
# 1.43 21-Jul-2008 damien

add ieee80211_priv.h file: contains definitions private to net80211.
this must not be included by drivers.


# 1.42 16-Jun-2008 damien

remove now useless casts since the rijndael_* protos have been
constified.


# 1.41 26-Apr-2008 damien

move things from ieee80211_ifattach() to ieee80211_crypto_attach().


# 1.40 21-Apr-2008 damien

- do not process ethernet PAE frames if RSN is not enabled
- add a ieee80211_recv_action() function (will be used later)
- some cleanup, remove unused prototypes, get rid of the
IEEE80211_VERIFY_* macros


# 1.39 18-Apr-2008 djm

extend the if_ethersubr.c crc functions to support updating a running
crc in addition to the existing "oneshot" mode and use them to replace
ieee80211_crc_update() with the new ether_crc32_le_update(). Saves 1k
kernel bss + some code.

Mark the new ether_crc32_[lb]e_update functions as __pure for a
~25x speedup (on my i386 at least).

feedback and ok damien@


# 1.38 17-Apr-2008 damien

call ieee80211_crc_init() only once, when the first 802.11 device
attaches instead of at every attach.

discussed with deraadt@


# 1.37 16-Apr-2008 damien

Kernel implementation of the 4-way handshake and group-key
handshake protocols (both supplicant and authenticator state
machines) as defined in the IEEE 802.11i standard.

Software implementation of the TKIP (Temporal Key Integrity
Protocol) and CCMP (CTR with CBC-MAC Protocol) protocols.

This diff doesn't implement any of the 802.1X authentication
protocols and thus only PSK authentication (using pre-shared
keys) is currently supported.

In concrete terms, this adds support for WPA-PSK and WPA2-PSK
protocols, both in station and hostap modes.

The following drivers are marked as WPA-capable and should
work: bwi(4), malo(4), ral(4), iwn(4), wpi(4), ural(4),
rum(4), upgt(4), and zyd(4)

The following options have been added to ifconfig(8):
wpa, wpapsk, wpaprotos, wpaakms, wpaciphers, wpagroupcipher

wpa-psk(8) can be used to generate keys from passphrases.

tested by many@
ok deraadt@


Revision tags: OPENBSD_4_3_BASE
# 1.36 11-Sep-2007 damien

remove horrid casts now that SHA1Update() has been constified.


# 1.35 29-Aug-2007 damien

- use ieee80211_get_hdrlen() where appropriate.
- discard all EAPOL-Key frames with an unknown descriptor version.
- when receiving message 3/4 of the 4-way handshake, do not install
the PTK if the INSTALL bit is not set. this fixes 4-way handshake
with APs using group keys only.
- similarly, do not mark the 802.1X port as valid if the SECURE bit
is not set (it will be marked as valid after group key handshake).


# 1.34 23-Aug-2007 damien

fix ieee80211_map_ptk() for TKIP.


# 1.33 22-Aug-2007 damien

add a ieee80211_get_txkey() function to determine the key to use for
transmitting a frame to a given node.
change ieee80211_encrypt() so that it now takes the key as parameter.
this change is required because drivers doing hardware crypto need to
know what key is being used.


# 1.32 22-Aug-2007 damien

- add k_rxmic and k_txmic fields to struct ieee80211_key to store the
Tx/Rx MIC for TKIP.
- add two functions to map a PTK and a GTK to an IEEE 802.11 key and
use them in ieee80211_input.c instead of duplicating the same code.
properly set Tx/Rx MIC in the IEEE 802.11 key in the case of TKIP.
- add ic_psk to struct ieee80211com to store the pre-shared key.
- fix setting of the SECURE bit in outgoing EAPOL-Key frames.
- when receiving msg 2 of the 4-way handshake, deauthenticate the
station if the RSN IE does not match that of the (Re)Association
request.
- before parsing an RSN or WPA IE, check that there's enough room for
the version field (2 bytes) which is mandatory.
- various tweaks while i'm here.


Revision tags: OPENBSD_4_2_BASE
# 1.31 03-Aug-2007 damien

add a ni_eapol_desc field to struct ieee80211_node to know whether
a station is using WPA1 or RSN descriptors.
make sure that a station that advertises WPA1 capability in an IE
uses the WPA1 EAPOL-Key descriptor type and not the RSN one.
fix construction of EAPOL-Key frames for WPA1.
i can now successfuly complete a 4-way and group-key handshake
with both a WPA1 and a WPA2 access point.
add some TKIP encapsulation code (no SW crypto yet).

ok deraadt@


# 1.30 01-Aug-2007 damien

add generic ieee80211_encrypt() and ieee80211_decrypt() functions that
can handle multiple ciphers (the key to use is determined automatically
by these functions based on the frame's destination address).
add ieee80211_ccmp_encrypt() and ieee80211_ccmp_decrypt().
those two functions only do encapsulation/decapsulation of CCMP frames
for now (they don't do SW crypto). they will help to test things with
drivers that can do HW crypto.
add a ni_pairwise_key field to struct ieee80211_node to actually install
the pairwise transient key.
install the GTK in ic_nw_keys[].


# 1.29 01-Aug-2007 damien

group key handshake message 1 is very different between RSN and WPA1.
RSN uses a GTK KDE while WPA1 stores the GTK in the EAPOL-Key frame
data field (encrypted) and uses some bits in the info field.
split ieee80211_recv_group_msg1() in two separate functions.


# 1.28 01-Aug-2007 damien

all WPA implementations i have tested use EAPOL-Key frames version 1,
so use that too and remove a check in ieee80211_recv_eapol().
WPA1 stores the group key id into bits 4-5 of the EAPOL-Key frame info
field and uses bit 6 to indicate if the key is Rx/Tx or Rx only.
remove a check in ieee80211_eapol_key_decrypt() because WPA1 encrypts
the payload of message 1 of the group-key handshake without setting the
encrypted bit in the info field.


# 1.27 01-Aug-2007 damien

the EAPOL-Key MIC must be computed with the MIC bit set.
this simplifies ieee80211_eapol_key_mic() and ieee80211_eapol_key_check_mic()
quite a bit.
set the EAPOL-Key body length before computing the MIC since the MIC is
computed with the 802.1X header too.
add a missing htons() while i'm here.


# 1.26 28-Jul-2007 damien

extend the ieee80211_key structure with a key identifier, a flags field
and a 64-bit receive sequence counter (for group keys).
add a ieee80211_cipher_keylen() function to retrieve the key length
in bytes used by a specific cipher.
account for 802.1X header size when computing the Key MIC.
some cleanup in comments and variable names while i'm here.


# 1.25 24-Jul-2007 damien

new function to check the MIC of a received EAPOL-Key frame.


# 1.24 24-Jul-2007 damien

use rc4_skip().
fix ieee80211_eapol_key_encrypt() so that we don't add more padding
bytes than necessary in the case of AES Key Wrap encryption.


# 1.23 24-Jul-2007 damien

remove some unused key derivation functions.
we won't support PeerKey handshake in a first time.


# 1.22 24-Jul-2007 damien

remove arc4_ compatibility macros.


# 1.21 24-Jul-2007 damien

add functions to compute EAPOL-Key Key MIC fields and to encrypt/decrypt
EAPOL-Key Data fields.


# 1.20 24-Jul-2007 damien

add ic_globalcnt to struct ieee80211com:
in an RSNA, each STA must maintain a 256-bit global key counter that
must be initialized to a random value (see 8.5.7).


# 1.19 18-Jul-2007 damien

modify ieee80211_aes_key_wrap() to support in-place encryption.
explicitly use ovbcopy() even if our kernel memcpy() supports
overlapping buffers.


# 1.18 18-Jul-2007 damien

add AES Key Wrap algorithm (see RFC 3394).
this will be used to encrypt/decrypt EAPOL-Key frames payload.


# 1.17 18-Jul-2007 damien

replace the ieee80211_wepkey structure with a more generic ieee80211_key
one that can be used with other ciphers than WEP.


# 1.16 14-Jul-2007 damien

s/uint8_t/u_int8_t/ for consistency.


# 1.15 14-Jul-2007 damien

update QoS Tx/Rx sequence numbers for each TID.
add a parameter to ieee80211_decap() to handle different 802.11
header sizes.
cleanup and clarify ieee80211_classify().


# 1.14 05-Jul-2007 damien

add myself to the copyright list.


# 1.13 05-Jul-2007 damien

add the pseudo-random function (PRF) and various key derivation
functions defined in 802.11i.


# 1.12 16-Jun-2007 damien

constify


# 1.11 16-Jun-2007 damien

de-static

ok jsg@


# 1.10 06-Jun-2007 damien

The license permits us to redistribute this code under the BSD or the GPLv2.
Choose the BSD license so that future enhancements will be BSD-only.

ok jsg@ reyk@ deraadt@


Revision tags: OPENBSD_4_1_BASE
# 1.9 29-Dec-2006 reyk

fix the key buffer size used for software wep, this could cause
problems with non-standard wep keys >= 104 bits.

thanks to Alexander Bluhm

ok mglocker@ jsg@


Revision tags: OPENBSD_4_0_BASE
# 1.8 18-Jun-2006 damien

Improve 802.11b/g interoperability and move toward better compliance
with IEEE Std 802.11g-2003 standard:

- add ERP Information Element in probe responses and beacons
- keep track of the number of associated non-ERP STAs and non-short slot
time capable STAs in the BSS
- enable use of RTS/CTS or CTS-to-self protection when required by the BSS
- add a ic_updateslot() callback to notify drivers of slot time changes
- cleanup computation of mgmt frames sizes in ieee80211_output.c
- nuke unnecessary <sys/cdefs.h> includes
- remove an unused macro (LOGICALLY_EQUAL) while i'm here

From {free,net}bsd, with additional fixes.

ok brad@, reyk@


Revision tags: OPENBSD_3_9_BASE
# 1.7 08-Sep-2005 reyk

mostly knf

ok jsg@


# 1.6 08-Sep-2005 jsg

Remove the last of the FreeBSD compatiblity goop.
ok reyk@


# 1.5 08-Sep-2005 jsg

Remove FreeBSD if_printf compat function from net80211.
ok reyk@


# 1.4 07-Sep-2005 jsg

Remove FreeBSD/NetBSD ifdef mess. We are not likely to be
doing a wholesale merge with them in future.
very enthusiastic ok from reyk@


Revision tags: OPENBSD_3_6_BASE OPENBSD_3_7_BASE OPENBSD_3_8_BASE
# 1.3 28-Jun-2004 millert

Don't restrict WEP keys to exactly 40 or 108 bits.


# 1.2 27-Jun-2004 millert

Hack to avoid panic in arc4maybeinit() due to rnd device not being
attached yet.


# 1.1 22-Jun-2004 millert

Import current NetBSD/FreeBSD 802.11 framework.
Based in part on a diff from Matthew Gream.


Revision tags: OPENBSD_6_2_BASE
# 1.71 18-Aug-2017 stsp

Clear WPA group keys from memory before initiating a key exchange
with an access point. Prevents false positive 'reused group key'
warnings in dmesg when re-associating to the same access point.
Problem reported by tb@
ok tb@


# 1.70 02-May-2017 mikeb

Switch 802.11 crypto over to the new AES

OK stsp@


Revision tags: OPENBSD_6_1_BASE
# 1.69 23-Mar-2017 tb

branches: 1.69.4;
Use explicit_bzero() to wipe out key material and add some sizes to free().

ok stsp


# 1.68 20-Dec-2016 stsp

Disable TKIP (WPA1) by default.

It is time for this legacy of WEP to die (remember WEP?).
The 802.11-2012 standard says:
The use of TKIP is deprecated. The TKIP algorithm is unsuitable for
the purposes of this standard.

TKIP has numerous problems. One of which is that TKIP allows a denial of
service attack which can be triggered by any client. Report 2 Michael MIC
failures to a TKIP AP to trigger "TKIP countermeasures". The AP is now
required by the 802.11 standard to lock everyone out for at least 60 seconds.
The network will remain unusable for as long as such MIC failure reports
are sent twice per minute.

TKIP remains available for interoperability purposes, for now.
It must be enabled manually with ifconfig(8).

Prompted by discussion with Mathy Vanhoef.
ok deraadt@ sthen@ reyk@


# 1.67 17-Dec-2016 stsp

Complete our half-done implementation of TKIP countermeasures in hostap mode.

The previous code would disable the AP until next reboot upon MIC failure.
Instead, disable the AP for 60 seconds, as required by the 802.11 standard.
I randomly added a bit of time (up to 120 seconds total) just because we can.

Problem reported by Mathy Vanhoef, thanks!
ok deraadt@
random input reyk@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.66 24-Nov-2015 mpi

branches: 1.66.4;
No need to include <net/if_arp.h>

This header is only needed because <netinet/if_ether.h> declares a
structure that needs it. But it turns out that <net/if.h> already
includes it as workaround.

A proper solution would be to stop declarting "struct ether_arp"
there. But no driver should need this header.


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.65 23-Dec-2014 tedu

unifdef some more INET. v4 4life.


# 1.64 18-Nov-2014 tedu

move arc4random prototype to systm.h. more appropriate for most code
to include that than rdnvar.h. ok deraadt dlg


# 1.63 14-Sep-2014 jsg

remove uneeded proc.h includes
ok mpi@ kspillner@


Revision tags: OPENBSD_5_6_BASE
# 1.62 12-Jul-2014 tedu

add a size argument to free. will be used soon, but for now default to 0.
after discussions with beck deraadt kettenis.


Revision tags: OPENBSD_5_5_BASE
# 1.61 21-Nov-2013 mpi

Remove unneeded include.

ok deraadt@


Revision tags: OPENBSD_4_9_BASE OPENBSD_5_0_BASE OPENBSD_5_1_BASE OPENBSD_5_2_BASE OPENBSD_5_3_BASE OPENBSD_5_4_BASE
# 1.60 11-Jan-2011 deraadt

for key material that is being being discarded, convert bzero() to
explicit_bzero() where required
ok markus mikeb


Revision tags: OPENBSD_4_8_BASE
# 1.59 20-Jul-2010 matthew

Switch some obvious network stack MAC comparisons from bcmp() to
timingsafe_bcmp().

ok deraadt@; committed over WPA.


Revision tags: OPENBSD_4_5_BASE OPENBSD_4_6_BASE OPENBSD_4_7_BASE
# 1.58 13-Feb-2009 damien

Change ifconfig wpaakms default setting to `psk' instead of `psk,802.1x'.
Some supplicants will autoselect 802.1X without giving users the
possibility to choose between PSK or 802.1X.

Similarly, no longer announce `PSK with SHA-256 based KDF' AKMP (defined
in Draft 802.11w) by default in the RSN IE of beacons and probe responses
as it confuses some broken supplicants. This kind of sacrifies security
for interoperability with shitty (but unfortunately widespread) clients
that do not follow the 802.11 standard properly.
This fixes associations from Intel PROSet on XP and also reportedly fixes
some Mac OS clients. I will likely make `psk-sha256' configurable through
ifconfig wpaakms after the 4.5 release.


# 1.57 26-Jan-2009 damien

Add some initial HT bits (not enabled yet) based on 802.11n Draft 7.01:
- implement A-MPDU frames buffering and reordering
- implement A-MSDU decapsulation
- process/send ADDBA Request, ADDBA Response and DELBA action frames
- process Block Ack Request control frames (including MTBAR)
- implement PBAC support (Protected Block Ack)
- add some incomplete HT Capabilities and HT Operation IEs parsing

Add more Management Frame Protection bits based on 802.11w Draft 7.0:
- implement SA Query procedure (both AP and STA)
- cleanup BIP

Fix some bugs:
- fix check for WEP key length that otherwise caused a stack smash in
ieee80211_wep_encrypt (pointed out by Xavier Santolaria on macppc)
- properly stop EAPOL timeout: fixes a panic that occured in HostAP mode
when turning the interface down while a 4-way handshake is in progress
(pointed out by Doughertys)

Did some code cleanup too.

The HT bits are currently not compiled in (IEEE80211_NO_HT is defined)
because they won't be ready until after the next release and I didn't
want to grow the kernel or to inadvertently introduce new bugs.
They are here such that other people can look at the code.
Notice that I had to add an extra parameter to ic_send_mgmt() for
action frames, that is why there are small changes in drivers defining
their own ic_send_mgmt() handler.

Sorry for the not very incremental diff but this has been sitting in
my tree for too long now.


# 1.56 27-Sep-2008 damien

Initial implementation of PMKSA caching and pre-authentication.
This will be required for future WPA-Enterprise support (802.1X).
Add ieee80211_needs_auth() function (not implemented yet) to
notify the userland 802.1X PACP machine when an 802.1X port
becomes enabled (that is after successfull 802.11 Open System
authentication).
Add SIOCS80211KEYRUN and SIOCS80211KEYAVAIL ioctls so that the
PACP state machine can kick the 802.11 key state machine and
install PMKs obtained from 802.1X (pre-)authentication.

Enable SHA-256 based AKMPs by default while I'm here (TGw).
This uses SHA-256 for key-derivation (instead of SHA1), AES-128-CMAC
for data integrity, and AES Key Wrap for data protection of EAPOL-Key
frames. An OpenBSD AP will always advertise this capability and an
OpenBSD STA will always prefer SHA-256 based AKMPs over SHA1 based
ones if both are supported by an AP.


# 1.55 27-Aug-2008 damien

introduce new IEEE80211_STA_ONLY kernel option that can be set to
remove IBSS and HostAP support from net80211 and 802.11 drivers.
it can be used to shrink RAMDISK kernels for instance (like what
was done for wi(4)).
it also has the benefit of highlighting what is specific to IBSS
and HostAP modes in the code.
the cost is that we now have two code paths to maintain.


# 1.54 14-Aug-2008 damien

ieee80211_derive_pmkid() is not used either


# 1.53 14-Aug-2008 damien

#ifdef notyet ieee80211_kdf() as it is not used yet (shrink kernel a bit)


# 1.52 12-Aug-2008 damien

add the code to encrypt/decrypt management frames, retrieve key id
from MMIE etc...
this code can't be triggered as no drivers claim MFP capability yet.


# 1.51 12-Aug-2008 damien

missing SHA-256 bits.


# 1.50 12-Aug-2008 damien

new SHA-256 based AKMPs.


# 1.49 12-Aug-2008 damien

add support for EAPOL-Key v3 descriptors (similar to v2 except that the
MIC is computed using AES-128-CMAC instead of HMAC-SHA1).
add a SHA-256 based key derivation function (not used yet).


# 1.48 12-Aug-2008 damien

the only integrity group cipher currently supported is AES-128-CMAC.


# 1.47 12-Aug-2008 damien

extend the ic_nw_keys[] array to 6 elements.
indices 0-3 will be used for group data keys while indices 4-5 will
be used for integrity group keys.
add a ic_rsngroupmgmtcipher field too.


# 1.46 12-Aug-2008 damien

get rid of the map_ptk()/map_gtk() functions, just inline them
which makes things easier to track.


# 1.45 12-Aug-2008 damien

simplify ieee80211_derive_ptk() prototype.
pass the AKMP so we can support other key derivation functions in the
future.


# 1.44 12-Aug-2008 damien

use HMAC-MD5, HMAC-SHA1 and AES Key Wrap sys/crypto/


Revision tags: OPENBSD_4_4_BASE
# 1.43 21-Jul-2008 damien

add ieee80211_priv.h file: contains definitions private to net80211.
this must not be included by drivers.


# 1.42 16-Jun-2008 damien

remove now useless casts since the rijndael_* protos have been
constified.


# 1.41 26-Apr-2008 damien

move things from ieee80211_ifattach() to ieee80211_crypto_attach().


# 1.40 21-Apr-2008 damien

- do not process ethernet PAE frames if RSN is not enabled
- add a ieee80211_recv_action() function (will be used later)
- some cleanup, remove unused prototypes, get rid of the
IEEE80211_VERIFY_* macros


# 1.39 18-Apr-2008 djm

extend the if_ethersubr.c crc functions to support updating a running
crc in addition to the existing "oneshot" mode and use them to replace
ieee80211_crc_update() with the new ether_crc32_le_update(). Saves 1k
kernel bss + some code.

Mark the new ether_crc32_[lb]e_update functions as __pure for a
~25x speedup (on my i386 at least).

feedback and ok damien@


# 1.38 17-Apr-2008 damien

call ieee80211_crc_init() only once, when the first 802.11 device
attaches instead of at every attach.

discussed with deraadt@


# 1.37 16-Apr-2008 damien

Kernel implementation of the 4-way handshake and group-key
handshake protocols (both supplicant and authenticator state
machines) as defined in the IEEE 802.11i standard.

Software implementation of the TKIP (Temporal Key Integrity
Protocol) and CCMP (CTR with CBC-MAC Protocol) protocols.

This diff doesn't implement any of the 802.1X authentication
protocols and thus only PSK authentication (using pre-shared
keys) is currently supported.

In concrete terms, this adds support for WPA-PSK and WPA2-PSK
protocols, both in station and hostap modes.

The following drivers are marked as WPA-capable and should
work: bwi(4), malo(4), ral(4), iwn(4), wpi(4), ural(4),
rum(4), upgt(4), and zyd(4)

The following options have been added to ifconfig(8):
wpa, wpapsk, wpaprotos, wpaakms, wpaciphers, wpagroupcipher

wpa-psk(8) can be used to generate keys from passphrases.

tested by many@
ok deraadt@


Revision tags: OPENBSD_4_3_BASE
# 1.36 11-Sep-2007 damien

remove horrid casts now that SHA1Update() has been constified.


# 1.35 29-Aug-2007 damien

- use ieee80211_get_hdrlen() where appropriate.
- discard all EAPOL-Key frames with an unknown descriptor version.
- when receiving message 3/4 of the 4-way handshake, do not install
the PTK if the INSTALL bit is not set. this fixes 4-way handshake
with APs using group keys only.
- similarly, do not mark the 802.1X port as valid if the SECURE bit
is not set (it will be marked as valid after group key handshake).


# 1.34 23-Aug-2007 damien

fix ieee80211_map_ptk() for TKIP.


# 1.33 22-Aug-2007 damien

add a ieee80211_get_txkey() function to determine the key to use for
transmitting a frame to a given node.
change ieee80211_encrypt() so that it now takes the key as parameter.
this change is required because drivers doing hardware crypto need to
know what key is being used.


# 1.32 22-Aug-2007 damien

- add k_rxmic and k_txmic fields to struct ieee80211_key to store the
Tx/Rx MIC for TKIP.
- add two functions to map a PTK and a GTK to an IEEE 802.11 key and
use them in ieee80211_input.c instead of duplicating the same code.
properly set Tx/Rx MIC in the IEEE 802.11 key in the case of TKIP.
- add ic_psk to struct ieee80211com to store the pre-shared key.
- fix setting of the SECURE bit in outgoing EAPOL-Key frames.
- when receiving msg 2 of the 4-way handshake, deauthenticate the
station if the RSN IE does not match that of the (Re)Association
request.
- before parsing an RSN or WPA IE, check that there's enough room for
the version field (2 bytes) which is mandatory.
- various tweaks while i'm here.


Revision tags: OPENBSD_4_2_BASE
# 1.31 03-Aug-2007 damien

add a ni_eapol_desc field to struct ieee80211_node to know whether
a station is using WPA1 or RSN descriptors.
make sure that a station that advertises WPA1 capability in an IE
uses the WPA1 EAPOL-Key descriptor type and not the RSN one.
fix construction of EAPOL-Key frames for WPA1.
i can now successfuly complete a 4-way and group-key handshake
with both a WPA1 and a WPA2 access point.
add some TKIP encapsulation code (no SW crypto yet).

ok deraadt@


# 1.30 01-Aug-2007 damien

add generic ieee80211_encrypt() and ieee80211_decrypt() functions that
can handle multiple ciphers (the key to use is determined automatically
by these functions based on the frame's destination address).
add ieee80211_ccmp_encrypt() and ieee80211_ccmp_decrypt().
those two functions only do encapsulation/decapsulation of CCMP frames
for now (they don't do SW crypto). they will help to test things with
drivers that can do HW crypto.
add a ni_pairwise_key field to struct ieee80211_node to actually install
the pairwise transient key.
install the GTK in ic_nw_keys[].


# 1.29 01-Aug-2007 damien

group key handshake message 1 is very different between RSN and WPA1.
RSN uses a GTK KDE while WPA1 stores the GTK in the EAPOL-Key frame
data field (encrypted) and uses some bits in the info field.
split ieee80211_recv_group_msg1() in two separate functions.


# 1.28 01-Aug-2007 damien

all WPA implementations i have tested use EAPOL-Key frames version 1,
so use that too and remove a check in ieee80211_recv_eapol().
WPA1 stores the group key id into bits 4-5 of the EAPOL-Key frame info
field and uses bit 6 to indicate if the key is Rx/Tx or Rx only.
remove a check in ieee80211_eapol_key_decrypt() because WPA1 encrypts
the payload of message 1 of the group-key handshake without setting the
encrypted bit in the info field.


# 1.27 01-Aug-2007 damien

the EAPOL-Key MIC must be computed with the MIC bit set.
this simplifies ieee80211_eapol_key_mic() and ieee80211_eapol_key_check_mic()
quite a bit.
set the EAPOL-Key body length before computing the MIC since the MIC is
computed with the 802.1X header too.
add a missing htons() while i'm here.


# 1.26 28-Jul-2007 damien

extend the ieee80211_key structure with a key identifier, a flags field
and a 64-bit receive sequence counter (for group keys).
add a ieee80211_cipher_keylen() function to retrieve the key length
in bytes used by a specific cipher.
account for 802.1X header size when computing the Key MIC.
some cleanup in comments and variable names while i'm here.


# 1.25 24-Jul-2007 damien

new function to check the MIC of a received EAPOL-Key frame.


# 1.24 24-Jul-2007 damien

use rc4_skip().
fix ieee80211_eapol_key_encrypt() so that we don't add more padding
bytes than necessary in the case of AES Key Wrap encryption.


# 1.23 24-Jul-2007 damien

remove some unused key derivation functions.
we won't support PeerKey handshake in a first time.


# 1.22 24-Jul-2007 damien

remove arc4_ compatibility macros.


# 1.21 24-Jul-2007 damien

add functions to compute EAPOL-Key Key MIC fields and to encrypt/decrypt
EAPOL-Key Data fields.


# 1.20 24-Jul-2007 damien

add ic_globalcnt to struct ieee80211com:
in an RSNA, each STA must maintain a 256-bit global key counter that
must be initialized to a random value (see 8.5.7).


# 1.19 18-Jul-2007 damien

modify ieee80211_aes_key_wrap() to support in-place encryption.
explicitly use ovbcopy() even if our kernel memcpy() supports
overlapping buffers.


# 1.18 18-Jul-2007 damien

add AES Key Wrap algorithm (see RFC 3394).
this will be used to encrypt/decrypt EAPOL-Key frames payload.


# 1.17 18-Jul-2007 damien

replace the ieee80211_wepkey structure with a more generic ieee80211_key
one that can be used with other ciphers than WEP.


# 1.16 14-Jul-2007 damien

s/uint8_t/u_int8_t/ for consistency.


# 1.15 14-Jul-2007 damien

update QoS Tx/Rx sequence numbers for each TID.
add a parameter to ieee80211_decap() to handle different 802.11
header sizes.
cleanup and clarify ieee80211_classify().


# 1.14 05-Jul-2007 damien

add myself to the copyright list.


# 1.13 05-Jul-2007 damien

add the pseudo-random function (PRF) and various key derivation
functions defined in 802.11i.


# 1.12 16-Jun-2007 damien

constify


# 1.11 16-Jun-2007 damien

de-static

ok jsg@


# 1.10 06-Jun-2007 damien

The license permits us to redistribute this code under the BSD or the GPLv2.
Choose the BSD license so that future enhancements will be BSD-only.

ok jsg@ reyk@ deraadt@


Revision tags: OPENBSD_4_1_BASE
# 1.9 29-Dec-2006 reyk

fix the key buffer size used for software wep, this could cause
problems with non-standard wep keys >= 104 bits.

thanks to Alexander Bluhm

ok mglocker@ jsg@


Revision tags: OPENBSD_4_0_BASE
# 1.8 18-Jun-2006 damien

Improve 802.11b/g interoperability and move toward better compliance
with IEEE Std 802.11g-2003 standard:

- add ERP Information Element in probe responses and beacons
- keep track of the number of associated non-ERP STAs and non-short slot
time capable STAs in the BSS
- enable use of RTS/CTS or CTS-to-self protection when required by the BSS
- add a ic_updateslot() callback to notify drivers of slot time changes
- cleanup computation of mgmt frames sizes in ieee80211_output.c
- nuke unnecessary <sys/cdefs.h> includes
- remove an unused macro (LOGICALLY_EQUAL) while i'm here

From {free,net}bsd, with additional fixes.

ok brad@, reyk@


Revision tags: OPENBSD_3_9_BASE
# 1.7 08-Sep-2005 reyk

mostly knf

ok jsg@


# 1.6 08-Sep-2005 jsg

Remove the last of the FreeBSD compatiblity goop.
ok reyk@


# 1.5 08-Sep-2005 jsg

Remove FreeBSD if_printf compat function from net80211.
ok reyk@


# 1.4 07-Sep-2005 jsg

Remove FreeBSD/NetBSD ifdef mess. We are not likely to be
doing a wholesale merge with them in future.
very enthusiastic ok from reyk@


Revision tags: OPENBSD_3_6_BASE OPENBSD_3_7_BASE OPENBSD_3_8_BASE
# 1.3 28-Jun-2004 millert

Don't restrict WEP keys to exactly 40 or 108 bits.


# 1.2 27-Jun-2004 millert

Hack to avoid panic in arc4maybeinit() due to rnd device not being
attached yet.


# 1.1 22-Jun-2004 millert

Import current NetBSD/FreeBSD 802.11 framework.
Based in part on a diff from Matthew Gream.