You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'staging-3.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver fixes from Greg KH: "Here are a few staging driver fixes for issues that have been reported for 3.15-rc2. Also dominating the diffstat for the pull request is the removal of the rtl8187se driver. It's no longer needed in staging as a "real" driver for this hardware is now merged in the tree in the "correct" location in drivers/net/ All of these patches have been tested in linux-next" * tag 'staging-3.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: staging: r8188eu: Fix case where ethtype was never obtained and always be checked against 0 staging: r8712u: Fix case where ethtype was never obtained and always be checked against 0 staging: r8188eu: Calling rtw_get_stainfo() with a NULL sta_addr will return NULL staging: comedi: fix circular locking dependency in comedi_mmap() staging: r8723au: Add missing initialization of change_inx in sort algorithm Staging: unisys: use after free in list_for_each() staging: unisys: use after free in error messages staging: speakup: fix misuse of kstrtol() in handle_goto() staging: goldfish: Call free_irq in error path staging: delete rtl8187se wireless driver staging: rtl8723au: Fix buffer overflow in rtw_get_wfd_ie() staging: gs_fpgaboot: remove __TIMESTAMP__ macro staging: vme: fix memory leak in vme_user_probe() staging: fpgaboot: clean up Makefile staging/usbip: fix store_attach() sscanf return value check staging/usbip: userspace - fix usbipd SIGSEGV from refresh_exported_devices() staging: rtl8188eu: remove spaces, correct counts to unbreak P2P ioctls staging/rtl8821ae: Fix OOM handling in _rtl_init_deferred_work()
This commit is contained in:
@@ -40,8 +40,6 @@ source "drivers/staging/olpc_dcon/Kconfig"
|
||||
|
||||
source "drivers/staging/panel/Kconfig"
|
||||
|
||||
source "drivers/staging/rtl8187se/Kconfig"
|
||||
|
||||
source "drivers/staging/rtl8192u/Kconfig"
|
||||
|
||||
source "drivers/staging/rtl8192e/Kconfig"
|
||||
|
||||
@@ -12,7 +12,6 @@ obj-$(CONFIG_PRISM2_USB) += wlan-ng/
|
||||
obj-$(CONFIG_COMEDI) += comedi/
|
||||
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
|
||||
obj-$(CONFIG_PANEL) += panel/
|
||||
obj-$(CONFIG_R8187SE) += rtl8187se/
|
||||
obj-$(CONFIG_RTL8192U) += rtl8192u/
|
||||
obj-$(CONFIG_RTL8192E) += rtl8192e/
|
||||
obj-$(CONFIG_R8712U) += rtl8712/
|
||||
|
||||
@@ -61,6 +61,8 @@ static void __comedi_buf_free(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct comedi_async *async = s->async;
|
||||
struct comedi_buf_map *bm;
|
||||
unsigned long flags;
|
||||
|
||||
if (async->prealloc_buf) {
|
||||
vunmap(async->prealloc_buf);
|
||||
@@ -68,8 +70,11 @@ static void __comedi_buf_free(struct comedi_device *dev,
|
||||
async->prealloc_bufsz = 0;
|
||||
}
|
||||
|
||||
comedi_buf_map_put(async->buf_map);
|
||||
spin_lock_irqsave(&s->spin_lock, flags);
|
||||
bm = async->buf_map;
|
||||
async->buf_map = NULL;
|
||||
spin_unlock_irqrestore(&s->spin_lock, flags);
|
||||
comedi_buf_map_put(bm);
|
||||
}
|
||||
|
||||
static void __comedi_buf_alloc(struct comedi_device *dev,
|
||||
@@ -80,6 +85,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
|
||||
struct page **pages = NULL;
|
||||
struct comedi_buf_map *bm;
|
||||
struct comedi_buf_page *buf;
|
||||
unsigned long flags;
|
||||
unsigned i;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) {
|
||||
@@ -92,8 +98,10 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
|
||||
if (!bm)
|
||||
return;
|
||||
|
||||
async->buf_map = bm;
|
||||
kref_init(&bm->refcount);
|
||||
spin_lock_irqsave(&s->spin_lock, flags);
|
||||
async->buf_map = bm;
|
||||
spin_unlock_irqrestore(&s->spin_lock, flags);
|
||||
bm->dma_dir = s->async_dma_dir;
|
||||
if (bm->dma_dir != DMA_NONE)
|
||||
/* Need ref to hardware device to free buffer later. */
|
||||
@@ -127,7 +135,9 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
|
||||
|
||||
pages[i] = virt_to_page(buf->virt_addr);
|
||||
}
|
||||
spin_lock_irqsave(&s->spin_lock, flags);
|
||||
bm->n_pages = i;
|
||||
spin_unlock_irqrestore(&s->spin_lock, flags);
|
||||
|
||||
/* vmap the prealloc_buf if all the pages were allocated */
|
||||
if (i == n_pages)
|
||||
@@ -150,6 +160,29 @@ int comedi_buf_map_put(struct comedi_buf_map *bm)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* returns s->async->buf_map and increments its kref refcount */
|
||||
struct comedi_buf_map *
|
||||
comedi_buf_map_from_subdev_get(struct comedi_subdevice *s)
|
||||
{
|
||||
struct comedi_async *async = s->async;
|
||||
struct comedi_buf_map *bm = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
if (!async)
|
||||
return NULL;
|
||||
|
||||
spin_lock_irqsave(&s->spin_lock, flags);
|
||||
bm = async->buf_map;
|
||||
/* only want it if buffer pages allocated */
|
||||
if (bm && bm->n_pages)
|
||||
comedi_buf_map_get(bm);
|
||||
else
|
||||
bm = NULL;
|
||||
spin_unlock_irqrestore(&s->spin_lock, flags);
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
||||
bool comedi_buf_is_mmapped(struct comedi_async *async)
|
||||
{
|
||||
struct comedi_buf_map *bm = async->buf_map;
|
||||
|
||||
@@ -1926,14 +1926,21 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
struct comedi_device *dev = file->private_data;
|
||||
struct comedi_subdevice *s;
|
||||
struct comedi_async *async;
|
||||
struct comedi_buf_map *bm;
|
||||
struct comedi_buf_map *bm = NULL;
|
||||
unsigned long start = vma->vm_start;
|
||||
unsigned long size;
|
||||
int n_pages;
|
||||
int i;
|
||||
int retval;
|
||||
|
||||
mutex_lock(&dev->mutex);
|
||||
/*
|
||||
* 'trylock' avoids circular dependency with current->mm->mmap_sem
|
||||
* and down-reading &dev->attach_lock should normally succeed without
|
||||
* contention unless the device is in the process of being attached
|
||||
* or detached.
|
||||
*/
|
||||
if (!down_read_trylock(&dev->attach_lock))
|
||||
return -EAGAIN;
|
||||
|
||||
if (!dev->attached) {
|
||||
dev_dbg(dev->class_dev, "no driver attached\n");
|
||||
@@ -1973,7 +1980,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
}
|
||||
|
||||
n_pages = size >> PAGE_SHIFT;
|
||||
bm = async->buf_map;
|
||||
|
||||
/* get reference to current buf map (if any) */
|
||||
bm = comedi_buf_map_from_subdev_get(s);
|
||||
if (!bm || n_pages > bm->n_pages) {
|
||||
retval = -EINVAL;
|
||||
goto done;
|
||||
@@ -1997,7 +2006,8 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
|
||||
retval = 0;
|
||||
done:
|
||||
mutex_unlock(&dev->mutex);
|
||||
up_read(&dev->attach_lock);
|
||||
comedi_buf_map_put(bm); /* put reference to buf map - okay if NULL */
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ void comedi_buf_reset(struct comedi_async *async);
|
||||
bool comedi_buf_is_mmapped(struct comedi_async *async);
|
||||
void comedi_buf_map_get(struct comedi_buf_map *bm);
|
||||
int comedi_buf_map_put(struct comedi_buf_map *bm);
|
||||
struct comedi_buf_map *comedi_buf_map_from_subdev_get(
|
||||
struct comedi_subdevice *s);
|
||||
unsigned int comedi_buf_write_n_allocated(struct comedi_async *async);
|
||||
void comedi_device_cancel_all(struct comedi_device *dev);
|
||||
|
||||
|
||||
@@ -334,6 +334,7 @@ static int goldfish_audio_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
err_misc_register_failed:
|
||||
free_irq(data->irq, data);
|
||||
err_request_irq_failed:
|
||||
dma_free_coherent(&pdev->dev, COMBINED_BUFFER_SIZE,
|
||||
data->buffer_virt, data->buffer_phys);
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
gs_fpga-y += gs_fpgaboot.o io.o
|
||||
obj-$(CONFIG_GS_FPGABOOT) += gs_fpga.o
|
||||
|
||||
ccflags-$(CONFIG_GS_FPGA_DEBUG) := -DDEBUG
|
||||
|
||||
@@ -373,7 +373,6 @@ static int __init gs_fpgaboot_init(void)
|
||||
r = -1;
|
||||
|
||||
pr_info("FPGA DOWNLOAD --->\n");
|
||||
pr_info("built at %s UTC\n", __TIMESTAMP__);
|
||||
|
||||
pr_info("FPGA image file name: %s\n", file);
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
config R8187SE
|
||||
tristate "RealTek RTL8187SE Wireless LAN NIC driver"
|
||||
depends on PCI && WLAN
|
||||
depends on m
|
||||
select WIRELESS_EXT
|
||||
select WEXT_PRIV
|
||||
select EEPROM_93CX6
|
||||
select CRYPTO
|
||||
---help---
|
||||
If built as a module, it will be called r8187se.ko.
|
||||
@@ -1,38 +0,0 @@
|
||||
|
||||
#ccflags-y += -DCONFIG_IEEE80211_NOWEP=y
|
||||
#ccflags-y += -std=gnu89
|
||||
#ccflags-y += -O2
|
||||
#CC = gcc
|
||||
|
||||
ccflags-y := -DSW_ANTE
|
||||
ccflags-y += -DTX_TRACK
|
||||
ccflags-y += -DHIGH_POWER
|
||||
ccflags-y += -DSW_DIG
|
||||
ccflags-y += -DRATE_ADAPT
|
||||
|
||||
#enable it for legacy power save, disable it for leisure power save
|
||||
ccflags-y += -DENABLE_LPS
|
||||
|
||||
|
||||
#ccflags-y := -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
|
||||
|
||||
r8187se-y := \
|
||||
r8180_core.o \
|
||||
r8180_wx.o \
|
||||
r8180_rtl8225z2.o \
|
||||
r8185b_init.o \
|
||||
r8180_dm.o \
|
||||
ieee80211/dot11d.o \
|
||||
ieee80211/ieee80211_softmac.o \
|
||||
ieee80211/ieee80211_rx.o \
|
||||
ieee80211/ieee80211_tx.o \
|
||||
ieee80211/ieee80211_wx.o \
|
||||
ieee80211/ieee80211_module.o \
|
||||
ieee80211/ieee80211_softmac_wx.o \
|
||||
ieee80211/ieee80211_crypt.o \
|
||||
ieee80211/ieee80211_crypt_tkip.o \
|
||||
ieee80211/ieee80211_crypt_ccmp.o \
|
||||
ieee80211/ieee80211_crypt_wep.o
|
||||
|
||||
obj-$(CONFIG_R8187SE) += r8187se.o
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
TODO:
|
||||
- prepare private ieee80211 stack for merge with rtl8192su's version:
|
||||
- add hwsec_active flag to struct ieee80211_device
|
||||
- add bHwSec flag to cb_desc structure
|
||||
- switch to use shared "librtl" instead of private ieee80211 stack
|
||||
- switch to use LIB80211
|
||||
- switch to use MAC80211
|
||||
- use kernel coding style
|
||||
- checkpatch.pl fixes
|
||||
- sparse fixes
|
||||
- integrate with drivers/net/wireless/rtl818x
|
||||
|
||||
Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
|
||||
@@ -1,189 +0,0 @@
|
||||
#include "dot11d.h"
|
||||
|
||||
void Dot11d_Init(struct ieee80211_device *ieee)
|
||||
{
|
||||
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
|
||||
|
||||
pDot11dInfo->bEnabled = 0;
|
||||
|
||||
pDot11dInfo->State = DOT11D_STATE_NONE;
|
||||
pDot11dInfo->CountryIeLen = 0;
|
||||
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
|
||||
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
|
||||
RESET_CIE_WATCHDOG(ieee);
|
||||
|
||||
netdev_info(ieee->dev, "Dot11d_Init()\n");
|
||||
}
|
||||
|
||||
/* Reset to the state as we are just entering a regulatory domain. */
|
||||
void Dot11d_Reset(struct ieee80211_device *ieee)
|
||||
{
|
||||
u32 i;
|
||||
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
|
||||
|
||||
/* Clear old channel map */
|
||||
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
|
||||
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
|
||||
/* Set new channel map */
|
||||
for (i = 1; i <= 11; i++)
|
||||
(pDot11dInfo->channel_map)[i] = 1;
|
||||
|
||||
for (i = 12; i <= 14; i++)
|
||||
(pDot11dInfo->channel_map)[i] = 2;
|
||||
|
||||
pDot11dInfo->State = DOT11D_STATE_NONE;
|
||||
pDot11dInfo->CountryIeLen = 0;
|
||||
RESET_CIE_WATCHDOG(ieee);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* Update country IE from Beacon or Probe Response and configure PHY for
|
||||
* operation in the regulatory domain.
|
||||
*
|
||||
* TODO:
|
||||
* Configure Tx power.
|
||||
*
|
||||
* Assumption:
|
||||
* 1. IS_DOT11D_ENABLE() is TRUE.
|
||||
* 2. Input IE is an valid one.
|
||||
*/
|
||||
void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
|
||||
u16 CoutryIeLen, u8 *pCoutryIe)
|
||||
{
|
||||
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
|
||||
u8 i, j, NumTriples, MaxChnlNum;
|
||||
u8 index, MaxTxPowerInDbm;
|
||||
PCHNL_TXPOWER_TRIPLE pTriple;
|
||||
|
||||
if ((CoutryIeLen - 3)%3 != 0) {
|
||||
netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
|
||||
Dot11d_Reset(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
|
||||
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
|
||||
MaxChnlNum = 0;
|
||||
NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */
|
||||
pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
|
||||
for (i = 0; i < NumTriples; i++) {
|
||||
if (MaxChnlNum >= pTriple->FirstChnl) {
|
||||
/*
|
||||
* It is not in a monotonically increasing order,
|
||||
* so stop processing.
|
||||
*/
|
||||
netdev_info(dev->dev,
|
||||
"Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
|
||||
Dot11d_Reset(dev);
|
||||
return;
|
||||
}
|
||||
if (MAX_CHANNEL_NUMBER <
|
||||
(pTriple->FirstChnl + pTriple->NumChnls)) {
|
||||
/*
|
||||
* It is not a valid set of channel id,
|
||||
* so stop processing
|
||||
*/
|
||||
netdev_info(dev->dev,
|
||||
"Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
|
||||
Dot11d_Reset(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
for (j = 0; j < pTriple->NumChnls; j++) {
|
||||
index = pTriple->FirstChnl + j;
|
||||
pDot11dInfo->channel_map[index] = 1;
|
||||
MaxTxPowerInDbm = pTriple->MaxTxPowerInDbm;
|
||||
pDot11dInfo->MaxTxPwrDbmList[index] = MaxTxPowerInDbm;
|
||||
MaxChnlNum = pTriple->FirstChnl + j;
|
||||
}
|
||||
|
||||
pTriple = (PCHNL_TXPOWER_TRIPLE)((u8 *)pTriple + 3);
|
||||
}
|
||||
#if 1
|
||||
netdev_info(dev->dev, "Channel List:");
|
||||
for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
|
||||
if (pDot11dInfo->channel_map[i] > 0)
|
||||
netdev_info(dev->dev, " %d", i);
|
||||
netdev_info(dev->dev, "\n");
|
||||
#endif
|
||||
|
||||
UPDATE_CIE_SRC(dev, pTaddr);
|
||||
|
||||
pDot11dInfo->CountryIeLen = CoutryIeLen;
|
||||
memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen);
|
||||
pDot11dInfo->State = DOT11D_STATE_LEARNED;
|
||||
}
|
||||
|
||||
u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel)
|
||||
{
|
||||
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
|
||||
u8 MaxTxPwrInDbm = 255;
|
||||
|
||||
if (MAX_CHANNEL_NUMBER < Channel) {
|
||||
netdev_info(dev->dev, "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
|
||||
return MaxTxPwrInDbm;
|
||||
}
|
||||
if (pDot11dInfo->channel_map[Channel])
|
||||
MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
|
||||
|
||||
return MaxTxPwrInDbm;
|
||||
}
|
||||
|
||||
|
||||
void DOT11D_ScanComplete(struct ieee80211_device *dev)
|
||||
{
|
||||
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
|
||||
|
||||
switch (pDot11dInfo->State) {
|
||||
case DOT11D_STATE_LEARNED:
|
||||
pDot11dInfo->State = DOT11D_STATE_DONE;
|
||||
break;
|
||||
|
||||
case DOT11D_STATE_DONE:
|
||||
if (GET_CIE_WATCHDOG(dev) == 0) {
|
||||
/* Reset country IE if previous one is gone. */
|
||||
Dot11d_Reset(dev);
|
||||
}
|
||||
break;
|
||||
case DOT11D_STATE_NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int IsLegalChannel(struct ieee80211_device *dev, u8 channel)
|
||||
{
|
||||
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
|
||||
|
||||
if (MAX_CHANNEL_NUMBER < channel) {
|
||||
netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
|
||||
return 0;
|
||||
}
|
||||
if (pDot11dInfo->channel_map[channel] > 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ToLegalChannel(struct ieee80211_device *dev, u8 channel)
|
||||
{
|
||||
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
|
||||
u8 default_chn = 0;
|
||||
u32 i = 0;
|
||||
|
||||
for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) {
|
||||
if (pDot11dInfo->channel_map[i] > 0) {
|
||||
default_chn = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (MAX_CHANNEL_NUMBER < channel) {
|
||||
netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
|
||||
return default_chn;
|
||||
}
|
||||
|
||||
if (pDot11dInfo->channel_map[channel] > 0)
|
||||
return channel;
|
||||
|
||||
return default_chn;
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
#ifndef __INC_DOT11D_H
|
||||
#define __INC_DOT11D_H
|
||||
|
||||
#include "ieee80211.h"
|
||||
|
||||
/* #define ENABLE_DOT11D */
|
||||
|
||||
/* #define DOT11D_MAX_CHNL_NUM 83 */
|
||||
|
||||
typedef struct _CHNL_TXPOWER_TRIPLE {
|
||||
u8 FirstChnl;
|
||||
u8 NumChnls;
|
||||
u8 MaxTxPowerInDbm;
|
||||
} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
|
||||
|
||||
typedef enum _DOT11D_STATE {
|
||||
DOT11D_STATE_NONE = 0,
|
||||
DOT11D_STATE_LEARNED,
|
||||
DOT11D_STATE_DONE,
|
||||
} DOT11D_STATE;
|
||||
|
||||
typedef struct _RT_DOT11D_INFO {
|
||||
/* DECLARE_RT_OBJECT(RT_DOT12D_INFO); */
|
||||
|
||||
bool bEnabled; /* dot11MultiDomainCapabilityEnabled */
|
||||
|
||||
u16 CountryIeLen; /* > 0 if CountryIeBuf[] contains valid country information element. */
|
||||
u8 CountryIeBuf[MAX_IE_LEN];
|
||||
u8 CountryIeSrcAddr[6]; /* Source AP of the country IE. */
|
||||
u8 CountryIeWatchdog;
|
||||
|
||||
u8 channel_map[MAX_CHANNEL_NUMBER+1]; /* !!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */
|
||||
/* u8 ChnlListLen; // #Bytes valid in ChnlList[]. */
|
||||
/* u8 ChnlList[DOT11D_MAX_CHNL_NUM]; */
|
||||
u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
|
||||
|
||||
DOT11D_STATE State;
|
||||
} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
|
||||
|
||||
#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1:0)
|
||||
#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5])
|
||||
#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
|
||||
|
||||
#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
|
||||
#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
|
||||
|
||||
#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
|
||||
#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
|
||||
|
||||
#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
|
||||
(((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
|
||||
FALSE : \
|
||||
(!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
|
||||
|
||||
#define CIE_WATCHDOG_TH 1
|
||||
#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
|
||||
#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
|
||||
#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
|
||||
|
||||
#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
|
||||
|
||||
void Dot11d_Init(struct ieee80211_device *dev);
|
||||
void Dot11d_Reset(struct ieee80211_device *dev);
|
||||
void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
|
||||
u16 CoutryIeLen, u8 *pCoutryIe);
|
||||
u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel);
|
||||
void DOT11D_ScanComplete(struct ieee80211_device *dev);
|
||||
int IsLegalChannel(struct ieee80211_device *dev, u8 channel);
|
||||
int ToLegalChannel(struct ieee80211_device *dev, u8 channel);
|
||||
|
||||
#endif /* #ifndef __INC_DOT11D_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Host AP crypto routines
|
||||
*
|
||||
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
|
||||
* Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. See README and COPYING for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
//#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
#include "ieee80211.h"
|
||||
|
||||
MODULE_AUTHOR("Jouni Malinen");
|
||||
MODULE_DESCRIPTION("HostAP crypto");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
struct ieee80211_crypto_alg {
|
||||
struct list_head list;
|
||||
struct ieee80211_crypto_ops *ops;
|
||||
};
|
||||
|
||||
|
||||
struct ieee80211_crypto {
|
||||
struct list_head algs;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
static struct ieee80211_crypto *hcrypt;
|
||||
|
||||
void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
|
||||
{
|
||||
struct list_head *ptr, *n;
|
||||
struct ieee80211_crypt_data *entry;
|
||||
|
||||
for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
|
||||
ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
|
||||
entry = list_entry(ptr, struct ieee80211_crypt_data, list);
|
||||
|
||||
if (atomic_read(&entry->refcnt) != 0 && !force)
|
||||
continue;
|
||||
|
||||
list_del(ptr);
|
||||
|
||||
if (entry->ops)
|
||||
entry->ops->deinit(entry->priv);
|
||||
kfree(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void ieee80211_crypt_deinit_handler(unsigned long data)
|
||||
{
|
||||
struct ieee80211_device *ieee = (struct ieee80211_device *)data;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ieee->lock, flags);
|
||||
ieee80211_crypt_deinit_entries(ieee, 0);
|
||||
if (!list_empty(&ieee->crypt_deinit_list)) {
|
||||
pr_debug("entries remaining in delayed crypt deletion list\n");
|
||||
ieee->crypt_deinit_timer.expires = jiffies + HZ;
|
||||
add_timer(&ieee->crypt_deinit_timer);
|
||||
}
|
||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||
|
||||
}
|
||||
|
||||
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
|
||||
struct ieee80211_crypt_data **crypt)
|
||||
{
|
||||
struct ieee80211_crypt_data *tmp;
|
||||
unsigned long flags;
|
||||
|
||||
if (*crypt == NULL)
|
||||
return;
|
||||
|
||||
tmp = *crypt;
|
||||
*crypt = NULL;
|
||||
|
||||
/* must not run ops->deinit() while there may be pending encrypt or
|
||||
* decrypt operations. Use a list of delayed deinits to avoid needing
|
||||
* locking. */
|
||||
|
||||
spin_lock_irqsave(&ieee->lock, flags);
|
||||
list_add(&tmp->list, &ieee->crypt_deinit_list);
|
||||
if (!timer_pending(&ieee->crypt_deinit_timer)) {
|
||||
ieee->crypt_deinit_timer.expires = jiffies + HZ;
|
||||
add_timer(&ieee->crypt_deinit_timer);
|
||||
}
|
||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||
}
|
||||
|
||||
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct ieee80211_crypto_alg *alg;
|
||||
|
||||
if (hcrypt == NULL)
|
||||
return -1;
|
||||
|
||||
alg = kzalloc(sizeof(*alg), GFP_KERNEL);
|
||||
if (alg == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
alg->ops = ops;
|
||||
|
||||
spin_lock_irqsave(&hcrypt->lock, flags);
|
||||
list_add(&alg->list, &hcrypt->algs);
|
||||
spin_unlock_irqrestore(&hcrypt->lock, flags);
|
||||
|
||||
pr_debug("registered algorithm '%s'\n", ops->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct list_head *ptr;
|
||||
struct ieee80211_crypto_alg *del_alg = NULL;
|
||||
|
||||
if (hcrypt == NULL)
|
||||
return -1;
|
||||
|
||||
spin_lock_irqsave(&hcrypt->lock, flags);
|
||||
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
|
||||
struct ieee80211_crypto_alg *alg =
|
||||
(struct ieee80211_crypto_alg *) ptr;
|
||||
if (alg->ops == ops) {
|
||||
list_del(&alg->list);
|
||||
del_alg = alg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&hcrypt->lock, flags);
|
||||
|
||||
if (del_alg) {
|
||||
pr_debug("unregistered algorithm '%s'\n", ops->name);
|
||||
kfree(del_alg);
|
||||
}
|
||||
|
||||
return del_alg ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct list_head *ptr;
|
||||
struct ieee80211_crypto_alg *found_alg = NULL;
|
||||
|
||||
if (hcrypt == NULL)
|
||||
return NULL;
|
||||
|
||||
spin_lock_irqsave(&hcrypt->lock, flags);
|
||||
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
|
||||
struct ieee80211_crypto_alg *alg =
|
||||
(struct ieee80211_crypto_alg *) ptr;
|
||||
if (strcmp(alg->ops->name, name) == 0) {
|
||||
found_alg = alg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&hcrypt->lock, flags);
|
||||
|
||||
if (found_alg)
|
||||
return found_alg->ops;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void *ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
|
||||
static void ieee80211_crypt_null_deinit(void *priv) {}
|
||||
|
||||
static struct ieee80211_crypto_ops ieee80211_crypt_null = {
|
||||
.name = "NULL",
|
||||
.init = ieee80211_crypt_null_init,
|
||||
.deinit = ieee80211_crypt_null_deinit,
|
||||
.encrypt_mpdu = NULL,
|
||||
.decrypt_mpdu = NULL,
|
||||
.encrypt_msdu = NULL,
|
||||
.decrypt_msdu = NULL,
|
||||
.set_key = NULL,
|
||||
.get_key = NULL,
|
||||
.extra_prefix_len = 0,
|
||||
.extra_postfix_len = 0,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
||||
int ieee80211_crypto_init(void)
|
||||
{
|
||||
int ret = -ENOMEM;
|
||||
|
||||
hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL);
|
||||
if (!hcrypt)
|
||||
goto out;
|
||||
|
||||
INIT_LIST_HEAD(&hcrypt->algs);
|
||||
spin_lock_init(&hcrypt->lock);
|
||||
|
||||
ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
|
||||
if (ret < 0) {
|
||||
kfree(hcrypt);
|
||||
hcrypt = NULL;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void ieee80211_crypto_deinit(void)
|
||||
{
|
||||
struct list_head *ptr, *n;
|
||||
struct ieee80211_crypto_alg *alg = NULL;
|
||||
|
||||
if (hcrypt == NULL)
|
||||
return;
|
||||
|
||||
list_for_each_safe(ptr, n, &hcrypt->algs) {
|
||||
alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
|
||||
if (alg) {
|
||||
list_del(ptr);
|
||||
pr_debug("unregistered algorithm '%s' (deinit)\n",
|
||||
alg->ops->name);
|
||||
kfree(alg);
|
||||
}
|
||||
}
|
||||
kfree(hcrypt);
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Original code based on Host AP (software wireless LAN access point) driver
|
||||
* for Intersil Prism2/2.5/3.
|
||||
*
|
||||
* Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
|
||||
* <jkmaline@cc.hut.fi>
|
||||
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
|
||||
*
|
||||
* Adaption to a generic IEEE 802.11 stack by James Ketrenos
|
||||
* <jketreno@linux.intel.com>
|
||||
*
|
||||
* Copyright (c) 2004, Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. See README and COPYING for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file defines the interface to the ieee80211 crypto module.
|
||||
*/
|
||||
#ifndef IEEE80211_CRYPT_H
|
||||
#define IEEE80211_CRYPT_H
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
struct ieee80211_crypto_ops {
|
||||
const char *name;
|
||||
|
||||
/* init new crypto context (e.g., allocate private data space,
|
||||
* select IV, etc.); returns NULL on failure or pointer to allocated
|
||||
* private data on success */
|
||||
void * (*init)(int keyidx);
|
||||
|
||||
/* deinitialize crypto context and free allocated private data */
|
||||
void (*deinit)(void *priv);
|
||||
|
||||
/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
|
||||
* value from decrypt_mpdu is passed as the keyidx value for
|
||||
* decrypt_msdu. skb must have enough head and tail room for the
|
||||
* encryption; if not, error will be returned; these functions are
|
||||
* called for all MPDUs (i.e., fragments).
|
||||
*/
|
||||
int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
|
||||
int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
|
||||
|
||||
/* These functions are called for full MSDUs, i.e. full frames.
|
||||
* These can be NULL if full MSDU operations are not needed. */
|
||||
int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
|
||||
int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
|
||||
void *priv);
|
||||
|
||||
int (*set_key)(void *key, int len, u8 *seq, void *priv);
|
||||
int (*get_key)(void *key, int len, u8 *seq, void *priv);
|
||||
|
||||
/* procfs handler for printing out key information and possible
|
||||
* statistics */
|
||||
char * (*print_stats)(char *p, void *priv);
|
||||
|
||||
/* maximum number of bytes added by encryption; encrypt buf is
|
||||
* allocated with extra_prefix_len bytes, copy of in_buf, and
|
||||
* extra_postfix_len; encrypt need not use all this space, but
|
||||
* the result must start at the beginning of the buffer and correct
|
||||
* length must be returned */
|
||||
int extra_prefix_len, extra_postfix_len;
|
||||
|
||||
struct module *owner;
|
||||
};
|
||||
|
||||
struct ieee80211_crypt_data {
|
||||
struct list_head list; /* delayed deletion list */
|
||||
struct ieee80211_crypto_ops *ops;
|
||||
void *priv;
|
||||
atomic_t refcnt;
|
||||
};
|
||||
|
||||
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
|
||||
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
|
||||
struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
|
||||
void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
|
||||
void ieee80211_crypt_deinit_handler(unsigned long);
|
||||
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
|
||||
struct ieee80211_crypt_data **crypt);
|
||||
|
||||
#endif
|
||||
@@ -1,455 +0,0 @@
|
||||
/*
|
||||
* Host AP crypt: host-based CCMP encryption implementation for Host AP driver
|
||||
*
|
||||
* Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. See README and COPYING for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/wireless.h>
|
||||
|
||||
#include "ieee80211.h"
|
||||
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
MODULE_AUTHOR("Jouni Malinen");
|
||||
MODULE_DESCRIPTION("Host AP crypt: CCMP");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
#define AES_BLOCK_LEN 16
|
||||
#define CCMP_HDR_LEN 8
|
||||
#define CCMP_MIC_LEN 8
|
||||
#define CCMP_TK_LEN 16
|
||||
#define CCMP_PN_LEN 6
|
||||
|
||||
struct ieee80211_ccmp_data {
|
||||
u8 key[CCMP_TK_LEN];
|
||||
int key_set;
|
||||
|
||||
u8 tx_pn[CCMP_PN_LEN];
|
||||
u8 rx_pn[CCMP_PN_LEN];
|
||||
|
||||
u32 dot11RSNAStatsCCMPFormatErrors;
|
||||
u32 dot11RSNAStatsCCMPReplays;
|
||||
u32 dot11RSNAStatsCCMPDecryptErrors;
|
||||
|
||||
int key_idx;
|
||||
|
||||
struct crypto_tfm *tfm;
|
||||
|
||||
/* scratch buffers for virt_to_page() (crypto API) */
|
||||
u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
|
||||
tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
|
||||
u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
|
||||
};
|
||||
|
||||
static void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
|
||||
const u8 pt[16], u8 ct[16])
|
||||
{
|
||||
crypto_cipher_encrypt_one((void *)tfm, ct, pt);
|
||||
}
|
||||
|
||||
static void *ieee80211_ccmp_init(int key_idx)
|
||||
{
|
||||
struct ieee80211_ccmp_data *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
|
||||
if (priv == NULL)
|
||||
goto fail;
|
||||
priv->key_idx = key_idx;
|
||||
|
||||
priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR(priv->tfm)) {
|
||||
pr_debug("could not allocate crypto API aes\n");
|
||||
priv->tfm = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return priv;
|
||||
|
||||
fail:
|
||||
if (priv) {
|
||||
if (priv->tfm)
|
||||
crypto_free_cipher((void *)priv->tfm);
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void ieee80211_ccmp_deinit(void *priv)
|
||||
{
|
||||
struct ieee80211_ccmp_data *_priv = priv;
|
||||
|
||||
if (_priv && _priv->tfm)
|
||||
crypto_free_cipher((void *)_priv->tfm);
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
|
||||
static inline void xor_block(u8 *b, u8 *a, size_t len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
b[i] ^= a[i];
|
||||
}
|
||||
|
||||
static void ccmp_init_blocks(struct crypto_tfm *tfm,
|
||||
struct ieee80211_hdr_4addr *hdr,
|
||||
u8 *pn, size_t dlen, u8 *b0, u8 *auth,
|
||||
u8 *s0)
|
||||
{
|
||||
u8 *pos, qc = 0;
|
||||
size_t aad_len;
|
||||
u16 fc;
|
||||
int a4_included, qc_included;
|
||||
u8 aad[2 * AES_BLOCK_LEN];
|
||||
|
||||
fc = le16_to_cpu(hdr->frame_ctl);
|
||||
a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
|
||||
(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
|
||||
/*
|
||||
qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
|
||||
(WLAN_FC_GET_STYPE(fc) & 0x08));
|
||||
*/
|
||||
qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
|
||||
(WLAN_FC_GET_STYPE(fc) & 0x80));
|
||||
aad_len = 22;
|
||||
if (a4_included)
|
||||
aad_len += 6;
|
||||
if (qc_included) {
|
||||
pos = (u8 *) &hdr->addr4;
|
||||
if (a4_included)
|
||||
pos += 6;
|
||||
qc = *pos & 0x0f;
|
||||
aad_len += 2;
|
||||
}
|
||||
/* CCM Initial Block:
|
||||
* Flag (Include authentication header, M=3 (8-octet MIC),
|
||||
* L=1 (2-octet Dlen))
|
||||
* Nonce: 0x00 | A2 | PN
|
||||
* Dlen */
|
||||
b0[0] = 0x59;
|
||||
b0[1] = qc;
|
||||
memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
|
||||
memcpy(b0 + 8, pn, CCMP_PN_LEN);
|
||||
b0[14] = (dlen >> 8) & 0xff;
|
||||
b0[15] = dlen & 0xff;
|
||||
|
||||
/* AAD:
|
||||
* FC with bits 4..6 and 11..13 masked to zero; 14 is always one
|
||||
* A1 | A2 | A3
|
||||
* SC with bits 4..15 (seq#) masked to zero
|
||||
* A4 (if present)
|
||||
* QC (if present)
|
||||
*/
|
||||
pos = (u8 *) hdr;
|
||||
aad[0] = 0; /* aad_len >> 8 */
|
||||
aad[1] = aad_len & 0xff;
|
||||
aad[2] = pos[0] & 0x8f;
|
||||
aad[3] = pos[1] & 0xc7;
|
||||
memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
|
||||
pos = (u8 *) &hdr->seq_ctl;
|
||||
aad[22] = pos[0] & 0x0f;
|
||||
aad[23] = 0; /* all bits masked */
|
||||
memset(aad + 24, 0, 8);
|
||||
if (a4_included)
|
||||
memcpy(aad + 24, hdr->addr4, ETH_ALEN);
|
||||
if (qc_included) {
|
||||
aad[a4_included ? 30 : 24] = qc;
|
||||
/* rest of QC masked */
|
||||
}
|
||||
|
||||
/* Start with the first block and AAD */
|
||||
ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
|
||||
xor_block(auth, aad, AES_BLOCK_LEN);
|
||||
ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
|
||||
xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
|
||||
ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
|
||||
b0[0] &= 0x07;
|
||||
b0[14] = b0[15] = 0;
|
||||
ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
|
||||
}
|
||||
|
||||
static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct ieee80211_ccmp_data *key = priv;
|
||||
int data_len, i;
|
||||
u8 *pos;
|
||||
struct ieee80211_hdr_4addr *hdr;
|
||||
int blocks, last, len;
|
||||
u8 *mic;
|
||||
u8 *b0 = key->tx_b0;
|
||||
u8 *b = key->tx_b;
|
||||
u8 *e = key->tx_e;
|
||||
u8 *s0 = key->tx_s0;
|
||||
|
||||
if (skb_headroom(skb) < CCMP_HDR_LEN ||
|
||||
skb_tailroom(skb) < CCMP_MIC_LEN ||
|
||||
skb->len < hdr_len)
|
||||
return -1;
|
||||
|
||||
data_len = skb->len - hdr_len;
|
||||
pos = skb_push(skb, CCMP_HDR_LEN);
|
||||
memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
|
||||
pos += hdr_len;
|
||||
|
||||
i = CCMP_PN_LEN - 1;
|
||||
while (i >= 0) {
|
||||
key->tx_pn[i]++;
|
||||
if (key->tx_pn[i] != 0)
|
||||
break;
|
||||
i--;
|
||||
}
|
||||
|
||||
*pos++ = key->tx_pn[5];
|
||||
*pos++ = key->tx_pn[4];
|
||||
*pos++ = 0;
|
||||
*pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
|
||||
*pos++ = key->tx_pn[3];
|
||||
*pos++ = key->tx_pn[2];
|
||||
*pos++ = key->tx_pn[1];
|
||||
*pos++ = key->tx_pn[0];
|
||||
|
||||
hdr = (struct ieee80211_hdr_4addr *)skb->data;
|
||||
mic = skb_put(skb, CCMP_MIC_LEN);
|
||||
|
||||
ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
|
||||
|
||||
blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
|
||||
last = data_len % AES_BLOCK_LEN;
|
||||
|
||||
for (i = 1; i <= blocks; i++) {
|
||||
len = (i == blocks && last) ? last : AES_BLOCK_LEN;
|
||||
/* Authentication */
|
||||
xor_block(b, pos, len);
|
||||
ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
|
||||
/* Encryption, with counter */
|
||||
b0[14] = (i >> 8) & 0xff;
|
||||
b0[15] = i & 0xff;
|
||||
ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
|
||||
xor_block(pos, e, len);
|
||||
pos += len;
|
||||
}
|
||||
|
||||
for (i = 0; i < CCMP_MIC_LEN; i++)
|
||||
mic[i] = b[i] ^ s0[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct ieee80211_ccmp_data *key = priv;
|
||||
u8 keyidx, *pos;
|
||||
struct ieee80211_hdr_4addr *hdr;
|
||||
u8 pn[6];
|
||||
size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
|
||||
u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
|
||||
u8 *b0 = key->rx_b0;
|
||||
u8 *b = key->rx_b;
|
||||
u8 *a = key->rx_a;
|
||||
int i, blocks, last, len;
|
||||
|
||||
if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
|
||||
key->dot11RSNAStatsCCMPFormatErrors++;
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdr = (struct ieee80211_hdr_4addr *)skb->data;
|
||||
pos = skb->data + hdr_len;
|
||||
keyidx = pos[3];
|
||||
if (!(keyidx & (1 << 5))) {
|
||||
if (net_ratelimit()) {
|
||||
pr_debug("received packet without ExtIV flag from %pM\n",
|
||||
hdr->addr2);
|
||||
}
|
||||
key->dot11RSNAStatsCCMPFormatErrors++;
|
||||
return -2;
|
||||
}
|
||||
keyidx >>= 6;
|
||||
if (key->key_idx != keyidx) {
|
||||
pr_debug("RX tkey->key_idx=%d frame keyidx=%d priv=%p\n",
|
||||
key->key_idx, keyidx, priv);
|
||||
return -6;
|
||||
}
|
||||
if (!key->key_set) {
|
||||
if (net_ratelimit()) {
|
||||
pr_debug("received packet from %pM with keyid=%d that does not have a configured key\n",
|
||||
hdr->addr2, keyidx);
|
||||
}
|
||||
return -3;
|
||||
}
|
||||
|
||||
pn[0] = pos[7];
|
||||
pn[1] = pos[6];
|
||||
pn[2] = pos[5];
|
||||
pn[3] = pos[4];
|
||||
pn[4] = pos[1];
|
||||
pn[5] = pos[0];
|
||||
pos += 8;
|
||||
|
||||
if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
|
||||
if (net_ratelimit()) {
|
||||
pr_debug("replay detected: STA=%pM previous PN %pm received PN %pm\n",
|
||||
hdr->addr2, key->rx_pn, pn);
|
||||
}
|
||||
key->dot11RSNAStatsCCMPReplays++;
|
||||
return -4;
|
||||
}
|
||||
|
||||
ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
|
||||
xor_block(mic, b, CCMP_MIC_LEN);
|
||||
|
||||
blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
|
||||
last = data_len % AES_BLOCK_LEN;
|
||||
|
||||
for (i = 1; i <= blocks; i++) {
|
||||
len = (i == blocks && last) ? last : AES_BLOCK_LEN;
|
||||
/* Decrypt, with counter */
|
||||
b0[14] = (i >> 8) & 0xff;
|
||||
b0[15] = i & 0xff;
|
||||
ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
|
||||
xor_block(pos, b, len);
|
||||
/* Authentication */
|
||||
xor_block(a, pos, len);
|
||||
ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
|
||||
pos += len;
|
||||
}
|
||||
|
||||
if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
|
||||
if (net_ratelimit())
|
||||
pr_debug("decrypt failed: STA=%pM\n", hdr->addr2);
|
||||
|
||||
key->dot11RSNAStatsCCMPDecryptErrors++;
|
||||
return -5;
|
||||
}
|
||||
|
||||
memcpy(key->rx_pn, pn, CCMP_PN_LEN);
|
||||
|
||||
/* Remove hdr and MIC */
|
||||
memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
|
||||
skb_pull(skb, CCMP_HDR_LEN);
|
||||
skb_trim(skb, skb->len - CCMP_MIC_LEN);
|
||||
|
||||
return keyidx;
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
|
||||
{
|
||||
struct ieee80211_ccmp_data *data = priv;
|
||||
int keyidx;
|
||||
struct crypto_tfm *tfm = data->tfm;
|
||||
|
||||
keyidx = data->key_idx;
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->key_idx = keyidx;
|
||||
data->tfm = tfm;
|
||||
if (len == CCMP_TK_LEN) {
|
||||
memcpy(data->key, key, CCMP_TK_LEN);
|
||||
data->key_set = 1;
|
||||
if (seq) {
|
||||
data->rx_pn[0] = seq[5];
|
||||
data->rx_pn[1] = seq[4];
|
||||
data->rx_pn[2] = seq[3];
|
||||
data->rx_pn[3] = seq[2];
|
||||
data->rx_pn[4] = seq[1];
|
||||
data->rx_pn[5] = seq[0];
|
||||
}
|
||||
crypto_cipher_setkey((void *)data->tfm, data->key, CCMP_TK_LEN);
|
||||
} else if (len == 0)
|
||||
data->key_set = 0;
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
|
||||
{
|
||||
struct ieee80211_ccmp_data *data = priv;
|
||||
|
||||
if (len < CCMP_TK_LEN)
|
||||
return -1;
|
||||
|
||||
if (!data->key_set)
|
||||
return 0;
|
||||
memcpy(key, data->key, CCMP_TK_LEN);
|
||||
|
||||
if (seq) {
|
||||
seq[0] = data->tx_pn[5];
|
||||
seq[1] = data->tx_pn[4];
|
||||
seq[2] = data->tx_pn[3];
|
||||
seq[3] = data->tx_pn[2];
|
||||
seq[4] = data->tx_pn[1];
|
||||
seq[5] = data->tx_pn[0];
|
||||
}
|
||||
|
||||
return CCMP_TK_LEN;
|
||||
}
|
||||
|
||||
|
||||
static char *ieee80211_ccmp_print_stats(char *p, void *priv)
|
||||
{
|
||||
struct ieee80211_ccmp_data *ccmp = priv;
|
||||
p += sprintf(p,
|
||||
"key[%d] alg=CCMP key_set=%d tx_pn=%pm rx_pn=%pm format_errors=%d replays=%d decrypt_errors=%d\n",
|
||||
ccmp->key_idx, ccmp->key_set,
|
||||
ccmp->tx_pn, ccmp->rx_pn,
|
||||
ccmp->dot11RSNAStatsCCMPFormatErrors,
|
||||
ccmp->dot11RSNAStatsCCMPReplays,
|
||||
ccmp->dot11RSNAStatsCCMPDecryptErrors);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void ieee80211_ccmp_null(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
|
||||
.name = "CCMP",
|
||||
.init = ieee80211_ccmp_init,
|
||||
.deinit = ieee80211_ccmp_deinit,
|
||||
.encrypt_mpdu = ieee80211_ccmp_encrypt,
|
||||
.decrypt_mpdu = ieee80211_ccmp_decrypt,
|
||||
.encrypt_msdu = NULL,
|
||||
.decrypt_msdu = NULL,
|
||||
.set_key = ieee80211_ccmp_set_key,
|
||||
.get_key = ieee80211_ccmp_get_key,
|
||||
.print_stats = ieee80211_ccmp_print_stats,
|
||||
.extra_prefix_len = CCMP_HDR_LEN,
|
||||
.extra_postfix_len = CCMP_MIC_LEN,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
||||
int ieee80211_crypto_ccmp_init(void)
|
||||
{
|
||||
return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
|
||||
}
|
||||
|
||||
|
||||
void ieee80211_crypto_ccmp_exit(void)
|
||||
{
|
||||
ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,277 +0,0 @@
|
||||
/*
|
||||
* Host AP crypt: host-based WEP encryption implementation for Host AP driver
|
||||
*
|
||||
* Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. See README and COPYING for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include "ieee80211.h"
|
||||
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/crc32.h>
|
||||
|
||||
MODULE_AUTHOR("Jouni Malinen");
|
||||
MODULE_DESCRIPTION("Host AP crypt: WEP");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
struct prism2_wep_data {
|
||||
u32 iv;
|
||||
#define WEP_KEY_LEN 13
|
||||
u8 key[WEP_KEY_LEN + 1];
|
||||
u8 key_len;
|
||||
u8 key_idx;
|
||||
struct crypto_blkcipher *tx_tfm;
|
||||
struct crypto_blkcipher *rx_tfm;
|
||||
};
|
||||
|
||||
static void *prism2_wep_init(int keyidx)
|
||||
{
|
||||
struct prism2_wep_data *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
|
||||
if (priv == NULL)
|
||||
goto fail;
|
||||
priv->key_idx = keyidx;
|
||||
priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR(priv->tx_tfm)) {
|
||||
pr_debug("could not allocate crypto API arc4\n");
|
||||
priv->tx_tfm = NULL;
|
||||
goto fail;
|
||||
}
|
||||
priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR(priv->rx_tfm)) {
|
||||
pr_debug("could not allocate crypto API arc4\n");
|
||||
priv->rx_tfm = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* start WEP IV from a random value */
|
||||
get_random_bytes(&priv->iv, 4);
|
||||
|
||||
return priv;
|
||||
|
||||
fail:
|
||||
if (priv) {
|
||||
if (priv->tx_tfm)
|
||||
crypto_free_blkcipher(priv->tx_tfm);
|
||||
if (priv->rx_tfm)
|
||||
crypto_free_blkcipher(priv->rx_tfm);
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void prism2_wep_deinit(void *priv)
|
||||
{
|
||||
struct prism2_wep_data *_priv = priv;
|
||||
|
||||
if (_priv) {
|
||||
if (_priv->tx_tfm)
|
||||
crypto_free_blkcipher(_priv->tx_tfm);
|
||||
if (_priv->rx_tfm)
|
||||
crypto_free_blkcipher(_priv->rx_tfm);
|
||||
}
|
||||
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
|
||||
* for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
|
||||
* so the payload length increases with 8 bytes.
|
||||
*
|
||||
* WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
|
||||
*/
|
||||
static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct prism2_wep_data *wep = priv;
|
||||
struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
|
||||
u32 klen, len;
|
||||
u8 key[WEP_KEY_LEN + 3];
|
||||
u8 *pos;
|
||||
u32 crc;
|
||||
u8 *icv;
|
||||
struct scatterlist sg;
|
||||
|
||||
if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
|
||||
skb->len < hdr_len)
|
||||
return -1;
|
||||
|
||||
len = skb->len - hdr_len;
|
||||
pos = skb_push(skb, 4);
|
||||
memmove(pos, pos + 4, hdr_len);
|
||||
pos += hdr_len;
|
||||
|
||||
klen = 3 + wep->key_len;
|
||||
|
||||
wep->iv++;
|
||||
|
||||
/* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
|
||||
* scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
|
||||
* can be used to speedup attacks, so avoid using them. */
|
||||
if ((wep->iv & 0xff00) == 0xff00) {
|
||||
u8 B = (wep->iv >> 16) & 0xff;
|
||||
if (B >= 3 && B < klen)
|
||||
wep->iv += 0x0100;
|
||||
}
|
||||
|
||||
/* Prepend 24-bit IV to RC4 key and TX frame */
|
||||
*pos++ = key[0] = (wep->iv >> 16) & 0xff;
|
||||
*pos++ = key[1] = (wep->iv >> 8) & 0xff;
|
||||
*pos++ = key[2] = wep->iv & 0xff;
|
||||
*pos++ = wep->key_idx << 6;
|
||||
|
||||
/* Copy rest of the WEP key (the secret part) */
|
||||
memcpy(key + 3, wep->key, wep->key_len);
|
||||
|
||||
/* Append little-endian CRC32 and encrypt it to produce ICV */
|
||||
crc = ~crc32_le(~0, pos, len);
|
||||
icv = skb_put(skb, 4);
|
||||
icv[0] = crc;
|
||||
icv[1] = crc >> 8;
|
||||
icv[2] = crc >> 16;
|
||||
icv[3] = crc >> 24;
|
||||
|
||||
crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
|
||||
sg_init_one(&sg, pos, len + 4);
|
||||
|
||||
return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
|
||||
}
|
||||
|
||||
/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
|
||||
* the frame: IV (4 bytes), encrypted payload (including SNAP header),
|
||||
* ICV (4 bytes). len includes both IV and ICV.
|
||||
*
|
||||
* Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
|
||||
* failure. If frame is OK, IV and ICV will be removed.
|
||||
*/
|
||||
static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
|
||||
{
|
||||
struct prism2_wep_data *wep = priv;
|
||||
struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
|
||||
u32 klen, plen;
|
||||
u8 key[WEP_KEY_LEN + 3];
|
||||
u8 keyidx, *pos;
|
||||
u32 crc;
|
||||
u8 icv[4];
|
||||
struct scatterlist sg;
|
||||
|
||||
if (skb->len < hdr_len + 8)
|
||||
return -1;
|
||||
|
||||
pos = skb->data + hdr_len;
|
||||
key[0] = *pos++;
|
||||
key[1] = *pos++;
|
||||
key[2] = *pos++;
|
||||
keyidx = *pos++ >> 6;
|
||||
if (keyidx != wep->key_idx)
|
||||
return -1;
|
||||
|
||||
klen = 3 + wep->key_len;
|
||||
|
||||
/* Copy rest of the WEP key (the secret part) */
|
||||
memcpy(key + 3, wep->key, wep->key_len);
|
||||
|
||||
/* Apply RC4 to data and compute CRC32 over decrypted data */
|
||||
plen = skb->len - hdr_len - 8;
|
||||
|
||||
crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
|
||||
sg_init_one(&sg, pos, plen + 4);
|
||||
|
||||
if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
|
||||
return -7;
|
||||
|
||||
crc = ~crc32_le(~0, pos, plen);
|
||||
icv[0] = crc;
|
||||
icv[1] = crc >> 8;
|
||||
icv[2] = crc >> 16;
|
||||
icv[3] = crc >> 24;
|
||||
|
||||
if (memcmp(icv, pos + plen, 4) != 0) {
|
||||
/* ICV mismatch - drop frame */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Remove IV and ICV */
|
||||
memmove(skb->data + 4, skb->data, hdr_len);
|
||||
skb_pull(skb, 4);
|
||||
skb_trim(skb, skb->len - 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
|
||||
{
|
||||
struct prism2_wep_data *wep = priv;
|
||||
|
||||
if (len < 0 || len > WEP_KEY_LEN)
|
||||
return -1;
|
||||
|
||||
memcpy(wep->key, key, len);
|
||||
wep->key_len = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
|
||||
{
|
||||
struct prism2_wep_data *wep = priv;
|
||||
|
||||
if (len < wep->key_len)
|
||||
return -1;
|
||||
|
||||
memcpy(key, wep->key, wep->key_len);
|
||||
|
||||
return wep->key_len;
|
||||
}
|
||||
|
||||
static char *prism2_wep_print_stats(char *p, void *priv)
|
||||
{
|
||||
struct prism2_wep_data *wep = priv;
|
||||
p += sprintf(p, "key[%d] alg=WEP len=%d\n",
|
||||
wep->key_idx, wep->key_len);
|
||||
return p;
|
||||
}
|
||||
|
||||
static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
|
||||
.name = "WEP",
|
||||
.init = prism2_wep_init,
|
||||
.deinit = prism2_wep_deinit,
|
||||
.encrypt_mpdu = prism2_wep_encrypt,
|
||||
.decrypt_mpdu = prism2_wep_decrypt,
|
||||
.encrypt_msdu = NULL,
|
||||
.decrypt_msdu = NULL,
|
||||
.set_key = prism2_wep_set_key,
|
||||
.get_key = prism2_wep_get_key,
|
||||
.print_stats = prism2_wep_print_stats,
|
||||
.extra_prefix_len = 4, /* IV */
|
||||
.extra_postfix_len = 4, /* ICV */
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
int ieee80211_crypto_wep_init(void)
|
||||
{
|
||||
return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
|
||||
}
|
||||
|
||||
void ieee80211_crypto_wep_exit(void)
|
||||
{
|
||||
ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
|
||||
}
|
||||
|
||||
void ieee80211_wep_null(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user