xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/mvl88w8977/mlan/esa/common/pmkCache.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file pmkcache.c
2  *
3  *  @brief This file defines pmk cache functions
4  *
5  * Copyright (C) 2014-2017, Marvell International Ltd.
6  *
7  * This software file (the "File") is distributed by Marvell International
8  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
9  * (the "License").  You may use, redistribute and/or modify this File in
10  * accordance with the terms and conditions of the License, a copy of which
11  * is available by writing to the Free Software Foundation, Inc.,
12  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
13  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
14  *
15  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
18  * this warranty disclaimer.
19  */
20 
21 /******************************************************
22 Change log:
23     03/07/2014: Initial version
24 ******************************************************/
25 #include "wl_macros.h"
26 #include "pass_phrase.h"
27 #include "pmkCache.h"
28 #include "hostsa_ext_def.h"
29 #include "authenticator.h"
30 #include "tlv.h"
31 #include "keyMgmtApStaCommon.h"
32 
33 #define MAX_PMK_CACHE_ENTRIES 10
34 
35 pmkElement_t pmkCache[MAX_PMK_CACHE_ENTRIES];
36 
37 char PSKPassPhrase[PSK_PASS_PHRASE_LEN_MAX];
38 /*
39 **  Replacement rank is used to determine which cache entry to replace
40 **  once the cache is full.  The rank order is determined by usage. The
41 **  least recently used cache element is the first to be replaced.
42 **
43 **  replacementRankMax is an indication of the number of cache entries used.
44 **  It is used to  determine the rank of the current cache entry used.
45 **
46 **  Rank order goes from 1 to MAX_PMK_CACHE_ENTRIES. If the cache is full,
47 **  the element with rank 1 is first to be replaced.
48 **
49 **  Replacement rank of zero indicates that the entry is invalid.
50 */
51 
52 UINT8 *
pmkCacheFindPSK(void * priv,UINT8 * pSsid,UINT8 ssidLen)53 pmkCacheFindPSK(void *priv, UINT8 *pSsid, UINT8 ssidLen)
54 {
55 	UINT8 *pPMK = NULL;
56 	pmkElement_t *pPMKElement;
57 
58 	if (!pPMK) {
59 		/* extract the PSK from the cache entry */
60 		pPMKElement =
61 			pmkCacheFindPSKElement((void *)priv, pSsid, ssidLen);
62 		if (pPMKElement) {
63 			pPMK = pPMKElement->PMK;
64 		} else if ('\0' != PSKPassPhrase[0]) {
65 			/* Generate a new PSK entry with the
66 			 ** provided passphrase.
67 			 */
68 			pmkCacheAddPSK((void *)priv, pSsid, ssidLen, NULL,
69 				       PSKPassPhrase);
70 			pPMKElement =
71 				pmkCacheFindPSKElement((void *)priv, pSsid,
72 						       ssidLen);
73 			pmkCacheGeneratePSK((void *)priv, pSsid, ssidLen,
74 					    PSKPassPhrase, pPMKElement->PMK);
75 			pPMK = pPMKElement->PMK;
76 		}
77 	}
78 
79 	return pPMK;
80 }
81 
82 UINT8 *
pmkCacheFindPassphrase(void * priv,UINT8 * pSsid,UINT8 ssidLen)83 pmkCacheFindPassphrase(void *priv, UINT8 *pSsid, UINT8 ssidLen)
84 {
85 	UINT8 *pPassphrase = NULL;
86 	pmkElement_t *pPMKElement;
87 
88 	if (!pPassphrase) {
89 		/* extract the PSK from the cache entry */
90 		pPMKElement =
91 			pmkCacheFindPSKElement((void *)priv, pSsid, ssidLen);
92 		if (pPMKElement) {
93 			pPassphrase = pPMKElement->passphrase;
94 		}
95 
96 	}
97 
98 	return pPassphrase;
99 }
100 
101 void
pmkCacheSetPassphrase(void * priv,char * pPassphrase)102 pmkCacheSetPassphrase(void *priv, char *pPassphrase)
103 {
104 	phostsa_private psapriv = (phostsa_private)priv;
105 	hostsa_util_fns *util_fns = &psapriv->util_fns;
106 
107 	if (pPassphrase != NULL) {
108 		memcpy(util_fns, PSKPassPhrase,
109 		       pPassphrase, sizeof(PSKPassPhrase));
110 	}
111 }
112 
113 void
pmkCacheGetPassphrase(void * priv,char * pPassphrase)114 pmkCacheGetPassphrase(void *priv, char *pPassphrase)
115 {
116 	phostsa_private psapriv = (phostsa_private)priv;
117 	hostsa_util_fns *util_fns = &psapriv->util_fns;
118 
119 	if (pPassphrase != NULL) {
120 		memcpy(util_fns, pPassphrase,
121 		       PSKPassPhrase, sizeof(PSKPassPhrase));
122 	}
123 }
124 
125 void
pmkCacheInit(void * priv)126 pmkCacheInit(void *priv)
127 {
128 	phostsa_private psapriv = (phostsa_private)priv;
129 	hostsa_util_fns *util_fns = &psapriv->util_fns;
130 
131 	memset(util_fns, pmkCache, 0x00, sizeof(pmkCache));
132 	memset(util_fns, PSKPassPhrase, 0x00, sizeof(PSKPassPhrase));
133 	replacementRankMax = 0;
134 }
135 
136 void
pmkCacheFlush(void * priv)137 pmkCacheFlush(void *priv)
138 {
139 	phostsa_private psapriv = (phostsa_private)priv;
140 	hostsa_util_fns *util_fns = &psapriv->util_fns;
141 
142 	memset(util_fns, pmkCache, 0x00, sizeof(pmkCache));
143 	replacementRankMax = 0;
144 }
145 
146 //#pragma arm section code = ".init"
147 void
pmkCacheRomInit(void)148 pmkCacheRomInit(void)
149 {
150 	ramHook_MAX_PMK_CACHE_ENTRIES = MAX_PMK_CACHE_ENTRIES;
151 	ramHook_pmkCache = &pmkCache[0];
152 	ramHook_PSKPassPhrase = &PSKPassPhrase[0];
153 //    ramHook_hal_SetCpuMaxSpeed    = hal_SetCpuOpToSecuritySpeed;
154 //    ramHook_hal_RestoreCpuSpeed   = cm_SetPerformanceParams;
155 }
156 
157 //#pragma arm section code
158 
159 #ifdef DRV_EMBEDDED_SUPPLICANT
160 
161 t_u16
SupplicantSetPassphrase(void * priv,void * pPassphraseBuf)162 SupplicantSetPassphrase(void *priv, void *pPassphraseBuf)
163 {
164 	phostsa_private psapriv = (phostsa_private)priv;
165 	hostsa_util_fns *util_fns = NULL;
166 	mlan_ds_passphrase *psk = (mlan_ds_passphrase *)pPassphraseBuf;
167 	IEEEtypes_MacAddr_t *pBssid = NULL;
168 	UINT8 *pPMK = NULL;
169 	UINT8 Passphrase[PSK_PASS_PHRASE_LEN_MAX], *pPassphrase = NULL;
170 	UINT8 *pSsid = NULL;
171 	UINT8 ssidLen = 0;
172 	UINT16 retVal = 0;
173 	t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
174 
175 	if (!psapriv)
176 		return retVal;
177 	util_fns = &psapriv->util_fns;
178 
179 	if (memcmp(util_fns, (t_u8 *)&psk->bssid, zero_mac, sizeof(zero_mac)))
180 		pBssid = (IEEEtypes_MacAddr_t *)&psk->bssid;
181 
182 	ssidLen = psk->ssid.ssid_len;
183 	if (ssidLen > 0)
184 		pSsid = psk->ssid.ssid;
185 
186 	if (psk->psk_type == MLAN_PSK_PASSPHRASE) {
187 		pPassphrase = psk->psk.passphrase.passphrase;
188 		memset(util_fns, Passphrase, 0x00, sizeof(Passphrase));
189 		memcpy(util_fns, Passphrase, pPassphrase,
190 		       MIN(MLAN_MAX_PASSPHRASE_LENGTH,
191 			   psk->psk.passphrase.passphrase_len));
192 	}
193 
194 	if (psk->psk_type == MLAN_PSK_PMK)
195 		pPMK = psk->psk.pmk.pmk;
196 
197 	/* Always enable the supplicant on a set */
198 	// supplicantEnable(priv);
199 
200 	if (pBssid && pPMK) {
201 		pmkCacheAddPMK(priv, pBssid, pPMK);
202 	} else if (pSsid) {
203 		if (pPMK) {
204 			pmkCacheAddPSK(priv, pSsid, ssidLen, pPMK, NULL);
205 		} else if (pPassphrase) {
206 			pmkCacheAddPSK(priv, pSsid, ssidLen, NULL, Passphrase);
207 			pPMK = pmkCacheFindPSK(priv, pSsid, ssidLen);
208 			pmkCacheGeneratePSK(priv, pSsid, ssidLen,
209 					    (char *)Passphrase, pPMK);
210 		} else {
211 			/* Just an SSID so we can't set anything in the cache */
212 			retVal = 1;
213 		}
214 	} else if (pPassphrase) {
215 		memcpy(util_fns, PSKPassPhrase, Passphrase, sizeof(Passphrase));
216 	} else {
217 		/* Not enough data to set anything in the cache */
218 		retVal = 1;
219 	}
220 
221 	return retVal;
222 }
223 
224 BOOLEAN
SupplicantClearPMK_internal(void * priv,void * pPassphraseBuf)225 SupplicantClearPMK_internal(void *priv, void *pPassphraseBuf)
226 {
227 	phostsa_private psapriv = (phostsa_private)priv;
228 	hostsa_util_fns *util_fns = &psapriv->util_fns;
229 	mlan_ds_passphrase *psk = (mlan_ds_passphrase *)pPassphraseBuf;
230 	IEEEtypes_MacAddr_t *pBssid = NULL;
231 	UINT8 *pPassphrase = NULL;
232 	UINT8 *pSsid = NULL;
233 	UINT8 ssidLen = 0;
234 	t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
235 
236 	if (memcmp(util_fns, (t_u8 *)&psk->bssid, zero_mac, sizeof(zero_mac)))
237 		pBssid = (IEEEtypes_MacAddr_t *)&psk->bssid;
238 
239 	ssidLen = psk->ssid.ssid_len;
240 	if (ssidLen > 0)
241 		pSsid = psk->ssid.ssid;
242 
243 	if (psk->psk_type == MLAN_PSK_PASSPHRASE)
244 		pPassphrase = psk->psk.passphrase.passphrase;
245 
246 	if (pBssid) {
247 		pmkCacheDeletePMK(priv, (UINT8 *)pBssid);
248 	} else if (pSsid) {
249 		pmkCacheDeletePSK(priv, pSsid, ssidLen);
250 	} else if (pPassphrase) {
251 		/* Clear the global passphrase by setting it to blank */
252 		memset(util_fns, ramHook_PSKPassPhrase, 0x00,
253 		       PSK_PASS_PHRASE_LEN_MAX);
254 	} else {
255 		return FALSE;
256 	}
257 
258 	return TRUE;
259 }
260 
261 void
SupplicantClearPMK(void * priv,void * pPassphrase)262 SupplicantClearPMK(void *priv, void *pPassphrase)
263 {
264 	if (!priv)
265 		return;
266 
267 	if (!SupplicantClearPMK_internal(priv, pPassphrase)) {
268 		/* Always disable the supplicant on a flush */
269 		supplicantDisable(priv);
270 		pmkCacheFlush(priv);
271 	}
272 }
273 
274 void
SupplicantQueryPassphrase(void * priv,void * pPassphraseBuf)275 SupplicantQueryPassphrase(void *priv, void *pPassphraseBuf)
276 {
277 	phostsa_private psapriv = (phostsa_private)priv;
278 	hostsa_util_fns *util_fns = NULL;
279 	mlan_ds_passphrase *psk = (mlan_ds_passphrase *)pPassphraseBuf;
280 	UINT8 *pPassphrase = NULL;
281 	UINT8 *pSsid = NULL;
282 	UINT8 ssidLen = 0;
283 
284 	if (!psapriv)
285 		return;
286 
287 	util_fns = &psapriv->util_fns;
288 	ssidLen = psk->ssid.ssid_len;
289 	pSsid = psk->ssid.ssid;
290 
291 	if (ssidLen) {
292 		pPassphrase = pmkCacheFindPassphrase(priv, pSsid, ssidLen);
293 		if (pPassphrase) {
294 			psk->psk_type = MLAN_PSK_PASSPHRASE;
295 			memcpy(util_fns, psk->psk.passphrase.passphrase,
296 			       pPassphrase, PSK_PASS_PHRASE_LEN_MAX);
297 			psk->psk.passphrase.passphrase_len =
298 				wlan_strlen(pPassphrase);
299 		}
300 	}
301 
302 }
303 #endif
304