Path: blob/main/tools/regression/net80211/tkip/test_tkip.c
105418 views
/*-1* Copyright (c) 2004 Sam Leffler, Errno Consulting2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. The name of the author may not be used to endorse or promote products13* derived from this software without specific prior written permission.14*15* Alternatively, this software may be distributed under the terms of the16* GNU General Public License ("GPL") version 2 as published by the Free17* Software Foundation.18*19* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR20* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES21* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.22* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,23* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT24* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,25* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY26* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT27* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF28* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29*/3031/*32* TKIP test module.33*/34#include <sys/param.h>35#include <sys/kernel.h>36#include <sys/systm.h>37#include <sys/mbuf.h>38#include <sys/module.h>3940#include <sys/socket.h>4142#include <net/if.h>43#include <net/if_var.h>44#include <net/if_media.h>4546#include <net80211/ieee80211_var.h>4748/*49Key 12 34 56 78 90 12 34 56 78 90 12 34 56 78 90 125034 56 78 90 12 34 56 78 90 12 34 56 78 90 12 3451PN 0x00000000000152IV 00 20 01 20 00 00 00 0053Phase1 bb 58 07 1f 9e 93 b4 38 25 4b54Phase2 00 20 01 4c fe 67 be d2 7c 86 7b 1b f8 02 8b 1c55*/5657static const u_int8_t test1_key[] = {580x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,590x34, 0x56, 0x78, 0x90, 0x12,60610x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, /* TX MIC */62/*63* NB: 11i test vector specifies a RX MIC key different64* from the TX key. But this doesn't work to enmic,65* encrypt, then decrypt, demic. So instead we use66* the same key for doing the MIC in each direction.67*68* XXX need additional vectors to test alternate MIC keys69*/70#if 0710x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, /* 11i RX MIC */72#else730x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, /* TX copy */74#endif75};76static const u_int8_t test1_phase1[] = {770xbb, 0x58, 0x07, 0x1f, 0x9e, 0x93, 0xb4, 0x38, 0x25, 0x4b78};79static const u_int8_t test1_phase2[] = {800x00, 0x20, 0x01, 0x4c, 0xfe, 0x67, 0xbe, 0xd2, 0x7c, 0x86,810x7b, 0x1b, 0xf8, 0x02, 0x8b, 0x1c,82};8384/* Plaintext MPDU with MIC */85static const u_int8_t test1_plaintext[] = {860x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07,870x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,880xaa,0xaa,0x03,0x00,0x00,0x00,0x08,0x00,0x45,0x00,0x00,0x54,0x00,0x00,0x40,0x00,890x40,0x01,0xa5,0x55,0xc0,0xa8,0x0a,0x02,0xc0,0xa8,0x0a,0x01,0x08,0x00,0x3a,0xb0,900x00,0x00,0x00,0x00,0xcd,0x4c,0x05,0x00,0x00,0x00,0x00,0x00,0x08,0x09,0x0a,0x0b,910x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,920x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,930x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,94/* MIC */ 0x68,0x81,0xa3,0xf3,0xd6,0x48,0xd0,0x3c95};9697/* Encrypted MPDU with MIC and ICV */98static const u_int8_t test1_encrypted[] = {990x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07,1000x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,0x00,0x20,0x01,0x20,0x00,0x00,0x00,0x00,1010xc0,0x0e,0x14,0xfc,0xe7,0xcf,0xab,0xc7,0x75,0x47,0xe6,0x66,0xe5,0x7c,0x0d,0xac,1020x70,0x4a,0x1e,0x35,0x8a,0x88,0xc1,0x1c,0x8e,0x2e,0x28,0x2e,0x38,0x01,0x02,0x7a,1030x46,0x56,0x05,0x5e,0xe9,0x3e,0x9c,0x25,0x47,0x02,0xe9,0x73,0x58,0x05,0xdd,0xb5,1040x76,0x9b,0xa7,0x3f,0x1e,0xbb,0x56,0xe8,0x44,0xef,0x91,0x22,0x85,0xd3,0xdd,0x6e,1050x54,0x1e,0x82,0x38,0x73,0x55,0x8a,0xdb,0xa0,0x79,0x06,0x8a,0xbd,0x7f,0x7f,0x50,1060x95,0x96,0x75,0xac,0xc4,0xb4,0xde,0x9a,0xa9,0x9c,0x05,0xf2,0x89,0xa7,0xc5,0x2f,1070xee,0x5b,0xfc,0x14,0xf6,0xf8,0xe5,0xf8108};109110#define TEST(n,name,cipher,keyix,pn) { \111name, IEEE80211_CIPHER_##cipher,keyix, pn##LL, \112test##n##_key, sizeof(test##n##_key), \113test##n##_phase1, sizeof(test##n##_phase1), \114test##n##_phase2, sizeof(test##n##_phase2), \115test##n##_plaintext, sizeof(test##n##_plaintext), \116test##n##_encrypted, sizeof(test##n##_encrypted) \117}118119struct ciphertest {120const char *name;121int cipher;122int keyix;123u_int64_t pn;124const u_int8_t *key;125size_t key_len;126const u_int8_t *phase1;127size_t phase1_len;128const u_int8_t *phase2;129size_t phase2_len;130const u_int8_t *plaintext;131size_t plaintext_len;132const u_int8_t *encrypted;133size_t encrypted_len;134} tkiptests[] = {135TEST(1, "TKIP test mpdu 1", TKIP, 0, 0),136};137138struct tkip_ctx {139struct ieee80211com *tc_ic; /* for diagnostics */140141uint16_t tx_ttak[5];142uint8_t tx_rc4key[16];143144uint16_t rx_ttak[5];145int rx_phase1_done;146uint8_t rx_rc4key[16];147uint64_t rx_rsc; /* held until MIC verified */148};149150static void151dumpdata(const char *tag, const void *p, size_t len)152{153int i;154155printf("%s: 0x%p len %u", tag, p, len);156for (i = 0; i < len; i++) {157if ((i % 16) == 0)158printf("\n%03d:", i);159printf(" %02x", ((const u_int8_t *)p)[i]);160}161printf("\n");162}163164static void165cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)166{167int i;168169for (i = 0; i < genlen; i++)170if (((const u_int8_t *)gen)[i] != ((const u_int8_t *)ref)[i]) {171printf("first difference at byte %u\n", i);172break;173}174dumpdata("Generated", gen, genlen);175dumpdata("Reference", ref, reflen);176}177178static int179runtest(struct ieee80211vap *vap, struct ciphertest *t)180{181struct tkip_ctx *ctx;182struct ieee80211_key *key = &vap->iv_nw_keys[t->keyix];183struct mbuf *m = NULL;184const struct ieee80211_cipher *cip;185u_int len;186int hdrlen;187188printf("%s: ", t->name);189190/*191* Setup key.192*/193memset(key, 0, sizeof(*key));194key->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;195key->wk_cipher = &ieee80211_cipher_none;196if (!ieee80211_crypto_newkey(vap, t->cipher,197IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, key)) {198printf("FAIL: ieee80211_crypto_newkey failed\n");199goto bad;200}201202memcpy(key->wk_key, t->key, t->key_len);203key->wk_keylen = 128/NBBY;204memset(key->wk_keyrsc, 0, sizeof(key->wk_keyrsc));205key->wk_keytsc = t->pn;206if (!ieee80211_crypto_setkey(vap, key)) {207printf("FAIL: ieee80211_crypto_setkey failed\n");208goto bad;209}210211/*212* Craft frame from plaintext data.213*/214cip = key->wk_cipher;215m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);216m->m_data += cip->ic_header;217len = t->plaintext_len - IEEE80211_WEP_MICLEN;218memcpy(mtod(m, void *), t->plaintext, len);219m->m_len = len;220m->m_pkthdr.len = m->m_len;221hdrlen = ieee80211_anyhdrsize(mtod(m, void *));222223/*224* Add MIC.225*/226if (!ieee80211_crypto_enmic(vap, key, m, 1)) {227printf("FAIL: tkip enmic failed\n");228goto bad;229}230/*231* Verify: frame length, frame contents.232*/233if (m->m_pkthdr.len != t->plaintext_len) {234printf("FAIL: enmic botch; length mismatch\n");235cmpfail(mtod(m, const void *), m->m_pkthdr.len,236t->plaintext, t->plaintext_len);237goto bad;238}239if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {240printf("FAIL: enmic botch\n");241cmpfail(mtod(m, const void *), m->m_pkthdr.len,242t->plaintext, t->plaintext_len);243goto bad;244}245/*246* Encrypt frame w/ MIC.247*/248if (!cip->ic_encap(key, m)) {249printf("FAIL: tkip encap failed\n");250goto bad;251}252/*253* Verify: phase1, phase2, frame length, frame contents.254*/255ctx = key->wk_private;256if (memcmp(ctx->tx_ttak, t->phase1, t->phase1_len)) {257printf("FAIL: encrypt phase1 botch\n");258cmpfail(ctx->tx_ttak, sizeof(ctx->tx_ttak),259t->phase1, t->phase1_len);260goto bad;261} else if (memcmp(ctx->tx_rc4key, t->phase2, t->phase2_len)) {262printf("FAIL: encrypt phase2 botch\n");263cmpfail(ctx->tx_rc4key, sizeof(ctx->tx_rc4key),264t->phase2, t->phase2_len);265goto bad;266} else if (m->m_pkthdr.len != t->encrypted_len) {267printf("FAIL: encrypt data length mismatch\n");268cmpfail(mtod(m, const void *), m->m_pkthdr.len,269t->encrypted, t->encrypted_len);270goto bad;271} else if (memcmp(mtod(m, const void *), t->encrypted, m->m_pkthdr.len)) {272printf("FAIL: encrypt data does not compare\n");273cmpfail(mtod(m, const void *), m->m_pkthdr.len,274t->encrypted, t->encrypted_len);275dumpdata("Plaintext", t->plaintext, t->plaintext_len);276goto bad;277}278279/*280* Decrypt frame.281*/282if (!cip->ic_decap(key, m, hdrlen)) {283printf("tkip decap failed\n");284/*285* Check reason for failure: phase1, phase2, frame data (ICV).286*/287if (memcmp(ctx->rx_ttak, t->phase1, t->phase1_len)) {288printf("FAIL: decrypt phase1 botch\n");289cmpfail(ctx->rx_ttak, sizeof(ctx->rx_ttak),290t->phase1, t->phase1_len);291} else if (memcmp(ctx->rx_rc4key, t->phase2, t->phase2_len)) {292printf("FAIL: decrypt phase2 botch\n");293cmpfail(ctx->rx_rc4key, sizeof(ctx->rx_rc4key),294t->phase2, t->phase2_len);295} else {296printf("FAIL: decrypt data does not compare\n");297cmpfail(mtod(m, const void *), m->m_pkthdr.len,298t->plaintext, t->plaintext_len);299}300goto bad;301}302/*303* Verify: frame length, frame contents.304*/305if (m->m_pkthdr.len != t->plaintext_len) {306printf("FAIL: decap botch; length mismatch\n");307cmpfail(mtod(m, const void *), m->m_pkthdr.len,308t->plaintext, t->plaintext_len);309goto bad;310}311if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {312printf("FAIL: decap botch; data does not compare\n");313cmpfail(mtod(m, const void *), m->m_pkthdr.len,314t->plaintext, t->plaintext_len);315goto bad;316}317/*318* De-MIC decrypted frame.319*/320if (!ieee80211_crypto_demic(vap, key, m, 1)) {321printf("FAIL: tkip demic failed\n");322goto bad;323}324/* XXX check frame length and contents... */325m_freem(m);326ieee80211_crypto_delkey(vap, key);327printf("PASS\n");328return 1;329bad:330if (m != NULL)331m_freem(m);332ieee80211_crypto_delkey(vap, key);333return 0;334}335336/*337* Module glue.338*/339340static int debug = 0;341static int tests = -1;342343static int344init_crypto_tkip_test(void)345{346struct ieee80211com ic;347struct ieee80211vap vap;348struct ifnet ifp;349int i, pass, total;350351memset(&ic, 0, sizeof(ic));352memset(&vap, 0, sizeof(vap));353memset(&ifp, 0, sizeof(ifp));354355ieee80211_crypto_attach(&ic);356357/* some minimal initialization */358strncpy(ifp.if_xname, "test_ccmp", sizeof(ifp.if_xname));359vap.iv_ic = ⁣360vap.iv_ifp = &ifp;361if (debug)362vap.iv_debug = IEEE80211_MSG_CRYPTO;363ieee80211_crypto_vattach(&vap);364365pass = 0;366total = 0;367for (i = 0; i < nitems(tkiptests); i++)368if (tests & (1<<i)) {369total++;370pass += runtest(&vap, &tkiptests[i]);371}372printf("%u of %u 802.11i TKIP test vectors passed\n", pass, total);373374ieee80211_crypto_vdetach(&vap);375ieee80211_crypto_detach(&ic);376377return (pass == total ? 0 : -1);378}379380static int381test_tkip_modevent(module_t mod, int type, void *unused)382{383switch (type) {384case MOD_LOAD:385(void) init_crypto_tkip_test();386return 0;387case MOD_UNLOAD:388return 0;389}390return EINVAL;391}392393static moduledata_t test_tkip_mod = {394"test_tkip",395test_tkip_modevent,3960397};398DECLARE_MODULE(test_tkip, test_tkip_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);399MODULE_VERSION(test_tkip, 1);400MODULE_DEPEND(test_tkip, wlan, 1, 1, 1);401402403