Update to new version 0.8.16 from BRCM

Sync with main tree commit b8349523e460493fa0b4de36c689595109e45e91
Author: Neeraj Kumar Garg <neerajkg@broadcom.com>
Date:   Tue Dec 27 23:21:45 2011 +0200
    P2P: Reject p2p_group_add if forced frequency is not acceptable

Change-Id: Icb4541a371b05c270e80440d7a7fdea7f33ff61e
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index ecfaf30..91fa4a9 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -147,6 +147,7 @@
 	sm->methodState = METHOD_NONE;
 	sm->allowNotifications = TRUE;
 	sm->decision = DECISION_FAIL;
+	sm->ClientTimeout = EAP_CLIENT_TIMEOUT_DEFAULT;
 	eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
 	eapol_set_bool(sm, EAPOL_eapSuccess, FALSE);
 	eapol_set_bool(sm, EAPOL_eapFail, FALSE);
@@ -1242,6 +1243,7 @@
 #endif /* CONFIG_FIPS */
 	tlsconf.event_cb = eap_peer_sm_tls_event;
 	tlsconf.cb_ctx = sm;
+	tlsconf.cert_in_cb = conf->cert_in_cb;
 	sm->ssl_ctx = tls_init(&tlsconf);
 	if (sm->ssl_ctx == NULL) {
 		wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS "
@@ -1466,16 +1468,11 @@
 
 
 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
-typedef enum {
-	TYPE_IDENTITY, TYPE_PASSWORD, TYPE_OTP, TYPE_PIN, TYPE_NEW_PASSWORD,
-	TYPE_PASSPHRASE
-} eap_ctrl_req_type;
-
-static void eap_sm_request(struct eap_sm *sm, eap_ctrl_req_type type,
+static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field,
 			   const char *msg, size_t msglen)
 {
 	struct eap_peer_config *config;
-	char *field, *txt, *tmp;
+	char *txt = NULL, *tmp;
 
 	if (sm == NULL)
 		return;
@@ -1483,29 +1480,20 @@
 	if (config == NULL)
 		return;
 
-	switch (type) {
-	case TYPE_IDENTITY:
-		field = "IDENTITY";
-		txt = "Identity";
+	switch (field) {
+	case WPA_CTRL_REQ_EAP_IDENTITY:
 		config->pending_req_identity++;
 		break;
-	case TYPE_PASSWORD:
-		field = "PASSWORD";
-		txt = "Password";
+	case WPA_CTRL_REQ_EAP_PASSWORD:
 		config->pending_req_password++;
 		break;
-	case TYPE_NEW_PASSWORD:
-		field = "NEW_PASSWORD";
-		txt = "New Password";
+	case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
 		config->pending_req_new_password++;
 		break;
-	case TYPE_PIN:
-		field = "PIN";
-		txt = "PIN";
+	case WPA_CTRL_REQ_EAP_PIN:
 		config->pending_req_pin++;
 		break;
-	case TYPE_OTP:
-		field = "OTP";
+	case WPA_CTRL_REQ_EAP_OTP:
 		if (msg) {
 			tmp = os_malloc(msglen + 3);
 			if (tmp == NULL)
@@ -1524,9 +1512,7 @@
 			txt = config->pending_req_otp;
 		}
 		break;
-	case TYPE_PASSPHRASE:
-		field = "PASSPHRASE";
-		txt = "Private key passphrase";
+	case WPA_CTRL_REQ_EAP_PASSPHRASE:
 		config->pending_req_passphrase++;
 		break;
 	default:
@@ -1559,7 +1545,7 @@
  */
 void eap_sm_request_identity(struct eap_sm *sm)
 {
-	eap_sm_request(sm, TYPE_IDENTITY, NULL, 0);
+	eap_sm_request(sm, WPA_CTRL_REQ_EAP_IDENTITY, NULL, 0);
 }
 
 
@@ -1574,7 +1560,7 @@
  */
 void eap_sm_request_password(struct eap_sm *sm)
 {
-	eap_sm_request(sm, TYPE_PASSWORD, NULL, 0);
+	eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSWORD, NULL, 0);
 }
 
 
@@ -1589,7 +1575,7 @@
  */
 void eap_sm_request_new_password(struct eap_sm *sm)
 {
-	eap_sm_request(sm, TYPE_NEW_PASSWORD, NULL, 0);
+	eap_sm_request(sm, WPA_CTRL_REQ_EAP_NEW_PASSWORD, NULL, 0);
 }
 
 
@@ -1604,7 +1590,7 @@
  */
 void eap_sm_request_pin(struct eap_sm *sm)
 {
-	eap_sm_request(sm, TYPE_PIN, NULL, 0);
+	eap_sm_request(sm, WPA_CTRL_REQ_EAP_PIN, NULL, 0);
 }
 
 
@@ -1620,7 +1606,7 @@
  */
 void eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len)
 {
-	eap_sm_request(sm, TYPE_OTP, msg, msg_len);
+	eap_sm_request(sm, WPA_CTRL_REQ_EAP_OTP, msg, msg_len);
 }
 
 
@@ -1635,7 +1621,7 @@
  */
 void eap_sm_request_passphrase(struct eap_sm *sm)
 {
-	eap_sm_request(sm, TYPE_PASSPHRASE, NULL, 0);
+	eap_sm_request(sm, WPA_CTRL_REQ_EAP_PASSPHRASE, NULL, 0);
 }
 
 
diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
index 2a80d4e..f35197f 100644
--- a/src/eap_peer/eap.h
+++ b/src/eap_peer/eap.h
@@ -216,10 +216,10 @@
 	/**
 	 * eap_param_needed - Notify that EAP parameter is needed
 	 * @ctx: eapol_ctx from eap_peer_sm_init() call
-	 * @field: Field name (e.g., "IDENTITY")
+	 * @field: Field indicator (e.g., WPA_CTRL_REQ_EAP_IDENTITY)
 	 * @txt: User readable text describing the required parameter
 	 */
-	void (*eap_param_needed)(void *ctx, const char *field,
+	void (*eap_param_needed)(void *ctx, enum wpa_ctrl_req_type field,
 				 const char *txt);
 
 	/**
@@ -262,6 +262,11 @@
 	 * This is only used by EAP-WSC and can be left %NULL if not available.
 	 */
 	struct wps_context *wps;
+
+	/**
+	 * cert_in_cb - Include server certificates in callback
+	 */
+	int cert_in_cb;
 };
 
 struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index 182f01a..766764b 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -235,21 +235,20 @@
 
 static void eap_aka_clear_identities(struct eap_aka_data *data, int id)
 {
-	wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old%s%s%s",
-		   id & CLEAR_PSEUDONYM ? " pseudonym" : "",
-		   id & CLEAR_REAUTH_ID ? " reauth_id" : "",
-		   id & CLEAR_EAP_ID ? " eap_id" : "");
 	if (id & CLEAR_PSEUDONYM) {
+		wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old pseudonym");
 		os_free(data->pseudonym);
 		data->pseudonym = NULL;
 		data->pseudonym_len = 0;
 	}
 	if (id & CLEAR_REAUTH_ID) {
+		wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old reauth_id");
 		os_free(data->reauth_id);
 		data->reauth_id = NULL;
 		data->reauth_id_len = 0;
 	}
 	if (id & CLEAR_EAP_ID) {
+		wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old eap_id");
 		os_free(data->last_eap_identity);
 		data->last_eap_identity = NULL;
 		data->last_eap_identity_len = 0;
@@ -880,11 +879,11 @@
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
 
-	/* Old reauthentication and pseudonym identities must not be used
-	 * anymore. In other words, if no new identities are received, full
-	 * authentication will be used on next reauthentication. */
-	eap_aka_clear_identities(data, CLEAR_PSEUDONYM | CLEAR_REAUTH_ID |
-				 CLEAR_EAP_ID);
+	/* Old reauthentication identity must not be used anymore. In
+	 * other words, if no new identities are received, full
+	 * authentication will be used on next reauthentication (using
+	 * pseudonym identity or permanent identity). */
+	eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
 
 	if (attr->encr_data) {
 		u8 *decrypted;
diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c
index 5d3e69d..3cfb41a 100644
--- a/src/eap_peer/eap_fast.c
+++ b/src/eap_peer/eap_fast.c
@@ -444,8 +444,9 @@
 		return 0;
 	}
 
-	if (data->phase2_priv == NULL &&
-	    eap_fast_init_phase2_method(sm, data) < 0) {
+	if ((data->phase2_priv == NULL &&
+	     eap_fast_init_phase2_method(sm, data) < 0) ||
+	    data->phase2_method == NULL) {
 		wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize "
 			   "Phase 2 EAP method %d", *pos);
 		ret->methodState = METHOD_DONE;
@@ -542,7 +543,7 @@
 
 static struct wpabuf * eap_fast_process_eap_payload_tlv(
 	struct eap_sm *sm, struct eap_fast_data *data,
-	struct eap_method_ret *ret, const struct eap_hdr *req,
+	struct eap_method_ret *ret,
 	u8 *eap_payload_tlv, size_t eap_payload_tlv_len)
 {
 	struct eap_hdr *hdr;
@@ -1037,11 +1038,15 @@
 	} else {
 		/*
 		 * This is PAC refreshing, i.e., normal authentication that is
-		 * expected to be completed with an EAP-Success.
+		 * expected to be completed with an EAP-Success. However,
+		 * RFC 5422, Section 3.5 allows EAP-Failure to be sent even
+		 * after protected success exchange in case of EAP-Fast
+		 * provisioning, so we better use DECISION_COND_SUCC here
+		 * instead of DECISION_UNCOND_SUCC.
 		 */
 		wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV "
 			   "- PAC refreshing completed successfully");
-		ret->decision = DECISION_UNCOND_SUCC;
+		ret->decision = DECISION_COND_SUCC;
 	}
 	ret->methodState = METHOD_DONE;
 	return eap_fast_tlv_pac_ack();
@@ -1184,7 +1189,7 @@
 
 	if (tlv.eap_payload_tlv) {
 		tmp = eap_fast_process_eap_payload_tlv(
-			sm, data, ret, req, tlv.eap_payload_tlv,
+			sm, data, ret, tlv.eap_payload_tlv,
 			tlv.eap_payload_tlv_len);
 		resp = wpabuf_concat(resp, tmp);
 	}
diff --git a/src/eap_peer/eap_methods.c b/src/eap_peer/eap_methods.c
index 3b0af05..937fd45 100644
--- a/src/eap_peer/eap_methods.c
+++ b/src/eap_peer/eap_methods.c
@@ -77,6 +77,8 @@
 const char * eap_get_name(int vendor, EapType type)
 {
 	struct eap_method *m;
+	if (vendor == EAP_VENDOR_IETF && type == EAP_TYPE_EXPANDED)
+		return "expanded";
 	for (m = eap_methods; m; m = m->next) {
 		if (m->vendor == vendor && m->method == type)
 			return m->name;
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
index 2b72084..7cb8213 100644
--- a/src/eap_peer/eap_peap.c
+++ b/src/eap_peer/eap_peap.c
@@ -196,7 +196,7 @@
  * @nak_type: TLV type (EAP_TLV_*)
  * Returns: Buffer to the allocated EAP-TLV NAK message or %NULL on failure
  *
- * This funtion builds an EAP-TLV NAK message. The caller is responsible for
+ * This function builds an EAP-TLV NAK message. The caller is responsible for
  * freeing the returned buffer.
  */
 static struct wpabuf * eap_tlv_build_nak(int id, u16 nak_type)
@@ -285,8 +285,10 @@
 	 * in the end of the label just before ISK; is that just a typo?)
 	 */
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TempKey", tk, 40);
-	peap_prfplus(data->peap_version, tk, 40, "Inner Methods Compound Keys",
-		     isk, sizeof(isk), imck, sizeof(imck));
+	if (peap_prfplus(data->peap_version, tk, 40,
+			 "Inner Methods Compound Keys",
+			 isk, sizeof(isk), imck, sizeof(imck)) < 0)
+		return -1;
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IMCK (IPMKj)",
 			imck, sizeof(imck));
 
@@ -346,8 +348,8 @@
  * @status: Status (EAP_TLV_RESULT_SUCCESS or EAP_TLV_RESULT_FAILURE)
  * Returns: Buffer to the allocated EAP-TLV Result message or %NULL on failure
  *
- * This funtion builds an EAP-TLV Result message. The caller is responsible for
- * freeing the returned buffer.
+ * This function builds an EAP-TLV Result message. The caller is responsible
+ * for freeing the returned buffer.
  */
 static struct wpabuf * eap_tlv_build_result(struct eap_sm *sm,
 					    struct eap_peap_data *data,
@@ -1247,9 +1249,12 @@
 		 * termination for this label while the one used for deriving
 		 * IPMK|CMK did not use null termination.
 		 */
-		peap_prfplus(data->peap_version, data->ipmk, 40,
-			     "Session Key Generating Function",
-			     (u8 *) "\00", 1, csk, sizeof(csk));
+		if (peap_prfplus(data->peap_version, data->ipmk, 40,
+				 "Session Key Generating Function",
+				 (u8 *) "\00", 1, csk, sizeof(csk)) < 0) {
+			os_free(key);
+			return NULL;
+		}
 		wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CSK", csk, sizeof(csk));
 		os_memcpy(key, csk, EAP_TLS_KEY_LEN);
 		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived key",
diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c
index e4705b7..1957c82 100644
--- a/src/eap_peer/eap_pwd.c
+++ b/src/eap_peer/eap_pwd.c
@@ -423,8 +423,7 @@
 	BN_bn2bin(y, element + BN_num_bytes(data->grp->prime) + offset);
 
 	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD,
-			     sizeof(struct eap_pwd_hdr) +
-			     BN_num_bytes(data->grp->order) +
+			     1 + BN_num_bytes(data->grp->order) +
 			     (2 * BN_num_bytes(data->grp->prime)),
 			     EAP_CODE_RESPONSE, eap_get_id(reqData));
 	if (resp == NULL)
@@ -465,6 +464,7 @@
 	u32 cs;
 	u16 grp;
 	u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr;
+	int offset;
 
 	/*
 	 * first build up the ciphersuite which is group | random_function |
@@ -497,7 +497,8 @@
 	 * value may start with a few zeros and the previous one did not.
 	 */
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(data->k, cruft);
+	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k);
+	BN_bn2bin(data->k, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
 
 	/* server element: x, y */
@@ -509,15 +510,19 @@
 		goto fin;
 	}
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(x, cruft);
+	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
+	BN_bn2bin(x, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(y, cruft);
+	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
+	BN_bn2bin(y, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
 
 	/* server scalar */
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(data->server_scalar, cruft);
+	offset = BN_num_bytes(data->grp->order) -
+		BN_num_bytes(data->server_scalar);
+	BN_bn2bin(data->server_scalar, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
 
 	/* my element: x, y */
@@ -530,15 +535,19 @@
 	}
 
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(x, cruft);
+	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
+	BN_bn2bin(x, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(y, cruft);
+	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
+	BN_bn2bin(y, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
 
 	/* my scalar */
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(data->my_scalar, cruft);
+	offset = BN_num_bytes(data->grp->order) -
+		BN_num_bytes(data->my_scalar);
+	BN_bn2bin(data->my_scalar, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
 
 	/* the ciphersuite */
@@ -564,7 +573,8 @@
 
 	/* k */
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(data->k, cruft);
+	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k);
+	BN_bn2bin(data->k, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
 
 	/* my element */
@@ -576,15 +586,19 @@
 		goto fin;
 	}
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(x, cruft);
+	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
+	BN_bn2bin(x, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(y, cruft);
+	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
+	BN_bn2bin(y, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
 
 	/* my scalar */
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(data->my_scalar, cruft);
+	offset = BN_num_bytes(data->grp->order) -
+		BN_num_bytes(data->my_scalar);
+	BN_bn2bin(data->my_scalar, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
 
 	/* server element: x, y */
@@ -596,15 +610,19 @@
 		goto fin;
 	}
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(x, cruft);
+	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
+	BN_bn2bin(x, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(y, cruft);
+	offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
+	BN_bn2bin(y, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
 
 	/* server scalar */
 	os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-	BN_bn2bin(data->server_scalar, cruft);
+	offset = BN_num_bytes(data->grp->order) -
+		BN_num_bytes(data->server_scalar);
+	BN_bn2bin(data->server_scalar, cruft + offset);
 	H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
 
 	/* the ciphersuite */
@@ -614,7 +632,7 @@
 	H_Final(&ctx, conf);
 
 	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD,
-			     sizeof(struct eap_pwd_hdr) + SHA256_DIGEST_LENGTH,
+			     1 + SHA256_DIGEST_LENGTH,
 			     EAP_CODE_RESPONSE, eap_get_id(reqData));
 	if (resp == NULL)
 		goto fin;
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index 6677063..06fbc5b 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -266,21 +266,20 @@
 
 static void eap_sim_clear_identities(struct eap_sim_data *data, int id)
 {
-	wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old%s%s%s",
-		   id & CLEAR_PSEUDONYM ? " pseudonym" : "",
-		   id & CLEAR_REAUTH_ID ? " reauth_id" : "",
-		   id & CLEAR_EAP_ID ? " eap_id" : "");
-	if (id & CLEAR_PSEUDONYM) {
+	if ((id & CLEAR_PSEUDONYM) && data->pseudonym) {
+		wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old pseudonym");
 		os_free(data->pseudonym);
 		data->pseudonym = NULL;
 		data->pseudonym_len = 0;
 	}
-	if (id & CLEAR_REAUTH_ID) {
+	if ((id & CLEAR_REAUTH_ID) && data->reauth_id) {
+		wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old reauth_id");
 		os_free(data->reauth_id);
 		data->reauth_id = NULL;
 		data->reauth_id_len = 0;
 	}
-	if (id & CLEAR_EAP_ID) {
+	if ((id & CLEAR_EAP_ID) && data->last_eap_identity) {
+		wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old eap_id");
 		os_free(data->last_eap_identity);
 		data->last_eap_identity = NULL;
 		data->last_eap_identity_len = 0;
@@ -649,11 +648,11 @@
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 
-	/* Old reauthentication and pseudonym identities must not be used
-	 * anymore. In other words, if no new identities are received, full
-	 * authentication will be used on next reauthentication. */
-	eap_sim_clear_identities(data, CLEAR_PSEUDONYM | CLEAR_REAUTH_ID |
-				 CLEAR_EAP_ID);
+	/* Old reauthentication identity must not be used anymore. In
+	 * other words, if no new reauth identity is received, full
+	 * authentication will be used on next reauthentication (using
+	 * pseudonym identity or permanent identity). */
+	eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
 
 	if (attr->encr_data) {
 		u8 *decrypted;
diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
index d1567e9..2934ba4 100644
--- a/src/eap_peer/eap_tls_common.c
+++ b/src/eap_peer/eap_tls_common.c
@@ -112,7 +112,6 @@
 		wpa_printf(MSG_DEBUG, "TLS: using phase1 config options");
 		eap_tls_params_from_conf1(params, config);
 	}
-	params->tls_ia = data->tls_ia;
 
 	/*
 	 * Use blob data, if available. Otherwise, leave reference to external
@@ -295,9 +294,9 @@
 	os_memcpy(rnd + keys.client_random_len, keys.server_random,
 		  keys.server_random_len);
 
-	if (tls_prf(keys.master_key, keys.master_key_len,
-		    label, rnd, keys.client_random_len +
-		    keys.server_random_len, out, len))
+	if (tls_prf_sha1_md5(keys.master_key, keys.master_key_len,
+			     label, rnd, keys.client_random_len +
+			     keys.server_random_len, out, len))
 		goto fail;
 
 	os_free(rnd);
diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h
index e9e0998..e9a07b8 100644
--- a/src/eap_peer/eap_tls_common.h
+++ b/src/eap_peer/eap_tls_common.h
@@ -66,11 +66,6 @@
 	int include_tls_length;
 
 	/**
-	 * tls_ia - Whether TLS/IA is enabled for this TLS connection
-	 */
-	int tls_ia;
-
-	/**
 	 * eap - EAP state machine allocated with eap_peer_sm_init()
 	 */
 	struct eap_sm *eap;
diff --git a/src/eap_peer/eap_tnc.c b/src/eap_peer/eap_tnc.c
index 6c95f72..da288eb 100644
--- a/src/eap_peer/eap_tnc.c
+++ b/src/eap_peer/eap_tnc.c
@@ -15,7 +15,6 @@
 #include "includes.h"
 
 #include "common.h"
-#include "base64.h"
 #include "eap_i.h"
 #include "tncc.h"
 
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
index e8f0f38..612dfa7 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -1,6 +1,6 @@
 /*
  * EAP peer method: EAP-TTLS (RFC 5281)
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -26,17 +26,7 @@
 #include "eap_config.h"
 
 
-/* Maximum supported TTLS version
- * 0 = RFC 5281
- * 1 = draft-funk-eap-ttls-v1-00.txt
- */
-#ifndef EAP_TTLS_VERSION
-#define EAP_TTLS_VERSION 0 /* TTLSv1 implementation is not yet complete */
-#endif /* EAP_TTLS_VERSION */
-
-
-#define MSCHAPV2_KEY_LEN 16
-#define MSCHAPV2_NT_RESPONSE_LEN 24
+#define EAP_TTLS_VERSION 0
 
 
 static void eap_ttls_deinit(struct eap_sm *sm, void *priv);
@@ -44,9 +34,8 @@
 
 struct eap_ttls_data {
 	struct eap_ssl_data ssl;
-	int ssl_initialized;
 
-	int ttls_version, force_ttls_version;
+	int ttls_version;
 
 	const struct eap_method *phase2_method;
 	void *phase2_priv;
@@ -91,22 +80,9 @@
 	if (data == NULL)
 		return NULL;
 	data->ttls_version = EAP_TTLS_VERSION;
-	data->force_ttls_version = -1;
 	selected = "EAP";
 	data->phase2_type = EAP_TTLS_PHASE2_EAP;
 
-#if EAP_TTLS_VERSION > 0
-	if (config && config->phase1) {
-		const char *pos = os_strstr(config->phase1, "ttlsver=");
-		if (pos) {
-			data->force_ttls_version = atoi(pos + 8);
-			data->ttls_version = data->force_ttls_version;
-			wpa_printf(MSG_DEBUG, "EAP-TTLS: Forced TTLS version "
-				   "%d", data->force_ttls_version);
-		}
-	}
-#endif /* EAP_TTLS_VERSION */
-
 	if (config && config->phase2) {
 		if (os_strstr(config->phase2, "autheap=")) {
 			selected = "EAP";
@@ -140,19 +116,11 @@
 		data->phase2_eap_type.method = EAP_TYPE_NONE;
 	}
 
-#if EAP_TTLS_VERSION > 0
-	if (!(tls_capabilities(sm->ssl_ctx) & TLS_CAPABILITY_IA) &&
-	    data->ttls_version > 0) {
-		if (data->force_ttls_version > 0) {
-			wpa_printf(MSG_INFO, "EAP-TTLS: Forced TTLSv%d and "
-				   "TLS library does not support TLS/IA.",
-				   data->force_ttls_version);
-			eap_ttls_deinit(sm, data);
-			return NULL;
-		}
-		data->ttls_version = 0;
+	if (eap_peer_tls_ssl_init(sm, &data->ssl, config)) {
+		wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
+		eap_ttls_deinit(sm, data);
+		return NULL;
 	}
-#endif /* EAP_TTLS_VERSION */
 
 	return data;
 }
@@ -176,8 +144,7 @@
 		return;
 	eap_ttls_phase2_eap_deinit(sm, data);
 	os_free(data->phase2_eap_types);
-	if (data->ssl_initialized)
-		eap_peer_tls_ssl_deinit(sm, &data->ssl);
+	eap_peer_tls_ssl_deinit(sm, &data->ssl);
 	os_free(data->key_data);
 	wpabuf_free(data->pending_phase2_req);
 	os_free(data);
@@ -246,39 +213,6 @@
 }
 
 
-#if EAP_TTLS_VERSION > 0
-static int eap_ttls_ia_permute_inner_secret(struct eap_sm *sm,
-					    struct eap_ttls_data *data,
-					    const u8 *key, size_t key_len)
-{
-	u8 *buf;
-	size_t buf_len;
-	int ret;
-
-	if (key) {
-		buf_len = 2 + key_len;
-		buf = os_malloc(buf_len);
-		if (buf == NULL)
-			return -1;
-		WPA_PUT_BE16(buf, key_len);
-		os_memcpy(buf + 2, key, key_len);
-	} else {
-		buf = NULL;
-		buf_len = 0;
-	}
-
-	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Session keys for TLS/IA inner "
-			"secret permutation", buf, buf_len);
-	ret = tls_connection_ia_permute_inner_secret(sm->ssl_ctx,
-						     data->ssl.conn,
-						     buf, buf_len);
-	os_free(buf);
-
-	return ret;
-}
-#endif /* EAP_TTLS_VERSION */
-
-
 static int eap_ttls_v0_derive_key(struct eap_sm *sm,
 				  struct eap_ttls_data *data)
 {
@@ -298,156 +232,10 @@
 }
 
 
-#if EAP_TTLS_VERSION > 0
-static int eap_ttls_v1_derive_key(struct eap_sm *sm,
-				  struct eap_ttls_data *data)
-{
-	struct tls_keys keys;
-	u8 *rnd;
-
-	os_free(data->key_data);
-	data->key_data = NULL;
-
-	os_memset(&keys, 0, sizeof(keys));
-	if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
-	    keys.client_random == NULL || keys.server_random == NULL ||
-	    keys.inner_secret == NULL) {
-		wpa_printf(MSG_INFO, "EAP-TTLS: Could not get inner secret, "
-			   "client random, or server random to derive keying "
-			   "material");
-		return -1;
-	}
-
-	rnd = os_malloc(keys.client_random_len + keys.server_random_len);
-	data->key_data = os_malloc(EAP_TLS_KEY_LEN);
-	if (rnd == NULL || data->key_data == NULL) {
-		wpa_printf(MSG_INFO, "EAP-TTLS: No memory for key derivation");
-		os_free(rnd);
-		os_free(data->key_data);
-		data->key_data = NULL;
-		return -1;
-	}
-	os_memcpy(rnd, keys.client_random, keys.client_random_len);
-	os_memcpy(rnd + keys.client_random_len, keys.server_random,
-		  keys.server_random_len);
-
-	if (tls_prf(keys.inner_secret, keys.inner_secret_len,
-		    "ttls v1 keying material", rnd, keys.client_random_len +
-		    keys.server_random_len, data->key_data, EAP_TLS_KEY_LEN)) {
-		wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
-		os_free(rnd);
-		os_free(data->key_data);
-		data->key_data = NULL;
-		return -1;
-	}
-
-	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: client/server random",
-		    rnd, keys.client_random_len + keys.server_random_len);
-	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: TLS/IA inner secret",
-			keys.inner_secret, keys.inner_secret_len);
-
-	os_free(rnd);
-
-	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
-			data->key_data, EAP_TLS_KEY_LEN);
-
-	return 0;
-}
-#endif /* EAP_TTLS_VERSION */
-
-
 static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
 					struct eap_ttls_data *data, size_t len)
 {
-#if EAP_TTLS_VERSION > 0
-	struct tls_keys keys;
-	u8 *challenge, *rnd;
-#endif /* EAP_TTLS_VERSION */
-
-	if (data->ttls_version == 0) {
-		return eap_peer_tls_derive_key(sm, &data->ssl,
-					       "ttls challenge", len);
-	}
-
-#if EAP_TTLS_VERSION > 0
-
-	os_memset(&keys, 0, sizeof(keys));
-	if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
-	    keys.client_random == NULL || keys.server_random == NULL ||
-	    keys.inner_secret == NULL) {
-		wpa_printf(MSG_INFO, "EAP-TTLS: Could not get inner secret, "
-			   "client random, or server random to derive "
-			   "implicit challenge");
-		return NULL;
-	}
-
-	rnd = os_malloc(keys.client_random_len + keys.server_random_len);
-	challenge = os_malloc(len);
-	if (rnd == NULL || challenge == NULL) {
-		wpa_printf(MSG_INFO, "EAP-TTLS: No memory for implicit "
-			   "challenge derivation");
-		os_free(rnd);
-		os_free(challenge);
-		return NULL;
-	}
-	os_memcpy(rnd, keys.server_random, keys.server_random_len);
-	os_memcpy(rnd + keys.server_random_len, keys.client_random,
-		  keys.client_random_len);
-
-	if (tls_prf(keys.inner_secret, keys.inner_secret_len,
-		    "inner application challenge", rnd,
-		    keys.client_random_len + keys.server_random_len,
-		    challenge, len)) {
-		wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive implicit "
-			   "challenge");
-		os_free(rnd);
-		os_free(challenge);
-		return NULL;
-	}
-
-	os_free(rnd);
-
-	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived implicit challenge",
-			challenge, len);
-
-	return challenge;
-
-#else /* EAP_TTLS_VERSION */
-
-	return NULL;
-
-#endif /* EAP_TTLS_VERSION */
-}
-
-
-static void eap_ttlsv1_phase2_eap_finish(struct eap_sm *sm,
-					 struct eap_ttls_data *data,
-					 struct eap_method_ret *ret)
-{
-#if EAP_TTLS_VERSION > 0
-	if (data->ttls_version > 0) {
-		const struct eap_method *m = data->phase2_method;
-		void *priv = data->phase2_priv;
-
-		/* TTLSv1 requires TLS/IA FinalPhaseFinished */
-		if (ret->decision == DECISION_UNCOND_SUCC)
-			ret->decision = DECISION_COND_SUCC;
-		ret->methodState = METHOD_CONT;
-
-		if (ret->decision == DECISION_COND_SUCC &&
-		    m->isKeyAvailable && m->getKey &&
-		    m->isKeyAvailable(sm, priv)) {
-			u8 *key;
-			size_t key_len;
-			key = m->getKey(sm, priv, &key_len);
-			if (key) {
-				eap_ttls_ia_permute_inner_secret(
-					sm, data, key, key_len);
-				os_free(key);
-			}
-		}
-	}
-#endif /* EAP_TTLS_VERSION */
+	return eap_peer_tls_derive_key(sm, &data->ssl, "ttls challenge", len);
 }
 
 
@@ -494,7 +282,6 @@
 		ret->methodState = iret.methodState;
 		ret->decision = iret.decision;
 	}
-	eap_ttlsv1_phase2_eap_finish(sm, data, ret);
 
 	return 0;
 }
@@ -615,26 +402,6 @@
 }
 
 
-static void eap_ttlsv1_permute_inner(struct eap_sm *sm,
-				     struct eap_ttls_data *data)
-{
-#if EAP_TTLS_VERSION > 0
-	u8 session_key[2 * MSCHAPV2_KEY_LEN];
-
-	if (data->ttls_version == 0)
-		return;
-
-	get_asymetric_start_key(data->master_key, session_key,
-				MSCHAPV2_KEY_LEN, 0, 0);
-	get_asymetric_start_key(data->master_key,
-				session_key + MSCHAPV2_KEY_LEN,
-				MSCHAPV2_KEY_LEN, 1, 0);
-	eap_ttls_ia_permute_inner_secret(sm, data, session_key,
-					 sizeof(session_key));
-#endif /* EAP_TTLS_VERSION */
-}
-
-
 static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
 					    struct eap_ttls_data *data,
 					    struct eap_method_ret *ret,
@@ -702,8 +469,6 @@
 	}
 	data->auth_response_valid = 1;
 
-	eap_ttlsv1_permute_inner(sm, data);
-
 	pos += 24;
 	os_free(challenge);
 	AVP_PAD(buf, pos);
@@ -711,7 +476,7 @@
 	wpabuf_put(msg, pos - buf);
 	*resp = msg;
 
-	if (sm->workaround && data->ttls_version == 0) {
+	if (sm->workaround) {
 		/* At least FreeRADIUS seems to be terminating
 		 * EAP-TTLS/MSHCAPV2 without the expected MS-CHAP-v2 Success
 		 * packet. */
@@ -798,17 +563,10 @@
 	wpabuf_put(msg, pos - buf);
 	*resp = msg;
 
-	if (data->ttls_version > 0) {
-		/* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success,
-		 * so do not allow connection to be terminated yet. */
-		ret->methodState = METHOD_CONT;
-		ret->decision = DECISION_COND_SUCC;
-	} else {
-		/* EAP-TTLS/MSCHAP does not provide tunneled success
-		 * notification, so assume that Phase2 succeeds. */
-		ret->methodState = METHOD_DONE;
-		ret->decision = DECISION_COND_SUCC;
-	}
+	/* EAP-TTLS/MSCHAP does not provide tunneled success
+	 * notification, so assume that Phase2 succeeds. */
+	ret->methodState = METHOD_DONE;
+	ret->decision = DECISION_COND_SUCC;
 
 	return 0;
 }
@@ -859,17 +617,10 @@
 	wpabuf_put(msg, pos - buf);
 	*resp = msg;
 
-	if (data->ttls_version > 0) {
-		/* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success,
-		 * so do not allow connection to be terminated yet. */
-		ret->methodState = METHOD_CONT;
-		ret->decision = DECISION_COND_SUCC;
-	} else {
-		/* EAP-TTLS/PAP does not provide tunneled success notification,
-		 * so assume that Phase2 succeeds. */
-		ret->methodState = METHOD_DONE;
-		ret->decision = DECISION_COND_SUCC;
-	}
+	/* EAP-TTLS/PAP does not provide tunneled success notification,
+	 * so assume that Phase2 succeeds. */
+	ret->methodState = METHOD_DONE;
+	ret->decision = DECISION_COND_SUCC;
 
 	return 0;
 }
@@ -942,17 +693,10 @@
 	wpabuf_put(msg, pos - buf);
 	*resp = msg;
 
-	if (data->ttls_version > 0) {
-		/* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success,
-		 * so do not allow connection to be terminated yet. */
-		ret->methodState = METHOD_CONT;
-		ret->decision = DECISION_COND_SUCC;
-	} else {
-		/* EAP-TTLS/CHAP does not provide tunneled success
-		 * notification, so assume that Phase2 succeeds. */
-		ret->methodState = METHOD_DONE;
-		ret->decision = DECISION_COND_SUCC;
-	}
+	/* EAP-TTLS/CHAP does not provide tunneled success
+	 * notification, so assume that Phase2 succeeds. */
+	ret->methodState = METHOD_DONE;
+	ret->decision = DECISION_COND_SUCC;
 
 	return 0;
 }
@@ -1027,36 +771,6 @@
 }
 
 
-#if EAP_TTLS_VERSION > 0
-static struct wpabuf * eap_ttls_build_phase_finished(
-	struct eap_sm *sm, struct eap_ttls_data *data, int id, int final)
-{
-	struct wpabuf *req, *buf;
-
-	buf = tls_connection_ia_send_phase_finished(sm->ssl_ctx,
-						    data->ssl.conn,
-						    final);
-	if (buf == NULL)
-		return NULL;
-
-	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS,
-			    1 + wpabuf_len(buf),
-			    EAP_CODE_RESPONSE, id);
-	if (req == NULL) {
-		wpabuf_free(buf);
-		return NULL;
-	}
-
-	wpabuf_put_u8(req, data->ttls_version);
-	wpabuf_put_buf(req, buf);
-	wpabuf_free(buf);
-	eap_update_len(req);
-
-	return req;
-}
-#endif /* EAP_TTLS_VERSION */
-
-
 struct ttls_parse_avp {
 	u8 *mschapv2;
 	u8 *eapdata;
@@ -1366,19 +1080,9 @@
 
 	wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 MSCHAPV2 "
 		   "authentication succeeded");
-	if (data->ttls_version > 0) {
-		/*
-		 * EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report
-		 * success, so do not allow connection to be terminated
-		 * yet.
-		 */
-		ret->methodState = METHOD_CONT;
-		ret->decision = DECISION_COND_SUCC;
-	} else {
-		ret->methodState = METHOD_DONE;
-		ret->decision = DECISION_UNCOND_SUCC;
-		data->phase2_success = 1;
-	}
+	ret->methodState = METHOD_DONE;
+	ret->decision = DECISION_UNCOND_SUCC;
+	data->phase2_success = 1;
 
 	/*
 	 * Reply with empty data; authentication server will reply
@@ -1493,24 +1197,6 @@
 }
 
 
-#if EAP_TTLS_VERSION > 0
-static void eap_ttls_final_phase_finished(struct eap_sm *sm,
-					  struct eap_ttls_data *data,
-					  struct eap_method_ret *ret,
-					  u8 identifier,
-					  struct wpabuf **out_data)
-{
-	wpa_printf(MSG_DEBUG, "EAP-TTLS: FinalPhaseFinished received");
-	wpa_printf(MSG_INFO, "EAP-TTLS: TLS/IA authentication succeeded");
-	ret->methodState = METHOD_DONE;
-	ret->decision = DECISION_UNCOND_SUCC;
-	data->phase2_success = 1;
-	*out_data = eap_ttls_build_phase_finished(sm, data, identifier, 1);
-	eap_ttls_v1_derive_key(sm, data);
-}
-#endif /* EAP_TTLS_VERSION */
-
-
 static int eap_ttls_implicit_identity_request(struct eap_sm *sm,
 					      struct eap_ttls_data *data,
 					      struct eap_method_ret *ret,
@@ -1534,6 +1220,21 @@
 			   "processing failed");
 		retval = -1;
 	} else {
+		struct eap_peer_config *config = eap_get_config(sm);
+		if (resp == NULL &&
+		    (config->pending_req_identity ||
+		     config->pending_req_password ||
+		     config->pending_req_otp ||
+		     config->pending_req_new_password)) {
+			/*
+			 * Use empty buffer to force implicit request
+			 * processing when EAP request is re-processed after
+			 * user input.
+			 */
+			wpabuf_free(data->pending_phase2_req);
+			data->pending_phase2_req = wpabuf_alloc(0);
+		}
+
 		retval = eap_ttls_encrypt_response(sm, data, resp, identifier,
 						   out_data);
 	}
@@ -1627,17 +1328,6 @@
 	if (retval)
 		goto done;
 
-#if EAP_TTLS_VERSION > 0
-	if (data->ttls_version > 0 &&
-	    (in_decrypted == NULL || wpabuf_len(in_decrypted) == 0) &&
-	    tls_connection_ia_final_phase_finished(sm->ssl_ctx,
-						   data->ssl.conn)) {
-		eap_ttls_final_phase_finished(sm, data, ret, identifier,
-					      out_data);
-		goto done;
-	}
-#endif /* EAP_TTLS_VERSION */
-
 continue_req:
 	data->phase2_start = 0;
 
@@ -1662,46 +1352,6 @@
 }
 
 
-static int eap_ttls_process_start(struct eap_sm *sm,
-				  struct eap_ttls_data *data, u8 flags,
-				  struct eap_method_ret *ret)
-{
-	struct eap_peer_config *config = eap_get_config(sm);
-
-	wpa_printf(MSG_DEBUG, "EAP-TTLS: Start (server ver=%d, own ver=%d)",
-		   flags & EAP_TLS_VERSION_MASK, data->ttls_version);
-#if EAP_TTLS_VERSION > 0
-	if ((flags & EAP_TLS_VERSION_MASK) < data->ttls_version)
-		data->ttls_version = flags & EAP_TLS_VERSION_MASK;
-	if (data->force_ttls_version >= 0 &&
-	    data->force_ttls_version != data->ttls_version) {
-		wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to select "
-			   "forced TTLS version %d",
-			   data->force_ttls_version);
-		ret->methodState = METHOD_DONE;
-		ret->decision = DECISION_FAIL;
-		ret->allowNotifications = FALSE;
-		return -1;
-	}
-	wpa_printf(MSG_DEBUG, "EAP-TTLS: Using TTLS version %d",
-		   data->ttls_version);
-
-	if (data->ttls_version > 0)
-		data->ssl.tls_ia = 1;
-#endif /* EAP_TTLS_VERSION */
-	if (!data->ssl_initialized &&
-	    eap_peer_tls_ssl_init(sm, &data->ssl, config)) {
-		wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
-		return -1;
-	}
-	data->ssl_initialized = 1;
-
-	wpa_printf(MSG_DEBUG, "EAP-TTLS: Start");
-
-	return 0;
-}
-
-
 static int eap_ttls_process_handshake(struct eap_sm *sm,
 				      struct eap_ttls_data *data,
 				      struct eap_method_ret *ret,
@@ -1725,8 +1375,7 @@
 			ret->methodState = METHOD_MAY_CONT;
 		}
 		data->phase2_start = 1;
-		if (data->ttls_version == 0)
-			eap_ttls_v0_derive_key(sm, data);
+		eap_ttls_v0_derive_key(sm, data);
 
 		if (*out_data == NULL || wpabuf_len(*out_data) == 0) {
 			if (eap_ttls_decrypt(sm, data, ret, identifier,
@@ -1761,7 +1410,7 @@
 				       struct eap_ttls_data *data,
 				       struct eap_method_ret *ret)
 {
-	if (data->ttls_version == 0 && ret->methodState == METHOD_DONE) {
+	if (ret->methodState == METHOD_DONE) {
 		ret->allowNotifications = FALSE;
 		if (ret->decision == DECISION_UNCOND_SUCC ||
 		    ret->decision == DECISION_COND_SUCC) {
@@ -1779,8 +1428,7 @@
 			}
 #endif /* EAP_TNC */
 		}
-	} else if (data->ttls_version == 0 &&
-		   ret->methodState == METHOD_MAY_CONT &&
+	} else if (ret->methodState == METHOD_MAY_CONT &&
 		   (ret->decision == DECISION_UNCOND_SUCC ||
 		    ret->decision == DECISION_COND_SUCC)) {
 			wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "
@@ -1808,8 +1456,9 @@
 	id = eap_get_id(reqData);
 
 	if (flags & EAP_TLS_FLAGS_START) {
-		if (eap_ttls_process_start(sm, data, flags, ret) < 0)
-			return NULL;
+		wpa_printf(MSG_DEBUG, "EAP-TTLS: Start (server ver=%d, own "
+			   "ver=%d)", flags & EAP_TLS_VERSION_MASK,
+			   data->ttls_version);
 
 		/* RFC 5281, Ch. 9.2:
 		 * "This packet MAY contain additional information in the form
@@ -1817,13 +1466,6 @@
 		 * For now, ignore any potential extra data.
 		 */
 		left = 0;
-	} else if (!data->ssl_initialized) {
-		wpa_printf(MSG_DEBUG, "EAP-TTLS: First message did not "
-			   "include Start flag");
-		ret->methodState = METHOD_DONE;
-		ret->decision = DECISION_FAIL;
-		ret->allowNotifications = FALSE;
-		return NULL;
 	}
 
 	resp = NULL;
diff --git a/src/eap_peer/ikev2.c b/src/eap_peer/ikev2.c
index 1e169a0..acd7611 100644
--- a/src/eap_peer/ikev2.c
+++ b/src/eap_peer/ikev2.c
@@ -425,7 +425,7 @@
 	}
 
 	/* RFC 4306, Section 3.4:
-	 * The length of DH public value MUST be equal to the lenght of the
+	 * The length of DH public value MUST be equal to the length of the
 	 * prime modulus.
 	 */
 	if (kei_len - 4 != data->dh->prime_len) {