merged EAP framework from branch into trunk
authorMartin Willi <martin@strongswan.org>
Mon, 12 Feb 2007 15:56:47 +0000 (15:56 -0000)
committerMartin Willi <martin@strongswan.org>
Mon, 12 Feb 2007 15:56:47 +0000 (15:56 -0000)
includes a lot of other modifications

64 files changed:
configure.in
scripts/cfg-leak
scripts/cfg-nodebug
scripts/cfg-norm
src/charon/Makefile.am
src/charon/config/policies/local_policy_store.c
src/charon/config/policies/policy.c
src/charon/config/policies/policy.h
src/charon/config/policies/policy_store.h
src/charon/daemon.c
src/charon/daemon.h
src/charon/doc/standards/rfc3748.txt [new file with mode: 0644]
src/charon/doc/standards/rfc4739.txt [new file with mode: 0644]
src/charon/encoding/generator.c
src/charon/encoding/message.c
src/charon/encoding/parser.c
src/charon/encoding/payloads/eap_payload.c
src/charon/encoding/payloads/eap_payload.h
src/charon/encoding/payloads/encodings.h
src/charon/encoding/payloads/notify_payload.c
src/charon/encoding/payloads/notify_payload.h
src/charon/sa/authenticators/authenticator.c
src/charon/sa/authenticators/eap/eap_aka.c [new file with mode: 0644]
src/charon/sa/authenticators/eap/eap_aka.h [new file with mode: 0644]
src/charon/sa/authenticators/eap/eap_method.c [new file with mode: 0644]
src/charon/sa/authenticators/eap/eap_method.h [new file with mode: 0644]
src/charon/sa/authenticators/eap_authenticator.c [new file with mode: 0644]
src/charon/sa/authenticators/eap_authenticator.h [new file with mode: 0644]
src/charon/sa/authenticators/psk_authenticator.c
src/charon/sa/authenticators/rsa_authenticator.c
src/charon/sa/ike_sa.c
src/charon/sa/transactions/create_child_sa.c
src/charon/sa/transactions/ike_auth.c
src/charon/threads/stroke_interface.c
src/libstrongswan/Makefile.am
src/libstrongswan/chunk.c
src/libstrongswan/chunk.h
src/libstrongswan/crypto/hashers/hasher.h
src/libstrongswan/crypto/hashers/md5_hasher.c
src/libstrongswan/crypto/hashers/sha1_hasher.c
src/libstrongswan/crypto/hashers/sha2_hasher.c
src/libstrongswan/crypto/prfs/fips_prf.c [new file with mode: 0644]
src/libstrongswan/crypto/prfs/fips_prf.h [new file with mode: 0644]
src/libstrongswan/crypto/prfs/prf.c
src/libstrongswan/crypto/prfs/prf.h
src/libstrongswan/crypto/signers/hmac_signer.c
src/libstrongswan/crypto/signers/hmac_signer.h
src/libstrongswan/crypto/signers/signer.c
src/libstrongswan/crypto/signers/signer.h
src/libstrongswan/library.c
src/libstrongswan/library.h
src/libstrongswan/utils/leak_detective.c
src/starter/Makefile.am
src/starter/args.c
src/starter/confread.c
src/starter/confread.h
src/starter/invokecharon.c
src/starter/keywords.h
src/starter/keywords.txt
src/starter/starterstroke.c
src/stroke/stroke.c
src/stroke/stroke.h
testing/start-testing
testing/testing.conf

index ffc142f..89ab54f 100644 (file)
@@ -19,9 +19,7 @@ dnl ===========================
 AC_INIT(strongSwan,4.0.8)
 AM_INIT_AUTOMAKE(tar-ustar)
 AC_C_BIGENDIAN
-AC_SUBST(ipsecdir, '${libexecdir}/ipsec')
 AC_SUBST(confdir, '${sysconfdir}')
-AC_SUBST(piddir, '/var/run')
 
 dnl =================================
 dnl  check --enable-xxx & --with-xxx
@@ -30,7 +28,7 @@ dnl =================================
 
 AC_ARG_WITH(
     [default-pkcs11],
-    AS_HELP_STRING([--with-default-pkcs11=lib],[set the default PKCS11 library other than /usr/lib/opensc-pkcs11.so]),
+    AS_HELP_STRING([--with-default-pkcs11=lib],[set the default PKCS11 library other than "/usr/lib/opensc-pkcs11.so"]),
     [AC_DEFINE_UNQUOTED(PKCS11_DEFAULT_LIB, "$withval")],
     [AC_DEFINE_UNQUOTED(PKCS11_DEFAULT_LIB, "/usr/lib/opensc-pkcs11.so")]
 )
@@ -43,18 +41,39 @@ AC_ARG_WITH(
 
 AC_ARG_WITH(
     [random-device],
-    AS_HELP_STRING([--with-random-device=dev],[set the device for real random data other than /dev/random]),
+    AS_HELP_STRING([--with-random-device=dev],[set the device for real random data other than "/dev/random"]),
     [AC_DEFINE_UNQUOTED(DEV_RANDOM, "$withval")],
     [AC_DEFINE_UNQUOTED(DEV_RANDOM, "/dev/random")]
 )
 
 AC_ARG_WITH(
     [urandom-device],
-    AS_HELP_STRING([--with-urandom-device=dev],[set the device for pseudo random data other than /dev/urandom]),
+    AS_HELP_STRING([--with-urandom-device=dev],[set the device for pseudo random data other than "/dev/urandom"]),
     [AC_DEFINE_UNQUOTED(DEV_URANDOM, "$withval")],
     [AC_DEFINE_UNQUOTED(DEV_URANDOM, "/dev/urandom")]
 )
 
+AC_ARG_WITH(
+    [ipsecdir],
+    AS_HELP_STRING([--with-ipsecdir=dir],[installation path for ipsec tools other than "libexecdir/ipsec"]),
+    [AC_SUBST(ipsecdir, "$withval")],
+    [AC_SUBST(ipsecdir, "${libexecdir}/ipsec")]
+)
+
+AC_ARG_WITH(
+    [piddir],
+    AS_HELP_STRING([--with-piddir=dir],[path for PID and UNIX socket files other than "/var/run"]),
+    [AC_SUBST(piddir, "$withval")],
+    [AC_SUBST(piddir, "/var/run")]
+)
+
+AC_ARG_WITH(
+    [eapdir],
+    AS_HELP_STRING([--with-eapdir=dir],[path for pluggable EAP modules other than "ipsecdir/eap"]),
+    [AC_SUBST(eapdir, "$withval")],
+    [AC_SUBST(eapdir, "${ipsecdir}/eap")]
+)
+
 AC_ARG_ENABLE(
     [http],
     AS_HELP_STRING([--enable-http],[enable OCSP and fetching of Certificates and CRLs over HTTP (default is NO). Requires libcurl.]),
index 00623a1..44c3ec8 100755 (executable)
@@ -1,2 +1,4 @@
 #!/bin/bash
-CFLAGS="-Wall -Wno-format -Wno-pointer-sign -Wno-strict-aliasing -g -O2" ./configure --sysconfdir=/etc --with-random-device=/dev/urandom --enable-ldap --enable-http --enable-leak-detective
+CFLAGS="-Wall -Wno-format -Wno-pointer-sign -Wno-strict-aliasing -g -O2" ./configure \
+--sysconfdir=/etc --with-random-device=/dev/urandom --enable-ldap --enable-http \
+--enable-leak-detective
index 7f5e581..319f512 100755 (executable)
@@ -1,2 +1,3 @@
 #!/bin/bash
-CFLAGS="-Wall -Wno-format -Wno-pointer-sign -Wno-strict-aliasing -O2 -DDEBUG_LEVEL=0" ./configure --sysconfdir=/etc --with-random-device=/dev/urandom --enable-ldap --enable-http
+CFLAGS="-Wall -Wno-format -Wno-pointer-sign -Wno-strict-aliasing -O2 -DDEBUG_LEVEL=0" ./configure \
+--sysconfdir=/etc --with-random-device=/dev/urandom --enable-ldap --enable-http
index 164f9a6..54faf73 100755 (executable)
@@ -1,2 +1,3 @@
 #!/bin/bash
-CFLAGS="-Wall -Wno-format -Wno-pointer-sign -Wno-strict-aliasing -g -O2" ./configure --sysconfdir=/etc --with-random-device=/dev/urandom --enable-ldap --enable-http
+CFLAGS="-Wall -Wno-format -Wno-pointer-sign -Wno-strict-aliasing -g -O2" ./configure \
+--sysconfdir=/etc --with-random-device=/dev/urandom --enable-ldap --enable-http
index 913556f..c4a6afa 100644 (file)
@@ -1,5 +1,9 @@
 # SUBDIRS = . testing
 
+eap_LTLIBRARIES =
+
+# build optional EAP modules
+
 ipsec_PROGRAMS = charon
 
 charon_SOURCES = \
@@ -24,6 +28,8 @@ sa/transactions/rekey_ike_sa.h sa/transactions/rekey_ike_sa.c \
 sa/authenticators/authenticator.h sa/authenticators/authenticator.c \
 sa/authenticators/rsa_authenticator.h sa/authenticators/rsa_authenticator.c \
 sa/authenticators/psk_authenticator.h sa/authenticators/psk_authenticator.c \
+sa/authenticators/eap_authenticator.h sa/authenticators/eap_authenticator.c \
+sa/authenticators/eap/eap_method.h sa/authenticators/eap/eap_method.c \
 sa/child_sa.c sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_manager.c sa/ike_sa_manager.h \
 sa/ike_sa_id.c sa/ike_sa_id.h encoding/payloads/encryption_payload.c \
 encoding/payloads/cert_payload.c encoding/payloads/payload.h encoding/payloads/traffic_selector_substructure.c \
@@ -59,5 +65,5 @@ threads/sender.h threads/kernel_interface.h threads/scheduler.h threads/receiver
 threads/thread_pool.h threads/receiver.h threads/stroke_interface.h
 
 INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke
-AM_CFLAGS = -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_PIDDIR=\"${piddir}\"
-charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lgmp -lpthread -lm
+AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_PIDDIR=\"${piddir}\" -DIPSEC_EAPDIR=\"${eapdir}\"
+charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lgmp -lpthread -lm -ldl
index 7d2fad1..7eef382 100644 (file)
@@ -92,8 +92,7 @@ static bool contains_traffic_selectors(policy_t *policy, bool mine,
 static policy_t *get_policy(private_local_policy_store_t *this, 
                                                        identification_t *my_id, identification_t *other_id,
                                                    linked_list_t *my_ts, linked_list_t *other_ts,
-                                                   host_t *my_host, host_t *other_host,
-                                                       linked_list_t *requested_ca_keyids)
+                                                   host_t *my_host, host_t *other_host)
 {
        typedef enum {
                PRIO_UNDEFINED =        0x00,
@@ -254,7 +253,7 @@ local_policy_store_t *local_policy_store_create(void)
        
        this->public.policy_store.add_policy = (void (*) (policy_store_t*,policy_t*))add_policy;
        this->public.policy_store.get_policy = (policy_t* (*) (policy_store_t*,identification_t*,identification_t*,
-                                                                                       linked_list_t*,linked_list_t*,host_t*,host_t*,linked_list_t*))get_policy;
+                                                                                       linked_list_t*,linked_list_t*,host_t*,host_t*))get_policy;
        this->public.policy_store.get_policy_by_name = (policy_t* (*) (policy_store_t*,char*))get_policy_by_name;
        this->public.policy_store.delete_policy = (status_t (*) (policy_store_t*,char*))delete_policy;
        this->public.policy_store.create_iterator = (iterator_t* (*) (policy_store_t*))create_iterator;
index 34bd151..e68a8ad 100644 (file)
@@ -84,6 +84,11 @@ struct private_policy_t {
        auth_method_t auth_method;
        
        /**
+        * EAP type to use for peer authentication
+        */
+       eap_type_t eap_type;
+       
+       /**
         * we have a cert issued by this CA
         */
        identification_t *my_ca;
@@ -194,6 +199,14 @@ static auth_method_t get_auth_method(private_policy_t *this)
 }
 
 /**
+ * Implementation of connection_t.get_eap_type.
+ */
+static eap_type_t get_eap_type(private_policy_t *this)
+{
+       return this->eap_type;
+}
+
+/**
  * Get traffic selectors, with wildcard-address update
  */
 static linked_list_t *get_traffic_selectors(private_policy_t *this, linked_list_t *list, host_t *host)
@@ -492,7 +505,7 @@ static void destroy(private_policy_t *this)
  * Described in header-file
  */
 policy_t *policy_create(char *name, identification_t *my_id, identification_t *other_id,
-                                               auth_method_t auth_method,
+                                               auth_method_t auth_method, eap_type_t eap_type,
                                                u_int32_t hard_lifetime, u_int32_t soft_lifetime, 
                                                u_int32_t jitter, char *updown, bool hostaccess,
                                                mode_t mode, dpd_action_t dpd_action)
@@ -506,6 +519,7 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
        this->public.get_my_ca = (identification_t* (*) (policy_t*))get_my_ca;
        this->public.get_other_ca = (identification_t* (*) (policy_t*))get_other_ca;
        this->public.get_auth_method = (auth_method_t (*) (policy_t*)) get_auth_method;
+       this->public.get_eap_type = (eap_type_t (*) (policy_t*)) get_eap_type;
        this->public.get_my_traffic_selectors = (linked_list_t* (*) (policy_t*,host_t*))get_my_traffic_selectors;
        this->public.get_other_traffic_selectors = (linked_list_t* (*) (policy_t*,host_t*))get_other_traffic_selectors;
        this->public.select_my_traffic_selectors = (linked_list_t* (*) (policy_t*,linked_list_t*,host_t*))select_my_traffic_selectors;
@@ -530,6 +544,7 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
        this->my_id = my_id;
        this->other_id = other_id;
        this->auth_method = auth_method;
+       this->eap_type = eap_type;
        this->hard_lifetime = hard_lifetime;
        this->soft_lifetime = soft_lifetime;
        this->jitter = jitter;
index 123383c..a2d9ae8 100644 (file)
@@ -32,6 +32,7 @@ typedef struct policy_t policy_t;
 #include <config/traffic_selector.h>
 #include <config/proposal.h>
 #include <sa/authenticators/authenticator.h>
+#include <sa/authenticators/eap/eap_method.h>
 
 
 /**
@@ -148,6 +149,14 @@ struct policy_t {
         * @return                      authentication method
         */
        auth_method_t (*get_auth_method) (policy_t *this);
+
+       /**
+        * @brief Get the EAP type to use for peer authentication.
+        * 
+        * @param this          calling object
+        * @return                      authentication method
+        */
+       eap_type_t (*get_eap_type) (policy_t *this);
        
        /**
         * @brief Get configured traffic selectors for our site.
@@ -358,6 +367,7 @@ struct policy_t {
  * @param my_id                        identification_t for ourselves
  * @param other_id                     identification_t for the remote guy
  * @param auth_method          Authentication method to use for our(!) auth data
+ * @param eap_type                     EAP type to use for peer authentication
  * @param hard_lifetime                lifetime before deleting an SA
  * @param soft_lifetime                lifetime before rekeying an SA
  * @param jitter                       range of randomization time
@@ -371,7 +381,7 @@ struct policy_t {
  */
 policy_t *policy_create(char *name, 
                                                identification_t *my_id, identification_t *other_id,
-                                               auth_method_t auth_method,
+                                               auth_method_t auth_method, eap_type_t eap_type,
                                                u_int32_t hard_lifetime, u_int32_t soft_lifetime,
                                                u_int32_t jitter, char *updown, bool hostaccess,
                                                mode_t mode, dpd_action_t dpd_action);
index 6b47005..cd88709 100755 (executable)
@@ -49,14 +49,13 @@ struct policy_store_t {
         * other_id must be fully qualified. my_id may be %any, as the
         * other peer may not include an IDr Request.
         *
-        * @param this                                  calling object
-        * @param my_id                                 own ID of the policy
-        * @param other_id                              others ID of the policy
-        * @param my_ts                                 traffic selectors requested for local host
-        * @param other_ts                              traffic selectors requested for remote host
-        * @param my_host                               host to use for wilcards in TS compare
-        * @param other_host                    host to use for wildcards in TS compare
-        * @param requested_ca_keyids   list of requested CA keyids
+        * @param this                  calling object
+        * @param my_id                 own ID of the policy
+        * @param other_id              others ID of the policy
+        * @param my_ts                 traffic selectors requested for local host
+        * @param other_ts              traffic selectors requested for remote host
+        * @param my_host               host to use for wilcards in TS compare
+        * @param other_host    host to use for wildcards in TS compare
         * @return
         *                                              - matching policy_t, if found
         *                                              - NULL otherwise
@@ -64,8 +63,7 @@ struct policy_store_t {
        policy_t *(*get_policy) (policy_store_t *this, 
                                                         identification_t *my_id, identification_t *other_id,
                                                         linked_list_t *my_ts, linked_list_t *other_ts,
-                                                        host_t *my_host, host_t* other_host,
-                                                        linked_list_t *requested_ca_keyids);
+                                                        host_t *my_host, host_t* other_host);
 
        /**
         * @brief Returns a policy identified by a connection name.
index 2d15b58..3bac57f 100644 (file)
@@ -42,6 +42,7 @@
 #include <config/credentials/local_credential_store.h>
 #include <config/connections/local_connection_store.h>
 #include <config/policies/local_policy_store.h>
+#include <sa/authenticators/eap/eap_method.h>
 
 
 typedef struct private_daemon_t private_daemon_t;
@@ -393,6 +394,7 @@ int main(int argc, char *argv[])
 {
        bool strict_crl_policy = FALSE;
        bool use_syslog = FALSE;
+       char *eapdir = IPSEC_EAPDIR;
 
        private_daemon_t *private_charon;
        FILE *pid_file;
@@ -416,6 +418,7 @@ int main(int argc, char *argv[])
                        { "version", no_argument, NULL, 'v' },
                        { "use-syslog", no_argument, NULL, 'l' },
                        { "strictcrlpolicy", no_argument, NULL, 'r' },
+                       { "eapdir", required_argument, NULL, 'e' },
                        /* TODO: handle "debug-all" */
                        { "debug-dmn", required_argument, &signal, DBG_DMN },
                        { "debug-mgr", required_argument, &signal, DBG_MGR },
@@ -447,6 +450,9 @@ int main(int argc, char *argv[])
                        case 'r':
                                strict_crl_policy = TRUE;
                                continue;
+                       case 'e':
+                               eapdir = optarg;
+                               continue;
                        case 0:
                                /* option is in signal */
                                levels[signal] = atoi(optarg);
@@ -463,6 +469,8 @@ int main(int argc, char *argv[])
        
        /* initialize daemon */
        initialize(private_charon, strict_crl_policy, use_syslog, levels);
+       /* load pluggable EAP modules */
+       eap_method_load(eapdir);
        
        /* check/setup PID file */
        if (stat(PID_FILE, &stb) == 0)
@@ -477,6 +485,7 @@ int main(int argc, char *argv[])
                fprintf(pid_file, "%d\n", getpid());
                fclose(pid_file);
        }
+       
        /* log socket info */
        list = charon->socket->create_local_address_list(charon->socket);
        DBG1(DBG_NET, "listening on %d addresses:", list->get_count(list));
@@ -490,6 +499,7 @@ int main(int argc, char *argv[])
        /* run daemon */
        run(private_charon);
        
+       eap_method_unload();
        /* normal termination, cleanup and exit */
        destroy(private_charon);
        unlink(PID_FILE);
index afe8805..8296aea 100644 (file)
@@ -180,6 +180,14 @@ typedef struct daemon_t daemon_t;
  */
 
 /**
+ * @defgroup eap eap
+ *
+ * EAP authentication module interface and it's implementations.
+ *
+ * @ingroup authenticators
+ */
+
+/**
  * @defgroup threads threads
  *
  * Threaded classes, which will do their job alone.
diff --git a/src/charon/doc/standards/rfc3748.txt b/src/charon/doc/standards/rfc3748.txt
new file mode 100644 (file)
index 0000000..75600c1
--- /dev/null
@@ -0,0 +1,3755 @@
+
+
+
+
+
+
+Network Working Group                                           B. Aboba
+Request for Comments: 3748                                     Microsoft
+Obsoletes: 2284                                                 L. Blunk
+Category: Standards Track                             Merit Network, Inc
+                                                           J. Vollbrecht
+                                               Vollbrecht Consulting LLC
+                                                              J. Carlson
+                                                                     Sun
+                                                       H. Levkowetz, Ed.
+                                                             ipUnplugged
+                                                               June 2004
+
+
+                Extensible Authentication Protocol (EAP)
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2004).
+
+Abstract
+
+   This document defines the Extensible Authentication Protocol (EAP),
+   an authentication framework which supports multiple authentication
+   methods.  EAP typically runs directly over data link layers such as
+   Point-to-Point Protocol (PPP) or IEEE 802, without requiring IP.  EAP
+   provides its own support for duplicate elimination and
+   retransmission, but is reliant on lower layer ordering guarantees.
+   Fragmentation is not supported within EAP itself; however, individual
+   EAP methods may support this.
+
+   This document obsoletes RFC 2284.  A summary of the changes between
+   this document and RFC 2284 is available in Appendix A.
+
+
+
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                     [Page 1]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+Table of Contents
+
+   1.   Introduction. . . . . . . . . . . . . . . . . . . . . . . . .  3
+        1.1.  Specification of Requirements . . . . . . . . . . . . .  4
+        1.2.  Terminology . . . . . . . . . . . . . . . . . . . . . .  4
+        1.3.  Applicability . . . . . . . . . . . . . . . . . . . . .  6
+   2.   Extensible Authentication Protocol (EAP). . . . . . . . . . .  7
+        2.1.  Support for Sequences . . . . . . . . . . . . . . . . .  9
+        2.2.  EAP Multiplexing Model. . . . . . . . . . . . . . . . . 10
+        2.3.  Pass-Through Behavior . . . . . . . . . . . . . . . . . 12
+        2.4.  Peer-to-Peer Operation. . . . . . . . . . . . . . . . . 14
+   3.   Lower Layer Behavior. . . . . . . . . . . . . . . . . . . . . 15
+        3.1.  Lower Layer Requirements. . . . . . . . . . . . . . . . 15
+        3.2.  EAP Usage Within PPP. . . . . . . . . . . . . . . . . . 18
+              3.2.1. PPP Configuration Option Format. . . . . . . . . 18
+        3.3.  EAP Usage Within IEEE 802 . . . . . . . . . . . . . . . 19
+        3.4.  Lower Layer Indications . . . . . . . . . . . . . . . . 19
+   4.   EAP Packet Format . . . . . . . . . . . . . . . . . . . . . . 20
+        4.1.  Request and Response. . . . . . . . . . . . . . . . . . 21
+        4.2.  Success and Failure . . . . . . . . . . . . . . . . . . 23
+        4.3.  Retransmission Behavior . . . . . . . . . . . . . . . . 26
+   5.   Initial EAP Request/Response Types. . . . . . . . . . . . . . 27
+        5.1.  Identity. . . . . . . . . . . . . . . . . . . . . . . . 28
+        5.2.  Notification. . . . . . . . . . . . . . . . . . . . . . 29
+        5.3.  Nak . . . . . . . . . . . . . . . . . . . . . . . . . . 31
+              5.3.1. Legacy Nak . . . . . . . . . . . . . . . . . . . 31
+              5.3.2. Expanded Nak . . . . . . . . . . . . . . . . . . 32
+        5.4.  MD5-Challenge . . . . . . . . . . . . . . . . . . . . . 35
+        5.5.  One-Time Password (OTP) . . . . . . . . . . . . . . . . 36
+        5.6.  Generic Token Card (GTC). . . . . . . . . . . . . . . . 37
+        5.7.  Expanded Types. . . . . . . . . . . . . . . . . . . . . 38
+        5.8.  Experimental. . . . . . . . . . . . . . . . . . . . . . 40
+   6.   IANA Considerations . . . . . . . . . . . . . . . . . . . . . 40
+        6.1.  Packet Codes. . . . . . . . . . . . . . . . . . . . . . 41
+        6.2.  Method Types. . . . . . . . . . . . . . . . . . . . . . 41
+   7.   Security Considerations . . . . . . . . . . . . . . . . . . . 42
+        7.1.  Threat Model. . . . . . . . . . . . . . . . . . . . . . 42
+        7.2.  Security Claims . . . . . . . . . . . . . . . . . . . . 43
+              7.2.1. Security Claims Terminology for EAP Methods. . . 44
+        7.3.  Identity Protection . . . . . . . . . . . . . . . . . . 46
+        7.4.  Man-in-the-Middle Attacks . . . . . . . . . . . . . . . 47
+        7.5.  Packet Modification Attacks . . . . . . . . . . . . . . 48
+        7.6.  Dictionary Attacks. . . . . . . . . . . . . . . . . . . 49
+        7.7.  Connection to an Untrusted Network. . . . . . . . . . . 49
+        7.8.  Negotiation Attacks . . . . . . . . . . . . . . . . . . 50
+        7.9.  Implementation Idiosyncrasies . . . . . . . . . . . . . 50
+        7.10. Key Derivation. . . . . . . . . . . . . . . . . . . . . 51
+        7.11. Weak Ciphersuites . . . . . . . . . . . . . . . . . . . 53
+
+
+
+Aboba, et al.               Standards Track                     [Page 2]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+        7.12. Link Layer. . . . . . . . . . . . . . . . . . . . . . . 53
+        7.13. Separation of Authenticator and Backend Authentication
+              Server. . . . . . . . . . . . . . . . . . . . . . . . . 54
+        7.14. Cleartext Passwords . . . . . . . . . . . . . . . . . . 55
+        7.15. Channel Binding . . . . . . . . . . . . . . . . . . . . 55
+        7.16. Protected Result Indications. . . . . . . . . . . . . . 56
+   8.   Acknowledgements. . . . . . . . . . . . . . . . . . . . . . . 58
+   9.   References. . . . . . . . . . . . . . . . . . . . . . . . . . 59
+        9.1.  Normative References. . . . . . . . . . . . . . . . . . 59
+        9.2.  Informative References. . . . . . . . . . . . . . . . . 60
+   Appendix A. Changes from RFC 2284. . . . . . . . . . . . . . . . . 64
+   Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 66
+   Full Copyright Statement . . . . . . . . . . . . . . . . . . . . . 67
+
+1.  Introduction
+
+   This document defines the Extensible Authentication Protocol (EAP),
+   an authentication framework which supports multiple authentication
+   methods.  EAP typically runs directly over data link layers such as
+   Point-to-Point Protocol (PPP) or IEEE 802, without requiring IP.  EAP
+   provides its own support for duplicate elimination and
+   retransmission, but is reliant on lower layer ordering guarantees.
+   Fragmentation is not supported within EAP itself; however, individual
+   EAP methods may support this.
+
+   EAP may be used on dedicated links, as well as switched circuits, and
+   wired as well as wireless links.  To date, EAP has been implemented
+   with hosts and routers that connect via switched circuits or dial-up
+   lines using PPP [RFC1661].  It has also been implemented with
+   switches and access points using IEEE 802 [IEEE-802].  EAP
+   encapsulation on IEEE 802 wired media is described in [IEEE-802.1X],
+   and encapsulation on IEEE wireless LANs in [IEEE-802.11i].
+
+   One of the advantages of the EAP architecture is its flexibility.
+   EAP is used to select a specific authentication mechanism, typically
+   after the authenticator requests more information in order to
+   determine the specific authentication method to be used.  Rather than
+   requiring the authenticator to be updated to support each new
+   authentication method, EAP permits the use of a backend
+   authentication server, which may implement some or all authentication
+   methods, with the authenticator acting as a pass-through for some or
+   all methods and peers.
+
+   Within this document, authenticator requirements apply regardless of
+   whether the authenticator is operating as a pass-through or not.
+   Where the requirement is meant to apply to either the authenticator
+   or backend authentication server, depending on where the EAP
+   authentication is terminated, the term "EAP server" will be used.
+
+
+
+Aboba, et al.               Standards Track                     [Page 3]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+1.1.  Specification of Requirements
+
+   In this document, several words are used to signify the requirements
+   of the specification.  The key words "MUST", "MUST NOT", "REQUIRED",
+   "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
+   and "OPTIONAL" in this document are to be interpreted as described in
+   [RFC2119].
+
+1.2.  Terminology
+
+   This document frequently uses the following terms:
+
+   authenticator
+      The end of the link initiating EAP authentication.  The term
+      authenticator is used in [IEEE-802.1X], and has the same meaning
+      in this document.
+
+   peer
+      The end of the link that responds to the authenticator.  In
+      [IEEE-802.1X], this end is known as the Supplicant.
+
+   Supplicant
+      The end of the link that responds to the authenticator in [IEEE-
+      802.1X].  In this document, this end of the link is called the
+      peer.
+
+   backend authentication server
+      A backend authentication server is an entity that provides an
+      authentication service to an authenticator.  When used, this
+      server typically executes EAP methods for the authenticator.  This
+      terminology is also used in [IEEE-802.1X].
+
+   AAA
+      Authentication, Authorization, and Accounting.  AAA protocols with
+      EAP support include RADIUS [RFC3579] and Diameter [DIAM-EAP].  In
+      this document, the terms "AAA server" and "backend authentication
+      server" are used interchangeably.
+
+   Displayable Message
+      This is interpreted to be a human readable string of characters.
+      The message encoding MUST follow the UTF-8 transformation format
+      [RFC2279].
+
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                     [Page 4]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   EAP server
+      The entity that terminates the EAP authentication method with the
+      peer.  In the case where no backend authentication server is used,
+      the EAP server is part of the authenticator.  In the case where
+      the authenticator operates in pass-through mode, the EAP server is
+      located on the backend authentication server.
+
+   Silently Discard
+      This means the implementation discards the packet without further
+      processing.  The implementation SHOULD provide the capability of
+      logging the event, including the contents of the silently
+      discarded packet, and SHOULD record the event in a statistics
+      counter.
+
+   Successful Authentication
+      In the context of this document, "successful authentication" is an
+      exchange of EAP messages, as a result of which the authenticator
+      decides to allow access by the peer, and the peer decides to use
+      this access.  The authenticator's decision typically involves both
+      authentication and authorization aspects; the peer may
+      successfully authenticate to the authenticator, but access may be
+      denied by the authenticator due to policy reasons.
+
+   Message Integrity Check (MIC)
+      A keyed hash function used for authentication and integrity
+      protection of data.  This is usually called a Message
+      Authentication Code (MAC), but IEEE 802 specifications (and this
+      document) use the acronym MIC to avoid confusion with Medium
+      Access Control.
+
+   Cryptographic Separation
+      Two keys (x and y) are "cryptographically separate" if an
+      adversary that knows all messages exchanged in the protocol cannot
+      compute x from y or y from x without "breaking" some cryptographic
+      assumption.  In particular, this definition allows that the
+      adversary has the knowledge of all nonces sent in cleartext, as
+      well as all predictable counter values used in the protocol.
+      Breaking a cryptographic assumption would typically require
+      inverting a one-way function or predicting the outcome of a
+      cryptographic pseudo-random number generator without knowledge of
+      the secret state.  In other words, if the keys are
+      cryptographically separate, there is no shortcut to compute x from
+      y or y from x, but the work an adversary must do to perform this
+      computation is equivalent to performing an exhaustive search for
+      the secret state value.
+
+
+
+
+
+
+Aboba, et al.               Standards Track                     [Page 5]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   Master Session Key (MSK)
+      Keying material that is derived between the EAP peer and server
+      and exported by the EAP method.  The MSK is at least 64 octets in
+      length.  In existing implementations, a AAA server acting as an
+      EAP server transports the MSK to the authenticator.
+
+   Extended Master Session Key (EMSK)
+      Additional keying material derived between the EAP client and
+      server that is exported by the EAP method.  The EMSK is at least
+      64 octets in length.  The EMSK is not shared with the
+      authenticator or any other third party.  The EMSK is reserved for
+      future uses that are not defined yet.
+
+   Result indications
+      A method provides result indications if after the method's last
+      message is sent and received:
+
+      1) The peer is aware of whether it has authenticated the server,
+         as well as whether the server has authenticated it.
+
+      2) The server is aware of whether it has authenticated the peer,
+         as well as whether the peer has authenticated it.
+
+   In the case where successful authentication is sufficient to
+   authorize access, then the peer and authenticator will also know if
+   the other party is willing to provide or accept access.  This may not
+   always be the case.  An authenticated peer may be denied access due
+   to lack of authorization (e.g., session limit) or other reasons.
+   Since the EAP exchange is run between the peer and the server, other
+   nodes (such as AAA proxies) may also affect the authorization
+   decision.  This is discussed in more detail in Section 7.16.
+
+1.3.  Applicability
+
+   EAP was designed for use in network access authentication, where IP
+   layer connectivity may not be available.  Use of EAP for other
+   purposes, such as bulk data transport, is NOT RECOMMENDED.
+
+   Since EAP does not require IP connectivity, it provides just enough
+   support for the reliable transport of authentication protocols, and
+   no more.
+
+   EAP is a lock-step protocol which only supports a single packet in
+   flight.  As a result, EAP cannot efficiently transport bulk data,
+   unlike transport protocols such as TCP [RFC793] or SCTP [RFC2960].
+
+
+
+
+
+
+Aboba, et al.               Standards Track                     [Page 6]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   While EAP provides support for retransmission, it assumes ordering
+   guarantees provided by the lower layer, so out of order reception is
+   not supported.
+
+   Since EAP does not support fragmentation and reassembly, EAP
+   authentication methods generating payloads larger than the minimum
+   EAP MTU need to provide fragmentation support.
+
+   While authentication methods such as EAP-TLS [RFC2716] provide
+   support for fragmentation and reassembly, the EAP methods defined in
+   this document do not.  As a result, if the EAP packet size exceeds
+   the EAP MTU of the link, these methods will encounter difficulties.
+
+   EAP authentication is initiated by the server (authenticator),
+   whereas many authentication protocols are initiated by the client
+   (peer).  As a result, it may be necessary for an authentication
+   algorithm to add one or two additional messages (at most one
+   roundtrip) in order to run over EAP.
+
+   Where certificate-based authentication is supported, the number of
+   additional roundtrips may be much larger due to fragmentation of
+   certificate chains.  In general, a fragmented EAP packet will require
+   as many round-trips to send as there are fragments.  For example, a
+   certificate chain 14960 octets in size would require ten round-trips
+   to send with a 1496 octet EAP MTU.
+
+   Where EAP runs over a lower layer in which significant packet loss is
+   experienced, or where the connection between the authenticator and
+   authentication server experiences significant packet loss, EAP
+   methods requiring many round-trips can experience difficulties.  In
+   these situations, use of EAP methods with fewer roundtrips is
+   advisable.
+
+2.  Extensible Authentication Protocol (EAP)
+
+   The EAP authentication exchange proceeds as follows:
+
+   [1] The authenticator sends a Request to authenticate the peer.  The
+       Request has a Type field to indicate what is being requested.
+       Examples of Request Types include Identity, MD5-challenge, etc.
+       The MD5-challenge Type corresponds closely to the CHAP
+       authentication protocol [RFC1994].  Typically, the authenticator
+       will send an initial Identity Request; however, an initial
+       Identity Request is not required, and MAY be bypassed.  For
+       example, the identity may not be required where it is determined
+       by the port to which the peer has connected (leased lines,
+
+
+
+
+
+Aboba, et al.               Standards Track                     [Page 7]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+       dedicated switch or dial-up ports), or where the identity is
+       obtained in another fashion (via calling station identity or MAC
+       address, in the Name field of the MD5-Challenge Response, etc.).
+
+   [2] The peer sends a Response packet in reply to a valid Request.  As
+       with the Request packet, the Response packet contains a Type
+       field, which corresponds to the Type field of the Request.
+
+   [3] The authenticator sends an additional Request packet, and the
+       peer replies with a Response.  The sequence of Requests and
+       Responses continues as long as needed.  EAP is a 'lock step'
+       protocol, so that other than the initial Request, a new Request
+       cannot be sent prior to receiving a valid Response.  The
+       authenticator is responsible for retransmitting requests as
+       described in Section 4.1.  After a suitable number of
+       retransmissions, the authenticator SHOULD end the EAP
+       conversation.  The authenticator MUST NOT send a Success or
+       Failure packet when retransmitting or when it fails to get a
+       response from the peer.
+
+   [4] The conversation continues until the authenticator cannot
+       authenticate the peer (unacceptable Responses to one or more
+       Requests), in which case the authenticator implementation MUST
+       transmit an EAP Failure (Code 4).  Alternatively, the
+       authentication conversation can continue until the authenticator
+       determines that successful authentication has occurred, in which
+       case the authenticator MUST transmit an EAP Success (Code 3).
+
+   Advantages:
+
+   o  The EAP protocol can support multiple authentication mechanisms
+      without having to pre-negotiate a particular one.
+
+   o  Network Access Server (NAS) devices (e.g., a switch or access
+      point) do not have to understand each authentication method and
+      MAY act as a pass-through agent for a backend authentication
+      server.  Support for pass-through is optional.  An authenticator
+      MAY authenticate local peers, while at the same time acting as a
+      pass-through for non-local peers and authentication methods it
+      does not implement locally.
+
+   o  Separation of the authenticator from the backend authentication
+      server simplifies credentials management and policy decision
+      making.
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                     [Page 8]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   Disadvantages:
+
+   o  For use in PPP, EAP requires the addition of a new authentication
+      Type to PPP LCP and thus PPP implementations will need to be
+      modified to use it.  It also strays from the previous PPP
+      authentication model of negotiating a specific authentication
+      mechanism during LCP.  Similarly, switch or access point
+      implementations need to support [IEEE-802.1X] in order to use EAP.
+
+   o  Where the authenticator is separate from the backend
+      authentication server, this complicates the security analysis and,
+      if needed, key distribution.
+
+2.1.  Support for Sequences
+
+   An EAP conversation MAY utilize a sequence of methods.  A common
+   example of this is an Identity request followed by a single EAP
+   authentication method such as an MD5-Challenge.  However, the peer
+   and authenticator MUST utilize only one authentication method (Type 4
+   or greater) within an EAP conversation, after which the authenticator
+   MUST send a Success or Failure packet.
+
+   Once a peer has sent a Response of the same Type as the initial
+   Request, an authenticator MUST NOT send a Request of a different Type
+   prior to completion of the final round of a given method (with the
+   exception of a Notification-Request) and MUST NOT send a Request for
+   an additional method of any Type after completion of the initial
+   authentication method; a peer receiving such Requests MUST treat them
+   as invalid, and silently discard them.  As a result, Identity Requery
+   is not supported.
+
+   A peer MUST NOT send a Nak (legacy or expanded) in reply to a Request
+   after an initial non-Nak Response has been sent.  Since spoofed EAP
+   Request packets may be sent by an attacker, an authenticator
+   receiving an unexpected Nak SHOULD discard it and log the event.
+
+   Multiple authentication methods within an EAP conversation are not
+   supported due to their vulnerability to man-in-the-middle attacks
+   (see Section 7.4) and incompatibility with existing implementations.
+
+   Where a single EAP authentication method is utilized, but other
+   methods are run within it (a "tunneled" method), the prohibition
+   against multiple authentication methods does not apply.  Such
+   "tunneled" methods appear as a single authentication method to EAP.
+   Backward compatibility can be provided, since a peer not supporting a
+   "tunneled" method can reply to the initial EAP-Request with a Nak
+
+
+
+
+
+Aboba, et al.               Standards Track                     [Page 9]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   (legacy or expanded).  To address security vulnerabilities,
+   "tunneled" methods MUST support protection against man-in-the-middle
+   attacks.
+
+2.2.  EAP Multiplexing Model
+
+   Conceptually, EAP implementations consist of the following
+   components:
+
+   [a] Lower layer.  The lower layer is responsible for transmitting and
+       receiving EAP frames between the peer and authenticator.  EAP has
+       been run over a variety of lower layers including PPP, wired IEEE
+       802 LANs [IEEE-802.1X], IEEE 802.11 wireless LANs [IEEE-802.11],
+       UDP (L2TP [RFC2661] and IKEv2 [IKEv2]), and TCP [PIC].  Lower
+       layer behavior is discussed in Section 3.
+
+   [b] EAP layer.  The EAP layer receives and transmits EAP packets via
+       the lower layer, implements duplicate detection and
+       retransmission, and delivers and receives EAP messages to and
+       from the EAP peer and authenticator layers.
+
+   [c] EAP peer and authenticator layers.  Based on the Code field, the
+       EAP layer demultiplexes incoming EAP packets to the EAP peer and
+       authenticator layers.  Typically, an EAP implementation on a
+       given host will support either peer or authenticator
+       functionality, but it is possible for a host to act as both an
+       EAP peer and authenticator.  In such an implementation both EAP
+       peer and authenticator layers will be present.
+
+   [d] EAP method layers.  EAP methods implement the authentication
+       algorithms and receive and transmit EAP messages via the EAP peer
+       and authenticator layers.  Since fragmentation support is not
+       provided by EAP itself, this is the responsibility of EAP
+       methods, which are discussed in Section 5.
+
+   The EAP multiplexing model is illustrated in Figure 1 below.  Note
+   that there is no requirement that an implementation conform to this
+   model, as long as the on-the-wire behavior is consistent with it.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 10]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+         +-+-+-+-+-+-+-+-+-+-+-+-+  +-+-+-+-+-+-+-+-+-+-+-+-+
+         |           |           |  |           |           |
+         | EAP method| EAP method|  | EAP method| EAP method|
+         | Type = X  | Type = Y  |  | Type = X  | Type = Y  |
+         |       V   |           |  |       ^   |           |
+         +-+-+-+-!-+-+-+-+-+-+-+-+  +-+-+-+-!-+-+-+-+-+-+-+-+
+         |       !               |  |       !               |
+         |  EAP  ! Peer layer    |  |  EAP  ! Auth. layer   |
+         |       !               |  |       !               |
+         +-+-+-+-!-+-+-+-+-+-+-+-+  +-+-+-+-!-+-+-+-+-+-+-+-+
+         |       !               |  |       !               |
+         |  EAP  ! layer         |  |  EAP  ! layer         |
+         |       !               |  |       !               |
+         +-+-+-+-!-+-+-+-+-+-+-+-+  +-+-+-+-!-+-+-+-+-+-+-+-+
+         |       !               |  |       !               |
+         | Lower ! layer         |  | Lower ! layer         |
+         |       !               |  |       !               |
+         +-+-+-+-!-+-+-+-+-+-+-+-+  +-+-+-+-!-+-+-+-+-+-+-+-+
+                 !                          !
+                 !   Peer                   ! Authenticator
+                 +------------>-------------+
+
+                     Figure 1: EAP Multiplexing Model
+
+   Within EAP, the Code field functions much like a protocol number in
+   IP.  It is assumed that the EAP layer demultiplexes incoming EAP
+   packets according to the Code field.  Received EAP packets with
+   Code=1 (Request), 3 (Success), and 4 (Failure) are delivered by the
+   EAP layer to the EAP peer layer, if implemented.  EAP packets with
+   Code=2 (Response) are delivered to the EAP authenticator layer, if
+   implemented.
+
+   Within EAP, the Type field functions much like a port number in UDP
+   or TCP.  It is assumed that the EAP peer and authenticator layers
+   demultiplex incoming EAP packets according to their Type, and deliver
+   them only to the EAP method corresponding to that Type.  An EAP
+   method implementation on a host may register to receive packets from
+   the peer or authenticator layers, or both, depending on which role(s)
+   it supports.
+
+   Since EAP authentication methods may wish to access the Identity,
+   implementations SHOULD make the Identity Request and Response
+   accessible to authentication methods (Types 4 or greater), in
+   addition to the Identity method.  The Identity Type is discussed in
+   Section 5.1.
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 11]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   A Notification Response is only used as confirmation that the peer
+   received the Notification Request, not that it has processed it, or
+   displayed the message to the user.  It cannot be assumed that the
+   contents of the Notification Request or Response are available to
+   another method.  The Notification Type is discussed in Section 5.2.
+
+   Nak (Type 3) or Expanded Nak (Type 254) are utilized for the purposes
+   of method negotiation.  Peers respond to an initial EAP Request for
+   an unacceptable Type with a Nak Response (Type 3) or Expanded Nak
+   Response (Type 254).  It cannot be assumed that the contents of the
+   Nak Response(s) are available to another method.  The Nak Type(s) are
+   discussed in Section 5.3.
+
+   EAP packets with Codes of Success or Failure do not include a Type
+   field, and are not delivered to an EAP method.  Success and Failure
+   are discussed in Section 4.2.
+
+   Given these considerations, the Success, Failure, Nak Response(s),
+   and Notification Request/Response messages MUST NOT be used to carry
+   data destined for delivery to other EAP methods.
+
+2.3.  Pass-Through Behavior
+
+   When operating as a "pass-through authenticator", an authenticator
+   performs checks on the Code, Identifier, and Length fields as
+   described in Section 4.1.  It forwards EAP packets received from the
+   peer and destined to its authenticator layer to the backend
+   authentication server; packets received from the backend
+   authentication server destined to the peer are forwarded to it.
+
+   A host receiving an EAP packet may only do one of three things with
+   it: act on it, drop it, or forward it.  The forwarding decision is
+   typically based only on examination of the Code, Identifier, and
+   Length fields.  A pass-through authenticator implementation MUST be
+   capable of forwarding EAP packets received from the peer with Code=2
+   (Response) to the backend authentication server. It also MUST be
+   capable of receiving EAP packets from the backend authentication
+   server and forwarding EAP packets of Code=1 (Request), Code=3
+   (Success), and Code=4 (Failure) to the peer.
+
+   Unless the authenticator implements one or more authentication
+   methods locally which support the authenticator role, the EAP method
+   layer header fields (Type, Type-Data) are not examined as part of the
+   forwarding decision.  Where the authenticator supports local
+   authentication methods, it MAY examine the Type field to determine
+   whether to act on the packet itself or forward it.  Compliant pass-
+   through authenticator implementations MUST by default forward EAP
+   packets of any Type.
+
+
+
+Aboba, et al.               Standards Track                    [Page 12]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   EAP packets received with Code=1 (Request), Code=3 (Success), and
+   Code=4 (Failure) are demultiplexed by the EAP layer and delivered to
+   the peer layer.  Therefore, unless a host implements an EAP peer
+   layer, these packets will be silently discarded.  Similarly, EAP
+   packets received with Code=2 (Response) are demultiplexed by the EAP
+   layer and delivered to the authenticator layer.  Therefore, unless a
+   host implements an EAP authenticator layer, these packets will be
+   silently discarded.  The behavior of a "pass-through peer" is
+   undefined within this specification, and is unsupported by AAA
+   protocols such as RADIUS [RFC3579] and Diameter [DIAM-EAP].
+
+   The forwarding model is illustrated in Figure 2.
+
+        Peer         Pass-through Authenticator   Authentication
+                                                      Server
+
+   +-+-+-+-+-+-+                                   +-+-+-+-+-+-+
+   |           |                                   |           |
+   |EAP method |                                   |EAP method |
+   |     V     |                                   |     ^     |
+   +-+-+-!-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-!-+-+-+
+   |     !     |   |EAP  |  EAP  |             |   |     !     |
+   |     !     |   |Peer |  Auth.| EAP Auth.   |   |     !     |
+   |EAP  ! peer|   |     | +-----------+       |   |EAP  !Auth.|
+   |     !     |   |     | !     |     !       |   |     !     |
+   +-+-+-!-+-+-+   +-+-+-+-!-+-+-+-+-+-!-+-+-+-+   +-+-+-!-+-+-+
+   |     !     |   |       !     |     !       |   |     !     |
+   |EAP  !layer|   |   EAP !layer| EAP !layer  |   |EAP  !layer|
+   |     !     |   |       !     |     !       |   |     !     |
+   +-+-+-!-+-+-+   +-+-+-+-!-+-+-+-+-+-!-+-+-+-+   +-+-+-!-+-+-+
+   |     !     |   |       !     |     !       |   |     !     |
+   |Lower!layer|   |  Lower!layer| AAA ! /IP   |   | AAA ! /IP |
+   |     !     |   |       !     |     !       |   |     !     |
+   +-+-+-!-+-+-+   +-+-+-+-!-+-+-+-+-+-!-+-+-+-+   +-+-+-!-+-+-+
+         !                 !           !                 !
+         !                 !           !                 !
+         +-------->--------+           +--------->-------+
+
+
+                   Figure 2: Pass-through Authenticator
+
+   For sessions in which the authenticator acts as a pass-through, it
+   MUST determine the outcome of the authentication solely based on the
+   Accept/Reject indication sent by the backend authentication server;
+   the outcome MUST NOT be determined by the contents of an EAP packet
+   sent along with the Accept/Reject indication, or the absence of such
+   an encapsulated EAP packet.
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 13]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+2.4.  Peer-to-Peer Operation
+
+   Since EAP is a peer-to-peer protocol, an independent and simultaneous
+   authentication may take place in the reverse direction (depending on
+   the capabilities of the lower layer).  Both ends of the link may act
+   as authenticators and peers at the same time.  In this case, it is
+   necessary for both ends to implement EAP authenticator and peer
+   layers.  In addition, the EAP method implementations on both peers
+   must support both authenticator and peer functionality.
+
+   Although EAP supports peer-to-peer operation, some EAP
+   implementations, methods, AAA protocols, and link layers may not
+   support this.  Some EAP methods may support asymmetric
+   authentication, with one type of credential being required for the
+   peer and another type for the authenticator.  Hosts supporting peer-
+   to-peer operation with such a method would need to be provisioned
+   with both types of credentials.
+
+   For example, EAP-TLS [RFC2716] is a client-server protocol in which
+   distinct certificate profiles are typically utilized for the client
+   and server.  This implies that a host supporting peer-to-peer
+   authentication with EAP-TLS would need to implement both the EAP peer
+   and authenticator layers, support both peer and authenticator roles
+   in the EAP-TLS implementation, and provision certificates appropriate
+   for each role.
+
+   AAA protocols such as RADIUS/EAP [RFC3579] and Diameter EAP [DIAM-
+   EAP] only support "pass-through authenticator" operation.  As noted
+   in [RFC3579] Section 2.6.2, a RADIUS server responds to an Access-
+   Request encapsulating an EAP-Request, Success, or Failure packet with
+   an Access-Reject.  There is therefore no support for "pass-through
+   peer" operation.
+
+   Even where a method is used which supports mutual authentication and
+   result indications, several considerations may dictate that two EAP
+   authentications (one in each direction) are required.  These include:
+
+   [1] Support for bi-directional session key derivation in the lower
+       layer.  Lower layers such as IEEE 802.11 may only support uni-
+       directional derivation and transport of transient session keys.
+       For example, the group-key handshake defined in [IEEE-802.11i] is
+       uni-directional, since in IEEE 802.11 infrastructure mode, only
+       the Access Point (AP) sends multicast/broadcast traffic.  In IEEE
+       802.11 ad hoc mode, where either peer may send
+       multicast/broadcast traffic, two uni-directional group-key
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 14]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+       exchanges are required.  Due to limitations of the design, this
+       also implies the need for unicast key derivations and EAP method
+       exchanges to occur in each direction.
+
+   [2] Support for tie-breaking in the lower layer.  Lower layers such
+       as IEEE 802.11 ad hoc do not support "tie breaking" wherein two
+       hosts initiating authentication with each other will only go
+       forward with a single authentication.  This implies that even if
+       802.11 were to support a bi-directional group-key handshake, then
+       two authentications, one in each direction, might still occur.
+
+   [3] Peer policy satisfaction.  EAP methods may support result
+       indications, enabling the peer to indicate to the EAP server
+       within the method that it successfully authenticated the EAP
+       server, as well as for the server to indicate that it has
+       authenticated the peer.  However, a pass-through authenticator
+       will not be aware that the peer has accepted the credentials
+       offered by the EAP server, unless this information is provided to
+       the authenticator via the AAA protocol.  The authenticator SHOULD
+       interpret the receipt of a key attribute within an Accept packet
+       as an indication that the peer has successfully authenticated the
+       server.
+
+   However, it is possible that the EAP peer's access policy was not
+   satisfied during the initial EAP exchange, even though mutual
+   authentication occurred.  For example, the EAP authenticator may not
+   have demonstrated authorization to act in both peer and authenticator
+   roles.  As a result, the peer may require an additional
+   authentication in the reverse direction, even if the peer provided an
+   indication that the EAP server had successfully authenticated to it.
+
+3.  Lower Layer Behavior
+
+3.1.  Lower Layer Requirements
+
+   EAP makes the following assumptions about lower layers:
+
+   [1] Unreliable transport.  In EAP, the authenticator retransmits
+       Requests that have not yet received Responses so that EAP does
+       not assume that lower layers are reliable.  Since EAP defines its
+       own retransmission behavior, it is possible (though undesirable)
+       for retransmission to occur both in the lower layer and the EAP
+       layer when EAP is run over a reliable lower layer.
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 15]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   Note that EAP Success and Failure packets are not retransmitted.
+   Without a reliable lower layer, and with a non-negligible error rate,
+   these packets can be lost, resulting in timeouts.  It is therefore
+   desirable for implementations to improve their resilience to loss of
+   EAP Success or Failure packets, as described in Section 4.2.
+
+   [2] Lower layer error detection.  While EAP does not assume that the
+       lower layer is reliable, it does rely on lower layer error
+       detection (e.g., CRC, Checksum, MIC, etc.).  EAP methods may not
+       include a MIC, or if they do, it may not be computed over all the
+       fields in the EAP packet, such as the Code, Identifier, Length,
+       or Type fields.  As a result, without lower layer error
+       detection, undetected errors could creep into the EAP layer or
+       EAP method layer header fields, resulting in authentication
+       failures.
+
+       For example, EAP TLS [RFC2716], which computes its MIC over the
+       Type-Data field only, regards MIC validation failures as a fatal
+       error.  Without lower layer error detection, this method, and
+       others like it, will not perform reliably.
+
+   [3] Lower layer security.  EAP does not require lower layers to
+       provide security services such as per-packet confidentiality,
+       authentication, integrity, and replay protection.  However, where
+       these security services are available, EAP methods supporting Key
+       Derivation (see Section 7.2.1) can be used to provide dynamic
+       keying material.  This makes it possible to bind the EAP
+       authentication to subsequent data and protect against data
+       modification, spoofing, or replay.  See Section 7.1 for details.
+
+   [4] Minimum MTU.  EAP is capable of functioning on lower layers that
+       provide an EAP MTU size of 1020 octets or greater.
+
+       EAP does not support path MTU discovery, and fragmentation and
+       reassembly is not supported by EAP, nor by the methods defined in
+       this specification: Identity (1), Notification (2), Nak Response
+       (3), MD5-Challenge (4), One Time Password (5), Generic Token Card
+       (6), and expanded Nak Response (254) Types.
+
+       Typically, the EAP peer obtains information on the EAP MTU from
+       the lower layers and sets the EAP frame size to an appropriate
+       value.  Where the authenticator operates in pass-through mode,
+       the authentication server does not have a direct way of
+       determining the EAP MTU, and therefore relies on the
+       authenticator to provide it with this information, such as via
+       the Framed-MTU attribute, as described in [RFC3579], Section 2.4.
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 16]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+       While methods such as EAP-TLS [RFC2716] support fragmentation and
+       reassembly, EAP methods originally designed for use within PPP
+       where a 1500 octet MTU is guaranteed for control frames (see
+       [RFC1661], Section 6.1) may lack fragmentation and reassembly
+       features.
+
+       EAP methods can assume a minimum EAP MTU of 1020 octets in the
+       absence of other information.  EAP methods SHOULD include support
+       for fragmentation and reassembly if their payloads can be larger
+       than this minimum EAP MTU.
+
+       EAP is a lock-step protocol, which implies a certain inefficiency
+       when handling fragmentation and reassembly.  Therefore, if the
+       lower layer supports fragmentation and reassembly (such as where
+       EAP is transported over IP), it may be preferable for
+       fragmentation and reassembly to occur in the lower layer rather
+       than in EAP.  This can be accomplished by providing an
+       artificially large EAP MTU to EAP, causing fragmentation and
+       reassembly to be handled within the lower layer.
+
+   [5] Possible duplication.  Where the lower layer is reliable, it will
+       provide the EAP layer with a non-duplicated stream of packets.
+       However,  while it is desirable that lower layers provide for
+       non-duplication, this is not a requirement.  The Identifier field
+       provides both the peer and authenticator with the ability to
+       detect duplicates.
+
+   [6] Ordering guarantees.  EAP does not require the Identifier to be
+       monotonically increasing, and so is reliant on lower layer
+       ordering guarantees for correct operation.  EAP was originally
+       defined to run on PPP, and [RFC1661] Section 1 has an ordering
+       requirement:
+
+           "The Point-to-Point Protocol is designed for simple links
+           which transport packets between two peers.  These links
+           provide full-duplex simultaneous bi-directional operation,
+           and are assumed to deliver packets in order."
+
+       Lower layer transports for EAP MUST preserve ordering between a
+       source and destination at a given priority level (the ordering
+       guarantee provided by [IEEE-802]).
+
+       Reordering, if it occurs, will typically result in an EAP
+       authentication failure, causing EAP authentication to be re-run.
+       In an environment in which reordering is likely, it is therefore
+       expected that EAP authentication failures will be common.  It is
+       RECOMMENDED that EAP only be run over lower layers that provide
+       ordering guarantees; running EAP over raw IP or UDP transport is
+
+
+
+Aboba, et al.               Standards Track                    [Page 17]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+       NOT RECOMMENDED.  Encapsulation of EAP within RADIUS [RFC3579]
+       satisfies ordering requirements, since RADIUS is a "lockstep"
+       protocol that delivers packets in order.
+
+3.2.  EAP Usage Within PPP
+
+   In order to establish communications over a point-to-point link, each
+   end of the PPP link first sends LCP packets to configure the data
+   link during the Link Establishment phase.  After the link has been
+   established, PPP provides for an optional Authentication phase before
+   proceeding to the Network-Layer Protocol phase.
+
+   By default, authentication is not mandatory.  If authentication of
+   the link is desired, an implementation MUST specify the
+   Authentication Protocol Configuration Option during the Link
+   Establishment phase.
+
+   If the identity of the peer has been established in the
+   Authentication phase, the server can use that identity in the
+   selection of options for the following network layer negotiations.
+
+   When implemented within PPP, EAP does not select a specific
+   authentication mechanism at the PPP Link Control Phase, but rather
+   postpones this until the Authentication Phase.  This allows the
+   authenticator to request more information before determining the
+   specific authentication mechanism.  This also permits the use of a
+   "backend" server which actually implements the various mechanisms
+   while the PPP authenticator merely passes through the authentication
+   exchange.  The PPP Link Establishment and Authentication phases, and
+   the Authentication Protocol Configuration Option, are defined in The
+   Point-to-Point Protocol (PPP) [RFC1661].
+
+3.2.1.  PPP Configuration Option Format
+
+   A summary of the PPP Authentication Protocol Configuration Option
+   format to negotiate EAP follows.  The fields are transmitted from
+   left to right.
+
+   Exactly one EAP packet is encapsulated in the Information field of a
+   PPP Data Link Layer frame where the protocol field indicates type hex
+   C227 (PPP EAP).
+
+
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 18]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Type      |    Length     |     Authentication Protocol   |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Type
+
+      3
+
+   Length
+
+      4
+
+   Authentication Protocol
+
+      C227 (Hex) for Extensible Authentication Protocol (EAP)
+
+3.3.  EAP Usage Within IEEE 802
+
+   The encapsulation of EAP over IEEE 802 is defined in [IEEE-802.1X].
+   The IEEE 802 encapsulation of EAP does not involve PPP, and IEEE
+   802.1X does not include support for link or network layer
+   negotiations.  As a result, within IEEE 802.1X, it is not possible to
+   negotiate non-EAP authentication mechanisms, such as PAP or CHAP
+   [RFC1994].
+
+3.4.  Lower Layer Indications
+
+   The reliability and security of lower layer indications is dependent
+   on the lower layer.  Since EAP is media independent, the presence or
+   absence of lower layer security is not taken into account in the
+   processing of EAP messages.
+
+   To improve reliability, if a peer receives a lower layer success
+   indication as defined in Section 7.2, it MAY conclude that a Success
+   packet has been lost, and behave as if it had actually received a
+   Success packet.  This includes choosing to ignore the Success in some
+   circumstances as described in Section 4.2.
+
+   A discussion of some reliability and security issues with lower layer
+   indications in PPP, IEEE 802 wired networks, and IEEE 802.11 wireless
+   LANs can be found in the Security Considerations, Section 7.12.
+
+   After EAP authentication is complete, the peer will typically
+   transmit and receive data via the authenticator.  It is desirable to
+   provide assurance that the entities transmitting data are the same
+   ones that successfully completed EAP authentication.  To accomplish
+
+
+
+Aboba, et al.               Standards Track                    [Page 19]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   this, it is necessary for the lower layer to provide per-packet
+   integrity, authentication and replay protection, and to bind these
+   per-packet services to the keys derived during EAP authentication.
+   Otherwise, it is possible for subsequent data traffic to be modified,
+   spoofed, or replayed.
+
+   Where keying material for the lower layer ciphersuite is itself
+   provided by EAP, ciphersuite negotiation and key activation are
+   controlled by the lower layer.  In PPP, ciphersuites are negotiated
+   within ECP so that it is not possible to use keys derived from EAP
+   authentication until the completion of ECP.  Therefore, an initial
+   EAP exchange cannot be protected by a PPP ciphersuite, although EAP
+   re-authentication can be protected.
+
+   In IEEE 802 media, initial key activation also typically occurs after
+   completion of EAP authentication.  Therefore an initial EAP exchange
+   typically cannot be protected by the lower layer ciphersuite,
+   although an EAP re-authentication or pre-authentication exchange can
+   be protected.
+
+4.  EAP Packet Format
+
+   A summary of the EAP packet format is shown below.  The fields are
+   transmitted from left to right.
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Code      |  Identifier   |            Length             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |    Data ...
+   +-+-+-+-+
+
+   Code
+
+      The Code field is one octet and identifies the Type of EAP packet.
+      EAP Codes are assigned as follows:
+
+         1       Request
+         2       Response
+         3       Success
+         4       Failure
+
+      Since EAP only defines Codes 1-4, EAP packets with other codes
+      MUST be silently discarded by both authenticators and peers.
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 20]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   Identifier
+
+      The Identifier field is one octet and aids in matching Responses
+      with Requests.
+
+   Length
+
+      The Length field is two octets and indicates the length, in
+      octets, of the EAP packet including the Code, Identifier, Length,
+      and Data fields.  Octets outside the range of the Length field
+      should be treated as Data Link Layer padding and MUST be ignored
+      upon reception.  A message with the Length field set to a value
+      larger than the number of received octets MUST be silently
+      discarded.
+
+   Data
+
+      The Data field is zero or more octets.  The format of the Data
+      field is determined by the Code field.
+
+4.1.  Request and Response
+
+   Description
+
+      The Request packet (Code field set to 1) is sent by the
+      authenticator to the peer.  Each Request has a Type field which
+      serves to indicate what is being requested.  Additional Request
+      packets MUST be sent until a valid Response packet is received, an
+      optional retry counter expires, or a lower layer failure
+      indication is received.
+
+      Retransmitted Requests MUST be sent with the same Identifier value
+      in order to distinguish them from new Requests.  The content of
+      the data field is dependent on the Request Type.  The peer MUST
+      send a Response packet in reply to a valid Request packet.
+      Responses MUST only be sent in reply to a valid Request and never
+      be retransmitted on a timer.
+
+      If a peer receives a valid duplicate Request for which it has
+      already sent a Response, it MUST resend its original Response
+      without reprocessing the Request.  Requests MUST be processed in
+      the order that they are received, and MUST be processed to their
+      completion before inspecting the next Request.
+
+   A summary of the Request and Response packet format follows.  The
+   fields are transmitted from left to right.
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 21]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Code      |  Identifier   |            Length             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Type      |  Type-Data ...
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
+
+   Code
+
+      1 for Request
+      2 for Response
+
+   Identifier
+
+      The Identifier field is one octet.  The Identifier field MUST be
+      the same if a Request packet is retransmitted due to a timeout
+      while waiting for a Response.  Any new (non-retransmission)
+      Requests MUST modify the Identifier field.
+
+      The Identifier field of the Response MUST match that of the
+      currently outstanding Request.  An authenticator receiving a
+      Response whose Identifier value does not match that of the
+      currently outstanding Request MUST silently discard the Response.
+
+      In order to avoid confusion between new Requests and
+      retransmissions, the Identifier value chosen for each new Request
+      need only be different from the previous Request, but need not be
+      unique within the conversation.  One way to achieve this is to
+      start the Identifier at an initial value and increment it for each
+      new Request.  Initializing the first Identifier with a random
+      number rather than starting from zero is recommended, since it
+      makes sequence attacks somewhat more difficult.
+
+      Since the Identifier space is unique to each session,
+      authenticators are not restricted to only 256 simultaneous
+      authentication conversations.  Similarly, with re-authentication,
+      an EAP conversation might continue over a long period of time, and
+      is not limited to only 256 roundtrips.
+
+   Implementation Note: The authenticator is responsible for
+   retransmitting Request messages.  If the Request message is obtained
+   from elsewhere (such as from a backend authentication server), then
+   the authenticator will need to save a copy of the Request in order to
+   accomplish this.  The peer is responsible for detecting and handling
+   duplicate Request messages before processing them in any way,
+   including passing them on to an outside party.  The authenticator is
+   also responsible for discarding Response messages with a non-matching
+
+
+
+Aboba, et al.               Standards Track                    [Page 22]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   Identifier value before acting on them in any way, including passing
+   them on to the backend authentication server for verification.  Since
+   the authenticator can retransmit before receiving a Response from the
+   peer, the authenticator can receive multiple Responses, each with a
+   matching Identifier.  Until a new Request is received by the
+   authenticator, the Identifier value is not updated, so that the
+   authenticator forwards Responses to the backend authentication
+   server, one at a time.
+
+   Length
+
+      The Length field is two octets and indicates the length of the EAP
+      packet including the Code, Identifier, Length, Type, and Type-Data
+      fields.  Octets outside the range of the Length field should be
+      treated as Data Link Layer padding and MUST be ignored upon
+      reception.  A message with the Length field set to a value larger
+      than the number of received octets MUST be silently discarded.
+
+   Type
+
+      The Type field is one octet.  This field indicates the Type of
+      Request or Response.  A single Type MUST be specified for each EAP
+      Request or Response.  An initial specification of Types follows in
+      Section 5 of this document.
+
+      The Type field of a Response MUST either match that of the
+      Request, or correspond to a legacy or Expanded Nak (see Section
+      5.3) indicating that a Request Type is unacceptable to the peer.
+      A peer MUST NOT send a Nak (legacy or expanded) in response to a
+      Request, after an initial non-Nak Response has been sent.  An EAP
+      server receiving a Response not meeting these requirements MUST
+      silently discard it.
+
+   Type-Data
+
+      The Type-Data field varies with the Type of Request and the
+      associated Response.
+
+4.2.  Success and Failure
+
+   The Success packet is sent by the authenticator to the peer after
+   completion of an EAP authentication method (Type 4 or greater) to
+   indicate that the peer has authenticated successfully to the
+   authenticator.  The authenticator MUST transmit an EAP packet with
+   the Code field set to 3 (Success).  If the authenticator cannot
+   authenticate the peer (unacceptable Responses to one or more
+   Requests), then after unsuccessful completion of the EAP method in
+   progress, the implementation MUST transmit an EAP packet with the
+
+
+
+Aboba, et al.               Standards Track                    [Page 23]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   Code field set to 4 (Failure).  An authenticator MAY wish to issue
+   multiple Requests before sending a Failure response in order to allow
+   for human typing mistakes.  Success and Failure packets MUST NOT
+   contain additional data.
+
+   Success and Failure packets MUST NOT be sent by an EAP authenticator
+   if the specification of the given method does not explicitly permit
+   the method to finish at that point.  A peer EAP implementation
+   receiving a Success or Failure packet where sending one is not
+   explicitly permitted MUST silently discard it.  By default, an EAP
+   peer MUST silently discard a "canned" Success packet (a Success
+   packet sent immediately upon connection).  This ensures that a rogue
+   authenticator will not be able to bypass mutual authentication by
+   sending a Success packet prior to conclusion of the EAP method
+   conversation.
+
+   Implementation Note: Because the Success and Failure packets are not
+   acknowledged, they are not retransmitted by the authenticator, and
+   may be potentially lost.  A peer MUST allow for this circumstance as
+   described in this note.  See also Section 3.4 for guidance on the
+   processing of lower layer success and failure indications.
+
+   As described in Section 2.1, only a single EAP authentication method
+   is allowed within an EAP conversation.  EAP methods may implement
+   result indications.  After the authenticator sends a failure result
+   indication to the peer, regardless of the response from the peer, it
+   MUST subsequently send a Failure packet.  After the authenticator
+   sends a success result indication to the peer and receives a success
+   result indication from the peer, it MUST subsequently send a Success
+   packet.
+
+   On the peer, once the method completes unsuccessfully (that is,
+   either the authenticator sends a failure result indication, or the
+   peer decides that it does not want to continue the conversation,
+   possibly after sending a failure result indication), the peer MUST
+   terminate the conversation and indicate failure to the lower layer.
+   The peer MUST silently discard Success packets and MAY silently
+   discard Failure packets.  As a result, loss of a Failure packet need
+   not result in a timeout.
+
+   On the peer, after success result indications have been exchanged by
+   both sides, a Failure packet MUST be silently discarded.  The peer
+   MAY, in the event that an EAP Success is not received, conclude that
+   the EAP Success packet was lost and that authentication concluded
+   successfully.
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 24]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   If the authenticator has not sent a result indication, and the peer
+   is willing to continue the conversation, the peer waits for a Success
+   or Failure packet once the method completes, and MUST NOT silently
+   discard either of them.  In the event that neither a Success nor
+   Failure packet is received, the peer SHOULD terminate the
+   conversation to avoid lengthy timeouts in case the lost packet was an
+   EAP Failure.
+
+   If the peer attempts to authenticate to the authenticator and fails
+   to do so, the authenticator MUST send a Failure packet and MUST NOT
+   grant access by sending a Success packet.  However, an authenticator
+   MAY omit having the peer authenticate to it in situations where
+   limited access is offered (e.g., guest access).  In this case, the
+   authenticator MUST send a Success packet.
+
+   Where the peer authenticates successfully to the authenticator, but
+   the authenticator does not send a result indication, the
+   authenticator MAY deny access by sending a Failure packet where the
+   peer is not currently authorized for network access.
+
+   A summary of the Success and Failure packet format is shown below.
+   The fields are transmitted from left to right.
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Code      |  Identifier   |            Length             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Code
+
+      3 for Success
+      4 for Failure
+
+   Identifier
+
+      The Identifier field is one octet and aids in matching replies to
+      Responses.  The Identifier field MUST match the Identifier field
+      of the Response packet that it is sent in response to.
+
+   Length
+
+      4
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 25]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+4.3.  Retransmission Behavior
+
+   Because the authentication process will often involve user input,
+   some care must be taken when deciding upon retransmission strategies
+   and authentication timeouts.  By default, where EAP is run over an
+   unreliable lower layer, the EAP retransmission timer SHOULD be
+   dynamically estimated.  A maximum of 3-5 retransmissions is
+   suggested.
+
+   When run over a reliable lower layer (e.g., EAP over ISAKMP/TCP, as
+   within [PIC]), the authenticator retransmission timer SHOULD be set
+   to an infinite value, so that retransmissions do not occur at the EAP
+   layer.  The peer may still maintain a timeout value so as to avoid
+   waiting indefinitely for a Request.
+
+   Where the authentication process requires user input, the measured
+   round trip times may be determined by user responsiveness rather than
+   network characteristics, so that dynamic RTO estimation may not be
+   helpful.  Instead, the retransmission timer SHOULD be set so as to
+   provide sufficient time for the user to respond, with longer timeouts
+   required in certain cases, such as where Token Cards (see Section
+   5.6) are involved.
+
+   In order to provide the EAP authenticator with guidance as to the
+   appropriate timeout value, a hint can be communicated to the
+   authenticator by the backend authentication server (such as via the
+   RADIUS Session-Timeout attribute).
+
+   In order to dynamically estimate the EAP retransmission timer, the
+   algorithms for the estimation of SRTT, RTTVAR, and RTO described in
+   [RFC2988] are RECOMMENDED, including use of Karn's algorithm, with
+   the following potential modifications:
+
+   [a] In order to avoid synchronization behaviors that can occur with
+       fixed timers among distributed systems, the retransmission timer
+       is calculated with a jitter by using the RTO value and randomly
+       adding a value drawn between -RTOmin/2 and RTOmin/2.  Alternative
+       calculations to create jitter MAY be used.  These MUST be
+       pseudo-random.  For a discussion of pseudo-random number
+       generation, see [RFC1750].
+
+   [b] When EAP is transported over a single link (as opposed to over
+       the Internet), smaller values of RTOinitial, RTOmin, and RTOmax
+       MAY be used.  Recommended values are RTOinitial=1 second,
+       RTOmin=200ms, and RTOmax=20 seconds.
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 26]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   [c] When EAP is transported over a single link (as opposed to over
+       the Internet), estimates MAY be done on a per-authenticator
+       basis, rather than a per-session basis.  This enables the
+       retransmission estimate to make the most use of information on
+       link-layer behavior.
+
+   [d] An EAP implementation MAY clear SRTT and RTTVAR after backing off
+       the timer multiple times, as it is likely that the current SRTT
+       and RTTVAR are bogus in this situation.  Once SRTT and RTTVAR are
+       cleared, they should be initialized with the next RTT sample
+       taken as described in [RFC2988] equation 2.2.
+
+5.  Initial EAP Request/Response Types
+
+   This section defines the initial set of EAP Types used in Request/
+   Response exchanges.  More Types may be defined in future documents.
+   The Type field is one octet and identifies the structure of an EAP
+   Request or Response packet.  The first 3 Types are considered special
+   case Types.
+
+   The remaining Types define authentication exchanges.  Nak (Type 3) or
+   Expanded Nak (Type 254) are valid only for Response packets, they
+   MUST NOT be sent in a Request.
+
+   All EAP implementations MUST support Types 1-4, which are defined in
+   this document, and SHOULD support Type 254.  Implementations MAY
+   support other Types defined here or in future RFCs.
+
+             1       Identity
+             2       Notification
+             3       Nak (Response only)
+             4       MD5-Challenge
+             5       One Time Password (OTP)
+             6       Generic Token Card (GTC)
+           254       Expanded Types
+           255       Experimental use
+
+   EAP methods MAY support authentication based on shared secrets.  If
+   the shared secret is a passphrase entered by the user,
+   implementations MAY support entering passphrases with non-ASCII
+   characters.  In this case, the input should be processed using an
+   appropriate stringprep [RFC3454] profile, and encoded in octets using
+   UTF-8 encoding [RFC2279].  A preliminary version of a possible
+   stringprep profile is described in [SASLPREP].
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 27]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+5.1.  Identity
+
+   Description
+
+      The Identity Type is used to query the identity of the peer.
+      Generally, the authenticator will issue this as the initial
+      Request.  An optional displayable message MAY be included to
+      prompt the peer in the case where there is an expectation of
+      interaction with a user.  A Response of Type 1 (Identity) SHOULD
+      be sent in Response to a Request with a Type of 1 (Identity).
+
+      Some EAP implementations piggy-back various options into the
+      Identity Request after a NUL-character.  By default, an EAP
+      implementation SHOULD NOT assume that an Identity Request or
+      Response can be larger than 1020 octets.
+
+      It is RECOMMENDED that the Identity Response be used primarily for
+      routing purposes and selecting which EAP method to use.  EAP
+      Methods SHOULD include a method-specific mechanism for obtaining
+      the identity, so that they do not have to rely on the Identity
+      Response.  Identity Requests and Responses are sent in cleartext,
+      so an attacker may snoop on the identity, or even modify or spoof
+      identity exchanges.  To address these threats, it is preferable
+      for an EAP method to include an identity exchange that supports
+      per-packet authentication, integrity and replay protection, and
+      confidentiality.  The Identity Response may not be the appropriate
+      identity for the method; it may have been truncated or obfuscated
+      so as to provide privacy, or it may have been decorated for
+      routing purposes.  Where the peer is configured to only accept
+      authentication methods supporting protected identity exchanges,
+      the peer MAY provide an abbreviated Identity Response (such as
+      omitting the peer-name portion of the NAI [RFC2486]).  For further
+      discussion of identity protection, see Section 7.3.
+
+   Implementation Note: The peer MAY obtain the Identity via user input.
+   It is suggested that the authenticator retry the Identity Request in
+   the case of an invalid Identity or authentication failure to allow
+   for potential typos on the part of the user.  It is suggested that
+   the Identity Request be retried a minimum of 3 times before
+   terminating the authentication.  The Notification Request MAY be used
+   to indicate an invalid authentication attempt prior to transmitting a
+   new Identity Request (optionally, the failure MAY be indicated within
+   the message of the new Identity Request itself).
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 28]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   Type
+
+      1
+
+   Type-Data
+
+      This field MAY contain a displayable message in the Request,
+      containing UTF-8 encoded ISO 10646 characters [RFC2279].  Where
+      the Request contains a null, only the portion of the field prior
+      to the null is displayed.  If the Identity is unknown, the
+      Identity Response field should be zero bytes in length.  The
+      Identity Response field MUST NOT be null terminated.  In all
+      cases, the length of the Type-Data field is derived from the
+      Length field of the Request/Response packet.
+
+   Security Claims (see Section 7.2):
+
+      Auth. mechanism:           None
+      Ciphersuite negotiation:   No
+      Mutual authentication:     No
+      Integrity protection:      No
+      Replay protection:         No
+      Confidentiality:           No
+      Key derivation:            No
+      Key strength:              N/A
+      Dictionary attack prot.:   N/A
+      Fast reconnect:            No
+      Crypt. binding:            N/A
+      Session independence:      N/A
+      Fragmentation:             No
+      Channel binding:           No
+
+5.2.  Notification
+
+   Description
+
+      The Notification Type is optionally used to convey a displayable
+      message from the authenticator to the peer.  An authenticator MAY
+      send a Notification Request to the peer at any time when there is
+      no outstanding Request, prior to completion of an EAP
+      authentication method.  The peer MUST respond to a Notification
+      Request with a Notification Response unless the EAP authentication
+      method specification prohibits the use of Notification messages.
+      In any case, a Nak Response MUST NOT be sent in response to a
+      Notification Request.  Note that the default maximum length of a
+      Notification Request is 1020 octets.  By default, this leaves at
+      most 1015 octets for the human readable message.
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 29]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+      An EAP method MAY indicate within its specification that
+      Notification messages must not be sent during that method.  In
+      this case, the peer MUST silently discard Notification Requests
+      from the point where an initial Request for that Type is answered
+      with a Response of the same Type.
+
+      The peer SHOULD display this message to the user or log it if it
+      cannot be displayed.  The Notification Type is intended to provide
+      an acknowledged notification of some imperative nature, but it is
+      not an error indication, and therefore does not change the state
+      of the peer.  Examples include a password with an expiration time
+      that is about to expire, an OTP sequence integer which is nearing
+      0, an authentication failure warning, etc.  In most circumstances,
+      Notification should not be required.
+
+   Type
+
+      2
+
+   Type-Data
+
+      The Type-Data field in the Request contains a displayable message
+      greater than zero octets in length, containing UTF-8 encoded ISO
+      10646 characters [RFC2279].  The length of the message is
+      determined by the Length field of the Request packet.  The message
+      MUST NOT be null terminated.  A Response MUST be sent in reply to
+      the Request with a Type field of 2 (Notification).  The Type-Data
+      field of the Response is zero octets in length.  The Response
+      should be sent immediately (independent of how the message is
+      displayed or logged).
+
+   Security Claims (see Section 7.2):
+
+      Auth. mechanism:           None
+      Ciphersuite negotiation:   No
+      Mutual authentication:     No
+      Integrity protection:      No
+      Replay protection:         No
+      Confidentiality:           No
+      Key derivation:            No
+      Key strength:              N/A
+      Dictionary attack prot.:   N/A
+      Fast reconnect:            No
+      Crypt. binding:            N/A
+      Session independence:      N/A
+      Fragmentation:             No
+      Channel binding:           No
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 30]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+5.3.  Nak
+
+5.3.1.  Legacy Nak
+
+   Description
+
+      The legacy Nak Type is valid only in Response messages.  It is
+      sent in reply to a Request where the desired authentication Type
+      is unacceptable.  Authentication Types are numbered 4 and above.
+      The Response contains one or more authentication Types desired by
+      the Peer.  Type zero (0) is used to indicate that the sender has
+      no viable alternatives, and therefore the authenticator SHOULD NOT
+      send another Request after receiving a Nak Response containing a
+      zero value.
+
+      Since the legacy Nak Type is valid only in Responses and has very
+      limited functionality, it MUST NOT be used as a general purpose
+      error indication, such as for communication of error messages, or
+      negotiation of parameters specific to a particular EAP method.
+
+   Code
+
+      2 for Response.
+
+   Identifier
+
+      The Identifier field is one octet and aids in matching Responses
+      with Requests.  The Identifier field of a legacy Nak Response MUST
+      match the Identifier field of the Request packet that it is sent
+      in response to.
+
+   Length
+
+      >=6
+
+   Type
+
+      3
+
+   Type-Data
+
+      Where a peer receives a Request for an unacceptable authentication
+      Type (4-253,255), or a peer lacking support for Expanded Types
+      receives a Request for Type 254, a Nak Response (Type 3) MUST be
+      sent.  The Type-Data field of the Nak Response (Type 3) MUST
+      contain one or more octets indicating the desired authentication
+      Type(s), one octet per Type, or the value zero (0) to indicate no
+      proposed alternative.  A peer supporting Expanded Types that
+
+
+
+Aboba, et al.               Standards Track                    [Page 31]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+      receives a Request for an unacceptable authentication Type (4-253,
+      255) MAY include the value 254 in the Nak Response (Type 3) to
+      indicate the desire for an Expanded authentication Type. If the
+      authenticator can accommodate this preference, it will respond
+      with an Expanded Type Request (Type 254).
+
+   Security Claims (see Section 7.2):
+
+      Auth. mechanism:           None
+      Ciphersuite negotiation:   No
+      Mutual authentication:     No
+      Integrity protection:      No
+      Replay protection:         No
+      Confidentiality:           No
+      Key derivation:            No
+      Key strength:              N/A
+      Dictionary attack prot.:   N/A
+      Fast reconnect:            No
+      Crypt. binding:            N/A
+      Session independence:      N/A
+      Fragmentation:             No
+      Channel binding:           No
+
+
+5.3.2.  Expanded Nak
+
+   Description
+
+      The Expanded Nak Type is valid only in Response messages.  It MUST
+      be sent only in reply to a Request of Type 254 (Expanded Type)
+      where the authentication Type is unacceptable.  The Expanded Nak
+      Type uses the Expanded Type format itself, and the Response
+      contains one or more authentication Types desired by the peer, all
+      in Expanded Type format.  Type zero (0) is used to indicate that
+      the sender has no viable alternatives.  The general format of the
+      Expanded Type is described in Section 5.7.
+
+      Since the Expanded Nak Type is valid only in Responses and has
+      very limited functionality, it MUST NOT be used as a general
+      purpose error indication, such as for communication of error
+      messages, or negotiation of parameters specific to a particular
+      EAP method.
+
+   Code
+
+      2 for Response.
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 32]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   Identifier
+
+      The Identifier field is one octet and aids in matching Responses
+      with Requests.  The Identifier field of an Expanded Nak Response
+      MUST match the Identifier field of the Request packet that it is
+      sent in response to.
+
+   Length
+
+      >=20
+
+   Type
+
+      254
+
+   Vendor-Id
+
+      0 (IETF)
+
+   Vendor-Type
+
+      3 (Nak)
+
+   Vendor-Data
+
+      The Expanded Nak Type is only sent when the Request contains an
+      Expanded Type (254) as defined in Section 5.7.  The Vendor-Data
+      field of the Nak Response MUST contain one or more authentication
+      Types (4 or greater), all in expanded format, 8 octets per Type,
+      or the value zero (0), also in Expanded Type format, to indicate
+      no proposed alternative.  The desired authentication Types may
+      include a mixture of Vendor-Specific and IETF Types.  For example,
+      an Expanded Nak Response indicating a preference for OTP (Type 5),
+      and an MIT (Vendor-Id=20) Expanded Type of 6 would appear as
+      follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 33]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     2         |  Identifier   |           Length=28           |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |   Type=254    |                0 (IETF)                       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                3 (Nak)                        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |   Type=254    |                0 (IETF)                       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                5 (OTP)                        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |   Type=254    |                20 (MIT)                       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                6                              |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   An Expanded Nak Response indicating a no desired alternative would
+   appear as follows:
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     2         |  Identifier   |           Length=20           |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |   Type=254    |                0 (IETF)                       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                3 (Nak)                        |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |   Type=254    |                0 (IETF)                       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                                0 (No alternative)             |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Security Claims (see Section 7.2):
+
+      Auth. mechanism:           None
+      Ciphersuite negotiation:   No
+      Mutual authentication:     No
+      Integrity protection:      No
+      Replay protection:         No
+      Confidentiality:           No
+      Key derivation:            No
+      Key strength:              N/A
+      Dictionary attack prot.:   N/A
+      Fast reconnect:            No
+      Crypt. binding:            N/A
+
+
+
+Aboba, et al.               Standards Track                    [Page 34]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+      Session independence:      N/A
+      Fragmentation:             No
+      Channel binding:           No
+
+
+5.4.  MD5-Challenge
+
+   Description
+
+      The MD5-Challenge Type is analogous to the PPP CHAP protocol
+      [RFC1994] (with MD5 as the specified algorithm).  The Request
+      contains a "challenge" message to the peer.  A Response MUST be
+      sent in reply to the Request.  The Response MAY be either of Type
+      4 (MD5-Challenge), Nak (Type 3), or Expanded Nak (Type 254).  The
+      Nak reply indicates the peer's desired authentication Type(s).
+      EAP peer and EAP server implementations MUST support the MD5-
+      Challenge mechanism.  An authenticator that supports only pass-
+      through MUST allow communication with a backend authentication
+      server that is capable of supporting MD5-Challenge, although the
+      EAP authenticator implementation need not support MD5-Challenge
+      itself.  However, if the EAP authenticator can be configured to
+      authenticate peers locally (e.g., not operate in pass-through),
+      then the requirement for support of the MD5-Challenge mechanism
+      applies.
+
+      Note that the use of the Identifier field in the MD5-Challenge
+      Type is different from that described in [RFC1994].  EAP allows
+      for retransmission of MD5-Challenge Request packets, while
+      [RFC1994] states that both the Identifier and Challenge fields
+      MUST change each time a Challenge (the CHAP equivalent of the
+      MD5-Challenge Request packet) is sent.
+
+      Note: [RFC1994] treats the shared secret as an octet string, and
+      does not specify how it is entered into the system (or if it is
+      handled by the user at all).  EAP MD5-Challenge implementations
+      MAY support entering passphrases with non-ASCII characters.  See
+      Section 5 for instructions how the input should be processed and
+      encoded into octets.
+
+   Type
+
+      4
+
+   Type-Data
+
+      The contents of the Type-Data field is summarized below.  For
+      reference on the use of these fields, see the PPP Challenge
+      Handshake Authentication Protocol [RFC1994].
+
+
+
+Aboba, et al.               Standards Track                    [Page 35]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |  Value-Size   |  Value ...
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |  Name ...
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Security Claims (see Section 7.2):
+
+      Auth. mechanism:           Password or pre-shared key.
+      Ciphersuite negotiation:   No
+      Mutual authentication:     No
+      Integrity protection:      No
+      Replay protection:         No
+      Confidentiality:           No
+      Key derivation:            No
+      Key strength:              N/A
+      Dictionary attack prot.:   No
+      Fast reconnect:            No
+      Crypt. binding:            N/A
+      Session independence:      N/A
+      Fragmentation:             No
+      Channel binding:           No
+
+5.5.  One-Time Password (OTP)
+
+   Description
+
+      The One-Time Password system is defined in "A One-Time Password
+      System" [RFC2289] and "OTP Extended Responses" [RFC2243].  The
+      Request contains an OTP challenge in the format described in
+      [RFC2289].  A Response MUST be sent in reply to the Request.  The
+      Response MUST be of Type 5 (OTP), Nak (Type 3), or Expanded Nak
+      (Type 254).  The Nak Response indicates the peer's desired
+      authentication Type(s).  The EAP OTP method is intended for use
+      with the One-Time Password system only, and MUST NOT be used to
+      provide support for cleartext passwords.
+
+   Type
+
+      5
+
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 36]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   Type-Data
+
+      The Type-Data field contains the OTP "challenge" as a displayable
+      message in the Request.  In the Response, this field is used for
+      the 6 words from the OTP dictionary [RFC2289].  The messages MUST
+      NOT be null terminated.  The length of the field is derived from
+      the Length field of the Request/Reply packet.
+
+      Note: [RFC2289] does not specify how the secret pass-phrase is
+      entered by the user, or how the pass-phrase is converted into
+      octets.  EAP OTP implementations MAY support entering passphrases
+      with non-ASCII characters.  See Section 5 for instructions on how
+      the input should be processed and encoded into octets.
+
+   Security Claims (see Section 7.2):
+
+      Auth. mechanism:           One-Time Password
+      Ciphersuite negotiation:   No
+      Mutual authentication:     No
+      Integrity protection:      No
+      Replay protection:         Yes
+      Confidentiality:           No
+      Key derivation:            No
+      Key strength:              N/A
+      Dictionary attack prot.:   No
+      Fast reconnect:            No
+      Crypt. binding:            N/A
+      Session independence:      N/A
+      Fragmentation:             No
+      Channel binding:           No
+
+
+5.6.  Generic Token Card (GTC)
+
+   Description
+
+      The Generic Token Card Type is defined for use with various Token
+      Card implementations which require user input.  The Request
+      contains a displayable message and the Response contains the Token
+      Card information necessary for authentication.  Typically, this
+      would be information read by a user from the Token card device and
+      entered as ASCII text.  A Response MUST be sent in reply to the
+      Request.  The Response MUST be of Type 6 (GTC), Nak (Type 3), or
+      Expanded Nak (Type 254).  The Nak Response indicates the peer's
+      desired authentication Type(s).  The EAP GTC method is intended
+      for use with the Token Cards supporting challenge/response
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 37]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+      authentication and MUST NOT be used to provide support for
+      cleartext passwords in the absence of a protected tunnel with
+      server authentication.
+
+   Type
+
+      6
+
+   Type-Data
+
+      The Type-Data field in the Request contains a displayable message
+      greater than zero octets in length.  The length of the message is
+      determined by the Length field of the Request packet.  The message
+      MUST NOT be null terminated.  A Response MUST be sent in reply to
+      the Request with a Type field of 6 (Generic Token Card).  The
+      Response contains data from the Token Card required for
+      authentication.  The length of the data is determined by the
+      Length field of the Response packet.
+
+      EAP GTC implementations MAY support entering a response with non-
+      ASCII characters.  See Section 5 for instructions how the input
+      should be processed and encoded into octets.
+
+   Security Claims (see Section 7.2):
+
+      Auth. mechanism:           Hardware token.
+      Ciphersuite negotiation:   No
+      Mutual authentication:     No
+      Integrity protection:      No
+      Replay protection:         No
+      Confidentiality:           No
+      Key derivation:            No
+      Key strength:              N/A
+      Dictionary attack prot.:   No
+      Fast reconnect:            No
+      Crypt. binding:            N/A
+      Session independence:      N/A
+      Fragmentation:             No
+      Channel binding:           No
+
+
+5.7.  Expanded Types
+
+   Description
+
+      Since many of the existing uses of EAP are vendor-specific, the
+      Expanded method Type is available to allow vendors to support
+      their own Expanded Types not suitable for general usage.
+
+
+
+Aboba, et al.               Standards Track                    [Page 38]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+      The Expanded Type is also used to expand the global Method Type
+      space beyond the original 255 values.  A Vendor-Id of 0 maps the
+      original 255 possible Types onto a space of 2^32-1 possible Types.
+      (Type 0 is only used in a Nak Response to indicate no acceptable
+      alternative).
+
+      An implementation that supports the Expanded attribute MUST treat
+      EAP Types that are less than 256 equivalently, whether they appear
+      as a single octet or as the 32-bit Vendor-Type within an Expanded
+      Type where Vendor-Id is 0.  Peers not equipped to interpret the
+      Expanded Type MUST send a Nak as described in Section 5.3.1, and
+      negotiate a more suitable authentication method.
+
+      A summary of the Expanded Type format is shown below.  The fields
+      are transmitted from left to right.
+
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |     Type      |               Vendor-Id                       |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |                          Vendor-Type                          |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |              Vendor data...
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+   Type
+
+      254 for Expanded Type
+
+   Vendor-Id
+
+      The Vendor-Id is 3 octets and represents the SMI Network
+      Management Private Enterprise Code of the Vendor in network byte
+      order, as allocated by IANA.  A Vendor-Id of zero is reserved for
+      use by the IETF in providing an expanded global EAP Type space.
+
+   Vendor-Type
+
+      The Vendor-Type field is four octets and represents the vendor-
+      specific method Type.
+
+      If the Vendor-Id is zero, the Vendor-Type field is an extension
+      and superset of the existing namespace for EAP Types.  The first
+      256 Types are reserved for compatibility with single-octet EAP
+      Types that have already been assigned or may be assigned in the
+      future.  Thus, EAP Types from 0 through 255 are semantically
+      identical, whether they appear as single octet EAP Types or as
+
+
+
+Aboba, et al.               Standards Track                    [Page 39]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+      Vendor-Types when Vendor-Id is zero.  There is one exception to
+      this rule: Expanded Nak and Legacy Nak packets share the same
+      Type, but must be treated differently because they have a
+      different format.
+
+   Vendor-Data
+
+      The Vendor-Data field is defined by the vendor.  Where a Vendor-Id
+      of zero is present, the Vendor-Data field will be used for
+      transporting the contents of EAP methods of Types defined by the
+      IETF.
+
+5.8.  Experimental
+
+   Description
+
+      The Experimental Type has no fixed format or content.  It is
+      intended for use when experimenting with new EAP Types.  This Type
+      is intended for experimental and testing purposes.  No guarantee
+      is made for interoperability between peers using this Type, as
+      outlined in [RFC3692].
+
+   Type
+
+      255
+
+   Type-Data
+
+      Undefined
+
+6.  IANA Considerations
+
+   This section provides guidance to the Internet Assigned Numbers
+   Authority (IANA) regarding registration of values related to the EAP
+   protocol, in accordance with BCP 26, [RFC2434].
+
+   There are two name spaces in EAP that require registration: Packet
+   Codes and method Types.
+
+   EAP is not intended as a general-purpose protocol, and allocations
+   SHOULD NOT be made for purposes unrelated to authentication.
+
+   The following terms are used here with the meanings defined in BCP
+   26: "name space", "assigned value", "registration".
+
+   The following policies are used here with the meanings defined in BCP
+   26: "Private Use", "First Come First Served", "Expert Review",
+   "Specification Required", "IETF Consensus", "Standards Action".
+
+
+
+Aboba, et al.               Standards Track                    [Page 40]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   For registration requests where a Designated Expert should be
+   consulted, the responsible IESG area director should appoint the
+   Designated Expert.  The intention is that any allocation will be
+   accompanied by a published RFC.  But in order to allow for the
+   allocation of values prior to the RFC being approved for publication,
+   the Designated Expert can approve allocations once it seems clear
+   that an RFC will be published.  The Designated expert will post a
+   request to the EAP WG mailing list (or a successor designated by the
+   Area Director) for comment and review, including an Internet-Draft.
+   Before a period of 30 days has passed, the Designated Expert will
+   either approve or deny the registration request and publish a notice
+   of the decision to the EAP WG mailing list or its successor, as well
+   as informing IANA.  A denial notice must be justified by an
+   explanation, and in the cases where it is possible, concrete
+   suggestions on how the request can be modified so as to become
+   acceptable should be provided.
+
+6.1.  Packet Codes
+
+   Packet Codes have a range from 1 to 255, of which 1-4 have been
+   allocated.  Because a new Packet Code has considerable impact on
+   interoperability, a new Packet Code requires Standards Action, and
+   should be allocated starting at 5.
+
+6.2.  Method Types
+
+   The original EAP method Type space has a range from 1 to 255, and is
+   the scarcest resource in EAP, and thus must be allocated with care.
+   Method Types 1-45 have been allocated, with 20 available for re-use.
+   Method Types 20 and 46-191 may be allocated on the advice of a
+   Designated Expert, with Specification Required.
+
+   Allocation of blocks of method Types (more than one for a given
+   purpose) should require IETF Consensus.  EAP Type Values 192-253 are
+   reserved and allocation requires Standards Action.
+
+   Method Type 254 is allocated for the Expanded Type.  Where the
+   Vendor-Id field is non-zero, the Expanded Type is used for functions
+   specific only to one vendor's implementation of EAP, where no
+   interoperability is deemed useful.  When used with a Vendor-Id of
+   zero, method Type 254 can also be used to provide for an expanded
+   IETF method Type space.  Method Type values 256-4294967295 may be
+   allocated after Type values 1-191 have been allocated, on the advice
+   of a Designated Expert, with Specification Required.
+
+   Method Type 255 is allocated for Experimental use, such as testing of
+   new EAP methods before a permanent Type is allocated.
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 41]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+7.  Security Considerations
+
+   This section defines a generic threat model as well as the EAP method
+   security claims mitigating those threats.
+
+   It is expected that the generic threat model and corresponding
+   security claims will used to define EAP method requirements for use
+   in specific environments.  An example of such a requirements analysis
+   is provided in [IEEE-802.11i-req].  A security claims section is
+   required in EAP method specifications, so that EAP methods can be
+   evaluated against the requirements.
+
+7.1.  Threat Model
+
+   EAP was developed for use with PPP [RFC1661] and was later adapted
+   for use in wired IEEE 802 networks [IEEE-802] in [IEEE-802.1X].
+   Subsequently, EAP has been proposed for use on wireless LAN networks
+   and over the Internet.  In all these situations, it is possible for
+   an attacker to gain access to links over which EAP packets are
+   transmitted.  For example, attacks on telephone infrastructure are
+   documented in [DECEPTION].
+
+   An attacker with access to the link may carry out a number of
+   attacks, including:
+
+   [1]  An attacker may try to discover user identities by snooping
+        authentication traffic.
+
+   [2]  An attacker may try to modify or spoof EAP packets.
+
+   [3]  An attacker may launch denial of service attacks by spoofing
+        lower layer indications or Success/Failure packets, by replaying
+        EAP packets, or by generating packets with overlapping
+        Identifiers.
+
+   [4]  An attacker may attempt to recover the pass-phrase by mounting
+        an offline dictionary attack.
+
+   [5]  An attacker may attempt to convince the peer to connect to an
+        untrusted network by mounting a man-in-the-middle attack.
+
+   [6]  An attacker may attempt to disrupt the EAP negotiation in order
+        cause a weak authentication method to be selected.
+
+   [7]  An attacker may attempt to recover keys by taking advantage of
+        weak key derivation techniques used within EAP methods.
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 42]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   [8]  An attacker may attempt to take advantage of weak ciphersuites
+        subsequently used after the EAP conversation is complete.
+
+   [9]  An attacker may attempt to perform downgrading attacks on lower
+        layer ciphersuite negotiation in order to ensure that a weaker
+        ciphersuite is used subsequently to EAP authentication.
+
+   [10] An attacker acting as an authenticator may provide incorrect
+        information to the EAP peer and/or server via out-of-band
+        mechanisms (such as via a AAA or lower layer protocol).  This
+        includes impersonating another authenticator, or providing
+        inconsistent information to the peer and EAP server.
+
+   Depending on the lower layer, these attacks may be carried out
+   without requiring physical proximity.  Where EAP is used over
+   wireless networks, EAP packets may be forwarded by authenticators
+   (e.g., pre-authentication) so that the attacker need not be within
+   the coverage area of an authenticator in order to carry out an attack
+   on it or its peers.  Where EAP is used over the Internet, attacks may
+   be carried out at an even greater distance.
+
+7.2.  Security Claims
+
+   In order to clearly articulate the security provided by an EAP
+   method, EAP method specifications MUST include a Security Claims
+   section, including the following declarations:
+
+   [a] Mechanism.  This is a statement of the authentication technology:
+       certificates, pre-shared keys, passwords, token cards, etc.
+
+   [b] Security claims.  This is a statement of the claimed security
+       properties of the method, using terms defined in Section 7.2.1:
+       mutual authentication, integrity protection, replay protection,
+       confidentiality, key derivation, dictionary attack resistance,
+       fast reconnect, cryptographic binding.  The Security Claims
+       section of an EAP method specification SHOULD provide
+       justification for the claims that are made.  This can be
+       accomplished by including a proof in an Appendix, or including a
+       reference to a proof.
+
+   [c] Key strength.  If the method derives keys, then the effective key
+       strength MUST be estimated.  This estimate is meant for potential
+       users of the method to determine if the keys produced are strong
+       enough for the intended application.
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 43]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+       The effective key strength SHOULD be stated as a number of bits,
+       defined as follows: If the effective key strength is N bits, the
+       best currently known methods to recover the key (with non-
+       negligible probability) require, on average, an effort comparable
+       to 2^(N-1) operations of a typical block cipher.  The statement
+       SHOULD be accompanied by a short rationale, explaining how this
+       number was derived.  This explanation SHOULD include the
+       parameters required to achieve the stated key strength based on
+       current knowledge of the algorithms.
+
+       (Note: Although it is difficult to define what "comparable
+       effort" and "typical block cipher" exactly mean, reasonable
+       approximations are sufficient here.  Refer to e.g. [SILVERMAN]
+       for more discussion.)
+
+       The key strength depends on the methods used to derive the keys.
+       For instance, if keys are derived from a shared secret (such as a
+       password or a long-term secret), and possibly some public
+       information such as nonces, the effective key strength is limited
+       by the strength of the long-term secret (assuming that the
+       derivation procedure is computationally simple).  To take another
+       example, when using public key algorithms, the strength of the
+       symmetric key depends on the strength of the public keys used.
+
+   [d] Description of key hierarchy.  EAP methods deriving keys MUST
+       either provide a reference to a key hierarchy specification, or
+       describe how Master Session Keys (MSKs) and Extended Master
+       Session Keys (EMSKs) are to be derived.
+
+   [e] Indication of vulnerabilities.  In addition to the security
+       claims that are made, the specification MUST indicate which of
+       the security claims detailed in Section 7.2.1 are NOT being made.
+
+7.2.1.  Security Claims Terminology for EAP Methods
+
+   These terms are used to describe the security properties of EAP
+   methods:
+
+   Protected ciphersuite negotiation
+      This refers to the ability of an EAP method to negotiate the
+      ciphersuite used to protect the EAP conversation, as well as to
+      integrity protect the negotiation.  It does not refer to the
+      ability to negotiate the ciphersuite used to protect data.
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 44]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   Mutual authentication
+      This refers to an EAP method in which, within an interlocked
+      exchange, the authenticator authenticates the peer and the peer
+      authenticates the authenticator.  Two independent one-way methods,
+      running in opposite directions do not provide mutual
+      authentication as defined here.
+
+   Integrity protection
+      This refers to providing data origin authentication and protection
+      against unauthorized modification of information for EAP packets
+      (including EAP Requests and Responses).  When making this claim, a
+      method specification MUST describe the EAP packets and fields
+      within the EAP packet that are protected.
+
+   Replay protection
+      This refers to protection against replay of an EAP method or its
+      messages, including success and failure result indications.
+
+   Confidentiality
+      This refers to encryption of EAP messages, including EAP Requests
+      and Responses, and success and failure result indications.  A
+      method making this claim MUST support identity protection (see
+      Section 7.3).
+
+   Key derivation
+      This refers to the ability of the EAP method to derive exportable
+      keying material, such as the Master Session Key (MSK), and
+      Extended Master Session Key (EMSK).  The MSK is used only for
+      further key derivation, not directly for protection of the EAP
+      conversation or subsequent data.  Use of the EMSK is reserved.
+
+   Key strength
+      If the effective key strength is N bits, the best currently known
+      methods to recover the key (with non-negligible probability)
+      require, on average, an effort comparable to 2^(N-1) operations of
+      a typical block cipher.
+
+   Dictionary attack resistance
+      Where password authentication is used, passwords are commonly
+      selected from a small set (as compared to a set of N-bit keys),
+      which raises a concern about dictionary attacks.  A method may be
+      said to provide protection against dictionary attacks if, when it
+      uses a password as a secret, the method does not allow an offline
+      attack that has a work factor based on the number of passwords in
+      an attacker's dictionary.
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 45]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   Fast reconnect
+      The ability, in the case where a security association has been
+      previously established, to create a new or refreshed security
+      association more efficiently or in a smaller number of round-
+      trips.
+
+   Cryptographic binding
+      The demonstration of the EAP peer to the EAP server that a single
+      entity has acted as the EAP peer for all methods executed within a
+      tunnel method.  Binding MAY also imply that the EAP server
+      demonstrates to the peer that a single entity has acted as the EAP
+      server for all methods executed within a tunnel method.  If
+      executed correctly, binding serves to mitigate man-in-the-middle
+      vulnerabilities.
+
+   Session independence
+      The demonstration that passive attacks (such as capture of the EAP
+      conversation) or active attacks (including compromise of the MSK
+      or EMSK) does not enable compromise of subsequent or prior MSKs or
+      EMSKs.
+
+   Fragmentation
+      This refers to whether an EAP method supports fragmentation and
+      reassembly.  As noted in Section 3.1, EAP methods should support
+      fragmentation and reassembly if EAP packets can exceed the minimum
+      MTU of 1020 octets.
+
+   Channel binding
+      The communication within an EAP method of integrity-protected
+      channel properties such as endpoint identifiers which can be
+      compared to values communicated via out of band mechanisms (such
+      as via a AAA or lower layer protocol).
+
+   Note: This list of security claims is not exhaustive.  Additional
+   properties, such as additional denial-of-service protection, may be
+   relevant as well.
+
+7.3.  Identity Protection
+
+   An Identity exchange is optional within the EAP conversation.
+   Therefore, it is possible to omit the Identity exchange entirely, or
+   to use a method-specific identity exchange once a protected channel
+   has been established.
+
+   However, where roaming is supported as described in [RFC2607], it may
+   be necessary to locate the appropriate backend authentication server
+   before the authentication conversation can proceed.  The realm
+   portion of the Network Access Identifier (NAI) [RFC2486] is typically
+
+
+
+Aboba, et al.               Standards Track                    [Page 46]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   included within the EAP-Response/Identity in order to enable the
+   authentication exchange to be routed to the appropriate backend
+   authentication server.  Therefore, while the peer-name portion of the
+   NAI may be omitted in the EAP-Response/Identity where proxies or
+   relays are present, the realm portion may be required.
+
+   It is possible for the identity in the identity response to be
+   different from the identity authenticated by the EAP method.  This
+   may be intentional in the case of identity privacy.  An EAP method
+   SHOULD use the authenticated identity when making access control
+   decisions.
+
+7.4.  Man-in-the-Middle Attacks
+
+   Where EAP is tunneled within another protocol that omits peer
+   authentication, there exists a potential vulnerability to a man-in-
+   the-middle attack.  For details, see [BINDING] and [MITM].
+
+   As noted in Section 2.1, EAP does not permit untunneled sequences of
+   authentication methods.  Were a sequence of EAP authentication
+   methods to be permitted, the peer might not have proof that a single
+   entity has acted as the authenticator for all EAP methods within the
+   sequence.  For example, an authenticator might terminate one EAP
+   method, then forward the next method in the sequence to another party
+   without the peer's knowledge or consent.  Similarly, the
+   authenticator might not have proof that a single entity has acted as
+   the peer for all EAP methods within the sequence.
+
+   Tunneling EAP within another protocol enables an attack by a rogue
+   EAP authenticator tunneling EAP to a legitimate server.  Where the
+   tunneling protocol is used for key establishment but does not require
+   peer authentication, an attacker convincing a legitimate peer to
+   connect to it will be able to tunnel EAP packets to a legitimate
+   server, successfully authenticating and obtaining the key.  This
+   allows the attacker to successfully establish itself as a man-in-
+   the-middle, gaining access to the network, as well as the ability to
+   decrypt data traffic between the legitimate peer and server.
+
+   This attack may be mitigated by the following measures:
+
+   [a] Requiring mutual authentication within EAP tunneling mechanisms.
+
+   [b] Requiring cryptographic binding between the EAP tunneling
+       protocol and the tunneled EAP methods.  Where cryptographic
+       binding is supported, a mechanism is also needed to protect
+       against downgrade attacks that would bypass it.  For further
+       details on cryptographic binding, see [BINDING].
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 47]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   [c] Limiting the EAP methods authorized for use without protection,
+       based on peer and authenticator policy.
+
+   [d] Avoiding the use of tunnels when a single, strong method is
+       available.
+
+7.5.  Packet Modification Attacks
+
+   While EAP methods may support per-packet data origin authentication,
+   integrity, and replay protection, support is not provided within the
+   EAP layer.
+
+   Since the Identifier is only a single octet, it is easy to guess,
+   allowing an attacker to successfully inject or replay EAP packets.
+   An attacker may also modify EAP headers (Code, Identifier, Length,
+   Type) within EAP packets where the header is unprotected.  This could
+   cause packets to be inappropriately discarded or misinterpreted.
+
+   To protect EAP packets against modification, spoofing, or replay,
+   methods supporting protected ciphersuite negotiation, mutual
+   authentication, and key derivation, as well as integrity and replay
+   protection, are recommended.  See Section 7.2.1 for definitions of
+   these security claims.
+
+   Method-specific MICs may be used to provide protection.  If a per-
+   packet MIC is employed within an EAP method, then peers,
+   authentication servers, and authenticators not operating in pass-
+   through mode MUST validate the MIC.  MIC validation failures SHOULD
+   be logged.  Whether a MIC validation failure is considered a fatal
+   error or not is determined by the EAP method specification.
+
+   It is RECOMMENDED that methods providing integrity protection of EAP
+   packets include coverage of all the EAP header fields, including the
+   Code, Identifier, Length, Type, and Type-Data fields.
+
+   Since EAP messages of Types Identity, Notification, and Nak do not
+   include their own MIC, it may be desirable for the EAP method MIC to
+   cover information contained within these messages, as well as the
+   header of each EAP message.
+
+   To provide protection, EAP also may be encapsulated within a
+   protected channel created by protocols such as ISAKMP [RFC2408], as
+   is done in [IKEv2] or within TLS [RFC2246].  However, as noted in
+   Section 7.4, EAP tunneling may result in a man-in-the-middle
+   vulnerability.
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 48]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   Existing EAP methods define message integrity checks (MICs) that
+   cover more than one EAP packet.  For example, EAP-TLS [RFC2716]
+   defines a MIC over a TLS record that could be split into multiple
+   fragments; within the FINISHED message, the MIC is computed over
+   previous messages.  Where the MIC covers more than one EAP packet, a
+   MIC validation failure is typically considered a fatal error.
+
+   Within EAP-TLS [RFC2716], a MIC validation failure is treated as a
+   fatal error, since that is what is specified in TLS [RFC2246].
+   However, it is also possible to develop EAP methods that support
+   per-packet MICs, and respond to verification failures by silently
+   discarding the offending packet.
+
+   In this document, descriptions of EAP message handling assume that
+   per-packet MIC validation, where it occurs, is effectively performed
+   as though it occurs before sending any responses or changing the
+   state of the host which received the packet.
+
+7.6.  Dictionary Attacks
+
+   Password authentication algorithms such as EAP-MD5, MS-CHAPv1
+   [RFC2433], and Kerberos V [RFC1510] are known to be vulnerable to
+   dictionary attacks.  MS-CHAPv1 vulnerabilities are documented in
+   [PPTPv1]; MS-CHAPv2 vulnerabilities are documented in [PPTPv2];
+   Kerberos vulnerabilities are described in [KRBATTACK], [KRBLIM], and
+   [KERB4WEAK].
+
+   In order to protect against dictionary attacks, authentication
+   methods resistant to dictionary attacks (as defined in Section 7.2.1)
+   are recommended.
+
+   If an authentication algorithm is used that is known to be vulnerable
+   to dictionary attacks, then the conversation may be tunneled within a
+   protected channel in order to provide additional protection.
+   However, as noted in Section 7.4, EAP tunneling may result in a man-
+   in-the-middle vulnerability, and therefore dictionary attack
+   resistant methods are preferred.
+
+7.7.  Connection to an Untrusted Network
+
+   With EAP methods supporting one-way authentication, such as EAP-MD5,
+   the peer does not authenticate the authenticator, making the peer
+   vulnerable to attack by a rogue authenticator.  Methods supporting
+   mutual authentication (as defined in Section 7.2.1) address this
+   vulnerability.
+
+   In EAP there is no requirement that authentication be full duplex or
+   that the same protocol be used in both directions.  It is perfectly
+
+
+
+Aboba, et al.               Standards Track                    [Page 49]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   acceptable for different protocols to be used in each direction.
+   This will, of course, depend on the specific protocols negotiated.
+   However, in general, completing a single unitary mutual
+   authentication is preferable to two one-way authentications, one in
+   each direction.  This is because separate authentications that are
+   not bound cryptographically so as to demonstrate they are part of the
+   same session are subject to man-in-the-middle attacks, as discussed
+   in Section 7.4.
+
+7.8.  Negotiation Attacks
+
+   In a negotiation attack, the attacker attempts to convince the peer
+   and authenticator to negotiate a less secure EAP method.  EAP does
+   not provide protection for Nak Response packets, although it is
+   possible for a method to include coverage of Nak Responses within a
+   method-specific MIC.
+
+   Within or associated with each authenticator, it is not anticipated
+   that a particular named peer will support a choice of methods.  This
+   would make the peer vulnerable to attacks that negotiate the least
+   secure method from among a set.  Instead, for each named peer, there
+   SHOULD be an indication of exactly one method used to authenticate
+   that peer name.  If a peer needs to make use of different
+   authentication methods under different circumstances, then distinct
+   identities SHOULD be employed, each of which identifies exactly one
+   authentication method.
+
+7.9.  Implementation Idiosyncrasies
+
+   The interaction of EAP with lower layers such as PPP and IEEE 802 are
+   highly implementation dependent.
+
+   For example, upon failure of authentication, some PPP implementations
+   do not terminate the link, instead limiting traffic in Network-Layer
+   Protocols to a filtered subset, which in turn allows the peer the
+   opportunity to update secrets or send mail to the network
+   administrator indicating a problem.  Similarly, while an
+   authentication failure will result in denied access to the controlled
+   port in [IEEE-802.1X], limited traffic may be permitted on the
+   uncontrolled port.
+
+   In EAP there is no provision for retries of failed authentication.
+   However, in PPP the LCP state machine can renegotiate the
+   authentication protocol at any time, thus allowing a new attempt.
+   Similarly, in IEEE 802.1X the Supplicant or Authenticator can re-
+   authenticate at any time.  It is recommended that any counters used
+   for authentication failure not be reset until after successful
+   authentication, or subsequent termination of the failed link.
+
+
+
+Aboba, et al.               Standards Track                    [Page 50]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+7.10.  Key Derivation
+
+   It is possible for the peer and EAP server to mutually authenticate
+   and derive keys.  In order to provide keying material for use in a
+   subsequently negotiated ciphersuite, an EAP method supporting key
+   derivation MUST export a Master Session Key (MSK) of at least 64
+   octets, and an Extended Master Session Key (EMSK) of at least 64
+   octets.  EAP Methods deriving keys MUST provide for mutual
+   authentication between the EAP peer and the EAP Server.
+
+   The MSK and EMSK MUST NOT be used directly to protect data; however,
+   they are of sufficient size to enable derivation of a AAA-Key
+   subsequently used to derive Transient Session Keys (TSKs) for use
+   with the selected ciphersuite.  Each ciphersuite is responsible for
+   specifying how to derive the TSKs from the AAA-Key.
+
+   The AAA-Key is derived from the keying material exported by the EAP
+   method (MSK and EMSK).  This derivation occurs on the AAA server.  In
+   many existing protocols that use EAP, the AAA-Key and MSK are
+   equivalent, but more complicated mechanisms are possible (see
+   [KEYFRAME] for details).
+
+   EAP methods SHOULD ensure the freshness of the MSK and EMSK, even in
+   cases where one party may not have a high quality random number
+   generator.  A RECOMMENDED method is for each party to provide a nonce
+   of at least 128 bits, used in the derivation of the MSK and EMSK.
+
+   EAP methods export the MSK and EMSK, but not Transient Session Keys
+   so as to allow EAP methods to be ciphersuite and media independent.
+   Keying material exported by EAP methods MUST be independent of the
+   ciphersuite negotiated to protect data.
+
+   Depending on the lower layer, EAP methods may run before or after
+   ciphersuite negotiation, so that the selected ciphersuite may not be
+   known to the EAP method.  By providing keying material usable with
+   any ciphersuite, EAP methods can used with a wide range of
+   ciphersuites and media.
+
+   In order to preserve algorithm independence, EAP methods deriving
+   keys SHOULD support (and document) the protected negotiation of the
+   ciphersuite used to protect the EAP conversation between the peer and
+   server.  This is distinct from the ciphersuite negotiated between the
+   peer and authenticator, used to protect data.
+
+   The strength of Transient Session Keys (TSKs) used to protect data is
+   ultimately dependent on the strength of keys generated by the EAP
+   method.  If an EAP method cannot produce keying material of
+   sufficient strength, then the TSKs may be subject to a brute force
+
+
+
+Aboba, et al.               Standards Track                    [Page 51]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   attack.  In order to enable deployments requiring strong keys, EAP
+   methods supporting key derivation SHOULD be capable of generating an
+   MSK and EMSK, each with an effective key strength of at least 128
+   bits.
+
+   Methods supporting key derivation MUST demonstrate cryptographic
+   separation between the MSK and EMSK branches of the EAP key
+   hierarchy.  Without violating a fundamental cryptographic assumption
+   (such as the non-invertibility of a one-way function), an attacker
+   recovering the MSK or EMSK MUST NOT be able to recover the other
+   quantity with a level of effort less than brute force.
+
+   Non-overlapping substrings of the MSK MUST be cryptographically
+   separate from each other, as defined in Section 7.2.1.  That is,
+   knowledge of one substring MUST NOT help in recovering some other
+   substring without breaking some hard cryptographic assumption.  This
+   is required because some existing ciphersuites form TSKs by simply
+   splitting the AAA-Key to pieces of appropriate length.  Likewise,
+   non-overlapping substrings of the EMSK MUST be cryptographically
+   separate from each other, and from substrings of the MSK.
+
+   The EMSK is reserved for future use and MUST remain on the EAP peer
+   and EAP server where it is derived; it MUST NOT be transported to, or
+   shared with, additional parties, or used to derive any other keys.
+   (This restriction will be relaxed in a future document that specifies
+   how the EMSK can be used.)
+
+   Since EAP does not provide for explicit key lifetime negotiation, EAP
+   peers, authenticators, and authentication servers MUST be prepared
+   for situations in which one of the parties discards the key state,
+   which remains valid on another party.
+
+   This specification does not provide detailed guidance on how EAP
+   methods derive the MSK and EMSK, how the AAA-Key is derived from the
+   MSK and/or EMSK, or how the TSKs are derived from the AAA-Key.
+
+   The development and validation of key derivation algorithms is
+   difficult, and as a result, EAP methods SHOULD re-use well
+   established and analyzed mechanisms for key derivation (such as those
+   specified in IKE [RFC2409] or TLS [RFC2246]), rather than inventing
+   new ones. EAP methods SHOULD also utilize well established and
+   analyzed mechanisms for MSK and EMSK derivation.  Further details on
+   EAP Key Derivation are provided within [KEYFRAME].
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 52]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+7.11.  Weak Ciphersuites
+
+   If after the initial EAP authentication, data packets are sent
+   without per-packet authentication, integrity, and replay protection,
+   an attacker with access to the media can inject packets, "flip bits"
+   within existing packets, replay packets, or even hijack the session
+   completely.  Without per-packet confidentiality, it is possible to
+   snoop data packets.
+
+   To protect against data modification, spoofing, or snooping, it is
+   recommended that EAP methods supporting mutual authentication and key
+   derivation (as defined by Section 7.2.1) be used, along with lower
+   layers providing per-packet confidentiality, authentication,
+   integrity, and replay protection.
+
+   Additionally, if the lower layer performs ciphersuite negotiation, it
+   should be understood that EAP does not provide by itself integrity
+   protection of that negotiation.  Therefore, in order to avoid
+   downgrading attacks which would lead to weaker ciphersuites being
+   used, clients implementing lower layer ciphersuite negotiation SHOULD
+   protect against negotiation downgrading.
+
+   This can be done by enabling users to configure which ciphersuites
+   are acceptable as a matter of security policy, or the ciphersuite
+   negotiation MAY be authenticated using keying material derived from
+   the EAP authentication and a MIC algorithm agreed upon in advance by
+   lower-layer peers.
+
+7.12.  Link Layer
+
+   There are reliability and security issues with link layer indications
+   in PPP, IEEE 802 LANs, and IEEE 802.11 wireless LANs:
+
+   [a] PPP.  In PPP, link layer indications such as LCP-Terminate (a
+       link failure indication) and NCP (a link success indication) are
+       not authenticated or integrity protected.  They can therefore be
+       spoofed by an attacker with access to the link.
+
+   [b] IEEE 802.  IEEE 802.1X EAPOL-Start and EAPOL-Logoff frames are
+       not authenticated or integrity protected.  They can therefore be
+       spoofed by an attacker with access to the link.
+
+   [c] IEEE 802.11.  In IEEE 802.11, link layer indications include
+       Disassociate and Deauthenticate frames (link failure
+       indications), and the first message of the 4-way handshake (link
+       success indication).  These messages are not authenticated or
+       integrity protected, and although they are not forwardable, they
+       are spoofable by an attacker within range.
+
+
+
+Aboba, et al.               Standards Track                    [Page 53]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   In IEEE 802.11, IEEE 802.1X data frames may be sent as Class 3
+   unicast data frames, and are therefore forwardable.  This implies
+   that while EAPOL-Start and EAPOL-Logoff messages may be authenticated
+   and integrity protected, they can be spoofed by an authenticated
+   attacker far from the target when "pre-authentication" is enabled.
+
+   In IEEE 802.11, a "link down" indication is an unreliable indication
+   of link failure, since wireless signal strength can come and go and
+   may be influenced by radio frequency interference generated by an
+   attacker.  To avoid unnecessary resets, it is advisable to damp these
+   indications, rather than passing them directly to the EAP.  Since EAP
+   supports retransmission, it is robust against transient connectivity
+   losses.
+
+7.13.  Separation of Authenticator and Backend Authentication Server
+
+   It is possible for the EAP peer and EAP server to mutually
+   authenticate and derive a AAA-Key for a ciphersuite used to protect
+   subsequent data traffic.  This does not present an issue on the peer,
+   since the peer and EAP client reside on the same machine; all that is
+   required is for the client to derive the AAA-Key from the MSK and
+   EMSK exported by the EAP method, and to subsequently pass a Transient
+   Session Key (TSK) to the ciphersuite module.
+
+   However, in the case where the authenticator and authentication
+   server reside on different machines, there are several implications
+   for security.
+
+   [a] Authentication will occur between the peer and the authentication
+       server, not between the peer and the authenticator.  This means
+       that it is not possible for the peer to validate the identity of
+       the authenticator that it is speaking to, using EAP alone.
+
+   [b] As discussed in [RFC3579], the authenticator is dependent on the
+       AAA protocol in order to know the outcome of an authentication
+       conversation, and does not look at the encapsulated EAP packet
+       (if one is present) to determine the outcome.  In practice, this
+       implies that the AAA protocol spoken between the authenticator
+       and authentication server MUST support per-packet authentication,
+       integrity, and replay protection.
+
+   [c] After completion of the EAP conversation, where lower layer
+       security services such as per-packet confidentiality,
+       authentication, integrity, and replay protection will be enabled,
+       a secure association protocol SHOULD be run between the peer and
+       authenticator in order to provide mutual authentication between
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 54]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+       the peer and authenticator, guarantee liveness of transient
+       session keys, provide protected ciphersuite and capabilities
+       negotiation for subsequent data, and synchronize key usage.
+
+   [d] A AAA-Key derived from the MSK and/or EMSK negotiated between the
+       peer and authentication server MAY be transmitted to the
+       authenticator.  Therefore, a mechanism needs to be provided to
+       transmit the AAA-Key from the authentication server to the
+       authenticator that needs it.  The specification of the AAA-key
+       derivation, transport, and wrapping mechanisms is outside the
+       scope of this document.  Further details on AAA-Key Derivation
+       are provided within [KEYFRAME].
+
+7.14.  Cleartext Passwords
+
+   This specification does not define a mechanism for cleartext password
+   authentication.  The omission is intentional.  Use of cleartext
+   passwords would allow the password to be captured by an attacker with
+   access to a link over which EAP packets are transmitted.
+
+   Since protocols encapsulating EAP, such as RADIUS [RFC3579], may not
+   provide confidentiality, EAP packets may be subsequently encapsulated
+   for transport over the Internet where they may be captured by an
+   attacker.
+
+   As a result, cleartext passwords cannot be securely used within EAP,
+   except where encapsulated within a protected tunnel with server
+   authentication.  Some of the same risks apply to EAP methods without
+   dictionary attack resistance, as defined in Section 7.2.1.  For
+   details, see Section 7.6.
+
+7.15.  Channel Binding
+
+   It is possible for a compromised or poorly implemented EAP
+   authenticator to communicate incorrect information to the EAP peer
+   and/or server.  This may enable an authenticator to impersonate
+   another authenticator or communicate incorrect information via out-
+   of-band mechanisms (such as via a AAA or lower layer protocol).
+
+   Where EAP is used in pass-through mode, the EAP peer typically does
+   not verify the identity of the pass-through authenticator, it only
+   verifies that the pass-through authenticator is trusted by the EAP
+   server.  This creates a potential security vulnerability.
+
+   Section 4.3.7 of [RFC3579] describes how an EAP pass-through
+   authenticator acting as a AAA client can be detected if it attempts
+   to impersonate another authenticator (such by sending incorrect NAS-
+   Identifier [RFC2865], NAS-IP-Address [RFC2865] or NAS-IPv6-Address
+
+
+
+Aboba, et al.               Standards Track                    [Page 55]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   [RFC3162] attributes via the AAA protocol).  However, it is possible
+   for a pass-through authenticator acting as a AAA client to provide
+   correct information to the AAA server while communicating misleading
+   information to the EAP peer via a lower layer protocol.
+
+   For example, it is possible for a compromised authenticator to
+   utilize another authenticator's Called-Station-Id or NAS-Identifier
+   in communicating with the EAP peer via a lower layer protocol, or for
+   a pass-through authenticator acting as a AAA client to provide an
+   incorrect peer Calling-Station-Id [RFC2865][RFC3580] to the AAA
+   server via the AAA protocol.
+
+   In order to address this vulnerability, EAP methods may support a
+   protected exchange of channel properties such as endpoint
+   identifiers, including (but not limited to): Called-Station-Id
+   [RFC2865][RFC3580], Calling-Station-Id [RFC2865][RFC3580], NAS-
+   Identifier [RFC2865], NAS-IP-Address [RFC2865], and NAS-IPv6-Address
+   [RFC3162].
+
+   Using such a protected exchange, it is possible to match the channel
+   properties provided by the authenticator via out-of-band mechanisms
+   against those exchanged within the EAP method.  Where discrepancies
+   are found, these SHOULD be logged; additional actions MAY also be
+   taken, such as denying access.
+
+7.16.  Protected Result Indications
+
+   Within EAP, Success and Failure packets are neither acknowledged nor
+   integrity protected.  Result indications improve resilience to loss
+   of Success and Failure packets when EAP is run over lower layers
+   which do not support retransmission or synchronization of the
+   authentication state.  In media such as IEEE 802.11, which provides
+   for retransmission, as well as synchronization of authentication
+   state via the 4-way handshake defined in [IEEE-802.11i], additional
+   resilience is typically of marginal benefit.
+
+   Depending on the method and circumstances, result indications can be
+   spoofable by an attacker.  A method is said to provide protected
+   result indications if it supports result indications, as well as the
+   "integrity protection" and "replay protection" claims.  A method
+   supporting protected result indications MUST indicate which result
+   indications are protected, and which are not.
+
+   Protected result indications are not required to protect against
+   rogue authenticators.  Within a mutually authenticating method,
+   requiring that the server authenticate to the peer before the peer
+   will accept a Success packet prevents an attacker from acting as a
+   rogue authenticator.
+
+
+
+Aboba, et al.               Standards Track                    [Page 56]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   However, it is possible for an attacker to forge a Success packet
+   after the server has authenticated to the peer, but before the peer
+   has authenticated to the server.  If the peer were to accept the
+   forged Success packet and attempt to access the network when it had
+   not yet successfully authenticated to the server, a denial of service
+   attack could be mounted against the peer.  After such an attack, if
+   the lower layer supports failure indications, the authenticator can
+   synchronize state with the peer by providing a lower layer failure
+   indication.  See Section 7.12 for details.
+
+   If a server were to authenticate the peer and send a Success packet
+   prior to determining whether the peer has authenticated the
+   authenticator, an idle timeout can occur if the authenticator is not
+   authenticated by the peer.  Where supported by the lower layer, an
+   authenticator sensing the absence of the peer can free resources.
+
+   In a method supporting result indications, a peer that has
+   authenticated the server does not consider the authentication
+   successful until it receives an indication that the server
+   successfully authenticated it.  Similarly, a server that has
+   successfully authenticated the peer does not consider the
+   authentication successful until it receives an indication that the
+   peer has authenticated the server.
+
+   In order to avoid synchronization problems, prior to sending a
+   success result indication, it is desirable for the sender to verify
+   that sufficient authorization exists for granting access, though, as
+   discussed below, this is not always possible.
+
+   While result indications may enable synchronization of the
+   authentication result between the peer and server, this does not
+   guarantee that the peer and authenticator will be synchronized in
+   terms of their authorization or that timeouts will not occur.  For
+   example, the EAP server may not be aware of an authorization decision
+   made by a AAA proxy; the AAA server may check authorization only
+   after authentication has completed successfully, to discover that
+   authorization cannot be granted, or the AAA server may grant access
+   but the authenticator may be unable to provide it due to a temporary
+   lack of resources.  In these situations, synchronization may only be
+   achieved via lower layer result indications.
+
+   Success indications may be explicit or implicit.  For example, where
+   a method supports error messages, an implicit success indication may
+   be defined as the reception of a specific message without a preceding
+   error message.  Failures are typically indicated explicitly.  As
+   described in Section 4.2, a peer silently discards a Failure packet
+   received at a point where the method does not explicitly permit this
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 57]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   to be sent.  For example, a method providing its own error messages
+   might require the peer to receive an error message prior to accepting
+   a Failure packet.
+
+   Per-packet authentication, integrity, and replay protection of result
+   indications protects against spoofing.  Since protected result
+   indications require use of a key for per-packet authentication and
+   integrity protection, methods supporting protected result indications
+   MUST also support the "key derivation", "mutual authentication",
+   "integrity protection", and "replay protection" claims.
+
+   Protected result indications address some denial-of-service
+   vulnerabilities due to spoofing of Success and Failure packets,
+   though not all.  EAP methods can typically provide protected result
+   indications only in some circumstances.  For example, errors can
+   occur prior to key derivation, and so it may not be possible to
+   protect all failure indications.  It is also possible that result
+   indications may not be supported in both directions or that
+   synchronization may not be achieved in all modes of operation.
+
+   For example, within EAP-TLS [RFC2716], in the client authentication
+   handshake, the server authenticates the peer, but does not receive a
+   protected indication of whether the peer has authenticated it.  In
+   contrast, the peer authenticates the server and is aware of whether
+   the server has authenticated it.  In the session resumption
+   handshake, the peer authenticates the server, but does not receive a
+   protected indication of whether the server has authenticated it.  In
+   this mode, the server authenticates the peer and is aware of whether
+   the peer has authenticated it.
+
+8.  Acknowledgements
+
+   This protocol derives much of its inspiration from Dave Carrel's AHA
+   document, as well as the PPP CHAP protocol [RFC1994].  Valuable
+   feedback was provided by Yoshihiro Ohba of Toshiba America Research,
+   Jari Arkko of Ericsson, Sachin Seth of Microsoft, Glen Zorn of Cisco
+   Systems, Jesse Walker of Intel, Bill Arbaugh, Nick Petroni and Bryan
+   Payne of the University of Maryland, Steve Bellovin of AT&T Research,
+   Paul Funk of Funk Software, Pasi Eronen of Nokia, Joseph Salowey of
+   Cisco, Paul Congdon of HP, and members of the EAP working group.
+
+   The use of Security Claims sections for EAP methods, as required by
+   Section 7.2 and specified for each EAP method described in this
+   document, was inspired by Glen Zorn through [EAP-EVAL].
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 58]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+9.  References
+
+9.1.  Normative References
+
+   [RFC1661]          Simpson, W., "The Point-to-Point Protocol (PPP)",
+                      STD 51, RFC 1661, July 1994.
+
+   [RFC1994]          Simpson, W., "PPP Challenge Handshake
+                      Authentication Protocol (CHAP)", RFC 1994, August
+                      1996.
+
+   [RFC2119]          Bradner, S., "Key words for use in RFCs to
+                      Indicate Requirement Levels", BCP 14, RFC 2119,
+                      March 1997.
+
+   [RFC2243]          Metz, C., "OTP Extended Responses", RFC 2243,
+                      November 1997.
+
+   [RFC2279]          Yergeau, F., "UTF-8, a transformation format of
+                      ISO 10646", RFC 2279, January 1998.
+
+   [RFC2289]          Haller, N., Metz, C., Nesser, P. and M. Straw, "A
+                      One-Time Password System", RFC 2289, February
+                      1998.
+
+   [RFC2434]          Narten, T. and H. Alvestrand, "Guidelines for
+                      Writing an IANA Considerations Section in RFCs",
+                      BCP 26, RFC 2434, October 1998.
+
+   [RFC2988]          Paxson, V. and M. Allman, "Computing TCP's
+                      Retransmission Timer", RFC 2988, November 2000.
+
+   [IEEE-802]         Institute of Electrical and Electronics Engineers,
+                      "Local and Metropolitan Area Networks: Overview
+                      and Architecture", IEEE Standard 802, 1990.
+
+   [IEEE-802.1X]      Institute of Electrical and Electronics Engineers,
+                      "Local and Metropolitan Area Networks: Port-Based
+                      Network Access Control", IEEE Standard 802.1X,
+                      September 2001.
+
+
+
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 59]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+9.2.  Informative References
+
+   [RFC793]           Postel, J., "Transmission Control Protocol", STD
+                      7, RFC 793, September 1981.
+
+   [RFC1510]          Kohl, J. and B. Neuman, "The Kerberos Network
+                      Authentication Service (V5)", RFC 1510, September
+                      1993.
+
+   [RFC1750]          Eastlake, D., Crocker, S. and J. Schiller,
+                      "Randomness Recommendations for Security", RFC
+                      1750, December 1994.
+
+   [RFC2246]          Dierks, T., Allen, C., Treese, W., Karlton, P.,
+                      Freier, A. and P. Kocher, "The TLS Protocol
+                      Version 1.0", RFC 2246, January 1999.
+
+   [RFC2284]          Blunk, L. and J. Vollbrecht, "PPP Extensible
+                      Authentication Protocol (EAP)", RFC 2284, March
+                      1998.
+
+   [RFC2486]          Aboba, B. and M. Beadles, "The Network Access
+                      Identifier", RFC 2486, January 1999.
+
+   [RFC2408]          Maughan, D., Schneider, M. and M. Schertler,
+                      "Internet Security Association and Key Management
+                      Protocol (ISAKMP)", RFC 2408, November 1998.
+
+   [RFC2409]          Harkins, D. and D. Carrel, "The Internet Key
+                      Exchange (IKE)", RFC 2409, November 1998.
+
+   [RFC2433]          Zorn, G. and S. Cobb, "Microsoft PPP CHAP
+                      Extensions", RFC 2433, October 1998.
+
+   [RFC2607]          Aboba, B. and J. Vollbrecht, "Proxy Chaining and
+                      Policy Implementation in Roaming", RFC 2607, June
+                      1999.
+
+   [RFC2661]          Townsley, W., Valencia, A., Rubens, A., Pall, G.,
+                      Zorn, G. and B. Palter, "Layer Two Tunneling
+                      Protocol "L2TP"", RFC 2661, August 1999.
+
+   [RFC2716]          Aboba, B. and D. Simon, "PPP EAP TLS
+                      Authentication Protocol", RFC 2716, October 1999.
+
+   [RFC2865]          Rigney, C., Willens, S., Rubens, A. and W.
+                      Simpson, "Remote Authentication Dial In User
+                      Service (RADIUS)", RFC 2865, June 2000.
+
+
+
+Aboba, et al.               Standards Track                    [Page 60]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   [RFC2960]          Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
+                      Schwarzbauer, H., Taylor, T., Rytina, I., Kalla,
+                      M., Zhang, L. and V. Paxson, "Stream Control
+                      Transmission Protocol", RFC 2960, October 2000.
+
+   [RFC3162]          Aboba, B., Zorn, G. and D. Mitton, "RADIUS and
+                      IPv6", RFC 3162, August 2001.
+
+   [RFC3454]          Hoffman, P. and M. Blanchet, "Preparation of
+                      Internationalized Strings ("stringprep")", RFC
+                      3454, December 2002.
+
+   [RFC3579]          Aboba, B. and P. Calhoun, "RADIUS (Remote
+                      Authentication Dial In User Service) Support For
+                      Extensible Authentication Protocol (EAP)", RFC
+                      3579, September 2003.
+
+   [RFC3580]          Congdon, P., Aboba, B., Smith, A., Zorn, G. and J.
+                      Roese, "IEEE 802.1X Remote Authentication Dial In
+                      User Service (RADIUS) Usage Guidelines", RFC 3580,
+                      September 2003.
+
+   [RFC3692]          Narten, T., "Assigning Experimental and Testing
+                      Numbers Considered Useful", BCP 82, RFC 3692,
+                      January 2004.
+
+   [DECEPTION]        Slatalla, M. and J. Quittner, "Masters of
+                      Deception", Harper-Collins, New York, 1995.
+
+   [KRBATTACK]        Wu, T., "A Real-World Analysis of Kerberos
+                      Password Security", Proceedings of the 1999 ISOC
+                      Network and Distributed System Security Symposium,
+                      http://www.isoc.org/isoc/conferences/ndss/99/
+                      proceedings/papers/wu.pdf.
+
+   [KRBLIM]           Bellovin, S. and M. Merrit, "Limitations of the
+                      Kerberos authentication system", Proceedings of
+                      the 1991 Winter USENIX Conference, pp. 253-267,
+                      1991.
+
+   [KERB4WEAK]        Dole, B., Lodin, S. and E. Spafford, "Misplaced
+                      trust:  Kerberos 4 session keys", Proceedings of
+                      the Internet Society Network and Distributed
+                      System Security Symposium, pp. 60-70, March 1997.
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 61]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   [PIC]              Aboba, B., Krawczyk, H. and Y. Sheffer, "PIC, A
+                      Pre-IKE Credential Provisioning Protocol", Work in
+                      Progress, October 2002.
+
+   [IKEv2]            Kaufman, C., "Internet Key Exchange (IKEv2)
+                      Protocol", Work in Progress, January 2004.
+
+   [PPTPv1]           Schneier, B. and Mudge, "Cryptanalysis of
+                      Microsoft's Point-to- Point Tunneling Protocol",
+                      Proceedings of the 5th ACM Conference on
+                      Communications and Computer Security, ACM Press,
+                      November 1998.
+
+   [IEEE-802.11]      Institute of Electrical and Electronics Engineers,
+                      "Wireless LAN Medium Access Control (MAC) and
+                      Physical Layer (PHY) Specifications", IEEE
+                      Standard 802.11, 1999.
+
+   [SILVERMAN]        Silverman, Robert D., "A Cost-Based Security
+                      Analysis of Symmetric and Asymmetric Key Lengths",
+                      RSA Laboratories Bulletin 13, April 2000 (Revised
+                      November 2001),
+                      http://www.rsasecurity.com/rsalabs/bulletins/
+                      bulletin13.html.
+
+   [KEYFRAME]         Aboba, B., "EAP Key Management Framework", Work in
+                      Progress, October 2003.
+
+   [SASLPREP]         Zeilenga, K., "SASLprep: Stringprep profile for
+                      user names and passwords", Work in Progress, March
+                      2004.
+
+   [IEEE-802.11i]     Institute of Electrical and Electronics Engineers,
+                      "Unapproved Draft Supplement to Standard for
+                      Telecommunications and Information Exchange
+                      Between Systems - LAN/MAN Specific Requirements -
+                      Part 11: Wireless LAN Medium Access Control (MAC)
+                      and Physical Layer (PHY) Specifications:
+                      Specification for Enhanced Security", IEEE Draft
+                      802.11i (work in progress), 2003.
+
+   [DIAM-EAP]         Eronen, P., Hiller, T. and G. Zorn, "Diameter
+                      Extensible Authentication Protocol (EAP)
+                      Application", Work in Progress, February 2004.
+
+   [EAP-EVAL]         Zorn, G., "Specifying Security Claims for EAP
+                      Authentication Types", Work in Progress, October
+                      2002.
+
+
+
+Aboba, et al.               Standards Track                    [Page 62]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   [BINDING]          Puthenkulam, J., "The Compound Authentication
+                      Binding Problem", Work in Progress, October 2003.
+
+   [MITM]             Asokan, N., Niemi, V. and K. Nyberg, "Man-in-the-
+                      Middle in Tunneled Authentication Protocols", IACR
+                      ePrint Archive Report 2002/163, October 2002,
+                      <http://eprint.iacr.org/2002/163>.
+
+   [IEEE-802.11i-req] Stanley, D., "EAP Method Requirements for Wireless
+                      LANs", Work in Progress, February 2004.
+
+   [PPTPv2]           Schneier, B. and Mudge, "Cryptanalysis of
+                      Microsoft's PPTP Authentication Extensions (MS-
+                      CHAPv2)", CQRE 99, Springer-Verlag, 1999, pp.
+                      192-203.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 63]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+Appendix A. Changes from RFC 2284
+
+   This section lists the major changes between [RFC2284] and this
+   document.  Minor changes, including style, grammar, spelling, and
+   editorial changes are not mentioned here.
+
+   o  The Terminology section (Section 1.2) has been expanded, defining
+      more concepts and giving more exact definitions.
+
+   o  The concepts of Mutual Authentication, Key Derivation, and Result
+      Indications are introduced and discussed throughout the document
+      where appropriate.
+
+   o In Section 2, it is explicitly specified that more than one
+      exchange of Request and Response packets may occur as part of the
+      EAP authentication exchange.  How this may be used and how it may
+      not be used is specified in detail in Section 2.1.
+
+   o  Also in Section 2, some requirements have been made explicit for
+      the authenticator when acting in pass-through mode.
+
+   o  An EAP multiplexing model (Section 2.2) has been added to
+      illustrate a typical implementation of EAP.  There is no
+      requirement that an implementation conform to this model, as long
+      as the on-the-wire behavior is consistent with it.
+
+   o  As EAP is now in use with a variety of lower layers, not just PPP
+      for which it was first designed, Section 3 on lower layer behavior
+      has been added.
+
+   o  In the description of the EAP Request and Response interaction
+      (Section 4.1), both the behavior on receiving duplicate requests,
+      and when packets should be silently discarded has been more
+      exactly specified.  The implementation notes in this section have
+      been substantially expanded.
+
+   o  In Section 4.2, it has been clarified that Success and Failure
+      packets must not contain additional data, and the implementation
+      note has been expanded.  A subsection giving requirements on
+      processing of success and failure packets has been added.
+
+   o  Section 5 on EAP Request/Response Types lists two new Type values:
+      the Expanded Type (Section 5.7), which is used to expand the Type
+      value number space, and the Experimental Type.  In the Expanded
+      Type number space, the new Expanded Nak (Section 5.3.2) Type has
+      been added.  Clarifications have been made in the description of
+      most of the existing Types.  Security claims summaries have been
+      added for authentication methods.
+
+
+
+Aboba, et al.               Standards Track                    [Page 64]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+   o  In Sections 5, 5.1, and 5.2, a requirement has been added such
+      that fields with displayable messages should contain UTF-8 encoded
+      ISO 10646 characters.
+
+   o  It is now required in Section 5.1 that if the Type-Data field of
+      an Identity Request contains a NUL-character, only the part before
+      the null is displayed.  RFC 2284 prohibits the null termination of
+      the Type-Data field of Identity messages.  This rule has been
+      relaxed for Identity Request messages and the Identity Request
+      Type-Data field may now be null terminated.
+
+   o  In Section 5.5, support for OTP Extended Responses [RFC2243] has
+      been added to EAP OTP.
+
+   o  An IANA Considerations section (Section 6) has been added, giving
+      registration policies for the numbering spaces defined for EAP.
+
+   o  The Security Considerations (Section 7) have been greatly
+      expanded, giving a much more comprehensive coverage of possible
+      threats and other security considerations.
+
+   o  In Section 7.5, text has been added on method-specific behavior,
+      providing guidance on how EAP method-specific integrity checks
+      should be processed.  Where possible, it is desirable for a
+      method-specific MIC to be computed over the entire EAP packet,
+      including the EAP layer header (Code, Identifier, Length) and EAP
+      method layer header (Type, Type-Data).
+
+   o  In Section 7.14 the security risks involved in use of cleartext
+      passwords with EAP are described.
+
+   o  In Section 7.15 text has been added relating to detection of rogue
+      NAS behavior.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 65]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+Authors' Addresses
+
+   Bernard Aboba
+   Microsoft Corporation
+   One Microsoft Way
+   Redmond, WA  98052
+   USA
+
+   Phone: +1 425 706 6605
+   Fax:   +1 425 936 6605
+   EMail: bernarda@microsoft.com
+
+   Larry J. Blunk
+   Merit Network, Inc
+   4251 Plymouth Rd., Suite 2000
+   Ann Arbor, MI  48105-2785
+   USA
+
+   Phone: +1 734-647-9563
+   Fax:   +1 734-647-3185
+   EMail: ljb@merit.edu
+
+   John R. Vollbrecht
+   Vollbrecht Consulting LLC
+   9682 Alice Hill Drive
+   Dexter, MI  48130
+   USA
+
+   EMail: jrv@umich.edu
+
+   James Carlson
+   Sun Microsystems, Inc
+   1 Network Drive
+   Burlington, MA  01803-2757
+   USA
+
+   Phone: +1 781 442 2084
+   Fax:   +1 781 442 1677
+   EMail: james.d.carlson@sun.com
+
+   Henrik Levkowetz
+   ipUnplugged AB
+   Arenavagen 33
+   Stockholm  S-121 28
+   SWEDEN
+
+   Phone: +46 708 32 16 08
+   EMail: henrik@levkowetz.com
+
+
+
+Aboba, et al.               Standards Track                    [Page 66]
+\f
+RFC 3748                          EAP                          June 2004
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (2004).  This document is subject
+   to the rights, licenses and restrictions contained in BCP 78, and
+   except as set forth therein, the authors retain all their rights.
+
+   This document and the information contained herein are provided on an
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+   The IETF takes no position regarding the validity or scope of any
+   Intellectual Property Rights or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; nor does it represent that it has
+   made any independent effort to identify any such rights.  Information
+   on the procedures with respect to rights in RFC documents can be
+   found in BCP 78 and BCP 79.
+
+   Copies of IPR disclosures made to the IETF Secretariat and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementers or users of this
+   specification can be obtained from the IETF on-line IPR repository at
+   http://www.ietf.org/ipr.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights that may cover technology that may be required to implement
+   this standard.  Please address the information to the IETF at ietf-
+   ipr@ietf.org.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+Aboba, et al.               Standards Track                    [Page 67]
+\f
diff --git a/src/charon/doc/standards/rfc4739.txt b/src/charon/doc/standards/rfc4739.txt
new file mode 100644 (file)
index 0000000..db5cf6a
--- /dev/null
@@ -0,0 +1,619 @@
+
+
+
+
+
+
+Network Working Group                                          P. Eronen
+Request for Comments: 4739                                         Nokia
+Category: Experimental                                       J. Korhonen
+                                                             TeliaSonera
+                                                           November 2006
+
+
+                   Multiple Authentication Exchanges
+             in the Internet Key Exchange (IKEv2) Protocol
+
+Status of This Memo
+
+   This memo defines an Experimental Protocol for the Internet
+   community.  It does not specify an Internet standard of any kind.
+   Discussion and suggestions for improvement are requested.
+   Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The IETF Trust (2006).
+
+Abstract
+
+   The Internet Key Exchange (IKEv2) protocol supports several
+   mechanisms for authenticating the parties, including signatures with
+   public-key certificates, shared secrets, and Extensible
+   Authentication Protocol (EAP) methods.  Currently, each endpoint uses
+   only one of these mechanisms to authenticate itself.  This document
+   specifies an extension to IKEv2 that allows the use of multiple
+   authentication exchanges, using either different mechanisms or the
+   same mechanism.  This extension allows, for instance, performing
+   certificate-based authentication of the client host followed by an
+   EAP authentication of the user.  When backend authentication servers
+   are used, they can belong to different administrative domains, such
+   as the network access provider and the service provider.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eronen & Korhonen             Experimental                      [Page 1]
+\f
+RFC 4739           Multiple Auth. Exchanges in IKEv2       November 2006
+
+
+Table of Contents
+
+   1. Introduction ....................................................3
+      1.1. Usage Scenarios ............................................4
+      1.2. Terminology ................................................5
+   2. Solution ........................................................5
+      2.1. Solution Overview ..........................................5
+      2.2. Example 1: Multiple EAP Authentications ....................6
+      2.3. Example 2: Mixed EAP and Certificate Authentications .......7
+      2.4. Example 3: Multiple Initiator Certificates .................8
+      2.5. Example 4: Multiple Responder Certificates .................8
+   3. Payload Formats .................................................9
+      3.1. MULTIPLE_AUTH_SUPPORTED Notify Payload .....................9
+      3.2. ANOTHER_AUTH_FOLLOWS Notify Payload ........................9
+   4. IANA Considerations .............................................9
+   5. Security Considerations .........................................9
+   6. Acknowledgments ................................................10
+   7. References .....................................................10
+      7.1. Normative References ......................................10
+      7.2. Informative References ....................................10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eronen & Korhonen             Experimental                      [Page 2]
+\f
+RFC 4739           Multiple Auth. Exchanges in IKEv2       November 2006
+
+
+1.  Introduction
+
+   IKEv2 [IKEv2] supports several mechanisms for parties involved in the
+   IKE_SA (IKE security association).  These include signatures with
+   public-key certificates, shared secrets, and Extensible
+   Authentication Protocol (EAP) methods.
+
+   Currently, each endpoint uses only one of these mechanisms to
+   authenticate itself.  However, there are scenarios where making the
+   authorization decision in IKEv2 (whether to allow access or not)
+   requires using several of these methods.
+
+   For instance, it may be necessary to authenticate both the host
+   (machine) requesting access, and the user currently using the host.
+   These two authentications would use two separate sets of credentials
+   (such as certificates and associated private keys) and might even use
+   different authentication mechanisms.
+
+   To take another example, when an operator is hosting a Virtual
+   Private Network (VPN) gateway service for a third party, it may be
+   necessary to authenticate the client to both the operator (for
+   billing purposes) and the third party's Authentication,
+   Authorization, and Accounting (AAA) server (for authorizing access to
+   the third party's internal network).
+
+   This document specifies an extension to IKEv2 that allows the use of
+   multiple authentication exchanges, using either different mechanisms
+   or the same mechanism.  This extension allows, for instance,
+   performing certificate-based authentication of the client host
+   followed by an EAP authentication of the user.
+
+   Each authentication exchange requiring communication with backend AAA
+   servers may be directed to different backend AAA servers, located
+   even in different administrative domains.  However, details of the
+   communication between the IKEv2 gateway and the backend
+   authentication servers are beyond the scope of this document.  In
+   particular, this document does not specify any changes to existing
+   AAA protocols, and it does not require the use of any particular AAA
+   protocol.
+
+   In case of several EAP authentications, it is important to notice
+   that they are not a "sequence" (as described in Section 2.1 of
+   [EAP]), but separate independent EAP conversations, which are usually
+   also terminated in different EAP servers.  Multiple authentication
+   methods within a single EAP conversation are still prohibited as
+   described in Section 2.1 of [EAP].  Using multiple independent EAP
+   conversations is similar to the separate Network Access Provider
+   (NAP) and Internet Service Provider (ISP) authentication exchanges
+
+
+
+Eronen & Korhonen             Experimental                      [Page 3]
+\f
+RFC 4739           Multiple Auth. Exchanges in IKEv2       November 2006
+
+
+   planned for [PANA].  The discovery of the appropriate EAP server for
+   each EAP authentication conversation is based on AAA routing.
+
+1.1.  Usage Scenarios
+
+   Figure 1 shows an example architecture of an operator-hosted VPN
+   scenario that could benefit from a two-phase authentication within
+   the IKEv2 exchange.  First, the client authenticates towards the
+   Network Access Provider (NAP) and gets access to the NAP-hosted VPN
+   gateway.  The first-phase authentication involves the backend AAA
+   server of the NAP.  After the first authentication, the client
+   initiates the second authentication round that also involves the
+   Third Party's backend AAA server.  If both authentications succeed,
+   the required IPsec tunnels are set up and the client can access
+   protected networks behind the Third Party.
+
+
+       Client                         *Network Access Provider*
+     +---------+                    +---------+              +-----+
+     |         |                    |  NAP's  |              | NAP |
+     |Protected|     IPsec SAs      | Tunnel  | AAA Protocol | AAA |
+     |Endpoint |<------------------>|Endpoint |<------------>|Serv/|
+     |         |                    |         |              |Proxy|
+     +---------+                    +---------+              +-----+
+                                       ^                        ^
+                            IPsec or  /                  AAA    |
+                        Leased Line  /                 Protocol |
+                                    /                           |
+                                   v                            |
+                           +---------+    *Third Party*         v
+                           |3rd Party|                       +-----+
+            Protected      | Tunnel  |                       | 3rd |
+               Subnet <----|Endpoint |                       |Party|
+                           |         |                       | AAA |
+                           +---------+                       +-----+
+
+          Figure 1: Two-phase authentication used to gain access to
+          the Third Party network via Network Access Provider.  AAA
+          traffic goes through NAP's AAA server.
+
+   The NAP's AAA server can be used to proxy the AAA traffic to the
+   Third Party's backend AAA server.  Alternatively, the AAA traffic
+   from the NAP's tunnel endpoint could go directly to the Third Party's
+   backend AAA servers.  However, this is more or less an AAA routing
+   issue.
+
+
+
+
+
+
+Eronen & Korhonen             Experimental                      [Page 4]
+\f
+RFC 4739           Multiple Auth. Exchanges in IKEv2       November 2006
+
+
+1.2.  Terminology
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+   document are to be interpreted as described in [KEYWORDS].
+
+   The terms and abbreviations "authenticator", "backend authentication
+   server", "EAP server", and "peer" in this document are to be
+   interpreted as described in [EAP].
+
+   When messages containing IKEv2 payloads are described, optional
+   payloads are shown in brackets (for instance, "[FOO]"), and a plus
+   sign indicates that a payload can be repeated one or more times (for
+   instance, "FOO+").
+
+2.  Solution
+
+2.1.  Solution Overview
+
+   The peers announce support for this IKEv2 extension by including a
+   MULTIPLE_AUTH_SUPPORTED notification in the IKE_SA_INIT response
+   (responder) and the first IKE_AUTH request (initiator).
+
+   If both peers support this extension, either of them can announce
+   that it wishes to have a second authentication by including an
+   ANOTHER_AUTH_FOLLOWS notification in any IKE_AUTH message that
+   contains an AUTH payload.  This indicates that the peer sending the
+   ANOTHER_AUTH_FOLLOWS wishes to authenticate another set of
+   credentials to the other peer.  The next IKE_AUTH message sent by
+   this peer will contain a second identity payload (IDi or IDr) and
+   starts another authentication exchange.  The IKE_AUTH phase is
+   considered successful only if all the individual authentication
+   exchanges complete successfully.
+
+   It is assumed that both peers know what credentials they want to
+   present; there is no negotiation about, for instance, what type of
+   authentication is to be done.  As in IKEv2, EAP-based authentication
+   is always requested by the initiator (by omitting the AUTH payload).
+
+   The AUTH payloads are calculated as specified in [IKEv2] Sections
+   2.15 and 2.16, where IDi' refers to the latest IDi payload sent by
+   the initiator, and IDr' refers to the latest IDr payload sent by the
+   responder.  If EAP methods that do not generate shared keys are used,
+   it is possible that several AUTH payloads with identical contents are
+   sent.  When such EAP methods are used, the purpose of the AUTH
+   payload is simply to delimit the authentication exchanges, and ensure
+   that the IKE_SA_INIT request/response messages were not modified.
+
+
+
+
+Eronen & Korhonen             Experimental                      [Page 5]
+\f
+RFC 4739           Multiple Auth. Exchanges in IKEv2       November 2006
+
+
+2.2.  Example 1: Multiple EAP Authentications
+
+   This example shows certificate-based authentication of the responder
+   followed by an EAP authentication exchange (messages 1-10).  When the
+   first EAP exchange is ending (the initiator is sending its AUTH
+   payload), the initiator announces that it wishes to have a second
+   authentication exchange by including an ANOTHER_AUTH_FOLLOWS
+   notification (message 9).
+
+   After this, a second authentication exchange begins.  The initiator
+   sends a new IDi payload but no AUTH payload (message 11), indicating
+   that EAP will be used.  After that, another EAP authentication
+   exchange follows (messages 12-18).
+
+      Initiator                   Responder
+     -----------                 -----------
+      1. HDR, SA, KE, Ni -->
+                             <--  2. HDR, SA, KE, Nr, [CERTREQ],
+                                          N(MULTIPLE_AUTH_SUPPORTED)
+      3. HDR, SK { IDi, [CERTREQ+], [IDr],
+                   SA, TSi, TSr, N(MULTIPLE_AUTH_SUPPORTED) }  -->
+                             <--  4. HDR, SK { IDr, [CERT+], AUTH,
+                                               EAP(Request) }
+      5. HDR, SK { EAP(Response) }  -->
+                             <--  6. HDR, SK { EAP(Request) }
+      7. HDR, SK { EAP(Response) }  -->
+                             <--  8. HDR, SK { EAP(Success) }
+      9. HDR, SK { AUTH,
+                   N(ANOTHER_AUTH_FOLLOWS) }  -->
+                             <--  10. HDR, SK { AUTH }
+      11. HDR, SK { IDi }  -->
+                             <--  12. HDR, SK { EAP(Request) }
+      13. HDR, SK { EAP(Response) }  -->
+                             <--  14. HDR, SK { EAP(Request) }
+      15. HDR, SK { EAP(Response) }  -->
+                             <--  16. HDR, SK { EAP(Success) }
+      17. HDR, SK { AUTH }  -->
+                             <--  18. HDR, SK { AUTH, SA, TSi, TSr }
+
+          Example 1: Certificate-based authentication of the
+          responder, followed by two EAP authentication exchanges.
+
+
+
+
+
+
+
+
+
+
+Eronen & Korhonen             Experimental                      [Page 6]
+\f
+RFC 4739           Multiple Auth. Exchanges in IKEv2       November 2006
+
+
+2.3.  Example 2: Mixed EAP and Certificate Authentications
+
+   Another example is shown below: here both the initiator and the
+   responder are first authenticated using certificates (or shared
+   secrets); this is followed by an EAP authentication exchange.
+
+      Initiator                   Responder
+     -----------                 -----------
+      1. HDR, SA, KE, Ni -->
+                             <--  2. HDR, SA, KE, Nr, [CERTREQ],
+                                          N(MULTIPLE_AUTH_SUPPORTED)
+      3. HDR, SK { IDi, [CERT+], [CERTREQ+], [IDr], AUTH,
+                   SA, TSi, TSr, N(MULTIPLE_AUTH_SUPPORTED),
+                   N(ANOTHER_AUTH_FOLLOWS) }  -->
+                             <--  4. HDR, SK { IDr, [CERT+], AUTH }
+      5. HDR, SK { IDi }  -->
+                             <--  6. HDR, SK { EAP(Request) }
+      7. HDR, SK { EAP(Response) }  -->
+                             <--  8. HDR, SK { EAP(Request) }
+      9. HDR, SK { EAP(Response) }  -->
+                             <--  10. HDR, SK { EAP(Success) }
+      11. HDR, SK { AUTH }  -->
+                             <--  12. HDR, SK { AUTH, SA, TSi, TSr }
+
+             Example 2: Certificate-based (or shared-secret-based)
+             authentication of the initiator and the responder,
+             followed by an EAP authentication exchange.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eronen & Korhonen             Experimental                      [Page 7]
+\f
+RFC 4739           Multiple Auth. Exchanges in IKEv2       November 2006
+
+
+2.4.  Example 3: Multiple Initiator Certificates
+
+   This example shows yet another possibility: the initiator has two
+   different certificates (and associated private keys), and
+   authenticates both of them to the responder.
+
+      Initiator                   Responder
+     -----------                 -----------
+      1. HDR, SA, KE, Ni -->
+                             <--  2. HDR, SA, KE, Nr, [CERTREQ],
+                                          N(MULTIPLE_AUTH_SUPPORTED)
+      3. HDR, SK { IDi, [CERT+], [CERTREQ+], [IDr], AUTH,
+                   SA, TSi, TSr, N(MULTIPLE_AUTH_SUPPORTED),
+                   N(ANOTHER_AUTH_FOLLOWS) }  -->
+                             <--  4. HDR, SK { IDr, [CERT+], AUTH }
+      5. HDR, SK { IDi, [CERT+], AUTH }  -->
+                             <--  6. HDR, SK { SA, TSi, TSr }
+
+          Example 3: Two certificate-based authentications of the
+          initiator, and one certificate-based authentication
+          of the responder.
+
+2.5.  Example 4: Multiple Responder Certificates
+
+   This example shows yet another possibility: the responder has two
+   different certificates (and associated private keys), and
+   authenticates both of them to the initiator.
+
+      Initiator                   Responder
+     -----------                 -----------
+      1. HDR, SA, KE, Ni -->
+                             <--  2. HDR, SA, KE, Nr, [CERTREQ],
+                                          N(MULTIPLE_AUTH_SUPPORTED)
+      3. HDR, SK { IDi, [CERT+], [CERTREQ+], [IDr], AUTH,
+                   SA, TSi, TSr, N(MULTIPLE_AUTH_SUPPORTED) }  -->
+                             <--  4. HDR, SK { IDr, [CERT+], AUTH,
+                                               N(ANOTHER_AUTH_FOLLOWS) }
+      5. HDR, SK { }  -->
+                             <--  6. HDR, SK { IDr, [CERT+], AUTH,
+                                               SA, TSi, TSr }
+
+          Example 4: Two certificate-based authentications of the
+          responder, and one certificate-based authentication
+          of the initiator.
+
+
+
+
+
+
+
+Eronen & Korhonen             Experimental                      [Page 8]
+\f
+RFC 4739           Multiple Auth. Exchanges in IKEv2       November 2006
+
+
+3.  Payload Formats
+
+3.1.  MULTIPLE_AUTH_SUPPORTED Notify Payload
+
+   The MULTIPLE_AUTH_SUPPORTED notification is included in the
+   IKE_SA_INIT response or the first IKE_AUTH request to indicate that
+   the peer supports this specification.  The Notify Message Type is
+   MULTIPLE_AUTH_SUPPORTED (16404).  The Protocol ID and SPI Size fields
+   MUST be set to zero, and there is no data associated with this Notify
+   type.
+
+3.2.  ANOTHER_AUTH_FOLLOWS Notify Payload
+
+   The ANOTHER_AUTH_FOLLOWS notification payload is included in an
+   IKE_AUTH message containing an AUTH payload to indicate that the peer
+   wants to continue with another authentication exchange.  The Notify
+   Message Type is ANOTHER_AUTH_FOLLOWS (16405).  The Protocol ID and
+   SPI Size fields MUST be set to zero, and there is no data associated
+   with this Notify type.
+
+4.  IANA Considerations
+
+   This document defines two new IKEv2 notifications,
+   MULTIPLE_AUTH_SUPPORTED and ANOTHER_AUTH_FOLLOWS, whose values are
+   allocated from the "IKEv2 Notify Message Types" namespace defined in
+   [IKEv2].
+
+   This document does not define any new namespaces to be managed by
+   IANA.
+
+5.  Security Considerations
+
+   Security considerations for IKEv2 are discussed in [IKEv2].  The
+   reader is encouraged to pay special attention to considerations
+   relating to the use of EAP methods that do not generate shared keys.
+   However, the use of multiple authentication exchanges results in at
+   least one new security consideration.
+
+   In normal IKEv2, the responder authenticates the initiator before
+   revealing its identity (except when EAP is used).  When multiple
+   authentication exchanges are used to authenticate the initiator, the
+   responder has to reveal its identity before all of the initiator
+   authentication exchanges have been completed.
+
+
+
+
+
+
+
+
+Eronen & Korhonen             Experimental                      [Page 9]
+\f
+RFC 4739           Multiple Auth. Exchanges in IKEv2       November 2006
+
+
+6.  Acknowledgments
+
+   The authors would like to thank Bernard Aboba, Jari Arkko, Spencer
+   Dawkins, Lakshminath Dondeti, Henry Haverinen, Russ Housley, Mika
+   Joutsenvirta, Charlie Kaufman, Tero Kivinen, Yoav Nir, Magnus
+   Nystrom, Mohan Parthasarathy, and Juha Savolainen for their valuable
+   comments.
+
+7.  References
+
+7.1.  Normative References
+
+   [IKEv2]     Kaufman, C., "Internet Key Exchange (IKEv2) Protocol",
+               RFC 4306, December 2005.
+
+   [KEYWORDS]  Bradner, S., "Key words for use in RFCs to Indicate
+               Requirement Levels", RFC 2119, March 1997.
+
+7.2.  Informative References
+
+   [EAP]       Aboba, B., Blunk, L., Vollbrecht, J., Carlson, J., and H.
+               Levkowetz, "Extensible Authentication Protocol (EAP)",
+               RFC 3748, June 2004.
+
+   [PANA]      Yegin, A., Ohba, Y., Penno, R., Tsirtsis, G., and C.
+               Wang, "Protocol for Carrying Authentication for Network
+               Access (PANA) Requirements", RFC 4058, May 2005.
+
+Authors' Addresses
+
+   Pasi Eronen
+   Nokia Research Center
+   P.O. Box 407
+   FIN-00045 Nokia Group
+   Finland
+
+   EMail: pasi.eronen@nokia.com
+
+
+   Jouni Korhonen
+   TeliaSonera
+   P.O. Box 970
+   FIN-00051 Sonera
+   Finland
+
+   EMail: jouni.korhonen@teliasonera.com
+
+
+
+
+
+Eronen & Korhonen             Experimental                     [Page 10]
+\f
+RFC 4739           Multiple Auth. Exchanges in IKEv2       November 2006
+
+
+Full Copyright Statement
+
+   Copyright (C) The IETF Trust (2006).
+
+   This document is subject to the rights, licenses and restrictions
+   contained in BCP 78, and except as set forth therein, the authors
+   retain all their rights.
+
+   This document and the information contained herein are provided on an
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST,
+   AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT
+   THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
+   IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+   PURPOSE.
+
+Intellectual Property
+
+   The IETF takes no position regarding the validity or scope of any
+   Intellectual Property Rights or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; nor does it represent that it has
+   made any independent effort to identify any such rights.  Information
+   on the procedures with respect to rights in RFC documents can be
+   found in BCP 78 and BCP 79.
+
+   Copies of IPR disclosures made to the IETF Secretariat and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementers or users of this
+   specification can be obtained from the IETF on-line IPR repository at
+   http://www.ietf.org/ipr.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights that may cover technology that may be required to implement
+   this standard.  Please address the information to the IETF at
+   ietf-ipr@ietf.org.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+Eronen & Korhonen             Experimental                     [Page 11]
+\f
index 07db45f..efa845b 100644 (file)
@@ -738,7 +738,7 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
                        case SPIS:
                        case CONFIGURATION_ATTRIBUTE_VALUE:
                        case VID_DATA:
-                       case EAP_MESSAGE:
+                       case EAP_DATA:
                        {
                                u_int32_t payload_length_position_offset;
                                u_int16_t length_of_payload;
@@ -777,7 +777,7 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
                                        case CONFIGURATION_ATTRIBUTE_VALUE:
                                                header_length = CONFIGURATION_ATTRIBUTE_HEADER_LENGTH;
                                                break;
-                                       case EAP_MESSAGE:
+                                       case EAP_DATA:
                                                header_length = EAP_PAYLOAD_HEADER_LENGTH;
                                                break;
                                        default:
index f1b92e9..fb37c99 100644 (file)
@@ -142,11 +142,12 @@ static payload_rule_t ike_sa_init_r_payload_rules[] = {
  */
 static payload_rule_t ike_auth_i_payload_rules[] = {
        {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
+       {EXTENSIBLE_AUTHENTICATION,0,1,TRUE,TRUE},
+       {AUTHENTICATION,0,1,TRUE,TRUE},
        {ID_INITIATOR,1,1,TRUE,FALSE},
        {CERTIFICATE,0,1,TRUE,FALSE},
        {CERTIFICATE_REQUEST,0,1,TRUE,FALSE},
        {ID_RESPONDER,0,1,TRUE,FALSE},
-       {AUTHENTICATION,1,1,TRUE,FALSE},
        {SECURITY_ASSOCIATION,1,1,TRUE,FALSE},
        {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE,FALSE},
        {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE,FALSE},
@@ -158,12 +159,13 @@ static payload_rule_t ike_auth_i_payload_rules[] = {
  */
 static payload_rule_t ike_auth_r_payload_rules[] = {
        {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE},
+       {EXTENSIBLE_AUTHENTICATION,0,1,TRUE,TRUE},
        {CERTIFICATE,0,1,TRUE,FALSE},
-       {ID_RESPONDER,1,1,TRUE,FALSE},
-       {AUTHENTICATION,1,1,TRUE,FALSE},
-       {SECURITY_ASSOCIATION,1,1,TRUE,FALSE},
-       {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE,FALSE},
-       {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE,FALSE},
+       {ID_RESPONDER,0,1,TRUE,FALSE},
+       {AUTHENTICATION,0,1,TRUE,FALSE},
+       {SECURITY_ASSOCIATION,0,1,TRUE,FALSE},
+       {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE},
+       {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE},
        {CONFIGURATION,0,1,TRUE,FALSE},
 };
 
index d7f10f7..d7caf70 100644 (file)
@@ -626,7 +626,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               break;                                  
+                               break;
                        }
                        case U_INT_32:
                        {
@@ -635,7 +635,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               break;          
+                               break;
                        }
                        case U_INT_64:
                        {
@@ -644,7 +644,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               break;  
+                               break;
                        }
                        case IKE_SPI:
                        {
@@ -653,7 +653,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               break;  
+                               break;
                        }
                        case RESERVED_BIT:
                        {
@@ -662,7 +662,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               break;  
+                               break;
                        }
                        case RESERVED_BYTE:
                        {
@@ -680,7 +680,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               break;  
+                               break;
                        }
                        case PAYLOAD_LENGTH:
                        {
@@ -690,7 +690,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        return PARSE_ERROR;
                                }
                                payload_length = *(u_int16_t*)(output + rule->offset);
-                               break;                                                  
+                               break;
                        }
                        case HEADER_LENGTH:
                        {
@@ -699,7 +699,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               break;                                                  
+                               break;
                        }
                        case SPI_SIZE:
                        {
@@ -709,7 +709,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        return PARSE_ERROR;
                                }
                                spi_size = *(u_int8_t*)(output + rule->offset);
-                               break;                                                  
+                               break;
                        }
                        case SPI:
                        {
@@ -718,7 +718,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               break;                                                  
+                               break;
                        }
                        case PROPOSALS:
                        {
@@ -728,7 +728,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               break;                                                  
+                               break;
                        }
                        case TRANSFORMS:
                        {
@@ -738,7 +738,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               break;                                                  
+                               break;
                        }
                        case TRANSFORM_ATTRIBUTES:
                        {
@@ -748,7 +748,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               break;                                                  
+                               break;
                        }
                        case CONFIGURATION_ATTRIBUTES:
                        {
@@ -758,7 +758,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               break;                                                  
+                               break;
                        }
                        case ATTRIBUTE_FORMAT:
                        {
@@ -789,7 +789,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                }
                                attribute_length = *(u_int16_t*)(output + rule->offset);
                                break;
-                       }                       
+                       }
                        case ATTRIBUTE_LENGTH_OR_VALUE:
                        {       
                                if (this->parse_uint16(this, rule_number, output + rule->offset) != SUCCESS) 
@@ -820,7 +820,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }               
-                               break;                  
+                               break;
                        }
                        case ID_DATA:
                        {
@@ -830,7 +830,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }       
-                               break;                  
+                               break;
                        }
                        case AUTH_DATA:
                        {
@@ -839,8 +839,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                {
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
-                               }               
-                               break;                  
+                               }
+                               break;
                        }
                        case CERT_DATA:
                        {
@@ -849,8 +849,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                {
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
-                               }               
-                               break;                  
+                               }
+                               break;
                        }
                        case CERTREQ_DATA:
                        {
@@ -859,18 +859,18 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
                                {
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
-                               }               
-                               break;                  
+                               }
+                               break;
                        }
-                       case EAP_MESSAGE:
+                       case EAP_DATA:
                        {
                                size_t data_length = payload_length - EAP_PAYLOAD_HEADER_LENGTH;
                                if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS) 
                                {
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
-                               }               
-                               break;                  
+                               }
+                               break;
                        }
                        case SPIS:
                        {
index aa886e9..79ab32f 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "eap_payload.h"
 
+#include <daemon.h>
 
 typedef struct private_eap_payload_t private_eap_payload_t;
 
@@ -54,9 +55,9 @@ struct private_eap_payload_t {
        u_int16_t payload_length;
        
        /**
-        * The contained message.
+        * EAP message data, if available
         */
-       chunk_t message;
+       chunk_t data;
 };
 
 /**
@@ -80,21 +81,21 @@ encoding_rule_t eap_payload_encodings[] = {
        { RESERVED_BIT, 0                                                                                                       },
        { RESERVED_BIT, 0                                                                                                       },
        /* Length of the whole payload*/
-       { PAYLOAD_LENGTH,       offsetof(private_eap_payload_t, payload_length)},
-       /* some eap data bytes, length is defined in PAYLOAD_LENGTH */
-       { EAP_MESSAGE,          offsetof(private_eap_payload_t, message)                }
+       { PAYLOAD_LENGTH,       offsetof(private_eap_payload_t, payload_length) },
+       /* chunt to data, starting at "code" */
+       { EAP_DATA,                     offsetof(private_eap_payload_t, data)                   },
 };
 
 /*
-                           1                   2                   3
+                            1                   2                   3
         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        ! Next Payload  !C!  RESERVED   !         Payload Length        !
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       !                                                               !
-       ~                       EAP Message                             ~
-       !                                                               !
+       !     Code      ! Identifier    !           Length              !
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       !     Type      ! Type_Data...
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
 */
 
 /**
@@ -102,6 +103,47 @@ encoding_rule_t eap_payload_encodings[] = {
  */
 static status_t verify(private_eap_payload_t *this)
 {
+       u_int16_t length;
+       u_int8_t code;
+       
+       if (this->data.len < 4)
+       {
+               DBG1(DBG_ENC, "EAP payloads EAP message too short (%d)", this->data.len);
+               return FAILED;
+       }
+       code = *this->data.ptr;
+       length = htons(*(u_int16_t*)(this->data.ptr + 2));
+       if (this->data.len != length)
+       {
+               DBG1(DBG_ENC, "EAP payload length (%d) does not match contained message length (%d)",
+                        this->data.len, length);
+               return FAILED;
+       }
+       switch (code)
+       {
+               case EAP_REQUEST:
+               case EAP_RESPONSE:
+               {
+                       if (this->data.len < 4)
+                       {
+                               DBG1(DBG_ENC, "EAP Request/Response does not have any data");
+                               return FAILED;
+                       }
+                       break;
+               }
+               case EAP_SUCCESS:
+               case EAP_FAILURE:
+               {
+                       if (this->data.len != 4)
+                       {
+                               DBG1(DBG_ENC, "EAP Success/Failure has data");
+                               return FAILED;
+                       }
+                       break;
+               }
+               default:
+                       return FAILED;
+       }
        return SUCCESS;
 }
 
@@ -147,40 +189,59 @@ static size_t get_length(private_eap_payload_t *this)
 }
 
 /**
- * Implementation of eap_payload_t.set_message.
+ * Implementation of eap_payload_t.get_data.
+ */
+static chunk_t get_data(private_eap_payload_t *this)
+{
+       return this->data;
+}
+
+/**
+ * Implementation of eap_payload_t.set_data.
  */
-static void set_message (private_eap_payload_t *this, chunk_t message)
+static void set_data(private_eap_payload_t *this, chunk_t data)
 {
-       if (this->message.ptr != NULL)
+       chunk_free(&this->data);
+       this->data = chunk_clone(data);
+       this->payload_length = this->data.len + 4;
+}
+
+/**
+ * Implementation of eap_payload_t.get_code.
+ */
+static eap_code_t get_code(private_eap_payload_t *this)
+{
+       if (this->data.len > 0)
        {
-               chunk_free(&(this->message));
+               return *this->data.ptr;
        }
-       this->message.ptr = clalloc(message.ptr,message.len);
-       this->message.len = message.len;
-       this->payload_length = EAP_PAYLOAD_HEADER_LENGTH + this->message.len;
+       /* should not happen, as it is verified */
+       return 0;
 }
 
 /**
- * Implementation of eap_payload_t.get_message.
+ * Implementation of eap_payload_t.get_identifier.
  */
-static chunk_t get_message (private_eap_payload_t *this)
+static u_int8_t get_identifier(private_eap_payload_t *this)
 {
-       return (this->message);
+       if (this->data.len > 1)
+       {
+               return *(this->data.ptr + 1);
+       }
+       /* should not happen, as it is verified */
+       return 0;
 }
 
 /**
- * Implementation of eap_payload_t.get_data_clone.
+ * Implementation of eap_payload_t.get_type.
  */
-static chunk_t get_message_clone (private_eap_payload_t *this)
+static eap_type_t get_type(private_eap_payload_t *this)
 {
-       chunk_t cloned_message;
-       if (this->message.ptr == NULL)
+       if (this->data.len > 4)
        {
-               return (this->message);
+               return *(this->data.ptr + 4);
        }
-       cloned_message.ptr = clalloc(this->message.ptr,this->message.len);
-       cloned_message.len = this->message.len;
-       return cloned_message;
+       return 0;
 }
 
 /**
@@ -188,12 +249,8 @@ static chunk_t get_message_clone (private_eap_payload_t *this)
  */
 static void destroy(private_eap_payload_t *this)
 {
-       if (this->message.ptr != NULL)
-       {
-               chunk_free(&(this->message));
-       }
-       
-       free(this);     
+       chunk_free(&this->data);
+       free(this);
 }
 
 /*
@@ -202,7 +259,7 @@ static void destroy(private_eap_payload_t *this)
 eap_payload_t *eap_payload_create()
 {
        private_eap_payload_t *this = malloc_thing(private_eap_payload_t);
-
+       
        /* interface functions */
        this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
        this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
@@ -214,15 +271,61 @@ eap_payload_t *eap_payload_create()
        
        /* public functions */
        this->public.destroy = (void (*) (eap_payload_t *)) destroy;
-       this->public.set_message = (void (*) (eap_payload_t *,chunk_t)) set_message;
-       this->public.get_message_clone = (chunk_t (*) (eap_payload_t *)) get_message_clone;
-       this->public.get_message = (chunk_t (*) (eap_payload_t *)) get_message;
+       this->public.get_data = (chunk_t (*) (eap_payload_t*))get_data;
+       this->public.set_data = (void (*) (eap_payload_t *,chunk_t))set_data;
+       this->public.get_code = (eap_code_t (*) (eap_payload_t*))get_code;
+       this->public.get_identifier = (u_int8_t (*) (eap_payload_t*))get_identifier;
+       this->public.get_type = (eap_type_t (*) (eap_payload_t*))get_type;
        
        /* private variables */
        this->critical = FALSE;
        this->next_payload = NO_PAYLOAD;
        this->payload_length = EAP_PAYLOAD_HEADER_LENGTH;
-       this->message = chunk_empty;
+       this->data = chunk_empty;
+       
+       return &(this->public);
+}
+
+/*
+ * Described in header
+ */
+eap_payload_t *eap_payload_create_data(chunk_t data)
+{
+       eap_payload_t *this = eap_payload_create();
+       
+       this->set_data(this, data);
+       return this;
+}
 
-       return (&(this->public));
+/*
+ * Described in header
+ */
+eap_payload_t *eap_payload_create_code(eap_code_t code)
+{
+       eap_payload_t *this = eap_payload_create();
+       chunk_t data = chunk_alloca(4);
+       
+       *(data.ptr + 0) = code;
+       *(data.ptr + 1) = 0;
+       *(u_int16_t*)(data.ptr + 2) = htons(data.len);
+       
+       this->set_data(this, data);
+       return this;
+}
+
+/*
+ * Described in header
+ */
+eap_payload_t *eap_payload_create_nak()
+{
+       eap_payload_t *this = eap_payload_create();
+       chunk_t data = chunk_alloca(5);
+       
+       *(data.ptr + 0) = EAP_RESPONSE;
+       *(data.ptr + 1) = 0;
+       *(u_int16_t*)(data.ptr + 2) = htons(data.len);
+       *(data.ptr + 4) = EAP_NAK;
+       
+       this->set_data(this, data);
+       return this;
 }
index bf493eb..13c0ade 100644 (file)
@@ -28,6 +28,7 @@ typedef struct eap_payload_t eap_payload_t;
 
 #include <library.h>
 #include <encoding/payloads/payload.h>
+#include <sa/authenticators/eap/eap_method.h>
 
 /**
  * Length of a EAP payload without the EAP Message in bytes.
@@ -44,62 +45,105 @@ typedef struct eap_payload_t eap_payload_t;
  * @b Constructors:
  * - eap_payload_create()
  *
- * @todo Implement functionality for this payload
- *
  * @ingroup payloads
  */
 struct eap_payload_t {
+       
        /**
         * The payload_t interface.
         */
        payload_t payload_interface;
        
        /**
-        * @brief Set the EAP Message.
-        * 
-        * Data are getting cloned.
+        * @brief Set the contained EAP data.
+        *
+        * This contains the FULL EAP message starting with "code".
+        * Chunk gets cloned.
+        *
+        * @param this          calling eap_payload_t object
+        * @param message       EAP data
+        */
+       void (*set_data) (eap_payload_t *this, chunk_t data);
+       
+       /**
+        * @brief Get the contained EAP data.
+        *
+        * This contains the FULL EAP message starting with "code".
         *
-        * @param this                  calling eap_payload_t object
-        * @param message               EAP message as chunk_t
+        * @param this          calling eap_payload_t object
+        * @return                      EAP data (pointer to internal data)
         */
-       void (*set_message) (eap_payload_t *this, chunk_t message);
+       chunk_t (*get_data) (eap_payload_t *this);
        
        /**
-        * @brief Get the EAP message.
-        * 
-        * Returned data are a copy of the internal one.
+        * @brief Get the EAP code.
         *
-        * @param this                  calling eap_payload_t object
-        * @return                              EAP message as chunk_t
+        * @param this          calling eap_payload_t object
+        * @return                      EAP message as chunk_t
         */
-       chunk_t (*get_message_clone) (eap_payload_t *this);
+       eap_code_t (*get_code) (eap_payload_t *this);
        
        /**
-        * @brief Get the EAP message.
-        * 
-        * Returned data are NOT copied.
+        * @brief Get the EAP identifier.
         *
-        * @param this                  calling eap_payload_t object
-        * @return                              EAP message as chunk_t
+        * @param this          calling eap_payload_t object
+        * @return                      unique identifier
         */
-       chunk_t (*get_message) (eap_payload_t *this);
+       u_int8_t (*get_identifier) (eap_payload_t *this);
+       
+       /**
+        * @brief Get the EAP method type.
+        *
+        * @param this          calling eap_payload_t object
+        * @return                      EAP method type
+        */
+       eap_type_t (*get_type) (eap_payload_t *this);
        
        /**
         * @brief Destroys an eap_payload_t object.
         *
-        * @param this  eap_payload_t object to destroy
+        * @param this          eap_payload_t object to destroy
         */
        void (*destroy) (eap_payload_t *this);
 };
 
 /**
  * @brief Creates an empty eap_payload_t object.
- * 
+ *
  * @return eap_payload_t object
- * 
+ *
  * @ingroup payloads
  */
 eap_payload_t *eap_payload_create(void);
 
+/**
+ * @brief Creates an eap_payload_t object with data.
+ *
+ * @return eap_payload_t object
+ *
+ * @ingroup payloads
+ */
+eap_payload_t *eap_payload_create_data(chunk_t data);
+
+/**
+ * @brief Creates an eap_payload_t object with a code.
+ *
+ * Could should be either EAP_SUCCESS/EAP_FAILURE, use 
+ * constructor above otherwise.
+ *
+ * @return eap_payload_t object
+ *
+ * @ingroup payloads
+ */
+eap_payload_t *eap_payload_create_code(eap_code_t code);
+
+/**
+ * @brief Creates an eap_payload_t EAP_RESPONSE containing an EAP_NAK.
+ *
+ * @return eap_payload_t object
+ *
+ * @ingroup payloads
+ */
+eap_payload_t *eap_payload_create_nak();
 
 #endif /* EAP_PAYLOAD_H_ */
index ed5596e..5e07fbf 100644 (file)
@@ -449,7 +449,7 @@ enum encoding_type_t {
         * 
         * When parsing (Payload Length - 4) bytes are read and written into the chunk pointing to.
         */
-       EAP_MESSAGE,
+       EAP_DATA,
        
        /**
         * Representating the SPIS field in a DELETE payload.
index b11d8f2..38ee094 100644 (file)
@@ -75,7 +75,9 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, INVALID_SELECTORS,
        "COOKIE2",
        "NO_NATS_ALLOWED",
        "AUTH_LIFETIME");
-ENUM_END(notify_type_names, AUTH_LIFETIME);
+ENUM_NEXT(notify_type_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, AUTH_LIFETIME,
+       "EAP_ONLY_AUTHENTICATION");
+ENUM_END(notify_type_names, EAP_ONLY_AUTHENTICATION);
 
 typedef struct private_notify_payload_t private_notify_payload_t;
 
index 8861b9f..4319326 100644 (file)
@@ -88,8 +88,10 @@ enum notify_type_t {
        NO_NATS_ALLOWED = 16402,
        /* repeated authentication extension, RFC4478 */
        AUTH_LIFETIME = 16403,
+       /* draft-eronen-ipsec-ikev2-eap-auth, not assigned by IANA yet */
+       EAP_ONLY_AUTHENTICATION = 40960,
        /* BEET mode, not even a draft yet. private use */
-       USE_BEET_MODE = 40960,
+       USE_BEET_MODE = 40961,
 };
 
 /**
index 2460181..707aae9 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <sa/authenticators/rsa_authenticator.h>
 #include <sa/authenticators/psk_authenticator.h>
+#include <sa/authenticators/eap_authenticator.h>
 
 
 ENUM_BEGIN(auth_method_names, AUTH_RSA, AUTH_DSS,
@@ -47,6 +48,8 @@ authenticator_t *authenticator_create(ike_sa_t *ike_sa, auth_method_t auth_metho
                        return (authenticator_t*)rsa_authenticator_create(ike_sa);
                case AUTH_PSK:
                        return (authenticator_t*)psk_authenticator_create(ike_sa);
+               case AUTH_EAP:
+                       return (authenticator_t*)eap_authenticator_create(ike_sa);
                default:
                        return NULL;
        }
diff --git a/src/charon/sa/authenticators/eap/eap_aka.c b/src/charon/sa/authenticators/eap/eap_aka.c
new file mode 100644 (file)
index 0000000..0c1bb33
--- /dev/null
@@ -0,0 +1,1399 @@
+/**
+ * @file eap_aka.c
+ *
+ * @brief Implementation of eap_aka_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+
+/* The EAP-AKA method uses it's own simple parser for processing EAP-AKA
+ * payloads, as the IKEv2 parser is not suitable for that job. There are
+ * two simple methods for parsing payloads, read_header() and read_attribute().
+ * Every EAP-AKA payload consists of a header and a list of attributes. Those
+ * functions mentioned read the data and return the type of the found
+ * attribute/EAP-AKA-type. For generating a EAP-AKA message, we have a
+ * build_aka_payload(), which builds the whole message from a variable
+ * argument list containing its attributes.
+ * The processing of messages is split up in various functions:
+ * - peer_process() - General processing multiplexer for the peer
+ *   - peer_process_challenge() - Specific AKA-Challenge processor
+ *   - peer_process_notification() - Processing of AKA-Notification
+ * - server_process() - General processing multiplexer for the server
+ *   - peer_process_challenge() - Processing of a received Challenge response
+ *   - peer_process_synchronize() - Process a sequence number synchronization
+ * - server_initiate() - Initiation method for the server, calls
+ *   - server_initiate_challenge() - Initiation of AKA-Challenge
+ */
+
+#include <string.h>
+#include <unistd.h>
+
+#include "eap_aka.h"
+
+#include <daemon.h>
+#include <library.h>
+#include <utils/randomizer.h>
+#include <crypto/hashers/hasher.h>
+#include <crypto/prfs/fips_prf.h>
+
+/* Use test vectors specified in S.S0055
+#define TEST_VECTORS */
+
+#define RAND_LENGTH            16
+#define RES_LENGTH             16
+#define SQN_LENGTH              6
+#define K_LENGTH               16
+#define MAC_LENGTH              8
+#define CK_LENGTH              16
+#define IK_LENGTH              16
+#define AK_LENGTH               6
+#define AMF_LENGTH              2
+#define FMK_LENGTH              4
+#define AUTN_LENGTH    (SQN_LENGTH + AMF_LENGTH + MAC_LENGTH)
+#define AUTS_LENGTH    (SQN_LENGTH + MAC_LENGTH)
+#define PAYLOAD_LENGTH 64
+#define MK_LENGTH              20
+#define MSK_LENGTH             64
+#define EMSK_LENGTH            64
+#define KAUTH_LENGTH   16
+#define KENCR_LENGTH   16
+#define AT_MAC_LENGTH  16
+
+#define F1                       0x42
+#define F1STAR           0x43
+#define F2                       0x44
+#define F3                       0x45
+#define F4                       0x46
+#define F5                       0x47
+#define F5STAR           0x48
+
+ENUM_BEGIN(aka_subtype_names, AKA_CHALLENGE, AKA_IDENTITY,
+       "AKA_CHALLENGE",
+       "AKA_AUTHENTICATION_REJECT",
+       "AKA_3",
+       "AKA_SYNCHRONIZATION_FAILURE",
+       "AKA_IDENTITY");
+ENUM_NEXT(aka_subtype_names, AKA_NOTIFICATION, AKA_CLIENT_ERROR, AKA_IDENTITY,
+       "AKA_NOTIFICATION",
+       "AKA_REAUTHENTICATION",
+       "AKA_CLIENT_ERROR");
+ENUM_END(aka_subtype_names, AKA_CLIENT_ERROR);
+
+
+ENUM_BEGIN(aka_attribute_names, AT_END, AT_CLIENT_ERROR_CODE,
+       "AT_END",
+       "AT_0",
+       "AT_RAND",
+       "AT_AUTN",
+       "AT_RES",
+       "AT_AUTS",
+       "AT_5",
+       "AT_PADDING",
+       "AT_NONCE_MT",
+       "AT_8",
+       "AT_9",
+       "AT_PERMANENT_ID_REQ",
+       "AT_MAC",
+       "AT_NOTIFICATION",
+       "AT_ANY_ID_REQ",
+       "AT_IDENTITY",
+       "AT_VERSION_LIST",
+       "AT_SELECTED_VERSION",
+       "AT_FULLAUTH_ID_REQ",
+       "AT_18",
+       "AT_COUNTER",
+       "AT_COUNTER_TOO_SMALL",
+       "AT_NONCE_S",
+       "AT_CLIENT_ERROR_CODE");
+ENUM_NEXT(aka_attribute_names, AT_IV, AT_RESULT_IND, AT_CLIENT_ERROR_CODE,
+       "AT_IV",
+       "AT_ENCR_DATA",
+       "AT_131",
+       "AT_NEXT_PSEUDONYM",
+       "AT_NEXT_REAUTH_ID",
+       "AT_CHECKCODE",
+       "AT_RESULT_IND");
+ENUM_END(aka_attribute_names, AT_RESULT_IND);
+
+
+typedef struct private_eap_aka_t private_eap_aka_t;
+
+/**
+ * Private data of an eap_aka_t object.
+ */
+struct private_eap_aka_t {
+       
+       /**
+        * Public authenticator_t interface.
+        */
+       eap_aka_t public;
+       
+       /**
+        * ID of the server
+        */
+       identification_t *server;
+       
+       /**
+        * ID of the peer
+        */
+       identification_t *peer;
+       
+       /**
+        * Key for EAP MAC
+        */
+       chunk_t k_auth;
+       
+       /**
+        * Key for EAP encryption
+        */
+       chunk_t k_encr;
+       
+       /**
+        * MSK
+        */
+       chunk_t msk;
+       
+       /**
+        * Extendend MSK
+        */
+       chunk_t emsk;
+       
+       /**
+        * Expected result from client XRES
+        */
+       chunk_t xres;
+       
+       /**
+        * Shared secret K from ipsec.conf (padded)
+        */
+       chunk_t k;
+       
+       /**
+        * random value RAND generated by server
+        */
+        chunk_t rand;
+};
+
+/** Family key, as proposed in S.S0055 */
+static u_int8_t fmk_buf[] = {0x41, 0x48, 0x41, 0x47};
+static chunk_t fmk = chunk_from_buf(fmk_buf);
+
+/** Authentication management field */
+static u_int8_t amf_buf[] = {0x00, 0x01};
+static chunk_t amf = chunk_from_buf(amf_buf);
+
+/** AT_CLIENT_ERROR_CODE AKA attribute */
+static u_int8_t client_error_code_buf[] = {0, 0};
+static chunk_t client_error_code = chunk_from_buf(client_error_code_buf);
+
+/** previously used sqn by peer, next one must be greater */
+static u_int8_t peer_sqn_buf[6];
+static chunk_t peer_sqn = chunk_from_buf(peer_sqn_buf);
+
+/** set SQN to the current time */
+static void update_sqn(u_int8_t *sqn, time_t offset)
+{
+       timeval_t time;
+       gettimeofday(&time, NULL);
+       /* set sqb_sqn to an integer containing seconds followed by most
+        * significant useconds */
+       time.tv_sec = htonl(time.tv_sec + offset);
+       /* usec's are never larger than 0x000f423f, so we shift the 12 first bits */
+       time.tv_usec <<= 12;
+       time.tv_usec = htonl(time.tv_usec);
+       memcpy(sqn, &time.tv_sec, 4);
+       memcpy(sqn + 4, &time.tv_usec, 2);
+}
+
+/** initialize peers SQN to the current system time at startup */
+static void __attribute__ ((constructor))init_sqn(void)
+{
+       update_sqn(peer_sqn_buf, 0);
+}
+
+/**
+ * Binary represnation of the polynom T^160 + T^5 + T^3 + T^2 + 1
+ */
+static u_int8_t g[] = {
+       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x2d
+};
+
+/**
+ * Predefined random bits from the RAND Corporation book
+ */
+static u_int8_t a[] = {
+       0x9d, 0xe9, 0xc9, 0xc8, 0xef, 0xd5, 0x78, 0x11,
+       0x48, 0x23, 0x14, 0x01, 0x90, 0x1f, 0x2d, 0x49,
+       0x3f, 0x4c, 0x63, 0x65
+};
+
+/**
+ * Predefined random bits from the RAND Corporation book
+ */
+static u_int8_t b[] = {
+       0x75, 0xef, 0xd1, 0x5c, 0x4b, 0x8f, 0x8f, 0x51,
+       0x4e, 0xf3, 0xbc, 0xc3, 0x79, 0x4a, 0x76, 0x5e,
+       0x7e, 0xec, 0x45, 0xe0
+};
+
+/**
+ * Multiplicate two mpz_t with bits interpreted as polynoms.
+ */
+static void mpz_mul_poly(mpz_t r, mpz_t a, mpz_t b)
+{
+       mpz_t bm, rm;
+       int current = 0, shifted = 0, shift;
+       
+       mpz_init_set(bm, b);
+       mpz_init_set_ui(rm, 0);
+       /* scan through a, for each found bit: */
+       while ((current = mpz_scan1(a, current)) != ULONG_MAX)
+       {
+               /* XOR shifted b into r */
+               shift = current - shifted;
+               mpz_mul_2exp(bm, bm, shift);
+               shifted += shift;
+               mpz_xor(rm, rm, bm);
+               current++;
+       }
+       
+       mpz_swap(r, rm);
+       mpz_clear(rm);
+       mpz_clear(bm);
+}
+
+/**
+ * Calculate the sum of a + b interpreted as polynoms.
+ */
+static void mpz_add_poly(mpz_t res, mpz_t a, mpz_t b)
+{
+       /* addition of polynominals is just the XOR */
+       mpz_xor(res, a, b);
+}
+
+/**
+ * Calculate the remainder of a/b interpreted as polynoms.
+ */
+static void mpz_mod_poly(mpz_t r, mpz_t a, mpz_t b)
+{
+       /* Example:
+        * a = 10001010
+        * b = 00000101
+        */
+       int a_bit, b_bit, diff;
+       mpz_t bm, am;
+       
+       mpz_init_set(am, a);
+       mpz_init(bm);
+       
+       a_bit = mpz_sizeinbase(a, 2);
+       b_bit = mpz_sizeinbase(b, 2);
+       
+       /* don't do anything if b > a */
+       if (a_bit >= b_bit)
+       {
+               /* shift b left to align up most signaficant "1" to a:
+                * a = 10001010
+                * b = 10100000
+                */
+               mpz_mul_2exp(bm, b, a_bit - b_bit);
+               do
+               {
+                       /* XOR b into a, this kills the most significant "1":
+                        * a = 00101010
+                        */
+                       mpz_xor(am, am, bm);
+                       /* find the next most significant "1" in a, and align up b:
+                        * a = 00101010
+                        * b = 00101000
+                        */
+                       diff = a_bit - mpz_sizeinbase(am, 2);
+                       mpz_div_2exp(bm, bm, diff);
+                       a_bit -= diff;
+               }
+               while (b_bit <= mpz_sizeinbase(bm, 2));
+               /* While b is not shifted to its original value */
+       }
+       /* after another iteration:
+        * a = 00000010
+        * which is the polynomial modulo
+        */
+       
+       mpz_swap(r, am);
+       mpz_clear(am);
+       mpz_clear(bm);
+}
+
+/**
+ * Step 4 of the various fx() functions:
+ * Polynomial whiten calculations
+ */
+static void step4(u_int8_t x[])
+{
+       mpz_t xm, am, bm, gm;
+       
+       mpz_init(xm);
+       mpz_init(am);
+       mpz_init(bm);
+       mpz_init(gm);
+       
+       mpz_import(xm, HASH_SIZE_SHA1, 1, 1, 1, 0, x);
+       mpz_import(am, sizeof(a), 1, 1, 1, 0, a);
+       mpz_import(bm, sizeof(b), 1, 1, 1, 0, b);
+       mpz_import(gm, sizeof(g), 1, 1, 1, 0, g);
+
+       mpz_mul_poly(xm, am, xm);
+       mpz_add_poly(xm, bm, xm);
+       mpz_mod_poly(xm, xm, gm);
+       
+       mpz_export(x, NULL, 1, HASH_SIZE_SHA1, 1, 0, xm);
+       
+       mpz_clear(xm);
+       mpz_clear(am);
+       mpz_clear(bm);
+       mpz_clear(gm);
+}
+
+/**
+ * Step 3 of the various fx() functions:
+ * XOR the key into the SHA1 IV
+ */
+static void step3(chunk_t k, chunk_t payload, u_int8_t h[])
+{
+       u_int8_t iv[] = {
+               0x67,0x45,0x23,0x01,0xEF,0xCD,0xAB,0x89,0x98,0xBA,
+               0xDC,0xFE,0x10,0x32,0x54,0x76,0xC3,0xD2,0xE1,0xF0,
+       };
+       
+       /* XOR key into IV */
+       memxor(iv, k.ptr, k.len);
+       
+       /* hash it with the G() function defined in FIPS 186-2 from fips_prf.h */
+       g_sha1(iv, payload, h);
+}
+
+/**
+ * Calculation function for f2(), f3(), f4()
+ */
+static void fx(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t out[])
+{
+       chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
+       u_int8_t h[HASH_SIZE_SHA1];
+       u_int8_t i;
+       
+       for (i = 0; i < 2; i++)
+       {
+               memset(payload.ptr, 0x5c, payload.len);
+               payload.ptr[11] ^= f;
+               memxor(payload.ptr + 12, fmk.ptr, fmk.len);
+               memxor(payload.ptr + 24, rand.ptr, rand.len);
+               
+               payload.ptr[3]  ^= i;
+               payload.ptr[19] ^= i;
+               payload.ptr[35] ^= i;
+               payload.ptr[51] ^= i;
+               
+               step3(k, payload, h);
+               step4(h);
+               memcpy(out + i * 8, h, 8);
+       }
+}
+
+/**
+ * Calculation function of f1() and f1star()
+ */
+static void f1x(u_int8_t f, chunk_t k, chunk_t rand, chunk_t sqn,
+                               chunk_t amf, u_int8_t mac[])
+{
+       /* generate MAC = f1(FMK, SQN, RAND, AMF)
+        * K is loaded into hashers IV; FMK, RAND, SQN, AMF are XORed in a 512-bit
+        * payload which gets hashed
+        */
+       chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
+       u_int8_t h[HASH_SIZE_SHA1];
+       
+       memset(payload.ptr, 0x5c, PAYLOAD_LENGTH);
+       payload.ptr[11] ^= f;
+       memxor(payload.ptr + 12, fmk.ptr, fmk.len);
+       memxor(payload.ptr + 16, rand.ptr, rand.len);
+       memxor(payload.ptr + 34, sqn.ptr, sqn.len);
+       memxor(payload.ptr + 42, amf.ptr, amf.len);
+       
+       step3(k, payload, h);
+       step4(h);
+       memcpy(mac, h, MAC_LENGTH);
+}
+
+/**
+ * Calculation function of f5() and f5star()
+ */
+static void f5x(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t ak[])
+{
+       chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
+       u_int8_t h[HASH_SIZE_SHA1];
+       
+       memset(payload.ptr, 0x5c, payload.len);
+       payload.ptr[11] ^= f;
+       memxor(payload.ptr + 12, fmk.ptr, fmk.len);
+       memxor(payload.ptr + 16, rand.ptr, rand.len);
+       
+       step3(k, payload, h);
+       step4(h);
+       memcpy(ak, h, AK_LENGTH);
+}
+
+/**
+ * Calculate the MAC from a RAND, SQN, AMF value using K
+ */
+static void f1(chunk_t k, chunk_t rand, chunk_t sqn, chunk_t amf, u_int8_t mac[])
+{
+       f1x(F1, k, rand, sqn, amf, mac);
+       DBG3(DBG_IKE, "MAC %b", mac, MAC_LENGTH);
+}
+
+/**
+ * Calculate the MACS from a RAND, SQN, AMF value using K
+ */
+static void f1star(chunk_t k, chunk_t rand, chunk_t sqn, chunk_t amf, u_int8_t macs[])
+{
+       f1x(F1STAR, k, rand, sqn, amf, macs);
+       DBG3(DBG_IKE, "MACS %b", macs, MAC_LENGTH);
+}
+
+/**
+ * Calculate RES from RAND using K
+ */
+static void f2(chunk_t k, chunk_t rand, u_int8_t res[])
+{
+       fx(F2, k, rand, res);
+       DBG3(DBG_IKE, "RES %b", res, RES_LENGTH);
+}
+
+/**
+ * Calculate CK from RAND using K
+ */
+static void f3(chunk_t k, chunk_t rand, u_int8_t ck[])
+{
+       fx(F3, k, rand, ck);
+       DBG3(DBG_IKE, "CK %b", ck, CK_LENGTH);
+}
+
+/**
+ * Calculate IK from RAND using K
+ */
+static void f4(chunk_t k, chunk_t rand, u_int8_t ik[])
+{
+       fx(F4, k, rand, ik);
+       DBG3(DBG_IKE, "IK %b", ik, IK_LENGTH);
+}
+
+/**
+ * Calculate AK from a RAND using K
+ */
+static void f5(chunk_t k, chunk_t rand, u_int8_t ak[])
+{
+       f5x(F5, k, rand, ak);
+       DBG3(DBG_IKE, "AK %b", ak, AK_LENGTH);
+}
+
+/**
+ * Calculate AKS from a RAND using K
+ */
+static void f5star(chunk_t k, chunk_t rand, u_int8_t aks[])
+{
+       f5x(F5STAR, k, rand, aks);
+       DBG3(DBG_IKE, "AKS %b", aks, AK_LENGTH);
+}
+
+/**
+ * derive the keys needed for EAP_AKA
+ */
+static void derive_keys(private_eap_aka_t *this, identification_t *id)
+{
+       hasher_t *hasher;
+       prf_t *prf;
+       chunk_t ck, ik, mk, identity, tmp;
+       
+       ck = chunk_alloca(CK_LENGTH);
+       ik = chunk_alloca(IK_LENGTH);
+       mk = chunk_alloca(MK_LENGTH);
+       identity = id->get_encoding(id);
+       
+       /* MK = SHA1( Identity | IK | CK ) */
+       f3(this->k, this->rand, ck.ptr);
+       f4(this->k, this->rand, ik.ptr);
+       DBG3(DBG_IKE, "Identity %B", &identity);
+       tmp = chunk_cata("ccc", identity, ik, ck);
+       DBG3(DBG_IKE, "Identity|IK|CK %B", &tmp);
+       hasher = hasher_create(HASH_SHA1);
+       hasher->get_hash(hasher, tmp, mk.ptr);
+       hasher->destroy(hasher);
+       
+       /* K_encr | K_auth | MSK | EMSK = prf(0) | prf(0)
+        * FIPS PRF has 320 bit block size, we need 160 byte for keys
+        *  => run prf four times */
+       prf = prf_create(PRF_FIPS_SHA1_160);
+       prf->set_key(prf, mk);
+       tmp = chunk_alloca(prf->get_block_size(prf) * 4);
+       prf->get_bytes(prf, chunk_empty, tmp.ptr);
+       prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 1);
+       prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 2);
+       prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 3);
+       prf->destroy(prf);
+       chunk_free(&this->k_encr);
+       chunk_free(&this->k_auth);
+       chunk_free(&this->msk);
+       chunk_free(&this->emsk);
+       chunk_split(tmp, "aaaa", 16, &this->k_encr, 16, &this->k_auth,
+                               64, &this->msk, 64, &this->emsk);
+       DBG3(DBG_IKE, "MK %B", &mk);
+       DBG3(DBG_IKE, "PRF res %B", &tmp);
+       DBG3(DBG_IKE, "K_encr %B", &this->k_encr);
+       DBG3(DBG_IKE, "K_auth %B", &this->k_auth);
+       DBG3(DBG_IKE, "MSK %B", &this->msk);
+       DBG3(DBG_IKE, "EMSK %B", &this->emsk);
+}
+
+/*
+ * Get a shared key from ipsec.secrets.
+ * We use the standard keys as used in preshared key authentication. As
+ * these keys have an undefined length, we:
+ * - strip them if they are longer
+ * - fill them up with '\0' if they are shorter
+ */
+static status_t load_key(identification_t *me, identification_t *other, chunk_t *k)
+{
+       chunk_t shared_key;
+
+       if (charon->credentials->get_shared_key(charon->credentials, me,
+                                                                                       other, &shared_key) != SUCCESS)
+       {
+               return NOT_FOUND;
+       }
+       chunk_free(k);
+       *k = chunk_alloc(K_LENGTH);
+       memset(k->ptr, '\0', k->len);
+       memcpy(k->ptr, shared_key.ptr, min(shared_key.len, k->len));
+       chunk_free(&shared_key);
+       return SUCCESS;
+}
+
+/**
+ * skip EAP_AKA header in message and returns its AKA subtype
+ */
+static aka_subtype_t read_header(chunk_t *message)
+{
+       aka_subtype_t type;
+
+       if (message->len < 8)
+       {
+               *message = chunk_empty;
+               return 0;
+       }
+       type = *(message->ptr + 5);
+       *message = chunk_skip(*message, 8);
+       return type;
+}
+
+/**
+ * read the next attribute from the chunk data
+ */
+static aka_attribute_t read_attribute(chunk_t *data, chunk_t *attr_data)
+{
+       aka_attribute_t attribute;
+       size_t length;
+       
+       DBG3(DBG_IKE, "reading attribute from %B", data);
+       
+       if (data->len < 2)
+       {
+               return AT_END;
+       }
+       /* read attribute and length */
+       attribute = *data->ptr++;
+       length = *data->ptr++ * 4 - 2;
+       data->len -= 2;
+       DBG3(DBG_IKE, "found attribute %N with length %d",
+                aka_attribute_names, attribute, length);
+       if (length > data->len)
+       {
+               return AT_END;
+       }
+       /* apply attribute value to attr_data */
+       attr_data->len = length;
+       attr_data->ptr = data->ptr;
+       /* update data to point to next attribute */
+       *data = chunk_skip(*data, length);
+       return attribute;
+}
+
+/**
+ * Build an AKA payload from different attributes.
+ * The variable argument takes an aka_attribute_t
+ * followed by its data in a chunk.
+ */
+static eap_payload_t *build_aka_payload(private_eap_aka_t *this, eap_code_t code,
+                                                                               u_int8_t identifier, aka_subtype_t type, ...)
+{
+       chunk_t message = chunk_alloca(512); /* is enought for all current messages */
+       chunk_t pos = message;
+       eap_payload_t *payload;
+       va_list args;
+       aka_attribute_t attr;
+       u_int8_t *mac_pos = NULL;
+       
+       /* write EAP header, skip length bytes */
+       *pos.ptr++ = code;
+       *pos.ptr++ = identifier;
+       pos.ptr += 2;
+       pos.len -= 4;
+       /* write AKA header with type and subtype, null reserved bytes */
+       *pos.ptr++ = EAP_AKA;
+       *pos.ptr++ = type;
+       *pos.ptr++ = 0;
+       *pos.ptr++ = 0;
+       pos.len -= 4;
+       
+       va_start(args, type);
+       while ((attr = va_arg(args, aka_attribute_t)) != AT_END)
+       {
+               chunk_t data = va_arg(args, chunk_t);
+               
+               DBG3(DBG_IKE, "building %N %B", aka_attribute_names, attr, &data);
+               
+               /* write attribute header */
+               *pos.ptr++ = attr;
+               pos.len--;
+               
+               switch (attr)
+               {
+                       case AT_RES:
+                       {
+                               /* attribute length in 4byte words */
+                               *pos.ptr = data.len/4 + 1;
+                               pos = chunk_skip(pos, 1);
+                               /* RES length in bits */
+                               *(u_int16_t*)pos.ptr = htons(data.len * 8);
+                               pos = chunk_skip(pos, sizeof(u_int16_t));
+                               memcpy(pos.ptr, data.ptr, data.len);
+                               pos = chunk_skip(pos, data.len);
+                               break;
+                       }
+                       case AT_AUTN:
+                       case AT_RAND:
+                       {
+                               *pos.ptr++ = data.len/4 + 1; pos.len--;
+                               *pos.ptr++ = 0; pos.len--;
+                               *pos.ptr++ = 0; pos.len--;
+                               memcpy(pos.ptr, data.ptr, data.len);
+                               pos = chunk_skip(pos, data.len);
+                               break;
+                       }
+                       case AT_MAC:
+                       {
+                               *pos.ptr++ = 5; pos.len--;
+                               *pos.ptr++ = 0; pos.len--;
+                               *pos.ptr++ = 0; pos.len--;
+                               mac_pos = pos.ptr;
+                               /* MAC is calculated over message including zeroed AT_MAC attribute */
+                               memset(mac_pos, 0, AT_MAC_LENGTH);
+                               pos.ptr += AT_MAC_LENGTH;
+                               pos.len -= AT_MAC_LENGTH;
+                               break;
+                       }
+                       default:
+                       {
+                               /* length is data length in 4-bytes + 1 for header */
+                               *pos.ptr = data.len/4 + 1;
+                               pos = chunk_skip(pos, 1);
+                               memcpy(pos.ptr, data.ptr, data.len);
+                               pos = chunk_skip(pos, data.len);
+                       }
+               }
+       }
+       va_end(args);
+       
+       /* calculate message length, write into header */
+       message.len = pos.ptr - message.ptr;
+       *(u_int16_t*)(message.ptr + 2) = htons(message.len);
+       
+       /* create MAC if AT_MAC attribte was included */
+       if (mac_pos)
+       {
+               signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
+               signer->set_key(signer, this->k_auth);
+               DBG3(DBG_IKE, "AT_MAC signature of %B", &message);
+               DBG3(DBG_IKE, "using key %B", &this->k_auth);
+               signer->get_signature(signer, message, mac_pos);
+               DBG3(DBG_IKE, "is %b", mac_pos, AT_MAC_LENGTH);
+               signer->destroy(signer);
+       }
+       
+       /* payload constructor takes data with some bytes skipped */
+       payload = eap_payload_create_data(message);
+       
+       DBG3(DBG_IKE, "created EAP message %B", &message);
+       return payload;
+}
+
+/**
+ * Initiate a AKA-Challenge using SQN
+ */
+static status_t server_initiate_challenge(private_eap_aka_t *this, chunk_t sqn, eap_payload_t **out)
+{
+       randomizer_t *randomizer;
+       status_t status;
+       chunk_t mac, ak, autn;
+       
+       mac = chunk_alloca(MAC_LENGTH);
+       ak = chunk_alloca(AK_LENGTH);
+       chunk_free(&this->rand);
+       chunk_free(&this->xres);
+       
+       /* generate RAND:
+        * we use our standard randomizer, not f0() proposed in S.S0055
+        */
+       randomizer = randomizer_create();
+       status = randomizer->allocate_pseudo_random_bytes(randomizer, RAND_LENGTH, &this->rand);
+       randomizer->destroy(randomizer);
+       if (status != SUCCESS)
+       {
+               DBG1(DBG_IKE, "generating RAND for EAP-AKA authentication failed");
+               return FAILED;
+       }
+       
+#      ifdef TEST_VECTORS
+       /* Test vector for RAND */
+       u_int8_t test_rand[] = {
+               0x4b,0x05,0x2b,0x20,0xe2,0xa0,0x6c,0x8f,
+               0xf7,0x00,0xda,0x51,0x2b,0x4e,0x11,0x1e,
+       };
+       memcpy(this->rand.ptr, test_rand, this->rand.len); 
+#      endif /* TEST_VECTORS */
+       
+       /* Get the shared key K: */
+       if (load_key(this->server, this->peer, &this->k) != SUCCESS)
+       {
+               DBG1(DBG_IKE, "no shared key found for IDs '%D' - '%D' to authenticate "
+                               "with EAP-AKA", this->server, this->peer);
+               return FAILED;
+       }
+       
+#      ifdef TEST_VECTORS
+       /* Test vector for K */
+       u_int8_t test_k[] = {
+               0xad,0x1b,0x5a,0x15,0x9b,0xe8,0x6b,0x2c,
+               0xa6,0x6c,0x7a,0xe4,0x0b,0xba,0x9b,0x9d,
+       };
+       memcpy(this->k.ptr, test_k, this->k.len);
+#      endif /* TEST_VECTORS */
+       
+       /* generate MAC */
+       f1(this->k, this->rand, sqn, amf, mac.ptr);
+       
+       /* generate AK */
+       f5(this->k, this->rand, ak.ptr);
+       
+       /* precalculate XRES as expected from client */
+       this->xres = chunk_alloc(RES_LENGTH);
+       f2(this->k, this->rand, this->xres.ptr);
+       
+       /* calculate AUTN = (SQN xor AK) || AMF || MAC */
+       autn = chunk_cata("ccc", sqn, amf, mac);
+       memxor(autn.ptr, ak.ptr, ak.len);
+       DBG3(DBG_IKE, "AUTN %B", &autn);
+       
+       
+       /* derive K_encr, K_auth, MSK, EMSK  */
+       derive_keys(this, this->peer);
+       
+       /* build payload */
+       *out = build_aka_payload(this, EAP_REQUEST, 0, AKA_CHALLENGE,
+                                                        AT_RAND, this->rand, AT_AUTN, autn, AT_MAC,
+                                                        chunk_empty, AT_END);
+       return NEED_MORE;
+}
+
+/**
+ * Implementation of eap_method_t.initiate for an EAP_AKA server
+ */
+static status_t server_initiate(private_eap_aka_t *this, eap_payload_t **out)
+{
+       chunk_t sqn = chunk_alloca(SQN_LENGTH);
+       
+       /* we use an offset of 3 minutes to tolerate clock inaccuracy
+        * without the need to synchronize sequence numbers */
+       update_sqn(sqn.ptr, 180);
+       
+#      ifdef TEST_VECTORS
+       /* Test vector for SQN */
+       u_int8_t test_sqn[] = {0x00,0x00,0x00,0x00,0x00,0x01};
+       memcpy(sqn.ptr, test_sqn, sqn.len); 
+#      endif /* TEST_VECTORS */
+       
+       return server_initiate_challenge(this, sqn, out);
+}
+
+static status_t server_process_synchronize(private_eap_aka_t *this,
+                                                                                  eap_payload_t *in, eap_payload_t **out)
+{
+       chunk_t attr, auts = chunk_empty, pos, message, macs, xmacs, sqn, aks, amf;
+       u_int i;
+       
+       message = in->get_data(in);
+       pos = message;
+       read_header(&pos);
+       
+       /* iterate over attributes */
+       while (TRUE)
+       {
+               aka_attribute_t attribute = read_attribute(&pos, &attr);
+               switch (attribute)
+               {
+                       case AT_END:
+                               break;
+                       case AT_AUTS:
+                               auts = attr;
+                               continue;
+                       default:
+                               if (attribute >= 0 && attribute <= 127)
+                               {
+                                       DBG1(DBG_IKE, "found non skippable attribute %N",
+                                                aka_attribute_names, attribute);
+                                       return FAILED;
+                               }
+                               DBG1(DBG_IKE, "ignoring skippable attribute %N",
+                                        aka_attribute_names, attribute);
+                               continue;
+               }
+               break;
+       }
+       
+       if (auts.len != AUTS_LENGTH)
+       {
+               DBG1(DBG_IKE, "synchronization request didn't contain useable AUTS");
+               return FAILED;
+       }
+       
+       chunk_split(auts, "mm", SQN_LENGTH, &sqn, MAC_LENGTH, &macs);
+       aks = chunk_alloca(AK_LENGTH);
+       f5star(this->k, this->rand, aks.ptr);
+       /* decrypt serial number by XORing AKS */
+       memxor(sqn.ptr, aks.ptr, aks.len);
+       
+       /* verify MACS */
+       xmacs = chunk_alloca(MAC_LENGTH);
+       amf = chunk_alloca(AMF_LENGTH);
+       /* an AMF of zero is used for MACS calculation */
+       memset(amf.ptr, 0, amf.len);
+       f1star(this->k, this->rand, sqn, amf, xmacs.ptr);
+       if (!chunk_equals(macs, xmacs))
+       {
+               DBG1(DBG_IKE, "received MACS does not match XMACS");
+               DBG3(DBG_IKE, "MACS %B XMACS %B", &macs, &xmacs);
+               return FAILED;
+       }
+       
+       /* retry the challenge with the received SQN + 1*/
+       for (i = SQN_LENGTH - 1; i >= 0; i--)
+       {
+               if (++sqn.ptr[i] != 0)
+               {
+                       break;
+               }
+       }
+       return server_initiate_challenge(this, sqn, out);
+}
+
+/**
+ * process an AKA_Challenge response
+ */
+static status_t server_process_challenge(private_eap_aka_t *this, eap_payload_t *in)
+{
+       chunk_t attr, res = chunk_empty, at_mac = chunk_empty, pos, message;
+       
+       message = in->get_data(in);
+       pos = message;
+       read_header(&pos);
+       
+       /* iterate over attributes */
+       while (TRUE)
+       {
+               aka_attribute_t attribute = read_attribute(&pos, &attr);
+               switch (attribute)
+               {
+                       case AT_END:
+                               break;
+                       case AT_RES:
+                               res = attr;
+                               if (attr.len == 2 + RES_LENGTH &&
+                                       *(u_int16_t*)attr.ptr == htons(RES_LENGTH * 8))
+                               {
+                                       res = chunk_skip(attr, 2);
+                               }
+                               continue;
+
+                       case AT_MAC:
+                               attr = chunk_skip(attr, 2);
+                               at_mac = chunk_clonea(attr);
+                               /* zero MAC in message for MAC verification */
+                               memset(attr.ptr, 0, attr.len);
+                               continue;
+                       default:
+                               if (attribute >= 0 && attribute <= 127)
+                               {
+                                       DBG1(DBG_IKE, "found non skippable attribute %N",
+                                                aka_attribute_names, attribute);
+                                       return FAILED;
+                               }
+                               DBG1(DBG_IKE, "ignoring skippable attribute %N",
+                                        aka_attribute_names, attribute);
+                               continue;
+               }
+               break;
+       }
+       
+       /* verify EAP message MAC AT_MAC */
+       {
+               bool valid;
+               signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
+               signer->set_key(signer, this->k_auth);
+               DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
+               DBG3(DBG_IKE, "using key %B", &this->k_auth);
+               valid = signer->verify_signature(signer, message, at_mac);
+               signer->destroy(signer);
+               if (!valid)
+               {
+                       DBG1(DBG_IKE, "MAC in AT_MAC attribute verification failed");
+                       return FAILED;
+               }
+       }
+       
+       /* compare received RES against stored precalculated XRES */
+       if (!chunk_equals(res, this->xres))
+       {
+               DBG1(DBG_IKE, "received RES does not match XRES");
+               DBG3(DBG_IKE, "RES %Bb XRES %B", &res, &this->xres);
+               return FAILED;
+       }
+       return SUCCESS;
+}
+
+/**
+ * Implementation of eap_method_t.process for EAP_AKA servers
+ */
+static status_t server_process(private_eap_aka_t *this,
+                                                          eap_payload_t *in, eap_payload_t **out)
+{
+       chunk_t message;
+       aka_subtype_t type;
+       
+       message = in->get_data(in);
+       type = read_header(&message);
+       
+       DBG3(DBG_IKE, "received EAP message %B",  &message);
+       
+       switch (type)
+       {
+               case AKA_CHALLENGE:
+               {
+                       return server_process_challenge(this, in);
+               }
+               case AKA_AUTHENTICATION_REJECT:
+               case AKA_CLIENT_ERROR:
+               {
+                       DBG1(DBG_IKE, "received %N, authentication failed",
+                                aka_subtype_names, type);
+                       return FAILED;
+               }
+               case AKA_SYNCHRONIZATION_FAILURE:
+               {
+                       DBG1(DBG_IKE, "received %N, retrying with received SQN",
+                                aka_subtype_names, type);
+                       return server_process_synchronize(this, in, out);
+               }
+               default:
+                       DBG1(DBG_IKE, "received unknown AKA subtype %N, authentication failed",
+                                aka_subtype_names, type);
+                       return FAILED;
+       }
+}
+
+/**
+ * Process an incoming AKA-Challenge client side
+ */
+static status_t peer_process_challenge(private_eap_aka_t *this,
+                                                                          eap_payload_t *in, eap_payload_t **out)
+{
+       chunk_t attr = chunk_empty;
+       chunk_t autn = chunk_empty, at_mac = chunk_empty;
+       chunk_t ak, sqn, sqn_ak, mac, xmac, res, amf, message, pos;
+       u_int8_t identifier;
+       
+       ak = chunk_alloca(AK_LENGTH);
+       xmac = chunk_alloca(MAC_LENGTH);
+       res = chunk_alloca(RES_LENGTH);
+       chunk_free(&this->rand);
+       
+       message = in->get_data(in);
+       pos = message;
+       read_header(&pos);
+       identifier = in->get_identifier(in);
+       
+       DBG3(DBG_IKE, "reading attributes from %B", &pos);
+       
+       /* iterate over attributes */
+       while (TRUE)
+       {
+               aka_attribute_t attribute = read_attribute(&pos, &attr);
+               switch (attribute)
+               {
+                       case AT_END:
+                               break;
+                       case AT_RAND:
+                               this->rand = chunk_clone(chunk_skip(attr, 2));
+                               continue;
+                       case AT_AUTN:
+                               autn = chunk_skip(attr, 2);
+                               continue;
+                       case AT_MAC:
+                               attr = chunk_skip(attr, 2);
+                               at_mac = chunk_clonea(attr);
+                               /* set MAC in message to zero for own MAC verification */
+                               memset(attr.ptr, 0, attr.len);
+                               continue;
+                       default:
+                               if (attribute >= 0 && attribute <= 127)
+                               {
+                                       /* non skippable attribute, abort */
+                                       *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
+                                                               AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
+                                       DBG1(DBG_IKE, "found non skippable attribute %N, sending %N %d",
+                                                aka_attribute_names, attribute,
+                                                aka_attribute_names, AT_CLIENT_ERROR_CODE, 0);
+                                       return NEED_MORE;
+                               }
+                               DBG1(DBG_IKE, "ignoring skippable attribute %N",
+                                        aka_attribute_names, attribute);
+                               continue;
+               }
+               break;
+       }
+       
+       if (this->rand.len != RAND_LENGTH || autn.len != AUTN_LENGTH)
+       {
+               /* required attributes wrong/not found, abort */
+               *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
+                                       AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
+               DBG1(DBG_IKE, "could not find valid RAND/AUTN attribute, sending %N %d",
+                        aka_attribute_names, AT_CLIENT_ERROR_CODE, 0);
+               return NEED_MORE;
+       }
+       /* split up AUTN = SQN xor AK | AMF | MAC */
+       chunk_split(autn, "mmm", SQN_LENGTH, &sqn_ak, AMF_LENGTH, &amf, MAC_LENGTH, &mac);
+       
+       /* Get the shared key K: */
+       chunk_free(&this->k);
+       if (load_key(this->peer, this->server, &this->k) != SUCCESS)
+       {
+               *out = build_aka_payload(this, EAP_RESPONSE, identifier,
+                                                                AKA_AUTHENTICATION_REJECT, AT_END);
+               DBG3(DBG_IKE, "no shared key found for IDs '%D' - '%D' to authenticate "
+                        "with EAP-AKA, sending %N", this->peer, this->server,
+                        aka_subtype_names, AKA_AUTHENTICATION_REJECT);
+               return NEED_MORE;
+       }
+#      ifdef TEST_VECTORS
+       /* Test vector for K */
+       u_int8_t test_k[] = {
+               0xad,0x1b,0x5a,0x15,0x9b,0xe8,0x6b,0x2c,
+               0xa6,0x6c,0x7a,0xe4,0x0b,0xba,0x9b,0x9d,
+       };
+       memcpy(this->k.ptr, test_k, this->k.len);
+#      endif /* TEST_VECTORS */
+       
+       /* calculate anonymity key AK */
+       f5(this->k, this->rand, ak.ptr);
+       /* XOR AK into SQN to decrypt it */
+       sqn = chunk_clonea(sqn_ak);
+       memxor(sqn.ptr, ak.ptr, sqn.len);
+       
+       /* calculate expected MAC and compare against received one */
+       f1(this->k, this->rand, sqn, amf, xmac.ptr);
+       if (!chunk_equals(mac, xmac))
+       {
+               *out = build_aka_payload(this, EAP_RESPONSE, identifier,
+                                                                AKA_AUTHENTICATION_REJECT, AT_END);
+               DBG1(DBG_IKE, "received MAC does not match XMAC, sending %N",
+                        aka_subtype_names, AKA_AUTHENTICATION_REJECT);
+               DBG3(DBG_IKE, "MAC %B XMAC %B", &mac, &xmac);
+               return NEED_MORE;
+       }
+       
+       if (memcmp(peer_sqn.ptr, sqn.ptr, sqn.len) >= 0)
+       {
+               /* sequence number invalid. send AUTS */
+               chunk_t auts, macs, aks, amf;
+               
+               macs = chunk_alloca(MAC_LENGTH);
+               aks = chunk_alloca(AK_LENGTH);
+               amf = chunk_alloca(AMF_LENGTH);
+               
+               /* AMF is set to zero in AKA_SYNCHRONIZATION_FAILURE */
+               memset(amf.ptr, 0, amf.len);            
+               /* AKS = f5*(RAND) */
+               f5star(this->k, this->rand, aks.ptr);
+               /* MACS = f1*(RAND) */
+               f1star(this->k, this->rand, peer_sqn, amf, macs.ptr);
+               /* AUTS = SQN xor AKS | MACS */
+               memxor(aks.ptr, peer_sqn.ptr, aks.len);
+               auts = chunk_cata("cc", aks, macs);
+               
+               *out = build_aka_payload(this, EAP_RESPONSE, identifier,
+                                                                AKA_SYNCHRONIZATION_FAILURE,
+                                                                AT_AUTS, auts, AT_END);
+               DBG1(DBG_IKE, "received SQN invalid, sending %N",
+                        aka_subtype_names, AKA_SYNCHRONIZATION_FAILURE);
+               DBG3(DBG_IKE, "received SQN %B\ncurrent SQN %B", &sqn, &peer_sqn);
+               return NEED_MORE;
+       }
+       
+       /* derive K_encr, K_auth, MSK, EMSK  */
+       derive_keys(this, this->peer);
+                               
+       /* verify EAP message MAC AT_MAC */
+       {
+               bool valid;
+               signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
+               signer->set_key(signer, this->k_auth);
+               
+               DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
+               DBG3(DBG_IKE, "using key %B", &this->k_auth);
+               valid = signer->verify_signature(signer, message, at_mac);
+               signer->destroy(signer);
+               if (!valid)
+               {
+                       *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
+                                                       AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
+                       DBG1(DBG_IKE, "MAC in AT_MAC attribute verification "
+                                "failed, sending %N %d", aka_attribute_names,
+                                AT_CLIENT_ERROR_CODE, 0);
+                       return NEED_MORE;
+               }
+       }
+       
+       /* update stored SQN to the received one */
+       memcpy(peer_sqn.ptr, sqn.ptr, sqn.len);
+       
+       /* calculate RES */
+       f2(this->k, this->rand, res.ptr);
+       
+       /* build response */
+       *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CHALLENGE,
+                                                        AT_RES, res, AT_MAC, chunk_empty, AT_END);
+       return NEED_MORE;
+}
+
+/**
+ * Process an incoming AKA-Notification as client
+ */
+static status_t peer_process_notification(private_eap_aka_t *this,
+                                                                                 eap_payload_t *in, eap_payload_t **out)
+{
+       chunk_t message, pos, attr;
+       u_int8_t identifier;
+       
+       message = in->get_data(in);
+       pos = message;
+       read_header(&pos);
+       identifier = in->get_identifier(in);
+       
+       DBG3(DBG_IKE, "reading attributes from %B", &pos);
+       
+       /* iterate over attributes */
+       while (TRUE)
+       {
+               aka_attribute_t attribute = read_attribute(&pos, &attr);
+               switch (attribute)
+               {
+                       case AT_END:
+                               break;
+                       case AT_NOTIFICATION:
+                               if (attr.len != 2)
+                               {
+                                       DBG1(DBG_IKE, "received invalid AKA notification, ignored");
+                               }
+                               else
+                               {
+                                       DBG1(DBG_IKE, "received AKA notification code %d, ignored",
+                                                ntohs(*(u_int16_t*)attr.ptr));
+                               }
+                               continue;
+                       default:
+                               if (attribute >= 0 && attribute <= 127)
+                               {
+                                       DBG1(DBG_IKE, "ignoring non-skippable attribute %N in %N",
+                                               aka_attribute_names, attribute, aka_subtype_names,
+                                               AKA_NOTIFICATION);
+                               }
+                               else
+                               {
+                                       DBG1(DBG_IKE, "ignoring skippable attribute %N",
+                                                aka_attribute_names, attribute);
+                               }
+                               continue;
+               }
+               break;
+       }
+       return NEED_MORE;
+}
+
+/**
+ * Implementation of eap_method_t.process for an EAP_AKA peer
+ */
+static status_t peer_process(private_eap_aka_t *this,
+                                                        eap_payload_t *in, eap_payload_t **out)
+{
+       aka_subtype_t type;
+       chunk_t message;
+       u_int8_t identifier;
+       
+       message = in->get_data(in);
+       type = read_header(&message);
+       identifier = in->get_identifier(in);
+       
+       DBG3(DBG_IKE, "received EAP message %B",  &message);
+       
+       switch (type)
+       {
+               case AKA_CHALLENGE:
+               {
+                       return peer_process_challenge(this, in, out);
+               }
+               case AKA_NOTIFICATION:
+               {
+                       return peer_process_notification(this, in, out);
+               }
+               default:
+               {
+                       *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
+                                               AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
+                       DBG1(DBG_IKE, "received unsupported %N request, sending %N %d",
+                                aka_subtype_names, type,
+                                aka_attribute_names, AT_CLIENT_ERROR_CODE, 0);
+                       return NEED_MORE;
+               }
+       }
+}
+
+/**
+ * Implementation of eap_method_t.initiate for an EAP AKA peer
+ */
+static status_t peer_initiate(private_eap_aka_t *this, eap_payload_t **out)
+{
+       /* peer never initiates */
+       return FAILED;
+}
+
+/**
+ * Implementation of eap_method_t.get_type.
+ */
+static eap_type_t get_type(private_eap_aka_t *this)
+{
+       return EAP_AKA;
+}
+
+/**
+ * Implementation of eap_method_t.get_msk.
+ */
+static status_t get_msk(private_eap_aka_t *this, chunk_t *msk)
+{
+       if (this->msk.ptr)
+       {
+               *msk = this->msk;
+               return SUCCESS;
+       }
+       return FAILED;
+}
+
+/**
+ * Implementation of eap_method_t.is_mutual.
+ */
+static bool is_mutual(private_eap_aka_t *this)
+{
+       return TRUE;
+}
+
+/**
+ * Implementation of eap_method_t.destroy.
+ */
+static void destroy(private_eap_aka_t *this)
+{
+       chunk_free(&this->k_encr);
+       chunk_free(&this->k_auth);
+       chunk_free(&this->msk);
+       chunk_free(&this->emsk);
+       chunk_free(&this->xres);
+       chunk_free(&this->k);
+       chunk_free(&this->rand);
+       free(this);
+}
+
+/*
+ * Described in header.
+ */
+eap_aka_t *eap_create(eap_role_t role,
+                                         identification_t *server, identification_t *peer)
+{
+       private_eap_aka_t *this = malloc_thing(private_eap_aka_t);
+       
+       /* public functions */
+       switch (role)
+       {
+               case EAP_SERVER:
+                       this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))server_initiate;
+                       this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))server_process;
+                       break;
+               case EAP_PEER:
+                       this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))peer_initiate;
+                       this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))peer_process;
+                       break;
+               default:
+                       free(this);
+                       return NULL;
+       }
+       this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*))get_type;
+       this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
+       this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
+       this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
+       
+       /* private data */
+       this->server = server;
+       this->peer = peer;
+       this->k_encr = chunk_empty;
+       this->k_auth = chunk_empty;
+       this->msk = chunk_empty;
+       this->emsk = chunk_empty;
+       this->xres = chunk_empty;
+       this->k = chunk_empty;
+       this->rand = chunk_empty;
+       
+       return &this->public;
+}
diff --git a/src/charon/sa/authenticators/eap/eap_aka.h b/src/charon/sa/authenticators/eap/eap_aka.h
new file mode 100644 (file)
index 0000000..cc740f6
--- /dev/null
@@ -0,0 +1,133 @@
+/**
+ * @file eap_aka.h
+ *
+ * @brief Interface of eap_aka_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef EAP_AKA_H_
+#define EAP_AKA_H_
+
+typedef struct eap_aka_t eap_aka_t;
+typedef enum aka_subtype_t aka_subtype_t;
+typedef enum aka_attribute_t aka_attribute_t;
+
+#include <sa/authenticators/eap/eap_method.h>
+
+
+/**
+ * Subtypes of AKA messages
+ */
+enum aka_subtype_t {
+       AKA_CHALLENGE = 1,
+       AKA_AUTHENTICATION_REJECT = 2,
+       AKA_SYNCHRONIZATION_FAILURE = 4,
+       AKA_IDENTITY = 5,
+       AKA_NOTIFICATION = 12,
+       AKA_REAUTHENTICATION = 13,
+       AKA_CLIENT_ERROR = 14,
+};
+
+/**
+ * enum names for aka_subtype_t
+ */
+extern enum_name_t *aka_subtype_names;
+
+/**
+ * Attribute types in AKA messages
+ */
+enum aka_attribute_t {
+       /** defines the end of attribute list */
+       AT_END = -1,
+       AT_RAND = 1,
+       AT_AUTN = 2,
+       AT_RES = 3,
+       AT_AUTS = 4,
+       AT_PADDING = 6,
+       AT_NONCE_MT = 7,
+       AT_PERMANENT_ID_REQ = 10,
+       AT_MAC = 11,
+       AT_NOTIFICATION = 12,
+       AT_ANY_ID_REQ = 13,
+       AT_IDENTITY = 14,
+       AT_VERSION_LIST = 15,
+       AT_SELECTED_VERSION = 16,
+       AT_FULLAUTH_ID_REQ = 17,
+       AT_COUNTER = 19,
+       AT_COUNTER_TOO_SMALL = 20,
+       AT_NONCE_S = 21,
+       AT_CLIENT_ERROR_CODE = 22,
+       AT_IV = 129,
+       AT_ENCR_DATA = 130,
+       AT_NEXT_PSEUDONYM = 132,
+       AT_NEXT_REAUTH_ID = 133,
+       AT_CHECKCODE = 134,
+       AT_RESULT_IND = 135,
+};
+
+/**
+ * enum names for aka_attribute_t
+ */
+extern enum_name_t *aka_attribute_names;
+
+
+/**
+ * @brief Implementation of the eap_method_t interface using EAP-AKA.
+ *
+ * EAP-AKA uses 3rd generation mobile phone standard authentication
+ * mechanism for authentication. It is a mutual authentication
+ * mechanism which establishs a shared key and therefore supports EAP_ONLY
+ * authentication. This implementation follows the standard of the
+ * 3GPP2 (S.S0055) and not the one of 3GGP.
+ * The shared key used for authentication is from ipsec.secrets. The
+ * peers ID is used to query it.
+ * The AKA mechanism uses sequence numbers to detect replay attacks. The
+ * peer stores the sequence number normally in a USIM and accepts
+ * incremental sequence numbers (incremental for lifetime of the USIM). To
+ * prevent a complex sequence number management, this implementation uses
+ * a sequence number derived from time. It is initialized to the startup
+ * time of the daemon. As long as the (UTC) time of the system is not
+ * turned back while the daemon is not running, this method is secure.
+ *
+ * @b Constructors:
+ *  - eap_aka_create()
+ *  - eap_client_create() using eap_method EAP_AKA
+ *
+ * @ingroup eap
+ */
+struct eap_aka_t {
+
+       /**
+        * Implemented eap_method_t interface.
+        */
+       eap_method_t eap_method_interface;
+};
+
+/**
+ * @brief Creates the EAP method EAP-AKA.
+ *
+ * @param server       ID of the EAP server
+ * @param peer         ID of the EAP client
+ * @return                     eap_aka_t object
+ *
+ * @ingroup eap
+ */
+eap_aka_t *eap_create(eap_role_t role,
+                                         identification_t *server, identification_t *peer);
+
+#endif /* EAP_AKA_H_ */
diff --git a/src/charon/sa/authenticators/eap/eap_method.c b/src/charon/sa/authenticators/eap/eap_method.c
new file mode 100644 (file)
index 0000000..435aa9d
--- /dev/null
@@ -0,0 +1,243 @@
+/**
+ * @file eap_method.c
+ *
+ * @brief Generic constructor for eap_methods.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <string.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <error.h>
+#include <dlfcn.h>
+
+#include "eap_method.h"
+
+#include <daemon.h>
+#include <library.h>
+#include <utils/linked_list.h>
+#include <utils/identification.h>
+
+
+ENUM_BEGIN(eap_type_names, EAP_IDENTITY, EAP_TOKEN_CARD,
+       "EAP_IDENTITY",
+       "EAP_NOTIFICATION",
+       "EAP_NAK",
+       "EAP_MD5",
+       "EAP_ONE_TIME_PASSWORD",
+       "EAP_TOKEN_CARD");
+ENUM_NEXT(eap_type_names, EAP_AKA, EAP_AKA, EAP_TOKEN_CARD,
+       "EAP_AKA");
+ENUM_END(eap_type_names, EAP_AKA);
+
+ENUM(eap_code_names, EAP_REQUEST, EAP_FAILURE,
+       "EAP_REQUEST",
+       "EAP_RESPONSE",
+       "EAP_SUCCESS",
+       "EAP_FAILURE",
+);
+
+ENUM(eap_role_names, EAP_SERVER, EAP_PEER,
+       "EAP_SERVER",
+       "EAP_PEER",
+);
+
+
+typedef struct module_entry_t module_entry_t;
+
+/**
+ * Representation of a loaded module: EAP type, library handle, constructor
+ */
+struct module_entry_t {
+       eap_type_t type;
+       void *handle;
+       eap_constructor_t constructor;
+};
+
+/** List of module_entry_t's */
+static linked_list_t *modules = NULL;
+
+/**
+ * unload modules at daemon shutdown
+ */
+void eap_method_unload()
+{
+       if (modules)
+       {
+               module_entry_t *entry;
+               
+               while (modules->remove_last(modules, (void**)&entry) == SUCCESS)
+               {
+                       DBG2(DBG_CFG, "unloaded module for %s", eap_type_names, entry->type);
+                       dlclose(entry->handle);
+                       free(entry);
+               }
+               modules->destroy(modules);
+               modules = NULL;
+       }
+}
+
+/**
+ * Load EAP modules at daemon startup
+ */
+void eap_method_load(char *directory)
+{
+       struct dirent* entry;
+       struct stat stb;
+       DIR* dir;
+       
+       eap_method_unload();    
+       modules = linked_list_create();
+       
+       if (stat(directory, &stb) == -1 || !(stb.st_mode & S_IFDIR))
+       {
+               DBG1(DBG_CFG, "error opening EAP modules directory %s", directory);
+               return;
+       }
+       if (stb.st_uid != 0)
+       {
+               DBG1(DBG_CFG, "EAP modules directory %s not owned by root, skipped", directory);
+               return;
+       }
+       if (stb.st_mode & S_IWOTH || stb.st_mode & S_IWGRP)
+       {
+               DBG1(DBG_CFG, "EAP modules directory %s writable by others, skipped", directory);
+               return;
+       }
+
+       dir = opendir(directory);
+       if (dir == NULL)
+       {
+               DBG1(DBG_CFG, "error opening EAP modules directory %s", directory);
+               return;
+       }
+       
+       DBG1(DBG_CFG, "loading EAP modules from '%s'", directory);
+
+       while ((entry = readdir(dir)) != NULL)
+       {
+               char file[256];
+               module_entry_t module, *loaded_module;
+               eap_method_t *method;
+               identification_t *id;
+               char *ending;
+               
+               snprintf(file, sizeof(file), "%s/%s", directory, entry->d_name);
+               
+               if (stat(file, &stb) == -1 || !(stb.st_mode & S_IFREG))
+               {
+                       DBG2(DBG_CFG, "  skipping %s, doesn't look like a file",
+                                entry->d_name);
+                       continue;
+               }
+               ending = entry->d_name + strlen(entry->d_name) - 3;
+               if (ending <= entry->d_name || !streq(ending, ".so"))
+               {
+                       /* skip anything which does not look like a library */
+                       DBG2(DBG_CFG, "  skipping %s, doesn't look like a library",
+                                entry->d_name);
+                       continue;
+               }
+               if (stb.st_uid != 0)
+               {
+                       DBG1(DBG_CFG, "  skipping %s, file is not owned by root", entry->d_name);
+                       return;
+               }
+               if (stb.st_mode & S_IWOTH || stb.st_mode & S_IWGRP)
+               {
+                       DBG1(DBG_CFG, "  skipping %s, file is writeable by others", entry->d_name);
+                       continue;
+               }
+               
+               /* try to load the library */
+               module.handle = dlopen(file, RTLD_LAZY);
+               if (module.handle == NULL)
+               {
+                       DBG1(DBG_CFG, "  opening EAP module %s failed: %s", entry->d_name,
+                                dlerror());
+                       continue;
+               }
+               module.constructor = dlsym(module.handle, "eap_create");
+               if (module.constructor == NULL)
+               {
+                       DBG1(DBG_CFG, "  EAP module %s has no eap_create() function, skipped",
+                               entry->d_name);
+                       dlclose(module.handle);
+                       continue;
+               }
+               
+               /* get the type implemented in the method, create an instance for it */
+               id = identification_create_from_string("john@doe.xyz");
+               method = module.constructor(EAP_SERVER, id, id);
+               if (method == NULL)
+               {
+                       method = module.constructor(EAP_PEER, id, id);
+               }
+               id->destroy(id);
+               if (method == NULL)
+               {
+                       DBG1(DBG_CFG, "  unable to create instance of EAP method %s, skipped",
+                                entry->d_name);
+                       dlclose(module.handle);
+                       continue;
+               }
+               module.type = method->get_type(method);
+               method->destroy(method);
+               
+               DBG1(DBG_CFG, "  loaded EAP method %N successfully from %s",
+                        eap_type_names, module.type, entry->d_name);
+                        
+               loaded_module = malloc_thing(module_entry_t);
+               memcpy(loaded_module, &module, sizeof(module));
+               modules->insert_last(modules, loaded_module);
+       }
+       closedir(dir);
+}
+
+/*
+ * Described in header.
+ */
+eap_method_t *eap_method_create(eap_type_t type, eap_role_t role,
+                                                               identification_t *server,
+                                                               identification_t *peer)
+{
+       eap_method_t *method = NULL;
+       iterator_t *iterator;
+       module_entry_t *entry;
+       
+       iterator = modules->create_iterator(modules, TRUE);
+       while (iterator->iterate(iterator, (void**)&entry))
+       {
+               if (entry->type == type)
+               {
+                       method = entry->constructor(role, server, peer);
+                       if (method)
+                       {
+                               break;
+                       }
+               }
+       }
+       iterator->destroy(iterator);
+       
+       if (method == NULL)
+       {
+               DBG1(DBG_CFG, "no EAP module found for %N %N",
+                        eap_type_names, type, eap_role_names, role);
+       }
+       return method;
+}
diff --git a/src/charon/sa/authenticators/eap/eap_method.h b/src/charon/sa/authenticators/eap/eap_method.h
new file mode 100644 (file)
index 0000000..2b09c0f
--- /dev/null
@@ -0,0 +1,241 @@
+/**
+ * @file eap_method.h
+ *
+ * @brief Interface eap_method_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef EAP_METHOD_H_
+#define EAP_METHOD_H_
+
+typedef struct eap_method_t eap_method_t;
+typedef enum eap_role_t eap_role_t;
+typedef enum eap_type_t eap_type_t;
+typedef enum eap_code_t eap_code_t;
+
+#include <library.h>
+#include <utils/identification.h>
+#include <encoding/payloads/eap_payload.h>
+
+/**
+ * Role of an eap_method, SERVER or PEER (client)
+ *
+ * @ingroup eap
+ */
+enum eap_role_t {
+       EAP_SERVER,
+       EAP_PEER,
+};
+/**
+ * enum names for eap_role_t.
+ *
+ * @ingroup eap
+ */
+extern enum_name_t *eap_role_names;
+
+/**
+ * EAP types, defines the EAP method implementation
+ *
+ * @ingroup eap
+ */
+enum eap_type_t {
+       EAP_IDENTITY = 1,
+       EAP_NOTIFICATION = 2,
+       EAP_NAK = 3,
+       EAP_MD5 = 4,
+       EAP_ONE_TIME_PASSWORD = 5,
+       EAP_TOKEN_CARD = 6,
+       EAP_AKA = 23,
+};
+
+/**
+ * enum names for eap_type_t.
+ *
+ * @ingroup eap
+ */
+extern enum_name_t *eap_type_names;
+
+/**
+ * EAP code, type of an EAP message
+ *
+ * @ingroup eap
+ */
+enum eap_code_t {
+       EAP_REQUEST = 1,
+       EAP_RESPONSE = 2,
+       EAP_SUCCESS = 3,
+       EAP_FAILURE = 4,
+};
+
+/**
+ * enum names for eap_code_t.
+ *
+ * @ingroup eap
+ */
+extern enum_name_t *eap_code_names;
+
+
+/**
+ * @brief Interface of an EAP method for server and client side.
+ *
+ * An EAP method initiates an EAP exchange and processes requests and
+ * responses. An EAP method may need multiple exchanges before succeeding, and
+ * the eap_authentication may use multiple EAP methods to authenticate a peer.
+ * To accomplish these requirements, all EAP methods have their own
+ * implementation while the eap_authenticatior uses one or more of these
+ * EAP methods. Sending of EAP(SUCCESS/FAILURE) message is not the job
+ * of the method, the eap_authenticator does this.
+ * An EAP method may establish a MSK, this is used the complete the
+ * authentication. Even if a mutual EAP method is used, the traditional
+ * AUTH payloads are required. Only these include the nonces and messages from
+ * ike_sa_init and therefore prevent man in the middle attacks.
+ *
+ * @b Constructors:
+ *  - eap_method_create()
+ *
+ * @ingroup eap
+ */
+struct eap_method_t {
+       
+       /**
+        * @brief Initiate the EAP exchange.
+        *
+        * initiate() is only useable for server implementations, as clients only
+        * reply to server requests.
+        * A eap_payload is created in "out" if result is NEED_MORE.
+        *
+        * @param this          calling object
+        * @param out           eap_payload to send to the client
+        * @return
+        *                                      - NEED_MORE, if an other exchange is required
+        *                                      - FAILED, if unable to create eap request payload
+        */
+       status_t (*initiate) (eap_method_t *this, eap_payload_t **out);
+       
+       /**
+        * @brief Process a received EAP message.
+        *
+        * A eap_payload is created in "out" if result is NEED_MORE.
+        *
+        * @param this          calling object
+        * @param in            eap_payload response received
+        * @param out           created eap_payload to send
+        * @return
+        *                                      - NEED_MORE, if an other exchange is required
+        *                                      - FAILED, if EAP method failed
+        *                                      - SUCCESS, if EAP method succeeded
+        */
+       status_t (*process) (eap_method_t *this, eap_payload_t *in,
+                                                eap_payload_t **out);
+       
+       /**
+        * @brief Get the EAP type implemented in this method.
+        *
+        * @param this          calling object
+        * @return               &