diff options
Diffstat (limited to 'net/mac80211/wpa.c')
| -rw-r--r-- | net/mac80211/wpa.c | 57 |
1 files changed, 22 insertions, 35 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 5332014cb229..f4971cd45c64 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
| @@ -31,8 +31,8 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
| 31 | unsigned int hdrlen; | 31 | unsigned int hdrlen; |
| 32 | struct ieee80211_hdr *hdr; | 32 | struct ieee80211_hdr *hdr; |
| 33 | struct sk_buff *skb = tx->skb; | 33 | struct sk_buff *skb = tx->skb; |
| 34 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 34 | int authenticator; | 35 | int authenticator; |
| 35 | int wpa_test = 0; | ||
| 36 | int tail; | 36 | int tail; |
| 37 | 37 | ||
| 38 | hdr = (struct ieee80211_hdr *)skb->data; | 38 | hdr = (struct ieee80211_hdr *)skb->data; |
| @@ -47,16 +47,15 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
| 47 | data = skb->data + hdrlen; | 47 | data = skb->data + hdrlen; |
| 48 | data_len = skb->len - hdrlen; | 48 | data_len = skb->len - hdrlen; |
| 49 | 49 | ||
| 50 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 50 | if (info->control.hw_key && |
| 51 | !(tx->flags & IEEE80211_TX_FRAGMENTED) && | 51 | !(tx->flags & IEEE80211_TX_FRAGMENTED) && |
| 52 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && | 52 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) { |
| 53 | !wpa_test) { | 53 | /* hwaccel - with no need for SW-generated MMIC */ |
| 54 | /* hwaccel - with no need for preallocated room for MMIC */ | ||
| 55 | return TX_CONTINUE; | 54 | return TX_CONTINUE; |
| 56 | } | 55 | } |
| 57 | 56 | ||
| 58 | tail = MICHAEL_MIC_LEN; | 57 | tail = MICHAEL_MIC_LEN; |
| 59 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | 58 | if (!info->control.hw_key) |
| 60 | tail += TKIP_ICV_LEN; | 59 | tail += TKIP_ICV_LEN; |
| 61 | 60 | ||
| 62 | if (WARN_ON(skb_tailroom(skb) < tail || | 61 | if (WARN_ON(skb_tailroom(skb) < tail || |
| @@ -147,17 +146,16 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
| 147 | int len, tail; | 146 | int len, tail; |
| 148 | u8 *pos; | 147 | u8 *pos; |
| 149 | 148 | ||
| 150 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 149 | if (info->control.hw_key && |
| 151 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | 150 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
| 152 | /* hwaccel - with no need for preallocated room for IV/ICV */ | 151 | /* hwaccel - with no need for software-generated IV */ |
| 153 | info->control.hw_key = &tx->key->conf; | ||
| 154 | return 0; | 152 | return 0; |
| 155 | } | 153 | } |
| 156 | 154 | ||
| 157 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 155 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 158 | len = skb->len - hdrlen; | 156 | len = skb->len - hdrlen; |
| 159 | 157 | ||
| 160 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 158 | if (info->control.hw_key) |
| 161 | tail = 0; | 159 | tail = 0; |
| 162 | else | 160 | else |
| 163 | tail = TKIP_ICV_LEN; | 161 | tail = TKIP_ICV_LEN; |
| @@ -175,13 +173,11 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
| 175 | if (key->u.tkip.tx.iv16 == 0) | 173 | if (key->u.tkip.tx.iv16 == 0) |
| 176 | key->u.tkip.tx.iv32++; | 174 | key->u.tkip.tx.iv32++; |
| 177 | 175 | ||
| 178 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 176 | pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); |
| 179 | /* hwaccel - with preallocated room for IV */ | ||
| 180 | ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); | ||
| 181 | 177 | ||
| 182 | info->control.hw_key = &tx->key->conf; | 178 | /* hwaccel - with software IV */ |
| 179 | if (info->control.hw_key) | ||
| 183 | return 0; | 180 | return 0; |
| 184 | } | ||
| 185 | 181 | ||
| 186 | /* Add room for ICV */ | 182 | /* Add room for ICV */ |
| 187 | skb_put(skb, TKIP_ICV_LEN); | 183 | skb_put(skb, TKIP_ICV_LEN); |
| @@ -363,24 +359,20 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
| 363 | int hdrlen, len, tail; | 359 | int hdrlen, len, tail; |
| 364 | u8 *pos, *pn; | 360 | u8 *pos, *pn; |
| 365 | int i; | 361 | int i; |
| 366 | bool skip_hw; | ||
| 367 | |||
| 368 | skip_hw = (tx->key->conf.flags & IEEE80211_KEY_FLAG_SW_MGMT) && | ||
| 369 | ieee80211_is_mgmt(hdr->frame_control); | ||
| 370 | 362 | ||
| 371 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 363 | if (info->control.hw_key && |
| 372 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) && | 364 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
| 373 | !skip_hw) { | 365 | /* |
| 374 | /* hwaccel - with no need for preallocated room for CCMP | 366 | * hwaccel has no need for preallocated room for CCMP |
| 375 | * header or MIC fields */ | 367 | * header or MIC fields |
| 376 | info->control.hw_key = &tx->key->conf; | 368 | */ |
| 377 | return 0; | 369 | return 0; |
| 378 | } | 370 | } |
| 379 | 371 | ||
| 380 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 372 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 381 | len = skb->len - hdrlen; | 373 | len = skb->len - hdrlen; |
| 382 | 374 | ||
| 383 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 375 | if (info->control.hw_key) |
| 384 | tail = 0; | 376 | tail = 0; |
| 385 | else | 377 | else |
| 386 | tail = CCMP_MIC_LEN; | 378 | tail = CCMP_MIC_LEN; |
| @@ -405,11 +397,9 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
| 405 | 397 | ||
| 406 | ccmp_pn2hdr(pos, pn, key->conf.keyidx); | 398 | ccmp_pn2hdr(pos, pn, key->conf.keyidx); |
| 407 | 399 | ||
| 408 | if ((key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && !skip_hw) { | 400 | /* hwaccel - with software CCMP header */ |
| 409 | /* hwaccel - with preallocated room for CCMP header */ | 401 | if (info->control.hw_key) |
| 410 | info->control.hw_key = &tx->key->conf; | ||
| 411 | return 0; | 402 | return 0; |
| 412 | } | ||
| 413 | 403 | ||
| 414 | pos += CCMP_HDR_LEN; | 404 | pos += CCMP_HDR_LEN; |
| 415 | ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0); | 405 | ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0); |
| @@ -525,11 +515,8 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) | |||
| 525 | u8 *pn, aad[20]; | 515 | u8 *pn, aad[20]; |
| 526 | int i; | 516 | int i; |
| 527 | 517 | ||
| 528 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 518 | if (info->control.hw_key) |
| 529 | /* hwaccel */ | ||
| 530 | info->control.hw_key = &tx->key->conf; | ||
| 531 | return 0; | 519 | return 0; |
| 532 | } | ||
| 533 | 520 | ||
| 534 | if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) | 521 | if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) |
| 535 | return TX_DROP; | 522 | return TX_DROP; |
