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 = ⁣ 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); 404