0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 #include <linux/crc32.h>
0053 #include <linux/netdevice.h>
0054 #include <linux/wireless.h>
0055 #include <linux/random.h>
0056 #include <linux/kernel.h>
0057 #include "p80211hdr.h"
0058 #include "p80211types.h"
0059 #include "p80211msg.h"
0060 #include "p80211conv.h"
0061 #include "p80211netdev.h"
0062
0063 #define WEP_KEY(x) (((x) & 0xC0) >> 6)
0064
0065
0066
0067 int wep_change_key(struct wlandevice *wlandev, int keynum, u8 *key, int keylen)
0068 {
0069 if (keylen < 0)
0070 return -1;
0071 if (keylen >= MAX_KEYLEN)
0072 return -1;
0073 if (!key)
0074 return -1;
0075 if (keynum < 0)
0076 return -1;
0077 if (keynum >= NUM_WEPKEYS)
0078 return -1;
0079
0080 wlandev->wep_keylens[keynum] = keylen;
0081 memcpy(wlandev->wep_keys[keynum], key, keylen);
0082
0083 return 0;
0084 }
0085
0086
0087
0088
0089
0090 int wep_decrypt(struct wlandevice *wlandev, u8 *buf, u32 len, int key_override,
0091 u8 *iv, u8 *icv)
0092 {
0093 u32 i, j, k, crc, keylen;
0094 u8 s[256], key[64], c_crc[4];
0095 u8 keyidx;
0096
0097
0098 if (len <= 0)
0099 return -1;
0100
0101
0102 key[0] = iv[0];
0103 key[1] = iv[1];
0104 key[2] = iv[2];
0105 keyidx = WEP_KEY(iv[3]);
0106
0107 if (key_override >= 0)
0108 keyidx = key_override;
0109
0110 if (keyidx >= NUM_WEPKEYS)
0111 return -2;
0112
0113 keylen = wlandev->wep_keylens[keyidx];
0114
0115 if (keylen == 0)
0116 return -3;
0117
0118
0119 memcpy(key + 3, wlandev->wep_keys[keyidx], keylen);
0120
0121 keylen += 3;
0122
0123
0124 for (i = 0; i < 256; i++)
0125 s[i] = i;
0126 j = 0;
0127 for (i = 0; i < 256; i++) {
0128 j = (j + s[i] + key[i % keylen]) & 0xff;
0129 swap(i, j);
0130 }
0131
0132
0133 i = 0;
0134 j = 0;
0135 for (k = 0; k < len; k++) {
0136 i = (i + 1) & 0xff;
0137 j = (j + s[i]) & 0xff;
0138 swap(i, j);
0139 buf[k] ^= s[(s[i] + s[j]) & 0xff];
0140 }
0141 crc = ~crc32_le(~0, buf, len);
0142
0143
0144 c_crc[0] = crc;
0145 c_crc[1] = crc >> 8;
0146 c_crc[2] = crc >> 16;
0147 c_crc[3] = crc >> 24;
0148
0149 for (k = 0; k < 4; k++) {
0150 i = (i + 1) & 0xff;
0151 j = (j + s[i]) & 0xff;
0152 swap(i, j);
0153 if ((c_crc[k] ^ s[(s[i] + s[j]) & 0xff]) != icv[k])
0154 return -(4 | (k << 4));
0155 }
0156
0157 return 0;
0158 }
0159
0160
0161 int wep_encrypt(struct wlandevice *wlandev, u8 *buf,
0162 u8 *dst, u32 len, int keynum, u8 *iv, u8 *icv)
0163 {
0164 u32 i, j, k, crc, keylen;
0165 u8 s[256], key[64];
0166
0167
0168 if (len <= 0)
0169 return -1;
0170
0171
0172 if (keynum >= NUM_WEPKEYS)
0173 return -2;
0174 keylen = wlandev->wep_keylens[keynum];
0175 if (keylen <= 0)
0176 return -3;
0177
0178
0179 get_random_bytes(iv, 3);
0180 while ((iv[1] == 0xff) && (iv[0] >= 3) && (iv[0] < keylen))
0181 get_random_bytes(iv, 3);
0182
0183 iv[3] = (keynum & 0x03) << 6;
0184
0185 key[0] = iv[0];
0186 key[1] = iv[1];
0187 key[2] = iv[2];
0188
0189
0190 memcpy(key + 3, wlandev->wep_keys[keynum], keylen);
0191
0192 keylen += 3;
0193
0194
0195 for (i = 0; i < 256; i++)
0196 s[i] = i;
0197 j = 0;
0198 for (i = 0; i < 256; i++) {
0199 j = (j + s[i] + key[i % keylen]) & 0xff;
0200 swap(i, j);
0201 }
0202
0203
0204 i = 0;
0205 j = 0;
0206 for (k = 0; k < len; k++) {
0207 i = (i + 1) & 0xff;
0208 j = (j + s[i]) & 0xff;
0209 swap(i, j);
0210 dst[k] = buf[k] ^ s[(s[i] + s[j]) & 0xff];
0211 }
0212 crc = ~crc32_le(~0, buf, len);
0213
0214
0215 icv[0] = crc;
0216 icv[1] = crc >> 8;
0217 icv[2] = crc >> 16;
0218 icv[3] = crc >> 24;
0219
0220 for (k = 0; k < 4; k++) {
0221 i = (i + 1) & 0xff;
0222 j = (j + s[i]) & 0xff;
0223 swap(i, j);
0224 icv[k] ^= s[(s[i] + s[j]) & 0xff];
0225 }
0226
0227 return 0;
0228 }