nl80211: Validate NL80211_ATTR_KEY_SEQ length
authorJouni Malinen <jouni.malinen@atheros.com>
Fri, 15 May 2009 09:38:32 +0000 (12:38 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 20 May 2009 18:46:25 +0000 (14:46 -0400)
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 <jouni.malinen@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/key.c
net/wireless/nl80211.c
net/wireless/util.c

index 827ea8e6ee0a3855387f77f33d68c51ab35a3abf..ce267565e18076ec4a852e52aa54bcdc418c0bbf 100644 (file)
@@ -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;
index 0e22b5f5880fef771fb01ff66c20b7c2a08689fa..1cf57f53a283c0565d084dfa91de30dd77414e20 100644 (file)
@@ -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 },
index beb226e78cd7d9f0d5afe732e259c5c2047955a9..b94c8604ad7c61cb8439b7610bd289bd47b27369 100644 (file)
@@ -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;
 }