summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2019-06-12 12:19:56 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2019-06-20 02:18:33 -0400
commit4be297016cd3a6aedbcc3b053da16cdd42546f04 (patch)
tree0c1c5e88b5dfd15e33bc6aab30fb3667e56247d4
parentaf1f3d327d49d9bb94d9c173023e6cbdc5453d38 (diff)
net/lib80211: move TKIP handling to ARC4 library code
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>
-rw-r--r--net/wireless/Kconfig1
-rw-r--r--net/wireless/lib80211_crypt_tkip.c48
2 files changed, 18 insertions, 31 deletions
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index abff3c6a5b50..2cfc5b7800e9 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -219,6 +219,7 @@ config LIB80211_CRYPT_CCMP
219 219
220config LIB80211_CRYPT_TKIP 220config LIB80211_CRYPT_TKIP
221 tristate 221 tristate
222 select CRYPTO_LIB_ARC4
222 223
223config LIB80211_DEBUG 224config LIB80211_DEBUG
224 bool "lib80211 debugging messages" 225 bool "lib80211 debugging messages"
diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c
index 11eaa5956f00..0fd155c4e0a6 100644
--- a/net/wireless/lib80211_crypt_tkip.c
+++ b/net/wireless/lib80211_crypt_tkip.c
@@ -13,6 +13,7 @@
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 14
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/fips.h>
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
@@ -29,6 +30,7 @@
29#include <linux/ieee80211.h> 30#include <linux/ieee80211.h>
30#include <net/iw_handler.h> 31#include <net/iw_handler.h>
31 32
33#include <crypto/arc4.h>
32#include <crypto/hash.h> 34#include <crypto/hash.h>
33#include <linux/crypto.h> 35#include <linux/crypto.h>
34#include <linux/crc32.h> 36#include <linux/crc32.h>
@@ -64,9 +66,9 @@ struct lib80211_tkip_data {
64 66
65 int key_idx; 67 int key_idx;
66 68
67 struct crypto_cipher *rx_tfm_arc4; 69 struct arc4_ctx rx_ctx_arc4;
70 struct arc4_ctx tx_ctx_arc4;
68 struct crypto_shash *rx_tfm_michael; 71 struct crypto_shash *rx_tfm_michael;
69 struct crypto_cipher *tx_tfm_arc4;
70 struct crypto_shash *tx_tfm_michael; 72 struct crypto_shash *tx_tfm_michael;
71 73
72 /* scratch buffers for virt_to_page() (crypto API) */ 74 /* scratch buffers for virt_to_page() (crypto API) */
@@ -93,30 +95,21 @@ static void *lib80211_tkip_init(int key_idx)
93{ 95{
94 struct lib80211_tkip_data *priv; 96 struct lib80211_tkip_data *priv;
95 97
98 if (fips_enabled)
99 return NULL;
100
96 priv = kzalloc(sizeof(*priv), GFP_ATOMIC); 101 priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
97 if (priv == NULL) 102 if (priv == NULL)
98 goto fail; 103 goto fail;
99 104
100 priv->key_idx = key_idx; 105 priv->key_idx = key_idx;
101 106
102 priv->tx_tfm_arc4 = crypto_alloc_cipher("arc4", 0, 0);
103 if (IS_ERR(priv->tx_tfm_arc4)) {
104 priv->tx_tfm_arc4 = NULL;
105 goto fail;
106 }
107
108 priv->tx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0); 107 priv->tx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
109 if (IS_ERR(priv->tx_tfm_michael)) { 108 if (IS_ERR(priv->tx_tfm_michael)) {
110 priv->tx_tfm_michael = NULL; 109 priv->tx_tfm_michael = NULL;
111 goto fail; 110 goto fail;
112 } 111 }
113 112
114 priv->rx_tfm_arc4 = crypto_alloc_cipher("arc4", 0, 0);
115 if (IS_ERR(priv->rx_tfm_arc4)) {
116 priv->rx_tfm_arc4 = NULL;
117 goto fail;
118 }
119
120 priv->rx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0); 113 priv->rx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
121 if (IS_ERR(priv->rx_tfm_michael)) { 114 if (IS_ERR(priv->rx_tfm_michael)) {
122 priv->rx_tfm_michael = NULL; 115 priv->rx_tfm_michael = NULL;
@@ -128,9 +121,7 @@ static void *lib80211_tkip_init(int key_idx)
128 fail: 121 fail:
129 if (priv) { 122 if (priv) {
130 crypto_free_shash(priv->tx_tfm_michael); 123 crypto_free_shash(priv->tx_tfm_michael);
131 crypto_free_cipher(priv->tx_tfm_arc4);
132 crypto_free_shash(priv->rx_tfm_michael); 124 crypto_free_shash(priv->rx_tfm_michael);
133 crypto_free_cipher(priv->rx_tfm_arc4);
134 kfree(priv); 125 kfree(priv);
135 } 126 }
136 127
@@ -142,11 +133,9 @@ static void lib80211_tkip_deinit(void *priv)
142 struct lib80211_tkip_data *_priv = priv; 133 struct lib80211_tkip_data *_priv = priv;
143 if (_priv) { 134 if (_priv) {
144 crypto_free_shash(_priv->tx_tfm_michael); 135 crypto_free_shash(_priv->tx_tfm_michael);
145 crypto_free_cipher(_priv->tx_tfm_arc4);
146 crypto_free_shash(_priv->rx_tfm_michael); 136 crypto_free_shash(_priv->rx_tfm_michael);
147 crypto_free_cipher(_priv->rx_tfm_arc4);
148 } 137 }
149 kfree(priv); 138 kzfree(priv);
150} 139}
151 140
152static inline u16 RotR1(u16 val) 141static inline u16 RotR1(u16 val)
@@ -345,7 +334,6 @@ static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
345 int len; 334 int len;
346 u8 rc4key[16], *pos, *icv; 335 u8 rc4key[16], *pos, *icv;
347 u32 crc; 336 u32 crc;
348 int i;
349 337
350 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { 338 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
351 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 339 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
@@ -370,9 +358,9 @@ static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
370 icv[2] = crc >> 16; 358 icv[2] = crc >> 16;
371 icv[3] = crc >> 24; 359 icv[3] = crc >> 24;
372 360
373 crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16); 361 arc4_setkey(&tkey->tx_ctx_arc4, rc4key, 16);
374 for (i = 0; i < len + 4; i++) 362 arc4_crypt(&tkey->tx_ctx_arc4, pos, pos, len + 4);
375 crypto_cipher_encrypt_one(tkey->tx_tfm_arc4, pos + i, pos + i); 363
376 return 0; 364 return 0;
377} 365}
378 366
@@ -400,7 +388,6 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
400 u8 icv[4]; 388 u8 icv[4];
401 u32 crc; 389 u32 crc;
402 int plen; 390 int plen;
403 int i;
404 391
405 hdr = (struct ieee80211_hdr *)skb->data; 392 hdr = (struct ieee80211_hdr *)skb->data;
406 393
@@ -453,9 +440,8 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
453 440
454 plen = skb->len - hdr_len - 12; 441 plen = skb->len - hdr_len - 12;
455 442
456 crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); 443 arc4_setkey(&tkey->rx_ctx_arc4, rc4key, 16);
457 for (i = 0; i < plen + 4; i++) 444 arc4_crypt(&tkey->rx_ctx_arc4, pos, pos, plen + 4);
458 crypto_cipher_decrypt_one(tkey->rx_tfm_arc4, pos + i, pos + i);
459 445
460 crc = ~crc32_le(~0, pos, plen); 446 crc = ~crc32_le(~0, pos, plen);
461 icv[0] = crc; 447 icv[0] = crc;
@@ -640,17 +626,17 @@ static int lib80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
640 struct lib80211_tkip_data *tkey = priv; 626 struct lib80211_tkip_data *tkey = priv;
641 int keyidx; 627 int keyidx;
642 struct crypto_shash *tfm = tkey->tx_tfm_michael; 628 struct crypto_shash *tfm = tkey->tx_tfm_michael;
643 struct crypto_cipher *tfm2 = tkey->tx_tfm_arc4; 629 struct arc4_ctx *tfm2 = &tkey->tx_ctx_arc4;
644 struct crypto_shash *tfm3 = tkey->rx_tfm_michael; 630 struct crypto_shash *tfm3 = tkey->rx_tfm_michael;
645 struct crypto_cipher *tfm4 = tkey->rx_tfm_arc4; 631 struct arc4_ctx *tfm4 = &tkey->rx_ctx_arc4;
646 632
647 keyidx = tkey->key_idx; 633 keyidx = tkey->key_idx;
648 memset(tkey, 0, sizeof(*tkey)); 634 memset(tkey, 0, sizeof(*tkey));
649 tkey->key_idx = keyidx; 635 tkey->key_idx = keyidx;
650 tkey->tx_tfm_michael = tfm; 636 tkey->tx_tfm_michael = tfm;
651 tkey->tx_tfm_arc4 = tfm2; 637 tkey->tx_ctx_arc4 = *tfm2;
652 tkey->rx_tfm_michael = tfm3; 638 tkey->rx_tfm_michael = tfm3;
653 tkey->rx_tfm_arc4 = tfm4; 639 tkey->rx_ctx_arc4 = *tfm4;
654 if (len == TKIP_KEY_LEN) { 640 if (len == TKIP_KEY_LEN) {
655 memcpy(tkey->key, key, TKIP_KEY_LEN); 641 memcpy(tkey->key, key, TKIP_KEY_LEN);
656 tkey->key_set = 1; 642 tkey->key_set = 1;