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:
Kiran Kumar Lokere
2018-08-30 16:33:26 -07:00
کامیت شده توسط nshrivas
والد 61cbe85a14
کامیت 605e7a710b
2فایلهای تغییر یافته به همراه413 افزوده شده و 4 حذف شده

مشاهده پرونده

@@ -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;
}