xref: /freebsd/contrib/wpa/src/common/ptksa_cache.c (revision a90b9d0159070121c221b966469c3e36d912bf82)
1c1d255d3SCy Schubert /*
2c1d255d3SCy Schubert  * RSN PTKSA cache implementation
3c1d255d3SCy Schubert  *
4c1d255d3SCy Schubert  * Copyright (C) 2019 Intel Corporation
5c1d255d3SCy Schubert  *
6c1d255d3SCy Schubert  * This software may be distributed under the terms of the BSD license.
7c1d255d3SCy Schubert  * See README for more details.
8c1d255d3SCy Schubert  */
9c1d255d3SCy Schubert 
10c1d255d3SCy Schubert #include "includes.h"
11c1d255d3SCy Schubert #include "utils/common.h"
12c1d255d3SCy Schubert #include "eloop.h"
13c1d255d3SCy Schubert #include "common/ptksa_cache.h"
14c1d255d3SCy Schubert 
15c1d255d3SCy Schubert #define PTKSA_CACHE_MAX_ENTRIES 16
16c1d255d3SCy Schubert 
17c1d255d3SCy Schubert struct ptksa_cache {
18c1d255d3SCy Schubert 	struct dl_list ptksa;
19c1d255d3SCy Schubert 	unsigned int n_ptksa;
20c1d255d3SCy Schubert };
21c1d255d3SCy Schubert 
22*a90b9d01SCy Schubert #ifdef CONFIG_PTKSA_CACHE
23*a90b9d01SCy Schubert 
24c1d255d3SCy Schubert static void ptksa_cache_set_expiration(struct ptksa_cache *ptksa);
25c1d255d3SCy Schubert 
26c1d255d3SCy Schubert 
ptksa_cache_free_entry(struct ptksa_cache * ptksa,struct ptksa_cache_entry * entry)27c1d255d3SCy Schubert static void ptksa_cache_free_entry(struct ptksa_cache *ptksa,
28c1d255d3SCy Schubert 				   struct ptksa_cache_entry *entry)
29c1d255d3SCy Schubert {
30c1d255d3SCy Schubert 	ptksa->n_ptksa--;
31c1d255d3SCy Schubert 
32c1d255d3SCy Schubert 	dl_list_del(&entry->list);
33c1d255d3SCy Schubert 	bin_clear_free(entry, sizeof(*entry));
34c1d255d3SCy Schubert }
35c1d255d3SCy Schubert 
36c1d255d3SCy Schubert 
ptksa_cache_expire(void * eloop_ctx,void * timeout_ctx)37c1d255d3SCy Schubert static void ptksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
38c1d255d3SCy Schubert {
39c1d255d3SCy Schubert 	struct ptksa_cache *ptksa = eloop_ctx;
40c1d255d3SCy Schubert 	struct ptksa_cache_entry *e, *next;
41c1d255d3SCy Schubert 	struct os_reltime now;
42c1d255d3SCy Schubert 
43c1d255d3SCy Schubert 	if (!ptksa)
44c1d255d3SCy Schubert 		return;
45c1d255d3SCy Schubert 
46c1d255d3SCy Schubert 	os_get_reltime(&now);
47c1d255d3SCy Schubert 
48c1d255d3SCy Schubert 	dl_list_for_each_safe(e, next, &ptksa->ptksa,
49c1d255d3SCy Schubert 			      struct ptksa_cache_entry, list) {
50c1d255d3SCy Schubert 		if (e->expiration > now.sec)
51c1d255d3SCy Schubert 			continue;
52c1d255d3SCy Schubert 
53c1d255d3SCy Schubert 		wpa_printf(MSG_DEBUG, "Expired PTKSA cache entry for " MACSTR,
54c1d255d3SCy Schubert 			   MAC2STR(e->addr));
55c1d255d3SCy Schubert 
56*a90b9d01SCy Schubert 		if (e->cb && e->ctx)
57*a90b9d01SCy Schubert 			e->cb(e);
58*a90b9d01SCy Schubert 		else
59c1d255d3SCy Schubert 			ptksa_cache_free_entry(ptksa, e);
60c1d255d3SCy Schubert 	}
61c1d255d3SCy Schubert 
62c1d255d3SCy Schubert 	ptksa_cache_set_expiration(ptksa);
63c1d255d3SCy Schubert }
64c1d255d3SCy Schubert 
65c1d255d3SCy Schubert 
ptksa_cache_set_expiration(struct ptksa_cache * ptksa)66c1d255d3SCy Schubert static void ptksa_cache_set_expiration(struct ptksa_cache *ptksa)
67c1d255d3SCy Schubert {
68c1d255d3SCy Schubert 	struct ptksa_cache_entry *e;
69c1d255d3SCy Schubert 	int sec;
70c1d255d3SCy Schubert 	struct os_reltime now;
71c1d255d3SCy Schubert 
72c1d255d3SCy Schubert 	eloop_cancel_timeout(ptksa_cache_expire, ptksa, NULL);
73c1d255d3SCy Schubert 
74c1d255d3SCy Schubert 	if (!ptksa || !ptksa->n_ptksa)
75c1d255d3SCy Schubert 		return;
76c1d255d3SCy Schubert 
77c1d255d3SCy Schubert 	e = dl_list_first(&ptksa->ptksa, struct ptksa_cache_entry, list);
78c1d255d3SCy Schubert 	if (!e)
79c1d255d3SCy Schubert 		return;
80c1d255d3SCy Schubert 
81c1d255d3SCy Schubert 	os_get_reltime(&now);
82c1d255d3SCy Schubert 	sec = e->expiration - now.sec;
83c1d255d3SCy Schubert 	if (sec < 0)
84c1d255d3SCy Schubert 		sec = 0;
85c1d255d3SCy Schubert 
86c1d255d3SCy Schubert 	eloop_register_timeout(sec + 1, 0, ptksa_cache_expire, ptksa, NULL);
87c1d255d3SCy Schubert }
88c1d255d3SCy Schubert 
89c1d255d3SCy Schubert 
90c1d255d3SCy Schubert /*
91c1d255d3SCy Schubert  * ptksa_cache_init - Initialize PTKSA cache
92c1d255d3SCy Schubert  *
93c1d255d3SCy Schubert  * Returns: Pointer to PTKSA cache data or %NULL on failure
94c1d255d3SCy Schubert  */
ptksa_cache_init(void)95c1d255d3SCy Schubert struct ptksa_cache * ptksa_cache_init(void)
96c1d255d3SCy Schubert {
97c1d255d3SCy Schubert 	struct ptksa_cache *ptksa = os_zalloc(sizeof(struct ptksa_cache));
98c1d255d3SCy Schubert 
99c1d255d3SCy Schubert 	wpa_printf(MSG_DEBUG, "PTKSA: Initializing");
100c1d255d3SCy Schubert 
101c1d255d3SCy Schubert 	if (ptksa)
102c1d255d3SCy Schubert 		dl_list_init(&ptksa->ptksa);
103c1d255d3SCy Schubert 
104c1d255d3SCy Schubert 	return ptksa;
105c1d255d3SCy Schubert }
106c1d255d3SCy Schubert 
107c1d255d3SCy Schubert 
108c1d255d3SCy Schubert /*
109c1d255d3SCy Schubert  * ptksa_cache_deinit - Free all entries in PTKSA cache
110c1d255d3SCy Schubert  * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
111c1d255d3SCy Schubert  */
ptksa_cache_deinit(struct ptksa_cache * ptksa)112c1d255d3SCy Schubert void ptksa_cache_deinit(struct ptksa_cache *ptksa)
113c1d255d3SCy Schubert {
114c1d255d3SCy Schubert 	struct ptksa_cache_entry *e, *next;
115c1d255d3SCy Schubert 
116c1d255d3SCy Schubert 	if (!ptksa)
117c1d255d3SCy Schubert 		return;
118c1d255d3SCy Schubert 
119c1d255d3SCy Schubert 	wpa_printf(MSG_DEBUG, "PTKSA: Deinit. n_ptksa=%u", ptksa->n_ptksa);
120c1d255d3SCy Schubert 
121c1d255d3SCy Schubert 	dl_list_for_each_safe(e, next, &ptksa->ptksa,
122c1d255d3SCy Schubert 			      struct ptksa_cache_entry, list)
123c1d255d3SCy Schubert 		ptksa_cache_free_entry(ptksa, e);
124c1d255d3SCy Schubert 
125c1d255d3SCy Schubert 	eloop_cancel_timeout(ptksa_cache_expire, ptksa, NULL);
126c1d255d3SCy Schubert 	os_free(ptksa);
127c1d255d3SCy Schubert }
128c1d255d3SCy Schubert 
129c1d255d3SCy Schubert 
130c1d255d3SCy Schubert /*
131c1d255d3SCy Schubert  * ptksa_cache_get - Fetch a PTKSA cache entry
132c1d255d3SCy Schubert  * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
133c1d255d3SCy Schubert  * @addr: Peer address or %NULL to match any
134c1d255d3SCy Schubert  * @cipher: Specific cipher suite to search for or WPA_CIPHER_NONE for any
135c1d255d3SCy Schubert  * Returns: Pointer to PTKSA cache entry or %NULL if no match was found
136c1d255d3SCy Schubert  */
ptksa_cache_get(struct ptksa_cache * ptksa,const u8 * addr,u32 cipher)137c1d255d3SCy Schubert struct ptksa_cache_entry * ptksa_cache_get(struct ptksa_cache *ptksa,
138c1d255d3SCy Schubert 					   const u8 *addr, u32 cipher)
139c1d255d3SCy Schubert {
140c1d255d3SCy Schubert 	struct ptksa_cache_entry *e;
141c1d255d3SCy Schubert 
142c1d255d3SCy Schubert 	if (!ptksa)
143c1d255d3SCy Schubert 		return NULL;
144c1d255d3SCy Schubert 
145c1d255d3SCy Schubert 	dl_list_for_each(e, &ptksa->ptksa, struct ptksa_cache_entry, list) {
146*a90b9d01SCy Schubert 		if ((!addr || ether_addr_equal(e->addr, addr)) &&
147c1d255d3SCy Schubert 		    (cipher == WPA_CIPHER_NONE || cipher == e->cipher))
148c1d255d3SCy Schubert 			return e;
149c1d255d3SCy Schubert 	}
150c1d255d3SCy Schubert 
151c1d255d3SCy Schubert 	return NULL;
152c1d255d3SCy Schubert }
153c1d255d3SCy Schubert 
154c1d255d3SCy Schubert 
155c1d255d3SCy Schubert /*
156c1d255d3SCy Schubert  * ptksa_cache_list - Dump text list of entries in PTKSA cache
157c1d255d3SCy Schubert  * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
158c1d255d3SCy Schubert  * @buf: Buffer for the list
159c1d255d3SCy Schubert  * @len: Length of the buffer
160c1d255d3SCy Schubert  * Returns: Number of bytes written to buffer
161c1d255d3SCy Schubert  *
162c1d255d3SCy Schubert  * This function is used to generate a text format representation of the
163c1d255d3SCy Schubert  * current PTKSA cache contents for the ctrl_iface PTKSA command.
164c1d255d3SCy Schubert  */
ptksa_cache_list(struct ptksa_cache * ptksa,char * buf,size_t len)165c1d255d3SCy Schubert int ptksa_cache_list(struct ptksa_cache *ptksa, char *buf, size_t len)
166c1d255d3SCy Schubert {
167c1d255d3SCy Schubert 	struct ptksa_cache_entry *e;
168c1d255d3SCy Schubert 	int i = 0, ret;
169c1d255d3SCy Schubert 	char *pos = buf;
170c1d255d3SCy Schubert 	struct os_reltime now;
171c1d255d3SCy Schubert 
172c1d255d3SCy Schubert 	if (!ptksa)
173c1d255d3SCy Schubert 		return 0;
174c1d255d3SCy Schubert 
175c1d255d3SCy Schubert 	os_get_reltime(&now);
176c1d255d3SCy Schubert 
177c1d255d3SCy Schubert 	ret = os_snprintf(pos, buf + len - pos,
178c1d255d3SCy Schubert 			  "Index / ADDR / Cipher / expiration (secs) / TK / KDK\n");
179c1d255d3SCy Schubert 	if (os_snprintf_error(buf + len - pos, ret))
180c1d255d3SCy Schubert 		return pos - buf;
181c1d255d3SCy Schubert 	pos += ret;
182c1d255d3SCy Schubert 
183c1d255d3SCy Schubert 	dl_list_for_each(e, &ptksa->ptksa, struct ptksa_cache_entry, list) {
184c1d255d3SCy Schubert 		ret = os_snprintf(pos, buf + len - pos, "%u " MACSTR,
185c1d255d3SCy Schubert 				  i, MAC2STR(e->addr));
186c1d255d3SCy Schubert 		if (os_snprintf_error(buf + len - pos, ret))
187c1d255d3SCy Schubert 			return pos - buf;
188c1d255d3SCy Schubert 		pos += ret;
189c1d255d3SCy Schubert 
190c1d255d3SCy Schubert 		ret = os_snprintf(pos, buf + len - pos, " %s %lu ",
191c1d255d3SCy Schubert 				  wpa_cipher_txt(e->cipher),
192c1d255d3SCy Schubert 				  e->expiration - now.sec);
193c1d255d3SCy Schubert 		if (os_snprintf_error(buf + len - pos, ret))
194c1d255d3SCy Schubert 			return pos - buf;
195c1d255d3SCy Schubert 		pos += ret;
196c1d255d3SCy Schubert 
197c1d255d3SCy Schubert 		ret = wpa_snprintf_hex(pos, buf + len - pos, e->ptk.tk,
198c1d255d3SCy Schubert 				       e->ptk.tk_len);
199c1d255d3SCy Schubert 		if (os_snprintf_error(buf + len - pos, ret))
200c1d255d3SCy Schubert 			return pos - buf;
201c1d255d3SCy Schubert 		pos += ret;
202c1d255d3SCy Schubert 
203c1d255d3SCy Schubert 		ret = os_snprintf(pos, buf + len - pos, " ");
204c1d255d3SCy Schubert 		if (os_snprintf_error(buf + len - pos, ret))
205c1d255d3SCy Schubert 			return pos - buf;
206c1d255d3SCy Schubert 		pos += ret;
207c1d255d3SCy Schubert 
208c1d255d3SCy Schubert 		ret = wpa_snprintf_hex(pos, buf + len - pos, e->ptk.kdk,
209c1d255d3SCy Schubert 				       e->ptk.kdk_len);
210c1d255d3SCy Schubert 		if (os_snprintf_error(buf + len - pos, ret))
211c1d255d3SCy Schubert 			return pos - buf;
212c1d255d3SCy Schubert 		pos += ret;
213c1d255d3SCy Schubert 
214c1d255d3SCy Schubert 		ret = os_snprintf(pos, buf + len - pos, "\n");
215c1d255d3SCy Schubert 		if (os_snprintf_error(buf + len - pos, ret))
216c1d255d3SCy Schubert 			return pos - buf;
217c1d255d3SCy Schubert 		pos += ret;
218c1d255d3SCy Schubert 
219c1d255d3SCy Schubert 		i++;
220c1d255d3SCy Schubert 	}
221c1d255d3SCy Schubert 
222c1d255d3SCy Schubert 	return pos - buf;
223c1d255d3SCy Schubert }
224c1d255d3SCy Schubert 
225c1d255d3SCy Schubert 
226c1d255d3SCy Schubert /*
227c1d255d3SCy Schubert  * ptksa_cache_flush - Flush PTKSA cache entries
228c1d255d3SCy Schubert  *
229c1d255d3SCy Schubert  * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
230c1d255d3SCy Schubert  * @addr: Peer address or %NULL to match any
231c1d255d3SCy Schubert  * @cipher: Specific cipher suite to search for or WPA_CIPHER_NONE for any
232c1d255d3SCy Schubert  */
ptksa_cache_flush(struct ptksa_cache * ptksa,const u8 * addr,u32 cipher)233c1d255d3SCy Schubert void ptksa_cache_flush(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher)
234c1d255d3SCy Schubert {
235c1d255d3SCy Schubert 	struct ptksa_cache_entry *e, *next;
236c1d255d3SCy Schubert 	bool removed = false;
237c1d255d3SCy Schubert 
238c1d255d3SCy Schubert 	if (!ptksa)
239c1d255d3SCy Schubert 		return;
240c1d255d3SCy Schubert 
241c1d255d3SCy Schubert 	dl_list_for_each_safe(e, next, &ptksa->ptksa, struct ptksa_cache_entry,
242c1d255d3SCy Schubert 			      list) {
243*a90b9d01SCy Schubert 		if ((!addr || ether_addr_equal(e->addr, addr)) &&
244c1d255d3SCy Schubert 		    (cipher == WPA_CIPHER_NONE || cipher == e->cipher)) {
245c1d255d3SCy Schubert 			wpa_printf(MSG_DEBUG,
246c1d255d3SCy Schubert 				   "Flush PTKSA cache entry for " MACSTR,
247c1d255d3SCy Schubert 				   MAC2STR(e->addr));
248c1d255d3SCy Schubert 
249c1d255d3SCy Schubert 			ptksa_cache_free_entry(ptksa, e);
250c1d255d3SCy Schubert 			removed = true;
251c1d255d3SCy Schubert 		}
252c1d255d3SCy Schubert 	}
253c1d255d3SCy Schubert 
254c1d255d3SCy Schubert 	if (removed)
255c1d255d3SCy Schubert 		ptksa_cache_set_expiration(ptksa);
256c1d255d3SCy Schubert }
257c1d255d3SCy Schubert 
258c1d255d3SCy Schubert 
259c1d255d3SCy Schubert /*
260c1d255d3SCy Schubert  * ptksa_cache_add - Add a PTKSA cache entry
261c1d255d3SCy Schubert  * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
262*a90b9d01SCy Schubert  * @own_addr: Own MAC address
263c1d255d3SCy Schubert  * @addr: Peer address
264c1d255d3SCy Schubert  * @cipher: The cipher used
265c1d255d3SCy Schubert  * @life_time: The PTK life time in seconds
266c1d255d3SCy Schubert  * @ptk: The PTK
267*a90b9d01SCy Schubert  * @life_time_expiry_cb: Callback for alternative expiration handling
268*a90b9d01SCy Schubert  * @ctx: Context pointer to save into e->ctx for the callback
269*a90b9d01SCy Schubert  * @akmp: The key management mechanism that was used to derive the PTK
270c1d255d3SCy Schubert  * Returns: Pointer to the added PTKSA cache entry or %NULL on error
271c1d255d3SCy Schubert  *
272c1d255d3SCy Schubert  * This function creates a PTKSA entry and adds it to the PTKSA cache.
273c1d255d3SCy Schubert  * If an old entry is already in the cache for the same peer and cipher
274c1d255d3SCy Schubert  * this entry will be replaced with the new entry.
275c1d255d3SCy Schubert  */
ptksa_cache_add(struct ptksa_cache * ptksa,const u8 * own_addr,const u8 * addr,u32 cipher,u32 life_time,const struct wpa_ptk * ptk,void (* life_time_expiry_cb)(struct ptksa_cache_entry * e),void * ctx,u32 akmp)276c1d255d3SCy Schubert struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa,
277*a90b9d01SCy Schubert 					   const u8 *own_addr,
278c1d255d3SCy Schubert 					   const u8 *addr, u32 cipher,
279c1d255d3SCy Schubert 					   u32 life_time,
280*a90b9d01SCy Schubert 					   const struct wpa_ptk *ptk,
281*a90b9d01SCy Schubert 					   void (*life_time_expiry_cb)
282*a90b9d01SCy Schubert 					   (struct ptksa_cache_entry *e),
283*a90b9d01SCy Schubert 					   void *ctx, u32 akmp)
284c1d255d3SCy Schubert {
2854b72b91aSCy Schubert 	struct ptksa_cache_entry *entry, *tmp, *tmp2 = NULL;
286c1d255d3SCy Schubert 	struct os_reltime now;
287*a90b9d01SCy Schubert 	bool set_expiry = false;
288c1d255d3SCy Schubert 
289c1d255d3SCy Schubert 	if (!ptksa || !ptk || !addr || !life_time || cipher == WPA_CIPHER_NONE)
290c1d255d3SCy Schubert 		return NULL;
291c1d255d3SCy Schubert 
292c1d255d3SCy Schubert 	/* remove a previous entry if present */
293c1d255d3SCy Schubert 	ptksa_cache_flush(ptksa, addr, cipher);
294c1d255d3SCy Schubert 
295c1d255d3SCy Schubert 	/* no place to add another entry */
296c1d255d3SCy Schubert 	if (ptksa->n_ptksa >= PTKSA_CACHE_MAX_ENTRIES)
297c1d255d3SCy Schubert 		return NULL;
298c1d255d3SCy Schubert 
299c1d255d3SCy Schubert 	entry = os_zalloc(sizeof(*entry));
300c1d255d3SCy Schubert 	if (!entry)
301c1d255d3SCy Schubert 		return NULL;
302c1d255d3SCy Schubert 
303c1d255d3SCy Schubert 	dl_list_init(&entry->list);
304c1d255d3SCy Schubert 	os_memcpy(entry->addr, addr, ETH_ALEN);
305c1d255d3SCy Schubert 	entry->cipher = cipher;
306*a90b9d01SCy Schubert 	entry->cb = life_time_expiry_cb;
307*a90b9d01SCy Schubert 	entry->ctx = ctx;
308*a90b9d01SCy Schubert 	entry->akmp = akmp;
309*a90b9d01SCy Schubert 
310*a90b9d01SCy Schubert 	if (own_addr)
311*a90b9d01SCy Schubert 		os_memcpy(entry->own_addr, own_addr, ETH_ALEN);
312c1d255d3SCy Schubert 
313c1d255d3SCy Schubert 	os_memcpy(&entry->ptk, ptk, sizeof(entry->ptk));
314c1d255d3SCy Schubert 
315c1d255d3SCy Schubert 	os_get_reltime(&now);
316c1d255d3SCy Schubert 	entry->expiration = now.sec + life_time;
317c1d255d3SCy Schubert 
318c1d255d3SCy Schubert 	dl_list_for_each(tmp, &ptksa->ptksa, struct ptksa_cache_entry, list) {
3194b72b91aSCy Schubert 		if (tmp->expiration > entry->expiration) {
3204b72b91aSCy Schubert 			tmp2 = tmp;
321c1d255d3SCy Schubert 			break;
322c1d255d3SCy Schubert 		}
3234b72b91aSCy Schubert 	}
324c1d255d3SCy Schubert 
325*a90b9d01SCy Schubert 	if (dl_list_empty(&entry->list))
326*a90b9d01SCy Schubert 		set_expiry = true;
327c1d255d3SCy Schubert 	/*
3284b72b91aSCy Schubert 	 * If the expiration is later then all other or the list is empty
3294b72b91aSCy Schubert 	 * entries, add it to the end of the list;
330c1d255d3SCy Schubert 	 * otherwise add it before the relevant entry.
331c1d255d3SCy Schubert 	 */
3324b72b91aSCy Schubert 	if (tmp2)
3334b72b91aSCy Schubert 		dl_list_add(&tmp2->list, &entry->list);
334c1d255d3SCy Schubert 	else
3354b72b91aSCy Schubert 		dl_list_add_tail(&ptksa->ptksa, &entry->list);
336c1d255d3SCy Schubert 
337c1d255d3SCy Schubert 	ptksa->n_ptksa++;
338c1d255d3SCy Schubert 	wpa_printf(MSG_DEBUG,
339c1d255d3SCy Schubert 		   "Added PTKSA cache entry addr=" MACSTR " cipher=%u",
340c1d255d3SCy Schubert 		   MAC2STR(addr), cipher);
341c1d255d3SCy Schubert 
342*a90b9d01SCy Schubert 	if (set_expiry)
343*a90b9d01SCy Schubert 		ptksa_cache_set_expiration(ptksa);
344*a90b9d01SCy Schubert 
345c1d255d3SCy Schubert 	return entry;
346c1d255d3SCy Schubert }
347*a90b9d01SCy Schubert 
348*a90b9d01SCy Schubert #else /* CONFIG_PTKSA_CACHE */
349*a90b9d01SCy Schubert 
ptksa_cache_init(void)350*a90b9d01SCy Schubert struct ptksa_cache * ptksa_cache_init(void)
351*a90b9d01SCy Schubert {
352*a90b9d01SCy Schubert 	return (struct ptksa_cache *) 1;
353*a90b9d01SCy Schubert }
354*a90b9d01SCy Schubert 
355*a90b9d01SCy Schubert 
ptksa_cache_deinit(struct ptksa_cache * ptksa)356*a90b9d01SCy Schubert void ptksa_cache_deinit(struct ptksa_cache *ptksa)
357*a90b9d01SCy Schubert {
358*a90b9d01SCy Schubert }
359*a90b9d01SCy Schubert 
360*a90b9d01SCy Schubert 
361*a90b9d01SCy Schubert struct ptksa_cache_entry *
ptksa_cache_get(struct ptksa_cache * ptksa,const u8 * addr,u32 cipher)362*a90b9d01SCy Schubert ptksa_cache_get(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher)
363*a90b9d01SCy Schubert {
364*a90b9d01SCy Schubert 	return NULL;
365*a90b9d01SCy Schubert }
366*a90b9d01SCy Schubert 
367*a90b9d01SCy Schubert 
ptksa_cache_list(struct ptksa_cache * ptksa,char * buf,size_t len)368*a90b9d01SCy Schubert int ptksa_cache_list(struct ptksa_cache *ptksa, char *buf, size_t len)
369*a90b9d01SCy Schubert {
370*a90b9d01SCy Schubert 	return -1;
371*a90b9d01SCy Schubert }
372*a90b9d01SCy Schubert 
373*a90b9d01SCy Schubert 
374*a90b9d01SCy Schubert struct ptksa_cache_entry *
ptksa_cache_add(struct ptksa_cache * ptksa,const u8 * own_addr,const u8 * addr,u32 cipher,u32 life_time,const struct wpa_ptk * ptk,void (* cb)(struct ptksa_cache_entry * e),void * ctx,u32 akmp)375*a90b9d01SCy Schubert ptksa_cache_add(struct ptksa_cache *ptksa, const u8 *own_addr, const u8 *addr,
376*a90b9d01SCy Schubert 		u32 cipher, u32 life_time, const struct wpa_ptk *ptk,
377*a90b9d01SCy Schubert 		void (*cb)(struct ptksa_cache_entry *e), void *ctx, u32 akmp)
378*a90b9d01SCy Schubert {
379*a90b9d01SCy Schubert 	return NULL;
380*a90b9d01SCy Schubert }
381*a90b9d01SCy Schubert 
382*a90b9d01SCy Schubert 
ptksa_cache_flush(struct ptksa_cache * ptksa,const u8 * addr,u32 cipher)383*a90b9d01SCy Schubert void ptksa_cache_flush(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher)
384*a90b9d01SCy Schubert {
385*a90b9d01SCy Schubert }
386*a90b9d01SCy Schubert 
387*a90b9d01SCy Schubert #endif /* CONFIG_PTKSA_CACHE */
388