Skip to content

Commit

Permalink
orinoco: Use shash instead of ahash for MIC calculations
Browse files Browse the repository at this point in the history
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 1fef293 as I
accidentally applied this patch to wireless-drivers-next when I was supposed to
apply this wireless-drivers

Cc: [email protected] # 4.9 only
Reported-by: Eric Biggers <[email protected]>
Signed-off-by: Andy Lutomirski <[email protected]>
Signed-off-by: Kalle Valo <[email protected]>
  • Loading branch information
amluto authored and Kalle Valo committed Dec 30, 2016
1 parent f5a0aab commit 570b90f
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 21 deletions.
44 changes: 26 additions & 18 deletions drivers/net/wireless/intersil/orinoco/mic.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
/********************************************************************/
int orinoco_mic_init(struct orinoco_private *priv)
{
priv->tx_tfm_mic = crypto_alloc_ahash("michael_mic", 0,
priv->tx_tfm_mic = crypto_alloc_shash("michael_mic", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->tx_tfm_mic)) {
printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
Expand All @@ -25,7 +25,7 @@ int orinoco_mic_init(struct orinoco_private *priv)
return -ENOMEM;
}

priv->rx_tfm_mic = crypto_alloc_ahash("michael_mic", 0,
priv->rx_tfm_mic = crypto_alloc_shash("michael_mic", 0,
CRYPTO_ALG_ASYNC);
if (IS_ERR(priv->rx_tfm_mic)) {
printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
Expand All @@ -40,17 +40,16 @@ int orinoco_mic_init(struct orinoco_private *priv)
void orinoco_mic_free(struct orinoco_private *priv)
{
if (priv->tx_tfm_mic)
crypto_free_ahash(priv->tx_tfm_mic);
crypto_free_shash(priv->tx_tfm_mic);
if (priv->rx_tfm_mic)
crypto_free_ahash(priv->rx_tfm_mic);
crypto_free_shash(priv->rx_tfm_mic);
}

int orinoco_mic(struct crypto_ahash *tfm_michael, u8 *key,
int orinoco_mic(struct crypto_shash *tfm_michael, u8 *key,
u8 *da, u8 *sa, u8 priority,
u8 *data, size_t data_len, u8 *mic)
{
AHASH_REQUEST_ON_STACK(req, tfm_michael);
struct scatterlist sg[2];
SHASH_DESC_ON_STACK(desc, tfm_michael);
u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
int err;

Expand All @@ -67,18 +66,27 @@ int orinoco_mic(struct crypto_ahash *tfm_michael, u8 *key,
hdr[ETH_ALEN * 2 + 2] = 0;
hdr[ETH_ALEN * 2 + 3] = 0;

/* Use scatter gather to MIC header and data in one go */
sg_init_table(sg, 2);
sg_set_buf(&sg[0], hdr, sizeof(hdr));
sg_set_buf(&sg[1], data, data_len);
desc->tfm = tfm_michael;
desc->flags = 0;

if (crypto_ahash_setkey(tfm_michael, key, MIC_KEYLEN))
return -1;
err = crypto_shash_setkey(tfm_michael, key, MIC_KEYLEN);
if (err)
return err;

err = crypto_shash_init(desc);
if (err)
return err;

err = crypto_shash_update(desc, hdr, sizeof(hdr));
if (err)
return err;

err = crypto_shash_update(desc, data, data_len);
if (err)
return err;

err = crypto_shash_final(desc, mic);
shash_desc_zero(desc);

ahash_request_set_tfm(req, tfm_michael);
ahash_request_set_callback(req, 0, NULL, NULL);
ahash_request_set_crypt(req, sg, mic, data_len + sizeof(hdr));
err = crypto_ahash_digest(req);
ahash_request_zero(req);
return err;
}
3 changes: 2 additions & 1 deletion drivers/net/wireless/intersil/orinoco/mic.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define _ORINOCO_MIC_H_

#include <linux/types.h>
#include <crypto/hash.h>

#define MICHAEL_MIC_LEN 8

Expand All @@ -15,7 +16,7 @@ struct crypto_ahash;

int orinoco_mic_init(struct orinoco_private *priv);
void orinoco_mic_free(struct orinoco_private *priv);
int orinoco_mic(struct crypto_ahash *tfm_michael, u8 *key,
int orinoco_mic(struct crypto_shash *tfm_michael, u8 *key,
u8 *da, u8 *sa, u8 priority,
u8 *data, size_t data_len, u8 *mic);

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/intersil/orinoco/orinoco.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ struct orinoco_private {
u8 *wpa_ie;
int wpa_ie_len;

struct crypto_ahash *rx_tfm_mic;
struct crypto_ahash *tx_tfm_mic;
struct crypto_shash *rx_tfm_mic;
struct crypto_shash *tx_tfm_mic;

unsigned int wpa_enabled:1;
unsigned int tkip_cm_active:1;
Expand Down

0 comments on commit 570b90f

Please sign in to comment.