12efe996bSSam Leffler /*- 22efe996bSSam Leffler * Copyright (c) 2004 Sam Leffler, Errno Consulting 32efe996bSSam Leffler * All rights reserved. 42efe996bSSam Leffler * 52efe996bSSam Leffler * Redistribution and use in source and binary forms, with or without 62efe996bSSam Leffler * modification, are permitted provided that the following conditions 72efe996bSSam Leffler * are met: 82efe996bSSam Leffler * 1. Redistributions of source code must retain the above copyright 92efe996bSSam Leffler * notice, this list of conditions and the following disclaimer. 102efe996bSSam Leffler * 2. Redistributions in binary form must reproduce the above copyright 112efe996bSSam Leffler * notice, this list of conditions and the following disclaimer in the 122efe996bSSam Leffler * documentation and/or other materials provided with the distribution. 132efe996bSSam Leffler * 3. The name of the author may not be used to endorse or promote products 142efe996bSSam Leffler * derived from this software without specific prior written permission. 152efe996bSSam Leffler * 162efe996bSSam Leffler * Alternatively, this software may be distributed under the terms of the 172efe996bSSam Leffler * GNU General Public License ("GPL") version 2 as published by the Free 182efe996bSSam Leffler * Software Foundation. 192efe996bSSam Leffler * 202efe996bSSam Leffler * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 212efe996bSSam Leffler * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 222efe996bSSam Leffler * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 232efe996bSSam Leffler * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 242efe996bSSam Leffler * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 252efe996bSSam Leffler * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 262efe996bSSam Leffler * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 272efe996bSSam Leffler * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 282efe996bSSam Leffler * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 292efe996bSSam Leffler * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 302efe996bSSam Leffler * 312efe996bSSam Leffler * $FreeBSD$ 322efe996bSSam Leffler */ 332efe996bSSam Leffler 342efe996bSSam Leffler /* 352efe996bSSam Leffler * TKIP test module. 362efe996bSSam Leffler */ 372efe996bSSam Leffler #include <sys/param.h> 382efe996bSSam Leffler #include <sys/kernel.h> 392efe996bSSam Leffler #include <sys/systm.h> 402efe996bSSam Leffler #include <sys/mbuf.h> 412efe996bSSam Leffler #include <sys/module.h> 422efe996bSSam Leffler 432efe996bSSam Leffler #include <sys/socket.h> 442efe996bSSam Leffler 452efe996bSSam Leffler #include <net/if.h> 46*3c64fc9cSAndriy Voskoboinyk #include <net/if_var.h> 472efe996bSSam Leffler #include <net/if_media.h> 482efe996bSSam Leffler 492efe996bSSam Leffler #include <net80211/ieee80211_var.h> 502efe996bSSam Leffler 512efe996bSSam Leffler /* 522efe996bSSam Leffler Key 12 34 56 78 90 12 34 56 78 90 12 34 56 78 90 12 532efe996bSSam Leffler 34 56 78 90 12 34 56 78 90 12 34 56 78 90 12 34 542efe996bSSam Leffler PN 0x000000000001 552efe996bSSam Leffler IV 00 20 01 20 00 00 00 00 562efe996bSSam Leffler Phase1 bb 58 07 1f 9e 93 b4 38 25 4b 572efe996bSSam Leffler Phase2 00 20 01 4c fe 67 be d2 7c 86 7b 1b f8 02 8b 1c 582efe996bSSam Leffler */ 592efe996bSSam Leffler 602efe996bSSam Leffler static const u_int8_t test1_key[] = { 612efe996bSSam Leffler 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 622efe996bSSam Leffler 0x34, 0x56, 0x78, 0x90, 0x12, 632efe996bSSam Leffler 642efe996bSSam Leffler 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, /* TX MIC */ 652efe996bSSam Leffler /* 662efe996bSSam Leffler * NB: 11i test vector specifies a RX MIC key different 672efe996bSSam Leffler * from the TX key. But this doesn't work to enmic, 682efe996bSSam Leffler * encrypt, then decrypt, demic. So instead we use 692efe996bSSam Leffler * the same key for doing the MIC in each direction. 702efe996bSSam Leffler * 712efe996bSSam Leffler * XXX need additional vectors to test alternate MIC keys 722efe996bSSam Leffler */ 732efe996bSSam Leffler #if 0 742efe996bSSam Leffler 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, /* 11i RX MIC */ 752efe996bSSam Leffler #else 762efe996bSSam Leffler 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, /* TX copy */ 772efe996bSSam Leffler #endif 782efe996bSSam Leffler }; 792efe996bSSam Leffler static const u_int8_t test1_phase1[] = { 802efe996bSSam Leffler 0xbb, 0x58, 0x07, 0x1f, 0x9e, 0x93, 0xb4, 0x38, 0x25, 0x4b 812efe996bSSam Leffler }; 822efe996bSSam Leffler static const u_int8_t test1_phase2[] = { 832efe996bSSam Leffler 0x00, 0x20, 0x01, 0x4c, 0xfe, 0x67, 0xbe, 0xd2, 0x7c, 0x86, 842efe996bSSam Leffler 0x7b, 0x1b, 0xf8, 0x02, 0x8b, 0x1c, 852efe996bSSam Leffler }; 862efe996bSSam Leffler 872efe996bSSam Leffler /* Plaintext MPDU with MIC */ 882efe996bSSam Leffler static const u_int8_t test1_plaintext[] = { 892efe996bSSam Leffler 0x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07, 902efe996bSSam Leffler 0x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02, 912efe996bSSam Leffler 0xaa,0xaa,0x03,0x00,0x00,0x00,0x08,0x00,0x45,0x00,0x00,0x54,0x00,0x00,0x40,0x00, 922efe996bSSam Leffler 0x40,0x01,0xa5,0x55,0xc0,0xa8,0x0a,0x02,0xc0,0xa8,0x0a,0x01,0x08,0x00,0x3a,0xb0, 932efe996bSSam Leffler 0x00,0x00,0x00,0x00,0xcd,0x4c,0x05,0x00,0x00,0x00,0x00,0x00,0x08,0x09,0x0a,0x0b, 942efe996bSSam Leffler 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b, 952efe996bSSam Leffler 0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b, 962efe996bSSam Leffler 0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, 972efe996bSSam Leffler /* MIC */ 0x68,0x81,0xa3,0xf3,0xd6,0x48,0xd0,0x3c 982efe996bSSam Leffler }; 992efe996bSSam Leffler 1002efe996bSSam Leffler /* Encrypted MPDU with MIC and ICV */ 1012efe996bSSam Leffler static const u_int8_t test1_encrypted[] = { 1022efe996bSSam Leffler 0x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07, 1032efe996bSSam Leffler 0x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,0x00,0x20,0x01,0x20,0x00,0x00,0x00,0x00, 1042efe996bSSam Leffler 0xc0,0x0e,0x14,0xfc,0xe7,0xcf,0xab,0xc7,0x75,0x47,0xe6,0x66,0xe5,0x7c,0x0d,0xac, 1052efe996bSSam Leffler 0x70,0x4a,0x1e,0x35,0x8a,0x88,0xc1,0x1c,0x8e,0x2e,0x28,0x2e,0x38,0x01,0x02,0x7a, 1062efe996bSSam Leffler 0x46,0x56,0x05,0x5e,0xe9,0x3e,0x9c,0x25,0x47,0x02,0xe9,0x73,0x58,0x05,0xdd,0xb5, 1072efe996bSSam Leffler 0x76,0x9b,0xa7,0x3f,0x1e,0xbb,0x56,0xe8,0x44,0xef,0x91,0x22,0x85,0xd3,0xdd,0x6e, 1082efe996bSSam Leffler 0x54,0x1e,0x82,0x38,0x73,0x55,0x8a,0xdb,0xa0,0x79,0x06,0x8a,0xbd,0x7f,0x7f,0x50, 1092efe996bSSam Leffler 0x95,0x96,0x75,0xac,0xc4,0xb4,0xde,0x9a,0xa9,0x9c,0x05,0xf2,0x89,0xa7,0xc5,0x2f, 1102efe996bSSam Leffler 0xee,0x5b,0xfc,0x14,0xf6,0xf8,0xe5,0xf8 1112efe996bSSam Leffler }; 1122efe996bSSam Leffler 1132efe996bSSam Leffler #define TEST(n,name,cipher,keyix,pn) { \ 1142efe996bSSam Leffler name, IEEE80211_CIPHER_##cipher,keyix, pn##LL, \ 1152efe996bSSam Leffler test##n##_key, sizeof(test##n##_key), \ 1162efe996bSSam Leffler test##n##_phase1, sizeof(test##n##_phase1), \ 1172efe996bSSam Leffler test##n##_phase2, sizeof(test##n##_phase2), \ 1182efe996bSSam Leffler test##n##_plaintext, sizeof(test##n##_plaintext), \ 1192efe996bSSam Leffler test##n##_encrypted, sizeof(test##n##_encrypted) \ 1202efe996bSSam Leffler } 1212efe996bSSam Leffler 1222efe996bSSam Leffler struct ciphertest { 1232efe996bSSam Leffler const char *name; 1242efe996bSSam Leffler int cipher; 1252efe996bSSam Leffler int keyix; 1262efe996bSSam Leffler u_int64_t pn; 1272efe996bSSam Leffler const u_int8_t *key; 1282efe996bSSam Leffler size_t key_len; 1292efe996bSSam Leffler const u_int8_t *phase1; 1302efe996bSSam Leffler size_t phase1_len; 1312efe996bSSam Leffler const u_int8_t *phase2; 1322efe996bSSam Leffler size_t phase2_len; 1332efe996bSSam Leffler const u_int8_t *plaintext; 1342efe996bSSam Leffler size_t plaintext_len; 1352efe996bSSam Leffler const u_int8_t *encrypted; 1362efe996bSSam Leffler size_t encrypted_len; 1372efe996bSSam Leffler } tkiptests[] = { 1382efe996bSSam Leffler TEST(1, "TKIP test mpdu 1", TKIP, 0, 0), 1392efe996bSSam Leffler }; 1402efe996bSSam Leffler 1412efe996bSSam Leffler struct tkip_ctx { 1422efe996bSSam Leffler struct ieee80211com *tc_ic; /* for diagnostics */ 1432efe996bSSam Leffler 1442efe996bSSam Leffler uint16_t tx_ttak[5]; 1452efe996bSSam Leffler uint8_t tx_rc4key[16]; 1462efe996bSSam Leffler 1472efe996bSSam Leffler uint16_t rx_ttak[5]; 1482efe996bSSam Leffler int rx_phase1_done; 1492efe996bSSam Leffler uint8_t rx_rc4key[16]; 1502efe996bSSam Leffler uint64_t rx_rsc; /* held until MIC verified */ 1512efe996bSSam Leffler }; 1522efe996bSSam Leffler 1532efe996bSSam Leffler static void 1542efe996bSSam Leffler dumpdata(const char *tag, const void *p, size_t len) 1552efe996bSSam Leffler { 1562efe996bSSam Leffler int i; 1572efe996bSSam Leffler 1582efe996bSSam Leffler printf("%s: 0x%p len %u", tag, p, len); 1592efe996bSSam Leffler for (i = 0; i < len; i++) { 1602efe996bSSam Leffler if ((i % 16) == 0) 1612efe996bSSam Leffler printf("\n%03d:", i); 1622efe996bSSam Leffler printf(" %02x", ((const u_int8_t *)p)[i]); 1632efe996bSSam Leffler } 1642efe996bSSam Leffler printf("\n"); 1652efe996bSSam Leffler } 1662efe996bSSam Leffler 1672efe996bSSam Leffler static void 1682efe996bSSam Leffler cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen) 1692efe996bSSam Leffler { 1702efe996bSSam Leffler int i; 1712efe996bSSam Leffler 1722efe996bSSam Leffler for (i = 0; i < genlen; i++) 1732efe996bSSam Leffler if (((const u_int8_t *)gen)[i] != ((const u_int8_t *)ref)[i]) { 1742efe996bSSam Leffler printf("first difference at byte %u\n", i); 1752efe996bSSam Leffler break; 1762efe996bSSam Leffler } 1772efe996bSSam Leffler dumpdata("Generated", gen, genlen); 1782efe996bSSam Leffler dumpdata("Reference", ref, reflen); 1792efe996bSSam Leffler } 1802efe996bSSam Leffler 1812efe996bSSam Leffler static int 182*3c64fc9cSAndriy Voskoboinyk runtest(struct ieee80211vap *vap, struct ciphertest *t) 1832efe996bSSam Leffler { 1842efe996bSSam Leffler struct tkip_ctx *ctx; 185*3c64fc9cSAndriy Voskoboinyk struct ieee80211_key *key = &vap->iv_nw_keys[t->keyix]; 1862efe996bSSam Leffler struct mbuf *m = NULL; 1872efe996bSSam Leffler const struct ieee80211_cipher *cip; 1882efe996bSSam Leffler u_int len; 189*3c64fc9cSAndriy Voskoboinyk int hdrlen; 1902efe996bSSam Leffler 1912efe996bSSam Leffler printf("%s: ", t->name); 1922efe996bSSam Leffler 1932efe996bSSam Leffler /* 1942efe996bSSam Leffler * Setup key. 1952efe996bSSam Leffler */ 196*3c64fc9cSAndriy Voskoboinyk memset(key, 0, sizeof(*key)); 197*3c64fc9cSAndriy Voskoboinyk key->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV; 198*3c64fc9cSAndriy Voskoboinyk key->wk_cipher = &ieee80211_cipher_none; 199*3c64fc9cSAndriy Voskoboinyk if (!ieee80211_crypto_newkey(vap, t->cipher, 200*3c64fc9cSAndriy Voskoboinyk IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, key)) { 2012efe996bSSam Leffler printf("FAIL: ieee80211_crypto_newkey failed\n"); 2022efe996bSSam Leffler goto bad; 2032efe996bSSam Leffler } 2042efe996bSSam Leffler 205*3c64fc9cSAndriy Voskoboinyk memcpy(key->wk_key, t->key, t->key_len); 206*3c64fc9cSAndriy Voskoboinyk key->wk_keylen = 128/NBBY; 207*3c64fc9cSAndriy Voskoboinyk memset(key->wk_keyrsc, 0, sizeof(key->wk_keyrsc)); 208*3c64fc9cSAndriy Voskoboinyk key->wk_keytsc = t->pn; 209*3c64fc9cSAndriy Voskoboinyk if (!ieee80211_crypto_setkey(vap, key)) { 2102efe996bSSam Leffler printf("FAIL: ieee80211_crypto_setkey failed\n"); 2112efe996bSSam Leffler goto bad; 2122efe996bSSam Leffler } 2132efe996bSSam Leffler 2142efe996bSSam Leffler /* 2152efe996bSSam Leffler * Craft frame from plaintext data. 2162efe996bSSam Leffler */ 217*3c64fc9cSAndriy Voskoboinyk cip = key->wk_cipher; 2182efe996bSSam Leffler m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR); 2192efe996bSSam Leffler m->m_data += cip->ic_header; 2202efe996bSSam Leffler len = t->plaintext_len - IEEE80211_WEP_MICLEN; 2212efe996bSSam Leffler memcpy(mtod(m, void *), t->plaintext, len); 2222efe996bSSam Leffler m->m_len = len; 2232efe996bSSam Leffler m->m_pkthdr.len = m->m_len; 224*3c64fc9cSAndriy Voskoboinyk hdrlen = ieee80211_anyhdrsize(mtod(m, void *)); 2252efe996bSSam Leffler 2262efe996bSSam Leffler /* 2272efe996bSSam Leffler * Add MIC. 2282efe996bSSam Leffler */ 229*3c64fc9cSAndriy Voskoboinyk if (!ieee80211_crypto_enmic(vap, key, m, 1)) { 2302efe996bSSam Leffler printf("FAIL: tkip enmic failed\n"); 2312efe996bSSam Leffler goto bad; 2322efe996bSSam Leffler } 2332efe996bSSam Leffler /* 2342efe996bSSam Leffler * Verify: frame length, frame contents. 2352efe996bSSam Leffler */ 2362efe996bSSam Leffler if (m->m_pkthdr.len != t->plaintext_len) { 2372efe996bSSam Leffler printf("FAIL: enmic botch; length mismatch\n"); 2382efe996bSSam Leffler cmpfail(mtod(m, const void *), m->m_pkthdr.len, 2392efe996bSSam Leffler t->plaintext, t->plaintext_len); 2402efe996bSSam Leffler goto bad; 2412efe996bSSam Leffler } 2422efe996bSSam Leffler if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) { 2432efe996bSSam Leffler printf("FAIL: enmic botch\n"); 2442efe996bSSam Leffler cmpfail(mtod(m, const void *), m->m_pkthdr.len, 2452efe996bSSam Leffler t->plaintext, t->plaintext_len); 2462efe996bSSam Leffler goto bad; 2472efe996bSSam Leffler } 2482efe996bSSam Leffler /* 2492efe996bSSam Leffler * Encrypt frame w/ MIC. 2502efe996bSSam Leffler */ 251*3c64fc9cSAndriy Voskoboinyk if (!cip->ic_encap(key, m)) { 2522efe996bSSam Leffler printf("FAIL: tkip encap failed\n"); 2532efe996bSSam Leffler goto bad; 2542efe996bSSam Leffler } 2552efe996bSSam Leffler /* 2562efe996bSSam Leffler * Verify: phase1, phase2, frame length, frame contents. 2572efe996bSSam Leffler */ 258*3c64fc9cSAndriy Voskoboinyk ctx = key->wk_private; 2592efe996bSSam Leffler if (memcmp(ctx->tx_ttak, t->phase1, t->phase1_len)) { 2602efe996bSSam Leffler printf("FAIL: encrypt phase1 botch\n"); 2612efe996bSSam Leffler cmpfail(ctx->tx_ttak, sizeof(ctx->tx_ttak), 2622efe996bSSam Leffler t->phase1, t->phase1_len); 2632efe996bSSam Leffler goto bad; 2642efe996bSSam Leffler } else if (memcmp(ctx->tx_rc4key, t->phase2, t->phase2_len)) { 2652efe996bSSam Leffler printf("FAIL: encrypt phase2 botch\n"); 2662efe996bSSam Leffler cmpfail(ctx->tx_rc4key, sizeof(ctx->tx_rc4key), 2672efe996bSSam Leffler t->phase2, t->phase2_len); 2682efe996bSSam Leffler goto bad; 2692efe996bSSam Leffler } else if (m->m_pkthdr.len != t->encrypted_len) { 2702efe996bSSam Leffler printf("FAIL: encrypt data length mismatch\n"); 2712efe996bSSam Leffler cmpfail(mtod(m, const void *), m->m_pkthdr.len, 2722efe996bSSam Leffler t->encrypted, t->encrypted_len); 2732efe996bSSam Leffler goto bad; 2742efe996bSSam Leffler } else if (memcmp(mtod(m, const void *), t->encrypted, m->m_pkthdr.len)) { 2752efe996bSSam Leffler printf("FAIL: encrypt data does not compare\n"); 2762efe996bSSam Leffler cmpfail(mtod(m, const void *), m->m_pkthdr.len, 2772efe996bSSam Leffler t->encrypted, t->encrypted_len); 2782efe996bSSam Leffler dumpdata("Plaintext", t->plaintext, t->plaintext_len); 2792efe996bSSam Leffler goto bad; 2802efe996bSSam Leffler } 2812efe996bSSam Leffler 2822efe996bSSam Leffler /* 2832efe996bSSam Leffler * Decrypt frame. 2842efe996bSSam Leffler */ 285*3c64fc9cSAndriy Voskoboinyk if (!cip->ic_decap(key, m, hdrlen)) { 2862efe996bSSam Leffler printf("tkip decap failed\n"); 2872efe996bSSam Leffler /* 2882efe996bSSam Leffler * Check reason for failure: phase1, phase2, frame data (ICV). 2892efe996bSSam Leffler */ 2902efe996bSSam Leffler if (memcmp(ctx->rx_ttak, t->phase1, t->phase1_len)) { 2912efe996bSSam Leffler printf("FAIL: decrypt phase1 botch\n"); 2922efe996bSSam Leffler cmpfail(ctx->rx_ttak, sizeof(ctx->rx_ttak), 2932efe996bSSam Leffler t->phase1, t->phase1_len); 2942efe996bSSam Leffler } else if (memcmp(ctx->rx_rc4key, t->phase2, t->phase2_len)) { 2952efe996bSSam Leffler printf("FAIL: decrypt phase2 botch\n"); 2962efe996bSSam Leffler cmpfail(ctx->rx_rc4key, sizeof(ctx->rx_rc4key), 2972efe996bSSam Leffler t->phase2, t->phase2_len); 2982efe996bSSam Leffler } else { 2992efe996bSSam Leffler printf("FAIL: decrypt data does not compare\n"); 3002efe996bSSam Leffler cmpfail(mtod(m, const void *), m->m_pkthdr.len, 3012efe996bSSam Leffler t->plaintext, t->plaintext_len); 3022efe996bSSam Leffler } 3032efe996bSSam Leffler goto bad; 3042efe996bSSam Leffler } 3052efe996bSSam Leffler /* 3062efe996bSSam Leffler * Verify: frame length, frame contents. 3072efe996bSSam Leffler */ 3082efe996bSSam Leffler if (m->m_pkthdr.len != t->plaintext_len) { 3092efe996bSSam Leffler printf("FAIL: decap botch; length mismatch\n"); 3102efe996bSSam Leffler cmpfail(mtod(m, const void *), m->m_pkthdr.len, 3112efe996bSSam Leffler t->plaintext, t->plaintext_len); 3122efe996bSSam Leffler goto bad; 3132efe996bSSam Leffler } 3142efe996bSSam Leffler if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) { 3152efe996bSSam Leffler printf("FAIL: decap botch; data does not compare\n"); 3162efe996bSSam Leffler cmpfail(mtod(m, const void *), m->m_pkthdr.len, 3172efe996bSSam Leffler t->plaintext, t->plaintext_len); 3182efe996bSSam Leffler goto bad; 3192efe996bSSam Leffler } 3202efe996bSSam Leffler /* 3212efe996bSSam Leffler * De-MIC decrypted frame. 3222efe996bSSam Leffler */ 323*3c64fc9cSAndriy Voskoboinyk if (!ieee80211_crypto_demic(vap, key, m, 1)) { 3242efe996bSSam Leffler printf("FAIL: tkip demic failed\n"); 3252efe996bSSam Leffler goto bad; 3262efe996bSSam Leffler } 3272efe996bSSam Leffler /* XXX check frame length and contents... */ 328*3c64fc9cSAndriy Voskoboinyk m_freem(m); 329*3c64fc9cSAndriy Voskoboinyk ieee80211_crypto_delkey(vap, key); 3302efe996bSSam Leffler printf("PASS\n"); 3312efe996bSSam Leffler return 1; 3322efe996bSSam Leffler bad: 3332efe996bSSam Leffler if (m != NULL) 3342efe996bSSam Leffler m_freem(m); 335*3c64fc9cSAndriy Voskoboinyk ieee80211_crypto_delkey(vap, key); 3362efe996bSSam Leffler return 0; 3372efe996bSSam Leffler } 3382efe996bSSam Leffler 3392efe996bSSam Leffler /* 3402efe996bSSam Leffler * Module glue. 3412efe996bSSam Leffler */ 3422efe996bSSam Leffler 3432efe996bSSam Leffler static int debug = 0; 3442efe996bSSam Leffler static int tests = -1; 3452efe996bSSam Leffler 3462efe996bSSam Leffler static int 3472efe996bSSam Leffler init_crypto_tkip_test(void) 3482efe996bSSam Leffler { 3492efe996bSSam Leffler struct ieee80211com ic; 350*3c64fc9cSAndriy Voskoboinyk struct ieee80211vap vap; 351*3c64fc9cSAndriy Voskoboinyk struct ifnet ifp; 3522efe996bSSam Leffler int i, pass, total; 3532efe996bSSam Leffler 3542efe996bSSam Leffler memset(&ic, 0, sizeof(ic)); 355*3c64fc9cSAndriy Voskoboinyk memset(&vap, 0, sizeof(vap)); 356*3c64fc9cSAndriy Voskoboinyk memset(&ifp, 0, sizeof(ifp)); 357*3c64fc9cSAndriy Voskoboinyk 3582efe996bSSam Leffler ieee80211_crypto_attach(&ic); 3592efe996bSSam Leffler 360*3c64fc9cSAndriy Voskoboinyk /* some minimal initialization */ 361*3c64fc9cSAndriy Voskoboinyk strncpy(ifp.if_xname, "test_ccmp", sizeof(ifp.if_xname)); 362*3c64fc9cSAndriy Voskoboinyk vap.iv_ic = ⁣ 363*3c64fc9cSAndriy Voskoboinyk vap.iv_ifp = &ifp; 364*3c64fc9cSAndriy Voskoboinyk if (debug) 365*3c64fc9cSAndriy Voskoboinyk vap.iv_debug = IEEE80211_MSG_CRYPTO; 366*3c64fc9cSAndriy Voskoboinyk ieee80211_crypto_vattach(&vap); 367*3c64fc9cSAndriy Voskoboinyk 3682efe996bSSam Leffler pass = 0; 3692efe996bSSam Leffler total = 0; 370*3c64fc9cSAndriy Voskoboinyk for (i = 0; i < nitems(tkiptests); i++) 3712efe996bSSam Leffler if (tests & (1<<i)) { 3722efe996bSSam Leffler total++; 373*3c64fc9cSAndriy Voskoboinyk pass += runtest(&vap, &tkiptests[i]); 3742efe996bSSam Leffler } 3752efe996bSSam Leffler printf("%u of %u 802.11i TKIP test vectors passed\n", pass, total); 376*3c64fc9cSAndriy Voskoboinyk 377*3c64fc9cSAndriy Voskoboinyk ieee80211_crypto_vdetach(&vap); 3782efe996bSSam Leffler ieee80211_crypto_detach(&ic); 379*3c64fc9cSAndriy Voskoboinyk 3802efe996bSSam Leffler return (pass == total ? 0 : -1); 3812efe996bSSam Leffler } 3822efe996bSSam Leffler 3832efe996bSSam Leffler static int 3842efe996bSSam Leffler test_tkip_modevent(module_t mod, int type, void *unused) 3852efe996bSSam Leffler { 3862efe996bSSam Leffler switch (type) { 3872efe996bSSam Leffler case MOD_LOAD: 3882efe996bSSam Leffler (void) init_crypto_tkip_test(); 3892efe996bSSam Leffler return 0; 3902efe996bSSam Leffler case MOD_UNLOAD: 3912efe996bSSam Leffler return 0; 3922efe996bSSam Leffler } 3932efe996bSSam Leffler return EINVAL; 3942efe996bSSam Leffler } 3952efe996bSSam Leffler 3962efe996bSSam Leffler static moduledata_t test_tkip_mod = { 3972efe996bSSam Leffler "test_tkip", 3982efe996bSSam Leffler test_tkip_modevent, 3999823d527SKevin Lo 0 4002efe996bSSam Leffler }; 4012efe996bSSam Leffler DECLARE_MODULE(test_tkip, test_tkip_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 4022efe996bSSam Leffler MODULE_VERSION(test_tkip, 1); 4032efe996bSSam Leffler MODULE_DEPEND(test_tkip, wlan, 1, 1, 1); 404