EAP-FAST: authenticated provisioning failure on Cisco ACS 5.4

Jouni Malinen j
Sun Apr 26 11:35:39 PDT 2015

On Fri, Apr 24, 2015 at 08:52:53AM +0000, Nakashima Akihiro wrote:
> I found that wpa_supplicant v2.4 cannot be authenticated with Cisco ACS
> Secure 5.4 using EAP-FAST, server authenticated provisioning.
> I confirmed older wpa_supplicant also have this issue (tested with v0.73).

Unfortunately I don't have ACS 5.4 in my test setup, so I have not been
able to verify this myself.

> The ACS say "12152 Rejected PAC provisioning request because supplicant
> failed to adhere to protocol".

That sounds like something new added to ACS since this used to work with
older versions..

> According to log of wpa_supplicant, EAP-FAST sequence between wpa_supplicant
> and ACS is below:
>       wpa_supplicant                         authenticator (ACS)

>                                         <--- Intermediate-Result (Success)
>                                              Crypto-Binding
>  Crypto-Binding                   --->
>  Intermediate-Result (Success)
>  PAC

> I confirmed RFC 4851 and section [4.2.8. Crypto-Binding TLV] describe below:
>    The Crypto-Binding TLV MUST be included with the Intermediate-Result
>    TLV to perform Cryptographic Binding after each successful EAP method
>    in a sequence of EAP methods.
> Therefore, I think wpa_suplicant should add Intermediate-Result TLV first,
> and add Crypto-Binding TLV and PAC TLV as additional TLVs of
> the Intermediate-Result TLV.

What is this specific order of TLVs based on? I did not find anything in
RFC 4851 describing a requirement of Intermediate-Result TLV being
before Crypto-Binding TLV in the message. Taken into account how those
TLVs are calculated, there is no difference in their payload regardless
of in which order they happen to be included.

> I modified src/eap_peer/eap_fast.c to add Intermediate-Result TLV first
> for trial, it worked well.

Did you test both anonymous and authenticated provisioning
(fast_provisioning=1 and fast_provisioning=2)? Would you be able to
share full debug log with and without this change in eap_fast.c?

> diff -uprN a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c
> @@ -1198,6 +1198,12 @@ static int eap_fast_process_decrypted(st

> +       if (tlv.iresult == EAP_TLV_RESULT_SUCCESS) {
> +               tmp = eap_fast_tlv_result(failed ? EAP_TLV_RESULT_FAILURE :
> +                                         EAP_TLV_RESULT_SUCCESS, 1);
> +               resp = wpabuf_concat(resp, tmp);
> +       }
> +
>         if (tlv.crypto_binding) {
>                 tmp = eap_fast_process_crypto_binding(sm, data, ret,
>                                                       tlv.crypto_binding,

This would break the design where the local failed variable is set to 1
only in case the eap_fast_process_crypto_binding() call returns an
error. In other words, this would result in the Intermediate-Result
reporting success regardless of whether the Crypto-Binding from the
server was accepted.

If changing the order of these two TLVs in the message makes this work
with ACS, that can obviously be done, but only with the result value
fixed to take into account possible failure in Crypto-Binding
processing. In any case, this does not really sound like a fix, but a
workaround for incorrect ACS behavior taken into account RFC 4851 does
not seem to describe any requirement for the order of TLVs and that
"12152 Rejected PAC provisioning request because supplicant
failed to adhere to protocol" does not seem to match the RFC if it is
indeed triggered only due to the Intermediate-Result TLV being after,
not before, Crypto-Binding TLV.

The change should look more like this:

diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c
index 68d7fba..392fc2d 100644
--- a/src/eap_peer/eap_fast.c
+++ b/src/eap_peer/eap_fast.c
@@ -1176,7 +1176,7 @@ static int eap_fast_process_decrypted(struct eap_sm *sm,
 				      struct wpabuf *decrypted,
 				      struct wpabuf **out_data)
-	struct wpabuf *resp = NULL, *tmp;
+	struct wpabuf *resp = NULL, *tmp, *binding = NULL;
 	struct eap_fast_tlv_parse tlv;
 	int failed = 0;
@@ -1199,13 +1199,11 @@ static int eap_fast_process_decrypted(struct eap_sm *sm,
 	if (tlv.crypto_binding) {
-		tmp = eap_fast_process_crypto_binding(sm, data, ret,
-						      tlv.crypto_binding,
-						      tlv.crypto_binding_len);
-		if (tmp == NULL)
+		binding = eap_fast_process_crypto_binding(
+			sm, data, ret, tlv.crypto_binding,
+			tlv.crypto_binding_len);
+		if (!binding)
 			failed = 1;
-		else
-			resp = wpabuf_concat(resp, tmp);
 	if (tlv.iresult == EAP_TLV_RESULT_SUCCESS) {
@@ -1214,6 +1212,9 @@ static int eap_fast_process_decrypted(struct eap_sm *sm,
 		resp = wpabuf_concat(resp, tmp);
+	if (binding)
+		resp = wpabuf_concat(resp, binding);
 	if (tlv.eap_payload_tlv) {
 		tmp = eap_fast_process_eap_payload_tlv(
 			sm, data, ret, tlv.eap_payload_tlv,

> On the other hand, it seems that hostapd's EAP-FAST sequence is also
> strange.
> The EAP-FAST sequence between wpa_supplicant and hostapd is below:

>      wpa_supplicant                         authenticator (hostapd)
>                                        <--- Result (Success)
>                                             Crypto-Binding
> Crypto-Binding                   --->
> Result (Success)

> Section [4.2.2. Result TLV] describe that Result TLV format cannot
> include
> additional TLV like Crypto-Binding TLV.

Where does it say that? I can only see it restricting other TLVs in case
of the Result TLV indicating failure which is not the case in this

> Therefore, I think hostapd should response with Intermediate-Result TLV.

3.3.1 says this: "In the case where only one EAP method is executed in
the tunnel, the Intermediate-Result TLV MUST NOT be sent with the Result

I'm not sure whether hostapd behavior here is because of that or if
there is something else explaining this. If you continue to think
something is wrong in the behavior, please share a more complete debug
log. There was not sufficient detail in this message to determine how
EAP-FAST was being used especially as far as use of anonymous vs.
authenticated provisioning is concerned.

Jouni Malinen                                            PGP id EFC895FA

More information about the Hostap mailing list