qcacmn: Add FILS crypto API for rIK generation
Replace the lim_default_hmac_sha256_kdf() & lim_create_fils_rik() API with crypto API since both these API are primarily for cryptographic derivation of re-authentication integrity key(rIK) Use the new crypto APIs qdf_default_hmac_sha256_kdf(), wlan_crypto_create_fils_rik() for this. Change-Id: I1c8f38ee0124b8b3eb527d4b01d39add134e181b CRs-Fixed: 2752635
This commit is contained in:

committed by
snandini

parent
acc1ea0d14
commit
0df12365ac
@@ -54,6 +54,8 @@ extern "C" {
|
|||||||
#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)
|
||||||
|
|
||||||
|
#define WLAN_MAX_PRF_INTERATIONS_COUNT 255
|
||||||
|
|
||||||
/* Function declarations and documenation */
|
/* Function declarations and documenation */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,6 +89,34 @@ int qdf_get_hmac_hash(uint8_t *type, uint8_t *key,
|
|||||||
uint32_t keylen, uint8_t element_cnt,
|
uint32_t keylen, uint8_t element_cnt,
|
||||||
uint8_t *addr[], uint32_t *addr_len, int8_t *hash);
|
uint8_t *addr[], uint32_t *addr_len, int8_t *hash);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qdf_default_hmac_sha256_kdf()- This API calculates key data using default kdf
|
||||||
|
* defined in RFC4306.
|
||||||
|
* @secret: key which needs to be used in crypto
|
||||||
|
* @secret_len: key_len of secret
|
||||||
|
* @label: PRF label
|
||||||
|
* @optional_data: Data used for hash
|
||||||
|
* @optional_data_len: data length
|
||||||
|
* @key: key data output
|
||||||
|
* @keylen: key data length
|
||||||
|
*
|
||||||
|
* This API creates default KDF as defined in RFC4306
|
||||||
|
* PRF+ (K,S) = T1 | T2 | T3 | T4 | ...
|
||||||
|
* T1 = PRF (K, S | 0x01)
|
||||||
|
* T2 = PRF (K, T1 | S | 0x02)
|
||||||
|
* T3 = PRF (K, T2 | S | 0x03)
|
||||||
|
* T4 = PRF (K, T3 | S | 0x04)
|
||||||
|
*
|
||||||
|
* for every iteration its creates 32 bit of hash
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS
|
||||||
|
*/
|
||||||
|
QDF_STATUS
|
||||||
|
qdf_default_hmac_sha256_kdf(uint8_t *secret, uint32_t secret_len,
|
||||||
|
uint8_t *label, uint8_t *optional_data,
|
||||||
|
uint32_t optional_data_len, uint8_t *key,
|
||||||
|
uint32_t keylen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qdf_get_keyed_hash: API to get hash using specific crypto and
|
* qdf_get_keyed_hash: API to get hash using specific crypto and
|
||||||
* scatterlist elements.
|
* scatterlist elements.
|
||||||
|
@@ -78,6 +78,63 @@ int qdf_get_hmac_hash(uint8_t *type, uint8_t *key,
|
|||||||
src_len, element_cnt, hash);
|
src_len, element_cnt, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDF_STATUS
|
||||||
|
qdf_default_hmac_sha256_kdf(uint8_t *secret, uint32_t secret_len,
|
||||||
|
uint8_t *label, uint8_t *optional_data,
|
||||||
|
uint32_t optional_data_len, uint8_t *key,
|
||||||
|
uint32_t keylen)
|
||||||
|
{
|
||||||
|
uint8_t tmp_hash[SHA256_DIGEST_SIZE] = {0};
|
||||||
|
uint8_t count = 1;
|
||||||
|
uint8_t *addr[4];
|
||||||
|
uint32_t len[4];
|
||||||
|
uint32_t current_position = 0, remaining_data = SHA256_DIGEST_SIZE;
|
||||||
|
|
||||||
|
addr[0] = tmp_hash;
|
||||||
|
len[0] = SHA256_DIGEST_SIZE;
|
||||||
|
addr[1] = label;
|
||||||
|
len[1] = strlen(label) + 1;
|
||||||
|
addr[2] = optional_data;
|
||||||
|
len[2] = optional_data_len;
|
||||||
|
addr[3] = &count;
|
||||||
|
len[3] = 1;
|
||||||
|
|
||||||
|
if (keylen == 0 ||
|
||||||
|
(keylen > (WLAN_MAX_PRF_INTERATIONS_COUNT * SHA256_DIGEST_SIZE))) {
|
||||||
|
qdf_err("invalid key length %d", keylen);
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create T1 */
|
||||||
|
if (qdf_get_hmac_hash(HMAC_SHA256_CRYPTO_TYPE, secret, secret_len, 3,
|
||||||
|
&addr[1], &len[1], tmp_hash) < 0) {
|
||||||
|
qdf_err("failed to get hmac hash");
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update hash from tmp_hash */
|
||||||
|
qdf_mem_copy(key + current_position, tmp_hash, remaining_data);
|
||||||
|
current_position += remaining_data;
|
||||||
|
|
||||||
|
for (count = 2; current_position < keylen; count++) {
|
||||||
|
remaining_data = keylen - current_position;
|
||||||
|
if (remaining_data > SHA256_DIGEST_SIZE)
|
||||||
|
remaining_data = SHA256_DIGEST_SIZE;
|
||||||
|
|
||||||
|
/* Create T-n */
|
||||||
|
if (qdf_get_hmac_hash(HMAC_SHA256_CRYPTO_TYPE, secret,
|
||||||
|
secret_len, 4, addr, len, tmp_hash) < 0) {
|
||||||
|
qdf_err("failed to get hmac hash");
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
/* Update hash from tmp_hash */
|
||||||
|
qdf_mem_copy(key + current_position, tmp_hash, remaining_data);
|
||||||
|
current_position += remaining_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* qdf_update_dbl from RFC 5297. Length of d is AES_BLOCK_SIZE (128 bits) */
|
/* qdf_update_dbl from RFC 5297. Length of d is AES_BLOCK_SIZE (128 bits) */
|
||||||
void qdf_update_dbl(uint8_t *d)
|
void qdf_update_dbl(uint8_t *d)
|
||||||
{
|
{
|
||||||
|
@@ -981,4 +981,24 @@ void wlan_crypto_set_sae_single_pmk_bss_cap(struct wlan_objmgr_vdev *vdev,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_FILS_SK
|
||||||
|
/**
|
||||||
|
* lim_create_fils_rik()- This API create rik using rrk coming from
|
||||||
|
* supplicant.
|
||||||
|
* @rrk: input rrk
|
||||||
|
* @rrk_len: rrk length
|
||||||
|
* @rik: Created rik
|
||||||
|
* @rik_len: rik length to be filled
|
||||||
|
*
|
||||||
|
* rIK = KDF (K, S), where
|
||||||
|
* K = rRK and
|
||||||
|
* S = rIK Label + "\0" + cryptosuite + length
|
||||||
|
* The rIK Label is the 8-bit ASCII string:
|
||||||
|
* Re-authentication Integrity Key@ietf.org
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS
|
||||||
|
*/
|
||||||
|
QDF_STATUS wlan_crypto_create_fils_rik(uint8_t *rrk, uint8_t rrk_len,
|
||||||
|
uint8_t *rik, uint32_t *rik_len);
|
||||||
|
#endif /* WLAN_FEATURE_FILS_SK */
|
||||||
#endif /* end of _WLAN_CRYPTO_GLOBAL_API_H_ */
|
#endif /* end of _WLAN_CRYPTO_GLOBAL_API_H_ */
|
||||||
|
@@ -75,6 +75,10 @@
|
|||||||
#define WLAN_CRYPTO_WPI_SMS4_PADLEN (1)
|
#define WLAN_CRYPTO_WPI_SMS4_PADLEN (1)
|
||||||
#define WLAN_CRYPTO_WPI_SMS4_MICLEN (16)
|
#define WLAN_CRYPTO_WPI_SMS4_MICLEN (16)
|
||||||
|
|
||||||
|
/* FILS definitions */
|
||||||
|
#define WLAN_CRYPTO_FILS_OPTIONAL_DATA_LEN 3
|
||||||
|
#define WLAN_CRYPTO_FILS_RIK_LABEL "Re-authentication Integrity Key@ietf.org"
|
||||||
|
|
||||||
/* key used for xmit */
|
/* key used for xmit */
|
||||||
#define WLAN_CRYPTO_KEY_XMIT (0x01)
|
#define WLAN_CRYPTO_KEY_XMIT (0x01)
|
||||||
/* key used for recv */
|
/* key used for recv */
|
||||||
@@ -217,6 +221,21 @@ enum wlan_crypto_key_type {
|
|||||||
#define IS_WEP_CIPHER(_c) ((_c == WLAN_CRYPTO_CIPHER_WEP) || \
|
#define IS_WEP_CIPHER(_c) ((_c == WLAN_CRYPTO_CIPHER_WEP) || \
|
||||||
(_c == WLAN_CRYPTO_CIPHER_WEP_40) || \
|
(_c == WLAN_CRYPTO_CIPHER_WEP_40) || \
|
||||||
(_c == WLAN_CRYPTO_CIPHER_WEP_104))
|
(_c == WLAN_CRYPTO_CIPHER_WEP_104))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enum fils_erp_cryptosuite: this enum defines the cryptosuites used
|
||||||
|
* to calculate auth tag and auth tag length as defined by RFC 6696 5.3.1
|
||||||
|
* @HMAC_SHA256_64: sha256 with auth tag len as 64 bits
|
||||||
|
* @HMAC_SHA256_128: sha256 with auth tag len as 128 bits
|
||||||
|
* @HMAC_SHA256_256: sha256 with auth tag len as 256 bits
|
||||||
|
*/
|
||||||
|
enum fils_erp_cryptosuite {
|
||||||
|
INVALID_CRYPTO = 0, /* reserved */
|
||||||
|
HMAC_SHA256_64,
|
||||||
|
HMAC_SHA256_128,
|
||||||
|
HMAC_SHA256_256,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct wlan_crypto_pmksa - structure of crypto to contain pmkid
|
* struct wlan_crypto_pmksa - structure of crypto to contain pmkid
|
||||||
* @bssid: bssid for which pmkid is saved
|
* @bssid: bssid for which pmkid is saved
|
||||||
|
@@ -4486,5 +4486,38 @@ void wlan_crypto_set_sae_single_pmk_bss_cap(struct wlan_objmgr_vdev *vdev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_FILS_SK
|
||||||
|
QDF_STATUS wlan_crypto_create_fils_rik(uint8_t *rrk, uint8_t rrk_len,
|
||||||
|
uint8_t *rik, uint32_t *rik_len)
|
||||||
|
{
|
||||||
|
uint8_t optional_data[WLAN_CRYPTO_FILS_OPTIONAL_DATA_LEN];
|
||||||
|
uint8_t label[] = WLAN_CRYPTO_FILS_RIK_LABEL;
|
||||||
|
QDF_STATUS status;
|
||||||
|
|
||||||
|
if (!rrk || !rik) {
|
||||||
|
crypto_err("FILS rrk/rik NULL");
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional_data[0] = HMAC_SHA256_128;
|
||||||
|
/* basic validation */
|
||||||
|
if (rrk_len <= 0) {
|
||||||
|
crypto_err("invalid r_rk length %d", rrk_len);
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlan_crypto_put_be16(&optional_data[1], rrk_len);
|
||||||
|
status = qdf_default_hmac_sha256_kdf(rrk, rrk_len, label, optional_data,
|
||||||
|
sizeof(optional_data), rik,
|
||||||
|
rrk_len);
|
||||||
|
if (QDF_IS_STATUS_ERROR(status)) {
|
||||||
|
crypto_err("failed to create rik");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
*rik_len = rrk_len;
|
||||||
|
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* WLAN_FEATURE_FILS_SK */
|
||||||
|
Reference in New Issue
Block a user