Browse Source

qcacmn: Add crypto service files

Add crypto service files

Change-Id: I6efa8e633ca414a819c0ede05c44e89aebde8ad3
Ashok Ponnaiah 8 years ago
parent
commit
89d288129e

+ 345 - 0
umac/cmn_services/crypto/inc/wlan_crypto_global_api.h

@@ -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_ */

+ 296 - 0
umac/cmn_services/crypto/inc/wlan_crypto_global_def.h

@@ -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_ */

+ 331 - 0
umac/cmn_services/crypto/src/wlan_crypto_ccmp.c

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

+ 300 - 0
umac/cmn_services/crypto/src/wlan_crypto_def_i.h

@@ -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_ */

+ 2055 - 0
umac/cmn_services/crypto/src/wlan_crypto_global_api.c

@@ -0,0 +1,2055 @@
+/*
+ * 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 <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"
+#include "wlan_crypto_obj_mgr_i.h"
+#include "wlan_crypto_pmf_i.h"
+
+
+const struct wlan_crypto_cipher *wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX];
+
+
+/**
+ * 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
+ */
+static struct wlan_crypto_params *wlan_crypto_vdev_get_comp_params(
+				struct wlan_objmgr_vdev *vdev,
+				struct wlan_crypto_comp_priv **crypto_priv){
+	*crypto_priv = (struct wlan_crypto_comp_priv *)
+					wlan_get_vdev_crypto_obj(vdev);
+	if (*crypto_priv == NULL) {
+		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
+		return NULL;
+	}
+
+	return &((*crypto_priv)->crypto_params);
+}
+
+/**
+ * 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
+ */
+static struct wlan_crypto_params *wlan_crypto_peer_get_comp_params(
+				struct wlan_objmgr_peer *peer,
+				struct wlan_crypto_comp_priv **crypto_priv){
+
+	*crypto_priv = (struct wlan_crypto_comp_priv *)
+					wlan_get_peer_crypto_obj(peer);
+	if (*crypto_priv == NULL) {
+		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
+		return NULL;
+	}
+
+	return &((*crypto_priv)->crypto_params);
+}
+
+/**
+ * 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){
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+
+	crypto_priv = (struct wlan_crypto_comp_priv *)
+					wlan_get_vdev_crypto_obj(vdev);
+
+	if (crypto_priv == NULL) {
+		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	crypto_params = &(crypto_priv->crypto_params);
+	switch (param) {
+	case WLAN_CRYPTO_PARAM_AUTH_MODE:
+		status = wlan_crypto_set_authmode(crypto_params, value);
+		break;
+	case WLAN_CRYPTO_PARAM_UCAST_CIPHER:
+		status = wlan_crypto_set_ucastciphers(crypto_params, value);
+		break;
+	case WLAN_CRYPTO_PARAM_MCAST_CIPHER:
+		status = wlan_crypto_set_mcastcipher(crypto_params, value);
+		break;
+	case WLAN_CRYPTO_PARAM_MGMT_CIPHER:
+		status = wlan_crypto_set_mgmtcipher(crypto_params, value);
+		break;
+	case WLAN_CRYPTO_PARAM_CIPHER_CAP:
+		status = wlan_crypto_set_cipher_cap(crypto_params, value);
+		break;
+	case WLAN_CRYPTO_PARAM_RSN_CAP:
+		status = wlan_crypto_set_rsn_cap(crypto_params,	value);
+		break;
+	case WLAN_CRYPTO_PARAM_KEY_MGMT:
+		status = wlan_crypto_set_key_mgmt(crypto_params, value);
+		break;
+	default:
+		status = QDF_STATUS_E_INVAL;
+	}
+
+	return status;
+}
+
+/**
+ * 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){
+	int32_t value = -1;
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+	crypto_priv = (struct wlan_crypto_comp_priv *)
+				wlan_get_vdev_crypto_obj(vdev);
+
+	if (crypto_priv == NULL) {
+		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	crypto_params = &(crypto_priv->crypto_params);
+	switch (param) {
+	case WLAN_CRYPTO_PARAM_AUTH_MODE:
+		value = wlan_crypto_get_authmode(crypto_params);
+		break;
+	case WLAN_CRYPTO_PARAM_UCAST_CIPHER:
+		value = wlan_crypto_get_ucastciphers(crypto_params);
+		break;
+	case WLAN_CRYPTO_PARAM_MCAST_CIPHER:
+		value = wlan_crypto_get_mcastcipher(crypto_params);
+		break;
+	case WLAN_CRYPTO_PARAM_MGMT_CIPHER:
+		value = wlan_crypto_get_mgmtciphers(crypto_params);
+		break;
+	case WLAN_CRYPTO_PARAM_CIPHER_CAP:
+		value = wlan_crypto_get_cipher_cap(crypto_params);
+		break;
+	case WLAN_CRYPTO_PARAM_RSN_CAP:
+		value = wlan_crypto_get_rsn_cap(crypto_params);
+		break;
+	case WLAN_CRYPTO_PARAM_KEY_MGMT:
+		value = wlan_crypto_get_key_mgmt(crypto_params);
+		break;
+	default:
+		value = QDF_STATUS_E_INVAL;
+	}
+
+	return value;
+}
+
+static void  initialize_send_iv(uint8_t *iv, uint8_t *init_iv)
+{
+	int8_t i = 0;
+
+	for (i = 0; i < WLAN_CRYPTO_WAPI_IV_SIZE/4; i++) {
+		*(((uint32_t *)iv)+i) =
+				qdf_be32_to_cpu(*(((uint32_t *)(init_iv))+i));
+	}
+}
+/**
+ * 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){
+
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+	struct wlan_crypto_key *key;
+	const struct wlan_crypto_cipher *cipher;
+	uint8_t *macaddr = NULL;
+	bool isbcast;
+
+	if (!req_key || req_key->keylen > (sizeof(req_key->keydata))) {
+		qdf_print("%s[%d] req_key invalid\n", __func__, __LINE__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	isbcast = qdf_is_macaddr_broadcast(
+				(struct qdf_mac_addr *)req_key->macaddr);
+	if (req_key->keylen == 0) {
+		/* zero length keys, only set default key id if flags are set*/
+		if ((req_key->flags & WLAN_CRYPTO_KEY_DEFAULT)
+			&& (req_key->keyix != WLAN_CRYPTO_KEYIX_NONE)
+			&& (!IS_MGMT_CIPHER(req_key->type))) {
+			wlan_crypto_default_key(vdev,
+				req_key->macaddr,
+				req_key->keyix,
+				!isbcast);
+			return QDF_STATUS_SUCCESS;
+		}
+		qdf_print("%s[%d] req_key len zero\n", __func__, __LINE__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	cipher = wlan_crypto_cipher_ops[req_key->type];
+
+	if (!cipher && !IS_MGMT_CIPHER(req_key->type)) {
+		qdf_print("%s[%d] cipher invalid\n", __func__, __LINE__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if ((IS_MGMT_CIPHER(req_key->type))
+		|| ((req_key->keylen != (cipher->keylen/NBBY))
+		&& (req_key->type != WLAN_CRYPTO_CIPHER_WEP))) {
+		qdf_print("%s[%d] cipher invalid\n", __func__, __LINE__);
+		return QDF_STATUS_E_INVAL;
+	} else if ((req_key->type == WLAN_CRYPTO_CIPHER_WEP) &&
+		!((req_key->keylen != WLAN_CRYPTO_KEY_WEP40_LEN)
+		|| (req_key->keylen != WLAN_CRYPTO_KEY_WEP104_LEN)
+		|| (req_key->keylen != WLAN_CRYPTO_KEY_WEP128_LEN))) {
+		qdf_print("%s[%d] cipher invalid\n", __func__, __LINE__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (req_key->keyix == WLAN_CRYPTO_KEYIX_NONE) {
+		if (req_key->flags != (WLAN_CRYPTO_KEY_XMIT
+						| WLAN_CRYPTO_KEY_RECV)) {
+			req_key->flags = (WLAN_CRYPTO_KEY_XMIT
+						| WLAN_CRYPTO_KEY_RECV);
+		}
+	} else {
+		if ((req_key->keyix > WLAN_CRYPTO_MAXKEYIDX)
+			&& (!IS_MGMT_CIPHER(req_key->type))) {
+			return QDF_STATUS_E_INVAL;
+		}
+
+		req_key->flags = (WLAN_CRYPTO_KEY_XMIT
+					| WLAN_CRYPTO_KEY_RECV);
+		req_key->flags |= WLAN_CRYPTO_KEY_GROUP;
+	}
+
+	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)req_key->macaddr)) {
+		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
+								&crypto_priv);
+		wlan_vdev_obj_lock(vdev);
+		macaddr = wlan_vdev_mlme_get_macaddr(vdev);
+		wlan_vdev_obj_unlock(vdev);
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		if (IS_MGMT_CIPHER(req_key->type)) {
+			key = crypto_priv->igtk_key;
+		} else {
+			if (!HAS_MCAST_CIPHER(crypto_params, req_key->type)
+				&& (req_key->type != WLAN_CRYPTO_CIPHER_WEP)) {
+				return QDF_STATUS_E_INVAL;
+			}
+			if (!crypto_priv->key[req_key->keyix]) {
+				crypto_priv->key[req_key->keyix]
+					= qdf_mem_malloc(
+						sizeof(struct wlan_crypto_key));
+				if (!crypto_priv->key[req_key->keyix])
+					return QDF_STATUS_E_NOMEM;
+			}
+			key = crypto_priv->key[req_key->keyix];
+		}
+	} else {
+		struct wlan_objmgr_peer *peer;
+
+		wlan_vdev_obj_lock(vdev);
+		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
+					wlan_vdev_get_psoc(vdev),
+					req_key->macaddr,
+					wlan_vdev_mlme_get_macaddr(vdev),
+					WLAN_CRYPTO_ID);
+		wlan_vdev_obj_unlock(vdev);
+		macaddr = req_key->macaddr;
+		if (peer == NULL) {
+			qdf_print("%s[%d] peer NULL\n", __func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		crypto_params = wlan_crypto_peer_get_comp_params(peer,
+								&crypto_priv);
+		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
+
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+		if (IS_MGMT_CIPHER(req_key->type)) {
+			key = crypto_priv->igtk_key;
+		} else {
+			uint16_t kid = req_key->keyix;
+			if (kid == WLAN_CRYPTO_KEYIX_NONE)
+				kid = 0;
+			if (!crypto_priv->key[kid]) {
+				crypto_priv->key[kid]
+					= qdf_mem_malloc(
+						sizeof(struct wlan_crypto_key));
+				if (!crypto_priv->key[kid])
+					return QDF_STATUS_E_NOMEM;
+			}
+			key = crypto_priv->key[kid];
+		}
+	}
+
+	/* alloc key might not required as it is already there */
+	key->cipher_table = (void *)cipher;
+	key->keylen = req_key->keylen;
+	key->flags = req_key->flags;
+
+	if (req_key->keyix == WLAN_CRYPTO_KEYIX_NONE)
+		key->keyix = 0;
+	else
+		key->keyix = req_key->keyix;
+
+	if ((req_key->type == WLAN_CRYPTO_CIPHER_WAPI_SMS4)
+		|| (req_key->type == WLAN_CRYPTO_CIPHER_WAPI_GCM4)) {
+		uint8_t iv_AP[16] = {	0x5c, 0x36, 0x5c, 0x36,
+					0x5c, 0x36, 0x5c, 0x36,
+					0x5c, 0x36, 0x5c, 0x36,
+					0x5c, 0x36, 0x5c, 0x37};
+		uint8_t iv_STA[16] = {	0x5c, 0x36, 0x5c, 0x36,
+					0x5c, 0x36, 0x5c, 0x36,
+					0x5c, 0x36, 0x5c, 0x36,
+					0x5c, 0x36, 0x5c, 0x36};
+
+		/* During Tx PN should be increment and
+		 * send but as per our implementation we increment only after
+		 * Tx complete. So First packet PN check will be failed.
+		 * To compensate increment the PN here by 2
+		 */
+		wlan_vdev_obj_lock(vdev);
+		if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) {
+			iv_AP[15] += 2;
+			wlan_vdev_obj_unlock(vdev);
+			qdf_mem_copy(key->recviv, iv_STA,
+						WLAN_CRYPTO_WAPI_IV_SIZE);
+			/*initialize send iv */
+			qdf_mem_zero((uint8_t *)(key->txiv),
+						WLAN_CRYPTO_WAPI_IV_SIZE);
+			initialize_send_iv(key->txiv, iv_AP);
+		} else {
+			iv_STA[15] += 2;
+			wlan_vdev_obj_unlock(vdev);
+			qdf_mem_copy(key->recviv, iv_AP,
+						WLAN_CRYPTO_WAPI_IV_SIZE);
+			/*initialize send iv */
+			qdf_mem_zero((uint8_t *)(key->txiv),
+						WLAN_CRYPTO_WAPI_IV_SIZE);
+			initialize_send_iv(key->txiv, iv_STA);
+		}
+	} else {
+		uint8_t i = 0;
+		qdf_mem_copy((uint8_t *)(&key->keytsc),
+			(uint8_t *)(&req_key->keytsc), sizeof(key->keytsc));
+		for (i = 0; i < WLAN_CRYPTO_TID_SIZE; i++) {
+			qdf_mem_copy((uint8_t *)(&key->keyrsc[i]),
+					(uint8_t *)(&req_key->keyrsc),
+					sizeof(key->keyrsc[0]));
+		}
+	}
+
+	qdf_mem_copy(key->keyval, req_key->keydata, sizeof(key->keyval));
+	key->valid = 1;
+
+	if (!macaddr) {
+		qdf_print("%s[%d] macaddr invalid\n", __func__, __LINE__);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if ((IS_MGMT_CIPHER(req_key->type))
+		&& HAS_MGMT_CIPHER(crypto_params, req_key->type)) {
+		if (HAS_CIPHER_CAP(crypto_params,
+					WLAN_CRYPTO_CAP_PMF_OFFLOAD)) {
+			struct wlan_objmgr_psoc *psoc;
+			wlan_vdev_obj_lock(vdev);
+			psoc = wlan_vdev_get_psoc(vdev);
+			wlan_vdev_obj_unlock(vdev);
+
+			if (!psoc)
+				return QDF_STATUS_E_NULL_VALUE;
+			if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) {
+				WLAN_CRYPTO_TX_OPS_SETKEY(psoc)(vdev,
+						key, macaddr, req_key->type);
+			}
+		}
+		status = wlan_crypto_set_igtk_key(key);
+		return status;
+	} else {
+		struct wlan_objmgr_psoc *psoc;
+		wlan_vdev_obj_lock(vdev);
+		psoc = wlan_vdev_get_psoc(vdev);
+		wlan_vdev_obj_unlock(vdev);
+		if (!psoc)
+			return QDF_STATUS_E_NULL_VALUE;
+
+		if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) {
+			WLAN_CRYPTO_TX_OPS_SETKEY(psoc)(vdev, key,
+							macaddr, req_key->type);
+		}
+	}
+	status = cipher->setkey(key);
+
+	return status;
+}
+
+/**
+ * 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){
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+	struct wlan_crypto_key *key;
+
+	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) {
+		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
+								&crypto_priv);
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+		}
+			return QDF_STATUS_E_INVAL;
+
+		if (!HAS_MCAST_CIPHER(crypto_params, req_key->type))
+			return QDF_STATUS_E_INVAL;
+
+		key = crypto_priv->key[crypto_priv->def_tx_keyid];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+	} else {
+		struct wlan_objmgr_peer *peer;
+
+		wlan_vdev_obj_lock(vdev);
+		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
+					wlan_vdev_get_psoc(vdev),
+					mac_addr,
+					wlan_vdev_mlme_get_macaddr(vdev),
+					WLAN_CRYPTO_ID);
+		wlan_vdev_obj_unlock(vdev);
+		if (peer == NULL) {
+			qdf_print("%s[%d] peer NULL\n", __func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+		crypto_params = wlan_crypto_peer_get_comp_params(peer,
+								&crypto_priv);
+		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		if (!HAS_UCAST_CIPHER(crypto_params, req_key->type))
+			return QDF_STATUS_E_INVAL;
+
+		key = crypto_priv->key[crypto_priv->def_tx_keyid];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+	}
+
+	if (key->valid) {
+		qdf_mem_copy(req_key->keydata,
+				key->keyval, sizeof(key->keyval));
+		qdf_mem_copy((uint8_t *)(&req_key->keytsc),
+				(uint8_t *)(&key->keytsc),
+				sizeof(req_key->keytsc));
+		qdf_mem_copy((uint8_t *)(&req_key->keyrsc),
+				(uint8_t *)(&key->keyrsc[0]),
+				sizeof(req_key->keyrsc));
+		req_key->keylen = key->keylen;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * 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){
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+	struct wlan_crypto_key *key;
+	struct wlan_crypto_cipher *cipher_table;
+
+	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)macaddr)) {
+		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
+								&crypto_priv);
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		key = crypto_priv->key[key_idx];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+		crypto_priv->key[key_idx] = NULL;
+	} else {
+		struct wlan_objmgr_peer *peer;
+
+		wlan_vdev_obj_lock(vdev);
+		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
+				wlan_vdev_get_psoc(vdev), macaddr,
+				wlan_vdev_mlme_get_macaddr(vdev),
+				WLAN_CRYPTO_ID);
+		wlan_vdev_obj_unlock(vdev);
+		if (peer == NULL) {
+			qdf_print("%s[%d] peer NULL\n", __func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+		crypto_params = wlan_crypto_peer_get_comp_params(peer,
+								&crypto_priv);
+		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		key = crypto_priv->key[key_idx];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+		crypto_priv->key[key_idx] = NULL;
+	}
+	if (key->valid) {
+		struct wlan_objmgr_psoc *psoc;
+		wlan_vdev_obj_lock(vdev);
+		psoc = wlan_vdev_get_psoc(vdev);
+		wlan_vdev_obj_unlock(vdev);
+		if (!psoc)
+			return QDF_STATUS_E_NULL_VALUE;
+
+		cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
+
+		if (WLAN_CRYPTO_TX_OPS_DELKEY(psoc)) {
+			WLAN_CRYPTO_TX_OPS_DELKEY(psoc)(vdev, key,
+						macaddr, cipher_table->cipher);
+		}
+	}
+	qdf_mem_free(key);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * 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){
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+	struct wlan_crypto_key *key;
+	struct wlan_objmgr_psoc *psoc;
+
+	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)macaddr)) {
+		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
+								&crypto_priv);
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		key = crypto_priv->key[key_idx];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+	} else {
+		struct wlan_objmgr_peer *peer;
+		wlan_vdev_obj_lock(vdev);
+		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
+				wlan_vdev_get_psoc(vdev), macaddr,
+				wlan_vdev_mlme_get_macaddr(vdev),
+				WLAN_CRYPTO_ID);
+		wlan_vdev_obj_unlock(vdev);
+
+		if (peer == NULL) {
+			qdf_print("%s[%d] peer NULL\n", __func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+		crypto_params = wlan_crypto_peer_get_comp_params(peer,
+								&crypto_priv);
+		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		key = crypto_priv->key[key_idx];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+	}
+	if (!key->valid)
+		return QDF_STATUS_E_INVAL;
+
+	wlan_vdev_obj_lock(vdev);
+	psoc = wlan_vdev_get_psoc(vdev);
+	wlan_vdev_obj_unlock(vdev);
+	if (!psoc)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	if (WLAN_CRYPTO_TX_OPS_DEFAULTKEY(psoc)) {
+		WLAN_CRYPTO_TX_OPS_DEFAULTKEY(psoc)(vdev, key_idx,
+						macaddr);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * 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 *mac_addr,
+				uint8_t encapdone){
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+	struct wlan_crypto_key *key;
+	QDF_STATUS status;
+	struct wlan_crypto_cipher *cipher_table;
+
+	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) {
+		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
+								&crypto_priv);
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		key = crypto_priv->key[crypto_priv->def_tx_keyid];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+
+	} else {
+		struct wlan_objmgr_peer *peer;
+
+		wlan_vdev_obj_lock(vdev);
+		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
+				wlan_vdev_get_psoc(vdev), mac_addr,
+				wlan_vdev_mlme_get_macaddr(vdev),
+				WLAN_CRYPTO_ID);
+		wlan_vdev_obj_unlock(vdev);
+
+		if (peer == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+		crypto_params = wlan_crypto_peer_get_comp_params(peer,
+								&crypto_priv);
+		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
+
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		key = crypto_priv->key[crypto_priv->def_tx_keyid];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+	}
+	/* if tkip, is counter measures enabled, then drop the frame */
+	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
+	status = cipher_table->encap(key, wbuf, encapdone,
+						ieee80211_hdrsize(wbuf));
+
+	return status;
+}
+EXPORT_SYMBOL(wlan_crypto_encap);
+
+/**
+ * wlan_crypto_decap - called by mgmt for decap 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_decap(struct wlan_objmgr_vdev *vdev,
+				qdf_nbuf_t wbuf,
+				uint8_t *mac_addr,
+				uint8_t tid){
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+	struct wlan_crypto_key *key;
+	QDF_STATUS status;
+	struct wlan_crypto_cipher *cipher_table;
+
+	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) {
+		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
+								&crypto_priv);
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		key = crypto_priv->key[crypto_priv->def_tx_keyid];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+
+	} else {
+		struct wlan_objmgr_peer *peer;
+
+		wlan_vdev_obj_lock(vdev);
+		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
+					wlan_vdev_get_psoc(vdev),
+					mac_addr,
+					wlan_vdev_mlme_get_macaddr(vdev),
+					WLAN_CRYPTO_ID);
+		wlan_vdev_obj_unlock(vdev);
+		if (peer == NULL) {
+			qdf_print("%s[%d] peer NULL\n", __func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		crypto_params = wlan_crypto_peer_get_comp_params(peer,
+								&crypto_priv);
+		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
+
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		key = crypto_priv->key[crypto_priv->def_tx_keyid];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+	}
+	/* if tkip, is counter measures enabled, then drop the frame */
+	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
+	status = cipher_table->decap(key, wbuf, tid, ieee80211_hdrsize(wbuf));
+
+	return status;
+}
+EXPORT_SYMBOL(wlan_crypto_decap);
+/**
+ * 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 *mac_addr,
+				uint8_t encapdone){
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+	struct wlan_crypto_key *key;
+	QDF_STATUS status;
+	struct wlan_crypto_cipher *cipher_table;
+
+	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) {
+		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
+								&crypto_priv);
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		key = crypto_priv->key[crypto_priv->def_tx_keyid];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+
+	} else {
+		struct wlan_objmgr_peer *peer;
+
+		wlan_vdev_obj_lock(vdev);
+		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
+					wlan_vdev_get_psoc(vdev),
+					mac_addr,
+					wlan_vdev_mlme_get_macaddr(vdev),
+					WLAN_CRYPTO_ID);
+		wlan_vdev_obj_unlock(vdev);
+		if (peer == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		crypto_params = wlan_crypto_peer_get_comp_params(peer,
+								&crypto_priv);
+		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
+
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		key = crypto_priv->key[crypto_priv->def_tx_keyid];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+	}
+	/* if tkip, is counter measures enabled, then drop the frame */
+	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
+	status = cipher_table->enmic(key, wbuf, encapdone,
+						ieee80211_hdrsize(wbuf));
+
+	return status;
+}
+
+/**
+ * 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 *mac_addr,
+				uint8_t tid){
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+	struct wlan_crypto_key *key;
+	QDF_STATUS status;
+	struct wlan_crypto_cipher *cipher_table;
+
+	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr)) {
+		crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
+								&crypto_priv);
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		key = crypto_priv->key[crypto_priv->def_tx_keyid];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+
+	} else {
+		struct wlan_objmgr_peer *peer;
+
+		wlan_vdev_obj_lock(vdev);
+		peer = wlan_objmgr_get_peer_by_mac_n_vdev(
+					wlan_vdev_get_psoc(vdev),
+					mac_addr,
+					wlan_vdev_mlme_get_macaddr(vdev),
+					WLAN_CRYPTO_ID);
+		wlan_vdev_obj_unlock(vdev);
+		if (peer == NULL) {
+			qdf_print("%s[%d] peer NULL\n", __func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		crypto_params = wlan_crypto_peer_get_comp_params(peer,
+								&crypto_priv);
+		wlan_objmgr_peer_release_ref(peer, WLAN_CRYPTO_ID);
+
+		if (crypto_priv == NULL) {
+			qdf_print("%s[%d] crypto_priv NULL\n",
+							__func__, __LINE__);
+			return QDF_STATUS_E_INVAL;
+		}
+
+		key = crypto_priv->key[crypto_priv->def_tx_keyid];
+		if (!key)
+			return QDF_STATUS_E_INVAL;
+	}
+	/* if tkip, is counter measures enabled, then drop the frame */
+	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
+	status = cipher_table->demic(key, wbuf, tid, ieee80211_hdrsize(wbuf));
+
+	return status;
+}
+
+/**
+ * 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){
+
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *vdev_crypto_params;
+	struct wlan_crypto_params *peer_crypto_params;
+
+	if (!vdev || !peer)
+		return false;
+	vdev_crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
+							&crypto_priv);
+	if (crypto_priv == NULL) {
+		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	peer_crypto_params = wlan_crypto_peer_get_comp_params(peer,
+							&crypto_priv);
+	if (crypto_priv == NULL) {
+		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (((vdev_crypto_params->rsn_caps &
+					WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) &&
+		(vdev_crypto_params->rsn_caps &
+					WLAN_CRYPTO_RSN_CAP_MFP_ENABLED))
+		|| (vdev_crypto_params->rsn_caps &
+					WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)) {
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * wlan_crypto_add_mmie - called by mgmt txrx to add mmie in frame
+ *
+ * @vdev: vdev
+ * @bfrm:  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 *bfrm,
+				uint32_t len) {
+	struct wlan_crypto_key *key;
+	struct ieee80211_ath_mmie *mmie;
+	uint8_t *pn, aad[20], *efrm, nounce[12];
+	struct ieee80211_frame *wh;
+	uint32_t i, hdrlen;
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+
+	crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
+							&crypto_priv);
+	if (crypto_priv == NULL) {
+		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
+		return NULL;
+	}
+
+	key = crypto_priv->igtk_key;
+	if (!key)
+		return NULL;
+
+	if (!key && !bfrm) {
+		/* Invalid Key or frame */
+		return NULL;
+	}
+
+	efrm = bfrm + len;
+	len += sizeof(*mmie);
+	hdrlen = sizeof(*wh);
+
+	mmie = (struct ieee80211_ath_mmie *) efrm;
+	mmie->element_id = IEEE80211_ELEMID_MMIE;
+	mmie->length = sizeof(*mmie) - 2;
+	mmie->key_id = qdf_cpu_to_le16(key->keyix);
+
+	/* PN = PN + 1 */
+	pn = (uint8_t *)&key->keytsc;
+
+	for (i = 0; i <= 5; i++) {
+		pn[i]++;
+		if (pn[i])
+			break;
+	}
+
+	/* Copy IPN */
+	qdf_mem_copy(mmie->sequence_number, pn, 6);
+
+	wh = (struct ieee80211_frame *) bfrm;
+
+	/* generate BIP AAD: FC(masked) || A1 || A2 || A3 */
+
+	/* FC type/subtype */
+	aad[0] = wh->i_fc[0];
+	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
+	aad[1] = wh->i_fc[1] & ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT
+						| IEEE80211_FC1_MORE_DATA);
+	/* A1 || A2 || A3 */
+	qdf_mem_copy(aad + 2, wh->i_addr1, IEEE80211_ADDR_LEN);
+	qdf_mem_copy(aad + 8, wh->i_addr2, IEEE80211_ADDR_LEN);
+	qdf_mem_copy(aad + 14, wh->i_addr3, IEEE80211_ADDR_LEN);
+	/*
+	 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
+	 */
+
+	if ((HAS_MGMT_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CMAC))
+		|| HAS_MGMT_CIPHER(crypto_params,
+					WLAN_CRYPTO_CIPHER_AES_CMAC_256)) {
+		/* size of MIC is 16 for GMAC, size of mic for CMAC is 8 */
+		len -= 8;
+		mmie->length -= 8;
+		wlan_crypto_cmac_calc_mic(key, aad, bfrm + hdrlen,
+						len - hdrlen, mmie->mic);
+	} else if ((HAS_MGMT_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_GMAC))
+		|| HAS_MGMT_CIPHER(crypto_params,
+					WLAN_CRYPTO_CIPHER_AES_GMAC_256)) {
+		qdf_mem_copy(nounce, wh->i_addr2, IEEE80211_ADDR_LEN);
+		qdf_mem_copy(nounce + 6, pn, 6);
+		wlan_crypto_gmac_calc_mic(key, aad, bfrm + hdrlen, 20,
+							mmie->mic, nounce);
+	} else {
+		qdf_print("%s CMAC/GMAC Not valid rsn\n", __func__);
+		return NULL;
+	}
+
+	return bfrm + 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){
+	struct ieee80211_ath_mmie   *mmie = NULL;
+	uint8_t *ipn, aad[20], mic[16], nounce[12];
+	struct wlan_crypto_key *key;
+	struct ieee80211_frame *wh;
+	uint8_t mic_length;
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+
+	/* check if frame is illegal length */
+	if ((efrm < frm) || ((efrm - frm) < sizeof(*wh)))
+		return false;
+
+	crypto_priv = (struct wlan_crypto_comp_priv *)
+				wlan_get_vdev_crypto_obj(vdev);
+	if (crypto_priv == NULL) {
+		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
+		return false;
+	}
+
+	crypto_params = &(crypto_priv->crypto_params);
+		key = crypto_priv->igtk_key;
+	if (!key)
+		return false;
+
+	if ((HAS_MGMT_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CMAC))
+		|| HAS_MGMT_CIPHER(crypto_params,
+					WLAN_CRYPTO_CIPHER_AES_CMAC_256)) {
+		mmie = (struct ieee80211_ath_mmie *)(efrm - sizeof(*mmie) + 8);
+	} else if ((HAS_MGMT_CIPHER(crypto_params,
+						WLAN_CRYPTO_CIPHER_AES_GMAC))
+		|| HAS_MGMT_CIPHER(crypto_params,
+					WLAN_CRYPTO_CIPHER_AES_GMAC_256)) {
+		mmie = (struct ieee80211_ath_mmie *)(efrm - sizeof(*mmie));
+	}
+	/* check Elem ID*/
+	if ((mmie == NULL) || (mmie->element_id != IEEE80211_ELEMID_MMIE)) {
+		/* IE is not Mgmt MIC IE */
+		return false;
+	}
+
+	/* validate ipn */
+	ipn = mmie->sequence_number;
+	if (qdf_mem_cmp(ipn, key->keyrsc, 6) <= 0) {
+		/* replay error */
+		return false;
+	}
+
+	/* construct AAD */
+	wh = (struct ieee80211_frame *)frm;
+	/* generate BIP AAD: FC(masked) || A1 || A2 || A3 */
+
+	/* FC type/subtype */
+	aad[0] = wh->i_fc[0];
+	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
+	aad[1] = wh->i_fc[1] & ~(IEEE80211_FC1_RETRY | IEEE80211_FC1_PWR_MGT
+						| IEEE80211_FC1_MORE_DATA);
+	/* A1 || A2 || A3 */
+	qdf_mem_copy(aad + 2, wh->i_addr_all, 3 * IEEE80211_ADDR_LEN);
+
+	/*
+	 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
+	 */
+	if ((HAS_MGMT_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CMAC))
+		|| HAS_MGMT_CIPHER(crypto_params,
+					WLAN_CRYPTO_CIPHER_AES_CMAC_256)) {
+		mic_length = 8;
+		 wlan_crypto_cmac_calc_mic(key, aad, (uint8_t *)(wh+1),
+					(efrm - (uint8_t *)(wh+1)), mic);
+	} else if ((HAS_MGMT_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_GMAC))
+		|| HAS_MGMT_CIPHER(crypto_params,
+					WLAN_CRYPTO_CIPHER_AES_GMAC_256)) {
+		mic_length = 16;
+		qdf_mem_copy(nounce, wh->i_addr2, IEEE80211_ADDR_LEN);
+		qdf_mem_copy(nounce + 6, ipn, 6);
+		wlan_crypto_gmac_calc_mic(key, aad,  (uint8_t *)(wh+1),
+							20, mic, nounce);
+	} else
+		return false;
+
+	if (qdf_mem_cmp(mic, mmie->mic, mic_length) != 0)
+		/* MMIE MIC mismatch */
+		return false;
+
+	/* Update the receive sequence number */
+	qdf_mem_copy(key->keyrsc, ipn, 6);
+
+	return true;
+}
+
+
+static int32_t wlan_crypto_wpa_cipher_to_suite(uint32_t cipher)
+{
+	int32_t status = -1;
+
+	switch (cipher) {
+	case WLAN_CRYPTO_CIPHER_TKIP:
+		return WPA_CIPHER_SUITE_TKIP;
+	case WLAN_CRYPTO_CIPHER_AES_CCM:
+		return WPA_CIPHER_SUITE_CCMP;
+	case WLAN_CRYPTO_CIPHER_NONE:
+		return WPA_CIPHER_SUITE_NONE;
+	}
+
+	return status;
+}
+
+static int32_t wlan_crypto_rsn_cipher_to_suite(uint32_t cipher)
+{
+	int32_t status = -1;
+
+	switch (cipher) {
+	case WLAN_CRYPTO_CIPHER_TKIP:
+		return RSN_CIPHER_SUITE_TKIP;
+	case WLAN_CRYPTO_CIPHER_AES_CCM:
+		return RSN_CIPHER_SUITE_CCMP;
+	case WLAN_CRYPTO_CIPHER_AES_CCM_256:
+		return RSN_CIPHER_SUITE_CCMP_256;
+	case WLAN_CRYPTO_CIPHER_AES_GCM:
+		return RSN_CIPHER_SUITE_GCMP;
+	case WLAN_CRYPTO_CIPHER_AES_GCM_256:
+		return RSN_CIPHER_SUITE_GCMP_256;
+	case WLAN_CRYPTO_CIPHER_AES_CMAC:
+		return RSN_CIPHER_SUITE_AES_CMAC;
+	case WLAN_CRYPTO_CIPHER_AES_CMAC_256:
+		return RSN_CIPHER_SUITE_BIP_CMAC_256;
+	case WLAN_CRYPTO_CIPHER_AES_GMAC:
+		return RSN_CIPHER_SUITE_BIP_GMAC_128;
+	case WLAN_CRYPTO_CIPHER_AES_GMAC_256:
+		return RSN_CIPHER_SUITE_BIP_GMAC_256;
+	case WLAN_CRYPTO_CIPHER_NONE:
+		return RSN_CIPHER_SUITE_NONE;
+	}
+
+	return status;
+}
+
+/*
+ * Convert an RSN key management/authentication algorithm
+ * to an internal code.
+ */
+static int32_t
+wlan_crypto_rsn_keymgmt_to_suite(uint32_t keymgmt)
+{
+	int32_t status = -1;
+
+	switch (keymgmt) {
+	case WLAN_CRYPTO_KEY_MGMT_NONE:
+		return RSN_AUTH_KEY_MGMT_NONE;
+	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X:
+		return RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
+	case WLAN_CRYPTO_KEY_MGMT_PSK:
+		return RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
+	case WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X:
+		return RSN_AUTH_KEY_MGMT_FT_802_1X;
+	case WLAN_CRYPTO_KEY_MGMT_FT_PSK:
+		return RSN_AUTH_KEY_MGMT_FT_PSK;
+	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256:
+		return RSN_AUTH_KEY_MGMT_802_1X_SHA256;
+	case WLAN_CRYPTO_KEY_MGMT_PSK_SHA256:
+		return RSN_AUTH_KEY_MGMT_PSK_SHA256;
+	case WLAN_CRYPTO_KEY_MGMT_SAE:
+		return RSN_AUTH_KEY_MGMT_SAE;
+	case WLAN_CRYPTO_KEY_MGMT_FT_SAE:
+		return RSN_AUTH_KEY_MGMT_FT_SAE;
+	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B:
+		return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
+	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192:
+		return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
+	case WLAN_CRYPTO_KEY_MGMT_CCKM:
+		return RSN_AUTH_KEY_MGMT_CCKM;
+	case WLAN_CRYPTO_KEY_MGMT_OSEN:
+		return RSN_AUTH_KEY_MGMT_OSEN;
+	}
+
+	return status;
+}
+
+/*
+ * Convert an RSN key management/authentication algorithm
+ * to an internal code.
+ */
+static int32_t
+wlan_crypto_wpa_keymgmt_to_suite(uint32_t keymgmt)
+{
+	int32_t status = -1;
+
+	switch (keymgmt) {
+	case WLAN_CRYPTO_KEY_MGMT_NONE:
+		return WPA_AUTH_KEY_MGMT_NONE;
+	case WLAN_CRYPTO_KEY_MGMT_IEEE8021X:
+		return WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
+	case WLAN_CRYPTO_KEY_MGMT_PSK:
+		return WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X;
+	case WLAN_CRYPTO_KEY_MGMT_CCKM:
+		return WPA_AUTH_KEY_MGMT_CCKM;
+	}
+
+	return status;
+}
+/**
+ *
+ * Convert a WPA cipher selector OUI to an internal
+ * cipher algorithm.  Where appropriate we also
+ * record any key length.
+ */
+static int32_t wlan_crypto_wpa_suite_to_cipher(uint8_t *sel, uint8_t *keylen)
+{
+	uint32_t w = LE_READ_4(sel);
+	int32_t status = -1;
+
+	switch (w) {
+	case WPA_CIPHER_SUITE_TKIP:
+		return WLAN_CRYPTO_CIPHER_TKIP;
+	case WPA_CIPHER_SUITE_CCMP:
+		return WLAN_CRYPTO_CIPHER_AES_CCM;
+	case WPA_CIPHER_SUITE_NONE:
+		return WLAN_CRYPTO_CIPHER_NONE;
+	}
+
+	return status;
+}
+
+/*
+ * Convert a WPA key management/authentication algorithm
+ * to an internal code.
+ */
+static int32_t wlan_crypto_wpa_suite_to_keymgmt(uint8_t *sel)
+{
+	uint32_t w = LE_READ_4(sel);
+	int32_t status = -1;
+
+	switch (w) {
+	case WPA_AUTH_KEY_MGMT_UNSPEC_802_1X:
+		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X;
+	case WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X:
+		return WLAN_CRYPTO_KEY_MGMT_PSK;
+	case WPA_AUTH_KEY_MGMT_CCKM:
+		return WLAN_CRYPTO_KEY_MGMT_CCKM;
+	case WPA_AUTH_KEY_MGMT_NONE:
+		return WLAN_CRYPTO_KEY_MGMT_NONE;
+	}
+	return status;
+}
+
+/*
+ * Convert a RSN cipher selector OUI to an internal
+ * cipher algorithm.  Where appropriate we also
+ * record any key length.
+ */
+static int32_t wlan_crypto_rsn_suite_to_cipher(uint8_t *sel)
+{
+	uint32_t w = LE_READ_4(sel);
+	int32_t status = -1;
+
+	switch (w) {
+	case RSN_CIPHER_SUITE_TKIP:
+		return WLAN_CRYPTO_CIPHER_TKIP;
+	case RSN_CIPHER_SUITE_CCMP:
+		return WLAN_CRYPTO_CIPHER_AES_CCM;
+	case RSN_CIPHER_SUITE_CCMP_256:
+		return WLAN_CRYPTO_CIPHER_AES_CCM_256;
+	case RSN_CIPHER_SUITE_GCMP:
+		return WLAN_CRYPTO_CIPHER_AES_GCM;
+	case RSN_CIPHER_SUITE_GCMP_256:
+		return WLAN_CRYPTO_CIPHER_AES_GCM_256;
+	case RSN_CIPHER_SUITE_AES_CMAC:
+		return WLAN_CRYPTO_CIPHER_AES_CMAC;
+	case RSN_CIPHER_SUITE_BIP_CMAC_256:
+		return WLAN_CRYPTO_CIPHER_AES_CMAC_256;
+	case RSN_CIPHER_SUITE_BIP_GMAC_128:
+		return WLAN_CRYPTO_CIPHER_AES_GMAC;
+	case RSN_CIPHER_SUITE_BIP_GMAC_256:
+		return WLAN_CRYPTO_CIPHER_AES_GMAC_256;
+	case RSN_CIPHER_SUITE_NONE:
+		return WLAN_CRYPTO_CIPHER_NONE;
+	}
+
+	return status;
+}
+/*
+ * Convert an RSN key management/authentication algorithm
+ * to an internal code.
+ */
+static int32_t wlan_crypto_rsn_suite_to_keymgmt(uint8_t *sel)
+{
+	uint32_t w = LE_READ_4(sel);
+	int32_t status = -1;
+
+	switch (w) {
+	case RSN_AUTH_KEY_MGMT_UNSPEC_802_1X:
+		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X;
+	case RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X:
+		return WLAN_CRYPTO_KEY_MGMT_PSK;
+	case RSN_AUTH_KEY_MGMT_FT_802_1X:
+		return WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X;
+	case RSN_AUTH_KEY_MGMT_FT_PSK:
+		return WLAN_CRYPTO_KEY_MGMT_FT_PSK;
+	case RSN_AUTH_KEY_MGMT_802_1X_SHA256:
+		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256;
+	case RSN_AUTH_KEY_MGMT_PSK_SHA256:
+		return WLAN_CRYPTO_KEY_MGMT_PSK_SHA256;
+	case RSN_AUTH_KEY_MGMT_SAE:
+		return WLAN_CRYPTO_KEY_MGMT_SAE;
+	case RSN_AUTH_KEY_MGMT_FT_SAE:
+		return WLAN_CRYPTO_KEY_MGMT_FT_SAE;
+	case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B:
+		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B;
+	case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192:
+		return WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192;
+	case RSN_AUTH_KEY_MGMT_CCKM:
+		return WLAN_CRYPTO_KEY_MGMT_CCKM;
+	case RSN_AUTH_KEY_MGMT_OSEN:
+		return WLAN_CRYPTO_KEY_MGMT_OSEN;
+	}
+
+	return status;
+}
+
+/**
+ * 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 *crypto_params,
+					uint8_t *frm){
+	uint8_t len = frm[1];
+	int32_t w;
+	int n;
+	uint8_t cipher_length;
+	/*
+	 * Check the length once for fixed parts: OUI, type,
+	 * version, mcast cipher, and 2 selector counts.
+	 * Other, variable-length data, must be checked separately.
+	 */
+	RESET_AUTHMODE(crypto_params);
+	SET_AUTHMODE(crypto_params, WLAN_CRYPTO_AUTH_WPA);
+
+	if (len < 14)
+		return QDF_STATUS_E_INVAL;
+
+	frm += 6, len -= 4;	 /* NB: len is payload only */
+	/* NB: iswapoui already validated the OUI and type */
+	w = LE_READ_2(frm);
+	if (w != WPA_VERSION)
+		return QDF_STATUS_E_INVAL;
+
+	frm += 2, len -= 2;
+
+	/* multicast/group cipher */
+	RESET_MCAST_CIPHERS(crypto_params);
+	w = wlan_crypto_wpa_suite_to_cipher(frm, &cipher_length);
+	if (w < 0)
+		return QDF_STATUS_E_INVAL;
+	SET_MCAST_CIPHER(crypto_params, w);
+	frm += 4, len -= 4;
+
+	/* unicast ciphers */
+	n = LE_READ_2(frm);
+	frm += 2, len -= 2;
+	if (len < n*4+2)
+		return QDF_STATUS_E_INVAL;
+
+	RESET_UCAST_CIPHERS(crypto_params);
+	for (; n > 0; n--) {
+		w = wlan_crypto_wpa_suite_to_cipher(frm, &cipher_length);
+		if (w < 0)
+			return QDF_STATUS_E_INVAL;
+		SET_UCAST_CIPHER(crypto_params, w);
+		frm += 4, len -= 4;
+	}
+
+	if (!crypto_params->ucastcipherset)
+		return QDF_STATUS_E_INVAL;
+
+	/* key management algorithms */
+	n = LE_READ_2(frm);
+	frm += 2, len -= 2;
+	if (len < n*4)
+		return QDF_STATUS_E_INVAL;
+
+	w = 0;
+	RESET_KEY_MGMT(crypto_params);
+	for (; n > 0; n--) {
+		w = wlan_crypto_wpa_suite_to_keymgmt(frm);
+		if (w < 0)
+			return QDF_STATUS_E_INVAL;
+		SET_KEY_MGMT(crypto_params, w);
+		frm += 4, len -= 4;
+	}
+
+	/* optional capabilities */
+	if (len >= 2) {
+		crypto_params->rsn_caps = LE_READ_2(frm);
+		frm += 2, len -= 2;
+	}
+
+	return 0;
+}
+
+/**
+ * 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 wpa is
+ * matching with given crypto params
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS wlan_crypto_rsnie_check(struct wlan_crypto_params *crypto_params,
+					uint8_t *frm){
+	uint8_t len = frm[1];
+	int32_t w;
+	int n;
+	uint8_t cipher_length;
+	/*
+	 * Check the length once for fixed parts: OUI, type,
+	 * version, mcast cipher, and 2 selector counts.
+	 * Other, variable-length data, must be checked separately.
+	 */
+	RESET_AUTHMODE(crypto_params);
+	SET_AUTHMODE(crypto_params, WLAN_CRYPTO_AUTH_RSNA);
+
+	if (len < 14)
+		return QDF_STATUS_E_INVAL;
+
+	frm += 6, len -= 4;
+	/* NB: iswapoui already validated the OUI and type */
+	w = LE_READ_2(frm);
+	if (w != RSN_VERSION)
+		return QDF_STATUS_E_INVAL;
+
+	frm += 2, len -= 2;
+
+	/* multicast/group cipher */
+	RESET_MCAST_CIPHERS(crypto_params);
+	w = wlan_crypto_rsn_suite_to_cipher(frm);
+	if (w < 0)
+		return QDF_STATUS_E_INVAL;
+	SET_MCAST_CIPHER(crypto_params, w);
+	frm += 4, len -= 4;
+
+	/* unicast ciphers */
+	n = LE_READ_2(frm);
+	frm += 2, len -= 2;
+	if (len < n*4+2)
+		return QDF_STATUS_E_INVAL;
+
+	RESET_UCAST_CIPHERS(crypto_params);
+	for (; n > 0; n--) {
+		SET_UCAST_CIPHER(crypto_params,
+				wlan_crypto_rsn_suite_to_cipher(frm));
+		w = wlan_crypto_wpa_suite_to_cipher(frm, &cipher_length);
+		if (w < 0)
+			return QDF_STATUS_E_INVAL;
+		frm += 4, len -= 4;
+	}
+
+	if (crypto_params->ucastcipherset == 0)
+		return QDF_STATUS_E_INVAL;
+
+	/* key management algorithms */
+	n = LE_READ_2(frm);
+	frm += 2, len -= 2;
+	if (len < n*4)
+		return QDF_STATUS_E_INVAL;
+	w = 0;
+
+	RESET_KEY_MGMT(crypto_params);
+	for (; n > 0; n--) {
+		w = wlan_crypto_rsn_suite_to_keymgmt(frm);
+		if (w < 0)
+			return QDF_STATUS_E_INVAL;
+		SET_KEY_MGMT(crypto_params, w);
+		frm += 4, len -= 4;
+	}
+
+	/* optional capabilities */
+	if (len >= 2) {
+		crypto_params->rsn_caps = LE_READ_2(frm);
+		frm += 2, len -= 2;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * 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 *crypto_params,
+				uint8_t *iebuf){
+	uint8_t *frm = iebuf;
+	uint8_t *selcnt;
+	uint32_t mcastcipher;
+
+	*frm++ = IEEE80211_ELEMID_VENDOR;
+	*frm++ = 0;
+	WLAN_CRYPTO_ADDSELECTOR(frm, WPA_TYPE_OUI);
+	WLAN_CRYPTO_ADDSHORT(frm, WPA_VERSION);
+
+
+	/* multicast cipher */
+	mcastcipher = wlan_crypto_get_mcastcipher(crypto_params);
+	WLAN_CRYPTO_ADDSELECTOR(frm,
+				wlan_crypto_wpa_cipher_to_suite(mcastcipher));
+
+	/* unicast cipher list */
+	selcnt = frm;
+	WLAN_CRYPTO_ADDSHORT(frm, 0);
+	/* do not use CCMP unicast cipher in WPA mode */
+	if (UCIPHER_IS_TKIP(crypto_params)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			 wlan_crypto_wpa_cipher_to_suite(
+						WLAN_CRYPTO_CIPHER_TKIP));
+	}
+	if (UCIPHER_IS_CCMP128(crypto_params)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			wlan_crypto_wpa_cipher_to_suite(
+						WLAN_CRYPTO_CIPHER_AES_CCM));
+	}
+	if (UCIPHER_IS_CLEAR(crypto_params)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			wlan_crypto_wpa_cipher_to_suite(
+						WLAN_CRYPTO_CIPHER_AES_CCM));
+	}
+
+	/* authenticator selector list */
+	selcnt = frm;
+	WLAN_CRYPTO_ADDSHORT(frm, 0);
+
+	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_IEEE8021X)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			wlan_crypto_wpa_keymgmt_to_suite(
+					WLAN_CRYPTO_KEY_MGMT_IEEE8021X));
+	} else if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_PSK)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			wlan_crypto_wpa_keymgmt_to_suite(
+						WLAN_CRYPTO_KEY_MGMT_PSK));
+	} else if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_CCKM)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			wlan_crypto_wpa_keymgmt_to_suite(
+						WLAN_CRYPTO_KEY_MGMT_CCKM));
+	} else {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			wlan_crypto_wpa_keymgmt_to_suite(
+						WLAN_CRYPTO_KEY_MGMT_NONE));
+	}
+
+	/* calculate element length */
+	iebuf[1] = frm - iebuf - 2;
+
+	return frm;
+}
+
+/**
+ * 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 *crypto_params,
+				uint8_t *iebuf){
+	uint8_t *frm = iebuf;
+	uint8_t *selcnt;
+	uint32_t mcastcipher;
+
+	*frm++ = IEEE80211_ELEMID_RSN;
+	*frm++ = 0;
+	WLAN_CRYPTO_ADDSHORT(frm, RSN_VERSION);
+
+
+	/* multicast cipher */
+	mcastcipher = wlan_crypto_get_mcastcipher(crypto_params);
+	WLAN_CRYPTO_ADDSELECTOR(frm,
+				wlan_crypto_rsn_cipher_to_suite(mcastcipher));
+
+	/* unicast cipher list */
+	selcnt = frm;
+	WLAN_CRYPTO_ADDSHORT(frm, 0);
+	/* do not use CCMP unicast cipher in WPA mode */
+	if (UCIPHER_IS_TKIP(crypto_params)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			 wlan_crypto_rsn_cipher_to_suite(
+						WLAN_CRYPTO_CIPHER_TKIP));
+	}
+	if (UCIPHER_IS_CCMP128(crypto_params)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			wlan_crypto_rsn_cipher_to_suite(
+						WLAN_CRYPTO_CIPHER_AES_CCM));
+	}
+	if (UCIPHER_IS_CCMP256(crypto_params)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			wlan_crypto_rsn_cipher_to_suite(
+					WLAN_CRYPTO_CIPHER_AES_CCM_256));
+	}
+
+	if (UCIPHER_IS_GCMP128(crypto_params)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			 wlan_crypto_rsn_cipher_to_suite(
+					WLAN_CRYPTO_CIPHER_AES_GCM));
+	}
+	if (UCIPHER_IS_GCMP256(crypto_params)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			wlan_crypto_rsn_cipher_to_suite(
+					WLAN_CRYPTO_CIPHER_AES_GCM_256));
+	}
+	if (UCIPHER_IS_CLEAR(crypto_params)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			wlan_crypto_rsn_cipher_to_suite(
+					WLAN_CRYPTO_CIPHER_AES_CCM));
+	}
+
+
+	/* authenticator selector list */
+	selcnt = frm;
+	WLAN_CRYPTO_ADDSHORT(frm, 0);
+	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_CCKM)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+			wlan_crypto_rsn_keymgmt_to_suite(
+					WLAN_CRYPTO_KEY_MGMT_CCKM));
+	} else {
+		if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_PSK)) {
+			selcnt[0]++;
+			WLAN_CRYPTO_ADDSELECTOR(frm,
+				wlan_crypto_rsn_keymgmt_to_suite(
+					WLAN_CRYPTO_KEY_MGMT_PSK));
+		}
+		if (HAS_KEY_MGMT(crypto_params,
+					WLAN_CRYPTO_KEY_MGMT_IEEE8021X)) {
+			selcnt[0]++;
+			WLAN_CRYPTO_ADDSELECTOR(frm,
+				wlan_crypto_rsn_keymgmt_to_suite(
+					WLAN_CRYPTO_KEY_MGMT_IEEE8021X));
+		}
+		if (HAS_KEY_MGMT(crypto_params,
+					WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X)) {
+			selcnt[0]++;
+			WLAN_CRYPTO_ADDSELECTOR(frm,
+				wlan_crypto_rsn_keymgmt_to_suite(
+					WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X));
+		}
+		if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_FT_PSK)) {
+			selcnt[0]++;
+			WLAN_CRYPTO_ADDSELECTOR(frm,
+				wlan_crypto_rsn_keymgmt_to_suite(
+					WLAN_CRYPTO_KEY_MGMT_FT_PSK));
+		}
+		if (HAS_KEY_MGMT(crypto_params,
+				WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256)) {
+			selcnt[0]++;
+			WLAN_CRYPTO_ADDSELECTOR(frm,
+				wlan_crypto_rsn_keymgmt_to_suite(
+					WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SHA256));
+		}
+		if (HAS_KEY_MGMT(crypto_params,
+					WLAN_CRYPTO_KEY_MGMT_PSK_SHA256)) {
+			selcnt[0]++;
+			WLAN_CRYPTO_ADDSELECTOR(frm,
+				wlan_crypto_rsn_keymgmt_to_suite(
+					WLAN_CRYPTO_KEY_MGMT_PSK_SHA256));
+		}
+		if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_OSEN)) {
+			selcnt[0]++;
+			WLAN_CRYPTO_ADDSELECTOR(frm,
+				wlan_crypto_rsn_keymgmt_to_suite(
+					WLAN_CRYPTO_KEY_MGMT_OSEN));
+		}
+	}
+
+	/* optional capabilities */
+	if (crypto_params->rsn_caps != 0 &&
+		crypto_params->rsn_caps != WLAN_CRYPTO_RSN_CAP_PREAUTH){
+
+		WLAN_CRYPTO_ADDSHORT(frm, crypto_params->rsn_caps);
+
+		if (HAS_MGMT_CIPHER(crypto_params,
+						WLAN_CRYPTO_CIPHER_AES_CMAC)) {
+			selcnt[0]++;
+			WLAN_CRYPTO_ADDSELECTOR(frm,
+				 wlan_crypto_rsn_cipher_to_suite(
+						WLAN_CRYPTO_CIPHER_AES_CMAC));
+		}
+		if (HAS_MGMT_CIPHER(crypto_params,
+						WLAN_CRYPTO_CIPHER_AES_GMAC)) {
+			selcnt[0]++;
+			WLAN_CRYPTO_ADDSELECTOR(frm,
+				 wlan_crypto_rsn_cipher_to_suite(
+						WLAN_CRYPTO_CIPHER_AES_GMAC));
+		}
+		if (HAS_MGMT_CIPHER(crypto_params,
+					 WLAN_CRYPTO_CIPHER_AES_CMAC_256)) {
+			selcnt[0]++;
+			WLAN_CRYPTO_ADDSELECTOR(frm,
+				 wlan_crypto_rsn_cipher_to_suite(
+					WLAN_CRYPTO_CIPHER_AES_CMAC_256));
+		}
+
+		if (HAS_MGMT_CIPHER(crypto_params,
+					WLAN_CRYPTO_CIPHER_AES_GMAC_256)) {
+			selcnt[0]++;
+			WLAN_CRYPTO_ADDSELECTOR(frm,
+				 wlan_crypto_rsn_cipher_to_suite(
+					WLAN_CRYPTO_CIPHER_AES_GMAC_256));
+		}
+	}
+	/* calculate element length */
+	iebuf[1] = frm - iebuf - 2;
+
+	return frm;
+}
+bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev,
+				struct wlan_crypto_params *crypto_params){
+	struct wlan_crypto_params *my_crypto_params;
+	my_crypto_params = wlan_crypto_vdev_get_crypto_params(vdev);
+
+	/*
+	 * Check peer's pairwise ciphers.
+	 * At least one must match with our unicast cipher
+	 */
+	if (!UCAST_CIPHER_MATCH(crypto_params, my_crypto_params))
+		return false;
+	/*
+	 * Check peer's group cipher is our enabled multicast cipher.
+	 */
+	if (!MCAST_CIPHER_MATCH(crypto_params, my_crypto_params))
+		return false;
+	/*
+	 * Check peer's key management class set (PSK or UNSPEC)
+	 */
+	if (!KEY_MGMTSET_MATCH(crypto_params, my_crypto_params))
+		return false;
+
+	return true;
+}
+
+/**
+ * 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){
+	/* Need to check is there real requirement for this function
+	 * as PN check is already handled in decap function.
+	 */
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * 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){
+	struct wlan_crypto_comp_priv *crypto_priv;
+
+	return wlan_crypto_vdev_get_comp_params(vdev, &crypto_priv);
+}
+
+/**
+ * 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){
+	struct wlan_crypto_comp_priv *crypto_priv;
+
+	return wlan_crypto_peer_get_comp_params(peer, &crypto_priv);
+}
+
+
+QDF_STATUS wlan_crypto_set_peer_wep_keys(struct wlan_objmgr_vdev *vdev,
+						uint8_t *mac_addr){
+	uint8_t keymac[IEEE80211_ADDR_LEN];
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+	struct wlan_crypto_key *key;
+	struct wlan_crypto_key *tmp_key;
+	struct wlan_crypto_cipher *cipher_table;
+	struct wlan_objmgr_psoc *psoc;
+	int i;
+	enum tQDF_ADAPTER_MODE opmode;
+
+	if (!vdev)
+		return QDF_STATUS_E_NULL_VALUE;
+	wlan_vdev_obj_lock(vdev);
+	psoc = wlan_vdev_get_psoc(vdev);
+	wlan_vdev_obj_unlock(vdev);
+
+	if (!psoc)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
+							&crypto_priv);
+	if (crypto_priv == NULL) {
+		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	/* push only valid static WEP keys from vap */
+	if (AUTH_IS_8021X(crypto_params))
+		return QDF_STATUS_E_INVAL;
+
+	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac_addr))
+		return QDF_STATUS_E_INVAL;
+
+	tmp_key = (struct wlan_crypto_key *)qdf_mem_malloc(
+					sizeof(struct wlan_crypto_key));
+
+	if (!tmp_key)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	opmode = wlan_vdev_mlme_get_opmode(vdev);
+
+	/* push only valid static WEP keys from vap */
+
+	for (i = 0; i < WLAN_CRYPTO_MAXKEYIDX; i++) {
+		if (crypto_priv->key[i]) {
+			key = crypto_priv->key[i];
+			if (!key || !key->valid)
+				continue;
+
+			cipher_table = (struct wlan_crypto_cipher *)
+							key->cipher_table;
+
+			if (cipher_table->cipher == WLAN_CRYPTO_CIPHER_WEP) {
+				qdf_mem_copy(tmp_key, key,
+						sizeof(struct wlan_crypto_key));
+				qdf_copy_macaddr((struct qdf_mac_addr *)keymac,
+					(struct qdf_mac_addr *)mac_addr);
+
+				/* setting the broadcast/multicast key for sta*/
+				if (opmode == QDF_STA_MODE ||
+						opmode == QDF_IBSS_MODE){
+					if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) {
+						WLAN_CRYPTO_TX_OPS_SETKEY(psoc)(
+							vdev, tmp_key, mac_addr,
+							cipher_table->cipher);
+					}
+				}
+
+				/* setting unicast key */
+				tmp_key->flags &= ~WLAN_CRYPTO_KEY_GROUP;
+				if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) {
+					WLAN_CRYPTO_TX_OPS_SETKEY(psoc)(vdev,
+						tmp_key, mac_addr,
+						cipher_table->cipher);
+				}
+			}
+		}
+	}
+	qdf_mem_free(tmp_key);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * 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){
+	crypto_rx_ops->crypto_encap      = wlan_crypto_encap;
+	crypto_rx_ops->crypto_decap      = wlan_crypto_decap;
+	crypto_rx_ops->crypto_enmic      = wlan_crypto_enmic;
+	crypto_rx_ops->crypto_demic      = wlan_crypto_demic;
+	crypto_rx_ops->set_peer_wep_keys = wlan_crypto_set_peer_wep_keys;
+
+	return QDF_STATUS_SUCCESS;
+}

+ 44 - 0
umac/cmn_services/crypto/src/wlan_crypto_main.c

@@ -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();
+}

+ 40 - 0
umac/cmn_services/crypto/src/wlan_crypto_main.h

@@ -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_ */

+ 40 - 0
umac/cmn_services/crypto/src/wlan_crypto_main_i.h

@@ -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_ */

+ 82 - 0
umac/cmn_services/crypto/src/wlan_crypto_none.c

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

+ 307 - 0
umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c

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

+ 48 - 0
umac/cmn_services/crypto/src/wlan_crypto_obj_mgr_i.h

@@ -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_*/

+ 310 - 0
umac/cmn_services/crypto/src/wlan_crypto_param_handling.c

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

+ 196 - 0
umac/cmn_services/crypto/src/wlan_crypto_param_handling_i.h

@@ -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_ */

+ 208 - 0
umac/cmn_services/crypto/src/wlan_crypto_tkip.c

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

+ 83 - 0
umac/cmn_services/crypto/src/wlan_crypto_wapi.c

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

+ 162 - 0
umac/cmn_services/crypto/src/wlan_crypto_wep.c

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