diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2002-10-27 16:20:49 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2002-10-27 16:20:49 +0000 |
commit | e91cb80664555fdef39ea54b8dc681c10c47d544 (patch) | |
tree | a5657ccb4503949461ab7c31fb534349de7d9cb1 | |
parent | 08c7476bd7d6da9c4b04d2eb087340ebba4f3fc9 (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.8 | 7 | ||||
-rw-r--r-- | sbin/wicontrol/wicontrol.c | 41 | ||||
-rw-r--r-- | sys/dev/ic/if_wi.c | 90 | ||||
-rw-r--r-- | sys/dev/ic/if_wi_ieee.h | 17 | ||||
-rw-r--r-- | sys/dev/ic/if_wireg.h | 4 | ||||
-rw-r--r-- | sys/dev/ic/if_wivar.h | 3 |
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; |