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:02:34 -0700 |
commit | 83e593bc9a8b0b814c37f3a5669137962d99eb3f (patch) | |
tree | db5ea8d8bdf0d4b0f009ab7e9a082a1ccb130b53 | |
parent | 5936573ee430fbd10c9181be8a71b9602418f71c (diff) | |
download | qcacld-android-msm-crosshatch-4.9-q-preview-3.tar.gz |
qcacld-3.0: Send frames with GCMP MIC LEN if encryption is GCMPandroid-q-preview-3_r0.3android-msm-crosshatch-4.9-q-preview-3
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>
-rw-r--r-- | core/cds/inc/cds_ieee80211_common.h | 4 | ||||
-rw-r--r-- | core/wma/inc/wma.h | 2 | ||||
-rw-r--r-- | core/wma/src/wma_data.c | 15 | ||||
-rw-r--r-- | core/wma/src/wma_mgmt.c | 20 |
4 files changed, 33 insertions, 8 deletions
diff --git a/core/cds/inc/cds_ieee80211_common.h b/core/cds/inc/cds_ieee80211_common.h index b3c036bea7..c9a3448c7d 100644 --- a/core/cds/inc/cds_ieee80211_common.h +++ b/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/core/wma/inc/wma.h b/core/wma/inc/wma.h index 3083c1ebc9..47b6532af1 100644 --- a/core/wma/inc/wma.h +++ b/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 @@ -1126,6 +1127,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/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index ce3aedc5d9..5b3e978cff 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -2718,11 +2718,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, @@ -2745,7 +2754,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/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 1a0fc4287c..5e61e62138 100644 --- a/core/wma/src/wma_mgmt.c +++ b/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", @@ -3361,6 +3365,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) || @@ -3387,15 +3392,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 |