2 * Copyright (c) 2004 Sam Leffler, Errno Consulting
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
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.
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/systm.h>
41 #include <sys/module.h>
43 #include <sys/socket.h>
46 #include <net/if_media.h>
48 #include <net80211/ieee80211_var.h>
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
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
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,
63 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, /* TX MIC */
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.
70 * XXX need additional vectors to test alternate MIC keys
73 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, /* 11i RX MIC */
75 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, /* TX copy */
78 static const u_int8_t test1_phase1[] = {
79 0xbb, 0x58, 0x07, 0x1f, 0x9e, 0x93, 0xb4, 0x38, 0x25, 0x4b
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,
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
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
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) \
128 const u_int8_t *phase1;
130 const u_int8_t *phase2;
132 const u_int8_t *plaintext;
133 size_t plaintext_len;
134 const u_int8_t *encrypted;
135 size_t encrypted_len;
137 TEST(1, "TKIP test mpdu 1", TKIP, 0, 0),
141 struct ieee80211com *tc_ic; /* for diagnostics */
145 uint8_t tx_rc4key[16];
149 uint8_t rx_rc4key[16];
150 uint64_t rx_rsc; /* held until MIC verified */
154 dumpdata(const char *tag, const void *p, size_t len)
158 printf("%s: 0x%p len %u", tag, p, len);
159 for (i = 0; i < len; i++) {
161 printf("\n%03d:", i);
162 printf(" %02x", ((const u_int8_t *)p)[i]);
168 cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
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);
177 dumpdata("Generated", gen, genlen);
178 dumpdata("Reference", ref, reflen);
182 runtest(struct ieee80211com *ic, struct ciphertest *t)
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];
191 printf("%s: ", t->name);
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");
205 memcpy(key.wk_key, t->key, t->key_len);
206 key.wk_keylen = 128/NBBY;
208 key.wk_keytsc = t->pn;
209 if (!ieee80211_crypto_setkey(ic, &key, mac)) {
210 printf("FAIL: ieee80211_crypto_setkey failed\n");
215 * Craft frame from plaintext data.
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);
223 m->m_pkthdr.len = m->m_len;
228 if (!ieee80211_crypto_enmic(ic, &key, m)) {
229 printf("FAIL: tkip enmic failed\n");
233 * Verify: frame length, frame contents.
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);
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);
248 * Encrypt frame w/ MIC.
250 if (!cip->ic_encap(&key, m, t->keyix<<6)) {
251 printf("FAIL: tkip encap failed\n");
255 * Verify: phase1, phase2, frame length, frame contents.
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);
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);
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);
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);
284 if (!cip->ic_decap(&key, m)) {
285 printf("tkip decap failed\n");
287 * Check reason for failure: phase1, phase2, frame data (ICV).
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);
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);
305 * Verify: frame length, frame contents.
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);
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);
320 * De-MIC decrypted frame.
322 if (!ieee80211_crypto_demic(ic, &key, m)) {
323 printf("FAIL: tkip demic failed\n");
326 /* XXX check frame length and contents... */
332 ieee80211_crypto_delkey(ic, &key);
340 static int debug = 0;
341 static int tests = -1;
344 init_crypto_tkip_test(void)
346 #define N(a) (sizeof(a)/sizeof(a[0]))
347 struct ieee80211com ic;
350 memset(&ic, 0, sizeof(ic));
352 ic.ic_debug = IEEE80211_MSG_CRYPTO;
353 ieee80211_crypto_attach(&ic);
357 for (i = 0; i < N(tkiptests); i++)
358 if (tests & (1<<i)) {
360 pass += runtest(&ic, &tkiptests[i]);
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);
369 test_tkip_modevent(module_t mod, int type, void *unused)
373 (void) init_crypto_tkip_test();
381 static moduledata_t test_tkip_mod = {
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);