/*
 * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * 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.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */



/*============================================================================
  FILE:         vos_utils.c

  OVERVIEW:     This source file contains definitions for vOS crypto APIs
                The four APIs mentioned in this file are used for
                initializing, and de-initializing a crypto context, and
                obtaining truly random data (for keys), as well as
                SHA1 HMAC, and AES encrypt and decrypt routines.

                The routines include:
                vos_crypto_init() - Initializes Crypto module
                vos_crypto_deinit() - De-initializes Crypto module
                vos_rand_get_bytes() - Generates random byte
                vos_sha1_hmac_str() - Generate the HMAC-SHA1 of a string given a key
                vos_encrypt_AES() - Generate AES Encrypted byte stream
                vos_decrypt_AES() - Decrypts an AES Encrypted byte stream

  DEPENDENCIES:
============================================================================*/

/*============================================================================
  EDIT HISTORY FOR MODULE

============================================================================*/

/*----------------------------------------------------------------------------
 * Include Files
 * -------------------------------------------------------------------------*/

#include "vos_trace.h"
#include "vos_utils.h"
#include "vos_memory.h"

#include <linux/err.h>
#include <linux/random.h>
#if(LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0))
#include <crypto/skcipher.h>
#else
#include <linux/crypto.h>
#endif
#include <linux/scatterlist.h>
#include <linux/completion.h>
#include <linux/ieee80211.h>
#include <crypto/hash.h>
#include <crypto/aes.h>
#include <wcnss_api.h>
#ifdef CONFIG_CNSS
#include <linux/qcomwlan_secif.h>
#endif
#include <errno.h>

#include "ieee80211_common.h"
/*----------------------------------------------------------------------------
 * Preprocessor Definitions and Constants
 * -------------------------------------------------------------------------*/
#define AAD_LEN 20
#define IV_SIZE_AES_128 16
#define CMAC_IPN_LEN 6


/*----------------------------------------------------------------------------
 * Type Declarations
 * -------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
 * Global Data Definitions
 * -------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
 * Static Variable Definitions
 * -------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
   Function Definitions and Documentation
 * -------------------------------------------------------------------------*/
#ifndef CONFIG_CNSS
#if defined(WLAN_FEATURE_11W) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
#define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */

static inline void xor_128(const u8 *a, const u8 *b, u8 *out)
{
        u8 i;

        for (i = 0; i < AES_BLOCK_SIZE; i++)
                out[i] = a[i] ^ b[i];
}

static inline void leftshift_onebit(const u8 *input, u8 *output)
{
        int i, overflow = 0;

        for (i = (AES_BLOCK_SIZE - 1); i >= 0; i--) {
                output[i] = input[i] << 1;
                output[i] |= overflow;
                overflow = (input[i] & 0x80) ? 1 : 0;
        }
        return;
}

static void generate_subkey(struct crypto_cipher *tfm, u8 *k1, u8 *k2)
{
        u8 l[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE];
        u8 const_rb[AES_BLOCK_SIZE] = {
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};
        u8 const_zero[AES_BLOCK_SIZE] = {
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

        crypto_cipher_encrypt_one(tfm, l, const_zero);

        if ((l[0] & 0x80) == 0) { /* If MSB(l) = 0, then k1 = l << 1 */
                leftshift_onebit(l, k1);
        } else {    /* Else k1 = ( l << 1 ) (+) Rb */
                leftshift_onebit(l, tmp);
                xor_128(tmp, const_rb, k1);
        }

        if ((k1[0] & 0x80) == 0) {
                leftshift_onebit(k1, k2);
        } else {
                leftshift_onebit(k1, tmp);
                xor_128(tmp, const_rb, k2);
        }
}

static inline void padding(u8 *lastb, u8 *pad, u16 length)
{
        u8 j;

        /* original last block */
        for (j = 0; j < AES_BLOCK_SIZE; j++)  {
                if (j < length)
                        pad[j] = lastb[j];
                else if (j == length)
                        pad[j] = 0x80;
                else
                        pad[j] = 0x00;
        }
}

void cmac_calc_mic(struct crypto_cipher *tfm, u8 *m,
                                u16 length, u8 *mac)
{
        u8 x[AES_BLOCK_SIZE], y[AES_BLOCK_SIZE];
        u8 m_last[AES_BLOCK_SIZE], padded[AES_BLOCK_SIZE];
        u8 k1[AES_KEYSIZE_128], k2[AES_KEYSIZE_128];
        int cmpBlk;
        int i, nBlocks = (length + 15)/AES_BLOCK_SIZE;

        generate_subkey(tfm, k1, k2);

        if (nBlocks == 0) {
                nBlocks = 1;
                cmpBlk = 0;
        } else {
                cmpBlk = ((length % AES_BLOCK_SIZE) == 0) ? 1 : 0;
        }

        if (cmpBlk) { /* Last block is complete block */
                xor_128(&m[AES_BLOCK_SIZE * (nBlocks - 1)], k1, m_last);
        } else { /* Last block is not complete block */
                padding(&m[AES_BLOCK_SIZE * (nBlocks - 1)], padded,
                        length % AES_BLOCK_SIZE);
                xor_128(padded, k2, m_last);
        }

        for (i = 0; i < AES_BLOCK_SIZE; i++)
                x[i] = 0;

        for (i = 0; i < (nBlocks - 1); i++) {
                xor_128(x, &m[AES_BLOCK_SIZE * i], y); /* y = Mi (+) x */
                crypto_cipher_encrypt_one(tfm, x, y); /* x = AES-128(KEY, y) */
        }

        xor_128(x, m_last, y);
        crypto_cipher_encrypt_one(tfm, x, y);

        vos_mem_copy(mac, x, CMAC_TLEN);
}
#endif
#endif

/*--------------------------------------------------------------------------

  \brief vos_crypto_init() - Initializes Crypto module

  The vos_crypto_init() function initializes Crypto module.

  \param phCryptProv - pointer to the Crypt handle

  \return VOS_STATUS_SUCCESS - Successfully generated random memory.

          VOS_STATUS_E_FAULT  - pbBuf is an invalid pointer.

          VOS_STATUS_E_FAILURE - default return value if it fails due to
          unknown reasons

       ***VOS_STATUS_E_RESOURCES - System resources (other than memory)
          are unavailable
  \sa

    ( *** return value not considered yet )
  --------------------------------------------------------------------------*/
VOS_STATUS vos_crypto_init( v_U32_t *phCryptProv )
{
    VOS_STATUS uResult = VOS_STATUS_E_FAILURE;

    // This implementation doesn't require a crypto context
    *phCryptProv  = 0;
    uResult = VOS_STATUS_SUCCESS;
    return ( uResult );
}

VOS_STATUS vos_crypto_deinit( v_U32_t hCryptProv )
{
    VOS_STATUS uResult = VOS_STATUS_E_FAILURE;

    // CryptReleaseContext succeeded
    uResult = VOS_STATUS_SUCCESS;

    return ( uResult );
}

/*--------------------------------------------------------------------------

  \brief vos_rand_get_bytes() - Generates random byte

  The vos_rand_get_bytes() function generate random bytes.

  Buffer should be allocated before calling vos_rand_get_bytes().

  Attempting to initialize an already initialized lock results in
  a failure.

  \param lock - pointer to the opaque lock object to initialize

  \return VOS_STATUS_SUCCESS - Successfully generated random memory.

          VOS_STATUS_E_FAULT  - pbBuf is an invalid pointer.

          VOS_STATUS_E_FAILURE - default return value if it fails due to
          unknown reasons

       ***VOS_STATUS_E_RESOURCES - System resources (other than memory)
          are unavailable
  \sa

    ( *** return value not considered yet )
  --------------------------------------------------------------------------*/
VOS_STATUS vos_rand_get_bytes( v_U32_t cryptHandle, v_U8_t *pbBuf, v_U32_t numBytes )
{
   VOS_STATUS uResult = VOS_STATUS_E_FAILURE;

   //check for invalid pointer
   if ( NULL == pbBuf )
   {
      uResult = VOS_STATUS_E_FAULT;
      return ( uResult );
   }

   get_random_bytes( pbBuf, numBytes);
   // "Random sequence generated."
   uResult = VOS_STATUS_SUCCESS;
   return ( uResult );
}


#ifdef WLAN_FEATURE_11W
v_U8_t vos_get_mmie_size()
{
    return sizeof(struct ieee80211_mmie);
}

/*--------------------------------------------------------------------------

  \brief vos_increase_seq() - Increase the IPN aka Sequence number by one unit

  The vos_increase_seq() function increases the IPN by one unit.

  \param ipn - pointer to the IPN aka Sequence number [6 bytes]

  --------------------------------------------------------------------------*/
static void
vos_increase_seq(v_U8_t *ipn)
{
     v_U64_t value = 0;
     if (ipn)
     {
         value = (0xffffffffffff)& (*((v_U64_t *)ipn));
         value = value + 1;
         vos_mem_copy(ipn, &value, IEEE80211_MMIE_IPNLEN);
     }
}

/*--------------------------------------------------------------------------

  \brief vos_attach_mmie() - attches the complete MMIE at the end of frame

  The vos_attach_mmie() calculates the entire MMIE and attaches at the end
  of Broadcast/Multicast robust management frames.

  \param igtk - pointer  group key which will be used to calculate
                the 8 byte MIC.
  \param ipn - pointer ipn, it is also known as sequence number
  \param key_id - key identication number
  \param frm - pointer to the start of the frame.
  \param efrm - pointer to the end of the frame.
  \param frmLen - size of the entire frame.

  \return - this function will return VOS_TRUE on success and VOS_FALSE on
            failure.

  --------------------------------------------------------------------------*/

v_BOOL_t
vos_attach_mmie(v_U8_t *igtk, v_U8_t *ipn, u_int16_t key_id,
                v_U8_t* frm, v_U8_t* efrm, u_int16_t frmLen)
{
    struct ieee80211_mmie  *mmie;
    struct ieee80211_frame *wh;
    v_U8_t aad[AAD_LEN], mic[CMAC_TLEN], *input = NULL;
    v_U8_t previous_ipn[IEEE80211_MMIE_IPNLEN] = {0};
    v_U16_t nBytes = 0;
    int ret = 0;
    struct crypto_cipher *tfm;

    /*  This is how received frame look like
     *
     *        <------------frmLen---------------------------->
     *
     *        +---------------+----------------------+-------+
     *        | 802.11 HEADER | Management framebody | MMIE  |
     *        +---------------+----------------------+-------+
     *                                                       ^
     *                                                       |
     *                                                      efrm
     *   This is how MMIE from above frame look like
     *
     *
     *        <------------ 18 Bytes----------------------------->
     *        +--------+---------+---------+-----------+---------+
     *        |Element | Length  | Key id  |   IPN     |  MIC    |
     *        |  id    |         |         |           |         |
     *        +--------+---------+---------+-----------+---------+
     * Octet     1         1         2         6            8
     *
     */

    /* Check if frame is invalid length */
    if (((efrm - frm) != frmLen) || (frmLen < sizeof(*wh)))
    {
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                  "%s: Invalid frame length", __func__);
        return VOS_FALSE;
    }
    mmie = (struct ieee80211_mmie *)(efrm - sizeof(*mmie));

    /* Copy Element id */
    mmie->element_id = IEEE80211_ELEMID_MMIE;

    /* Copy Length */
    mmie->length = sizeof(*mmie)-2;

    /* Copy Key id */
    mmie->key_id = key_id;

    /*
     * In case of error, revert back to original IPN
     * to do that copy the original IPN into previous_ipn
     */
    vos_mem_copy(&previous_ipn[0], ipn, IEEE80211_MMIE_IPNLEN);
    vos_increase_seq(ipn);
    vos_mem_copy(mmie->sequence_number, ipn, IEEE80211_MMIE_IPNLEN);

    /*
     * Calculate MIC and then copy
     */
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    tfm = crypto_alloc_cipher( "aes", 0, CRYPTO_ALG_ASYNC);
#else
    tfm = wcnss_wlan_crypto_alloc_cipher( "aes", 0, CRYPTO_ALG_ASYNC);
#endif
    if (IS_ERR(tfm))
    {
        ret = PTR_ERR(tfm);
        tfm = NULL;
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,
             "%s: crypto_alloc_cipher failed (%d)", __func__, ret);
        goto err_tfm;
    }

    ret = crypto_cipher_setkey(tfm, igtk, AES_KEYSIZE_128);
    if (ret) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,
             "%s: crypto_cipher_setkey failed (%d)", __func__, ret);
        goto err_tfm;
    }

    /* 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 */
    vos_mem_copy(aad + 2, wh->i_addr_all, 3 * IEEE80211_ADDR_LEN);

    /* MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) */
    nBytes = AAD_LEN + (frmLen - sizeof(struct ieee80211_frame));
    input = (v_U8_t *)vos_mem_malloc(nBytes);
    if (NULL == input)
    {
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                  "%s: Memory allocation failed", __func__);
        ret = VOS_STATUS_E_NOMEM;
        goto err_tfm;
    }

    /*
     * Copy the AAD, Management frame body, and
     * MMIE with 8 bit MIC zeroed out
     */
    vos_mem_zero(input, nBytes);
    vos_mem_copy(input, aad, AAD_LEN);
    /* Copy Management Frame Body and MMIE without MIC*/
    vos_mem_copy(input+AAD_LEN,
                (v_U8_t*)(efrm-(frmLen-sizeof(struct ieee80211_frame))),
                nBytes - AAD_LEN - CMAC_TLEN);

#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    cmac_calc_mic(tfm, input, nBytes, mic);
#else
    wcnss_wlan_cmac_calc_mic(tfm, input, nBytes, mic);
#endif
    vos_mem_free(input);

    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
            "CMAC(T)= %02X %02X %02X %02X %02X %02X %02X %02X",
            mic[0], mic[1], mic[2], mic[3],
            mic[4], mic[5], mic[6], mic[7]);
    vos_mem_copy(mmie->mic, mic, IEEE80211_MMIE_MICLEN);


err_tfm:
    if (ret)
    {
       vos_mem_copy(ipn, previous_ipn, IEEE80211_MMIE_IPNLEN);
    }

    if (tfm)
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
       crypto_free_cipher(tfm);
#else
       wcnss_wlan_crypto_free_cipher(tfm);
#endif
    return !ret?VOS_TRUE:VOS_FALSE;
}

v_BOOL_t vos_is_mmie_valid(v_U8_t *igtk, v_U8_t *ipn,
                           v_U8_t* frm, v_U8_t* efrm)
{
    struct ieee80211_mmie  *mmie;
    struct ieee80211_frame *wh;
    v_U8_t *rx_ipn, aad[AAD_LEN], mic[CMAC_TLEN], *input;
    v_U16_t nBytes = 0;
    int ret = 0;
    struct crypto_cipher *tfm;

    /* Check if frame is invalid length */
    if ((efrm < frm) || ((efrm - frm) < sizeof(*wh))) {
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                "Invalid frame length");
        return VOS_FALSE;
    }

    mmie = (struct ieee80211_mmie *)(efrm - sizeof(*mmie));

    /* Check Element ID */
    if ((mmie->element_id != IEEE80211_ELEMID_MMIE) ||
        (mmie->length != (sizeof(*mmie)-2))) {
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                "IE is not Mgmt MIC IE or Invalid length");
        /* IE is not Mgmt MIC IE or invalid length */
        return VOS_FALSE;
    }

    /* Validate IPN */
    rx_ipn = mmie->sequence_number;
    if (OS_MEMCMP(rx_ipn, ipn, CMAC_IPN_LEN) <= 0)
    {
        /* Replay error */
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
            "Replay error mmie ipn %02X %02X %02X %02X %02X %02X"
            " drvr ipn %02X %02X %02X %02X %02X %02X",
            rx_ipn[0], rx_ipn[1], rx_ipn[2], rx_ipn[3], rx_ipn[4], rx_ipn[5],
            ipn[0], ipn[1], ipn[2], ipn[3], ipn[4], ipn[5]);
        return VOS_FALSE;
    }

#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    tfm = crypto_alloc_cipher( "aes", 0, CRYPTO_ALG_ASYNC);
#else
    tfm = wcnss_wlan_crypto_alloc_cipher( "aes", 0, CRYPTO_ALG_ASYNC);
#endif
    if (IS_ERR(tfm)) {
        ret = PTR_ERR(tfm);
        tfm = NULL;
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,
             "crypto_alloc_cipher failed (%d)", ret);
        goto err_tfm;
    }

    ret = crypto_cipher_setkey(tfm, igtk, AES_KEYSIZE_128);
    if (ret) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,
             "crypto_cipher_setkey failed (%d)", ret);
        goto err_tfm;
    }

    /* 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 */
    vos_mem_copy(aad + 2, wh->i_addr_all, 3 * IEEE80211_ADDR_LEN);

    /* MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) */
    nBytes = AAD_LEN + (efrm - (v_U8_t*)(wh+1));
    input = (v_U8_t *)vos_mem_malloc(nBytes);
    if (NULL == input)
    {
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
             "Memory allocation failed");
        ret = VOS_STATUS_E_NOMEM;
        goto err_tfm;
    }

    /* Copy the AAD, MMIE with 8 bit MIC zeroed out */
    vos_mem_zero(input, nBytes);
    vos_mem_copy(input, aad, AAD_LEN);
    vos_mem_copy(input+AAD_LEN, (v_U8_t*)(wh+1), nBytes - AAD_LEN - CMAC_TLEN);

#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    cmac_calc_mic(tfm, input, nBytes, mic);
#else
    wcnss_wlan_cmac_calc_mic(tfm, input, nBytes, mic);
#endif
    vos_mem_free(input);

    VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
            "CMAC(T)= %02X %02X %02X %02X %02X %02X %02X %02X",
            mic[0], mic[1], mic[2], mic[3],
            mic[4], mic[5], mic[6], mic[7]);

    if (OS_MEMCMP(mic, mmie->mic, CMAC_TLEN) != 0) {
        /* MMIE MIC mismatch */
        VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
                "BC/MC MGMT frame MMIE MIC check Failed"
                " rmic %02X %02X %02X %02X %02X %02X %02X %02X"
                " cmic %02X %02X %02X %02X %02X %02X %02X %02X",
                mmie->mic[0], mmie->mic[1], mmie->mic[2], mmie->mic[3],
                mmie->mic[4], mmie->mic[5], mmie->mic[6], mmie->mic[7],
                mic[0], mic[1], mic[2], mic[3],
                mic[4], mic[5], mic[6], mic[7]);
        return VOS_FALSE;
    }

    /* Update IPN */
    vos_mem_copy(ipn, rx_ipn, CMAC_IPN_LEN);

err_tfm:
    if (tfm)
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
        crypto_free_cipher(tfm);
#else
        wcnss_wlan_crypto_free_cipher(tfm);
#endif

    return !ret?VOS_TRUE:VOS_FALSE;
}

#endif /* WLAN_FEATURE_11W */
/**
 * vos_sha1_hmac_str
 *
 * FUNCTION:
 * Generate the HMAC-SHA1 of a string given a key.
 *
 * LOGIC:
 * Standard HMAC processing from RFC 2104. The code is provided in the
 * appendix of the RFC.
 *
 * ASSUMPTIONS:
 * The RFC is correct.
 *
 * @param text text to be hashed
 * @param textLen length of text
 * @param key key to use for HMAC
 * @param keyLen length of key
 * @param digest holds resultant SHA1 HMAC (20B)
 *
 * @return VOS_STATUS_SUCCSS if the operation succeeds
 *
 */

struct hmac_sha1_result {
    struct completion completion;
    int err;
};

static void hmac_sha1_complete(struct crypto_async_request *req, int err)
{
    struct hmac_sha1_result *r = req->data;
    if (err == -EINPROGRESS)
        return;
    r->err = err;
    complete(&r->completion);
}

int hmac_sha1(v_U8_t *key, v_U8_t ksize, char *plaintext, v_U8_t psize,
              v_U8_t *output, v_U8_t outlen)
{
    int ret = 0;
    struct crypto_ahash *tfm;
    struct scatterlist sg;
    struct ahash_request *req;
    struct hmac_sha1_result tresult;
    void *hash_buff = NULL;

    unsigned char hash_result[64];
    int i;

    memset(output, 0, outlen);

    init_completion(&tresult.completion);

#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    tfm = crypto_alloc_ahash("hmac(sha1)", CRYPTO_ALG_TYPE_AHASH,
                                        CRYPTO_ALG_TYPE_AHASH_MASK);
#else
    tfm = wcnss_wlan_crypto_alloc_ahash("hmac(sha1)", CRYPTO_ALG_TYPE_AHASH,
                                        CRYPTO_ALG_TYPE_AHASH_MASK);
#endif
    if (IS_ERR(tfm)) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_ahash failed");
        ret = PTR_ERR(tfm);
        goto err_tfm;
    }

    req = ahash_request_alloc(tfm, GFP_KERNEL);
    if (!req) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "failed to allocate request for hmac(sha1)");
        ret = -ENOMEM;
        goto err_req;
    }

    ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                               hmac_sha1_complete, &tresult);

    hash_buff = kzalloc(psize, GFP_KERNEL);
    if (!hash_buff) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "failed to kzalloc hash_buff");
        ret = -ENOMEM;
        goto err_hash_buf;
    }

    memset(hash_result, 0, 64);
    vos_mem_copy(hash_buff, plaintext, psize);
    sg_init_one(&sg, hash_buff, psize);

    if (ksize) {
        crypto_ahash_clear_flags(tfm, ~0);
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
        ret = crypto_ahash_setkey(tfm, key, ksize);
#else
        ret = wcnss_wlan_crypto_ahash_setkey(tfm, key, ksize);
#endif

        if (ret) {
            VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_ahash_setkey failed");
            goto err_setkey;
        }
    }

    ahash_request_set_crypt(req, &sg, hash_result, psize);
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    ret = crypto_ahash_digest(req);
#else
    ret = wcnss_wlan_crypto_ahash_digest(req);
#endif
    VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "ret 0x%x", ret);

    switch (ret) {
    case 0:
        for (i=0; i< outlen; i++)
            output[i] = hash_result[i];
        break;
    case -EINPROGRESS:
    case -EBUSY:
        ret = wait_for_completion_interruptible(&tresult.completion);
        if (!ret && !tresult.err) {
            for (i = 0; i < outlen; i++)
               output[i] = hash_result[i];
            INIT_COMPLETION(tresult.completion);
            break;
        } else {
            VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "wait_for_completion_interruptible failed");
            if (!ret)
                ret = tresult.err;
            goto out;
        }
    default:
        goto out;
    }

out:
err_setkey:
    kfree(hash_buff);
err_hash_buf:
    ahash_request_free(req);
err_req:
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    crypto_free_ahash(tfm);
#else
    wcnss_wlan_crypto_free_ahash(tfm);
#endif
err_tfm:
    return ret;
}

VOS_STATUS vos_sha1_hmac_str(v_U32_t cryptHandle, /* Handle */
           v_U8_t *pText, /* pointer to data stream */
           v_U32_t textLen, /* length of data stream */
           v_U8_t *pKey, /* pointer to authentication key */
           v_U32_t keyLen, /* length of authentication key */
           v_U8_t digest[VOS_DIGEST_SHA1_SIZE])/* caller digest to be filled in */
{
    int ret = 0;

    ret = hmac_sha1(
            pKey,                   //v_U8_t *key,
            (v_U8_t) keyLen,        //v_U8_t ksize,
            (char *)pText,          //char *plaintext,
            (v_U8_t) textLen,       //v_U8_t psize,
            digest,                 //v_U8_t *output,
            VOS_DIGEST_SHA1_SIZE    //v_U8_t outlen
            );

    if (ret != 0) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"hmac_sha1() call failed");
        return VOS_STATUS_E_FAULT;
    }

    return VOS_STATUS_SUCCESS;
}

/**
 * vos_md5_hmac_str
 *
 * FUNCTION:
 * Generate the HMAC-MD5 of a string given a key.
 *
 * LOGIC:
 * Standard HMAC processing from RFC 2104. The code is provided in the
 * appendix of the RFC.
 *
 * ASSUMPTIONS:
 * The RFC is correct.
 *
 * @param text text to be hashed
 * @param textLen length of text
 * @param key key to use for HMAC
 * @param keyLen length of key
 * @param digest holds resultant MD5 HMAC (20B)
 *
 * @return VOS_STATUS_SUCCSS if the operation succeeds
 *
 */
struct hmac_md5_result {
    struct completion completion;
    int err;
};

static void hmac_md5_complete(struct crypto_async_request *req, int err)
{
    struct hmac_md5_result *r = req->data;
    if (err == -EINPROGRESS)
            return;
    r->err = err;
    complete(&r->completion);
}

int hmac_md5(v_U8_t *key, v_U8_t ksize, char *plaintext, v_U8_t psize,
                v_U8_t *output, v_U8_t outlen)
{
    int ret = 0;
    struct crypto_ahash *tfm;
    struct scatterlist sg;
    struct ahash_request *req;
    struct hmac_md5_result tresult = {.err = 0};
    void *hash_buff = NULL;

    unsigned char hash_result[64];
    int i;

    memset(output, 0, outlen);

    init_completion(&tresult.completion);

#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    tfm = crypto_alloc_ahash("hmac(md5)", CRYPTO_ALG_TYPE_AHASH,
                                        CRYPTO_ALG_TYPE_AHASH_MASK);
#else
    tfm = wcnss_wlan_crypto_alloc_ahash("hmac(md5)", CRYPTO_ALG_TYPE_AHASH,
                                        CRYPTO_ALG_TYPE_AHASH_MASK);
#endif
    if (IS_ERR(tfm)) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_ahash failed");
                ret = PTR_ERR(tfm);
                goto err_tfm;
    }

    req = ahash_request_alloc(tfm, GFP_KERNEL);
    if (!req) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "failed to allocate request for hmac(md5)");
        ret = -ENOMEM;
        goto err_req;
    }

    ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                                        hmac_md5_complete, &tresult);

    hash_buff = kzalloc(psize, GFP_KERNEL);
    if (!hash_buff) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "failed to kzalloc hash_buff");
        ret = -ENOMEM;
        goto err_hash_buf;
    }

    memset(hash_result, 0, 64);
    vos_mem_copy(hash_buff, plaintext, psize);
    sg_init_one(&sg, hash_buff, psize);

    if (ksize) {
        crypto_ahash_clear_flags(tfm, ~0);
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
        ret = crypto_ahash_setkey(tfm, key, ksize);
#else
        ret = wcnss_wlan_crypto_ahash_setkey(tfm, key, ksize);
#endif
        if (ret) {
            VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_ahash_setkey failed");
            goto err_setkey;
        }
    }

    ahash_request_set_crypt(req, &sg, hash_result, psize);
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    ret = crypto_ahash_digest(req);
#else
    ret = wcnss_wlan_crypto_ahash_digest(req);
#endif

    VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "ret 0x%x", ret);

    switch (ret) {
        case 0:
            for (i=0; i< outlen; i++)
                    output[i] = hash_result[i];
            break;
        case -EINPROGRESS:
        case -EBUSY:
             ret = wait_for_completion_interruptible(&tresult.completion);
             if (!ret && !tresult.err) {
                 for (i = 0; i < outlen; i++)
                    output[i] = hash_result[i];
                  INIT_COMPLETION(tresult.completion);
                  break;
             } else {
                 VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "wait_for_completion_interruptible failed");
                 if (!ret)
                     ret = tresult.err;
                 goto out;
             }
        default:
              goto out;
        }

out:
err_setkey:
        kfree(hash_buff);
err_hash_buf:
        ahash_request_free(req);
err_req:
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
        crypto_free_ahash(tfm);
#else
        wcnss_wlan_crypto_free_ahash(tfm);
#endif
err_tfm:
        return ret;
}

VOS_STATUS vos_md5_hmac_str(v_U32_t cryptHandle, /* Handle */
           v_U8_t *pText, /* pointer to data stream */
           v_U32_t textLen, /* length of data stream */
           v_U8_t *pKey, /* pointer to authentication key */
           v_U32_t keyLen, /* length of authentication key */
           v_U8_t digest[VOS_DIGEST_MD5_SIZE])/* caller digest to be filled in */
{
    int ret = 0;

    ret = hmac_md5(
            pKey,                   //v_U8_t *key,
            (v_U8_t) keyLen,        //v_U8_t ksize,
            (char *)pText,          //char *plaintext,
            (v_U8_t) textLen,       //v_U8_t psize,
            digest,                 //v_U8_t *output,
            VOS_DIGEST_MD5_SIZE     //v_U8_t outlen
            );

    if (ret != 0) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"hmac_md5() call failed");
        return VOS_STATUS_E_FAULT;
    }

    return VOS_STATUS_SUCCESS;
}


struct ecb_aes_result {
    struct completion completion;
    int err;
};

static void ecb_aes_complete(struct crypto_async_request *req, int err)
{
    struct ecb_aes_result *r = req->data;
    if (err == -EINPROGRESS)
        return;
    r->err = err;
    complete(&r->completion);
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0))
/*--------------------------------------------------------------------------

  \brief vos_encrypt_AES() - Generate AES Encrypted byte stream

  The vos_encrypt_AES() function generates the encrypted byte stream for given text.

  Buffer should be allocated before calling vos_rand_get_bytes().

  Attempting to initialize an already initialized lock results in
  a failure.

  \param lock - pointer to the opaque lock object to initialize

  \return VOS_STATUS_SUCCESS - Successfully generated random memory.

          VOS_STATUS_E_FAULT  - pbBuf is an invalid pointer.

          VOS_STATUS_E_FAILURE - default return value if it fails due to
          unknown reasons

       ***VOS_STATUS_E_RESOURCES - System resources (other than memory)
          are unavailable
  \sa

    ( *** return value not considered yet )
  --------------------------------------------------------------------------*/
VOS_STATUS vos_encrypt_AES(v_U32_t cryptHandle, /* Handle */
                           v_U8_t *pPlainText, /* pointer to data stream */
                           v_U8_t *pCiphertext,
                           v_U8_t *pKey) /* pointer to authentication key */
{
    struct ecb_aes_result result;
    struct crypto_skcipher *tfm;
    struct skcipher_request *req;
    int ret = 0;
    char iv[IV_SIZE_AES_128];
    struct scatterlist sg_in;
    struct scatterlist sg_out;

    init_completion(&result.completion);

#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    tfm =  crypto_alloc_skcipher( "cbc(aes)", 0, 0);
#else
    tfm =  wcnss_wlan_crypto_alloc_ablkcipher( "cbc(aes)", 0, 0);
#endif
    if (IS_ERR(tfm)) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_skcipher failed");
        ret = PTR_ERR(tfm);
        goto err_tfm;
    }

    req = skcipher_request_alloc(tfm, GFP_KERNEL);
    if (!req) {
        VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "Failed to allocate request for cbc(aes)");
        ret = -ENOMEM;
        goto err_req;
    }

    skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                                    ecb_aes_complete, &result);


    crypto_skcipher_clear_flags(tfm, ~0);

    ret = crypto_skcipher_setkey(tfm, pKey, AES_KEYSIZE_128);
    if (ret) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_skcipher_setkey failed");
        goto err_setkey;
    }

    memset(iv, 0, IV_SIZE_AES_128);

    sg_init_one(&sg_in, pPlainText, AES_BLOCK_SIZE);

    sg_init_one(&sg_out, pCiphertext, AES_BLOCK_SIZE);

    skcipher_request_set_crypt(req, &sg_in, &sg_out, AES_BLOCK_SIZE, iv);

    ret = crypto_skcipher_encrypt(req);
    if (ret == -EINPROGRESS || ret == -EBUSY) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_skcipher_encrypt failed ret %d", ret);
        wait_for_completion(&result.completion);
        ret = result.err;
    }


// -------------------------------------
err_setkey:
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    skcipher_request_free(req);
#else
    wcnss_wlan_ablkcipher_request_free(req);
#endif
err_req:
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    crypto_free_skcipher(tfm);
#else
    wcnss_wlan_crypto_free_ablkcipher(tfm);
#endif
err_tfm:
    //return ret;
    if (ret != 0) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"%s() call failed", __func__);
        return VOS_STATUS_E_FAULT;
   }

    return VOS_STATUS_SUCCESS;
}
#else //(LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0))
VOS_STATUS vos_encrypt_AES(v_U32_t cryptHandle, /* Handle */
                           v_U8_t *pPlainText, /* pointer to data stream */
                           v_U8_t *pCiphertext,
                           v_U8_t *pKey) /* pointer to authentication key */
{
    struct ecb_aes_result result;
    struct ablkcipher_request *req;
    struct crypto_ablkcipher *tfm;
    int ret = 0;
    char iv[IV_SIZE_AES_128];
    struct scatterlist sg_in;
    struct scatterlist sg_out;

    init_completion(&result.completion);

#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    tfm =  crypto_alloc_ablkcipher( "cbc(aes)", 0, 0);
#else
    tfm =  wcnss_wlan_crypto_alloc_ablkcipher( "cbc(aes)", 0, 0);
#endif
    if (IS_ERR(tfm)) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_ablkcipher failed");
        ret = PTR_ERR(tfm);
        goto err_tfm;
    }

    req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
    if (!req) {
        VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "Failed to allocate request for cbc(aes)");
        ret = -ENOMEM;
        goto err_req;
    }

    ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                                    ecb_aes_complete, &result);


    crypto_ablkcipher_clear_flags(tfm, ~0);

    ret = crypto_ablkcipher_setkey(tfm, pKey, AES_KEYSIZE_128);
    if (ret) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_cipher_setkey failed");
        goto err_setkey;
    }

    memset(iv, 0, IV_SIZE_AES_128);

    sg_init_one(&sg_in, pPlainText, AES_BLOCK_SIZE);

    sg_init_one(&sg_out, pCiphertext, AES_BLOCK_SIZE);

    ablkcipher_request_set_crypt(req, &sg_in, &sg_out, AES_BLOCK_SIZE, iv);

    crypto_ablkcipher_encrypt(req);



// -------------------------------------
err_setkey:
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    ablkcipher_request_free(req);
#else
    wcnss_wlan_ablkcipher_request_free(req);
#endif
err_req:
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    crypto_free_ablkcipher(tfm);
#else
    wcnss_wlan_crypto_free_ablkcipher(tfm);
#endif
err_tfm:
    //return ret;
    if (ret != 0) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"%s() call failed", __func__);
        return VOS_STATUS_E_FAULT;
   }

    return VOS_STATUS_SUCCESS;
}
#endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0))

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0))
/*--------------------------------------------------------------------------

  \brief vos_decrypt_AES() - Decrypts an AES Encrypted byte stream

  The vos_decrypt_AES() function decrypts the encrypted byte stream.

  Buffer should be allocated before calling vos_rand_get_bytes().

  Attempting to initialize an already initialized lock results in
  a failure.

  \param lock - pointer to the opaque lock object to initialize

  \return VOS_STATUS_SUCCESS - Successfully generated random memory.

          VOS_STATUS_E_FAULT  - pbBuf is an invalid pointer.

          VOS_STATUS_E_FAILURE - default return value if it fails due to
          unknown reasons

       ***VOS_STATUS_E_RESOURCES - System resources (other than memory)
          are unavailable
  \sa

    ( *** return value not considered yet )
  --------------------------------------------------------------------------*/
VOS_STATUS vos_decrypt_AES(v_U32_t cryptHandle, /* Handle */
                           v_U8_t *pText, /* pointer to data stream */
                           v_U8_t *pDecrypted,
                           v_U8_t *pKey) /* pointer to authentication key */
{
//    VOS_STATUS uResult = VOS_STATUS_E_FAILURE;
    struct ecb_aes_result result;
    struct skcipher_request *req;
    struct crypto_skcipher *tfm;
    int ret = 0;
    char iv[IV_SIZE_AES_128];
    struct scatterlist sg_in;
    struct scatterlist sg_out;

    init_completion(&result.completion);

#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    tfm =  crypto_alloc_skcipher( "cbc(aes)", 0, 0);
#else
    tfm =  wcnss_wlan_crypto_alloc_ablkcipher( "cbc(aes)", 0, 0);
#endif
    if (IS_ERR(tfm)) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_skcipher failed");
        ret = PTR_ERR(tfm);
        goto err_tfm;
    }

    req = skcipher_request_alloc(tfm, GFP_KERNEL);
    if (!req) {
        VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "Failed to allocate request for cbc(aes)");
        ret = -ENOMEM;
        goto err_req;
    }

    skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                                    ecb_aes_complete, &result);


    crypto_skcipher_clear_flags(tfm, ~0);

    ret = crypto_skcipher_setkey(tfm, pKey, AES_KEYSIZE_128);
    if (ret) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_cipher_setkey failed");
        goto err_setkey;
       }

    memset(iv, 0, IV_SIZE_AES_128);

    sg_init_one(&sg_in, pText, AES_BLOCK_SIZE);

    sg_init_one(&sg_out, pDecrypted, AES_BLOCK_SIZE);

    skcipher_request_set_crypt(req, &sg_in, &sg_out, AES_BLOCK_SIZE, iv);

    ret = crypto_skcipher_decrypt(req);
    skcipher_request_zero(req);
    if (ret) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"AES: failed to decrypt received packet");
    }


// -------------------------------------
err_setkey:
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    skcipher_request_free(req);
#else
    wcnss_wlan_ablkcipher_request_free(req);
#endif
err_req:
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    crypto_free_skcipher(tfm);
#else
    wcnss_wlan_crypto_free_ablkcipher(tfm);
#endif
err_tfm:
    //return ret;
    if (ret != 0) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"%s() call failed", __func__);
        return VOS_STATUS_E_FAULT;
      }

    return VOS_STATUS_SUCCESS;
}
#else //LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0)
VOS_STATUS vos_decrypt_AES(v_U32_t cryptHandle, /* Handle */
                           v_U8_t *pText, /* pointer to data stream */
                           v_U8_t *pDecrypted,
                           v_U8_t *pKey) /* pointer to authentication key */
{
//    VOS_STATUS uResult = VOS_STATUS_E_FAILURE;
    struct ecb_aes_result result;
    struct ablkcipher_request *req;
    struct crypto_ablkcipher *tfm;
    int ret = 0;
    char iv[IV_SIZE_AES_128];
    struct scatterlist sg_in;
    struct scatterlist sg_out;

    init_completion(&result.completion);

#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    tfm =  crypto_alloc_ablkcipher( "cbc(aes)", 0, 0);
#else
    tfm =  wcnss_wlan_crypto_alloc_ablkcipher( "cbc(aes)", 0, 0);
#endif
    if (IS_ERR(tfm)) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_ablkcipher failed");
        ret = PTR_ERR(tfm);
        goto err_tfm;
    }

    req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
    if (!req) {
        VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "Failed to allocate request for cbc(aes)");
        ret = -ENOMEM;
        goto err_req;
    }

    ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                                    ecb_aes_complete, &result);


    crypto_ablkcipher_clear_flags(tfm, ~0);

    ret = crypto_ablkcipher_setkey(tfm, pKey, AES_KEYSIZE_128);
    if (ret) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_cipher_setkey failed");
        goto err_setkey;
       }

    memset(iv, 0, IV_SIZE_AES_128);

    sg_init_one(&sg_in, pText, AES_BLOCK_SIZE);

    sg_init_one(&sg_out, pDecrypted, AES_BLOCK_SIZE);

    ablkcipher_request_set_crypt(req, &sg_in, &sg_out, AES_BLOCK_SIZE, iv);

    crypto_ablkcipher_decrypt(req);



// -------------------------------------
err_setkey:
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    ablkcipher_request_free(req);
#else
    wcnss_wlan_ablkcipher_request_free(req);
#endif
err_req:
#if  !defined(CONFIG_CNSS) && (defined(HIF_USB) || defined(HIF_SDIO) || defined(CONFIG_NON_QC_PLATFORM_PCI))
    crypto_free_ablkcipher(tfm);
#else
    wcnss_wlan_crypto_free_ablkcipher(tfm);
#endif
err_tfm:
    //return ret;
    if (ret != 0) {
        VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"%s() call failed", __func__);
        return VOS_STATUS_E_FAULT;
      }

    return VOS_STATUS_SUCCESS;
}
#endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0))

v_U32_t vos_chan_to_freq(v_U8_t chan)
{
    if (chan < VOS_24_GHZ_CHANNEL_14)       // ch 0 - ch 13
        return VOS_24_GHZ_BASE_FREQ + chan * VOS_CHAN_SPACING_5MHZ;
    else if (chan == VOS_24_GHZ_CHANNEL_14) // ch 14
        return VOS_CHAN_14_FREQ;
    else if (chan < VOS_24_GHZ_CHANNEL_27)  // ch 15 - ch 26
        return VOS_CHAN_15_FREQ +
               (chan - VOS_24_GHZ_CHANNEL_15) * VOS_CHAN_SPACING_20MHZ;
    else if (chan == VOS_5_GHZ_CHANNEL_170)
        return VOS_CHAN_170_FREQ;
     else
        return VOS_5_GHZ_BASE_FREQ + chan * VOS_CHAN_SPACING_5MHZ;
}

v_U8_t vos_freq_to_chan(v_U32_t freq)
{
    v_U8_t chan;

    if (freq > VOS_24_GHZ_BASE_FREQ && freq < VOS_CHAN_14_FREQ)
        chan = ((freq - VOS_24_GHZ_BASE_FREQ)/VOS_CHAN_SPACING_5MHZ);
    else if (freq == VOS_CHAN_14_FREQ)
        chan = VOS_24_GHZ_CHANNEL_14;
    else if ((freq > VOS_24_GHZ_BASE_FREQ) && (freq < VOS_5_GHZ_BASE_FREQ))
        chan = (((freq - VOS_CHAN_15_FREQ)/VOS_CHAN_SPACING_20MHZ) +
                VOS_24_GHZ_CHANNEL_15);
    else
        chan = (freq - VOS_5_GHZ_BASE_FREQ)/VOS_CHAN_SPACING_5MHZ;
    return chan;
}


v_U8_t vos_chan_to_band(v_U32_t chan)
{
    if (chan <= VOS_24_GHZ_CHANNEL_14)
        return VOS_BAND_2GHZ;

    return VOS_BAND_5GHZ;
}

#ifdef FEATURE_WLAN_DIAG_SUPPORT
/**
 * vos_tdls_tx_rx_mgmt_event()- send tdls mgmt rx tx event
 * @event_id: event id
 * @tx_rx: tx or rx
 * @type: type of frame
 * @action_sub_type: action frame type
 * @peer_mac: peer mac
 *
 * This Function sends tdls mgmt rx tx diag event
 *
 * Return: void.
 */
void vos_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx,
		uint8_t type, uint8_t action_sub_type, uint8_t *peer_mac)
{
	WLAN_VOS_DIAG_EVENT_DEF(tdls_tx_rx_mgmt,
		struct vos_event_tdls_tx_rx_mgmt);
	vos_mem_zero(&tdls_tx_rx_mgmt, sizeof(tdls_tx_rx_mgmt));

	tdls_tx_rx_mgmt.event_id = event_id;
	tdls_tx_rx_mgmt.tx_rx = tx_rx;
	tdls_tx_rx_mgmt.type = type;
	tdls_tx_rx_mgmt.action_sub_type = action_sub_type;
	vos_mem_copy(tdls_tx_rx_mgmt.peer_mac,
			peer_mac, VOS_MAC_ADDR_SIZE);
	WLAN_VOS_DIAG_EVENT_REPORT(&tdls_tx_rx_mgmt,
				EVENT_WLAN_TDLS_TX_RX_MGMT);
}
#endif

/**
 * vos_rounddown_pow_of_two() - Round down to nearest power of two
 * @n: number to be tested
 *
 * Test if the input number is power of two, and return the nearest power of two
 *
 * Return: number rounded down to the nearest power of two
 */
unsigned long vos_rounddown_pow_of_two(unsigned long n)
{
	if (is_power_of_2(n))
		return n; /* already a power of 2 */

	return __rounddown_pow_of_two(n);
}

/**
 * vos_status_to_os_return(): translates vos_status types to linux return types
 * @status: status to translate
 *
 * Translates error types that linux may want to handle specially.
 *
 * return: 0 or the linux error code that most closely matches the VOS_STATUS.
 *      defaults to -1 (EPERM)
 */
int vos_status_to_os_return(VOS_STATUS status)
{
	switch (status) {
	case VOS_STATUS_SUCCESS:
		return 0;
	case VOS_STATUS_E_FAULT:
		return -EFAULT;
	case VOS_STATUS_E_TIMEOUT:
	case VOS_STATUS_E_BUSY:
		return -EBUSY;
	case VOS_STATUS_E_AGAIN:
		return -EAGAIN;
	case VOS_STATUS_E_NOSUPPORT:
		return -ENOSYS;
	case VOS_STATUS_E_ALREADY:
		return -EALREADY;
	case VOS_STATUS_E_NOMEM:
		return -ENOMEM;
	case VOS_STATUS_E_FAILURE:
	case VOS_STATUS_E_INVAL:
		return -EINVAL;
	default:
		VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
			  FL("Unhandled VOS_STATUS:%d"), status);
		return -EPERM;
	}
}
