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:
Pragaspathi Thilagaraj
2020-08-10 00:59:38 +05:30
gecommit door snandini
bovenliggende acc1ea0d14
commit 0df12365ac
5 gewijzigde bestanden met toevoegingen van 160 en 1 verwijderingen

Bestand weergeven

@@ -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.

Bestand weergeven

@@ -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)
{

Bestand weergeven

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

Bestand weergeven

@@ -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

Bestand weergeven

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