lib80211 WEP/TKIP test

This sort of requires hard-coding the WEP IV to be useful...

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 166920a..0ee566c 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -114,4 +114,12 @@
 
 	  If you choose to build a module, it'll be called rndis_wlan.
 
+config LIB80211_TEST
+	tristate "lib80211 test"
+	select LIB80211
+	select LIB80211_CRYPT_WEP
+	select LIB80211_CRYPT_TKIP
+	help
+	  whatever
+
 endif # WLAN
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 7fc9630..ea45a53 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -27,3 +27,4 @@
 obj-$(CONFIG_USB_NET_RNDIS_WLAN)	+= rndis_wlan.o
 
 obj-$(CONFIG_MAC80211_HWSIM)	+= mac80211_hwsim.o
+obj-$(CONFIG_LIB80211_TEST) += lib80211_test.o
diff --git a/drivers/net/wireless/lib80211_test.c b/drivers/net/wireless/lib80211_test.c
new file mode 100644
index 0000000..0022c02
--- /dev/null
+++ b/drivers/net/wireless/lib80211_test.c
@@ -0,0 +1,83 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <net/lib80211.h>
+
+static int init(void)
+{
+	struct lib80211_crypto_ops *ops;
+	struct lib80211_crypt_data crypt;
+	struct sk_buff *skb;
+	int i, err;
+	static const struct {
+		char *name;
+		char *key;
+		u8 keylen;
+	} algos[] = {
+		{
+			.name = "WEP",
+			.key = "asdfx",
+			.keylen = 5,
+		},
+		{
+			.name = "TKIP",
+			.key = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+			.keylen = 32,
+		}
+	};
+	static const struct ieee80211_hdr_3addr hdr = {
+		.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
+					     IEEE80211_STYPE_DATA),
+	};
+
+	for (i = 0; i < ARRAY_SIZE(algos); i++) {
+		ops = lib80211_get_crypto_ops(algos[i].name);
+		if (!ops) {
+			printk(KERN_INFO "failed to look up %s\n", algos[i].name);
+			continue;
+		}
+
+		crypt.ops = ops;
+		crypt.priv = crypt.ops->init(0);
+		if (!crypt.priv) {
+			printk(KERN_INFO "failed to init %s\n", algos[i].name);
+			continue;
+		}
+
+		err = crypt.ops->set_key(algos[i].key, algos[i].keylen,
+					 "\x00\x00\x00\x00\x00\x00\x00\x00",
+					 crypt.priv);
+		if (err) {
+			printk(KERN_INFO "failed to set key for %s (err=%d)\n", algos[i].name, err);
+			goto deinit;
+		}
+
+		skb = dev_alloc_skb(2000);
+		if (WARN_ON(!skb))
+			goto deinit;
+
+		skb_put_data(skb, &hdr, sizeof(hdr));
+		skb_put_data(skb, "0123456789abcdef", 16);
+
+		err = crypt.ops->encrypt_mpdu(skb, sizeof(hdr), crypt.priv);
+		if (err) {
+			printk(KERN_INFO "failed to encrypt for %s (err=%d)\n", algos[i].name, err);
+			goto free;
+		}
+
+		print_hex_dump(KERN_DEBUG, algos[i].name, DUMP_PREFIX_OFFSET,
+			       16, 1, skb->data, skb->len, false);
+
+free:
+		kfree_skb(skb);
+deinit:
+		crypt.ops->deinit(crypt.priv);
+	}
+
+	return 0;
+}
+module_init(init);
+
+static void leave(void)
+{
+}
+module_exit(leave);
\ No newline at end of file