Update regression tests for current API, add makefiles

The new crypto API uses VAP, so allocate one.  Use keys from
vap->iv_nw_keys with the provided key index (0 for TKIP), don't allocate
another key on the stack.  Synchronize context structures with the
current code.

Return -ENXIO on failure.  It's hard to find a sensible code for crypto
test failure, but -1 (-EPERM) was misleading.  Fix TKIP test that was
ignoring failures.

Update module parameters for Linux 2.6.  Provide makefiles to facilitate
compilation.  Fix all sparse warnings.


git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@2983 0192ed92-7a03-0410-a25b-9323aeb14dbd
This commit is contained in:
proski 2007-11-27 21:40:19 +00:00
parent 4df2d580a7
commit 261fcaa170
7 changed files with 257 additions and 73 deletions

28
regression/Makefile Normal file
View File

@ -0,0 +1,28 @@
ifeq ($(obj),)
obj= .
endif
TOP = $(obj)/..
obj-y := ccmp/ tkip/ wep/
include $(TOP)/Makefile.inc
modules:
ifdef LINUX24
for i in $(obj-y); do \
$(MAKE) -C $$i || exit 1; \
done
else
$(MAKE) -C $(KERNELPATH) SUBDIRS=$(shell pwd) modules
endif
install:
for i in $(obj-y); do \
$(MAKE) -C $$i install || exit 1; \
done
clean:
for i in $(obj-y); do \
$(MAKE) -C $$i clean; \
done

34
regression/ccmp/Makefile Normal file
View File

@ -0,0 +1,34 @@
#
# Makefile for the CCMP regression test.
#
ifeq ($(obj),)
obj= .
endif
TOP = $(obj)/../..
obj-m += ath_test_ccmp.o
ath_test_ccmp-objs := test_ccmp.o
include $(TOP)/Makefile.inc
INCS += -I$(TOP) -I$(WLAN)
EXTRA_CFLAGS+= $(INCS) $(COPTS)
-include $(TOPDIR)/Rules.make
all:
$(MAKE) -C $(KERNELPATH) SUBDIRS=$(shell pwd) modules
install:
test -d $(DESTDIR)/$(KMODPATH) || mkdir -p $(DESTDIR)/$(KMODPATH)
install -m 0644 ath_test_ccmp.$(KMODSUF) $(DESTDIR)/$(KMODPATH)
clean:
-rm -f *~ *.o *.ko *.mod.c
-rm -f .depend .version .*.o.flags .*.o.d .*.o.cmd .*.ko.cmd
-rm -rf .tmp_versions
ath_test_ccmp.o: $(ath_test_ccmp-objs)
$(LD) $(LDOPTS) -o ath_test_ccmp.$(KMODSUF) -r $(ath_test_ccmp-objs)

View File

@ -528,7 +528,7 @@ static const u_int8_t test8_encrypted[] = { /* Encrypted MPDU with MIC */
test##n##_encrypted, sizeof(test##n##_encrypted) \
}
struct ciphertest {
static struct ciphertest {
const char *name;
int cipher;
int keyix;
@ -555,7 +555,7 @@ dumpdata(const char *tag, const void *p, size_t len)
{
int i;
printk("%s: 0x%p len %u", tag, p, len);
printk("%s: 0x%p len %zu", tag, p, len);
for (i = 0; i < len; i++) {
if ((i % 16) == 0)
printk("\n%03d:", i);
@ -578,32 +578,34 @@ cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
dumpdata("Reference", ref, reflen);
}
int
runtest(struct ieee80211com *ic, struct ciphertest *t)
static int
runtest(struct ieee80211vap *vap, struct ciphertest *t)
{
struct ieee80211_key key;
struct ieee80211_key *key;
struct sk_buff *skb = NULL;
const struct ieee80211_cipher *cip;
u_int8_t mac[IEEE80211_ADDR_LEN];
int hdrlen;
printk("%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, t->cipher, &key)) {
key = &vap->iv_nw_keys[t->keyix];
key->wk_keyix = t->keyix;
if (!ieee80211_crypto_newkey(vap, t->cipher,
IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV,
key)) {
printk("FAIL: ieee80211_crypto_newkey failed\n");
goto bad;
}
memcpy(key.wk_key, t->key, t->key_len);
key.wk_keylen = t->key_len;
key.wk_keyrsc = 0;
key.wk_keytsc = t->pn - 1; /* PN-1 since we do encap */
if (!ieee80211_crypto_setkey(ic, &key, mac)) {
memcpy(key->wk_key, t->key, t->key_len);
key->wk_keylen = t->key_len;
memset(key->wk_keyrsc, 0, sizeof(key->wk_keyrsc));
key->wk_keytsc = t->pn - 1; /* PN-1 since we do encap */
if (!ieee80211_crypto_setkey(vap, key, mac, NULL)) {
printk("FAIL: ieee80211_crypto_setkey failed\n");
goto bad;
}
@ -611,7 +613,7 @@ runtest(struct ieee80211com *ic, struct ciphertest *t)
/*
* Craft frame from plaintext data.
*/
cip = key.wk_cipher;
cip = key->wk_cipher;
skb = ieee80211_dev_alloc_skb(t->plaintext_len +
cip->ic_header + cip->ic_trailer);
if (skb == NULL) {
@ -624,7 +626,7 @@ runtest(struct ieee80211com *ic, struct ciphertest *t)
/*
* Encrypt frame w/ MIC.
*/
if (!(*cip->ic_encap)(&key, skb, t->keyix << 6)) {
if (!(*cip->ic_encap)(key, skb, t->keyix << 6)) {
printk("FAIL: ccmp encap failed\n");
goto bad;
}
@ -647,7 +649,8 @@ runtest(struct ieee80211com *ic, struct ciphertest *t)
/*
* Decrypt frame; strip MIC.
*/
if (!(*cip->ic_decap)(&key, skb)) {
hdrlen = ieee80211_hdrspace(vap->iv_ic, skb->data);
if (!(*cip->ic_decap)(key, skb, hdrlen)) {
printk("FAIL: ccmp decap failed\n");
cmpfail(skb->data, skb->len,
t->plaintext, t->plaintext_len);
@ -668,13 +671,13 @@ runtest(struct ieee80211com *ic, struct ciphertest *t)
goto bad;
}
ieee80211_dev_kfree_skb(&skb);
ieee80211_crypto_delkey(ic, &key);
ieee80211_crypto_delkey(vap, key, NULL);
printk("PASS\n");
return 1;
bad:
if (skb != NULL)
ieee80211_dev_kfree_skb(&skb);
ieee80211_crypto_delkey(ic, &key);
ieee80211_crypto_delkey(vap, key, NULL);
return 0;
}
@ -688,11 +691,18 @@ MODULE_LICENSE("Dual BSD/GPL");
#endif
static int tests = -1;
MODULE_PARM(tests, "i");
MODULE_PARM_DESC(tests, "Specify which tests to run");
static int debug = 0;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
MODULE_PARM(tests, "i");
MODULE_PARM(debug, "i");
#else
#include <linux/moduleparam.h>
module_param(tests, int, 0600);
module_param(debug, int, 0600);
#endif
MODULE_PARM_DESC(tests, "Specify which tests to run");
MODULE_PARM_DESC(debug, "Enable IEEE80211_MSG_CRYPTO");
static int __init
@ -700,23 +710,28 @@ init_crypto_ccmp_test(void)
{
#define N(a) (sizeof(a)/sizeof(a[0]))
struct ieee80211com ic;
struct ieee80211vap vap;
int i, pass, total;
memset(&ic, 0, sizeof(ic));
memset(&vap, 0, sizeof(vap));
vap.iv_ic = &ic;
if (debug)
ic.msg_enable = IEEE80211_MSG_CRYPTO;
vap.iv_debug = IEEE80211_MSG_CRYPTO;
ieee80211_crypto_attach(&ic);
ieee80211_crypto_vattach(&vap);
pass = 0;
total = 0;
for (i = 0; i < N(ccmptests); i++)
if (tests & (1 << i)) {
total++;
pass += runtest(&ic, &ccmptests[i]);
pass += runtest(&vap, &ccmptests[i]);
}
printk("%u of %u 802.11i AES-CCMP test vectors passed\n", pass, total);
ieee80211_crypto_vdetach(&vap);
ieee80211_crypto_detach(&ic);
return (pass == total ? 0 : -1);
return (pass == total ? 0 : -ENXIO);
#undef N
}
module_init(init_crypto_ccmp_test);

34
regression/tkip/Makefile Normal file
View File

@ -0,0 +1,34 @@
#
# Makefile for the TKIP regression test.
#
ifeq ($(obj),)
obj= .
endif
TOP = $(obj)/../..
obj-m += ath_test_tkip.o
ath_test_tkip-objs := test_tkip.o
include $(TOP)/Makefile.inc
INCS += -I$(TOP) -I$(WLAN)
EXTRA_CFLAGS+= $(INCS) $(COPTS)
-include $(TOPDIR)/Rules.make
all:
$(MAKE) -C $(KERNELPATH) SUBDIRS=$(shell pwd) modules
install:
test -d $(DESTDIR)/$(KMODPATH) || mkdir -p $(DESTDIR)/$(KMODPATH)
install -m 0644 ath_test_tkip.$(KMODSUF) $(DESTDIR)/$(KMODPATH)
clean:
-rm -f *~ *.o *.ko *.mod.c
-rm -f .depend .version .*.o.flags .*.o.d .*.o.cmd .*.ko.cmd
-rm -rf .tmp_versions
ath_test_tkip.o: $(ath_test_tkip-objs)
$(LD) $(LDOPTS) -o ath_test_tkip.$(KMODSUF) -r $(ath_test_tkip-objs)

View File

@ -109,7 +109,8 @@ static const u_int8_t ref_encrypted[] = {
};
struct tkip_ctx {
struct ieee80211com *tc_ic; /* for diagnostics */
struct ieee80211vap *tc_vap; /* for diagnostics + statistics */
struct ieee80211com *tc_ic;
u16 tx_ttak[5];
int tx_phase1_done;
@ -126,7 +127,7 @@ dumpdata(const char *tag, const void *p, size_t len)
{
int i;
printk("%s: 0x%p len %u", tag, p, len);
printk("%s: 0x%p len %zu", tag, p, len);
for (i = 0; i < len; i++) {
if ((i % 16) == 0)
printk("\n%03d:", i);
@ -149,31 +150,34 @@ cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
dumpdata("Reference", ref, reflen);
}
void
tkip_test(struct ieee80211com *ic)
static int
tkip_test(struct ieee80211vap *vap)
{
struct tkip_ctx *ctx;
struct ieee80211_key key;
struct ieee80211_key *key;
struct sk_buff *skb = NULL;
const struct ieee80211_cipher *cip;
u_int8_t mac[IEEE80211_ADDR_LEN];
int hdrlen;
const int keyix = 0;
/*
* 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, &key)) {
key = &vap->iv_nw_keys[keyix];
key->wk_keyix = keyix;
if (!ieee80211_crypto_newkey(vap, IEEE80211_CIPHER_TKIP,
IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV,
key)) {
printk("ieee80211_crypto_newkey failed\n");
goto bad;
}
memcpy(key.wk_key, ref_key, sizeof(ref_key));
key.wk_keylen = 128 / NBBY;
key.wk_keyrsc = 0;
key.wk_keytsc = 0;
if (!ieee80211_crypto_setkey(ic, &key, mac)) {
memcpy(key->wk_key, ref_key, sizeof(ref_key));
key->wk_keylen = 128 / NBBY;
memset(key->wk_keyrsc, 0, sizeof(key->wk_keyrsc));
key->wk_keytsc = 0;
if (!ieee80211_crypto_setkey(vap, key, mac, NULL)) {
printk("ieee80211_crypto_setkey failed\n");
goto bad;
}
@ -183,7 +187,7 @@ tkip_test(struct ieee80211com *ic)
* we leave the MIC off as we'll add it ourself
* and then check it against the reference data.
*/
cip = key.wk_cipher;
cip = key->wk_cipher;
skb = ieee80211_dev_alloc_skb(sizeof(ref_plaintext) +
cip->ic_miclen + cip->ic_header + cip->ic_trailer);
if (skb == NULL) {
@ -197,7 +201,7 @@ tkip_test(struct ieee80211com *ic)
/*
* Add MIC.
*/
if (!ieee80211_crypto_enmic(ic, &key, skb)) {
if (!ieee80211_crypto_enmic(vap, key, skb, 0)) {
printk("tkip enmic failed\n");
goto bad;
}
@ -219,14 +223,14 @@ tkip_test(struct ieee80211com *ic)
/*
* Encrypt frame w/ MIC.
*/
if (!(*cip->ic_encap)(&key, skb, 0 << 6)) {
if (!(*cip->ic_encap)(key, skb, 0 << 6)) {
printk("tkip encap failed\n");
goto bad;
}
/*
* Verify: phase1, phase2, frame length, frame contents.
*/
ctx = key.wk_private;
ctx = key->wk_private;
if (memcmp(ctx->tx_ttak, ref_phase1, sizeof(ref_phase1))) {
printk("encrypt phase1 botch\n");
cmpfail(ctx->tx_ttak, sizeof(ctx->tx_ttak),
@ -253,7 +257,8 @@ tkip_test(struct ieee80211com *ic)
/*
* Decrypt frame.
*/
if (!(*cip->ic_decap)(&key, skb)) {
hdrlen = ieee80211_hdrspace(vap->iv_ic, skb->data);
if (!(*cip->ic_decap)(key, skb, hdrlen)) {
printk("tkip decap failed\n");
/*
* Check reason for failure: phase1, phase2, frame data (ICV).
@ -291,16 +296,20 @@ tkip_test(struct ieee80211com *ic)
/*
* De-MIC decrypted frame.
*/
if (!ieee80211_crypto_demic(ic, &key, skb)) {
if (!ieee80211_crypto_demic(vap, key, skb, hdrlen)) {
printk("tkip demic failed\n");
goto bad;
}
/* XXX check frame length and contents... */
ieee80211_dev_kfree_skb(&skb);
ieee80211_crypto_delkey(vap, key, NULL);
printk("802.11i TKIP test vectors passed\n");
return 1;
bad:
if (skb != NULL)
ieee80211_dev_kfree_skb(&skb);
ieee80211_crypto_delkey(ic, &key);
ieee80211_crypto_delkey(vap, key, NULL);
return 0;
}
/*
@ -313,23 +322,37 @@ MODULE_LICENSE("Dual BSD/GPL");
#endif
static int debug = 0;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
MODULE_PARM(debug, "i");
#else
#include <linux/moduleparam.h>
module_param(debug, int, 0600);
#endif
MODULE_PARM_DESC(debug, "Enable IEEE80211_MSG_CRYPTO");
static int __init
init_crypto_tkip_test(void)
{
struct ieee80211com ic;
struct ieee80211vap vap;
int pass = 0;
const int total = 1;
memset(&ic, 0, sizeof(ic));
memset(&vap, 0, sizeof(vap));
vap.iv_ic = &ic;
if (debug)
ic.msg_enable = IEEE80211_MSG_CRYPTO;
vap.iv_debug = IEEE80211_MSG_CRYPTO;
ieee80211_crypto_attach(&ic);
ieee80211_crypto_vattach(&vap);
tkip_test(&ic);
pass += tkip_test(&vap);
ieee80211_crypto_vdetach(&vap);
ieee80211_crypto_detach(&ic);
return 0;
return (pass == total ? 0 : -ENXIO);
}
module_init(init_crypto_tkip_test);

34
regression/wep/Makefile Normal file
View File

@ -0,0 +1,34 @@
#
# Makefile for the WEP regression test.
#
ifeq ($(obj),)
obj= .
endif
TOP = $(obj)/../..
obj-m += ath_test_wep.o
ath_test_wep-objs := test_wep.o
include $(TOP)/Makefile.inc
INCS += -I$(TOP) -I$(WLAN)
EXTRA_CFLAGS+= $(INCS) $(COPTS)
-include $(TOPDIR)/Rules.make
all:
$(MAKE) -C $(KERNELPATH) SUBDIRS=$(shell pwd) modules
install:
test -d $(DESTDIR)/$(KMODPATH) || mkdir -p $(DESTDIR)/$(KMODPATH)
install -m 0644 ath_test_wep.$(KMODSUF) $(DESTDIR)/$(KMODPATH)
clean:
-rm -f *~ *.o *.ko *.mod.c
-rm -f .depend .version .*.o.flags .*.o.d .*.o.cmd .*.ko.cmd
-rm -rf .tmp_versions
ath_test_wep.o: $(ath_test_wep-objs)
$(LD) $(LDOPTS) -o ath_test_wep.$(KMODSUF) -r $(ath_test_wep-objs)

View File

@ -133,7 +133,7 @@ static const u_int8_t test1_encrypted[] = { /* Encrypted MPDU */
test##n##_encrypted, sizeof(test##n##_encrypted) \
}
struct ciphertest {
static struct ciphertest {
const char *name;
int cipher;
int keyix;
@ -153,7 +153,7 @@ dumpdata(const char *tag, const void *p, size_t len)
{
int i;
printk("%s: 0x%p len %u", tag, p, len);
printk("%s: 0x%p len %zu", tag, p, len);
for (i = 0; i < len; i++) {
if ((i % 16) == 0)
printk("\n%03d:", i);
@ -177,39 +177,42 @@ cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
}
struct wep_ctx_hw { /* for use with h/w support */
struct ieee80211vap *wc_vap; /* for diagnostics + statistics */
struct ieee80211com *wc_ic; /* for diagnostics */
u_int32_t wc_iv; /* initial vector for crypto */
};
int
runtest(struct ieee80211com *ic, struct ciphertest *t)
static int
runtest(struct ieee80211vap *vap, struct ciphertest *t)
{
struct ieee80211_key key;
struct ieee80211_key *key;
struct sk_buff *skb = NULL;
const struct ieee80211_cipher *cip;
u_int8_t mac[IEEE80211_ADDR_LEN];
struct wep_ctx_hw *ctx;
int hdrlen;
printk("%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, t->cipher, &key)) {
key = &vap->iv_nw_keys[t->keyix];
key->wk_keyix = t->keyix;
if (!ieee80211_crypto_newkey(vap, t->cipher,
IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV,
key)) {
printk("FAIL: ieee80211_crypto_newkey failed\n");
goto bad;
}
memcpy(key.wk_key, t->key, t->key_len);
key.wk_keylen = t->key_len;
if (!ieee80211_crypto_setkey(ic, &key, mac)) {
memcpy(key->wk_key, t->key, t->key_len);
key->wk_keylen = t->key_len;
if (!ieee80211_crypto_setkey(vap, key, mac, NULL)) {
printk("FAIL: ieee80211_crypto_setkey failed\n");
goto bad;
}
cip = key.wk_cipher;
cip = key->wk_cipher;
/*
* Craft encrypted frame from known data.
@ -224,7 +227,8 @@ runtest(struct ieee80211com *ic, struct ciphertest *t)
/*
* Decrypt frame.
*/
if (!(*cip->ic_decap)(&key, skb)) {
hdrlen = ieee80211_hdrspace(vap->iv_ic, skb->data);
if (!(*cip->ic_decap)(key, skb, hdrlen)) {
printk("FAIL: wep decap failed\n");
cmpfail(skb->data, skb->len,
t->plaintext, t->plaintext_len);
@ -248,9 +252,9 @@ runtest(struct ieee80211com *ic, struct ciphertest *t)
/*
* Encrypt frame.
*/
ctx = (struct wep_ctx_hw *) key.wk_private;
ctx = (struct wep_ctx_hw *) key->wk_private;
memcpy(&ctx->wc_iv, t->iv, sizeof(t->iv)); /* for encap/encrypt */
if (!(*cip->ic_encap)(&key, skb, t->keyix << 6)) {
if (!(*cip->ic_encap)(key, skb, t->keyix << 6)) {
printk("FAIL: wep encap failed\n");
goto bad;
}
@ -271,13 +275,13 @@ runtest(struct ieee80211com *ic, struct ciphertest *t)
}
if (skb != NULL)
ieee80211_dev_kfree_skb(&skb);
ieee80211_crypto_delkey(ic, &key);
ieee80211_crypto_delkey(vap, key, NULL);
printk("PASS\n");
return 1;
bad:
if (skb != NULL)
ieee80211_dev_kfree_skb(&skb);
ieee80211_crypto_delkey(ic, &key);
ieee80211_crypto_delkey(vap, key, NULL);
return 0;
}
@ -291,11 +295,18 @@ MODULE_LICENSE("Dual BSD/GPL");
#endif
static int tests = -1;
MODULE_PARM(tests, "i");
MODULE_PARM_DESC(tests, "Specify which tests to run");
static int debug = 0;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
MODULE_PARM(tests, "i");
MODULE_PARM(debug, "i");
#else
#include <linux/moduleparam.h>
module_param(tests, int, 0600);
module_param(debug, int, 0600);
#endif
MODULE_PARM_DESC(tests, "Specify which tests to run");
MODULE_PARM_DESC(debug, "Enable IEEE80211_MSG_CRYPTO");
static int __init
@ -303,22 +314,27 @@ init_crypto_wep_test(void)
{
#define N(a) (sizeof(a)/sizeof(a[0]))
struct ieee80211com ic;
struct ieee80211vap vap;
int i, pass, total;
memset(&ic, 0, sizeof(ic));
memset(&vap, 0, sizeof(vap));
vap.iv_ic = &ic;
if (debug)
ic.msg_enable = IEEE80211_MSG_CRYPTO;
vap.iv_debug = IEEE80211_MSG_CRYPTO;
ieee80211_crypto_attach(&ic);
ieee80211_crypto_vattach(&vap);
pass = 0;
total = 0;
for (i = 0; i < N(weptests); i++)
if (tests & (1 << i)) {
total++;
pass += runtest(&ic, &weptests[i]);
pass += runtest(&vap, &weptests[i]);
}
printk("%u of %u 802.11i WEP test vectors passed\n", pass, total);
ieee80211_crypto_vdetach(&vap);
ieee80211_crypto_detach(&ic);
return (pass == total ? 0 : -1);
return (pass == total ? 0 : -ENXIO);
#undef N
}
module_init(init_crypto_wep_test);