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