Module Name:    src
Committed By:   maxv
Date:           Wed Jan 17 17:41:38 UTC 2018

Modified Files:
        src/sys/net80211: ieee80211_crypto.c ieee80211_crypto_ccmp.c
            ieee80211_crypto_tkip.c ieee80211_crypto_wep.c

Log Message:
Style, and fix two pretty bad mistakes in the crypto functions:

 * They call M_PREPEND, but don't pass the updated pointer back to the
   caller.

 * They use memmove on the mbuf data, but they don't ensure that the
   area they touch is contiguous.

This fix is not complete, ieee80211_crypto_encap too needs to pass back
the updated pointer. This will be done in another commit.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/net80211/ieee80211_crypto.c
cvs rdiff -u -r1.11 -r1.12 src/sys/net80211/ieee80211_crypto_ccmp.c
cvs rdiff -u -r1.12 -r1.13 src/sys/net80211/ieee80211_crypto_tkip.c
cvs rdiff -u -r1.9 -r1.10 src/sys/net80211/ieee80211_crypto_wep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net80211/ieee80211_crypto.c
diff -u src/sys/net80211/ieee80211_crypto.c:1.19 src/sys/net80211/ieee80211_crypto.c:1.20
--- src/sys/net80211/ieee80211_crypto.c:1.19	Tue Jan 16 09:04:30 2018
+++ src/sys/net80211/ieee80211_crypto.c	Wed Jan 17 17:41:38 2018
@@ -1,5 +1,6 @@
-/*	$NetBSD: ieee80211_crypto.c,v 1.19 2018/01/16 09:04:30 maxv Exp $	*/
-/*-
+/*	$NetBSD: ieee80211_crypto.c,v 1.20 2018/01/17 17:41:38 maxv Exp $	*/
+
+/*
  * Copyright (c) 2001 Atsushi Onoe
  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
  * All rights reserved.
@@ -36,7 +37,7 @@
 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto.c,v 1.12 2005/08/08 18:46:35 sam Exp $");
 #endif
 #ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto.c,v 1.19 2018/01/16 09:04:30 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto.c,v 1.20 2018/01/17 17:41:38 maxv Exp $");
 #endif
 
 #ifdef _KERNEL_OPT
@@ -68,22 +69,22 @@ __KERNEL_RCSID(0, "$NetBSD: ieee80211_cr
 /*
  * Table of registered cipher modules.
  */
-static	const struct ieee80211_cipher *ciphers[IEEE80211_CIPHER_MAX];
+static const struct ieee80211_cipher *ciphers[IEEE80211_CIPHER_MAX];
 
 #ifdef INET
 #include <netinet/in.h> 
 #include <net/if_ether.h>
 #endif
 
-static	int _ieee80211_crypto_delkey(struct ieee80211com *,
-		struct ieee80211_key *);
+static int _ieee80211_crypto_delkey(struct ieee80211com *,
+    struct ieee80211_key *);
 
 /*
  * Default "null" key management routines.
  */
 static int
 null_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *k,
-	ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
+    ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
 {
 	if (!(&ic->ic_nw_keys[0] <= k &&
 	     k < &ic->ic_nw_keys[IEEE80211_WEP_NKID])) {
@@ -106,20 +107,25 @@ null_key_alloc(struct ieee80211com *ic, 
 	*rxkeyix = IEEE80211_KEYIX_NONE;	/* XXX maybe *keyix? */
 	return 1;
 }
+
 static int
-null_key_delete(struct ieee80211com *ic,
-    const struct ieee80211_key *k)
+null_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k)
 {
 	return 1;
 }
-static 	int
-null_key_set(struct ieee80211com *ic,
-    const struct ieee80211_key *k,
+
+static int
+null_key_set(struct ieee80211com *ic, const struct ieee80211_key *k,
     const u_int8_t mac[IEEE80211_ADDR_LEN])
 {
 	return 1;
 }
-static void null_key_update(struct ieee80211com *ic) {}
+
+static void
+null_key_update(struct ieee80211com *ic)
+{
+	;
+}
 
 /*
  * Write-arounds for common operations.
@@ -134,23 +140,21 @@ cipher_detach(struct ieee80211_key *key)
  * Wrappers for driver key management methods.
  */
 static __inline int
-dev_key_alloc(struct ieee80211com *ic,
-	const struct ieee80211_key *key,
-	ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
+dev_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *key,
+    ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
 {
 	return ic->ic_crypto.cs_key_alloc(ic, key, keyix, rxkeyix);
 }
 
 static __inline int
-dev_key_delete(struct ieee80211com *ic,
-	const struct ieee80211_key *key)
+dev_key_delete(struct ieee80211com *ic, const struct ieee80211_key *key)
 {
 	return ic->ic_crypto.cs_key_delete(ic, key);
 }
 
 static __inline int
 dev_key_set(struct ieee80211com *ic, const struct ieee80211_key *key,
-	const u_int8_t mac[IEEE80211_ADDR_LEN])
+    const u_int8_t mac[IEEE80211_ADDR_LEN])
 {
 	return ic->ic_crypto.cs_key_set(ic, key, mac);
 }
@@ -260,8 +264,8 @@ static const char *cipher_modnames[] = {
  *	ieee80211_key_update_end(ic);
  */
 int
-ieee80211_crypto_newkey(struct ieee80211com *ic,
-	int cipher, int flags, struct ieee80211_key *key)
+ieee80211_crypto_newkey(struct ieee80211com *ic, int cipher, int flags,
+    struct ieee80211_key *key)
 {
 #define	N(a)	(sizeof(a) / sizeof(a[0]))
 	const struct ieee80211_cipher *cip;
@@ -279,6 +283,7 @@ ieee80211_crypto_newkey(struct ieee80211
 		return 0;
 	}
 	cip = ciphers[cipher];
+
 	if (cip == NULL) {
 		/*
 		 * Auto-load cipher module if we have a well-known name
@@ -311,9 +316,10 @@ ieee80211_crypto_newkey(struct ieee80211
 
 	oflags = key->wk_flags;
 	flags &= IEEE80211_KEY_COMMON;
+
 	/*
 	 * If the hardware does not support the cipher then
-	 * fallback to a host-based implementation.
+	 * fall back to a host-based implementation.
 	 */
 	if ((ic->ic_caps & (1<<cipher)) == 0) {
 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
@@ -321,6 +327,7 @@ ieee80211_crypto_newkey(struct ieee80211
 		    __func__, cip->ic_name);
 		flags |= IEEE80211_KEY_SWCRYPT;
 	}
+
 	/*
 	 * Hardware TKIP with software MIC is an important
 	 * combination; we handle it by flagging each key,
@@ -473,7 +480,7 @@ ieee80211_crypto_delglobalkeys(struct ie
 
 	ieee80211_key_update_begin(ic);
 	for (i = 0; i < IEEE80211_WEP_NKID; i++)
-		(void) _ieee80211_crypto_delkey(ic, &ic->ic_nw_keys[i]);
+		(void)_ieee80211_crypto_delkey(ic, &ic->ic_nw_keys[i]);
 	ieee80211_key_update_end(ic);
 }
 
@@ -486,7 +493,7 @@ ieee80211_crypto_delglobalkeys(struct ie
  */
 int
 ieee80211_crypto_setkey(struct ieee80211com *ic, struct ieee80211_key *key,
-		const u_int8_t macaddr[IEEE80211_ADDR_LEN])
+    const u_int8_t macaddr[IEEE80211_ADDR_LEN])
 {
 	const struct ieee80211_cipher *cip = key->wk_cipher;
 
@@ -524,13 +531,14 @@ ieee80211_crypto_setkey(struct ieee80211
  * Add privacy headers appropriate for the specified key.
  */
 struct ieee80211_key *
-ieee80211_crypto_encap(struct ieee80211com *ic,
-	struct ieee80211_node *ni, struct mbuf *m)
+ieee80211_crypto_encap(struct ieee80211com *ic, struct ieee80211_node *ni,
+    struct mbuf *m)
 {
 	struct ieee80211_key *k;
 	struct ieee80211_frame *wh;
 	const struct ieee80211_cipher *cip;
-	u_int8_t keyid;
+	u_int8_t keyid, *hdr;
+	int hdrlen;
 
 	/*
 	 * Multicast traffic always uses the multicast key.
@@ -556,6 +564,25 @@ ieee80211_crypto_encap(struct ieee80211c
 		k = &ni->ni_ucastkey;
 	}
 	cip = k->wk_cipher;
+
+	/*
+	 * The crypto header is added after the IEEE802.11 header. Prepend
+	 * the size of the crypto header, and move the IEEE802.11 header back
+	 * to the beginning of the mbuf. Ensure everything is contiguous.
+	 */
+	hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
+	M_PREPEND(m, cip->ic_header, M_NOWAIT);
+	if (m && m->m_len < hdrlen + cip->ic_header) {
+		m = m_pullup(m, hdrlen + cip->ic_header);
+	}
+	if (m == NULL) {
+		return NULL;
+	}
+	hdr = mtod(m, u_int8_t *);
+	memmove(hdr, hdr + cip->ic_header, hdrlen);
+
+	/* XXX pass the updated pointer back to the caller */
+
 	return (cip->ic_encap(k, m, keyid<<6) ? k : NULL);
 }
 
@@ -570,7 +597,7 @@ ieee80211_crypto_encap(struct ieee80211c
  */
 struct ieee80211_key *
 ieee80211_crypto_decap(struct ieee80211com *ic,
-	struct ieee80211_node *ni, struct mbuf **mp, int hdrlen)
+    struct ieee80211_node *ni, struct mbuf **mp, int hdrlen)
 {
 	const struct ieee80211_cipher *cip;
 	struct ieee80211_key *k;

Index: src/sys/net80211/ieee80211_crypto_ccmp.c
diff -u src/sys/net80211/ieee80211_crypto_ccmp.c:1.11 src/sys/net80211/ieee80211_crypto_ccmp.c:1.12
--- src/sys/net80211/ieee80211_crypto_ccmp.c:1.11	Sat Oct 18 08:33:29 2014
+++ src/sys/net80211/ieee80211_crypto_ccmp.c	Wed Jan 17 17:41:38 2018
@@ -34,7 +34,7 @@
 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_ccmp.c,v 1.7 2005/07/11 03:06:23 sam Exp $");
 #endif
 #ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_ccmp.c,v 1.11 2014/10/18 08:33:29 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_ccmp.c,v 1.12 2018/01/17 17:41:38 maxv Exp $");
 #endif
 
 /*
@@ -148,16 +148,7 @@ ccmp_encap(struct ieee80211_key *k, stru
 	int hdrlen;
 
 	hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
-
-	/*
-	 * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
-	 */
-	M_PREPEND(m, ccmp.ic_header, M_NOWAIT);
-	if (m == NULL)
-		return 0;
-	ivp = mtod(m, u_int8_t *);
-	ovbcopy(ivp + ccmp.ic_header, ivp, hdrlen);
-	ivp += hdrlen;
+	ivp = mtod(m, u_int8_t *) + hdrlen;
 
 	k->wk_keytsc++;		/* XXX wrap at 48 bits */
 	ivp[0] = k->wk_keytsc >> 0;		/* PN0 */

Index: src/sys/net80211/ieee80211_crypto_tkip.c
diff -u src/sys/net80211/ieee80211_crypto_tkip.c:1.12 src/sys/net80211/ieee80211_crypto_tkip.c:1.13
--- src/sys/net80211/ieee80211_crypto_tkip.c:1.12	Sat Oct 18 08:33:29 2014
+++ src/sys/net80211/ieee80211_crypto_tkip.c	Wed Jan 17 17:41:38 2018
@@ -34,7 +34,7 @@
 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_tkip.c,v 1.10 2005/08/08 18:46:35 sam Exp $");
 #endif
 #ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_tkip.c,v 1.12 2014/10/18 08:33:29 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_tkip.c,v 1.13 2018/01/17 17:41:38 maxv Exp $");
 #endif
 
 /*
@@ -175,17 +175,9 @@ tkip_encap(struct ieee80211_key *k, stru
 		ic->ic_stats.is_crypto_tkipcm++;
 		return 0;
 	}
-	hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
 
-	/*
-	 * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
-	 */
-	M_PREPEND(m, tkip.ic_header, M_NOWAIT);
-	if (m == NULL)
-		return 0;
-	ivp = mtod(m, u_int8_t *);
-	memmove(ivp, ivp + tkip.ic_header, hdrlen);
-	ivp += hdrlen;
+	hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
+	ivp = mtod(m, u_int8_t *) + hdrlen;
 
 	ivp[0] = k->wk_keytsc >> 8;		/* TSC1 */
 	ivp[1] = (ivp[0] | 0x20) & 0x7f;	/* WEP seed */

Index: src/sys/net80211/ieee80211_crypto_wep.c
diff -u src/sys/net80211/ieee80211_crypto_wep.c:1.9 src/sys/net80211/ieee80211_crypto_wep.c:1.10
--- src/sys/net80211/ieee80211_crypto_wep.c:1.9	Sun Oct  9 14:50:20 2016
+++ src/sys/net80211/ieee80211_crypto_wep.c	Wed Jan 17 17:41:38 2018
@@ -34,7 +34,7 @@
 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_wep.c,v 1.7 2005/06/10 16:11:24 sam Exp $");
 #endif
 #ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_wep.c,v 1.9 2016/10/09 14:50:20 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_wep.c,v 1.10 2018/01/17 17:41:38 maxv Exp $");
 #endif
 
 /*
@@ -132,16 +132,7 @@ wep_encap(struct ieee80211_key *k, struc
 	int hdrlen;
 
 	hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
-
-	/*
-	 * Copy down 802.11 header and add the IV + KeyID.
-	 */
-	M_PREPEND(m, wep.ic_header, M_NOWAIT);
-	if (m == NULL)
-		return 0;
-	ivp = mtod(m, u_int8_t *);
-	ovbcopy(ivp + wep.ic_header, ivp, hdrlen);
-	ivp += hdrlen;
+	ivp = mtod(m, u_int8_t *) + hdrlen;
 
 	/*
 	 * XXX

Reply via email to