config root man

Current Path : /usr/src/tools/regression/net80211/tkip/

FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64
Upload File :
Current File : //usr/src/tools/regression/net80211/tkip/test_tkip.c

/*-
 * Copyright (c) 2004 Sam Leffler, Errno Consulting
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD: release/9.1.0/tools/regression/net80211/tkip/test_tkip.c 145904 2005-05-05 13:16:30Z avatar $
 */

/*
 * TKIP test module.
 */
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/module.h>

#include <sys/socket.h>

#include <net/if.h>
#include <net/if_media.h>

#include <net80211/ieee80211_var.h>

/*
Key	12 34 56 78 90 12 34 56 78 90 12 34 56 78 90 12
	34 56 78 90 12 34 56 78 90 12 34 56 78 90 12 34
PN	0x000000000001
IV	00 20 01 20 00 00 00 00
Phase1	bb 58 07 1f 9e 93 b4 38 25 4b
Phase2	00 20 01 4c fe 67 be d2 7c 86 7b 1b f8 02 8b 1c 
*/

static const u_int8_t test1_key[] = {
	0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
	0x34, 0x56, 0x78, 0x90, 0x12,

	0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,		/* TX MIC */
	/*
	 * NB: 11i test vector specifies a RX MIC key different
	 *     from the TX key.  But this doesn't work to enmic,
	 *     encrypt, then decrypt, demic.  So instead we use
	 *     the same key for doing the MIC in each direction.
	 *
	 * XXX need additional vectors to test alternate MIC keys
	 */
#if 0
	0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34,		/* 11i RX MIC */
#else
	0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78,		/* TX copy */
#endif
};
static const u_int8_t test1_phase1[] = {
	0xbb, 0x58, 0x07, 0x1f, 0x9e, 0x93, 0xb4, 0x38, 0x25, 0x4b
};
static const u_int8_t test1_phase2[] = {
	0x00, 0x20, 0x01, 0x4c, 0xfe, 0x67, 0xbe, 0xd2, 0x7c, 0x86,
	0x7b, 0x1b, 0xf8, 0x02, 0x8b, 0x1c, 
};

/* Plaintext MPDU with MIC */
static const u_int8_t test1_plaintext[] = {
0x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07,
0x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,
0xaa,0xaa,0x03,0x00,0x00,0x00,0x08,0x00,0x45,0x00,0x00,0x54,0x00,0x00,0x40,0x00,
0x40,0x01,0xa5,0x55,0xc0,0xa8,0x0a,0x02,0xc0,0xa8,0x0a,0x01,0x08,0x00,0x3a,0xb0,
0x00,0x00,0x00,0x00,0xcd,0x4c,0x05,0x00,0x00,0x00,0x00,0x00,0x08,0x09,0x0a,0x0b,
0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,
0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,
0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
/* MIC */ 0x68,0x81,0xa3,0xf3,0xd6,0x48,0xd0,0x3c
};

/* Encrypted MPDU with MIC and ICV */
static const u_int8_t test1_encrypted[] = {
0x08,0x42,0x2c,0x00,0x02,0x03,0x04,0x05,0x06,0x08,0x02,0x03,0x04,0x05,0x06,0x07,
0x02,0x03,0x04,0x05,0x06,0x07,0xd0,0x02,0x00,0x20,0x01,0x20,0x00,0x00,0x00,0x00,
0xc0,0x0e,0x14,0xfc,0xe7,0xcf,0xab,0xc7,0x75,0x47,0xe6,0x66,0xe5,0x7c,0x0d,0xac,
0x70,0x4a,0x1e,0x35,0x8a,0x88,0xc1,0x1c,0x8e,0x2e,0x28,0x2e,0x38,0x01,0x02,0x7a,
0x46,0x56,0x05,0x5e,0xe9,0x3e,0x9c,0x25,0x47,0x02,0xe9,0x73,0x58,0x05,0xdd,0xb5,
0x76,0x9b,0xa7,0x3f,0x1e,0xbb,0x56,0xe8,0x44,0xef,0x91,0x22,0x85,0xd3,0xdd,0x6e,
0x54,0x1e,0x82,0x38,0x73,0x55,0x8a,0xdb,0xa0,0x79,0x06,0x8a,0xbd,0x7f,0x7f,0x50,
0x95,0x96,0x75,0xac,0xc4,0xb4,0xde,0x9a,0xa9,0x9c,0x05,0xf2,0x89,0xa7,0xc5,0x2f,
0xee,0x5b,0xfc,0x14,0xf6,0xf8,0xe5,0xf8
};

#define	TEST(n,name,cipher,keyix,pn) { \
	name, IEEE80211_CIPHER_##cipher,keyix, pn##LL, \
	test##n##_key,   sizeof(test##n##_key), \
	test##n##_phase1,   sizeof(test##n##_phase1), \
	test##n##_phase2,   sizeof(test##n##_phase2), \
	test##n##_plaintext, sizeof(test##n##_plaintext), \
	test##n##_encrypted, sizeof(test##n##_encrypted) \
}

struct ciphertest {
	const char	*name;
	int		cipher;
	int		keyix;
	u_int64_t	pn;
	const u_int8_t	*key;
	size_t		key_len;
	const u_int8_t	*phase1;
	size_t		phase1_len;
	const u_int8_t	*phase2;
	size_t		phase2_len;
	const u_int8_t	*plaintext;
	size_t		plaintext_len;
	const u_int8_t	*encrypted;
	size_t		encrypted_len;
} tkiptests[] = {
	TEST(1, "TKIP test mpdu 1", TKIP, 0, 0),
};

struct tkip_ctx {
	struct ieee80211com *tc_ic;	/* for diagnostics */

	uint16_t tx_ttak[5];
	int	tx_phase1_done;
	uint8_t	tx_rc4key[16];

	uint16_t rx_ttak[5];
	int	rx_phase1_done;
	uint8_t	rx_rc4key[16];
	uint64_t rx_rsc;		/* held until MIC verified */
};

static void
dumpdata(const char *tag, const void *p, size_t len)
{
	int i;

	printf("%s: 0x%p len %u", tag, p, len);
	for (i = 0; i < len; i++) {
		if ((i % 16) == 0)
			printf("\n%03d:", i);
		printf(" %02x", ((const u_int8_t *)p)[i]);
	}
	printf("\n");
}

static void
cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
{
	int i;

	for (i = 0; i < genlen; i++)
		if (((const u_int8_t *)gen)[i] != ((const u_int8_t *)ref)[i]) {
			printf("first difference at byte %u\n", i);
			break;
		}
	dumpdata("Generated", gen, genlen);
	dumpdata("Reference", ref, reflen);
}

static int
runtest(struct ieee80211com *ic, struct ciphertest *t)
{
	struct tkip_ctx *ctx;
	struct ieee80211_key key;
	struct mbuf *m = NULL;
	const struct ieee80211_cipher *cip;
	u_int8_t mac[IEEE80211_ADDR_LEN];
	u_int len;

	printf("%s: ", t->name);

	/*
	 * Setup key.
	 */
	memset(&key, 0, sizeof(key));
	key.wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
	key.wk_cipher = &ieee80211_cipher_none;
	if (!ieee80211_crypto_newkey(ic, IEEE80211_CIPHER_TKIP,
	    IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, &key)) {
		printf("FAIL: ieee80211_crypto_newkey failed\n");
		goto bad;
	}

	memcpy(key.wk_key, t->key, t->key_len);
	key.wk_keylen = 128/NBBY;
	key.wk_keyrsc = 0;
	key.wk_keytsc = t->pn;
	if (!ieee80211_crypto_setkey(ic, &key, mac)) {
		printf("FAIL: ieee80211_crypto_setkey failed\n");
		goto bad;
	}

	/*
	 * Craft frame from plaintext data.
	 */
	cip = key.wk_cipher;
	m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
	m->m_data += cip->ic_header;
	len = t->plaintext_len - IEEE80211_WEP_MICLEN;
	memcpy(mtod(m, void *), t->plaintext, len);
	m->m_len = len;
	m->m_pkthdr.len = m->m_len;

	/*
	 * Add MIC.
	 */
	if (!ieee80211_crypto_enmic(ic, &key, m)) {
		printf("FAIL: tkip enmic failed\n");
		goto bad;
	}
	/*
	 * Verify: frame length, frame contents.
	 */
	if (m->m_pkthdr.len != t->plaintext_len) {
		printf("FAIL: enmic botch; length mismatch\n");
		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
			t->plaintext, t->plaintext_len);
		goto bad;
	}
	if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
		printf("FAIL: enmic botch\n");
		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
			t->plaintext, t->plaintext_len);
		goto bad;
	}
	/*
	 * Encrypt frame w/ MIC.
	 */
	if (!cip->ic_encap(&key, m, t->keyix<<6)) {
		printf("FAIL: tkip encap failed\n");
		goto bad;
	}
	/*
	 * Verify: phase1, phase2, frame length, frame contents.
	 */
	ctx = key.wk_private;
	if (memcmp(ctx->tx_ttak, t->phase1, t->phase1_len)) {
		printf("FAIL: encrypt phase1 botch\n");
		cmpfail(ctx->tx_ttak, sizeof(ctx->tx_ttak),
			t->phase1, t->phase1_len);
		goto bad;
	} else if (memcmp(ctx->tx_rc4key, t->phase2, t->phase2_len)) {
		printf("FAIL: encrypt phase2 botch\n");
		cmpfail(ctx->tx_rc4key, sizeof(ctx->tx_rc4key),
			t->phase2, t->phase2_len);
		goto bad;
	} else if (m->m_pkthdr.len != t->encrypted_len) {
		printf("FAIL: encrypt data length mismatch\n");
		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
			t->encrypted, t->encrypted_len);
		goto bad;
	} else if (memcmp(mtod(m, const void *), t->encrypted, m->m_pkthdr.len)) {
		printf("FAIL: encrypt data does not compare\n");
		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
			t->encrypted, t->encrypted_len);
		dumpdata("Plaintext", t->plaintext, t->plaintext_len);
		goto bad;
	}

	/*
	 * Decrypt frame.
	 */
	if (!cip->ic_decap(&key, m)) {
		printf("tkip decap failed\n");
		/*
		 * Check reason for failure: phase1, phase2, frame data (ICV).
		 */
		if (memcmp(ctx->rx_ttak, t->phase1, t->phase1_len)) {
			printf("FAIL: decrypt phase1 botch\n");
			cmpfail(ctx->rx_ttak, sizeof(ctx->rx_ttak),
				t->phase1, t->phase1_len);
		} else if (memcmp(ctx->rx_rc4key, t->phase2, t->phase2_len)) {
			printf("FAIL: decrypt phase2 botch\n");
			cmpfail(ctx->rx_rc4key, sizeof(ctx->rx_rc4key),
				t->phase2, t->phase2_len);
		} else {
			printf("FAIL: decrypt data does not compare\n");
			cmpfail(mtod(m, const void *), m->m_pkthdr.len,
				t->plaintext, t->plaintext_len);
		}
		goto bad;
	}
	/*
	 * Verify: frame length, frame contents.
	 */
	if (m->m_pkthdr.len != t->plaintext_len) {
		printf("FAIL: decap botch; length mismatch\n");
		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
			t->plaintext, t->plaintext_len);
		goto bad;
	}
	if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
		printf("FAIL: decap botch; data does not compare\n");
		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
			t->plaintext, t->plaintext_len);
		goto bad;
	}
	/*
	 * De-MIC decrypted frame.
	 */
	if (!ieee80211_crypto_demic(ic, &key, m)) {
		printf("FAIL: tkip demic failed\n");
		goto bad;
	}
	/* XXX check frame length and contents... */
	printf("PASS\n");
	return 1;
bad:
	if (m != NULL)
		m_freem(m);
	ieee80211_crypto_delkey(ic, &key);
	return 0;
}

/*
 * Module glue.
 */

static	int debug = 0;
static	int tests = -1;

static int
init_crypto_tkip_test(void)
{
#define	N(a)	(sizeof(a)/sizeof(a[0]))
	struct ieee80211com ic;
	int i, pass, total;

	memset(&ic, 0, sizeof(ic));
	if (debug)
		ic.ic_debug = IEEE80211_MSG_CRYPTO;
	ieee80211_crypto_attach(&ic);

	pass = 0;
	total = 0;
	for (i = 0; i < N(tkiptests); i++)
		if (tests & (1<<i)) {
			total++;
			pass += runtest(&ic, &tkiptests[i]);
		}
	printf("%u of %u 802.11i TKIP test vectors passed\n", pass, total);
	ieee80211_crypto_detach(&ic);
	return (pass == total ? 0 : -1);
#undef N
}

static int
test_tkip_modevent(module_t mod, int type, void *unused)
{
	switch (type) {
	case MOD_LOAD:
		(void) init_crypto_tkip_test();
		return 0;
	case MOD_UNLOAD:
		return 0;
	}
	return EINVAL;
}

static moduledata_t test_tkip_mod = {
	"test_tkip",
	test_tkip_modevent,
	0
};
DECLARE_MODULE(test_tkip, test_tkip_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
MODULE_VERSION(test_tkip, 1);
MODULE_DEPEND(test_tkip, wlan, 1, 1, 1);

Man Man