diff --git a/sys/net80211/ieee80211_crypto.h b/sys/net80211/ieee80211_crypto.h --- a/sys/net80211/ieee80211_crypto.h +++ b/sys/net80211/ieee80211_crypto.h @@ -102,6 +102,7 @@ #define IEEE80211_KEY_NOMIC 0x00010000 /* don't insert MIC for !mgmt */ #define IEEE80211_KEY_NOMICMGT 0x00020000 /* don't insert MIC for mgmt */ #define IEEE80211_KEY_IGTK 0x00040000 /* key is used for iGTK */ +#define IEEE80211_KEY_MFP 0x00080000 /* key is used for MFP TX/RX */ ieee80211_keyix wk_keyix; /* h/w key index */ ieee80211_keyix wk_rxkeyix; /* optional h/w rx key index */ @@ -118,7 +119,7 @@ }; #define IEEE80211_KEY_COMMON /* common flags passed in by apps */\ (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP | \ - IEEE80211_KEY_NOREPLAY | IEEE80211_KEY_IGTK) + IEEE80211_KEY_NOREPLAY | IEEE80211_KEY_IGTK | IEEE80211_KEY_MFP) #define IEEE80211_KEY_SWCRYPT \ (IEEE80211_KEY_SWENCRYPT | IEEE80211_KEY_SWDECRYPT) diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -1199,6 +1199,7 @@ struct ieee80211req_key ik; struct ieee80211_node *ni; struct ieee80211_key *wk; + uint32_t key_flags; uint16_t kid; int error, i; @@ -1242,8 +1243,25 @@ ni = NULL; } error = 0; + + /* + * The ioctl API only has 8 bits, and the interesting + * stuff for MFP is above that. Grab the key contents + * here, truncating to make sure it's not sign extended. + */ + key_flags = (((int) ik.ik_flags) & 0xff); + + /* + * See if the node may reqiure MFP. If so then tag the node + * as MFP so the key allocation logic has a chance to change + * things. (eg some older NICs may not do CCMP encrypt/decrypt + * correctly for MFP frames due to the MFP nonce field flag.) + */ + if (ni != NULL && ni->ni_flags & IEEE80211_NODE_MFP) + key_flags |= IEEE80211_KEY_MFP; + ieee80211_key_update_begin(vap); - if (ieee80211_crypto_newkey(vap, ik.ik_type, ik.ik_flags, wk)) { + if (ieee80211_crypto_newkey(vap, ik.ik_type, key_flags, wk)) { int key_len; for (i = 0; i < IEEE80211_TID_SIZE; i++)