diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/ieee80211/ieee80211_crypt_wep.c | 61 | ||||
| -rw-r--r-- | net/ieee80211/ieee80211_tx.c | 2 | ||||
| -rw-r--r-- | net/ieee80211/ieee80211_wx.c | 2 | ||||
| -rw-r--r-- | net/netlink/af_netlink.c | 2 |
4 files changed, 46 insertions, 21 deletions
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c index 073aebdf0f67..f8dca31be5dd 100644 --- a/net/ieee80211/ieee80211_crypt_wep.c +++ b/net/ieee80211/ieee80211_crypt_wep.c | |||
| @@ -75,22 +75,14 @@ static void prism2_wep_deinit(void *priv) | |||
| 75 | kfree(priv); | 75 | kfree(priv); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | /* Perform WEP encryption on given skb that has at least 4 bytes of headroom | 78 | /* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */ |
| 79 | * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted, | 79 | static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len, void *priv) |
| 80 | * so the payload length increases with 8 bytes. | ||
| 81 | * | ||
| 82 | * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) | ||
| 83 | */ | ||
| 84 | static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | ||
| 85 | { | 80 | { |
| 86 | struct prism2_wep_data *wep = priv; | 81 | struct prism2_wep_data *wep = priv; |
| 87 | u32 crc, klen, len; | 82 | u32 klen, len; |
| 88 | u8 key[WEP_KEY_LEN + 3]; | 83 | u8 *pos; |
| 89 | u8 *pos, *icv; | 84 | |
| 90 | struct scatterlist sg; | 85 | if (skb_headroom(skb) < 4 || skb->len < hdr_len) |
| 91 | |||
| 92 | if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 || | ||
| 93 | skb->len < hdr_len) | ||
| 94 | return -1; | 86 | return -1; |
| 95 | 87 | ||
| 96 | len = skb->len - hdr_len; | 88 | len = skb->len - hdr_len; |
| @@ -112,15 +104,47 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | |||
| 112 | } | 104 | } |
| 113 | 105 | ||
| 114 | /* Prepend 24-bit IV to RC4 key and TX frame */ | 106 | /* Prepend 24-bit IV to RC4 key and TX frame */ |
| 115 | *pos++ = key[0] = (wep->iv >> 16) & 0xff; | 107 | *pos++ = (wep->iv >> 16) & 0xff; |
| 116 | *pos++ = key[1] = (wep->iv >> 8) & 0xff; | 108 | *pos++ = (wep->iv >> 8) & 0xff; |
| 117 | *pos++ = key[2] = wep->iv & 0xff; | 109 | *pos++ = wep->iv & 0xff; |
| 118 | *pos++ = wep->key_idx << 6; | 110 | *pos++ = wep->key_idx << 6; |
| 119 | 111 | ||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | /* Perform WEP encryption on given skb that has at least 4 bytes of headroom | ||
| 116 | * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted, | ||
| 117 | * so the payload length increases with 8 bytes. | ||
| 118 | * | ||
| 119 | * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) | ||
| 120 | */ | ||
| 121 | static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | ||
| 122 | { | ||
| 123 | struct prism2_wep_data *wep = priv; | ||
| 124 | u32 crc, klen, len; | ||
| 125 | u8 *pos, *icv; | ||
| 126 | struct scatterlist sg; | ||
| 127 | u8 key[WEP_KEY_LEN + 3]; | ||
| 128 | |||
| 129 | /* other checks are in prism2_wep_build_iv */ | ||
| 130 | if (skb_tailroom(skb) < 4) | ||
| 131 | return -1; | ||
| 132 | |||
| 133 | /* add the IV to the frame */ | ||
| 134 | if (prism2_wep_build_iv(skb, hdr_len, priv)) | ||
| 135 | return -1; | ||
| 136 | |||
| 137 | /* Copy the IV into the first 3 bytes of the key */ | ||
| 138 | memcpy(key, skb->data + hdr_len, 3); | ||
| 139 | |||
| 120 | /* Copy rest of the WEP key (the secret part) */ | 140 | /* Copy rest of the WEP key (the secret part) */ |
| 121 | memcpy(key + 3, wep->key, wep->key_len); | 141 | memcpy(key + 3, wep->key, wep->key_len); |
| 142 | |||
| 143 | len = skb->len - hdr_len - 4; | ||
| 144 | pos = skb->data + hdr_len + 4; | ||
| 145 | klen = 3 + wep->key_len; | ||
| 122 | 146 | ||
| 123 | /* Append little-endian CRC32 and encrypt it to produce ICV */ | 147 | /* Append little-endian CRC32 over only the data and encrypt it to produce ICV */ |
| 124 | crc = ~crc32_le(~0, pos, len); | 148 | crc = ~crc32_le(~0, pos, len); |
| 125 | icv = skb_put(skb, 4); | 149 | icv = skb_put(skb, 4); |
| 126 | icv[0] = crc; | 150 | icv[0] = crc; |
| @@ -231,6 +255,7 @@ static struct ieee80211_crypto_ops ieee80211_crypt_wep = { | |||
| 231 | .name = "WEP", | 255 | .name = "WEP", |
| 232 | .init = prism2_wep_init, | 256 | .init = prism2_wep_init, |
| 233 | .deinit = prism2_wep_deinit, | 257 | .deinit = prism2_wep_deinit, |
| 258 | .build_iv = prism2_wep_build_iv, | ||
| 234 | .encrypt_mpdu = prism2_wep_encrypt, | 259 | .encrypt_mpdu = prism2_wep_encrypt, |
| 235 | .decrypt_mpdu = prism2_wep_decrypt, | 260 | .decrypt_mpdu = prism2_wep_decrypt, |
| 236 | .encrypt_msdu = NULL, | 261 | .encrypt_msdu = NULL, |
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c index 445f206e65e0..e5b33c8d5dbc 100644 --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c | |||
| @@ -288,7 +288,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 288 | /* Determine total amount of storage required for TXB packets */ | 288 | /* Determine total amount of storage required for TXB packets */ |
| 289 | bytes = skb->len + SNAP_SIZE + sizeof(u16); | 289 | bytes = skb->len + SNAP_SIZE + sizeof(u16); |
| 290 | 290 | ||
| 291 | if (host_encrypt) | 291 | if (host_encrypt || host_build_iv) |
| 292 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | | 292 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | |
| 293 | IEEE80211_FCTL_PROTECTED; | 293 | IEEE80211_FCTL_PROTECTED; |
| 294 | else | 294 | else |
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c index 181755f2aa8b..406d5b964905 100644 --- a/net/ieee80211/ieee80211_wx.c +++ b/net/ieee80211/ieee80211_wx.c | |||
| @@ -284,7 +284,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, | |||
| 284 | }; | 284 | }; |
| 285 | int i, key, key_provided, len; | 285 | int i, key, key_provided, len; |
| 286 | struct ieee80211_crypt_data **crypt; | 286 | struct ieee80211_crypt_data **crypt; |
| 287 | int host_crypto = ieee->host_encrypt || ieee->host_decrypt; | 287 | int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv; |
| 288 | 288 | ||
| 289 | IEEE80211_DEBUG_WX("SET_ENCODE\n"); | 289 | IEEE80211_DEBUG_WX("SET_ENCODE\n"); |
| 290 | 290 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 7849cac14d3a..a67f1b44c9a3 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -402,7 +402,7 @@ static int netlink_create(struct socket *sock, int protocol) | |||
| 402 | groups = nl_table[protocol].groups; | 402 | groups = nl_table[protocol].groups; |
| 403 | netlink_unlock_table(); | 403 | netlink_unlock_table(); |
| 404 | 404 | ||
| 405 | if ((err = __netlink_create(sock, protocol) < 0)) | 405 | if ((err = __netlink_create(sock, protocol)) < 0) |
| 406 | goto out_module; | 406 | goto out_module; |
| 407 | 407 | ||
| 408 | nlk = nlk_sk(sock->sk); | 408 | nlk = nlk_sk(sock->sk); |
