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