From 9f26a952210e44691f784b77bf1f83a500d63f58 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 15 May 2009 12:38:32 +0300 Subject: nl80211: Validate NL80211_ATTR_KEY_SEQ length Validate RSC (NL80211_ATTR_KEY_SEQ) length in nl80211/cfg80211 instead of having to do this in all the drivers. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- net/mac80211/key.c | 6 +++--- net/wireless/nl80211.c | 1 + net/wireless/util.c | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 827ea8e6ee0..ce267565e18 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -320,7 +320,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, case ALG_TKIP: key->conf.iv_len = TKIP_IV_LEN; key->conf.icv_len = TKIP_ICV_LEN; - if (seq && seq_len == 6) { + if (seq) { for (i = 0; i < NUM_RX_DATA_QUEUES; i++) { key->u.tkip.rx[i].iv32 = get_unaligned_le32(&seq[2]); @@ -332,7 +332,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, case ALG_CCMP: key->conf.iv_len = CCMP_HDR_LEN; key->conf.icv_len = CCMP_MIC_LEN; - if (seq && seq_len == CCMP_PN_LEN) { + if (seq) { for (i = 0; i < NUM_RX_DATA_QUEUES; i++) for (j = 0; j < CCMP_PN_LEN; j++) key->u.ccmp.rx_pn[i][j] = @@ -342,7 +342,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, case ALG_AES_CMAC: key->conf.iv_len = 0; key->conf.icv_len = sizeof(struct ieee80211_mmie); - if (seq && seq_len == 6) + if (seq) for (j = 0; j < 6; j++) key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1]; break; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0e22b5f5880..1cf57f53a28 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -77,6 +77,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, + [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, diff --git a/net/wireless/util.c b/net/wireless/util.c index beb226e78cd..b94c8604ad7 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -181,5 +181,20 @@ int cfg80211_validate_key_settings(struct key_params *params, int key_idx, return -EINVAL; } + if (params->seq) { + switch (params->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + /* These ciphers do not use key sequence */ + return -EINVAL; + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_AES_CMAC: + if (params->seq_len != 6) + return -EINVAL; + break; + } + } + return 0; } -- cgit v1.2.3-70-g09d2