Commit 4b8b9c8f authored by Roland Vossen's avatar Roland Vossen Committed by Greg Kroah-Hartman

staging: brcm80211: fullmac sparse endianness encryption keys check

Added support by making a distinction between a struct and its little
endian relative.
Reviewed-by: default avatarArend van Spriel <arend@broadcom.com>
Reviewed-by: default avatarFranky Lin <frankyl@broadcom.com>
Signed-off-by: default avatarRoland Vossen <rvossen@broadcom.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent a8a4d920
...@@ -405,6 +405,11 @@ struct brcmf_ssid { ...@@ -405,6 +405,11 @@ struct brcmf_ssid {
unsigned char SSID[32]; unsigned char SSID[32];
}; };
struct brcmf_ssid_le {
__le32 SSID_len;
unsigned char SSID[32];
};
struct brcmf_scan_params { struct brcmf_scan_params {
struct brcmf_ssid ssid; /* default: {0, ""} */ struct brcmf_ssid ssid; /* default: {0, ""} */
u8 bssid[ETH_ALEN]; /* default: bcast */ u8 bssid[ETH_ALEN]; /* default: bcast */
...@@ -500,16 +505,37 @@ struct brcmf_wsec_key { ...@@ -500,16 +505,37 @@ struct brcmf_wsec_key {
u32 pad_1[18]; u32 pad_1[18];
u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
u32 flags; /* misc flags */ u32 flags; /* misc flags */
u32 pad_2[2]; u32 pad_2[3];
int pad_3; u32 iv_initialized; /* has IV been initialized already? */
int iv_initialized; /* has IV been initialized already? */ u32 pad_3;
int pad_4;
/* Rx IV */ /* Rx IV */
struct { struct {
u32 hi; /* upper 32 bits of IV */ u32 hi; /* upper 32 bits of IV */
u16 lo; /* lower 16 bits of IV */ u16 lo; /* lower 16 bits of IV */
} rxiv; } rxiv;
u32 pad_5[2]; u32 pad_4[2];
u8 ea[ETH_ALEN]; /* per station */
};
/*
* dongle requires same struct as above but with fields in little endian order
*/
struct brcmf_wsec_key_le {
__le32 index; /* key index */
__le32 len; /* key length */
u8 data[WLAN_MAX_KEY_LEN]; /* key data */
__le32 pad_1[18];
__le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
__le32 flags; /* misc flags */
__le32 pad_2[3];
__le32 iv_initialized; /* has IV been initialized already? */
__le32 pad_3;
/* Rx IV */
struct {
__le32 hi; /* upper 32 bits of IV */
__le16 lo; /* lower 16 bits of IV */
} rxiv;
__le32 pad_4[2];
u8 ea[ETH_ALEN]; /* per station */ u8 ea[ETH_ALEN]; /* per station */
}; };
......
...@@ -247,17 +247,6 @@ static const u32 __wl_cipher_suites[] = { ...@@ -247,17 +247,6 @@ static const u32 __wl_cipher_suites[] = {
WLAN_CIPHER_SUITE_AES_CMAC, WLAN_CIPHER_SUITE_AES_CMAC,
}; };
static void convert_key_from_CPU(struct brcmf_wsec_key *key)
{
key->index = cpu_to_le32(key->index);
key->len = cpu_to_le32(key->len);
key->algo = cpu_to_le32(key->algo);
key->flags = cpu_to_le32(key->flags);
key->rxiv.hi = cpu_to_le32(key->rxiv.hi);
key->rxiv.lo = cpu_to_le16(key->rxiv.lo);
key->iv_initialized = cpu_to_le32(key->iv_initialized);
}
static s32 static s32
brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len) brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
{ {
...@@ -278,6 +267,33 @@ brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len) ...@@ -278,6 +267,33 @@ brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
return err; return err;
} }
static void convert_key_from_CPU(struct brcmf_wsec_key *key,
struct brcmf_wsec_key_le *key_le)
{
key_le->index = cpu_to_le32(key->index);
key_le->len = cpu_to_le32(key->len);
key_le->algo = cpu_to_le32(key->algo);
key_le->flags = cpu_to_le32(key->flags);
key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
memcpy(key_le->data, key->data, sizeof(key->data));
memcpy(key_le->ea, key->ea, sizeof(key->ea));
}
static int send_key_to_dongle(struct net_device *dev,
struct brcmf_wsec_key *key)
{
int err;
struct brcmf_wsec_key_le key_le;
convert_key_from_CPU(key, &key_le);
err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
if (err)
WL_ERR("WLC_SET_KEY error (%d)\n", err);
return err;
}
static s32 static s32
brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
enum nl80211_iftype type, u32 *flags, enum nl80211_iftype type, u32 *flags,
...@@ -1200,13 +1216,10 @@ brcmf_set_set_sharedkey(struct net_device *dev, ...@@ -1200,13 +1216,10 @@ brcmf_set_set_sharedkey(struct net_device *dev,
WL_CONN("key length (%d) key index (%d) algo (%d)\n", WL_CONN("key length (%d) key index (%d) algo (%d)\n",
key.len, key.index, key.algo); key.len, key.index, key.algo);
WL_CONN("key \"%s\"\n", key.data); WL_CONN("key \"%s\"\n", key.data);
convert_key_from_CPU(&key); err = send_key_to_dongle(dev, &key);
err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, if (err)
sizeof(key));
if (unlikely(err)) {
WL_ERR("WLC_SET_KEY error (%d)\n", err);
return err; return err;
}
if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) { if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
WL_CONN("set auth_type to shared key\n"); WL_CONN("set auth_type to shared key\n");
val = 1; /* shared key */ val = 1; /* shared key */
...@@ -1461,6 +1474,7 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev, ...@@ -1461,6 +1474,7 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, const u8 *mac_addr, struct key_params *params) u8 key_idx, const u8 *mac_addr, struct key_params *params)
{ {
struct brcmf_wsec_key key; struct brcmf_wsec_key key;
struct brcmf_wsec_key_le key_le;
s32 err = 0; s32 err = 0;
memset(&key, 0, sizeof(key)); memset(&key, 0, sizeof(key));
...@@ -1473,12 +1487,9 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev, ...@@ -1473,12 +1487,9 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev,
/* check for key index change */ /* check for key index change */
if (key.len == 0) { if (key.len == 0) {
/* key delete */ /* key delete */
convert_key_from_CPU(&key); err = send_key_to_dongle(dev, &key);
err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); if (err)
if (unlikely(err)) {
WL_ERR("key delete error (%d)\n", err);
return err; return err;
}
} else { } else {
if (key.len > sizeof(key.data)) { if (key.len > sizeof(key.data)) {
WL_ERR("Invalid key length (%d)\n", key.len); WL_ERR("Invalid key length (%d)\n", key.len);
...@@ -1531,10 +1542,11 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev, ...@@ -1531,10 +1542,11 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev,
WL_ERR("Invalid cipher (0x%x)\n", params->cipher); WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
return -EINVAL; return -EINVAL;
} }
convert_key_from_CPU(&key); convert_key_from_CPU(&key, &key_le);
brcmf_netdev_wait_pend8021x(dev); brcmf_netdev_wait_pend8021x(dev);
err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key_le,
sizeof(key_le));
if (unlikely(err)) { if (unlikely(err)) {
WL_ERR("WLC_SET_KEY error (%d)\n", err); WL_ERR("WLC_SET_KEY error (%d)\n", err);
return err; return err;
...@@ -1606,13 +1618,9 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, ...@@ -1606,13 +1618,9 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
goto done; goto done;
} }
/* Set the new key/index */ err = send_key_to_dongle(dev, &key); /* Set the new key/index */
convert_key_from_CPU(&key); if (err)
err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
if (unlikely(err)) {
WL_ERR("WLC_SET_KEY error (%d)\n", err);
goto done; goto done;
}
val = WEP_ENABLED; val = WEP_ENABLED;
err = brcmf_dev_intvar_get(dev, "wsec", &wsec); err = brcmf_dev_intvar_get(dev, "wsec", &wsec);
...@@ -1658,17 +1666,15 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, ...@@ -1658,17 +1666,15 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
key.algo = CRYPTO_ALGO_OFF; key.algo = CRYPTO_ALGO_OFF;
WL_CONN("key index (%d)\n", key_idx); WL_CONN("key index (%d)\n", key_idx);
/* Set the new key/index */ /* Set the new key/index */
convert_key_from_CPU(&key); err = send_key_to_dongle(dev, &key);
err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); if (err) {
if (unlikely(err)) {
if (err == -EINVAL) { if (err == -EINVAL) {
if (key.index >= DOT11_MAX_DEFAULT_KEYS) if (key.index >= DOT11_MAX_DEFAULT_KEYS)
/* we ignore this key index in this case */ /* we ignore this key index in this case */
WL_ERR("invalid key index (%d)\n", key_idx); WL_ERR("invalid key index (%d)\n", key_idx);
} else }
WL_ERR("WLC_SET_KEY error (%d)\n", err);
/* Ignore this error, may happen during DISASSOC */ /* Ignore this error, may happen during DISASSOC */
err = -EAGAIN; err = -EAGAIN;
goto done; goto done;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment