mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-22 14:41:27 +00:00
mac80111: Add GCMP and GCMP-256 ciphers
This allows mac80211 to configure GCMP and GCMP-256 to the driver and also use software-implementation within mac80211 when the driver does not support this with hardware accelaration. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> [remove a spurious newline] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
cfcf1682c4
commit
00b9cfa3ff
14 changed files with 492 additions and 9 deletions
|
@ -24,6 +24,7 @@
|
|||
#include "debugfs_key.h"
|
||||
#include "aes_ccm.h"
|
||||
#include "aes_cmac.h"
|
||||
#include "aes_gcm.h"
|
||||
|
||||
|
||||
/**
|
||||
|
@ -163,6 +164,8 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
|
|||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
/* all of these we can do in software - if driver can */
|
||||
if (ret == 1)
|
||||
return 0;
|
||||
|
@ -412,6 +415,25 @@ ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
|
|||
return ERR_PTR(err);
|
||||
}
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
key->conf.iv_len = IEEE80211_GCMP_HDR_LEN;
|
||||
key->conf.icv_len = IEEE80211_GCMP_MIC_LEN;
|
||||
for (i = 0; seq && i < IEEE80211_NUM_TIDS + 1; i++)
|
||||
for (j = 0; j < IEEE80211_GCMP_PN_LEN; j++)
|
||||
key->u.gcmp.rx_pn[i][j] =
|
||||
seq[IEEE80211_GCMP_PN_LEN - j - 1];
|
||||
/* Initialize AES key state here as an optimization so that
|
||||
* it does not need to be initialized for every packet.
|
||||
*/
|
||||
key->u.gcmp.tfm = ieee80211_aes_gcm_key_setup_encrypt(key_data,
|
||||
key_len);
|
||||
if (IS_ERR(key->u.gcmp.tfm)) {
|
||||
err = PTR_ERR(key->u.gcmp.tfm);
|
||||
kfree(key);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (cs) {
|
||||
size_t len = (seq_len > MAX_PN_LEN) ?
|
||||
|
@ -433,10 +455,18 @@ ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
|
|||
|
||||
static void ieee80211_key_free_common(struct ieee80211_key *key)
|
||||
{
|
||||
if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
|
||||
switch (key->conf.cipher) {
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
ieee80211_aes_key_free(key->u.ccmp.tfm);
|
||||
if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||
ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
ieee80211_aes_gcm_key_free(key->u.gcmp.tfm);
|
||||
break;
|
||||
}
|
||||
kzfree(key);
|
||||
}
|
||||
|
||||
|
@ -760,6 +790,16 @@ void ieee80211_get_key_tx_seq(struct ieee80211_key_conf *keyconf,
|
|||
seq->ccmp.pn[1] = pn64 >> 32;
|
||||
seq->ccmp.pn[0] = pn64 >> 40;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
pn64 = atomic64_read(&key->u.gcmp.tx_pn);
|
||||
seq->gcmp.pn[5] = pn64;
|
||||
seq->gcmp.pn[4] = pn64 >> 8;
|
||||
seq->gcmp.pn[3] = pn64 >> 16;
|
||||
seq->gcmp.pn[2] = pn64 >> 24;
|
||||
seq->gcmp.pn[1] = pn64 >> 32;
|
||||
seq->gcmp.pn[0] = pn64 >> 40;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
@ -796,6 +836,16 @@ void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf,
|
|||
pn = key->u.aes_cmac.rx_pn;
|
||||
memcpy(seq->aes_cmac.pn, pn, IEEE80211_CMAC_PN_LEN);
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
|
||||
return;
|
||||
if (tid < 0)
|
||||
pn = key->u.gcmp.rx_pn[IEEE80211_NUM_TIDS];
|
||||
else
|
||||
pn = key->u.gcmp.rx_pn[tid];
|
||||
memcpy(seq->gcmp.pn, pn, IEEE80211_GCMP_PN_LEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_get_key_rx_seq);
|
||||
|
@ -831,6 +881,16 @@ void ieee80211_set_key_tx_seq(struct ieee80211_key_conf *keyconf,
|
|||
((u64)seq->aes_cmac.pn[0] << 40);
|
||||
atomic64_set(&key->u.aes_cmac.tx_pn, pn64);
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
pn64 = (u64)seq->gcmp.pn[5] |
|
||||
((u64)seq->gcmp.pn[4] << 8) |
|
||||
((u64)seq->gcmp.pn[3] << 16) |
|
||||
((u64)seq->gcmp.pn[2] << 24) |
|
||||
((u64)seq->gcmp.pn[1] << 32) |
|
||||
((u64)seq->gcmp.pn[0] << 40);
|
||||
atomic64_set(&key->u.gcmp.tx_pn, pn64);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
break;
|
||||
|
@ -868,6 +928,16 @@ void ieee80211_set_key_rx_seq(struct ieee80211_key_conf *keyconf,
|
|||
pn = key->u.aes_cmac.rx_pn;
|
||||
memcpy(pn, seq->aes_cmac.pn, IEEE80211_CMAC_PN_LEN);
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_GCMP:
|
||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||
if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
|
||||
return;
|
||||
if (tid < 0)
|
||||
pn = key->u.gcmp.rx_pn[IEEE80211_NUM_TIDS];
|
||||
else
|
||||
pn = key->u.gcmp.rx_pn[tid];
|
||||
memcpy(pn, seq->gcmp.pn, IEEE80211_GCMP_PN_LEN);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue