qcacmn: Add support for GMAC MIC calculation
Add changes to calculate MIC using aead calls in linux Change-Id: I710b1c748c36babc8e66aaf920a07f9657f6e273 CRs-Fixed: 2164910
This commit is contained in:

committed by
snandini

parent
b3c81ac057
commit
f5d592433f
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* any purpose with or without fee is hereby granted, provided that the
|
||||||
@@ -47,6 +47,9 @@ extern "C" {
|
|||||||
#define FIXED_PARAM_OFFSET_ASSOC_REQ 4
|
#define FIXED_PARAM_OFFSET_ASSOC_REQ 4
|
||||||
#define FIXED_PARAM_OFFSET_ASSOC_RSP 6
|
#define FIXED_PARAM_OFFSET_ASSOC_RSP 6
|
||||||
|
|
||||||
|
#define AAD_LEN 20
|
||||||
|
#define IEEE80211_MMIE_GMAC_MICLEN 16
|
||||||
|
|
||||||
#define IS_VALID_CTR_KEY_LEN(len) ((((len) == 16) || ((len) == 32) || \
|
#define IS_VALID_CTR_KEY_LEN(len) ((((len) == 16) || ((len) == 32) || \
|
||||||
((len) == 48)) ? 1 : 0)
|
((len) == 48)) ? 1 : 0)
|
||||||
|
|
||||||
@@ -136,6 +139,23 @@ int qdf_aes_s2v(const uint8_t *key, unsigned int key_len, const uint8_t *s[],
|
|||||||
*/
|
*/
|
||||||
int qdf_aes_ctr(const uint8_t *key, unsigned int key_len, uint8_t *siv,
|
int qdf_aes_ctr(const uint8_t *key, unsigned int key_len, uint8_t *siv,
|
||||||
const uint8_t *src, size_t src_len, uint8_t *dest, bool enc);
|
const uint8_t *src, size_t src_len, uint8_t *dest, bool enc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qdf_crypto_aes_gmac: This API calculates MIC for GMAC
|
||||||
|
* @key: key used for operation
|
||||||
|
* @key_length: key length
|
||||||
|
* @iv: Initialization vector
|
||||||
|
* @aad: Additional authentication data
|
||||||
|
* @data: Pointer to data
|
||||||
|
* @data_len: Length of data
|
||||||
|
* @mic: Pointer to MIC
|
||||||
|
*
|
||||||
|
* Return: 0 if success else Error number
|
||||||
|
*/
|
||||||
|
int qdf_crypto_aes_gmac(uint8_t *key, uint16_t key_length,
|
||||||
|
uint8_t *iv, uint8_t *aad, uint8_t *data,
|
||||||
|
uint16_t data_len, uint8_t *mic);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* any purpose with or without fee is hereby granted, provided that the
|
||||||
@@ -28,6 +28,8 @@
|
|||||||
#include <crypto/hash.h>
|
#include <crypto/hash.h>
|
||||||
#include <crypto/aes.h>
|
#include <crypto/aes.h>
|
||||||
#include <crypto/skcipher.h>
|
#include <crypto/skcipher.h>
|
||||||
|
#include <crypto/aead.h>
|
||||||
|
#include <linux/ieee80211.h>
|
||||||
|
|
||||||
/* Function Definitions and Documentation */
|
/* Function Definitions and Documentation */
|
||||||
#define MAX_HMAC_ELEMENT_CNT 10
|
#define MAX_HMAC_ELEMENT_CNT 10
|
||||||
@@ -352,3 +354,84 @@ int qdf_aes_ctr(const uint8_t *key, unsigned int key_len, uint8_t *siv,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||||
|
int qdf_crypto_aes_gmac(uint8_t *key, uint16_t key_length,
|
||||||
|
uint8_t *iv, uint8_t *aad, uint8_t *data,
|
||||||
|
uint16_t data_len, uint8_t *mic)
|
||||||
|
{
|
||||||
|
struct crypto_aead *tfm;
|
||||||
|
int ret = 0;
|
||||||
|
struct scatterlist sg[4];
|
||||||
|
uint16_t req_size;
|
||||||
|
struct aead_request *req = NULL;
|
||||||
|
uint8_t *aad_ptr, *input;
|
||||||
|
|
||||||
|
tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
|
||||||
|
if (IS_ERR(tfm)) {
|
||||||
|
ret = PTR_ERR(tfm);
|
||||||
|
tfm = NULL;
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
|
||||||
|
"%s: crypto_alloc_aead failed (%d)", __func__, ret);
|
||||||
|
goto err_tfm;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = crypto_aead_setkey(tfm, key, key_length);
|
||||||
|
if (ret) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
|
||||||
|
"crypto_aead_setkey failed (%d)", ret);
|
||||||
|
goto err_tfm;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = crypto_aead_setauthsize(tfm, IEEE80211_MMIE_GMAC_MICLEN);
|
||||||
|
if (ret) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
|
||||||
|
"crypto_aead_setauthsize failed (%d)", ret);
|
||||||
|
goto err_tfm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare aead request */
|
||||||
|
req_size = sizeof(*req) + crypto_aead_reqsize(tfm) +
|
||||||
|
IEEE80211_MMIE_GMAC_MICLEN + AAD_LEN;
|
||||||
|
req = qdf_mem_malloc(req_size);
|
||||||
|
if (!req) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
|
||||||
|
"Memory allocation failed");
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_tfm;
|
||||||
|
}
|
||||||
|
|
||||||
|
input = (uint8_t *)req + sizeof(*req) + crypto_aead_reqsize(tfm);
|
||||||
|
aad_ptr = input + IEEE80211_MMIE_GMAC_MICLEN;
|
||||||
|
qdf_mem_copy(aad_ptr, aad, AAD_LEN);
|
||||||
|
|
||||||
|
/* Scatter list operations */
|
||||||
|
sg_init_table(sg, 4);
|
||||||
|
sg_set_buf(&sg[0], aad_ptr, AAD_LEN);
|
||||||
|
sg_set_buf(&sg[1], data, data_len);
|
||||||
|
sg_set_buf(&sg[2], input, IEEE80211_MMIE_GMAC_MICLEN);
|
||||||
|
sg_set_buf(&sg[3], mic, IEEE80211_MMIE_GMAC_MICLEN);
|
||||||
|
|
||||||
|
aead_request_set_tfm(req, tfm);
|
||||||
|
aead_request_set_crypt(req, sg, sg, 0, iv);
|
||||||
|
aead_request_set_ad(req,
|
||||||
|
AAD_LEN + data_len + IEEE80211_MMIE_GMAC_MICLEN);
|
||||||
|
crypto_aead_encrypt(req);
|
||||||
|
|
||||||
|
err_tfm:
|
||||||
|
if (tfm)
|
||||||
|
crypto_free_aead(tfm);
|
||||||
|
|
||||||
|
if (req)
|
||||||
|
qdf_mem_free(req);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int qdf_crypto_aes_gmac(uint8_t *key, uint16_t key_length,
|
||||||
|
uint8_t *iv, uint8_t *aad, uint8_t *data,
|
||||||
|
uint16_t data_len, uint8_t *mic)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Reference in New Issue
Block a user