Path: blob/main/tools/regression/net80211/wep/test_wep.c
48253 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* WEP test module.33*34* Test vectors come from section I.7.2 of P802.11i/D7.0, October 2003.35*36* To use this tester load the net80211 layer (either as a module or37* by statically configuring it into your kernel), then insmod this38* module. It should automatically run all test cases and print39* information for each. To run one or more tests you can specify a40* tests parameter to the module that is a bit mask of the set of tests41* you want; e.g. insmod wep_test tests=7 will run only test mpdu's42* 1, 2, and 3.43*/44#include <sys/param.h>45#include <sys/kernel.h>46#include <sys/systm.h>47#include <sys/mbuf.h>48#include <sys/module.h>4950#include <sys/socket.h>5152#include <net/if.h>53#include <net/if_var.h>54#include <net/if_media.h>5556#include <net80211/ieee80211_var.h>5758/*59MPDU data60aa aa 03 00 00 00 08 00 45 00 00 4e 66 1a 00 00 80 11 be 64 0a 00 01 22610a ff ff ff 00 89 00 89 00 3a 00 00 80 a6 01 10 00 01 00 00 00 00 00 006220 45 43 45 4a 45 48 45 43 46 43 45 50 46 45 45 49 45 46 46 43 43 41 436341 43 41 43 41 43 41 41 41 00 00 20 00 016465RC4 encryption is performed as follows:66176718 Key fb 02 9e 30 31 32 33 3468Plaintext69aa aa 03 00 00 00 08 00 45 00 00 4e 66 1a 00 00 80 11 be 64 0a 00 017022 0a ff ff ff 00 89 00 89 00 3a 00 00 80 a6 01 10 00 01 00 00 00 007100 00 20 45 43 45 4a 45 48 45 43 46 43 45 50 46 45 45 49 45 46 46 437243 41 43 41 43 41 43 41 43 41 41 41 00 00 20 00 01 1b d0 b6 0473Ciphertext74f6 9c 58 06 bd 6c e8 46 26 bc be fb 94 74 65 0a ad 1f 79 09 b0 f6 4d755f 58 a5 03 a2 58 b7 ed 22 eb 0e a6 49 30 d3 a0 56 a5 57 42 fc ce 14761d 48 5f 8a a8 36 de a1 8d f4 2c 53 80 80 5a d0 c6 1a 5d 6f 58 f4 107740 b2 4b 7d 1a 69 38 56 ed 0d 43 98 e7 ae e3 bf 0e 2a 2c a8 f778The plaintext consists of the MPDU data, followed by a 4-octet CRC-3279calculated over the MPDU data.8019 The expanded MPDU, after WEP encapsulation, is as follows:81208221 IV fb 02 9e 8083MPDU data84f6 9c 58 06 bd 6c e8 46 26 bc be fb 94 74 65 0a ad 1f 79 09 b0 f6 4d 5f 58 a58503 a2 58 b7 ed 22 eb 0e a6 49 30 d3 a0 56 a5 57 42 fc ce 14 1d 48 5f 8a a8 3686de a1 8d f4 2c 53 80 80 5a d0 c6 1a 5d 6f 58 f4 10 40 b2 4b 7d 1a 69 38 56 ed870d 43 98 e7 ae e3 bf 0e88ICV 2a 2c a8 f789*/90static const u_int8_t test1_key[] = { /* TK (w/o IV) */910x30, 0x31, 0x32, 0x33, 0x34,92};93static const u_int8_t test1_plaintext[] = { /* Plaintext MPDU */940x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28, /* 802.11 Header */950xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,960xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,970xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, /* Plaintext data */980x45, 0x00, 0x00, 0x4e, 0x66, 0x1a, 0x00, 0x00,990x80, 0x11, 0xbe, 0x64, 0x0a, 0x00, 0x01, 0x22,1000x0a, 0xff, 0xff, 0xff, 0x00, 0x89, 0x00, 0x89,1010x00, 0x3a, 0x00, 0x00, 0x80, 0xa6, 0x01, 0x10,1020x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1030x20, 0x45, 0x43, 0x45, 0x4a, 0x45, 0x48, 0x45,1040x43, 0x46, 0x43, 0x45, 0x50, 0x46, 0x45, 0x45,1050x49, 0x45, 0x46, 0x46, 0x43, 0x43, 0x41, 0x43,1060x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x41,1070x41, 0x00, 0x00, 0x20, 0x00, 0x01,108};109static const u_int8_t test1_encrypted[] = { /* Encrypted MPDU */1100x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,1110xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,1120xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,1130xfb, 0x02, 0x9e, 0x80, 0xf6, 0x9c, 0x58, 0x06,1140xbd, 0x6c, 0xe8, 0x46, 0x26, 0xbc, 0xbe, 0xfb,1150x94, 0x74, 0x65, 0x0a, 0xad, 0x1f, 0x79, 0x09,1160xb0, 0xf6, 0x4d, 0x5f, 0x58, 0xa5, 0x03, 0xa2,1170x58, 0xb7, 0xed, 0x22, 0xeb, 0x0e, 0xa6, 0x49,1180x30, 0xd3, 0xa0, 0x56, 0xa5, 0x57, 0x42, 0xfc,1190xce, 0x14, 0x1d, 0x48, 0x5f, 0x8a, 0xa8, 0x36,1200xde, 0xa1, 0x8d, 0xf4, 0x2c, 0x53, 0x80, 0x80,1210x5a, 0xd0, 0xc6, 0x1a, 0x5d, 0x6f, 0x58, 0xf4,1220x10, 0x40, 0xb2, 0x4b, 0x7d, 0x1a, 0x69, 0x38,1230x56, 0xed, 0x0d, 0x43, 0x98, 0xe7, 0xae, 0xe3,1240xbf, 0x0e, 0x2a, 0x2c, 0xa8, 0xf7,125};126127/* XXX fix byte order of iv */128#define TEST(n,name,cipher,keyix,iv0,iv1,iv2,iv3) { \129name, IEEE80211_CIPHER_##cipher,keyix, { iv2,iv1,iv0,iv3 }, \130test##n##_key, sizeof(test##n##_key), \131test##n##_plaintext, sizeof(test##n##_plaintext), \132test##n##_encrypted, sizeof(test##n##_encrypted) \133}134135struct ciphertest {136const char *name;137int cipher;138int keyix;139u_int8_t iv[4];140const u_int8_t *key;141size_t key_len;142const u_int8_t *plaintext;143size_t plaintext_len;144const u_int8_t *encrypted;145size_t encrypted_len;146} weptests[] = {147TEST(1, "WEP test mpdu 1", WEP, 2, 0xfb, 0x02, 0x9e, 0x80),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}177178struct wep_ctx_hw { /* for use with h/w support */179struct ieee80211vap *wc_vap; /* for diagnostics+statistics */180struct ieee80211com *wc_ic;181uint32_t wc_iv; /* initial vector for crypto */182};183184static int185runtest(struct ieee80211vap *vap, struct ciphertest *t)186{187struct ieee80211_key *key = &vap->iv_nw_keys[t->keyix];188struct mbuf *m = NULL;189const struct ieee80211_cipher *cip;190struct wep_ctx_hw *ctx;191int hdrlen;192193printf("%s: ", t->name);194195/*196* Setup key.197*/198memset(key, 0, sizeof(*key));199key->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;200key->wk_cipher = &ieee80211_cipher_none;201if (!ieee80211_crypto_newkey(vap, t->cipher,202IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, key)) {203printf("FAIL: ieee80211_crypto_newkey failed\n");204goto bad;205}206207memcpy(key->wk_key, t->key, t->key_len);208key->wk_keylen = t->key_len;209if (!ieee80211_crypto_setkey(vap, key)) {210printf("FAIL: ieee80211_crypto_setkey failed\n");211goto bad;212}213214/*215* Craft frame from plaintext data.216*/217cip = key->wk_cipher;218m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);219memcpy(mtod(m, void *), t->encrypted, t->encrypted_len);220m->m_len = t->encrypted_len;221m->m_pkthdr.len = m->m_len;222hdrlen = ieee80211_anyhdrsize(mtod(m, void *));223224/*225* Decrypt frame.226*/227if (!cip->ic_decap(key, m, hdrlen)) {228printf("FAIL: wep decap failed\n");229cmpfail(mtod(m, const void *), m->m_pkthdr.len,230t->plaintext, t->plaintext_len);231goto bad;232}233/*234* Verify: frame length, frame contents.235*/236if (m->m_pkthdr.len != t->plaintext_len) {237printf("FAIL: decap botch; length mismatch\n");238cmpfail(mtod(m, const void *), m->m_pkthdr.len,239t->plaintext, t->plaintext_len);240goto bad;241} else if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {242printf("FAIL: decap botch; data does not compare\n");243cmpfail(mtod(m, const void *), m->m_pkthdr.len,244t->plaintext, t->plaintext_len);245goto bad;246}247248/*249* Encrypt frame.250*/251ctx = (struct wep_ctx_hw *) key->wk_private;252ctx->wc_vap = vap;253ctx->wc_ic = vap->iv_ic;254memcpy(&ctx->wc_iv, t->iv, sizeof(t->iv)); /* for encap/encrypt */255if (!cip->ic_encap(key, m)) {256printf("FAIL: wep encap failed\n");257goto bad;258}259/*260* Verify: frame length, frame contents.261*/262if (m->m_pkthdr.len != t->encrypted_len) {263printf("FAIL: encap data length mismatch\n");264cmpfail(mtod(m, const void *), m->m_pkthdr.len,265t->encrypted, t->encrypted_len);266goto bad;267} else if (memcmp(mtod(m, const void *), t->encrypted, m->m_pkthdr.len)) {268printf("FAIL: encrypt data does not compare\n");269cmpfail(mtod(m, const void *), m->m_pkthdr.len,270t->encrypted, t->encrypted_len);271dumpdata("Plaintext", t->plaintext, t->plaintext_len);272goto bad;273}274m_freem(m);275ieee80211_crypto_delkey(vap, key);276printf("PASS\n");277return 1;278bad:279if (m != NULL)280m_freem(m);281ieee80211_crypto_delkey(vap, key);282return 0;283}284285/*286* Module glue.287*/288289static int tests = -1;290static int debug = 0;291292static int293init_crypto_wep_test(void)294{295struct ieee80211com ic;296struct ieee80211vap vap;297struct ifnet ifp;298int i, pass, total;299300memset(&ic, 0, sizeof(ic));301memset(&vap, 0, sizeof(vap));302memset(&ifp, 0, sizeof(ifp));303304ieee80211_crypto_attach(&ic);305306/* some minimal initialization */307strncpy(ifp.if_xname, "test_ccmp", sizeof(ifp.if_xname));308vap.iv_ic = ⁣309vap.iv_ifp = &ifp;310if (debug)311vap.iv_debug = IEEE80211_MSG_CRYPTO;312ieee80211_crypto_vattach(&vap);313314pass = 0;315total = 0;316for (i = 0; i < nitems(weptests); i++)317if (tests & (1<<i)) {318total++;319pass += runtest(&vap, &weptests[i]);320}321printf("%u of %u 802.11i WEP test vectors passed\n", pass, total);322323ieee80211_crypto_vdetach(&vap);324ieee80211_crypto_detach(&ic);325326return (pass == total ? 0 : -1);327}328329static int330test_wep_modevent(module_t mod, int type, void *unused)331{332switch (type) {333case MOD_LOAD:334(void) init_crypto_wep_test();335return 0;336case MOD_UNLOAD:337return 0;338}339return EINVAL;340}341342static moduledata_t test_wep_mod = {343"test_wep",344test_wep_modevent,3450346};347DECLARE_MODULE(test_wep, test_wep_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);348MODULE_VERSION(test_wep, 1);349MODULE_DEPEND(test_wep, wlan, 1, 1, 1);350351352