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.
  */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to