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