summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2002-10-27 16:20:49 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2002-10-27 16:20:49 +0000
commite91cb80664555fdef39ea54b8dc681c10c47d544 (patch)
treea5657ccb4503949461ab7c31fb534349de7d9cb1
parent08c7476bd7d6da9c4b04d2eb087340ebba4f3fc9 (diff)
Add an option to use software WEP now that we have a software decrypt
function. Can be useful for cards that only support 40-bit WEP or where the card firmware lacks weak IVs avoidance. Prism/Symbol only. In the future this will be expanded to support proposed WEP replacements. Based on code from Jamison Adcock.
-rw-r--r--sbin/wicontrol/wicontrol.87
-rw-r--r--sbin/wicontrol/wicontrol.c41
-rw-r--r--sys/dev/ic/if_wi.c90
-rw-r--r--sys/dev/ic/if_wi_ieee.h17
-rw-r--r--sys/dev/ic/if_wireg.h4
-rw-r--r--sys/dev/ic/if_wivar.h3
6 files changed, 144 insertions, 18 deletions
diff --git a/sbin/wicontrol/wicontrol.8 b/sbin/wicontrol/wicontrol.8
index 29ea743e637..74f61595437 100644
--- a/sbin/wicontrol/wicontrol.8
+++ b/sbin/wicontrol/wicontrol.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: wicontrol.8,v 1.40 2002/06/09 08:13:09 todd Exp $
+.\" $OpenBSD: wicontrol.8,v 1.41 2002/10/27 16:20:48 millert Exp $
.\"
.\" Copyright (c) 1997, 1998, 1999
.\" Bill Paul <wpaul@ctr.columbia.edu> All rights reserved.
@@ -44,6 +44,7 @@
.Op Fl olL
.Op Fl e Ar 0|1
.Op Fl k Ar key "[ -v 1|2|3|4 ]"
+.Op Fl x Ar 0|1
.Op Fl t Ar tx rate
.Op Fl n Ar network name
.Op Fl s Ar station name
@@ -145,6 +146,10 @@ keys, in which case WEP encryption will simply fail to work.
.It Fl T Ar 1|2|3|4
Specify which of the four WEP encryption keys will be used to encrypt
transmitted packets.
+.It Fl x Ar 0|1
+[Prism2/Symbol only]
+Select between firmware-based (0) and software-based (1) WEP.
+Firmware-based WEP is the default.
.It Fl t Ar tx rate
Set the transmit rate of the specified interface.
The legal values
diff --git a/sbin/wicontrol/wicontrol.c b/sbin/wicontrol/wicontrol.c
index fde184c294f..bdeb051009c 100644
--- a/sbin/wicontrol/wicontrol.c
+++ b/sbin/wicontrol/wicontrol.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wicontrol.c,v 1.42 2002/10/11 13:33:14 millert Exp $ */
+/* $OpenBSD: wicontrol.c,v 1.43 2002/10/27 16:20:48 millert Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -69,7 +69,7 @@
static const char copyright[] = "@(#) Copyright (c) 1997, 1998, 1999\
Bill Paul. All rights reserved.";
static const char rcsid[] =
- "@(#) $OpenBSD: wicontrol.c,v 1.42 2002/10/11 13:33:14 millert Exp $";
+ "@(#) $OpenBSD: wicontrol.c,v 1.43 2002/10/27 16:20:48 millert Exp $";
#endif
void wi_getval(char *, struct wi_req *);
@@ -82,6 +82,7 @@ void wi_sethex(char *, int, char *);
void wi_printwords(struct wi_req *);
void wi_printbool(struct wi_req *);
void wi_printhex(struct wi_req *);
+void wi_printalgorithm(struct wi_req *wreq);
void wi_printaplist(char *);
void wi_dumpinfo(char *);
void wi_setkeys(char *, int, char *);
@@ -451,6 +452,23 @@ wi_printhex(wreq)
}
void
+wi_printalgorithm(wreq)
+ struct wi_req *wreq;
+{
+ switch(letoh16(wreq->wi_val[0])) {
+ case WI_CRYPTO_FIRMWARE_WEP:
+ printf("[ Firmware WEP ]");
+ break;
+ case WI_CRYPTO_SOFTWARE_WEP:
+ printf("[ Software WEP ]");
+ break;
+ default:
+ printf("[ Unknown ]");
+ break;
+ }
+}
+
+void
wi_printaplist(iface)
char *iface;
{
@@ -575,6 +593,7 @@ wi_printaplist(iface)
#define WI_HEXBYTES 0x04
#define WI_KEYSTRUCT 0x05
#define WI_CARDINFO 0x06
+#define WI_ALGORITHM 0x07
struct wi_table {
int wi_code;
@@ -614,7 +633,8 @@ struct wi_table wi_table[] = {
};
struct wi_table wi_crypt_table[] = {
- { WI_RID_ENCRYPTION, WI_BOOL, "WEP encryption:\t\t\t\t" },
+ { WI_RID_ENCRYPTION, WI_BOOL, "Encryption:\t\t\t\t" },
+ { WI_FRID_CRYPTO_ALG, WI_ALGORITHM, "Encryption algorithm:\t\t\t" },
{ WI_RID_CNFAUTHMODE, WI_WORDS,
"Authentication type \n(1=OpenSys, 2=Shared Key):\t\t" },
{ WI_RID_TX_CRYPT_KEY, WI_WORDS, "TX encryption key:\t\t\t" },
@@ -705,6 +725,9 @@ wi_dumpinfo(iface)
case WI_KEYSTRUCT:
wi_printkeys(&wreq);
break;
+ case WI_ALGORITHM:
+ wi_printalgorithm(&wreq);
+ break;
default:
break;
}
@@ -822,10 +845,11 @@ usage()
fprintf(stderr,
"usage: %s [interface] [-olL] [-t tx rate] [-n network name]\n"
" [-s station name] [-e 0|1] [-k key [-v 1|2|3|4]] [-T 1|2|3|4]\n"
- " [-F 0|1] [-c 0|1] [-q SSID] [-p port type] [-a access point density]\n"
- " [-m MAC address] [-d max data length] [-r RTS threshold]\n"
- " [-f frequency] [-M 0|1] [-P 0|1] [-S max sleep duration]\n"
- " [-A 1|2|3] [-D 0|1|2] [-R 1|3]\n", __progname);
+ " [-x 0|1] [-F 0|1] [-c 0|1] [-q SSID] [-p port type]\n"
+ " [-a access point density] [-m MAC address] [-d max data length]\n"
+ " [-r RTS threshold] [-f frequency] [-M 0|1] [-P 0|1]\n"
+ " [-S max sleep duration] [-A 1|2|3] [-D 0|1|2] [-R 1|3]\n",
+ __progname);
exit(1);
}
@@ -850,6 +874,7 @@ struct wi_func wi_opt[] = {
{ 'r', wi_setword, WI_RID_RTS_THRESH, NULL },
{ 's', wi_setstr, WI_RID_NODENAME, NULL },
{ 't', wi_setword, WI_RID_TX_RATE, NULL },
+ { 'x', wi_setword, WI_FRID_CRYPTO_ALG, NULL },
{ 'A', wi_setword, WI_RID_CNFAUTHMODE, NULL },
{ 'D', wi_setword, WI_RID_SYMBOL_DIVERSITY, NULL },
{ 'M', wi_setword, WI_RID_MICROWAVE_OVEN, NULL },
@@ -886,7 +911,7 @@ main(argc, argv)
}
while ((ch = getopt(argc, argv,
- "a:c:d:e:f:hi:k:lm:n:op:q:r:s:t:v:A:D:F:LM:S:P:R:T:")) != -1) {
+ "a:c:d:e:f:hi:k:lm:n:op:q:r:s:t:v:x:A:D:F:LM:S:P:R:T:")) != -1) {
for (p = 0; ch && wi_opt[p].key; p++)
if (ch == wi_opt[p].key) {
if (ch == 'p' && !isdigit(*optarg))
diff --git a/sys/dev/ic/if_wi.c b/sys/dev/ic/if_wi.c
index f574ec96406..43f57873903 100644
--- a/sys/dev/ic/if_wi.c
+++ b/sys/dev/ic/if_wi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wi.c,v 1.87 2002/10/27 14:46:30 markus Exp $ */
+/* $OpenBSD: if_wi.c,v 1.88 2002/10/27 16:20:48 millert Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -124,7 +124,7 @@ u_int32_t widebug = WIDEBUG;
#if !defined(lint) && !defined(__OpenBSD__)
static const char rcsid[] =
- "$OpenBSD: if_wi.c,v 1.87 2002/10/27 14:46:30 markus Exp $";
+ "$OpenBSD: if_wi.c,v 1.88 2002/10/27 16:20:48 millert Exp $";
#endif /* lint */
#ifdef foo
@@ -234,6 +234,7 @@ wi_attach(sc)
sc->wi_roaming = WI_DEFAULT_ROAMING;
sc->wi_authtype = WI_DEFAULT_AUTHTYPE;
sc->wi_diversity = WI_DEFAULT_DIVERSITY;
+ sc->wi_crypto_algorithm = WI_CRYPTO_FIRMWARE_WEP;
/*
* Read the default channel from the NIC. This may vary
@@ -701,6 +702,46 @@ wi_rxeof(sc)
ifp->if_ipackets++;
+ if (sc->wi_use_wep &&
+ rx_frame.wi_frame_ctl & WI_FCTL_WEP) {
+ int len;
+ u_int8_t rx_buf[1596];
+
+ switch (sc->wi_crypto_algorithm) {
+ case WI_CRYPTO_FIRMWARE_WEP:
+ break;
+ case WI_CRYPTO_SOFTWARE_WEP:
+ m_copydata(m, 0, m->m_pkthdr.len,
+ (caddr_t)rx_buf);
+ len = m->m_pkthdr.len -
+ sizeof(struct ether_header);
+ if (wi_do_hostdecrypt(sc, rx_buf +
+ sizeof(struct ether_header), len)) {
+ if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf(WI_PRT_FMT ": Error decrypting incoming packet.\n", WI_PRT_ARG(sc));
+ return;
+ }
+ len -= IEEE80211_WEP_IVLEN +
+ IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
+ /*
+ * copy data back to mbufs:
+ * we need to ditch the IV & most LLC/SNAP stuff
+ * (except SNAP type, we're going use that to
+ * overwrite the ethertype in the ether_header)
+ */
+ m_copyback(m, sizeof(struct ether_header) -
+ WI_ETHERTYPE_LEN, WI_ETHERTYPE_LEN +
+ (len - WI_SNAPHDR_LEN),
+ rx_buf + sizeof(struct ether_header) +
+ IEEE80211_WEP_IVLEN +
+ IEEE80211_WEP_KIDLEN + WI_SNAPHDR_LEN);
+ m_adj(m, -(WI_ETHERTYPE_LEN +
+ IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
+ WI_SNAPHDR_LEN));
+ break;
+ }
+ }
+
if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
/*
* Give host AP code first crack at data packets.
@@ -1034,7 +1075,7 @@ wi_write_record(sc, ltv)
struct wi_ltv_gen *ltv;
{
u_int8_t *ptr;
- u_int16_t val;
+ u_int16_t val = 0;
int i;
struct wi_ltv_gen p2ltv;
@@ -1081,9 +1122,20 @@ wi_write_record(sc, ltv)
if (sc->wi_authtype != IEEE80211_AUTH_OPEN ||
sc->sc_firmware_type == WI_SYMBOL)
val |= EXCLUDE_UNENCRYPTED;
- /* TX encryption is broken in Host AP mode. */
- if (sc->wi_ptype == WI_PORTTYPE_HOSTAP)
- val |= HOST_ENCRYPT;
+
+ switch (sc->wi_crypto_algorithm) {
+ case WI_CRYPTO_FIRMWARE_WEP:
+ /*
+ * TX encryption is broken in
+ * Host AP mode.
+ */
+ if (sc->wi_ptype == WI_PORTTYPE_HOSTAP)
+ val |= HOST_ENCRYPT;
+ break;
+ case WI_CRYPTO_SOFTWARE_WEP:
+ val |= HOST_ENCRYPT|HOST_DECRYPT;
+ break;
+ }
p2ltv.wi_val = htole16(val);
} else
p2ltv.wi_val = htole16(HOST_ENCRYPT | HOST_DECRYPT);
@@ -1400,6 +1452,20 @@ wi_setdef(sc, wreq)
bcopy((char *)wreq, (char *)&sc->wi_keys,
sizeof(struct wi_ltv_keys));
break;
+ case WI_FRID_CRYPTO_ALG:
+ switch (letoh16(wreq->wi_val[0])) {
+ case WI_CRYPTO_FIRMWARE_WEP:
+ sc->wi_crypto_algorithm = WI_CRYPTO_FIRMWARE_WEP;
+ break;
+ case WI_CRYPTO_SOFTWARE_WEP:
+ sc->wi_crypto_algorithm = WI_CRYPTO_SOFTWARE_WEP;
+ break;
+ default:
+ printf(WI_PRT_FMT ": unsupported crypto algorithm %d\n",
+ WI_PRT_ARG(sc), letoh16(wreq->wi_val[0]));
+ error = EINVAL;
+ }
+ break;
default:
error = EINVAL;
break;
@@ -1558,6 +1624,11 @@ wi_ioctl(ifp, command, data)
wreq.wi_len = sc->wi_scanbuf_len;
break;
}
+ case WI_FRID_CRYPTO_ALG:
+ wreq.wi_val[0] =
+ htole16((u_int16_t)sc->wi_crypto_algorithm);
+ wreq.wi_len = 1;
+ break;
default:
if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) {
error = EINVAL;
@@ -1593,6 +1664,13 @@ wi_ioctl(ifp, command, data)
error = wi_write_record(sc,
(struct wi_ltv_gen *)&wreq);
break;
+ case WI_FRID_CRYPTO_ALG:
+ if (sc->sc_firmware_type != WI_LUCENT) {
+ error = wi_setdef(sc, &wreq);
+ if (!error && (ifp->if_flags & IFF_UP))
+ wi_init(sc);
+ }
+ break;
case WI_RID_SYMBOL_DIVERSITY:
case WI_RID_ROAMING_MODE:
case WI_RID_CREATE_IBSS:
diff --git a/sys/dev/ic/if_wi_ieee.h b/sys/dev/ic/if_wi_ieee.h
index a164e612311..2a3b8d9eb32 100644
--- a/sys/dev/ic/if_wi_ieee.h
+++ b/sys/dev/ic/if_wi_ieee.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wi_ieee.h,v 1.15 2002/10/22 19:48:22 millert Exp $ */
+/* $OpenBSD: if_wi_ieee.h,v 1.16 2002/10/27 16:20:48 millert Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -343,6 +343,15 @@ struct wi_ltv_keys {
#define WI_RID_SCAN_RES 0xFD88 /* Scan Results Table */
/*
+ * The following do not get passed down to the card, they are used
+ * by wicontrol to modify the behavior of the driver (use WEP in software or
+ * firmware, use alternate cryptographic algorithms, etc.) I'm calling them
+ * "fake record IDs."
+ */
+#define WI_FRID_CRYPTO_ALG 0xFCE3
+#define WI_FRID_DEBUGGING 0xFCE4
+
+/*
* bsd-airtools v0.2 - source-mods v0.2 [common.h]
* by h1kari - (c) Dachb0den Labs 2001
*/
@@ -709,6 +718,12 @@ struct wi_scan_p2_hdr {
#define WI_RID_MAC_PROC_DELAY 0xFDC5 /* MAC processing delay time */
#define WI_RID_DATA_RATES 0xFDC6 /* supported data rates */
+/*
+ * Values for supported crypto algorithms:
+ */
+#define WI_CRYPTO_FIRMWARE_WEP 0x00 /* default */
+#define WI_CRYPTO_SOFTWARE_WEP 0x01
+
/* Firmware types */
#define WI_NOTYPE 0
#define WI_LUCENT 1
diff --git a/sys/dev/ic/if_wireg.h b/sys/dev/ic/if_wireg.h
index b96f7307f3c..6f22e79c6db 100644
--- a/sys/dev/ic/if_wireg.h
+++ b/sys/dev/ic/if_wireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wireg.h,v 1.29 2002/10/10 20:27:46 millert Exp $ */
+/* $OpenBSD: if_wireg.h,v 1.30 2002/10/27 16:20:48 millert Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -598,3 +598,5 @@ struct wi_frame {
#define WI_SNAP_WORD1 (WI_SNAP_K2 | (WI_SNAP_CONTROL << 8))
#define WI_SNAPHDR_LEN 0x6
#define WI_FCS_LEN 0x4
+
+#define WI_ETHERTYPE_LEN 0x2
diff --git a/sys/dev/ic/if_wivar.h b/sys/dev/ic/if_wivar.h
index d9bbe6778ef..f17bebdc0d6 100644
--- a/sys/dev/ic/if_wivar.h
+++ b/sys/dev/ic/if_wivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wivar.h,v 1.19 2002/10/10 20:27:46 millert Exp $ */
+/* $OpenBSD: if_wivar.h,v 1.20 2002/10/27 16:20:48 millert Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -78,6 +78,7 @@ struct wi_softc {
struct ieee80211_nwid wi_ibss_name;
int wi_use_wep;
+ int wi_crypto_algorithm;
int wi_tx_key;
struct wi_ltv_keys wi_keys;
struct wi_counters wi_stats;