All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/2] peap: Extend EAP Extensions to handle multiple TLVs
@ 2019-12-12 20:10 Tim Kourt
  2019-12-12 20:10 ` [PATCH v2 2/2] peap: Add support for Crypto-Binding in PEAPv0 Tim Kourt
  2019-12-12 21:14 ` [PATCH v2 1/2] peap: Extend EAP Extensions to handle multiple TLVs Denis Kenzior
  0 siblings, 2 replies; 4+ messages in thread
From: Tim Kourt @ 2019-12-12 20:10 UTC (permalink / raw
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 5143 bytes --]

The handler for EAP Extensions has been modified to support multiple
TLV types instead of the single Result TLV. This will allow to handle
the other TLVs such as Crypto-Binding TLV.
---
 src/eap-peap.c | 125 ++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 88 insertions(+), 37 deletions(-)

diff --git a/src/eap-peap.c b/src/eap-peap.c
index ed18c667..8059e60b 100644
--- a/src/eap-peap.c
+++ b/src/eap-peap.c
@@ -111,6 +111,7 @@ static void eap_peap_phase2_complete(enum eap_result result, void *user_data)
  */
 #define EAP_EXTENSIONS_HEADER_LEN 5
 #define EAP_EXTENSIONS_TLV_HEADER_LEN 4
+#define EAP_EXTENSIONS_TLV_M_BIT_MASK 0x8000
 
 enum eap_extensions_tlv_type {
 	/* Reserved = 0x0000, */
@@ -127,39 +128,24 @@ enum eap_extensions_result {
 static int eap_extensions_handle_result_tlv(struct eap_state *eap,
 						const uint8_t *data,
 						size_t data_len,
-						uint8_t *response)
+						uint8_t *response,
+						uint8_t *result)
 {
+	static const uint8_t result_tlv_len = 2;
 	struct peap_state *peap_state;
-	uint16_t type;
-	uint16_t len;
-	uint16_t result;
 
-	if (data_len < EAP_EXTENSIONS_TLV_HEADER_LEN + 2)
-		return -ENOENT;
-
-	type = l_get_be16(data);
-
-	if (type != EAP_EXTENSIONS_TLV_TYPE_RESULT)
-		return -ENOENT;
-
-	data += 2;
-
-	len = l_get_be16(data);
-
-	if (len != 2)
-		return -ENOENT;
-
-	data += 2;
+	if (data_len != result_tlv_len)
+		return -EBADMSG;
 
-	result = l_get_be16(data);
+	*result = l_get_be16(data);
 
-	l_debug("result: %d", result);
+	l_debug("result: %d", *result);
 
-	switch (result) {
+	switch (*result) {
 	case EAP_EXTENSIONS_RESULT_SUCCCESS:
 		peap_state = eap_tls_common_get_variant_data(eap);
 
-		result = eap_method_is_success(peap_state->phase2) ?
+		*result = eap_method_is_success(peap_state->phase2) ?
 					EAP_EXTENSIONS_RESULT_SUCCCESS :
 					EAP_EXTENSIONS_RESULT_FAILURE;
 		/* fall through */
@@ -169,13 +155,68 @@ static int eap_extensions_handle_result_tlv(struct eap_state *eap,
 		return -ENOENT;
 	}
 
-	l_put_be16(EAP_EXTENSIONS_TLV_TYPE_RESULT,
-					&response[EAP_EXTENSIONS_HEADER_LEN]);
-	l_put_be16(2, &response[EAP_EXTENSIONS_HEADER_LEN + 2]);
-	l_put_be16(result, &response[EAP_EXTENSIONS_HEADER_LEN +
-						EAP_EXTENSIONS_TLV_HEADER_LEN]);
+	/* Build response Result TLV */
+
+	l_put_be16(EAP_EXTENSIONS_TLV_TYPE_RESULT, response);
+	response += 2;
+
+	l_put_be16(result_tlv_len, response);
+	response += 2;
+
+	l_put_be16(*result, response);
+
+	return EAP_EXTENSIONS_TLV_HEADER_LEN + result_tlv_len;
+}
+
+static int eap_extensions_process_tlvs(struct eap_state *eap,
+						const uint8_t *data,
+						size_t data_len,
+						uint8_t *response,
+						uint8_t *result)
+{
+	int response_len = 0;
+	uint16_t tlv_type;
+	uint16_t tlv_value_len;
+
+	while (data_len >= EAP_EXTENSIONS_TLV_HEADER_LEN) {
+		int response_tlv_len = 0;
+
+		tlv_type = l_get_be16(data);
+		data += 2;
+
+		tlv_value_len = l_get_be16(data);
+		data += 2;
+
+		data_len -= EAP_EXTENSIONS_TLV_HEADER_LEN;
+
+		if (data_len < tlv_value_len)
+			return -EBADMSG;
+
+		switch (tlv_type) {
+		case EAP_EXTENSIONS_TLV_TYPE_RESULT:
+			response_tlv_len = eap_extensions_handle_result_tlv(eap,
+						data, tlv_value_len, response,
+						result);
+
+			break;
+		default:
+			if (tlv_type & EAP_EXTENSIONS_TLV_M_BIT_MASK)
+				return -ENOENT;
+
+			break;
+		}
+
+		if (response_tlv_len < 0)
+			return response_tlv_len;
+
+		response += response_tlv_len;
+		response_len += response_tlv_len;
+
+		data += tlv_value_len;
+		data_len -= tlv_value_len;
+	}
 
-	return result;
+	return response_len;
 }
 
 static void eap_extensions_handle_request(struct eap_state *eap,
@@ -184,24 +225,34 @@ static void eap_extensions_handle_request(struct eap_state *eap,
 							size_t len)
 {
 	struct peap_state *peap_state;
-	uint8_t response[EAP_EXTENSIONS_HEADER_LEN +
-					EAP_EXTENSIONS_TLV_HEADER_LEN + 2];
-	int r = eap_extensions_handle_result_tlv(eap, pkt, len, response);
+	uint8_t result = EAP_EXTENSIONS_RESULT_FAILURE;
+	/*
+	 * The buffer size is chosen to satisfy the needs of the two supported
+	 * TLVs.
+	 */
+	uint8_t response[256];
+	int response_len;
 
-	if (r < 0)
+	response_len = eap_extensions_process_tlvs(eap, pkt, len,
+					&response[EAP_EXTENSIONS_HEADER_LEN],
+					&result);
+
+	if (response_len < 0)
 		return;
 
+	response_len += EAP_EXTENSIONS_HEADER_LEN;
+
 	response[0] = EAP_CODE_RESPONSE;
 	response[1] = id;
-	l_put_be16(sizeof(response), &response[2]);
+	l_put_be16(response_len, &response[2]);
 	response[4] = EAP_TYPE_EXTENSIONS;
 
-	eap_peap_phase2_send_response(response, sizeof(response), eap);
+	eap_peap_phase2_send_response(response, response_len, eap);
 
 	eap_discard_success_and_failure(eap, false);
 	eap_tls_common_set_completed(eap);
 
-	if (r != EAP_EXTENSIONS_RESULT_SUCCCESS) {
+	if (result != EAP_EXTENSIONS_RESULT_SUCCCESS) {
 		eap_tls_common_set_phase2_failed(eap);
 
 		eap_tls_common_tunnel_close(eap);
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/2] peap: Add support for Crypto-Binding in PEAPv0
  2019-12-12 20:10 [PATCH v2 1/2] peap: Extend EAP Extensions to handle multiple TLVs Tim Kourt
@ 2019-12-12 20:10 ` Tim Kourt
  2019-12-12 21:14   ` Denis Kenzior
  2019-12-12 21:14 ` [PATCH v2 1/2] peap: Extend EAP Extensions to handle multiple TLVs Denis Kenzior
  1 sibling, 1 reply; 4+ messages in thread
From: Tim Kourt @ 2019-12-12 20:10 UTC (permalink / raw
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 5950 bytes --]

The Crypto Binding TLV is used to ensure that the EAP peer and the
EAP server participated in both the inner and the outer EAP
authentications of a PEAP authentication by cryptographically associating
the phase 1 and phase 2 authentications.

The usage of Crypto-Binding in PEAPv0 is optional and is triggered by
the reception of the Crypto-Binding TLV from the server.
---
 src/eap-peap.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 169 insertions(+), 1 deletion(-)

diff --git a/src/eap-peap.c b/src/eap-peap.c
index 8059e60b..dd2438b8 100644
--- a/src/eap-peap.c
+++ b/src/eap-peap.c
@@ -29,6 +29,7 @@
 #include <errno.h>
 #include <ell/ell.h>
 
+#include "src/crypto.h"
 #include "src/missing.h"
 #include "src/eap.h"
 #include "src/eap-private.h"
@@ -117,9 +118,170 @@ enum eap_extensions_tlv_type {
 	/* Reserved = 0x0000, */
 	/* Reserved = 0x0001, */
 	/* Reserved = 0x0002, */
-	EAP_EXTENSIONS_TLV_TYPE_RESULT = 0x8003,
+	EAP_EXTENSIONS_TLV_TYPE_RESULT        = 0x8003,
+	EAP_EXTENSIONS_TLV_TYPE_CRYPTOBINDING = 0x000C,
 };
 
+enum TLV_CRYPTOBINDING_TYPE {
+	TLV_CRYPTOBINDING_TYPE_REQUEST =  0,
+	TLV_CRYPTOBINDING_TYPE_RESPONSE = 1,
+};
+
+static bool cryptobinding_tlv_generate_csk(struct eap_state *eap, uint8_t *imck)
+{
+	struct peap_state *peap_state = eap_tls_common_get_variant_data(eap);
+	static const char *label = "Session Key Generating Function";
+
+	if (!prf_plus_sha1(imck, 40, label, strlen(label), "\00", 1,
+				peap_state->key, sizeof(peap_state->key)))
+		return false;
+
+	return true;
+}
+
+static bool cryptobinding_tlv_generate_imck(struct eap_state *eap,
+							uint8_t *imck_out)
+{
+	struct peap_state *peap_state = eap_tls_common_get_variant_data(eap);
+	static const char *label = "Inner Methods Compound Keys";
+	uint8_t isk[32];
+
+	memset(isk, 0, sizeof(isk));
+
+	if (!prf_plus_sha1(peap_state->key, 40, label, strlen(label),
+					isk, sizeof(isk), imck_out, 60))
+		return false;
+
+	return true;
+}
+
+static int eap_extensions_handle_cryptobinding_tlv(struct eap_state *eap,
+							const uint8_t *data,
+							uint16_t tlv_value_len,
+							uint8_t *response)
+{
+	static const uint8_t cryptobinding_val_len = 56;
+	static const uint8_t cryptobinding_compound_mac_len = 20;
+	static const uint8_t cryptobinding_nonce_len = 32;
+	const uint8_t *nonce;
+	const uint8_t *server_compound_mac;
+	uint8_t client_compound_mac[cryptobinding_compound_mac_len];
+	const uint8_t *cryptobinding_tlv_value;
+	uint8_t buf[61];
+	uint8_t imck[60];
+
+	if (tlv_value_len != cryptobinding_val_len)
+		return -ENOENT;
+
+	cryptobinding_tlv_value = data;
+
+	/* Reserved byte: must be ignored on receipt. */
+	data += 1;
+
+	/* Version byte: must be set to 0. */
+	if (*data)
+		return -ENOENT;
+
+	data += 1;
+
+	/* RecvVersion byte: must be set to 0. */
+	if (*data)
+		return -ENOENT;
+
+	data += 1;
+
+	/* SubType byte: cryptobinding TLV request. */
+	if (*data != TLV_CRYPTOBINDING_TYPE_REQUEST)
+		return -ENOENT;
+
+	data += 1;
+
+	nonce = data;
+	data += cryptobinding_nonce_len;
+
+	server_compound_mac = data;
+
+	l_put_be16(EAP_EXTENSIONS_TLV_TYPE_CRYPTOBINDING, &buf[0]);
+	l_put_be16(tlv_value_len, &buf[2]);
+	memcpy(&buf[4], cryptobinding_tlv_value,
+					4 + cryptobinding_nonce_len);
+	memset(&buf[EAP_EXTENSIONS_TLV_HEADER_LEN + 4 +
+						cryptobinding_nonce_len],
+					0, cryptobinding_compound_mac_len);
+	buf[60] = EAP_TYPE_PEAP;
+
+	if (!cryptobinding_tlv_generate_imck(eap, imck)) {
+		l_error("PEAP: Failed to generate IMCK to validate "
+						"server compound MAC.");
+
+		return -ENOENT;
+	}
+
+	if (!hmac_sha1(imck + 40, 20, buf, sizeof(buf), client_compound_mac,
+					cryptobinding_compound_mac_len)) {
+		l_error("PEAP: Failed to generate compound MAC to validate "
+						"server compound MAC.");
+
+		return -ENOENT;
+	}
+
+	if (memcmp(server_compound_mac, client_compound_mac,
+					cryptobinding_compound_mac_len)) {
+		l_error("PEAP: Generated compound MAC and server compound MAC "
+							"don't match.");
+
+		return -ENOENT;
+	}
+
+	/* Build response Crypto-Binding TLV */
+	data = response;
+
+	l_put_be16(EAP_EXTENSIONS_TLV_TYPE_CRYPTOBINDING, response);
+	response += 2;
+
+	l_put_be16(cryptobinding_val_len, response);
+	response += 2;
+
+	/* Reserved - must be set to 0. */
+	l_put_u8(0, response);
+	response += 1;
+
+	/* Version */
+	l_put_u8(EAP_TLS_VERSION_0, response);
+	response += 1;
+
+	/* Received Version */
+	l_put_u8(EAP_TLS_VERSION_0, response);
+	response += 1;
+
+	/* Sub-Type */
+	l_put_u8(TLV_CRYPTOBINDING_TYPE_RESPONSE, response);
+	response += 1;
+
+	memcpy(response, nonce, cryptobinding_nonce_len);
+	response += cryptobinding_nonce_len;
+
+	memcpy(buf, data, EAP_EXTENSIONS_TLV_HEADER_LEN + 4 +
+						cryptobinding_nonce_len);
+
+	if (!hmac_sha1(imck + 40, 20, buf, sizeof(buf), client_compound_mac,
+					cryptobinding_compound_mac_len)) {
+		l_error("PEAP: Failed to generate client compound MAC.");
+
+		return -ENOENT;
+	}
+
+	memcpy(response, client_compound_mac, cryptobinding_compound_mac_len);
+
+	if (!cryptobinding_tlv_generate_csk(eap, imck)) {
+		l_error("PEAP: Failed to generate Compound Session Key.");
+
+		return -ENOENT;
+	}
+
+	return EAP_EXTENSIONS_TLV_HEADER_LEN + cryptobinding_val_len;
+}
+
 enum eap_extensions_result {
 	EAP_EXTENSIONS_RESULT_SUCCCESS = 1,
 	EAP_EXTENSIONS_RESULT_FAILURE  = 2,
@@ -199,6 +361,12 @@ static int eap_extensions_process_tlvs(struct eap_state *eap,
 						result);
 
 			break;
+		case EAP_EXTENSIONS_TLV_TYPE_CRYPTOBINDING:
+			response_tlv_len =
+				eap_extensions_handle_cryptobinding_tlv(eap,
+						data, tlv_value_len, response);
+
+			break;
 		default:
 			if (tlv_type & EAP_EXTENSIONS_TLV_M_BIT_MASK)
 				return -ENOENT;
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 1/2] peap: Extend EAP Extensions to handle multiple TLVs
  2019-12-12 20:10 [PATCH v2 1/2] peap: Extend EAP Extensions to handle multiple TLVs Tim Kourt
  2019-12-12 20:10 ` [PATCH v2 2/2] peap: Add support for Crypto-Binding in PEAPv0 Tim Kourt
@ 2019-12-12 21:14 ` Denis Kenzior
  1 sibling, 0 replies; 4+ messages in thread
From: Denis Kenzior @ 2019-12-12 21:14 UTC (permalink / raw
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 431 bytes --]

Hi Tim,

On 12/12/19 2:10 PM, Tim Kourt wrote:
> The handler for EAP Extensions has been modified to support multiple
> TLV types instead of the single Result TLV. This will allow to handle
> the other TLVs such as Crypto-Binding TLV.
> ---
>   src/eap-peap.c | 125 ++++++++++++++++++++++++++++++++++++++++-----------------
>   1 file changed, 88 insertions(+), 37 deletions(-)
> 

Applied, thanks.

Regards,
-Denis

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 2/2] peap: Add support for Crypto-Binding in PEAPv0
  2019-12-12 20:10 ` [PATCH v2 2/2] peap: Add support for Crypto-Binding in PEAPv0 Tim Kourt
@ 2019-12-12 21:14   ` Denis Kenzior
  0 siblings, 0 replies; 4+ messages in thread
From: Denis Kenzior @ 2019-12-12 21:14 UTC (permalink / raw
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 740 bytes --]

Hi Tim,

On 12/12/19 2:10 PM, Tim Kourt wrote:
> The Crypto Binding TLV is used to ensure that the EAP peer and the
> EAP server participated in both the inner and the outer EAP
> authentications of a PEAP authentication by cryptographically associating
> the phase 1 and phase 2 authentications.
> 
> The usage of Crypto-Binding in PEAPv0 is optional and is triggered by
> the reception of the Crypto-Binding TLV from the server.
> ---
>   src/eap-peap.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>   1 file changed, 169 insertions(+), 1 deletion(-)
> 

I changed the -ENOENTs to -EBADMSG/-EIO since those make a bit more 
sense in the context of the handler.

Applied, thanks.

Regards,
-Denis

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-12-12 21:14 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-12-12 20:10 [PATCH v2 1/2] peap: Extend EAP Extensions to handle multiple TLVs Tim Kourt
2019-12-12 20:10 ` [PATCH v2 2/2] peap: Add support for Crypto-Binding in PEAPv0 Tim Kourt
2019-12-12 21:14   ` Denis Kenzior
2019-12-12 21:14 ` [PATCH v2 1/2] peap: Extend EAP Extensions to handle multiple TLVs Denis Kenzior

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.