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.
This commit is contained in:
parent
0e321d4c9b
commit
d89ae4bbdd
|
@ -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_crypto.c,v 1.19 2018/01/16 09:04:30 maxv E
|
|||
/*
|
||||
* 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, const struct ieee80211_key *k,
|
|||
*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 ieee80211com *ic,
|
|||
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 ieee80211com *ic,
|
|||
|
||||
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 ieee80211com *ic,
|
|||
__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 ieee80211com *ic)
|
|||
|
||||
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 ieee80211com *ic)
|
|||
*/
|
||||
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 ieee80211com *ic, struct ieee80211_key *key,
|
|||
* 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 ieee80211com *ic,
|
|||
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 ieee80211com *ic,
|
|||
*/
|
||||
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;
|
||||
|
|
|
@ -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, struct mbuf *m, u_int8_t keyid)
|
|||
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 */
|
||||
|
|
|
@ -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, struct mbuf *m, u_int8_t keyid)
|
|||
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 */
|
||||
|
|
|
@ -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, struct mbuf *m, u_int8_t keyid)
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue