diff options
author | Jouni Malinen <jkmaline@cc.hut.fi> | 2005-07-30 23:43:20 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-07-31 00:28:02 -0400 |
commit | 62fe7e378109537ff80971c5208e12d40bf88bee (patch) | |
tree | 6facd4654afbef6590e21c4fde0c71fb7ed79f2e /drivers | |
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')
-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 | |||
7 | Host AP mode that allows the card to act as an IEEE 802.11 | 7 | Host AP mode that allows the card to act as an IEEE 802.11 |
8 | access point. | 8 | access point. |
9 | 9 | ||
10 | In addition, this includes generic IEEE 802.11 code, e.g., for | ||
11 | WEP/TKIP/CCMP encryption that can be shared with other drivers. | ||
12 | |||
13 | See <http://hostap.epitest.fi/> for more information about the | 10 | See <http://hostap.epitest.fi/> for more information about the |
14 | Host AP driver configuration and tools. This site includes | 11 | Host AP driver configuration and tools. This site includes |
15 | information and tools (hostapd and wpa_supplicant) for WPA/WPA2 | 12 | information and tools (hostapd and wpa_supplicant) for WPA/WPA2 |
@@ -22,36 +19,6 @@ config HOSTAP | |||
22 | The driver can be compiled as a module and it will be called | 19 | The driver can be compiled as a module and it will be called |
23 | "hostap.ko". | 20 | "hostap.ko". |
24 | 21 | ||
25 | config HOSTAP_WEP | ||
26 | tristate "IEEE 802.11 WEP encryption" | ||
27 | depends on HOSTAP | ||
28 | select CRYPTO | ||
29 | ---help--- | ||
30 | Software implementation of IEEE 802.11 WEP encryption. | ||
31 | |||
32 | This can be compiled as a modules and it will be called | ||
33 | "hostap_crypt_wep.ko". | ||
34 | |||
35 | config HOSTAP_TKIP | ||
36 | tristate "IEEE 802.11 TKIP encryption" | ||
37 | depends on HOSTAP | ||
38 | select CRYPTO | ||
39 | ---help--- | ||
40 | Software implementation of IEEE 802.11 TKIP encryption. | ||
41 | |||
42 | This can be compiled as a modules and it will be called | ||
43 | "hostap_crypt_tkip.ko". | ||
44 | |||
45 | config HOSTAP_CCMP | ||
46 | tristate "IEEE 802.11 CCMP encryption" | ||
47 | depends on HOSTAP | ||
48 | select CRYPTO | ||
49 | ---help--- | ||
50 | Software implementation of IEEE 802.11 CCMP encryption. | ||
51 | |||
52 | This can be compiled as a modules and it will be called | ||
53 | "hostap_crypt_ccmp.ko". | ||
54 | |||
55 | config HOSTAP_FIRMWARE | 22 | config HOSTAP_FIRMWARE |
56 | bool "Support downloading firmware images with Host AP driver" | 23 | bool "Support downloading firmware images with Host AP driver" |
57 | depends on HOSTAP | 24 | 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 @@ | |||
1 | obj-$(CONFIG_HOSTAP) += hostap.o | 1 | obj-$(CONFIG_HOSTAP) += hostap.o |
2 | obj-$(CONFIG_HOSTAP_WEP) += hostap_crypt_wep.o | ||
3 | obj-$(CONFIG_HOSTAP_TKIP) += hostap_crypt_tkip.o | ||
4 | obj-$(CONFIG_HOSTAP_CCMP) += hostap_crypt_ccmp.o | ||
5 | 2 | ||
6 | obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o | 3 | obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o |
7 | obj-$(CONFIG_HOSTAP_PLX) += hostap_plx.o | 4 | 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 @@ | |||
4 | * | 4 | * |
5 | * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen | 5 | * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen |
6 | * <jkmaline@cc.hut.fi> | 6 | * <jkmaline@cc.hut.fi> |
7 | * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi> | 7 | * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -34,16 +34,12 @@ | |||
34 | #include "hostap_80211.h" | 34 | #include "hostap_80211.h" |
35 | #include "hostap_ap.h" | 35 | #include "hostap_ap.h" |
36 | #include "hostap.h" | 36 | #include "hostap.h" |
37 | #include "hostap_crypt.h" | ||
38 | 37 | ||
39 | MODULE_AUTHOR("Jouni Malinen"); | 38 | MODULE_AUTHOR("Jouni Malinen"); |
40 | MODULE_DESCRIPTION("Host AP common routines"); | 39 | MODULE_DESCRIPTION("Host AP common routines"); |
41 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
42 | MODULE_VERSION(PRISM2_VERSION); | 41 | MODULE_VERSION(PRISM2_VERSION); |
43 | 42 | ||
44 | /* Old hostap_crypt module is now part of hostap module. */ | ||
45 | #include "hostap_crypt.c" | ||
46 | |||
47 | #define TX_TIMEOUT (2 * HZ) | 43 | #define TX_TIMEOUT (2 * HZ) |
48 | 44 | ||
49 | #define PRISM2_MAX_FRAME_SIZE 2304 | 45 | #define PRISM2_MAX_FRAME_SIZE 2304 |
@@ -66,7 +62,7 @@ static int prism2_ap_translate_scan(struct net_device *dev, char *buffer); | |||
66 | static int prism2_hostapd(struct ap_data *ap, | 62 | static int prism2_hostapd(struct ap_data *ap, |
67 | struct prism2_hostapd_param *param); | 63 | struct prism2_hostapd_param *param); |
68 | static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, | 64 | static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, |
69 | struct prism2_crypt_data ***crypt); | 65 | struct ieee80211_crypt_data ***crypt); |
70 | static void ap_control_kickall(struct ap_data *ap); | 66 | static void ap_control_kickall(struct ap_data *ap); |
71 | #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT | 67 | #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT |
72 | static int ap_control_add_mac(struct mac_restrictions *mac_restrictions, | 68 | static int ap_control_add_mac(struct mac_restrictions *mac_restrictions, |
@@ -1156,8 +1152,6 @@ struct proc_dir_entry *hostap_proc; | |||
1156 | 1152 | ||
1157 | static int __init hostap_init(void) | 1153 | static int __init hostap_init(void) |
1158 | { | 1154 | { |
1159 | hostap_crypto_init(); | ||
1160 | |||
1161 | if (proc_net != NULL) { | 1155 | if (proc_net != NULL) { |
1162 | hostap_proc = proc_mkdir("hostap", proc_net); | 1156 | hostap_proc = proc_mkdir("hostap", proc_net); |
1163 | if (!hostap_proc) | 1157 | if (!hostap_proc) |
@@ -1176,8 +1170,6 @@ static void __exit hostap_exit(void) | |||
1176 | hostap_proc = NULL; | 1170 | hostap_proc = NULL; |
1177 | remove_proc_entry("hostap", proc_net); | 1171 | remove_proc_entry("hostap", proc_net); |
1178 | } | 1172 | } |
1179 | |||
1180 | hostap_crypto_deinit(); | ||
1181 | } | 1173 | } |
1182 | 1174 | ||
1183 | 1175 | ||
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); | |||
101 | int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev); | 101 | int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev); |
102 | int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev); | 102 | int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev); |
103 | struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, | 103 | struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, |
104 | struct prism2_crypt_data *crypt); | 104 | struct ieee80211_crypt_data *crypt); |
105 | int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev); | 105 | int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev); |
106 | 106 | ||
107 | #endif /* HOSTAP_80211_H */ | 107 | #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) | |||
613 | /* Called only as a tasklet (software IRQ) */ | 613 | /* Called only as a tasklet (software IRQ) */ |
614 | static inline int | 614 | static inline int |
615 | hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, | 615 | hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, |
616 | struct prism2_crypt_data *crypt) | 616 | struct ieee80211_crypt_data *crypt) |
617 | { | 617 | { |
618 | struct hostap_ieee80211_hdr *hdr; | 618 | struct hostap_ieee80211_hdr *hdr; |
619 | int res, hdrlen; | 619 | int res, hdrlen; |
@@ -652,7 +652,7 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, | |||
652 | /* Called only as a tasklet (software IRQ) */ | 652 | /* Called only as a tasklet (software IRQ) */ |
653 | static inline int | 653 | static inline int |
654 | hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb, | 654 | hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb, |
655 | int keyidx, struct prism2_crypt_data *crypt) | 655 | int keyidx, struct ieee80211_crypt_data *crypt) |
656 | { | 656 | { |
657 | struct hostap_ieee80211_hdr *hdr; | 657 | struct hostap_ieee80211_hdr *hdr; |
658 | int res, hdrlen; | 658 | int res, hdrlen; |
@@ -698,7 +698,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, | |||
698 | int from_assoc_ap = 0; | 698 | int from_assoc_ap = 0; |
699 | u8 dst[ETH_ALEN]; | 699 | u8 dst[ETH_ALEN]; |
700 | u8 src[ETH_ALEN]; | 700 | u8 src[ETH_ALEN]; |
701 | struct prism2_crypt_data *crypt = NULL; | 701 | struct ieee80211_crypt_data *crypt = NULL; |
702 | void *sta = NULL; | 702 | void *sta = NULL; |
703 | int keyidx = 0; | 703 | int keyidx = 0; |
704 | 704 | ||
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) | |||
284 | 284 | ||
285 | /* Called only from software IRQ */ | 285 | /* Called only from software IRQ */ |
286 | struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, | 286 | struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, |
287 | struct prism2_crypt_data *crypt) | 287 | struct ieee80211_crypt_data *crypt) |
288 | { | 288 | { |
289 | struct hostap_interface *iface; | 289 | struct hostap_interface *iface; |
290 | local_info_t *local; | 290 | 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 @@ | |||
2 | * Intersil Prism2 driver with Host AP (software access point) support | 2 | * Intersil Prism2 driver with Host AP (software access point) support |
3 | * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen | 3 | * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen |
4 | * <jkmaline@cc.hut.fi> | 4 | * <jkmaline@cc.hut.fi> |
5 | * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> | 5 | * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> |
6 | * | 6 | * |
7 | * This file is to be included into hostap.c when S/W AP functionality is | 7 | * This file is to be included into hostap.c when S/W AP functionality is |
8 | * compiled. | 8 | * compiled. |
@@ -1206,7 +1206,7 @@ static void prism2_check_tx_rates(struct sta_info *sta) | |||
1206 | 1206 | ||
1207 | static void ap_crypt_init(struct ap_data *ap) | 1207 | static void ap_crypt_init(struct ap_data *ap) |
1208 | { | 1208 | { |
1209 | ap->crypt = hostap_get_crypto_ops("WEP"); | 1209 | ap->crypt = ieee80211_get_crypto_ops("WEP"); |
1210 | 1210 | ||
1211 | if (ap->crypt) { | 1211 | if (ap->crypt) { |
1212 | if (ap->crypt->init) { | 1212 | if (ap->crypt->init) { |
@@ -1224,7 +1224,7 @@ static void ap_crypt_init(struct ap_data *ap) | |||
1224 | 1224 | ||
1225 | if (ap->crypt == NULL) { | 1225 | if (ap->crypt == NULL) { |
1226 | printk(KERN_WARNING "AP could not initialize WEP: load module " | 1226 | printk(KERN_WARNING "AP could not initialize WEP: load module " |
1227 | "hostap_crypt_wep.o\n"); | 1227 | "ieee80211_crypt_wep.ko\n"); |
1228 | } | 1228 | } |
1229 | } | 1229 | } |
1230 | 1230 | ||
@@ -1293,7 +1293,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb, | |||
1293 | u16 auth_alg, auth_transaction, status_code, *pos; | 1293 | u16 auth_alg, auth_transaction, status_code, *pos; |
1294 | u16 resp = WLAN_STATUS_SUCCESS, fc; | 1294 | u16 resp = WLAN_STATUS_SUCCESS, fc; |
1295 | struct sta_info *sta = NULL; | 1295 | struct sta_info *sta = NULL; |
1296 | struct prism2_crypt_data *crypt; | 1296 | struct ieee80211_crypt_data *crypt; |
1297 | char *txt = ""; | 1297 | char *txt = ""; |
1298 | 1298 | ||
1299 | len = skb->len - IEEE80211_MGMT_HDR_LEN; | 1299 | 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, | |||
3058 | /* Called only as a tasklet (software IRQ) */ | 3058 | /* Called only as a tasklet (software IRQ) */ |
3059 | int hostap_handle_sta_crypto(local_info_t *local, | 3059 | int hostap_handle_sta_crypto(local_info_t *local, |
3060 | struct hostap_ieee80211_hdr *hdr, | 3060 | struct hostap_ieee80211_hdr *hdr, |
3061 | struct prism2_crypt_data **crypt, void **sta_ptr) | 3061 | struct ieee80211_crypt_data **crypt, |
3062 | void **sta_ptr) | ||
3062 | { | 3063 | { |
3063 | struct sta_info *sta; | 3064 | struct sta_info *sta; |
3064 | 3065 | ||
@@ -3206,7 +3207,7 @@ void hostap_update_rates(local_info_t *local) | |||
3206 | 3207 | ||
3207 | 3208 | ||
3208 | static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, | 3209 | static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, |
3209 | struct prism2_crypt_data ***crypt) | 3210 | struct ieee80211_crypt_data ***crypt) |
3210 | { | 3211 | { |
3211 | struct sta_info *sta; | 3212 | struct sta_info *sta; |
3212 | 3213 | ||
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 { | |||
81 | u32 tx_since_last_failure; | 81 | u32 tx_since_last_failure; |
82 | u32 tx_consecutive_exc; | 82 | u32 tx_consecutive_exc; |
83 | 83 | ||
84 | struct prism2_crypt_data *crypt; | 84 | struct ieee80211_crypt_data *crypt; |
85 | 85 | ||
86 | int ap; /* whether this station is an AP */ | 86 | int ap; /* whether this station is an AP */ |
87 | 87 | ||
@@ -216,7 +216,7 @@ struct ap_data { | |||
216 | 216 | ||
217 | /* WEP operations for generating challenges to be used with shared key | 217 | /* WEP operations for generating challenges to be used with shared key |
218 | * authentication */ | 218 | * authentication */ |
219 | struct hostap_crypto_ops *crypt; | 219 | struct ieee80211_crypto_ops *crypt; |
220 | void *crypt_priv; | 220 | void *crypt_priv; |
221 | #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ | 221 | #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ |
222 | }; | 222 | }; |
@@ -236,7 +236,7 @@ typedef enum { | |||
236 | struct hostap_tx_data { | 236 | struct hostap_tx_data { |
237 | struct sk_buff *skb; | 237 | struct sk_buff *skb; |
238 | int host_encrypt; | 238 | int host_encrypt; |
239 | struct prism2_crypt_data *crypt; | 239 | struct ieee80211_crypt_data *crypt; |
240 | void *sta_ptr; | 240 | void *sta_ptr; |
241 | }; | 241 | }; |
242 | ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx); | 242 | 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, | |||
253 | int wds); | 253 | int wds); |
254 | int hostap_handle_sta_crypto(local_info_t *local, | 254 | int hostap_handle_sta_crypto(local_info_t *local, |
255 | struct hostap_ieee80211_hdr *hdr, | 255 | struct hostap_ieee80211_hdr *hdr, |
256 | struct prism2_crypt_data **crypt, void **sta_ptr); | 256 | struct ieee80211_crypt_data **crypt, |
257 | void **sta_ptr); | ||
257 | int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr); | 258 | int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr); |
258 | int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr); | 259 | int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr); |
259 | int hostap_add_sta(struct ap_data *ap, u8 *sta_addr); | 260 | 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 @@ | |||
1 | /* | ||
2 | * Host AP crypto routines | ||
3 | * | ||
4 | * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. See README and COPYING for | ||
9 | * more details. | ||
10 | */ | ||
11 | |||
12 | struct hostap_crypto_alg { | ||
13 | struct list_head list; | ||
14 | struct hostap_crypto_ops *ops; | ||
15 | }; | ||
16 | |||
17 | |||
18 | struct hostap_crypto { | ||
19 | struct list_head algs; | ||
20 | spinlock_t lock; | ||
21 | }; | ||
22 | |||
23 | static struct hostap_crypto *hcrypt; | ||
24 | |||
25 | |||
26 | int hostap_register_crypto_ops(struct hostap_crypto_ops *ops) | ||
27 | { | ||
28 | unsigned long flags; | ||
29 | struct hostap_crypto_alg *alg; | ||
30 | |||
31 | if (hcrypt == NULL) | ||
32 | return -1; | ||
33 | |||
34 | alg = (struct hostap_crypto_alg *) kmalloc(sizeof(*alg), GFP_KERNEL); | ||
35 | if (alg == NULL) | ||
36 | return -ENOMEM; | ||
37 | |||
38 | memset(alg, 0, sizeof(*alg)); | ||
39 | alg->ops = ops; | ||
40 | |||
41 | spin_lock_irqsave(&hcrypt->lock, flags); | ||
42 | list_add(&alg->list, &hcrypt->algs); | ||
43 | spin_unlock_irqrestore(&hcrypt->lock, flags); | ||
44 | |||
45 | printk(KERN_DEBUG "hostap_crypt: registered algorithm '%s'\n", | ||
46 | ops->name); | ||
47 | |||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | |||
52 | int hostap_unregister_crypto_ops(struct hostap_crypto_ops *ops) | ||
53 | { | ||
54 | unsigned long flags; | ||
55 | struct list_head *ptr; | ||
56 | struct hostap_crypto_alg *del_alg = NULL; | ||
57 | |||
58 | if (hcrypt == NULL) | ||
59 | return -1; | ||
60 | |||
61 | spin_lock_irqsave(&hcrypt->lock, flags); | ||
62 | for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { | ||
63 | struct hostap_crypto_alg *alg = | ||
64 | (struct hostap_crypto_alg *) ptr; | ||
65 | if (alg->ops == ops) { | ||
66 | list_del(&alg->list); | ||
67 | del_alg = alg; | ||
68 | break; | ||
69 | } | ||
70 | } | ||
71 | spin_unlock_irqrestore(&hcrypt->lock, flags); | ||
72 | |||
73 | if (del_alg) { | ||
74 | printk(KERN_DEBUG "hostap_crypt: unregistered algorithm " | ||
75 | "'%s'\n", ops->name); | ||
76 | kfree(del_alg); | ||
77 | } | ||
78 | |||
79 | return del_alg ? 0 : -1; | ||
80 | } | ||
81 | |||
82 | |||
83 | struct hostap_crypto_ops * hostap_get_crypto_ops(const char *name) | ||
84 | { | ||
85 | unsigned long flags; | ||
86 | struct list_head *ptr; | ||
87 | struct hostap_crypto_alg *found_alg = NULL; | ||
88 | |||
89 | if (hcrypt == NULL) | ||
90 | return NULL; | ||
91 | |||
92 | spin_lock_irqsave(&hcrypt->lock, flags); | ||
93 | for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { | ||
94 | struct hostap_crypto_alg *alg = | ||
95 | (struct hostap_crypto_alg *) ptr; | ||
96 | if (strcmp(alg->ops->name, name) == 0) { | ||
97 | found_alg = alg; | ||
98 | break; | ||
99 | } | ||
100 | } | ||
101 | spin_unlock_irqrestore(&hcrypt->lock, flags); | ||
102 | |||
103 | if (found_alg) | ||
104 | return found_alg->ops; | ||
105 | else | ||
106 | return NULL; | ||
107 | } | ||
108 | |||
109 | |||
110 | static void * hostap_crypt_null_init(int keyidx) { return (void *) 1; } | ||
111 | static void hostap_crypt_null_deinit(void *priv) {} | ||
112 | |||
113 | static struct hostap_crypto_ops hostap_crypt_null = { | ||
114 | .name = "NULL", | ||
115 | .init = hostap_crypt_null_init, | ||
116 | .deinit = hostap_crypt_null_deinit, | ||
117 | .encrypt_mpdu = NULL, | ||
118 | .decrypt_mpdu = NULL, | ||
119 | .encrypt_msdu = NULL, | ||
120 | .decrypt_msdu = NULL, | ||
121 | .set_key = NULL, | ||
122 | .get_key = NULL, | ||
123 | .extra_prefix_len = 0, | ||
124 | .extra_postfix_len = 0 | ||
125 | }; | ||
126 | |||
127 | |||
128 | static int __init hostap_crypto_init(void) | ||
129 | { | ||
130 | hcrypt = (struct hostap_crypto *) kmalloc(sizeof(*hcrypt), GFP_KERNEL); | ||
131 | if (hcrypt == NULL) | ||
132 | return -ENOMEM; | ||
133 | |||
134 | memset(hcrypt, 0, sizeof(*hcrypt)); | ||
135 | INIT_LIST_HEAD(&hcrypt->algs); | ||
136 | spin_lock_init(&hcrypt->lock); | ||
137 | |||
138 | (void) hostap_register_crypto_ops(&hostap_crypt_null); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | |||
144 | static void __exit hostap_crypto_deinit(void) | ||
145 | { | ||
146 | struct list_head *ptr, *n; | ||
147 | |||
148 | if (hcrypt == NULL) | ||
149 | return; | ||
150 | |||
151 | for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; | ||
152 | ptr = n, n = ptr->next) { | ||
153 | struct hostap_crypto_alg *alg = | ||
154 | (struct hostap_crypto_alg *) ptr; | ||
155 | list_del(ptr); | ||
156 | printk(KERN_DEBUG "hostap_crypt: unregistered algorithm " | ||
157 | "'%s' (deinit)\n", alg->ops->name); | ||
158 | kfree(alg); | ||
159 | } | ||
160 | |||
161 | kfree(hcrypt); | ||
162 | } | ||
163 | |||
164 | |||
165 | EXPORT_SYMBOL(hostap_register_crypto_ops); | ||
166 | EXPORT_SYMBOL(hostap_unregister_crypto_ops); | ||
167 | 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 @@ | |||
1 | #ifndef PRISM2_CRYPT_H | ||
2 | #define PRISM2_CRYPT_H | ||
3 | |||
4 | struct hostap_crypto_ops { | ||
5 | char *name; | ||
6 | |||
7 | /* init new crypto context (e.g., allocate private data space, | ||
8 | * select IV, etc.); returns NULL on failure or pointer to allocated | ||
9 | * private data on success */ | ||
10 | void * (*init)(int keyidx); | ||
11 | |||
12 | /* deinitialize crypto context and free allocated private data */ | ||
13 | void (*deinit)(void *priv); | ||
14 | |||
15 | /* encrypt/decrypt return < 0 on error or >= 0 on success. The return | ||
16 | * value from decrypt_mpdu is passed as the keyidx value for | ||
17 | * decrypt_msdu. skb must have enough head and tail room for the | ||
18 | * encryption; if not, error will be returned; these functions are | ||
19 | * called for all MPDUs (i.e., fragments). | ||
20 | */ | ||
21 | int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); | ||
22 | int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); | ||
23 | |||
24 | /* These functions are called for full MSDUs, i.e. full frames. | ||
25 | * These can be NULL if full MSDU operations are not needed. */ | ||
26 | int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv); | ||
27 | int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len, | ||
28 | void *priv); | ||
29 | |||
30 | int (*set_key)(void *key, int len, u8 *seq, void *priv); | ||
31 | int (*get_key)(void *key, int len, u8 *seq, void *priv); | ||
32 | |||
33 | /* procfs handler for printing out key information and possible | ||
34 | * statistics */ | ||
35 | char * (*print_stats)(char *p, void *priv); | ||
36 | |||
37 | /* maximum number of bytes added by encryption; encrypt buf is | ||
38 | * allocated with extra_prefix_len bytes, copy of in_buf, and | ||
39 | * extra_postfix_len; encrypt need not use all this space, but | ||
40 | * the result must start at the beginning of the buffer and correct | ||
41 | * length must be returned */ | ||
42 | int extra_prefix_len, extra_postfix_len; | ||
43 | }; | ||
44 | |||
45 | |||
46 | int hostap_register_crypto_ops(struct hostap_crypto_ops *ops); | ||
47 | int hostap_unregister_crypto_ops(struct hostap_crypto_ops *ops); | ||
48 | struct hostap_crypto_ops * hostap_get_crypto_ops(const char *name); | ||
49 | |||
50 | #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 @@ | |||
1 | /* | ||
2 | * Host AP crypt: host-based CCMP encryption implementation for Host AP driver | ||
3 | * | ||
4 | * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. See README and COPYING for | ||
9 | * more details. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/version.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/random.h> | ||
18 | #include <linux/skbuff.h> | ||
19 | #include <linux/netdevice.h> | ||
20 | #include <linux/if_ether.h> | ||
21 | #include <linux/if_arp.h> | ||
22 | #include <linux/wireless.h> | ||
23 | #include <net/iw_handler.h> | ||
24 | #include <asm/string.h> | ||
25 | |||
26 | #include "hostap_crypt.h" | ||
27 | #include "hostap_wlan.h" | ||
28 | #include "hostap_80211.h" | ||
29 | |||
30 | #ifndef CONFIG_CRYPTO | ||
31 | #error CONFIG_CRYPTO is required to build this module. | ||
32 | #endif | ||
33 | #include <linux/crypto.h> | ||
34 | #include <asm/scatterlist.h> | ||
35 | |||
36 | MODULE_AUTHOR("Jouni Malinen"); | ||
37 | MODULE_DESCRIPTION("Host AP crypt: CCMP"); | ||
38 | MODULE_LICENSE("GPL"); | ||
39 | MODULE_VERSION(PRISM2_VERSION); | ||
40 | |||
41 | |||
42 | #define AES_BLOCK_LEN 16 | ||
43 | #define CCMP_HDR_LEN 8 | ||
44 | #define CCMP_MIC_LEN 8 | ||
45 | #define CCMP_TK_LEN 16 | ||
46 | #define CCMP_PN_LEN 6 | ||
47 | |||
48 | |||
49 | struct hostap_ccmp_data { | ||
50 | u8 key[CCMP_TK_LEN]; | ||
51 | int key_set; | ||
52 | |||
53 | u8 tx_pn[CCMP_PN_LEN]; | ||
54 | u8 rx_pn[CCMP_PN_LEN]; | ||
55 | |||
56 | u32 dot11RSNAStatsCCMPFormatErrors; | ||
57 | u32 dot11RSNAStatsCCMPReplays; | ||
58 | u32 dot11RSNAStatsCCMPDecryptErrors; | ||
59 | |||
60 | int key_idx; | ||
61 | |||
62 | struct crypto_tfm *tfm; | ||
63 | |||
64 | /* scratch buffers for virt_to_page() (crypto API) */ | ||
65 | u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN], | ||
66 | tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN]; | ||
67 | u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; | ||
68 | }; | ||
69 | |||
70 | |||
71 | void hostap_ccmp_aes_encrypt(struct crypto_tfm *tfm, | ||
72 | const u8 pt[16], u8 ct[16]) | ||
73 | { | ||
74 | struct scatterlist src, dst; | ||
75 | |||
76 | src.page = virt_to_page(pt); | ||
77 | src.offset = offset_in_page(pt); | ||
78 | src.length = AES_BLOCK_LEN; | ||
79 | |||
80 | dst.page = virt_to_page(ct); | ||
81 | dst.offset = offset_in_page(ct); | ||
82 | dst.length = AES_BLOCK_LEN; | ||
83 | |||
84 | crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN); | ||
85 | } | ||
86 | |||
87 | |||
88 | static void * hostap_ccmp_init(int key_idx) | ||
89 | { | ||
90 | struct hostap_ccmp_data *priv; | ||
91 | |||
92 | if (!try_module_get(THIS_MODULE)) | ||
93 | return NULL; | ||
94 | |||
95 | priv = (struct hostap_ccmp_data *) kmalloc(sizeof(*priv), GFP_ATOMIC); | ||
96 | if (priv == NULL) { | ||
97 | goto fail; | ||
98 | } | ||
99 | memset(priv, 0, sizeof(*priv)); | ||
100 | priv->key_idx = key_idx; | ||
101 | |||
102 | priv->tfm = crypto_alloc_tfm("aes", 0); | ||
103 | if (priv->tfm == NULL) { | ||
104 | printk(KERN_DEBUG "hostap_crypt_ccmp: could not allocate " | ||
105 | "crypto API aes\n"); | ||
106 | goto fail; | ||
107 | } | ||
108 | |||
109 | return priv; | ||
110 | |||
111 | fail: | ||
112 | if (priv) { | ||
113 | if (priv->tfm) | ||
114 | crypto_free_tfm(priv->tfm); | ||
115 | kfree(priv); | ||
116 | } | ||
117 | module_put(THIS_MODULE); | ||
118 | return NULL; | ||
119 | } | ||
120 | |||
121 | |||
122 | static void hostap_ccmp_deinit(void *priv) | ||
123 | { | ||
124 | struct hostap_ccmp_data *_priv = priv; | ||
125 | if (_priv && _priv->tfm) | ||
126 | crypto_free_tfm(_priv->tfm); | ||
127 | kfree(priv); | ||
128 | module_put(THIS_MODULE); | ||
129 | } | ||
130 | |||
131 | |||
132 | static inline void xor_block(u8 *b, u8 *a, size_t len) | ||
133 | { | ||
134 | int i; | ||
135 | for (i = 0; i < len; i++) | ||
136 | b[i] ^= a[i]; | ||
137 | } | ||
138 | |||
139 | |||
140 | static void ccmp_init_blocks(struct crypto_tfm *tfm, | ||
141 | struct hostap_ieee80211_hdr *hdr, | ||
142 | u8 *pn, size_t dlen, u8 *b0, u8 *auth, | ||
143 | u8 *s0) | ||
144 | { | ||
145 | u8 *pos, qc = 0; | ||
146 | size_t aad_len; | ||
147 | u16 fc; | ||
148 | int a4_included, qc_included; | ||
149 | u8 aad[2 * AES_BLOCK_LEN]; | ||
150 | |||
151 | fc = le16_to_cpu(hdr->frame_control); | ||
152 | a4_included = ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == | ||
153 | (WLAN_FC_TODS | WLAN_FC_FROMDS)); | ||
154 | qc_included = ((HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) && | ||
155 | (HOSTAP_FC_GET_STYPE(fc) & 0x08)); | ||
156 | aad_len = 22; | ||
157 | if (a4_included) | ||
158 | aad_len += 6; | ||
159 | if (qc_included) { | ||
160 | pos = (u8 *) &hdr->addr4; | ||
161 | if (a4_included) | ||
162 | pos += 6; | ||
163 | qc = *pos & 0x0f; | ||
164 | aad_len += 2; | ||
165 | } | ||
166 | |||
167 | /* CCM Initial Block: | ||
168 | * Flag (Include authentication header, M=3 (8-octet MIC), | ||
169 | * L=1 (2-octet Dlen)) | ||
170 | * Nonce: 0x00 | A2 | PN | ||
171 | * Dlen */ | ||
172 | b0[0] = 0x59; | ||
173 | b0[1] = qc; | ||
174 | memcpy(b0 + 2, hdr->addr2, ETH_ALEN); | ||
175 | memcpy(b0 + 8, pn, CCMP_PN_LEN); | ||
176 | b0[14] = (dlen >> 8) & 0xff; | ||
177 | b0[15] = dlen & 0xff; | ||
178 | |||
179 | /* AAD: | ||
180 | * FC with bits 4..6 and 11..13 masked to zero; 14 is always one | ||
181 | * A1 | A2 | A3 | ||
182 | * SC with bits 4..15 (seq#) masked to zero | ||
183 | * A4 (if present) | ||
184 | * QC (if present) | ||
185 | */ | ||
186 | pos = (u8 *) hdr; | ||
187 | aad[0] = 0; /* aad_len >> 8 */ | ||
188 | aad[1] = aad_len & 0xff; | ||
189 | aad[2] = pos[0] & 0x8f; | ||
190 | aad[3] = pos[1] & 0xc7; | ||
191 | memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN); | ||
192 | pos = (u8 *) &hdr->seq_ctrl; | ||
193 | aad[22] = pos[0] & 0x0f; | ||
194 | aad[23] = 0; /* all bits masked */ | ||
195 | memset(aad + 24, 0, 8); | ||
196 | if (a4_included) | ||
197 | memcpy(aad + 24, hdr->addr4, ETH_ALEN); | ||
198 | if (qc_included) { | ||
199 | aad[a4_included ? 30 : 24] = qc; | ||
200 | /* rest of QC masked */ | ||
201 | } | ||
202 | |||
203 | /* Start with the first block and AAD */ | ||
204 | hostap_ccmp_aes_encrypt(tfm, b0, auth); | ||
205 | xor_block(auth, aad, AES_BLOCK_LEN); | ||
206 | hostap_ccmp_aes_encrypt(tfm, auth, auth); | ||
207 | xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); | ||
208 | hostap_ccmp_aes_encrypt(tfm, auth, auth); | ||
209 | b0[0] &= 0x07; | ||
210 | b0[14] = b0[15] = 0; | ||
211 | hostap_ccmp_aes_encrypt(tfm, b0, s0); | ||
212 | } | ||
213 | |||
214 | |||
215 | static int hostap_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | ||
216 | { | ||
217 | struct hostap_ccmp_data *key = priv; | ||
218 | int data_len, i, blocks, last, len; | ||
219 | u8 *pos, *mic; | ||
220 | struct hostap_ieee80211_hdr *hdr; | ||
221 | u8 *b0 = key->tx_b0; | ||
222 | u8 *b = key->tx_b; | ||
223 | u8 *e = key->tx_e; | ||
224 | u8 *s0 = key->tx_s0; | ||
225 | |||
226 | if (skb_headroom(skb) < CCMP_HDR_LEN || | ||
227 | skb_tailroom(skb) < CCMP_MIC_LEN || | ||
228 | skb->len < hdr_len) | ||
229 | return -1; | ||
230 | |||
231 | data_len = skb->len - hdr_len; | ||
232 | pos = skb_push(skb, CCMP_HDR_LEN); | ||
233 | memmove(pos, pos + CCMP_HDR_LEN, hdr_len); | ||
234 | pos += hdr_len; | ||
235 | mic = skb_put(skb, CCMP_MIC_LEN); | ||
236 | |||
237 | i = CCMP_PN_LEN - 1; | ||
238 | while (i >= 0) { | ||
239 | key->tx_pn[i]++; | ||
240 | if (key->tx_pn[i] != 0) | ||
241 | break; | ||
242 | i--; | ||
243 | } | ||
244 | |||
245 | *pos++ = key->tx_pn[5]; | ||
246 | *pos++ = key->tx_pn[4]; | ||
247 | *pos++ = 0; | ||
248 | *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */; | ||
249 | *pos++ = key->tx_pn[3]; | ||
250 | *pos++ = key->tx_pn[2]; | ||
251 | *pos++ = key->tx_pn[1]; | ||
252 | *pos++ = key->tx_pn[0]; | ||
253 | |||
254 | hdr = (struct hostap_ieee80211_hdr *) skb->data; | ||
255 | ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); | ||
256 | |||
257 | blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; | ||
258 | last = data_len % AES_BLOCK_LEN; | ||
259 | |||
260 | for (i = 1; i <= blocks; i++) { | ||
261 | len = (i == blocks && last) ? last : AES_BLOCK_LEN; | ||
262 | /* Authentication */ | ||
263 | xor_block(b, pos, len); | ||
264 | hostap_ccmp_aes_encrypt(key->tfm, b, b); | ||
265 | /* Encryption, with counter */ | ||
266 | b0[14] = (i >> 8) & 0xff; | ||
267 | b0[15] = i & 0xff; | ||
268 | hostap_ccmp_aes_encrypt(key->tfm, b0, e); | ||
269 | xor_block(pos, e, len); | ||
270 | pos += len; | ||
271 | } | ||
272 | |||
273 | for (i = 0; i < CCMP_MIC_LEN; i++) | ||
274 | mic[i] = b[i] ^ s0[i]; | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | |||
280 | static int hostap_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | ||
281 | { | ||
282 | struct hostap_ccmp_data *key = priv; | ||
283 | u8 keyidx, *pos; | ||
284 | struct hostap_ieee80211_hdr *hdr; | ||
285 | u8 *b0 = key->rx_b0; | ||
286 | u8 *b = key->rx_b; | ||
287 | u8 *a = key->rx_a; | ||
288 | u8 pn[6]; | ||
289 | int i, blocks, last, len; | ||
290 | size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN; | ||
291 | u8 *mic = skb->data + skb->len - CCMP_MIC_LEN; | ||
292 | |||
293 | if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { | ||
294 | key->dot11RSNAStatsCCMPFormatErrors++; | ||
295 | return -1; | ||
296 | } | ||
297 | |||
298 | hdr = (struct hostap_ieee80211_hdr *) skb->data; | ||
299 | pos = skb->data + hdr_len; | ||
300 | keyidx = pos[3]; | ||
301 | if (!(keyidx & (1 << 5))) { | ||
302 | if (net_ratelimit()) { | ||
303 | printk(KERN_DEBUG "CCMP: received packet without ExtIV" | ||
304 | " flag from " MACSTR "\n", MAC2STR(hdr->addr2)); | ||
305 | } | ||
306 | key->dot11RSNAStatsCCMPFormatErrors++; | ||
307 | return -2; | ||
308 | } | ||
309 | keyidx >>= 6; | ||
310 | if (key->key_idx != keyidx) { | ||
311 | printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame " | ||
312 | "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv); | ||
313 | return -6; | ||
314 | } | ||
315 | if (!key->key_set) { | ||
316 | if (net_ratelimit()) { | ||
317 | printk(KERN_DEBUG "CCMP: received packet from " MACSTR | ||
318 | " with keyid=%d that does not have a configured" | ||
319 | " key\n", MAC2STR(hdr->addr2), keyidx); | ||
320 | } | ||
321 | return -3; | ||
322 | } | ||
323 | |||
324 | pn[0] = pos[7]; | ||
325 | pn[1] = pos[6]; | ||
326 | pn[2] = pos[5]; | ||
327 | pn[3] = pos[4]; | ||
328 | pn[4] = pos[1]; | ||
329 | pn[5] = pos[0]; | ||
330 | pos += 8; | ||
331 | |||
332 | if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { | ||
333 | if (net_ratelimit()) { | ||
334 | printk(KERN_DEBUG "CCMP: replay detected: STA=" MACSTR | ||
335 | " previous PN %02x%02x%02x%02x%02x%02x " | ||
336 | "received PN %02x%02x%02x%02x%02x%02x\n", | ||
337 | MAC2STR(hdr->addr2), MAC2STR(key->rx_pn), | ||
338 | MAC2STR(pn)); | ||
339 | } | ||
340 | key->dot11RSNAStatsCCMPReplays++; | ||
341 | return -4; | ||
342 | } | ||
343 | |||
344 | ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b); | ||
345 | xor_block(mic, b, CCMP_MIC_LEN); | ||
346 | |||
347 | blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; | ||
348 | last = data_len % AES_BLOCK_LEN; | ||
349 | |||
350 | for (i = 1; i <= blocks; i++) { | ||
351 | len = (i == blocks && last) ? last : AES_BLOCK_LEN; | ||
352 | /* Decrypt, with counter */ | ||
353 | b0[14] = (i >> 8) & 0xff; | ||
354 | b0[15] = i & 0xff; | ||
355 | hostap_ccmp_aes_encrypt(key->tfm, b0, b); | ||
356 | xor_block(pos, b, len); | ||
357 | /* Authentication */ | ||
358 | xor_block(a, pos, len); | ||
359 | hostap_ccmp_aes_encrypt(key->tfm, a, a); | ||
360 | pos += len; | ||
361 | } | ||
362 | |||
363 | if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { | ||
364 | if (net_ratelimit()) { | ||
365 | printk(KERN_DEBUG "CCMP: decrypt failed: STA=" | ||
366 | MACSTR "\n", MAC2STR(hdr->addr2)); | ||
367 | } | ||
368 | key->dot11RSNAStatsCCMPDecryptErrors++; | ||
369 | return -5; | ||
370 | } | ||
371 | |||
372 | memcpy(key->rx_pn, pn, CCMP_PN_LEN); | ||
373 | |||
374 | /* Remove hdr and MIC */ | ||
375 | memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len); | ||
376 | skb_pull(skb, CCMP_HDR_LEN); | ||
377 | skb_trim(skb, skb->len - CCMP_MIC_LEN); | ||
378 | |||
379 | return keyidx; | ||
380 | } | ||
381 | |||
382 | |||
383 | static int hostap_ccmp_set_key(void *key, int len, u8 *seq, void *priv) | ||
384 | { | ||
385 | struct hostap_ccmp_data *data = priv; | ||
386 | int keyidx; | ||
387 | struct crypto_tfm *tfm = data->tfm; | ||
388 | |||
389 | keyidx = data->key_idx; | ||
390 | memset(data, 0, sizeof(*data)); | ||
391 | data->key_idx = keyidx; | ||
392 | data->tfm = tfm; | ||
393 | if (len == CCMP_TK_LEN) { | ||
394 | memcpy(data->key, key, CCMP_TK_LEN); | ||
395 | data->key_set = 1; | ||
396 | if (seq) { | ||
397 | data->rx_pn[0] = seq[5]; | ||
398 | data->rx_pn[1] = seq[4]; | ||
399 | data->rx_pn[2] = seq[3]; | ||
400 | data->rx_pn[3] = seq[2]; | ||
401 | data->rx_pn[4] = seq[1]; | ||
402 | data->rx_pn[5] = seq[0]; | ||
403 | } | ||
404 | crypto_cipher_setkey(data->tfm, data->key, CCMP_TK_LEN); | ||
405 | } else if (len == 0) { | ||
406 | data->key_set = 0; | ||
407 | } else | ||
408 | return -1; | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | |||
414 | static int hostap_ccmp_get_key(void *key, int len, u8 *seq, void *priv) | ||
415 | { | ||
416 | struct hostap_ccmp_data *data = priv; | ||
417 | |||
418 | if (len < CCMP_TK_LEN) | ||
419 | return -1; | ||
420 | |||
421 | if (!data->key_set) | ||
422 | return 0; | ||
423 | memcpy(key, data->key, CCMP_TK_LEN); | ||
424 | |||
425 | if (seq) { | ||
426 | seq[0] = data->tx_pn[5]; | ||
427 | seq[1] = data->tx_pn[4]; | ||
428 | seq[2] = data->tx_pn[3]; | ||
429 | seq[3] = data->tx_pn[2]; | ||
430 | seq[4] = data->tx_pn[1]; | ||
431 | seq[5] = data->tx_pn[0]; | ||
432 | } | ||
433 | |||
434 | return CCMP_TK_LEN; | ||
435 | } | ||
436 | |||
437 | |||
438 | static char * hostap_ccmp_print_stats(char *p, void *priv) | ||
439 | { | ||
440 | struct hostap_ccmp_data *ccmp = priv; | ||
441 | p += sprintf(p, "key[%d] alg=CCMP key_set=%d " | ||
442 | "tx_pn=%02x%02x%02x%02x%02x%02x " | ||
443 | "rx_pn=%02x%02x%02x%02x%02x%02x " | ||
444 | "format_errors=%d replays=%d decrypt_errors=%d\n", | ||
445 | ccmp->key_idx, ccmp->key_set, | ||
446 | MAC2STR(ccmp->tx_pn), MAC2STR(ccmp->rx_pn), | ||
447 | ccmp->dot11RSNAStatsCCMPFormatErrors, | ||
448 | ccmp->dot11RSNAStatsCCMPReplays, | ||
449 | ccmp->dot11RSNAStatsCCMPDecryptErrors); | ||
450 | |||
451 | return p; | ||
452 | } | ||
453 | |||
454 | |||
455 | static struct hostap_crypto_ops hostap_crypt_ccmp = { | ||
456 | .name = "CCMP", | ||
457 | .init = hostap_ccmp_init, | ||
458 | .deinit = hostap_ccmp_deinit, | ||
459 | .encrypt_mpdu = hostap_ccmp_encrypt, | ||
460 | .decrypt_mpdu = hostap_ccmp_decrypt, | ||
461 | .encrypt_msdu = NULL, | ||
462 | .decrypt_msdu = NULL, | ||
463 | .set_key = hostap_ccmp_set_key, | ||
464 | .get_key = hostap_ccmp_get_key, | ||
465 | .print_stats = hostap_ccmp_print_stats, | ||
466 | .extra_prefix_len = CCMP_HDR_LEN, | ||
467 | .extra_postfix_len = CCMP_MIC_LEN | ||
468 | }; | ||
469 | |||
470 | |||
471 | static int __init hostap_crypto_ccmp_init(void) | ||
472 | { | ||
473 | if (hostap_register_crypto_ops(&hostap_crypt_ccmp) < 0) | ||
474 | return -1; | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | |||
480 | static void __exit hostap_crypto_ccmp_exit(void) | ||
481 | { | ||
482 | hostap_unregister_crypto_ops(&hostap_crypt_ccmp); | ||
483 | } | ||
484 | |||
485 | |||
486 | module_init(hostap_crypto_ccmp_init); | ||
487 | 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 @@ | |||
1 | /* | ||
2 | * Host AP crypt: host-based TKIP encryption implementation for Host AP driver | ||
3 | * | ||
4 | * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. See README and COPYING for | ||
9 | * more details. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/version.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/random.h> | ||
18 | #include <linux/skbuff.h> | ||
19 | #include <linux/netdevice.h> | ||
20 | #include <linux/if_ether.h> | ||
21 | #include <linux/if_arp.h> | ||
22 | #include <linux/wireless.h> | ||
23 | #include <net/iw_handler.h> | ||
24 | #include <asm/string.h> | ||
25 | |||
26 | #include "hostap_crypt.h" | ||
27 | #include "hostap_wlan.h" | ||
28 | #include "hostap_80211.h" | ||
29 | #include "hostap_config.h" | ||
30 | |||
31 | #ifndef CONFIG_CRYPTO | ||
32 | #error CONFIG_CRYPTO is required to build this module. | ||
33 | #endif | ||
34 | #include <linux/crypto.h> | ||
35 | #include <asm/scatterlist.h> | ||
36 | #include <linux/crc32.h> | ||
37 | |||
38 | MODULE_AUTHOR("Jouni Malinen"); | ||
39 | MODULE_DESCRIPTION("Host AP crypt: TKIP"); | ||
40 | MODULE_LICENSE("GPL"); | ||
41 | MODULE_VERSION(PRISM2_VERSION); | ||
42 | |||
43 | |||
44 | struct hostap_tkip_data { | ||
45 | #define TKIP_KEY_LEN 32 | ||
46 | u8 key[TKIP_KEY_LEN]; | ||
47 | int key_set; | ||
48 | |||
49 | u32 tx_iv32; | ||
50 | u16 tx_iv16; | ||
51 | u16 tx_ttak[5]; | ||
52 | int tx_phase1_done; | ||
53 | |||
54 | u32 rx_iv32; | ||
55 | u16 rx_iv16; | ||
56 | u16 rx_ttak[5]; | ||
57 | int rx_phase1_done; | ||
58 | u32 rx_iv32_new; | ||
59 | u16 rx_iv16_new; | ||
60 | |||
61 | u32 dot11RSNAStatsTKIPReplays; | ||
62 | u32 dot11RSNAStatsTKIPICVErrors; | ||
63 | u32 dot11RSNAStatsTKIPLocalMICFailures; | ||
64 | |||
65 | int key_idx; | ||
66 | |||
67 | struct crypto_tfm *tfm_arc4; | ||
68 | struct crypto_tfm *tfm_michael; | ||
69 | |||
70 | /* scratch buffers for virt_to_page() (crypto API) */ | ||
71 | u8 rx_hdr[16], tx_hdr[16]; | ||
72 | }; | ||
73 | |||
74 | |||
75 | static void * hostap_tkip_init(int key_idx) | ||
76 | { | ||
77 | struct hostap_tkip_data *priv; | ||
78 | |||
79 | if (!try_module_get(THIS_MODULE)) | ||
80 | return NULL; | ||
81 | |||
82 | priv = (struct hostap_tkip_data *) kmalloc(sizeof(*priv), GFP_ATOMIC); | ||
83 | if (priv == NULL) | ||
84 | goto fail; | ||
85 | memset(priv, 0, sizeof(*priv)); | ||
86 | priv->key_idx = key_idx; | ||
87 | |||
88 | priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0); | ||
89 | if (priv->tfm_arc4 == NULL) { | ||
90 | printk(KERN_DEBUG "hostap_crypt_tkip: could not allocate " | ||
91 | "crypto API arc4\n"); | ||
92 | goto fail; | ||
93 | } | ||
94 | |||
95 | priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0); | ||
96 | if (priv->tfm_michael == NULL) { | ||
97 | printk(KERN_DEBUG "hostap_crypt_tkip: could not allocate " | ||
98 | "crypto API michael_mic\n"); | ||
99 | goto fail; | ||
100 | } | ||
101 | |||
102 | return priv; | ||
103 | |||
104 | fail: | ||
105 | if (priv) { | ||
106 | if (priv->tfm_michael) | ||
107 | crypto_free_tfm(priv->tfm_michael); | ||
108 | if (priv->tfm_arc4) | ||
109 | crypto_free_tfm(priv->tfm_arc4); | ||
110 | kfree(priv); | ||
111 | } | ||
112 | module_put(THIS_MODULE); | ||
113 | return NULL; | ||
114 | } | ||
115 | |||
116 | |||
117 | static void hostap_tkip_deinit(void *priv) | ||
118 | { | ||
119 | struct hostap_tkip_data *_priv = priv; | ||
120 | if (_priv && _priv->tfm_michael) | ||
121 | crypto_free_tfm(_priv->tfm_michael); | ||
122 | if (_priv && _priv->tfm_arc4) | ||
123 | crypto_free_tfm(_priv->tfm_arc4); | ||
124 | kfree(priv); | ||
125 | module_put(THIS_MODULE); | ||
126 | } | ||
127 | |||
128 | |||
129 | static inline u16 RotR1(u16 val) | ||
130 | { | ||
131 | return (val >> 1) | (val << 15); | ||
132 | } | ||
133 | |||
134 | |||
135 | static inline u8 Lo8(u16 val) | ||
136 | { | ||
137 | return val & 0xff; | ||
138 | } | ||
139 | |||
140 | |||
141 | static inline u8 Hi8(u16 val) | ||
142 | { | ||
143 | return val >> 8; | ||
144 | } | ||
145 | |||
146 | |||
147 | static inline u16 Lo16(u32 val) | ||
148 | { | ||
149 | return val & 0xffff; | ||
150 | } | ||
151 | |||
152 | |||
153 | static inline u16 Hi16(u32 val) | ||
154 | { | ||
155 | return val >> 16; | ||
156 | } | ||
157 | |||
158 | |||
159 | static inline u16 Mk16(u8 hi, u8 lo) | ||
160 | { | ||
161 | return lo | (((u16) hi) << 8); | ||
162 | } | ||
163 | |||
164 | |||
165 | static inline u16 Mk16_le(u16 *v) | ||
166 | { | ||
167 | return le16_to_cpu(*v); | ||
168 | } | ||
169 | |||
170 | |||
171 | static const u16 Sbox[256] = | ||
172 | { | ||
173 | 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, | ||
174 | 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, | ||
175 | 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, | ||
176 | 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, | ||
177 | 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, | ||
178 | 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, | ||
179 | 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, | ||
180 | 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, | ||
181 | 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, | ||
182 | 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, | ||
183 | 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, | ||
184 | 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, | ||
185 | 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, | ||
186 | 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, | ||
187 | 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, | ||
188 | 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, | ||
189 | 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, | ||
190 | 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, | ||
191 | 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, | ||
192 | 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, | ||
193 | 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, | ||
194 | 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, | ||
195 | 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, | ||
196 | 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, | ||
197 | 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, | ||
198 | 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, | ||
199 | 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, | ||
200 | 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, | ||
201 | 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, | ||
202 | 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, | ||
203 | 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, | ||
204 | 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, | ||
205 | }; | ||
206 | |||
207 | |||
208 | static inline u16 _S_(u16 v) | ||
209 | { | ||
210 | u16 t = Sbox[Hi8(v)]; | ||
211 | return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8)); | ||
212 | } | ||
213 | |||
214 | |||
215 | #define PHASE1_LOOP_COUNT 8 | ||
216 | |||
217 | static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32) | ||
218 | { | ||
219 | int i, j; | ||
220 | |||
221 | /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */ | ||
222 | TTAK[0] = Lo16(IV32); | ||
223 | TTAK[1] = Hi16(IV32); | ||
224 | TTAK[2] = Mk16(TA[1], TA[0]); | ||
225 | TTAK[3] = Mk16(TA[3], TA[2]); | ||
226 | TTAK[4] = Mk16(TA[5], TA[4]); | ||
227 | |||
228 | for (i = 0; i < PHASE1_LOOP_COUNT; i++) { | ||
229 | j = 2 * (i & 1); | ||
230 | TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j])); | ||
231 | TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j])); | ||
232 | TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j])); | ||
233 | TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j])); | ||
234 | TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | |||
239 | static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, | ||
240 | u16 IV16) | ||
241 | { | ||
242 | /* Make temporary area overlap WEP seed so that the final copy can be | ||
243 | * avoided on little endian hosts. */ | ||
244 | u16 *PPK = (u16 *) &WEPSeed[4]; | ||
245 | |||
246 | /* Step 1 - make copy of TTAK and bring in TSC */ | ||
247 | PPK[0] = TTAK[0]; | ||
248 | PPK[1] = TTAK[1]; | ||
249 | PPK[2] = TTAK[2]; | ||
250 | PPK[3] = TTAK[3]; | ||
251 | PPK[4] = TTAK[4]; | ||
252 | PPK[5] = TTAK[4] + IV16; | ||
253 | |||
254 | /* Step 2 - 96-bit bijective mixing using S-box */ | ||
255 | PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0])); | ||
256 | PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2])); | ||
257 | PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4])); | ||
258 | PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6])); | ||
259 | PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8])); | ||
260 | PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10])); | ||
261 | |||
262 | PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12])); | ||
263 | PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14])); | ||
264 | PPK[2] += RotR1(PPK[1]); | ||
265 | PPK[3] += RotR1(PPK[2]); | ||
266 | PPK[4] += RotR1(PPK[3]); | ||
267 | PPK[5] += RotR1(PPK[4]); | ||
268 | |||
269 | /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value | ||
270 | * WEPSeed[0..2] is transmitted as WEP IV */ | ||
271 | WEPSeed[0] = Hi8(IV16); | ||
272 | WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F; | ||
273 | WEPSeed[2] = Lo8(IV16); | ||
274 | WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1); | ||
275 | |||
276 | #ifdef __BIG_ENDIAN | ||
277 | { | ||
278 | int i; | ||
279 | for (i = 0; i < 6; i++) | ||
280 | PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8); | ||
281 | } | ||
282 | #endif | ||
283 | } | ||
284 | |||
285 | |||
286 | static int hostap_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | ||
287 | { | ||
288 | struct hostap_tkip_data *tkey = priv; | ||
289 | int len; | ||
290 | u8 rc4key[16], *pos, *icv; | ||
291 | struct hostap_ieee80211_hdr *hdr; | ||
292 | u32 crc; | ||
293 | struct scatterlist sg; | ||
294 | |||
295 | if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 || | ||
296 | skb->len < hdr_len) | ||
297 | return -1; | ||
298 | |||
299 | hdr = (struct hostap_ieee80211_hdr *) skb->data; | ||
300 | if (!tkey->tx_phase1_done) { | ||
301 | tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, | ||
302 | tkey->tx_iv32); | ||
303 | tkey->tx_phase1_done = 1; | ||
304 | } | ||
305 | tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); | ||
306 | |||
307 | len = skb->len - hdr_len; | ||
308 | pos = skb_push(skb, 8); | ||
309 | memmove(pos, pos + 8, hdr_len); | ||
310 | pos += hdr_len; | ||
311 | icv = skb_put(skb, 4); | ||
312 | |||
313 | *pos++ = rc4key[0]; | ||
314 | *pos++ = rc4key[1]; | ||
315 | *pos++ = rc4key[2]; | ||
316 | *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */; | ||
317 | *pos++ = tkey->tx_iv32 & 0xff; | ||
318 | *pos++ = (tkey->tx_iv32 >> 8) & 0xff; | ||
319 | *pos++ = (tkey->tx_iv32 >> 16) & 0xff; | ||
320 | *pos++ = (tkey->tx_iv32 >> 24) & 0xff; | ||
321 | |||
322 | crc = ~crc32_le(~0, pos, len); | ||
323 | icv[0] = crc; | ||
324 | icv[1] = crc >> 8; | ||
325 | icv[2] = crc >> 16; | ||
326 | icv[3] = crc >> 24; | ||
327 | |||
328 | crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); | ||
329 | sg.page = virt_to_page(pos); | ||
330 | sg.offset = offset_in_page(pos); | ||
331 | sg.length = len + 4; | ||
332 | crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4); | ||
333 | |||
334 | tkey->tx_iv16++; | ||
335 | if (tkey->tx_iv16 == 0) { | ||
336 | tkey->tx_phase1_done = 0; | ||
337 | tkey->tx_iv32++; | ||
338 | } | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | |||
344 | static int hostap_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | ||
345 | { | ||
346 | struct hostap_tkip_data *tkey = priv; | ||
347 | u8 rc4key[16]; | ||
348 | u8 keyidx, *pos, icv[4]; | ||
349 | u32 iv32; | ||
350 | u16 iv16; | ||
351 | struct hostap_ieee80211_hdr *hdr; | ||
352 | u32 crc; | ||
353 | struct scatterlist sg; | ||
354 | int plen; | ||
355 | |||
356 | if (skb->len < hdr_len + 8 + 4) | ||
357 | return -1; | ||
358 | |||
359 | hdr = (struct hostap_ieee80211_hdr *) skb->data; | ||
360 | pos = skb->data + hdr_len; | ||
361 | keyidx = pos[3]; | ||
362 | if (!(keyidx & (1 << 5))) { | ||
363 | if (net_ratelimit()) { | ||
364 | printk(KERN_DEBUG "TKIP: received packet without ExtIV" | ||
365 | " flag from " MACSTR "\n", MAC2STR(hdr->addr2)); | ||
366 | } | ||
367 | return -2; | ||
368 | } | ||
369 | keyidx >>= 6; | ||
370 | if (tkey->key_idx != keyidx) { | ||
371 | printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame " | ||
372 | "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv); | ||
373 | return -6; | ||
374 | } | ||
375 | if (!tkey->key_set) { | ||
376 | if (net_ratelimit()) { | ||
377 | printk(KERN_DEBUG "TKIP: received packet from " MACSTR | ||
378 | " with keyid=%d that does not have a configured" | ||
379 | " key\n", MAC2STR(hdr->addr2), keyidx); | ||
380 | } | ||
381 | return -3; | ||
382 | } | ||
383 | iv16 = (pos[0] << 8) | pos[2]; | ||
384 | iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); | ||
385 | pos += 8; | ||
386 | |||
387 | if (iv32 < tkey->rx_iv32 || | ||
388 | (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { | ||
389 | if (net_ratelimit()) { | ||
390 | printk(KERN_DEBUG "TKIP: replay detected: STA=" MACSTR | ||
391 | " previous TSC %08x%04x received TSC " | ||
392 | "%08x%04x\n", MAC2STR(hdr->addr2), | ||
393 | tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); | ||
394 | } | ||
395 | tkey->dot11RSNAStatsTKIPReplays++; | ||
396 | return -4; | ||
397 | } | ||
398 | |||
399 | if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) { | ||
400 | tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32); | ||
401 | tkey->rx_phase1_done = 1; | ||
402 | } | ||
403 | tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16); | ||
404 | |||
405 | plen = skb->len - hdr_len - 12; | ||
406 | |||
407 | crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); | ||
408 | sg.page = virt_to_page(pos); | ||
409 | sg.offset = offset_in_page(pos); | ||
410 | sg.length = plen + 4; | ||
411 | crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4); | ||
412 | |||
413 | crc = ~crc32_le(~0, pos, plen); | ||
414 | icv[0] = crc; | ||
415 | icv[1] = crc >> 8; | ||
416 | icv[2] = crc >> 16; | ||
417 | icv[3] = crc >> 24; | ||
418 | if (memcmp(icv, pos + plen, 4) != 0) { | ||
419 | if (iv32 != tkey->rx_iv32) { | ||
420 | /* Previously cached Phase1 result was already lost, so | ||
421 | * it needs to be recalculated for the next packet. */ | ||
422 | tkey->rx_phase1_done = 0; | ||
423 | } | ||
424 | if (net_ratelimit()) { | ||
425 | printk(KERN_DEBUG "TKIP: ICV error detected: STA=" | ||
426 | MACSTR "\n", MAC2STR(hdr->addr2)); | ||
427 | } | ||
428 | tkey->dot11RSNAStatsTKIPICVErrors++; | ||
429 | return -5; | ||
430 | } | ||
431 | |||
432 | /* Update real counters only after Michael MIC verification has | ||
433 | * completed */ | ||
434 | tkey->rx_iv32_new = iv32; | ||
435 | tkey->rx_iv16_new = iv16; | ||
436 | |||
437 | /* Remove IV and ICV */ | ||
438 | memmove(skb->data + 8, skb->data, hdr_len); | ||
439 | skb_pull(skb, 8); | ||
440 | skb_trim(skb, skb->len - 4); | ||
441 | |||
442 | return keyidx; | ||
443 | } | ||
444 | |||
445 | |||
446 | static int michael_mic(struct hostap_tkip_data *tkey, u8 *key, u8 *hdr, | ||
447 | u8 *data, size_t data_len, u8 *mic) | ||
448 | { | ||
449 | struct scatterlist sg[2]; | ||
450 | |||
451 | if (tkey->tfm_michael == NULL) { | ||
452 | printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); | ||
453 | return -1; | ||
454 | } | ||
455 | sg[0].page = virt_to_page(hdr); | ||
456 | sg[0].offset = offset_in_page(hdr); | ||
457 | sg[0].length = 16; | ||
458 | |||
459 | sg[1].page = virt_to_page(data); | ||
460 | sg[1].offset = offset_in_page(data); | ||
461 | sg[1].length = data_len; | ||
462 | |||
463 | crypto_digest_init(tkey->tfm_michael); | ||
464 | crypto_digest_setkey(tkey->tfm_michael, key, 8); | ||
465 | crypto_digest_update(tkey->tfm_michael, sg, 2); | ||
466 | crypto_digest_final(tkey->tfm_michael, mic); | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | |||
472 | static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) | ||
473 | { | ||
474 | struct hostap_ieee80211_hdr *hdr11; | ||
475 | |||
476 | hdr11 = (struct hostap_ieee80211_hdr *) skb->data; | ||
477 | switch (le16_to_cpu(hdr11->frame_control) & | ||
478 | (WLAN_FC_FROMDS | WLAN_FC_TODS)) { | ||
479 | case WLAN_FC_TODS: | ||
480 | memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ | ||
481 | memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ | ||
482 | break; | ||
483 | case WLAN_FC_FROMDS: | ||
484 | memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ | ||
485 | memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */ | ||
486 | break; | ||
487 | case WLAN_FC_FROMDS | WLAN_FC_TODS: | ||
488 | memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ | ||
489 | memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */ | ||
490 | break; | ||
491 | case 0: | ||
492 | memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ | ||
493 | memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ | ||
494 | break; | ||
495 | } | ||
496 | |||
497 | hdr[12] = 0; /* priority */ | ||
498 | hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ | ||
499 | } | ||
500 | |||
501 | |||
502 | static int hostap_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) | ||
503 | { | ||
504 | struct hostap_tkip_data *tkey = priv; | ||
505 | u8 *pos; | ||
506 | |||
507 | if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { | ||
508 | printk(KERN_DEBUG "Invalid packet for Michael MIC add " | ||
509 | "(tailroom=%d hdr_len=%d skb->len=%d)\n", | ||
510 | skb_tailroom(skb), hdr_len, skb->len); | ||
511 | return -1; | ||
512 | } | ||
513 | |||
514 | michael_mic_hdr(skb, tkey->tx_hdr); | ||
515 | pos = skb_put(skb, 8); | ||
516 | if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr, | ||
517 | skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) | ||
518 | return -1; | ||
519 | |||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | |||
524 | static void hostap_michael_mic_failure(struct net_device *dev, | ||
525 | struct hostap_ieee80211_hdr *hdr, | ||
526 | int keyidx) | ||
527 | { | ||
528 | union iwreq_data wrqu; | ||
529 | char buf[128]; | ||
530 | |||
531 | /* TODO: needed parameters: count, keyid, key type, src address, TSC */ | ||
532 | sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=" | ||
533 | MACSTR ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", | ||
534 | MAC2STR(hdr->addr2)); | ||
535 | memset(&wrqu, 0, sizeof(wrqu)); | ||
536 | wrqu.data.length = strlen(buf); | ||
537 | wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); | ||
538 | } | ||
539 | |||
540 | |||
541 | static int hostap_michael_mic_verify(struct sk_buff *skb, int keyidx, | ||
542 | int hdr_len, void *priv) | ||
543 | { | ||
544 | struct hostap_tkip_data *tkey = priv; | ||
545 | u8 mic[8]; | ||
546 | |||
547 | if (!tkey->key_set) | ||
548 | return -1; | ||
549 | |||
550 | michael_mic_hdr(skb, tkey->rx_hdr); | ||
551 | if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr, | ||
552 | skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) | ||
553 | return -1; | ||
554 | if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { | ||
555 | struct hostap_ieee80211_hdr *hdr; | ||
556 | hdr = (struct hostap_ieee80211_hdr *) skb->data; | ||
557 | printk(KERN_DEBUG "%s: Michael MIC verification failed for " | ||
558 | "MSDU from " MACSTR " keyidx=%d\n", | ||
559 | skb->dev ? skb->dev->name : "N/A", MAC2STR(hdr->addr2), | ||
560 | keyidx); | ||
561 | if (skb->dev) | ||
562 | hostap_michael_mic_failure(skb->dev, hdr, keyidx); | ||
563 | tkey->dot11RSNAStatsTKIPLocalMICFailures++; | ||
564 | return -1; | ||
565 | } | ||
566 | |||
567 | /* Update TSC counters for RX now that the packet verification has | ||
568 | * completed. */ | ||
569 | tkey->rx_iv32 = tkey->rx_iv32_new; | ||
570 | tkey->rx_iv16 = tkey->rx_iv16_new; | ||
571 | |||
572 | skb_trim(skb, skb->len - 8); | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | |||
578 | static int hostap_tkip_set_key(void *key, int len, u8 *seq, void *priv) | ||
579 | { | ||
580 | struct hostap_tkip_data *tkey = priv; | ||
581 | int keyidx; | ||
582 | struct crypto_tfm *tfm = tkey->tfm_michael; | ||
583 | struct crypto_tfm *tfm2 = tkey->tfm_arc4; | ||
584 | |||
585 | keyidx = tkey->key_idx; | ||
586 | memset(tkey, 0, sizeof(*tkey)); | ||
587 | tkey->key_idx = keyidx; | ||
588 | tkey->tfm_michael = tfm; | ||
589 | tkey->tfm_arc4 = tfm2; | ||
590 | if (len == TKIP_KEY_LEN) { | ||
591 | memcpy(tkey->key, key, TKIP_KEY_LEN); | ||
592 | tkey->key_set = 1; | ||
593 | tkey->tx_iv16 = 1; /* TSC is initialized to 1 */ | ||
594 | if (seq) { | ||
595 | tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) | | ||
596 | (seq[3] << 8) | seq[2]; | ||
597 | tkey->rx_iv16 = (seq[1] << 8) | seq[0]; | ||
598 | } | ||
599 | } else if (len == 0) { | ||
600 | tkey->key_set = 0; | ||
601 | } else | ||
602 | return -1; | ||
603 | |||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | |||
608 | static int hostap_tkip_get_key(void *key, int len, u8 *seq, void *priv) | ||
609 | { | ||
610 | struct hostap_tkip_data *tkey = priv; | ||
611 | |||
612 | if (len < TKIP_KEY_LEN) | ||
613 | return -1; | ||
614 | |||
615 | if (!tkey->key_set) | ||
616 | return 0; | ||
617 | memcpy(key, tkey->key, TKIP_KEY_LEN); | ||
618 | |||
619 | if (seq) { | ||
620 | /* Return the sequence number of the last transmitted frame. */ | ||
621 | u16 iv16 = tkey->tx_iv16; | ||
622 | u32 iv32 = tkey->tx_iv32; | ||
623 | if (iv16 == 0) | ||
624 | iv32--; | ||
625 | iv16--; | ||
626 | seq[0] = tkey->tx_iv16; | ||
627 | seq[1] = tkey->tx_iv16 >> 8; | ||
628 | seq[2] = tkey->tx_iv32; | ||
629 | seq[3] = tkey->tx_iv32 >> 8; | ||
630 | seq[4] = tkey->tx_iv32 >> 16; | ||
631 | seq[5] = tkey->tx_iv32 >> 24; | ||
632 | } | ||
633 | |||
634 | return TKIP_KEY_LEN; | ||
635 | } | ||
636 | |||
637 | |||
638 | static char * hostap_tkip_print_stats(char *p, void *priv) | ||
639 | { | ||
640 | struct hostap_tkip_data *tkip = priv; | ||
641 | p += sprintf(p, "key[%d] alg=TKIP key_set=%d " | ||
642 | "tx_pn=%02x%02x%02x%02x%02x%02x " | ||
643 | "rx_pn=%02x%02x%02x%02x%02x%02x " | ||
644 | "replays=%d icv_errors=%d local_mic_failures=%d\n", | ||
645 | tkip->key_idx, tkip->key_set, | ||
646 | (tkip->tx_iv32 >> 24) & 0xff, | ||
647 | (tkip->tx_iv32 >> 16) & 0xff, | ||
648 | (tkip->tx_iv32 >> 8) & 0xff, | ||
649 | tkip->tx_iv32 & 0xff, | ||
650 | (tkip->tx_iv16 >> 8) & 0xff, | ||
651 | tkip->tx_iv16 & 0xff, | ||
652 | (tkip->rx_iv32 >> 24) & 0xff, | ||
653 | (tkip->rx_iv32 >> 16) & 0xff, | ||
654 | (tkip->rx_iv32 >> 8) & 0xff, | ||
655 | tkip->rx_iv32 & 0xff, | ||
656 | (tkip->rx_iv16 >> 8) & 0xff, | ||
657 | tkip->rx_iv16 & 0xff, | ||
658 | tkip->dot11RSNAStatsTKIPReplays, | ||
659 | tkip->dot11RSNAStatsTKIPICVErrors, | ||
660 | tkip->dot11RSNAStatsTKIPLocalMICFailures); | ||
661 | return p; | ||
662 | } | ||
663 | |||
664 | |||
665 | static struct hostap_crypto_ops hostap_crypt_tkip = { | ||
666 | .name = "TKIP", | ||
667 | .init = hostap_tkip_init, | ||
668 | .deinit = hostap_tkip_deinit, | ||
669 | .encrypt_mpdu = hostap_tkip_encrypt, | ||
670 | .decrypt_mpdu = hostap_tkip_decrypt, | ||
671 | .encrypt_msdu = hostap_michael_mic_add, | ||
672 | .decrypt_msdu = hostap_michael_mic_verify, | ||
673 | .set_key = hostap_tkip_set_key, | ||
674 | .get_key = hostap_tkip_get_key, | ||
675 | .print_stats = hostap_tkip_print_stats, | ||
676 | .extra_prefix_len = 4 + 4 /* IV + ExtIV */, | ||
677 | .extra_postfix_len = 8 + 4 /* MIC + ICV */ | ||
678 | }; | ||
679 | |||
680 | |||
681 | static int __init hostap_crypto_tkip_init(void) | ||
682 | { | ||
683 | if (hostap_register_crypto_ops(&hostap_crypt_tkip) < 0) | ||
684 | return -1; | ||
685 | |||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | |||
690 | static void __exit hostap_crypto_tkip_exit(void) | ||
691 | { | ||
692 | hostap_unregister_crypto_ops(&hostap_crypt_tkip); | ||
693 | } | ||
694 | |||
695 | |||
696 | module_init(hostap_crypto_tkip_init); | ||
697 | 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 @@ | |||
1 | /* | ||
2 | * Host AP crypt: host-based WEP encryption implementation for Host AP driver | ||
3 | * | ||
4 | * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. See README and COPYING for | ||
9 | * more details. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/version.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/random.h> | ||
18 | #include <linux/skbuff.h> | ||
19 | #include <asm/string.h> | ||
20 | |||
21 | #include "hostap_crypt.h" | ||
22 | #include "hostap_config.h" | ||
23 | |||
24 | #ifndef CONFIG_CRYPTO | ||
25 | #error CONFIG_CRYPTO is required to build this module. | ||
26 | #endif | ||
27 | #include <linux/crypto.h> | ||
28 | #include <asm/scatterlist.h> | ||
29 | #include <linux/crc32.h> | ||
30 | |||
31 | MODULE_AUTHOR("Jouni Malinen"); | ||
32 | MODULE_DESCRIPTION("Host AP crypt: WEP"); | ||
33 | MODULE_LICENSE("GPL"); | ||
34 | MODULE_VERSION(PRISM2_VERSION); | ||
35 | |||
36 | |||
37 | struct prism2_wep_data { | ||
38 | u32 iv; | ||
39 | #define WEP_KEY_LEN 13 | ||
40 | u8 key[WEP_KEY_LEN + 1]; | ||
41 | u8 key_len; | ||
42 | u8 key_idx; | ||
43 | struct crypto_tfm *tfm; | ||
44 | }; | ||
45 | |||
46 | |||
47 | static void * prism2_wep_init(int keyidx) | ||
48 | { | ||
49 | struct prism2_wep_data *priv; | ||
50 | |||
51 | if (!try_module_get(THIS_MODULE)) | ||
52 | return NULL; | ||
53 | |||
54 | priv = (struct prism2_wep_data *) kmalloc(sizeof(*priv), GFP_ATOMIC); | ||
55 | if (priv == NULL) | ||
56 | goto fail; | ||
57 | memset(priv, 0, sizeof(*priv)); | ||
58 | priv->key_idx = keyidx; | ||
59 | |||
60 | priv->tfm = crypto_alloc_tfm("arc4", 0); | ||
61 | if (priv->tfm == NULL) { | ||
62 | printk(KERN_DEBUG "hostap_crypt_wep: could not allocate " | ||
63 | "crypto API arc4\n"); | ||
64 | goto fail; | ||
65 | } | ||
66 | |||
67 | /* start WEP IV from a random value */ | ||
68 | get_random_bytes(&priv->iv, 4); | ||
69 | |||
70 | return priv; | ||
71 | |||
72 | fail: | ||
73 | if (priv) { | ||
74 | if (priv->tfm) | ||
75 | crypto_free_tfm(priv->tfm); | ||
76 | kfree(priv); | ||
77 | } | ||
78 | module_put(THIS_MODULE); | ||
79 | return NULL; | ||
80 | } | ||
81 | |||
82 | |||
83 | static void prism2_wep_deinit(void *priv) | ||
84 | { | ||
85 | struct prism2_wep_data *_priv = priv; | ||
86 | if (_priv && _priv->tfm) | ||
87 | crypto_free_tfm(_priv->tfm); | ||
88 | kfree(priv); | ||
89 | module_put(THIS_MODULE); | ||
90 | } | ||
91 | |||
92 | |||
93 | /* Perform WEP encryption on given skb that has at least 4 bytes of headroom | ||
94 | * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted, | ||
95 | * so the payload length increases with 8 bytes. | ||
96 | * | ||
97 | * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) | ||
98 | */ | ||
99 | static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | ||
100 | { | ||
101 | struct prism2_wep_data *wep = priv; | ||
102 | u32 crc, klen, len; | ||
103 | u8 key[WEP_KEY_LEN + 3]; | ||
104 | u8 *pos, *icv; | ||
105 | struct scatterlist sg; | ||
106 | |||
107 | if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 || | ||
108 | skb->len < hdr_len) | ||
109 | return -1; | ||
110 | |||
111 | len = skb->len - hdr_len; | ||
112 | pos = skb_push(skb, 4); | ||
113 | memmove(pos, pos + 4, hdr_len); | ||
114 | pos += hdr_len; | ||
115 | |||
116 | klen = 3 + wep->key_len; | ||
117 | |||
118 | wep->iv++; | ||
119 | |||
120 | /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key | ||
121 | * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N) | ||
122 | * can be used to speedup attacks, so avoid using them. */ | ||
123 | if ((wep->iv & 0xff00) == 0xff00) { | ||
124 | u8 B = (wep->iv >> 16) & 0xff; | ||
125 | if (B >= 3 && B < klen) | ||
126 | wep->iv += 0x0100; | ||
127 | } | ||
128 | |||
129 | /* Prepend 24-bit IV to RC4 key and TX frame */ | ||
130 | *pos++ = key[0] = (wep->iv >> 16) & 0xff; | ||
131 | *pos++ = key[1] = (wep->iv >> 8) & 0xff; | ||
132 | *pos++ = key[2] = wep->iv & 0xff; | ||
133 | *pos++ = wep->key_idx << 6; | ||
134 | |||
135 | /* Copy rest of the WEP key (the secret part) */ | ||
136 | memcpy(key + 3, wep->key, wep->key_len); | ||
137 | |||
138 | /* Append little-endian CRC32 and encrypt it to produce ICV */ | ||
139 | crc = ~crc32_le(~0, pos, len); | ||
140 | icv = skb_put(skb, 4); | ||
141 | icv[0] = crc; | ||
142 | icv[1] = crc >> 8; | ||
143 | icv[2] = crc >> 16; | ||
144 | icv[3] = crc >> 24; | ||
145 | |||
146 | crypto_cipher_setkey(wep->tfm, key, klen); | ||
147 | sg.page = virt_to_page(pos); | ||
148 | sg.offset = offset_in_page(pos); | ||
149 | sg.length = len + 4; | ||
150 | crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4); | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | |||
156 | /* Perform WEP decryption on given buffer. Buffer includes whole WEP part of | ||
157 | * the frame: IV (4 bytes), encrypted payload (including SNAP header), | ||
158 | * ICV (4 bytes). len includes both IV and ICV. | ||
159 | * | ||
160 | * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on | ||
161 | * failure. If frame is OK, IV and ICV will be removed. | ||
162 | */ | ||
163 | static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | ||
164 | { | ||
165 | struct prism2_wep_data *wep = priv; | ||
166 | u32 crc, klen, plen; | ||
167 | u8 key[WEP_KEY_LEN + 3]; | ||
168 | u8 keyidx, *pos, icv[4]; | ||
169 | struct scatterlist sg; | ||
170 | |||
171 | if (skb->len < hdr_len + 8) | ||
172 | return -1; | ||
173 | |||
174 | pos = skb->data + hdr_len; | ||
175 | key[0] = *pos++; | ||
176 | key[1] = *pos++; | ||
177 | key[2] = *pos++; | ||
178 | keyidx = *pos++ >> 6; | ||
179 | if (keyidx != wep->key_idx) | ||
180 | return -1; | ||
181 | |||
182 | klen = 3 + wep->key_len; | ||
183 | |||
184 | /* Copy rest of the WEP key (the secret part) */ | ||
185 | memcpy(key + 3, wep->key, wep->key_len); | ||
186 | |||
187 | /* Apply RC4 to data and compute CRC32 over decrypted data */ | ||
188 | plen = skb->len - hdr_len - 8; | ||
189 | |||
190 | crypto_cipher_setkey(wep->tfm, key, klen); | ||
191 | sg.page = virt_to_page(pos); | ||
192 | sg.offset = offset_in_page(pos); | ||
193 | sg.length = plen + 4; | ||
194 | crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4); | ||
195 | |||
196 | crc = ~crc32_le(~0, pos, plen); | ||
197 | icv[0] = crc; | ||
198 | icv[1] = crc >> 8; | ||
199 | icv[2] = crc >> 16; | ||
200 | icv[3] = crc >> 24; | ||
201 | if (memcmp(icv, pos + plen, 4) != 0) { | ||
202 | /* ICV mismatch - drop frame */ | ||
203 | return -2; | ||
204 | } | ||
205 | |||
206 | /* Remove IV and ICV */ | ||
207 | memmove(skb->data + 4, skb->data, hdr_len); | ||
208 | skb_pull(skb, 4); | ||
209 | skb_trim(skb, skb->len - 4); | ||
210 | |||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | |||
215 | static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv) | ||
216 | { | ||
217 | struct prism2_wep_data *wep = priv; | ||
218 | |||
219 | if (len < 0 || len > WEP_KEY_LEN) | ||
220 | return -1; | ||
221 | |||
222 | memcpy(wep->key, key, len); | ||
223 | wep->key_len = len; | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | |||
229 | static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) | ||
230 | { | ||
231 | struct prism2_wep_data *wep = priv; | ||
232 | |||
233 | if (len < wep->key_len) | ||
234 | return -1; | ||
235 | |||
236 | memcpy(key, wep->key, wep->key_len); | ||
237 | |||
238 | return wep->key_len; | ||
239 | } | ||
240 | |||
241 | |||
242 | static char * prism2_wep_print_stats(char *p, void *priv) | ||
243 | { | ||
244 | struct prism2_wep_data *wep = priv; | ||
245 | p += sprintf(p, "key[%d] alg=WEP len=%d\n", | ||
246 | wep->key_idx, wep->key_len); | ||
247 | return p; | ||
248 | } | ||
249 | |||
250 | |||
251 | static struct hostap_crypto_ops hostap_crypt_wep = { | ||
252 | .name = "WEP", | ||
253 | .init = prism2_wep_init, | ||
254 | .deinit = prism2_wep_deinit, | ||
255 | .encrypt_mpdu = prism2_wep_encrypt, | ||
256 | .decrypt_mpdu = prism2_wep_decrypt, | ||
257 | .encrypt_msdu = NULL, | ||
258 | .decrypt_msdu = NULL, | ||
259 | .set_key = prism2_wep_set_key, | ||
260 | .get_key = prism2_wep_get_key, | ||
261 | .print_stats = prism2_wep_print_stats, | ||
262 | .extra_prefix_len = 4 /* IV */, | ||
263 | .extra_postfix_len = 4 /* ICV */ | ||
264 | }; | ||
265 | |||
266 | |||
267 | static int __init hostap_crypto_wep_init(void) | ||
268 | { | ||
269 | if (hostap_register_crypto_ops(&hostap_crypt_wep) < 0) | ||
270 | return -1; | ||
271 | |||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | |||
276 | static void __exit hostap_crypto_wep_exit(void) | ||
277 | { | ||
278 | hostap_unregister_crypto_ops(&hostap_crypt_wep); | ||
279 | } | ||
280 | |||
281 | |||
282 | module_init(hostap_crypto_wep_init); | ||
283 | 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 @@ | |||
4 | * | 4 | * |
5 | * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen | 5 | * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen |
6 | * <jkmaline@cc.hut.fi> | 6 | * <jkmaline@cc.hut.fi> |
7 | * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi> | 7 | * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 10 | * 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) | |||
2967 | static void prism2_crypt_deinit_entries(local_info_t *local, int force) | 2967 | static void prism2_crypt_deinit_entries(local_info_t *local, int force) |
2968 | { | 2968 | { |
2969 | struct list_head *ptr, *n; | 2969 | struct list_head *ptr, *n; |
2970 | struct prism2_crypt_data *entry; | 2970 | struct ieee80211_crypt_data *entry; |
2971 | 2971 | ||
2972 | for (ptr = local->crypt_deinit_list.next, n = ptr->next; | 2972 | for (ptr = local->crypt_deinit_list.next, n = ptr->next; |
2973 | ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) { | 2973 | ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) { |
2974 | entry = list_entry(ptr, struct prism2_crypt_data, list); | 2974 | entry = list_entry(ptr, struct ieee80211_crypt_data, list); |
2975 | 2975 | ||
2976 | if (atomic_read(&entry->refcnt) != 0 && !force) | 2976 | if (atomic_read(&entry->refcnt) != 0 && !force) |
2977 | continue; | 2977 | continue; |
@@ -3531,7 +3531,7 @@ static void prism2_free_local_data(struct net_device *dev) | |||
3531 | prism2_callback(local, PRISM2_CALLBACK_DISABLE); | 3531 | prism2_callback(local, PRISM2_CALLBACK_DISABLE); |
3532 | 3532 | ||
3533 | for (i = 0; i < WEP_KEYS; i++) { | 3533 | for (i = 0; i < WEP_KEYS; i++) { |
3534 | struct prism2_crypt_data *crypt = local->crypt[i]; | 3534 | struct ieee80211_crypt_data *crypt = local->crypt[i]; |
3535 | if (crypt) { | 3535 | if (crypt) { |
3536 | if (crypt->ops) | 3536 | if (crypt->ops) |
3537 | crypt->ops->deinit(crypt->priv); | 3537 | 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, | |||
115 | 115 | ||
116 | 116 | ||
117 | static void prism2_crypt_delayed_deinit(local_info_t *local, | 117 | static void prism2_crypt_delayed_deinit(local_info_t *local, |
118 | struct prism2_crypt_data **crypt) | 118 | struct ieee80211_crypt_data **crypt) |
119 | { | 119 | { |
120 | struct prism2_crypt_data *tmp; | 120 | struct ieee80211_crypt_data *tmp; |
121 | unsigned long flags; | 121 | unsigned long flags; |
122 | 122 | ||
123 | tmp = *crypt; | 123 | tmp = *crypt; |
@@ -147,7 +147,7 @@ static int prism2_ioctl_siwencode(struct net_device *dev, | |||
147 | struct hostap_interface *iface; | 147 | struct hostap_interface *iface; |
148 | local_info_t *local; | 148 | local_info_t *local; |
149 | int i; | 149 | int i; |
150 | struct prism2_crypt_data **crypt; | 150 | struct ieee80211_crypt_data **crypt; |
151 | 151 | ||
152 | iface = netdev_priv(dev); | 152 | iface = netdev_priv(dev); |
153 | local = iface->local; | 153 | local = iface->local; |
@@ -175,18 +175,19 @@ static int prism2_ioctl_siwencode(struct net_device *dev, | |||
175 | } | 175 | } |
176 | 176 | ||
177 | if (*crypt == NULL) { | 177 | if (*crypt == NULL) { |
178 | struct prism2_crypt_data *new_crypt; | 178 | struct ieee80211_crypt_data *new_crypt; |
179 | 179 | ||
180 | /* take WEP into use */ | 180 | /* take WEP into use */ |
181 | new_crypt = (struct prism2_crypt_data *) | 181 | new_crypt = (struct ieee80211_crypt_data *) |
182 | kmalloc(sizeof(struct prism2_crypt_data), GFP_KERNEL); | 182 | kmalloc(sizeof(struct ieee80211_crypt_data), |
183 | GFP_KERNEL); | ||
183 | if (new_crypt == NULL) | 184 | if (new_crypt == NULL) |
184 | return -ENOMEM; | 185 | return -ENOMEM; |
185 | memset(new_crypt, 0, sizeof(struct prism2_crypt_data)); | 186 | memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); |
186 | new_crypt->ops = hostap_get_crypto_ops("WEP"); | 187 | new_crypt->ops = ieee80211_get_crypto_ops("WEP"); |
187 | if (!new_crypt->ops) { | 188 | if (!new_crypt->ops) { |
188 | request_module("hostap_crypt_wep"); | 189 | request_module("ieee80211_crypt_wep"); |
189 | new_crypt->ops = hostap_get_crypto_ops("WEP"); | 190 | new_crypt->ops = ieee80211_get_crypto_ops("WEP"); |
190 | } | 191 | } |
191 | if (new_crypt->ops) | 192 | if (new_crypt->ops) |
192 | new_crypt->priv = new_crypt->ops->init(i); | 193 | new_crypt->priv = new_crypt->ops->init(i); |
@@ -251,7 +252,7 @@ static int prism2_ioctl_giwencode(struct net_device *dev, | |||
251 | local_info_t *local; | 252 | local_info_t *local; |
252 | int i, len; | 253 | int i, len; |
253 | u16 val; | 254 | u16 val; |
254 | struct prism2_crypt_data *crypt; | 255 | struct ieee80211_crypt_data *crypt; |
255 | 256 | ||
256 | iface = netdev_priv(dev); | 257 | iface = netdev_priv(dev); |
257 | local = iface->local; | 258 | local = iface->local; |
@@ -3259,8 +3260,8 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, | |||
3259 | local_info_t *local = iface->local; | 3260 | local_info_t *local = iface->local; |
3260 | struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; | 3261 | struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; |
3261 | int i, ret = 0; | 3262 | int i, ret = 0; |
3262 | struct hostap_crypto_ops *ops; | 3263 | struct ieee80211_crypto_ops *ops; |
3263 | struct prism2_crypt_data **crypt; | 3264 | struct ieee80211_crypt_data **crypt; |
3264 | void *sta_ptr; | 3265 | void *sta_ptr; |
3265 | u8 *addr; | 3266 | u8 *addr; |
3266 | const char *alg, *module; | 3267 | const char *alg, *module; |
@@ -3308,15 +3309,15 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, | |||
3308 | switch (ext->alg) { | 3309 | switch (ext->alg) { |
3309 | case IW_ENCODE_ALG_WEP: | 3310 | case IW_ENCODE_ALG_WEP: |
3310 | alg = "WEP"; | 3311 | alg = "WEP"; |
3311 | module = "hostap_crypt_wep"; | 3312 | module = "ieee80211_crypt_wep"; |
3312 | break; | 3313 | break; |
3313 | case IW_ENCODE_ALG_TKIP: | 3314 | case IW_ENCODE_ALG_TKIP: |
3314 | alg = "TKIP"; | 3315 | alg = "TKIP"; |
3315 | module = "hostap_crypt_tkip"; | 3316 | module = "ieee80211_crypt_tkip"; |
3316 | break; | 3317 | break; |
3317 | case IW_ENCODE_ALG_CCMP: | 3318 | case IW_ENCODE_ALG_CCMP: |
3318 | alg = "CCMP"; | 3319 | alg = "CCMP"; |
3319 | module = "hostap_crypt_ccmp"; | 3320 | module = "ieee80211_crypt_ccmp"; |
3320 | break; | 3321 | break; |
3321 | default: | 3322 | default: |
3322 | printk(KERN_DEBUG "%s: unsupported algorithm %d\n", | 3323 | printk(KERN_DEBUG "%s: unsupported algorithm %d\n", |
@@ -3325,10 +3326,10 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, | |||
3325 | goto done; | 3326 | goto done; |
3326 | } | 3327 | } |
3327 | 3328 | ||
3328 | ops = hostap_get_crypto_ops(alg); | 3329 | ops = ieee80211_get_crypto_ops(alg); |
3329 | if (ops == NULL) { | 3330 | if (ops == NULL) { |
3330 | request_module(module); | 3331 | request_module(module); |
3331 | ops = hostap_get_crypto_ops(alg); | 3332 | ops = ieee80211_get_crypto_ops(alg); |
3332 | } | 3333 | } |
3333 | if (ops == NULL) { | 3334 | if (ops == NULL) { |
3334 | printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", | 3335 | printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", |
@@ -3347,17 +3348,18 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev, | |||
3347 | } | 3348 | } |
3348 | 3349 | ||
3349 | if (*crypt == NULL || (*crypt)->ops != ops) { | 3350 | if (*crypt == NULL || (*crypt)->ops != ops) { |
3350 | struct prism2_crypt_data *new_crypt; | 3351 | struct ieee80211_crypt_data *new_crypt; |
3351 | 3352 | ||
3352 | prism2_crypt_delayed_deinit(local, crypt); | 3353 | prism2_crypt_delayed_deinit(local, crypt); |
3353 | 3354 | ||
3354 | new_crypt = (struct prism2_crypt_data *) | 3355 | new_crypt = (struct ieee80211_crypt_data *) |
3355 | kmalloc(sizeof(struct prism2_crypt_data), GFP_KERNEL); | 3356 | kmalloc(sizeof(struct ieee80211_crypt_data), |
3357 | GFP_KERNEL); | ||
3356 | if (new_crypt == NULL) { | 3358 | if (new_crypt == NULL) { |
3357 | ret = -ENOMEM; | 3359 | ret = -ENOMEM; |
3358 | goto done; | 3360 | goto done; |
3359 | } | 3361 | } |
3360 | memset(new_crypt, 0, sizeof(struct prism2_crypt_data)); | 3362 | memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); |
3361 | new_crypt->ops = ops; | 3363 | new_crypt->ops = ops; |
3362 | new_crypt->priv = new_crypt->ops->init(i); | 3364 | new_crypt->priv = new_crypt->ops->init(i); |
3363 | if (new_crypt->priv == NULL) { | 3365 | if (new_crypt->priv == NULL) { |
@@ -3436,7 +3438,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev, | |||
3436 | { | 3438 | { |
3437 | struct hostap_interface *iface = dev->priv; | 3439 | struct hostap_interface *iface = dev->priv; |
3438 | local_info_t *local = iface->local; | 3440 | local_info_t *local = iface->local; |
3439 | struct prism2_crypt_data **crypt; | 3441 | struct ieee80211_crypt_data **crypt; |
3440 | void *sta_ptr; | 3442 | void *sta_ptr; |
3441 | int max_key_len, i; | 3443 | int max_key_len, i; |
3442 | struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; | 3444 | struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; |
@@ -3505,8 +3507,8 @@ static int prism2_ioctl_set_encryption(local_info_t *local, | |||
3505 | int param_len) | 3507 | int param_len) |
3506 | { | 3508 | { |
3507 | int ret = 0; | 3509 | int ret = 0; |
3508 | struct hostap_crypto_ops *ops; | 3510 | struct ieee80211_crypto_ops *ops; |
3509 | struct prism2_crypt_data **crypt; | 3511 | struct ieee80211_crypt_data **crypt; |
3510 | void *sta_ptr; | 3512 | void *sta_ptr; |
3511 | 3513 | ||
3512 | param->u.crypt.err = 0; | 3514 | param->u.crypt.err = 0; |
@@ -3544,16 +3546,16 @@ static int prism2_ioctl_set_encryption(local_info_t *local, | |||
3544 | goto done; | 3546 | goto done; |
3545 | } | 3547 | } |
3546 | 3548 | ||
3547 | ops = hostap_get_crypto_ops(param->u.crypt.alg); | 3549 | ops = ieee80211_get_crypto_ops(param->u.crypt.alg); |
3548 | if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { | 3550 | if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { |
3549 | request_module("hostap_crypt_wep"); | 3551 | request_module("ieee80211_crypt_wep"); |
3550 | ops = hostap_get_crypto_ops(param->u.crypt.alg); | 3552 | ops = ieee80211_get_crypto_ops(param->u.crypt.alg); |
3551 | } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { | 3553 | } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { |
3552 | request_module("hostap_crypt_tkip"); | 3554 | request_module("ieee80211_crypt_tkip"); |
3553 | ops = hostap_get_crypto_ops(param->u.crypt.alg); | 3555 | ops = ieee80211_get_crypto_ops(param->u.crypt.alg); |
3554 | } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { | 3556 | } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { |
3555 | request_module("hostap_crypt_ccmp"); | 3557 | request_module("ieee80211_crypt_ccmp"); |
3556 | ops = hostap_get_crypto_ops(param->u.crypt.alg); | 3558 | ops = ieee80211_get_crypto_ops(param->u.crypt.alg); |
3557 | } | 3559 | } |
3558 | if (ops == NULL) { | 3560 | if (ops == NULL) { |
3559 | printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", | 3561 | printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", |
@@ -3568,17 +3570,18 @@ static int prism2_ioctl_set_encryption(local_info_t *local, | |||
3568 | local->host_decrypt = local->host_encrypt = 1; | 3570 | local->host_decrypt = local->host_encrypt = 1; |
3569 | 3571 | ||
3570 | if (*crypt == NULL || (*crypt)->ops != ops) { | 3572 | if (*crypt == NULL || (*crypt)->ops != ops) { |
3571 | struct prism2_crypt_data *new_crypt; | 3573 | struct ieee80211_crypt_data *new_crypt; |
3572 | 3574 | ||
3573 | prism2_crypt_delayed_deinit(local, crypt); | 3575 | prism2_crypt_delayed_deinit(local, crypt); |
3574 | 3576 | ||
3575 | new_crypt = (struct prism2_crypt_data *) | 3577 | new_crypt = (struct ieee80211_crypt_data *) |
3576 | kmalloc(sizeof(struct prism2_crypt_data), GFP_KERNEL); | 3578 | kmalloc(sizeof(struct ieee80211_crypt_data), |
3579 | GFP_KERNEL); | ||
3577 | if (new_crypt == NULL) { | 3580 | if (new_crypt == NULL) { |
3578 | ret = -ENOMEM; | 3581 | ret = -ENOMEM; |
3579 | goto done; | 3582 | goto done; |
3580 | } | 3583 | } |
3581 | memset(new_crypt, 0, sizeof(struct prism2_crypt_data)); | 3584 | memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); |
3582 | new_crypt->ops = ops; | 3585 | new_crypt->ops = ops; |
3583 | new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); | 3586 | new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); |
3584 | if (new_crypt->priv == NULL) { | 3587 | if (new_crypt->priv == NULL) { |
@@ -3642,7 +3645,7 @@ static int prism2_ioctl_get_encryption(local_info_t *local, | |||
3642 | struct prism2_hostapd_param *param, | 3645 | struct prism2_hostapd_param *param, |
3643 | int param_len) | 3646 | int param_len) |
3644 | { | 3647 | { |
3645 | struct prism2_crypt_data **crypt; | 3648 | struct ieee80211_crypt_data **crypt; |
3646 | void *sta_ptr; | 3649 | void *sta_ptr; |
3647 | int max_key_len; | 3650 | int max_key_len; |
3648 | 3651 | ||
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 @@ | |||
2 | #define HOSTAP_WLAN_H | 2 | #define HOSTAP_WLAN_H |
3 | 3 | ||
4 | #include "hostap_config.h" | 4 | #include "hostap_config.h" |
5 | #include "hostap_crypt.h" | ||
6 | #include "hostap_common.h" | 5 | #include "hostap_common.h" |
7 | 6 | ||
8 | #define MAX_PARM_DEVICES 8 | 7 | #define MAX_PARM_DEVICES 8 |
@@ -534,13 +533,6 @@ struct prism2_frag_entry { | |||
534 | }; | 533 | }; |
535 | 534 | ||
536 | 535 | ||
537 | struct prism2_crypt_data { | ||
538 | struct list_head list; /* delayed deletion list */ | ||
539 | struct hostap_crypto_ops *ops; | ||
540 | void *priv; | ||
541 | atomic_t refcnt; | ||
542 | }; | ||
543 | |||
544 | struct hostap_cmd_queue { | 536 | struct hostap_cmd_queue { |
545 | struct list_head list; | 537 | struct list_head list; |
546 | wait_queue_head_t compl; | 538 | wait_queue_head_t compl; |
@@ -765,7 +757,7 @@ struct local_info { | |||
765 | 757 | ||
766 | #define WEP_KEYS 4 | 758 | #define WEP_KEYS 4 |
767 | #define WEP_KEY_LEN 13 | 759 | #define WEP_KEY_LEN 13 |
768 | struct prism2_crypt_data *crypt[WEP_KEYS]; | 760 | struct ieee80211_crypt_data *crypt[WEP_KEYS]; |
769 | int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ | 761 | int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ |
770 | struct timer_list crypt_deinit_timer; | 762 | struct timer_list crypt_deinit_timer; |
771 | struct list_head crypt_deinit_list; | 763 | struct list_head crypt_deinit_list; |