mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
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>
This commit is contained in:
parent
050bd74b70
commit
8b523f2041
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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 =
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
Loading…
Reference in New Issue
Block a user