All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/6] peap: Introduce PEAP state
@ 2019-12-05 21:13 Tim Kourt
  2019-12-05 21:13 ` [PATCH 2/6] peap: Delay key installation until success of Phase 2 Tim Kourt
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Tim Kourt @ 2019-12-05 21:13 UTC (permalink / raw)
  To: iwd

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

Introduction of the state struct will allow to hold the additional
state variables related to the implementation of PEAP.
---
 src/eap-peap.c | 44 +++++++++++++++++++++++++++++++-------------
 1 file changed, 31 insertions(+), 13 deletions(-)

diff --git a/src/eap-peap.c b/src/eap-peap.c
index 16ab0319..c400ddee 100644
--- a/src/eap-peap.c
+++ b/src/eap-peap.c
@@ -41,6 +41,10 @@
  * PEAPv1: draft-josefsson-pppext-eap-tls-eap-05
  */
 
+struct peap_state {
+	struct eap_state *phase2;
+};
+
 static void eap_peap_phase2_send_response(const uint8_t *pdu, size_t pdu_len,
 								void *user_data)
 {
@@ -116,6 +120,7 @@ static int eap_extensions_handle_result_avp(struct eap_state *eap,
 						size_t data_len,
 						uint8_t *response)
 {
+	struct peap_state *peap_state;
 	uint16_t type;
 	uint16_t len;
 	uint16_t result;
@@ -143,8 +148,9 @@ static int eap_extensions_handle_result_avp(struct eap_state *eap,
 
 	switch (result) {
 	case EAP_EXTENSIONS_RESULT_SUCCCESS:
-		result = eap_method_is_success(
-				eap_tls_common_get_variant_data(eap)) ?
+		peap_state = eap_tls_common_get_variant_data(eap);
+
+		result = eap_method_is_success(peap_state->phase2) ?
 					EAP_EXTENSIONS_RESULT_SUCCCESS :
 					EAP_EXTENSIONS_RESULT_FAILURE;
 		/* fall through */
@@ -225,6 +231,7 @@ static bool eap_peap_tunnel_handle_request(struct eap_state *eap,
 							const uint8_t *pkt,
 								size_t len)
 {
+	struct peap_state *peap_state;
 	uint8_t id;
 
 	if (len > 4 && pkt[4] == EAP_TYPE_EXTENSIONS) {
@@ -247,6 +254,8 @@ static bool eap_peap_tunnel_handle_request(struct eap_state *eap,
 		return true;
 	}
 
+	peap_state = eap_tls_common_get_variant_data(eap);
+
 	if (eap_tls_common_get_negotiated_version(eap) == EAP_TLS_VERSION_0) {
 		if (len < 1)
 			return false;
@@ -259,32 +268,37 @@ static bool eap_peap_tunnel_handle_request(struct eap_state *eap,
 		 */
 		eap_save_last_id(eap, &id);
 
-		__eap_handle_request(eap_tls_common_get_variant_data(eap), id,
-								pkt, len);
+		__eap_handle_request(peap_state->phase2, id, pkt, len);
 
 		return true;
 	}
 
-	eap_rx_packet(eap_tls_common_get_variant_data(eap), pkt, len);
+	eap_rx_packet(peap_state->phase2, pkt, len);
 
 	return true;
 }
 
-static void eap_peap_state_reset(void *phase2)
+static void eap_peap_state_reset(void *variant_data)
 {
-	if (!phase2)
+	struct peap_state *peap_state = variant_data;
+
+	if (!peap_state)
 		return;
 
-	eap_reset(phase2);
+	eap_reset(peap_state->phase2);
 }
 
-static void eap_peap_state_destroy(void *phase2)
+static void eap_peap_state_destroy(void *variant_data)
 {
-	if (!phase2)
+	struct peap_state *peap_state = variant_data;
+
+	if (!peap_state)
 		return;
 
-	eap_reset(phase2);
-	eap_free(phase2);
+	eap_reset(peap_state->phase2);
+	eap_free(peap_state->phase2);
+
+	l_free(peap_state);
 }
 
 static int eap_peap_settings_check(struct l_settings *settings,
@@ -323,6 +337,7 @@ static bool eap_peap_settings_load(struct eap_state *eap,
 						const char *prefix)
 {
 	char setting_key_prefix[72];
+	struct peap_state *peap_state;
 	void *phase2;
 
 	phase2 = eap_new(eap_peap_phase2_send_response,
@@ -343,11 +358,14 @@ static bool eap_peap_settings_load(struct eap_state *eap,
 		return false;
 	}
 
+	peap_state = l_new(struct peap_state, 1);
+	peap_state->phase2 = phase2;
+
 	snprintf(setting_key_prefix, sizeof(setting_key_prefix), "%sPEAP-",
 									prefix);
 
 	if (!eap_tls_common_settings_load(eap, settings, setting_key_prefix,
-							&eap_ttls_ops, phase2))
+						&eap_ttls_ops, peap_state))
 		return false;
 
 	return true;
-- 
2.13.6

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

* [PATCH 2/6] peap: Delay key installation until success of Phase 2
  2019-12-05 21:13 [PATCH 1/6] peap: Introduce PEAP state Tim Kourt
@ 2019-12-05 21:13 ` Tim Kourt
  2019-12-05 21:13 ` [PATCH 3/6] peap: Rename AVPs to TLVs Tim Kourt
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Tim Kourt @ 2019-12-05 21:13 UTC (permalink / raw)
  To: iwd

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

Previously, the key was installed once the runnel was created
despite the outcome of the second authentication phase. Now, the
key installation is delayed until the successful completion of
the second authentication phase. This excludes the unnecessary
operations in the case of a failure and key reinstallation with
cypro-binding in use.
---
 src/eap-peap.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/src/eap-peap.c b/src/eap-peap.c
index c400ddee..eb0b0c5f 100644
--- a/src/eap-peap.c
+++ b/src/eap-peap.c
@@ -43,6 +43,8 @@
 
 struct peap_state {
 	struct eap_state *phase2;
+
+	uint8_t key[128];
 };
 
 static void eap_peap_phase2_send_response(const uint8_t *pdu, size_t pdu_len,
@@ -66,6 +68,7 @@ static void eap_peap_phase2_send_response(const uint8_t *pdu, size_t pdu_len,
 static void eap_peap_phase2_complete(enum eap_result result, void *user_data)
 {
 	struct eap_state *eap = user_data;
+	struct peap_state *peap_state;
 
 	l_debug("result: %d", result);
 
@@ -94,6 +97,12 @@ static void eap_peap_phase2_complete(enum eap_result result, void *user_data)
 		return;
 	}
 
+	peap_state = eap_tls_common_get_variant_data(eap);
+
+	eap_set_key_material(eap, peap_state->key + 0, 64, NULL, 0, NULL,
+								0, NULL, 0);
+	explicit_bzero(peap_state->key, sizeof(peap_state->key));
+
 	eap_method_success(eap);
 }
 
@@ -174,6 +183,7 @@ static void eap_extensions_handle_request(struct eap_state *eap,
 							const uint8_t *pkt,
 							size_t len)
 {
+	struct peap_state *peap_state;
 	uint8_t response[EAP_EXTENSIONS_HEADER_LEN +
 					EAP_EXTENSIONS_AVP_HEADER_LEN + 2];
 	int r = eap_extensions_handle_result_avp(eap, pkt, len, response);
@@ -199,13 +209,19 @@ static void eap_extensions_handle_request(struct eap_state *eap,
 		return;
 	}
 
+	peap_state = eap_tls_common_get_variant_data(eap);
+
+	eap_set_key_material(eap, peap_state->key + 0, 64, NULL, 0, NULL,
+								0, NULL, 0);
+	explicit_bzero(peap_state->key, sizeof(peap_state->key));
+
 	eap_method_success(eap);
 }
 
 static bool eap_peap_tunnel_ready(struct eap_state *eap,
 						const char *peer_identity)
 {
-	uint8_t msk_emsk[128];
+	struct peap_state *peap_state = eap_tls_common_get_variant_data(eap);
 
 	/*
 	* PEAPv1: draft-josefsson-pppext-eap-tls-eap-05, Section 2.1.1
@@ -217,10 +233,7 @@ static bool eap_peap_tunnel_ready(struct eap_state *eap,
 
 	/* MSK, EMSK and challenge derivation */
 	eap_tls_common_tunnel_prf_get_bytes(eap, true, "client EAP encryption",
-								msk_emsk, 128);
-
-	eap_set_key_material(eap, msk_emsk + 0, 64, NULL, 0, NULL, 0, NULL, 0);
-	explicit_bzero(msk_emsk, sizeof(msk_emsk));
+						peap_state->key, 128);
 
 	eap_tls_common_send_empty_response(eap);
 
@@ -286,6 +299,8 @@ static void eap_peap_state_reset(void *variant_data)
 		return;
 
 	eap_reset(peap_state->phase2);
+
+	explicit_bzero(peap_state->key, sizeof(peap_state->key));
 }
 
 static void eap_peap_state_destroy(void *variant_data)
@@ -298,6 +313,8 @@ static void eap_peap_state_destroy(void *variant_data)
 	eap_reset(peap_state->phase2);
 	eap_free(peap_state->phase2);
 
+	explicit_bzero(peap_state->key, sizeof(peap_state->key));
+
 	l_free(peap_state);
 }
 
-- 
2.13.6

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

* [PATCH 3/6] peap: Rename AVPs to TLVs
  2019-12-05 21:13 [PATCH 1/6] peap: Introduce PEAP state Tim Kourt
  2019-12-05 21:13 ` [PATCH 2/6] peap: Delay key installation until success of Phase 2 Tim Kourt
@ 2019-12-05 21:13 ` Tim Kourt
  2019-12-05 21:13 ` [PATCH 4/6] peap: Extend EAP Extensions to handle multiple TLVs Tim Kourt
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Tim Kourt @ 2019-12-05 21:13 UTC (permalink / raw)
  To: iwd

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

Most of the literature seems to refer to AVPs as TLVs. Rename the
variables to follow the common nomenclature.
---
 src/eap-peap.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/eap-peap.c b/src/eap-peap.c
index eb0b0c5f..ed18c667 100644
--- a/src/eap-peap.c
+++ b/src/eap-peap.c
@@ -110,13 +110,13 @@ static void eap_peap_phase2_complete(enum eap_result result, void *user_data)
  * PEAPv0: draft-kamath-pppext-peapv0-00, Section 2
  */
 #define EAP_EXTENSIONS_HEADER_LEN 5
-#define EAP_EXTENSIONS_AVP_HEADER_LEN 4
+#define EAP_EXTENSIONS_TLV_HEADER_LEN 4
 
-enum eap_extensions_avp_type {
+enum eap_extensions_tlv_type {
 	/* Reserved = 0x0000, */
 	/* Reserved = 0x0001, */
 	/* Reserved = 0x0002, */
-	EAP_EXTENSIONS_AVP_TYPE_RESULT = 0x8003,
+	EAP_EXTENSIONS_TLV_TYPE_RESULT = 0x8003,
 };
 
 enum eap_extensions_result {
@@ -124,7 +124,7 @@ enum eap_extensions_result {
 	EAP_EXTENSIONS_RESULT_FAILURE  = 2,
 };
 
-static int eap_extensions_handle_result_avp(struct eap_state *eap,
+static int eap_extensions_handle_result_tlv(struct eap_state *eap,
 						const uint8_t *data,
 						size_t data_len,
 						uint8_t *response)
@@ -134,12 +134,12 @@ static int eap_extensions_handle_result_avp(struct eap_state *eap,
 	uint16_t len;
 	uint16_t result;
 
-	if (data_len < EAP_EXTENSIONS_AVP_HEADER_LEN + 2)
+	if (data_len < EAP_EXTENSIONS_TLV_HEADER_LEN + 2)
 		return -ENOENT;
 
 	type = l_get_be16(data);
 
-	if (type != EAP_EXTENSIONS_AVP_TYPE_RESULT)
+	if (type != EAP_EXTENSIONS_TLV_TYPE_RESULT)
 		return -ENOENT;
 
 	data += 2;
@@ -169,11 +169,11 @@ static int eap_extensions_handle_result_avp(struct eap_state *eap,
 		return -ENOENT;
 	}
 
-	l_put_be16(EAP_EXTENSIONS_AVP_TYPE_RESULT,
+	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_AVP_HEADER_LEN]);
+						EAP_EXTENSIONS_TLV_HEADER_LEN]);
 
 	return result;
 }
@@ -185,8 +185,8 @@ static void eap_extensions_handle_request(struct eap_state *eap,
 {
 	struct peap_state *peap_state;
 	uint8_t response[EAP_EXTENSIONS_HEADER_LEN +
-					EAP_EXTENSIONS_AVP_HEADER_LEN + 2];
-	int r = eap_extensions_handle_result_avp(eap, pkt, len, response);
+					EAP_EXTENSIONS_TLV_HEADER_LEN + 2];
+	int r = eap_extensions_handle_result_tlv(eap, pkt, len, response);
 
 	if (r < 0)
 		return;
-- 
2.13.6

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

* [PATCH 4/6] peap: Extend EAP Extensions to handle multiple TLVs
  2019-12-05 21:13 [PATCH 1/6] peap: Introduce PEAP state Tim Kourt
  2019-12-05 21:13 ` [PATCH 2/6] peap: Delay key installation until success of Phase 2 Tim Kourt
  2019-12-05 21:13 ` [PATCH 3/6] peap: Rename AVPs to TLVs Tim Kourt
@ 2019-12-05 21:13 ` Tim Kourt
  2019-12-09  7:46   ` Denis Kenzior
  2019-12-05 21:13 ` [PATCH 5/6] crypto: Add support for PRF+ SHA1 Tim Kourt
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Tim Kourt @ 2019-12-05 21:13 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 3838 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 | 90 ++++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 65 insertions(+), 25 deletions(-)

diff --git a/src/eap-peap.c b/src/eap-peap.c
index ed18c667..8cd73c82 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, */
@@ -119,6 +120,8 @@ enum eap_extensions_tlv_type {
 	EAP_EXTENSIONS_TLV_TYPE_RESULT = 0x8003,
 };
 
+#define TLV_RESULT_VAL_LEN 2
+
 enum eap_extensions_result {
 	EAP_EXTENSIONS_RESULT_SUCCCESS = 1,
 	EAP_EXTENSIONS_RESULT_FAILURE  = 2,
@@ -126,31 +129,15 @@ enum eap_extensions_result {
 
 static int eap_extensions_handle_result_tlv(struct eap_state *eap,
 						const uint8_t *data,
-						size_t data_len,
+						uint16_t tlv_value_len,
 						uint8_t *response)
 {
 	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)
+	if (tlv_value_len != TLV_RESULT_VAL_LEN)
 		return -ENOENT;
 
-	data += 2;
-
 	result = l_get_be16(data);
 
 	l_debug("result: %d", result);
@@ -169,11 +156,62 @@ 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(TLV_RESULT_VAL_LEN, response);
+	response += 2;
+
+	l_put_be16(result, response);
+
+	return result;
+}
+
+static int eap_extensions_process_tlvs(struct eap_state *eap,
+						const uint8_t *data,
+						size_t data_len,
+						uint8_t *response)
+{
+	uint16_t tlv_type;
+	uint16_t tlv_value_len;
+	int r;
+	int result = EAP_EXTENSIONS_RESULT_FAILURE;
+
+	while (data_len >= EAP_EXTENSIONS_TLV_HEADER_LEN) {
+		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 -ENOENT;
+
+		switch (tlv_type) {
+		case EAP_EXTENSIONS_TLV_TYPE_RESULT:
+			result = r = eap_extensions_handle_result_tlv(eap,
+						data, tlv_value_len, response);
+
+			response += EAP_EXTENSIONS_TLV_HEADER_LEN +
+							TLV_RESULT_VAL_LEN;
+			break;
+		default:
+			if (tlv_type & EAP_EXTENSIONS_TLV_M_BIT_MASK)
+				return -ENOENT;
+
+			break;
+		}
+
+		if (r < 0)
+			return r;
+
+		data += tlv_value_len;
+		data_len -= tlv_value_len;
+	}
 
 	return result;
 }
@@ -185,8 +223,10 @@ static void eap_extensions_handle_request(struct eap_state *eap,
 {
 	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);
+				EAP_EXTENSIONS_TLV_HEADER_LEN +
+						TLV_RESULT_VAL_LEN];
+	int r = eap_extensions_process_tlvs(eap, pkt, len,
+					&response[EAP_EXTENSIONS_HEADER_LEN]);
 
 	if (r < 0)
 		return;
-- 
2.13.6

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

* [PATCH 5/6] crypto: Add support for PRF+ SHA1
  2019-12-05 21:13 [PATCH 1/6] peap: Introduce PEAP state Tim Kourt
                   ` (2 preceding siblings ...)
  2019-12-05 21:13 ` [PATCH 4/6] peap: Extend EAP Extensions to handle multiple TLVs Tim Kourt
@ 2019-12-05 21:13 ` Tim Kourt
  2019-12-09  7:47   ` Denis Kenzior
  2019-12-05 21:13 ` [PATCH 6/6] peap: Add support for Crypto-Binding in PEAPv0 Tim Kourt
  2019-12-09  7:40 ` [PATCH 1/6] peap: Introduce PEAP state Denis Kenzior
  5 siblings, 1 reply; 10+ messages in thread
From: Tim Kourt @ 2019-12-05 21:13 UTC (permalink / raw)
  To: iwd

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

The PRF+ algorithm is based Internet Key Exchange (IKEv2) Protocol:
	https://www.ietf.org/rfc/rfc4306.txt
---
 src/crypto.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/crypto.h |  3 +++
 2 files changed, 67 insertions(+)

diff --git a/src/crypto.c b/src/crypto.c
index 67a042be..c1fe83a2 100644
--- a/src/crypto.c
+++ b/src/crypto.c
@@ -581,6 +581,70 @@ bool prf_sha1(const void *key, size_t key_len,
 	return true;
 }
 
+bool prf_plus_sha1(const void *key, size_t key_len,
+					const void *label, size_t label_len,
+					const void *seed, size_t seed_len,
+					void *output, size_t size)
+{
+	/*
+	 * PRF+ (K, S, LEN) = T1 | T2 | T3 | T4 | ... where:
+	 *
+	 * T1 = HMAC-SHA1 (K, S | LEN | 0x01 | 0x00 | 0x00)
+	 *
+	 * T2 = HMAC-SHA1 (K, T1 | S | LEN | 0x02 | 0x00 | 0x00)
+	 *
+	 * T3 = HMAC-SHA1 (K, T2 | S | LEN | 0x03 | 0x00 | 0x00)
+	 *
+	 * T4 = HMAC-SHA1 (K, T3 | S | LEN | 0x04 | 0x00 | 0x00)
+	 *
+	 * ...
+	 */
+
+	static const uint8_t SHA1_MAC_LEN = 20;
+	static const uint8_t nil_bytes[2] = { 0, 0 };
+	struct l_checksum *hmac;
+	uint8_t t[SHA1_MAC_LEN];
+	uint8_t counter;
+	struct iovec iov[5] = {
+		[0] = { .iov_base = (void *) t, .iov_len = 0 },
+		[1] = { .iov_base = (void *) label, .iov_len = label_len },
+		[2] = { .iov_base = (void *) seed, .iov_len = seed_len },
+		[3] = { .iov_base = &counter, .iov_len = 1 },
+		[4] = { .iov_base = (void *) nil_bytes, .iov_len = 2 },
+	};
+
+	hmac = l_checksum_new_hmac(L_CHECKSUM_SHA1, key, key_len);
+	if (!hmac)
+		return false;
+
+	/* PRF processes in 160-bit chunks (20 bytes) */
+	for (counter = 1;; counter++) {
+		size_t len;
+
+		if (size > SHA1_MAC_LEN)
+			len = SHA1_MAC_LEN;
+		else
+			len = size;
+
+		l_checksum_updatev(hmac, iov, 5);
+		l_checksum_get_digest(hmac, t, len);
+
+		memcpy(output, t, len);
+
+		size -= len;
+
+		if (!size)
+			break;
+
+		output += len;
+		iov[0].iov_len = len;
+	}
+
+	l_checksum_free(hmac);
+
+	return true;
+}
+
 /* Defined in 802.11-2012, Section 11.6.1.7.2 Key derivation function (KDF) */
 bool kdf_sha256(const void *key, size_t key_len,
 		const void *prefix, size_t prefix_len,
diff --git a/src/crypto.h b/src/crypto.h
index 23ca2450..89e2402c 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -106,6 +106,9 @@ bool kdf_sha384(const void *key, size_t key_len,
 bool prf_sha1(const void *key, size_t key_len,
 		const void *prefix, size_t prefix_len,
 		const void *data, size_t data_len, void *output, size_t size);
+bool prf_plus_sha1(const void *key, size_t key_len,
+		const void *prefix, size_t prefix_len,
+		const void *data, size_t data_len, void *output, size_t size);
 bool hkdf_extract(enum l_checksum_type type, const uint8_t *key, size_t key_len,
 				uint8_t num_args, uint8_t *out, ...);
 
-- 
2.13.6

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

* [PATCH 6/6] peap: Add support for Crypto-Binding in PEAPv0
  2019-12-05 21:13 [PATCH 1/6] peap: Introduce PEAP state Tim Kourt
                   ` (3 preceding siblings ...)
  2019-12-05 21:13 ` [PATCH 5/6] crypto: Add support for PRF+ SHA1 Tim Kourt
@ 2019-12-05 21:13 ` Tim Kourt
  2019-12-09  8:00   ` Denis Kenzior
  2019-12-09  7:40 ` [PATCH 1/6] peap: Introduce PEAP state Denis Kenzior
  5 siblings, 1 reply; 10+ messages in thread
From: Tim Kourt @ 2019-12-05 21:13 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 6547 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 | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 177 insertions(+), 2 deletions(-)

diff --git a/src/eap-peap.c b/src/eap-peap.c
index 8cd73c82..b2897186 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"
@@ -113,13 +114,178 @@ static void eap_peap_phase2_complete(enum eap_result result, void *user_data)
 #define EAP_EXTENSIONS_TLV_HEADER_LEN 4
 #define EAP_EXTENSIONS_TLV_M_BIT_MASK 0x8000
 
+#define TLV_CRYPTOBINDING_VAL_LEN 56
+#define TLV_CRYPTOBINDING_NONCE_LEN 32
+#define TLV_CRYPTOBINDING_COMPOUND_MAC_LEN 20
+
 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);
+	char *label;
+
+	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 uint8_t isk[32];
+	char *label;
+
+	label = "Inner Methods Compound Keys";
+	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)
+{
+	const uint8_t *nonce;
+	const uint8_t *server_compound_mac;
+	uint8_t compound_mac[TLV_CRYPTOBINDING_COMPOUND_MAC_LEN];
+	const uint8_t *cryptobinding_tlv_value;
+	uint8_t buf[61];
+	uint8_t imck[60];
+
+	if (tlv_value_len != TLV_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 += TLV_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 + TLV_CRYPTOBINDING_NONCE_LEN);
+	memset(&buf[EAP_EXTENSIONS_TLV_HEADER_LEN + 4 +
+						TLV_CRYPTOBINDING_NONCE_LEN],
+					0, TLV_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), compound_mac,
+					TLV_CRYPTOBINDING_COMPOUND_MAC_LEN)) {
+		l_error("PEAP: Failed to generate compound MAC to validate "
+						"server compound MAC.");
+
+		return -ENOENT;
+	}
+
+	if (memcmp(server_compound_mac, compound_mac,
+					TLV_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(TLV_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, TLV_CRYPTOBINDING_NONCE_LEN);
+	response += TLV_CRYPTOBINDING_NONCE_LEN;
+
+	memcpy(buf, data, EAP_EXTENSIONS_TLV_HEADER_LEN + 4 +
+						TLV_CRYPTOBINDING_NONCE_LEN);
+
+	if (!hmac_sha1(imck + 40, 20, buf, sizeof(buf), compound_mac,
+					TLV_CRYPTOBINDING_COMPOUND_MAC_LEN)) {
+		l_error("PEAP: Failed to generate client compound MAC.");
+
+		return -ENOENT;
+	}
+
+	memcpy(response, compound_mac, 20);
+
+	if (!cryptobinding_tlv_generate_csk(eap, imck)) {
+		l_error("PEAP: Failed to generate Compound Session Key.");
+
+		return -ENOENT;
+	}
+
+	return 0;
+}
+
 #define TLV_RESULT_VAL_LEN 2
 
 enum eap_extensions_result {
@@ -199,6 +365,13 @@ static int eap_extensions_process_tlvs(struct eap_state *eap,
 			response += EAP_EXTENSIONS_TLV_HEADER_LEN +
 							TLV_RESULT_VAL_LEN;
 			break;
+		case EAP_EXTENSIONS_TLV_TYPE_CRYPTOBINDING:
+			r = eap_extensions_handle_cryptobinding_tlv(eap,
+						data, tlv_value_len, response);
+
+			response += EAP_EXTENSIONS_TLV_HEADER_LEN +
+						TLV_CRYPTOBINDING_VAL_LEN;
+			break;
 		default:
 			if (tlv_type & EAP_EXTENSIONS_TLV_M_BIT_MASK)
 				return -ENOENT;
@@ -224,7 +397,9 @@ static void eap_extensions_handle_request(struct eap_state *eap,
 	struct peap_state *peap_state;
 	uint8_t response[EAP_EXTENSIONS_HEADER_LEN +
 				EAP_EXTENSIONS_TLV_HEADER_LEN +
-						TLV_RESULT_VAL_LEN];
+						TLV_RESULT_VAL_LEN +
+				EAP_EXTENSIONS_TLV_HEADER_LEN +
+						TLV_CRYPTOBINDING_VAL_LEN];
 	int r = eap_extensions_process_tlvs(eap, pkt, len,
 					&response[EAP_EXTENSIONS_HEADER_LEN]);
 
-- 
2.13.6

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

* Re: [PATCH 1/6] peap: Introduce PEAP state
  2019-12-05 21:13 [PATCH 1/6] peap: Introduce PEAP state Tim Kourt
                   ` (4 preceding siblings ...)
  2019-12-05 21:13 ` [PATCH 6/6] peap: Add support for Crypto-Binding in PEAPv0 Tim Kourt
@ 2019-12-09  7:40 ` Denis Kenzior
  5 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2019-12-09  7:40 UTC (permalink / raw)
  To: iwd

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

Hi Tim,

On 12/5/19 3:13 PM, Tim Kourt wrote:
> Introduction of the state struct will allow to hold the additional
> state variables related to the implementation of PEAP.
> ---
>   src/eap-peap.c | 44 +++++++++++++++++++++++++++++++-------------
>   1 file changed, 31 insertions(+), 13 deletions(-)
> 

Patches 1-3 applied, thanks.

Regards,
-Denis

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

* Re: [PATCH 4/6] peap: Extend EAP Extensions to handle multiple TLVs
  2019-12-05 21:13 ` [PATCH 4/6] peap: Extend EAP Extensions to handle multiple TLVs Tim Kourt
@ 2019-12-09  7:46   ` Denis Kenzior
  0 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2019-12-09  7:46 UTC (permalink / raw)
  To: iwd

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

Hi Tim,

On 12/5/19 3:13 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 | 90 ++++++++++++++++++++++++++++++++++++++++++----------------
>   1 file changed, 65 insertions(+), 25 deletions(-)
> 
> diff --git a/src/eap-peap.c b/src/eap-peap.c
> index ed18c667..8cd73c82 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, */
> @@ -119,6 +120,8 @@ enum eap_extensions_tlv_type {
>   	EAP_EXTENSIONS_TLV_TYPE_RESULT = 0x8003,
>   };
>   
> +#define TLV_RESULT_VAL_LEN 2
> +

Generally we don't like using #define for something that will be used 
only in one place.  Use a static const function variable if you feel 
using a constant isn't elegant.

>   enum eap_extensions_result {
>   	EAP_EXTENSIONS_RESULT_SUCCCESS = 1,
>   	EAP_EXTENSIONS_RESULT_FAILURE  = 2,
> @@ -126,31 +129,15 @@ enum eap_extensions_result {
>   
>   static int eap_extensions_handle_result_tlv(struct eap_state *eap,
>   						const uint8_t *data,
> -						size_t data_len,
> +						uint16_t tlv_value_len,

I'm not sure this is any better

>   						uint8_t *response)
>   {
>   	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)
> +	if (tlv_value_len != TLV_RESULT_VAL_LEN)
>   		return -ENOENT;

Just nitpicking, but I don't think ENOENT fits now.  Use -EINVAL or -EBADMSG
>   
> -	data += 2;
> -
>   	result = l_get_be16(data);
>   
>   	l_debug("result: %d", result);
> @@ -169,11 +156,62 @@ 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(TLV_RESULT_VAL_LEN, response);
> +	response += 2;
> +
> +	l_put_be16(result, response);
> +
> +	return result;
> +}
> +
> +static int eap_extensions_process_tlvs(struct eap_state *eap,
> +						const uint8_t *data,
> +						size_t data_len,
> +						uint8_t *response)
> +{
> +	uint16_t tlv_type;
> +	uint16_t tlv_value_len;
> +	int r;
> +	int result = EAP_EXTENSIONS_RESULT_FAILURE;
> +
> +	while (data_len >= EAP_EXTENSIONS_TLV_HEADER_LEN) {
> +		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 -ENOENT;

Same here, -EBADMSG might be better

> +
> +		switch (tlv_type) {
> +		case EAP_EXTENSIONS_TLV_TYPE_RESULT:
> +			result = r = eap_extensions_handle_result_tlv(eap,
> +						data, tlv_value_len, response);
> +
> +			response += EAP_EXTENSIONS_TLV_HEADER_LEN +
> +							TLV_RESULT_VAL_LEN;
> +			break;
> +		default:
> +			if (tlv_type & EAP_EXTENSIONS_TLV_M_BIT_MASK)
> +				return -ENOENT;
> +
> +			break;
> +		}
> +
> +		if (r < 0)
> +			return r;
> +
> +		data += tlv_value_len;
> +		data_len -= tlv_value_len;
> +	}
>   
>   	return result;
>   }
> @@ -185,8 +223,10 @@ static void eap_extensions_handle_request(struct eap_state *eap,
>   {
>   	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);
> +				EAP_EXTENSIONS_TLV_HEADER_LEN +
> +						TLV_RESULT_VAL_LEN];
> +	int r = eap_extensions_process_tlvs(eap, pkt, len,
> +					&response[EAP_EXTENSIONS_HEADER_LEN]);
>   
>   	if (r < 0)
>   		return;
> 

Regards,
-Denis

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

* Re: [PATCH 5/6] crypto: Add support for PRF+ SHA1
  2019-12-05 21:13 ` [PATCH 5/6] crypto: Add support for PRF+ SHA1 Tim Kourt
@ 2019-12-09  7:47   ` Denis Kenzior
  0 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2019-12-09  7:47 UTC (permalink / raw)
  To: iwd

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

Hi Tim,

On 12/5/19 3:13 PM, Tim Kourt wrote:
> The PRF+ algorithm is based Internet Key Exchange (IKEv2) Protocol:
> 	https://www.ietf.org/rfc/rfc4306.txt
> ---
>   src/crypto.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   src/crypto.h |  3 +++
>   2 files changed, 67 insertions(+)
> 

Applied, thanks.

Regards,
-Denis

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

* Re: [PATCH 6/6] peap: Add support for Crypto-Binding in PEAPv0
  2019-12-05 21:13 ` [PATCH 6/6] peap: Add support for Crypto-Binding in PEAPv0 Tim Kourt
@ 2019-12-09  8:00   ` Denis Kenzior
  0 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2019-12-09  8:00 UTC (permalink / raw)
  To: iwd

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

Hi Tim,

On 12/5/19 3:13 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 | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>   1 file changed, 177 insertions(+), 2 deletions(-)
> 
> diff --git a/src/eap-peap.c b/src/eap-peap.c
> index 8cd73c82..b2897186 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"
> @@ -113,13 +114,178 @@ static void eap_peap_phase2_complete(enum eap_result result, void *user_data)
>   #define EAP_EXTENSIONS_TLV_HEADER_LEN 4
>   #define EAP_EXTENSIONS_TLV_M_BIT_MASK 0x8000
>   
> +#define TLV_CRYPTOBINDING_VAL_LEN 56
> +#define TLV_CRYPTOBINDING_NONCE_LEN 32
> +#define TLV_CRYPTOBINDING_COMPOUND_MAC_LEN 20
> +

Same comment as in patch 4, no point defining these when they're used once.

>   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);
> +	char *label;
> +
> +	label = "Session Key Generating Function";
> +

Why isn't label static const char *?

> +	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 uint8_t isk[32];

This likely should not be static

> +	char *label;
> +
> +	label = "Inner Methods Compound Keys";

And this should be static const char *label = ".."

> +	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)
> +{
> +	const uint8_t *nonce;
> +	const uint8_t *server_compound_mac;
> +	uint8_t compound_mac[TLV_CRYPTOBINDING_COMPOUND_MAC_LEN];
> +	const uint8_t *cryptobinding_tlv_value;
> +	uint8_t buf[61];
> +	uint8_t imck[60];
> +
> +	if (tlv_value_len != TLV_CRYPTOBINDING_VAL_LEN)
> +		return -ENOENT;
> +

-EBADMSG

> +	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;
> +

Okay, this is pretty long winded way of doing
static const uint8_t cryptobinding_magic[] = { 0x00, 0x00, 0x00, 0x01 };
!memcmp(data, cryptobinding_magic, sizeof(cryptobinding_magic))

> +	nonce = data;
> +	data += TLV_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 + TLV_CRYPTOBINDING_NONCE_LEN);
> +	memset(&buf[EAP_EXTENSIONS_TLV_HEADER_LEN + 4 +
> +						TLV_CRYPTOBINDING_NONCE_LEN],
> +					0, TLV_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;

-EIO

> +	}
> +
> +	if (!hmac_sha1(imck + 40, 20, buf, sizeof(buf), compound_mac,
> +					TLV_CRYPTOBINDING_COMPOUND_MAC_LEN)) {
> +		l_error("PEAP: Failed to generate compound MAC to validate "
> +						"server compound MAC.");
> +
> +		return -ENOENT;

-EIO

> +	}
> +
> +	if (memcmp(server_compound_mac, compound_mac,
> +					TLV_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(TLV_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, TLV_CRYPTOBINDING_NONCE_LEN);
> +	response += TLV_CRYPTOBINDING_NONCE_LEN;
> +
> +	memcpy(buf, data, EAP_EXTENSIONS_TLV_HEADER_LEN + 4 +
> +						TLV_CRYPTOBINDING_NONCE_LEN);
> +
> +	if (!hmac_sha1(imck + 40, 20, buf, sizeof(buf), compound_mac,
> +					TLV_CRYPTOBINDING_COMPOUND_MAC_LEN)) {
> +		l_error("PEAP: Failed to generate client compound MAC.");
> +
> +		return -ENOENT;
> +	}
> +
> +	memcpy(response, compound_mac, 20);
> +
> +	if (!cryptobinding_tlv_generate_csk(eap, imck)) {
> +		l_error("PEAP: Failed to generate Compound Session Key.");
> +
> +		return -ENOENT;
> +	}
> +
> +	return 0;
> +}
> +
>   #define TLV_RESULT_VAL_LEN 2
>   
>   enum eap_extensions_result {

<snip>

Regards,
-Denis

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

end of thread, other threads:[~2019-12-09  8:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-05 21:13 [PATCH 1/6] peap: Introduce PEAP state Tim Kourt
2019-12-05 21:13 ` [PATCH 2/6] peap: Delay key installation until success of Phase 2 Tim Kourt
2019-12-05 21:13 ` [PATCH 3/6] peap: Rename AVPs to TLVs Tim Kourt
2019-12-05 21:13 ` [PATCH 4/6] peap: Extend EAP Extensions to handle multiple TLVs Tim Kourt
2019-12-09  7:46   ` Denis Kenzior
2019-12-05 21:13 ` [PATCH 5/6] crypto: Add support for PRF+ SHA1 Tim Kourt
2019-12-09  7:47   ` Denis Kenzior
2019-12-05 21:13 ` [PATCH 6/6] peap: Add support for Crypto-Binding in PEAPv0 Tim Kourt
2019-12-09  8:00   ` Denis Kenzior
2019-12-09  7:40 ` [PATCH 1/6] peap: Introduce PEAP state 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.