iPXE
Data Structures | Macros | Functions | Variables
wep.c File Reference

The WEP wireless encryption method (insecure!) More...

#include <ipxe/net80211.h>
#include <ipxe/sec80211.h>
#include <ipxe/crypto.h>
#include <ipxe/arc4.h>
#include <ipxe/crc32.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

Go to the source code of this file.

Data Structures

struct  wep_ctx
 Context for WEP encryption and decryption. More...
 

Macros

#define WEP_IV_LEN   3
 Length of WEP initialisation vector. More...
 
#define WEP_KID_LEN   1
 Length of WEP key ID byte. More...
 
#define WEP_ICV_LEN   4
 Length of WEP ICV checksum. More...
 
#define WEP_MAX_KEY   16
 Maximum length of WEP key. More...
 
#define WEP_HEADER_LEN   4
 Amount of data placed before the encrypted bytes. More...
 
#define WEP_TRAILER_LEN   4
 Amount of data placed after the encrypted bytes. More...
 
#define WEP_OVERHEAD   8
 Total WEP overhead bytes. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
 FILE_SECBOOT (FORBIDDEN)
 
static int wep_init (struct net80211_crypto *crypto, const void *key, int keylen, const void *rsc __unused)
 Initialize WEP algorithm. More...
 
static struct io_bufferwep_encrypt (struct net80211_crypto *crypto, struct io_buffer *iob)
 Encrypt packet using WEP. More...
 
static struct io_bufferwep_decrypt (struct net80211_crypto *crypto, struct io_buffer *eiob)
 Decrypt packet using WEP. More...
 
static int trivial_init (struct net80211_device *dev)
 Initialize trivial 802.11 security handshaker. More...
 
static int trivial_change_key (struct net80211_device *dev)
 Check for key change on trivial 802.11 security handshaker. More...
 

Variables

struct net80211_crypto wep_crypto __net80211_crypto
 WEP cryptosystem for 802.11. More...
 
struct net80211_handshaker trivial_handshaker __net80211_handshaker
 Trivial 802.11 security handshaker. More...
 

Detailed Description

The WEP wireless encryption method (insecure!)

The data field in a WEP-encrypted packet contains a 3-byte initialisation vector, one-byte Key ID field (only the bottom two bits are ever used), encrypted data, and a 4-byte encrypted CRC of the plaintext data, called the ICV. To decrypt it, the IV is prepended to the shared key and the data stream (including ICV) is run through the ARC4 stream cipher; if the ICV matches a CRC32 calculated on the plaintext, the packet is valid.

For efficiency and code-size reasons, this file assumes it is running on a little-endian machine.

Definition in file wep.c.

Macro Definition Documentation

◆ WEP_IV_LEN

#define WEP_IV_LEN   3

Length of WEP initialisation vector.

Definition at line 49 of file wep.c.

◆ WEP_KID_LEN

#define WEP_KID_LEN   1

Length of WEP key ID byte.

Definition at line 52 of file wep.c.

◆ WEP_ICV_LEN

#define WEP_ICV_LEN   4

Length of WEP ICV checksum.

Definition at line 55 of file wep.c.

◆ WEP_MAX_KEY

#define WEP_MAX_KEY   16

Maximum length of WEP key.

Definition at line 58 of file wep.c.

◆ WEP_HEADER_LEN

#define WEP_HEADER_LEN   4

Amount of data placed before the encrypted bytes.

Definition at line 61 of file wep.c.

◆ WEP_TRAILER_LEN

#define WEP_TRAILER_LEN   4

Amount of data placed after the encrypted bytes.

Definition at line 64 of file wep.c.

◆ WEP_OVERHEAD

#define WEP_OVERHEAD   8

Total WEP overhead bytes.

Definition at line 67 of file wep.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( FORBIDDEN  )

◆ wep_init()

static int wep_init ( struct net80211_crypto crypto,
const void *  key,
int  keylen,
const void *rsc  __unused 
)
static

Initialize WEP algorithm.

Parameters
crypto802.11 cryptographic algorithm
keyWEP key to use
keylenLength of WEP key
rscInitial receive sequence counter (unused)
Return values
rcReturn status code

Standard key lengths are 5 and 13 bytes; 16-byte keys are occasionally supported as an extension to the standard.

Definition at line 99 of file wep.c.

101 {
102  struct wep_ctx *ctx = crypto->priv;
103 
104  ctx->keylen = ( keylen > WEP_MAX_KEY ? WEP_MAX_KEY : keylen );
105  memcpy ( ctx->key + WEP_IV_LEN, key, ctx->keylen );
106 
107  return 0;
108 }
#define WEP_MAX_KEY
Maximum length of WEP key.
Definition: wep.c:58
#define WEP_IV_LEN
Length of WEP initialisation vector.
Definition: wep.c:49
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
void * memcpy(void *dest, const void *src, size_t len) __nonnull
Context for WEP encryption and decryption.
Definition: wep.c:70
int keylen
Length of WEP key (not including IV bytes)
Definition: wep.c:81
void * priv
Private data for the algorithm to store key and state info.
Definition: net80211.h:766
union @391 key
Sense key.
Definition: scsi.h:18

References ctx, key, wep_ctx::keylen, memcpy(), net80211_crypto::priv, WEP_IV_LEN, and WEP_MAX_KEY.

Referenced by trivial_change_key().

◆ wep_encrypt()

static struct io_buffer* wep_encrypt ( struct net80211_crypto crypto,
struct io_buffer iob 
)
static

Encrypt packet using WEP.

Parameters
crypto802.11 cryptographic algorithm
iobI/O buffer of plaintext packet
Return values
eiobNewly allocated I/O buffer for encrypted packet, or NULL

If memory allocation fails, NULL is returned.

Definition at line 119 of file wep.c.

121 {
122  struct wep_ctx *ctx = crypto->priv;
123  struct io_buffer *eiob;
124  struct ieee80211_frame *hdr;
125  const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
126  int datalen = iob_len ( iob ) - hdrlen;
127  int newlen = hdrlen + datalen + WEP_OVERHEAD;
128  u32 iv, icv;
129 
130  eiob = alloc_iob ( newlen );
131  if ( ! eiob )
132  return NULL;
133 
134  memcpy ( iob_put ( eiob, hdrlen ), iob->data, hdrlen );
135  hdr = eiob->data;
137 
138  /* Calculate IV, put it in the header (with key ID byte = 0), and
139  set it up at the start of the encryption key. */
140  iv = random() & 0xffffff; /* IV in bottom 3 bytes, top byte = KID = 0 */
141  memcpy ( iob_put ( eiob, WEP_HEADER_LEN ), &iv, WEP_HEADER_LEN );
142  memcpy ( ctx->key, &iv, WEP_IV_LEN );
143 
144  /* Encrypt the data using RC4 */
145  cipher_setkey ( &arc4_algorithm, &ctx->arc4, ctx->key,
146  ctx->keylen + WEP_IV_LEN );
147  cipher_encrypt ( &arc4_algorithm, &ctx->arc4, iob->data + hdrlen,
148  iob_put ( eiob, datalen ), datalen );
149 
150  /* Add ICV */
151  icv = ~crc32_le ( ~0, iob->data + hdrlen, datalen );
152  cipher_encrypt ( &arc4_algorithm, &ctx->arc4, &icv,
153  iob_put ( eiob, WEP_ICV_LEN ), WEP_ICV_LEN );
154 
155  return eiob;
156 }
#define iob_put(iobuf, len)
Definition: iobuf.h:125
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
#define WEP_IV_LEN
Length of WEP initialisation vector.
Definition: wep.c:49
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:131
u8 iv[16]
Initialization vector.
Definition: wpa.h:60
u32 crc32_le(u32 seed, const void *data, size_t len)
Calculate 32-bit little-endian CRC checksum.
Definition: crc32.c:40
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:251
#define WEP_HEADER_LEN
Amount of data placed before the encrypted bytes.
Definition: wep.c:61
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define IEEE80211_TYP_FRAME_HEADER_LEN
Frame header length for frames we might work with.
Definition: ieee80211.h:60
#define WEP_OVERHEAD
Total WEP overhead bytes.
Definition: wep.c:67
u16 datalen
Length of the data field in bytes, network byte order.
Definition: wpa.h:84
#define IEEE80211_FC_PROTECTED
802.11 Frame Control field: Protected flag
Definition: ieee80211.h:264
Context for WEP encryption and decryption.
Definition: wep.c:70
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:32
void * priv
Private data for the algorithm to store key and state info.
Definition: net80211.h:766
struct cipher_algorithm arc4_algorithm
Definition: arc4.c:118
#define WEP_ICV_LEN
Length of WEP ICV checksum.
Definition: wep.c:55
void * data
Start of data.
Definition: iobuf.h:53
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
uint32_t u32
Definition: stdint.h:24
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:235
A persistent I/O buffer.
Definition: iobuf.h:38

References alloc_iob(), arc4_algorithm, cipher_encrypt, cipher_setkey(), crc32_le(), ctx, io_buffer::data, datalen, hdr, IEEE80211_FC_PROTECTED, IEEE80211_TYP_FRAME_HEADER_LEN, iob_len(), iob_put, iv, memcpy(), NULL, net80211_crypto::priv, random(), WEP_HEADER_LEN, WEP_ICV_LEN, WEP_IV_LEN, and WEP_OVERHEAD.

◆ wep_decrypt()

static struct io_buffer* wep_decrypt ( struct net80211_crypto crypto,
struct io_buffer eiob 
)
static

Decrypt packet using WEP.

Parameters
crypto802.11 cryptographic algorithm
eiobI/O buffer of encrypted packet
Return values
iobNewly allocated I/O buffer for plaintext packet, or NULL

If a consistency check for the decryption fails (usually indicating an invalid key), NULL is returned.

Definition at line 168 of file wep.c.

170 {
171  struct wep_ctx *ctx = crypto->priv;
172  struct io_buffer *iob;
173  struct ieee80211_frame *hdr;
174  const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
175  int datalen = iob_len ( eiob ) - hdrlen - WEP_OVERHEAD;
176  int newlen = hdrlen + datalen;
177  u32 iv, icv, crc;
178 
179  iob = alloc_iob ( newlen );
180  if ( ! iob )
181  return NULL;
182 
183  memcpy ( iob_put ( iob, hdrlen ), eiob->data, hdrlen );
184  hdr = iob->data;
185  hdr->fc &= ~IEEE80211_FC_PROTECTED;
186 
187  /* Strip off IV and use it to initialize cryptosystem */
188  memcpy ( &iv, eiob->data + hdrlen, 4 );
189  iv &= 0xffffff; /* ignore key ID byte */
190  memcpy ( ctx->key, &iv, WEP_IV_LEN );
191 
192  /* Decrypt the data using RC4 */
193  cipher_setkey ( &arc4_algorithm, &ctx->arc4, ctx->key,
194  ctx->keylen + WEP_IV_LEN );
195  cipher_decrypt ( &arc4_algorithm, &ctx->arc4, eiob->data + hdrlen +
196  WEP_HEADER_LEN, iob_put ( iob, datalen ), datalen );
197 
198  /* Strip off ICV and verify it */
199  cipher_decrypt ( &arc4_algorithm, &ctx->arc4, eiob->data + hdrlen +
201  crc = ~crc32_le ( ~0, iob->data + hdrlen, datalen );
202  if ( crc != icv ) {
203  DBGC ( crypto, "WEP %p CRC mismatch: expect %08x, get %08x\n",
204  crypto, icv, crc );
205  free_iob ( iob );
206  return NULL;
207  }
208  return iob;
209 }
#define iob_put(iobuf, len)
Definition: iobuf.h:125
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
#define DBGC(...)
Definition: compiler.h:505
An 802.11 data or management frame without QoS or WDS header fields.
Definition: ieee80211.h:300
#define WEP_IV_LEN
Length of WEP initialisation vector.
Definition: wep.c:49
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:131
u8 iv[16]
Initialization vector.
Definition: wpa.h:60
u32 crc32_le(u32 seed, const void *data, size_t len)
Calculate 32-bit little-endian CRC checksum.
Definition: crc32.c:40
#define WEP_HEADER_LEN
Amount of data placed before the encrypted bytes.
Definition: wep.c:61
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define IEEE80211_TYP_FRAME_HEADER_LEN
Frame header length for frames we might work with.
Definition: ieee80211.h:60
#define WEP_OVERHEAD
Total WEP overhead bytes.
Definition: wep.c:67
u16 datalen
Length of the data field in bytes, network byte order.
Definition: wpa.h:84
#define IEEE80211_FC_PROTECTED
802.11 Frame Control field: Protected flag
Definition: ieee80211.h:264
Context for WEP encryption and decryption.
Definition: wep.c:70
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:261
void * priv
Private data for the algorithm to store key and state info.
Definition: net80211.h:766
struct cipher_algorithm arc4_algorithm
Definition: arc4.c:118
#define WEP_ICV_LEN
Length of WEP ICV checksum.
Definition: wep.c:55
void * data
Start of data.
Definition: iobuf.h:53
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
uint32_t u32
Definition: stdint.h:24
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:235
A persistent I/O buffer.
Definition: iobuf.h:38

References alloc_iob(), arc4_algorithm, cipher_decrypt, cipher_setkey(), crc32_le(), ctx, io_buffer::data, datalen, DBGC, free_iob(), hdr, IEEE80211_FC_PROTECTED, IEEE80211_TYP_FRAME_HEADER_LEN, iob_len(), iob_put, iv, memcpy(), NULL, net80211_crypto::priv, WEP_HEADER_LEN, WEP_ICV_LEN, WEP_IV_LEN, and WEP_OVERHEAD.

◆ trivial_init()

static int trivial_init ( struct net80211_device dev)
static

Initialize trivial 802.11 security handshaker.

Parameters
dev802.11 device
ctxSecurity handshaker

This simply fetches a WEP key from netX/key, and if it exists, installs WEP cryptography on the 802.11 device. No real handshaking is performed.

Definition at line 230 of file wep.c.

231 {
232  u8 key[WEP_MAX_KEY]; /* support up to 128-bit keys */
233  int len;
234  int rc;
235 
236  if ( dev->associating &&
238  return 0; /* no crypto? OK. */
239 
241  &net80211_key_setting, key, WEP_MAX_KEY );
242 
243  if ( len <= 0 ) {
244  DBGC ( dev, "802.11 %p cannot do WEP without a key\n", dev );
245  return -EACCES;
246  }
247 
248  /* Full 128-bit keys are a nonstandard extension, but they're
249  utterly trivial to support, so we do. */
250  if ( len != 5 && len != 13 && len != 16 ) {
251  DBGC ( dev, "802.11 %p invalid WEP key length %d\n",
252  dev, len );
253  return -EINVAL;
254  }
255 
256  DBGC ( dev, "802.11 %p installing %d-bit WEP\n", dev, len * 8 );
257 
259  NULL );
260  if ( rc < 0 )
261  return rc;
262 
263  return 0;
264 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
enum net80211_crypto_alg crypto
Cryptographic algorithm used on the network.
Definition: net80211.h:1087
#define WEP_MAX_KEY
Maximum length of WEP key.
Definition: wep.c:58
#define DBGC(...)
Definition: compiler.h:505
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.c:804
#define EACCES
Permission denied.
Definition: errno.h:299
Network protected with WEP (awful RC4-based system)
Definition: net80211.h:145
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:587
struct net80211_crypto * crypto
802.11 cryptosystem for our current network
Definition: net80211.h:940
ring len
Length.
Definition: dwmac.h:231
int sec80211_install(struct net80211_crypto **which, enum net80211_crypto_alg crypt, const void *key, int len, const void *rsc)
Install 802.11 cryptosystem.
Definition: sec80211.c:114
No security, an "Open" network.
Definition: net80211.h:131
struct net80211_wlan * associating
Network with which we are associating.
Definition: net80211.h:866
struct net_device * netdev
The net_device that wraps us.
Definition: net80211.h:789
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
uint8_t u8
Definition: stdint.h:20
union @391 key
Sense key.
Definition: scsi.h:18

References net80211_device::associating, net80211_device::crypto, net80211_wlan::crypto, DBGC, EACCES, EINVAL, fetch_raw_setting(), key, len, NET80211_CRYPT_NONE, NET80211_CRYPT_WEP, net80211_device::netdev, netdev_settings(), NULL, rc, sec80211_install(), and WEP_MAX_KEY.

◆ trivial_change_key()

static int trivial_change_key ( struct net80211_device dev)
static

Check for key change on trivial 802.11 security handshaker.

Parameters
dev802.11 device
ctxSecurity handshaker

Definition at line 272 of file wep.c.

273 {
274  u8 key[WEP_MAX_KEY];
275  int len;
276  int change = 0;
277 
278  /* If going from WEP to clear, or something else to WEP, reassociate. */
279  if ( ! dev->crypto || ( dev->crypto->init != wep_init ) )
280  change ^= 1;
281 
283  &net80211_key_setting, key, WEP_MAX_KEY );
284  if ( len <= 0 )
285  change ^= 1;
286 
287  /* Changing crypto type => return nonzero to reassociate. */
288  if ( change )
289  return -EINVAL;
290 
291  /* Going from no crypto to still no crypto => nothing to do. */
292  if ( len <= 0 )
293  return 0;
294 
295  /* Otherwise, reinitialise WEP with new key. */
296  return wep_init ( dev->crypto, key, len, NULL );
297 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
#define WEP_MAX_KEY
Maximum length of WEP key.
Definition: wep.c:58
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.c:804
int(* init)(struct net80211_crypto *crypto, const void *key, int keylen, const void *rsc)
Initialize cryptosystem using a given key.
Definition: net80211.h:707
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:587
struct net80211_crypto * crypto
802.11 cryptosystem for our current network
Definition: net80211.h:940
ring len
Length.
Definition: dwmac.h:231
static int wep_init(struct net80211_crypto *crypto, const void *key, int keylen, const void *rsc __unused)
Initialize WEP algorithm.
Definition: wep.c:99
struct net_device * netdev
The net_device that wraps us.
Definition: net80211.h:789
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
uint8_t u8
Definition: stdint.h:20
union @391 key
Sense key.
Definition: scsi.h:18

References net80211_device::crypto, EINVAL, fetch_raw_setting(), net80211_crypto::init, key, len, net80211_device::netdev, netdev_settings(), NULL, wep_init(), and WEP_MAX_KEY.

Variable Documentation

◆ __net80211_crypto

struct net80211_crypto wep_crypto __net80211_crypto
Initial value:
= {
.algorithm = NET80211_CRYPT_WEP,
.init = wep_init,
.encrypt = wep_encrypt,
.decrypt = wep_decrypt,
.priv_len = sizeof ( struct wep_ctx ),
}
Network protected with WEP (awful RC4-based system)
Definition: net80211.h:145
Context for WEP encryption and decryption.
Definition: wep.c:70
static struct io_buffer * wep_decrypt(struct net80211_crypto *crypto, struct io_buffer *eiob)
Decrypt packet using WEP.
Definition: wep.c:168
static int wep_init(struct net80211_crypto *crypto, const void *key, int keylen, const void *rsc __unused)
Initialize WEP algorithm.
Definition: wep.c:99
static struct io_buffer * wep_encrypt(struct net80211_crypto *crypto, struct io_buffer *iob)
Encrypt packet using WEP.
Definition: wep.c:119

WEP cryptosystem for 802.11.

Definition at line 212 of file wep.c.

◆ __net80211_handshaker

struct net80211_handshaker trivial_handshaker __net80211_handshaker
Initial value:
= {
.protocol = NET80211_SECPROT_NONE,
.init = trivial_init,
.change_key = trivial_change_key,
.priv_len = 0,
}
No security handshaking.
Definition: net80211.h:102
static int trivial_init(struct net80211_device *dev)
Initialize trivial 802.11 security handshaker.
Definition: wep.c:230
static int trivial_change_key(struct net80211_device *dev)
Check for key change on trivial 802.11 security handshaker.
Definition: wep.c:272

Trivial 802.11 security handshaker.

Definition at line 300 of file wep.c.