diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-07-07 21:07:49 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-07-08 22:35:50 +0200 |
commit | 3473187d2459a078e00e5fac8aafc30af69c57fa (patch) | |
tree | 93c3da6dbcbfd09ea81884bee790219d4cee0d56 /net/mac80211/wep.c | |
parent | ath9k: fix a buffer leak in A-MPDU completion (diff) | |
download | linux-3473187d2459a078e00e5fac8aafc30af69c57fa.tar.xz linux-3473187d2459a078e00e5fac8aafc30af69c57fa.zip |
mac80211: remove wep dependency
The current mac80211 code assumes that WEP is always available. If WEP
fails to initialize, ieee80211_register_hw will always fail.
In some cases (e.g. FIPS certification), the cryptography used by WEP is
unavailable. However, in such cases there is no good reason why CCMP
encryption (or even no link level encryption) cannot be used. So, this
patch removes mac80211's assumption that WEP (and TKIP) will always be
available for use.
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/wep.c')
-rw-r--r-- | net/mac80211/wep.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 5f3a4113bda1..6d133b6efce5 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -47,8 +47,10 @@ int ieee80211_wep_init(struct ieee80211_local *local) void ieee80211_wep_free(struct ieee80211_local *local) { - crypto_free_blkcipher(local->wep_tx_tfm); - crypto_free_blkcipher(local->wep_rx_tfm); + if (!IS_ERR(local->wep_tx_tfm)) + crypto_free_blkcipher(local->wep_tx_tfm); + if (!IS_ERR(local->wep_rx_tfm)) + crypto_free_blkcipher(local->wep_rx_tfm); } static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) @@ -122,19 +124,24 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local, /* Perform WEP encryption using given key. data buffer must have tailroom * for 4-byte ICV. data_len must not include this ICV. Note: this function * does _not_ add IV. data = RC4(data | CRC32(data)) */ -void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, - size_t klen, u8 *data, size_t data_len) +int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, + size_t klen, u8 *data, size_t data_len) { struct blkcipher_desc desc = { .tfm = tfm }; struct scatterlist sg; __le32 icv; + if (IS_ERR(tfm)) + return -1; + icv = cpu_to_le32(~crc32_le(~0, data, data_len)); put_unaligned(icv, (__le32 *)(data + data_len)); crypto_blkcipher_setkey(tfm, rc4key, klen); sg_init_one(&sg, data, data_len + WEP_ICV_LEN); crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length); + + return 0; } @@ -168,10 +175,8 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, /* Add room for ICV */ skb_put(skb, WEP_ICV_LEN); - ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3, - iv + WEP_IV_LEN, len); - - return 0; + return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3, + iv + WEP_IV_LEN, len); } @@ -185,6 +190,9 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, struct scatterlist sg; __le32 crc; + if (IS_ERR(tfm)) + return -1; + crypto_blkcipher_setkey(tfm, rc4key, klen); sg_init_one(&sg, data, data_len + WEP_ICV_LEN); crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length); |