svn commit: r308354 - head/sys/net80211

Adrian Chadd adrian at FreeBSD.org
Sat Nov 5 22:41:23 UTC 2016


Author: adrian
Date: Sat Nov  5 22:41:22 2016
New Revision: 308354
URL: https://svnweb.freebsd.org/changeset/base/308354

Log:
  [net80211] begin fleshing out new hardware crypto offload features.
  
  * extend the keycache flag word to be 32 bits, not 16 bits
  * add new key flags for transmit:
    + IEEE80211_KEY_NOIV: Don't insert IV in the payload when transmitting data frames;
    + IEEE80211_KEY_NOIVMGT:  Don't insert IV in the payload when transmitting MIC frames;
    + IEEE80211_KEY_NOMIC: Don't insert MIC in the payload when transmitting data frames;
    + IEEE80211_KEY_NOMICMGT: don't insert MIC in the payload when transmitting management
      frames.
  
  * teach ieee80211_crypto_demic() about hardware decrypted frames:
    + if frames are hardware decrypted and the frame has failed MIC, treat it as a
       michael failure.
    + if frames are hardware decrypted and the frame has stripped MIC, we can't check the
      MIC in the payload - we don't have anything to compare it against.
  
  This is only part of the work required to successfully transmit/receive
  hardware crypto frames such as the qualcomm atheros 11ac offload chips.
  
  There will be further work in the transmit and receive path before this
  can be done by default.
  
  Reviewed by:	avos
  Differential Revision:	https://reviews.freebsd.org/D8364

Modified:
  head/sys/net80211/ieee80211_crypto.c
  head/sys/net80211/ieee80211_crypto.h

Modified: head/sys/net80211/ieee80211_crypto.c
==============================================================================
--- head/sys/net80211/ieee80211_crypto.c	Sat Nov  5 22:09:21 2016	(r308353)
+++ head/sys/net80211/ieee80211_crypto.c	Sat Nov  5 22:41:22 2016	(r308354)
@@ -633,6 +633,61 @@ ieee80211_crypto_decap(struct ieee80211_
 #undef IEEE80211_WEP_HDRLEN
 }
 
+
+/*
+ * Check and remove any MIC.
+ */
+int
+ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k,
+    struct mbuf *m, int force)
+{
+	const struct ieee80211_cipher *cip;
+	const struct ieee80211_rx_stats *rxs;
+	struct ieee80211_frame *wh;
+
+	rxs = ieee80211_get_rx_params_ptr(m);
+	wh = mtod(m, struct ieee80211_frame *);
+
+	/*
+	 * Handle demic / mic errors from hardware-decrypted offload devices.
+	 */
+	if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_DECRYPTED)) {
+		if (rxs->c_pktflags & IEEE80211_RX_F_FAIL_MIC) {
+			/*
+			 * Hardware has said MIC failed.  We don't care about
+			 * whether it was stripped or not.
+			 *
+			 * Eventually - teach the demic methods in crypto
+			 * modules to handle a NULL key and not to dereference
+			 * it.
+			 */
+			ieee80211_notify_michael_failure(vap, wh, -1);
+			return (0);
+		}
+
+		if (rxs->c_pktflags & IEEE80211_RX_F_MMIC_STRIP) {
+			/*
+			 * Hardware has decrypted and not indicated a
+			 * MIC failure and has stripped the MIC.
+			 * We may not have a key, so for now just
+			 * return OK.
+			 */
+			return (1);
+		}
+	}
+
+	/*
+	 * If we don't have a key at this point then we don't
+	 * have to demic anything.
+	 */
+	if (k == NULL)
+		return (1);
+
+	cip = k->wk_cipher;
+	return (cip->ic_miclen > 0 ? cip->ic_demic(k, m, force) : 1);
+}
+
+
 static void
 load_ucastkey(void *arg, struct ieee80211_node *ni)
 {

Modified: head/sys/net80211/ieee80211_crypto.h
==============================================================================
--- head/sys/net80211/ieee80211_crypto.h	Sat Nov  5 22:09:21 2016	(r308353)
+++ head/sys/net80211/ieee80211_crypto.h	Sat Nov  5 22:41:22 2016	(r308354)
@@ -73,19 +73,25 @@ typedef uint16_t ieee80211_keyix;	/* h/w
 
 struct ieee80211_key {
 	uint8_t		wk_keylen;	/* key length in bytes */
-	uint8_t		wk_pad;
-	uint16_t	wk_flags;
-#define	IEEE80211_KEY_XMIT	0x0001	/* key used for xmit */
-#define	IEEE80211_KEY_RECV	0x0002	/* key used for recv */
-#define	IEEE80211_KEY_GROUP	0x0004	/* key used for WPA group operation */
-#define	IEEE80211_KEY_NOREPLAY	0x0008	/* ignore replay failures */
-#define	IEEE80211_KEY_SWENCRYPT	0x0010	/* host-based encrypt */
-#define	IEEE80211_KEY_SWDECRYPT	0x0020	/* host-based decrypt */
-#define	IEEE80211_KEY_SWENMIC	0x0040	/* host-based enmic */
-#define	IEEE80211_KEY_SWDEMIC	0x0080	/* host-based demic */
-#define	IEEE80211_KEY_DEVKEY	0x0100	/* device key request completed */
-#define	IEEE80211_KEY_CIPHER0	0x1000	/* cipher-specific action 0 */
-#define	IEEE80211_KEY_CIPHER1	0x2000	/* cipher-specific action 1 */
+	uint8_t		wk_pad;		/* .. some drivers use this. Fix that. */
+	uint8_t		wk_pad1[2];
+	uint32_t	wk_flags;
+#define	IEEE80211_KEY_XMIT	0x00000001	/* key used for xmit */
+#define	IEEE80211_KEY_RECV	0x00000002	/* key used for recv */
+#define	IEEE80211_KEY_GROUP	0x00000004	/* key used for WPA group operation */
+#define	IEEE80211_KEY_NOREPLAY	0x00000008	/* ignore replay failures */
+#define	IEEE80211_KEY_SWENCRYPT	0x00000010	/* host-based encrypt */
+#define	IEEE80211_KEY_SWDECRYPT	0x00000020	/* host-based decrypt */
+#define	IEEE80211_KEY_SWENMIC	0x00000040	/* host-based enmic */
+#define	IEEE80211_KEY_SWDEMIC	0x00000080	/* host-based demic */
+#define	IEEE80211_KEY_DEVKEY	0x00000100	/* device key request completed */
+#define	IEEE80211_KEY_CIPHER0	0x00001000	/* cipher-specific action 0 */
+#define	IEEE80211_KEY_CIPHER1	0x00002000	/* cipher-specific action 1 */
+#define	IEEE80211_KEY_NOIV	0x00004000	/* don't insert IV/MIC for !mgmt */
+#define	IEEE80211_KEY_NOIVMGT	0x00008000	/* don't insert IV/MIC for mgmt */
+#define	IEEE80211_KEY_NOMIC	0x00010000	/* don't insert MIC for !mgmt */
+#define	IEEE80211_KEY_NOMICMGT	0x00020000	/* don't insert MIC for mgmt */
+
 	ieee80211_keyix	wk_keyix;	/* h/w key index */
 	ieee80211_keyix	wk_rxkeyix;	/* optional h/w rx key index */
 	uint8_t		wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
@@ -203,18 +209,8 @@ struct ieee80211_key *ieee80211_crypto_e
 		struct mbuf *);
 struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211_node *,
 		struct mbuf *, int);
-
-/*
- * Check and remove any MIC.
- */
-static __inline int
-ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k,
-	struct mbuf *m, int force)
-{
-	const struct ieee80211_cipher *cip = k->wk_cipher;
-	return (cip->ic_miclen > 0 ? cip->ic_demic(k, m, force) : 1);
-}
-
+int ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k,
+		struct mbuf *, int);
 /*
  * Add any MIC.
  */


More information about the svn-src-all mailing list