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:

gecommit door
snandini

bovenliggende
acc1ea0d14
commit
0df12365ac
@@ -54,6 +54,8 @@ extern "C" {
|
||||
#define IS_VALID_CTR_KEY_LEN(len) ((((len) == 16) || ((len) == 32) || \
|
||||
((len) == 48)) ? 1 : 0)
|
||||
|
||||
#define WLAN_MAX_PRF_INTERATIONS_COUNT 255
|
||||
|
||||
/* 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,
|
||||
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
|
||||
* scatterlist elements.
|
||||
|
@@ -78,6 +78,63 @@ int qdf_get_hmac_hash(uint8_t *type, uint8_t *key,
|
||||
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) */
|
||||
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
|
||||
|
||||
#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_ */
|
||||
|
@@ -75,6 +75,10 @@
|
||||
#define WLAN_CRYPTO_WPI_SMS4_PADLEN (1)
|
||||
#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 */
|
||||
#define WLAN_CRYPTO_KEY_XMIT (0x01)
|
||||
/* key used for recv */
|
||||
@@ -217,6 +221,21 @@ enum wlan_crypto_key_type {
|
||||
#define IS_WEP_CIPHER(_c) ((_c == WLAN_CRYPTO_CIPHER_WEP) || \
|
||||
(_c == WLAN_CRYPTO_CIPHER_WEP_40) || \
|
||||
(_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
|
||||
* @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
|
||||
|
||||
#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 */
|
||||
|
Verwijs in nieuw issue
Block a user