diff --git a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c index bbe047c80d88..d633d31d9f1f 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c +++ b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c @@ -271,7 +271,7 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev, struct wlan_crypto_params *crypto_params; struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_peer *peer; - struct wlan_crypto_key *key; + struct wlan_crypto_key *key = NULL; const struct wlan_crypto_cipher *cipher; uint8_t macaddr[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; bool isbcast; @@ -313,10 +313,10 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev, qdf_print("%s[%d] cipher invalid\n", __func__, __LINE__); return QDF_STATUS_E_INVAL; } else if ((req_key->type == WLAN_CRYPTO_CIPHER_WEP) && - !((req_key->keylen != WLAN_CRYPTO_KEY_WEP40_LEN) - || (req_key->keylen != WLAN_CRYPTO_KEY_WEP104_LEN) - || (req_key->keylen != WLAN_CRYPTO_KEY_WEP128_LEN))) { - qdf_print("%s[%d] cipher invalid\n", __func__, __LINE__); + !((req_key->keylen == WLAN_CRYPTO_KEY_WEP40_LEN) + || (req_key->keylen == WLAN_CRYPTO_KEY_WEP104_LEN) + || (req_key->keylen == WLAN_CRYPTO_KEY_WEP128_LEN))) { + qdf_print("%s[%d] wep key len invalid\n", __func__, __LINE__); return QDF_STATUS_E_INVAL; } @@ -384,16 +384,23 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev, } if (vdev_mode == QDF_STA_MODE) { peer = wlan_vdev_get_bsspeer(vdev); - if (!peer) { - qdf_print("%s[%d] peer is null\n", - __func__, __LINE__); + if (!(peer && (QDF_STATUS_SUCCESS + == wlan_objmgr_peer_try_get_ref(peer, + WLAN_CRYPTO_ID)))) { + qdf_print("%s[%d] peer %p failed\n", + __func__, __LINE__, peer); + if (IS_MGMT_CIPHER(req_key->type)) { + crypto_priv->igtk_key = NULL; + crypto_priv->igtk_key_type + = WLAN_CRYPTO_CIPHER_NONE; + } else + crypto_priv->key[req_key->keyix] = NULL; + if (key) + qdf_mem_free(key); return QDF_STATUS_E_INVAL; } - wlan_objmgr_peer_try_get_ref(peer, WLAN_CRYPTO_ID); - wlan_peer_obj_lock(peer); qdf_mem_copy(macaddr, wlan_peer_get_macaddr(peer), WLAN_ALEN); - wlan_peer_obj_unlock(peer); wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID); } } else { @@ -643,7 +650,7 @@ QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev, struct wlan_crypto_key *key; struct wlan_crypto_cipher *cipher_table; struct wlan_objmgr_psoc *psoc; - uint8_t bssid_mac[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + uint8_t bssid_mac[WLAN_ALEN]; if (!vdev || !macaddr || (key_idx >= WLAN_CRYPTO_MAXKEYIDX)) { qdf_print("%s[%d] Invalid params vdev %p, macaddr %p" @@ -732,7 +739,7 @@ QDF_STATUS wlan_crypto_default_key(struct wlan_objmgr_vdev *vdev, struct wlan_crypto_params *crypto_params; struct wlan_crypto_key *key; struct wlan_objmgr_psoc *psoc; - uint8_t bssid_mac[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + uint8_t bssid_mac[WLAN_ALEN]; wlan_vdev_obj_lock(vdev); qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN); @@ -819,7 +826,7 @@ QDF_STATUS wlan_crypto_encap(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; struct wlan_crypto_cipher *cipher_table; struct wlan_objmgr_psoc *psoc; - uint8_t bssid_mac[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + uint8_t bssid_mac[WLAN_ALEN]; if (!wlan_crypto_is_data_protected((uint8_t *)qdf_nbuf_data(wbuf))) return QDF_STATUS_E_INVAL; @@ -902,7 +909,7 @@ QDF_STATUS wlan_crypto_decap(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; struct wlan_crypto_cipher *cipher_table; struct wlan_objmgr_psoc *psoc; - uint8_t bssid_mac[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + uint8_t bssid_mac[WLAN_ALEN]; if (!wlan_crypto_is_data_protected((uint8_t *)qdf_nbuf_data(wbuf))) return QDF_STATUS_E_INVAL; @@ -984,7 +991,7 @@ QDF_STATUS wlan_crypto_enmic(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; struct wlan_crypto_cipher *cipher_table; struct wlan_objmgr_psoc *psoc; - uint8_t bssid_mac[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + uint8_t bssid_mac[WLAN_ALEN]; wlan_vdev_obj_lock(vdev); qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN); @@ -1065,7 +1072,7 @@ QDF_STATUS wlan_crypto_demic(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; struct wlan_crypto_cipher *cipher_table; struct wlan_objmgr_psoc *psoc; - uint8_t bssid_mac[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + uint8_t bssid_mac[WLAN_ALEN]; wlan_vdev_obj_lock(vdev); qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN); @@ -2392,11 +2399,13 @@ QDF_STATUS wlan_crypto_set_peer_wep_keys(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr){ uint8_t keymac[WLAN_ALEN]; struct wlan_crypto_comp_priv *crypto_priv; + struct wlan_crypto_comp_priv *sta_crypto_priv; struct wlan_crypto_params *crypto_params; struct wlan_crypto_key *key; - struct wlan_crypto_key *tmp_key; + struct wlan_crypto_key *sta_key; struct wlan_crypto_cipher *cipher_table; struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_peer *peer; int i; enum tQDF_ADAPTER_MODE opmode; @@ -2424,14 +2433,37 @@ QDF_STATUS wlan_crypto_set_peer_wep_keys(struct wlan_objmgr_vdev *vdev, if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) return QDF_STATUS_E_INVAL; - tmp_key = (struct wlan_crypto_key *)qdf_mem_malloc( - sizeof(struct wlan_crypto_key)); + if (opmode == QDF_STA_MODE) { + peer = wlan_vdev_get_bsspeer(vdev); + if (!(peer && (QDF_STATUS_SUCCESS + == wlan_objmgr_peer_try_get_ref(peer, + WLAN_CRYPTO_ID)))) { + qdf_print("%s[%d] peer %p ref failed\n", + __func__, __LINE__, peer); + return QDF_STATUS_E_INVAL; + } + } else { + uint8_t bssid_mac[WLAN_ALEN]; - if (!tmp_key) - return QDF_STATUS_E_NULL_VALUE; + wlan_vdev_obj_lock(vdev); + qdf_mem_copy(bssid_mac, + wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN); + wlan_vdev_obj_unlock(vdev); + peer = wlan_objmgr_get_peer_by_mac_n_vdev( + psoc, mac_addr, bssid_mac, WLAN_CRYPTO_ID); + if (!peer) { + qdf_print("%s[%d] peer NULL\n", __func__, __LINE__); + return QDF_STATUS_E_INVAL; + } + } - /* push only valid static WEP keys from vap */ + wlan_crypto_peer_get_comp_params(peer, &sta_crypto_priv); + wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID); + if (sta_crypto_priv == NULL) { + qdf_print("%s[%d] sta priv is null\n", __func__, __LINE__); + return QDF_STATUS_E_INVAL; + } for (i = 0; i < WLAN_CRYPTO_MAXKEYIDX; i++) { if (crypto_priv->key[i]) { @@ -2443,37 +2475,47 @@ QDF_STATUS wlan_crypto_set_peer_wep_keys(struct wlan_objmgr_vdev *vdev, key->cipher_table; if (cipher_table->cipher == WLAN_CRYPTO_CIPHER_WEP) { - qdf_mem_copy(tmp_key, key, + sta_key = qdf_mem_malloc( + sizeof(struct wlan_crypto_key)); + if (!sta_key) { + qdf_print("%s[%d] key alloc failed\n", + __func__, __LINE__); + return QDF_STATUS_E_NOMEM; + } + sta_crypto_priv->key[i] = sta_key; + qdf_mem_copy(sta_key, key, sizeof(struct wlan_crypto_key)); qdf_copy_macaddr((struct qdf_mac_addr *)keymac, (struct qdf_mac_addr *)mac_addr); - tmp_key->flags &= ~WLAN_CRYPTO_KEY_DEFAULT; - if (crypto_priv->def_tx_keyid == i) - tmp_key->flags - |= WLAN_CRYPTO_KEY_DEFAULT; + sta_key->flags &= ~WLAN_CRYPTO_KEY_DEFAULT; + if (crypto_priv->def_tx_keyid == i) { + sta_key->flags + |= WLAN_CRYPTO_KEY_DEFAULT; + sta_crypto_priv->def_tx_keyid = + crypto_priv->def_tx_keyid; + } /* setting the broadcast/multicast key for sta*/ if (opmode == QDF_STA_MODE || opmode == QDF_IBSS_MODE){ if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) { WLAN_CRYPTO_TX_OPS_SETKEY(psoc)( - vdev, tmp_key, mac_addr, + vdev, sta_key, mac_addr, cipher_table->cipher); } } /* setting unicast key */ - tmp_key->flags &= ~WLAN_CRYPTO_KEY_GROUP; + sta_key->flags &= ~WLAN_CRYPTO_KEY_GROUP; if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) { WLAN_CRYPTO_TX_OPS_SETKEY(psoc)(vdev, - tmp_key, mac_addr, + sta_key, mac_addr, cipher_table->cipher); } } } } - qdf_mem_free(tmp_key); return QDF_STATUS_SUCCESS; } diff --git a/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c b/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c index fab3cd609f4e..585c1949d69b 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c +++ b/umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c @@ -30,6 +30,7 @@ #include #include "wlan_crypto_global_def.h" +#include "wlan_crypto_global_api.h" #include "wlan_crypto_def_i.h" #include "wlan_crypto_main_i.h" #include "wlan_crypto_obj_mgr_i.h" @@ -97,6 +98,7 @@ static QDF_STATUS wlan_crypto_vdev_obj_create_handler( struct wlan_crypto_comp_priv *crypto_priv; struct wlan_objmgr_pdev *pdev; struct wlan_crypto_params *crypto_param; + QDF_STATUS status; if (!vdev) return QDF_STATUS_E_INVAL; @@ -127,10 +129,14 @@ static QDF_STATUS wlan_crypto_vdev_obj_create_handler( /* update the fw_caps into ciphercaps then attach to objmgr*/ wlan_crypto_register_all_ciphers(crypto_param); - return wlan_objmgr_vdev_component_obj_attach(vdev, + status = wlan_objmgr_vdev_component_obj_attach(vdev, WLAN_UMAC_COMP_CRYPTO, (void *)crypto_priv, QDF_STATUS_SUCCESS); + if (status != QDF_STATUS_SUCCESS) + qdf_mem_free(crypto_priv); + + return status; } static QDF_STATUS wlan_crypto_peer_obj_create_handler( @@ -138,6 +144,8 @@ static QDF_STATUS wlan_crypto_peer_obj_create_handler( void *arg) { struct wlan_crypto_comp_priv *crypto_priv; + uint8_t keymac[WLAN_ALEN]; + QDF_STATUS status; if (!peer) return QDF_STATUS_E_INVAL; @@ -146,10 +154,24 @@ static QDF_STATUS wlan_crypto_peer_obj_create_handler( if (!crypto_priv) return QDF_STATUS_E_NOMEM; - return wlan_objmgr_peer_component_obj_attach(peer, - WLAN_UMAC_COMP_CRYPTO, - (void *)crypto_priv, - QDF_STATUS_SUCCESS); + status = wlan_objmgr_peer_component_obj_attach(peer, + WLAN_UMAC_COMP_CRYPTO, (void *)crypto_priv, + QDF_STATUS_SUCCESS); + + if (status == QDF_STATUS_SUCCESS) { + if (wlan_vdev_get_selfpeer(peer->peer_objmgr.vdev) != peer) { + qdf_copy_macaddr((struct qdf_mac_addr *)keymac, + (struct qdf_mac_addr *)wlan_peer_get_macaddr(peer)); + wlan_crypto_set_peer_wep_keys( + wlan_peer_get_vdev(peer), keymac); + } + } else { + qdf_print("%s[%d] peer obj failed status %d\n", + __func__, __LINE__, status); + qdf_mem_free(crypto_priv); + } + + return status; } static QDF_STATUS wlan_crypto_psoc_obj_destroy_handler( diff --git a/umac/cmn_services/crypto/src/wlan_crypto_wep.c b/umac/cmn_services/crypto/src/wlan_crypto_wep.c index e8f0e5b879cb..149c0199c3b6 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_wep.c +++ b/umac/cmn_services/crypto/src/wlan_crypto_wep.c @@ -56,12 +56,21 @@ static QDF_STATUS wep_encap(struct wlan_crypto_key *key, ivp = (uint8_t *)qdf_nbuf_data(wbuf); } else { ivp = (uint8_t *)qdf_nbuf_push_head(wbuf, - cipher_table->header); - memmove(ivp, ivp + cipher_table->header, hdrlen); + cipher_table->header + + cipher_table->trailer); + qdf_mem_move(ivp, + ivp + cipher_table->header + cipher_table->trailer, + hdrlen); + qdf_mem_move(ivp + hdrlen + cipher_table->header, + ivp + hdrlen + + cipher_table->header + cipher_table->trailer, + (qdf_nbuf_len(wbuf) - hdrlen + - cipher_table->header + cipher_table->trailer)); + ivp = (uint8_t *)qdf_nbuf_data(wbuf); } ivp += hdrlen; - + key->keytsc++; #if _BYTE_ORDER == _BIG_ENDIAN ivp[2] = key->keyrsc[0] >> 0; ivp[1] = key->keyrsc[0] >> 8; diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c index f1732d9004b0..e14205a36cf8 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c +++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c @@ -614,24 +614,24 @@ QDF_STATUS wlan_objmgr_vdev_peer_attach(struct wlan_objmgr_vdev *vdev, objmgr->wlan_peer_count++; wlan_pdev_incr_peer_count(wlan_vdev_get_pdev(vdev)); - if ((wlan_peer_get_peer_type(peer) == WLAN_PEER_AP) || - (wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_GO)) { - if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), - wlan_vdev_mlme_get_macaddr(vdev)) == - QDF_STATUS_SUCCESS) { - /* - * if peer mac address and vdev mac address match, set - * this peer as self peer - */ - wlan_vdev_set_selfpeer(vdev, peer); - /* For AP mode, self peer and BSS peer are same */ - if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) - wlan_vdev_set_bsspeer(vdev, peer); - } - /* set BSS peer for sta */ - if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) + if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), + wlan_vdev_mlme_get_macaddr(vdev)) == + QDF_STATUS_SUCCESS) { + /* + * if peer mac address and vdev mac address match, set + * this peer as self peer + */ + wlan_vdev_set_selfpeer(vdev, peer); + /* For AP mode, self peer and BSS peer are same */ + if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) wlan_vdev_set_bsspeer(vdev, peer); } + /* set BSS peer for sta */ + if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) && + ((wlan_peer_get_peer_type(peer) == WLAN_PEER_AP) || + (wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_GO))) + wlan_vdev_set_bsspeer(vdev, peer); + /* Increment vdev ref count to make sure it won't be destroyed before */ wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID); wlan_vdev_obj_unlock(vdev);