<commit_before>/*	$OpenBSD: ieee80211_pae_output.c,v 1.9 2008/08/12 19:29:07 damien Exp $	*/

/*-
 * Copyright (c) 2007,2008 <NAME> <<EMAIL>>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This code implements the 4-Way Handshake and Group Key Handshake protocols
 * (both Supplicant and Authenticator Key Transmit state machines) defined in
 * IEEE Std 802.11-2007 section 8.5.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/endian.h>
#include <sys/errno.h>
#include <sys/proc.h>

#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/if_arp.h>
#include <net/if_llc.h>
#include <net/bpf.h>

#ifdef INET
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#endif

#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_priv.h>

int		ieee80211_send_eapol_key(struct ieee80211com *, struct mbuf *,
		    struct ieee80211_node *, const struct ieee80211_ptk *);
u_int8_t	*ieee80211_add_gtk_kde(u_int8_t *, struct ieee80211_node *,
		    const struct ieee80211_key *);
u_int8_t	*ieee80211_add_pmkid_kde(u_int8_t *, const u_int8_t *);
u_int8_t	*ieee80211_add_igtk_kde(u_int8_t *,
		    const struct ieee80211_key *);
struct mbuf 	*ieee80211_get_eapol_key(int, int, u_int);

/*
 * Send an EAPOL-Key frame to node `ni'.  If MIC or encryption is required,
 * the PTK must be passed (otherwise it can be set to NULL.)
 */
int
ieee80211_send_eapol_key(struct ieee80211com *ic, struct mbuf *m,
    struct ieee80211_node *ni, const struct ieee80211_ptk *ptk)
{
	struct ifnet *ifp = &ic->ic_if;
	struct ether_header *eh;
	struct ieee80211_eapol_key *key;
	u_int16_t info;
	int s, len, error;

	M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
	if (m == NULL)
		return ENOMEM;
	/* no need to m_pullup here (ok by construction) */
	eh = mtod(m, struct ether_header *);
	eh->ether_type = htons(ETHERTYPE_PAE);
	IEEE80211_ADDR_COPY(eh->ether_shost, ic->ic_myaddr);
	IEEE80211_ADDR_COPY(eh->ether_dhost, ni->ni_macaddr);

	key = (struct ieee80211_eapol_key *)&eh[1];
	key->version = EAPOL_VERSION;
	key->type = EAPOL_KEY;
	key->desc = (ni->ni_rsnprotos == IEEE80211_PROTO_RSN) ?
	    EAPOL_KEY_DESC_IEEE80211 : EAPOL_KEY_DESC_WPA;

	info = BE_READ_2(key->info);
	/* use V3 descriptor if KDF is SHA256-based */
	if (ni->ni_rsnakms == IEEE80211_AKM_SHA256_8021X ||
	    ni->ni_rsnakms == IEEE80211_AKM_SHA256_PSK)
		info |= EAPOL_KEY_DESC_V3;
	/* use V2 descriptor if pairwise or group cipher is CCMP */
	else if (ni->ni_rsncipher == IEEE80211_CIPHER_CCMP ||
	    ni->ni_rsngroupcipher == IEEE80211_CIPHER_CCMP)
		info |= EAPOL_KEY_DESC_V2;
	else
		info |= EAPOL_KEY_DESC_V1;
	BE_WRITE_2(key->info, info);

	len = m->m_len - sizeof(struct ether_header);
	BE_WRITE_2(key->paylen, len - sizeof(*key));
	BE_WRITE_2(key->len, len - 4);

	if (info & EAPOL_KEY_ENCRYPTED) {
		if (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) {
			/* clear "Encrypted" bit for WPA */
			info &= ~EAPOL_KEY_ENCRYPTED;
			BE_WRITE_2(key->info, info);
		}
		ieee80211_eapol_key_encrypt(ic, key, ptk->kek);

		if ((info & EAPOL_KEY_VERSION_MASK) == EAPOL_KEY_DESC_V2) {
			/* AES Key Wrap adds 8 bytes + padding */
			m->m_pkthdr.len = m->m_len =
			    sizeof(*eh) + 4 + BE_READ_2(key->len);
		}
	}
	if (info & EAPOL_KEY_KEYMIC)
		ieee80211_eapol_key_mic(key, ptk->kck);

	len = m->m_pkthdr.len;<commit_msg>v3 descriptors use AES Key Wrap too.<commit_after>/*	$OpenBSD: ieee80211_pae_output.c,v 1.10 2008/08/12 19:34:35 damien Exp $	*/

/*-
 * Copyright (c) 2007,2008 <NAME> <<EMAIL>>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This code implements the 4-Way Handshake and Group Key Handshake protocols
 * (both Supplicant and Authenticator Key Transmit state machines) defined in
 * IEEE Std 802.11-2007 section 8.5.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/endian.h>
#include <sys/errno.h>
#include <sys/proc.h>

#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/if_arp.h>
#include <net/if_llc.h>
#include <net/bpf.h>

#ifdef INET
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#endif

#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_priv.h>

int		ieee80211_send_eapol_key(struct ieee80211com *, struct mbuf *,
		    struct ieee80211_node *, const struct ieee80211_ptk *);
u_int8_t	*ieee80211_add_gtk_kde(u_int8_t *, struct ieee80211_node *,
		    const struct ieee80211_key *);
u_int8_t	*ieee80211_add_pmkid_kde(u_int8_t *, const u_int8_t *);
u_int8_t	*ieee80211_add_igtk_kde(u_int8_t *,
		    const struct ieee80211_key *);
struct mbuf 	*ieee80211_get_eapol_key(int, int, u_int);

/*
 * Send an EAPOL-Key frame to node `ni'.  If MIC or encryption is required,
 * the PTK must be passed (otherwise it can be set to NULL.)
 */
int
ieee80211_send_eapol_key(struct ieee80211com *ic, struct mbuf *m,
    struct ieee80211_node *ni, const struct ieee80211_ptk *ptk)
{
	struct ifnet *ifp = &ic->ic_if;
	struct ether_header *eh;
	struct ieee80211_eapol_key *key;
	u_int16_t info;
	int s, len, error;

	M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
	if (m == NULL)
		return ENOMEM;
	/* no need to m_pullup here (ok by construction) */
	eh = mtod(m, struct ether_header *);
	eh->ether_type = htons(ETHERTYPE_PAE);
	IEEE80211_ADDR_COPY(eh->ether_shost, ic->ic_myaddr);
	IEEE80211_ADDR_COPY(eh->ether_dhost, ni->ni_macaddr);

	key = (struct ieee80211_eapol_key *)&eh[1];
	key->version = EAPOL_VERSION;
	key->type = EAPOL_KEY;
	key->desc = (ni->ni_rsnprotos == IEEE80211_PROTO_RSN) ?
	    EAPOL_KEY_DESC_IEEE80211 : EAPOL_KEY_DESC_WPA;

	info = BE_READ_2(key->info);
	/* use V3 descriptor if KDF is SHA256-based */
	if (ni->ni_rsnakms == IEEE80211_AKM_SHA256_8021X ||
	    ni->ni_rsnakms == IEEE80211_AKM_SHA256_PSK)
		info |= EAPOL_KEY_DESC_V3;
	/* use V2 descriptor if pairwise or group cipher is CCMP */
	else if (ni->ni_rsncipher == IEEE80211_CIPHER_CCMP ||
	    ni->ni_rsngroupcipher == IEEE80211_CIPHER_CCMP)
		info |= EAPOL_KEY_DESC_V2;
	else
		info |= EAPOL_KEY_DESC_V1;
	BE_WRITE_2(key->info, info);

	len = m->m_len - sizeof(struct ether_header);
	BE_WRITE_2(key->paylen, len - sizeof(*key));
	BE_WRITE_2(key->len, len - 4);

	if (info & EAPOL_KEY_ENCRYPTED) {
		if (ni->ni_rsnprotos == IEEE80211_PROTO_WPA) {
			/* clear "Encrypted" bit for WPA */
			info &= ~EAPOL_KEY_ENCRYPTED;
			BE_WRITE_2(key->info, info);
		}
		ieee80211_eapol_key_encrypt(ic, key, ptk->kek);

		if ((info & EAPOL_KEY_VERSION_MASK) != EAPOL_KEY_DESC_V1) {
			/* AES Key Wrap adds 8 bytes + padding */
			m->m_pkthdr.len = m->m_len =
			    sizeof(*eh) + 4 + BE_READ_2(key->len);
		}
	}
	if (info & EAPOL_KEY_KEYMIC)
		ieee80211_eapol_key_mic(key, ptk->kck);

	len = m->m_pkthdr.len;
{'fraction_non_alphanumeric': 0.11778097292115984, 'fraction_numerical': 0.05751258087706686, 'mean_word_length': 4.469855832241153, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7126513', 'n_tokens_mistral': 3758, 'n_tokens_neox': 3229, 'n_words': 827}