]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/regression/net80211/tkip/test_tkip.c
Import mandoc 1.14.3
[FreeBSD/FreeBSD.git] / tools / regression / net80211 / tkip / test_tkip.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  * TKIP test module.
36  */
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/systm.h>
40 #include <sys/mbuf.h>
41 #include <sys/module.h>
42
43 #include <sys/socket.h>
44
45 #include <net/if.h>
46 #include <net/if_var.h>
47 #include <net/if_media.h>
48
49 #include <net80211/ieee80211_var.h>
50
51 /*
52 Key     12 34 56 78 90 12 34 56 78 90 12 34 56 78 90 12
53         34 56 78 90 12 34 56 78 90 12 34 56 78 90 12 34
54 PN      0x000000000001
55 IV      00 20 01 20 00 00 00 00
56 Phase1  bb 58 07 1f 9e 93 b4 38 25 4b
57 Phase2  00 20 01 4c fe 67 be d2 7c 86 7b 1b f8 02 8b 1c 
58 */
59
60 static const u_int8_t test1_key[] = {
61         0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
62         0x34, 0x56, 0x78, 0x90, 0x12,
63
64         0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,         /* TX MIC */
65         /*
66          * NB: 11i test vector specifies a RX MIC key different
67          *     from the TX key.  But this doesn't work to enmic,
68          *     encrypt, then decrypt, demic.  So instead we use
69          *     the same key for doing the MIC in each direction.
70          *
71          * XXX need additional vectors to test alternate MIC keys
72          */
73 #if 0
74         0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34,         /* 11i RX MIC */
75 #else
76         0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,         /* TX copy */
77 #endif
78 };
79 static const u_int8_t test1_phase1[] = {
80         0xbb, 0x58, 0x07, 0x1f, 0x9e, 0x93, 0xb4, 0x38, 0x25, 0x4b
81 };
82 static const u_int8_t test1_phase2[] = {
83         0x00, 0x20, 0x01, 0x4c, 0xfe, 0x67, 0xbe, 0xd2, 0x7c, 0x86,
84         0x7b, 0x1b, 0xf8, 0x02, 0x8b, 0x1c, 
85 };
86
87 /* Plaintext MPDU with MIC */
88 static const u_int8_t test1_plaintext[] = {
89 0x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07,
90 0x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,
91 0xaa,0xaa,0x03,0x00,0x00,0x00,0x08,0x00,0x45,0x00,0x00,0x54,0x00,0x00,0x40,0x00,
92 0x40,0x01,0xa5,0x55,0xc0,0xa8,0x0a,0x02,0xc0,0xa8,0x0a,0x01,0x08,0x00,0x3a,0xb0,
93 0x00,0x00,0x00,0x00,0xcd,0x4c,0x05,0x00,0x00,0x00,0x00,0x00,0x08,0x09,0x0a,0x0b,
94 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
95 0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,
96 0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
97 /* MIC */ 0x68,0x81,0xa3,0xf3,0xd6,0x48,0xd0,0x3c
98 };
99
100 /* Encrypted MPDU with MIC and ICV */
101 static const u_int8_t test1_encrypted[] = {
102 0x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07,
103 0x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,0x00,0x20,0x01,0x20,0x00,0x00,0x00,0x00,
104 0xc0,0x0e,0x14,0xfc,0xe7,0xcf,0xab,0xc7,0x75,0x47,0xe6,0x66,0xe5,0x7c,0x0d,0xac,
105 0x70,0x4a,0x1e,0x35,0x8a,0x88,0xc1,0x1c,0x8e,0x2e,0x28,0x2e,0x38,0x01,0x02,0x7a,
106 0x46,0x56,0x05,0x5e,0xe9,0x3e,0x9c,0x25,0x47,0x02,0xe9,0x73,0x58,0x05,0xdd,0xb5,
107 0x76,0x9b,0xa7,0x3f,0x1e,0xbb,0x56,0xe8,0x44,0xef,0x91,0x22,0x85,0xd3,0xdd,0x6e,
108 0x54,0x1e,0x82,0x38,0x73,0x55,0x8a,0xdb,0xa0,0x79,0x06,0x8a,0xbd,0x7f,0x7f,0x50,
109 0x95,0x96,0x75,0xac,0xc4,0xb4,0xde,0x9a,0xa9,0x9c,0x05,0xf2,0x89,0xa7,0xc5,0x2f,
110 0xee,0x5b,0xfc,0x14,0xf6,0xf8,0xe5,0xf8
111 };
112
113 #define TEST(n,name,cipher,keyix,pn) { \
114         name, IEEE80211_CIPHER_##cipher,keyix, pn##LL, \
115         test##n##_key,   sizeof(test##n##_key), \
116         test##n##_phase1,   sizeof(test##n##_phase1), \
117         test##n##_phase2,   sizeof(test##n##_phase2), \
118         test##n##_plaintext, sizeof(test##n##_plaintext), \
119         test##n##_encrypted, sizeof(test##n##_encrypted) \
120 }
121
122 struct ciphertest {
123         const char      *name;
124         int             cipher;
125         int             keyix;
126         u_int64_t       pn;
127         const u_int8_t  *key;
128         size_t          key_len;
129         const u_int8_t  *phase1;
130         size_t          phase1_len;
131         const u_int8_t  *phase2;
132         size_t          phase2_len;
133         const u_int8_t  *plaintext;
134         size_t          plaintext_len;
135         const u_int8_t  *encrypted;
136         size_t          encrypted_len;
137 } tkiptests[] = {
138         TEST(1, "TKIP test mpdu 1", TKIP, 0, 0),
139 };
140
141 struct tkip_ctx {
142         struct ieee80211com *tc_ic;     /* for diagnostics */
143
144         uint16_t tx_ttak[5];
145         uint8_t tx_rc4key[16];
146
147         uint16_t rx_ttak[5];
148         int     rx_phase1_done;
149         uint8_t rx_rc4key[16];
150         uint64_t rx_rsc;                /* held until MIC verified */
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 static int
182 runtest(struct ieee80211vap *vap, struct ciphertest *t)
183 {
184         struct tkip_ctx *ctx;
185         struct ieee80211_key *key = &vap->iv_nw_keys[t->keyix];
186         struct mbuf *m = NULL;
187         const struct ieee80211_cipher *cip;
188         u_int len;
189         int hdrlen;
190
191         printf("%s: ", t->name);
192
193         /*
194          * Setup key.
195          */
196         memset(key, 0, sizeof(*key));
197         key->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
198         key->wk_cipher = &ieee80211_cipher_none;
199         if (!ieee80211_crypto_newkey(vap, t->cipher,
200             IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, key)) {
201                 printf("FAIL: ieee80211_crypto_newkey failed\n");
202                 goto bad;
203         }
204
205         memcpy(key->wk_key, t->key, t->key_len);
206         key->wk_keylen = 128/NBBY;
207         memset(key->wk_keyrsc, 0, sizeof(key->wk_keyrsc));
208         key->wk_keytsc = t->pn;
209         if (!ieee80211_crypto_setkey(vap, key)) {
210                 printf("FAIL: ieee80211_crypto_setkey failed\n");
211                 goto bad;
212         }
213
214         /*
215          * Craft frame from plaintext data.
216          */
217         cip = key->wk_cipher;
218         m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
219         m->m_data += cip->ic_header;
220         len = t->plaintext_len - IEEE80211_WEP_MICLEN;
221         memcpy(mtod(m, void *), t->plaintext, len);
222         m->m_len = len;
223         m->m_pkthdr.len = m->m_len;
224         hdrlen = ieee80211_anyhdrsize(mtod(m, void *));
225
226         /*
227          * Add MIC.
228          */
229         if (!ieee80211_crypto_enmic(vap, key, m, 1)) {
230                 printf("FAIL: tkip enmic failed\n");
231                 goto bad;
232         }
233         /*
234          * Verify: frame length, frame contents.
235          */
236         if (m->m_pkthdr.len != t->plaintext_len) {
237                 printf("FAIL: enmic botch; length mismatch\n");
238                 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
239                         t->plaintext, t->plaintext_len);
240                 goto bad;
241         }
242         if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
243                 printf("FAIL: enmic botch\n");
244                 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
245                         t->plaintext, t->plaintext_len);
246                 goto bad;
247         }
248         /*
249          * Encrypt frame w/ MIC.
250          */
251         if (!cip->ic_encap(key, m)) {
252                 printf("FAIL: tkip encap failed\n");
253                 goto bad;
254         }
255         /*
256          * Verify: phase1, phase2, frame length, frame contents.
257          */
258         ctx = key->wk_private;
259         if (memcmp(ctx->tx_ttak, t->phase1, t->phase1_len)) {
260                 printf("FAIL: encrypt phase1 botch\n");
261                 cmpfail(ctx->tx_ttak, sizeof(ctx->tx_ttak),
262                         t->phase1, t->phase1_len);
263                 goto bad;
264         } else if (memcmp(ctx->tx_rc4key, t->phase2, t->phase2_len)) {
265                 printf("FAIL: encrypt phase2 botch\n");
266                 cmpfail(ctx->tx_rc4key, sizeof(ctx->tx_rc4key),
267                         t->phase2, t->phase2_len);
268                 goto bad;
269         } else if (m->m_pkthdr.len != t->encrypted_len) {
270                 printf("FAIL: encrypt data length mismatch\n");
271                 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
272                         t->encrypted, t->encrypted_len);
273                 goto bad;
274         } else if (memcmp(mtod(m, const void *), t->encrypted, m->m_pkthdr.len)) {
275                 printf("FAIL: encrypt data does not compare\n");
276                 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
277                         t->encrypted, t->encrypted_len);
278                 dumpdata("Plaintext", t->plaintext, t->plaintext_len);
279                 goto bad;
280         }
281
282         /*
283          * Decrypt frame.
284          */
285         if (!cip->ic_decap(key, m, hdrlen)) {
286                 printf("tkip decap failed\n");
287                 /*
288                  * Check reason for failure: phase1, phase2, frame data (ICV).
289                  */
290                 if (memcmp(ctx->rx_ttak, t->phase1, t->phase1_len)) {
291                         printf("FAIL: decrypt phase1 botch\n");
292                         cmpfail(ctx->rx_ttak, sizeof(ctx->rx_ttak),
293                                 t->phase1, t->phase1_len);
294                 } else if (memcmp(ctx->rx_rc4key, t->phase2, t->phase2_len)) {
295                         printf("FAIL: decrypt phase2 botch\n");
296                         cmpfail(ctx->rx_rc4key, sizeof(ctx->rx_rc4key),
297                                 t->phase2, t->phase2_len);
298                 } else {
299                         printf("FAIL: decrypt data does not compare\n");
300                         cmpfail(mtod(m, const void *), m->m_pkthdr.len,
301                                 t->plaintext, t->plaintext_len);
302                 }
303                 goto bad;
304         }
305         /*
306          * Verify: frame length, frame contents.
307          */
308         if (m->m_pkthdr.len != t->plaintext_len) {
309                 printf("FAIL: decap botch; length mismatch\n");
310                 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
311                         t->plaintext, t->plaintext_len);
312                 goto bad;
313         }
314         if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
315                 printf("FAIL: decap botch; data does not compare\n");
316                 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
317                         t->plaintext, t->plaintext_len);
318                 goto bad;
319         }
320         /*
321          * De-MIC decrypted frame.
322          */
323         if (!ieee80211_crypto_demic(vap, key, m, 1)) {
324                 printf("FAIL: tkip demic failed\n");
325                 goto bad;
326         }
327         /* XXX check frame length and contents... */
328         m_freem(m);
329         ieee80211_crypto_delkey(vap, key);
330         printf("PASS\n");
331         return 1;
332 bad:
333         if (m != NULL)
334                 m_freem(m);
335         ieee80211_crypto_delkey(vap, key);
336         return 0;
337 }
338
339 /*
340  * Module glue.
341  */
342
343 static  int debug = 0;
344 static  int tests = -1;
345
346 static int
347 init_crypto_tkip_test(void)
348 {
349         struct ieee80211com ic;
350         struct ieee80211vap vap;
351         struct ifnet ifp;
352         int i, pass, total;
353
354         memset(&ic, 0, sizeof(ic));
355         memset(&vap, 0, sizeof(vap));
356         memset(&ifp, 0, sizeof(ifp));
357
358         ieee80211_crypto_attach(&ic);
359
360         /* some minimal initialization */
361         strncpy(ifp.if_xname, "test_ccmp", sizeof(ifp.if_xname));
362         vap.iv_ic = &ic;
363         vap.iv_ifp = &ifp;
364         if (debug)
365                 vap.iv_debug = IEEE80211_MSG_CRYPTO;
366         ieee80211_crypto_vattach(&vap);
367
368         pass = 0;
369         total = 0;
370         for (i = 0; i < nitems(tkiptests); i++)
371                 if (tests & (1<<i)) {
372                         total++;
373                         pass += runtest(&vap, &tkiptests[i]);
374                 }
375         printf("%u of %u 802.11i TKIP test vectors passed\n", pass, total);
376
377         ieee80211_crypto_vdetach(&vap);
378         ieee80211_crypto_detach(&ic);
379
380         return (pass == total ? 0 : -1);
381 }
382
383 static int
384 test_tkip_modevent(module_t mod, int type, void *unused)
385 {
386         switch (type) {
387         case MOD_LOAD:
388                 (void) init_crypto_tkip_test();
389                 return 0;
390         case MOD_UNLOAD:
391                 return 0;
392         }
393         return EINVAL;
394 }
395
396 static moduledata_t test_tkip_mod = {
397         "test_tkip",
398         test_tkip_modevent,
399         0
400 };
401 DECLARE_MODULE(test_tkip, test_tkip_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
402 MODULE_VERSION(test_tkip, 1);
403 MODULE_DEPEND(test_tkip, wlan, 1, 1, 1);