hostapd: remove version tag from directory
[dragonfly.git] / contrib / hostapd / eap_psk.c
1 /*
2  * hostapd / EAP-PSK (RFC 4764) server
3  * Copyright (c) 2005-2007, 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  * Note: EAP-PSK is an EAP authentication method and as such, completely
15  * different from WPA-PSK. This file is not needed for WPA-PSK functionality.
16  */
17
18 #include "includes.h"
19
20 #include "hostapd.h"
21 #include "common.h"
22 #include "eap_i.h"
23 #include "aes_wrap.h"
24 #include "eap_psk_common.h"
25
26
27 struct eap_psk_data {
28         enum { PSK_1, PSK_3, SUCCESS, FAILURE } state;
29         u8 rand_s[EAP_PSK_RAND_LEN];
30         u8 rand_p[EAP_PSK_RAND_LEN];
31         u8 *id_p, *id_s;
32         size_t id_p_len, id_s_len;
33         u8 ak[EAP_PSK_AK_LEN], kdk[EAP_PSK_KDK_LEN], tek[EAP_PSK_TEK_LEN];
34         u8 msk[EAP_MSK_LEN];
35         u8 emsk[EAP_EMSK_LEN];
36 };
37
38
39 static void * eap_psk_init(struct eap_sm *sm)
40 {
41         struct eap_psk_data *data;
42
43         data = wpa_zalloc(sizeof(*data));
44         if (data == NULL)
45                 return NULL;
46         data->state = PSK_1;
47         data->id_s = (u8 *) "hostapd";
48         data->id_s_len = 7;
49
50         return data;
51 }
52
53
54 static void eap_psk_reset(struct eap_sm *sm, void *priv)
55 {
56         struct eap_psk_data *data = priv;
57         free(data->id_p);
58         free(data);
59 }
60
61
62 static u8 * eap_psk_build_1(struct eap_sm *sm, struct eap_psk_data *data,
63                             int id, size_t *reqDataLen)
64 {
65         struct eap_psk_hdr_1 *req;
66
67         wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-1 (sending)");
68
69         if (hostapd_get_rand(data->rand_s, EAP_PSK_RAND_LEN)) {
70                 wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data");
71                 data->state = FAILURE;
72                 return NULL;
73         }
74         wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: RAND_S (server rand)",
75                     data->rand_s, EAP_PSK_RAND_LEN);
76
77         *reqDataLen = sizeof(*req) + data->id_s_len;
78         req = malloc(*reqDataLen);
79         if (req == NULL) {
80                 wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory "
81                            "request");
82                 data->state = FAILURE;
83                 return NULL;
84         }
85
86         req->code = EAP_CODE_REQUEST;
87         req->identifier = id;
88         req->length = htons(*reqDataLen);
89         req->type = EAP_TYPE_PSK;
90         req->flags = EAP_PSK_FLAGS_SET_T(0); /* T=0 */
91         memcpy(req->rand_s, data->rand_s, EAP_PSK_RAND_LEN);
92         memcpy((u8 *) (req + 1), data->id_s, data->id_s_len);
93
94         return (u8 *) req;
95 }
96
97
98 static u8 * eap_psk_build_3(struct eap_sm *sm, struct eap_psk_data *data,
99                             int id, size_t *reqDataLen)
100 {
101         struct eap_psk_hdr_3 *req;
102         u8 *buf, *pchannel, nonce[16];
103         size_t buflen;
104
105         wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-3 (sending)");
106
107         *reqDataLen = sizeof(*req) + 4 + 16 + 1;
108         req = malloc(*reqDataLen);
109         if (req == NULL) {
110                 wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory "
111                            "request");
112                 data->state = FAILURE;
113                 return NULL;
114         }
115
116         req->code = EAP_CODE_REQUEST;
117         req->identifier = id;
118         req->length = htons(*reqDataLen);
119         req->type = EAP_TYPE_PSK;
120         req->flags = EAP_PSK_FLAGS_SET_T(2); /* T=2 */
121         memcpy(req->rand_s, data->rand_s, EAP_PSK_RAND_LEN);
122
123         /* MAC_S = OMAC1-AES-128(AK, ID_S||RAND_P) */
124         buflen = data->id_s_len + EAP_PSK_RAND_LEN;
125         buf = malloc(buflen);
126         if (buf == NULL) {
127                 free(req);
128                 data->state = FAILURE;
129                 return NULL;
130         }
131         memcpy(buf, data->id_s, data->id_s_len);
132         memcpy(buf + data->id_s_len, data->rand_p, EAP_PSK_RAND_LEN);
133         omac1_aes_128(data->ak, buf, buflen, req->mac_s);
134         free(buf);
135
136         eap_psk_derive_keys(data->kdk, data->rand_p, data->tek, data->msk,
137                             data->emsk);
138         wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: TEK", data->tek, EAP_PSK_TEK_LEN);
139         wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: MSK", data->msk, EAP_MSK_LEN);
140         wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: EMSK", data->emsk, EAP_EMSK_LEN);
141
142         memset(nonce, 0, sizeof(nonce));
143         pchannel = (u8 *) (req + 1);
144         memcpy(pchannel, nonce + 12, 4);
145         memset(pchannel + 4, 0, 16); /* Tag */
146         pchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_SUCCESS << 6;
147         wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL (plaintext)",
148                     pchannel, 4 + 16 + 1);
149         aes_128_eax_encrypt(data->tek, nonce, sizeof(nonce), (u8 *) req, 22,
150                             pchannel + 4 + 16, 1, pchannel + 4);
151         wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL (encrypted)",
152                     pchannel, 4 + 16 + 1);
153
154         return (u8 *) req;
155 }
156
157
158 static u8 * eap_psk_buildReq(struct eap_sm *sm, void *priv, int id,
159                                   size_t *reqDataLen)
160 {
161         struct eap_psk_data *data = priv;
162
163         switch (data->state) {
164         case PSK_1:
165                 return eap_psk_build_1(sm, data, id, reqDataLen);
166         case PSK_3:
167                 return eap_psk_build_3(sm, data, id, reqDataLen);
168         default:
169                 wpa_printf(MSG_DEBUG, "EAP-PSK: Unknown state %d in buildReq",
170                            data->state);
171                 break;
172         }
173         return NULL;
174 }
175
176
177 static Boolean eap_psk_check(struct eap_sm *sm, void *priv,
178                              u8 *respData, size_t respDataLen)
179 {
180         struct eap_psk_data *data = priv;
181         struct eap_psk_hdr *resp;
182         size_t len;
183         u8 t;
184
185         resp = (struct eap_psk_hdr *) respData;
186         if (respDataLen < sizeof(*resp) || resp->type != EAP_TYPE_PSK ||
187             (len = ntohs(resp->length)) > respDataLen ||
188             len < sizeof(*resp)) {
189                 wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame");
190                 return TRUE;
191         }
192         t = EAP_PSK_FLAGS_GET_T(resp->flags);
193
194         wpa_printf(MSG_DEBUG, "EAP-PSK: received frame: T=%d", t);
195
196         if (data->state == PSK_1 && t != 1) {
197                 wpa_printf(MSG_DEBUG, "EAP-PSK: Expected PSK-2 - "
198                            "ignore T=%d", t);
199                 return TRUE;
200         }
201
202         if (data->state == PSK_3 && t != 3) {
203                 wpa_printf(MSG_DEBUG, "EAP-PSK: Expected PSK-4 - "
204                            "ignore T=%d", t);
205                 return TRUE;
206         }
207
208         if ((t == 1 && len < sizeof(struct eap_psk_hdr_2)) ||
209             (t == 3 && len < sizeof(struct eap_psk_hdr_4))) {
210                 wpa_printf(MSG_DEBUG, "EAP-PSK: Too short frame");
211                 return TRUE;
212         }
213
214         return FALSE;
215 }
216
217
218 static void eap_psk_process_2(struct eap_sm *sm,
219                               struct eap_psk_data *data,
220                               u8 *respData, size_t respDataLen)
221 {
222         struct eap_psk_hdr_2 *resp;
223         u8 *pos, mac[EAP_PSK_MAC_LEN], *buf;
224         size_t len, left, buflen;
225         int i;
226
227         if (data->state != PSK_1)
228                 return;
229
230         wpa_printf(MSG_DEBUG, "EAP-PSK: Received PSK-2");
231
232         resp = (struct eap_psk_hdr_2 *) respData;
233         len = ntohs(resp->length);
234         pos = (u8 *) (resp + 1);
235         left = len - sizeof(*resp);
236
237         free(data->id_p);
238         data->id_p = malloc(left);
239         if (data->id_p == NULL) {
240                 wpa_printf(MSG_INFO, "EAP-PSK: Failed to allocate memory for "
241                            "ID_P");
242                 return;
243         }
244         memcpy(data->id_p, pos, left);
245         data->id_p_len = left;
246         wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-PSK: ID_P",
247                           data->id_p, data->id_p_len);
248
249         if (eap_user_get(sm, data->id_p, data->id_p_len, 0) < 0) {
250                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: unknown ID_P",
251                                   data->id_p, data->id_p_len);
252                 data->state = FAILURE;
253                 return;
254         }
255
256         for (i = 0;
257              i < EAP_MAX_METHODS &&
258                      (sm->user->methods[i].vendor != EAP_VENDOR_IETF ||
259                       sm->user->methods[i].method != EAP_TYPE_NONE);
260              i++) {
261                 if (sm->user->methods[i].vendor == EAP_VENDOR_IETF &&
262                     sm->user->methods[i].method == EAP_TYPE_PSK)
263                         break;
264         }
265
266         if (i >= EAP_MAX_METHODS ||
267             sm->user->methods[i].vendor != EAP_VENDOR_IETF ||
268             sm->user->methods[i].method != EAP_TYPE_PSK) {
269                 wpa_hexdump_ascii(MSG_DEBUG,
270                                   "EAP-PSK: EAP-PSK not enabled for ID_P",
271                                   data->id_p, data->id_p_len);
272                 data->state = FAILURE;
273                 return;
274         }
275
276         if (sm->user->password == NULL ||
277             sm->user->password_len != EAP_PSK_PSK_LEN) {
278                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: invalid password in "
279                                   "user database for ID_P",
280                                   data->id_p, data->id_p_len);
281                 data->state = FAILURE;
282                 return;
283         }
284         eap_psk_key_setup(sm->user->password, data->ak, data->kdk);
285         wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: AK", data->ak, EAP_PSK_AK_LEN);
286         wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: KDK", data->kdk, EAP_PSK_KDK_LEN);
287
288         wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: RAND_P (client rand)",
289                     resp->rand_p, EAP_PSK_RAND_LEN);
290         memcpy(data->rand_p, resp->rand_p, EAP_PSK_RAND_LEN);
291
292         /* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */
293         buflen = data->id_p_len + data->id_s_len + 2 * EAP_PSK_RAND_LEN;
294         buf = malloc(buflen);
295         if (buf == NULL) {
296                 data->state = FAILURE;
297                 return;
298         }
299         memcpy(buf, data->id_p, data->id_p_len);
300         pos = buf + data->id_p_len;
301         memcpy(pos, data->id_s, data->id_s_len);
302         pos += data->id_s_len;
303         memcpy(pos, data->rand_s, EAP_PSK_RAND_LEN);
304         pos += EAP_PSK_RAND_LEN;
305         memcpy(pos, data->rand_p, EAP_PSK_RAND_LEN);
306         omac1_aes_128(data->ak, buf, buflen, mac);
307         free(buf);
308         wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", resp->mac_p, EAP_PSK_MAC_LEN);
309         if (memcmp(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) {
310                 wpa_printf(MSG_INFO, "EAP-PSK: Invalid MAC_P");
311                 wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Expected MAC_P",
312                             mac, EAP_PSK_MAC_LEN);
313                 data->state = FAILURE;
314                 return;
315         }
316
317         data->state = PSK_3;
318 }
319
320
321 static void eap_psk_process_4(struct eap_sm *sm,
322                               struct eap_psk_data *data,
323                               u8 *respData, size_t respDataLen)
324 {
325         struct eap_psk_hdr_4 *resp;
326         u8 *pos, *decrypted, nonce[16], *tag;
327         size_t left;
328
329         if (data->state != PSK_3)
330                 return;
331
332         wpa_printf(MSG_DEBUG, "EAP-PSK: Received PSK-4");
333
334         resp = (struct eap_psk_hdr_4 *) respData;
335         pos = (u8 *) (resp + 1);
336         left = ntohs(resp->length) - sizeof(*resp);
337
338         wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Encrypted PCHANNEL", pos, left);
339
340         if (left < 4 + 16 + 1) {
341                 wpa_printf(MSG_INFO, "EAP-PSK: Too short PCHANNEL data in "
342                            "PSK-4 (len=%lu, expected 21)",
343                            (unsigned long) left);
344                 return;
345         }
346
347         if (pos[0] == 0 && pos[1] == 0 && pos[2] == 0 && pos[3] == 0) {
348                 wpa_printf(MSG_DEBUG, "EAP-PSK: Nonce did not increase");
349                 return;
350         }
351
352         memset(nonce, 0, 12);
353         memcpy(nonce + 12, pos, 4);
354         pos += 4;
355         left -= 4;
356         tag = pos;
357         pos += 16;
358         left -= 16;
359
360         decrypted = malloc(left);
361         if (decrypted == NULL)
362                 return;
363         memcpy(decrypted, pos, left);
364
365         if (aes_128_eax_decrypt(data->tek, nonce, sizeof(nonce),
366                                 respData, 22, decrypted, left, tag)) {
367                 wpa_printf(MSG_WARNING, "EAP-PSK: PCHANNEL decryption failed");
368                 free(decrypted);
369                 data->state = FAILURE;
370                 return;
371         }
372         wpa_hexdump(MSG_DEBUG, "EAP-PSK: Decrypted PCHANNEL message",
373                     decrypted, left);
374
375         /* Verify R flag */
376         switch (decrypted[0] >> 6) {
377         case EAP_PSK_R_FLAG_CONT:
378                 wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - CONT - unsupported");
379                 data->state = FAILURE;
380                 break;
381         case EAP_PSK_R_FLAG_DONE_SUCCESS:
382                 wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_SUCCESS");
383                 data->state = SUCCESS;
384                 break;
385         case EAP_PSK_R_FLAG_DONE_FAILURE:
386                 wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_FAILURE");
387                 data->state = FAILURE;
388                 break;
389         }
390         free(decrypted);
391 }
392
393
394 static void eap_psk_process(struct eap_sm *sm, void *priv,
395                                  u8 *respData, size_t respDataLen)
396 {
397         struct eap_psk_data *data = priv;
398         struct eap_psk_hdr *resp;
399
400         if (sm->user == NULL || sm->user->password == NULL) {
401                 wpa_printf(MSG_INFO, "EAP-PSK: Plaintext password not "
402                            "configured");
403                 data->state = FAILURE;
404                 return;
405         }
406
407         resp = (struct eap_psk_hdr *) respData;
408
409         switch (EAP_PSK_FLAGS_GET_T(resp->flags)) {
410         case 1:
411                 eap_psk_process_2(sm, data, respData, respDataLen);
412                 break;
413         case 3:
414                 eap_psk_process_4(sm, data, respData, respDataLen);
415                 break;
416         }
417 }
418
419
420 static Boolean eap_psk_isDone(struct eap_sm *sm, void *priv)
421 {
422         struct eap_psk_data *data = priv;
423         return data->state == SUCCESS || data->state == FAILURE;
424 }
425
426
427 static u8 * eap_psk_getKey(struct eap_sm *sm, void *priv, size_t *len)
428 {
429         struct eap_psk_data *data = priv;
430         u8 *key;
431
432         if (data->state != SUCCESS)
433                 return NULL;
434
435         key = malloc(EAP_MSK_LEN);
436         if (key == NULL)
437                 return NULL;
438         memcpy(key, data->msk, EAP_MSK_LEN);
439         *len = EAP_MSK_LEN;
440
441         return key;
442 }
443
444
445 static u8 * eap_psk_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
446 {
447         struct eap_psk_data *data = priv;
448         u8 *key;
449
450         if (data->state != SUCCESS)
451                 return NULL;
452
453         key = malloc(EAP_EMSK_LEN);
454         if (key == NULL)
455                 return NULL;
456         memcpy(key, data->emsk, EAP_EMSK_LEN);
457         *len = EAP_EMSK_LEN;
458
459         return key;
460 }
461
462
463 static Boolean eap_psk_isSuccess(struct eap_sm *sm, void *priv)
464 {
465         struct eap_psk_data *data = priv;
466         return data->state == SUCCESS;
467 }
468
469
470 int eap_server_psk_register(void)
471 {
472         struct eap_method *eap;
473         int ret;
474
475         eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
476                                       EAP_VENDOR_IETF, EAP_TYPE_PSK, "PSK");
477         if (eap == NULL)
478                 return -1;
479
480         eap->init = eap_psk_init;
481         eap->reset = eap_psk_reset;
482         eap->buildReq = eap_psk_buildReq;
483         eap->check = eap_psk_check;
484         eap->process = eap_psk_process;
485         eap->isDone = eap_psk_isDone;
486         eap->getKey = eap_psk_getKey;
487         eap->isSuccess = eap_psk_isSuccess;
488         eap->get_emsk = eap_psk_get_emsk;
489
490         ret = eap_server_method_register(eap);
491         if (ret)
492                 eap_server_method_free(eap);
493         return ret;
494 }