diff options
author | Jouni Malinen <jkmaline@cc.hut.fi> | 2005-07-30 20:43:20 -0700 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-07-31 00:28:02 -0400 |
commit | 62fe7e378109537ff80971c5208e12d40bf88bee (patch) | |
tree | 6facd4654afbef6590e21c4fde0c71fb7ed79f2e /drivers/net/wireless | |
parent | ebed67d2847a9d299b47eeb5d82744671ab2b198 (diff) |
[PATCH] hostap: Replace crypto code with net/ieee80211 version
Replace Host AP version of WEP, TKIP, CCMP implementation with
net/ieee80211 that has more or less identical implementation (since
it is based on the Host AP implementation). Remove Host AP specific
implementation and modules from drivers/net/wireless/hostap.
Signed-off-by: Jouni Malinen <jkmaline@cc.hut.fi>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/hostap/Kconfig | 33 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_80211.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_80211_rx.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_80211_tx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_ap.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_ap.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_crypt.c | 167 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_crypt.h | 50 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_crypt_ccmp.c | 487 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_crypt_tkip.c | 697 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_crypt_wep.c | 283 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_hw.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_ioctl.c | 77 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_wlan.h | 10 |
16 files changed, 64 insertions, 1795 deletions
diff --git a/drivers/net/wireless/hostap/Kconfig b/drivers/net/wireless/hostap/Kconfig index 2871e879b51..1445f3f2600 100644 --- a/drivers/net/wireless/hostap/Kconfig +++ b/drivers/net/wireless/hostap/Kconfig @@ -7,9 +7,6 @@ config HOSTAP Host AP mode that allows the card to act as an IEEE 802.11 access point. - In addition, this includes generic IEEE 802.11 code, e.g., for - WEP/TKIP/CCMP encryption that can be shared with other drivers. - See <http://hostap.epitest.fi/> for more information about the Host AP driver configuration and tools. This site includes information and tools (hostapd and wpa_supplicant) for WPA/WPA2 @@ -22,36 +19,6 @@ config HOSTAP The driver can be compiled as a module and it will be called "hostap.ko". -config HOSTAP_WEP - tristate "IEEE 802.11 WEP encryption" - depends on HOSTAP - select CRYPTO - ---help--- - Software implementation of IEEE 802.11 WEP encryption. - - This can be compiled as a modules and it will be called - "hostap_crypt_wep.ko". - -config HOSTAP_TKIP - tristate "IEEE 802.11 TKIP encryption" - depends on HOSTAP - select CRYPTO - ---help--- - Software implementation of IEEE 802.11 TKIP encryption. - - This can be compiled as a modules and it will be called - "hostap_crypt_tkip.ko". - -config HOSTAP_CCMP - tristate "IEEE 802.11 CCMP encryption" - depends on HOSTAP - select CRYPTO - ---help--- - Software implementation of IEEE 802.11 CCMP encryption. - - This can be compiled as a modules and it will be called - "hostap_crypt_ccmp.ko". - config HOSTAP_FIRMWARE bool "Support downloading firmware images with Host AP driver" depends on HOSTAP diff --git a/drivers/net/wireless/hostap/Makefile b/drivers/net/wireless/hostap/Makefile index 08755407503..fc62235bfc2 100644 --- a/drivers/net/wireless/hostap/Makefile +++ b/drivers/net/wireless/hostap/Makefile @@ -1,7 +1,4 @@ obj-$(CONFIG_HOSTAP) += hostap.o -obj-$(CONFIG_HOSTAP_WEP) += hostap_crypt_wep.o -obj-$(CONFIG_HOSTAP_TKIP) += hostap_crypt_tkip.o -obj-$(CONFIG_HOSTAP_CCMP) += hostap_crypt_ccmp.o obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o obj-$(CONFIG_HOSTAP_PLX) += hostap_plx.o diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap.c index 75c75103f67..0858eba4575 100644 --- a/drivers/net/wireless/hostap/hostap.c +++ b/drivers/net/wireless/hostap/hostap.c @@ -4,7 +4,7 @@ * * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen * <jkmaline@cc.hut.fi> - * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi> + * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -34,16 +34,12 @@ #include "hostap_80211.h" #include "hostap_ap.h" #include "hostap.h" -#include "hostap_crypt.h" MODULE_AUTHOR("Jouni Malinen"); MODULE_DESCRIPTION("Host AP common routines"); MODULE_LICENSE("GPL"); MODULE_VERSION(PRISM2_VERSION); -/* Old hostap_crypt module is now part of hostap module. */ -#include "hostap_crypt.c" - #define TX_TIMEOUT (2 * HZ) #define PRISM2_MAX_FRAME_SIZE 2304 @@ -66,7 +62,7 @@ static int prism2_ap_translate_scan(struct net_device *dev, char *buffer); static int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param); static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, - struct prism2_crypt_data ***crypt); + struct ieee80211_crypt_data ***crypt); static void ap_control_kickall(struct ap_data *ap); #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT static int ap_control_add_mac(struct mac_restrictions *mac_restrictions, @@ -1156,8 +1152,6 @@ struct proc_dir_entry *hostap_proc; static int __init hostap_init(void) { - hostap_crypto_init(); - if (proc_net != NULL) { hostap_proc = proc_mkdir("hostap", proc_net); if (!hostap_proc) @@ -1176,8 +1170,6 @@ static void __exit hostap_exit(void) hostap_proc = NULL; remove_proc_entry("hostap", proc_net); } - - hostap_crypto_deinit(); } diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h index 878151f4065..f3ad3445c72 100644 --- a/drivers/net/wireless/hostap/hostap_80211.h +++ b/drivers/net/wireless/hostap/hostap_80211.h @@ -101,7 +101,7 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb); int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev); int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev); struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, - struct prism2_crypt_data *crypt); + struct ieee80211_crypt_data *crypt); int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev); #endif /* HOSTAP_80211_H */ diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c index a0da9b9c890..f4ca1e88f31 100644 --- a/drivers/net/wireless/hostap/hostap_80211_rx.c +++ b/drivers/net/wireless/hostap/hostap_80211_rx.c @@ -613,7 +613,7 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb) /* Called only as a tasklet (software IRQ) */ static inline int hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, - struct prism2_crypt_data *crypt) + struct ieee80211_crypt_data *crypt) { struct hostap_ieee80211_hdr *hdr; int res, hdrlen; @@ -652,7 +652,7 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, /* Called only as a tasklet (software IRQ) */ static inline int hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb, - int keyidx, struct prism2_crypt_data *crypt) + int keyidx, struct ieee80211_crypt_data *crypt) { struct hostap_ieee80211_hdr *hdr; int res, hdrlen; @@ -698,7 +698,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, int from_assoc_ap = 0; u8 dst[ETH_ALEN]; u8 src[ETH_ALEN]; - struct prism2_crypt_data *crypt = NULL; + struct ieee80211_crypt_data *crypt = NULL; void *sta = NULL; int keyidx = 0; diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c index 52e81cd406f..8f39871d690 100644 --- a/drivers/net/wireless/hostap/hostap_80211_tx.c +++ b/drivers/net/wireless/hostap/hostap_80211_tx.c @@ -284,7 +284,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Called only from software IRQ */ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, - struct prism2_crypt_data *crypt) + struct ieee80211_crypt_data *crypt) { struct hostap_interface *iface; local_info_t *local; diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index f59912a0fb4..6e109dfb43e 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -2,7 +2,7 @@ * Intersil Prism2 driver with Host AP (software access point) support * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen * <jkmaline@cc.hut.fi> - * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> + * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> * * This file is to be included into hostap.c when S/W AP functionality is * compiled. @@ -1206,7 +1206,7 @@ static void prism2_check_tx_rates(struct sta_info *sta) static void ap_crypt_init(struct ap_data *ap) { - ap->crypt = hostap_get_crypto_ops("WEP"); + ap->crypt = ieee80211_get_crypto_ops("WEP"); if (ap->crypt) { if (ap->crypt->init) { @@ -1224,7 +1224,7 @@ static void ap_crypt_init(struct ap_data *ap) if (ap->crypt == NULL) { printk(KERN_WARNING "AP could not initialize WEP: load module " - "hostap_crypt_wep.o\n"); + "ieee80211_crypt_wep.ko\n"); } } @@ -1293,7 +1293,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb, u16 auth_alg, auth_transaction, status_code, *pos; u16 resp = WLAN_STATUS_SUCCESS, fc; struct sta_info *sta = NULL; - struct prism2_crypt_data *crypt; + struct ieee80211_crypt_data *crypt; char *txt = ""; len = skb->len - IEEE80211_MGMT_HDR_LEN; @@ -3058,7 +3058,8 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, /* Called only as a tasklet (software IRQ) */ int hostap_handle_sta_crypto(local_info_t *local, struct hostap_ieee80211_hdr *hdr, - struct prism2_crypt_data **crypt, void **sta_ptr) + struct ieee80211_crypt_data **crypt, + void **sta_ptr) { struct sta_info *sta; @@ -3206,7 +3207,7 @@ void hostap_update_rates(local_info_t *local) static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, - struct prism2_crypt_data ***crypt) + struct ieee80211_crypt_data ***crypt) { struct sta_info *sta; diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h index 10137f44436..137f78e4532 100644 --- a/drivers/net/wireless/hostap/hostap_ap.h +++ b/drivers/net/wireless/hostap/hostap_ap.h @@ -81,7 +81,7 @@ struct sta_info { u32 tx_since_last_failure; u32 tx_consecutive_exc; - struct prism2_crypt_data *crypt; + struct ieee80211_crypt_data *crypt; int ap; /* whether this station is an AP */ @@ -216,7 +216,7 @@ struct ap_data { /* WEP operations for generating challenges to be used with shared key * authentication */ - struct hostap_crypto_ops *crypt; + struct ieee80211_crypto_ops *crypt; void *crypt_priv; #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ }; @@ -236,7 +236,7 @@ typedef enum { struct hostap_tx_data { struct sk_buff *skb; int host_encrypt; - struct prism2_crypt_data *crypt; + struct ieee80211_crypt_data *crypt; void *sta_ptr; }; ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx); @@ -253,7 +253,8 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, int wds); int hostap_handle_sta_crypto(local_info_t *local, struct hostap_ieee80211_hdr *hdr, - struct prism2_crypt_data **crypt, void **sta_ptr); + struct ieee80211_crypt_data **crypt, + void **sta_ptr); int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr); int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr); int hostap_add_sta(struct ap_data *ap, u8 *sta_addr); diff --git a/drivers/net/wireless/hostap/hostap_crypt.c b/drivers/net/wireless/hostap/hostap_crypt.c deleted file mode 100644 index de5390d502f..00000000000 --- a/drivers/net/wireless/hostap/hostap_crypt.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Host AP crypto routines - * - * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - */ - -struct hostap_crypto_alg { - struct list_head list; - struct hostap_crypto_ops *ops; -}; - - -struct hostap_crypto { - struct list_head algs; - spinlock_t lock; -}; - -static struct hostap_crypto *hcrypt; - - -int hostap_register_crypto_ops(struct hostap_crypto_ops *ops) -{ - unsigned long flags; - struct hostap_crypto_alg *alg; - - if (hcrypt == NULL) - return -1; - - alg = (struct hostap_crypto_alg *) kmalloc(sizeof(*alg), GFP_KERNEL); - if (alg == NULL) - return -ENOMEM; - - memset(alg, 0, sizeof(*alg)); - alg->ops = ops; - - spin_lock_irqsave(&hcrypt->lock, flags); - list_add(&alg->list, &hcrypt->algs); - spin_unlock_irqrestore(&hcrypt->lock, flags); - - printk(KERN_DEBUG "hostap_crypt: registered algorithm '%s'\n", - ops->name); - - return 0; -} - - -int hostap_unregister_crypto_ops(struct hostap_crypto_ops *ops) -{ - unsigned long flags; - struct list_head *ptr; - struct hostap_crypto_alg *del_alg = NULL; - - if (hcrypt == NULL) - return -1; - - spin_lock_irqsave(&hcrypt->lock, flags); - for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { - struct hostap_crypto_alg *alg = - (struct hostap_crypto_alg *) ptr; - if (alg->ops == ops) { - list_del(&alg->list); - del_alg = alg; - break; - } - } - spin_unlock_irqrestore(&hcrypt->lock, flags); - - if (del_alg) { - printk(KERN_DEBUG "hostap_crypt: unregistered algorithm " - "'%s'\n", ops->name); - kfree(del_alg); - } - - return del_alg ? 0 : -1; -} - - -struct hostap_crypto_ops * hostap_get_crypto_ops(const char *name) -{ - unsigned long flags; - struct list_head *ptr; - struct hostap_crypto_alg *found_alg = NULL; - - if (hcrypt == NULL) - return NULL; - - spin_lock_irqsave(&hcrypt->lock, flags); - for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { - struct hostap_crypto_alg *alg = - (struct hostap_crypto_alg *) ptr; - if (strcmp(alg->ops->name, name) == 0) { - found_alg = alg; - break; - } - } - spin_unlock_irqrestore(&hcrypt->lock, flags); - - if (found_alg) - return found_alg->ops; - else - return NULL; -} - - -static void * hostap_crypt_null_init(int keyidx) { return (void *) 1; } -static void hostap_crypt_null_deinit(void *priv) {} - -static struct hostap_crypto_ops hostap_crypt_null = { - .name = "NULL", - .init = hostap_crypt_null_init, - .deinit = hostap_crypt_null_deinit, - .encrypt_mpdu = NULL, - .decrypt_mpdu = NULL, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = NULL, - .get_key = NULL, - .extra_prefix_len = 0, - .extra_postfix_len = 0 -}; - - -static int __init hostap_crypto_init(void) -{ - hcrypt = (struct hostap_crypto *) kmalloc(sizeof(*hcrypt), GFP_KERNEL); - if (hcrypt == NULL) - return -ENOMEM; - - memset(hcrypt, 0, sizeof(*hcrypt)); - INIT_LIST_HEAD(&hcrypt->algs); - spin_lock_init(&hcrypt->lock); - - (void) hostap_register_crypto_ops(&hostap_crypt_null); - - return 0; -} - - -static void __exit hostap_crypto_deinit(void) -{ - struct list_head *ptr, *n; - - if (hcrypt == NULL) - return; - - for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; - ptr = n, n = ptr->next) { - struct hostap_crypto_alg *alg = - (struct hostap_crypto_alg *) ptr; - list_del(ptr); - printk(KERN_DEBUG "hostap_crypt: unregistered algorithm " - "'%s' (deinit)\n", alg->ops->name); - kfree(alg); - } - - kfree(hcrypt); -} - - -EXPORT_SYMBOL(hostap_register_crypto_ops); -EXPORT_SYMBOL(hostap_unregister_crypto_ops); -EXPORT_SYMBOL(hostap_get_crypto_ops); diff --git a/drivers/net/wireless/hostap/hostap_crypt.h b/drivers/net/wireless/hostap/hostap_crypt.h deleted file mode 100644 index 45d66d0323b..00000000000 --- a/drivers/net/wireless/hostap/hostap_crypt.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef PRISM2_CRYPT_H -#define PRISM2_CRYPT_H - -struct hostap_crypto_ops { - char *name; - - /* init new crypto context (e.g., allocate private data space, - * select IV, etc.); returns NULL on failure or pointer to allocated - * private data on success */ - void * (*init)(int keyidx); - - /* deinitialize crypto context and free allocated private data */ - void (*deinit)(void *priv); - - /* encrypt/decrypt return < 0 on error or >= 0 on success. The return - * value from decrypt_mpdu is passed as the keyidx value for - * decrypt_msdu. skb must have enough head and tail room for the - * encryption; if not, error will be returned; these functions are - * called for all MPDUs (i.e., fragments). - */ - int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); - int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); - - /* These functions are called for full MSDUs, i.e. full frames. - * These can be NULL if full MSDU operations are not needed. */ - int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv); - int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len, - void *priv); - - int (*set_key)(void *key, int len, u8 *seq, void *priv); - int (*get_key)(void *key, int len, u8 *seq, void *priv); - - /* procfs handler for printing out key information and possible - * statistics */ - char * (*print_stats)(char *p, void *priv); - - /* maximum number of bytes added by encryption; encrypt buf is - * allocated with extra_prefix_len bytes, copy of in_buf, and - * extra_postfix_len; encrypt need not use all this space, but - * the result must start at the beginning of the buffer and correct - * length must be returned */ - int extra_prefix_len, extra_postfix_len; -}; - - -int hostap_register_crypto_ops(struct hostap_crypto_ops *ops); -int hostap_unregister_crypto_ops(struct hostap_crypto_ops *ops); -struct hostap_crypto_ops * hostap_get_crypto_ops(const char *name); - -#endif /* PRISM2_CRYPT_H */ diff --git a/drivers/net/wireless/hostap/hostap_crypt_ccmp.c b/drivers/net/wireless/hostap/hostap_crypt_ccmp.c deleted file mode 100644 index 9e18340f7a3..00000000000 --- a/drivers/net/wireless/hostap/hostap_crypt_ccmp.c +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Host AP crypt: host-based CCMP encryption implementation for Host AP driver - * - * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - */ - -#include <linux/config.h> -#include <linux/version.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/random.h> -#include <linux/skbuff.h> -#include <linux/netdevice.h> -#include <linux/if_ether.h> -#include <linux/if_arp.h> -#include <linux/wireless.h> -#include <net/iw_handler.h> -#include <asm/string.h> - -#include "hostap_crypt.h" -#include "hostap_wlan.h" -#include "hostap_80211.h" - -#ifndef CONFIG_CRYPTO -#error CONFIG_CRYPTO is required to build this module. -#endif -#include <linux/crypto.h> -#include <asm/scatterlist.h> - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: CCMP"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); - - -#define AES_BLOCK_LEN 16 -#define CCMP_HDR_LEN 8 -#define CCMP_MIC_LEN 8 -#define CCMP_TK_LEN 16 -#define CCMP_PN_LEN 6 - - -struct hostap_ccmp_data { - u8 key[CCMP_TK_LEN]; - int key_set; - - u8 tx_pn[CCMP_PN_LEN]; - u8 rx_pn[CCMP_PN_LEN]; - - u32 dot11RSNAStatsCCMPFormatErrors; - u32 dot11RSNAStatsCCMPReplays; - u32 dot11RSNAStatsCCMPDecryptErrors; - - int key_idx; - - struct crypto_tfm *tfm; - - /* scratch buffers for virt_to_page() (crypto API) */ - u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN], - tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN]; - u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; -}; - - -void hostap_ccmp_aes_encrypt(struct crypto_tfm *tfm, - const u8 pt[16], u8 ct[16]) -{ - struct scatterlist src, dst; - - src.page = virt_to_page(pt); - src.offset = offset_in_page(pt); - src.length = AES_BLOCK_LEN; - - dst.page = virt_to_page(ct); - dst.offset = offset_in_page(ct); - dst.length = AES_BLOCK_LEN; - - crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN); -} - - -static void * hostap_ccmp_init(int key_idx) -{ - struct hostap_ccmp_data *priv; - - if (!try_module_get(THIS_MODULE)) - return NULL; - - priv = (struct hostap_ccmp_data *) kmalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) { - goto fail; - } - memset(priv, 0, sizeof(*priv)); - priv->key_idx = key_idx; - - priv->tfm = crypto_alloc_tfm("aes", 0); - if (priv->tfm == NULL) { - printk(KERN_DEBUG "hostap_crypt_ccmp: could not allocate " - "crypto API aes\n"); - goto fail; - } - - return priv; - -fail: - if (priv) { - if (priv->tfm) - crypto_free_tfm(priv->tfm); - kfree(priv); - } - module_put(THIS_MODULE); - return NULL; -} - - -static void hostap_ccmp_deinit(void *priv) -{ - struct hostap_ccmp_data *_priv = priv; - if (_priv && _priv->tfm) - crypto_free_tfm(_priv->tfm); - kfree(priv); - module_put(THIS_MODULE); -} - - -static inline void xor_block(u8 *b, u8 *a, size_t len) -{ - int i; - for (i = 0; i < len; i++) - b[i] ^= a[i]; -} - - -static void ccmp_init_blocks(struct crypto_tfm *tfm, - struct hostap_ieee80211_hdr *hdr, - u8 *pn, size_t dlen, u8 *b0, u8 *auth, - u8 *s0) -{ - u8 *pos, qc = 0; - size_t aad_len; - u16 fc; - int a4_included, qc_included; - u8 aad[2 * AES_BLOCK_LEN]; - - fc = le16_to_cpu(hdr->frame_control); - a4_included = ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == - (WLAN_FC_TODS | WLAN_FC_FROMDS)); - qc_included = ((HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) && - (HOSTAP_FC_GET_STYPE(fc) & 0x08)); - aad_len = 22; - if (a4_included) - aad_len += 6; - if (qc_included) { - pos = (u8 *) &hdr->addr4; - if (a4_included) - pos += 6; - qc = *pos & 0x0f; - aad_len += 2; - } - - /* CCM Initial Block: - * Flag (Include authentication header, M=3 (8-octet MIC), - * L=1 (2-octet Dlen)) - * Nonce: 0x00 | A2 | PN - * Dlen */ - b0[0] = 0x59; - b0[1] = qc; - memcpy(b0 + 2, hdr->addr2, ETH_ALEN); - memcpy(b0 + 8, pn, CCMP_PN_LEN); - b0[14] = (dlen >> 8) & 0xff; - b0[15] = dlen & 0xff; - - /* AAD: - * FC with bits 4..6 and 11..13 masked to zero; 14 is always one - * A1 | A2 | A3 - * SC with bits 4..15 (seq#) masked to zero - * A4 (if present) - * QC (if present) - */ - pos = (u8 *) hdr; - aad[0] = 0; /* aad_len >> 8 */ - aad[1] = aad_len & 0xff; - aad[2] = pos[0] & 0x8f; - aad[3] = pos[1] & 0xc7; - memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN); - pos = (u8 *) &hdr->seq_ctrl; - aad[22] = pos[0] & 0x0f; - aad[23] = 0; /* all bits masked */ - memset(aad + 24, 0, 8); - if (a4_included) - memcpy(aad + 24, hdr->addr4, ETH_ALEN); - if (qc_included) { - aad[a4_included ? 30 : 24] = qc; - /* rest of QC masked */ - } - - /* Start with the first block and AAD */ - hostap_ccmp_aes_encrypt(tfm, b0, auth); - xor_block(auth, aad, AES_BLOCK_LEN); - hostap_ccmp_aes_encrypt(tfm, auth, auth); - xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); - hostap_ccmp_aes_encrypt(tfm, auth, auth); - b0[0] &= 0x07; - b0[14] = b0[15] = 0; - hostap_ccmp_aes_encrypt(tfm, b0, s0); -} - - -static int hostap_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct hostap_ccmp_data *key = priv; - int data_len, i, blocks, last, len; - u8 *pos, *mic; - struct hostap_ieee80211_hdr *hdr; - u8 *b0 = key->tx_b0; - u8 *b = key->tx_b; - u8 *e = key->tx_e; - u8 *s0 = key->tx_s0; - - if (skb_headroom(skb) < CCMP_HDR_LEN || - skb_tailroom(skb) < CCMP_MIC_LEN || - skb->len < hdr_len) - return -1; - - data_len = skb->len - hdr_len; - pos = skb_push(skb, CCMP_HDR_LEN); - memmove(pos, pos + CCMP_HDR_LEN, hdr_len); - pos += hdr_len; - mic = skb_put(skb, CCMP_MIC_LEN); - - i = CCMP_PN_LEN - 1; - while (i >= 0) { - key->tx_pn[i]++; - if (key->tx_pn[i] != 0) - break; - i--; - } - - *pos++ = key->tx_pn[5]; - *pos++ = key->tx_pn[4]; - *pos++ = 0; - *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */; - *pos++ = key->tx_pn[3]; - *pos++ = key->tx_pn[2]; - *pos++ = key->tx_pn[1]; - *pos++ = key->tx_pn[0]; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); - - blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; - last = data_len % AES_BLOCK_LEN; - - for (i = 1; i <= blocks; i++) { - len = (i == blocks && last) ? last : AES_BLOCK_LEN; - /* Authentication */ - xor_block(b, pos, len); - hostap_ccmp_aes_encrypt(key->tfm, b, b); - /* Encryption, with counter */ - b0[14] = (i >> 8) & 0xff; - b0[15] = i & 0xff; - hostap_ccmp_aes_encrypt(key->tfm, b0, e); - xor_block(pos, e, len); - pos += len; - } - - for (i = 0; i < CCMP_MIC_LEN; i++) - mic[i] = b[i] ^ s0[i]; - - return 0; -} - - -static int hostap_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct hostap_ccmp_data *key = priv; - u8 keyidx, *pos; - struct hostap_ieee80211_hdr *hdr; - u8 *b0 = key->rx_b0; - u8 *b = key->rx_b; - u8 *a = key->rx_a; - u8 pn[6]; - int i, blocks, last, len; - size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN; - u8 *mic = skb->data + skb->len - CCMP_MIC_LEN; - - if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { - key->dot11RSNAStatsCCMPFormatErrors++; - return -1; - } - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - pos = skb->data + hdr_len; - keyidx = pos[3]; - if (!(keyidx & (1 << 5))) { - if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet without ExtIV" - " flag from " MACSTR "\n", MAC2STR(hdr->addr2)); - } - key->dot11RSNAStatsCCMPFormatErrors++; - return -2; - } - keyidx >>= 6; - if (key->key_idx != keyidx) { - printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame " - "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv); - return -6; - } - if (!key->key_set) { - if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet from " MACSTR - " with keyid=%d that does not have a configured" - " key\n", MAC2STR(hdr->addr2), keyidx); - } - return -3; - } - - pn[0] = pos[7]; - pn[1] = pos[6]; - pn[2] = pos[5]; - pn[3] = pos[4]; - pn[4] = pos[1]; - pn[5] = pos[0]; - pos += 8; - - if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { - if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: replay detected: STA=" MACSTR - " previous PN %02x%02x%02x%02x%02x%02x " - "received PN %02x%02x%02x%02x%02x%02x\n", - MAC2STR(hdr->addr2), MAC2STR(key->rx_pn), - MAC2STR(pn)); - } - key->dot11RSNAStatsCCMPReplays++; - return -4; - } - - ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b); - xor_block(mic, b, CCMP_MIC_LEN); - - blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; - last = data_len % AES_BLOCK_LEN; - - for (i = 1; i <= blocks; i++) { - len = (i == blocks && last) ? last : AES_BLOCK_LEN; - /* Decrypt, with counter */ - b0[14] = (i >> 8) & 0xff; - b0[15] = i & 0xff; - hostap_ccmp_aes_encrypt(key->tfm, b0, b); - xor_block(pos, b, len); - /* Authentication */ - xor_block(a, pos, len); - hostap_ccmp_aes_encrypt(key->tfm, a, a); - pos += len; - } - - if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { - if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: decrypt failed: STA=" - MACSTR "\n", MAC2STR(hdr->addr2)); - } - key->dot11RSNAStatsCCMPDecryptErrors++; - return -5; - } - - memcpy(key->rx_pn, pn, CCMP_PN_LEN); - - /* Remove hdr and MIC */ - memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len); - skb_pull(skb, CCMP_HDR_LEN); - skb_trim(skb, skb->len - CCMP_MIC_LEN); - - return keyidx; -} - - -static int hostap_ccmp_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct hostap_ccmp_data *data = priv; - int keyidx; - struct crypto_tfm *tfm = data->tfm; - - keyidx = data->key_idx; - memset(data, 0, sizeof(*data)); - data->key_idx = keyidx; - data->tfm = tfm; - if (len == CCMP_TK_LEN) { - memcpy(data->key, key, CCMP_TK_LEN); - data->key_set = 1; - if (seq) { - data->rx_pn[0] = seq[5]; - data->rx_pn[1] = seq[4]; - data->rx_pn[2] = seq[3]; - data->rx_pn[3] = seq[2]; - data->rx_pn[4] = seq[1]; - data->rx_pn[5] = seq[0]; - } - crypto_cipher_setkey(data->tfm, data->key, CCMP_TK_LEN); - } else if (len == 0) { - data->key_set = 0; - } else - return -1; - - return 0; -} - - -static int hostap_ccmp_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct hostap_ccmp_data *data = priv; - - if (len < CCMP_TK_LEN) - return -1; - - if (!data->key_set) - return 0; - memcpy(key, data->key, CCMP_TK_LEN); - - if (seq) { - seq[0] = data->tx_pn[5]; - seq[1] = data->tx_pn[4]; - seq[2] = data->tx_pn[3]; - seq[3] = data->tx_pn[2]; - seq[4] = data->tx_pn[1]; - seq[5] = data->tx_pn[0]; - } - - return CCMP_TK_LEN; -} - - -static char * hostap_ccmp_print_stats(char *p, void *priv) -{ - struct hostap_ccmp_data *ccmp = priv; - p += sprintf(p, "key[%d] alg=CCMP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " - "format_errors=%d replays=%d decrypt_errors=%d\n", - ccmp->key_idx, ccmp->key_set, - MAC2STR(ccmp->tx_pn), MAC2STR(ccmp->rx_pn), - ccmp->dot11RSNAStatsCCMPFormatErrors, - ccmp->dot11RSNAStatsCCMPReplays, - ccmp->dot11RSNAStatsCCMPDecryptErrors); - - return p; -} - - -static struct hostap_crypto_ops hostap_crypt_ccmp = { - .name = "CCMP", - .init = hostap_ccmp_init, - .deinit = hostap_ccmp_deinit, - .encrypt_mpdu = hostap_ccmp_encrypt, - .decrypt_mpdu = hostap_ccmp_decrypt, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = hostap_ccmp_set_key, - .get_key = hostap_ccmp_get_key, - .print_stats = hostap_ccmp_print_stats, - .extra_prefix_len = CCMP_HDR_LEN, - .extra_postfix_len = CCMP_MIC_LEN -}; - - -static int __init hostap_crypto_ccmp_init(void) -{ - if (hostap_register_crypto_ops(&hostap_crypt_ccmp) < 0) - return -1; - - return 0; -} - - -static void __exit hostap_crypto_ccmp_exit(void) -{ - hostap_unregister_crypto_ops(&hostap_crypt_ccmp); -} - - -module_init(hostap_crypto_ccmp_init); -module_exit(hostap_crypto_ccmp_exit); diff --git a/drivers/net/wireless/hostap/hostap_crypt_tkip.c b/drivers/net/wireless/hostap/hostap_crypt_tkip.c deleted file mode 100644 index fcf1a014f4a..00000000000 --- a/drivers/net/wireless/hostap/hostap_crypt_tkip.c +++ /dev/null @@ -1,697 +0,0 @@ -/* - * Host AP crypt: host-based TKIP encryption implementation for Host AP driver - * - * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - */ - -#include <linux/config.h> -#include <linux/version.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/random.h> -#include <linux/skbuff.h> -#include <linux/netdevice.h> -#include <linux/if_ether.h> -#include <linux/if_arp.h> -#include <linux/wireless.h> -#include <net/iw_handler.h> -#include <asm/string.h> - -#include "hostap_crypt.h" -#include "hostap_wlan.h" -#include "hostap_80211.h" -#include "hostap_config.h" - -#ifndef CONFIG_CRYPTO -#error CONFIG_CRYPTO is required to build this module. -#endif -#include <linux/crypto.h> -#include <asm/scatterlist.h> -#include <linux/crc32.h> - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: TKIP"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); - - -struct hostap_tkip_data { -#define TKIP_KEY_LEN 32 - u8 key[TKIP_KEY_LEN]; - int key_set; - - u32 tx_iv32; - u16 tx_iv16; - u16 tx_ttak[5]; - int tx_phase1_done; - - u32 rx_iv32; - u16 rx_iv16; - u16 rx_ttak[5]; - int rx_phase1_done; - u32 rx_iv32_new; - u16 rx_iv16_new; - - u32 dot11RSNAStatsTKIPReplays; - u32 dot11RSNAStatsTKIPICVErrors; - u32 dot11RSNAStatsTKIPLocalMICFailures; - - int key_idx; - - struct crypto_tfm *tfm_arc4; - struct crypto_tfm *tfm_michael; - - /* scratch buffers for virt_to_page() (crypto API) */ - u8 rx_hdr[16], tx_hdr[16]; -}; - - -static void * hostap_tkip_init(int key_idx) -{ - struct hostap_tkip_data *priv; - - if (!try_module_get(THIS_MODULE)) - return NULL; - - priv = (struct hostap_tkip_data *) kmalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) - goto fail; - memset(priv, 0, sizeof(*priv)); - priv->key_idx = key_idx; - - priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0); - if (priv->tfm_arc4 == NULL) { - printk(KERN_DEBUG "hostap_crypt_tkip: could not allocate " - "crypto API arc4\n"); - goto fail; - } - - priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0); - if (priv->tfm_michael == NULL) { - printk(KERN_DEBUG "hostap_crypt_tkip: could not allocate " - "crypto API michael_mic\n"); - goto fail; - } - - return priv; - -fail: - if (priv) { - if (priv->tfm_michael) - crypto_free_tfm(priv->tfm_michael); - if (priv->tfm_arc4) - crypto_free_tfm(priv->tfm_arc4); - kfree(priv); - } - module_put(THIS_MODULE); - return NULL; -} - - -static void hostap_tkip_deinit(void *priv) -{ - struct hostap_tkip_data *_priv = priv; - if (_priv && _priv->tfm_michael) - crypto_free_tfm(_priv->tfm_michael); - if (_priv && _priv->tfm_arc4) - crypto_free_tfm(_priv->tfm_arc4); - kfree(priv); - module_put(THIS_MODULE); -} - - -static inline u16 RotR1(u16 val) -{ - return (val >> 1) | (val << 15); -} - - -static inline u8 Lo8(u16 val) -{ - return val & 0xff; -} - - -static inline u8 Hi8(u16 val) -{ - return val >> 8; -} - - -static inline u16 Lo16(u32 val) -{ - return val & 0xffff; -} - - -static inline u16 Hi16(u32 val) -{ - return val >> 16; -} - - -static inline u16 Mk16(u8 hi, u8 lo) -{ - return lo | (((u16) hi) << 8); -} - - -static inline u16 Mk16_le(u16 *v) -{ - return le16_to_cpu(*v); -} - - -static const u16 Sbox[256] = -{ - 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, - 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, - 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, - 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, - 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, - 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, - 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, - 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, - 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, - 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, - 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, - 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, - 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, - 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, - 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, - 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, - 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, - 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, - 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, - 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, - 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, - 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, - 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, - 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, - 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, - 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, - 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, - 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, - 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, - 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, - 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, - 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, -}; - - -static inline u16 _S_(u16 v) -{ - u16 t = Sbox[Hi8(v)]; - return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8)); -} - - -#define PHASE1_LOOP_COUNT 8 - -static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32) -{ - int i, j; - - /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */ - TTAK[0] = Lo16(IV32); - TTAK[1] = Hi16(IV32); - TTAK[2] = Mk16(TA[1], TA[0]); - TTAK[3] = Mk16(TA[3], TA[2]); - TTAK[4] = Mk16(TA[5], TA[4]); - - for (i = 0; i < PHASE1_LOOP_COUNT; i++) { - j = 2 * (i & 1); - TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j])); - TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j])); - TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j])); - TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j])); - TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i; - } -} - - -static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, - u16 IV16) -{ - /* Make temporary area overlap WEP seed so that the final copy can be - * avoided on little endian hosts. */ - u16 *PPK = (u16 *) &WEPSeed[4]; - - /* Step 1 - make copy of TTAK and bring in TSC */ - PPK[0] = TTAK[0]; - PPK[1] = TTAK[1]; - PPK[2] = TTAK[2]; - PPK[3] = TTAK[3]; - PPK[4] = TTAK[4]; - PPK[5] = TTAK[4] + IV16; - - /* Step 2 - 96-bit bijective mixing using S-box */ - PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0])); - PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2])); - PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4])); - PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6])); - PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8])); - PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10])); - - PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12])); - PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14])); - PPK[2] += RotR1(PPK[1]); - PPK[3] += RotR1(PPK[2]); - PPK[4] += RotR1(PPK[3]); - PPK[5] += RotR1(PPK[4]); - - /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value - * WEPSeed[0..2] is transmitted as WEP IV */ - WEPSeed[0] = Hi8(IV16); - WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F; - WEPSeed[2] = Lo8(IV16); - WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1); - -#ifdef __BIG_ENDIAN - { - int i; - for (i = 0; i < 6; i++) - PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8); - } -#endif -} - - -static int hostap_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct hostap_tkip_data *tkey = priv; - int len; - u8 rc4key[16], *pos, *icv; - struct hostap_ieee80211_hdr *hdr; - u32 crc; - struct scatterlist sg; - - if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 || - skb->len < hdr_len) - return -1; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - if (!tkey->tx_phase1_done) { - tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, - tkey->tx_iv32); - tkey->tx_phase1_done = 1; - } - tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); - - len = skb->len - hdr_len; - pos = skb_push(skb, 8); - memmove(pos, pos + 8, hdr_len); - pos += hdr_len; - icv = skb_put(skb, 4); - - *pos++ = rc4key[0]; - *pos++ = rc4key[1]; - *pos++ = rc4key[2]; - *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */; - *pos++ = tkey->tx_iv32 & 0xff; - *pos++ = (tkey->tx_iv32 >> 8) & 0xff; - *pos++ = (tkey->tx_iv32 >> 16) & 0xff; - *pos++ = (tkey->tx_iv32 >> 24) & 0xff; - - crc = ~crc32_le(~0, pos, len); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); - sg.page = virt_to_page(pos); - sg.offset = offset_in_page(pos); - sg.length = len + 4; - crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4); - - tkey->tx_iv16++; - if (tkey->tx_iv16 == 0) { - tkey->tx_phase1_done = 0; - tkey->tx_iv32++; - } - - return 0; -} - - -static int hostap_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct hostap_tkip_data *tkey = priv; - u8 rc4key[16]; - u8 keyidx, *pos, icv[4]; - u32 iv32; - u16 iv16; - struct hostap_ieee80211_hdr *hdr; - u32 crc; - struct scatterlist sg; - int plen; - - if (skb->len < hdr_len + 8 + 4) - return -1; - - hdr = (struct hostap_ieee80211_hdr *) skb->data; - pos = skb->data + hdr_len; - keyidx = pos[3]; - if (!(keyidx & (1 << 5))) { - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet without ExtIV" - " flag from " MACSTR "\n", MAC2STR(hdr->addr2)); - } - return -2; - } - keyidx >>= 6; - if (tkey->key_idx != keyidx) { - printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame " - "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv); - return -6; - } - if (!tkey->key_set) { - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet from " MACSTR - " with keyid=%d that does not have a configured" - " key\n", MAC2STR(hdr->addr2), keyidx); - } - return -3; - } - iv16 = (pos[0] << 8) | pos[2]; - iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); - pos += 8; - - if (iv32 < tkey->rx_iv32 || - (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: replay detected: STA=" MACSTR - " previous TSC %08x%04x received TSC " - "%08x%04x\n", MAC2STR(hdr->addr2), - tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); - } - tkey->dot11RSNAStatsTKIPReplays++; - return -4; - } - - if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) { - tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32); - tkey->rx_phase1_done = 1; - } - tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16); - - plen = skb->len - hdr_len - 12; - - crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); - sg.page = virt_to_page(pos); - sg.offset = offset_in_page(pos); - sg.length = plen + 4; - crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4); - - crc = ~crc32_le(~0, pos, plen); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - if (memcmp(icv, pos + plen, 4) != 0) { - if (iv32 != tkey->rx_iv32) { - /* Previously cached Phase1 result was already lost, so - * it needs to be recalculated for the next packet. */ - tkey->rx_phase1_done = 0; - } - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: ICV error detected: STA=" - MACSTR "\n", MAC2STR(hdr->addr2)); - } - tkey->dot11RSNAStatsTKIPICVErrors++; - return -5; - } - - /* Update real counters only after Michael MIC verification has - * completed */ - tkey->rx_iv32_new = iv32; - tkey->rx_iv16_new = iv16; - - /* Remove IV and ICV */ - memmove(skb->data + 8, skb->data, hdr_len); - skb_pull(skb, 8); - skb_trim(skb, skb->len - 4); - - return keyidx; -} - - -static int michael_mic(struct hostap_tkip_data *tkey, u8 *key, u8 *hdr, - u8 *data, size_t data_len, u8 *mic) -{ - struct scatterlist sg[2]; - - if (tkey->tfm_michael == NULL) { - printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); - return -1; - } - sg[0].page = virt_to_page(hdr); - sg[0].offset = offset_in_page(hdr); - sg[0].length = 16; - - sg[1].page = virt_to_page(data); - sg[1].offset = offset_in_page(data); - sg[1].length = data_len; - - crypto_digest_init(tkey->tfm_michael); - crypto_digest_setkey(tkey->tfm_michael, key, 8); - crypto_digest_update(tkey->tfm_michael, sg, 2); - crypto_digest_final(tkey->tfm_michael, mic); - - return 0; -} - - -static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) -{ - struct hostap_ieee80211_hdr *hdr11; - - hdr11 = (struct hostap_ieee80211_hdr *) skb->data; - switch (le16_to_cpu(hdr11->frame_control) & - (WLAN_FC_FROMDS | WLAN_FC_TODS)) { - case WLAN_FC_TODS: - memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ - break; - case WLAN_FC_FROMDS: - memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */ - break; - case WLAN_FC_FROMDS | WLAN_FC_TODS: - memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */ - break; - case 0: - memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ - break; - } - - hdr[12] = 0; /* priority */ - hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ -} - - -static int hostap_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct hostap_tkip_data *tkey = priv; - u8 *pos; - - if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { - printk(KERN_DEBUG "Invalid packet for Michael MIC add " - "(tailroom=%d hdr_len=%d skb->len=%d)\n", - skb_tailroom(skb), hdr_len, skb->len); - return -1; - } - - michael_mic_hdr(skb, tkey->tx_hdr); - pos = skb_put(skb, 8); - if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) - return -1; - - return 0; -} - - -static void hostap_michael_mic_failure(struct net_device *dev, - struct hostap_ieee80211_hdr *hdr, - int keyidx) -{ - union iwreq_data wrqu; - char buf[128]; - - /* TODO: needed parameters: count, keyid, key type, src address, TSC */ - sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=" - MACSTR ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", - MAC2STR(hdr->addr2)); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = strlen(buf); - wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); -} - - -static int hostap_michael_mic_verify(struct sk_buff *skb, int keyidx, - int hdr_len, void *priv) -{ - struct hostap_tkip_data *tkey = priv; - u8 mic[8]; - - if (!tkey->key_set) - return -1; - - michael_mic_hdr(skb, tkey->rx_hdr); - if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) - return -1; - if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { - struct hostap_ieee80211_hdr *hdr; - hdr = (struct hostap_ieee80211_hdr *) skb->data; - printk(KERN_DEBUG "%s: Michael MIC verification failed for " - "MSDU from " MACSTR " keyidx=%d\n", - skb->dev ? skb->dev->name : "N/A", MAC2STR(hdr->addr2), - keyidx); - if (skb->dev) - hostap_michael_mic_failure(skb->dev, hdr, keyidx); - tkey->dot11RSNAStatsTKIPLocalMICFailures++; - return -1; - } - - /* Update TSC counters for RX now that the packet verification has - * completed. */ - tkey->rx_iv32 = tkey->rx_iv32_new; - tkey->rx_iv16 = tkey->rx_iv16_new; - - skb_trim(skb, skb->len - 8); - - return 0; -} - - -static int hostap_tkip_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct hostap_tkip_data *tkey = priv; - int keyidx; - struct crypto_tfm *tfm = tkey->tfm_michael; - struct crypto_tfm *tfm2 = tkey->tfm_arc4; - - keyidx = tkey->key_idx; - memset(tkey, 0, sizeof(*tkey)); - tkey->key_idx = keyidx; - tkey->tfm_michael = tfm; - tkey->tfm_arc4 = tfm2; - if (len == TKIP_KEY_LEN) { - memcpy(tkey->key, key, TKIP_KEY_LEN); - tkey->key_set = 1; - tkey->tx_iv16 = 1; /* TSC is initialized to 1 */ - if (seq) { - tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) | - (seq[3] << 8) | seq[2]; - tkey->rx_iv16 = (seq[1] << 8) | seq[0]; - } - } else if (len == 0) { - tkey->key_set = 0; - } else - return -1; - - return 0; -} - - -static int hostap_tkip_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct hostap_tkip_data *tkey = priv; - - if (len < TKIP_KEY_LEN) - return -1; - - if (!tkey->key_set) - return 0; - memcpy(key, tkey->key, TKIP_KEY_LEN); - - if (seq) { - /* Return the sequence number of the last transmitted frame. */ - u16 iv16 = tkey->tx_iv16; - u32 iv32 = tkey->tx_iv32; - if (iv16 == 0) - iv32--; - iv16--; - seq[0] = tkey->tx_iv16; - seq[1] = tkey->tx_iv16 >> 8; - seq[2] = tkey->tx_iv32; - seq[3] = tkey->tx_iv32 >> 8; - seq[4] = tkey->tx_iv32 >> 16; - seq[5] = tkey->tx_iv32 >> 24; - } - - return TKIP_KEY_LEN; -} - - -static char * hostap_tkip_print_stats(char *p, void *priv) -{ - struct hostap_tkip_data *tkip = priv; - p += sprintf(p, "key[%d] alg=TKIP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " - "replays=%d icv_errors=%d local_mic_failures=%d\n", - tkip->key_idx, tkip->key_set, - (tkip->tx_iv32 >> 24) & 0xff, - (tkip->tx_iv32 >> 16) & 0xff, - (tkip->tx_iv32 >> 8) & 0xff, - tkip->tx_iv32 & 0xff, - (tkip->tx_iv16 >> 8) & 0xff, - tkip->tx_iv16 & 0xff, - (tkip->rx_iv32 >> 24) & 0xff, - (tkip->rx_iv32 >> 16) & 0xff, - (tkip->rx_iv32 >> 8) & 0xff, - tkip->rx_iv32 & 0xff, - (tkip->rx_iv16 >> 8) & 0xff, - tkip->rx_iv16 & 0xff, - tkip->dot11RSNAStatsTKIPReplays, - tkip->dot11RSNAStatsTKIPICVErrors, - tkip->dot11RSNAStatsTKIPLocalMICFailures); - return p; -} - - -static struct hostap_crypto_ops hostap_crypt_tkip = { - .name = "TKIP", - .init = hostap_tkip_init, - .deinit = hostap_tkip_deinit, - .encrypt_mpdu = hostap_tkip_encrypt, - .decrypt_mpdu = hostap_tkip_decrypt, - .encrypt_msdu = hostap_michael_mic_add, - .decrypt_msdu = hostap_michael_mic_verify, - .set_key = hostap_tkip_set_key, - .get_key = hostap_tkip_get_key, - .print_stats = hostap_tkip_print_stats, - .extra_prefix_len = 4 + 4 /* IV + ExtIV */, - .extra_postfix_len = 8 + 4 /* MIC + ICV */ -}; - - -static int __init hostap_crypto_tkip_init(void) -{ - if (hostap_register_crypto_ops(&hostap_crypt_tkip) < 0) - return -1; - - return 0; -} - - -static void __exit hostap_crypto_tkip_exit(void) -{ - hostap_unregister_crypto_ops(&hostap_crypt_tkip); -} - - -module_init(hostap_crypto_tkip_init); -module_exit(hostap_crypto_tkip_exit); diff --git a/drivers/net/wireless/hostap/hostap_crypt_wep.c b/drivers/net/wireless/hostap/hostap_crypt_wep.c deleted file mode 100644 index 66c403f1763..00000000000 --- a/drivers/net/wireless/hostap/hostap_crypt_wep.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Host AP crypt: host-based WEP encryption implementation for Host AP driver - * - * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - */ - -#include <linux/config.h> -#include <linux/version.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/random.h> -#include <linux/skbuff.h> -#include <asm/string.h> - -#include "hostap_crypt.h" -#include "hostap_config.h" - -#ifndef CONFIG_CRYPTO -#error CONFIG_CRYPTO is required to build this module. -#endif -#include <linux/crypto.h> -#include <asm/scatterlist.h> -#include <linux/crc32.h> - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: WEP"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(PRISM2_VERSION); - - -struct prism2_wep_data { - u32 iv; -#define WEP_KEY_LEN 13 - u8 key[WEP_KEY_LEN + 1]; - u8 key_len; - u8 key_idx; - struct crypto_tfm *tfm; -}; - - -static void * prism2_wep_init(int keyidx) -{ - struct prism2_wep_data *priv; - - if (!try_module_get(THIS_MODULE)) - return NULL; - - priv = (struct prism2_wep_data *) kmalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) - goto fail; - memset(priv, 0, sizeof(*priv)); - priv->key_idx = keyidx; - - priv->tfm = crypto_alloc_tfm("arc4", 0); - if (priv->tfm == NULL) { - printk(KERN_DEBUG "hostap_crypt_wep: could not allocate " - "crypto API arc4\n"); - goto fail; - } - - /* start WEP IV from a random value */ - get_random_bytes(&priv->iv, 4); - - return priv; - -fail: - if (priv) { - if (priv->tfm) - crypto_free_tfm(priv->tfm); - kfree(priv); - } - module_put(THIS_MODULE); - return NULL; -} - - -static void prism2_wep_deinit(void *priv) -{ - struct prism2_wep_data *_priv = priv; - if (_priv && _priv->tfm) - crypto_free_tfm(_priv->tfm); - kfree(priv); - module_put(THIS_MODULE); -} - - -/* Perform WEP encryption on given skb that has at least 4 bytes of headroom - * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted, - * so the payload length increases with 8 bytes. - * - * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) - */ -static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct prism2_wep_data *wep = priv; - u32 crc, klen, len; - u8 key[WEP_KEY_LEN + 3]; - u8 *pos, *icv; - struct scatterlist sg; - - if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 || - skb->len < hdr_len) - return -1; - - len = skb->len - hdr_len; - pos = skb_push(skb, 4); - memmove(pos, pos + 4, hdr_len); - pos += hdr_len; - - klen = 3 + wep->key_len; - - wep->iv++; - - /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key - * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N) - * can be used to speedup attacks, so avoid using them. */ - if ((wep->iv & 0xff00) == 0xff00) { - u8 B = (wep->iv >> 16) & 0xff; - if (B >= 3 && B < klen) - wep->iv += 0x0100; - } - - /* Prepend 24-bit IV to RC4 key and TX frame */ - *pos++ = key[0] = (wep->iv >> 16) & 0xff; - *pos++ = key[1] = (wep->iv >> 8) & 0xff; - *pos++ = key[2] = wep->iv & 0xff; - *pos++ = wep->key_idx << 6; - - /* Copy rest of the WEP key (the secret part) */ - memcpy(key + 3, wep->key, wep->key_len); - - /* Append little-endian CRC32 and encrypt it to produce ICV */ - crc = ~crc32_le(~0, pos, len); - icv = skb_put(skb, 4); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - crypto_cipher_setkey(wep->tfm, key, klen); - sg.page = virt_to_page(pos); - sg.offset = offset_in_page(pos); - sg.length = len + 4; - crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4); - - return 0; -} - - -/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of - * the frame: IV (4 bytes), encrypted payload (including SNAP header), - * ICV (4 bytes). len includes both IV and ICV. - * - * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on - * failure. If frame is OK, IV and ICV will be removed. - */ -static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct prism2_wep_data *wep = priv; - u32 crc, klen, plen; - u8 key[WEP_KEY_LEN + 3]; - u8 keyidx, *pos, icv[4]; - struct scatterlist sg; - - if (skb->len < hdr_len + 8) - return -1; - - pos = skb->data + hdr_len; - key[0] = *pos++; - key[1] = *pos++; - key[2] = *pos++; - keyidx = *pos++ >> 6; - if (keyidx != wep->key_idx) - return -1; - - klen = 3 + wep->key_len; - - /* Copy rest of the WEP key (the secret part) */ - memcpy(key + 3, wep->key, wep->key_len); - - /* Apply RC4 to data and compute CRC32 over decrypted data */ - plen = skb->len - hdr_len - 8; - - crypto_cipher_setkey(wep->tfm, key, klen); - sg.page = virt_to_page(pos); - sg.offset = offset_in_page(pos); - sg.length = plen + 4; - crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4); - - crc = ~crc32_le(~0, pos, plen); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - if (memcmp(icv, pos + plen, 4) != 0) { - /* ICV mismatch - drop frame */ - return -2; - } - - /* Remove IV and ICV */ - memmove(skb->data + 4, skb->data, hdr_len); - skb_pull(skb, 4); - skb_trim(skb, skb->len - 4); - - return 0; -} - - -static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct prism2_wep_data *wep = priv; - - if (len < 0 || len > WEP_KEY_LEN) - return -1; - - memcpy(wep->key, key, len); - wep->key_len = len; - - return 0; -} - - -static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct prism2_wep_data *wep = priv; - - if (len < wep->key_len) - return -1; - - memcpy(key, wep->key, wep->key_len); - - return wep->key_len; -} - - -static char * prism2_wep_print_stats(char *p, void *priv) -{ - struct prism2_wep_data *wep = priv; - p += sprintf(p, "key[%d] alg=WEP len=%d\n", - wep->key_idx, wep->key_len); - return p; -} - - -static struct hostap_crypto_ops hostap_crypt_wep = { - .name = "WEP", - .init = prism2_wep_init, - .deinit = prism2_wep_deinit, - .encrypt_mpdu = prism2_wep_encrypt, - .decrypt_mpdu = prism2_wep_decrypt, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = prism2_wep_set_key, - .get_key = prism2_wep_get_key, - .print_stats = prism2_wep_print_stats, - .extra_prefix_len = 4 /* IV */, - .extra_postfix_len = 4 /* ICV */ -}; - - -static int __init hostap_crypto_wep_init(void) -{ - if (hostap_register_crypto_ops(&hostap_crypt_wep) < 0) - return -1; - - return 0; -} - - -static void __exit hostap_crypto_wep_exit(void) -{ - hostap_unregister_crypto_ops(&hostap_crypt_wep); -} - - -module_init(hostap_crypto_wep_init); -module_exit(hostap_crypto_wep_exit); diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index 72a8a19ad8c..dc31f5351b3 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -4,7 +4,7 @@ * * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen * <jkmaline@cc.hut.fi> - * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi> + * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -2967,11 +2967,11 @@ static void prism2_check_sta_fw_version(local_info_t *local) static void prism2_crypt_deinit_entries(local_info_t *local, int force) { struct list_head *ptr, *n; - struct prism2_crypt_data *entry; + struct ieee80211_crypt_data *entry; for (ptr = local->crypt_deinit_list.next, n = ptr->next; ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) { - entry = list_entry(ptr, struct prism2_crypt_data, list); + entry = list_entry(ptr, struct ieee80211_crypt_data, list); if (atomic_read(&entry->refcnt) != 0 && !force) continue; @@ -3531,7 +3531,7 @@ static void prism2_free_local_data(struct net_device *dev) prism2_callback(local, PRISM2_CALLBACK_DISABLE); for (i = 0; i < WEP_KEYS; i++) { - struct prism2_crypt_data *crypt = local->crypt[i]; + struct ieee80211_crypt_data *crypt = local->crypt[i]; if (crypt) { if (crypt->ops) crypt->ops->deinit(crypt->priv); diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index bbed1e63458..f892aa87b13 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c @@ -115,9 +115,9 @@ static int prism2_get_name(struct net_device *dev, static void prism2_crypt_delayed_deinit(local_info_t *local, - struct prism2_crypt_data **crypt) + struct ieee80211_crypt_data **crypt) { - struct prism2_crypt_data *tmp; + struct ieee80211_crypt_data *tmp; unsigned long flags; tmp = *crypt; @@ -147,7 +147,7 @@ static int prism2_ioctl_siwencode(struct net_device *dev, struct hostap_interface *iface; local_info_t *local; int i; - struct prism2_crypt_data **crypt; + struct ieee80211_crypt_data **crypt; iface = netdev_priv(dev); local = iface->local; @@ -175,18 +175,19 @@ static int prism2_ioctl_siwencode(struct net_device *dev, } if (*crypt == NULL) { - struct prism2_crypt_data *new_crypt; + struct ieee80211_crypt_data *new_crypt; /* take WEP into use */ - new_crypt = (struct prism2_crypt_data *) - kmalloc(sizeof(struct prism2_crypt_data), GFP_KERNEL); + new_crypt = (struct ieee80211_crypt_data *) + kmalloc(sizeof(struct ieee80211_crypt_data), + GFP_KERNEL); if (new_crypt == NULL) return -ENOMEM; - memset(new_crypt, 0, sizeof(struct prism2_crypt_data)); - new_crypt->ops = hostap_get_crypto_ops("WEP"); + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); + new_crypt->ops = ieee80211_get_crypto_ops("WEP"); if (!new_crypt->ops) { - request_module("hostap_crypt_wep"); - new_crypt->ops = hostap_get_crypto_ops("WEP"); + request_module("ieee80211_crypt_wep"); + new_crypt->ops = ieee80211_get_crypto_ops("WEP"); } if (new_crypt->ops) new_crypt->priv = new_crypt->ops->init(i); @@ -251,7 +252,7 @@ static int prism2_ioctl_giwencode(struct net_device *dev, local_info_t *local; int i, len; u16 val; - struct prism2_crypt_data *crypt; + struct ieee80211_crypt_data *crypt; iface = netdev_priv(dev); local = iface->local; @@ -3259,8 +3260,8 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, local_info_t *local = iface->local; struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; int i, ret = 0; - struct hostap_crypto_ops *ops; - struct prism2_crypt_data **crypt; + struct ieee80211_crypto_ops *ops; + struct ieee80211_crypt_data **crypt; void *sta_ptr; u8 *addr; const char *alg, *module; @@ -3308,15 +3309,15 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, switch (ext->alg) { case IW_ENCODE_ALG_WEP: alg = "WEP"; - module = "hostap_crypt_wep"; + module = "ieee80211_crypt_wep"; break; case IW_ENCODE_ALG_TKIP: alg = "TKIP"; - module = "hostap_crypt_tkip"; + module = "ieee80211_crypt_tkip"; break; case IW_ENCODE_ALG_CCMP: alg = "CCMP"; - module = "hostap_crypt_ccmp"; + module = "ieee80211_crypt_ccmp"; break; default: printk(KERN_DEBUG "%s: unsupported algorithm %d\n", @@ -3325,10 +3326,10 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, goto done; } - ops = hostap_get_crypto_ops(alg); + ops = ieee80211_get_crypto_ops(alg); if (ops == NULL) { request_module(module); - ops = hostap_get_crypto_ops(alg); + ops = ieee80211_get_crypto_ops(alg); } if (ops == NULL) { printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", @@ -3347,17 +3348,18 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, } if (*crypt == NULL || (*crypt)->ops != ops) { - struct prism2_crypt_data *new_crypt; + struct ieee80211_crypt_data *new_crypt; prism2_crypt_delayed_deinit(local, crypt); - new_crypt = (struct prism2_crypt_data *) - kmalloc(sizeof(struct prism2_crypt_data), GFP_KERNEL); + new_crypt = (struct ieee80211_crypt_data *) + kmalloc(sizeof(struct ieee80211_crypt_data), + GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; } - memset(new_crypt, 0, sizeof(struct prism2_crypt_data)); + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ops; new_crypt->priv = new_crypt->ops->init(i); if (new_crypt->priv == NULL) { @@ -3436,7 +3438,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev, { struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; - struct prism2_crypt_data **crypt; + struct ieee80211_crypt_data **crypt; void *sta_ptr; int max_key_len, i; struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; @@ -3505,8 +3507,8 @@ static int prism2_ioctl_set_encryption(local_info_t *local, int param_len) { int ret = 0; - struct hostap_crypto_ops *ops; - struct prism2_crypt_data **crypt; + struct ieee80211_crypto_ops *ops; + struct ieee80211_crypt_data **crypt; void *sta_ptr; param->u.crypt.err = 0; @@ -3544,16 +3546,16 @@ static int prism2_ioctl_set_encryption(local_info_t *local, goto done; } - ops = hostap_get_crypto_ops(param->u.crypt.alg); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { - request_module("hostap_crypt_wep"); - ops = hostap_get_crypto_ops(param->u.crypt.alg); + request_module("ieee80211_crypt_wep"); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { - request_module("hostap_crypt_tkip"); - ops = hostap_get_crypto_ops(param->u.crypt.alg); + request_module("ieee80211_crypt_tkip"); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { - request_module("hostap_crypt_ccmp"); - ops = hostap_get_crypto_ops(param->u.crypt.alg); + request_module("ieee80211_crypt_ccmp"); + ops = ieee80211_get_crypto_ops(param->u.crypt.alg); } if (ops == NULL) { printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", @@ -3568,17 +3570,18 @@ static int prism2_ioctl_set_encryption(local_info_t *local, local->host_decrypt = local->host_encrypt = 1; if (*crypt == NULL || (*crypt)->ops != ops) { - struct prism2_crypt_data *new_crypt; + struct ieee80211_crypt_data *new_crypt; prism2_crypt_delayed_deinit(local, crypt); - new_crypt = (struct prism2_crypt_data *) - kmalloc(sizeof(struct prism2_crypt_data), GFP_KERNEL); + new_crypt = (struct ieee80211_crypt_data *) + kmalloc(sizeof(struct ieee80211_crypt_data), + GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; } - memset(new_crypt, 0, sizeof(struct prism2_crypt_data)); + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ops; new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); if (new_crypt->priv == NULL) { @@ -3642,7 +3645,7 @@ static int prism2_ioctl_get_encryption(local_info_t *local, struct prism2_hostapd_param *param, int param_len) { - struct prism2_crypt_data **crypt; + struct ieee80211_crypt_data **crypt; void *sta_ptr; int max_key_len; diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index f215a22e8fe..a632d45f334 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h @@ -2,7 +2,6 @@ #define HOSTAP_WLAN_H #include "hostap_config.h" -#include "hostap_crypt.h" #include "hostap_common.h" #define MAX_PARM_DEVICES 8 @@ -534,13 +533,6 @@ struct prism2_frag_entry { }; -struct prism2_crypt_data { - struct list_head list; /* delayed deletion list */ - struct hostap_crypto_ops *ops; - void *priv; - atomic_t refcnt; -}; - struct hostap_cmd_queue { struct list_head list; wait_queue_head_t compl; @@ -765,7 +757,7 @@ struct local_info { #define WEP_KEYS 4 #define WEP_KEY_LEN 13 - struct prism2_crypt_data *crypt[WEP_KEYS]; + struct ieee80211_crypt_data *crypt[WEP_KEYS]; int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ struct timer_list crypt_deinit_timer; struct list_head crypt_deinit_list; |