Loading include/net/ieee80211.h +166 −3 Original line number Diff line number Diff line Loading @@ -220,6 +220,7 @@ struct ieee80211_snap_hdr { /* Authentication algorithms */ #define WLAN_AUTH_OPEN 0 #define WLAN_AUTH_SHARED_KEY 1 #define WLAN_AUTH_LEAP 2 #define WLAN_AUTH_CHALLENGE_LEN 128 Loading Loading @@ -299,6 +300,23 @@ enum ieee80211_reasoncode { WLAN_REASON_CIPHER_SUITE_REJECTED = 24, }; /* Action categories - 802.11h */ enum ieee80211_actioncategories { WLAN_ACTION_SPECTRUM_MGMT = 0, /* Reserved 1-127 */ /* Error 128-255 */ }; /* Action details - 802.11h */ enum ieee80211_actiondetails { WLAN_ACTION_CATEGORY_MEASURE_REQUEST = 0, WLAN_ACTION_CATEGORY_MEASURE_REPORT = 1, WLAN_ACTION_CATEGORY_TPC_REQUEST = 2, WLAN_ACTION_CATEGORY_TPC_REPORT = 3, WLAN_ACTION_CATEGORY_CHANNEL_SWITCH = 4, /* 5 - 255 Reserved */ }; #define IEEE80211_STATMASK_SIGNAL (1<<0) #define IEEE80211_STATMASK_RSSI (1<<1) #define IEEE80211_STATMASK_NOISE (1<<2) Loading Loading @@ -377,6 +395,8 @@ struct ieee80211_rx_stats { u8 mask; u8 freq; u16 len; u64 tsf; u32 beacon_time; }; /* IEEE 802.11 requires that STA supports concurrent reception of at least Loading Loading @@ -608,6 +628,28 @@ struct ieee80211_auth { struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); struct ieee80211_channel_switch { u8 id; u8 len; u8 mode; u8 channel; u8 count; } __attribute__ ((packed)); struct ieee80211_action { struct ieee80211_hdr_3addr header; u8 category; u8 action; union { struct ieee80211_action_exchange { u8 token; struct ieee80211_info_element info_element[0]; } exchange; struct ieee80211_channel_switch channel_switch; } format; } __attribute__ ((packed)); struct ieee80211_disassoc { struct ieee80211_hdr_3addr header; __le16 reason; Loading Loading @@ -692,7 +734,15 @@ struct ieee80211_txb { /* QoS structure */ #define NETWORK_HAS_QOS_PARAMETERS (1<<3) #define NETWORK_HAS_QOS_INFORMATION (1<<4) #define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | NETWORK_HAS_QOS_INFORMATION) #define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | \ NETWORK_HAS_QOS_INFORMATION) /* 802.11h */ #define NETWORK_HAS_POWER_CONSTRAINT (1<<5) #define NETWORK_HAS_CSA (1<<6) #define NETWORK_HAS_QUIET (1<<7) #define NETWORK_HAS_IBSS_DFS (1<<8) #define NETWORK_HAS_TPC_REPORT (1<<9) #define QOS_QUEUE_NUM 4 #define QOS_OUI_LEN 3 Loading Loading @@ -748,6 +798,91 @@ struct ieee80211_tim_parameters { /*******************************************************/ enum { /* ieee80211_basic_report.map */ IEEE80211_BASIC_MAP_BSS = (1 << 0), IEEE80211_BASIC_MAP_OFDM = (1 << 1), IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2), IEEE80211_BASIC_MAP_RADAR = (1 << 3), IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4), /* Bits 5-7 are reserved */ }; struct ieee80211_basic_report { u8 channel; __le64 start_time; __le16 duration; u8 map; } __attribute__ ((packed)); enum { /* ieee80211_measurement_request.mode */ /* Bit 0 is reserved */ IEEE80211_MEASUREMENT_ENABLE = (1 << 1), IEEE80211_MEASUREMENT_REQUEST = (1 << 2), IEEE80211_MEASUREMENT_REPORT = (1 << 3), /* Bits 4-7 are reserved */ }; enum { IEEE80211_REPORT_BASIC = 0, /* required */ IEEE80211_REPORT_CCA = 1, /* optional */ IEEE80211_REPORT_RPI = 2, /* optional */ /* 3-255 reserved */ }; struct ieee80211_measurement_params { u8 channel; __le64 start_time; __le16 duration; } __attribute__ ((packed)); struct ieee80211_measurement_request { struct ieee80211_info_element ie; u8 token; u8 mode; u8 type; struct ieee80211_measurement_params params[0]; } __attribute__ ((packed)); struct ieee80211_measurement_report { struct ieee80211_info_element ie; u8 token; u8 mode; u8 type; union { struct ieee80211_basic_report basic[0]; } u; } __attribute__ ((packed)); struct ieee80211_tpc_report { u8 transmit_power; u8 link_margin; } __attribute__ ((packed)); struct ieee80211_channel_map { u8 channel; u8 map; } __attribute__ ((packed)); struct ieee80211_ibss_dfs { struct ieee80211_info_element ie; u8 owner[ETH_ALEN]; u8 recovery_interval; struct ieee80211_channel_map channel_map[0]; }; struct ieee80211_csa { u8 mode; u8 channel; u8 count; } __attribute__ ((packed)); struct ieee80211_quiet { u8 count; u8 period; u8 duration; u8 offset; } __attribute__ ((packed)); struct ieee80211_network { /* These entries are used to identify a unique network */ u8 bssid[ETH_ALEN]; Loading @@ -767,7 +902,7 @@ struct ieee80211_network { u8 rates_ex_len; unsigned long last_scanned; u8 mode; u8 flags; u32 flags; u32 last_associate; u32 time_stamp[2]; u16 beacon_interval; Loading @@ -779,6 +914,25 @@ struct ieee80211_network { u8 rsn_ie[MAX_WPA_IE_LEN]; size_t rsn_ie_len; struct ieee80211_tim_parameters tim; /* 802.11h info */ /* Power Constraint - mandatory if spctrm mgmt required */ u8 power_constraint; /* TPC Report - mandatory if spctrm mgmt required */ struct ieee80211_tpc_report tpc_report; /* IBSS DFS - mandatory if spctrm mgmt required and IBSS * NOTE: This is variable length and so must be allocated dynamically */ struct ieee80211_ibss_dfs *ibss_dfs; /* Channel Switch Announcement - optional if spctrm mgmt required */ struct ieee80211_csa csa; /* Quiet - optional if spctrm mgmt required */ struct ieee80211_quiet quiet; struct list_head list; }; Loading Loading @@ -924,7 +1078,10 @@ struct ieee80211_device { int (*handle_auth) (struct net_device * dev, struct ieee80211_auth * auth); int (*handle_deauth) (struct net_device * dev, struct ieee80211_auth * auth); struct ieee80211_deauth * auth); int (*handle_action) (struct net_device * dev, struct ieee80211_action * action, struct ieee80211_rx_stats * stats); int (*handle_disassoc) (struct net_device * dev, struct ieee80211_disassoc * assoc); int (*handle_beacon) (struct net_device * dev, Loading Loading @@ -1093,6 +1250,7 @@ extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, struct ieee80211_hdr_4addr *header, struct ieee80211_rx_stats *stats); extern void ieee80211_network_reset(struct ieee80211_network *network); /* ieee80211_geo.c */ extern const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device Loading @@ -1105,6 +1263,11 @@ extern int ieee80211_is_valid_channel(struct ieee80211_device *ieee, extern int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel); extern u8 ieee80211_freq_to_channel(struct ieee80211_device *ieee, u32 freq); extern u8 ieee80211_get_channel_flags(struct ieee80211_device *ieee, u8 channel); extern const struct ieee80211_channel *ieee80211_get_channel(struct ieee80211_device *ieee, u8 channel); /* ieee80211_wx.c */ extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee, Loading include/net/ieee80211_crypt.h +2 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,8 @@ struct ieee80211_crypto_ops { /* deinitialize crypto context and free allocated private data */ void (*deinit) (void *priv); int (*build_iv) (struct sk_buff * skb, int hdr_len, void *priv); int (*build_iv) (struct sk_buff * skb, int hdr_len, u8 *key, int keylen, 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 Loading net/ieee80211/ieee80211_crypt.c +5 −6 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ #include <linux/string.h> #include <net/ieee80211.h> MODULE_AUTHOR("Jouni Malinen"); MODULE_DESCRIPTION("HostAP crypto"); MODULE_LICENSE("GPL"); Loading net/ieee80211/ieee80211_crypt_ccmp.c +6 −2 Original line number Diff line number Diff line Loading @@ -190,7 +190,8 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, ieee80211_ccmp_aes_encrypt(tfm, b0, s0); } static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, void *priv) static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, u8 *aeskey, int keylen, void *priv) { struct ieee80211_ccmp_data *key = priv; int i; Loading @@ -199,6 +200,9 @@ static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, void *priv) if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len) return -1; if (aeskey != NULL && keylen >= CCMP_TK_LEN) memcpy(aeskey, key->key, CCMP_TK_LEN); pos = skb_push(skb, CCMP_HDR_LEN); memmove(pos, pos + CCMP_HDR_LEN, hdr_len); pos += hdr_len; Loading Loading @@ -238,7 +242,7 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) return -1; data_len = skb->len - hdr_len; len = ieee80211_ccmp_hdr(skb, hdr_len, priv); len = ieee80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv); if (len < 0) return -1; Loading net/ieee80211/ieee80211_crypt_tkip.c +28 −28 Original line number Diff line number Diff line Loading @@ -80,10 +80,9 @@ static void *ieee80211_tkip_init(int key_idx) { struct ieee80211_tkip_data *priv; priv = kmalloc(sizeof(*priv), GFP_ATOMIC); priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; Loading Loading @@ -271,34 +270,33 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK, #endif } static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv) static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, u8 * rc4key, int keylen, void *priv) { struct ieee80211_tkip_data *tkey = priv; int len; u8 *rc4key, *pos, *icv; u8 *pos; struct ieee80211_hdr_4addr *hdr; u32 crc; hdr = (struct ieee80211_hdr_4addr *)skb->data; if (skb_headroom(skb) < 8 || skb->len < hdr_len) return NULL; return -1; if (rc4key == NULL || keylen < 16) return -1; if (!tkey->tx_phase1_done) { tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, tkey->tx_iv32); tkey->tx_phase1_done = 1; } rc4key = kmalloc(16, GFP_ATOMIC); if (!rc4key) return NULL; tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); len = skb->len - hdr_len; pos = skb_push(skb, 8); memmove(pos, pos + 8, hdr_len); pos += hdr_len; icv = skb_put(skb, 4); *pos++ = *rc4key; *pos++ = *(rc4key + 1); Loading @@ -309,28 +307,28 @@ static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv) *pos++ = (tkey->tx_iv32 >> 16) & 0xff; *pos++ = (tkey->tx_iv32 >> 24) & 0xff; crc = ~crc32_le(~0, pos, len); icv[0] = crc; icv[1] = crc >> 8; icv[2] = crc >> 16; icv[3] = crc >> 24; tkey->tx_iv16++; if (tkey->tx_iv16 == 0) { tkey->tx_phase1_done = 0; tkey->tx_iv32++; } return rc4key; return 8; } static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) { struct ieee80211_tkip_data *tkey = priv; int len; const u8 *rc4key; u8 *pos; u8 rc4key[16], *pos, *icv; u32 crc; struct scatterlist sg; if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { if (net_ratelimit()) { struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *)skb->data; printk(KERN_DEBUG "TKIP countermeasures: dropped " printk(KERN_DEBUG ": TKIP countermeasures: dropped " "TX packet to " MAC_FMT "\n", MAC_ARG(hdr->addr1)); } Loading @@ -343,22 +341,23 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) len = skb->len - hdr_len; pos = skb->data + hdr_len; rc4key = ieee80211_tkip_hdr(skb, hdr_len, priv); if (!rc4key) if ((ieee80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0) return -1; icv = skb_put(skb, 4); crc = ~crc32_le(~0, pos, len); icv[0] = crc; icv[1] = crc >> 8; icv[2] = crc >> 16; icv[3] = crc >> 24; crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); sg.page = virt_to_page(pos); sg.offset = offset_in_page(pos); sg.length = len + 4; crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4); tkey->tx_iv16++; if (tkey->tx_iv16 == 0) { tkey->tx_phase1_done = 0; tkey->tx_iv32++; } return 0; } Loading @@ -379,7 +378,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { if (net_ratelimit()) { printk(KERN_DEBUG "TKIP countermeasures: dropped " printk(KERN_DEBUG ": TKIP countermeasures: dropped " "received packet from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); } Loading Loading @@ -695,6 +694,7 @@ static struct ieee80211_crypto_ops ieee80211_crypt_tkip = { .name = "TKIP", .init = ieee80211_tkip_init, .deinit = ieee80211_tkip_deinit, .build_iv = ieee80211_tkip_hdr, .encrypt_mpdu = ieee80211_tkip_encrypt, .decrypt_mpdu = ieee80211_tkip_decrypt, .encrypt_msdu = ieee80211_michael_mic_add, Loading Loading
include/net/ieee80211.h +166 −3 Original line number Diff line number Diff line Loading @@ -220,6 +220,7 @@ struct ieee80211_snap_hdr { /* Authentication algorithms */ #define WLAN_AUTH_OPEN 0 #define WLAN_AUTH_SHARED_KEY 1 #define WLAN_AUTH_LEAP 2 #define WLAN_AUTH_CHALLENGE_LEN 128 Loading Loading @@ -299,6 +300,23 @@ enum ieee80211_reasoncode { WLAN_REASON_CIPHER_SUITE_REJECTED = 24, }; /* Action categories - 802.11h */ enum ieee80211_actioncategories { WLAN_ACTION_SPECTRUM_MGMT = 0, /* Reserved 1-127 */ /* Error 128-255 */ }; /* Action details - 802.11h */ enum ieee80211_actiondetails { WLAN_ACTION_CATEGORY_MEASURE_REQUEST = 0, WLAN_ACTION_CATEGORY_MEASURE_REPORT = 1, WLAN_ACTION_CATEGORY_TPC_REQUEST = 2, WLAN_ACTION_CATEGORY_TPC_REPORT = 3, WLAN_ACTION_CATEGORY_CHANNEL_SWITCH = 4, /* 5 - 255 Reserved */ }; #define IEEE80211_STATMASK_SIGNAL (1<<0) #define IEEE80211_STATMASK_RSSI (1<<1) #define IEEE80211_STATMASK_NOISE (1<<2) Loading Loading @@ -377,6 +395,8 @@ struct ieee80211_rx_stats { u8 mask; u8 freq; u16 len; u64 tsf; u32 beacon_time; }; /* IEEE 802.11 requires that STA supports concurrent reception of at least Loading Loading @@ -608,6 +628,28 @@ struct ieee80211_auth { struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); struct ieee80211_channel_switch { u8 id; u8 len; u8 mode; u8 channel; u8 count; } __attribute__ ((packed)); struct ieee80211_action { struct ieee80211_hdr_3addr header; u8 category; u8 action; union { struct ieee80211_action_exchange { u8 token; struct ieee80211_info_element info_element[0]; } exchange; struct ieee80211_channel_switch channel_switch; } format; } __attribute__ ((packed)); struct ieee80211_disassoc { struct ieee80211_hdr_3addr header; __le16 reason; Loading Loading @@ -692,7 +734,15 @@ struct ieee80211_txb { /* QoS structure */ #define NETWORK_HAS_QOS_PARAMETERS (1<<3) #define NETWORK_HAS_QOS_INFORMATION (1<<4) #define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | NETWORK_HAS_QOS_INFORMATION) #define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | \ NETWORK_HAS_QOS_INFORMATION) /* 802.11h */ #define NETWORK_HAS_POWER_CONSTRAINT (1<<5) #define NETWORK_HAS_CSA (1<<6) #define NETWORK_HAS_QUIET (1<<7) #define NETWORK_HAS_IBSS_DFS (1<<8) #define NETWORK_HAS_TPC_REPORT (1<<9) #define QOS_QUEUE_NUM 4 #define QOS_OUI_LEN 3 Loading Loading @@ -748,6 +798,91 @@ struct ieee80211_tim_parameters { /*******************************************************/ enum { /* ieee80211_basic_report.map */ IEEE80211_BASIC_MAP_BSS = (1 << 0), IEEE80211_BASIC_MAP_OFDM = (1 << 1), IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2), IEEE80211_BASIC_MAP_RADAR = (1 << 3), IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4), /* Bits 5-7 are reserved */ }; struct ieee80211_basic_report { u8 channel; __le64 start_time; __le16 duration; u8 map; } __attribute__ ((packed)); enum { /* ieee80211_measurement_request.mode */ /* Bit 0 is reserved */ IEEE80211_MEASUREMENT_ENABLE = (1 << 1), IEEE80211_MEASUREMENT_REQUEST = (1 << 2), IEEE80211_MEASUREMENT_REPORT = (1 << 3), /* Bits 4-7 are reserved */ }; enum { IEEE80211_REPORT_BASIC = 0, /* required */ IEEE80211_REPORT_CCA = 1, /* optional */ IEEE80211_REPORT_RPI = 2, /* optional */ /* 3-255 reserved */ }; struct ieee80211_measurement_params { u8 channel; __le64 start_time; __le16 duration; } __attribute__ ((packed)); struct ieee80211_measurement_request { struct ieee80211_info_element ie; u8 token; u8 mode; u8 type; struct ieee80211_measurement_params params[0]; } __attribute__ ((packed)); struct ieee80211_measurement_report { struct ieee80211_info_element ie; u8 token; u8 mode; u8 type; union { struct ieee80211_basic_report basic[0]; } u; } __attribute__ ((packed)); struct ieee80211_tpc_report { u8 transmit_power; u8 link_margin; } __attribute__ ((packed)); struct ieee80211_channel_map { u8 channel; u8 map; } __attribute__ ((packed)); struct ieee80211_ibss_dfs { struct ieee80211_info_element ie; u8 owner[ETH_ALEN]; u8 recovery_interval; struct ieee80211_channel_map channel_map[0]; }; struct ieee80211_csa { u8 mode; u8 channel; u8 count; } __attribute__ ((packed)); struct ieee80211_quiet { u8 count; u8 period; u8 duration; u8 offset; } __attribute__ ((packed)); struct ieee80211_network { /* These entries are used to identify a unique network */ u8 bssid[ETH_ALEN]; Loading @@ -767,7 +902,7 @@ struct ieee80211_network { u8 rates_ex_len; unsigned long last_scanned; u8 mode; u8 flags; u32 flags; u32 last_associate; u32 time_stamp[2]; u16 beacon_interval; Loading @@ -779,6 +914,25 @@ struct ieee80211_network { u8 rsn_ie[MAX_WPA_IE_LEN]; size_t rsn_ie_len; struct ieee80211_tim_parameters tim; /* 802.11h info */ /* Power Constraint - mandatory if spctrm mgmt required */ u8 power_constraint; /* TPC Report - mandatory if spctrm mgmt required */ struct ieee80211_tpc_report tpc_report; /* IBSS DFS - mandatory if spctrm mgmt required and IBSS * NOTE: This is variable length and so must be allocated dynamically */ struct ieee80211_ibss_dfs *ibss_dfs; /* Channel Switch Announcement - optional if spctrm mgmt required */ struct ieee80211_csa csa; /* Quiet - optional if spctrm mgmt required */ struct ieee80211_quiet quiet; struct list_head list; }; Loading Loading @@ -924,7 +1078,10 @@ struct ieee80211_device { int (*handle_auth) (struct net_device * dev, struct ieee80211_auth * auth); int (*handle_deauth) (struct net_device * dev, struct ieee80211_auth * auth); struct ieee80211_deauth * auth); int (*handle_action) (struct net_device * dev, struct ieee80211_action * action, struct ieee80211_rx_stats * stats); int (*handle_disassoc) (struct net_device * dev, struct ieee80211_disassoc * assoc); int (*handle_beacon) (struct net_device * dev, Loading Loading @@ -1093,6 +1250,7 @@ extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, struct ieee80211_hdr_4addr *header, struct ieee80211_rx_stats *stats); extern void ieee80211_network_reset(struct ieee80211_network *network); /* ieee80211_geo.c */ extern const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device Loading @@ -1105,6 +1263,11 @@ extern int ieee80211_is_valid_channel(struct ieee80211_device *ieee, extern int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel); extern u8 ieee80211_freq_to_channel(struct ieee80211_device *ieee, u32 freq); extern u8 ieee80211_get_channel_flags(struct ieee80211_device *ieee, u8 channel); extern const struct ieee80211_channel *ieee80211_get_channel(struct ieee80211_device *ieee, u8 channel); /* ieee80211_wx.c */ extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee, Loading
include/net/ieee80211_crypt.h +2 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,8 @@ struct ieee80211_crypto_ops { /* deinitialize crypto context and free allocated private data */ void (*deinit) (void *priv); int (*build_iv) (struct sk_buff * skb, int hdr_len, void *priv); int (*build_iv) (struct sk_buff * skb, int hdr_len, u8 *key, int keylen, 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 Loading
net/ieee80211/ieee80211_crypt.c +5 −6 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ #include <linux/string.h> #include <net/ieee80211.h> MODULE_AUTHOR("Jouni Malinen"); MODULE_DESCRIPTION("HostAP crypto"); MODULE_LICENSE("GPL"); Loading
net/ieee80211/ieee80211_crypt_ccmp.c +6 −2 Original line number Diff line number Diff line Loading @@ -190,7 +190,8 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, ieee80211_ccmp_aes_encrypt(tfm, b0, s0); } static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, void *priv) static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, u8 *aeskey, int keylen, void *priv) { struct ieee80211_ccmp_data *key = priv; int i; Loading @@ -199,6 +200,9 @@ static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, void *priv) if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len) return -1; if (aeskey != NULL && keylen >= CCMP_TK_LEN) memcpy(aeskey, key->key, CCMP_TK_LEN); pos = skb_push(skb, CCMP_HDR_LEN); memmove(pos, pos + CCMP_HDR_LEN, hdr_len); pos += hdr_len; Loading Loading @@ -238,7 +242,7 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) return -1; data_len = skb->len - hdr_len; len = ieee80211_ccmp_hdr(skb, hdr_len, priv); len = ieee80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv); if (len < 0) return -1; Loading
net/ieee80211/ieee80211_crypt_tkip.c +28 −28 Original line number Diff line number Diff line Loading @@ -80,10 +80,9 @@ static void *ieee80211_tkip_init(int key_idx) { struct ieee80211_tkip_data *priv; priv = kmalloc(sizeof(*priv), GFP_ATOMIC); priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; Loading Loading @@ -271,34 +270,33 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK, #endif } static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv) static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, u8 * rc4key, int keylen, void *priv) { struct ieee80211_tkip_data *tkey = priv; int len; u8 *rc4key, *pos, *icv; u8 *pos; struct ieee80211_hdr_4addr *hdr; u32 crc; hdr = (struct ieee80211_hdr_4addr *)skb->data; if (skb_headroom(skb) < 8 || skb->len < hdr_len) return NULL; return -1; if (rc4key == NULL || keylen < 16) return -1; if (!tkey->tx_phase1_done) { tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, tkey->tx_iv32); tkey->tx_phase1_done = 1; } rc4key = kmalloc(16, GFP_ATOMIC); if (!rc4key) return NULL; tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); len = skb->len - hdr_len; pos = skb_push(skb, 8); memmove(pos, pos + 8, hdr_len); pos += hdr_len; icv = skb_put(skb, 4); *pos++ = *rc4key; *pos++ = *(rc4key + 1); Loading @@ -309,28 +307,28 @@ static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv) *pos++ = (tkey->tx_iv32 >> 16) & 0xff; *pos++ = (tkey->tx_iv32 >> 24) & 0xff; crc = ~crc32_le(~0, pos, len); icv[0] = crc; icv[1] = crc >> 8; icv[2] = crc >> 16; icv[3] = crc >> 24; tkey->tx_iv16++; if (tkey->tx_iv16 == 0) { tkey->tx_phase1_done = 0; tkey->tx_iv32++; } return rc4key; return 8; } static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) { struct ieee80211_tkip_data *tkey = priv; int len; const u8 *rc4key; u8 *pos; u8 rc4key[16], *pos, *icv; u32 crc; struct scatterlist sg; if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { if (net_ratelimit()) { struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *)skb->data; printk(KERN_DEBUG "TKIP countermeasures: dropped " printk(KERN_DEBUG ": TKIP countermeasures: dropped " "TX packet to " MAC_FMT "\n", MAC_ARG(hdr->addr1)); } Loading @@ -343,22 +341,23 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) len = skb->len - hdr_len; pos = skb->data + hdr_len; rc4key = ieee80211_tkip_hdr(skb, hdr_len, priv); if (!rc4key) if ((ieee80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0) return -1; icv = skb_put(skb, 4); crc = ~crc32_le(~0, pos, len); icv[0] = crc; icv[1] = crc >> 8; icv[2] = crc >> 16; icv[3] = crc >> 24; crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); sg.page = virt_to_page(pos); sg.offset = offset_in_page(pos); sg.length = len + 4; crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4); tkey->tx_iv16++; if (tkey->tx_iv16 == 0) { tkey->tx_phase1_done = 0; tkey->tx_iv32++; } return 0; } Loading @@ -379,7 +378,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { if (net_ratelimit()) { printk(KERN_DEBUG "TKIP countermeasures: dropped " printk(KERN_DEBUG ": TKIP countermeasures: dropped " "received packet from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); } Loading Loading @@ -695,6 +694,7 @@ static struct ieee80211_crypto_ops ieee80211_crypt_tkip = { .name = "TKIP", .init = ieee80211_tkip_init, .deinit = ieee80211_tkip_deinit, .build_iv = ieee80211_tkip_hdr, .encrypt_mpdu = ieee80211_tkip_encrypt, .decrypt_mpdu = ieee80211_tkip_decrypt, .encrypt_msdu = ieee80211_michael_mic_add, Loading