qcacmn: Add new crypto serivce apis for security checks
Add new crypto component service apis to check the security match. Change-Id: I66336c4924b2a2c203d6ba197ab649725f960ef8 CRs-Fixed: 2337195
This commit is contained in:

کامیت شده توسط
nshrivas

والد
61cbe85a14
کامیت
605e7a710b
@@ -589,4 +589,71 @@ uint16_t wlan_crypto_get_keyid(uint8_t *data, int hdrlen);
|
||||
* Return: void
|
||||
*/
|
||||
void wlan_crypto_restore_keys(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* wlan_crypto_check_open_none - called by ucfg to check for open security
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
*
|
||||
* This function gets called from ucfg to check open security.
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
bool wlan_crypto_check_open_none(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vedv_id);
|
||||
|
||||
/**
|
||||
* wlan_crypto_check_wep - called by ucfg to check for WEP security
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
*
|
||||
* This function gets called from ucfg to check WEP security.
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
bool wlan_crypto_check_wep(struct wlan_objmgr_psoc *psoc, uint8_t vedv_id);
|
||||
|
||||
/**
|
||||
* wlan_crypto_check_rsn_match - called by ucfg to check for RSN match
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @ie_ptr: pointer to IEs
|
||||
* @ie_len: IE length
|
||||
*
|
||||
* This function gets called from ucfg to check RSN match.
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
bool wlan_crypto_check_rsn_match(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vedv_id, uint8_t *ie_ptr,
|
||||
uint16_t ie_len);
|
||||
|
||||
/**
|
||||
* wlan_crypto_check_rsn_match - called by ucfg to check for WPA match
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @ie_ptr: pointer to IEs
|
||||
* @ie_len: IE length
|
||||
*
|
||||
* This function gets called from ucfg to check WPA match.
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
bool wlan_crypto_check_wpa_match(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vedv_id, uint8_t *ie_ptr,
|
||||
uint16_t ie_len);
|
||||
|
||||
/**
|
||||
* wlan_set_vdev_crypto_prarams_from_ie - Sets vdev crypto params from IE info
|
||||
* @vdev: vdev pointer
|
||||
* @ie_ptr: pointer to IE
|
||||
* @ie_len: IE length
|
||||
*
|
||||
* This function gets called from ucfg to set crypto params from IE data.
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS or error code
|
||||
*/
|
||||
QDF_STATUS wlan_set_vdev_crypto_prarams_from_ie(struct wlan_objmgr_vdev *vdev,
|
||||
uint8_t *ie_ptr,
|
||||
uint16_t ie_len);
|
||||
#endif /* end of _WLAN_CRYPTO_GLOBAL_API_H_ */
|
||||
|
@@ -19,6 +19,7 @@
|
||||
/**
|
||||
* DOC: Public APIs for crypto service
|
||||
*/
|
||||
|
||||
#include <qdf_types.h>
|
||||
#include <wlan_cmn.h>
|
||||
#include <wlan_objmgr_cmn.h>
|
||||
@@ -27,6 +28,7 @@
|
||||
#include <wlan_objmgr_pdev_obj.h>
|
||||
#include <wlan_objmgr_vdev_obj.h>
|
||||
#include <wlan_objmgr_peer_obj.h>
|
||||
#include <wlan_utility.h>
|
||||
|
||||
#include "wlan_crypto_global_def.h"
|
||||
#include "wlan_crypto_global_api.h"
|
||||
@@ -118,6 +120,7 @@ static QDF_STATUS wlan_crypto_set_param(struct wlan_crypto_params *crypto_params
|
||||
uint32_t value){
|
||||
QDF_STATUS status = QDF_STATUS_E_INVAL;
|
||||
|
||||
crypto_debug("param %d, value %d", param, value);
|
||||
switch (param) {
|
||||
case WLAN_CRYPTO_PARAM_AUTH_MODE:
|
||||
status = wlan_crypto_set_authmode(crypto_params, value);
|
||||
@@ -2570,24 +2573,42 @@ bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_crypto_params *my_crypto_params;
|
||||
my_crypto_params = wlan_crypto_vdev_get_crypto_params(vdev);
|
||||
|
||||
if (!my_crypto_params)
|
||||
if (!my_crypto_params) {
|
||||
crypto_debug("vdev crypto params is NULL");
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* Check peer's pairwise ciphers.
|
||||
* At least one must match with our unicast cipher
|
||||
*/
|
||||
if (!UCAST_CIPHER_MATCH(crypto_params, my_crypto_params))
|
||||
if (!UCAST_CIPHER_MATCH(crypto_params, my_crypto_params)) {
|
||||
crypto_debug("Unicast cipher match failed");
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* Check peer's group cipher is our enabled multicast cipher.
|
||||
*/
|
||||
if (!MCAST_CIPHER_MATCH(crypto_params, my_crypto_params))
|
||||
if (!MCAST_CIPHER_MATCH(crypto_params, my_crypto_params)) {
|
||||
crypto_debug("Multicast cipher match failed");
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* Check peer's key management class set (PSK or UNSPEC)
|
||||
*/
|
||||
if (!KEY_MGMTSET_MATCH(crypto_params, my_crypto_params))
|
||||
if (!KEY_MGMTSET_MATCH(crypto_params, my_crypto_params)) {
|
||||
crypto_debug("Key mgmt match failed");
|
||||
return false;
|
||||
}
|
||||
if (wlan_crypto_vdev_is_pmf_enabled(vdev) &&
|
||||
!(crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)) {
|
||||
crypto_debug("Peer is not PMF capable");
|
||||
return false;
|
||||
}
|
||||
if (!wlan_crypto_vdev_is_pmf_enabled(vdev) &&
|
||||
(crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)) {
|
||||
crypto_debug("Peer needs PMF, but vdev is not capable");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -3329,3 +3350,324 @@ void wlan_crypto_restore_keys(struct wlan_objmgr_vdev *vdev)
|
||||
WLAN_CRYPTO_ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_crypto_check_open_none - called by ucfg to check for open security
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
*
|
||||
* This function gets called from ucfg to check open security.
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
bool wlan_crypto_check_open_none(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
|
||||
{
|
||||
struct wlan_crypto_comp_priv *crypto_priv;
|
||||
struct wlan_crypto_params *crypto_params;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
bool match = true;
|
||||
|
||||
if (!psoc) {
|
||||
crypto_err("PSOC is NULL");
|
||||
return false;
|
||||
}
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
||||
WLAN_CRYPTO_ID);
|
||||
if (!vdev) {
|
||||
crypto_err("vdev is NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
crypto_priv = (struct wlan_crypto_comp_priv *)
|
||||
wlan_get_vdev_crypto_obj(vdev);
|
||||
|
||||
if (!crypto_priv) {
|
||||
crypto_err("crypto_priv NULL");
|
||||
match = false;
|
||||
goto send_res;
|
||||
}
|
||||
|
||||
crypto_params = &crypto_priv->crypto_params;
|
||||
|
||||
if (crypto_params->mcastcipherset != WLAN_CRYPTO_CIPHER_NONE) {
|
||||
match = false;
|
||||
goto send_res;
|
||||
}
|
||||
|
||||
if ((crypto_params->authmodeset != WLAN_CRYPTO_AUTH_AUTO) &&
|
||||
(crypto_params->authmodeset != WLAN_CRYPTO_AUTH_NONE))
|
||||
match = false;
|
||||
|
||||
send_res:
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_CRYPTO_ID);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_crypto_check_wep - called by ucfg to check for WEP security
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
*
|
||||
* This function gets called from ucfg to check WEP security.
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
bool wlan_crypto_check_wep(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
|
||||
{
|
||||
struct wlan_crypto_comp_priv *crypto_priv;
|
||||
struct wlan_crypto_params *crypto_params;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
bool match = true;
|
||||
|
||||
if (!psoc) {
|
||||
crypto_err("PSOC is NULL");
|
||||
return false;
|
||||
}
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
||||
WLAN_CRYPTO_ID);
|
||||
if (!vdev) {
|
||||
crypto_err("vdev is NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
crypto_priv = (struct wlan_crypto_comp_priv *)
|
||||
wlan_get_vdev_crypto_obj(vdev);
|
||||
|
||||
if (!crypto_priv) {
|
||||
crypto_err("crypto_priv NULL");
|
||||
match = false;
|
||||
goto send_res;
|
||||
}
|
||||
|
||||
crypto_params = &crypto_priv->crypto_params;
|
||||
|
||||
if ((crypto_params->ucastcipherset != WLAN_CRYPTO_CIPHER_WEP) &&
|
||||
(crypto_params->ucastcipherset != WLAN_CRYPTO_CIPHER_WEP_40) &&
|
||||
(crypto_params->ucastcipherset != WLAN_CRYPTO_CIPHER_WEP_104)) {
|
||||
match = false;
|
||||
goto send_res;
|
||||
}
|
||||
if ((crypto_params->mcastcipherset != WLAN_CRYPTO_CIPHER_WEP) &&
|
||||
(crypto_params->mcastcipherset != WLAN_CRYPTO_CIPHER_WEP_40) &&
|
||||
(crypto_params->mcastcipherset != WLAN_CRYPTO_CIPHER_WEP_104)) {
|
||||
match = false;
|
||||
goto send_res;
|
||||
}
|
||||
if (crypto_params->ucastcipherset != crypto_params->mcastcipherset) {
|
||||
match = false;
|
||||
goto send_res;
|
||||
}
|
||||
if ((crypto_params->authmodeset != WLAN_CRYPTO_AUTH_AUTO) &&
|
||||
(crypto_params->authmodeset != WLAN_CRYPTO_AUTH_OPEN) &&
|
||||
(crypto_params->authmodeset != WLAN_CRYPTO_AUTH_SHARED)) {
|
||||
match = false;
|
||||
}
|
||||
send_res:
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_CRYPTO_ID);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
wlan_get_crypto_params_from_rsn_ie(struct wlan_crypto_params *crypto_params,
|
||||
uint8_t *ie_ptr, uint16_t ie_len)
|
||||
{
|
||||
const uint8_t *rsn_ie = NULL;
|
||||
QDF_STATUS status;
|
||||
|
||||
qdf_mem_zero(crypto_params, sizeof(struct wlan_crypto_params));
|
||||
rsn_ie = wlan_get_ie_ptr_from_eid(WLAN_ELEMID_RSN, ie_ptr, ie_len);
|
||||
if (!rsn_ie) {
|
||||
crypto_err("RSN IE NULL");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
status = wlan_crypto_rsnie_check(crypto_params, (uint8_t *)rsn_ie);
|
||||
if (QDF_STATUS_SUCCESS != status) {
|
||||
crypto_err("RSN IE check failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
wlan_get_crypto_params_from_wpa_ie(struct wlan_crypto_params *crypto_params,
|
||||
uint8_t *ie_ptr, uint16_t ie_len)
|
||||
{
|
||||
const uint8_t *wpa_ie = NULL;
|
||||
uint32_t wpa_oui;
|
||||
QDF_STATUS status;
|
||||
|
||||
qdf_mem_zero(crypto_params, sizeof(struct wlan_crypto_params));
|
||||
|
||||
wpa_oui = WLAN_WPA_SEL(WLAN_WPA_OUI_TYPE);
|
||||
wpa_ie = wlan_get_vendor_ie_ptr_from_oui((uint8_t *)&wpa_oui,
|
||||
WLAN_OUI_SIZE, ie_ptr, ie_len);
|
||||
if (!wpa_ie) {
|
||||
crypto_err("WPA IE NULL");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
status = wlan_crypto_wpaie_check(crypto_params, (uint8_t *)wpa_ie);
|
||||
if (QDF_STATUS_SUCCESS != status) {
|
||||
crypto_err("WPA IE check failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
/**
|
||||
* wlan_crypto_check_rsn_match - called by ucfg to check for RSN match
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @ie_ptr: pointer to IEs
|
||||
* @ie_len: IE length
|
||||
*
|
||||
* This function gets called from ucfg to check RSN match.
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
bool wlan_crypto_check_rsn_match(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id, uint8_t *ie_ptr,
|
||||
uint16_t ie_len)
|
||||
{
|
||||
struct wlan_crypto_params peer_crypto_params;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
bool match = true;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!psoc) {
|
||||
crypto_err("PSOC is NULL");
|
||||
return false;
|
||||
}
|
||||
status = wlan_get_crypto_params_from_rsn_ie(&peer_crypto_params,
|
||||
ie_ptr, ie_len);
|
||||
if (QDF_STATUS_SUCCESS != status) {
|
||||
crypto_err("get crypto prarams from RSN IE failed");
|
||||
return false;
|
||||
}
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
||||
WLAN_CRYPTO_ID);
|
||||
if (!vdev) {
|
||||
crypto_err("vdev is NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
match = wlan_crypto_rsn_info(vdev, &peer_crypto_params);
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_CRYPTO_ID);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_crypto_check_wpa_match - called by ucfg to check for WPA match
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @ie_ptr: pointer to IEs
|
||||
* @ie_len: IE length
|
||||
*
|
||||
* This function gets called from ucfg to check WPA match.
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
bool wlan_crypto_check_wpa_match(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id, uint8_t *ie_ptr,
|
||||
uint16_t ie_len)
|
||||
{
|
||||
struct wlan_crypto_params peer_crypto_params;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
bool match = true;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!psoc) {
|
||||
crypto_err("PSOC is NULL");
|
||||
return false;
|
||||
}
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
||||
WLAN_CRYPTO_ID);
|
||||
if (!vdev) {
|
||||
crypto_err("vdev is NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
status = wlan_get_crypto_params_from_wpa_ie(&peer_crypto_params,
|
||||
ie_ptr, ie_len);
|
||||
if (QDF_STATUS_SUCCESS != status) {
|
||||
crypto_err("get crypto prarams from WPA IE failed");
|
||||
match = false;
|
||||
goto send_res;
|
||||
}
|
||||
match = wlan_crypto_rsn_info(vdev, &peer_crypto_params);
|
||||
send_res:
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_CRYPTO_ID);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wlan_crypto_merge_prarams(struct wlan_crypto_params *dst_params,
|
||||
struct wlan_crypto_params *src_params)
|
||||
{
|
||||
dst_params->authmodeset |= src_params->authmodeset;
|
||||
dst_params->ucastcipherset |= src_params->ucastcipherset;
|
||||
dst_params->mcastcipherset |= src_params->mcastcipherset;
|
||||
dst_params->mgmtcipherset |= src_params->mgmtcipherset;
|
||||
dst_params->cipher_caps |= src_params->cipher_caps;
|
||||
dst_params->key_mgmt |= src_params->key_mgmt;
|
||||
dst_params->rsn_caps |= src_params->rsn_caps;
|
||||
}
|
||||
|
||||
QDF_STATUS wlan_set_vdev_crypto_prarams_from_ie(struct wlan_objmgr_vdev *vdev,
|
||||
uint8_t *ie_ptr,
|
||||
uint16_t ie_len)
|
||||
{
|
||||
struct wlan_crypto_params crypto_params;
|
||||
QDF_STATUS status;
|
||||
struct wlan_crypto_params *vdev_crypto_params;
|
||||
struct wlan_crypto_comp_priv *crypto_priv;
|
||||
bool send_fail = false;
|
||||
|
||||
if (!vdev) {
|
||||
crypto_err("VDEV is NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!ie_ptr) {
|
||||
crypto_err("IE ptr is NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
crypto_priv = (struct wlan_crypto_comp_priv *)
|
||||
wlan_get_vdev_crypto_obj(vdev);
|
||||
|
||||
if (!crypto_priv) {
|
||||
crypto_err("crypto_priv NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
vdev_crypto_params = &crypto_priv->crypto_params;
|
||||
|
||||
qdf_mem_zero(vdev_crypto_params, sizeof(struct wlan_crypto_params));
|
||||
status = wlan_get_crypto_params_from_rsn_ie(&crypto_params,
|
||||
ie_ptr, ie_len);
|
||||
if (QDF_STATUS_SUCCESS == status) {
|
||||
wlan_crypto_merge_prarams(vdev_crypto_params, &crypto_params);
|
||||
} else {
|
||||
crypto_err("get crypto prarams from RSN IE failed");
|
||||
send_fail = true;
|
||||
}
|
||||
|
||||
status = wlan_get_crypto_params_from_wpa_ie(&crypto_params,
|
||||
ie_ptr, ie_len);
|
||||
if (QDF_STATUS_SUCCESS == status) {
|
||||
wlan_crypto_merge_prarams(vdev_crypto_params, &crypto_params);
|
||||
send_fail = false;
|
||||
} else {
|
||||
crypto_err("get crypto prarams from WPA IE failed");
|
||||
}
|
||||
|
||||
return send_fail ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
مرجع در شماره جدید
Block a user