EAP-FAST: Moved common peer/server functionality into a shared file
This commit is contained in:
		
							parent
							
								
									a4819630f6
								
							
						
					
					
						commit
						7f4c1d4300
					
				
					 4 changed files with 298 additions and 451 deletions
				
			
		|  | @ -15,6 +15,10 @@ | |||
| #include "includes.h" | ||||
| 
 | ||||
| #include "common.h" | ||||
| #include "sha1.h" | ||||
| #include "tls.h" | ||||
| #include "eap_defs.h" | ||||
| #include "eap_tlv_common.h" | ||||
| #include "eap_fast_common.h" | ||||
| 
 | ||||
| 
 | ||||
|  | @ -41,3 +45,260 @@ void eap_fast_put_tlv_buf(struct wpabuf *buf, u16 type, | |||
| 	eap_fast_put_tlv_hdr(buf, type, wpabuf_len(data)); | ||||
| 	wpabuf_put_buf(buf, data); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| struct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf) | ||||
| { | ||||
| 	struct wpabuf *e; | ||||
| 
 | ||||
| 	if (buf == NULL) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	/* Encapsulate EAP packet in EAP-Payload TLV */ | ||||
| 	wpa_printf(MSG_DEBUG, "EAP-FAST: Add EAP-Payload TLV"); | ||||
| 	e = wpabuf_alloc(sizeof(struct pac_tlv_hdr) + wpabuf_len(buf)); | ||||
| 	if (e == NULL) { | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory " | ||||
| 			   "for TLV encapsulation"); | ||||
| 		wpabuf_free(buf); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	eap_fast_put_tlv_buf(e, | ||||
| 			     EAP_TLV_TYPE_MANDATORY | EAP_TLV_EAP_PAYLOAD_TLV, | ||||
| 			     buf); | ||||
| 	wpabuf_free(buf); | ||||
| 	return e; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void eap_fast_derive_master_secret(const u8 *pac_key, const u8 *server_random, | ||||
| 				   const u8 *client_random, u8 *master_secret) | ||||
| { | ||||
| #define TLS_RANDOM_LEN 32 | ||||
| #define TLS_MASTER_SECRET_LEN 48 | ||||
| 	u8 seed[2 * TLS_RANDOM_LEN]; | ||||
| 
 | ||||
| 	wpa_hexdump(MSG_DEBUG, "EAP-FAST: client_random", | ||||
| 		    client_random, TLS_RANDOM_LEN); | ||||
| 	wpa_hexdump(MSG_DEBUG, "EAP-FAST: server_random", | ||||
| 		    server_random, TLS_RANDOM_LEN); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * RFC 4851, Section 5.1: | ||||
| 	 * master_secret = T-PRF(PAC-Key, "PAC to master secret label hash",  | ||||
| 	 *                       server_random + client_random, 48) | ||||
| 	 */ | ||||
| 	os_memcpy(seed, server_random, TLS_RANDOM_LEN); | ||||
| 	os_memcpy(seed + TLS_RANDOM_LEN, client_random, TLS_RANDOM_LEN); | ||||
| 	sha1_t_prf(pac_key, EAP_FAST_PAC_KEY_LEN, | ||||
| 		   "PAC to master secret label hash", | ||||
| 		   seed, sizeof(seed), master_secret, TLS_MASTER_SECRET_LEN); | ||||
| 
 | ||||
| 	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: master_secret", | ||||
| 			master_secret, TLS_MASTER_SECRET_LEN); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| u8 * eap_fast_derive_key(void *ssl_ctx, struct tls_connection *conn, | ||||
| 			 const char *label, size_t len) | ||||
| { | ||||
| 	struct tls_keys keys; | ||||
| 	u8 *rnd = NULL, *out; | ||||
| 	int block_size; | ||||
| 
 | ||||
| 	block_size = tls_connection_get_keyblock_size(ssl_ctx, conn); | ||||
| 	if (block_size < 0) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	out = os_malloc(block_size + len); | ||||
| 	if (out == NULL) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	if (tls_connection_prf(ssl_ctx, conn, label, 1, out, block_size + len) | ||||
| 	    == 0) { | ||||
| 		os_memmove(out, out + block_size, len); | ||||
| 		return out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (tls_connection_get_keys(ssl_ctx, conn, &keys)) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	rnd = os_malloc(keys.client_random_len + keys.server_random_len); | ||||
| 	if (rnd == NULL) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	os_memcpy(rnd, keys.server_random, keys.server_random_len); | ||||
| 	os_memcpy(rnd + keys.server_random_len, keys.client_random, | ||||
| 		  keys.client_random_len); | ||||
| 
 | ||||
| 	wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: master_secret for key " | ||||
| 			"expansion", keys.master_key, keys.master_key_len); | ||||
| 	if (tls_prf(keys.master_key, keys.master_key_len, | ||||
| 		    label, rnd, keys.client_random_len + | ||||
| 		    keys.server_random_len, out, block_size + len)) | ||||
| 		goto fail; | ||||
| 	os_free(rnd); | ||||
| 	os_memmove(out, out + block_size, len); | ||||
| 	return out; | ||||
| 
 | ||||
| fail: | ||||
| 	os_free(rnd); | ||||
| 	os_free(out); | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void eap_fast_derive_eap_msk(const u8 *simck, u8 *msk) | ||||
| { | ||||
| 	/*
 | ||||
| 	 * RFC 4851, Section 5.4: EAP Master Session Key Generation | ||||
| 	 * MSK = T-PRF(S-IMCK[j], "Session Key Generating Function", 64) | ||||
| 	 */ | ||||
| 
 | ||||
| 	sha1_t_prf(simck, EAP_FAST_SIMCK_LEN, | ||||
| 		   "Session Key Generating Function", (u8 *) "", 0, | ||||
| 		   msk, EAP_FAST_KEY_LEN); | ||||
| 	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (MSK)", | ||||
| 			msk, EAP_FAST_KEY_LEN); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void eap_fast_derive_eap_emsk(const u8 *simck, u8 *emsk) | ||||
| { | ||||
| 	/*
 | ||||
| 	 * RFC 4851, Section 5.4: EAP Master Session Key Genreration | ||||
| 	 * EMSK = T-PRF(S-IMCK[j], | ||||
| 	 *        "Extended Session Key Generating Function", 64) | ||||
| 	 */ | ||||
| 
 | ||||
| 	sha1_t_prf(simck, EAP_FAST_SIMCK_LEN, | ||||
| 		   "Extended Session Key Generating Function", (u8 *) "", 0, | ||||
| 		   emsk, EAP_EMSK_LEN); | ||||
| 	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (EMSK)", | ||||
| 			emsk, EAP_EMSK_LEN); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int eap_fast_parse_tlv(struct eap_fast_tlv_parse *tlv, | ||||
| 		       int tlv_type, u8 *pos, int len) | ||||
| { | ||||
| 	switch (tlv_type) { | ||||
| 	case EAP_TLV_EAP_PAYLOAD_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: EAP-Payload TLV", | ||||
| 			    pos, len); | ||||
| 		if (tlv->eap_payload_tlv) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " | ||||
| 				   "EAP-Payload TLV in the message"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		tlv->eap_payload_tlv = pos; | ||||
| 		tlv->eap_payload_tlv_len = len; | ||||
| 		break; | ||||
| 	case EAP_TLV_RESULT_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Result TLV", pos, len); | ||||
| 		if (tlv->result) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " | ||||
| 				   "Result TLV in the message"); | ||||
| 			tlv->result = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		if (len < 2) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " | ||||
| 				   "Result TLV"); | ||||
| 			tlv->result = EAP_TLV_RESULT_FAILURE; | ||||
| 			break; | ||||
| 		} | ||||
| 		tlv->result = WPA_GET_BE16(pos); | ||||
| 		if (tlv->result != EAP_TLV_RESULT_SUCCESS && | ||||
| 		    tlv->result != EAP_TLV_RESULT_FAILURE) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown Result %d", | ||||
| 				   tlv->result); | ||||
| 			tlv->result = EAP_TLV_RESULT_FAILURE; | ||||
| 		} | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Result: %s", | ||||
| 			   tlv->result == EAP_TLV_RESULT_SUCCESS ? | ||||
| 			   "Success" : "Failure"); | ||||
| 		break; | ||||
| 	case EAP_TLV_INTERMEDIATE_RESULT_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Intermediate Result TLV", | ||||
| 			    pos, len); | ||||
| 		if (len < 2) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " | ||||
| 				   "Intermediate-Result TLV"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			break; | ||||
| 		} | ||||
| 		if (tlv->iresult) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " | ||||
| 				   "Intermediate-Result TLV in the message"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		tlv->iresult = WPA_GET_BE16(pos); | ||||
| 		if (tlv->iresult != EAP_TLV_RESULT_SUCCESS && | ||||
| 		    tlv->iresult != EAP_TLV_RESULT_FAILURE) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown Intermediate " | ||||
| 				   "Result %d", tlv->iresult); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 		} | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Intermediate Result: %s", | ||||
| 			   tlv->iresult == EAP_TLV_RESULT_SUCCESS ? | ||||
| 			   "Success" : "Failure"); | ||||
| 		break; | ||||
| 	case EAP_TLV_CRYPTO_BINDING_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV", | ||||
| 			    pos, len); | ||||
| 		if (tlv->crypto_binding) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " | ||||
| 				   "Crypto-Binding TLV in the message"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		tlv->crypto_binding_len = sizeof(struct eap_tlv_hdr) + len; | ||||
| 		if (tlv->crypto_binding_len < sizeof(*tlv->crypto_binding)) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " | ||||
| 				   "Crypto-Binding TLV"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		tlv->crypto_binding = (struct eap_tlv_crypto_binding__tlv *) | ||||
| 			(pos - sizeof(struct eap_tlv_hdr)); | ||||
| 		break; | ||||
| 	case EAP_TLV_REQUEST_ACTION_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Request-Action TLV", | ||||
| 			    pos, len); | ||||
| 		if (tlv->request_action) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " | ||||
| 				   "Request-Action TLV in the message"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		if (len < 2) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " | ||||
| 				   "Request-Action TLV"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			break; | ||||
| 		} | ||||
| 		tlv->request_action = WPA_GET_BE16(pos); | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Request-Action: %d", | ||||
| 			   tlv->request_action); | ||||
| 		break; | ||||
| 	case EAP_TLV_PAC_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: PAC TLV", pos, len); | ||||
| 		if (tlv->pac) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " | ||||
| 				   "PAC TLV in the message"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		tlv->pac = pos; | ||||
| 		tlv->pac_len = len; | ||||
| 		break; | ||||
| 	default: | ||||
| 		/* Unknown TLV */ | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -84,11 +84,33 @@ struct eap_fast_key_block_provisioning { | |||
| 
 | ||||
| 
 | ||||
| struct wpabuf; | ||||
| struct tls_connection; | ||||
| 
 | ||||
| struct eap_fast_tlv_parse { | ||||
| 	u8 *eap_payload_tlv; | ||||
| 	size_t eap_payload_tlv_len; | ||||
| 	struct eap_tlv_crypto_binding__tlv *crypto_binding; | ||||
| 	size_t crypto_binding_len; | ||||
| 	int iresult; | ||||
| 	int result; | ||||
| 	int request_action; | ||||
| 	u8 *pac; | ||||
| 	size_t pac_len; | ||||
| }; | ||||
| 
 | ||||
| void eap_fast_put_tlv_hdr(struct wpabuf *buf, u16 type, u16 len); | ||||
| void eap_fast_put_tlv(struct wpabuf *buf, u16 type, const void *data, | ||||
| 		      u16 len); | ||||
| void eap_fast_put_tlv_buf(struct wpabuf *buf, u16 type, | ||||
| 			  const struct wpabuf *data); | ||||
| struct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf); | ||||
| void eap_fast_derive_master_secret(const u8 *pac_key, const u8 *server_random, | ||||
| 				   const u8 *client_random, u8 *master_secret); | ||||
| u8 * eap_fast_derive_key(void *ssl_ctx, struct tls_connection *conn, | ||||
| 			 const char *label, size_t len); | ||||
| void eap_fast_derive_eap_msk(const u8 *simck, u8 *msk); | ||||
| void eap_fast_derive_eap_emsk(const u8 *simck, u8 *emsk); | ||||
| int eap_fast_parse_tlv(struct eap_fast_tlv_parse *tlv, | ||||
| 		       int tlv_type, u8 *pos, int len); | ||||
| 
 | ||||
| #endif /* EAP_FAST_H */ | ||||
|  |  | |||
|  | @ -80,9 +80,6 @@ static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len, | |||
| 				      u8 *master_secret) | ||||
| { | ||||
| 	struct eap_fast_data *data = ctx; | ||||
| #define TLS_RANDOM_LEN 32 | ||||
| #define TLS_MASTER_SECRET_LEN 48 | ||||
| 	u8 seed[2 * TLS_RANDOM_LEN]; | ||||
| 
 | ||||
| 	wpa_printf(MSG_DEBUG, "EAP-FAST: SessionTicket callback"); | ||||
| 
 | ||||
|  | @ -101,10 +98,6 @@ static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len, | |||
| 	} | ||||
| 
 | ||||
| 	wpa_hexdump(MSG_DEBUG, "EAP-FAST: SessionTicket", ticket, len); | ||||
| 	wpa_hexdump(MSG_DEBUG, "EAP-FAST: client_random", | ||||
| 		    client_random, TLS_RANDOM_LEN); | ||||
| 	wpa_hexdump(MSG_DEBUG, "EAP-FAST: server_random", | ||||
| 		    server_random, TLS_RANDOM_LEN); | ||||
| 
 | ||||
| 	if (data->current_pac == NULL) { | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC-Key available for " | ||||
|  | @ -113,19 +106,9 @@ static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len, | |||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * RFC 4851, Section 5.1: | ||||
| 	 * master_secret = T-PRF(PAC-Key, "PAC to master secret label hash",  | ||||
| 	 *                       server_random + client_random, 48) | ||||
| 	 */ | ||||
| 	os_memcpy(seed, server_random, TLS_RANDOM_LEN); | ||||
| 	os_memcpy(seed + TLS_RANDOM_LEN, client_random, TLS_RANDOM_LEN); | ||||
| 	sha1_t_prf(data->current_pac->pac_key, EAP_FAST_PAC_KEY_LEN, | ||||
| 		   "PAC to master secret label hash", | ||||
| 		   seed, sizeof(seed), master_secret, TLS_MASTER_SECRET_LEN); | ||||
| 
 | ||||
| 	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: master_secret", | ||||
| 			master_secret, TLS_MASTER_SECRET_LEN); | ||||
| 	eap_fast_derive_master_secret(data->current_pac->pac_key, | ||||
| 				      server_random, client_random, | ||||
| 				      master_secret); | ||||
| 
 | ||||
| 	data->session_ticket_used = 1; | ||||
| 
 | ||||
|  | @ -268,74 +251,13 @@ static void eap_fast_deinit(struct eap_sm *sm, void *priv) | |||
| 
 | ||||
| static int eap_fast_derive_msk(struct eap_fast_data *data) | ||||
| { | ||||
| 	/* Derive EAP Master Session Keys (section 5.4) */ | ||||
| 	sha1_t_prf(data->simck, EAP_FAST_SIMCK_LEN, | ||||
| 		   "Session Key Generating Function", (u8 *) "", 0, | ||||
| 		   data->key_data, EAP_FAST_KEY_LEN); | ||||
| 	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (MSK)", | ||||
| 			data->key_data, EAP_FAST_KEY_LEN); | ||||
| 
 | ||||
| 	sha1_t_prf(data->simck, EAP_FAST_SIMCK_LEN, | ||||
| 		   "Extended Session Key Generating Function", | ||||
| 		   (u8 *) "", 0, data->emsk, EAP_EMSK_LEN); | ||||
| 	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (EMSK)", | ||||
| 			data->emsk, EAP_EMSK_LEN); | ||||
| 
 | ||||
| 	eap_fast_derive_eap_msk(data->simck, data->key_data); | ||||
| 	eap_fast_derive_eap_emsk(data->simck, data->emsk); | ||||
| 	data->success = 1; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static u8 * eap_fast_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, | ||||
| 				char *label, size_t len) | ||||
| { | ||||
| 	struct tls_keys keys; | ||||
| 	u8 *rnd = NULL, *out; | ||||
| 	int block_size; | ||||
| 
 | ||||
| 	block_size = tls_connection_get_keyblock_size(sm->ssl_ctx, data->conn); | ||||
| 	if (block_size < 0) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	out = os_malloc(block_size + len); | ||||
| 	if (out == NULL) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 1, out, | ||||
| 			       block_size + len) == 0) { | ||||
| 		os_memmove(out, out + block_size, len); | ||||
| 		return out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys)) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	rnd = os_malloc(keys.client_random_len + keys.server_random_len); | ||||
| 	if (rnd == NULL) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	os_memcpy(rnd, keys.server_random, keys.server_random_len); | ||||
| 	os_memcpy(rnd + keys.server_random_len, keys.client_random, | ||||
| 		  keys.client_random_len); | ||||
| 
 | ||||
| 	wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: master_secret for key " | ||||
| 			"expansion", keys.master_key, keys.master_key_len); | ||||
| 	if (tls_prf(keys.master_key, keys.master_key_len, | ||||
| 		    label, rnd, keys.client_random_len + | ||||
| 		    keys.server_random_len, out, block_size + len)) | ||||
| 		goto fail; | ||||
| 	os_free(rnd); | ||||
| 	os_memmove(out, out + block_size, len); | ||||
| 	return out; | ||||
| 
 | ||||
| fail: | ||||
| 	os_free(rnd); | ||||
| 	os_free(out); | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void eap_fast_derive_key_auth(struct eap_sm *sm, | ||||
| 				     struct eap_fast_data *data) | ||||
| { | ||||
|  | @ -345,7 +267,7 @@ static void eap_fast_derive_key_auth(struct eap_sm *sm, | |||
| 	 * Extra key material after TLS key_block: session_key_seed[40] | ||||
| 	 */ | ||||
| 
 | ||||
| 	sks = eap_fast_derive_key(sm, &data->ssl, "key expansion", | ||||
| 	sks = eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, "key expansion", | ||||
| 				  EAP_FAST_SKS_LEN); | ||||
| 	if (sks == NULL) { | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive " | ||||
|  | @ -371,7 +293,8 @@ static void eap_fast_derive_key_provisioning(struct eap_sm *sm, | |||
| { | ||||
| 	os_free(data->key_block_p); | ||||
| 	data->key_block_p = (struct eap_fast_key_block_provisioning *) | ||||
| 		eap_fast_derive_key(sm, &data->ssl, "key expansion", | ||||
| 		eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, | ||||
| 				    "key expansion", | ||||
| 				    sizeof(*data->key_block_p)); | ||||
| 	if (data->key_block_p == NULL) { | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive key block"); | ||||
|  | @ -596,29 +519,6 @@ static struct wpabuf * eap_fast_tlv_pac_ack(void) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static struct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf) | ||||
| { | ||||
| 	struct wpabuf *msg; | ||||
| 
 | ||||
| 	if (buf == NULL) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	/* Encapsulate EAP packet in EAP Payload TLV */ | ||||
| 	msg = wpabuf_alloc(sizeof(struct pac_tlv_hdr) + wpabuf_len(buf)); | ||||
| 	if (msg == NULL) { | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory " | ||||
| 			   "for TLV encapsulation"); | ||||
| 		wpabuf_free(buf); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	eap_fast_put_tlv_buf(msg, | ||||
| 			     EAP_TLV_TYPE_MANDATORY | EAP_TLV_EAP_PAYLOAD_TLV, | ||||
| 			     buf); | ||||
| 	wpabuf_free(buf); | ||||
| 	return msg; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 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, | ||||
|  | @ -1166,94 +1066,6 @@ static struct wpabuf * eap_fast_process_pac(struct eap_sm *sm, | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| struct eap_fast_tlv_parse { | ||||
| 	u8 *eap_payload_tlv; | ||||
| 	size_t eap_payload_tlv_len; | ||||
| 	u8 *pac; | ||||
| 	size_t pac_len; | ||||
| 	struct eap_tlv_crypto_binding__tlv *crypto_binding; | ||||
| 	size_t crypto_binding_len; | ||||
| 	int iresult; | ||||
| 	int result; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| static int eap_fast_parse_tlv(struct eap_fast_tlv_parse *tlv, | ||||
| 			      int tlv_type, u8 *pos, int len) | ||||
| { | ||||
| 	switch (tlv_type) { | ||||
| 	case EAP_TLV_EAP_PAYLOAD_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: EAP Payload TLV", | ||||
| 			    pos, len); | ||||
| 		tlv->eap_payload_tlv = pos; | ||||
| 		tlv->eap_payload_tlv_len = len; | ||||
| 		break; | ||||
| 	case EAP_TLV_RESULT_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Result TLV", pos, len); | ||||
| 		if (len < 2) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " | ||||
| 				   "Result TLV"); | ||||
| 			tlv->result = EAP_TLV_RESULT_FAILURE; | ||||
| 			break; | ||||
| 		} | ||||
| 		tlv->result = WPA_GET_BE16(pos); | ||||
| 		if (tlv->result != EAP_TLV_RESULT_SUCCESS && | ||||
| 		    tlv->result != EAP_TLV_RESULT_FAILURE) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown Result %d", | ||||
| 				   tlv->result); | ||||
| 			tlv->result = EAP_TLV_RESULT_FAILURE; | ||||
| 		} | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Result: %s", | ||||
| 			   tlv->result == EAP_TLV_RESULT_SUCCESS ? | ||||
| 			   "Success" : "Failure"); | ||||
| 		break; | ||||
| 	case EAP_TLV_INTERMEDIATE_RESULT_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Intermediate Result TLV", | ||||
| 			    pos, len); | ||||
| 		if (len < 2) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " | ||||
| 				   "Intermediate Result TLV"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			break; | ||||
| 		} | ||||
| 		tlv->iresult = WPA_GET_BE16(pos); | ||||
| 		if (tlv->iresult != EAP_TLV_RESULT_SUCCESS && | ||||
| 		    tlv->iresult != EAP_TLV_RESULT_FAILURE) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown Intermediate " | ||||
| 				   "Result %d", tlv->iresult); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 		} | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Intermediate Result: %s", | ||||
| 			   tlv->iresult == EAP_TLV_RESULT_SUCCESS ? | ||||
| 			   "Success" : "Failure"); | ||||
| 		break; | ||||
| 	case EAP_TLV_CRYPTO_BINDING_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV", | ||||
| 			    pos, len); | ||||
| 		tlv->crypto_binding_len = sizeof(struct eap_tlv_hdr) + len; | ||||
| 		if (tlv->crypto_binding_len < sizeof(*tlv->crypto_binding)) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " | ||||
| 				   "Crypto-Binding TLV"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		tlv->crypto_binding = (struct eap_tlv_crypto_binding__tlv *) | ||||
| 			(pos - sizeof(struct eap_tlv_hdr)); | ||||
| 		break; | ||||
| 	case EAP_TLV_PAC_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: PAC TLV", pos, len); | ||||
| 		tlv->pac = pos; | ||||
| 		tlv->pac_len = len; | ||||
| 		break; | ||||
| 	default: | ||||
| 		/* Unknown TLV */ | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static int eap_fast_parse_decrypted(struct wpabuf *decrypted, | ||||
| 				    struct eap_fast_tlv_parse *tlv, | ||||
| 				    struct wpabuf **resp) | ||||
|  |  | |||
|  | @ -128,9 +128,6 @@ static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len, | |||
| 				      u8 *master_secret) | ||||
| { | ||||
| 	struct eap_fast_data *data = ctx; | ||||
| #define TLS_RANDOM_LEN 32 | ||||
| #define TLS_MASTER_SECRET_LEN 48 | ||||
| 	u8 seed[2 * TLS_RANDOM_LEN]; | ||||
| 	const u8 *pac_opaque; | ||||
| 	size_t pac_opaque_len; | ||||
| 	u8 *buf, *pos, *end, *pac_key = NULL; | ||||
|  | @ -142,10 +139,6 @@ static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len, | |||
| 	wpa_printf(MSG_DEBUG, "EAP-FAST: SessionTicket callback"); | ||||
| 	wpa_hexdump(MSG_DEBUG, "EAP-FAST: SessionTicket (PAC-Opaque)", | ||||
| 		    ticket, len); | ||||
| 	wpa_hexdump(MSG_DEBUG, "EAP-FAST: client_random", | ||||
| 		    client_random, TLS_RANDOM_LEN); | ||||
| 	wpa_hexdump(MSG_DEBUG, "EAP-FAST: server_random", | ||||
| 		    server_random, TLS_RANDOM_LEN); | ||||
| 
 | ||||
| 	if (len < 4 || WPA_GET_BE16(ticket) != PAC_TYPE_PAC_OPAQUE) { | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Ignore invalid " | ||||
|  | @ -259,19 +252,8 @@ static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len, | |||
| 	if (lifetime - now.sec < PAC_KEY_REFRESH_TIME) | ||||
| 		data->send_new_pac = 1; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * RFC 4851, Section 5.1: | ||||
| 	 * master_secret = T-PRF(PAC-Key, "PAC to master secret label hash",  | ||||
| 	 *                       server_random + client_random, 48) | ||||
| 	 */ | ||||
| 	os_memcpy(seed, server_random, TLS_RANDOM_LEN); | ||||
| 	os_memcpy(seed + TLS_RANDOM_LEN, client_random, TLS_RANDOM_LEN); | ||||
| 	sha1_t_prf(pac_key, EAP_FAST_PAC_KEY_LEN, | ||||
| 		   "PAC to master secret label hash", | ||||
| 		   seed, sizeof(seed), master_secret, TLS_MASTER_SECRET_LEN); | ||||
| 
 | ||||
| 	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: master_secret", | ||||
| 			master_secret, TLS_MASTER_SECRET_LEN); | ||||
| 	eap_fast_derive_master_secret(pac_key, server_random, client_random, | ||||
| 				      master_secret); | ||||
| 
 | ||||
| 	os_free(buf); | ||||
| 
 | ||||
|  | @ -279,55 +261,6 @@ static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len, | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static u8 * eap_fast_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, | ||||
| 				char *label, size_t len) | ||||
| { | ||||
| 	struct tls_keys keys; | ||||
| 	u8 *rnd = NULL, *out; | ||||
| 	int block_size; | ||||
| 
 | ||||
| 	block_size = tls_connection_get_keyblock_size(sm->ssl_ctx, data->conn); | ||||
| 	if (block_size < 0) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	out = os_malloc(block_size + len); | ||||
| 	if (out == NULL) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 1, out, | ||||
| 			       block_size + len) == 0) { | ||||
| 		os_memmove(out, out + block_size, len); | ||||
| 		return out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys)) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	rnd = os_malloc(keys.client_random_len + keys.server_random_len); | ||||
| 	if (rnd == NULL) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	os_memcpy(rnd, keys.server_random, keys.server_random_len); | ||||
| 	os_memcpy(rnd + keys.server_random_len, keys.client_random, | ||||
| 		  keys.client_random_len); | ||||
| 
 | ||||
| 	wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: master_secret for key " | ||||
| 			"expansion", keys.master_key, keys.master_key_len); | ||||
| 	if (tls_prf(keys.master_key, keys.master_key_len, | ||||
| 		    label, rnd, keys.client_random_len + | ||||
| 		    keys.server_random_len, out, block_size + len)) | ||||
| 		goto fail; | ||||
| 	os_free(rnd); | ||||
| 	os_memmove(out, out + block_size, len); | ||||
| 	return out; | ||||
| 
 | ||||
| fail: | ||||
| 	os_free(rnd); | ||||
| 	os_free(out); | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void eap_fast_derive_key_auth(struct eap_sm *sm, | ||||
| 				     struct eap_fast_data *data) | ||||
| { | ||||
|  | @ -337,7 +270,7 @@ static void eap_fast_derive_key_auth(struct eap_sm *sm, | |||
| 	 * Extra key material after TLS key_block: session_key_seed[40] | ||||
| 	 */ | ||||
| 
 | ||||
| 	sks = eap_fast_derive_key(sm, &data->ssl, "key expansion", | ||||
| 	sks = eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, "key expansion", | ||||
| 				  EAP_FAST_SKS_LEN); | ||||
| 	if (sks == NULL) { | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive " | ||||
|  | @ -363,7 +296,8 @@ static void eap_fast_derive_key_provisioning(struct eap_sm *sm, | |||
| { | ||||
| 	os_free(data->key_block_p); | ||||
| 	data->key_block_p = (struct eap_fast_key_block_provisioning *) | ||||
| 		eap_fast_derive_key(sm, &data->ssl, "key expansion", | ||||
| 		eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, | ||||
| 				    "key expansion", | ||||
| 				    sizeof(*data->key_block_p)); | ||||
| 	if (data->key_block_p == NULL) { | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive key block"); | ||||
|  | @ -653,30 +587,6 @@ static struct wpabuf * eap_fast_encrypt(struct eap_sm *sm, | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static struct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf) | ||||
| { | ||||
| 	struct wpabuf *e; | ||||
| 
 | ||||
| 	if (buf == NULL) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	/* Encapsulate EAP packet in EAP-Payload TLV */ | ||||
| 	wpa_printf(MSG_DEBUG, "EAP-FAST: Add EAP-Payload TLV"); | ||||
| 	e = wpabuf_alloc(sizeof(struct pac_tlv_hdr) + wpabuf_len(buf)); | ||||
| 	if (e == NULL) { | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory " | ||||
| 			   "for TLV encapsulation"); | ||||
| 		wpabuf_free(buf); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	eap_fast_put_tlv_buf(e, | ||||
| 			     EAP_TLV_TYPE_MANDATORY | EAP_TLV_EAP_PAYLOAD_TLV, | ||||
| 			     buf); | ||||
| 	wpabuf_free(buf); | ||||
| 	return e; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static struct wpabuf * eap_fast_build_phase2_req(struct eap_sm *sm, | ||||
| 						 struct eap_fast_data *data, | ||||
| 						 u8 id) | ||||
|  | @ -1121,144 +1031,6 @@ static void eap_fast_process_phase2_eap(struct eap_sm *sm, | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| struct eap_fast_tlv_parse { | ||||
| 	u8 *eap_payload_tlv; | ||||
| 	size_t eap_payload_tlv_len; | ||||
| 	struct eap_tlv_crypto_binding__tlv *crypto_binding; | ||||
| 	size_t crypto_binding_len; | ||||
| 	int iresult; | ||||
| 	int result; | ||||
| 	int request_action; | ||||
| 	u8 *pac; | ||||
| 	size_t pac_len; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| static int eap_fast_parse_tlv(struct eap_fast_tlv_parse *tlv, | ||||
| 			      int tlv_type, u8 *pos, int len) | ||||
| { | ||||
| 	switch (tlv_type) { | ||||
| 	case EAP_TLV_EAP_PAYLOAD_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: EAP-Payload TLV", | ||||
| 			    pos, len); | ||||
| 		if (tlv->eap_payload_tlv) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " | ||||
| 				   "EAP-Payload TLV in the message"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		tlv->eap_payload_tlv = pos; | ||||
| 		tlv->eap_payload_tlv_len = len; | ||||
| 		break; | ||||
| 	case EAP_TLV_RESULT_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Result TLV", pos, len); | ||||
| 		if (tlv->result) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " | ||||
| 				   "Result TLV in the message"); | ||||
| 			tlv->result = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		if (len < 2) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " | ||||
| 				   "Result TLV"); | ||||
| 			tlv->result = EAP_TLV_RESULT_FAILURE; | ||||
| 			break; | ||||
| 		} | ||||
| 		tlv->result = WPA_GET_BE16(pos); | ||||
| 		if (tlv->result != EAP_TLV_RESULT_SUCCESS && | ||||
| 		    tlv->result != EAP_TLV_RESULT_FAILURE) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown Result %d", | ||||
| 				   tlv->result); | ||||
| 			tlv->result = EAP_TLV_RESULT_FAILURE; | ||||
| 		} | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Result: %s", | ||||
| 			   tlv->result == EAP_TLV_RESULT_SUCCESS ? | ||||
| 			   "Success" : "Failure"); | ||||
| 		break; | ||||
| 	case EAP_TLV_INTERMEDIATE_RESULT_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Intermediate Result TLV", | ||||
| 			    pos, len); | ||||
| 		if (len < 2) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " | ||||
| 				   "Intermediate-Result TLV"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			break; | ||||
| 		} | ||||
| 		if (tlv->iresult) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " | ||||
| 				   "Intermediate-Result TLV in the message"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		tlv->iresult = WPA_GET_BE16(pos); | ||||
| 		if (tlv->iresult != EAP_TLV_RESULT_SUCCESS && | ||||
| 		    tlv->iresult != EAP_TLV_RESULT_FAILURE) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Unknown Intermediate " | ||||
| 				   "Result %d", tlv->iresult); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 		} | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Intermediate Result: %s", | ||||
| 			   tlv->iresult == EAP_TLV_RESULT_SUCCESS ? | ||||
| 			   "Success" : "Failure"); | ||||
| 		break; | ||||
| 	case EAP_TLV_CRYPTO_BINDING_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV", | ||||
| 			    pos, len); | ||||
| 		if (tlv->crypto_binding) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " | ||||
| 				   "Crypto-Binding TLV in the message"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		tlv->crypto_binding_len = sizeof(struct eap_tlv_hdr) + len; | ||||
| 		if (tlv->crypto_binding_len < sizeof(*tlv->crypto_binding)) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " | ||||
| 				   "Crypto-Binding TLV"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		tlv->crypto_binding = (struct eap_tlv_crypto_binding__tlv *) | ||||
| 			(pos - sizeof(struct eap_tlv_hdr)); | ||||
| 		break; | ||||
| 	case EAP_TLV_REQUEST_ACTION_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Request-Action TLV", | ||||
| 			    pos, len); | ||||
| 		if (tlv->request_action) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " | ||||
| 				   "Request-Action TLV in the message"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		if (len < 2) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: Too short " | ||||
| 				   "Request-Action TLV"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			break; | ||||
| 		} | ||||
| 		tlv->request_action = WPA_GET_BE16(pos); | ||||
| 		wpa_printf(MSG_DEBUG, "EAP-FAST: Request-Action: %d", | ||||
| 			   tlv->request_action); | ||||
| 		break; | ||||
| 	case EAP_TLV_PAC_TLV: | ||||
| 		wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: PAC TLV", pos, len); | ||||
| 		if (tlv->pac) { | ||||
| 			wpa_printf(MSG_DEBUG, "EAP-FAST: More than one " | ||||
| 				   "PAC TLV in the message"); | ||||
| 			tlv->iresult = EAP_TLV_RESULT_FAILURE; | ||||
| 			return -2; | ||||
| 		} | ||||
| 		tlv->pac = pos; | ||||
| 		tlv->pac_len = len; | ||||
| 		break; | ||||
| 	default: | ||||
| 		/* Unknown TLV */ | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static int eap_fast_parse_tlvs(u8 *data, size_t data_len, | ||||
| 			       struct eap_fast_tlv_parse *tlv) | ||||
| { | ||||
|  | @ -1696,20 +1468,11 @@ static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len) | |||
| 	if (data->state != SUCCESS) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * RFC 4851, Section 5.4: EAP Master Session Key Genreration | ||||
| 	 * MSK = T-PRF(S-IMCK[j], "Session Key Generating Function", 64) | ||||
| 	 */ | ||||
| 
 | ||||
| 	eapKeyData = os_malloc(EAP_FAST_KEY_LEN); | ||||
| 	if (eapKeyData == NULL) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	sha1_t_prf(data->simck, EAP_FAST_SIMCK_LEN, | ||||
| 		   "Session Key Generating Function", (u8 *) "", 0, | ||||
| 		   eapKeyData, EAP_FAST_KEY_LEN); | ||||
| 	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (MSK)", | ||||
| 			eapKeyData, EAP_FAST_KEY_LEN); | ||||
| 	eap_fast_derive_eap_msk(data->simck, eapKeyData); | ||||
| 	*len = EAP_FAST_KEY_LEN; | ||||
| 
 | ||||
| 	return eapKeyData; | ||||
|  | @ -1724,22 +1487,11 @@ static u8 * eap_fast_get_emsk(struct eap_sm *sm, void *priv, size_t *len) | |||
| 	if (data->state != SUCCESS) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * RFC 4851, Section 5.4: EAP Master Session Key Genreration | ||||
| 	 * EMSK = T-PRF(S-IMCK[j], | ||||
| 	 *        "Extended Session Key Generating Function", 64) | ||||
| 	 */ | ||||
| 
 | ||||
| 	eapKeyData = os_malloc(EAP_EMSK_LEN); | ||||
| 	if (eapKeyData == NULL) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	sha1_t_prf(data->simck, EAP_FAST_SIMCK_LEN, | ||||
| 		   "Extended Session Key Generating Function", | ||||
| 		   (u8 *) "", 0, eapKeyData, EAP_EMSK_LEN); | ||||
| 	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Derived key (EMSK)", | ||||
| 			eapKeyData, EAP_EMSK_LEN); | ||||
| 
 | ||||
| 	eap_fast_derive_eap_emsk(data->simck, eapKeyData); | ||||
| 	*len = EAP_EMSK_LEN; | ||||
| 
 | ||||
| 	return eapKeyData; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Jouni Malinen
						Jouni Malinen