diff options
author | Jeremy Sowden <jeremy@azazel.net> | 2019-02-28 11:15:56 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-02-28 19:14:53 +0100 |
commit | 8b523f20417d5b8423895dd6b3118a6ab9d91d98 (patch) | |
tree | e6664b4771d1d118291f9ad5f0ff4d28a971f4d6 /drivers/staging/ks7010 | |
parent | 050bd74b700267d2f3fe13d8b9561752d7c7df19 (diff) | |
download | linux-8b523f20417d5b8423895dd6b3118a6ab9d91d98.tar.gz linux-8b523f20417d5b8423895dd6b3118a6ab9d91d98.tar.bz2 linux-8b523f20417d5b8423895dd6b3118a6ab9d91d98.zip |
staging: ks7010: removed custom Michael MIC implementation.
Changed the driver to use the kernel's own implementation.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/ks7010')
-rw-r--r-- | drivers/staging/ks7010/Makefile | 2 | ||||
-rw-r--r-- | drivers/staging/ks7010/TODO | 2 | ||||
-rw-r--r-- | drivers/staging/ks7010/ks_hostif.c | 111 | ||||
-rw-r--r-- | drivers/staging/ks7010/michael_mic.c | 127 | ||||
-rw-r--r-- | drivers/staging/ks7010/michael_mic.h | 21 |
5 files changed, 93 insertions, 170 deletions
diff --git a/drivers/staging/ks7010/Makefile b/drivers/staging/ks7010/Makefile index 07dc16cc86f5..412e2105a3a5 100644 --- a/drivers/staging/ks7010/Makefile +++ b/drivers/staging/ks7010/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_KS7010) += ks7010.o -ks7010-y := michael_mic.o ks_hostif.o ks_wlan_net.o ks7010_sdio.o +ks7010-y := ks_hostif.o ks_wlan_net.o ks7010_sdio.o diff --git a/drivers/staging/ks7010/TODO b/drivers/staging/ks7010/TODO index d393ca58e231..87a6dac4890d 100644 --- a/drivers/staging/ks7010/TODO +++ b/drivers/staging/ks7010/TODO @@ -27,8 +27,6 @@ Now the TODOs: - fix the 'card removal' event when card is inserted when booting - check what other upstream wireless mechanisms can be used instead of the custom ones here -- replace custom Michael MIC implementation with the kernel - implementation. This task is only required for a *clean* WEXT interface. Please send any patches to: Greg Kroah-Hartman <gregkh@linuxfoundation.org> diff --git a/drivers/staging/ks7010/ks_hostif.c b/drivers/staging/ks7010/ks_hostif.c index e48fc36b6ebd..06ebea0be118 100644 --- a/drivers/staging/ks7010/ks_hostif.c +++ b/drivers/staging/ks7010/ks_hostif.c @@ -6,15 +6,18 @@ * Copyright (C) 2009 Renesas Technology Corp. */ +#include <crypto/hash.h> #include <linux/circ_buf.h> #include <linux/if_arp.h> #include <net/iw_handler.h> #include <uapi/linux/llc.h> #include "eap_packet.h" #include "ks_wlan.h" -#include "michael_mic.h" #include "ks_hostif.h" +#define MICHAEL_MIC_KEY_LEN 8 +#define MICHAEL_MIC_LEN 8 + static inline void inc_smeqhead(struct ks_wlan_private *priv) { priv->sme_i.qhead = (priv->sme_i.qhead + 1) % SME_EVENT_BUFF_SIZE; @@ -191,6 +194,68 @@ static u8 read_ie(unsigned char *bp, u8 max, u8 *body) return size; } +static int +michael_mic(u8 *key, u8 *data, unsigned int len, u8 priority, u8 *result) +{ + u8 pad_data[4] = { priority, 0, 0, 0 }; + struct crypto_shash *tfm = NULL; + struct shash_desc *desc = NULL; + int ret; + + tfm = crypto_alloc_shash("michael_mic", 0, 0); + if (IS_ERR(tfm)) { + ret = PTR_ERR(tfm); + goto err; + } + + ret = crypto_shash_setkey(tfm, key, MICHAEL_MIC_KEY_LEN); + if (ret < 0) + goto err_free_tfm; + + desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL); + if (!desc) { + ret = -ENOMEM; + goto err_free_tfm; + } + + desc->tfm = tfm; + desc->flags = 0; + + ret = crypto_shash_init(desc); + if (ret < 0) + goto err_free_desc; + + // Compute the MIC value + /* + * IEEE802.11i page 47 + * Figure 43g TKIP MIC processing format + * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ + * |6 |6 |1 |3 |M |1 |1 |1 |1 |1 |1 |1 |1 | Octet + * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ + * |DA|SA|Priority|0 |Data|M0|M1|M2|M3|M4|M5|M6|M7| + * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ + */ + + ret = crypto_shash_update(desc, data, 12); + if (ret < 0) + goto err_free_desc; + + ret = crypto_shash_update(desc, pad_data, 4); + if (ret < 0) + goto err_free_desc; + + ret = crypto_shash_finup(desc, data + 12, len - 12, result); + +err_free_desc: + kzfree(desc); + +err_free_tfm: + crypto_free_shash(tfm); + +err: + return ret; +} + static int get_ap_information(struct ks_wlan_private *priv, struct ap_info *ap_info, struct local_ap *ap) @@ -273,11 +338,11 @@ int hostif_data_indication_wpa(struct ks_wlan_private *priv, { struct ether_hdr *eth_hdr; unsigned short eth_proto; - unsigned char recv_mic[8]; + unsigned char recv_mic[MICHAEL_MIC_LEN]; char buf[128]; unsigned long now; struct mic_failure *mic_failure; - struct michael_mic michael_mic; + u8 mic[MICHAEL_MIC_LEN]; union iwreq_data wrqu; unsigned int key_index = auth_type - 1; struct wpa_key *key = &priv->wpa.key[key_index]; @@ -300,14 +365,20 @@ int hostif_data_indication_wpa(struct ks_wlan_private *priv, netdev_dbg(priv->net_dev, "TKIP: protocol=%04X: size=%u\n", eth_proto, priv->rx_size); /* MIC save */ - memcpy(&recv_mic[0], (priv->rxp) + ((priv->rx_size) - 8), 8); - priv->rx_size = priv->rx_size - 8; + memcpy(&recv_mic[0], + (priv->rxp) + ((priv->rx_size) - sizeof(recv_mic)), + sizeof(recv_mic)); + priv->rx_size = priv->rx_size - sizeof(recv_mic); if (auth_type > 0 && auth_type < 4) { /* auth_type check */ - michael_mic_function(&michael_mic, key->rx_mic_key, - priv->rxp, priv->rx_size, - 0, michael_mic.result); + int ret; + + ret = michael_mic(key->rx_mic_key, + priv->rxp, priv->rx_size, + 0, mic); + if (ret < 0) + return ret; } - if (memcmp(michael_mic.result, recv_mic, 8) != 0) { + if (memcmp(mic, recv_mic, sizeof(mic)) != 0) { now = jiffies; mic_failure = &priv->wpa.mic_failure; /* MIC FAILURE */ @@ -1002,7 +1073,6 @@ int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *skb) int result = 0; unsigned short eth_proto; struct ether_hdr *eth_hdr; - struct michael_mic michael_mic; unsigned short keyinfo = 0; struct ieee802_1x_hdr *aa1x_hdr; struct wpa_eapol_key *eap_key; @@ -1109,17 +1179,20 @@ int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *skb) pp->auth_type = cpu_to_le16(TYPE_AUTH); } else { if (priv->wpa.pairwise_suite == IW_AUTH_CIPHER_TKIP) { - michael_mic_function(&michael_mic, - priv->wpa.key[0].tx_mic_key, - &pp->data[0], skb_len, - 0, michael_mic.result); - memcpy(p, michael_mic.result, 8); - length += 8; - skb_len += 8; - p += 8; + u8 mic[MICHAEL_MIC_LEN]; + + ret = michael_mic(priv->wpa.key[0].tx_mic_key, + &pp->data[0], skb_len, + 0, mic); + if (ret < 0) + goto err_kfree; + + memcpy(p, mic, sizeof(mic)); + length += sizeof(mic); + skb_len += sizeof(mic); + p += sizeof(mic); pp->auth_type = cpu_to_le16(TYPE_DATA); - } else if (priv->wpa.pairwise_suite == IW_AUTH_CIPHER_CCMP) { pp->auth_type = diff --git a/drivers/staging/ks7010/michael_mic.c b/drivers/staging/ks7010/michael_mic.c deleted file mode 100644 index 3acd79615f98..000000000000 --- a/drivers/staging/ks7010/michael_mic.c +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Driver for KeyStream wireless LAN - * - * Copyright (C) 2005-2008 KeyStream Corp. - * Copyright (C) 2009 Renesas Technology Corp. - */ - -#include <asm/unaligned.h> -#include <linux/bitops.h> -#include <linux/string.h> -#include "michael_mic.h" - -// Reset the state to the empty message. -static inline void michael_clear(struct michael_mic *mic) -{ - mic->l = mic->k0; - mic->r = mic->k1; - mic->m_bytes = 0; -} - -static void michael_init(struct michael_mic *mic, u8 *key) -{ - // Set the key - mic->k0 = get_unaligned_le32(key); - mic->k1 = get_unaligned_le32(key + 4); - - //clear(); - michael_clear(mic); -} - -static inline void michael_block(struct michael_mic *mic) -{ - mic->r ^= rol32(mic->l, 17); - mic->l += mic->r; - mic->r ^= ((mic->l & 0xff00ff00) >> 8) | - ((mic->l & 0x00ff00ff) << 8); - mic->l += mic->r; - mic->r ^= rol32(mic->l, 3); - mic->l += mic->r; - mic->r ^= ror32(mic->l, 2); - mic->l += mic->r; -} - -static void michael_append(struct michael_mic *mic, u8 *src, int bytes) -{ - int addlen; - - if (mic->m_bytes) { - addlen = 4 - mic->m_bytes; - if (addlen > bytes) - addlen = bytes; - memcpy(&mic->m[mic->m_bytes], src, addlen); - mic->m_bytes += addlen; - src += addlen; - bytes -= addlen; - - if (mic->m_bytes < 4) - return; - - mic->l ^= get_unaligned_le32(mic->m); - michael_block(mic); - mic->m_bytes = 0; - } - - while (bytes >= 4) { - mic->l ^= get_unaligned_le32(src); - michael_block(mic); - src += 4; - bytes -= 4; - } - - if (bytes > 0) { - mic->m_bytes = bytes; - memcpy(mic->m, src, bytes); - } -} - -static void michael_get_mic(struct michael_mic *mic, u8 *dst) -{ - u8 *data = mic->m; - - switch (mic->m_bytes) { - case 0: - mic->l ^= 0x5a; - break; - case 1: - mic->l ^= data[0] | 0x5a00; - break; - case 2: - mic->l ^= data[0] | (data[1] << 8) | 0x5a0000; - break; - case 3: - mic->l ^= data[0] | (data[1] << 8) | (data[2] << 16) | - 0x5a000000; - break; - } - michael_block(mic); - michael_block(mic); - // The appendByte function has already computed the result. - put_unaligned_le32(mic->l, dst); - put_unaligned_le32(mic->r, dst + 4); - - // Reset to the empty message. - michael_clear(mic); -} - -void michael_mic_function(struct michael_mic *mic, u8 *key, - u8 *data, unsigned int len, u8 priority, u8 *result) -{ - u8 pad_data[4] = { priority, 0, 0, 0 }; - // Compute the MIC value - /* - * IEEE802.11i page 47 - * Figure 43g TKIP MIC processing format - * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ - * |6 |6 |1 |3 |M |1 |1 |1 |1 |1 |1 |1 |1 | Octet - * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ - * |DA|SA|Priority|0 |Data|M0|M1|M2|M3|M4|M5|M6|M7| - * +--+--+--------+--+----+--+--+--+--+--+--+--+--+ - */ - michael_init(mic, key); - michael_append(mic, data, 12); /* |DA|SA| */ - michael_append(mic, pad_data, 4); /* |Priority|0|0|0| */ - michael_append(mic, data + 12, len - 12); /* |Data| */ - michael_get_mic(mic, result); -} diff --git a/drivers/staging/ks7010/michael_mic.h b/drivers/staging/ks7010/michael_mic.h deleted file mode 100644 index f0ac164b999b..000000000000 --- a/drivers/staging/ks7010/michael_mic.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Driver for KeyStream wireless LAN - * - * Copyright (C) 2005-2008 KeyStream Corp. - * Copyright (C) 2009 Renesas Technology Corp. - */ - -/* MichaelMIC routine define */ -struct michael_mic { - u32 k0; // Key - u32 k1; // Key - u32 l; // Current state - u32 r; // Current state - u8 m[4]; // Message accumulator (single word) - int m_bytes; // # bytes in M - u8 result[8]; -}; - -void michael_mic_function(struct michael_mic *mic, u8 *key, - u8 *data, unsigned int len, u8 priority, u8 *result); |