aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Lutomirski <luto@kernel.org>2016-12-12 15:55:55 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-19 14:18:03 -0500
commit4a940d6503e1ac6c6ba235a8f4c9b4fd61934fee (patch)
treed7086bf184a626d0c3d10e321b7783049f90455b
parent0edcc47cdb7f2d80c1e7236f5f797b7443cb2142 (diff)
orinoco: Use shash instead of ahash for MIC calculations
commit 570b90fa230b8021f51a67fab2245fe8df6fe37d upstream. Eric Biggers pointed out that the orinoco driver pointed scatterlists at the stack. Fix it by switching from ahash to shash. The result should be simpler, faster, and more correct. kvalo: cherry picked from commit 1fef293b8a9850cfa124a53c1d8878d355010403 as I accidentally applied this patch to wireless-drivers-next when I was supposed to apply this wireless-drivers Reported-by: Eric Biggers <ebiggers3@gmail.com> Signed-off-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/net/wireless/intersil/orinoco/mic.c44
-rw-r--r--drivers/net/wireless/intersil/orinoco/mic.h3
-rw-r--r--drivers/net/wireless/intersil/orinoco/orinoco.h4
3 files changed, 30 insertions, 21 deletions
diff --git a/drivers/net/wireless/intersil/orinoco/mic.c b/drivers/net/wireless/intersil/orinoco/mic.c
index bc7397d709d3..08bc7822f820 100644
--- a/drivers/net/wireless/intersil/orinoco/mic.c
+++ b/drivers/net/wireless/intersil/orinoco/mic.c
@@ -16,7 +16,7 @@
16/********************************************************************/ 16/********************************************************************/
17int orinoco_mic_init(struct orinoco_private *priv) 17int orinoco_mic_init(struct orinoco_private *priv)
18{ 18{
19 priv->tx_tfm_mic = crypto_alloc_ahash("michael_mic", 0, 19 priv->tx_tfm_mic = crypto_alloc_shash("michael_mic", 0,
20 CRYPTO_ALG_ASYNC); 20 CRYPTO_ALG_ASYNC);
21 if (IS_ERR(priv->tx_tfm_mic)) { 21 if (IS_ERR(priv->tx_tfm_mic)) {
22 printk(KERN_DEBUG "orinoco_mic_init: could not allocate " 22 printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
@@ -25,7 +25,7 @@ int orinoco_mic_init(struct orinoco_private *priv)
25 return -ENOMEM; 25 return -ENOMEM;
26 } 26 }
27 27
28 priv->rx_tfm_mic = crypto_alloc_ahash("michael_mic", 0, 28 priv->rx_tfm_mic = crypto_alloc_shash("michael_mic", 0,
29 CRYPTO_ALG_ASYNC); 29 CRYPTO_ALG_ASYNC);
30 if (IS_ERR(priv->rx_tfm_mic)) { 30 if (IS_ERR(priv->rx_tfm_mic)) {
31 printk(KERN_DEBUG "orinoco_mic_init: could not allocate " 31 printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
@@ -40,17 +40,16 @@ int orinoco_mic_init(struct orinoco_private *priv)
40void orinoco_mic_free(struct orinoco_private *priv) 40void orinoco_mic_free(struct orinoco_private *priv)
41{ 41{
42 if (priv->tx_tfm_mic) 42 if (priv->tx_tfm_mic)
43 crypto_free_ahash(priv->tx_tfm_mic); 43 crypto_free_shash(priv->tx_tfm_mic);
44 if (priv->rx_tfm_mic) 44 if (priv->rx_tfm_mic)
45 crypto_free_ahash(priv->rx_tfm_mic); 45 crypto_free_shash(priv->rx_tfm_mic);
46} 46}
47 47
48int orinoco_mic(struct crypto_ahash *tfm_michael, u8 *key, 48int orinoco_mic(struct crypto_shash *tfm_michael, u8 *key,
49 u8 *da, u8 *sa, u8 priority, 49 u8 *da, u8 *sa, u8 priority,
50 u8 *data, size_t data_len, u8 *mic) 50 u8 *data, size_t data_len, u8 *mic)
51{ 51{
52 AHASH_REQUEST_ON_STACK(req, tfm_michael); 52 SHASH_DESC_ON_STACK(desc, tfm_michael);
53 struct scatterlist sg[2];
54 u8 hdr[ETH_HLEN + 2]; /* size of header + padding */ 53 u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
55 int err; 54 int err;
56 55
@@ -67,18 +66,27 @@ int orinoco_mic(struct crypto_ahash *tfm_michael, u8 *key,
67 hdr[ETH_ALEN * 2 + 2] = 0; 66 hdr[ETH_ALEN * 2 + 2] = 0;
68 hdr[ETH_ALEN * 2 + 3] = 0; 67 hdr[ETH_ALEN * 2 + 3] = 0;
69 68
70 /* Use scatter gather to MIC header and data in one go */ 69 desc->tfm = tfm_michael;
71 sg_init_table(sg, 2); 70 desc->flags = 0;
72 sg_set_buf(&sg[0], hdr, sizeof(hdr));
73 sg_set_buf(&sg[1], data, data_len);
74 71
75 if (crypto_ahash_setkey(tfm_michael, key, MIC_KEYLEN)) 72 err = crypto_shash_setkey(tfm_michael, key, MIC_KEYLEN);
76 return -1; 73 if (err)
74 return err;
75
76 err = crypto_shash_init(desc);
77 if (err)
78 return err;
79
80 err = crypto_shash_update(desc, hdr, sizeof(hdr));
81 if (err)
82 return err;
83
84 err = crypto_shash_update(desc, data, data_len);
85 if (err)
86 return err;
87
88 err = crypto_shash_final(desc, mic);
89 shash_desc_zero(desc);
77 90
78 ahash_request_set_tfm(req, tfm_michael);
79 ahash_request_set_callback(req, 0, NULL, NULL);
80 ahash_request_set_crypt(req, sg, mic, data_len + sizeof(hdr));
81 err = crypto_ahash_digest(req);
82 ahash_request_zero(req);
83 return err; 91 return err;
84} 92}
diff --git a/drivers/net/wireless/intersil/orinoco/mic.h b/drivers/net/wireless/intersil/orinoco/mic.h
index ce731d05cc98..e8724e889219 100644
--- a/drivers/net/wireless/intersil/orinoco/mic.h
+++ b/drivers/net/wireless/intersil/orinoco/mic.h
@@ -6,6 +6,7 @@
6#define _ORINOCO_MIC_H_ 6#define _ORINOCO_MIC_H_
7 7
8#include <linux/types.h> 8#include <linux/types.h>
9#include <crypto/hash.h>
9 10
10#define MICHAEL_MIC_LEN 8 11#define MICHAEL_MIC_LEN 8
11 12
@@ -15,7 +16,7 @@ struct crypto_ahash;
15 16
16int orinoco_mic_init(struct orinoco_private *priv); 17int orinoco_mic_init(struct orinoco_private *priv);
17void orinoco_mic_free(struct orinoco_private *priv); 18void orinoco_mic_free(struct orinoco_private *priv);
18int orinoco_mic(struct crypto_ahash *tfm_michael, u8 *key, 19int orinoco_mic(struct crypto_shash *tfm_michael, u8 *key,
19 u8 *da, u8 *sa, u8 priority, 20 u8 *da, u8 *sa, u8 priority,
20 u8 *data, size_t data_len, u8 *mic); 21 u8 *data, size_t data_len, u8 *mic);
21 22
diff --git a/drivers/net/wireless/intersil/orinoco/orinoco.h b/drivers/net/wireless/intersil/orinoco/orinoco.h
index 2f0c84b1c440..5fa1c3e3713f 100644
--- a/drivers/net/wireless/intersil/orinoco/orinoco.h
+++ b/drivers/net/wireless/intersil/orinoco/orinoco.h
@@ -152,8 +152,8 @@ struct orinoco_private {
152 u8 *wpa_ie; 152 u8 *wpa_ie;
153 int wpa_ie_len; 153 int wpa_ie_len;
154 154
155 struct crypto_ahash *rx_tfm_mic; 155 struct crypto_shash *rx_tfm_mic;
156 struct crypto_ahash *tx_tfm_mic; 156 struct crypto_shash *tx_tfm_mic;
157 157
158 unsigned int wpa_enabled:1; 158 unsigned int wpa_enabled:1;
159 unsigned int tkip_cm_active:1; 159 unsigned int tkip_cm_active:1;