diff --git a/hostapd/Makefile b/hostapd/Makefile index 123b0980f..c0b68e05a 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -246,6 +246,7 @@ endif ifdef CONFIG_EAP_FAST CFLAGS += -DEAP_FAST OBJS += ../src/eap_server/eap_fast.o +OBJS += ../src/eap_common/eap_fast_common.o TLS_FUNCS=y NEED_T_PRF=y endif diff --git a/src/eap_common/eap_fast_common.c b/src/eap_common/eap_fast_common.c new file mode 100644 index 000000000..039c40eea --- /dev/null +++ b/src/eap_common/eap_fast_common.c @@ -0,0 +1,43 @@ +/* + * EAP-FAST common helper functions (RFC 4851) + * Copyright (c) 2008, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "eap_fast_common.h" + + +void eap_fast_put_tlv_hdr(struct wpabuf *buf, u16 type, u16 len) +{ + struct pac_tlv_hdr hdr; + hdr.type = host_to_be16(type); + hdr.len = host_to_be16(len); + wpabuf_put_data(buf, &hdr, sizeof(hdr)); +} + + +void eap_fast_put_tlv(struct wpabuf *buf, u16 type, const void *data, + u16 len) +{ + eap_fast_put_tlv_hdr(buf, type, len); + wpabuf_put_data(buf, data, len); +} + + +void eap_fast_put_tlv_buf(struct wpabuf *buf, u16 type, + const struct wpabuf *data) +{ + eap_fast_put_tlv_hdr(buf, type, wpabuf_len(data)); + wpabuf_put_buf(buf, data); +} diff --git a/src/eap_common/eap_fast_common.h b/src/eap_common/eap_fast_common.h index 5d821dab2..e69b7a0f3 100644 --- a/src/eap_common/eap_fast_common.h +++ b/src/eap_common/eap_fast_common.h @@ -82,4 +82,13 @@ struct eap_fast_key_block_provisioning { u8 client_challenge[16]; /* MSCHAPv2 ClientChallenge */ }; + +struct wpabuf; + +void eap_fast_put_tlv_hdr(struct wpabuf *buf, u16 type, u16 len); +void eap_fast_put_tlv(struct wpabuf *buf, u16 type, const void *data, + u16 len); +void eap_fast_put_tlv_buf(struct wpabuf *buf, u16 type, + const struct wpabuf *data); + #endif /* EAP_FAST_H */ diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c index caca89e5f..0d2e28cd6 100644 --- a/src/eap_peer/eap_fast.c +++ b/src/eap_peer/eap_fast.c @@ -599,24 +599,21 @@ static struct wpabuf * eap_fast_tlv_pac_ack(void) static struct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf) { struct wpabuf *msg; - struct eap_tlv_hdr *tlv; if (buf == NULL) return NULL; /* Encapsulate EAP packet in EAP Payload TLV */ - msg = wpabuf_alloc(sizeof(*tlv) + wpabuf_len(buf)); + msg = wpabuf_alloc(sizeof(struct pac_tlv_hdr) + wpabuf_len(buf)); if (msg == NULL) { wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory " "for TLV encapsulation"); wpabuf_free(buf); return NULL; } - tlv = wpabuf_put(msg, sizeof(*tlv)); - tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY | - EAP_TLV_EAP_PAYLOAD_TLV); - tlv->length = host_to_be16(wpabuf_len(buf)); - wpabuf_put_buf(msg, buf); + eap_fast_put_tlv_buf(msg, + EAP_TLV_TYPE_MANDATORY | EAP_TLV_EAP_PAYLOAD_TLV, + buf); wpabuf_free(buf); return msg; } diff --git a/src/eap_server/eap_fast.c b/src/eap_server/eap_fast.c index 390637bd8..7fd41f9ae 100644 --- a/src/eap_server/eap_fast.c +++ b/src/eap_server/eap_fast.c @@ -546,11 +546,10 @@ static struct wpabuf * eap_fast_build_start(struct eap_sm *sm, struct eap_fast_data *data, u8 id) { struct wpabuf *req; - struct pac_tlv_hdr *a_id; size_t srv_id_len = os_strlen(data->srv_id); req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_FAST, - 1 + sizeof(*a_id) + srv_id_len, + 1 + sizeof(struct pac_tlv_hdr) + srv_id_len, EAP_CODE_REQUEST, id); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-FAST: Failed to allocate memory for" @@ -560,10 +559,9 @@ static struct wpabuf * eap_fast_build_start(struct eap_sm *sm, } wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->fast_version); - a_id = wpabuf_put(req, sizeof(*a_id)); - a_id->type = host_to_be16(PAC_TYPE_A_ID); - a_id->len = host_to_be16(srv_id_len); - wpabuf_put_data(req, data->srv_id, srv_id_len); + + /* RFC 4851, 4.1.1. Authority ID Data */ + eap_fast_put_tlv(req, PAC_TYPE_A_ID, data->srv_id, srv_id_len); eap_fast_state(data, PHASE1); @@ -658,25 +656,22 @@ static struct wpabuf * eap_fast_encrypt(struct eap_sm *sm, static struct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf) { struct wpabuf *e; - struct eap_tlv_hdr *tlv; if (buf == NULL) return NULL; /* Encapsulate EAP packet in EAP-Payload TLV */ wpa_printf(MSG_DEBUG, "EAP-FAST: Add EAP-Payload TLV"); - e = wpabuf_alloc(sizeof(*tlv) + wpabuf_len(buf)); + e = wpabuf_alloc(sizeof(struct pac_tlv_hdr) + wpabuf_len(buf)); if (e == NULL) { wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory " "for TLV encapsulation"); wpabuf_free(buf); return NULL; } - tlv = wpabuf_put(e, sizeof(*tlv)); - tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY | - EAP_TLV_EAP_PAYLOAD_TLV); - tlv->length = host_to_be16(wpabuf_len(buf)); - wpabuf_put_buf(e, buf); + eap_fast_put_tlv_buf(e, + EAP_TLV_TYPE_MANDATORY | EAP_TLV_EAP_PAYLOAD_TLV, + buf); wpabuf_free(buf); return e; } @@ -783,7 +778,7 @@ static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm, u8 *pos; size_t buf_len, srv_id_len, pac_len; struct eap_tlv_hdr *pac_tlv; - struct pac_tlv_hdr *hdr, *pac_info; + struct pac_tlv_hdr *pac_info; struct eap_tlv_result_tlv *result; struct os_time now; @@ -843,8 +838,8 @@ static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm, pac_opaque, pac_len); buf_len = sizeof(*pac_tlv) + - sizeof(*hdr) + EAP_FAST_PAC_KEY_LEN + - sizeof(*hdr) + pac_len + + sizeof(struct pac_tlv_hdr) + EAP_FAST_PAC_KEY_LEN + + sizeof(struct pac_tlv_hdr) + pac_len + 2 * srv_id_len + 100 + sizeof(*result); buf = wpabuf_alloc(buf_len); if (buf == NULL) { @@ -859,16 +854,10 @@ static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm, EAP_TLV_PAC_TLV); /* PAC-Key */ - hdr = wpabuf_put(buf, sizeof(*hdr)); - hdr->type = host_to_be16(PAC_TYPE_PAC_KEY); - hdr->len = host_to_be16(EAP_FAST_PAC_KEY_LEN); - wpabuf_put_data(buf, pac_key, EAP_FAST_PAC_KEY_LEN); + eap_fast_put_tlv(buf, PAC_TYPE_PAC_KEY, pac_key, EAP_FAST_PAC_KEY_LEN); /* PAC-Opaque */ - hdr = wpabuf_put(buf, sizeof(*hdr)); - hdr->type = host_to_be16(PAC_TYPE_PAC_OPAQUE); - hdr->len = host_to_be16(pac_len); - wpabuf_put_data(buf, pac_opaque, pac_len); + eap_fast_put_tlv(buf, PAC_TYPE_PAC_OPAQUE, pac_opaque, pac_len); os_free(pac_opaque); /* PAC-Info */ @@ -876,29 +865,19 @@ static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm, pac_info->type = host_to_be16(PAC_TYPE_PAC_INFO); /* PAC-Lifetime (inside PAC-Info) */ - hdr = wpabuf_put(buf, sizeof(*hdr)); - hdr->type = host_to_be16(PAC_TYPE_CRED_LIFETIME); - hdr->len = host_to_be16(4); + eap_fast_put_tlv_hdr(buf, PAC_TYPE_CRED_LIFETIME, 4); wpabuf_put_be32(buf, now.sec + PAC_KEY_LIFETIME); /* A-ID (inside PAC-Info) */ - hdr = wpabuf_put(buf, sizeof(*hdr)); - hdr->type = host_to_be16(PAC_TYPE_A_ID); - hdr->len = host_to_be16(srv_id_len); - wpabuf_put_data(buf, data->srv_id, srv_id_len); + eap_fast_put_tlv(buf, PAC_TYPE_A_ID, data->srv_id, srv_id_len); /* Note: headers may be misaligned after A-ID */ /* A-ID-Info (inside PAC-Info) */ - hdr = wpabuf_put(buf, sizeof(*hdr)); - WPA_PUT_BE16((u8 *) &hdr->type, PAC_TYPE_A_ID_INFO); - WPA_PUT_BE16((u8 *) &hdr->len, srv_id_len); - wpabuf_put_data(buf, data->srv_id, srv_id_len); + eap_fast_put_tlv(buf, PAC_TYPE_A_ID_INFO, data->srv_id, srv_id_len); /* PAC-Type (inside PAC-Info) */ - hdr = wpabuf_put(buf, sizeof(*hdr)); - WPA_PUT_BE16((u8 *) &hdr->type, PAC_TYPE_PAC_TYPE); - WPA_PUT_BE16((u8 *) &hdr->len, 2); + eap_fast_put_tlv_hdr(buf, PAC_TYPE_PAC_TYPE, 2); wpabuf_put_be16(buf, PAC_TYPE_TUNNEL_PAC); /* Update PAC-Info and PAC TLV Length fields */ diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index de1a56fd2..41874e02b 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -423,9 +423,11 @@ ifdef CONFIG_EAP_FAST ifeq ($(CONFIG_EAP_FAST), dyn) CFLAGS += -DEAP_FAST_DYNAMIC EAPDYN += ../src/eap_peer/eap_fast.so +EAPDYN += ../src/eap_common/eap_fast_common.o else CFLAGS += -DEAP_FAST OBJS += ../src/eap_peer/eap_fast.o ../src/eap_peer/eap_fast_pac.o +OBJS += ../src/eap_common/eap_fast_common.o OBJS_h += ../src/eap_server/eap_fast.o endif TLS_FUNCS=y