2 * EAP peer method: EAP-FAST (draft-cam-winget-eap-fast-03.txt)
3 * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
19 #include "eap_tls_common.h"
20 #include "config_ssid.h"
27 * - encrypt PAC-Key in the PAC file
28 * - test session resumption and enable it if it interoperates
29 * - password change (pending mschapv2 packet; replay decrypted packet)
32 #define EAP_FAST_VERSION 1
33 #define EAP_FAST_KEY_LEN 64
34 #define EAP_FAST_PAC_KEY_LEN 32
35 #define EAP_FAST_SIMCK_LEN 40
36 #define EAP_FAST_SKS_LEN 40
38 #define TLS_EXT_PAC_OPAQUE 35
40 static const char *pac_file_hdr
=
41 "wpa_supplicant EAP-FAST PAC file - version 1";
44 static void eap_fast_deinit(struct eap_sm
*sm
, void *priv
);
47 #define PAC_TYPE_PAC_KEY 1
48 #define PAC_TYPE_PAC_OPAQUE 2
49 #define PAC_TYPE_CRED_LIFETIME 3
50 #define PAC_TYPE_A_ID 4
51 #define PAC_TYPE_I_ID 5
52 #define PAC_TYPE_SERVER_PROTECTED_DATA 6
53 #define PAC_TYPE_A_ID_INFO 7
54 #define PAC_TYPE_PAC_ACKNOWLEDGEMENT 8
55 #define PAC_TYPE_PAC_INFO 9
63 /* draft-cam-winget-eap-fast-provisioning-01.txt:
64 * 3.4 Key Derivations Used in the EAP-FAST Provisioning Exchange */
65 struct eap_fast_key_block_provisioning
{
66 /* Extra key material after TLS key_block */
67 u8 session_key_seed
[EAP_FAST_SKS_LEN
];
68 u8 server_challenge
[16];
69 u8 client_challenge
[16];
74 struct eap_fast_pac
*next
;
76 u8 pac_key
[EAP_FAST_PAC_KEY_LEN
];
78 size_t pac_opaque_len
;
90 struct eap_fast_data
{
91 struct eap_ssl_data ssl
;
95 const struct eap_method
*phase2_method
;
99 struct eap_method_type phase2_type
;
100 struct eap_method_type
*phase2_types
;
101 size_t num_phase2_types
;
102 int resuming
; /* starting a resumed session */
103 struct eap_fast_key_block_provisioning
*key_block_p
;
104 int provisioning_allowed
; /* is PAC provisioning allowed */
105 int provisioning
; /* doing PAC provisioning (not the normal auth) */
107 u8 key_data
[EAP_FAST_KEY_LEN
];
108 u8 emsk
[EAP_EMSK_LEN
];
111 struct eap_fast_pac
*pac
;
112 struct eap_fast_pac
*current_pac
;
114 int tls_master_secret_set
;
116 u8 simck
[EAP_FAST_SIMCK_LEN
];
121 static void eap_fast_free_pac(struct eap_fast_pac
*pac
)
123 os_free(pac
->pac_opaque
);
124 os_free(pac
->pac_info
);
127 os_free(pac
->a_id_info
);
132 static struct eap_fast_pac
* eap_fast_get_pac(struct eap_fast_data
*data
,
133 const u8
*a_id
, size_t a_id_len
)
135 struct eap_fast_pac
*pac
= data
->pac
;
138 if (pac
->a_id_len
== a_id_len
&&
139 os_memcmp(pac
->a_id
, a_id
, a_id_len
) == 0) {
148 static int eap_fast_add_pac(struct eap_fast_data
*data
,
149 struct eap_fast_pac
*entry
)
151 struct eap_fast_pac
*pac
, *prev
;
153 if (entry
== NULL
|| entry
->a_id
== NULL
)
156 /* Remove a possible old entry for the matching A-ID. */
160 if (pac
->a_id_len
== entry
->a_id_len
&&
161 os_memcmp(pac
->a_id
, entry
->a_id
, pac
->a_id_len
) == 0) {
163 data
->pac
= pac
->next
;
165 prev
->next
= pac
->next
;
167 if (data
->current_pac
== pac
)
168 data
->current_pac
= NULL
;
169 eap_fast_free_pac(pac
);
176 /* Allocate a new entry and add it to the list of PACs. */
177 pac
= os_zalloc(sizeof(*pac
));
181 os_memcpy(pac
->pac_key
, entry
->pac_key
, EAP_FAST_PAC_KEY_LEN
);
182 if (entry
->pac_opaque
) {
183 pac
->pac_opaque
= os_malloc(entry
->pac_opaque_len
);
184 if (pac
->pac_opaque
== NULL
) {
185 eap_fast_free_pac(pac
);
188 os_memcpy(pac
->pac_opaque
, entry
->pac_opaque
,
189 entry
->pac_opaque_len
);
190 pac
->pac_opaque_len
= entry
->pac_opaque_len
;
192 if (entry
->pac_info
) {
193 pac
->pac_info
= os_malloc(entry
->pac_info_len
);
194 if (pac
->pac_info
== NULL
) {
195 eap_fast_free_pac(pac
);
198 os_memcpy(pac
->pac_info
, entry
->pac_info
,
199 entry
->pac_info_len
);
200 pac
->pac_info_len
= entry
->pac_info_len
;
203 pac
->a_id
= os_malloc(entry
->a_id_len
);
204 if (pac
->a_id
== NULL
) {
205 eap_fast_free_pac(pac
);
208 os_memcpy(pac
->a_id
, entry
->a_id
,
210 pac
->a_id_len
= entry
->a_id_len
;
213 pac
->i_id
= os_malloc(entry
->i_id_len
);
214 if (pac
->i_id
== NULL
) {
215 eap_fast_free_pac(pac
);
218 os_memcpy(pac
->i_id
, entry
->i_id
,
220 pac
->i_id_len
= entry
->i_id_len
;
222 if (entry
->a_id_info
) {
223 pac
->a_id_info
= os_malloc(entry
->a_id_info_len
);
224 if (pac
->a_id_info
== NULL
) {
225 eap_fast_free_pac(pac
);
228 os_memcpy(pac
->a_id_info
, entry
->a_id_info
,
229 entry
->a_id_info_len
);
230 pac
->a_id_info_len
= entry
->a_id_info_len
;
232 pac
->next
= data
->pac
;
238 struct eap_fast_read_ctx
{
244 static int eap_fast_read_line(struct eap_fast_read_ctx
*rc
, char *buf
,
250 if (fgets(buf
, buf_len
, rc
->f
) == NULL
)
255 if (rc
->pos
>= rc
->end
)
258 while (l_end
< rc
->end
&& *l_end
!= '\n')
260 len
= l_end
- rc
->pos
;
263 os_memcpy(buf
, rc
->pos
, len
);
268 buf
[buf_len
- 1] = '\0';
270 while (*pos
!= '\0') {
271 if (*pos
== '\n' || *pos
== '\r') {
282 static u8
* eap_fast_parse_hex(const char *value
, size_t *len
)
289 hlen
= os_strlen(value
);
293 buf
= os_malloc(*len
);
296 if (hexstr2bin(value
, buf
, *len
)) {
304 static int eap_fast_load_pac(struct eap_sm
*sm
, struct eap_fast_data
*data
,
305 const char *pac_file
)
307 struct eap_fast_read_ctx rc
;
308 struct eap_fast_pac
*pac
= NULL
;
311 const int buf_len
= 2048;
312 int ret
= 0, line
= 0;
314 if (pac_file
== NULL
)
317 os_memset(&rc
, 0, sizeof(rc
));
319 if (os_strncmp(pac_file
, "blob://", 7) == 0) {
320 const struct wpa_config_blob
*blob
;
321 blob
= eap_get_config_blob(sm
, pac_file
+ 7);
323 wpa_printf(MSG_INFO
, "EAP-FAST: No PAC blob '%s' - "
324 "assume no PAC entries have been "
325 "provisioned", pac_file
+ 7);
328 rc
.pos
= (char *) blob
->data
;
329 rc
.end
= (char *) blob
->data
+ blob
->len
;
331 rc
.f
= fopen(pac_file
, "r");
333 wpa_printf(MSG_INFO
, "EAP-FAST: No PAC file '%s' - "
334 "assume no PAC entries have been "
335 "provisioned", pac_file
);
340 buf
= os_malloc(buf_len
);
346 if (eap_fast_read_line(&rc
, buf
, buf_len
) < 0 ||
347 os_strcmp(pac_file_hdr
, buf
) != 0) {
348 wpa_printf(MSG_INFO
, "EAP-FAST: Unrecognized header line in "
349 "PAC file '%s'", pac_file
);
356 while (eap_fast_read_line(&rc
, buf
, buf_len
) == 0) {
358 pos
= os_strchr(buf
, '=');
363 if (os_strcmp(buf
, "START") == 0) {
365 wpa_printf(MSG_INFO
, "EAP-FAST: START line "
366 "without END in '%s:%d'",
371 pac
= os_zalloc(sizeof(*pac
));
373 wpa_printf(MSG_INFO
, "EAP-FAST: No memory for "
378 } else if (os_strcmp(buf
, "END") == 0) {
380 wpa_printf(MSG_INFO
, "EAP-FAST: END line "
381 "without START in '%s:%d'",
386 pac
->next
= data
->pac
;
390 } else if (pac
&& os_strcmp(buf
, "PAC-Key") == 0) {
393 key
= eap_fast_parse_hex(pos
, &key_len
);
394 if (key
== NULL
|| key_len
!= EAP_FAST_PAC_KEY_LEN
) {
395 wpa_printf(MSG_INFO
, "EAP-FAST: Invalid "
396 "PAC-Key '%s:%d'", pac_file
, line
);
402 os_memcpy(pac
->pac_key
, key
, EAP_FAST_PAC_KEY_LEN
);
404 } else if (pac
&& os_strcmp(buf
, "PAC-Opaque") == 0) {
405 os_free(pac
->pac_opaque
);
407 eap_fast_parse_hex(pos
, &pac
->pac_opaque_len
);
408 if (pac
->pac_opaque
== NULL
) {
409 wpa_printf(MSG_INFO
, "EAP-FAST: Invalid "
410 "PAC-Opaque '%s:%d'",
415 } else if (pac
&& os_strcmp(buf
, "A-ID") == 0) {
417 pac
->a_id
= eap_fast_parse_hex(pos
, &pac
->a_id_len
);
418 if (pac
->a_id
== NULL
) {
419 wpa_printf(MSG_INFO
, "EAP-FAST: Invalid "
420 "A-ID '%s:%d'", pac_file
, line
);
424 } else if (pac
&& os_strcmp(buf
, "I-ID") == 0) {
426 pac
->i_id
= eap_fast_parse_hex(pos
, &pac
->i_id_len
);
427 if (pac
->i_id
== NULL
) {
428 wpa_printf(MSG_INFO
, "EAP-FAST: Invalid "
429 "I-ID '%s:%d'", pac_file
, line
);
433 } else if (pac
&& os_strcmp(buf
, "A-ID-Info") == 0) {
434 os_free(pac
->a_id_info
);
436 eap_fast_parse_hex(pos
, &pac
->a_id_info_len
);
437 if (pac
->a_id_info
== NULL
) {
438 wpa_printf(MSG_INFO
, "EAP-FAST: Invalid "
448 wpa_printf(MSG_INFO
, "EAP-FAST: PAC block not terminated with "
449 "END in '%s'", pac_file
);
450 eap_fast_free_pac(pac
);
459 wpa_printf(MSG_DEBUG
, "EAP-FAST: read %d PAC entries from "
460 "'%s'", count
, pac_file
);
467 static void eap_fast_write(char **buf
, char **pos
, size_t *buf_len
,
468 const char *field
, const u8
*data
,
474 if (data
== NULL
|| *buf
== NULL
)
477 need
= os_strlen(field
) + len
* 2 + 30;
479 need
+= os_strlen(field
) + len
+ 20;
481 if (*pos
- *buf
+ need
> *buf_len
) {
482 char *nbuf
= os_realloc(*buf
, *buf_len
+ need
);
492 ret
= os_snprintf(*pos
, *buf
+ *buf_len
- *pos
, "%s=", field
);
493 if (ret
< 0 || ret
>= *buf
+ *buf_len
- *pos
)
496 *pos
+= wpa_snprintf_hex(*pos
, *buf
+ *buf_len
- *pos
, data
, len
);
497 ret
= os_snprintf(*pos
, *buf
+ *buf_len
- *pos
, "\n");
498 if (ret
< 0 || ret
>= *buf
+ *buf_len
- *pos
)
503 ret
= os_snprintf(*pos
, *buf
+ *buf_len
- *pos
,
505 if (ret
< 0 || ret
>= *buf
+ *buf_len
- *pos
)
508 for (i
= 0; i
< len
; i
++) {
509 ret
= os_snprintf(*pos
, *buf
+ *buf_len
- *pos
,
511 if (ret
< 0 || ret
>= *buf
+ *buf_len
- *pos
)
515 ret
= os_snprintf(*pos
, *buf
+ *buf_len
- *pos
, "\n");
516 if (ret
< 0 || ret
>= *buf
+ *buf_len
- *pos
)
523 static int eap_fast_save_pac(struct eap_sm
*sm
, struct eap_fast_data
*data
,
524 const char *pac_file
)
527 struct eap_fast_pac
*pac
;
532 if (pac_file
== NULL
)
536 pos
= buf
= os_malloc(buf_len
);
540 ret
= os_snprintf(pos
, buf
+ buf_len
- pos
, "%s\n", pac_file_hdr
);
541 if (ret
< 0 || ret
>= buf
+ buf_len
- pos
) {
549 ret
= os_snprintf(pos
, buf
+ buf_len
- pos
, "START\n");
550 if (ret
< 0 || ret
>= buf
+ buf_len
- pos
) {
555 eap_fast_write(&buf
, &pos
, &buf_len
, "PAC-Key", pac
->pac_key
,
556 EAP_FAST_PAC_KEY_LEN
, 0);
557 eap_fast_write(&buf
, &pos
, &buf_len
, "PAC-Opaque",
558 pac
->pac_opaque
, pac
->pac_opaque_len
, 0);
559 eap_fast_write(&buf
, &pos
, &buf_len
, "PAC-Info", pac
->pac_info
,
560 pac
->pac_info_len
, 0);
561 eap_fast_write(&buf
, &pos
, &buf_len
, "A-ID", pac
->a_id
,
563 eap_fast_write(&buf
, &pos
, &buf_len
, "I-ID", pac
->i_id
,
565 eap_fast_write(&buf
, &pos
, &buf_len
, "A-ID-Info",
566 pac
->a_id_info
, pac
->a_id_info_len
, 1);
568 wpa_printf(MSG_DEBUG
, "EAP-FAST: No memory for PAC "
572 ret
= os_snprintf(pos
, buf
+ buf_len
- pos
, "END\n");
573 if (ret
< 0 || ret
>= buf
+ buf_len
- pos
) {
582 if (os_strncmp(pac_file
, "blob://", 7) == 0) {
583 struct wpa_config_blob
*blob
;
584 blob
= os_zalloc(sizeof(*blob
));
589 blob
->data
= (u8
*) buf
;
590 blob
->len
= pos
- buf
;
592 blob
->name
= os_strdup(pac_file
+ 7);
593 if (blob
->name
== NULL
) {
598 eap_set_config_blob(sm
, blob
);
600 f
= fopen(pac_file
, "w");
602 wpa_printf(MSG_INFO
, "EAP-FAST: Failed to open PAC "
603 "file '%s' for writing", pac_file
);
607 fprintf(f
, "%s", buf
);
612 wpa_printf(MSG_DEBUG
, "EAP-FAST: wrote %d PAC entries into '%s'",
619 static void * eap_fast_init(struct eap_sm
*sm
)
621 struct eap_fast_data
*data
;
622 struct wpa_ssid
*config
= eap_get_config(sm
);
624 data
= os_zalloc(sizeof(*data
));
627 data
->fast_version
= EAP_FAST_VERSION
;
629 if (config
&& config
->phase1
) {
630 if (os_strstr(config
->phase1
, "fast_provisioning=1")) {
631 data
->provisioning_allowed
= 1;
632 wpa_printf(MSG_DEBUG
, "EAP-FAST: Automatic PAC "
633 "provisioning is allowed");
637 if (config
&& config
->phase2
) {
638 char *start
, *pos
, *buf
;
639 struct eap_method_type
*methods
= NULL
, *_methods
;
641 size_t num_methods
= 0;
642 start
= buf
= os_strdup(config
->phase2
);
644 eap_fast_deinit(sm
, data
);
647 while (start
&& *start
!= '\0') {
649 pos
= os_strstr(start
, "auth=");
652 if (start
!= pos
&& *(pos
- 1) != ' ') {
658 pos
= os_strchr(start
, ' ');
661 method
= eap_get_phase2_type(start
, &vendor
);
662 if (vendor
== EAP_VENDOR_IETF
&&
663 method
== EAP_TYPE_NONE
) {
664 wpa_printf(MSG_ERROR
, "EAP-FAST: Unsupported "
665 "Phase2 method '%s'", start
);
668 _methods
= os_realloc(
670 num_methods
* sizeof(*methods
));
671 if (_methods
== NULL
) {
674 eap_fast_deinit(sm
, data
);
678 methods
[num_methods
- 1].vendor
= vendor
;
679 methods
[num_methods
- 1].method
= method
;
685 data
->phase2_types
= methods
;
686 data
->num_phase2_types
= num_methods
;
688 if (data
->phase2_types
== NULL
) {
690 eap_get_phase2_types(config
, &data
->num_phase2_types
);
692 if (data
->phase2_types
== NULL
) {
693 wpa_printf(MSG_ERROR
, "EAP-FAST: No Phase2 method available");
694 eap_fast_deinit(sm
, data
);
697 wpa_hexdump(MSG_DEBUG
, "EAP-FAST: Phase2 EAP types",
698 (u8
*) data
->phase2_types
,
699 data
->num_phase2_types
* sizeof(struct eap_method_type
));
700 data
->phase2_type
.vendor
= EAP_VENDOR_IETF
;
701 data
->phase2_type
.method
= EAP_TYPE_NONE
;
703 if (eap_tls_ssl_init(sm
, &data
->ssl
, config
)) {
704 wpa_printf(MSG_INFO
, "EAP-FAST: Failed to initialize SSL.");
705 eap_fast_deinit(sm
, data
);
709 /* The local RADIUS server in a Cisco AP does not seem to like empty
710 * fragments before data, so disable that workaround for CBC.
711 * TODO: consider making this configurable */
712 tls_connection_enable_workaround(sm
->ssl_ctx
, data
->ssl
.conn
);
714 if (eap_fast_load_pac(sm
, data
, config
->pac_file
) < 0) {
715 eap_fast_deinit(sm
, data
);
719 if (data
->pac
== NULL
&& !data
->provisioning_allowed
) {
720 wpa_printf(MSG_INFO
, "EAP-FAST: No PAC configured and "
721 "provisioning disabled");
722 eap_fast_deinit(sm
, data
);
730 static void eap_fast_deinit(struct eap_sm
*sm
, void *priv
)
732 struct eap_fast_data
*data
= priv
;
733 struct eap_fast_pac
*pac
, *prev
;
737 if (data
->phase2_priv
&& data
->phase2_method
)
738 data
->phase2_method
->deinit(sm
, data
->phase2_priv
);
739 os_free(data
->phase2_types
);
740 os_free(data
->key_block_p
);
741 eap_tls_ssl_deinit(sm
, &data
->ssl
);
748 eap_fast_free_pac(prev
);
754 static int eap_fast_encrypt(struct eap_sm
*sm
, struct eap_fast_data
*data
,
755 int id
, const u8
*plain
, size_t plain_len
,
756 u8
**out_data
, size_t *out_len
)
760 struct eap_hdr
*resp
;
762 /* TODO: add support for fragmentation, if needed. This will need to
763 * add TLS Message Length field, if the frame is fragmented. */
764 resp
= os_malloc(sizeof(struct eap_hdr
) + 2 + data
->ssl
.tls_out_limit
);
768 resp
->code
= EAP_CODE_RESPONSE
;
769 resp
->identifier
= id
;
771 pos
= (u8
*) (resp
+ 1);
772 *pos
++ = EAP_TYPE_FAST
;
773 *pos
++ = data
->fast_version
;
775 res
= tls_connection_encrypt(sm
->ssl_ctx
, data
->ssl
.conn
,
777 pos
, data
->ssl
.tls_out_limit
);
779 wpa_printf(MSG_INFO
, "EAP-FAST: Failed to encrypt Phase 2 "
785 *out_len
= sizeof(struct eap_hdr
) + 2 + res
;
786 resp
->length
= host_to_be16(*out_len
);
787 *out_data
= (u8
*) resp
;
792 static int eap_fast_phase2_nak(struct eap_fast_data
*data
,
794 u8
**resp
, size_t *resp_len
)
796 struct eap_hdr
*resp_hdr
;
797 u8
*pos
= (u8
*) (hdr
+ 1);
800 /* TODO: add support for expanded Nak */
801 wpa_printf(MSG_DEBUG
, "EAP-FAST: Phase 2 Request: Nak type=%d", *pos
);
802 wpa_hexdump(MSG_DEBUG
, "EAP-FAST: Allowed Phase2 EAP types",
803 (u8
*) data
->phase2_types
,
804 data
->num_phase2_types
* sizeof(struct eap_method_type
));
805 *resp_len
= sizeof(struct eap_hdr
) + 1;
806 *resp
= os_malloc(*resp_len
+ data
->num_phase2_types
);
810 resp_hdr
= (struct eap_hdr
*) (*resp
);
811 resp_hdr
->code
= EAP_CODE_RESPONSE
;
812 resp_hdr
->identifier
= hdr
->identifier
;
813 pos
= (u8
*) (resp_hdr
+ 1);
814 *pos
++ = EAP_TYPE_NAK
;
815 for (i
= 0; i
< data
->num_phase2_types
; i
++) {
816 if (data
->phase2_types
[i
].vendor
== EAP_VENDOR_IETF
&&
817 data
->phase2_types
[i
].method
< 256) {
819 *pos
++ = data
->phase2_types
[i
].method
;
822 resp_hdr
->length
= host_to_be16(*resp_len
);
828 static int eap_fast_derive_msk(struct eap_fast_data
*data
)
830 /* Derive EAP Master Session Keys (section 5.4) */
831 sha1_t_prf(data
->simck
, EAP_FAST_SIMCK_LEN
,
832 "Session Key Generating Function", (u8
*) "", 0,
833 data
->key_data
, EAP_FAST_KEY_LEN
);
834 wpa_hexdump_key(MSG_DEBUG
, "EAP-FAST: Derived key (MSK)",
835 data
->key_data
, EAP_FAST_KEY_LEN
);
837 sha1_t_prf(data
->simck
, EAP_FAST_SIMCK_LEN
,
838 "Extended Session Key Generating Function",
839 (u8
*) "", 0, data
->emsk
, EAP_EMSK_LEN
);
840 wpa_hexdump_key(MSG_DEBUG
, "EAP-FAST: Derived key (EMSK)",
841 data
->emsk
, EAP_EMSK_LEN
);
849 static int eap_fast_set_tls_master_secret(struct eap_sm
*sm
,
850 struct eap_fast_data
*data
,
851 const u8
*tls
, size_t tls_len
)
853 struct tls_keys keys
;
854 u8 master_secret
[48], *seed
;
855 const u8
*server_random
;
856 size_t seed_len
, server_random_len
;
858 if (data
->tls_master_secret_set
|| !data
->current_pac
||
859 tls_connection_get_keys(sm
->ssl_ctx
, data
->ssl
.conn
, &keys
) ||
860 keys
.client_random
== NULL
) {
864 wpa_hexdump(MSG_DEBUG
, "EAP-FAST: client_random",
865 keys
.client_random
, keys
.client_random_len
);
867 /* TLS master secret is needed before TLS library has processed this
868 * message which includes both ServerHello and an encrypted handshake
869 * message, so we need to parse server_random from this message before
870 * passing it to TLS library.
872 * Example TLS packet header:
873 * (16 03 01 00 2a 02 00 00 26 03 01 <32 bytes server_random>)
874 * Content Type: Handshake: 0x16
875 * Version: TLS 1.0 (0x0301)
876 * Lenghth: 42 (0x002a)
877 * Handshake Type: Server Hello: 0x02
878 * Length: 38 (0x000026)
879 * Version TLS 1.0 (0x0301)
882 if (tls_len
< 43 || tls
[0] != 0x16 ||
883 tls
[1] != 0x03 || tls
[2] != 0x01 ||
884 tls
[5] != 0x02 || tls
[9] != 0x03 || tls
[10] != 0x01) {
885 wpa_hexdump(MSG_DEBUG
, "EAP-FAST: unrecognized TLS "
886 "ServerHello", tls
, tls_len
);
889 server_random
= tls
+ 11;
890 server_random_len
= 32;
891 wpa_hexdump(MSG_DEBUG
, "EAP-FAST: server_random",
892 server_random
, server_random_len
);
894 seed_len
= keys
.client_random_len
+ server_random_len
;
895 seed
= os_malloc(seed_len
);
898 os_memcpy(seed
, server_random
, server_random_len
);
899 os_memcpy(seed
+ server_random_len
,
900 keys
.client_random
, keys
.client_random_len
);
902 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: T-PRF seed", seed
, seed_len
);
903 wpa_hexdump_key(MSG_MSGDUMP
, "EAP-FAST: PAC-Key",
904 data
->current_pac
->pac_key
, EAP_FAST_PAC_KEY_LEN
);
905 /* master_secret = T-PRF(PAC-Key, "PAC to master secret label hash",
906 * server_random + client_random, 48) */
907 sha1_t_prf(data
->current_pac
->pac_key
, EAP_FAST_PAC_KEY_LEN
,
908 "PAC to master secret label hash",
909 seed
, seed_len
, master_secret
, sizeof(master_secret
));
911 wpa_hexdump_key(MSG_DEBUG
, "EAP-FAST: TLS pre-master-secret",
912 master_secret
, sizeof(master_secret
));
914 data
->tls_master_secret_set
= 1;
916 return tls_connection_set_master_key(sm
->ssl_ctx
, data
->ssl
.conn
,
918 sizeof(master_secret
));
922 static u8
* eap_fast_derive_key(struct eap_sm
*sm
, struct eap_ssl_data
*data
,
923 char *label
, size_t len
)
925 struct tls_keys keys
;
926 u8
*rnd
= NULL
, *out
;
929 block_size
= tls_connection_get_keyblock_size(sm
->ssl_ctx
, data
->conn
);
933 out
= os_malloc(block_size
+ len
);
937 if (tls_connection_prf(sm
->ssl_ctx
, data
->conn
, label
, 1, out
,
938 block_size
+ len
) == 0) {
939 os_memmove(out
, out
+ block_size
, len
);
943 if (tls_connection_get_keys(sm
->ssl_ctx
, data
->conn
, &keys
))
946 rnd
= os_malloc(keys
.client_random_len
+ keys
.server_random_len
);
950 os_memcpy(rnd
, keys
.server_random
, keys
.server_random_len
);
951 os_memcpy(rnd
+ keys
.server_random_len
, keys
.client_random
,
952 keys
.client_random_len
);
954 wpa_hexdump_key(MSG_MSGDUMP
, "EAP-FAST: master_secret for key "
955 "expansion", keys
.master_key
, keys
.master_key_len
);
956 if (tls_prf(keys
.master_key
, keys
.master_key_len
,
957 label
, rnd
, keys
.client_random_len
+
958 keys
.server_random_len
, out
, block_size
+ len
))
961 os_memmove(out
, out
+ block_size
, len
);
971 static void eap_fast_derive_key_auth(struct eap_sm
*sm
,
972 struct eap_fast_data
*data
)
976 /* draft-cam-winget-eap-fast-05.txt:
977 * 5.1 EAP-FAST Authentication Phase 1: Key Derivations
978 * Extra key material after TLS key_block: session_ket_seed[40]
981 sks
= eap_fast_derive_key(sm
, &data
->ssl
, "key expansion",
984 wpa_printf(MSG_DEBUG
, "EAP-FAST: Failed to derive "
990 * draft-cam-winget-eap-fast-05.txt, 5.2:
991 * S-IMCK[0] = session_key_seed
993 wpa_hexdump_key(MSG_DEBUG
,
994 "EAP-FAST: session_key_seed (SKS = S-IMCK[0])",
995 sks
, EAP_FAST_SKS_LEN
);
997 os_memcpy(data
->simck
, sks
, EAP_FAST_SIMCK_LEN
);
1002 static void eap_fast_derive_key_provisioning(struct eap_sm
*sm
,
1003 struct eap_fast_data
*data
)
1005 os_free(data
->key_block_p
);
1006 data
->key_block_p
= (struct eap_fast_key_block_provisioning
*)
1007 eap_fast_derive_key(sm
, &data
->ssl
, "key expansion",
1008 sizeof(*data
->key_block_p
));
1009 if (data
->key_block_p
== NULL
) {
1010 wpa_printf(MSG_DEBUG
, "EAP-FAST: Failed to derive key block");
1014 * draft-cam-winget-eap-fast-05.txt, 5.2:
1015 * S-IMCK[0] = session_key_seed
1017 wpa_hexdump_key(MSG_DEBUG
,
1018 "EAP-FAST: session_key_seed (SKS = S-IMCK[0])",
1019 data
->key_block_p
->session_key_seed
,
1020 sizeof(data
->key_block_p
->session_key_seed
));
1021 data
->simck_idx
= 0;
1022 os_memcpy(data
->simck
, data
->key_block_p
->session_key_seed
,
1023 EAP_FAST_SIMCK_LEN
);
1024 wpa_hexdump_key(MSG_DEBUG
, "EAP-FAST: server_challenge",
1025 data
->key_block_p
->server_challenge
,
1026 sizeof(data
->key_block_p
->server_challenge
));
1027 wpa_hexdump_key(MSG_DEBUG
, "EAP-FAST: client_challenge",
1028 data
->key_block_p
->client_challenge
,
1029 sizeof(data
->key_block_p
->client_challenge
));
1033 static void eap_fast_derive_keys(struct eap_sm
*sm
, struct eap_fast_data
*data
)
1035 if (data
->current_pac
) {
1036 eap_fast_derive_key_auth(sm
, data
);
1038 eap_fast_derive_key_provisioning(sm
, data
);
1043 static int eap_fast_phase2_request(struct eap_sm
*sm
,
1044 struct eap_fast_data
*data
,
1045 struct eap_method_ret
*ret
,
1046 struct eap_hdr
*hdr
,
1047 u8
**resp
, size_t *resp_len
)
1049 size_t len
= be_to_host16(hdr
->length
);
1051 struct eap_method_ret iret
;
1053 if (len
<= sizeof(struct eap_hdr
)) {
1054 wpa_printf(MSG_INFO
, "EAP-FAST: too short "
1055 "Phase 2 request (len=%lu)", (unsigned long) len
);
1058 pos
= (u8
*) (hdr
+ 1);
1059 wpa_printf(MSG_DEBUG
, "EAP-FAST: Phase 2 Request: type=%d", *pos
);
1061 case EAP_TYPE_IDENTITY
:
1062 *resp
= eap_sm_buildIdentity(sm
, hdr
->identifier
, resp_len
, 1);
1065 if (data
->phase2_type
.vendor
== EAP_VENDOR_IETF
&&
1066 data
->phase2_type
.method
== EAP_TYPE_NONE
) {
1068 for (i
= 0; i
< data
->num_phase2_types
; i
++) {
1069 if (data
->phase2_types
[i
].vendor
!=
1071 data
->phase2_types
[i
].method
!= *pos
)
1074 data
->phase2_type
.vendor
=
1075 data
->phase2_types
[i
].vendor
;
1076 data
->phase2_type
.method
=
1077 data
->phase2_types
[i
].method
;
1078 wpa_printf(MSG_DEBUG
, "EAP-FAST: Selected "
1079 "Phase 2 EAP vendor %d method %d",
1080 data
->phase2_type
.vendor
,
1081 data
->phase2_type
.method
);
1085 if (*pos
!= data
->phase2_type
.method
||
1086 *pos
== EAP_TYPE_NONE
) {
1087 if (eap_fast_phase2_nak(data
, hdr
, resp
, resp_len
))
1092 if (data
->phase2_priv
== NULL
) {
1093 data
->phase2_method
= eap_sm_get_eap_methods(
1094 data
->phase2_type
.vendor
,
1095 data
->phase2_type
.method
);
1096 if (data
->phase2_method
) {
1097 if (data
->key_block_p
) {
1098 sm
->auth_challenge
=
1101 sm
->peer_challenge
=
1105 sm
->init_phase2
= 1;
1106 sm
->mschapv2_full_key
= 1;
1108 data
->phase2_method
->init(sm
);
1109 sm
->init_phase2
= 0;
1110 sm
->mschapv2_full_key
= 0;
1111 sm
->auth_challenge
= NULL
;
1112 sm
->peer_challenge
= NULL
;
1115 if (data
->phase2_priv
== NULL
|| data
->phase2_method
== NULL
) {
1116 wpa_printf(MSG_INFO
, "EAP-FAST: failed to initialize "
1117 "Phase 2 EAP method %d", *pos
);
1118 ret
->methodState
= METHOD_DONE
;
1119 ret
->decision
= DECISION_FAIL
;
1122 os_memset(&iret
, 0, sizeof(iret
));
1123 *resp
= data
->phase2_method
->process(sm
, data
->phase2_priv
,
1124 &iret
, (u8
*) hdr
, len
,
1126 if (*resp
== NULL
||
1127 (iret
.methodState
== METHOD_DONE
&&
1128 iret
.decision
== DECISION_FAIL
)) {
1129 ret
->methodState
= METHOD_DONE
;
1130 ret
->decision
= DECISION_FAIL
;
1131 } else if ((iret
.methodState
== METHOD_DONE
||
1132 iret
.methodState
== METHOD_MAY_CONT
) &&
1133 (iret
.decision
== DECISION_UNCOND_SUCC
||
1134 iret
.decision
== DECISION_COND_SUCC
)) {
1135 data
->phase2_success
= 1;
1145 static u8
* eap_fast_tlv_nak(int vendor_id
, int tlv_type
, size_t *len
)
1147 struct eap_tlv_nak_tlv
*nak
;
1148 *len
= sizeof(*nak
);
1149 nak
= os_malloc(*len
);
1152 nak
->tlv_type
= host_to_be16(EAP_TLV_TYPE_MANDATORY
| EAP_TLV_NAK_TLV
);
1153 nak
->length
= host_to_be16(6);
1154 nak
->vendor_id
= host_to_be32(vendor_id
);
1155 nak
->nak_type
= host_to_be16(tlv_type
);
1160 static u8
* eap_fast_tlv_result(int status
, int intermediate
, size_t *len
)
1162 struct eap_tlv_intermediate_result_tlv
*result
;
1163 *len
= sizeof(*result
);
1164 result
= os_malloc(*len
);
1167 result
->tlv_type
= host_to_be16(EAP_TLV_TYPE_MANDATORY
|
1169 EAP_TLV_INTERMEDIATE_RESULT_TLV
:
1170 EAP_TLV_RESULT_TLV
));
1171 result
->length
= host_to_be16(2);
1172 result
->status
= host_to_be16(status
);
1173 return (u8
*) result
;
1177 static u8
* eap_fast_tlv_pac_ack(size_t *len
)
1179 struct eap_tlv_result_tlv
*res
;
1180 struct eap_tlv_pac_ack_tlv
*ack
;
1182 *len
= sizeof(*res
) + sizeof(*ack
);
1183 res
= os_zalloc(*len
);
1187 res
->tlv_type
= host_to_be16(EAP_TLV_RESULT_TLV
|
1188 EAP_TLV_TYPE_MANDATORY
);
1189 res
->length
= host_to_be16(sizeof(*res
) - sizeof(struct eap_tlv_hdr
));
1190 res
->status
= host_to_be16(EAP_TLV_RESULT_SUCCESS
);
1192 ack
= (struct eap_tlv_pac_ack_tlv
*) (res
+ 1);
1193 ack
->tlv_type
= host_to_be16(EAP_TLV_PAC_TLV
|
1194 EAP_TLV_TYPE_MANDATORY
);
1195 ack
->length
= host_to_be16(sizeof(*ack
) - sizeof(struct eap_tlv_hdr
));
1196 ack
->pac_type
= host_to_be16(PAC_TYPE_PAC_ACKNOWLEDGEMENT
);
1197 ack
->pac_len
= host_to_be16(2);
1198 ack
->result
= host_to_be16(EAP_TLV_RESULT_SUCCESS
);
1204 static u8
* eap_fast_tlv_eap_payload(u8
*buf
, size_t *len
)
1206 struct eap_tlv_hdr
*tlv
;
1208 /* Encapsulate EAP packet in EAP Payload TLV */
1209 tlv
= os_malloc(sizeof(*tlv
) + *len
);
1211 wpa_printf(MSG_DEBUG
, "EAP-FAST: Failed to "
1212 "allocate memory for TLV "
1217 tlv
->tlv_type
= host_to_be16(EAP_TLV_TYPE_MANDATORY
|
1218 EAP_TLV_EAP_PAYLOAD_TLV
);
1219 tlv
->length
= host_to_be16(*len
);
1220 os_memcpy(tlv
+ 1, buf
, *len
);
1222 *len
+= sizeof(*tlv
);
1227 static u8
* eap_fast_process_crypto_binding(
1228 struct eap_sm
*sm
, struct eap_fast_data
*data
,
1229 struct eap_method_ret
*ret
,
1230 struct eap_tlv_crypto_binding__tlv
*_bind
, size_t bind_len
,
1231 size_t *resp_len
, int final
)
1234 struct eap_tlv_intermediate_result_tlv
*rresult
;
1235 struct eap_tlv_crypto_binding__tlv
*rbind
;
1236 u8 isk
[32], imck
[60], *cmk
, cmac
[20], *key
;
1240 wpa_printf(MSG_DEBUG
, "EAP-FAST: Crypto-Binding TLV: Version %d "
1241 "Received Version %d SubType %d",
1242 _bind
->version
, _bind
->received_version
, _bind
->subtype
);
1243 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: NONCE",
1244 _bind
->nonce
, sizeof(_bind
->nonce
));
1245 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: Compound MAC",
1246 _bind
->compound_mac
, sizeof(_bind
->compound_mac
));
1248 if (_bind
->version
!= EAP_FAST_VERSION
||
1249 _bind
->received_version
!= EAP_FAST_VERSION
||
1250 _bind
->subtype
!= EAP_TLV_CRYPTO_BINDING_SUBTYPE_REQUEST
) {
1251 wpa_printf(MSG_INFO
, "EAP-FAST: Invalid version/subtype in "
1252 "Crypto-Binding TLV: Version %d "
1253 "Received Version %d SubType %d",
1254 _bind
->version
, _bind
->received_version
,
1256 resp
= eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE
, 1,
1261 wpa_printf(MSG_DEBUG
, "EAP-FAST: Determining CMK[%d] for Compound MIC "
1262 "calculation", data
->simck_idx
+ 1);
1265 * draft-cam-winget-eap-fast-05.txt, 5.2:
1266 * IMCK[j] = T-PRF(S-IMCK[j-1], "Inner Methods Compound Keys",
1268 * S-IMCK[j] = first 40 octets of IMCK[j]
1269 * CMK[j] = last 20 octets of IMCK[j]
1272 os_memset(isk
, 0, sizeof(isk
));
1273 if (data
->phase2_method
== NULL
|| data
->phase2_priv
== NULL
) {
1274 wpa_printf(MSG_DEBUG
, "EAP-FAST: Phase 2 method not "
1278 if (data
->phase2_method
->isKeyAvailable
&& data
->phase2_method
->getKey
)
1280 if (!data
->phase2_method
->isKeyAvailable(sm
, data
->phase2_priv
)
1282 (key
= data
->phase2_method
->getKey(sm
, data
->phase2_priv
,
1283 &key_len
)) == NULL
) {
1284 wpa_printf(MSG_DEBUG
, "EAP-FAST: Could not get key "
1285 "material from Phase 2");
1288 if (key_len
> sizeof(isk
))
1289 key_len
= sizeof(isk
);
1290 os_memcpy(isk
, key
, key_len
);
1293 wpa_hexdump_key(MSG_MSGDUMP
, "EAP-FAST: ISK[j]", isk
, sizeof(isk
));
1294 sha1_t_prf(data
->simck
, EAP_FAST_SIMCK_LEN
,
1295 "Inner Methods Compound Keys",
1296 isk
, sizeof(isk
), imck
, sizeof(imck
));
1298 os_memcpy(data
->simck
, imck
, EAP_FAST_SIMCK_LEN
);
1299 wpa_hexdump_key(MSG_MSGDUMP
, "EAP-FAST: S-IMCK[j]",
1300 data
->simck
, EAP_FAST_SIMCK_LEN
);
1301 cmk
= imck
+ EAP_FAST_SIMCK_LEN
;
1302 wpa_hexdump_key(MSG_MSGDUMP
, "EAP-FAST: CMK[j]", cmk
, 20);
1304 os_memcpy(cmac
, _bind
->compound_mac
, sizeof(cmac
));
1305 os_memset(_bind
->compound_mac
, 0, sizeof(cmac
));
1306 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: Crypto-Binding TLV for Compound "
1307 "MAC calculation", (u8
*) _bind
, bind_len
);
1308 hmac_sha1(cmk
, 20, (u8
*) _bind
, bind_len
, _bind
->compound_mac
);
1309 res
= os_memcmp(cmac
, _bind
->compound_mac
, sizeof(cmac
));
1310 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: Received Compound MAC",
1311 cmac
, sizeof(cmac
));
1312 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: Calculated Compound MAC",
1313 _bind
->compound_mac
, sizeof(cmac
));
1315 wpa_printf(MSG_INFO
, "EAP-FAST: Compound MAC did not match");
1316 resp
= eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE
, 1,
1318 os_memcpy(_bind
->compound_mac
, cmac
, sizeof(cmac
));
1322 *resp_len
= sizeof(*rresult
) + sizeof(*rbind
);
1323 resp
= os_zalloc(*resp_len
);
1327 /* Both intermediate and final Result TLVs are identical, so ok to use
1328 * the same structure definition for them. */
1329 rresult
= (struct eap_tlv_intermediate_result_tlv
*) resp
;
1330 rresult
->tlv_type
= host_to_be16(EAP_TLV_TYPE_MANDATORY
|
1331 (final
? EAP_TLV_RESULT_TLV
:
1332 EAP_TLV_INTERMEDIATE_RESULT_TLV
));
1333 rresult
->length
= host_to_be16(2);
1334 rresult
->status
= host_to_be16(EAP_TLV_RESULT_SUCCESS
);
1336 if (!data
->provisioning
&& data
->phase2_success
&&
1337 eap_fast_derive_msk(data
) < 0) {
1338 wpa_printf(MSG_INFO
, "EAP-FAST: Failed to generate MSK");
1339 ret
->methodState
= METHOD_DONE
;
1340 ret
->decision
= DECISION_FAIL
;
1341 rresult
->status
= host_to_be16(EAP_TLV_RESULT_FAILURE
);
1342 data
->phase2_success
= 0;
1345 rbind
= (struct eap_tlv_crypto_binding__tlv
*) (rresult
+ 1);
1346 rbind
->tlv_type
= host_to_be16(EAP_TLV_TYPE_MANDATORY
|
1347 EAP_TLV_CRYPTO_BINDING_TLV_
);
1348 rbind
->length
= host_to_be16(sizeof(*rbind
) -
1349 sizeof(struct eap_tlv_hdr
));
1350 rbind
->version
= EAP_FAST_VERSION
;
1351 rbind
->received_version
= _bind
->version
;
1352 rbind
->subtype
= EAP_TLV_CRYPTO_BINDING_SUBTYPE_RESPONSE
;
1353 os_memcpy(rbind
->nonce
, _bind
->nonce
, sizeof(_bind
->nonce
));
1354 inc_byte_array(rbind
->nonce
, sizeof(rbind
->nonce
));
1355 hmac_sha1(cmk
, 20, (u8
*) rbind
, sizeof(*rbind
), rbind
->compound_mac
);
1357 wpa_printf(MSG_DEBUG
, "EAP-FAST: Reply Crypto-Binding TLV: Version %d "
1358 "Received Version %d SubType %d",
1359 rbind
->version
, rbind
->received_version
, rbind
->subtype
);
1360 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: NONCE",
1361 rbind
->nonce
, sizeof(rbind
->nonce
));
1362 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: Compound MAC",
1363 rbind
->compound_mac
, sizeof(rbind
->compound_mac
));
1365 if (final
&& data
->phase2_success
) {
1366 wpa_printf(MSG_DEBUG
, "EAP-FAST: Authentication completed "
1368 ret
->methodState
= METHOD_DONE
;
1369 ret
->decision
= DECISION_UNCOND_SUCC
;
1376 static u8
* eap_fast_process_pac(struct eap_sm
*sm
, struct eap_fast_data
*data
,
1377 struct eap_method_ret
*ret
,
1378 u8
*pac
, size_t pac_len
, size_t *resp_len
)
1380 struct wpa_ssid
*config
= eap_get_config(sm
);
1381 struct pac_tlv_hdr
*hdr
;
1384 int type
, pac_key_found
= 0;
1385 struct eap_fast_pac entry
;
1387 os_memset(&entry
, 0, sizeof(entry
));
1390 while (left
> sizeof(*hdr
)) {
1391 hdr
= (struct pac_tlv_hdr
*) pos
;
1392 type
= be_to_host16(hdr
->type
);
1393 len
= be_to_host16(hdr
->len
);
1394 pos
+= sizeof(*hdr
);
1395 left
-= sizeof(*hdr
);
1397 wpa_printf(MSG_DEBUG
, "EAP-FAST: PAC TLV overrun "
1398 "(type=%d len=%lu left=%lu)",
1399 type
, (unsigned long) len
,
1400 (unsigned long) left
);
1401 return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE
, 0,
1405 case PAC_TYPE_PAC_KEY
:
1406 wpa_hexdump_key(MSG_DEBUG
, "EAP-FAST: PAC-Key",
1408 if (len
!= EAP_FAST_PAC_KEY_LEN
) {
1409 wpa_printf(MSG_DEBUG
, "EAP-FAST: Invalid "
1410 "PAC-Key length %lu",
1411 (unsigned long) len
);
1415 os_memcpy(entry
.pac_key
, pos
, len
);
1417 case PAC_TYPE_PAC_OPAQUE
:
1418 wpa_hexdump(MSG_DEBUG
, "EAP-FAST: PAC-Opaque",
1420 entry
.pac_opaque
= pos
;
1421 entry
.pac_opaque_len
= len
;
1423 case PAC_TYPE_PAC_INFO
:
1424 wpa_hexdump(MSG_DEBUG
, "EAP-FAST: PAC-Info",
1426 entry
.pac_info
= pos
;
1427 entry
.pac_info_len
= len
;
1430 wpa_printf(MSG_DEBUG
, "EAP-FAST: Ignored unknown PAC "
1439 if (!pac_key_found
|| !entry
.pac_opaque
|| !entry
.pac_info
) {
1440 wpa_printf(MSG_DEBUG
, "EAP-FAST: PAC TLV does not include "
1441 "all the required fields");
1442 return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE
, 0,
1446 pos
= entry
.pac_info
;
1447 left
= entry
.pac_info_len
;
1448 while (left
> sizeof(*hdr
)) {
1449 hdr
= (struct pac_tlv_hdr
*) pos
;
1450 type
= be_to_host16(hdr
->type
);
1451 len
= be_to_host16(hdr
->len
);
1452 pos
+= sizeof(*hdr
);
1453 left
-= sizeof(*hdr
);
1455 wpa_printf(MSG_DEBUG
, "EAP-FAST: PAC-Info overrun "
1456 "(type=%d len=%lu left=%lu)",
1457 type
, (unsigned long) len
,
1458 (unsigned long) left
);
1459 return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE
, 0,
1464 wpa_hexdump_ascii(MSG_DEBUG
, "EAP-FAST: PAC-Info - "
1467 entry
.a_id_len
= len
;
1470 wpa_hexdump_ascii(MSG_DEBUG
, "EAP-FAST: PAC-Info - "
1473 entry
.i_id_len
= len
;
1475 case PAC_TYPE_A_ID_INFO
:
1476 wpa_hexdump_ascii(MSG_DEBUG
, "EAP-FAST: PAC-Info - "
1477 "A-ID-Info", pos
, len
);
1478 entry
.a_id_info
= pos
;
1479 entry
.a_id_info_len
= len
;
1482 wpa_printf(MSG_DEBUG
, "EAP-FAST: Ignored unknown "
1483 "PAC-Info type %d", type
);
1491 if (entry
.a_id
== NULL
|| entry
.a_id_info
== NULL
) {
1492 wpa_printf(MSG_DEBUG
, "EAP-FAST: PAC-Info does not include "
1493 "all the required fields");
1494 return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE
, 0,
1498 eap_fast_add_pac(data
, &entry
);
1499 eap_fast_save_pac(sm
, data
, config
->pac_file
);
1501 if (data
->provisioning
) {
1502 /* EAP-FAST provisioning does not provide keying material and
1503 * must end with an EAP-Failure. Authentication will be done
1504 * separately after this. */
1506 ret
->decision
= DECISION_FAIL
;
1507 wpa_printf(MSG_DEBUG
, "EAP-FAST: Send PAC-Acknowledgement TLV "
1508 "- Provisioning completed successfully");
1510 /* This is PAC refreshing, i.e., normal authentication that is
1511 * expected to be completed with an EAP-Success. */
1512 wpa_printf(MSG_DEBUG
, "EAP-FAST: Send PAC-Acknowledgement TLV "
1513 "- PAC refreshing completed successfully");
1514 ret
->decision
= DECISION_UNCOND_SUCC
;
1516 ret
->methodState
= METHOD_DONE
;
1517 return eap_fast_tlv_pac_ack(resp_len
);
1521 static int eap_fast_decrypt(struct eap_sm
*sm
, struct eap_fast_data
*data
,
1522 struct eap_method_ret
*ret
,
1523 const struct eap_hdr
*req
,
1524 const u8
*in_data
, size_t in_len
,
1525 u8
**out_data
, size_t *out_len
)
1527 u8
*in_decrypted
, *pos
, *end
;
1528 int len_decrypted
, len
;
1529 struct eap_hdr
*hdr
;
1531 size_t buf_len
, resp_len
;
1532 int mandatory
, tlv_type
;
1533 u8
*eap_payload_tlv
= NULL
, *pac
= NULL
;
1534 size_t eap_payload_tlv_len
= 0, pac_len
= 0;
1535 int iresult
= 0, result
= 0;
1536 struct eap_tlv_crypto_binding__tlv
*crypto_binding
= NULL
;
1537 size_t crypto_binding_len
= 0;
1540 int need_more_input
, stop
;
1542 wpa_printf(MSG_DEBUG
, "EAP-FAST: received %lu bytes encrypted data for"
1543 " Phase 2", (unsigned long) in_len
);
1545 msg
= eap_tls_data_reassemble(sm
, &data
->ssl
, in_data
, in_len
,
1546 &msg_len
, &need_more_input
);
1548 return need_more_input
? 1 : -1;
1551 if (data
->ssl
.tls_in_total
> buf_len
)
1552 buf_len
= data
->ssl
.tls_in_total
;
1553 in_decrypted
= os_malloc(buf_len
);
1554 if (in_decrypted
== NULL
) {
1555 os_free(data
->ssl
.tls_in
);
1556 data
->ssl
.tls_in
= NULL
;
1557 data
->ssl
.tls_in_len
= 0;
1558 wpa_printf(MSG_WARNING
, "EAP-FAST: failed to allocate memory "
1563 len_decrypted
= tls_connection_decrypt(sm
->ssl_ctx
, data
->ssl
.conn
,
1565 in_decrypted
, buf_len
);
1566 os_free(data
->ssl
.tls_in
);
1567 data
->ssl
.tls_in
= NULL
;
1568 data
->ssl
.tls_in_len
= 0;
1569 if (len_decrypted
< 0) {
1570 wpa_printf(MSG_INFO
, "EAP-FAST: Failed to decrypt Phase 2 "
1572 os_free(in_decrypted
);
1576 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: Decrypted Phase 2 TLV(s)",
1577 in_decrypted
, len_decrypted
);
1579 if (len_decrypted
< 4) {
1580 os_free(in_decrypted
);
1581 wpa_printf(MSG_INFO
, "EAP-FAST: Too short Phase 2 "
1582 "TLV frame (len=%d)", len_decrypted
);
1587 end
= in_decrypted
+ len_decrypted
;
1589 while (pos
+ 4 < end
&& !stop
) {
1590 mandatory
= pos
[0] & 0x80;
1591 tlv_type
= WPA_GET_BE16(pos
) & 0x3fff;
1593 len
= WPA_GET_BE16(pos
);
1595 if (pos
+ len
> end
) {
1596 os_free(in_decrypted
);
1597 wpa_printf(MSG_INFO
, "EAP-FAST: TLV overflow");
1600 wpa_printf(MSG_DEBUG
, "EAP-FAST: received Phase 2: "
1601 "TLV type %d length %d%s",
1602 tlv_type
, len
, mandatory
? " (mandatory)" : "");
1605 case EAP_TLV_EAP_PAYLOAD_TLV
:
1606 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: EAP Payload TLV",
1608 eap_payload_tlv
= pos
;
1609 eap_payload_tlv_len
= len
;
1611 case EAP_TLV_RESULT_TLV
:
1612 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: Result TLV",
1615 wpa_printf(MSG_DEBUG
, "EAP-FAST: Too short "
1617 result
= EAP_TLV_RESULT_FAILURE
;
1620 result
= WPA_GET_BE16(pos
);
1621 if (result
!= EAP_TLV_RESULT_SUCCESS
&&
1622 result
!= EAP_TLV_RESULT_FAILURE
) {
1623 wpa_printf(MSG_DEBUG
, "EAP-FAST: Unknown "
1624 "Result %d", result
);
1625 result
= EAP_TLV_RESULT_FAILURE
;
1627 wpa_printf(MSG_DEBUG
, "EAP-FAST: Result: %s",
1628 result
== EAP_TLV_RESULT_SUCCESS
?
1629 "Success" : "Failure");
1631 case EAP_TLV_INTERMEDIATE_RESULT_TLV
:
1632 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: Intermediate "
1633 "Result TLV", pos
, len
);
1635 wpa_printf(MSG_DEBUG
, "EAP-FAST: Too short "
1636 "Intermediate Result TLV");
1637 iresult
= EAP_TLV_RESULT_FAILURE
;
1640 iresult
= WPA_GET_BE16(pos
);
1641 if (iresult
!= EAP_TLV_RESULT_SUCCESS
&&
1642 iresult
!= EAP_TLV_RESULT_FAILURE
) {
1643 wpa_printf(MSG_DEBUG
, "EAP-FAST: Unknown "
1644 "Intermediate Result %d", iresult
);
1645 iresult
= EAP_TLV_RESULT_FAILURE
;
1647 wpa_printf(MSG_DEBUG
,
1648 "EAP-FAST: Intermediate Result: %s",
1649 iresult
== EAP_TLV_RESULT_SUCCESS
?
1650 "Success" : "Failure");
1652 case EAP_TLV_CRYPTO_BINDING_TLV_
:
1653 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: Crypto-Binding "
1655 crypto_binding_len
= sizeof(struct eap_tlv_hdr
) + len
;
1656 if (crypto_binding_len
< sizeof(*crypto_binding
)) {
1657 wpa_printf(MSG_DEBUG
, "EAP-FAST: Too short "
1658 "Crypto-Binding TLV");
1659 iresult
= EAP_TLV_RESULT_FAILURE
;
1664 (struct eap_tlv_crypto_binding__tlv
*)
1665 (pos
- sizeof(struct eap_tlv_hdr
));
1667 case EAP_TLV_PAC_TLV
:
1668 wpa_hexdump(MSG_MSGDUMP
, "EAP-FAST: PAC TLV",
1675 wpa_printf(MSG_DEBUG
, "EAP-FAST: Nak unknown "
1676 "mandatory TLV type %d", tlv_type
);
1677 resp
= eap_fast_tlv_nak(0, tlv_type
,
1681 wpa_printf(MSG_DEBUG
, "EAP-FAST: ignored "
1682 "unknown optional TLV type %d",
1691 if (!resp
&& result
== EAP_TLV_RESULT_FAILURE
) {
1692 resp
= eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE
, 0,
1695 os_free(in_decrypted
);
1700 if (!resp
&& iresult
== EAP_TLV_RESULT_FAILURE
) {
1701 resp
= eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE
, 1,
1704 os_free(in_decrypted
);
1709 if (!resp
&& eap_payload_tlv
) {
1710 if (eap_payload_tlv_len
< sizeof(*hdr
)) {
1711 wpa_printf(MSG_DEBUG
, "EAP-FAST: too short EAP "
1712 "Payload TLV (len=%lu)",
1713 (unsigned long) eap_payload_tlv_len
);
1714 os_free(in_decrypted
);
1717 hdr
= (struct eap_hdr
*) eap_payload_tlv
;
1718 if (be_to_host16(hdr
->length
) > eap_payload_tlv_len
) {
1719 wpa_printf(MSG_DEBUG
, "EAP-FAST: EAP packet overflow "
1720 "in EAP Payload TLV");
1721 os_free(in_decrypted
);
1724 if (hdr
->code
== EAP_CODE_REQUEST
) {
1725 if (eap_fast_phase2_request(sm
, data
, ret
, hdr
,
1726 &resp
, &resp_len
)) {
1727 os_free(in_decrypted
);
1728 wpa_printf(MSG_INFO
, "EAP-FAST: Phase2 "
1729 "Request processing failed");
1732 resp
= eap_fast_tlv_eap_payload(resp
, &resp_len
);
1734 os_free(in_decrypted
);
1738 wpa_printf(MSG_INFO
, "EAP-FAST: Unexpected code=%d in "
1739 "Phase 2 EAP header", hdr
->code
);
1740 os_free(in_decrypted
);
1745 if (!resp
&& crypto_binding
) {
1746 int final
= result
== EAP_TLV_RESULT_SUCCESS
;
1747 resp
= eap_fast_process_crypto_binding(sm
, data
, ret
,
1752 os_free(in_decrypted
);
1757 if (!resp
&& pac
&& result
!= EAP_TLV_RESULT_SUCCESS
) {
1758 wpa_printf(MSG_DEBUG
, "EAP-FAST: PAC TLV without Result TLV "
1759 "acknowledging success");
1760 resp
= eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE
, 0,
1763 os_free(in_decrypted
);
1768 if (!resp
&& pac
&& result
== EAP_TLV_RESULT_SUCCESS
) {
1769 resp
= eap_fast_process_pac(sm
, data
, ret
, pac
, pac_len
,
1772 os_free(in_decrypted
);
1777 os_free(in_decrypted
);
1780 wpa_printf(MSG_DEBUG
, "EAP-FAST: No recognized TLVs - send "
1781 "empty response packet");
1782 resp
= os_malloc(1);
1788 wpa_hexdump(MSG_DEBUG
, "EAP-FAST: Encrypting Phase 2 data",
1790 if (eap_fast_encrypt(sm
, data
, req
->identifier
, resp
, resp_len
,
1791 out_data
, out_len
)) {
1792 wpa_printf(MSG_INFO
, "EAP-FAST: Failed to encrypt a Phase 2 "
1801 static u8
* eap_fast_process(struct eap_sm
*sm
, void *priv
,
1802 struct eap_method_ret
*ret
,
1803 const u8
*reqData
, size_t reqDataLen
,
1804 size_t *respDataLen
)
1806 const struct eap_hdr
*req
;
1809 u8 flags
, *resp
, id
;
1811 struct eap_fast_data
*data
= priv
;
1813 pos
= eap_tls_process_init(sm
, &data
->ssl
, EAP_TYPE_FAST
, ret
,
1814 reqData
, reqDataLen
, &left
, &flags
);
1817 req
= (const struct eap_hdr
*) reqData
;
1818 id
= req
->identifier
;
1820 if (flags
& EAP_TLS_FLAGS_START
) {
1823 struct pac_tlv_hdr
*hdr
;
1825 wpa_printf(MSG_DEBUG
, "EAP-FAST: Start (server ver=%d, own "
1826 "ver=%d)", flags
& EAP_PEAP_VERSION_MASK
,
1827 data
->fast_version
);
1828 if ((flags
& EAP_PEAP_VERSION_MASK
) < data
->fast_version
)
1829 data
->fast_version
= flags
& EAP_PEAP_VERSION_MASK
;
1830 wpa_printf(MSG_DEBUG
, "EAP-FAST: Using FAST version %d",
1831 data
->fast_version
);
1835 if (left
> sizeof(*hdr
)) {
1837 hdr
= (struct pac_tlv_hdr
*) pos
;
1838 tlen
= be_to_host16(hdr
->len
);
1839 if (be_to_host16(hdr
->type
) == PAC_TYPE_A_ID
&&
1840 sizeof(*hdr
) + tlen
<= left
) {
1841 a_id
= (u8
*) (hdr
+ 1);
1845 wpa_hexdump_ascii(MSG_DEBUG
, "EAP-FAST: A-ID", a_id
, a_id_len
);
1847 data
->current_pac
= eap_fast_get_pac(data
, a_id
, a_id_len
);
1848 if (data
->current_pac
) {
1849 wpa_printf(MSG_DEBUG
, "EAP-FAST: PAC found for this "
1851 wpa_hexdump_ascii(MSG_MSGDUMP
, "EAP-FAST: A-ID-Info",
1852 data
->current_pac
->a_id_info
,
1853 data
->current_pac
->a_id_info_len
);
1856 if (data
->resuming
&& data
->current_pac
) {
1857 wpa_printf(MSG_DEBUG
, "EAP-FAST: Trying to resume "
1858 "session - do not add PAC-Opaque to TLS "
1860 if (tls_connection_client_hello_ext(
1861 sm
->ssl_ctx
, data
->ssl
.conn
,
1862 TLS_EXT_PAC_OPAQUE
, NULL
, 0) < 0) {
1863 wpa_printf(MSG_DEBUG
, "EAP-FAST: Failed to "
1864 "remove PAC-Opaque TLS extension");
1868 } else if (data
->current_pac
) {
1870 size_t tlv_len
, olen
;
1871 struct eap_tlv_hdr
*ehdr
;
1872 olen
= data
->current_pac
->pac_opaque_len
;
1873 tlv_len
= sizeof(*ehdr
) + olen
;
1874 tlv
= os_malloc(tlv_len
);
1876 ehdr
= (struct eap_tlv_hdr
*) tlv
;
1878 host_to_be16(PAC_TYPE_PAC_OPAQUE
);
1879 ehdr
->length
= host_to_be16(olen
);
1881 data
->current_pac
->pac_opaque
, olen
);
1884 tls_connection_client_hello_ext(
1885 sm
->ssl_ctx
, data
->ssl
.conn
,
1886 TLS_EXT_PAC_OPAQUE
, tlv
, tlv_len
) < 0) {
1887 wpa_printf(MSG_DEBUG
, "EAP-FAST: Failed to "
1888 "add PAC-Opaque TLS extension");
1895 if (!data
->provisioning_allowed
) {
1896 wpa_printf(MSG_DEBUG
, "EAP-FAST: No PAC found "
1897 "and provisioning disabled");
1900 wpa_printf(MSG_DEBUG
, "EAP-FAST: No PAC found - "
1901 "starting provisioning");
1902 ciphers
[0] = TLS_CIPHER_ANON_DH_AES128_SHA
;
1903 ciphers
[1] = TLS_CIPHER_NONE
;
1904 if (tls_connection_set_cipher_list(sm
->ssl_ctx
,
1907 wpa_printf(MSG_INFO
, "EAP-FAST: Could not "
1908 "configure anonymous DH for TLS "
1912 if (tls_connection_client_hello_ext(
1913 sm
->ssl_ctx
, data
->ssl
.conn
,
1914 TLS_EXT_PAC_OPAQUE
, NULL
, 0) < 0) {
1915 wpa_printf(MSG_DEBUG
, "EAP-FAST: Failed to "
1916 "remove PAC-Opaque TLS extension");
1919 data
->provisioning
= 1;
1922 left
= 0; /* A-ID is not used in further packet processing */
1926 if (tls_connection_established(sm
->ssl_ctx
, data
->ssl
.conn
) &&
1928 res
= eap_fast_decrypt(sm
, data
, ret
, req
, pos
, left
,
1929 &resp
, respDataLen
);
1931 ret
->methodState
= METHOD_DONE
;
1932 ret
->decision
= DECISION_FAIL
;
1933 /* Ack possible Alert that may have caused failure in
1938 if (eap_fast_set_tls_master_secret(sm
, data
, pos
, left
) < 0) {
1939 wpa_printf(MSG_DEBUG
, "EAP-FAST: Failed to configure "
1940 "TLS master secret");
1941 ret
->methodState
= METHOD_DONE
;
1942 ret
->decision
= DECISION_FAIL
;
1946 res
= eap_tls_process_helper(sm
, &data
->ssl
, EAP_TYPE_FAST
,
1947 data
->fast_version
, id
, pos
, left
,
1948 &resp
, respDataLen
);
1950 if (tls_connection_established(sm
->ssl_ctx
, data
->ssl
.conn
)) {
1951 wpa_printf(MSG_DEBUG
,
1952 "EAP-FAST: TLS done, proceed to Phase 2");
1954 eap_fast_derive_keys(sm
, data
);
1959 return eap_tls_build_ack(&data
->ssl
, respDataLen
, id
,
1960 EAP_TYPE_FAST
, data
->fast_version
);
1966 static Boolean
eap_fast_has_reauth_data(struct eap_sm
*sm
, void *priv
)
1968 struct eap_fast_data
*data
= priv
;
1969 return tls_connection_established(sm
->ssl_ctx
, data
->ssl
.conn
);
1973 static void eap_fast_deinit_for_reauth(struct eap_sm
*sm
, void *priv
)
1975 struct eap_fast_data
*data
= priv
;
1976 os_free(data
->key_block_p
);
1977 data
->key_block_p
= NULL
;
1981 static void * eap_fast_init_for_reauth(struct eap_sm
*sm
, void *priv
)
1983 struct eap_fast_data
*data
= priv
;
1984 if (eap_tls_reauth_init(sm
, &data
->ssl
)) {
1988 if (data
->phase2_priv
&& data
->phase2_method
&&
1989 data
->phase2_method
->init_for_reauth
)
1990 data
->phase2_method
->init_for_reauth(sm
, data
->phase2_priv
);
1991 data
->phase2_success
= 0;
1993 data
->provisioning
= 0;
1994 data
->simck_idx
= 0;
2000 static int eap_fast_get_status(struct eap_sm
*sm
, void *priv
, char *buf
,
2001 size_t buflen
, int verbose
)
2003 struct eap_fast_data
*data
= priv
;
2006 len
= eap_tls_status(sm
, &data
->ssl
, buf
, buflen
, verbose
);
2007 if (data
->phase2_method
) {
2008 ret
= os_snprintf(buf
+ len
, buflen
- len
,
2009 "EAP-FAST Phase2 method=%s\n",
2010 data
->phase2_method
->name
);
2011 if (ret
< 0 || (size_t) ret
>= buflen
- len
)
2019 static Boolean
eap_fast_isKeyAvailable(struct eap_sm
*sm
, void *priv
)
2021 struct eap_fast_data
*data
= priv
;
2022 return data
->success
;
2026 static u8
* eap_fast_getKey(struct eap_sm
*sm
, void *priv
, size_t *len
)
2028 struct eap_fast_data
*data
= priv
;
2034 key
= os_malloc(EAP_FAST_KEY_LEN
);
2038 *len
= EAP_FAST_KEY_LEN
;
2039 os_memcpy(key
, data
->key_data
, EAP_FAST_KEY_LEN
);
2045 static u8
* eap_fast_get_emsk(struct eap_sm
*sm
, void *priv
, size_t *len
)
2047 struct eap_fast_data
*data
= priv
;
2053 key
= os_malloc(EAP_EMSK_LEN
);
2057 *len
= EAP_EMSK_LEN
;
2058 os_memcpy(key
, data
->emsk
, EAP_EMSK_LEN
);
2064 int eap_peer_fast_register(void)
2066 struct eap_method
*eap
;
2069 eap
= eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION
,
2070 EAP_VENDOR_IETF
, EAP_TYPE_FAST
, "FAST");
2074 eap
->init
= eap_fast_init
;
2075 eap
->deinit
= eap_fast_deinit
;
2076 eap
->process
= eap_fast_process
;
2077 eap
->isKeyAvailable
= eap_fast_isKeyAvailable
;
2078 eap
->getKey
= eap_fast_getKey
;
2079 eap
->get_status
= eap_fast_get_status
;
2081 eap
->has_reauth_data
= eap_fast_has_reauth_data
;
2082 eap
->deinit_for_reauth
= eap_fast_deinit_for_reauth
;
2083 eap
->init_for_reauth
= eap_fast_init_for_reauth
;
2085 eap
->get_emsk
= eap_fast_get_emsk
;
2087 ret
= eap_peer_method_register(eap
);
2089 eap_peer_method_free(eap
);