Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tools/regression/net80211/wep/test_wep.c
48253 views
1
/*-
2
* Copyright (c) 2004 Sam Leffler, Errno Consulting
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. The name of the author may not be used to endorse or promote products
14
* derived from this software without specific prior written permission.
15
*
16
* Alternatively, this software may be distributed under the terms of the
17
* GNU General Public License ("GPL") version 2 as published by the Free
18
* Software Foundation.
19
*
20
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
/*
33
* WEP test module.
34
*
35
* Test vectors come from section I.7.2 of P802.11i/D7.0, October 2003.
36
*
37
* To use this tester load the net80211 layer (either as a module or
38
* by statically configuring it into your kernel), then insmod this
39
* module. It should automatically run all test cases and print
40
* information for each. To run one or more tests you can specify a
41
* tests parameter to the module that is a bit mask of the set of tests
42
* you want; e.g. insmod wep_test tests=7 will run only test mpdu's
43
* 1, 2, and 3.
44
*/
45
#include <sys/param.h>
46
#include <sys/kernel.h>
47
#include <sys/systm.h>
48
#include <sys/mbuf.h>
49
#include <sys/module.h>
50
51
#include <sys/socket.h>
52
53
#include <net/if.h>
54
#include <net/if_var.h>
55
#include <net/if_media.h>
56
57
#include <net80211/ieee80211_var.h>
58
59
/*
60
MPDU data
61
aa aa 03 00 00 00 08 00 45 00 00 4e 66 1a 00 00 80 11 be 64 0a 00 01 22
62
0a ff ff ff 00 89 00 89 00 3a 00 00 80 a6 01 10 00 01 00 00 00 00 00 00
63
20 45 43 45 4a 45 48 45 43 46 43 45 50 46 45 45 49 45 46 46 43 43 41 43
64
41 43 41 43 41 43 41 41 41 00 00 20 00 01
65
66
RC4 encryption is performed as follows:
67
17
68
18 Key fb 02 9e 30 31 32 33 34
69
Plaintext
70
aa aa 03 00 00 00 08 00 45 00 00 4e 66 1a 00 00 80 11 be 64 0a 00 01
71
22 0a ff ff ff 00 89 00 89 00 3a 00 00 80 a6 01 10 00 01 00 00 00 00
72
00 00 20 45 43 45 4a 45 48 45 43 46 43 45 50 46 45 45 49 45 46 46 43
73
43 41 43 41 43 41 43 41 43 41 41 41 00 00 20 00 01 1b d0 b6 04
74
Ciphertext
75
f6 9c 58 06 bd 6c e8 46 26 bc be fb 94 74 65 0a ad 1f 79 09 b0 f6 4d
76
5f 58 a5 03 a2 58 b7 ed 22 eb 0e a6 49 30 d3 a0 56 a5 57 42 fc ce 14
77
1d 48 5f 8a a8 36 de a1 8d f4 2c 53 80 80 5a d0 c6 1a 5d 6f 58 f4 10
78
40 b2 4b 7d 1a 69 38 56 ed 0d 43 98 e7 ae e3 bf 0e 2a 2c a8 f7
79
The plaintext consists of the MPDU data, followed by a 4-octet CRC-32
80
calculated over the MPDU data.
81
19 The expanded MPDU, after WEP encapsulation, is as follows:
82
20
83
21 IV fb 02 9e 80
84
MPDU data
85
f6 9c 58 06 bd 6c e8 46 26 bc be fb 94 74 65 0a ad 1f 79 09 b0 f6 4d 5f 58 a5
86
03 a2 58 b7 ed 22 eb 0e a6 49 30 d3 a0 56 a5 57 42 fc ce 14 1d 48 5f 8a a8 36
87
de a1 8d f4 2c 53 80 80 5a d0 c6 1a 5d 6f 58 f4 10 40 b2 4b 7d 1a 69 38 56 ed
88
0d 43 98 e7 ae e3 bf 0e
89
ICV 2a 2c a8 f7
90
*/
91
static const u_int8_t test1_key[] = { /* TK (w/o IV) */
92
0x30, 0x31, 0x32, 0x33, 0x34,
93
};
94
static const u_int8_t test1_plaintext[] = { /* Plaintext MPDU */
95
0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28, /* 802.11 Header */
96
0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
97
0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
98
0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, /* Plaintext data */
99
0x45, 0x00, 0x00, 0x4e, 0x66, 0x1a, 0x00, 0x00,
100
0x80, 0x11, 0xbe, 0x64, 0x0a, 0x00, 0x01, 0x22,
101
0x0a, 0xff, 0xff, 0xff, 0x00, 0x89, 0x00, 0x89,
102
0x00, 0x3a, 0x00, 0x00, 0x80, 0xa6, 0x01, 0x10,
103
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104
0x20, 0x45, 0x43, 0x45, 0x4a, 0x45, 0x48, 0x45,
105
0x43, 0x46, 0x43, 0x45, 0x50, 0x46, 0x45, 0x45,
106
0x49, 0x45, 0x46, 0x46, 0x43, 0x43, 0x41, 0x43,
107
0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x41,
108
0x41, 0x00, 0x00, 0x20, 0x00, 0x01,
109
};
110
static const u_int8_t test1_encrypted[] = { /* Encrypted MPDU */
111
0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
112
0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
113
0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
114
0xfb, 0x02, 0x9e, 0x80, 0xf6, 0x9c, 0x58, 0x06,
115
0xbd, 0x6c, 0xe8, 0x46, 0x26, 0xbc, 0xbe, 0xfb,
116
0x94, 0x74, 0x65, 0x0a, 0xad, 0x1f, 0x79, 0x09,
117
0xb0, 0xf6, 0x4d, 0x5f, 0x58, 0xa5, 0x03, 0xa2,
118
0x58, 0xb7, 0xed, 0x22, 0xeb, 0x0e, 0xa6, 0x49,
119
0x30, 0xd3, 0xa0, 0x56, 0xa5, 0x57, 0x42, 0xfc,
120
0xce, 0x14, 0x1d, 0x48, 0x5f, 0x8a, 0xa8, 0x36,
121
0xde, 0xa1, 0x8d, 0xf4, 0x2c, 0x53, 0x80, 0x80,
122
0x5a, 0xd0, 0xc6, 0x1a, 0x5d, 0x6f, 0x58, 0xf4,
123
0x10, 0x40, 0xb2, 0x4b, 0x7d, 0x1a, 0x69, 0x38,
124
0x56, 0xed, 0x0d, 0x43, 0x98, 0xe7, 0xae, 0xe3,
125
0xbf, 0x0e, 0x2a, 0x2c, 0xa8, 0xf7,
126
};
127
128
/* XXX fix byte order of iv */
129
#define TEST(n,name,cipher,keyix,iv0,iv1,iv2,iv3) { \
130
name, IEEE80211_CIPHER_##cipher,keyix, { iv2,iv1,iv0,iv3 }, \
131
test##n##_key, sizeof(test##n##_key), \
132
test##n##_plaintext, sizeof(test##n##_plaintext), \
133
test##n##_encrypted, sizeof(test##n##_encrypted) \
134
}
135
136
struct ciphertest {
137
const char *name;
138
int cipher;
139
int keyix;
140
u_int8_t iv[4];
141
const u_int8_t *key;
142
size_t key_len;
143
const u_int8_t *plaintext;
144
size_t plaintext_len;
145
const u_int8_t *encrypted;
146
size_t encrypted_len;
147
} weptests[] = {
148
TEST(1, "WEP test mpdu 1", WEP, 2, 0xfb, 0x02, 0x9e, 0x80),
149
};
150
151
static void
152
dumpdata(const char *tag, const void *p, size_t len)
153
{
154
int i;
155
156
printf("%s: 0x%p len %u", tag, p, len);
157
for (i = 0; i < len; i++) {
158
if ((i % 16) == 0)
159
printf("\n%03d:", i);
160
printf(" %02x", ((const u_int8_t *)p)[i]);
161
}
162
printf("\n");
163
}
164
165
static void
166
cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
167
{
168
int i;
169
170
for (i = 0; i < genlen; i++)
171
if (((const u_int8_t *)gen)[i] != ((const u_int8_t *)ref)[i]) {
172
printf("first difference at byte %u\n", i);
173
break;
174
}
175
dumpdata("Generated", gen, genlen);
176
dumpdata("Reference", ref, reflen);
177
}
178
179
struct wep_ctx_hw { /* for use with h/w support */
180
struct ieee80211vap *wc_vap; /* for diagnostics+statistics */
181
struct ieee80211com *wc_ic;
182
uint32_t wc_iv; /* initial vector for crypto */
183
};
184
185
static int
186
runtest(struct ieee80211vap *vap, struct ciphertest *t)
187
{
188
struct ieee80211_key *key = &vap->iv_nw_keys[t->keyix];
189
struct mbuf *m = NULL;
190
const struct ieee80211_cipher *cip;
191
struct wep_ctx_hw *ctx;
192
int hdrlen;
193
194
printf("%s: ", t->name);
195
196
/*
197
* Setup key.
198
*/
199
memset(key, 0, sizeof(*key));
200
key->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
201
key->wk_cipher = &ieee80211_cipher_none;
202
if (!ieee80211_crypto_newkey(vap, t->cipher,
203
IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, key)) {
204
printf("FAIL: ieee80211_crypto_newkey failed\n");
205
goto bad;
206
}
207
208
memcpy(key->wk_key, t->key, t->key_len);
209
key->wk_keylen = t->key_len;
210
if (!ieee80211_crypto_setkey(vap, key)) {
211
printf("FAIL: ieee80211_crypto_setkey failed\n");
212
goto bad;
213
}
214
215
/*
216
* Craft frame from plaintext data.
217
*/
218
cip = key->wk_cipher;
219
m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
220
memcpy(mtod(m, void *), t->encrypted, t->encrypted_len);
221
m->m_len = t->encrypted_len;
222
m->m_pkthdr.len = m->m_len;
223
hdrlen = ieee80211_anyhdrsize(mtod(m, void *));
224
225
/*
226
* Decrypt frame.
227
*/
228
if (!cip->ic_decap(key, m, hdrlen)) {
229
printf("FAIL: wep decap failed\n");
230
cmpfail(mtod(m, const void *), m->m_pkthdr.len,
231
t->plaintext, t->plaintext_len);
232
goto bad;
233
}
234
/*
235
* Verify: frame length, frame contents.
236
*/
237
if (m->m_pkthdr.len != t->plaintext_len) {
238
printf("FAIL: decap botch; length mismatch\n");
239
cmpfail(mtod(m, const void *), m->m_pkthdr.len,
240
t->plaintext, t->plaintext_len);
241
goto bad;
242
} else if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
243
printf("FAIL: decap botch; data does not compare\n");
244
cmpfail(mtod(m, const void *), m->m_pkthdr.len,
245
t->plaintext, t->plaintext_len);
246
goto bad;
247
}
248
249
/*
250
* Encrypt frame.
251
*/
252
ctx = (struct wep_ctx_hw *) key->wk_private;
253
ctx->wc_vap = vap;
254
ctx->wc_ic = vap->iv_ic;
255
memcpy(&ctx->wc_iv, t->iv, sizeof(t->iv)); /* for encap/encrypt */
256
if (!cip->ic_encap(key, m)) {
257
printf("FAIL: wep encap failed\n");
258
goto bad;
259
}
260
/*
261
* Verify: frame length, frame contents.
262
*/
263
if (m->m_pkthdr.len != t->encrypted_len) {
264
printf("FAIL: encap data length mismatch\n");
265
cmpfail(mtod(m, const void *), m->m_pkthdr.len,
266
t->encrypted, t->encrypted_len);
267
goto bad;
268
} else if (memcmp(mtod(m, const void *), t->encrypted, m->m_pkthdr.len)) {
269
printf("FAIL: encrypt data does not compare\n");
270
cmpfail(mtod(m, const void *), m->m_pkthdr.len,
271
t->encrypted, t->encrypted_len);
272
dumpdata("Plaintext", t->plaintext, t->plaintext_len);
273
goto bad;
274
}
275
m_freem(m);
276
ieee80211_crypto_delkey(vap, key);
277
printf("PASS\n");
278
return 1;
279
bad:
280
if (m != NULL)
281
m_freem(m);
282
ieee80211_crypto_delkey(vap, key);
283
return 0;
284
}
285
286
/*
287
* Module glue.
288
*/
289
290
static int tests = -1;
291
static int debug = 0;
292
293
static int
294
init_crypto_wep_test(void)
295
{
296
struct ieee80211com ic;
297
struct ieee80211vap vap;
298
struct ifnet ifp;
299
int i, pass, total;
300
301
memset(&ic, 0, sizeof(ic));
302
memset(&vap, 0, sizeof(vap));
303
memset(&ifp, 0, sizeof(ifp));
304
305
ieee80211_crypto_attach(&ic);
306
307
/* some minimal initialization */
308
strncpy(ifp.if_xname, "test_ccmp", sizeof(ifp.if_xname));
309
vap.iv_ic = &ic;
310
vap.iv_ifp = &ifp;
311
if (debug)
312
vap.iv_debug = IEEE80211_MSG_CRYPTO;
313
ieee80211_crypto_vattach(&vap);
314
315
pass = 0;
316
total = 0;
317
for (i = 0; i < nitems(weptests); i++)
318
if (tests & (1<<i)) {
319
total++;
320
pass += runtest(&vap, &weptests[i]);
321
}
322
printf("%u of %u 802.11i WEP test vectors passed\n", pass, total);
323
324
ieee80211_crypto_vdetach(&vap);
325
ieee80211_crypto_detach(&ic);
326
327
return (pass == total ? 0 : -1);
328
}
329
330
static int
331
test_wep_modevent(module_t mod, int type, void *unused)
332
{
333
switch (type) {
334
case MOD_LOAD:
335
(void) init_crypto_wep_test();
336
return 0;
337
case MOD_UNLOAD:
338
return 0;
339
}
340
return EINVAL;
341
}
342
343
static moduledata_t test_wep_mod = {
344
"test_wep",
345
test_wep_modevent,
346
0
347
};
348
DECLARE_MODULE(test_wep, test_wep_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
349
MODULE_VERSION(test_wep, 1);
350
MODULE_DEPEND(test_wep, wlan, 1, 1, 1);
351
352