qcacmn: Add crypto service files

Add crypto service files

Change-Id: I6efa8e633ca414a819c0ede05c44e89aebde8ad3
This commit is contained in:
Ashok Ponnaiah 2017-02-17 22:10:20 +05:30 • committed by Sandeep Puligilla
commit 89d288129e
16 changed files with 4847 additions and 0 deletions

View file

@ -0,0 +1,345 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Public APIs for crypto service
*/
#ifndef _WLAN_CRYPTO_GLOBAL_API_H_
#define _WLAN_CRYPTO_GLOBAL_API_H_
/**
* wlan_crypto_set_param - called by ucfg to set crypto param
*
* @vdev: vdev
* @param: param to be set.
* @value: value
*
* This function gets called from ucfg to set param
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_param(struct wlan_objmgr_vdev *vdev,
wlan_crypto_param_type param,
uint32_t value);
/**
* wlan_crypto_get_param - called by ucfg to get crypto param
*
* @vdev: vdev
* @param: param to be get.
*
* This function gets called from ucfg to get param
*
* Return: value or -1 for failure
*/
int32_t wlan_crypto_get_param(struct wlan_objmgr_vdev *vdev,
wlan_crypto_param_type param);
/**
* wlan_crypto_setkey - called by ucfg to setkey
*
* @vdev: vdev
* @req_key: req_key with cipher type, key macaddress
*
* This function gets called from ucfg to sey key
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_req_key *req_key);
/**
* wlan_crypto_getkey - called by ucfg to get key
*
* @vdev: vdev
* @req_key: key value will be copied in this req_key
* @mac_address: mac address of the peer for unicast key
* or broadcast address if group key is requested.
* This function gets called from ucfg to get key
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_getkey(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_req_key *req_key,
uint8_t *mac_addr);
/**
* wlan_crypto_delkey - called by ucfg to delete key
*
* @vdev: vdev
* @mac_address: mac address of the peer for unicast key
* or broadcast address if group key is deleted.
* @key_idx: key index to be deleted
* This function gets called from ucfg to delete key
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev,
uint8_t *macaddr,
uint8_t key_idx);
/**
* wlan_crypto_default_key - called by ucfg to set default tx key
*
* @vdev: vdev
* @mac_address: mac address of the peer for unicast key
* or broadcast address if group key need to made default.
* @key_idx: key index to be made as default key
* @unicast: is key was unicast or group key.
* This function gets called from ucfg to set default key
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_default_key(struct wlan_objmgr_vdev *vdev,
uint8_t *macaddr,
uint8_t key_idx,
bool unicast);
/**
* wlan_crypto_encap - called by mgmt for encap the frame based on cipher
*
* @vdev: vdev
* @wbuf: wbuf
* @macaddr: macaddr
* @encapdone: is encapdone already or not.
* This function gets called from mgmt txrx to encap frame.
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_encap(struct wlan_objmgr_vdev *vdev,
qdf_nbuf_t wbuf,
uint8_t *macaddr,
uint8_t encapdone);
/**
* wlan_crypto_decap - called by mgmt for decap the frame based on cipher
*
* @vdev: vdev
* @wbuf: wbuf
* @macaddr: macaddr
* @tid: tid of the packet.
* This function gets called from mgmt txrx to decap frame.
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_decap(struct wlan_objmgr_vdev *vdev,
qdf_nbuf_t wbuf,
uint8_t *macaddr,
uint8_t tid);
/**
* wlan_crypto_enmic - called by mgmt for adding mic in frame based on cipher
*
* @vdev: vdev
* @wbuf: wbuf
* @macaddr: macaddr
* @encapdone: is encapdone already or not.
* This function gets called from mgmt txrx to adding mic to the frame.
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_enmic(struct wlan_objmgr_vdev *vdev,
qdf_nbuf_t wbuf,
uint8_t *macaddr,
uint8_t encapdone);
/**
* wlan_crypto_demic - called by mgmt for remove and check mic for
* the frame based on cipher
*
* @vdev: vdev
* @wbuf: wbuf
* @macaddr: macaddr
* @tid: tid of the frame
* This function gets called from mgmt txrx to decap frame.
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_demic(struct wlan_objmgr_vdev *vdev,
qdf_nbuf_t wbuf,
uint8_t *macaddr,
uint8_t tid);
/**
* wlan_crypto_is_pmf_enabled - called by mgmt txrx to check is pmf enabled
*
* @vdev: vdev
* @peer: peer
*
* This function gets called by mgmt txrx to check is pmf enabled or not.
*
* Return: true or false
*/
bool wlan_crypto_is_pmf_enabled(struct wlan_objmgr_vdev *vdev,
struct wlan_objmgr_peer *peer);
/**
* wlan_crypto_add_mmie - called by mgmt txrx to add mmie in frame
*
* @vdev: vdev
* @frm: frame starting pointer
* @len: length of the frame
*
* This function gets called by mgmt txrx to add mmie in frame
*
* Return: end of frame or NULL in case failure
*/
uint8_t *wlan_crypto_add_mmie(struct wlan_objmgr_vdev *vdev,
uint8_t *frm,
uint32_t len);
/**
* wlan_crypto_is_mmie_valid - called by mgmt txrx to check mmie of the frame
*
* @vdev: vdev
* @frm: frame starting pointer
* @efrm: end of frame pointer
*
* This function gets called by mgmt txrx to check mmie of the frame
*
* Return: true or false
*/
bool wlan_crypto_is_mmie_valid(struct wlan_objmgr_vdev *vdev,
uint8_t *frm,
uint8_t *efrm);
/**
* wlan_crypto_wpaie_check - called by mlme to check the wpaie
*
*
* @crypto params: crypto params
* @iebuf: ie buffer
*
* This function gets called by mlme to check the contents of wpa is
* matching with given crypto params
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_wpaie_check(struct wlan_crypto_params *, uint8_t *frm);
/**
* wlan_crypto_rsnie_check - called by mlme to check the rsnie
*
* @crypto params: crypto params
* @iebuf: ie buffer
*
* This function gets called by mlme to check the contents of rsn is
* matching with given crypto params
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_rsnie_check(struct wlan_crypto_params *, uint8_t *frm);
/**
* wlan_crypto_build_wpaie - called by mlme to build wpaie
*
* @crypto params: crypto params
* @iebuf: ie buffer
*
* This function gets called by mlme to build wpaie from given crypto params
*
* Return: end of buffer
*/
uint8_t *wlan_crypto_build_wpaie(struct wlan_crypto_params *,
uint8_t *iebuf);
/**
* wlan_crypto_build_rsnie - called by mlme to build rsnie
*
* @crypto params: crypto params
* @iebuf: ie buffer
*
* This function gets called by mlme to build rsnie from given crypto params
*
* Return: end of buffer
*/
uint8_t *wlan_crypto_build_rsnie(struct wlan_crypto_params *,
uint8_t *iebuf);
/**
* wlan_crypto_rsn_info - check is given params matching with vdev params.
*
* @vdev: vdev
* @crypto params: crypto params
*
* This function gets called by mlme to check is given params matching with
* vdev params.
*
* Return: true success or false for failure.
*/
bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_params *crypto_params);
/**
* wlan_crypto_pn_check - called by data patch for PN check
*
* @vdev: vdev
* @wbuf: wbuf
*
* This function gets called by data patch for PN check
*
* Return: QDF_STATUS
*/
QDF_STATUS wlan_crypto_pn_check(struct wlan_objmgr_vdev *vdev,
qdf_nbuf_t wbuf);
/**
* wlan_crypto_vdev_get_crypto_params - called by mlme to get crypto params
*
* @vdev:vdev
*
* This function gets called by mlme to get crypto params
*
* Return: wlan_crypto_params or NULL in case of failure
*/
struct wlan_crypto_params *wlan_crypto_vdev_get_crypto_params(
struct wlan_objmgr_vdev *vdev);
/**
* wlan_crypto_peer_get_crypto_params - called by mlme to get crypto params
*
* @peer:peer
*
* This function gets called by mlme to get crypto params
*
* Return: wlan_crypto_params or NULL in case of failure
*/
struct wlan_crypto_params *wlan_crypto_peer_get_crypto_params(
struct wlan_objmgr_peer *peer);
/**
* wlan_crypto_set_peer_wep_keys - set wep keys into peer entries
*
* @peer:peer
*
* This function gets called by mlme, when auth frame is received.
* this helps in setting wep keys into peer data structure.
*
* Return: QDF_STATUS
*/
QDF_STATUS wlan_crypto_set_peer_wep_keys(struct wlan_objmgr_vdev *vdev,
uint8_t *mac_addr);
/**
* wlan_crypto_register_crypto_rx_ops - set crypto_rx_ops
*
* @crypto_rx_ops: crypto_rx_ops
*
* This function gets called by object manger to register crypto rx ops.
*
* Return: QDF_STATUS
*/
QDF_STATUS wlan_crypto_register_crypto_rx_ops(
struct wlan_lmac_if_crypto_rx_ops *crypto_rx_ops);
#endif /* end of _WLAN_CRYPTO_GLOBAL_API_H_ */

View file

@ -0,0 +1,296 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Public definations for crypto service
*/
#ifndef _WLAN_CRYPTO_GLOBAL_DEF_H_
#define _WLAN_CRYPTO_GLOBAL_DEF_H_
#define WLAN_CRYPTO_TID_SIZE (17)
#define WLAN_CRYPTO_KEYBUF_SIZE (32)
#define WLAN_CRYPTO_MICBUF_SIZE (16)
#define WLAN_CRYPTO_MIC_LEN (8)
#define WLAN_CRYPTO_MIC256_LEN (16)
#define WLAN_CRYPTO_TXMIC_OFFSET (0)
#define WLAN_CRYPTO_RXMIC_OFFSET (WLAN_CRYPTO_TXMIC_OFFSET + \
WLAN_CRYPTO_MIC_LEN)
#define WLAN_CRYPTO_WAPI_IV_SIZE (16)
#define WLAN_CRYPTO_CRC_LEN (4)
#define WLAN_CRYPTO_IV_LEN (3)
#define WLAN_CRYPTO_KEYID_LEN (1)
#define WLAN_CRYPTO_EXT_IV_LEN (4)
#define WLAN_CRYPTO_EXT_IV_BIT (0x20)
#define WLAN_CRYPTO_KEYIX_NONE ((uint16_t)-1)
#define WLAN_CRYPTO_MAXKEYIDX (4)
/* 40 bit wep key len */
#define WLAN_CRYPTO_KEY_WEP40_LEN (5)
/* 104 bit wep key len */
#define WLAN_CRYPTO_KEY_WEP104_LEN (13)
/* 128 bit wep key len */
#define WLAN_CRYPTO_KEY_WEP128_LEN (16)
#define WLAN_CRYPTO_WPI_SMS4_IVLEN (16)
#define WLAN_CRYPTO_WPI_SMS4_KIDLEN (1)
#define WLAN_CRYPTO_WPI_SMS4_PADLEN (1)
#define WLAN_CRYPTO_WPI_SMS4_MICLEN (16)
/* key used for xmit */
#define WLAN_CRYPTO_KEY_XMIT (0x01)
/* key used for recv */
#define WLAN_CRYPTO_KEY_RECV (0x02)
/* key used for WPA group operation */
#define WLAN_CRYPTO_KEY_GROUP (0x04)
/* key also used for management frames */
#define WLAN_CRYPTO_KEY_MFP (0x08)
/* host-based encryption */
#define WLAN_CRYPTO_KEY_SWENCRYPT (0x10)
/* host-based enmic */
#define WLAN_CRYPTO_KEY_SWENMIC (0x20)
/* do not remove unless OS commands us to do so */
#define WLAN_CRYPTO_KEY_PERSISTENT (0x40)
/* per STA default key */
#define WLAN_CRYPTO_KEY_DEFAULT (0x80)
/* host-based decryption */
#define WLAN_CRYPTO_KEY_SWDECRYPT (0x100)
/* host-based demic */
#define WLAN_CRYPTO_KEY_SWDEMIC (0x200)
#define WLAN_CRYPTO_KEY_SWCRYPT (WLAN_CRYPTO_KEY_SWENCRYPT \
| WLAN_CRYPTO_KEY_SWDECRYPT)
#define WLAN_CRYPTO_KEY_SWMIC (WLAN_CRYPTO_KEY_SWENMIC \
| WLAN_CRYPTO_KEY_SWDEMIC)
/*
* Cipher types
*/
typedef enum wlan_crypto_cipher_type {
WLAN_CRYPTO_CIPHER_WEP = 0,
WLAN_CRYPTO_CIPHER_TKIP = 1,
WLAN_CRYPTO_CIPHER_AES_OCB = 2,
WLAN_CRYPTO_CIPHER_AES_CCM = 3,
WLAN_CRYPTO_CIPHER_WAPI_SMS4 = 4,
WLAN_CRYPTO_CIPHER_CKIP = 5,
WLAN_CRYPTO_CIPHER_AES_CMAC = 6,
WLAN_CRYPTO_CIPHER_AES_CCM_256 = 7,
WLAN_CRYPTO_CIPHER_AES_CMAC_256 = 8,
WLAN_CRYPTO_CIPHER_AES_GCM = 9,
WLAN_CRYPTO_CIPHER_AES_GCM_256 = 10,
WLAN_CRYPTO_CIPHER_AES_GMAC = 11,
WLAN_CRYPTO_CIPHER_AES_GMAC_256 = 12,
WLAN_CRYPTO_CIPHER_WAPI_GCM4 = 13,
WLAN_CRYPTO_CIPHER_NONE = 14,
WLAN_CRYPTO_CIPHER_MAX = WLAN_CRYPTO_CIPHER_NONE,
} wlan_crypto_cipher_type;
/* Auth types */
typedef enum wlan_crypto_auth_mode {
WLAN_CRYPTO_AUTH_NONE = 0,
WLAN_CRYPTO_AUTH_OPEN = 1,
WLAN_CRYPTO_AUTH_SHARED = 2,
WLAN_CRYPTO_AUTH_8021X = 3,
WLAN_CRYPTO_AUTH_AUTO = 4,
WLAN_CRYPTO_AUTH_WPA = 5,
WLAN_CRYPTO_AUTH_RSNA = 6,
WLAN_CRYPTO_AUTH_CCKM = 7,
WLAN_CRYPTO_AUTH_WAPI = 8,
} wlan_crypto_auth_mode;
/* crypto capabilities */
typedef enum wlan_crypto_cap {
WLAN_CRYPTO_CAP_PRIVACY = 0,
WLAN_CRYPTO_CAP_WPA1 = 1,
WLAN_CRYPTO_CAP_WPA2 = 2,
WLAN_CRYPTO_CAP_WPA = 3,
WLAN_CRYPTO_CAP_AES = 4,
WLAN_CRYPTO_CAP_WEP = 5,
WLAN_CRYPTO_CAP_CKIP = 6,
WLAN_CRYPTO_CAP_TKIP_MIC = 7,
WLAN_CRYPTO_CAP_CCM256 = 8,
WLAN_CRYPTO_CAP_GCM = 9,
WLAN_CRYPTO_CAP_GCM_256 = 10,
WLAN_CRYPTO_CAP_WAPI_SMS4 = 11,
WLAN_CRYPTO_CAP_WAPI_GCM4 = 12,
WLAN_CRYPTO_CAP_KEY_MGMT_OFFLOAD = 13,
WLAN_CRYPTO_CAP_PMF = 14,
WLAN_CRYPTO_CAP_PMF_OFFLOAD = 15,
WLAN_CRYPTO_CAP_PN_TID_BASED = 16,
} wlan_crypto_cap;
typedef enum wlan_crypto_rsn_cap {
WLAN_CRYPTO_RSN_CAP_PREAUTH = 0x01,
WLAN_CRYPTO_RSN_CAP_MFP_ENABLED = 0x80,
WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED = 0x40,
} wlan_crypto_rsn_cap;
typedef enum wlan_crypto_key_mgmt {
WLAN_CRYPTO_KEY_MGMT_IEEE8021X = 0,
WLAN_CRYPTO_KEY_MGMT_PSK = 1,
WLAN_CRYPTO_KEY_MGMT_NONE = 2,
WLAN_CRYPTO_KEY_MGMT_IEEE8021X_NO_WPA = 3,
WLAN_CRYPTO_KEY_MGMT_WPA_NONE = 4,
WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X = 5,
WLAN_CRYPTO_KEY_MGMT_FT_PSK = 6,
WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256 = 7,
WLAN_CRYPTO_KEY_MGMT_PSK_SHA256 = 8,
WLAN_CRYPTO_KEY_MGMT_WPS = 9,
WLAN_CRYPTO_KEY_MGMT_SAE = 10,
WLAN_CRYPTO_KEY_MGMT_FT_SAE = 11,
WLAN_CRYPTO_KEY_MGMT_WAPI_PSK = 12,
WLAN_CRYPTO_KEY_MGMT_WAPI_CERT = 13,
WLAN_CRYPTO_KEY_MGMT_CCKM = 14,
WLAN_CRYPTO_KEY_MGMT_OSEN = 15,
WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B = 16,
WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192 = 17,
} wlan_crypto_key_mgmt;
/* crypto parames for vdev and peers */
struct wlan_crypto_params {
/* authentication mode set*/
uint32_t authmodeset;
/* unicast cipher set*/
uint32_t ucastcipherset;
/* mcast/group cipher set*/
uint32_t mcastcipherset;
/* management frames cipher set */
uint32_t mgmtcipherset;
/* cipher capabilities */
uint32_t cipher_caps;
/* rsn caps*/
uint16_t rsn_caps;
/* key mgmt used*/
uint16_t key_mgmt;
};
typedef enum wlan_crypto_param_type {
WLAN_CRYPTO_PARAM_AUTH_MODE,
WLAN_CRYPTO_PARAM_UCAST_CIPHER,
WLAN_CRYPTO_PARAM_MCAST_CIPHER,
WLAN_CRYPTO_PARAM_MGMT_CIPHER,
WLAN_CRYPTO_PARAM_CIPHER_CAP,
WLAN_CRYPTO_PARAM_RSN_CAP,
WLAN_CRYPTO_PARAM_KEY_MGMT,
} wlan_crypto_param_type;
/* key structure */
struct wlan_crypto_key {
uint8_t keylen;
/* key valid to indicate key is valid or not */;
bool valid;
/* key flags */;
uint16_t flags;
uint16_t keyix;
/* cipher ops table*/
void *cipher_table;
/* cipher context*/
void *private;
qdf_spinlock_t keylock;
/* WAPI key receive sequence counter */
uint8_t recviv[WLAN_CRYPTO_WAPI_IV_SIZE];
/* WAPI key transmit sequence counter */
uint8_t txiv[WLAN_CRYPTO_WAPI_IV_SIZE];
/* key transmit sequence counter */
uint64_t keytsc;
/* key receive sequence counter */
uint64_t keyrsc[WLAN_CRYPTO_TID_SIZE];
/* key receive sequence counter under suspect when pN jump is detected*/
uint64_t keyrsc_suspect[WLAN_CRYPTO_TID_SIZE];
/* key receive sequence counter */
uint64_t keyglobal;
/* key value */
uint8_t keyval[WLAN_CRYPTO_KEYBUF_SIZE
+ WLAN_CRYPTO_MICBUF_SIZE];
#define txmic (keyval + WLAN_CRYPTO_KEYBUF_SIZE \
+ WLAN_CRYPTO_TXMIC_OFFSET)
#define rxmic (keyval + WLAN_CRYPTO_KEYBUF_SIZE \
+ WLAN_CRYPTO_RXMIC_OFFSET)
};
struct wlan_crypto_req_key {
/* key/cipher type */
uint8_t type;
uint8_t pad;
/* key index */
uint16_t keyix
/* key length in bytes */;
uint8_t keylen;
/* key flags */;
uint8_t flags;
uint8_t macaddr[WLAN_MACADDR_LEN];
/* key receive sequence counter */
uint64_t keyrsc;
/* key transmit sequence counter */
uint64_t keytsc;
/* key value */
uint8_t keydata[WLAN_CRYPTO_KEYBUF_SIZE + WLAN_CRYPTO_MICBUF_SIZE];
};
/**
* struct wlan_lmac_if_crypto_tx_ops - structure of crypto function
* pointers
* @allockey: function pointer to alloc key in hw
* @setkey: function pointer to setkey in hw
* @delkey: function pointer to delkey in hw
* @defaultkey: function pointer to set default key
*/
struct wlan_lmac_if_crypto_tx_ops {
QDF_STATUS(*allockey)(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *key,
uint8_t *macaddr, uint32_t key_type);
QDF_STATUS(*setkey)(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *key,
uint8_t *macaddr, uint32_t key_type);
QDF_STATUS(*delkey)(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *key,
uint8_t *macaddr, uint32_t key_type);
QDF_STATUS(*defaultkey)(struct wlan_objmgr_vdev *vdev,
uint8_t keyix, uint8_t *macaddr);
};
/**
* struct wlan_lmac_if_crypto_rx_ops - structure of crypto rx function
* pointers
* @encap: function pointer to encap tx frame
* @decap: function pointer to decap rx frame in hw
* @enmic: function pointer to enmic tx frame
* @demic: function pointer to demic rx frame
*/
struct wlan_lmac_if_crypto_rx_ops {
QDF_STATUS(*crypto_encap)(struct wlan_objmgr_vdev *vdev,
qdf_nbuf_t wbuf, uint8_t *macaddr,
uint8_t encapdone);
QDF_STATUS(*crypto_decap)(struct wlan_objmgr_vdev *vdev,
qdf_nbuf_t wbuf, uint8_t *macaddr,
uint8_t tid);
QDF_STATUS(*crypto_enmic)(struct wlan_objmgr_vdev *vdev,
qdf_nbuf_t wbuf, uint8_t *macaddr,
uint8_t encapdone);
QDF_STATUS(*crypto_demic)(struct wlan_objmgr_vdev *vdev,
qdf_nbuf_t wbuf, uint8_t *macaddr,
uint8_t tid);
QDF_STATUS(*set_peer_wep_keys)(struct wlan_objmgr_vdev *vdev,
uint8_t *mac_addr);
};
#endif /* end of _WLAN_CRYPTO_GLOBAL_DEF_H_ */

View file

@ -0,0 +1,331 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Private API for handling CCMP related operations
*/
#include <qdf_types.h>
#include <wlan_cmn.h>
#include <wlan_objmgr_cmn.h>
#include <wlan_objmgr_global_obj.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_objmgr_peer_obj.h>
#include "wlan_crypto_global_def.h"
#include "wlan_crypto_def_i.h"
#include "wlan_crypto_main_i.h"
#include "wlan_crypto_obj_mgr_i.h"
#include "wlan_crypto_ccmp_i.h"
#define MAX_CCMP_PN_GAP_ERR_CHECK 0
static QDF_STATUS ccmp_setkey(struct wlan_crypto_key *key)
{
struct wlan_crypto_ccmp_ctx *ctx;
if (key->private == NULL) {
key->private = qdf_mem_malloc(
sizeof(struct wlan_crypto_ccmp_ctx));
if (key->private == NULL)
return QDF_STATUS_E_NOMEM;
}
ctx = key->private;
wlan_crypto_rijndael_set_key(&ctx->cc_aes, key->keyval,
(key->keylen*NBBY));
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS ccmp_encap(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t encapdone,
uint8_t hdrlen){
uint8_t *ivp;
struct ieee80211_frame *wh;
struct wlan_crypto_cipher *cipher_table;
cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
wh = (struct ieee80211_frame *)qdf_nbuf_data(wbuf);
/*
* Copy down 802.11 header and add the IV, KeyID, and ExtIV.
*/
if (encapdone) {
ivp = (uint8_t *)qdf_nbuf_data(wbuf);
} else {
ivp = (uint8_t *)qdf_nbuf_push_head(wbuf,
cipher_table->header);
qdf_mem_move(ivp, ivp + cipher_table->header, hdrlen);
/* recompute wh */
wh = (struct ieee80211_frame *) qdf_nbuf_data(wbuf);
}
ivp += hdrlen;
/* XXX wrap at 48 bits */
key->keytsc++;
ivp[0] = key->keytsc >> 0; /* PN0 */
ivp[1] = key->keytsc >> 8; /* PN1 */
ivp[2] = 0; /* Reserved */
ivp[3] = key->keyix | WLAN_CRYPTO_EXT_IV_BIT; /* KeyID | ExtID */
ivp[4] = key->keytsc >> 16; /* PN2 */
ivp[5] = key->keytsc >> 24; /* PN3 */
ivp[6] = key->keytsc >> 32; /* PN4 */
ivp[7] = key->keytsc >> 40; /* PN5 */
/*
* Finally, do software encrypt if neeed.
*/
if (key->flags & WLAN_CRYPTO_KEY_SWENCRYPT) {
if (!wlan_crypto_ccmp_encrypt(key, wbuf, hdrlen,
IEEE80211_IS_MFP_FRAME(wh))) {
return 0;
}
}
return QDF_STATUS_SUCCESS;
}
#define WLAN_CRYPTO_CCMP_PN_MAX(pn) (pn + MAX_CCMP_PN_GAP_ERR_CHECK)
static QDF_STATUS ccmp_decap(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t tid,
uint8_t hdrlen){
struct ieee80211_frame *wh;
uint8_t *ivp, *origHdr;
uint64_t pn;
uint8_t update_keyrsc = 1;
struct wlan_crypto_cipher *cipher_table;
cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
/*
* Header should have extended IV and sequence number;
* verify the former and validate the latter.
*/
origHdr = (uint8_t *)qdf_nbuf_data(wbuf);
wh = (struct ieee80211_frame *)origHdr;
ivp = origHdr + hdrlen;
if ((ivp[WLAN_CRYPTO_IV_LEN] & WLAN_CRYPTO_EXT_IV_BIT) == 0) {
/*invalid CCMP iv*/
return QDF_STATUS_E_INVAL;
}
tid = IEEE80211_NON_QOS_SEQ;
if (IEEE80211_QOS_HAS_SEQ(wh)) {
if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK)
== IEEE80211_FC1_DIR_DSTODS) {
tid = ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0]
& IEEE80211_QOS_TID;
} else {
tid = ((struct ieee80211_qosframe *)wh)->i_qos[0]
& IEEE80211_QOS_TID;
}
}
/* NB: assume IEEEE80211_WEP_MINLEN covers the extended IV */
pn = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]);
if (pn <= key->keyrsc[tid]) {
/*
* Replay violation.
*/
return QDF_STATUS_CRYPTO_PN_ERROR;
}
if ((key->flags & WLAN_CRYPTO_KEY_SWDECRYPT)) {
if (!wlan_crypto_ccmp_decrypt(key,
pn, wbuf, hdrlen, IEEE80211_IS_MFP_FRAME(wh))) {
return QDF_STATUS_CRYPTO_DECRYPT_FAILED;
}
}
/* we can get corrupted frame that has a bad PN.
* The PN upper bits tend to get corrupted.
* The PN should be a monotically increasing counter.
* if we detected a big jump, then we will throw away this frame.
*/
if ((key->keyrsc[tid] > 1) &&
(pn > (WLAN_CRYPTO_CCMP_PN_MAX(key->keyrsc[tid])))) {
/* PN jump wrt keyrsc is > MAX_CCMP_PN_GAP_ERR_CHECK -
* PN of current frame is suspected
*/
if (key->keyrsc_suspect[tid]) {
/* Check whether PN of the current frame
* is following prev PN seq or not
*/
if (pn < key->keyrsc_suspect[tid]) {
/* PN number of the curr frame < PN no of prev
* rxed frame. As we are not sure about prev
* suspect PN, to detect replay, check the
* current PN with global PN
*/
if (pn < key->keyglobal)
/* Replay violation */
return QDF_STATUS_CRYPTO_PN_ERROR;
else {
/* Current PN is following global PN,
* so mark this as suspected PN
* Don't update keyrsc & keyglobal
*/
key->keyrsc_suspect[tid] = pn;
update_keyrsc = 0;
}
} else if (pn <
(WLAN_CRYPTO_CCMP_PN_MAX(key->keyrsc_suspect[tid]))) {
/* Current PN is following prev suspected
* PN seq Update keyrsc & keyglobal
* (update_keyrsc = 1;)
*/
} else {
/* Current PN is neither following prev
* suspected PN nor prev Keyrsc.
* Mark this as new suspect and
* don't update keyrsc & keyglobal
*/
key->keyrsc_suspect[tid] = pn;
update_keyrsc = 0;
}
} else {
/* New Jump in PN observed
* So mark this PN as suspected and
* don't update keyrsc/keyglobal */
key->keyrsc_suspect[tid] = pn;
update_keyrsc = 0;
}
} else {
/* Valid PN, update keyrsc & keyglobal (update_keyrsc = 1;) */
}
/*
* Copy up 802.11 header and strip crypto bits.
*/
qdf_mem_move(origHdr + cipher_table->header, origHdr, hdrlen);
qdf_nbuf_pull_head(wbuf, cipher_table->header);
qdf_nbuf_trim_tail(wbuf, cipher_table->trailer);
if (update_keyrsc) {
/*
* Ok to update rsc now.
*/
key->keyrsc[tid] = pn;
key->keyglobal = pn;
key->keyrsc_suspect[tid] = 0;
}
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS ccmp_enmic(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t keyid,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS ccmp_demic(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t keyid,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
const struct wlan_crypto_cipher ccmp_cipher_table = {
"AES-CCM",
WLAN_CRYPTO_CIPHER_AES_CCM,
WLAN_CRYPTO_IV_LEN + WLAN_CRYPTO_KEYID_LEN + WLAN_CRYPTO_EXT_IV_LEN,
WLAN_CRYPTO_MIC_LEN,
0,
128,
ccmp_setkey,
ccmp_encap,
ccmp_decap,
ccmp_enmic,
ccmp_demic,
};
const struct wlan_crypto_cipher ccmp256_cipher_table = {
"AES-CCM256",
WLAN_CRYPTO_CIPHER_AES_CCM_256,
WLAN_CRYPTO_IV_LEN + WLAN_CRYPTO_KEYID_LEN + WLAN_CRYPTO_EXT_IV_LEN,
WLAN_CRYPTO_MIC256_LEN,
0,
256,
ccmp_setkey,
ccmp_encap,
ccmp_decap,
ccmp_enmic,
ccmp_demic,
};
const struct wlan_crypto_cipher gcmp_cipher_table = {
"AES-GCM",
WLAN_CRYPTO_CIPHER_AES_GCM,
WLAN_CRYPTO_IV_LEN + WLAN_CRYPTO_KEYID_LEN + WLAN_CRYPTO_EXT_IV_LEN,
WLAN_CRYPTO_MIC_LEN,
0,
128,
ccmp_setkey,
ccmp_encap,
ccmp_decap,
ccmp_enmic,
ccmp_demic,
};
const struct wlan_crypto_cipher gcmp256_cipher_table = {
"AES-GCM256",
WLAN_CRYPTO_CIPHER_AES_GCM_256,
WLAN_CRYPTO_IV_LEN + WLAN_CRYPTO_KEYID_LEN + WLAN_CRYPTO_EXT_IV_LEN,
WLAN_CRYPTO_MIC256_LEN,
0,
256,
ccmp_setkey,
ccmp_encap,
ccmp_decap,
ccmp_enmic,
ccmp_demic,
};
const struct wlan_crypto_cipher *ccmp_register(void){
return &ccmp_cipher_table;
}
const struct wlan_crypto_cipher *ccmp256_register(void){
return &ccmp256_cipher_table;
}
const struct wlan_crypto_cipher *gcmp_register(void){
return &gcmp_cipher_table;
}
const struct wlan_crypto_cipher *gcmp256_register(void){
return &gcmp256_cipher_table;
}

View file

@ -0,0 +1,300 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Private definations for handling crypto params
*/
#ifndef _WLAN_CRYPTO_DEF_I_H_
#define _WLAN_CRYPTO_DEF_I_H_
#define WLAN_CRYPTO_TX_OPS_ALLOCKEY(psoc) \
(psoc->soc_cb.tx_ops.crypto_tx_ops.allockey)
#define WLAN_CRYPTO_TX_OPS_SETKEY(psoc) \
(psoc->soc_cb.tx_ops.crypto_tx_ops.setkey)
#define WLAN_CRYPTO_TX_OPS_DELKEY(psoc) \
(psoc->soc_cb.tx_ops.crypto_tx_ops.delkey)
#define WLAN_CRYPTO_TX_OPS_DEFAULTKEY(psoc) \
(psoc->soc_cb.tx_ops.crypto_tx_ops.defaultkey)
/* unalligned little endian access */
#ifndef LE_READ_2
#define LE_READ_2(p) \
((uint16_t) \
((((const uint8_t *)(p))[0]) | \
(((const uint8_t *)(p))[1] << 8)))
#endif
#ifndef LE_READ_4
#define LE_READ_4(p) \
((uint32_t) \
((((const uint8_t *)(p))[0]) | \
(((const uint8_t *)(p))[1] << 8) | \
(((const uint8_t *)(p))[2] << 16) | \
(((const uint8_t *)(p))[3] << 24)))
#endif
#ifndef BE_READ_4
#define BE_READ_4(p) \
((uint32_t) \
((((const uint8_t *)(p))[0] << 24) | \
(((const uint8_t *)(p))[1] << 16) | \
(((const uint8_t *)(p))[2] << 8) | \
(((const uint8_t *)(p))[3])))
#endif
#ifndef READ_6
#define READ_6(b0, b1, b2, b3, b4, b5) ({ \
uint32_t iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24);\
uint16_t iv16 = (b4 << 0) | (b5 << 8);\
(((uint64_t)iv16) << 32) | iv32;\
})
#endif
#define OUI_SIZE (4)
#define WLAN_CRYPTO_ADDSHORT(frm, v) \
do {frm[0] = (v) & 0xff; frm[1] = (v) >> 8; frm += 2; } while (0)
#define WLAN_CRYPTO_ADDSELECTOR(frm, sel) \
do {qdf_mem_copy(frm, (uint8_t *)sel, OUI_SIZE); \
frm += OUI_SIZE; } while (0)
#define WLAN_CRYPTO_SELECTOR(a, b, c, d) \
((((uint32_t) (a)) << 24) | \
(((uint32_t) (b)) << 16) | \
(((uint32_t) (c)) << 8) | \
(uint32_t) (d))
#define WPA_TYPE_OUI WLAN_CRYPTO_SELECTOR(0x00, 0x50, 0xf2, 1)
#define WPA_AUTH_KEY_MGMT_NONE \
WLAN_CRYPTO_SELECTOR(0x00, 0x50, 0xf2, 0)
#define WPA_AUTH_KEY_MGMT_UNSPEC_802_1X \
WLAN_CRYPTO_SELECTOR(0x00, 0x50, 0xf2, 1)
#define WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X \
WLAN_CRYPTO_SELECTOR(0x00, 0x50, 0xf2, 2)
#define WPA_AUTH_KEY_MGMT_CCKM \
WLAN_CRYPTO_SELECTOR(0x00, 0x40, 0x96, 0)
#define WPA_CIPHER_SUITE_NONE WLAN_CRYPTO_SELECTOR(0x00, 0x50, 0xf2, 0)
#define WPA_CIPHER_SUITE_WEP40 WLAN_CRYPTO_SELECTOR(0x00, 0x50, 0xf2, 1)
#define WPA_CIPHER_SUITE_WEP104 WLAN_CRYPTO_SELECTOR(0x00, 0x50, 0xf2, 5)
#define WPA_CIPHER_SUITE_TKIP WLAN_CRYPTO_SELECTOR(0x00, 0x50, 0xf2, 2)
#define WPA_CIPHER_SUITE_CCMP WLAN_CRYPTO_SELECTOR(0x00, 0x50, 0xf2, 4)
#define RSN_AUTH_KEY_MGMT_NONE WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 0)
#define RSN_AUTH_KEY_MGMT_UNSPEC_802_1X \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 1)
#define RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 2)
#define RSN_AUTH_KEY_MGMT_FT_802_1X \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 3)
#define RSN_AUTH_KEY_MGMT_FT_PSK \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 4)
#define RSN_AUTH_KEY_MGMT_802_1X_SHA256 \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 5)
#define RSN_AUTH_KEY_MGMT_PSK_SHA256 \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 6)
#define RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 7)
#define RSN_AUTH_KEY_MGMT_SAE WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 8)
#define RSN_AUTH_KEY_MGMT_FT_SAE WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 9)
#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 11)
#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192 \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 12)
#define RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_192 \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 13)
#define RSN_AUTH_KEY_MGMT_CCKM WLAN_CRYPTO_SELECTOR(0x00, 0x40, 0x96, 0x00)
#define RSN_AUTH_KEY_MGMT_OSEN WLAN_CRYPTO_SELECTOR(0x50, 0x6f, 0x9a, 0x01)
#define RSN_CIPHER_SUITE_NONE WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 0)
#define RSN_CIPHER_SUITE_WEP40 WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 1)
#define RSN_CIPHER_SUITE_TKIP WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 2)
#define RSN_CIPHER_SUITE_WEP104 WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 5)
#define RSN_CIPHER_SUITE_CCMP WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 4)
#define RSN_CIPHER_SUITE_AES_CMAC WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 6)
#define RSN_CIPHER_SUITE_GCMP WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 8)
#define RSN_CIPHER_SUITE_GCMP_256 WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 9)
#define RSN_CIPHER_SUITE_CCMP_256 WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 10)
#define RSN_CIPHER_SUITE_BIP_GMAC_128 \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 11)
#define RSN_CIPHER_SUITE_BIP_GMAC_256 \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 12)
#define RSN_CIPHER_SUITE_BIP_CMAC_256 \
WLAN_CRYPTO_SELECTOR(0x00, 0x0f, 0xac, 13)
#define RESET_PARAM(__param) ((__param) = 0)
#define SET_PARAM(__param, __val) ((__param) |= (1<<(__val)))
#define HAS_PARAM(__param, __val) ((__param) & (1<<(__val)))
#define CLEAR_PARAM(__param, __val) ((__param) &= ((~1) << (__val)))
#define RESET_AUTHMODE(_param) ((_param)->authmodeset = 0)
#define SET_AUTHMODE(_param, _mode) ((_param)->authmodeset |= (1<<(_mode)))
#define HAS_AUTHMODE(_param, _mode) ((_param)->authmodeset & (1<<(_mode)))
#define AUTH_IS_OPEN(_param) HAS_AUTHMODE((_param), WLAN_CRYPTO_AUTH_OPEN)
#define AUTH_IS_SHARED_KEY(_param) \
HAS_AUTHMODE((_param), WLAN_CRYPTO_AUTH_SHARED)
#define AUTH_IS_8021X(_param) HAS_AUTHMODE((_param), WLAN_CRYPTO_AUTH_8021X)
#define AUTH_IS_WPA(_param) HAS_AUTHMODE((_param), WLAN_CRYPTO_AUTH_WPA)
#define AUTH_IS_RSNA(_param) HAS_AUTHMODE((_param), WLAN_CRYPTO_AUTH_RSNA)
#define AUTH_IS_CCKM(_param) HAS_AUTHMODE((_param), WLAN_CRYPTO_AUTH_CCKM)
#define AUTH_IS_WAI(_param) HAS_AUTHMODE((_param), WLAN_CRYPTO_AUTH_WAPI)
#define AUTH_IS_WPA2(_param) AUTH_IS_RSNA(_param)
#define AUTH_MATCH(_param1, _param2) \
(((_param1)->authmodeset & (_param2)->authmodeset) != 0)
#define RESET_UCAST_CIPHERS(_param) ((_param)->ucastcipherset = 0)
#define SET_UCAST_CIPHER(_param, _c) ((_param)->ucastcipherset |= (1<<(_c)))
#define HAS_UCAST_CIPHER(_param, _c) ((_param)->ucastcipherset & (1<<(_c)))
#define UCIPHER_IS_CLEAR(_param) \
HAS_UCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_NONE)
#define UCIPHER_IS_WEP(_param) \
HAS_UCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_WEP)
#define UCIPHER_IS_TKIP(_param) \
HAS_UCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_TKIP)
#define UCIPHER_IS_CCMP128(_param) \
HAS_UCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_CCM)
#define UCIPHER_IS_CCMP256(_param) \
HAS_UCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_CCM_256)
#define UCIPHER_IS_GCMP128(_param) \
HAS_UCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_GCM)
#define UCIPHER_IS_GCMP256(_param) \
HAS_UCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_GCM_256)
#define UCIPHER_IS_SMS4(_param) \
HAS_UCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_WAPI)
#define RESET_MCAST_CIPHERS(_param) ((_param)->mcastcipherset = 0)
#define SET_MCAST_CIPHER(_param, _c) ((_param)->mcastcipherset |= (1<<(_c)))
#define HAS_MCAST_CIPHER(_param, _c) ((_param)->mcastcipherset & (1<<(_c)))
#define HAS_ANY_MCAST_CIPHER(_param) ((_param)->mcastcipherset)
#define CLEAR_MCAST_CIPHER(_param, _c) \
((_param)->mcastcipherset &= (~(1)<<(_c)))
#define MCIPHER_IS_CLEAR(_param) \
HAS_MCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_NONE)
#define MCIPHER_IS_WEP(_param) \
HAS_MCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_WEP)
#define MCIPHER_IS_TKIP(_param) \
HAS_MCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_TKIP)
#define MCIPHER_IS_CCMP128(_param) \
HAS_MCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_CCM)
#define MCIPHER_IS_CCMP256(_param) \
HAS_MCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_CCM_256)
#define MCIPHER_IS_GCMP128(_param) \
HAS_MCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_GCM)
#define MCIPHER_IS_GCMP256(_param) \
HAS_MCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_GCM_256)
#define MCIPHER_IS_SMS4(_param) \
HAS_MCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_WAPI)
#define RESET_MGMT_CIPHERS(_param) ((_param)->mgmtcipherset = 0)
#define SET_MGMT_CIPHER(_param, _c) ((_param)->mgmtcipherset |= (1<<(_c)))
#define HAS_MGMT_CIPHER(_param, _c) ((_param)->mgmtcipherset & (1<<(_c)))
#define IS_MGMT_CIPHER(_c) ((_c == WLAN_CRYPTO_CIPHER_AES_CMAC) || \
(_c == WLAN_CRYPTO_CIPHER_AES_CMAC_256) || \
(_c == WLAN_CRYPTO_CIPHER_AES_GMAC) || \
(_c == WLAN_CRYPTO_CIPHER_AES_GMAC_256))
#define MGMT_CIPHER_IS_CMAC(_param) \
HAS_MGMT_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_CMAC)
#define MGMT_CIPHER_IS_CMAC256(_param) \
HAS_MGMT_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_CMAC_256)
#define MGMT_CIPHER_IS_GMAC(_param) \
HAS_MGMT_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_GMAC)
#define MGMT_CIPHER_IS_GMAC256(_param) \
HAS_MGMT_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_GMAC_256)
#define RESET_KEY_MGMT(_param) ((_param)->key_mgmt = 0)
#define SET_KEY_MGMT(_param, _c) ((_param)->key_mgmt |= (1<<(_c)))
#define HAS_KEY_MGMT(_param, _c) ((_param)->key_mgmt & (1<<(_c)))
#define UCAST_CIPHER_MATCH(_param1, _param2) \
(((_param1)->ucastcipherset & (_param2)->ucastcipherset) != 0)
#define MCAST_CIPHER_MATCH(_param1, _param2) \
(((_param1)->mcastcipherset & (_param2)->mcastcipherset) != 0)
#define MGMT_CIPHER_MATCH(_param1, _param2) \
(((_param1)->mgmtcipherset & (_param2)->mgmtcipherset) != 0)
#define KEY_MGMTSET_MATCH(_param1, _param2) \
(((_param1)->key_mgmt & (_param2)->key_mgmt) != 0 || \
(!(_param1)->key_mgmt && !(_param2)->key_mgmt))
#define RESET_CIPHER_CAP(_param) ((_param)->cipher_caps = 0)
#define SET_CIPHER_CAP(_param, _c) ((_param)->cipher_caps |= (1<<(_c)))
#define HAS_CIPHER_CAP(_param, _c) ((_param)->cipher_caps & (1<<(_c)))
#define HAS_ANY_CIPHER_CAP(_param) ((_param)->cipher_caps)
struct wlan_crypto_comp_priv {
struct wlan_crypto_params crypto_params;
struct wlan_crypto_key *key[4];
struct wlan_crypto_key *igtk_key;
uint8_t def_tx_keyid;
};
struct wlan_crypto_cipher {
/* printable name */
const char *cipher_name;
/* WLAN_CRYPTO_CIPHER_* */
wlan_crypto_cipher_type cipher;
/* size of privacy header (bytes) */
const uint8_t header;
/* size of privacy trailer (bytes) */
const uint8_t trailer;
/* size of mic trailer (bytes) */
const uint8_t miclen;
/* max key length */
const uint32_t keylen;
QDF_STATUS(*setkey)(struct wlan_crypto_key *);
QDF_STATUS(*encap)(struct wlan_crypto_key *,
qdf_nbuf_t, uint8_t, uint8_t);
QDF_STATUS(*decap)(struct wlan_crypto_key *,
qdf_nbuf_t, uint8_t, uint8_t);
QDF_STATUS(*enmic)(struct wlan_crypto_key *,
qdf_nbuf_t, uint8_t, uint8_t);
QDF_STATUS(*demic)(struct wlan_crypto_key *,
qdf_nbuf_t, uint8_t, uint8_t);
};
/*
* Return the size of the 802.11 header for a management or data frame.
*/
static inline int ieee80211_hdrsize(const void *data)
{
const struct ieee80211_frame *wh = (const struct ieee80211_frame *)data;
int16_t size = sizeof(struct ieee80211_frame);
if ((wh->i_fc[1] & 0x03) == 0x03)
size += 6;
if ((((wh)->i_fc[0] & (0x0c | 0x80)) == (0x00 | 0x80))) {
size += sizeof(uint16_t);
/* Qos frame with Order bit set indicates an HTC frame */
if (wh->i_fc[1] & 0x80)
size += (sizeof(uint8_t)*4);
}
return size;
}
#endif /* end of _WLAN_CRYPTO_DEF_I_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Public API intialization of crypto service with object manager
*/
#include <qdf_types.h>
#include "wlan_crypto_main_i.h"
#include "wlan_crypto_main.h"
/**
* wlan_crypto_init - Init the crypto service with object manager
* Called from umac init context.
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_init(void)
{
return __wlan_crypto_init();
}
/**
* wlan_crypto_deinit - Deinit the crypto service with object manager
* Called from umac deinit context.
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_deinit(void)
{
return __wlan_crypto_deinit();
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Private API for crypto service with object manager handler
*/
#ifndef _WLAN_CRYPTO_MAIN_H_
#define _WLAN_CRYPTO_MAIN_H_
/**
* wlan_crypto_init - Init the crypto service with object manager
* Called from umac init context.
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_init(void);
/**
* wlan_crypto_deinit - Deinit the crypto service with object manager
* Called from umac deinit context.
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_deinit(void);
#endif /* end of _WLAN_CRYPTO_MAIN_H_ */

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Private API for crypto service with object manager handler
*/
#ifndef _WLAN_CRYPTO_MAIN_I_H_
#define _WLAN_CRYPTO_MAIN_I_H_
/**
* wlan_crypto_init - Init the crypto service with object manager
* Called from umac init context.
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS __wlan_crypto_init(void);
/**
* wlan_crypto_deinit - Deinit the crypto service with object manager
* Called from umac deinit context.
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS __wlan_crypto_deinit(void);
#endif /* end of _WLAN_CRYPTO_MAIN_I_H_ */

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Public API intialization of crypto service with object manager
*/
#include <qdf_types.h>
#include <wlan_cmn.h>
#include <wlan_objmgr_cmn.h>
#include <wlan_objmgr_global_obj.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_objmgr_peer_obj.h>
#include "wlan_crypto_global_def.h"
#include "wlan_crypto_def_i.h"
#include "wlan_crypto_main_i.h"
#include "wlan_crypto_obj_mgr_i.h"
static QDF_STATUS none_setkey(struct wlan_crypto_key *key)
{
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS none_encap(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t encapdone,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS none_decap(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t tid,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS none_enmic(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t encapdone,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS none_demic(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t tid,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
const struct wlan_crypto_cipher none_cipher_table = {
"NONE",
WLAN_CRYPTO_CIPHER_NONE,
0,
0,
0,
0,
none_setkey,
none_encap,
none_decap,
none_enmic,
none_demic,
};
const struct wlan_crypto_cipher *none_register(void){
return &none_cipher_table;
}

View file

@ -0,0 +1,307 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Public API intialization of crypto service with object manager
*/
#include <qdf_types.h>
#include <wlan_cmn.h>
#include <wlan_objmgr_cmn.h>
#include <wlan_objmgr_global_obj.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_objmgr_peer_obj.h>
#include "wlan_crypto_global_def.h"
#include "wlan_crypto_def_i.h"
#include "wlan_crypto_main_i.h"
#include "wlan_crypto_obj_mgr_i.h"
extern const struct wlan_crypto_cipher *wep_register(void);
extern const struct wlan_crypto_cipher *tkip_register(void);
extern const struct wlan_crypto_cipher *ccmp_register(void);
extern const struct wlan_crypto_cipher *ccmp256_register(void);
extern const struct wlan_crypto_cipher *gcmp_register(void);
extern const struct wlan_crypto_cipher *gcmp256_register(void);
extern const struct wlan_crypto_cipher *wapi_register(void);
extern const struct wlan_crypto_cipher
*wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX];
static QDF_STATUS wlan_crypto_register_all_ciphers(
struct wlan_crypto_params *crypto_param)
{
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WEP] = wep_register();
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_TKIP] = tkip_register();
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM]
= ccmp_register();
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM_256]
= ccmp256_register();
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM]
= gcmp_register();
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM_256]
= gcmp256_register();
if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP)) {
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WEP]
= wep_register();
}
if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC)) {
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_TKIP]
= tkip_register();
}
if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES)) {
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM]
= ccmp_register();
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_CCM_256]
= ccmp256_register();
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM]
= gcmp_register();
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_AES_GCM_256]
= gcmp256_register();
}
if (HAS_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4)) {
wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_WAPI_SMS4]
= wapi_register();
}
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS wlan_crypto_psoc_obj_create_handler(
struct wlan_objmgr_psoc *psoc,
void *arg)
{
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS wlan_crypto_pdev_obj_create_handler(
struct wlan_objmgr_pdev *pdev,
void *arg)
{
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS wlan_crypto_vdev_obj_create_handler(
struct wlan_objmgr_vdev *vdev,
void *arg)
{
struct wlan_crypto_comp_priv *crypto_priv;
struct wlan_objmgr_pdev *pdev;
struct wlan_crypto_params *crypto_param;
if (!vdev)
return QDF_STATUS_E_INVAL;
crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv));
if (!crypto_priv)
return QDF_STATUS_E_NOMEM;
crypto_param = &(crypto_priv->crypto_params);
pdev = wlan_vdev_get_pdev(vdev);
wlan_pdev_obj_lock(pdev);
if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WEP))
SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WEP);
if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_TKIP))
SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_TKIP_MIC);
if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_AES))
SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_AES);
if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_CKIP))
SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_CKIP);
if (wlan_pdev_nif_fw_cap_get(pdev, WLAN_SOC_C_WAPI))
SET_CIPHER_CAP(crypto_param, WLAN_CRYPTO_CAP_WAPI_SMS4);
wlan_pdev_obj_unlock(pdev);
/* update the crypto cipher table based on the fw caps*/
/* 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,
WLAN_UMAC_COMP_CRYPTO,
(void *)crypto_priv,
QDF_STATUS_SUCCESS);
}
static QDF_STATUS wlan_crypto_peer_obj_create_handler(
struct wlan_objmgr_peer *peer,
void *arg)
{
struct wlan_crypto_comp_priv *crypto_priv;
if (!peer)
return QDF_STATUS_E_INVAL;
crypto_priv = qdf_mem_malloc(sizeof(struct wlan_crypto_comp_priv));
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);
}
static QDF_STATUS wlan_crypto_psoc_obj_destroy_handler(
struct wlan_objmgr_psoc *psoc,
void *arg){
return QDF_STATUS_COMP_DISABLED;
}
static QDF_STATUS wlan_crypto_pdev_obj_destroy_handler(
struct wlan_objmgr_pdev *pdev,
void *arg){
return QDF_STATUS_SUCCESS;
}
static void wlan_crypto_free_key(struct wlan_crypto_comp_priv *crypto_priv)
{
uint8_t i;
for (i = 0; i < WLAN_CRYPTO_MAXKEYIDX; i++) {
if (crypto_priv->key[i])
qdf_mem_free(crypto_priv->key[i]);
}
if (crypto_priv->igtk_key)
qdf_mem_free(crypto_priv->igtk_key);
}
static QDF_STATUS wlan_crypto_vdev_obj_destroy_handler(
struct wlan_objmgr_vdev *vdev,
void *arg){
struct wlan_crypto_comp_priv *crypto_priv;
crypto_priv = (struct wlan_crypto_comp_priv *)
wlan_get_vdev_crypto_obj(vdev);
wlan_objmgr_vdev_component_obj_detach(vdev,
WLAN_UMAC_COMP_CRYPTO,
(void *)crypto_priv);
wlan_crypto_free_key(crypto_priv);
qdf_mem_free(crypto_priv);
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS wlan_crypto_peer_obj_destroy_handler(
struct wlan_objmgr_peer *peer,
void *arg){
struct wlan_crypto_comp_priv *crypto_priv;
crypto_priv = (struct wlan_crypto_comp_priv *)
wlan_get_peer_crypto_obj(peer);
wlan_objmgr_peer_component_obj_detach(peer,
WLAN_UMAC_COMP_CRYPTO,
(void *)crypto_priv);
wlan_crypto_free_key(crypto_priv);
qdf_mem_free(crypto_priv);
return QDF_STATUS_SUCCESS;
}
/**
* wlan_crypto_init - Init the crypto service with object manager
* Called from umac init context.
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS __wlan_crypto_init(void)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
status = wlan_objmgr_register_vdev_create_handler(
WLAN_UMAC_COMP_CRYPTO,
wlan_crypto_vdev_obj_create_handler, NULL);
if (status != QDF_STATUS_SUCCESS)
goto err_vdev_create;
status = wlan_objmgr_register_peer_create_handler(
WLAN_UMAC_COMP_CRYPTO,
wlan_crypto_peer_obj_create_handler, NULL);
if (status != QDF_STATUS_SUCCESS)
goto err_peer_create;
status = wlan_objmgr_register_vdev_destroy_handler(
WLAN_UMAC_COMP_CRYPTO,
wlan_crypto_vdev_obj_destroy_handler, NULL);
if (status != QDF_STATUS_SUCCESS)
goto err_vdev_delete;
status = wlan_objmgr_register_peer_destroy_handler(
WLAN_UMAC_COMP_CRYPTO,
wlan_crypto_peer_obj_destroy_handler, NULL);
if (status != QDF_STATUS_SUCCESS)
goto err_peer_delete;
goto register_success;
err_peer_delete:
wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
wlan_crypto_vdev_obj_destroy_handler, NULL);
err_vdev_delete:
wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO,
wlan_crypto_peer_obj_create_handler, NULL);
err_peer_create:
wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
wlan_crypto_vdev_obj_create_handler, NULL);
err_vdev_create:
wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
wlan_crypto_pdev_obj_create_handler, NULL);
register_success:
return status;
}
/**
* wlan_crypto_deinit - Deinit the crypto service with object manager
* Called from umac deinit context.
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS __wlan_crypto_deinit(void)
{
if (wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_CRYPTO,
wlan_crypto_vdev_obj_create_handler, NULL)
!= QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CRYPTO,
wlan_crypto_peer_obj_create_handler, NULL)
!= QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
if (wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
wlan_crypto_vdev_obj_destroy_handler, NULL)
!= QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CRYPTO,
wlan_crypto_peer_obj_destroy_handler, NULL)
!= QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Public API intialization of crypto service with object manager
*/
#ifndef __WLAN_CRYPTO_OBJ_MGR_I_
#define __WLAN_CRYPTO_OBJ_MGR_I_
static inline void *wlan_get_vdev_crypto_obj(struct wlan_objmgr_vdev *vdev)
{
void *crypto_priv;
wlan_vdev_obj_lock(vdev);
crypto_priv = wlan_objmgr_vdev_get_comp_private_obj(vdev,
WLAN_UMAC_COMP_CRYPTO);
wlan_vdev_obj_unlock(vdev);
return crypto_priv;
}
static inline void *wlan_get_peer_crypto_obj(struct wlan_objmgr_peer *peer)
{
void *crypto_priv;
wlan_peer_obj_lock(peer);
crypto_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
WLAN_UMAC_COMP_CRYPTO);
wlan_peer_obj_unlock(peer);
return crypto_priv;
}
#endif /* end of __WLAN_CRYPTO_OBJ_MGR_I_*/

View file

@ -0,0 +1,310 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Public APIs for crypto service
*/
/* include files */
#include <qdf_types.h>
#include <wlan_cmn.h>
#include <wlan_objmgr_cmn.h>
#include <wlan_objmgr_global_obj.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_objmgr_peer_obj.h>
#include "wlan_crypto_global_def.h"
#include "wlan_crypto_global_api.h"
#include "wlan_crypto_def_i.h"
#include "wlan_crypto_param_handling_i.h"
static uint32_t
cipher2cap(int cipher)
{
switch (cipher) {
case WLAN_CRYPTO_CIPHER_WEP: return WLAN_CRYPTO_CAP_WEP;
case WLAN_CRYPTO_CIPHER_AES_OCB: return WLAN_CRYPTO_CAP_AES;
case WLAN_CRYPTO_CIPHER_AES_CCM: return WLAN_CRYPTO_CAP_AES;
case WLAN_CRYPTO_CIPHER_AES_CCM_256: return WLAN_CRYPTO_CAP_AES;
case WLAN_CRYPTO_CIPHER_AES_GCM: return WLAN_CRYPTO_CAP_AES;
case WLAN_CRYPTO_CIPHER_AES_GCM_256: return WLAN_CRYPTO_CAP_AES;
case WLAN_CRYPTO_CIPHER_CKIP: return WLAN_CRYPTO_CAP_CKIP;
case WLAN_CRYPTO_CIPHER_TKIP: return WLAN_CRYPTO_CAP_TKIP_MIC;
case WLAN_CRYPTO_CIPHER_WAPI_SMS4: return WLAN_CRYPTO_CAP_WAPI_SMS4;
case WLAN_CRYPTO_CIPHER_WAPI_GCM4: return WLAN_CRYPTO_CAP_WAPI_GCM4;
}
return 0;
}
/**
* wlan_crypto_set_authmode - called by ucfg to configure authmode for vdev
*
* @vdev: vdev
* @authmode: authmode
*
* This function gets called from ucfg to configure authmode for vdev.
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_authmode(struct wlan_crypto_params *crypto_params,
uint32_t authmode){
crypto_params->authmodeset = authmode;
return QDF_STATUS_SUCCESS;
}
/**
* wlan_crypto_get_authmode - called by ucfg to get authmode of particular vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get authmode of particular vdev
*
* Return: authmode
*/
int32_t wlan_crypto_get_authmode(struct wlan_crypto_params *crypto_params)
{
return crypto_params->authmodeset;
}
/**
* wlan_crypto_set_mcastcipher - called by ucfg to configure mcastcipher in vdev
*
* @vdev: vdev
* @wlan_crypto_cipher_type: mcast cipher value.
*
* This function gets called from ucfg to configure mcastcipher in vdev
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_mcastcipher(struct wlan_crypto_params *crypto_params,
wlan_crypto_cipher_type cipher){
uint16_t i;
uint32_t cap;
QDF_STATUS status = QDF_STATUS_E_INVAL;
RESET_MCAST_CIPHERS(crypto_params);
for (i = 0; i < WLAN_CRYPTO_CIPHER_MAX; i++) {
if (HAS_PARAM(cipher, i)) {
cap = cipher2cap(cipher & i);
if (cap && HAS_CIPHER_CAP(crypto_params, cap)) {
SET_MCAST_CIPHER(crypto_params, i);
status = QDF_STATUS_SUCCESS;
}
}
CLEAR_PARAM(cipher, i);
}
return status;
}
/**
* wlan_crypto_get_mcastcipher - called by ucfg to get mcastcipher from vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get mcastcipher of particular vdev
*
* Return: mcast cipher
*/
int32_t wlan_crypto_get_mcastcipher(struct wlan_crypto_params *crypto_params)
{
return crypto_params->mcastcipherset;
}
/**
* wlan_crypto_set_ucastciphers - called by ucfg to configure
* unicast ciphers in vdev
*
* @vdev: vdev
* @ciphers: bitmap value of all supported unicast ciphers
*
* This function gets called from ucfg to configure unicast ciphers in vdev
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_ucastciphers(
struct wlan_crypto_params *crypto_params,
uint32_t cipher){
uint16_t i;
uint32_t cap;
QDF_STATUS status = QDF_STATUS_E_INVAL;
RESET_UCAST_CIPHERS(crypto_params);
for (i = 0; i < WLAN_CRYPTO_CIPHER_MAX ; i++) {
if (HAS_PARAM(cipher, i)) {
cap = cipher2cap(cipher & i);
if (cap && HAS_CIPHER_CAP(crypto_params, cap)) {
SET_UCAST_CIPHER(crypto_params, i);
status = QDF_STATUS_SUCCESS;
}
}
CLEAR_PARAM(cipher, i);
}
return status;
}
/**
* wlan_crypto_get_ucastciphers - called by ucfg to get ucastcipher from vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get supported unicast ciphers
*
* Return: bitmap value of all supported unicast ciphers
*/
int32_t wlan_crypto_get_ucastciphers(struct wlan_crypto_params *crypto_params)
{
return crypto_params->ucastcipherset;
}
/**
* wlan_crypto_set_mgmtcipher - called by ucfg to configure
* mgmt ciphers in vdev
*
* @vdev: vdev
* @ciphers: bitmap value of all supported unicast ciphers
*
* This function gets called from ucfg to configure unicast ciphers in vdev
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_mgmtcipher(
struct wlan_crypto_params *crypto_params,
uint32_t value){
if (HAS_CIPHER_CAP(crypto_params, WLAN_CRYPTO_CAP_PMF) ||
HAS_CIPHER_CAP(crypto_params, WLAN_CRYPTO_CAP_PMF_OFFLOAD)) {
SET_MGMT_CIPHER(crypto_params, value);
return QDF_STATUS_SUCCESS;
}
return QDF_STATUS_E_INVAL;
}
/**
* wlan_crypto_get_mgmtciphers - called by ucfg to get mgmtcipher from vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get supported unicast ciphers
*
* Return: bitmap value of all supported unicast ciphers
*/
int32_t wlan_crypto_get_mgmtciphers(struct wlan_crypto_params *crypto_params)
{
return crypto_params->mgmtcipherset;
}
/**
* wlan_crypto_set_cipher_cap - called by ucfg to configure
* cipher cap in vdev
*
* @vdev: vdev
* @ciphers: bitmap value of all supported unicast ciphers
*
* This function gets called from ucfg to configure unicast ciphers in vdev
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_cipher_cap(
struct wlan_crypto_params *crypto_params,
uint32_t value){
crypto_params->cipher_caps = value;
return QDF_STATUS_SUCCESS;
}
/**
* wlan_crypto_get_cipher_cap - called by ucfg to get cipher caps from vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get supported unicast ciphers
*
* Return: bitmap value of all supported unicast ciphers
*/
int32_t wlan_crypto_get_cipher_cap(struct wlan_crypto_params *crypto_params)
{
return crypto_params->cipher_caps;
}
/**
* wlan_crypto_set_rsn_cap - called by ucfg to configure
* cipher cap in vdev
*
* @vdev: vdev
* @ciphers: bitmap value of all supported unicast ciphers
*
* This function gets called from ucfg to configure unicast ciphers in vdev
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_rsn_cap(
struct wlan_crypto_params *crypto_params,
uint32_t value){
crypto_params->rsn_caps = value;
return QDF_STATUS_SUCCESS;
}
/**
* wlan_crypto_get_rsn_cap - called by ucfg to get rsn caps from vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get supported unicast ciphers
*
* Return: bitmap value of all supported unicast ciphers
*/
int32_t wlan_crypto_get_rsn_cap(struct wlan_crypto_params *crypto_params)
{
return crypto_params->rsn_caps;
}
/**
* wlan_crypto_set_key_mgmt - called by ucfg to configure
* key_mgmt in vdev
*
* @vdev: vdev
* @ciphers: bitmap value of all supported unicast ciphers
*
* This function gets called from ucfg to configure unicast ciphers in vdev
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_key_mgmt(
struct wlan_crypto_params *crypto_params,
uint32_t value){
crypto_params->key_mgmt = value;
return QDF_STATUS_SUCCESS;
}
/**
* wlan_crypto_get_key_mgmt - called by ucfg to get key mgmt from vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get supported unicast ciphers
*
* Return: bitmap value of all supported unicast ciphers
*/
int32_t wlan_crypto_get_key_mgmt(struct wlan_crypto_params *crypto_params)
{
return crypto_params->key_mgmt;
}

View file

@ -0,0 +1,196 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Public APIs for crypto service
*/
/* include files */
#ifndef __WLAN_CRYPTO_PARAM_HANDLING_I_H_
#define __WLAN_CRYPTO_PARAM_HANDLING_I_H_
/**
* wlan_crypto_set_authmode - called by ucfg to configure authmode for vdev
*
* @vdev: vdev
* @authmode: authmode
*
* This function gets called from ucfg to configure authmode for vdev.
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_authmode(struct wlan_crypto_params *crypto_params,
uint32_t authmode);
/**
* wlan_crypto_get_authmode - called by ucfg to get authmode of particular vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get authmode of particular vdev
*
* Return: authmode
*/
int32_t wlan_crypto_get_authmode(struct wlan_crypto_params *crypto_params);
/**
* wlan_crypto_set_mcastcipher - called by ucfg to configure mcastcipher in vdev
*
* @vdev: vdev
* @wlan_crypto_cipher_type: mcast cipher value.
*
* This function gets called from ucfg to configure mcastcipher in vdev
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_mcastcipher(struct wlan_crypto_params *crypto_params,
wlan_crypto_cipher_type cipher);
/**
* wlan_crypto_get_mcastcipher - called by ucfg to get mcastcipher from vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get mcastcipher of particular vdev
*
* Return: mcast cipher
*/
int32_t wlan_crypto_get_mcastcipher(struct wlan_crypto_params *crypto_params);
/**
* wlan_crypto_set_ucastciphers - called by ucfg to configure
* unicast ciphers in vdev
*
* @vdev: vdev
* @ciphers: bitmap value of all supported unicast ciphers
*
* This function gets called from ucfg to configure unicast ciphers in vdev
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_ucastciphers(struct wlan_crypto_params *,
uint32_t ciphers);
/**
* wlan_crypto_get_ucastciphers - called by ucfg to get ucastcipher from vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get supported unicast ciphers
*
* Return: bitmap value of all supported unicast ciphers
*/
int32_t wlan_crypto_get_ucastciphers(struct wlan_crypto_params *crypto_params);
/**
* wlan_crypto_set_mgmtcipher - called by ucfg to configure
* mgmt ciphers in vdev
*
* @vdev: vdev
* @ciphers: bitmap value of all supported unicast ciphers
*
* This function gets called from ucfg to configure unicast ciphers in vdev
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_mgmtcipher(struct wlan_crypto_params *crypto_params,
uint32_t ciphers);
/**
* wlan_crypto_get_mgmtciphers - called by ucfg to get mgmtcipher from vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get supported unicast ciphers
*
* Return: bitmap value of all supported unicast ciphers
*/
int32_t wlan_crypto_get_mgmtciphers(struct wlan_crypto_params *crypto_params);
/**
* wlan_crypto_set_cipher_cap - called by ucfg to configure
* cipher cap in vdev
*
* @vdev: vdev
* @ciphers: bitmap value of all supported unicast ciphers
*
* This function gets called from ucfg to configure unicast ciphers in vdev
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_cipher_cap(struct wlan_crypto_params *crypto_params,
uint32_t ciphers);
/**
* wlan_crypto_get_cipher_cap - called by ucfg to get cipher caps from vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get supported unicast ciphers
*
* Return: bitmap value of all supported unicast ciphers
*/
int32_t wlan_crypto_get_cipher_cap(struct wlan_crypto_params *crypto_params);
/**
* wlan_crypto_set_rsn_cap - called by ucfg to configure
* cipher cap in vdev
*
* @vdev: vdev
* @ciphers: bitmap value of all supported unicast ciphers
*
* This function gets called from ucfg to configure unicast ciphers in vdev
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_rsn_cap(struct wlan_crypto_params *crypto_params,
uint32_t ciphers);
/**
* wlan_crypto_get_rsn_cap - called by ucfg to get rsn caps from vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get supported unicast ciphers
*
* Return: bitmap value of all supported unicast ciphers
*/
int32_t wlan_crypto_get_rsn_cap(struct wlan_crypto_params *crypto_params);
/**
* wlan_crypto_set_key_mgmt - called by ucfg to configure
* key_mgmt in vdev
*
* @vdev: vdev
* @ciphers: bitmap value of all supported unicast ciphers
*
* This function gets called from ucfg to configure unicast ciphers in vdev
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS wlan_crypto_set_key_mgmt(struct wlan_crypto_params *crypto_params,
uint32_t ciphers);
/**
* wlan_crypto_get_key_mgmt - called by ucfg to get key mgmt from vdev
*
* @vdev: vdev
*
* This function gets called from ucfg to get supported unicast ciphers
*
* Return: bitmap value of all supported unicast ciphers
*/
int32_t wlan_crypto_get_key_mgmt(struct wlan_crypto_params *crypto_params);
#endif /* __WLAN_CRYPTO_PARAM_HANDLING_I_H_ */

View file

@ -0,0 +1,208 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Public API intialization of crypto service with object manager
*/
#include <qdf_types.h>
#include <wlan_cmn.h>
#include <wlan_objmgr_cmn.h>
#include <wlan_objmgr_global_obj.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_objmgr_peer_obj.h>
#include "wlan_crypto_global_def.h"
#include "wlan_crypto_def_i.h"
#include "wlan_crypto_main_i.h"
#include "wlan_crypto_obj_mgr_i.h"
#include "wlan_crypto_tkip_i.h"
static QDF_STATUS tkip_enmic(struct wlan_crypto_key *key, qdf_nbuf_t wbuf,
uint8_t encapdone, uint8_t hdrlen);
static QDF_STATUS tkip_demic(struct wlan_crypto_key *key, qdf_nbuf_t wbuf,
uint8_t tid, uint8_t hdrlen);
static QDF_STATUS tkip_setkey(struct wlan_crypto_key *key)
{
struct wlan_crypto_tkip_ctx *ctx;
if (key->private == NULL) {
key->private = qdf_mem_malloc(
sizeof(struct wlan_crypto_tkip_ctx));
if (key->private == NULL)
return QDF_STATUS_E_NOMEM;
}
ctx = key->private;
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS tkip_encap(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t encapdone,
uint8_t hdrlen){
uint8_t *ivp;
struct ieee80211_frame *wh;
qdf_nbuf_t wbuf0;
uint16_t pktlen;
struct wlan_crypto_cipher *cipher_table;
cipher_table = key->cipher_table;
wh = (struct ieee80211_frame *)qdf_nbuf_data(wbuf);
/*
* Copy down 802.11 header and add the IV, KeyID, and ExtIV.
*/
if (encapdone) {
ivp = (uint8_t *)qdf_nbuf_data(wbuf);
} else {
ivp = (uint8_t *)qdf_nbuf_push_head(wbuf, cipher_table->header);
qdf_mem_move(ivp, (ivp + cipher_table->header), hdrlen);
wh = (struct ieee80211_frame *) qdf_nbuf_data(wbuf);
}
ivp += hdrlen;
key->keytsc++; /* XXX wrap at 48 bits */
ivp[0] = key->keytsc >> 8; /* TSC1 */
ivp[1] = (ivp[0] | 0x20) & 0x7f; /* WEP seed */
ivp[2] = key->keytsc >> 0; /* TSC0*/
ivp[3] = key->keyix | WLAN_CRYPTO_EXT_IV_BIT; /* KeyID | ExtID */
ivp[4] = key->keytsc >> 16; /* PN2 */
ivp[5] = key->keytsc >> 24; /* PN3 */
ivp[6] = key->keytsc >> 32; /* PN4 */
ivp[7] = key->keytsc >> 40; /* PN5 */
wbuf0 = wbuf;
pktlen = qdf_nbuf_len(wbuf);
while (qdf_nbuf_queue_next(wbuf0) != NULL) {
wbuf = qdf_nbuf_queue_next(wbuf0);
pktlen += qdf_nbuf_len(wbuf0);
}
/*
* Finally, do software encrypt if neeed.
*/
if (key->flags & WLAN_CRYPTO_KEY_SWENCRYPT) {
/*if not frag frame then do mic calculation */
if (tkip_enmic(key, wbuf, encapdone, hdrlen)
!= QDF_STATUS_SUCCESS) {
return QDF_STATUS_CRYPTO_ENCRYPT_FAILED;
}
if (!wlan_crypto_tkip_encrypt(key, wbuf, hdrlen))
return QDF_STATUS_CRYPTO_ENCRYPT_FAILED;
}
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS tkip_decap(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t tid,
uint8_t hdrlen){
struct ieee80211_frame *wh;
uint8_t *ivp, *origHdr;
uint64_t pn;
struct wlan_crypto_cipher *cipher_table;
cipher_table = key->cipher_table;
/*
* Header should have extended IV and sequence number;
* verify the former and validate the latter.
*/
origHdr = (uint8_t *)qdf_nbuf_data(wbuf);
wh = (struct ieee80211_frame *)origHdr;
ivp = origHdr + hdrlen;
if ((ivp[WLAN_CRYPTO_IV_LEN] & WLAN_CRYPTO_EXT_IV_BIT) == 0)
return 0;
tid = 16; /* non QoS*/
if ((((wh)->i_fc[0] & (0x0c | 0x80)) == (0x00 | 0x80))) {
if ((wh->i_fc[1] & 0x03) == 0x03) {
tid = ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0]
& 0x0f;
} else {
tid = ((struct ieee80211_qosframe *)wh)->i_qos[0]
& 0x0f;
}
}
/* NB: assume IEEEE80211_WEP_MINLEN covers the extended IV */
pn = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]);
if (pn <= key->keyrsc[tid]) {
/* Replay violation.*/
return 0;
}
if ((key->flags & WLAN_CRYPTO_KEY_SWDECRYPT)) {
if (!wlan_crypto_tkip_decrypt(key, wbuf, hdrlen) == 0)
return QDF_STATUS_CRYPTO_DECRYPT_FAILED;
}
/* PN will be updated in tkip_demic*/
/*
* Copy up 802.11 header and strip crypto bits.
*/
qdf_mem_move(origHdr + cipher_table->header, origHdr, hdrlen);
qdf_nbuf_pull_head(wbuf, cipher_table->header);
while (qdf_nbuf_queue_next(wbuf) != NULL)
wbuf = qdf_nbuf_queue_next(wbuf);
qdf_nbuf_trim_tail(wbuf, cipher_table->trailer);
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS tkip_enmic(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t encapdone,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS tkip_demic(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t tid,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
const struct wlan_crypto_cipher tkip_cipher_table = {
"TKIP",
WLAN_CRYPTO_CIPHER_TKIP,
WLAN_CRYPTO_IV_LEN + WLAN_CRYPTO_KEYID_LEN,
WLAN_CRYPTO_CRC_LEN,
WLAN_CRYPTO_MIC_LEN,
256,
tkip_setkey,
tkip_encap,
tkip_decap,
tkip_enmic,
tkip_demic,
};
const struct wlan_crypto_cipher *tkip_register(void){
return &tkip_cipher_table;
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Public API intialization of crypto service with object manager
*/
#include <qdf_types.h>
#include <wlan_cmn.h>
#include <wlan_objmgr_cmn.h>
#include <wlan_objmgr_global_obj.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_objmgr_peer_obj.h>
#include "wlan_crypto_global_def.h"
#include "wlan_crypto_def_i.h"
#include "wlan_crypto_main_i.h"
#include "wlan_crypto_obj_mgr_i.h"
static QDF_STATUS wapi_setkey(struct wlan_crypto_key *key)
{
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS wapi_encap(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t encapdone,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS wapi_decap(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t tid,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS wapi_enmic(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t encapdone,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS wapi_demic(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t tid,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
const struct wlan_crypto_cipher wapi_cipher_table = {
"WPI_SMS4",
WLAN_CRYPTO_CIPHER_WAPI_SMS4,
WLAN_CRYPTO_WPI_SMS4_IVLEN + WLAN_CRYPTO_WPI_SMS4_KIDLEN
+ WLAN_CRYPTO_WPI_SMS4_PADLEN,
WLAN_CRYPTO_WPI_SMS4_MICLEN,
0,
256,
wapi_setkey,
wapi_encap,
wapi_decap,
wapi_enmic,
wapi_demic,
};
const struct wlan_crypto_cipher *wapi_register(void){
return &wapi_cipher_table;
}

View file

@ -0,0 +1,162 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: Public API intialization of crypto service with object manager
*/
#include <qdf_types.h>
#include <wlan_cmn.h>
#include <wlan_objmgr_cmn.h>
#include <wlan_objmgr_global_obj.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_objmgr_peer_obj.h>
#include "wlan_crypto_global_def.h"
#include "wlan_crypto_def_i.h"
#include "wlan_crypto_main_i.h"
#include "wlan_crypto_obj_mgr_i.h"
#include "wlan_crypto_rijndael.h"
#include "wlan_crypto_tkip_i.h"
static QDF_STATUS wep_setkey(struct wlan_crypto_key *key)
{
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS wep_encap(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t encapdone,
uint8_t hdrlen)
{
uint8_t *ivp;
struct ieee80211_frame *wh;
struct wlan_crypto_cipher *cipher_table;
uint16_t off, data_len;
wh = (struct ieee80211_frame *)qdf_nbuf_data(wbuf);
cipher_table = key->cipher_table;
/*
* Copy down 802.11 header and add the IV, KeyID, and ExtIV.
*/
if (encapdone) {
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);
/* recompute wh */
wh = (struct ieee80211_frame *) qdf_nbuf_data(wbuf);
}
ivp += hdrlen;
#if _BYTE_ORDER == _BIG_ENDIAN
ivp[2] = key->keyrsc[0] >> 0;
ivp[1] = key->keyrsc[0] >> 8;
ivp[0] = key->keyrsc[0] >> 16;
#else
ivp[0] = key->keyrsc[0] >> 0;
ivp[1] = key->keyrsc[0] >> 8;
ivp[2] = key->keyrsc[0] >> 16;
#endif
ivp[3] = key->keyix;
/*
* Finally, do software encrypt if neeed.
*/
off = hdrlen + cipher_table->header;
data_len = qdf_nbuf_len(wbuf) - off;
if ((key->flags & WLAN_CRYPTO_KEY_SWENCRYPT) &&
!wlan_crypto_wep_encrypt(key->keyval, wbuf, off, data_len)) {
return QDF_STATUS_CRYPTO_ENCRYPT_FAILED;
}
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS wep_decap(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t tid,
uint8_t hdrlen)
{
struct ieee80211_frame *wh;
struct wlan_crypto_cipher *cipher_table;
uint8_t *origHdr = (uint8_t *)qdf_nbuf_data(wbuf);
uint16_t off, data_len;
wh = (struct ieee80211_frame *)origHdr;
cipher_table = key->cipher_table;
/*
* Check if the device handled the decrypt in hardware.
* If so we just strip the header; otherwise we need to
* handle the decrypt in software.
*/
off = hdrlen + cipher_table->header;
data_len = qdf_nbuf_len(wbuf) - off - cipher_table->trailer;
if ((key->flags & WLAN_CRYPTO_KEY_SWDECRYPT) &&
!wlan_crypto_wep_decrypt(key->keyval, wbuf, off, data_len)) {
return 0;
}
/*
* Copy up 802.11 header and strip crypto bits.
*/
qdf_mem_move(origHdr + cipher_table->header, origHdr, hdrlen);
qdf_nbuf_pull_head(wbuf, cipher_table->header);
qdf_nbuf_trim_tail(wbuf, cipher_table->trailer);
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS wep_enmic(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t tid,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS wep_demic(struct wlan_crypto_key *key,
qdf_nbuf_t wbuf,
uint8_t tid,
uint8_t hdrlen){
return QDF_STATUS_SUCCESS;
}
const struct wlan_crypto_cipher wep_cipher_table = {
"WEP",
WLAN_CRYPTO_CIPHER_WEP,
WLAN_CRYPTO_IV_LEN + WLAN_CRYPTO_KEYID_LEN,
WLAN_CRYPTO_CRC_LEN,
0,
152,
wep_setkey,
wep_encap,
wep_decap,
wep_enmic,
wep_demic,
};
const struct wlan_crypto_cipher *wep_register(void){
return &wep_cipher_table;
}