From 5d64a83690ed4544a7f5faa7868caba53e4f1bf4 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Wed, 5 Feb 2020 14:26:12 +0800 Subject: [PATCH] qcacmn: Add pmksa based on SSID and cache id For FILS pmksa cache, the pmksa add/del/query is based on SSID and cache id. The current crypto pmksa cache API dosn't support SSID and cache ID. 1. Add SSID/Cache ID support to pmksa API 2. Add RSN IE pmkid field based on SSID/cache ID Change-Id: I1577c6293b75d6f8e6210f314dd83462e06d8190 CRs-Fixed: 2621860 --- .../crypto/inc/wlan_crypto_global_api.h | 31 +++- .../crypto/inc/wlan_crypto_global_def.h | 9 +- .../crypto/src/wlan_crypto_global_api.c | 134 +++++++++++++----- umac/cmn_services/inc/wlan_cmn.h | 2 + 4 files changed, 135 insertions(+), 41 deletions(-) diff --git a/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h b/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h index 7f8a2b7637e5..be28bda1b929 100644 --- a/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h +++ b/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -320,6 +320,21 @@ QDF_STATUS wlan_crypto_rsnie_check(struct wlan_crypto_params *, uint8_t *frm); */ uint8_t *wlan_crypto_build_wpaie(struct wlan_objmgr_vdev *vdev, uint8_t *iebuf); + +/** + * wlan_crypto_build_rsnie_with_pmksa() - called by mlme to build rsnie + * @vdev: vdev + * @iebuf: ie buffer + * @pmksa: pmksa struct + * + * This function gets called by mlme to build rsnie from given vdev + * + * Return: end of buffer + */ +uint8_t *wlan_crypto_build_rsnie_with_pmksa(struct wlan_objmgr_vdev *vdev, + uint8_t *iebuf, + struct wlan_crypto_pmksa *pmksa); + /** * wlan_crypto_build_rsnie - called by mlme to build rsnie * @vdev: vdev @@ -852,6 +867,20 @@ QDF_STATUS wlan_crypto_set_key_req(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } #endif /* CRYPTO_SET_KEY_CONVERGED */ + +/** + * wlan_crypto_get_peer_pmksa() - called to get pmksa based on pmksa parameter + * @vdev: vdev + * @pmksa: bssid + * + * This function is to get pmksa based on pmksa parameter + * + * Return: wlan_crypto_pmksa when match found else NULL. + */ +struct wlan_crypto_pmksa * +wlan_crypto_get_peer_pmksa(struct wlan_objmgr_vdev *vdev, + struct wlan_crypto_pmksa *pmksa); + /** * wlan_crypto_get_pmksa - called to get pmksa of bssid passed. * @vdev: vdev diff --git a/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h b/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h index 607cc781d300..f293ac0860bb 100644 --- a/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h +++ b/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -222,13 +222,18 @@ enum wlan_crypto_key_type { * @pmkid: pmkid info * @pmk: pmk info * @pmk_len: pmk len + * @ssid_len: ssid length + * @ssid: ssid information + * @cache_id: cache id */ - struct wlan_crypto_pmksa { struct qdf_mac_addr bssid; uint8_t pmkid[PMKID_LEN]; uint8_t pmk[MAX_PMK_LEN]; uint8_t pmk_len; + uint8_t ssid_len; + uint8_t ssid[WLAN_SSID_MAX_LEN]; + uint8_t cache_id[WLAN_CACHE_ID_LEN]; }; /** diff --git a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c index ce97b1c9dab7..49b667f6395e 100644 --- a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c +++ b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c @@ -336,6 +336,19 @@ QDF_STATUS wlan_crypto_set_pmksa(struct wlan_crypto_params *crypto_params, qdf_mem_free(crypto_params->pmksa[i]); crypto_params->pmksa[i] = pmksa; return QDF_STATUS_SUCCESS; + } else if (pmksa->ssid_len && + !qdf_mem_cmp(pmksa->ssid, + crypto_params->pmksa[i]->ssid, + pmksa->ssid_len) && + !qdf_mem_cmp(pmksa->cache_id, + crypto_params->pmksa[i]->cache_id, + WLAN_CACHE_ID_LEN)){ + /* free the current pmksa and use this slot */ + qdf_mem_zero(crypto_params->pmksa[i], + sizeof(struct wlan_crypto_pmksa)); + qdf_mem_free(crypto_params->pmksa[i]); + crypto_params->pmksa[i] = pmksa; + return QDF_STATUS_SUCCESS; } } @@ -365,10 +378,22 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params, qdf_mem_free(crypto_params->pmksa[i]); crypto_params->pmksa[i] = NULL; return QDF_STATUS_SUCCESS; + } else if (pmksa->ssid_len && + !qdf_mem_cmp(pmksa->ssid, + crypto_params->pmksa[i]->ssid, + pmksa->ssid_len) && + !qdf_mem_cmp(pmksa->cache_id, + crypto_params->pmksa[i]->cache_id, + WLAN_CACHE_ID_LEN)){ + qdf_mem_zero(crypto_params->pmksa[i], + sizeof(struct wlan_crypto_pmksa)); + qdf_mem_free(crypto_params->pmksa[i]); + crypto_params->pmksa[i] = NULL; + return QDF_STATUS_SUCCESS; } } - return QDF_STATUS_E_INVAL; + return QDF_STATUS_SUCCESS; } QDF_STATUS wlan_crypto_pmksa_flush(struct wlan_crypto_params *crypto_params) @@ -428,6 +453,48 @@ QDF_STATUS wlan_crypto_set_del_pmksa(struct wlan_objmgr_vdev *vdev, return status; } +struct wlan_crypto_pmksa * +wlan_crypto_get_peer_pmksa(struct wlan_objmgr_vdev *vdev, + struct wlan_crypto_pmksa *pmksa) +{ + struct wlan_crypto_comp_priv *crypto_priv; + struct wlan_crypto_params *crypto_params; + uint8_t i; + + if (!pmksa) { + crypto_err("pmksa is NULL"); + return NULL; + } + crypto_priv = (struct wlan_crypto_comp_priv *) + wlan_get_vdev_crypto_obj(vdev); + + if (!crypto_priv) { + crypto_err("crypto_priv NULL"); + return NULL; + } + + crypto_params = &crypto_priv->crypto_params; + + for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) { + if (!crypto_params->pmksa[i]) + continue; + if (qdf_is_macaddr_equal(&pmksa->bssid, + &crypto_params->pmksa[i]->bssid)) { + return crypto_params->pmksa[i]; + } else if (pmksa->ssid_len && + !qdf_mem_cmp(pmksa->ssid, + crypto_params->pmksa[i]->ssid, + pmksa->ssid_len) && + !qdf_mem_cmp(pmksa->cache_id, + crypto_params->pmksa[i]->cache_id, + WLAN_CACHE_ID_LEN)){ + return crypto_params->pmksa[i]; + } + } + + return NULL; +} + struct wlan_crypto_pmksa * wlan_crypto_get_pmksa(struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *bssid) { @@ -460,6 +527,7 @@ wlan_crypto_get_pmksa(struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *bssid) return NULL; } + /** * wlan_crypto_is_htallowed - called to check is HT allowed for cipher * @vdev: vdev @@ -2632,19 +2700,9 @@ uint8_t *wlan_crypto_build_wpaie(struct wlan_objmgr_vdev *vdev, return frm; } -/** - * wlan_crypto_build_rsnie - called by mlme to build rsnie - * @vdev: vdev - * @iebuf: ie buffer - * @bssid: bssid mac address to add pmkid in rsnie - * - * This function gets called by mlme to build rsnie from given vdev - * - * Return: end of buffer - */ -uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev, - uint8_t *iebuf, - struct qdf_mac_addr *bssid) +uint8_t *wlan_crypto_build_rsnie_with_pmksa(struct wlan_objmgr_vdev *vdev, + uint8_t *iebuf, + struct wlan_crypto_pmksa *pmksa) { uint8_t *frm = iebuf; uint8_t *selcnt; @@ -2796,20 +2854,13 @@ add_rsn_caps: /* optional capabilities */ if (crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) { /* PMK list */ - if (bssid) { - struct wlan_crypto_pmksa *pmksa; - - pmksa = wlan_crypto_get_pmksa(vdev, bssid); - - if (pmksa) { - WLAN_CRYPTO_ADDSHORT(frm, 1); - qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN); - frm += PMKID_LEN; - } else { - WLAN_CRYPTO_ADDSHORT(frm, 0); - } - } else + if (pmksa) { + WLAN_CRYPTO_ADDSHORT(frm, 1); + qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN); + frm += PMKID_LEN; + } else { WLAN_CRYPTO_ADDSHORT(frm, 0); + } if (HAS_MGMT_CIPHER(crypto_params, WLAN_CRYPTO_CIPHER_AES_CMAC)) { @@ -2836,17 +2887,12 @@ add_rsn_caps: } } else { /* PMK list */ - if (bssid) { - struct wlan_crypto_pmksa *pmksa; - - pmksa = wlan_crypto_get_pmksa(vdev, bssid); - if (pmksa) { - WLAN_CRYPTO_ADDSHORT(frm, 1); - qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN); - frm += PMKID_LEN; - } else { - WLAN_CRYPTO_ADDSHORT(frm, 0); - } + if (pmksa) { + WLAN_CRYPTO_ADDSHORT(frm, 1); + qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN); + frm += PMKID_LEN; + } else { + WLAN_CRYPTO_ADDSHORT(frm, 0); } } @@ -2856,6 +2902,18 @@ add_rsn_caps: return frm; } +uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev, + uint8_t *iebuf, + struct qdf_mac_addr *bssid) +{ + struct wlan_crypto_pmksa *pmksa = NULL; + + if (bssid) + pmksa = wlan_crypto_get_pmksa(vdev, bssid); + + return wlan_crypto_build_rsnie_with_pmksa(vdev, iebuf, pmksa); +} + bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev, struct wlan_crypto_params *crypto_params){ struct wlan_crypto_params *my_crypto_params; diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h index 96b1e98039f8..1ddde97debc6 100644 --- a/umac/cmn_services/inc/wlan_cmn.h +++ b/umac/cmn_services/inc/wlan_cmn.h @@ -61,6 +61,8 @@ /* Max length of a SSID */ #define WLAN_SSID_MAX_LEN 32 +#define WLAN_CACHE_ID_LEN 2 + /* Max sequence number */ #define WLAN_MAX_SEQ_NUM 4096