diff options
author | Himanshu Agarwal <himanaga@codeaurora.org> | 2018-04-06 17:39:37 +0530 |
---|---|---|
committer | Srinivas Girigowda <quic_sgirigow@quicinc.com> | 2019-04-02 14:15:18 -0700 |
commit | e3ba2436764f634f0a4786fde998cc4c1b25839b (patch) | |
tree | 607c7bc03ebde65aa5da7d67914726ae747b7ba2 | |
parent | c6135cf81cedd5a5c4cc01c528f8c4a724223766 (diff) |
qcacld-3.0: Send frames with GCMP MIC LEN if encryption is GCMPandroid-q-preview-3_r0.2
CCMP and GCMP both have different lengths of their MIC part. MIC
length for CCMP is 8 bytes whereas it is 16 bytes for GCMP. When
encryption type is GCMP/GCMP-256, sending packets with CCMP MIC
length causes fw to drop the GCMP encrypted management packets
leading to connection issues.
Send GCMP encrypted frames with GCMP MIC length.
Change-Id: Ia83fa6ffde880fe69e5e4c3e3c3ce9c62ad8fa3c
CRs-Fixed: 2203224
Bug: 129483359
Signed-off-by: Srinivas Girigowda <quic_sgirigow@quicinc.com>
4 files changed, 33 insertions, 8 deletions
diff --git a/drivers/staging/qcacld-3.0/core/cds/inc/cds_ieee80211_common.h b/drivers/staging/qcacld-3.0/core/cds/inc/cds_ieee80211_common.h index b3c036bea771..c9a3448c7d49 100644 --- a/drivers/staging/qcacld-3.0/core/cds/inc/cds_ieee80211_common.h +++ b/drivers/staging/qcacld-3.0/core/cds/inc/cds_ieee80211_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011,2014-2015, 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011,2014-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1815,6 +1815,8 @@ enum { #define IEEE80211_CCMP_HEADERLEN 8 #define IEEE80211_CCMP_MICLEN 8 +#define WLAN_IEEE80211_GCMP_HEADERLEN 8 +#define WLAN_IEEE80211_GCMP_MICLEN 16 /* * 802.11w defines a MMIE chunk to be attached at the end of diff --git a/drivers/staging/qcacld-3.0/core/wma/inc/wma.h b/drivers/staging/qcacld-3.0/core/wma/inc/wma.h index cedc17908e19..93539ad3c0e7 100644 --- a/drivers/staging/qcacld-3.0/core/wma/inc/wma.h +++ b/drivers/staging/qcacld-3.0/core/wma/inc/wma.h @@ -1050,6 +1050,7 @@ struct roam_synch_frame_ind { * @aid: association id * @rmfEnabled: Robust Management Frame (RMF) enabled/disabled * @key: GTK key + * @ucast_key_cipher: unicast cipher key * @uapsd_cached_val: uapsd cached value * @stats_rsp: stats response * @fw_stats_set: fw stats value @@ -1125,6 +1126,7 @@ struct wma_txrx_node { uint8_t rmfEnabled; #ifdef WLAN_FEATURE_11W wma_igtk_key_t key; + uint32_t ucast_key_cipher; #endif /* WLAN_FEATURE_11W */ uint32_t uapsd_cached_val; tAniGetPEStatsRsp *stats_rsp; diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c index d5ac8b4ded75..a2bd09f2bbde 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c @@ -2722,11 +2722,20 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, if (!IEEE80211_IS_BROADCAST(wh->i_addr1) && !IEEE80211_IS_MULTICAST(wh->i_addr1)) { if (pFc->wep) { + uint8_t mic_len, hdr_len; + /* Allocate extra bytes for privacy header and * trailer */ - newFrmLen = frmLen + IEEE80211_CCMP_HEADERLEN + - IEEE80211_CCMP_MICLEN; + if (iface->ucast_key_cipher == + WMI_CIPHER_AES_GCM) { + hdr_len = WLAN_IEEE80211_GCMP_HEADERLEN; + mic_len = WLAN_IEEE80211_GCMP_MICLEN; + } else { + hdr_len = IEEE80211_CCMP_HEADERLEN; + mic_len = IEEE80211_CCMP_MICLEN; + } + newFrmLen = frmLen + hdr_len + mic_len; qdf_status = cds_packet_alloc((uint16_t) newFrmLen, (void **)&pFrame, @@ -2749,7 +2758,7 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, qdf_mem_set(pFrame, newFrmLen, 0); qdf_mem_copy(pFrame, wh, sizeof(*wh)); qdf_mem_copy(pFrame + sizeof(*wh) + - IEEE80211_CCMP_HEADERLEN, + hdr_len, pData + sizeof(*wh), frmLen - sizeof(*wh)); diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c index 0f5016af6dda..ce934a5cd9fc 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c @@ -1714,10 +1714,11 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle, params.key_len = key_params->key_len; #ifdef WLAN_FEATURE_11W + iface = &wma_handle->interfaces[key_params->vdev_id]; + if ((key_params->key_type == eSIR_ED_AES_128_CMAC) || (key_params->key_type == eSIR_ED_AES_GMAC_128) || (key_params->key_type == eSIR_ED_AES_GMAC_256)) { - iface = &wma_handle->interfaces[key_params->vdev_id]; if (iface) { iface->key.key_length = key_params->key_len; iface->key.key_cipher = params.key_cipher; @@ -1731,6 +1732,9 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle, CMAC_IPN_LEN); } } + + if (key_params->unicast && iface) + iface->ucast_key_cipher = params.key_cipher; #endif /* WLAN_FEATURE_11W */ WMA_LOGD("Key setup : vdev_id %d key_idx %d key_type %d key_len %d", @@ -3342,6 +3346,7 @@ int wma_process_rmf_frame(tp_wma_handle wma_handle, { uint8_t *orig_hdr; uint8_t *ccmp; + uint8_t mic_len, hdr_len; if ((wh)->i_fc[1] & IEEE80211_FC1_WEP) { if (IEEE80211_IS_BROADCAST(wh->i_addr1) || @@ -3368,15 +3373,22 @@ int wma_process_rmf_frame(tp_wma_handle wma_handle, return -EINVAL; } + if (iface->ucast_key_cipher == WMI_CIPHER_AES_GCM) { + hdr_len = WLAN_IEEE80211_GCMP_HEADERLEN; + mic_len = WLAN_IEEE80211_GCMP_MICLEN; + } else { + hdr_len = IEEE80211_CCMP_HEADERLEN; + mic_len = IEEE80211_CCMP_MICLEN; + } /* Strip privacy headers (and trailer) * for a received frame */ qdf_mem_move(orig_hdr + - IEEE80211_CCMP_HEADERLEN, wh, + hdr_len, wh, sizeof(*wh)); qdf_nbuf_pull_head(wbuf, - IEEE80211_CCMP_HEADERLEN); - qdf_nbuf_trim_tail(wbuf, IEEE80211_CCMP_MICLEN); + hdr_len); + qdf_nbuf_trim_tail(wbuf, mic_len); /* * CCMP header has been pulled off * reinitialize the start pointer of mac header |