Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Felix Fietkau and committed by
John W. Linville
5f9f1812 203afeca

+23 -28
-1
net/mac80211/Kconfig
··· 2 2 tristate "Generic IEEE 802.11 Networking Stack (mac80211)" 3 3 depends on CFG80211 4 4 select CRYPTO 5 - select CRYPTO_ECB 6 5 select CRYPTO_ARC4 7 6 select CRYPTO_AES 8 7 select CRC32
+2 -2
net/mac80211/ieee80211_i.h
··· 809 809 810 810 struct rate_control_ref *rate_ctrl; 811 811 812 - struct crypto_blkcipher *wep_tx_tfm; 813 - struct crypto_blkcipher *wep_rx_tfm; 812 + struct crypto_cipher *wep_tx_tfm; 813 + struct crypto_cipher *wep_rx_tfm; 814 814 u32 wep_iv; 815 815 816 816 /* see iface.c */
+2 -2
net/mac80211/tkip.c
··· 202 202 * @payload_len is the length of payload (_not_ including IV/ICV length). 203 203 * @ta is the transmitter addresses. 204 204 */ 205 - int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, 205 + int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, 206 206 struct ieee80211_key *key, 207 207 u8 *pos, size_t payload_len, u8 *ta) 208 208 { ··· 223 223 * beginning of the buffer containing IEEE 802.11 header payload, i.e., 224 224 * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the 225 225 * length of payload, including IV, Ext. IV, MIC, ICV. */ 226 - int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, 226 + int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, 227 227 struct ieee80211_key *key, 228 228 u8 *payload, size_t payload_len, u8 *ta, 229 229 u8 *ra, int only_iv, int queue,
+2 -2
net/mac80211/tkip.h
··· 15 15 16 16 u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16); 17 17 18 - int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, 18 + int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, 19 19 struct ieee80211_key *key, 20 20 u8 *pos, size_t payload_len, u8 *ta); 21 21 enum { ··· 24 24 TKIP_DECRYPT_INVALID_KEYIDX = -2, 25 25 TKIP_DECRYPT_REPLAY = -3, 26 26 }; 27 - int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, 27 + int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, 28 28 struct ieee80211_key *key, 29 29 u8 *payload, size_t payload_len, u8 *ta, 30 30 u8 *ra, int only_iv, int queue,
+15 -19
net/mac80211/wep.c
··· 30 30 /* start WEP IV from a random value */ 31 31 get_random_bytes(&local->wep_iv, WEP_IV_LEN); 32 32 33 - local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, 34 - CRYPTO_ALG_ASYNC); 33 + local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC); 35 34 if (IS_ERR(local->wep_tx_tfm)) { 36 35 local->wep_rx_tfm = ERR_PTR(-EINVAL); 37 36 return PTR_ERR(local->wep_tx_tfm); 38 37 } 39 38 40 - local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, 41 - CRYPTO_ALG_ASYNC); 39 + local->wep_rx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC); 42 40 if (IS_ERR(local->wep_rx_tfm)) { 43 - crypto_free_blkcipher(local->wep_tx_tfm); 41 + crypto_free_cipher(local->wep_tx_tfm); 44 42 local->wep_tx_tfm = ERR_PTR(-EINVAL); 45 43 return PTR_ERR(local->wep_rx_tfm); 46 44 } ··· 49 51 void ieee80211_wep_free(struct ieee80211_local *local) 50 52 { 51 53 if (!IS_ERR(local->wep_tx_tfm)) 52 - crypto_free_blkcipher(local->wep_tx_tfm); 54 + crypto_free_cipher(local->wep_tx_tfm); 53 55 if (!IS_ERR(local->wep_rx_tfm)) 54 - crypto_free_blkcipher(local->wep_rx_tfm); 56 + crypto_free_cipher(local->wep_rx_tfm); 55 57 } 56 58 57 59 static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen) ··· 125 127 /* Perform WEP encryption using given key. data buffer must have tailroom 126 128 * for 4-byte ICV. data_len must not include this ICV. Note: this function 127 129 * does _not_ add IV. data = RC4(data | CRC32(data)) */ 128 - int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 130 + int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key, 129 131 size_t klen, u8 *data, size_t data_len) 130 132 { 131 - struct blkcipher_desc desc = { .tfm = tfm }; 132 - struct scatterlist sg; 133 133 __le32 icv; 134 + int i; 134 135 135 136 if (IS_ERR(tfm)) 136 137 return -1; ··· 137 140 icv = cpu_to_le32(~crc32_le(~0, data, data_len)); 138 141 put_unaligned(icv, (__le32 *)(data + data_len)); 139 142 140 - crypto_blkcipher_setkey(tfm, rc4key, klen); 141 - sg_init_one(&sg, data, data_len + WEP_ICV_LEN); 142 - crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length); 143 + crypto_cipher_setkey(tfm, rc4key, klen); 144 + for (i = 0; i < data_len + WEP_ICV_LEN; i++) 145 + crypto_cipher_encrypt_one(tfm, data + i, data + i); 143 146 144 147 return 0; 145 148 } ··· 183 186 /* Perform WEP decryption using given key. data buffer includes encrypted 184 187 * payload, including 4-byte ICV, but _not_ IV. data_len must not include ICV. 185 188 * Return 0 on success and -1 on ICV mismatch. */ 186 - int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 189 + int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, 187 190 size_t klen, u8 *data, size_t data_len) 188 191 { 189 - struct blkcipher_desc desc = { .tfm = tfm }; 190 - struct scatterlist sg; 191 192 __le32 crc; 193 + int i; 192 194 193 195 if (IS_ERR(tfm)) 194 196 return -1; 195 197 196 - crypto_blkcipher_setkey(tfm, rc4key, klen); 197 - sg_init_one(&sg, data, data_len + WEP_ICV_LEN); 198 - crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length); 198 + crypto_cipher_setkey(tfm, rc4key, klen); 199 + for (i = 0; i < data_len + WEP_ICV_LEN; i++) 200 + crypto_cipher_decrypt_one(tfm, data + i, data + i); 199 201 200 202 crc = cpu_to_le32(~crc32_le(~0, data, data_len)); 201 203 if (memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0)
+2 -2
net/mac80211/wep.h
··· 18 18 19 19 int ieee80211_wep_init(struct ieee80211_local *local); 20 20 void ieee80211_wep_free(struct ieee80211_local *local); 21 - int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 21 + int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key, 22 22 size_t klen, u8 *data, size_t data_len); 23 23 int ieee80211_wep_encrypt(struct ieee80211_local *local, 24 24 struct sk_buff *skb, 25 25 const u8 *key, int keylen, int keyidx); 26 - int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 26 + int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, 27 27 size_t klen, u8 *data, size_t data_len); 28 28 bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); 29 29