diff options
| -rw-r--r-- | net/mac80211/wep.c | 52 | ||||
| -rw-r--r-- | net/mac80211/wep.h | 4 |
2 files changed, 23 insertions, 33 deletions
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index ef73105b3061..4fafb2d27c84 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
| @@ -67,10 +67,10 @@ static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) | |||
| 67 | 67 | ||
| 68 | 68 | ||
| 69 | static void ieee80211_wep_get_iv(struct ieee80211_local *local, | 69 | static void ieee80211_wep_get_iv(struct ieee80211_local *local, |
| 70 | struct ieee80211_key *key, u8 *iv) | 70 | int keylen, int keyidx, u8 *iv) |
| 71 | { | 71 | { |
| 72 | local->wep_iv++; | 72 | local->wep_iv++; |
| 73 | if (ieee80211_wep_weak_iv(local->wep_iv, key->conf.keylen)) | 73 | if (ieee80211_wep_weak_iv(local->wep_iv, keylen)) |
| 74 | local->wep_iv += 0x0100; | 74 | local->wep_iv += 0x0100; |
| 75 | 75 | ||
| 76 | if (!iv) | 76 | if (!iv) |
| @@ -79,13 +79,13 @@ static void ieee80211_wep_get_iv(struct ieee80211_local *local, | |||
| 79 | *iv++ = (local->wep_iv >> 16) & 0xff; | 79 | *iv++ = (local->wep_iv >> 16) & 0xff; |
| 80 | *iv++ = (local->wep_iv >> 8) & 0xff; | 80 | *iv++ = (local->wep_iv >> 8) & 0xff; |
| 81 | *iv++ = local->wep_iv & 0xff; | 81 | *iv++ = local->wep_iv & 0xff; |
| 82 | *iv++ = key->conf.keyidx << 6; | 82 | *iv++ = keyidx << 6; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | 85 | ||
| 86 | static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, | 86 | static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, |
| 87 | struct sk_buff *skb, | 87 | struct sk_buff *skb, |
| 88 | struct ieee80211_key *key) | 88 | int keylen, int keyidx) |
| 89 | { | 89 | { |
| 90 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 90 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 91 | unsigned int hdrlen; | 91 | unsigned int hdrlen; |
| @@ -100,7 +100,7 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, | |||
| 100 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 100 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 101 | newhdr = skb_push(skb, WEP_IV_LEN); | 101 | newhdr = skb_push(skb, WEP_IV_LEN); |
| 102 | memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); | 102 | memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); |
| 103 | ieee80211_wep_get_iv(local, key, newhdr + hdrlen); | 103 | ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen); |
| 104 | return newhdr + hdrlen; | 104 | return newhdr + hdrlen; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| @@ -144,26 +144,17 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, | |||
| 144 | * | 144 | * |
| 145 | * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) | 145 | * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) |
| 146 | */ | 146 | */ |
| 147 | int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb, | 147 | static int ieee80211_wep_encrypt(struct ieee80211_local *local, |
| 148 | struct ieee80211_key *key) | 148 | struct sk_buff *skb, |
| 149 | const u8 *key, int keylen, int keyidx) | ||
| 149 | { | 150 | { |
| 150 | u32 klen; | 151 | u8 *iv; |
| 151 | u8 *rc4key, *iv; | ||
| 152 | size_t len; | 152 | size_t len; |
| 153 | u8 rc4key[3 + WLAN_KEY_LEN_WEP104]; | ||
| 153 | 154 | ||
| 154 | if (!key || key->conf.alg != ALG_WEP) | 155 | iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx); |
| 155 | return -1; | 156 | if (!iv) |
| 156 | |||
| 157 | klen = 3 + key->conf.keylen; | ||
| 158 | rc4key = kmalloc(klen, GFP_ATOMIC); | ||
| 159 | if (!rc4key) | ||
| 160 | return -1; | ||
| 161 | |||
| 162 | iv = ieee80211_wep_add_iv(local, skb, key); | ||
| 163 | if (!iv) { | ||
| 164 | kfree(rc4key); | ||
| 165 | return -1; | 157 | return -1; |
| 166 | } | ||
| 167 | 158 | ||
| 168 | len = skb->len - (iv + WEP_IV_LEN - skb->data); | 159 | len = skb->len - (iv + WEP_IV_LEN - skb->data); |
| 169 | 160 | ||
| @@ -171,16 +162,14 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
| 171 | memcpy(rc4key, iv, 3); | 162 | memcpy(rc4key, iv, 3); |
| 172 | 163 | ||
| 173 | /* Copy rest of the WEP key (the secret part) */ | 164 | /* Copy rest of the WEP key (the secret part) */ |
| 174 | memcpy(rc4key + 3, key->conf.key, key->conf.keylen); | 165 | memcpy(rc4key + 3, key, keylen); |
| 175 | 166 | ||
| 176 | /* Add room for ICV */ | 167 | /* Add room for ICV */ |
| 177 | skb_put(skb, WEP_ICV_LEN); | 168 | skb_put(skb, WEP_ICV_LEN); |
| 178 | 169 | ||
| 179 | ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, klen, | 170 | ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3, |
| 180 | iv + WEP_IV_LEN, len); | 171 | iv + WEP_IV_LEN, len); |
| 181 | 172 | ||
| 182 | kfree(rc4key); | ||
| 183 | |||
| 184 | return 0; | 173 | return 0; |
| 185 | } | 174 | } |
| 186 | 175 | ||
| @@ -216,8 +205,9 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, | |||
| 216 | * failure. If frame is OK, IV and ICV will be removed, i.e., decrypted payload | 205 | * failure. If frame is OK, IV and ICV will be removed, i.e., decrypted payload |
| 217 | * is moved to the beginning of the skb and skb length will be reduced. | 206 | * is moved to the beginning of the skb and skb length will be reduced. |
| 218 | */ | 207 | */ |
| 219 | int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | 208 | static int ieee80211_wep_decrypt(struct ieee80211_local *local, |
| 220 | struct ieee80211_key *key) | 209 | struct sk_buff *skb, |
| 210 | struct ieee80211_key *key) | ||
| 221 | { | 211 | { |
| 222 | u32 klen; | 212 | u32 klen; |
| 223 | u8 *rc4key; | 213 | u8 *rc4key; |
| @@ -314,12 +304,16 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
| 314 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 304 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 315 | 305 | ||
| 316 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { | 306 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { |
| 317 | if (ieee80211_wep_encrypt(tx->local, skb, tx->key)) | 307 | if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key, |
| 308 | tx->key->conf.keylen, | ||
| 309 | tx->key->conf.keyidx)) | ||
| 318 | return -1; | 310 | return -1; |
| 319 | } else { | 311 | } else { |
| 320 | info->control.hw_key = &tx->key->conf; | 312 | info->control.hw_key = &tx->key->conf; |
| 321 | if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) { | 313 | if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) { |
| 322 | if (!ieee80211_wep_add_iv(tx->local, skb, tx->key)) | 314 | if (!ieee80211_wep_add_iv(tx->local, skb, |
| 315 | tx->key->conf.keylen, | ||
| 316 | tx->key->conf.keyidx)) | ||
| 323 | return -1; | 317 | return -1; |
| 324 | } | 318 | } |
| 325 | } | 319 | } |
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h index d3f0db48314e..85219ded8703 100644 --- a/net/mac80211/wep.h +++ b/net/mac80211/wep.h | |||
| @@ -22,10 +22,6 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, | |||
| 22 | size_t klen, u8 *data, size_t data_len); | 22 | size_t klen, u8 *data, size_t data_len); |
| 23 | int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, | 23 | int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, |
| 24 | size_t klen, u8 *data, size_t data_len); | 24 | size_t klen, u8 *data, size_t data_len); |
| 25 | int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb, | ||
| 26 | struct ieee80211_key *key); | ||
| 27 | int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | ||
| 28 | struct ieee80211_key *key); | ||
| 29 | bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); | 25 | bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); |
| 30 | 26 | ||
| 31 | ieee80211_rx_result | 27 | ieee80211_rx_result |
