Commit 5f9f1812 authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville

mac80211: remove the dependency on crypto_blkcipher

The only thing that using crypto_blkcipher with ecb does over just using
arc4 directly is wrapping the encrypt/decrypt function into a for loop,
looping over each individual character.
To be able to do this, it pulls in around 40 kb worth of unnecessary
kernel modules (at least on a MIPS embedded device).
Using arc4 directly not only eliminates those dependencies, it also makes
the code smaller.
Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 203afeca
...@@ -2,7 +2,6 @@ config MAC80211 ...@@ -2,7 +2,6 @@ config MAC80211
tristate "Generic IEEE 802.11 Networking Stack (mac80211)" tristate "Generic IEEE 802.11 Networking Stack (mac80211)"
depends on CFG80211 depends on CFG80211
select CRYPTO select CRYPTO
select CRYPTO_ECB
select CRYPTO_ARC4 select CRYPTO_ARC4
select CRYPTO_AES select CRYPTO_AES
select CRC32 select CRC32
......
...@@ -809,8 +809,8 @@ struct ieee80211_local { ...@@ -809,8 +809,8 @@ struct ieee80211_local {
struct rate_control_ref *rate_ctrl; struct rate_control_ref *rate_ctrl;
struct crypto_blkcipher *wep_tx_tfm; struct crypto_cipher *wep_tx_tfm;
struct crypto_blkcipher *wep_rx_tfm; struct crypto_cipher *wep_rx_tfm;
u32 wep_iv; u32 wep_iv;
/* see iface.c */ /* see iface.c */
......
...@@ -202,7 +202,7 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key); ...@@ -202,7 +202,7 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key);
* @payload_len is the length of payload (_not_ including IV/ICV length). * @payload_len is the length of payload (_not_ including IV/ICV length).
* @ta is the transmitter addresses. * @ta is the transmitter addresses.
*/ */
int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
struct ieee80211_key *key, struct ieee80211_key *key,
u8 *pos, size_t payload_len, u8 *ta) u8 *pos, size_t payload_len, u8 *ta)
{ {
...@@ -223,7 +223,7 @@ int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, ...@@ -223,7 +223,7 @@ int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
* beginning of the buffer containing IEEE 802.11 header payload, i.e., * beginning of the buffer containing IEEE 802.11 header payload, i.e.,
* including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the
* length of payload, including IV, Ext. IV, MIC, ICV. */ * length of payload, including IV, Ext. IV, MIC, ICV. */
int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm,
struct ieee80211_key *key, struct ieee80211_key *key,
u8 *payload, size_t payload_len, u8 *ta, u8 *payload, size_t payload_len, u8 *ta,
u8 *ra, int only_iv, int queue, u8 *ra, int only_iv, int queue,
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16); u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16);
int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
struct ieee80211_key *key, struct ieee80211_key *key,
u8 *pos, size_t payload_len, u8 *ta); u8 *pos, size_t payload_len, u8 *ta);
enum { enum {
...@@ -24,7 +24,7 @@ enum { ...@@ -24,7 +24,7 @@ enum {
TKIP_DECRYPT_INVALID_KEYIDX = -2, TKIP_DECRYPT_INVALID_KEYIDX = -2,
TKIP_DECRYPT_REPLAY = -3, TKIP_DECRYPT_REPLAY = -3,
}; };
int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm,
struct ieee80211_key *key, struct ieee80211_key *key,
u8 *payload, size_t payload_len, u8 *ta, u8 *payload, size_t payload_len, u8 *ta,
u8 *ra, int only_iv, int queue, u8 *ra, int only_iv, int queue,
......
...@@ -30,17 +30,15 @@ int ieee80211_wep_init(struct ieee80211_local *local) ...@@ -30,17 +30,15 @@ int ieee80211_wep_init(struct ieee80211_local *local)
/* start WEP IV from a random value */ /* start WEP IV from a random value */
get_random_bytes(&local->wep_iv, WEP_IV_LEN); get_random_bytes(&local->wep_iv, WEP_IV_LEN);
local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC);
CRYPTO_ALG_ASYNC);
if (IS_ERR(local->wep_tx_tfm)) { if (IS_ERR(local->wep_tx_tfm)) {
local->wep_rx_tfm = ERR_PTR(-EINVAL); local->wep_rx_tfm = ERR_PTR(-EINVAL);
return PTR_ERR(local->wep_tx_tfm); return PTR_ERR(local->wep_tx_tfm);
} }
local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, local->wep_rx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC);
CRYPTO_ALG_ASYNC);
if (IS_ERR(local->wep_rx_tfm)) { if (IS_ERR(local->wep_rx_tfm)) {
crypto_free_blkcipher(local->wep_tx_tfm); crypto_free_cipher(local->wep_tx_tfm);
local->wep_tx_tfm = ERR_PTR(-EINVAL); local->wep_tx_tfm = ERR_PTR(-EINVAL);
return PTR_ERR(local->wep_rx_tfm); return PTR_ERR(local->wep_rx_tfm);
} }
...@@ -51,9 +49,9 @@ int ieee80211_wep_init(struct ieee80211_local *local) ...@@ -51,9 +49,9 @@ int ieee80211_wep_init(struct ieee80211_local *local)
void ieee80211_wep_free(struct ieee80211_local *local) void ieee80211_wep_free(struct ieee80211_local *local)
{ {
if (!IS_ERR(local->wep_tx_tfm)) if (!IS_ERR(local->wep_tx_tfm))
crypto_free_blkcipher(local->wep_tx_tfm); crypto_free_cipher(local->wep_tx_tfm);
if (!IS_ERR(local->wep_rx_tfm)) if (!IS_ERR(local->wep_rx_tfm))
crypto_free_blkcipher(local->wep_rx_tfm); crypto_free_cipher(local->wep_rx_tfm);
} }
static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen)
...@@ -127,12 +125,11 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local, ...@@ -127,12 +125,11 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
/* Perform WEP encryption using given key. data buffer must have tailroom /* 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 * for 4-byte ICV. data_len must not include this ICV. Note: this function
* does _not_ add IV. data = RC4(data | CRC32(data)) */ * does _not_ add IV. data = RC4(data | CRC32(data)) */
int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
size_t klen, u8 *data, size_t data_len) size_t klen, u8 *data, size_t data_len)
{ {
struct blkcipher_desc desc = { .tfm = tfm };
struct scatterlist sg;
__le32 icv; __le32 icv;
int i;
if (IS_ERR(tfm)) if (IS_ERR(tfm))
return -1; return -1;
...@@ -140,9 +137,9 @@ int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, ...@@ -140,9 +137,9 @@ int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
icv = cpu_to_le32(~crc32_le(~0, data, data_len)); icv = cpu_to_le32(~crc32_le(~0, data, data_len));
put_unaligned(icv, (__le32 *)(data + data_len)); put_unaligned(icv, (__le32 *)(data + data_len));
crypto_blkcipher_setkey(tfm, rc4key, klen); crypto_cipher_setkey(tfm, rc4key, klen);
sg_init_one(&sg, data, data_len + WEP_ICV_LEN); for (i = 0; i < data_len + WEP_ICV_LEN; i++)
crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length); crypto_cipher_encrypt_one(tfm, data + i, data + i);
return 0; return 0;
} }
...@@ -186,19 +183,18 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, ...@@ -186,19 +183,18 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
/* Perform WEP decryption using given key. data buffer includes encrypted /* Perform WEP decryption using given key. data buffer includes encrypted
* payload, including 4-byte ICV, but _not_ IV. data_len must not include ICV. * payload, including 4-byte ICV, but _not_ IV. data_len must not include ICV.
* Return 0 on success and -1 on ICV mismatch. */ * Return 0 on success and -1 on ICV mismatch. */
int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
size_t klen, u8 *data, size_t data_len) size_t klen, u8 *data, size_t data_len)
{ {
struct blkcipher_desc desc = { .tfm = tfm };
struct scatterlist sg;
__le32 crc; __le32 crc;
int i;
if (IS_ERR(tfm)) if (IS_ERR(tfm))
return -1; return -1;
crypto_blkcipher_setkey(tfm, rc4key, klen); crypto_cipher_setkey(tfm, rc4key, klen);
sg_init_one(&sg, data, data_len + WEP_ICV_LEN); for (i = 0; i < data_len + WEP_ICV_LEN; i++)
crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length); crypto_cipher_decrypt_one(tfm, data + i, data + i);
crc = cpu_to_le32(~crc32_le(~0, data, data_len)); crc = cpu_to_le32(~crc32_le(~0, data, data_len));
if (memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0) if (memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0)
......
...@@ -18,12 +18,12 @@ ...@@ -18,12 +18,12 @@
int ieee80211_wep_init(struct ieee80211_local *local); int ieee80211_wep_init(struct ieee80211_local *local);
void ieee80211_wep_free(struct ieee80211_local *local); void ieee80211_wep_free(struct ieee80211_local *local);
int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
size_t klen, u8 *data, size_t data_len); size_t klen, u8 *data, size_t data_len);
int ieee80211_wep_encrypt(struct ieee80211_local *local, int ieee80211_wep_encrypt(struct ieee80211_local *local,
struct sk_buff *skb, struct sk_buff *skb,
const u8 *key, int keylen, int keyidx); const u8 *key, int keylen, int keyidx);
int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
size_t klen, u8 *data, size_t data_len); size_t klen, u8 *data, size_t data_len);
bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment