Skip to content

Commit

Permalink
net/lib80211: move WEP handling to ARC4 library code
Browse files Browse the repository at this point in the history
The crypto API abstraction is not very useful for invoking ciphers
directly, especially in the case of arc4, which only has a generic
implementation in C. So let's invoke the library code directly.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
Ard Biesheuvel authored and herbertx committed Jun 20, 2019
1 parent 5fdb373 commit af1f3d3
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 38 deletions.
1 change: 1 addition & 0 deletions net/wireless/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ config LIB80211

config LIB80211_CRYPT_WEP
tristate
select CRYPTO_LIB_ARC4

config LIB80211_CRYPT_CCMP
tristate
Expand Down
51 changes: 13 additions & 38 deletions net/wireless/lib80211_crypt_wep.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/

#include <linux/err.h>
#include <linux/fips.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
Expand All @@ -22,7 +23,7 @@

#include <net/lib80211.h>

#include <linux/crypto.h>
#include <crypto/arc4.h>
#include <linux/crc32.h>

MODULE_AUTHOR("Jouni Malinen");
Expand All @@ -35,52 +36,31 @@ struct lib80211_wep_data {
u8 key[WEP_KEY_LEN + 1];
u8 key_len;
u8 key_idx;
struct crypto_cipher *tx_tfm;
struct crypto_cipher *rx_tfm;
struct arc4_ctx tx_ctx;
struct arc4_ctx rx_ctx;
};

static void *lib80211_wep_init(int keyidx)
{
struct lib80211_wep_data *priv;

if (fips_enabled)
return NULL;

priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
if (priv == NULL)
goto fail;
return NULL;
priv->key_idx = keyidx;

priv->tx_tfm = crypto_alloc_cipher("arc4", 0, 0);
if (IS_ERR(priv->tx_tfm)) {
priv->tx_tfm = NULL;
goto fail;
}

priv->rx_tfm = crypto_alloc_cipher("arc4", 0, 0);
if (IS_ERR(priv->rx_tfm)) {
priv->rx_tfm = NULL;
goto fail;
}
/* start WEP IV from a random value */
get_random_bytes(&priv->iv, 4);

return priv;

fail:
if (priv) {
crypto_free_cipher(priv->tx_tfm);
crypto_free_cipher(priv->rx_tfm);
kfree(priv);
}
return NULL;
}

static void lib80211_wep_deinit(void *priv)
{
struct lib80211_wep_data *_priv = priv;
if (_priv) {
crypto_free_cipher(_priv->tx_tfm);
crypto_free_cipher(_priv->rx_tfm);
}
kfree(priv);
kzfree(priv);
}

/* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */
Expand Down Expand Up @@ -132,7 +112,6 @@ static int lib80211_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
u32 crc, klen, len;
u8 *pos, *icv;
u8 key[WEP_KEY_LEN + 3];
int i;

/* other checks are in lib80211_wep_build_iv */
if (skb_tailroom(skb) < 4)
Expand Down Expand Up @@ -160,10 +139,8 @@ static int lib80211_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
icv[2] = crc >> 16;
icv[3] = crc >> 24;

crypto_cipher_setkey(wep->tx_tfm, key, klen);

for (i = 0; i < len + 4; i++)
crypto_cipher_encrypt_one(wep->tx_tfm, pos + i, pos + i);
arc4_setkey(&wep->tx_ctx, key, klen);
arc4_crypt(&wep->tx_ctx, pos, pos, len + 4);

return 0;
}
Expand All @@ -181,7 +158,6 @@ static int lib80211_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
u32 crc, klen, plen;
u8 key[WEP_KEY_LEN + 3];
u8 keyidx, *pos, icv[4];
int i;

if (skb->len < hdr_len + 8)
return -1;
Expand All @@ -202,9 +178,8 @@ static int lib80211_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
/* Apply RC4 to data and compute CRC32 over decrypted data */
plen = skb->len - hdr_len - 8;

crypto_cipher_setkey(wep->rx_tfm, key, klen);
for (i = 0; i < plen + 4; i++)
crypto_cipher_decrypt_one(wep->rx_tfm, pos + i, pos + i);
arc4_setkey(&wep->rx_ctx, key, klen);
arc4_crypt(&wep->rx_ctx, pos, pos, plen + 4);

crc = ~crc32_le(~0, pos, plen);
icv[0] = crc;
Expand Down

0 comments on commit af1f3d3

Please sign in to comment.