Remove unneeded inclusion of hostapd header files
[wpasupplicant] / hostapd / pmksa_cache.c
1 /*
2  * hostapd - PMKSA cache for IEEE 802.11i RSN
3  * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "includes.h"
16
17 #include "common.h"
18 #include "sta_info.h"
19 #include "config.h"
20 #include "common.h"
21 #include "eloop.h"
22 #include "sha1.h"
23 #include "sha256.h"
24 #include "eapol_sm.h"
25 #include "pmksa_cache.h"
26
27
28 static const int pmksa_cache_max_entries = 1024;
29 static const int dot11RSNAConfigPMKLifetime = 43200;
30
31 struct rsn_pmksa_cache {
32 #define PMKID_HASH_SIZE 128
33 #define PMKID_HASH(pmkid) (unsigned int) ((pmkid)[0] & 0x7f)
34         struct rsn_pmksa_cache_entry *pmkid[PMKID_HASH_SIZE];
35         struct rsn_pmksa_cache_entry *pmksa;
36         int pmksa_count;
37
38         void (*free_cb)(struct rsn_pmksa_cache_entry *entry, void *ctx);
39         void *ctx;
40 };
41
42
43 static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa);
44
45
46 static void _pmksa_cache_free_entry(struct rsn_pmksa_cache_entry *entry)
47 {
48         if (entry == NULL)
49                 return;
50         os_free(entry->identity);
51         radius_free_class(&entry->radius_class);
52         os_free(entry);
53 }
54
55
56 static void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa,
57                                    struct rsn_pmksa_cache_entry *entry)
58 {
59         struct rsn_pmksa_cache_entry *pos, *prev;
60
61         pmksa->pmksa_count--;
62         pmksa->free_cb(entry, pmksa->ctx);
63         pos = pmksa->pmkid[PMKID_HASH(entry->pmkid)];
64         prev = NULL;
65         while (pos) {
66                 if (pos == entry) {
67                         if (prev != NULL) {
68                                 prev->hnext = pos->hnext;
69                         } else {
70                                 pmksa->pmkid[PMKID_HASH(entry->pmkid)] =
71                                         pos->hnext;
72                         }
73                         break;
74                 }
75                 prev = pos;
76                 pos = pos->hnext;
77         }
78
79         pos = pmksa->pmksa;
80         prev = NULL;
81         while (pos) {
82                 if (pos == entry) {
83                         if (prev != NULL)
84                                 prev->next = pos->next;
85                         else
86                                 pmksa->pmksa = pos->next;
87                         break;
88                 }
89                 prev = pos;
90                 pos = pos->next;
91         }
92         _pmksa_cache_free_entry(entry);
93 }
94
95
96 static void pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
97 {
98         struct rsn_pmksa_cache *pmksa = eloop_ctx;
99         struct os_time now;
100
101         os_get_time(&now);
102         while (pmksa->pmksa && pmksa->pmksa->expiration <= now.sec) {
103                 struct rsn_pmksa_cache_entry *entry = pmksa->pmksa;
104                 pmksa->pmksa = entry->next;
105                 wpa_printf(MSG_DEBUG, "RSN: expired PMKSA cache entry for "
106                            MACSTR, MAC2STR(entry->spa));
107                 pmksa_cache_free_entry(pmksa, entry);
108         }
109
110         pmksa_cache_set_expiration(pmksa);
111 }
112
113
114 static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa)
115 {
116         int sec;
117         struct os_time now;
118
119         eloop_cancel_timeout(pmksa_cache_expire, pmksa, NULL);
120         if (pmksa->pmksa == NULL)
121                 return;
122         os_get_time(&now);
123         sec = pmksa->pmksa->expiration - now.sec;
124         if (sec < 0)
125                 sec = 0;
126         eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, pmksa, NULL);
127 }
128
129
130 static void pmksa_cache_from_eapol_data(struct rsn_pmksa_cache_entry *entry,
131                                         struct eapol_state_machine *eapol)
132 {
133         if (eapol == NULL)
134                 return;
135
136         if (eapol->identity) {
137                 entry->identity = os_malloc(eapol->identity_len);
138                 if (entry->identity) {
139                         entry->identity_len = eapol->identity_len;
140                         os_memcpy(entry->identity, eapol->identity,
141                                   eapol->identity_len);
142                 }
143         }
144
145         radius_copy_class(&entry->radius_class, &eapol->radius_class);
146
147         entry->eap_type_authsrv = eapol->eap_type_authsrv;
148         entry->vlan_id = eapol->sta->vlan_id;
149 }
150
151
152 void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache_entry *entry,
153                                struct eapol_state_machine *eapol)
154 {
155         if (entry == NULL || eapol == NULL)
156                 return;
157
158         if (entry->identity) {
159                 os_free(eapol->identity);
160                 eapol->identity = os_malloc(entry->identity_len);
161                 if (eapol->identity) {
162                         eapol->identity_len = entry->identity_len;
163                         os_memcpy(eapol->identity, entry->identity,
164                                   entry->identity_len);
165                 }
166                 wpa_hexdump_ascii(MSG_DEBUG, "STA identity from PMKSA",
167                                   eapol->identity, eapol->identity_len);
168         }
169
170         radius_free_class(&eapol->radius_class);
171         radius_copy_class(&eapol->radius_class, &entry->radius_class);
172         if (eapol->radius_class.attr) {
173                 wpa_printf(MSG_DEBUG, "Copied %lu Class attribute(s) from "
174                            "PMKSA", (unsigned long) eapol->radius_class.count);
175         }
176
177         eapol->eap_type_authsrv = entry->eap_type_authsrv;
178         eapol->sta->vlan_id = entry->vlan_id;
179 }
180
181
182 static void pmksa_cache_link_entry(struct rsn_pmksa_cache *pmksa,
183                                    struct rsn_pmksa_cache_entry *entry)
184 {
185         struct rsn_pmksa_cache_entry *pos, *prev;
186
187         /* Add the new entry; order by expiration time */
188         pos = pmksa->pmksa;
189         prev = NULL;
190         while (pos) {
191                 if (pos->expiration > entry->expiration)
192                         break;
193                 prev = pos;
194                 pos = pos->next;
195         }
196         if (prev == NULL) {
197                 entry->next = pmksa->pmksa;
198                 pmksa->pmksa = entry;
199         } else {
200                 entry->next = prev->next;
201                 prev->next = entry;
202         }
203         entry->hnext = pmksa->pmkid[PMKID_HASH(entry->pmkid)];
204         pmksa->pmkid[PMKID_HASH(entry->pmkid)] = entry;
205
206         pmksa->pmksa_count++;
207         wpa_printf(MSG_DEBUG, "RSN: added PMKSA cache entry for " MACSTR,
208                    MAC2STR(entry->spa));
209         wpa_hexdump(MSG_DEBUG, "RSN: added PMKID", entry->pmkid, PMKID_LEN);
210 }
211
212
213 /**
214  * pmksa_cache_auth_add - Add a PMKSA cache entry
215  * @pmksa: Pointer to PMKSA cache data from pmksa_cache_auth_init()
216  * @pmk: The new pairwise master key
217  * @pmk_len: PMK length in bytes, usually PMK_LEN (32)
218  * @aa: Authenticator address
219  * @spa: Supplicant address
220  * @session_timeout: Session timeout
221  * @eapol: Pointer to EAPOL state machine data
222  * @akmp: WPA_KEY_MGMT_* used in key derivation
223  * Returns: Pointer to the added PMKSA cache entry or %NULL on error
224  *
225  * This function create a PMKSA entry for a new PMK and adds it to the PMKSA
226  * cache. If an old entry is already in the cache for the same Supplicant,
227  * this entry will be replaced with the new entry. PMKID will be calculated
228  * based on the PMK.
229  */
230 struct rsn_pmksa_cache_entry *
231 pmksa_cache_auth_add(struct rsn_pmksa_cache *pmksa,
232                      const u8 *pmk, size_t pmk_len,
233                 const u8 *aa, const u8 *spa, int session_timeout,
234                 struct eapol_state_machine *eapol, int akmp)
235 {
236         struct rsn_pmksa_cache_entry *entry, *pos;
237         struct os_time now;
238
239         if (pmk_len > PMK_LEN)
240                 return NULL;
241
242         entry = os_zalloc(sizeof(*entry));
243         if (entry == NULL)
244                 return NULL;
245         os_memcpy(entry->pmk, pmk, pmk_len);
246         entry->pmk_len = pmk_len;
247         rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid,
248                   wpa_key_mgmt_sha256(akmp));
249         os_get_time(&now);
250         entry->expiration = now.sec;
251         if (session_timeout > 0)
252                 entry->expiration += session_timeout;
253         else
254                 entry->expiration += dot11RSNAConfigPMKLifetime;
255         entry->akmp = akmp;
256         os_memcpy(entry->spa, spa, ETH_ALEN);
257         pmksa_cache_from_eapol_data(entry, eapol);
258
259         /* Replace an old entry for the same STA (if found) with the new entry
260          */
261         pos = pmksa_cache_auth_get(pmksa, spa, NULL);
262         if (pos)
263                 pmksa_cache_free_entry(pmksa, pos);
264
265         if (pmksa->pmksa_count >= pmksa_cache_max_entries && pmksa->pmksa) {
266                 /* Remove the oldest entry to make room for the new entry */
267                 wpa_printf(MSG_DEBUG, "RSN: removed the oldest PMKSA cache "
268                            "entry (for " MACSTR ") to make room for new one",
269                            MAC2STR(pmksa->pmksa->spa));
270                 pmksa_cache_free_entry(pmksa, pmksa->pmksa);
271         }
272
273         pmksa_cache_link_entry(pmksa, entry);
274
275         return entry;
276 }
277
278
279 struct rsn_pmksa_cache_entry *
280 pmksa_cache_add_okc(struct rsn_pmksa_cache *pmksa,
281                     const struct rsn_pmksa_cache_entry *old_entry,
282                     const u8 *aa, const u8 *pmkid)
283 {
284         struct rsn_pmksa_cache_entry *entry;
285
286         entry = os_zalloc(sizeof(*entry));
287         if (entry == NULL)
288                 return NULL;
289         os_memcpy(entry->pmkid, pmkid, PMKID_LEN);
290         os_memcpy(entry->pmk, old_entry->pmk, old_entry->pmk_len);
291         entry->pmk_len = old_entry->pmk_len;
292         entry->expiration = old_entry->expiration;
293         entry->akmp = old_entry->akmp;
294         os_memcpy(entry->spa, old_entry->spa, ETH_ALEN);
295         entry->opportunistic = 1;
296         if (old_entry->identity) {
297                 entry->identity = os_malloc(old_entry->identity_len);
298                 if (entry->identity) {
299                         entry->identity_len = old_entry->identity_len;
300                         os_memcpy(entry->identity, old_entry->identity,
301                                   old_entry->identity_len);
302                 }
303         }
304         radius_copy_class(&entry->radius_class, &old_entry->radius_class);
305         entry->eap_type_authsrv = old_entry->eap_type_authsrv;
306         entry->vlan_id = old_entry->vlan_id;
307         entry->opportunistic = 1;
308
309         pmksa_cache_link_entry(pmksa, entry);
310
311         return entry;
312 }
313
314
315 /**
316  * pmksa_cache_auth_deinit - Free all entries in PMKSA cache
317  * @pmksa: Pointer to PMKSA cache data from pmksa_cache_auth_init()
318  */
319 void pmksa_cache_auth_deinit(struct rsn_pmksa_cache *pmksa)
320 {
321         struct rsn_pmksa_cache_entry *entry, *prev;
322         int i;
323
324         if (pmksa == NULL)
325                 return;
326
327         entry = pmksa->pmksa;
328         while (entry) {
329                 prev = entry;
330                 entry = entry->next;
331                 _pmksa_cache_free_entry(prev);
332         }
333         eloop_cancel_timeout(pmksa_cache_expire, pmksa, NULL);
334         for (i = 0; i < PMKID_HASH_SIZE; i++)
335                 pmksa->pmkid[i] = NULL;
336         os_free(pmksa);
337 }
338
339
340 /**
341  * pmksa_cache_auth_get - Fetch a PMKSA cache entry
342  * @pmksa: Pointer to PMKSA cache data from pmksa_cache_auth_init()
343  * @spa: Supplicant address or %NULL to match any
344  * @pmkid: PMKID or %NULL to match any
345  * Returns: Pointer to PMKSA cache entry or %NULL if no match was found
346  */
347 struct rsn_pmksa_cache_entry *
348 pmksa_cache_auth_get(struct rsn_pmksa_cache *pmksa,
349                      const u8 *spa, const u8 *pmkid)
350 {
351         struct rsn_pmksa_cache_entry *entry;
352
353         if (pmkid)
354                 entry = pmksa->pmkid[PMKID_HASH(pmkid)];
355         else
356                 entry = pmksa->pmksa;
357         while (entry) {
358                 if ((spa == NULL ||
359                      os_memcmp(entry->spa, spa, ETH_ALEN) == 0) &&
360                     (pmkid == NULL ||
361                      os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0))
362                         return entry;
363                 entry = pmkid ? entry->hnext : entry->next;
364         }
365         return NULL;
366 }
367
368
369 /**
370  * pmksa_cache_get_okc - Fetch a PMKSA cache entry using OKC
371  * @pmksa: Pointer to PMKSA cache data from pmksa_cache_auth_init()
372  * @aa: Authenticator address
373  * @spa: Supplicant address
374  * @pmkid: PMKID
375  * Returns: Pointer to PMKSA cache entry or %NULL if no match was found
376  *
377  * Use opportunistic key caching (OKC) to find a PMK for a supplicant.
378  */
379 struct rsn_pmksa_cache_entry * pmksa_cache_get_okc(
380         struct rsn_pmksa_cache *pmksa, const u8 *aa, const u8 *spa,
381         const u8 *pmkid)
382 {
383         struct rsn_pmksa_cache_entry *entry;
384         u8 new_pmkid[PMKID_LEN];
385
386         entry = pmksa->pmksa;
387         while (entry) {
388                 if (os_memcmp(entry->spa, spa, ETH_ALEN) != 0)
389                         continue;
390                 rsn_pmkid(entry->pmk, entry->pmk_len, aa, spa, new_pmkid,
391                           wpa_key_mgmt_sha256(entry->akmp));
392                 if (os_memcmp(new_pmkid, pmkid, PMKID_LEN) == 0)
393                         return entry;
394                 entry = entry->next;
395         }
396         return NULL;
397 }
398
399
400 /**
401  * pmksa_cache_auth_init - Initialize PMKSA cache
402  * @free_cb: Callback function to be called when a PMKSA cache entry is freed
403  * @ctx: Context pointer for free_cb function
404  * Returns: Pointer to PMKSA cache data or %NULL on failure
405  */
406 struct rsn_pmksa_cache *
407 pmksa_cache_auth_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
408                                       void *ctx), void *ctx)
409 {
410         struct rsn_pmksa_cache *pmksa;
411
412         pmksa = os_zalloc(sizeof(*pmksa));
413         if (pmksa) {
414                 pmksa->free_cb = free_cb;
415                 pmksa->ctx = ctx;
416         }
417
418         return pmksa;
419 }