Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lib80211: absorb crypto bits from net/ieee80211

These bits are shared already between ipw2x00 and hostap, and could
probably be shared both more cleanly and with other drivers. This
commit simply relocates the code to lib80211 and adjusts the drivers
appropriately.

Signed-off-by: John W. Linville <linville@tuxdriver.com>

+680 -694
+4 -2
drivers/net/wireless/hostap/Kconfig
··· 2 2 tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)" 3 3 depends on WLAN_80211 4 4 select WIRELESS_EXT 5 - select IEEE80211 6 - select IEEE80211_CRYPT_WEP 5 + select LIB80211 6 + select LIB80211_CRYPT_WEP 7 + select LIB80211_CRYPT_TKIP 8 + select LIB80211_CRYPT_CCMP 7 9 ---help--- 8 10 Shared driver code for IEEE 802.11b wireless cards based on 9 11 Intersil Prism2/2.5/3 chipset. This driver supports so called
+1 -1
drivers/net/wireless/hostap/hostap.h
··· 63 63 int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac); 64 64 void ap_control_kickall(struct ap_data *ap); 65 65 void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, 66 - struct ieee80211_crypt_data ***crypt); 66 + struct lib80211_crypt_data ***crypt); 67 67 int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], 68 68 struct iw_quality qual[], int buf_size, 69 69 int aplist);
+1 -1
drivers/net/wireless/hostap/hostap_80211.h
··· 2 2 #define HOSTAP_80211_H 3 3 4 4 #include <linux/types.h> 5 - #include <net/ieee80211_crypt.h> 5 + #include <net/ieee80211.h> 6 6 7 7 struct hostap_ieee80211_mgmt { 8 8 __le16 frame_control;
+5 -5
drivers/net/wireless/hostap/hostap_80211_rx.c
··· 1 1 #include <linux/etherdevice.h> 2 - #include <net/ieee80211_crypt.h> 2 + #include <net/lib80211.h> 3 3 4 4 #include "hostap_80211.h" 5 5 #include "hostap.h" ··· 649 649 /* Called only as a tasklet (software IRQ) */ 650 650 static int 651 651 hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, 652 - struct ieee80211_crypt_data *crypt) 652 + struct lib80211_crypt_data *crypt) 653 653 { 654 654 struct ieee80211_hdr_4addr *hdr; 655 655 int res, hdrlen; ··· 687 687 /* Called only as a tasklet (software IRQ) */ 688 688 static int 689 689 hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb, 690 - int keyidx, struct ieee80211_crypt_data *crypt) 690 + int keyidx, struct lib80211_crypt_data *crypt) 691 691 { 692 692 struct ieee80211_hdr_4addr *hdr; 693 693 int res, hdrlen; ··· 733 733 int from_assoc_ap = 0; 734 734 u8 dst[ETH_ALEN]; 735 735 u8 src[ETH_ALEN]; 736 - struct ieee80211_crypt_data *crypt = NULL; 736 + struct lib80211_crypt_data *crypt = NULL; 737 737 void *sta = NULL; 738 738 int keyidx = 0; 739 739 ··· 785 785 int idx = 0; 786 786 if (skb->len >= hdrlen + 3) 787 787 idx = skb->data[hdrlen + 3] >> 6; 788 - crypt = local->crypt[idx]; 788 + crypt = local->crypt_info.crypt[idx]; 789 789 sta = NULL; 790 790 791 791 /* Use station specific key to override default keys if the
+5 -3
drivers/net/wireless/hostap/hostap_80211_tx.c
··· 306 306 307 307 /* Called only from software IRQ */ 308 308 static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, 309 - struct ieee80211_crypt_data *crypt) 309 + struct lib80211_crypt_data *crypt) 310 310 { 311 311 struct hostap_interface *iface; 312 312 local_info_t *local; ··· 405 405 if (local->host_encrypt) { 406 406 /* Set crypt to default algorithm and key; will be replaced in 407 407 * AP code if STA has own alg/key */ 408 - tx.crypt = local->crypt[local->tx_keyidx]; 408 + tx.crypt = local->crypt_info.crypt[local->crypt_info.tx_keyidx]; 409 409 tx.host_encrypt = 1; 410 410 } else { 411 411 tx.crypt = NULL; ··· 487 487 488 488 if (tx.crypt && (!tx.crypt->ops || !tx.crypt->ops->encrypt_mpdu)) 489 489 tx.crypt = NULL; 490 - else if ((tx.crypt || local->crypt[local->tx_keyidx]) && !no_encrypt) { 490 + else if ((tx.crypt || 491 + local->crypt_info.crypt[local->crypt_info.tx_keyidx]) && 492 + !no_encrypt) { 491 493 /* Add ISWEP flag both for firmware and host based encryption 492 494 */ 493 495 fc |= IEEE80211_FCTL_PROTECTED;
+6 -6
drivers/net/wireless/hostap/hostap_ap.c
··· 1206 1206 1207 1207 static void ap_crypt_init(struct ap_data *ap) 1208 1208 { 1209 - ap->crypt = ieee80211_get_crypto_ops("WEP"); 1209 + ap->crypt = lib80211_get_crypto_ops("WEP"); 1210 1210 1211 1211 if (ap->crypt) { 1212 1212 if (ap->crypt->init) { ··· 1224 1224 1225 1225 if (ap->crypt == NULL) { 1226 1226 printk(KERN_WARNING "AP could not initialize WEP: load module " 1227 - "ieee80211_crypt_wep.ko\n"); 1227 + "lib80211_crypt_wep.ko\n"); 1228 1228 } 1229 1229 } 1230 1230 ··· 1293 1293 __le16 *pos; 1294 1294 u16 resp = WLAN_STATUS_SUCCESS, fc; 1295 1295 struct sta_info *sta = NULL; 1296 - struct ieee80211_crypt_data *crypt; 1296 + struct lib80211_crypt_data *crypt; 1297 1297 char *txt = ""; 1298 1298 1299 1299 len = skb->len - IEEE80211_MGMT_HDR_LEN; ··· 1319 1319 int idx = 0; 1320 1320 if (skb->len >= hdrlen + 3) 1321 1321 idx = skb->data[hdrlen + 3] >> 6; 1322 - crypt = local->crypt[idx]; 1322 + crypt = local->crypt_info.crypt[idx]; 1323 1323 } 1324 1324 1325 1325 pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN); ··· 3065 3065 /* Called only as a tasklet (software IRQ) */ 3066 3066 int hostap_handle_sta_crypto(local_info_t *local, 3067 3067 struct ieee80211_hdr_4addr *hdr, 3068 - struct ieee80211_crypt_data **crypt, 3068 + struct lib80211_crypt_data **crypt, 3069 3069 void **sta_ptr) 3070 3070 { 3071 3071 struct sta_info *sta; ··· 3213 3213 3214 3214 3215 3215 void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, 3216 - struct ieee80211_crypt_data ***crypt) 3216 + struct lib80211_crypt_data ***crypt) 3217 3217 { 3218 3218 struct sta_info *sta; 3219 3219
+4 -4
drivers/net/wireless/hostap/hostap_ap.h
··· 74 74 u32 tx_since_last_failure; 75 75 u32 tx_consecutive_exc; 76 76 77 - struct ieee80211_crypt_data *crypt; 77 + struct lib80211_crypt_data *crypt; 78 78 79 79 int ap; /* whether this station is an AP */ 80 80 ··· 209 209 210 210 /* WEP operations for generating challenges to be used with shared key 211 211 * authentication */ 212 - struct ieee80211_crypto_ops *crypt; 212 + struct lib80211_crypto_ops *crypt; 213 213 void *crypt_priv; 214 214 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ 215 215 }; ··· 229 229 struct hostap_tx_data { 230 230 struct sk_buff *skb; 231 231 int host_encrypt; 232 - struct ieee80211_crypt_data *crypt; 232 + struct lib80211_crypt_data *crypt; 233 233 void *sta_ptr; 234 234 }; 235 235 ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx); ··· 244 244 struct hostap_80211_rx_status *rx_stats, 245 245 int wds); 246 246 int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr, 247 - struct ieee80211_crypt_data **crypt, 247 + struct lib80211_crypt_data **crypt, 248 248 void **sta_ptr); 249 249 int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr); 250 250 int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
+20 -16
drivers/net/wireless/hostap/hostap_hw.c
··· 47 47 #include <linux/wireless.h> 48 48 #include <net/iw_handler.h> 49 49 #include <net/ieee80211.h> 50 - #include <net/ieee80211_crypt.h> 50 + #include <net/lib80211.h> 51 51 #include <asm/irq.h> 52 52 53 53 #include "hostap_80211.h" ··· 2791 2791 static void prism2_crypt_deinit_entries(local_info_t *local, int force) 2792 2792 { 2793 2793 struct list_head *ptr, *n; 2794 - struct ieee80211_crypt_data *entry; 2794 + struct lib80211_crypt_data *entry; 2795 2795 2796 - for (ptr = local->crypt_deinit_list.next, n = ptr->next; 2797 - ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) { 2798 - entry = list_entry(ptr, struct ieee80211_crypt_data, list); 2796 + for (ptr = local->crypt_info.crypt_deinit_list.next, n = ptr->next; 2797 + ptr != &local->crypt_info.crypt_deinit_list; 2798 + ptr = n, n = ptr->next) { 2799 + entry = list_entry(ptr, struct lib80211_crypt_data, list); 2799 2800 2800 2801 if (atomic_read(&entry->refcnt) != 0 && !force) 2801 2802 continue; ··· 2817 2816 2818 2817 spin_lock_irqsave(&local->lock, flags); 2819 2818 prism2_crypt_deinit_entries(local, 0); 2820 - if (!list_empty(&local->crypt_deinit_list)) { 2819 + if (!list_empty(&local->crypt_info.crypt_deinit_list)) { 2821 2820 printk(KERN_DEBUG "%s: entries remaining in delayed crypt " 2822 2821 "deletion list\n", local->dev->name); 2823 - local->crypt_deinit_timer.expires = jiffies + HZ; 2824 - add_timer(&local->crypt_deinit_timer); 2822 + local->crypt_info.crypt_deinit_timer.expires = jiffies + HZ; 2823 + add_timer(&local->crypt_info.crypt_deinit_timer); 2825 2824 } 2826 2825 spin_unlock_irqrestore(&local->lock, flags); 2827 2826 ··· 3251 3250 3252 3251 INIT_LIST_HEAD(&local->cmd_queue); 3253 3252 init_waitqueue_head(&local->hostscan_wq); 3254 - INIT_LIST_HEAD(&local->crypt_deinit_list); 3255 - init_timer(&local->crypt_deinit_timer); 3256 - local->crypt_deinit_timer.data = (unsigned long) local; 3257 - local->crypt_deinit_timer.function = prism2_crypt_deinit_handler; 3253 + 3254 + local->crypt_info.name = dev->name; 3255 + local->crypt_info.lock = &local->lock; 3256 + INIT_LIST_HEAD(&local->crypt_info.crypt_deinit_list); 3257 + init_timer(&local->crypt_info.crypt_deinit_timer); 3258 + local->crypt_info.crypt_deinit_timer.data = (unsigned long) local; 3259 + local->crypt_info.crypt_deinit_timer.function = prism2_crypt_deinit_handler; 3258 3260 3259 3261 init_timer(&local->passive_scan_timer); 3260 3262 local->passive_scan_timer.data = (unsigned long) local; ··· 3358 3354 3359 3355 flush_scheduled_work(); 3360 3356 3361 - if (timer_pending(&local->crypt_deinit_timer)) 3362 - del_timer(&local->crypt_deinit_timer); 3357 + if (timer_pending(&local->crypt_info.crypt_deinit_timer)) 3358 + del_timer(&local->crypt_info.crypt_deinit_timer); 3363 3359 prism2_crypt_deinit_entries(local, 1); 3364 3360 3365 3361 if (timer_pending(&local->passive_scan_timer)) ··· 3378 3374 prism2_callback(local, PRISM2_CALLBACK_DISABLE); 3379 3375 3380 3376 for (i = 0; i < WEP_KEYS; i++) { 3381 - struct ieee80211_crypt_data *crypt = local->crypt[i]; 3377 + struct lib80211_crypt_data *crypt = local->crypt_info.crypt[i]; 3382 3378 if (crypt) { 3383 3379 if (crypt->ops) 3384 3380 crypt->ops->deinit(crypt->priv); 3385 3381 kfree(crypt); 3386 - local->crypt[i] = NULL; 3382 + local->crypt_info.crypt[i] = NULL; 3387 3383 } 3388 3384 } 3389 3385
+55 -55
drivers/net/wireless/hostap/hostap_ioctl.c
··· 2 2 3 3 #include <linux/types.h> 4 4 #include <linux/ethtool.h> 5 - #include <net/ieee80211_crypt.h> 5 + #include <net/lib80211.h> 6 6 7 7 #include "hostap_wlan.h" 8 8 #include "hostap.h" ··· 117 117 118 118 119 119 static void prism2_crypt_delayed_deinit(local_info_t *local, 120 - struct ieee80211_crypt_data **crypt) 120 + struct lib80211_crypt_data **crypt) 121 121 { 122 - struct ieee80211_crypt_data *tmp; 122 + struct lib80211_crypt_data *tmp; 123 123 unsigned long flags; 124 124 125 125 tmp = *crypt; ··· 133 133 * locking. */ 134 134 135 135 spin_lock_irqsave(&local->lock, flags); 136 - list_add(&tmp->list, &local->crypt_deinit_list); 137 - if (!timer_pending(&local->crypt_deinit_timer)) { 138 - local->crypt_deinit_timer.expires = jiffies + HZ; 139 - add_timer(&local->crypt_deinit_timer); 136 + list_add(&tmp->list, &local->crypt_info.crypt_deinit_list); 137 + if (!timer_pending(&local->crypt_info.crypt_deinit_timer)) { 138 + local->crypt_info.crypt_deinit_timer.expires = jiffies + HZ; 139 + add_timer(&local->crypt_info.crypt_deinit_timer); 140 140 } 141 141 spin_unlock_irqrestore(&local->lock, flags); 142 142 } ··· 149 149 struct hostap_interface *iface; 150 150 local_info_t *local; 151 151 int i; 152 - struct ieee80211_crypt_data **crypt; 152 + struct lib80211_crypt_data **crypt; 153 153 154 154 iface = netdev_priv(dev); 155 155 local = iface->local; 156 156 157 157 i = erq->flags & IW_ENCODE_INDEX; 158 158 if (i < 1 || i > 4) 159 - i = local->tx_keyidx; 159 + i = local->crypt_info.tx_keyidx; 160 160 else 161 161 i--; 162 162 if (i < 0 || i >= WEP_KEYS) 163 163 return -EINVAL; 164 164 165 - crypt = &local->crypt[i]; 165 + crypt = &local->crypt_info.crypt[i]; 166 166 167 167 if (erq->flags & IW_ENCODE_DISABLED) { 168 168 if (*crypt) ··· 177 177 } 178 178 179 179 if (*crypt == NULL) { 180 - struct ieee80211_crypt_data *new_crypt; 180 + struct lib80211_crypt_data *new_crypt; 181 181 182 182 /* take WEP into use */ 183 - new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), 183 + new_crypt = kzalloc(sizeof(struct lib80211_crypt_data), 184 184 GFP_KERNEL); 185 185 if (new_crypt == NULL) 186 186 return -ENOMEM; 187 - new_crypt->ops = ieee80211_get_crypto_ops("WEP"); 187 + new_crypt->ops = lib80211_get_crypto_ops("WEP"); 188 188 if (!new_crypt->ops) { 189 - request_module("ieee80211_crypt_wep"); 190 - new_crypt->ops = ieee80211_get_crypto_ops("WEP"); 189 + request_module("lib80211_crypt_wep"); 190 + new_crypt->ops = lib80211_get_crypto_ops("WEP"); 191 191 } 192 192 if (new_crypt->ops) 193 193 new_crypt->priv = new_crypt->ops->init(i); ··· 210 210 memset(keybuf + erq->length, 0, len - erq->length); 211 211 (*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv); 212 212 for (j = 0; j < WEP_KEYS; j++) { 213 - if (j != i && local->crypt[j]) { 213 + if (j != i && local->crypt_info.crypt[j]) { 214 214 first = 0; 215 215 break; 216 216 } 217 217 } 218 218 if (first) 219 - local->tx_keyidx = i; 219 + local->crypt_info.tx_keyidx = i; 220 220 } else { 221 221 /* No key data - just set the default TX key index */ 222 - local->tx_keyidx = i; 222 + local->crypt_info.tx_keyidx = i; 223 223 } 224 224 225 225 done: ··· 252 252 local_info_t *local; 253 253 int i, len; 254 254 u16 val; 255 - struct ieee80211_crypt_data *crypt; 255 + struct lib80211_crypt_data *crypt; 256 256 257 257 iface = netdev_priv(dev); 258 258 local = iface->local; 259 259 260 260 i = erq->flags & IW_ENCODE_INDEX; 261 261 if (i < 1 || i > 4) 262 - i = local->tx_keyidx; 262 + i = local->crypt_info.tx_keyidx; 263 263 else 264 264 i--; 265 265 if (i < 0 || i >= WEP_KEYS) 266 266 return -EINVAL; 267 267 268 - crypt = local->crypt[i]; 268 + crypt = local->crypt_info.crypt[i]; 269 269 erq->flags = i + 1; 270 270 271 271 if (crypt == NULL || crypt->ops == NULL) { ··· 3227 3227 local_info_t *local = iface->local; 3228 3228 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; 3229 3229 int i, ret = 0; 3230 - struct ieee80211_crypto_ops *ops; 3231 - struct ieee80211_crypt_data **crypt; 3230 + struct lib80211_crypto_ops *ops; 3231 + struct lib80211_crypt_data **crypt; 3232 3232 void *sta_ptr; 3233 3233 u8 *addr; 3234 3234 const char *alg, *module; ··· 3237 3237 if (i > WEP_KEYS) 3238 3238 return -EINVAL; 3239 3239 if (i < 1 || i > WEP_KEYS) 3240 - i = local->tx_keyidx; 3240 + i = local->crypt_info.tx_keyidx; 3241 3241 else 3242 3242 i--; 3243 3243 if (i < 0 || i >= WEP_KEYS) ··· 3247 3247 if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff && 3248 3248 addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) { 3249 3249 sta_ptr = NULL; 3250 - crypt = &local->crypt[i]; 3250 + crypt = &local->crypt_info.crypt[i]; 3251 3251 } else { 3252 3252 if (i != 0) 3253 3253 return -EINVAL; ··· 3260 3260 * is emulated by using default key idx 0. 3261 3261 */ 3262 3262 i = 0; 3263 - crypt = &local->crypt[i]; 3263 + crypt = &local->crypt_info.crypt[i]; 3264 3264 } else 3265 3265 return -EINVAL; 3266 3266 } ··· 3276 3276 switch (ext->alg) { 3277 3277 case IW_ENCODE_ALG_WEP: 3278 3278 alg = "WEP"; 3279 - module = "ieee80211_crypt_wep"; 3279 + module = "lib80211_crypt_wep"; 3280 3280 break; 3281 3281 case IW_ENCODE_ALG_TKIP: 3282 3282 alg = "TKIP"; 3283 - module = "ieee80211_crypt_tkip"; 3283 + module = "lib80211_crypt_tkip"; 3284 3284 break; 3285 3285 case IW_ENCODE_ALG_CCMP: 3286 3286 alg = "CCMP"; 3287 - module = "ieee80211_crypt_ccmp"; 3287 + module = "lib80211_crypt_ccmp"; 3288 3288 break; 3289 3289 default: 3290 3290 printk(KERN_DEBUG "%s: unsupported algorithm %d\n", ··· 3293 3293 goto done; 3294 3294 } 3295 3295 3296 - ops = ieee80211_get_crypto_ops(alg); 3296 + ops = lib80211_get_crypto_ops(alg); 3297 3297 if (ops == NULL) { 3298 3298 request_module(module); 3299 - ops = ieee80211_get_crypto_ops(alg); 3299 + ops = lib80211_get_crypto_ops(alg); 3300 3300 } 3301 3301 if (ops == NULL) { 3302 3302 printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", ··· 3315 3315 } 3316 3316 3317 3317 if (*crypt == NULL || (*crypt)->ops != ops) { 3318 - struct ieee80211_crypt_data *new_crypt; 3318 + struct lib80211_crypt_data *new_crypt; 3319 3319 3320 3320 prism2_crypt_delayed_deinit(local, crypt); 3321 3321 3322 - new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), 3322 + new_crypt = kzalloc(sizeof(struct lib80211_crypt_data), 3323 3323 GFP_KERNEL); 3324 3324 if (new_crypt == NULL) { 3325 3325 ret = -ENOMEM; ··· 3354 3354 3355 3355 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { 3356 3356 if (!sta_ptr) 3357 - local->tx_keyidx = i; 3357 + local->crypt_info.tx_keyidx = i; 3358 3358 } 3359 3359 3360 3360 3361 3361 if (sta_ptr == NULL && ext->key_len > 0) { 3362 3362 int first = 1, j; 3363 3363 for (j = 0; j < WEP_KEYS; j++) { 3364 - if (j != i && local->crypt[j]) { 3364 + if (j != i && local->crypt_info.crypt[j]) { 3365 3365 first = 0; 3366 3366 break; 3367 3367 } 3368 3368 } 3369 3369 if (first) 3370 - local->tx_keyidx = i; 3370 + local->crypt_info.tx_keyidx = i; 3371 3371 } 3372 3372 3373 3373 done: ··· 3399 3399 { 3400 3400 struct hostap_interface *iface = netdev_priv(dev); 3401 3401 local_info_t *local = iface->local; 3402 - struct ieee80211_crypt_data **crypt; 3402 + struct lib80211_crypt_data **crypt; 3403 3403 void *sta_ptr; 3404 3404 int max_key_len, i; 3405 3405 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; ··· 3411 3411 3412 3412 i = erq->flags & IW_ENCODE_INDEX; 3413 3413 if (i < 1 || i > WEP_KEYS) 3414 - i = local->tx_keyidx; 3414 + i = local->crypt_info.tx_keyidx; 3415 3415 else 3416 3416 i--; 3417 3417 ··· 3419 3419 if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff && 3420 3420 addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) { 3421 3421 sta_ptr = NULL; 3422 - crypt = &local->crypt[i]; 3422 + crypt = &local->crypt_info.crypt[i]; 3423 3423 } else { 3424 3424 i = 0; 3425 3425 sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt); ··· 3468 3468 int param_len) 3469 3469 { 3470 3470 int ret = 0; 3471 - struct ieee80211_crypto_ops *ops; 3472 - struct ieee80211_crypt_data **crypt; 3471 + struct lib80211_crypto_ops *ops; 3472 + struct lib80211_crypt_data **crypt; 3473 3473 void *sta_ptr; 3474 3474 3475 3475 param->u.crypt.err = 0; ··· 3486 3486 if (param->u.crypt.idx >= WEP_KEYS) 3487 3487 return -EINVAL; 3488 3488 sta_ptr = NULL; 3489 - crypt = &local->crypt[param->u.crypt.idx]; 3489 + crypt = &local->crypt_info.crypt[param->u.crypt.idx]; 3490 3490 } else { 3491 3491 if (param->u.crypt.idx) 3492 3492 return -EINVAL; ··· 3507 3507 goto done; 3508 3508 } 3509 3509 3510 - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 3510 + ops = lib80211_get_crypto_ops(param->u.crypt.alg); 3511 3511 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { 3512 - request_module("ieee80211_crypt_wep"); 3513 - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 3512 + request_module("lib80211_crypt_wep"); 3513 + ops = lib80211_get_crypto_ops(param->u.crypt.alg); 3514 3514 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { 3515 - request_module("ieee80211_crypt_tkip"); 3516 - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 3515 + request_module("lib80211_crypt_tkip"); 3516 + ops = lib80211_get_crypto_ops(param->u.crypt.alg); 3517 3517 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { 3518 - request_module("ieee80211_crypt_ccmp"); 3519 - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 3518 + request_module("lib80211_crypt_ccmp"); 3519 + ops = lib80211_get_crypto_ops(param->u.crypt.alg); 3520 3520 } 3521 3521 if (ops == NULL) { 3522 3522 printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", ··· 3531 3531 local->host_decrypt = local->host_encrypt = 1; 3532 3532 3533 3533 if (*crypt == NULL || (*crypt)->ops != ops) { 3534 - struct ieee80211_crypt_data *new_crypt; 3534 + struct lib80211_crypt_data *new_crypt; 3535 3535 3536 3536 prism2_crypt_delayed_deinit(local, crypt); 3537 3537 3538 - new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), 3538 + new_crypt = kzalloc(sizeof(struct lib80211_crypt_data), 3539 3539 GFP_KERNEL); 3540 3540 if (new_crypt == NULL) { 3541 3541 ret = -ENOMEM; ··· 3568 3568 3569 3569 if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { 3570 3570 if (!sta_ptr) 3571 - local->tx_keyidx = param->u.crypt.idx; 3571 + local->crypt_info.tx_keyidx = param->u.crypt.idx; 3572 3572 else if (param->u.crypt.idx) { 3573 3573 printk(KERN_DEBUG "%s: TX key idx setting failed\n", 3574 3574 local->dev->name); ··· 3604 3604 struct prism2_hostapd_param *param, 3605 3605 int param_len) 3606 3606 { 3607 - struct ieee80211_crypt_data **crypt; 3607 + struct lib80211_crypt_data **crypt; 3608 3608 void *sta_ptr; 3609 3609 int max_key_len; 3610 3610 ··· 3620 3620 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 3621 3621 sta_ptr = NULL; 3622 3622 if (param->u.crypt.idx >= WEP_KEYS) 3623 - param->u.crypt.idx = local->tx_keyidx; 3624 - crypt = &local->crypt[param->u.crypt.idx]; 3623 + param->u.crypt.idx = local->crypt_info.tx_keyidx; 3624 + crypt = &local->crypt_info.crypt[param->u.crypt.idx]; 3625 3625 } else { 3626 3626 param->u.crypt.idx = 0; 3627 3627 sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0,
+10 -9
drivers/net/wireless/hostap/hostap_main.c
··· 27 27 #include <net/net_namespace.h> 28 28 #include <net/iw_handler.h> 29 29 #include <net/ieee80211.h> 30 - #include <net/ieee80211_crypt.h> 30 + #include <net/lib80211.h> 31 31 #include <asm/uaccess.h> 32 32 33 33 #include "hostap_wlan.h" ··· 343 343 char keybuf[WEP_KEY_LEN + 1]; 344 344 enum { NONE, WEP, OTHER } encrypt_type; 345 345 346 - idx = local->tx_keyidx; 347 - if (local->crypt[idx] == NULL || local->crypt[idx]->ops == NULL) 346 + idx = local->crypt_info.tx_keyidx; 347 + if (local->crypt_info.crypt[idx] == NULL || 348 + local->crypt_info.crypt[idx]->ops == NULL) 348 349 encrypt_type = NONE; 349 - else if (strcmp(local->crypt[idx]->ops->name, "WEP") == 0) 350 + else if (strcmp(local->crypt_info.crypt[idx]->ops->name, "WEP") == 0) 350 351 encrypt_type = WEP; 351 352 else 352 353 encrypt_type = OTHER; ··· 395 394 /* 104-bit support seems to require that all the keys are set to the 396 395 * same keylen */ 397 396 keylen = 6; /* first 5 octets */ 398 - len = local->crypt[idx]->ops->get_key(keybuf, sizeof(keybuf), 399 - NULL, local->crypt[idx]->priv); 397 + len = local->crypt_info.crypt[idx]->ops->get_key(keybuf, sizeof(keybuf), NULL, 398 + local->crypt_info.crypt[idx]->priv); 400 399 if (idx >= 0 && idx < WEP_KEYS && len > 5) 401 400 keylen = WEP_KEY_LEN + 1; /* first 13 octets */ 402 401 403 402 for (i = 0; i < WEP_KEYS; i++) { 404 403 memset(keybuf, 0, sizeof(keybuf)); 405 - if (local->crypt[i]) { 406 - (void) local->crypt[i]->ops->get_key( 404 + if (local->crypt_info.crypt[i]) { 405 + (void) local->crypt_info.crypt[i]->ops->get_key( 407 406 keybuf, sizeof(keybuf), 408 - NULL, local->crypt[i]->priv); 407 + NULL, local->crypt_info.crypt[i]->priv); 409 408 } 410 409 if (local->func->set_rid(local->dev, 411 410 HFA384X_RID_CNFDEFAULTKEY0 + i,
+11 -9
drivers/net/wireless/hostap/hostap_proc.c
··· 2 2 3 3 #include <linux/types.h> 4 4 #include <linux/proc_fs.h> 5 - #include <net/ieee80211_crypt.h> 5 + #include <net/lib80211.h> 6 6 7 7 #include "hostap_wlan.h" 8 8 #include "hostap.h" ··· 36 36 p += sprintf(p, "dev_enabled=%d\n", local->dev_enabled); 37 37 p += sprintf(p, "sw_tick_stuck=%d\n", local->sw_tick_stuck); 38 38 for (i = 0; i < WEP_KEYS; i++) { 39 - if (local->crypt[i] && local->crypt[i]->ops) { 40 - p += sprintf(p, "crypt[%d]=%s\n", 41 - i, local->crypt[i]->ops->name); 39 + if (local->crypt_info.crypt[i] && 40 + local->crypt_info.crypt[i]->ops) { 41 + p += sprintf(p, "crypt[%d]=%s\n", i, 42 + local->crypt_info.crypt[i]->ops->name); 42 43 } 43 44 } 44 45 p += sprintf(p, "pri_only=%d\n", local->pri_only); ··· 207 206 return 0; 208 207 } 209 208 210 - p += sprintf(p, "tx_keyidx=%d\n", local->tx_keyidx); 209 + p += sprintf(p, "tx_keyidx=%d\n", local->crypt_info.tx_keyidx); 211 210 for (i = 0; i < WEP_KEYS; i++) { 212 - if (local->crypt[i] && local->crypt[i]->ops && 213 - local->crypt[i]->ops->print_stats) { 214 - p = local->crypt[i]->ops->print_stats( 215 - p, local->crypt[i]->priv); 211 + if (local->crypt_info.crypt[i] && 212 + local->crypt_info.crypt[i]->ops && 213 + local->crypt_info.crypt[i]->ops->print_stats) { 214 + p = local->crypt_info.crypt[i]->ops->print_stats( 215 + p, local->crypt_info.crypt[i]->priv); 216 216 } 217 217 } 218 218
+2 -4
drivers/net/wireless/hostap/hostap_wlan.h
··· 6 6 #include <linux/mutex.h> 7 7 #include <net/iw_handler.h> 8 8 #include <net/ieee80211_radiotap.h> 9 + #include <net/lib80211.h> 9 10 10 11 #include "hostap_config.h" 11 12 #include "hostap_common.h" ··· 764 763 765 764 #define WEP_KEYS 4 766 765 #define WEP_KEY_LEN 13 767 - struct ieee80211_crypt_data *crypt[WEP_KEYS]; 768 - int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ 769 - struct timer_list crypt_deinit_timer; 770 - struct list_head crypt_deinit_list; 766 + struct lib80211_crypt_info crypt_info; 771 767 772 768 int open_wep; /* allow unencrypted frames */ 773 769 int host_encrypt;
+6 -6
drivers/net/wireless/ipw2100.c
··· 4010 4010 else 4011 4011 len += sprintf(buf + len, "not connected\n"); 4012 4012 4013 - DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], "p"); 4013 + DUMP_VAR(ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx], "p"); 4014 4014 DUMP_VAR(status, "08lx"); 4015 4015 DUMP_VAR(config, "08lx"); 4016 4016 DUMP_VAR(capability, "08lx"); ··· 5514 5514 } 5515 5515 } 5516 5516 5517 - ipw2100_set_key_index(priv, priv->ieee->tx_keyidx, 1); 5517 + ipw2100_set_key_index(priv, priv->ieee->crypt_info.tx_keyidx, 1); 5518 5518 } 5519 5519 5520 5520 /* Always enable privacy so the Host can filter WEP packets if ··· 7620 7620 struct ipw2100_priv *priv = ieee80211_priv(dev); 7621 7621 struct ieee80211_device *ieee = priv->ieee; 7622 7622 struct iw_param *param = &wrqu->param; 7623 - struct ieee80211_crypt_data *crypt; 7623 + struct lib80211_crypt_data *crypt; 7624 7624 unsigned long flags; 7625 7625 int ret = 0; 7626 7626 ··· 7635 7635 break; 7636 7636 7637 7637 case IW_AUTH_TKIP_COUNTERMEASURES: 7638 - crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; 7638 + crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx]; 7639 7639 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) 7640 7640 break; 7641 7641 ··· 7712 7712 { 7713 7713 struct ipw2100_priv *priv = ieee80211_priv(dev); 7714 7714 struct ieee80211_device *ieee = priv->ieee; 7715 - struct ieee80211_crypt_data *crypt; 7715 + struct lib80211_crypt_data *crypt; 7716 7716 struct iw_param *param = &wrqu->param; 7717 7717 int ret = 0; 7718 7718 ··· 7728 7728 break; 7729 7729 7730 7730 case IW_AUTH_TKIP_COUNTERMEASURES: 7731 - crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; 7731 + crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx]; 7732 7732 if (!crypt || !crypt->ops->get_flags) { 7733 7733 IPW_DEBUG_WARNING("Can't get TKIP countermeasures: " 7734 7734 "crypt not set!\n");
+6 -6
drivers/net/wireless/ipw2200.c
··· 6600 6600 struct ipw_priv *priv = ieee80211_priv(dev); 6601 6601 struct ieee80211_device *ieee = priv->ieee; 6602 6602 struct iw_param *param = &wrqu->param; 6603 - struct ieee80211_crypt_data *crypt; 6603 + struct lib80211_crypt_data *crypt; 6604 6604 unsigned long flags; 6605 6605 int ret = 0; 6606 6606 ··· 6622 6622 break; 6623 6623 6624 6624 case IW_AUTH_TKIP_COUNTERMEASURES: 6625 - crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; 6625 + crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx]; 6626 6626 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) 6627 6627 break; 6628 6628 ··· 6699 6699 { 6700 6700 struct ipw_priv *priv = ieee80211_priv(dev); 6701 6701 struct ieee80211_device *ieee = priv->ieee; 6702 - struct ieee80211_crypt_data *crypt; 6702 + struct lib80211_crypt_data *crypt; 6703 6703 struct iw_param *param = &wrqu->param; 6704 6704 int ret = 0; 6705 6705 ··· 6715 6715 break; 6716 6716 6717 6717 case IW_AUTH_TKIP_COUNTERMEASURES: 6718 - crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; 6718 + crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx]; 6719 6719 if (!crypt || !crypt->ops->get_flags) 6720 6720 break; 6721 6721 ··· 10251 10251 case SEC_LEVEL_1: 10252 10252 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= 10253 10253 cpu_to_le16(IEEE80211_FCTL_PROTECTED); 10254 - tfd->u.data.key_index = priv->ieee->tx_keyidx; 10255 - if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <= 10254 + tfd->u.data.key_index = priv->ieee->crypt_info.tx_keyidx; 10255 + if (priv->ieee->sec.key_sizes[priv->ieee->crypt_info.tx_keyidx] <= 10256 10256 40) 10257 10257 tfd->u.data.key_index |= DCT_WEP_KEY_64Bit; 10258 10258 else
+3 -7
include/net/ieee80211.h
··· 30 30 #include <linux/wireless.h> 31 31 #include <linux/ieee80211.h> 32 32 33 + #include <net/lib80211.h> 34 + 33 35 #define IEEE80211_VERSION "git-1.1.13" 34 36 35 37 #define IEEE80211_DATA_LEN 2304 ··· 356 354 }; 357 355 358 356 struct ieee80211_device; 359 - 360 - #include "ieee80211_crypt.h" 361 357 362 358 #define SEC_KEY_1 (1<<0) 363 359 #define SEC_KEY_2 (1<<1) ··· 937 937 size_t wpa_ie_len; 938 938 u8 *wpa_ie; 939 939 940 - struct list_head crypt_deinit_list; 941 - struct ieee80211_crypt_data *crypt[WEP_KEYS]; 942 - int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ 943 - struct timer_list crypt_deinit_timer; 944 - int crypt_quiesced; 940 + struct lib80211_crypt_info crypt_info; 945 941 946 942 int bcrx_sta_key; /* use individual keys to override default keys even 947 943 * with RX of broad/multicast frames */
-108
include/net/ieee80211_crypt.h
··· 1 - /* 2 - * Original code based on Host AP (software wireless LAN access point) driver 3 - * for Intersil Prism2/2.5/3. 4 - * 5 - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 6 - * <j@w1.fi> 7 - * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi> 8 - * 9 - * Adaption to a generic IEEE 802.11 stack by James Ketrenos 10 - * <jketreno@linux.intel.com> 11 - * 12 - * Copyright (c) 2004, Intel Corporation 13 - * 14 - * This program is free software; you can redistribute it and/or modify 15 - * it under the terms of the GNU General Public License version 2 as 16 - * published by the Free Software Foundation. See README and COPYING for 17 - * more details. 18 - */ 19 - 20 - /* 21 - * This file defines the interface to the ieee80211 crypto module. 22 - */ 23 - #ifndef IEEE80211_CRYPT_H 24 - #define IEEE80211_CRYPT_H 25 - 26 - #include <linux/types.h> 27 - #include <linux/list.h> 28 - #include <net/ieee80211.h> 29 - #include <asm/atomic.h> 30 - 31 - enum { 32 - IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0), 33 - }; 34 - 35 - struct sk_buff; 36 - struct module; 37 - 38 - struct ieee80211_crypto_ops { 39 - const char *name; 40 - struct list_head list; 41 - 42 - /* init new crypto context (e.g., allocate private data space, 43 - * select IV, etc.); returns NULL on failure or pointer to allocated 44 - * private data on success */ 45 - void *(*init) (int keyidx); 46 - 47 - /* deinitialize crypto context and free allocated private data */ 48 - void (*deinit) (void *priv); 49 - 50 - int (*build_iv) (struct sk_buff * skb, int hdr_len, 51 - u8 *key, int keylen, void *priv); 52 - 53 - /* encrypt/decrypt return < 0 on error or >= 0 on success. The return 54 - * value from decrypt_mpdu is passed as the keyidx value for 55 - * decrypt_msdu. skb must have enough head and tail room for the 56 - * encryption; if not, error will be returned; these functions are 57 - * called for all MPDUs (i.e., fragments). 58 - */ 59 - int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv); 60 - int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv); 61 - 62 - /* These functions are called for full MSDUs, i.e. full frames. 63 - * These can be NULL if full MSDU operations are not needed. */ 64 - int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv); 65 - int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len, 66 - void *priv); 67 - 68 - int (*set_key) (void *key, int len, u8 * seq, void *priv); 69 - int (*get_key) (void *key, int len, u8 * seq, void *priv); 70 - 71 - /* procfs handler for printing out key information and possible 72 - * statistics */ 73 - char *(*print_stats) (char *p, void *priv); 74 - 75 - /* Crypto specific flag get/set for configuration settings */ 76 - unsigned long (*get_flags) (void *priv); 77 - unsigned long (*set_flags) (unsigned long flags, void *priv); 78 - 79 - /* maximum number of bytes added by encryption; encrypt buf is 80 - * allocated with extra_prefix_len bytes, copy of in_buf, and 81 - * extra_postfix_len; encrypt need not use all this space, but 82 - * the result must start at the beginning of the buffer and correct 83 - * length must be returned */ 84 - int extra_mpdu_prefix_len, extra_mpdu_postfix_len; 85 - int extra_msdu_prefix_len, extra_msdu_postfix_len; 86 - 87 - struct module *owner; 88 - }; 89 - 90 - struct ieee80211_crypt_data { 91 - struct list_head list; /* delayed deletion list */ 92 - struct ieee80211_crypto_ops *ops; 93 - void *priv; 94 - atomic_t refcnt; 95 - }; 96 - 97 - struct ieee80211_device; 98 - 99 - int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); 100 - int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); 101 - struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name); 102 - void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int); 103 - void ieee80211_crypt_deinit_handler(unsigned long); 104 - void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, 105 - struct ieee80211_crypt_data **crypt); 106 - void ieee80211_crypt_quiescing(struct ieee80211_device *ieee); 107 - 108 - #endif
+108
include/net/lib80211.h
··· 3 3 * 4 4 * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com> 5 5 * 6 + * Some bits copied from old ieee80211 component, w/ original copyright 7 + * notices below: 8 + * 9 + * Original code based on Host AP (software wireless LAN access point) driver 10 + * for Intersil Prism2/2.5/3. 11 + * 12 + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 13 + * <j@w1.fi> 14 + * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi> 15 + * 16 + * Adaption to a generic IEEE 802.11 stack by James Ketrenos 17 + * <jketreno@linux.intel.com> 18 + * 19 + * Copyright (c) 2004, Intel Corporation 20 + * 6 21 */ 7 22 8 23 #ifndef LIB80211_H 9 24 #define LIB80211_H 10 25 26 + #include <linux/types.h> 27 + #include <linux/list.h> 28 + #include <linux/module.h> 29 + #include <asm/atomic.h> 30 + #include <linux/if.h> 31 + #include <linux/skbuff.h> 11 32 #include <linux/ieee80211.h> 12 33 13 34 /* print_ssid() is intended to be used in debug (and possibly error) 14 35 * messages. It should never be used for passing ssid to user space. */ 15 36 const char *print_ssid(char *buf, const char *ssid, u8 ssid_len); 16 37 #define DECLARE_SSID_BUF(var) char var[IEEE80211_MAX_SSID_LEN * 4 + 1] __maybe_unused 38 + 39 + #define NUM_WEP_KEYS 4 40 + 41 + enum { 42 + IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0), 43 + }; 44 + 45 + struct lib80211_crypto_ops { 46 + const char *name; 47 + struct list_head list; 48 + 49 + /* init new crypto context (e.g., allocate private data space, 50 + * select IV, etc.); returns NULL on failure or pointer to allocated 51 + * private data on success */ 52 + void *(*init) (int keyidx); 53 + 54 + /* deinitialize crypto context and free allocated private data */ 55 + void (*deinit) (void *priv); 56 + 57 + int (*build_iv) (struct sk_buff * skb, int hdr_len, 58 + u8 *key, int keylen, void *priv); 59 + 60 + /* encrypt/decrypt return < 0 on error or >= 0 on success. The return 61 + * value from decrypt_mpdu is passed as the keyidx value for 62 + * decrypt_msdu. skb must have enough head and tail room for the 63 + * encryption; if not, error will be returned; these functions are 64 + * called for all MPDUs (i.e., fragments). 65 + */ 66 + int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv); 67 + int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv); 68 + 69 + /* These functions are called for full MSDUs, i.e. full frames. 70 + * These can be NULL if full MSDU operations are not needed. */ 71 + int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv); 72 + int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len, 73 + void *priv); 74 + 75 + int (*set_key) (void *key, int len, u8 * seq, void *priv); 76 + int (*get_key) (void *key, int len, u8 * seq, void *priv); 77 + 78 + /* procfs handler for printing out key information and possible 79 + * statistics */ 80 + char *(*print_stats) (char *p, void *priv); 81 + 82 + /* Crypto specific flag get/set for configuration settings */ 83 + unsigned long (*get_flags) (void *priv); 84 + unsigned long (*set_flags) (unsigned long flags, void *priv); 85 + 86 + /* maximum number of bytes added by encryption; encrypt buf is 87 + * allocated with extra_prefix_len bytes, copy of in_buf, and 88 + * extra_postfix_len; encrypt need not use all this space, but 89 + * the result must start at the beginning of the buffer and correct 90 + * length must be returned */ 91 + int extra_mpdu_prefix_len, extra_mpdu_postfix_len; 92 + int extra_msdu_prefix_len, extra_msdu_postfix_len; 93 + 94 + struct module *owner; 95 + }; 96 + 97 + struct lib80211_crypt_data { 98 + struct list_head list; /* delayed deletion list */ 99 + struct lib80211_crypto_ops *ops; 100 + void *priv; 101 + atomic_t refcnt; 102 + }; 103 + 104 + struct lib80211_crypt_info { 105 + char *name; 106 + /* Most clients will already have a lock, 107 + so just point to that. */ 108 + spinlock_t *lock; 109 + 110 + struct lib80211_crypt_data *crypt[NUM_WEP_KEYS]; 111 + int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ 112 + struct list_head crypt_deinit_list; 113 + struct timer_list crypt_deinit_timer; 114 + int crypt_quiesced; 115 + }; 116 + 117 + int lib80211_register_crypto_ops(struct lib80211_crypto_ops *ops); 118 + int lib80211_unregister_crypto_ops(struct lib80211_crypto_ops *ops); 119 + struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name); 120 + void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *, int); 121 + void lib80211_crypt_deinit_handler(unsigned long); 122 + void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info, 123 + struct lib80211_crypt_data **crypt); 124 + void lib80211_crypt_quiescing(struct lib80211_crypt_info *info); 17 125 18 126 #endif /* LIB80211_H */
+3 -12
net/ieee80211/Kconfig
··· 8 8 select CRYPTO_MICHAEL_MIC 9 9 select CRYPTO_ECB 10 10 select CRC32 11 - select IEEE80211_CRYPT_WEP 12 - select IEEE80211_CRYPT_TKIP 13 - select IEEE80211_CRYPT_CCMP 14 11 select LIB80211 12 + select LIB80211_CRYPT_WEP 13 + select LIB80211_CRYPT_TKIP 14 + select LIB80211_CRYPT_CCMP 15 15 ---help--- 16 16 This option enables the hardware independent IEEE 802.11 17 17 networking stack. This component is deprecated in favor of the ··· 39 39 40 40 If you are not trying to debug or develop the ieee80211 41 41 subsystem, you most likely want to say N here. 42 - 43 - config IEEE80211_CRYPT_WEP 44 - tristate 45 - 46 - config IEEE80211_CRYPT_CCMP 47 - tristate 48 - 49 - config IEEE80211_CRYPT_TKIP 50 - tristate
-4
net/ieee80211/Makefile
··· 1 1 obj-$(CONFIG_IEEE80211) += ieee80211.o 2 - obj-$(CONFIG_IEEE80211) += ieee80211_crypt.o 3 - obj-$(CONFIG_IEEE80211_CRYPT_WEP) += ieee80211_crypt_wep.o 4 - obj-$(CONFIG_IEEE80211_CRYPT_CCMP) += ieee80211_crypt_ccmp.o 5 - obj-$(CONFIG_IEEE80211_CRYPT_TKIP) += ieee80211_crypt_tkip.o 6 2 ieee80211-objs := \ 7 3 ieee80211_module.o \ 8 4 ieee80211_tx.o \
-206
net/ieee80211/ieee80211_crypt.c
··· 1 - /* 2 - * Host AP crypto routines 3 - * 4 - * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi> 5 - * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com> 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License version 2 as 9 - * published by the Free Software Foundation. See README and COPYING for 10 - * more details. 11 - * 12 - */ 13 - 14 - #include <linux/errno.h> 15 - #include <linux/module.h> 16 - #include <linux/init.h> 17 - #include <linux/slab.h> 18 - #include <linux/string.h> 19 - #include <net/ieee80211.h> 20 - 21 - MODULE_AUTHOR("Jouni Malinen"); 22 - MODULE_DESCRIPTION("HostAP crypto"); 23 - MODULE_LICENSE("GPL"); 24 - 25 - struct ieee80211_crypto_alg { 26 - struct list_head list; 27 - struct ieee80211_crypto_ops *ops; 28 - }; 29 - 30 - static LIST_HEAD(ieee80211_crypto_algs); 31 - static DEFINE_SPINLOCK(ieee80211_crypto_lock); 32 - 33 - void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) 34 - { 35 - struct ieee80211_crypt_data *entry, *next; 36 - unsigned long flags; 37 - 38 - spin_lock_irqsave(&ieee->lock, flags); 39 - list_for_each_entry_safe(entry, next, &ieee->crypt_deinit_list, list) { 40 - if (atomic_read(&entry->refcnt) != 0 && !force) 41 - continue; 42 - 43 - list_del(&entry->list); 44 - 45 - if (entry->ops) { 46 - entry->ops->deinit(entry->priv); 47 - module_put(entry->ops->owner); 48 - } 49 - kfree(entry); 50 - } 51 - spin_unlock_irqrestore(&ieee->lock, flags); 52 - } 53 - 54 - /* After this, crypt_deinit_list won't accept new members */ 55 - void ieee80211_crypt_quiescing(struct ieee80211_device *ieee) 56 - { 57 - unsigned long flags; 58 - 59 - spin_lock_irqsave(&ieee->lock, flags); 60 - ieee->crypt_quiesced = 1; 61 - spin_unlock_irqrestore(&ieee->lock, flags); 62 - } 63 - 64 - void ieee80211_crypt_deinit_handler(unsigned long data) 65 - { 66 - struct ieee80211_device *ieee = (struct ieee80211_device *)data; 67 - unsigned long flags; 68 - 69 - ieee80211_crypt_deinit_entries(ieee, 0); 70 - 71 - spin_lock_irqsave(&ieee->lock, flags); 72 - if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) { 73 - printk(KERN_DEBUG "%s: entries remaining in delayed crypt " 74 - "deletion list\n", ieee->dev->name); 75 - ieee->crypt_deinit_timer.expires = jiffies + HZ; 76 - add_timer(&ieee->crypt_deinit_timer); 77 - } 78 - spin_unlock_irqrestore(&ieee->lock, flags); 79 - } 80 - 81 - void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, 82 - struct ieee80211_crypt_data **crypt) 83 - { 84 - struct ieee80211_crypt_data *tmp; 85 - unsigned long flags; 86 - 87 - if (*crypt == NULL) 88 - return; 89 - 90 - tmp = *crypt; 91 - *crypt = NULL; 92 - 93 - /* must not run ops->deinit() while there may be pending encrypt or 94 - * decrypt operations. Use a list of delayed deinits to avoid needing 95 - * locking. */ 96 - 97 - spin_lock_irqsave(&ieee->lock, flags); 98 - if (!ieee->crypt_quiesced) { 99 - list_add(&tmp->list, &ieee->crypt_deinit_list); 100 - if (!timer_pending(&ieee->crypt_deinit_timer)) { 101 - ieee->crypt_deinit_timer.expires = jiffies + HZ; 102 - add_timer(&ieee->crypt_deinit_timer); 103 - } 104 - } 105 - spin_unlock_irqrestore(&ieee->lock, flags); 106 - } 107 - 108 - int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) 109 - { 110 - unsigned long flags; 111 - struct ieee80211_crypto_alg *alg; 112 - 113 - alg = kzalloc(sizeof(*alg), GFP_KERNEL); 114 - if (alg == NULL) 115 - return -ENOMEM; 116 - 117 - alg->ops = ops; 118 - 119 - spin_lock_irqsave(&ieee80211_crypto_lock, flags); 120 - list_add(&alg->list, &ieee80211_crypto_algs); 121 - spin_unlock_irqrestore(&ieee80211_crypto_lock, flags); 122 - 123 - printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n", 124 - ops->name); 125 - 126 - return 0; 127 - } 128 - 129 - int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) 130 - { 131 - struct ieee80211_crypto_alg *alg; 132 - unsigned long flags; 133 - 134 - spin_lock_irqsave(&ieee80211_crypto_lock, flags); 135 - list_for_each_entry(alg, &ieee80211_crypto_algs, list) { 136 - if (alg->ops == ops) 137 - goto found; 138 - } 139 - spin_unlock_irqrestore(&ieee80211_crypto_lock, flags); 140 - return -EINVAL; 141 - 142 - found: 143 - printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " 144 - "'%s'\n", ops->name); 145 - list_del(&alg->list); 146 - spin_unlock_irqrestore(&ieee80211_crypto_lock, flags); 147 - kfree(alg); 148 - return 0; 149 - } 150 - 151 - struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name) 152 - { 153 - struct ieee80211_crypto_alg *alg; 154 - unsigned long flags; 155 - 156 - spin_lock_irqsave(&ieee80211_crypto_lock, flags); 157 - list_for_each_entry(alg, &ieee80211_crypto_algs, list) { 158 - if (strcmp(alg->ops->name, name) == 0) 159 - goto found; 160 - } 161 - spin_unlock_irqrestore(&ieee80211_crypto_lock, flags); 162 - return NULL; 163 - 164 - found: 165 - spin_unlock_irqrestore(&ieee80211_crypto_lock, flags); 166 - return alg->ops; 167 - } 168 - 169 - static void *ieee80211_crypt_null_init(int keyidx) 170 - { 171 - return (void *)1; 172 - } 173 - 174 - static void ieee80211_crypt_null_deinit(void *priv) 175 - { 176 - } 177 - 178 - static struct ieee80211_crypto_ops ieee80211_crypt_null = { 179 - .name = "NULL", 180 - .init = ieee80211_crypt_null_init, 181 - .deinit = ieee80211_crypt_null_deinit, 182 - .owner = THIS_MODULE, 183 - }; 184 - 185 - static int __init ieee80211_crypto_init(void) 186 - { 187 - return ieee80211_register_crypto_ops(&ieee80211_crypt_null); 188 - } 189 - 190 - static void __exit ieee80211_crypto_deinit(void) 191 - { 192 - ieee80211_unregister_crypto_ops(&ieee80211_crypt_null); 193 - BUG_ON(!list_empty(&ieee80211_crypto_algs)); 194 - } 195 - 196 - EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); 197 - EXPORT_SYMBOL(ieee80211_crypt_deinit_handler); 198 - EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit); 199 - EXPORT_SYMBOL(ieee80211_crypt_quiescing); 200 - 201 - EXPORT_SYMBOL(ieee80211_register_crypto_ops); 202 - EXPORT_SYMBOL(ieee80211_unregister_crypto_ops); 203 - EXPORT_SYMBOL(ieee80211_get_crypto_ops); 204 - 205 - module_init(ieee80211_crypto_init); 206 - module_exit(ieee80211_crypto_deinit);
+59 -59
net/ieee80211/ieee80211_crypt_ccmp.c net/wireless/lib80211_crypt_ccmp.c
··· 1 1 /* 2 - * Host AP crypt: host-based CCMP encryption implementation for Host AP driver 2 + * lib80211 crypt: host-based CCMP encryption implementation for lib80211 3 3 * 4 4 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi> 5 + * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com> 5 6 * 6 7 * This program is free software; you can redistribute it and/or modify 7 8 * it under the terms of the GNU General Public License version 2 as ··· 23 22 #include <asm/string.h> 24 23 #include <linux/wireless.h> 25 24 26 - #include <net/ieee80211.h> 25 + #include <linux/ieee80211.h> 27 26 28 27 #include <linux/crypto.h> 28 + 29 + #include <net/lib80211.h> 29 30 30 31 MODULE_AUTHOR("Jouni Malinen"); 31 32 MODULE_DESCRIPTION("Host AP crypt: CCMP"); ··· 39 36 #define CCMP_TK_LEN 16 40 37 #define CCMP_PN_LEN 6 41 38 42 - struct ieee80211_ccmp_data { 39 + struct lib80211_ccmp_data { 43 40 u8 key[CCMP_TK_LEN]; 44 41 int key_set; 45 42 ··· 60 57 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; 61 58 }; 62 59 63 - static inline void ieee80211_ccmp_aes_encrypt(struct crypto_cipher *tfm, 60 + static inline void lib80211_ccmp_aes_encrypt(struct crypto_cipher *tfm, 64 61 const u8 pt[16], u8 ct[16]) 65 62 { 66 63 crypto_cipher_encrypt_one(tfm, ct, pt); 67 64 } 68 65 69 - static void *ieee80211_ccmp_init(int key_idx) 66 + static void *lib80211_ccmp_init(int key_idx) 70 67 { 71 - struct ieee80211_ccmp_data *priv; 68 + struct lib80211_ccmp_data *priv; 72 69 73 70 priv = kzalloc(sizeof(*priv), GFP_ATOMIC); 74 71 if (priv == NULL) ··· 77 74 78 75 priv->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); 79 76 if (IS_ERR(priv->tfm)) { 80 - printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate " 77 + printk(KERN_DEBUG "lib80211_crypt_ccmp: could not allocate " 81 78 "crypto API aes\n"); 82 79 priv->tfm = NULL; 83 80 goto fail; ··· 95 92 return NULL; 96 93 } 97 94 98 - static void ieee80211_ccmp_deinit(void *priv) 95 + static void lib80211_ccmp_deinit(void *priv) 99 96 { 100 - struct ieee80211_ccmp_data *_priv = priv; 97 + struct lib80211_ccmp_data *_priv = priv; 101 98 if (_priv && _priv->tfm) 102 99 crypto_free_cipher(_priv->tfm); 103 100 kfree(priv); ··· 111 108 } 112 109 113 110 static void ccmp_init_blocks(struct crypto_cipher *tfm, 114 - struct ieee80211_hdr_4addr *hdr, 111 + struct ieee80211_hdr *hdr, 115 112 u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0) 116 113 { 117 114 u8 *pos, qc = 0; 118 115 size_t aad_len; 119 - u16 fc; 120 116 int a4_included, qc_included; 121 117 u8 aad[2 * AES_BLOCK_LEN]; 122 118 123 - fc = le16_to_cpu(hdr->frame_ctl); 124 - a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == 125 - (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)); 126 - qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && 127 - (WLAN_FC_GET_STYPE(fc) & IEEE80211_STYPE_QOS_DATA)); 119 + a4_included = ieee80211_has_a4(hdr->frame_control); 120 + qc_included = ieee80211_is_data_qos(hdr->frame_control); 121 + 128 122 aad_len = 22; 129 123 if (a4_included) 130 124 aad_len += 6; ··· 158 158 aad[2] = pos[0] & 0x8f; 159 159 aad[3] = pos[1] & 0xc7; 160 160 memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN); 161 - pos = (u8 *) & hdr->seq_ctl; 161 + pos = (u8 *) & hdr->seq_ctrl; 162 162 aad[22] = pos[0] & 0x0f; 163 163 aad[23] = 0; /* all bits masked */ 164 164 memset(aad + 24, 0, 8); ··· 170 170 } 171 171 172 172 /* Start with the first block and AAD */ 173 - ieee80211_ccmp_aes_encrypt(tfm, b0, auth); 173 + lib80211_ccmp_aes_encrypt(tfm, b0, auth); 174 174 xor_block(auth, aad, AES_BLOCK_LEN); 175 - ieee80211_ccmp_aes_encrypt(tfm, auth, auth); 175 + lib80211_ccmp_aes_encrypt(tfm, auth, auth); 176 176 xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); 177 - ieee80211_ccmp_aes_encrypt(tfm, auth, auth); 177 + lib80211_ccmp_aes_encrypt(tfm, auth, auth); 178 178 b0[0] &= 0x07; 179 179 b0[14] = b0[15] = 0; 180 - ieee80211_ccmp_aes_encrypt(tfm, b0, s0); 180 + lib80211_ccmp_aes_encrypt(tfm, b0, s0); 181 181 } 182 182 183 - static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, 183 + static int lib80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, 184 184 u8 *aeskey, int keylen, void *priv) 185 185 { 186 - struct ieee80211_ccmp_data *key = priv; 186 + struct lib80211_ccmp_data *key = priv; 187 187 int i; 188 188 u8 *pos; 189 189 ··· 217 217 return CCMP_HDR_LEN; 218 218 } 219 219 220 - static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 220 + static int lib80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 221 221 { 222 - struct ieee80211_ccmp_data *key = priv; 222 + struct lib80211_ccmp_data *key = priv; 223 223 int data_len, i, blocks, last, len; 224 224 u8 *pos, *mic; 225 - struct ieee80211_hdr_4addr *hdr; 225 + struct ieee80211_hdr *hdr; 226 226 u8 *b0 = key->tx_b0; 227 227 u8 *b = key->tx_b; 228 228 u8 *e = key->tx_e; ··· 232 232 return -1; 233 233 234 234 data_len = skb->len - hdr_len; 235 - len = ieee80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv); 235 + len = lib80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv); 236 236 if (len < 0) 237 237 return -1; 238 238 239 239 pos = skb->data + hdr_len + CCMP_HDR_LEN; 240 240 mic = skb_put(skb, CCMP_MIC_LEN); 241 - hdr = (struct ieee80211_hdr_4addr *)skb->data; 241 + hdr = (struct ieee80211_hdr *)skb->data; 242 242 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); 243 243 244 244 blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); ··· 248 248 len = (i == blocks && last) ? last : AES_BLOCK_LEN; 249 249 /* Authentication */ 250 250 xor_block(b, pos, len); 251 - ieee80211_ccmp_aes_encrypt(key->tfm, b, b); 251 + lib80211_ccmp_aes_encrypt(key->tfm, b, b); 252 252 /* Encryption, with counter */ 253 253 b0[14] = (i >> 8) & 0xff; 254 254 b0[15] = i & 0xff; 255 - ieee80211_ccmp_aes_encrypt(key->tfm, b0, e); 255 + lib80211_ccmp_aes_encrypt(key->tfm, b0, e); 256 256 xor_block(pos, e, len); 257 257 pos += len; 258 258 } ··· 284 284 return 0; 285 285 } 286 286 287 - static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 287 + static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 288 288 { 289 - struct ieee80211_ccmp_data *key = priv; 289 + struct lib80211_ccmp_data *key = priv; 290 290 u8 keyidx, *pos; 291 - struct ieee80211_hdr_4addr *hdr; 291 + struct ieee80211_hdr *hdr; 292 292 u8 *b0 = key->rx_b0; 293 293 u8 *b = key->rx_b; 294 294 u8 *a = key->rx_a; ··· 302 302 return -1; 303 303 } 304 304 305 - hdr = (struct ieee80211_hdr_4addr *)skb->data; 305 + hdr = (struct ieee80211_hdr *)skb->data; 306 306 pos = skb->data + hdr_len; 307 307 keyidx = pos[3]; 308 308 if (!(keyidx & (1 << 5))) { ··· 337 337 pos += 8; 338 338 339 339 if (ccmp_replay_check(pn, key->rx_pn)) { 340 - if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) { 341 - IEEE80211_DEBUG_DROP("CCMP: replay detected: STA=%pM " 340 + if (net_ratelimit()) { 341 + printk(KERN_DEBUG "CCMP: replay detected: STA=%pM " 342 342 "previous PN %02x%02x%02x%02x%02x%02x " 343 343 "received PN %02x%02x%02x%02x%02x%02x\n", 344 344 hdr->addr2, ··· 361 361 /* Decrypt, with counter */ 362 362 b0[14] = (i >> 8) & 0xff; 363 363 b0[15] = i & 0xff; 364 - ieee80211_ccmp_aes_encrypt(key->tfm, b0, b); 364 + lib80211_ccmp_aes_encrypt(key->tfm, b0, b); 365 365 xor_block(pos, b, len); 366 366 /* Authentication */ 367 367 xor_block(a, pos, len); 368 - ieee80211_ccmp_aes_encrypt(key->tfm, a, a); 368 + lib80211_ccmp_aes_encrypt(key->tfm, a, a); 369 369 pos += len; 370 370 } 371 371 ··· 388 388 return keyidx; 389 389 } 390 390 391 - static int ieee80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv) 391 + static int lib80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv) 392 392 { 393 - struct ieee80211_ccmp_data *data = priv; 393 + struct lib80211_ccmp_data *data = priv; 394 394 int keyidx; 395 395 struct crypto_cipher *tfm = data->tfm; 396 396 ··· 418 418 return 0; 419 419 } 420 420 421 - static int ieee80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv) 421 + static int lib80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv) 422 422 { 423 - struct ieee80211_ccmp_data *data = priv; 423 + struct lib80211_ccmp_data *data = priv; 424 424 425 425 if (len < CCMP_TK_LEN) 426 426 return -1; ··· 441 441 return CCMP_TK_LEN; 442 442 } 443 443 444 - static char *ieee80211_ccmp_print_stats(char *p, void *priv) 444 + static char *lib80211_ccmp_print_stats(char *p, void *priv) 445 445 { 446 - struct ieee80211_ccmp_data *ccmp = priv; 446 + struct lib80211_ccmp_data *ccmp = priv; 447 447 448 448 p += sprintf(p, "key[%d] alg=CCMP key_set=%d " 449 449 "tx_pn=%02x%02x%02x%02x%02x%02x " ··· 461 461 return p; 462 462 } 463 463 464 - static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { 464 + static struct lib80211_crypto_ops lib80211_crypt_ccmp = { 465 465 .name = "CCMP", 466 - .init = ieee80211_ccmp_init, 467 - .deinit = ieee80211_ccmp_deinit, 468 - .build_iv = ieee80211_ccmp_hdr, 469 - .encrypt_mpdu = ieee80211_ccmp_encrypt, 470 - .decrypt_mpdu = ieee80211_ccmp_decrypt, 466 + .init = lib80211_ccmp_init, 467 + .deinit = lib80211_ccmp_deinit, 468 + .build_iv = lib80211_ccmp_hdr, 469 + .encrypt_mpdu = lib80211_ccmp_encrypt, 470 + .decrypt_mpdu = lib80211_ccmp_decrypt, 471 471 .encrypt_msdu = NULL, 472 472 .decrypt_msdu = NULL, 473 - .set_key = ieee80211_ccmp_set_key, 474 - .get_key = ieee80211_ccmp_get_key, 475 - .print_stats = ieee80211_ccmp_print_stats, 473 + .set_key = lib80211_ccmp_set_key, 474 + .get_key = lib80211_ccmp_get_key, 475 + .print_stats = lib80211_ccmp_print_stats, 476 476 .extra_mpdu_prefix_len = CCMP_HDR_LEN, 477 477 .extra_mpdu_postfix_len = CCMP_MIC_LEN, 478 478 .owner = THIS_MODULE, 479 479 }; 480 480 481 - static int __init ieee80211_crypto_ccmp_init(void) 481 + static int __init lib80211_crypto_ccmp_init(void) 482 482 { 483 - return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp); 483 + return lib80211_register_crypto_ops(&lib80211_crypt_ccmp); 484 484 } 485 485 486 - static void __exit ieee80211_crypto_ccmp_exit(void) 486 + static void __exit lib80211_crypto_ccmp_exit(void) 487 487 { 488 - ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp); 488 + lib80211_unregister_crypto_ops(&lib80211_crypt_ccmp); 489 489 } 490 490 491 - module_init(ieee80211_crypto_ccmp_init); 492 - module_exit(ieee80211_crypto_ccmp_exit); 491 + module_init(lib80211_crypto_ccmp_init); 492 + module_exit(lib80211_crypto_ccmp_exit);
+78 -76
net/ieee80211/ieee80211_crypt_tkip.c net/wireless/lib80211_crypt_tkip.c
··· 1 1 /* 2 - * Host AP crypt: host-based TKIP encryption implementation for Host AP driver 2 + * lib80211 crypt: host-based TKIP encryption implementation for lib80211 3 3 * 4 4 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi> 5 + * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com> 5 6 * 6 7 * This program is free software; you can redistribute it and/or modify 7 8 * it under the terms of the GNU General Public License version 2 as ··· 23 22 #include <linux/if_arp.h> 24 23 #include <asm/string.h> 25 24 26 - #include <net/ieee80211.h> 25 + #include <linux/wireless.h> 26 + #include <linux/ieee80211.h> 27 + #include <net/iw_handler.h> 27 28 28 29 #include <linux/crypto.h> 29 30 #include <linux/crc32.h> 30 31 32 + #include <net/lib80211.h> 33 + 31 34 MODULE_AUTHOR("Jouni Malinen"); 32 - MODULE_DESCRIPTION("Host AP crypt: TKIP"); 35 + MODULE_DESCRIPTION("lib80211 crypt: TKIP"); 33 36 MODULE_LICENSE("GPL"); 34 37 35 - struct ieee80211_tkip_data { 38 + struct lib80211_tkip_data { 36 39 #define TKIP_KEY_LEN 32 37 40 u8 key[TKIP_KEY_LEN]; 38 41 int key_set; ··· 70 65 unsigned long flags; 71 66 }; 72 67 73 - static unsigned long ieee80211_tkip_set_flags(unsigned long flags, void *priv) 68 + static unsigned long lib80211_tkip_set_flags(unsigned long flags, void *priv) 74 69 { 75 - struct ieee80211_tkip_data *_priv = priv; 70 + struct lib80211_tkip_data *_priv = priv; 76 71 unsigned long old_flags = _priv->flags; 77 72 _priv->flags = flags; 78 73 return old_flags; 79 74 } 80 75 81 - static unsigned long ieee80211_tkip_get_flags(void *priv) 76 + static unsigned long lib80211_tkip_get_flags(void *priv) 82 77 { 83 - struct ieee80211_tkip_data *_priv = priv; 78 + struct lib80211_tkip_data *_priv = priv; 84 79 return _priv->flags; 85 80 } 86 81 87 - static void *ieee80211_tkip_init(int key_idx) 82 + static void *lib80211_tkip_init(int key_idx) 88 83 { 89 - struct ieee80211_tkip_data *priv; 84 + struct lib80211_tkip_data *priv; 90 85 91 86 priv = kzalloc(sizeof(*priv), GFP_ATOMIC); 92 87 if (priv == NULL) ··· 97 92 priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, 98 93 CRYPTO_ALG_ASYNC); 99 94 if (IS_ERR(priv->tx_tfm_arc4)) { 100 - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 95 + printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate " 101 96 "crypto API arc4\n"); 102 97 priv->tx_tfm_arc4 = NULL; 103 98 goto fail; ··· 106 101 priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0, 107 102 CRYPTO_ALG_ASYNC); 108 103 if (IS_ERR(priv->tx_tfm_michael)) { 109 - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 104 + printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate " 110 105 "crypto API michael_mic\n"); 111 106 priv->tx_tfm_michael = NULL; 112 107 goto fail; ··· 115 110 priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, 116 111 CRYPTO_ALG_ASYNC); 117 112 if (IS_ERR(priv->rx_tfm_arc4)) { 118 - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 113 + printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate " 119 114 "crypto API arc4\n"); 120 115 priv->rx_tfm_arc4 = NULL; 121 116 goto fail; ··· 124 119 priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0, 125 120 CRYPTO_ALG_ASYNC); 126 121 if (IS_ERR(priv->rx_tfm_michael)) { 127 - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 122 + printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate " 128 123 "crypto API michael_mic\n"); 129 124 priv->rx_tfm_michael = NULL; 130 125 goto fail; ··· 148 143 return NULL; 149 144 } 150 145 151 - static void ieee80211_tkip_deinit(void *priv) 146 + static void lib80211_tkip_deinit(void *priv) 152 147 { 153 - struct ieee80211_tkip_data *_priv = priv; 148 + struct lib80211_tkip_data *_priv = priv; 154 149 if (_priv) { 155 150 if (_priv->tx_tfm_michael) 156 151 crypto_free_hash(_priv->tx_tfm_michael); ··· 310 305 #endif 311 306 } 312 307 313 - static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, 308 + static int lib80211_tkip_hdr(struct sk_buff *skb, int hdr_len, 314 309 u8 * rc4key, int keylen, void *priv) 315 310 { 316 - struct ieee80211_tkip_data *tkey = priv; 311 + struct lib80211_tkip_data *tkey = priv; 317 312 int len; 318 313 u8 *pos; 319 - struct ieee80211_hdr_4addr *hdr; 314 + struct ieee80211_hdr *hdr; 320 315 321 - hdr = (struct ieee80211_hdr_4addr *)skb->data; 316 + hdr = (struct ieee80211_hdr *)skb->data; 322 317 323 318 if (skb_headroom(skb) < 8 || skb->len < hdr_len) 324 319 return -1; ··· 356 351 return 8; 357 352 } 358 353 359 - static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 354 + static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 360 355 { 361 - struct ieee80211_tkip_data *tkey = priv; 356 + struct lib80211_tkip_data *tkey = priv; 362 357 struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 }; 363 358 int len; 364 359 u8 rc4key[16], *pos, *icv; ··· 367 362 368 363 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { 369 364 if (net_ratelimit()) { 370 - struct ieee80211_hdr_4addr *hdr = 371 - (struct ieee80211_hdr_4addr *)skb->data; 365 + struct ieee80211_hdr *hdr = 366 + (struct ieee80211_hdr *)skb->data; 372 367 printk(KERN_DEBUG ": TKIP countermeasures: dropped " 373 368 "TX packet to %pM\n", hdr->addr1); 374 369 } ··· 381 376 len = skb->len - hdr_len; 382 377 pos = skb->data + hdr_len; 383 378 384 - if ((ieee80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0) 379 + if ((lib80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0) 385 380 return -1; 386 381 387 382 icv = skb_put(skb, 4); ··· 410 405 return 0; 411 406 } 412 407 413 - static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 408 + static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 414 409 { 415 - struct ieee80211_tkip_data *tkey = priv; 410 + struct lib80211_tkip_data *tkey = priv; 416 411 struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 }; 417 412 u8 rc4key[16]; 418 413 u8 keyidx, *pos; 419 414 u32 iv32; 420 415 u16 iv16; 421 - struct ieee80211_hdr_4addr *hdr; 416 + struct ieee80211_hdr *hdr; 422 417 u8 icv[4]; 423 418 u32 crc; 424 419 struct scatterlist sg; 425 420 int plen; 426 421 427 - hdr = (struct ieee80211_hdr_4addr *)skb->data; 422 + hdr = (struct ieee80211_hdr *)skb->data; 428 423 429 424 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { 430 425 if (net_ratelimit()) { ··· 465 460 pos += 8; 466 461 467 462 if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { 468 - if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) { 469 - IEEE80211_DEBUG_DROP("TKIP: replay detected: STA=%pM" 463 + if (net_ratelimit()) { 464 + printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" 470 465 " previous TSC %08x%04x received TSC " 471 466 "%08x%04x\n", hdr->addr2, 472 467 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); ··· 505 500 * it needs to be recalculated for the next packet. */ 506 501 tkey->rx_phase1_done = 0; 507 502 } 508 - if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) { 509 - IEEE80211_DEBUG_DROP("TKIP: ICV error detected: STA=" 503 + if (net_ratelimit()) { 504 + printk(KERN_DEBUG "TKIP: ICV error detected: STA=" 510 505 "%pM\n", hdr->addr2); 511 506 } 512 507 tkey->dot11RSNAStatsTKIPICVErrors++; ··· 550 545 551 546 static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr) 552 547 { 553 - struct ieee80211_hdr_4addr *hdr11; 554 - u16 stype; 548 + struct ieee80211_hdr *hdr11; 555 549 556 - hdr11 = (struct ieee80211_hdr_4addr *)skb->data; 557 - stype = WLAN_FC_GET_STYPE(le16_to_cpu(hdr11->frame_ctl)); 550 + hdr11 = (struct ieee80211_hdr *)skb->data; 558 551 559 - switch (le16_to_cpu(hdr11->frame_ctl) & 552 + switch (le16_to_cpu(hdr11->frame_control) & 560 553 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { 561 554 case IEEE80211_FCTL_TODS: 562 555 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ ··· 574 571 break; 575 572 } 576 573 577 - if (stype & IEEE80211_STYPE_QOS_DATA) { 578 - const struct ieee80211_hdr_3addrqos *qoshdr = 579 - (struct ieee80211_hdr_3addrqos *)skb->data; 580 - hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID; 574 + if (ieee80211_is_data_qos(hdr11->frame_control)) { 575 + hdr[12] = le16_to_cpu(*ieee80211_get_qos_ctl(hdr11)) 576 + & IEEE80211_QOS_CTL_TID_MASK; 581 577 } else 582 578 hdr[12] = 0; /* priority */ 583 579 584 580 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ 585 581 } 586 582 587 - static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, 583 + static int lib80211_michael_mic_add(struct sk_buff *skb, int hdr_len, 588 584 void *priv) 589 585 { 590 - struct ieee80211_tkip_data *tkey = priv; 586 + struct lib80211_tkip_data *tkey = priv; 591 587 u8 *pos; 592 588 593 589 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { ··· 605 603 return 0; 606 604 } 607 605 608 - static void ieee80211_michael_mic_failure(struct net_device *dev, 609 - struct ieee80211_hdr_4addr *hdr, 606 + static void lib80211_michael_mic_failure(struct net_device *dev, 607 + struct ieee80211_hdr *hdr, 610 608 int keyidx) 611 609 { 612 610 union iwreq_data wrqu; ··· 626 624 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev); 627 625 } 628 626 629 - static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, 627 + static int lib80211_michael_mic_verify(struct sk_buff *skb, int keyidx, 630 628 int hdr_len, void *priv) 631 629 { 632 - struct ieee80211_tkip_data *tkey = priv; 630 + struct lib80211_tkip_data *tkey = priv; 633 631 u8 mic[8]; 634 632 635 633 if (!tkey->key_set) ··· 640 638 skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) 641 639 return -1; 642 640 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { 643 - struct ieee80211_hdr_4addr *hdr; 644 - hdr = (struct ieee80211_hdr_4addr *)skb->data; 641 + struct ieee80211_hdr *hdr; 642 + hdr = (struct ieee80211_hdr *)skb->data; 645 643 printk(KERN_DEBUG "%s: Michael MIC verification failed for " 646 644 "MSDU from %pM keyidx=%d\n", 647 645 skb->dev ? skb->dev->name : "N/A", hdr->addr2, 648 646 keyidx); 649 647 if (skb->dev) 650 - ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); 648 + lib80211_michael_mic_failure(skb->dev, hdr, keyidx); 651 649 tkey->dot11RSNAStatsTKIPLocalMICFailures++; 652 650 return -1; 653 651 } ··· 662 660 return 0; 663 661 } 664 662 665 - static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv) 663 + static int lib80211_tkip_set_key(void *key, int len, u8 * seq, void *priv) 666 664 { 667 - struct ieee80211_tkip_data *tkey = priv; 665 + struct lib80211_tkip_data *tkey = priv; 668 666 int keyidx; 669 667 struct crypto_hash *tfm = tkey->tx_tfm_michael; 670 668 struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4; ··· 695 693 return 0; 696 694 } 697 695 698 - static int ieee80211_tkip_get_key(void *key, int len, u8 * seq, void *priv) 696 + static int lib80211_tkip_get_key(void *key, int len, u8 * seq, void *priv) 699 697 { 700 - struct ieee80211_tkip_data *tkey = priv; 698 + struct lib80211_tkip_data *tkey = priv; 701 699 702 700 if (len < TKIP_KEY_LEN) 703 701 return -1; ··· 724 722 return TKIP_KEY_LEN; 725 723 } 726 724 727 - static char *ieee80211_tkip_print_stats(char *p, void *priv) 725 + static char *lib80211_tkip_print_stats(char *p, void *priv) 728 726 { 729 - struct ieee80211_tkip_data *tkip = priv; 727 + struct lib80211_tkip_data *tkip = priv; 730 728 p += sprintf(p, "key[%d] alg=TKIP key_set=%d " 731 729 "tx_pn=%02x%02x%02x%02x%02x%02x " 732 730 "rx_pn=%02x%02x%02x%02x%02x%02x " ··· 750 748 return p; 751 749 } 752 750 753 - static struct ieee80211_crypto_ops ieee80211_crypt_tkip = { 751 + static struct lib80211_crypto_ops lib80211_crypt_tkip = { 754 752 .name = "TKIP", 755 - .init = ieee80211_tkip_init, 756 - .deinit = ieee80211_tkip_deinit, 757 - .build_iv = ieee80211_tkip_hdr, 758 - .encrypt_mpdu = ieee80211_tkip_encrypt, 759 - .decrypt_mpdu = ieee80211_tkip_decrypt, 760 - .encrypt_msdu = ieee80211_michael_mic_add, 761 - .decrypt_msdu = ieee80211_michael_mic_verify, 762 - .set_key = ieee80211_tkip_set_key, 763 - .get_key = ieee80211_tkip_get_key, 764 - .print_stats = ieee80211_tkip_print_stats, 753 + .init = lib80211_tkip_init, 754 + .deinit = lib80211_tkip_deinit, 755 + .build_iv = lib80211_tkip_hdr, 756 + .encrypt_mpdu = lib80211_tkip_encrypt, 757 + .decrypt_mpdu = lib80211_tkip_decrypt, 758 + .encrypt_msdu = lib80211_michael_mic_add, 759 + .decrypt_msdu = lib80211_michael_mic_verify, 760 + .set_key = lib80211_tkip_set_key, 761 + .get_key = lib80211_tkip_get_key, 762 + .print_stats = lib80211_tkip_print_stats, 765 763 .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */ 766 764 .extra_mpdu_postfix_len = 4, /* ICV */ 767 765 .extra_msdu_postfix_len = 8, /* MIC */ 768 - .get_flags = ieee80211_tkip_get_flags, 769 - .set_flags = ieee80211_tkip_set_flags, 766 + .get_flags = lib80211_tkip_get_flags, 767 + .set_flags = lib80211_tkip_set_flags, 770 768 .owner = THIS_MODULE, 771 769 }; 772 770 773 - static int __init ieee80211_crypto_tkip_init(void) 771 + static int __init lib80211_crypto_tkip_init(void) 774 772 { 775 - return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip); 773 + return lib80211_register_crypto_ops(&lib80211_crypt_tkip); 776 774 } 777 775 778 - static void __exit ieee80211_crypto_tkip_exit(void) 776 + static void __exit lib80211_crypto_tkip_exit(void) 779 777 { 780 - ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip); 778 + lib80211_unregister_crypto_ops(&lib80211_crypt_tkip); 781 779 } 782 780 783 - module_init(ieee80211_crypto_tkip_init); 784 - module_exit(ieee80211_crypto_tkip_exit); 781 + module_init(lib80211_crypto_tkip_init); 782 + module_exit(lib80211_crypto_tkip_exit);
+40 -39
net/ieee80211/ieee80211_crypt_wep.c net/wireless/lib80211_crypt_wep.c
··· 1 1 /* 2 - * Host AP crypt: host-based WEP encryption implementation for Host AP driver 2 + * lib80211 crypt: host-based WEP encryption implementation for lib80211 3 3 * 4 4 * Copyright (c) 2002-2004, Jouni Malinen <j@w1.fi> 5 + * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com> 5 6 * 6 7 * This program is free software; you can redistribute it and/or modify 7 8 * it under the terms of the GNU General Public License version 2 as ··· 20 19 #include <linux/mm.h> 21 20 #include <asm/string.h> 22 21 23 - #include <net/ieee80211.h> 22 + #include <net/lib80211.h> 24 23 25 24 #include <linux/crypto.h> 26 25 #include <linux/crc32.h> 27 26 28 27 MODULE_AUTHOR("Jouni Malinen"); 29 - MODULE_DESCRIPTION("Host AP crypt: WEP"); 28 + MODULE_DESCRIPTION("lib80211 crypt: WEP"); 30 29 MODULE_LICENSE("GPL"); 31 30 32 - struct prism2_wep_data { 31 + struct lib80211_wep_data { 33 32 u32 iv; 34 33 #define WEP_KEY_LEN 13 35 34 u8 key[WEP_KEY_LEN + 1]; ··· 39 38 struct crypto_blkcipher *rx_tfm; 40 39 }; 41 40 42 - static void *prism2_wep_init(int keyidx) 41 + static void *lib80211_wep_init(int keyidx) 43 42 { 44 - struct prism2_wep_data *priv; 43 + struct lib80211_wep_data *priv; 45 44 46 45 priv = kzalloc(sizeof(*priv), GFP_ATOMIC); 47 46 if (priv == NULL) ··· 50 49 51 50 priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); 52 51 if (IS_ERR(priv->tx_tfm)) { 53 - printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " 52 + printk(KERN_DEBUG "lib80211_crypt_wep: could not allocate " 54 53 "crypto API arc4\n"); 55 54 priv->tx_tfm = NULL; 56 55 goto fail; ··· 58 57 59 58 priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); 60 59 if (IS_ERR(priv->rx_tfm)) { 61 - printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " 60 + printk(KERN_DEBUG "lib80211_crypt_wep: could not allocate " 62 61 "crypto API arc4\n"); 63 62 priv->rx_tfm = NULL; 64 63 goto fail; ··· 79 78 return NULL; 80 79 } 81 80 82 - static void prism2_wep_deinit(void *priv) 81 + static void lib80211_wep_deinit(void *priv) 83 82 { 84 - struct prism2_wep_data *_priv = priv; 83 + struct lib80211_wep_data *_priv = priv; 85 84 if (_priv) { 86 85 if (_priv->tx_tfm) 87 86 crypto_free_blkcipher(_priv->tx_tfm); ··· 92 91 } 93 92 94 93 /* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */ 95 - static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len, 94 + static int lib80211_wep_build_iv(struct sk_buff *skb, int hdr_len, 96 95 u8 *key, int keylen, void *priv) 97 96 { 98 - struct prism2_wep_data *wep = priv; 97 + struct lib80211_wep_data *wep = priv; 99 98 u32 klen, len; 100 99 u8 *pos; 101 100 ··· 135 134 * 136 135 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) 137 136 */ 138 - static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 137 + static int lib80211_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 139 138 { 140 - struct prism2_wep_data *wep = priv; 139 + struct lib80211_wep_data *wep = priv; 141 140 struct blkcipher_desc desc = { .tfm = wep->tx_tfm }; 142 141 u32 crc, klen, len; 143 142 u8 *pos, *icv; 144 143 struct scatterlist sg; 145 144 u8 key[WEP_KEY_LEN + 3]; 146 145 147 - /* other checks are in prism2_wep_build_iv */ 146 + /* other checks are in lib80211_wep_build_iv */ 148 147 if (skb_tailroom(skb) < 4) 149 148 return -1; 150 149 151 150 /* add the IV to the frame */ 152 - if (prism2_wep_build_iv(skb, hdr_len, NULL, 0, priv)) 151 + if (lib80211_wep_build_iv(skb, hdr_len, NULL, 0, priv)) 153 152 return -1; 154 153 155 154 /* Copy the IV into the first 3 bytes of the key */ ··· 182 181 * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on 183 182 * failure. If frame is OK, IV and ICV will be removed. 184 183 */ 185 - static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 184 + static int lib80211_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 186 185 { 187 - struct prism2_wep_data *wep = priv; 186 + struct lib80211_wep_data *wep = priv; 188 187 struct blkcipher_desc desc = { .tfm = wep->rx_tfm }; 189 188 u32 crc, klen, plen; 190 189 u8 key[WEP_KEY_LEN + 3]; ··· 233 232 return 0; 234 233 } 235 234 236 - static int prism2_wep_set_key(void *key, int len, u8 * seq, void *priv) 235 + static int lib80211_wep_set_key(void *key, int len, u8 * seq, void *priv) 237 236 { 238 - struct prism2_wep_data *wep = priv; 237 + struct lib80211_wep_data *wep = priv; 239 238 240 239 if (len < 0 || len > WEP_KEY_LEN) 241 240 return -1; ··· 246 245 return 0; 247 246 } 248 247 249 - static int prism2_wep_get_key(void *key, int len, u8 * seq, void *priv) 248 + static int lib80211_wep_get_key(void *key, int len, u8 * seq, void *priv) 250 249 { 251 - struct prism2_wep_data *wep = priv; 250 + struct lib80211_wep_data *wep = priv; 252 251 253 252 if (len < wep->key_len) 254 253 return -1; ··· 258 257 return wep->key_len; 259 258 } 260 259 261 - static char *prism2_wep_print_stats(char *p, void *priv) 260 + static char *lib80211_wep_print_stats(char *p, void *priv) 262 261 { 263 - struct prism2_wep_data *wep = priv; 262 + struct lib80211_wep_data *wep = priv; 264 263 p += sprintf(p, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len); 265 264 return p; 266 265 } 267 266 268 - static struct ieee80211_crypto_ops ieee80211_crypt_wep = { 267 + static struct lib80211_crypto_ops lib80211_crypt_wep = { 269 268 .name = "WEP", 270 - .init = prism2_wep_init, 271 - .deinit = prism2_wep_deinit, 272 - .build_iv = prism2_wep_build_iv, 273 - .encrypt_mpdu = prism2_wep_encrypt, 274 - .decrypt_mpdu = prism2_wep_decrypt, 269 + .init = lib80211_wep_init, 270 + .deinit = lib80211_wep_deinit, 271 + .build_iv = lib80211_wep_build_iv, 272 + .encrypt_mpdu = lib80211_wep_encrypt, 273 + .decrypt_mpdu = lib80211_wep_decrypt, 275 274 .encrypt_msdu = NULL, 276 275 .decrypt_msdu = NULL, 277 - .set_key = prism2_wep_set_key, 278 - .get_key = prism2_wep_get_key, 279 - .print_stats = prism2_wep_print_stats, 276 + .set_key = lib80211_wep_set_key, 277 + .get_key = lib80211_wep_get_key, 278 + .print_stats = lib80211_wep_print_stats, 280 279 .extra_mpdu_prefix_len = 4, /* IV */ 281 280 .extra_mpdu_postfix_len = 4, /* ICV */ 282 281 .owner = THIS_MODULE, 283 282 }; 284 283 285 - static int __init ieee80211_crypto_wep_init(void) 284 + static int __init lib80211_crypto_wep_init(void) 286 285 { 287 - return ieee80211_register_crypto_ops(&ieee80211_crypt_wep); 286 + return lib80211_register_crypto_ops(&lib80211_crypt_wep); 288 287 } 289 288 290 - static void __exit ieee80211_crypto_wep_exit(void) 289 + static void __exit lib80211_crypto_wep_exit(void) 291 290 { 292 - ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep); 291 + lib80211_unregister_crypto_ops(&lib80211_crypt_wep); 293 292 } 294 293 295 - module_init(ieee80211_crypto_wep_init); 296 - module_exit(ieee80211_crypto_wep_exit); 294 + module_init(lib80211_crypto_wep_init); 295 + module_exit(lib80211_crypto_wep_exit);
+13 -10
net/ieee80211/ieee80211_module.c
··· 180 180 ieee->host_open_frag = 1; 181 181 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ 182 182 183 - INIT_LIST_HEAD(&ieee->crypt_deinit_list); 184 - setup_timer(&ieee->crypt_deinit_timer, ieee80211_crypt_deinit_handler, 185 - (unsigned long)ieee); 186 - ieee->crypt_quiesced = 0; 187 - 188 183 spin_lock_init(&ieee->lock); 184 + 185 + ieee->crypt_info.name = dev->name; 186 + ieee->crypt_info.lock = &ieee->lock; 187 + INIT_LIST_HEAD(&ieee->crypt_info.crypt_deinit_list); 188 + setup_timer(&ieee->crypt_info.crypt_deinit_timer, 189 + lib80211_crypt_deinit_handler, 190 + (unsigned long)&ieee->crypt_info); 191 + ieee->crypt_info.crypt_quiesced = 0; 189 192 190 193 ieee->wpa_enabled = 0; 191 194 ieee->drop_unencrypted = 0; ··· 208 205 209 206 int i; 210 207 211 - ieee80211_crypt_quiescing(ieee); 212 - del_timer_sync(&ieee->crypt_deinit_timer); 213 - ieee80211_crypt_deinit_entries(ieee, 1); 208 + lib80211_crypt_quiescing(&ieee->crypt_info); 209 + del_timer_sync(&ieee->crypt_info.crypt_deinit_timer); 210 + lib80211_crypt_deinit_entries(&ieee->crypt_info, 1); 214 211 215 212 for (i = 0; i < WEP_KEYS; i++) { 216 - struct ieee80211_crypt_data *crypt = ieee->crypt[i]; 213 + struct lib80211_crypt_data *crypt = ieee->crypt_info.crypt[i]; 217 214 if (crypt) { 218 215 if (crypt->ops) { 219 216 crypt->ops->deinit(crypt->priv); 220 217 module_put(crypt->ops->owner); 221 218 } 222 219 kfree(crypt); 223 - ieee->crypt[i] = NULL; 220 + ieee->crypt_info.crypt[i] = NULL; 224 221 } 225 222 } 226 223
+4 -4
net/ieee80211/ieee80211_rx.c
··· 268 268 /* Called only as a tasklet (software IRQ), by ieee80211_rx */ 269 269 static int 270 270 ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, 271 - struct ieee80211_crypt_data *crypt) 271 + struct lib80211_crypt_data *crypt) 272 272 { 273 273 struct ieee80211_hdr_3addr *hdr; 274 274 int res, hdrlen; ··· 300 300 static int 301 301 ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, 302 302 struct sk_buff *skb, int keyidx, 303 - struct ieee80211_crypt_data *crypt) 303 + struct lib80211_crypt_data *crypt) 304 304 { 305 305 struct ieee80211_hdr_3addr *hdr; 306 306 int res, hdrlen; ··· 348 348 #endif 349 349 u8 dst[ETH_ALEN]; 350 350 u8 src[ETH_ALEN]; 351 - struct ieee80211_crypt_data *crypt = NULL; 351 + struct lib80211_crypt_data *crypt = NULL; 352 352 int keyidx = 0; 353 353 int can_be_decrypted = 0; 354 354 ··· 431 431 * is only allowed 2-bits of storage, no value of keyidx can 432 432 * be provided via above code that would result in keyidx 433 433 * being out of range */ 434 - crypt = ieee->crypt[keyidx]; 434 + crypt = ieee->crypt_info.crypt[keyidx]; 435 435 436 436 #ifdef NOT_YET 437 437 sta = NULL;
+4 -3
net/ieee80211/ieee80211_tx.c
··· 152 152 static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee, 153 153 struct sk_buff *frag, int hdr_len) 154 154 { 155 - struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx]; 155 + struct lib80211_crypt_data *crypt = 156 + ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; 156 157 int res; 157 158 158 159 if (crypt == NULL) ··· 271 270 .qos_ctl = 0 272 271 }; 273 272 u8 dest[ETH_ALEN], src[ETH_ALEN]; 274 - struct ieee80211_crypt_data *crypt; 273 + struct lib80211_crypt_data *crypt; 275 274 int priority = skb->priority; 276 275 int snapped = 0; 277 276 ··· 295 294 296 295 ether_type = ((struct ethhdr *)skb->data)->h_proto; 297 296 298 - crypt = ieee->crypt[ieee->tx_keyidx]; 297 + crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; 299 298 300 299 encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) && 301 300 ieee->sec.encrypt;
+34 -34
net/ieee80211/ieee80211_wx.c
··· 307 307 .flags = 0 308 308 }; 309 309 int i, key, key_provided, len; 310 - struct ieee80211_crypt_data **crypt; 310 + struct lib80211_crypt_data **crypt; 311 311 int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv; 312 312 DECLARE_SSID_BUF(ssid); 313 313 ··· 321 321 key_provided = 1; 322 322 } else { 323 323 key_provided = 0; 324 - key = ieee->tx_keyidx; 324 + key = ieee->crypt_info.tx_keyidx; 325 325 } 326 326 327 327 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ? 328 328 "provided" : "default"); 329 329 330 - crypt = &ieee->crypt[key]; 330 + crypt = &ieee->crypt_info.crypt[key]; 331 331 332 332 if (erq->flags & IW_ENCODE_DISABLED) { 333 333 if (key_provided && *crypt) { 334 334 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n", 335 335 key); 336 - ieee80211_crypt_delayed_deinit(ieee, crypt); 336 + lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt); 337 337 } else 338 338 IEEE80211_DEBUG_WX("Disabling encryption.\n"); 339 339 340 340 /* Check all the keys to see if any are still configured, 341 341 * and if no key index was provided, de-init them all */ 342 342 for (i = 0; i < WEP_KEYS; i++) { 343 - if (ieee->crypt[i] != NULL) { 343 + if (ieee->crypt_info.crypt[i] != NULL) { 344 344 if (key_provided) 345 345 break; 346 - ieee80211_crypt_delayed_deinit(ieee, 347 - &ieee->crypt[i]); 346 + lib80211_crypt_delayed_deinit(&ieee->crypt_info, 347 + &ieee->crypt_info.crypt[i]); 348 348 } 349 349 } 350 350 ··· 366 366 strcmp((*crypt)->ops->name, "WEP") != 0) { 367 367 /* changing to use WEP; deinit previously used algorithm 368 368 * on this key */ 369 - ieee80211_crypt_delayed_deinit(ieee, crypt); 369 + lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt); 370 370 } 371 371 372 372 if (*crypt == NULL && host_crypto) { 373 - struct ieee80211_crypt_data *new_crypt; 373 + struct lib80211_crypt_data *new_crypt; 374 374 375 375 /* take WEP into use */ 376 - new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), 376 + new_crypt = kzalloc(sizeof(struct lib80211_crypt_data), 377 377 GFP_KERNEL); 378 378 if (new_crypt == NULL) 379 379 return -ENOMEM; 380 - new_crypt->ops = ieee80211_get_crypto_ops("WEP"); 380 + new_crypt->ops = lib80211_get_crypto_ops("WEP"); 381 381 if (!new_crypt->ops) { 382 - request_module("ieee80211_crypt_wep"); 383 - new_crypt->ops = ieee80211_get_crypto_ops("WEP"); 382 + request_module("lib80211_crypt_wep"); 383 + new_crypt->ops = lib80211_get_crypto_ops("WEP"); 384 384 } 385 385 386 386 if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) ··· 391 391 new_crypt = NULL; 392 392 393 393 printk(KERN_WARNING "%s: could not initialize WEP: " 394 - "load module ieee80211_crypt_wep\n", dev->name); 394 + "load module lib80211_crypt_wep\n", dev->name); 395 395 return -EOPNOTSUPP; 396 396 } 397 397 *crypt = new_crypt; ··· 440 440 if (key_provided) { 441 441 IEEE80211_DEBUG_WX("Setting key %d to default Tx " 442 442 "key.\n", key); 443 - ieee->tx_keyidx = key; 443 + ieee->crypt_info.tx_keyidx = key; 444 444 sec.active_key = key; 445 445 sec.flags |= SEC_ACTIVE_KEY; 446 446 } ··· 485 485 { 486 486 struct iw_point *erq = &(wrqu->encoding); 487 487 int len, key; 488 - struct ieee80211_crypt_data *crypt; 488 + struct lib80211_crypt_data *crypt; 489 489 struct ieee80211_security *sec = &ieee->sec; 490 490 491 491 IEEE80211_DEBUG_WX("GET_ENCODE\n"); ··· 496 496 return -EINVAL; 497 497 key--; 498 498 } else 499 - key = ieee->tx_keyidx; 499 + key = ieee->crypt_info.tx_keyidx; 500 500 501 - crypt = ieee->crypt[key]; 501 + crypt = ieee->crypt_info.crypt[key]; 502 502 erq->flags = key + 1; 503 503 504 504 if (!sec->enabled) { ··· 531 531 int i, idx, ret = 0; 532 532 int group_key = 0; 533 533 const char *alg, *module; 534 - struct ieee80211_crypto_ops *ops; 535 - struct ieee80211_crypt_data **crypt; 534 + struct lib80211_crypto_ops *ops; 535 + struct lib80211_crypt_data **crypt; 536 536 537 537 struct ieee80211_security sec = { 538 538 .flags = 0, ··· 544 544 return -EINVAL; 545 545 idx--; 546 546 } else 547 - idx = ieee->tx_keyidx; 547 + idx = ieee->crypt_info.tx_keyidx; 548 548 549 549 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { 550 - crypt = &ieee->crypt[idx]; 550 + crypt = &ieee->crypt_info.crypt[idx]; 551 551 group_key = 1; 552 552 } else { 553 553 /* some Cisco APs use idx>0 for unicast in dynamic WEP */ 554 554 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP) 555 555 return -EINVAL; 556 556 if (ieee->iw_mode == IW_MODE_INFRA) 557 - crypt = &ieee->crypt[idx]; 557 + crypt = &ieee->crypt_info.crypt[idx]; 558 558 else 559 559 return -EINVAL; 560 560 } ··· 563 563 if ((encoding->flags & IW_ENCODE_DISABLED) || 564 564 ext->alg == IW_ENCODE_ALG_NONE) { 565 565 if (*crypt) 566 - ieee80211_crypt_delayed_deinit(ieee, crypt); 566 + lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt); 567 567 568 568 for (i = 0; i < WEP_KEYS; i++) 569 - if (ieee->crypt[i] != NULL) 569 + if (ieee->crypt_info.crypt[i] != NULL) 570 570 break; 571 571 572 572 if (i == WEP_KEYS) { ··· 589 589 switch (ext->alg) { 590 590 case IW_ENCODE_ALG_WEP: 591 591 alg = "WEP"; 592 - module = "ieee80211_crypt_wep"; 592 + module = "lib80211_crypt_wep"; 593 593 break; 594 594 case IW_ENCODE_ALG_TKIP: 595 595 alg = "TKIP"; 596 - module = "ieee80211_crypt_tkip"; 596 + module = "lib80211_crypt_tkip"; 597 597 break; 598 598 case IW_ENCODE_ALG_CCMP: 599 599 alg = "CCMP"; 600 - module = "ieee80211_crypt_ccmp"; 600 + module = "lib80211_crypt_ccmp"; 601 601 break; 602 602 default: 603 603 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", ··· 606 606 goto done; 607 607 } 608 608 609 - ops = ieee80211_get_crypto_ops(alg); 609 + ops = lib80211_get_crypto_ops(alg); 610 610 if (ops == NULL) { 611 611 request_module(module); 612 - ops = ieee80211_get_crypto_ops(alg); 612 + ops = lib80211_get_crypto_ops(alg); 613 613 } 614 614 if (ops == NULL) { 615 615 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", ··· 619 619 } 620 620 621 621 if (*crypt == NULL || (*crypt)->ops != ops) { 622 - struct ieee80211_crypt_data *new_crypt; 622 + struct lib80211_crypt_data *new_crypt; 623 623 624 - ieee80211_crypt_delayed_deinit(ieee, crypt); 624 + lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt); 625 625 626 626 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); 627 627 if (new_crypt == NULL) { ··· 649 649 650 650 skip_host_crypt: 651 651 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { 652 - ieee->tx_keyidx = idx; 652 + ieee->crypt_info.tx_keyidx = idx; 653 653 sec.active_key = idx; 654 654 sec.flags |= SEC_ACTIVE_KEY; 655 655 } ··· 715 715 return -EINVAL; 716 716 idx--; 717 717 } else 718 - idx = ieee->tx_keyidx; 718 + idx = ieee->crypt_info.tx_keyidx; 719 719 720 720 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && 721 721 ext->alg != IW_ENCODE_ALG_WEP)
+9
net/wireless/Kconfig
··· 82 82 83 83 Drivers should select this themselves if needed. Say Y if 84 84 you want this built into your kernel. 85 + 86 + config LIB80211_CRYPT_WEP 87 + tristate 88 + 89 + config LIB80211_CRYPT_CCMP 90 + tristate 91 + 92 + config LIB80211_CRYPT_TKIP 93 + tristate
+3
net/wireless/Makefile
··· 1 1 obj-$(CONFIG_WIRELESS_EXT) += wext.o 2 2 obj-$(CONFIG_CFG80211) += cfg80211.o 3 3 obj-$(CONFIG_LIB80211) += lib80211.o 4 + obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o 5 + obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o 6 + obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o 4 7 5 8 cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o 6 9 cfg80211-$(CONFIG_NL80211) += nl80211.o
+186 -5
net/wireless/lib80211.c
··· 3 3 * 4 4 * Copyright(c) 2008 John W. Linville <linville@tuxdriver.com> 5 5 * 6 + * Portions copied from old ieee80211 component, w/ original copyright 7 + * notices below: 8 + * 9 + * Host AP crypto routines 10 + * 11 + * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi> 12 + * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com> 13 + * 6 14 */ 7 15 8 16 #include <linux/module.h> 9 17 #include <linux/ctype.h> 10 18 #include <linux/ieee80211.h> 19 + #include <linux/errno.h> 20 + #include <linux/init.h> 21 + #include <linux/slab.h> 22 + #include <linux/string.h> 11 23 12 24 #include <net/lib80211.h> 13 25 ··· 30 18 MODULE_DESCRIPTION(DRV_DESCRIPTION); 31 19 MODULE_AUTHOR("John W. Linville <linville@tuxdriver.com>"); 32 20 MODULE_LICENSE("GPL"); 21 + 22 + struct lib80211_crypto_alg { 23 + struct list_head list; 24 + struct lib80211_crypto_ops *ops; 25 + }; 26 + 27 + static LIST_HEAD(lib80211_crypto_algs); 28 + static DEFINE_SPINLOCK(lib80211_crypto_lock); 33 29 34 30 const char *print_ssid(char *buf, const char *ssid, u8 ssid_len) 35 31 { ··· 71 51 } 72 52 EXPORT_SYMBOL(print_ssid); 73 53 74 - static int __init ieee80211_init(void) 54 + void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force) 75 55 { 76 - printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION "\n"); 56 + struct lib80211_crypt_data *entry, *next; 57 + unsigned long flags; 58 + 59 + spin_lock_irqsave(info->lock, flags); 60 + list_for_each_entry_safe(entry, next, &info->crypt_deinit_list, list) { 61 + if (atomic_read(&entry->refcnt) != 0 && !force) 62 + continue; 63 + 64 + list_del(&entry->list); 65 + 66 + if (entry->ops) { 67 + entry->ops->deinit(entry->priv); 68 + module_put(entry->ops->owner); 69 + } 70 + kfree(entry); 71 + } 72 + spin_unlock_irqrestore(info->lock, flags); 73 + } 74 + EXPORT_SYMBOL(lib80211_crypt_deinit_entries); 75 + 76 + /* After this, crypt_deinit_list won't accept new members */ 77 + void lib80211_crypt_quiescing(struct lib80211_crypt_info *info) 78 + { 79 + unsigned long flags; 80 + 81 + spin_lock_irqsave(info->lock, flags); 82 + info->crypt_quiesced = 1; 83 + spin_unlock_irqrestore(info->lock, flags); 84 + } 85 + EXPORT_SYMBOL(lib80211_crypt_quiescing); 86 + 87 + void lib80211_crypt_deinit_handler(unsigned long data) 88 + { 89 + struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data; 90 + unsigned long flags; 91 + 92 + lib80211_crypt_deinit_entries(info, 0); 93 + 94 + spin_lock_irqsave(info->lock, flags); 95 + if (!list_empty(&info->crypt_deinit_list) && !info->crypt_quiesced) { 96 + printk(KERN_DEBUG "%s: entries remaining in delayed crypt " 97 + "deletion list\n", info->name); 98 + info->crypt_deinit_timer.expires = jiffies + HZ; 99 + add_timer(&info->crypt_deinit_timer); 100 + } 101 + spin_unlock_irqrestore(info->lock, flags); 102 + } 103 + EXPORT_SYMBOL(lib80211_crypt_deinit_handler); 104 + 105 + void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info, 106 + struct lib80211_crypt_data **crypt) 107 + { 108 + struct lib80211_crypt_data *tmp; 109 + unsigned long flags; 110 + 111 + if (*crypt == NULL) 112 + return; 113 + 114 + tmp = *crypt; 115 + *crypt = NULL; 116 + 117 + /* must not run ops->deinit() while there may be pending encrypt or 118 + * decrypt operations. Use a list of delayed deinits to avoid needing 119 + * locking. */ 120 + 121 + spin_lock_irqsave(info->lock, flags); 122 + if (!info->crypt_quiesced) { 123 + list_add(&tmp->list, &info->crypt_deinit_list); 124 + if (!timer_pending(&info->crypt_deinit_timer)) { 125 + info->crypt_deinit_timer.expires = jiffies + HZ; 126 + add_timer(&info->crypt_deinit_timer); 127 + } 128 + } 129 + spin_unlock_irqrestore(info->lock, flags); 130 + } 131 + EXPORT_SYMBOL(lib80211_crypt_delayed_deinit); 132 + 133 + int lib80211_register_crypto_ops(struct lib80211_crypto_ops *ops) 134 + { 135 + unsigned long flags; 136 + struct lib80211_crypto_alg *alg; 137 + 138 + alg = kzalloc(sizeof(*alg), GFP_KERNEL); 139 + if (alg == NULL) 140 + return -ENOMEM; 141 + 142 + alg->ops = ops; 143 + 144 + spin_lock_irqsave(&lib80211_crypto_lock, flags); 145 + list_add(&alg->list, &lib80211_crypto_algs); 146 + spin_unlock_irqrestore(&lib80211_crypto_lock, flags); 147 + 148 + printk(KERN_DEBUG "lib80211_crypt: registered algorithm '%s'\n", 149 + ops->name); 150 + 77 151 return 0; 78 152 } 153 + EXPORT_SYMBOL(lib80211_register_crypto_ops); 79 154 80 - static void __exit ieee80211_exit(void) 155 + int lib80211_unregister_crypto_ops(struct lib80211_crypto_ops *ops) 156 + { 157 + struct lib80211_crypto_alg *alg; 158 + unsigned long flags; 159 + 160 + spin_lock_irqsave(&lib80211_crypto_lock, flags); 161 + list_for_each_entry(alg, &lib80211_crypto_algs, list) { 162 + if (alg->ops == ops) 163 + goto found; 164 + } 165 + spin_unlock_irqrestore(&lib80211_crypto_lock, flags); 166 + return -EINVAL; 167 + 168 + found: 169 + printk(KERN_DEBUG "lib80211_crypt: unregistered algorithm " 170 + "'%s'\n", ops->name); 171 + list_del(&alg->list); 172 + spin_unlock_irqrestore(&lib80211_crypto_lock, flags); 173 + kfree(alg); 174 + return 0; 175 + } 176 + EXPORT_SYMBOL(lib80211_unregister_crypto_ops); 177 + 178 + struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name) 179 + { 180 + struct lib80211_crypto_alg *alg; 181 + unsigned long flags; 182 + 183 + spin_lock_irqsave(&lib80211_crypto_lock, flags); 184 + list_for_each_entry(alg, &lib80211_crypto_algs, list) { 185 + if (strcmp(alg->ops->name, name) == 0) 186 + goto found; 187 + } 188 + spin_unlock_irqrestore(&lib80211_crypto_lock, flags); 189 + return NULL; 190 + 191 + found: 192 + spin_unlock_irqrestore(&lib80211_crypto_lock, flags); 193 + return alg->ops; 194 + } 195 + EXPORT_SYMBOL(lib80211_get_crypto_ops); 196 + 197 + static void *lib80211_crypt_null_init(int keyidx) 198 + { 199 + return (void *)1; 200 + } 201 + 202 + static void lib80211_crypt_null_deinit(void *priv) 81 203 { 82 204 } 83 205 84 - module_init(ieee80211_init); 85 - module_exit(ieee80211_exit); 206 + static struct lib80211_crypto_ops lib80211_crypt_null = { 207 + .name = "NULL", 208 + .init = lib80211_crypt_null_init, 209 + .deinit = lib80211_crypt_null_deinit, 210 + .owner = THIS_MODULE, 211 + }; 212 + 213 + static int __init lib80211_init(void) 214 + { 215 + printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION "\n"); 216 + return lib80211_register_crypto_ops(&lib80211_crypt_null); 217 + } 218 + 219 + static void __exit lib80211_exit(void) 220 + { 221 + lib80211_unregister_crypto_ops(&lib80211_crypt_null); 222 + BUG_ON(!list_empty(&lib80211_crypto_algs)); 223 + } 224 + 225 + module_init(lib80211_init); 226 + module_exit(lib80211_exit);