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)
 
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 48 of file wep.c.

◆ WEP_KID_LEN

#define WEP_KID_LEN   1

Length of WEP key ID byte.

Definition at line 51 of file wep.c.

◆ WEP_ICV_LEN

#define WEP_ICV_LEN   4

Length of WEP ICV checksum.

Definition at line 54 of file wep.c.

◆ WEP_MAX_KEY

#define WEP_MAX_KEY   16

Maximum length of WEP key.

Definition at line 57 of file wep.c.

◆ WEP_HEADER_LEN

#define WEP_HEADER_LEN   4

Amount of data placed before the encrypted bytes.

Definition at line 60 of file wep.c.

◆ WEP_TRAILER_LEN

#define WEP_TRAILER_LEN   4

Amount of data placed after the encrypted bytes.

Definition at line 63 of file wep.c.

◆ WEP_OVERHEAD

#define WEP_OVERHEAD   8

Total WEP overhead bytes.

Definition at line 66 of file wep.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ 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 98 of file wep.c.

100 {
101  struct wep_ctx *ctx = crypto->priv;
102 
103  ctx->keylen = ( keylen > WEP_MAX_KEY ? WEP_MAX_KEY : keylen );
104  memcpy ( ctx->key + WEP_IV_LEN, key, ctx->keylen );
105 
106  return 0;
107 }
#define WEP_MAX_KEY
Maximum length of WEP key.
Definition: wep.c:57
#define WEP_IV_LEN
Length of WEP initialisation vector.
Definition: wep.c:48
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:69
int keylen
Length of WEP key (not including IV bytes)
Definition: wep.c:80
void * priv
Private data for the algorithm to store key and state info.
Definition: net80211.h:766
union @375 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 118 of file wep.c.

120 {
121  struct wep_ctx *ctx = crypto->priv;
122  struct io_buffer *eiob;
123  struct ieee80211_frame *hdr;
124  const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
125  int datalen = iob_len ( iob ) - hdrlen;
126  int newlen = hdrlen + datalen + WEP_OVERHEAD;
127  u32 iv, icv;
128 
129  eiob = alloc_iob ( newlen );
130  if ( ! eiob )
131  return NULL;
132 
133  memcpy ( iob_put ( eiob, hdrlen ), iob->data, hdrlen );
134  hdr = eiob->data;
136 
137  /* Calculate IV, put it in the header (with key ID byte = 0), and
138  set it up at the start of the encryption key. */
139  iv = random() & 0xffffff; /* IV in bottom 3 bytes, top byte = KID = 0 */
140  memcpy ( iob_put ( eiob, WEP_HEADER_LEN ), &iv, WEP_HEADER_LEN );
141  memcpy ( ctx->key, &iv, WEP_IV_LEN );
142 
143  /* Encrypt the data using RC4 */
144  cipher_setkey ( &arc4_algorithm, &ctx->arc4, ctx->key,
145  ctx->keylen + WEP_IV_LEN );
146  cipher_encrypt ( &arc4_algorithm, &ctx->arc4, iob->data + hdrlen,
147  iob_put ( eiob, datalen ), datalen );
148 
149  /* Add ICV */
150  icv = ~crc32_le ( ~0, iob->data + hdrlen, datalen );
151  cipher_encrypt ( &arc4_algorithm, &ctx->arc4, &icv,
152  iob_put ( eiob, WEP_ICV_LEN ), WEP_ICV_LEN );
153 
154  return eiob;
155 }
#define iob_put(iobuf, len)
Definition: iobuf.h:116
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:48
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:128
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:39
#define cipher_encrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:202
#define WEP_HEADER_LEN
Amount of data placed before the encrypted bytes.
Definition: wep.c:60
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:66
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:69
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:30
void * priv
Private data for the algorithm to store key and state info.
Definition: net80211.h:766
uint32_t hdr
Message header.
Definition: intelvf.h:12
struct cipher_algorithm arc4_algorithm
Definition: arc4.c:124
#define WEP_ICV_LEN
Length of WEP ICV checksum.
Definition: wep.c:54
void * data
Start of data.
Definition: iobuf.h:44
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
uint32_t u32
Definition: stdint.h:23
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:187
A persistent I/O buffer.
Definition: iobuf.h:32

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 167 of file wep.c.

169 {
170  struct wep_ctx *ctx = crypto->priv;
171  struct io_buffer *iob;
172  struct ieee80211_frame *hdr;
173  const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
174  int datalen = iob_len ( eiob ) - hdrlen - WEP_OVERHEAD;
175  int newlen = hdrlen + datalen;
176  u32 iv, icv, crc;
177 
178  iob = alloc_iob ( newlen );
179  if ( ! iob )
180  return NULL;
181 
182  memcpy ( iob_put ( iob, hdrlen ), eiob->data, hdrlen );
183  hdr = iob->data;
184  hdr->fc &= ~IEEE80211_FC_PROTECTED;
185 
186  /* Strip off IV and use it to initialize cryptosystem */
187  memcpy ( &iv, eiob->data + hdrlen, 4 );
188  iv &= 0xffffff; /* ignore key ID byte */
189  memcpy ( ctx->key, &iv, WEP_IV_LEN );
190 
191  /* Decrypt the data using RC4 */
192  cipher_setkey ( &arc4_algorithm, &ctx->arc4, ctx->key,
193  ctx->keylen + WEP_IV_LEN );
194  cipher_decrypt ( &arc4_algorithm, &ctx->arc4, eiob->data + hdrlen +
195  WEP_HEADER_LEN, iob_put ( iob, datalen ), datalen );
196 
197  /* Strip off ICV and verify it */
198  cipher_decrypt ( &arc4_algorithm, &ctx->arc4, eiob->data + hdrlen +
200  crc = ~crc32_le ( ~0, iob->data + hdrlen, datalen );
201  if ( crc != icv ) {
202  DBGC ( crypto, "WEP %p CRC mismatch: expect %08x, get %08x\n",
203  crypto, icv, crc );
204  free_iob ( iob );
205  return NULL;
206  }
207  return iob;
208 }
#define iob_put(iobuf, len)
Definition: iobuf.h:116
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#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:48
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:128
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:39
#define WEP_HEADER_LEN
Amount of data placed before the encrypted bytes.
Definition: wep.c:60
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:66
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:69
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
#define cipher_decrypt(cipher, ctx, src, dst, len)
Definition: crypto.h:212
void * priv
Private data for the algorithm to store key and state info.
Definition: net80211.h:766
uint32_t hdr
Message header.
Definition: intelvf.h:12
struct cipher_algorithm arc4_algorithm
Definition: arc4.c:124
#define WEP_ICV_LEN
Length of WEP ICV checksum.
Definition: wep.c:54
void * data
Start of data.
Definition: iobuf.h:44
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
uint32_t u32
Definition: stdint.h:23
static int cipher_setkey(struct cipher_algorithm *cipher, void *ctx, const void *key, size_t keylen)
Definition: crypto.h:187
A persistent I/O buffer.
Definition: iobuf.h:32

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 229 of file wep.c.

230 {
231  u8 key[WEP_MAX_KEY]; /* support up to 128-bit keys */
232  int len;
233  int rc;
234 
235  if ( dev->associating &&
237  return 0; /* no crypto? OK. */
238 
240  &net80211_key_setting, key, WEP_MAX_KEY );
241 
242  if ( len <= 0 ) {
243  DBGC ( dev, "802.11 %p cannot do WEP without a key\n", dev );
244  return -EACCES;
245  }
246 
247  /* Full 128-bit keys are a nonstandard extension, but they're
248  utterly trivial to support, so we do. */
249  if ( len != 5 && len != 13 && len != 16 ) {
250  DBGC ( dev, "802.11 %p invalid WEP key length %d\n",
251  dev, len );
252  return -EINVAL;
253  }
254 
255  DBGC ( dev, "802.11 %p installing %d-bit WEP\n", dev, len * 8 );
256 
258  NULL );
259  if ( rc < 0 )
260  return rc;
261 
262  return 0;
263 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
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:57
#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:807
#define EACCES
Permission denied.
Definition: errno.h:298
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:577
struct net80211_crypto * crypto
802.11 cryptosystem for our current network
Definition: net80211.h:940
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:113
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
uint32_t len
Length.
Definition: ena.h:14
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
uint8_t u8
Definition: stdint.h:19
union @375 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 271 of file wep.c.

272 {
273  u8 key[WEP_MAX_KEY];
274  int len;
275  int change = 0;
276 
277  /* If going from WEP to clear, or something else to WEP, reassociate. */
278  if ( ! dev->crypto || ( dev->crypto->init != wep_init ) )
279  change ^= 1;
280 
282  &net80211_key_setting, key, WEP_MAX_KEY );
283  if ( len <= 0 )
284  change ^= 1;
285 
286  /* Changing crypto type => return nonzero to reassociate. */
287  if ( change )
288  return -EINVAL;
289 
290  /* Going from no crypto to still no crypto => nothing to do. */
291  if ( len <= 0 )
292  return 0;
293 
294  /* Otherwise, reinitialise WEP with new key. */
295  return wep_init ( dev->crypto, key, len, NULL );
296 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define WEP_MAX_KEY
Maximum length of WEP key.
Definition: wep.c:57
int fetch_raw_setting(struct settings *settings, const struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.c:807
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:577
struct net80211_crypto * crypto
802.11 cryptosystem for our current network
Definition: net80211.h:940
static int wep_init(struct net80211_crypto *crypto, const void *key, int keylen, const void *rsc __unused)
Initialize WEP algorithm.
Definition: wep.c:98
struct net_device * netdev
The net_device that wraps us.
Definition: net80211.h:789
uint32_t len
Length.
Definition: ena.h:14
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
uint8_t u8
Definition: stdint.h:19
union @375 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:69
static struct io_buffer * wep_decrypt(struct net80211_crypto *crypto, struct io_buffer *eiob)
Decrypt packet using WEP.
Definition: wep.c:167
static int wep_init(struct net80211_crypto *crypto, const void *key, int keylen, const void *rsc __unused)
Initialize WEP algorithm.
Definition: wep.c:98
static struct io_buffer * wep_encrypt(struct net80211_crypto *crypto, struct io_buffer *iob)
Encrypt packet using WEP.
Definition: wep.c:118

WEP cryptosystem for 802.11.

Definition at line 211 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:229
static int trivial_change_key(struct net80211_device *dev)
Check for key change on trivial 802.11 security handshaker.
Definition: wep.c:271

Trivial 802.11 security handshaker.

Definition at line 299 of file wep.c.