mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-05-13 13:09:43 +08:00
Import wpa from FreeBSD
This commit is contained in:
parent
847de24eb0
commit
9c9d11b481
692
freebsd/contrib/wpa/src/ap/ap_config.h
Normal file
692
freebsd/contrib/wpa/src/ap/ap_config.h
Normal file
@ -0,0 +1,692 @@
|
||||
/*
|
||||
* hostapd / Configuration definitions and helpers functions
|
||||
* Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef HOSTAPD_CONFIG_H
|
||||
#define HOSTAPD_CONFIG_H
|
||||
|
||||
#include "common/defs.h"
|
||||
#include "ip_addr.h"
|
||||
#include "common/wpa_common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/ieee802_11_common.h"
|
||||
#include "wps/wps.h"
|
||||
#include "fst/fst.h"
|
||||
|
||||
/**
|
||||
* mesh_conf - local MBSS state and settings
|
||||
*/
|
||||
struct mesh_conf {
|
||||
u8 meshid[32];
|
||||
u8 meshid_len;
|
||||
/* Active Path Selection Protocol Identifier */
|
||||
u8 mesh_pp_id;
|
||||
/* Active Path Selection Metric Identifier */
|
||||
u8 mesh_pm_id;
|
||||
/* Congestion Control Mode Identifier */
|
||||
u8 mesh_cc_id;
|
||||
/* Synchronization Protocol Identifier */
|
||||
u8 mesh_sp_id;
|
||||
/* Authentication Protocol Identifier */
|
||||
u8 mesh_auth_id;
|
||||
u8 *rsn_ie;
|
||||
int rsn_ie_len;
|
||||
#define MESH_CONF_SEC_NONE BIT(0)
|
||||
#define MESH_CONF_SEC_AUTH BIT(1)
|
||||
#define MESH_CONF_SEC_AMPE BIT(2)
|
||||
unsigned int security;
|
||||
int dot11MeshMaxRetries;
|
||||
int dot11MeshRetryTimeout; /* msec */
|
||||
int dot11MeshConfirmTimeout; /* msec */
|
||||
int dot11MeshHoldingTimeout; /* msec */
|
||||
};
|
||||
|
||||
#define MAX_STA_COUNT 2007
|
||||
#define MAX_VLAN_ID 4094
|
||||
|
||||
typedef u8 macaddr[ETH_ALEN];
|
||||
|
||||
struct mac_acl_entry {
|
||||
macaddr addr;
|
||||
int vlan_id;
|
||||
};
|
||||
|
||||
struct hostapd_radius_servers;
|
||||
struct ft_remote_r0kh;
|
||||
struct ft_remote_r1kh;
|
||||
|
||||
#define NUM_WEP_KEYS 4
|
||||
struct hostapd_wep_keys {
|
||||
u8 idx;
|
||||
u8 *key[NUM_WEP_KEYS];
|
||||
size_t len[NUM_WEP_KEYS];
|
||||
int keys_set;
|
||||
size_t default_len; /* key length used for dynamic key generation */
|
||||
};
|
||||
|
||||
typedef enum hostap_security_policy {
|
||||
SECURITY_PLAINTEXT = 0,
|
||||
SECURITY_STATIC_WEP = 1,
|
||||
SECURITY_IEEE_802_1X = 2,
|
||||
SECURITY_WPA_PSK = 3,
|
||||
SECURITY_WPA = 4,
|
||||
SECURITY_OSEN = 5
|
||||
} secpolicy;
|
||||
|
||||
struct hostapd_ssid {
|
||||
u8 ssid[SSID_MAX_LEN];
|
||||
size_t ssid_len;
|
||||
unsigned int ssid_set:1;
|
||||
unsigned int utf8_ssid:1;
|
||||
unsigned int wpa_passphrase_set:1;
|
||||
unsigned int wpa_psk_set:1;
|
||||
|
||||
char vlan[IFNAMSIZ + 1];
|
||||
secpolicy security_policy;
|
||||
|
||||
struct hostapd_wpa_psk *wpa_psk;
|
||||
char *wpa_passphrase;
|
||||
char *wpa_psk_file;
|
||||
|
||||
struct hostapd_wep_keys wep;
|
||||
|
||||
#define DYNAMIC_VLAN_DISABLED 0
|
||||
#define DYNAMIC_VLAN_OPTIONAL 1
|
||||
#define DYNAMIC_VLAN_REQUIRED 2
|
||||
int dynamic_vlan;
|
||||
#define DYNAMIC_VLAN_NAMING_WITHOUT_DEVICE 0
|
||||
#define DYNAMIC_VLAN_NAMING_WITH_DEVICE 1
|
||||
#define DYNAMIC_VLAN_NAMING_END 2
|
||||
int vlan_naming;
|
||||
#ifdef CONFIG_FULL_DYNAMIC_VLAN
|
||||
char *vlan_tagged_interface;
|
||||
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
|
||||
};
|
||||
|
||||
|
||||
#define VLAN_ID_WILDCARD -1
|
||||
|
||||
struct hostapd_vlan {
|
||||
struct hostapd_vlan *next;
|
||||
int vlan_id; /* VLAN ID or -1 (VLAN_ID_WILDCARD) for wildcard entry */
|
||||
char ifname[IFNAMSIZ + 1];
|
||||
int configured;
|
||||
int dynamic_vlan;
|
||||
#ifdef CONFIG_FULL_DYNAMIC_VLAN
|
||||
|
||||
#define DVLAN_CLEAN_WLAN_PORT 0x8
|
||||
int clean;
|
||||
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
|
||||
};
|
||||
|
||||
#define PMK_LEN 32
|
||||
struct hostapd_sta_wpa_psk_short {
|
||||
struct hostapd_sta_wpa_psk_short *next;
|
||||
u8 psk[PMK_LEN];
|
||||
};
|
||||
|
||||
struct hostapd_wpa_psk {
|
||||
struct hostapd_wpa_psk *next;
|
||||
int group;
|
||||
u8 psk[PMK_LEN];
|
||||
u8 addr[ETH_ALEN];
|
||||
u8 p2p_dev_addr[ETH_ALEN];
|
||||
};
|
||||
|
||||
struct hostapd_eap_user {
|
||||
struct hostapd_eap_user *next;
|
||||
u8 *identity;
|
||||
size_t identity_len;
|
||||
struct {
|
||||
int vendor;
|
||||
u32 method;
|
||||
} methods[EAP_MAX_METHODS];
|
||||
u8 *password;
|
||||
size_t password_len;
|
||||
int phase2;
|
||||
int force_version;
|
||||
unsigned int wildcard_prefix:1;
|
||||
unsigned int password_hash:1; /* whether password is hashed with
|
||||
* nt_password_hash() */
|
||||
unsigned int remediation:1;
|
||||
unsigned int macacl:1;
|
||||
int ttls_auth; /* EAP_TTLS_AUTH_* bitfield */
|
||||
struct hostapd_radius_attr *accept_attr;
|
||||
};
|
||||
|
||||
struct hostapd_radius_attr {
|
||||
u8 type;
|
||||
struct wpabuf *val;
|
||||
struct hostapd_radius_attr *next;
|
||||
};
|
||||
|
||||
|
||||
#define NUM_TX_QUEUES 4
|
||||
|
||||
struct hostapd_tx_queue_params {
|
||||
int aifs;
|
||||
int cwmin;
|
||||
int cwmax;
|
||||
int burst; /* maximum burst time in 0.1 ms, i.e., 10 = 1 ms */
|
||||
};
|
||||
|
||||
|
||||
#define MAX_ROAMING_CONSORTIUM_LEN 15
|
||||
|
||||
struct hostapd_roaming_consortium {
|
||||
u8 len;
|
||||
u8 oi[MAX_ROAMING_CONSORTIUM_LEN];
|
||||
};
|
||||
|
||||
struct hostapd_lang_string {
|
||||
u8 lang[3];
|
||||
u8 name_len;
|
||||
u8 name[252];
|
||||
};
|
||||
|
||||
#define MAX_NAI_REALMS 10
|
||||
#define MAX_NAI_REALMLEN 255
|
||||
#define MAX_NAI_EAP_METHODS 5
|
||||
#define MAX_NAI_AUTH_TYPES 4
|
||||
struct hostapd_nai_realm_data {
|
||||
u8 encoding;
|
||||
char realm_buf[MAX_NAI_REALMLEN + 1];
|
||||
char *realm[MAX_NAI_REALMS];
|
||||
u8 eap_method_count;
|
||||
struct hostapd_nai_realm_eap {
|
||||
u8 eap_method;
|
||||
u8 num_auths;
|
||||
u8 auth_id[MAX_NAI_AUTH_TYPES];
|
||||
u8 auth_val[MAX_NAI_AUTH_TYPES];
|
||||
} eap_method[MAX_NAI_EAP_METHODS];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hostapd_bss_config - Per-BSS configuration
|
||||
*/
|
||||
struct hostapd_bss_config {
|
||||
char iface[IFNAMSIZ + 1];
|
||||
char bridge[IFNAMSIZ + 1];
|
||||
char vlan_bridge[IFNAMSIZ + 1];
|
||||
char wds_bridge[IFNAMSIZ + 1];
|
||||
|
||||
enum hostapd_logger_level logger_syslog_level, logger_stdout_level;
|
||||
|
||||
unsigned int logger_syslog; /* module bitfield */
|
||||
unsigned int logger_stdout; /* module bitfield */
|
||||
|
||||
int max_num_sta; /* maximum number of STAs in station table */
|
||||
|
||||
int dtim_period;
|
||||
int bss_load_update_period;
|
||||
|
||||
int ieee802_1x; /* use IEEE 802.1X */
|
||||
int eapol_version;
|
||||
int eap_server; /* Use internal EAP server instead of external
|
||||
* RADIUS server */
|
||||
struct hostapd_eap_user *eap_user;
|
||||
char *eap_user_sqlite;
|
||||
char *eap_sim_db;
|
||||
int eap_server_erp; /* Whether ERP is enabled on internal EAP server */
|
||||
struct hostapd_ip_addr own_ip_addr;
|
||||
char *nas_identifier;
|
||||
struct hostapd_radius_servers *radius;
|
||||
int acct_interim_interval;
|
||||
int radius_request_cui;
|
||||
struct hostapd_radius_attr *radius_auth_req_attr;
|
||||
struct hostapd_radius_attr *radius_acct_req_attr;
|
||||
int radius_das_port;
|
||||
unsigned int radius_das_time_window;
|
||||
int radius_das_require_event_timestamp;
|
||||
struct hostapd_ip_addr radius_das_client_addr;
|
||||
u8 *radius_das_shared_secret;
|
||||
size_t radius_das_shared_secret_len;
|
||||
|
||||
struct hostapd_ssid ssid;
|
||||
|
||||
char *eap_req_id_text; /* optional displayable message sent with
|
||||
* EAP Request-Identity */
|
||||
size_t eap_req_id_text_len;
|
||||
int eapol_key_index_workaround;
|
||||
|
||||
size_t default_wep_key_len;
|
||||
int individual_wep_key_len;
|
||||
int wep_rekeying_period;
|
||||
int broadcast_key_idx_min, broadcast_key_idx_max;
|
||||
int eap_reauth_period;
|
||||
int erp_send_reauth_start;
|
||||
char *erp_domain;
|
||||
|
||||
int ieee802_11f; /* use IEEE 802.11f (IAPP) */
|
||||
char iapp_iface[IFNAMSIZ + 1]; /* interface used with IAPP broadcast
|
||||
* frames */
|
||||
|
||||
enum {
|
||||
ACCEPT_UNLESS_DENIED = 0,
|
||||
DENY_UNLESS_ACCEPTED = 1,
|
||||
USE_EXTERNAL_RADIUS_AUTH = 2
|
||||
} macaddr_acl;
|
||||
struct mac_acl_entry *accept_mac;
|
||||
int num_accept_mac;
|
||||
struct mac_acl_entry *deny_mac;
|
||||
int num_deny_mac;
|
||||
int wds_sta;
|
||||
int isolate;
|
||||
int start_disabled;
|
||||
|
||||
int auth_algs; /* bitfield of allowed IEEE 802.11 authentication
|
||||
* algorithms, WPA_AUTH_ALG_{OPEN,SHARED,LEAP} */
|
||||
|
||||
int wpa; /* bitfield of WPA_PROTO_WPA, WPA_PROTO_RSN */
|
||||
int wpa_key_mgmt;
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
enum mfp_options ieee80211w;
|
||||
int group_mgmt_cipher;
|
||||
/* dot11AssociationSAQueryMaximumTimeout (in TUs) */
|
||||
unsigned int assoc_sa_query_max_timeout;
|
||||
/* dot11AssociationSAQueryRetryTimeout (in TUs) */
|
||||
int assoc_sa_query_retry_timeout;
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
enum {
|
||||
PSK_RADIUS_IGNORED = 0,
|
||||
PSK_RADIUS_ACCEPTED = 1,
|
||||
PSK_RADIUS_REQUIRED = 2
|
||||
} wpa_psk_radius;
|
||||
int wpa_pairwise;
|
||||
int wpa_group;
|
||||
int wpa_group_rekey;
|
||||
int wpa_strict_rekey;
|
||||
int wpa_gmk_rekey;
|
||||
int wpa_ptk_rekey;
|
||||
int rsn_pairwise;
|
||||
int rsn_preauth;
|
||||
char *rsn_preauth_interfaces;
|
||||
int peerkey;
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
/* IEEE 802.11r - Fast BSS Transition */
|
||||
u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN];
|
||||
u8 r1_key_holder[FT_R1KH_ID_LEN];
|
||||
u32 r0_key_lifetime;
|
||||
u32 reassociation_deadline;
|
||||
struct ft_remote_r0kh *r0kh_list;
|
||||
struct ft_remote_r1kh *r1kh_list;
|
||||
int pmk_r1_push;
|
||||
int ft_over_ds;
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
|
||||
char *ctrl_interface; /* directory for UNIX domain sockets */
|
||||
#ifndef CONFIG_NATIVE_WINDOWS
|
||||
gid_t ctrl_interface_gid;
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
int ctrl_interface_gid_set;
|
||||
|
||||
char *ca_cert;
|
||||
char *server_cert;
|
||||
char *private_key;
|
||||
char *private_key_passwd;
|
||||
int check_crl;
|
||||
unsigned int tls_session_lifetime;
|
||||
char *ocsp_stapling_response;
|
||||
char *dh_file;
|
||||
char *openssl_ciphers;
|
||||
u8 *pac_opaque_encr_key;
|
||||
u8 *eap_fast_a_id;
|
||||
size_t eap_fast_a_id_len;
|
||||
char *eap_fast_a_id_info;
|
||||
int eap_fast_prov;
|
||||
int pac_key_lifetime;
|
||||
int pac_key_refresh_time;
|
||||
int eap_sim_aka_result_ind;
|
||||
int tnc;
|
||||
int fragment_size;
|
||||
u16 pwd_group;
|
||||
|
||||
char *radius_server_clients;
|
||||
int radius_server_auth_port;
|
||||
int radius_server_acct_port;
|
||||
int radius_server_ipv6;
|
||||
|
||||
int use_pae_group_addr; /* Whether to send EAPOL frames to PAE group
|
||||
* address instead of individual address
|
||||
* (for driver_wired.c).
|
||||
*/
|
||||
|
||||
int ap_max_inactivity;
|
||||
int ignore_broadcast_ssid;
|
||||
|
||||
int wmm_enabled;
|
||||
int wmm_uapsd;
|
||||
|
||||
struct hostapd_vlan *vlan;
|
||||
|
||||
macaddr bssid;
|
||||
|
||||
/*
|
||||
* Maximum listen interval that STAs can use when associating with this
|
||||
* BSS. If a STA tries to use larger value, the association will be
|
||||
* denied with status code 51.
|
||||
*/
|
||||
u16 max_listen_interval;
|
||||
|
||||
int disable_pmksa_caching;
|
||||
int okc; /* Opportunistic Key Caching */
|
||||
|
||||
int wps_state;
|
||||
#ifdef CONFIG_WPS
|
||||
int wps_independent;
|
||||
int ap_setup_locked;
|
||||
u8 uuid[16];
|
||||
char *wps_pin_requests;
|
||||
char *device_name;
|
||||
char *manufacturer;
|
||||
char *model_name;
|
||||
char *model_number;
|
||||
char *serial_number;
|
||||
u8 device_type[WPS_DEV_TYPE_LEN];
|
||||
char *config_methods;
|
||||
u8 os_version[4];
|
||||
char *ap_pin;
|
||||
int skip_cred_build;
|
||||
u8 *extra_cred;
|
||||
size_t extra_cred_len;
|
||||
int wps_cred_processing;
|
||||
int force_per_enrollee_psk;
|
||||
u8 *ap_settings;
|
||||
size_t ap_settings_len;
|
||||
char *upnp_iface;
|
||||
char *friendly_name;
|
||||
char *manufacturer_url;
|
||||
char *model_description;
|
||||
char *model_url;
|
||||
char *upc;
|
||||
struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
|
||||
int wps_nfc_pw_from_config;
|
||||
int wps_nfc_dev_pw_id;
|
||||
struct wpabuf *wps_nfc_dh_pubkey;
|
||||
struct wpabuf *wps_nfc_dh_privkey;
|
||||
struct wpabuf *wps_nfc_dev_pw;
|
||||
#endif /* CONFIG_WPS */
|
||||
int pbc_in_m1;
|
||||
char *server_id;
|
||||
|
||||
#define P2P_ENABLED BIT(0)
|
||||
#define P2P_GROUP_OWNER BIT(1)
|
||||
#define P2P_GROUP_FORMATION BIT(2)
|
||||
#define P2P_MANAGE BIT(3)
|
||||
#define P2P_ALLOW_CROSS_CONNECTION BIT(4)
|
||||
int p2p;
|
||||
#ifdef CONFIG_P2P
|
||||
u8 ip_addr_go[4];
|
||||
u8 ip_addr_mask[4];
|
||||
u8 ip_addr_start[4];
|
||||
u8 ip_addr_end[4];
|
||||
#endif /* CONFIG_P2P */
|
||||
|
||||
int disassoc_low_ack;
|
||||
int skip_inactivity_poll;
|
||||
|
||||
#define TDLS_PROHIBIT BIT(0)
|
||||
#define TDLS_PROHIBIT_CHAN_SWITCH BIT(1)
|
||||
int tdls;
|
||||
int disable_11n;
|
||||
int disable_11ac;
|
||||
|
||||
/* IEEE 802.11v */
|
||||
int time_advertisement;
|
||||
char *time_zone;
|
||||
int wnm_sleep_mode;
|
||||
int bss_transition;
|
||||
|
||||
/* IEEE 802.11u - Interworking */
|
||||
int interworking;
|
||||
int access_network_type;
|
||||
int internet;
|
||||
int asra;
|
||||
int esr;
|
||||
int uesa;
|
||||
int venue_info_set;
|
||||
u8 venue_group;
|
||||
u8 venue_type;
|
||||
u8 hessid[ETH_ALEN];
|
||||
|
||||
/* IEEE 802.11u - Roaming Consortium list */
|
||||
unsigned int roaming_consortium_count;
|
||||
struct hostapd_roaming_consortium *roaming_consortium;
|
||||
|
||||
/* IEEE 802.11u - Venue Name duples */
|
||||
unsigned int venue_name_count;
|
||||
struct hostapd_lang_string *venue_name;
|
||||
|
||||
/* IEEE 802.11u - Network Authentication Type */
|
||||
u8 *network_auth_type;
|
||||
size_t network_auth_type_len;
|
||||
|
||||
/* IEEE 802.11u - IP Address Type Availability */
|
||||
u8 ipaddr_type_availability;
|
||||
u8 ipaddr_type_configured;
|
||||
|
||||
/* IEEE 802.11u - 3GPP Cellular Network */
|
||||
u8 *anqp_3gpp_cell_net;
|
||||
size_t anqp_3gpp_cell_net_len;
|
||||
|
||||
/* IEEE 802.11u - Domain Name */
|
||||
u8 *domain_name;
|
||||
size_t domain_name_len;
|
||||
|
||||
unsigned int nai_realm_count;
|
||||
struct hostapd_nai_realm_data *nai_realm_data;
|
||||
|
||||
u16 gas_comeback_delay;
|
||||
int gas_frag_limit;
|
||||
|
||||
u8 qos_map_set[16 + 2 * 21];
|
||||
unsigned int qos_map_set_len;
|
||||
|
||||
int osen;
|
||||
int proxy_arp;
|
||||
int na_mcast_to_ucast;
|
||||
#ifdef CONFIG_HS20
|
||||
int hs20;
|
||||
int disable_dgaf;
|
||||
u16 anqp_domain_id;
|
||||
unsigned int hs20_oper_friendly_name_count;
|
||||
struct hostapd_lang_string *hs20_oper_friendly_name;
|
||||
u8 *hs20_wan_metrics;
|
||||
u8 *hs20_connection_capability;
|
||||
size_t hs20_connection_capability_len;
|
||||
u8 *hs20_operating_class;
|
||||
u8 hs20_operating_class_len;
|
||||
struct hs20_icon {
|
||||
u16 width;
|
||||
u16 height;
|
||||
char language[3];
|
||||
char type[256];
|
||||
char name[256];
|
||||
char file[256];
|
||||
} *hs20_icons;
|
||||
size_t hs20_icons_count;
|
||||
u8 osu_ssid[SSID_MAX_LEN];
|
||||
size_t osu_ssid_len;
|
||||
struct hs20_osu_provider {
|
||||
unsigned int friendly_name_count;
|
||||
struct hostapd_lang_string *friendly_name;
|
||||
char *server_uri;
|
||||
int *method_list;
|
||||
char **icons;
|
||||
size_t icons_count;
|
||||
char *osu_nai;
|
||||
unsigned int service_desc_count;
|
||||
struct hostapd_lang_string *service_desc;
|
||||
} *hs20_osu_providers, *last_osu;
|
||||
size_t hs20_osu_providers_count;
|
||||
unsigned int hs20_deauth_req_timeout;
|
||||
char *subscr_remediation_url;
|
||||
u8 subscr_remediation_method;
|
||||
#endif /* CONFIG_HS20 */
|
||||
|
||||
u8 wps_rf_bands; /* RF bands for WPS (WPS_RF_*) */
|
||||
|
||||
#ifdef CONFIG_RADIUS_TEST
|
||||
char *dump_msk_file;
|
||||
#endif /* CONFIG_RADIUS_TEST */
|
||||
|
||||
struct wpabuf *vendor_elements;
|
||||
|
||||
unsigned int sae_anti_clogging_threshold;
|
||||
int *sae_groups;
|
||||
|
||||
char *wowlan_triggers; /* Wake-on-WLAN triggers */
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
u8 bss_load_test[5];
|
||||
u8 bss_load_test_set;
|
||||
struct wpabuf *own_ie_override;
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
|
||||
#define MESH_ENABLED BIT(0)
|
||||
int mesh;
|
||||
|
||||
int radio_measurements;
|
||||
|
||||
int vendor_vht;
|
||||
|
||||
char *no_probe_resp_if_seen_on;
|
||||
char *no_auth_if_seen_on;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct hostapd_config - Per-radio interface configuration
|
||||
*/
|
||||
struct hostapd_config {
|
||||
struct hostapd_bss_config **bss, *last_bss;
|
||||
size_t num_bss;
|
||||
|
||||
u16 beacon_int;
|
||||
int rts_threshold;
|
||||
int fragm_threshold;
|
||||
u8 send_probe_response;
|
||||
u8 channel;
|
||||
u8 acs;
|
||||
struct wpa_freq_range_list acs_ch_list;
|
||||
enum hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */
|
||||
enum {
|
||||
LONG_PREAMBLE = 0,
|
||||
SHORT_PREAMBLE = 1
|
||||
} preamble;
|
||||
|
||||
int *supported_rates;
|
||||
int *basic_rates;
|
||||
|
||||
const struct wpa_driver_ops *driver;
|
||||
char *driver_params;
|
||||
|
||||
int ap_table_max_size;
|
||||
int ap_table_expiration_time;
|
||||
|
||||
unsigned int track_sta_max_num;
|
||||
unsigned int track_sta_max_age;
|
||||
|
||||
char country[3]; /* first two octets: country code as described in
|
||||
* ISO/IEC 3166-1. Third octet:
|
||||
* ' ' (ascii 32): all environments
|
||||
* 'O': Outdoor environemnt only
|
||||
* 'I': Indoor environment only
|
||||
*/
|
||||
|
||||
int ieee80211d;
|
||||
|
||||
int ieee80211h; /* DFS */
|
||||
|
||||
/*
|
||||
* Local power constraint is an octet encoded as an unsigned integer in
|
||||
* units of decibels. Invalid value -1 indicates that Power Constraint
|
||||
* element will not be added.
|
||||
*/
|
||||
int local_pwr_constraint;
|
||||
|
||||
/* Control Spectrum Management bit */
|
||||
int spectrum_mgmt_required;
|
||||
|
||||
struct hostapd_tx_queue_params tx_queue[NUM_TX_QUEUES];
|
||||
|
||||
/*
|
||||
* WMM AC parameters, in same order as 802.1D, i.e.
|
||||
* 0 = BE (best effort)
|
||||
* 1 = BK (background)
|
||||
* 2 = VI (video)
|
||||
* 3 = VO (voice)
|
||||
*/
|
||||
struct hostapd_wmm_ac_params wmm_ac_params[4];
|
||||
|
||||
int ht_op_mode_fixed;
|
||||
u16 ht_capab;
|
||||
int ieee80211n;
|
||||
int secondary_channel;
|
||||
int no_pri_sec_switch;
|
||||
int require_ht;
|
||||
int obss_interval;
|
||||
u32 vht_capab;
|
||||
int ieee80211ac;
|
||||
int require_vht;
|
||||
u8 vht_oper_chwidth;
|
||||
u8 vht_oper_centr_freq_seg0_idx;
|
||||
u8 vht_oper_centr_freq_seg1_idx;
|
||||
|
||||
#ifdef CONFIG_FST
|
||||
struct fst_iface_cfg fst_cfg;
|
||||
#endif /* CONFIG_FST */
|
||||
|
||||
#ifdef CONFIG_P2P
|
||||
u8 p2p_go_ctwindow;
|
||||
#endif /* CONFIG_P2P */
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
double ignore_probe_probability;
|
||||
double ignore_auth_probability;
|
||||
double ignore_assoc_probability;
|
||||
double ignore_reassoc_probability;
|
||||
double corrupt_gtk_rekey_mic_probability;
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
|
||||
#ifdef CONFIG_ACS
|
||||
unsigned int acs_num_scans;
|
||||
struct acs_bias {
|
||||
int channel;
|
||||
double bias;
|
||||
} *acs_chan_bias;
|
||||
unsigned int num_acs_chan_bias;
|
||||
#endif /* CONFIG_ACS */
|
||||
};
|
||||
|
||||
|
||||
int hostapd_mac_comp(const void *a, const void *b);
|
||||
int hostapd_mac_comp_empty(const void *a);
|
||||
struct hostapd_config * hostapd_config_defaults(void);
|
||||
void hostapd_config_defaults_bss(struct hostapd_bss_config *bss);
|
||||
void hostapd_config_free_eap_user(struct hostapd_eap_user *user);
|
||||
void hostapd_config_clear_wpa_psk(struct hostapd_wpa_psk **p);
|
||||
void hostapd_config_free_bss(struct hostapd_bss_config *conf);
|
||||
void hostapd_config_free(struct hostapd_config *conf);
|
||||
int hostapd_maclist_found(struct mac_acl_entry *list, int num_entries,
|
||||
const u8 *addr, int *vlan_id);
|
||||
int hostapd_rate_found(int *list, int rate);
|
||||
const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
|
||||
const u8 *addr, const u8 *p2p_dev_addr,
|
||||
const u8 *prev_psk);
|
||||
int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf);
|
||||
int hostapd_vlan_id_valid(struct hostapd_vlan *vlan, int vlan_id);
|
||||
const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan,
|
||||
int vlan_id);
|
||||
struct hostapd_radius_attr *
|
||||
hostapd_config_get_radius_attr(struct hostapd_radius_attr *attr, u8 type);
|
||||
int hostapd_config_check(struct hostapd_config *conf, int full_config);
|
||||
void hostapd_set_security_params(struct hostapd_bss_config *bss,
|
||||
int full_config);
|
||||
|
||||
#endif /* HOSTAPD_CONFIG_H */
|
844
freebsd/contrib/wpa/src/ap/ap_drv_ops.c
Normal file
844
freebsd/contrib/wpa/src/ap/ap_drv_ops.c
Normal file
@ -0,0 +1,844 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* hostapd - Driver operations
|
||||
* Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/hw_features_common.h"
|
||||
#include "wps/wps.h"
|
||||
#include "p2p/p2p.h"
|
||||
#include "hostapd.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "sta_info.h"
|
||||
#include "ap_config.h"
|
||||
#include "p2p_hostapd.h"
|
||||
#include "hs20.h"
|
||||
#include "ap_drv_ops.h"
|
||||
|
||||
|
||||
u32 hostapd_sta_flags_to_drv(u32 flags)
|
||||
{
|
||||
int res = 0;
|
||||
if (flags & WLAN_STA_AUTHORIZED)
|
||||
res |= WPA_STA_AUTHORIZED;
|
||||
if (flags & WLAN_STA_WMM)
|
||||
res |= WPA_STA_WMM;
|
||||
if (flags & WLAN_STA_SHORT_PREAMBLE)
|
||||
res |= WPA_STA_SHORT_PREAMBLE;
|
||||
if (flags & WLAN_STA_MFP)
|
||||
res |= WPA_STA_MFP;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
|
||||
struct wpabuf **beacon_ret,
|
||||
struct wpabuf **proberesp_ret,
|
||||
struct wpabuf **assocresp_ret)
|
||||
{
|
||||
struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
|
||||
u8 buf[200], *pos;
|
||||
|
||||
*beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
|
||||
|
||||
pos = buf;
|
||||
pos = hostapd_eid_time_adv(hapd, pos);
|
||||
if (pos != buf) {
|
||||
if (wpabuf_resize(&beacon, pos - buf) != 0)
|
||||
goto fail;
|
||||
wpabuf_put_data(beacon, buf, pos - buf);
|
||||
}
|
||||
pos = hostapd_eid_time_zone(hapd, pos);
|
||||
if (pos != buf) {
|
||||
if (wpabuf_resize(&proberesp, pos - buf) != 0)
|
||||
goto fail;
|
||||
wpabuf_put_data(proberesp, buf, pos - buf);
|
||||
}
|
||||
|
||||
pos = buf;
|
||||
pos = hostapd_eid_ext_capab(hapd, pos);
|
||||
if (pos != buf) {
|
||||
if (wpabuf_resize(&assocresp, pos - buf) != 0)
|
||||
goto fail;
|
||||
wpabuf_put_data(assocresp, buf, pos - buf);
|
||||
}
|
||||
pos = hostapd_eid_interworking(hapd, pos);
|
||||
pos = hostapd_eid_adv_proto(hapd, pos);
|
||||
pos = hostapd_eid_roaming_consortium(hapd, pos);
|
||||
if (pos != buf) {
|
||||
if (wpabuf_resize(&beacon, pos - buf) != 0)
|
||||
goto fail;
|
||||
wpabuf_put_data(beacon, buf, pos - buf);
|
||||
|
||||
if (wpabuf_resize(&proberesp, pos - buf) != 0)
|
||||
goto fail;
|
||||
wpabuf_put_data(proberesp, buf, pos - buf);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FST
|
||||
if (hapd->iface->fst_ies) {
|
||||
size_t add = wpabuf_len(hapd->iface->fst_ies);
|
||||
|
||||
if (wpabuf_resize(&beacon, add) < 0)
|
||||
goto fail;
|
||||
wpabuf_put_buf(beacon, hapd->iface->fst_ies);
|
||||
if (wpabuf_resize(&proberesp, add) < 0)
|
||||
goto fail;
|
||||
wpabuf_put_buf(proberesp, hapd->iface->fst_ies);
|
||||
if (wpabuf_resize(&assocresp, add) < 0)
|
||||
goto fail;
|
||||
wpabuf_put_buf(assocresp, hapd->iface->fst_ies);
|
||||
}
|
||||
#endif /* CONFIG_FST */
|
||||
|
||||
if (hapd->wps_beacon_ie) {
|
||||
if (wpabuf_resize(&beacon, wpabuf_len(hapd->wps_beacon_ie)) <
|
||||
0)
|
||||
goto fail;
|
||||
wpabuf_put_buf(beacon, hapd->wps_beacon_ie);
|
||||
}
|
||||
|
||||
if (hapd->wps_probe_resp_ie) {
|
||||
if (wpabuf_resize(&proberesp,
|
||||
wpabuf_len(hapd->wps_probe_resp_ie)) < 0)
|
||||
goto fail;
|
||||
wpabuf_put_buf(proberesp, hapd->wps_probe_resp_ie);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_P2P
|
||||
if (hapd->p2p_beacon_ie) {
|
||||
if (wpabuf_resize(&beacon, wpabuf_len(hapd->p2p_beacon_ie)) <
|
||||
0)
|
||||
goto fail;
|
||||
wpabuf_put_buf(beacon, hapd->p2p_beacon_ie);
|
||||
}
|
||||
|
||||
if (hapd->p2p_probe_resp_ie) {
|
||||
if (wpabuf_resize(&proberesp,
|
||||
wpabuf_len(hapd->p2p_probe_resp_ie)) < 0)
|
||||
goto fail;
|
||||
wpabuf_put_buf(proberesp, hapd->p2p_probe_resp_ie);
|
||||
}
|
||||
#endif /* CONFIG_P2P */
|
||||
|
||||
#ifdef CONFIG_P2P_MANAGER
|
||||
if (hapd->conf->p2p & P2P_MANAGE) {
|
||||
if (wpabuf_resize(&beacon, 100) == 0) {
|
||||
u8 *start, *p;
|
||||
start = wpabuf_put(beacon, 0);
|
||||
p = hostapd_eid_p2p_manage(hapd, start);
|
||||
wpabuf_put(beacon, p - start);
|
||||
}
|
||||
|
||||
if (wpabuf_resize(&proberesp, 100) == 0) {
|
||||
u8 *start, *p;
|
||||
start = wpabuf_put(proberesp, 0);
|
||||
p = hostapd_eid_p2p_manage(hapd, start);
|
||||
wpabuf_put(proberesp, p - start);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_P2P_MANAGER */
|
||||
|
||||
#ifdef CONFIG_WPS
|
||||
if (hapd->conf->wps_state) {
|
||||
struct wpabuf *a = wps_build_assoc_resp_ie();
|
||||
if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0)
|
||||
wpabuf_put_buf(assocresp, a);
|
||||
wpabuf_free(a);
|
||||
}
|
||||
#endif /* CONFIG_WPS */
|
||||
|
||||
#ifdef CONFIG_P2P_MANAGER
|
||||
if (hapd->conf->p2p & P2P_MANAGE) {
|
||||
if (wpabuf_resize(&assocresp, 100) == 0) {
|
||||
u8 *start, *p;
|
||||
start = wpabuf_put(assocresp, 0);
|
||||
p = hostapd_eid_p2p_manage(hapd, start);
|
||||
wpabuf_put(assocresp, p - start);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_P2P_MANAGER */
|
||||
|
||||
#ifdef CONFIG_WIFI_DISPLAY
|
||||
if (hapd->p2p_group) {
|
||||
struct wpabuf *a;
|
||||
a = p2p_group_assoc_resp_ie(hapd->p2p_group, P2P_SC_SUCCESS);
|
||||
if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0)
|
||||
wpabuf_put_buf(assocresp, a);
|
||||
wpabuf_free(a);
|
||||
}
|
||||
#endif /* CONFIG_WIFI_DISPLAY */
|
||||
|
||||
#ifdef CONFIG_HS20
|
||||
pos = buf;
|
||||
pos = hostapd_eid_hs20_indication(hapd, pos);
|
||||
if (pos != buf) {
|
||||
if (wpabuf_resize(&beacon, pos - buf) != 0)
|
||||
goto fail;
|
||||
wpabuf_put_data(beacon, buf, pos - buf);
|
||||
|
||||
if (wpabuf_resize(&proberesp, pos - buf) != 0)
|
||||
goto fail;
|
||||
wpabuf_put_data(proberesp, buf, pos - buf);
|
||||
}
|
||||
|
||||
pos = hostapd_eid_osen(hapd, buf);
|
||||
if (pos != buf) {
|
||||
if (wpabuf_resize(&beacon, pos - buf) != 0)
|
||||
goto fail;
|
||||
wpabuf_put_data(beacon, buf, pos - buf);
|
||||
|
||||
if (wpabuf_resize(&proberesp, pos - buf) != 0)
|
||||
goto fail;
|
||||
wpabuf_put_data(proberesp, buf, pos - buf);
|
||||
}
|
||||
#endif /* CONFIG_HS20 */
|
||||
|
||||
if (hapd->conf->vendor_elements) {
|
||||
size_t add = wpabuf_len(hapd->conf->vendor_elements);
|
||||
if (wpabuf_resize(&beacon, add) == 0)
|
||||
wpabuf_put_buf(beacon, hapd->conf->vendor_elements);
|
||||
if (wpabuf_resize(&proberesp, add) == 0)
|
||||
wpabuf_put_buf(proberesp, hapd->conf->vendor_elements);
|
||||
}
|
||||
|
||||
*beacon_ret = beacon;
|
||||
*proberesp_ret = proberesp;
|
||||
*assocresp_ret = assocresp;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
wpabuf_free(beacon);
|
||||
wpabuf_free(proberesp);
|
||||
wpabuf_free(assocresp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void hostapd_free_ap_extra_ies(struct hostapd_data *hapd,
|
||||
struct wpabuf *beacon,
|
||||
struct wpabuf *proberesp,
|
||||
struct wpabuf *assocresp)
|
||||
{
|
||||
wpabuf_free(beacon);
|
||||
wpabuf_free(proberesp);
|
||||
wpabuf_free(assocresp);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_reset_ap_wps_ie(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
|
||||
return 0;
|
||||
|
||||
return hapd->driver->set_ap_wps_ie(hapd->drv_priv, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
|
||||
{
|
||||
struct wpabuf *beacon, *proberesp, *assocresp;
|
||||
int ret;
|
||||
|
||||
if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
|
||||
return 0;
|
||||
|
||||
if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
|
||||
0)
|
||||
return -1;
|
||||
|
||||
ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
|
||||
assocresp);
|
||||
|
||||
hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_authorized(struct hostapd_data *hapd,
|
||||
struct sta_info *sta, int authorized)
|
||||
{
|
||||
if (authorized) {
|
||||
return hostapd_sta_set_flags(hapd, sta->addr,
|
||||
hostapd_sta_flags_to_drv(
|
||||
sta->flags),
|
||||
WPA_STA_AUTHORIZED, ~0);
|
||||
}
|
||||
|
||||
return hostapd_sta_set_flags(hapd, sta->addr,
|
||||
hostapd_sta_flags_to_drv(sta->flags),
|
||||
0, ~WPA_STA_AUTHORIZED);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
{
|
||||
int set_flags, total_flags, flags_and, flags_or;
|
||||
total_flags = hostapd_sta_flags_to_drv(sta->flags);
|
||||
set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
|
||||
if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
|
||||
sta->auth_alg == WLAN_AUTH_FT) &&
|
||||
sta->flags & WLAN_STA_AUTHORIZED)
|
||||
set_flags |= WPA_STA_AUTHORIZED;
|
||||
flags_or = total_flags & set_flags;
|
||||
flags_and = total_flags | ~set_flags;
|
||||
return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
|
||||
flags_or, flags_and);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
|
||||
int enabled)
|
||||
{
|
||||
struct wpa_bss_params params;
|
||||
os_memset(¶ms, 0, sizeof(params));
|
||||
params.ifname = ifname;
|
||||
params.enabled = enabled;
|
||||
if (enabled) {
|
||||
params.wpa = hapd->conf->wpa;
|
||||
params.ieee802_1x = hapd->conf->ieee802_1x;
|
||||
params.wpa_group = hapd->conf->wpa_group;
|
||||
if ((hapd->conf->wpa & (WPA_PROTO_WPA | WPA_PROTO_RSN)) ==
|
||||
(WPA_PROTO_WPA | WPA_PROTO_RSN))
|
||||
params.wpa_pairwise = hapd->conf->wpa_pairwise |
|
||||
hapd->conf->rsn_pairwise;
|
||||
else if (hapd->conf->wpa & WPA_PROTO_RSN)
|
||||
params.wpa_pairwise = hapd->conf->rsn_pairwise;
|
||||
else if (hapd->conf->wpa & WPA_PROTO_WPA)
|
||||
params.wpa_pairwise = hapd->conf->wpa_pairwise;
|
||||
params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
|
||||
params.rsn_preauth = hapd->conf->rsn_preauth;
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
params.ieee80211w = hapd->conf->ieee80211w;
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
}
|
||||
return hostapd_set_ieee8021x(hapd, ¶ms);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
|
||||
{
|
||||
char force_ifname[IFNAMSIZ];
|
||||
u8 if_addr[ETH_ALEN];
|
||||
return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
|
||||
NULL, NULL, force_ifname, if_addr, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
|
||||
{
|
||||
return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
|
||||
const u8 *addr, int aid, int val)
|
||||
{
|
||||
const char *bridge = NULL;
|
||||
|
||||
if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
|
||||
return -1;
|
||||
if (hapd->conf->wds_bridge[0])
|
||||
bridge = hapd->conf->wds_bridge;
|
||||
else if (hapd->conf->bridge[0])
|
||||
bridge = hapd->conf->bridge;
|
||||
return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
|
||||
bridge, ifname_wds);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
|
||||
u16 auth_alg)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
|
||||
return 0;
|
||||
return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
|
||||
u16 seq, u16 status, const u8 *ie, size_t len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->sta_auth == NULL)
|
||||
return 0;
|
||||
return hapd->driver->sta_auth(hapd->drv_priv, hapd->own_addr, addr,
|
||||
seq, status, ie, len);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
|
||||
int reassoc, u16 status, const u8 *ie, size_t len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL)
|
||||
return 0;
|
||||
return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr,
|
||||
reassoc, status, ie, len);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_sta_add(struct hostapd_data *hapd,
|
||||
const u8 *addr, u16 aid, u16 capability,
|
||||
const u8 *supp_rates, size_t supp_rates_len,
|
||||
u16 listen_interval,
|
||||
const struct ieee80211_ht_capabilities *ht_capab,
|
||||
const struct ieee80211_vht_capabilities *vht_capab,
|
||||
u32 flags, u8 qosinfo, u8 vht_opmode)
|
||||
{
|
||||
struct hostapd_sta_add_params params;
|
||||
|
||||
if (hapd->driver == NULL)
|
||||
return 0;
|
||||
if (hapd->driver->sta_add == NULL)
|
||||
return 0;
|
||||
|
||||
os_memset(¶ms, 0, sizeof(params));
|
||||
params.addr = addr;
|
||||
params.aid = aid;
|
||||
params.capability = capability;
|
||||
params.supp_rates = supp_rates;
|
||||
params.supp_rates_len = supp_rates_len;
|
||||
params.listen_interval = listen_interval;
|
||||
params.ht_capabilities = ht_capab;
|
||||
params.vht_capabilities = vht_capab;
|
||||
params.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED);
|
||||
params.vht_opmode = vht_opmode;
|
||||
params.flags = hostapd_sta_flags_to_drv(flags);
|
||||
params.qosinfo = qosinfo;
|
||||
return hapd->driver->sta_add(hapd->drv_priv, ¶ms);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
|
||||
u8 *tspec_ie, size_t tspec_ielen)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->add_tspec == NULL)
|
||||
return 0;
|
||||
return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie,
|
||||
tspec_ielen);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_privacy(hapd->drv_priv, enabled);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
|
||||
size_t elem_len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
|
||||
return 0;
|
||||
return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
|
||||
return 0;
|
||||
return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
||||
const char *ifname, const u8 *addr, void *bss_ctx,
|
||||
void **drv_priv, char *force_ifname, u8 *if_addr,
|
||||
const char *bridge, int use_existing)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->if_add == NULL)
|
||||
return -1;
|
||||
return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
|
||||
bss_ctx, drv_priv, force_ifname, if_addr,
|
||||
bridge, use_existing);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
||||
const char *ifname)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->drv_priv == NULL ||
|
||||
hapd->driver->if_remove == NULL)
|
||||
return -1;
|
||||
return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_ieee8021x(struct hostapd_data *hapd,
|
||||
struct wpa_bss_params *params)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
|
||||
const u8 *addr, int idx, u8 *seq)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
|
||||
return 0;
|
||||
return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
|
||||
seq);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_flush(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->flush == NULL)
|
||||
return 0;
|
||||
return hapd->driver->flush(hapd->drv_priv);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
|
||||
int freq, int channel, int ht_enabled, int vht_enabled,
|
||||
int sec_channel_offset, int vht_oper_chwidth,
|
||||
int center_segment0, int center_segment1)
|
||||
{
|
||||
struct hostapd_freq_params data;
|
||||
|
||||
if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
|
||||
vht_enabled, sec_channel_offset,
|
||||
vht_oper_chwidth,
|
||||
center_segment0, center_segment1,
|
||||
hapd->iface->current_mode ?
|
||||
hapd->iface->current_mode->vht_capab : 0))
|
||||
return -1;
|
||||
|
||||
if (hapd->driver == NULL)
|
||||
return 0;
|
||||
if (hapd->driver->set_freq == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_freq(hapd->drv_priv, &data);
|
||||
}
|
||||
|
||||
int hostapd_set_rts(struct hostapd_data *hapd, int rts)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_rts(hapd->drv_priv, rts);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_frag(struct hostapd_data *hapd, int frag)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_frag(hapd->drv_priv, frag);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
|
||||
int total_flags, int flags_or, int flags_and)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
|
||||
return 0;
|
||||
return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
|
||||
flags_or, flags_and);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_country(struct hostapd_data *hapd, const char *country)
|
||||
{
|
||||
if (hapd->driver == NULL ||
|
||||
hapd->driver->set_country == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_country(hapd->drv_priv, country);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
|
||||
int cw_min, int cw_max, int burst_time)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
|
||||
cw_min, cw_max, burst_time);
|
||||
}
|
||||
|
||||
|
||||
struct hostapd_hw_modes *
|
||||
hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
|
||||
u16 *flags)
|
||||
{
|
||||
if (hapd->driver == NULL ||
|
||||
hapd->driver->get_hw_feature_data == NULL)
|
||||
return NULL;
|
||||
return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
|
||||
flags);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_driver_commit(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->commit == NULL)
|
||||
return 0;
|
||||
return hapd->driver->commit(hapd->drv_priv);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_drv_none(struct hostapd_data *hapd)
|
||||
{
|
||||
return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
|
||||
}
|
||||
|
||||
|
||||
int hostapd_driver_scan(struct hostapd_data *hapd,
|
||||
struct wpa_driver_scan_params *params)
|
||||
{
|
||||
if (hapd->driver && hapd->driver->scan2)
|
||||
return hapd->driver->scan2(hapd->drv_priv, params);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
struct wpa_scan_results * hostapd_driver_get_scan_results(
|
||||
struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->driver && hapd->driver->get_scan_results2)
|
||||
return hapd->driver->get_scan_results2(hapd->drv_priv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
|
||||
int duration)
|
||||
{
|
||||
if (hapd->driver && hapd->driver->set_noa)
|
||||
return hapd->driver->set_noa(hapd->drv_priv, count, start,
|
||||
duration);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
|
||||
enum wpa_alg alg, const u8 *addr,
|
||||
int key_idx, int set_tx,
|
||||
const u8 *seq, size_t seq_len,
|
||||
const u8 *key, size_t key_len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_key == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
|
||||
key_idx, set_tx, seq, seq_len, key,
|
||||
key_len);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_drv_send_mlme(struct hostapd_data *hapd,
|
||||
const void *msg, size_t len, int noack)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
|
||||
return 0;
|
||||
return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
|
||||
const u8 *addr, int reason)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
|
||||
return 0;
|
||||
return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
|
||||
reason);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
|
||||
const u8 *addr, int reason)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
|
||||
return 0;
|
||||
return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
|
||||
reason);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper,
|
||||
const u8 *peer, u8 *buf, u16 *buf_len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL)
|
||||
return -1;
|
||||
return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf,
|
||||
buf_len);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
|
||||
unsigned int wait, const u8 *dst, const u8 *data,
|
||||
size_t len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->send_action == NULL)
|
||||
return 0;
|
||||
return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
|
||||
hapd->own_addr, hapd->own_addr, data,
|
||||
len, 0);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_start_dfs_cac(struct hostapd_iface *iface,
|
||||
enum hostapd_hw_mode mode, int freq,
|
||||
int channel, int ht_enabled, int vht_enabled,
|
||||
int sec_channel_offset, int vht_oper_chwidth,
|
||||
int center_segment0, int center_segment1)
|
||||
{
|
||||
struct hostapd_data *hapd = iface->bss[0];
|
||||
struct hostapd_freq_params data;
|
||||
int res;
|
||||
|
||||
if (!hapd->driver || !hapd->driver->start_dfs_cac)
|
||||
return 0;
|
||||
|
||||
if (!iface->conf->ieee80211h) {
|
||||
wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality "
|
||||
"is not enabled");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
|
||||
vht_enabled, sec_channel_offset,
|
||||
vht_oper_chwidth, center_segment0,
|
||||
center_segment1,
|
||||
iface->current_mode->vht_capab)) {
|
||||
wpa_printf(MSG_ERROR, "Can't set freq params");
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = hapd->driver->start_dfs_cac(hapd->drv_priv, &data);
|
||||
if (!res) {
|
||||
iface->cac_started = 1;
|
||||
os_get_reltime(&iface->dfs_cac_start);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
|
||||
const u8 *qos_map_set, u8 qos_map_set_len)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_qos_map == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
|
||||
qos_map_set_len);
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
|
||||
struct hostapd_hw_modes *mode,
|
||||
int acs_ch_list_all,
|
||||
int **freq_list)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mode->num_channels; i++) {
|
||||
struct hostapd_channel_data *chan = &mode->channels[i];
|
||||
|
||||
if ((acs_ch_list_all ||
|
||||
freq_range_list_includes(&hapd->iface->conf->acs_ch_list,
|
||||
chan->chan)) &&
|
||||
!(chan->flag & HOSTAPD_CHAN_DISABLED))
|
||||
int_array_add_unique(freq_list, chan->freq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int hostapd_drv_do_acs(struct hostapd_data *hapd)
|
||||
{
|
||||
struct drv_acs_params params;
|
||||
int ret, i, acs_ch_list_all = 0;
|
||||
u8 *channels = NULL;
|
||||
unsigned int num_channels = 0;
|
||||
struct hostapd_hw_modes *mode;
|
||||
int *freq_list = NULL;
|
||||
|
||||
if (hapd->driver == NULL || hapd->driver->do_acs == NULL)
|
||||
return 0;
|
||||
|
||||
os_memset(¶ms, 0, sizeof(params));
|
||||
params.hw_mode = hapd->iface->conf->hw_mode;
|
||||
|
||||
/*
|
||||
* If no chanlist config parameter is provided, include all enabled
|
||||
* channels of the selected hw_mode.
|
||||
*/
|
||||
if (!hapd->iface->conf->acs_ch_list.num)
|
||||
acs_ch_list_all = 1;
|
||||
|
||||
mode = hapd->iface->current_mode;
|
||||
if (mode) {
|
||||
channels = os_malloc(mode->num_channels);
|
||||
if (channels == NULL)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < mode->num_channels; i++) {
|
||||
struct hostapd_channel_data *chan = &mode->channels[i];
|
||||
if (!acs_ch_list_all &&
|
||||
!freq_range_list_includes(
|
||||
&hapd->iface->conf->acs_ch_list,
|
||||
chan->chan))
|
||||
continue;
|
||||
if (!(chan->flag & HOSTAPD_CHAN_DISABLED)) {
|
||||
channels[num_channels++] = chan->chan;
|
||||
int_array_add_unique(&freq_list, chan->freq);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < hapd->iface->num_hw_features; i++) {
|
||||
mode = &hapd->iface->hw_features[i];
|
||||
hostapd_get_hw_mode_any_channels(hapd, mode,
|
||||
acs_ch_list_all,
|
||||
&freq_list);
|
||||
}
|
||||
}
|
||||
|
||||
params.ch_list = channels;
|
||||
params.ch_list_len = num_channels;
|
||||
params.freq_list = freq_list;
|
||||
|
||||
params.ht_enabled = !!(hapd->iface->conf->ieee80211n);
|
||||
params.ht40_enabled = !!(hapd->iface->conf->ht_capab &
|
||||
HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET);
|
||||
params.vht_enabled = !!(hapd->iface->conf->ieee80211ac);
|
||||
params.ch_width = 20;
|
||||
if (hapd->iface->conf->ieee80211n && params.ht40_enabled)
|
||||
params.ch_width = 40;
|
||||
|
||||
/* Note: VHT20 is defined by combination of ht_capab & vht_oper_chwidth
|
||||
*/
|
||||
if (hapd->iface->conf->ieee80211ac && params.ht40_enabled) {
|
||||
if (hapd->iface->conf->vht_oper_chwidth == VHT_CHANWIDTH_80MHZ)
|
||||
params.ch_width = 80;
|
||||
else if (hapd->iface->conf->vht_oper_chwidth ==
|
||||
VHT_CHANWIDTH_160MHZ ||
|
||||
hapd->iface->conf->vht_oper_chwidth ==
|
||||
VHT_CHANWIDTH_80P80MHZ)
|
||||
params.ch_width = 160;
|
||||
}
|
||||
|
||||
ret = hapd->driver->do_acs(hapd->drv_priv, ¶ms);
|
||||
os_free(channels);
|
||||
|
||||
return ret;
|
||||
}
|
340
freebsd/contrib/wpa/src/ap/ap_drv_ops.h
Normal file
340
freebsd/contrib/wpa/src/ap/ap_drv_ops.h
Normal file
@ -0,0 +1,340 @@
|
||||
/*
|
||||
* hostapd - Driver operations
|
||||
* Copyright (c) 2009-2014, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef AP_DRV_OPS
|
||||
#define AP_DRV_OPS
|
||||
|
||||
enum wpa_driver_if_type;
|
||||
struct wpa_bss_params;
|
||||
struct wpa_driver_scan_params;
|
||||
struct ieee80211_ht_capabilities;
|
||||
struct ieee80211_vht_capabilities;
|
||||
struct hostapd_freq_params;
|
||||
|
||||
u32 hostapd_sta_flags_to_drv(u32 flags);
|
||||
int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
|
||||
struct wpabuf **beacon,
|
||||
struct wpabuf **proberesp,
|
||||
struct wpabuf **assocresp);
|
||||
void hostapd_free_ap_extra_ies(struct hostapd_data *hapd, struct wpabuf *beacon,
|
||||
struct wpabuf *proberesp,
|
||||
struct wpabuf *assocresp);
|
||||
int hostapd_reset_ap_wps_ie(struct hostapd_data *hapd);
|
||||
int hostapd_set_ap_wps_ie(struct hostapd_data *hapd);
|
||||
int hostapd_set_authorized(struct hostapd_data *hapd,
|
||||
struct sta_info *sta, int authorized);
|
||||
int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
|
||||
int enabled);
|
||||
int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname);
|
||||
int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname);
|
||||
int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
|
||||
const u8 *addr, int aid, int val);
|
||||
int hostapd_sta_add(struct hostapd_data *hapd,
|
||||
const u8 *addr, u16 aid, u16 capability,
|
||||
const u8 *supp_rates, size_t supp_rates_len,
|
||||
u16 listen_interval,
|
||||
const struct ieee80211_ht_capabilities *ht_capab,
|
||||
const struct ieee80211_vht_capabilities *vht_capab,
|
||||
u32 flags, u8 qosinfo, u8 vht_opmode);
|
||||
int hostapd_set_privacy(struct hostapd_data *hapd, int enabled);
|
||||
int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
|
||||
size_t elem_len);
|
||||
int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len);
|
||||
int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len);
|
||||
int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
||||
const char *ifname, const u8 *addr, void *bss_ctx,
|
||||
void **drv_priv, char *force_ifname, u8 *if_addr,
|
||||
const char *bridge, int use_existing);
|
||||
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
||||
const char *ifname);
|
||||
int hostapd_set_ieee8021x(struct hostapd_data *hapd,
|
||||
struct wpa_bss_params *params);
|
||||
int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
|
||||
const u8 *addr, int idx, u8 *seq);
|
||||
int hostapd_flush(struct hostapd_data *hapd);
|
||||
int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
|
||||
int freq, int channel, int ht_enabled, int vht_enabled,
|
||||
int sec_channel_offset, int vht_oper_chwidth,
|
||||
int center_segment0, int center_segment1);
|
||||
int hostapd_set_rts(struct hostapd_data *hapd, int rts);
|
||||
int hostapd_set_frag(struct hostapd_data *hapd, int frag);
|
||||
int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
|
||||
int total_flags, int flags_or, int flags_and);
|
||||
int hostapd_set_country(struct hostapd_data *hapd, const char *country);
|
||||
int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
|
||||
int cw_min, int cw_max, int burst_time);
|
||||
struct hostapd_hw_modes *
|
||||
hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
|
||||
u16 *flags);
|
||||
int hostapd_driver_commit(struct hostapd_data *hapd);
|
||||
int hostapd_drv_none(struct hostapd_data *hapd);
|
||||
int hostapd_driver_scan(struct hostapd_data *hapd,
|
||||
struct wpa_driver_scan_params *params);
|
||||
struct wpa_scan_results * hostapd_driver_get_scan_results(
|
||||
struct hostapd_data *hapd);
|
||||
int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
|
||||
int duration);
|
||||
int hostapd_drv_set_key(const char *ifname,
|
||||
struct hostapd_data *hapd,
|
||||
enum wpa_alg alg, const u8 *addr,
|
||||
int key_idx, int set_tx,
|
||||
const u8 *seq, size_t seq_len,
|
||||
const u8 *key, size_t key_len);
|
||||
int hostapd_drv_send_mlme(struct hostapd_data *hapd,
|
||||
const void *msg, size_t len, int noack);
|
||||
int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
|
||||
const u8 *addr, int reason);
|
||||
int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
|
||||
const u8 *addr, int reason);
|
||||
int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
|
||||
unsigned int wait, const u8 *dst, const u8 *data,
|
||||
size_t len);
|
||||
int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
|
||||
u16 auth_alg);
|
||||
int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
|
||||
u16 seq, u16 status, const u8 *ie, size_t len);
|
||||
int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
|
||||
int reassoc, u16 status, const u8 *ie, size_t len);
|
||||
int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
|
||||
u8 *tspec_ie, size_t tspec_ielen);
|
||||
int hostapd_start_dfs_cac(struct hostapd_iface *iface,
|
||||
enum hostapd_hw_mode mode, int freq,
|
||||
int channel, int ht_enabled, int vht_enabled,
|
||||
int sec_channel_offset, int vht_oper_chwidth,
|
||||
int center_segment0, int center_segment1);
|
||||
int hostapd_drv_do_acs(struct hostapd_data *hapd);
|
||||
|
||||
|
||||
#include "drivers/driver.h"
|
||||
|
||||
int hostapd_drv_wnm_oper(struct hostapd_data *hapd,
|
||||
enum wnm_oper oper, const u8 *peer,
|
||||
u8 *buf, u16 *buf_len);
|
||||
|
||||
int hostapd_drv_set_qos_map(struct hostapd_data *hapd, const u8 *qos_map_set,
|
||||
u8 qos_map_set_len);
|
||||
|
||||
static inline int hostapd_drv_set_countermeasures(struct hostapd_data *hapd,
|
||||
int enabled)
|
||||
{
|
||||
if (hapd->driver == NULL ||
|
||||
hapd->driver->hapd_set_countermeasures == NULL)
|
||||
return 0;
|
||||
return hapd->driver->hapd_set_countermeasures(hapd->drv_priv, enabled);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_set_sta_vlan(const char *ifname,
|
||||
struct hostapd_data *hapd,
|
||||
const u8 *addr, int vlan_id)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_sta_vlan == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_sta_vlan(hapd->drv_priv, addr, ifname,
|
||||
vlan_id);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_get_inact_sec(struct hostapd_data *hapd,
|
||||
const u8 *addr)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->get_inact_sec == NULL)
|
||||
return 0;
|
||||
return hapd->driver->get_inact_sec(hapd->drv_priv, addr);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_sta_remove(struct hostapd_data *hapd,
|
||||
const u8 *addr)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->sta_remove == NULL)
|
||||
return 0;
|
||||
return hapd->driver->sta_remove(hapd->drv_priv, addr);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_hapd_send_eapol(struct hostapd_data *hapd,
|
||||
const u8 *addr, const u8 *data,
|
||||
size_t data_len, int encrypt,
|
||||
u32 flags)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->hapd_send_eapol == NULL)
|
||||
return 0;
|
||||
return hapd->driver->hapd_send_eapol(hapd->drv_priv, addr, data,
|
||||
data_len, encrypt,
|
||||
hapd->own_addr, flags);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_read_sta_data(
|
||||
struct hostapd_data *hapd, struct hostap_sta_driver_data *data,
|
||||
const u8 *addr)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->read_sta_data == NULL)
|
||||
return -1;
|
||||
return hapd->driver->read_sta_data(hapd->drv_priv, data, addr);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_sta_clear_stats(struct hostapd_data *hapd,
|
||||
const u8 *addr)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->sta_clear_stats == NULL)
|
||||
return 0;
|
||||
return hapd->driver->sta_clear_stats(hapd->drv_priv, addr);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_set_acl(struct hostapd_data *hapd,
|
||||
struct hostapd_acl_params *params)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_acl == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_acl(hapd->drv_priv, params);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_set_ap(struct hostapd_data *hapd,
|
||||
struct wpa_driver_ap_params *params)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_ap == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_ap(hapd->drv_priv, params);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_set_radius_acl_auth(struct hostapd_data *hapd,
|
||||
const u8 *mac, int accepted,
|
||||
u32 session_timeout)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_radius_acl_auth == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_radius_acl_auth(hapd->drv_priv, mac, accepted,
|
||||
session_timeout);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_set_radius_acl_expire(struct hostapd_data *hapd,
|
||||
const u8 *mac)
|
||||
{
|
||||
if (hapd->driver == NULL ||
|
||||
hapd->driver->set_radius_acl_expire == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_radius_acl_expire(hapd->drv_priv, mac);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_set_authmode(struct hostapd_data *hapd,
|
||||
int auth_algs)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->set_authmode == NULL)
|
||||
return 0;
|
||||
return hapd->driver->set_authmode(hapd->drv_priv, auth_algs);
|
||||
}
|
||||
|
||||
static inline void hostapd_drv_poll_client(struct hostapd_data *hapd,
|
||||
const u8 *own_addr, const u8 *addr,
|
||||
int qos)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->poll_client == NULL)
|
||||
return;
|
||||
hapd->driver->poll_client(hapd->drv_priv, own_addr, addr, qos);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_get_survey(struct hostapd_data *hapd,
|
||||
unsigned int freq)
|
||||
{
|
||||
if (hapd->driver == NULL)
|
||||
return -1;
|
||||
if (!hapd->driver->get_survey)
|
||||
return -1;
|
||||
return hapd->driver->get_survey(hapd->drv_priv, freq);
|
||||
}
|
||||
|
||||
static inline int hostapd_get_country(struct hostapd_data *hapd, char *alpha2)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->get_country == NULL)
|
||||
return -1;
|
||||
return hapd->driver->get_country(hapd->drv_priv, alpha2);
|
||||
}
|
||||
|
||||
static inline const char * hostapd_drv_get_radio_name(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->drv_priv == NULL ||
|
||||
hapd->driver->get_radio_name == NULL)
|
||||
return NULL;
|
||||
return hapd->driver->get_radio_name(hapd->drv_priv);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_switch_channel(struct hostapd_data *hapd,
|
||||
struct csa_settings *settings)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->switch_channel == NULL)
|
||||
return -ENOTSUP;
|
||||
|
||||
return hapd->driver->switch_channel(hapd->drv_priv, settings);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_status(struct hostapd_data *hapd, char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->status == NULL)
|
||||
return -1;
|
||||
return hapd->driver->status(hapd->drv_priv, buf, buflen);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_br_add_ip_neigh(struct hostapd_data *hapd,
|
||||
int version, const u8 *ipaddr,
|
||||
int prefixlen, const u8 *addr)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->drv_priv == NULL ||
|
||||
hapd->driver->br_add_ip_neigh == NULL)
|
||||
return -1;
|
||||
return hapd->driver->br_add_ip_neigh(hapd->drv_priv, version, ipaddr,
|
||||
prefixlen, addr);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_br_delete_ip_neigh(struct hostapd_data *hapd,
|
||||
u8 version, const u8 *ipaddr)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->drv_priv == NULL ||
|
||||
hapd->driver->br_delete_ip_neigh == NULL)
|
||||
return -1;
|
||||
return hapd->driver->br_delete_ip_neigh(hapd->drv_priv, version,
|
||||
ipaddr);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_br_port_set_attr(struct hostapd_data *hapd,
|
||||
enum drv_br_port_attr attr,
|
||||
unsigned int val)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->drv_priv == NULL ||
|
||||
hapd->driver->br_port_set_attr == NULL)
|
||||
return -1;
|
||||
return hapd->driver->br_port_set_attr(hapd->drv_priv, attr, val);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd,
|
||||
enum drv_br_net_param param,
|
||||
unsigned int val)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->drv_priv == NULL ||
|
||||
hapd->driver->br_set_net_param == NULL)
|
||||
return -1;
|
||||
return hapd->driver->br_set_net_param(hapd->drv_priv, param, val);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd,
|
||||
int vendor_id, int subcmd,
|
||||
const u8 *data, size_t data_len,
|
||||
struct wpabuf *buf)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->vendor_cmd == NULL)
|
||||
return -1;
|
||||
return hapd->driver->vendor_cmd(hapd->drv_priv, vendor_id, subcmd, data,
|
||||
data_len, buf);
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_stop_ap(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->driver == NULL || hapd->driver->stop_ap == NULL)
|
||||
return 0;
|
||||
return hapd->driver->stop_ap(hapd->drv_priv);
|
||||
}
|
||||
|
||||
#endif /* AP_DRV_OPS */
|
494
freebsd/contrib/wpa/src/ap/hostapd.h
Normal file
494
freebsd/contrib/wpa/src/ap/hostapd.h
Normal file
@ -0,0 +1,494 @@
|
||||
/*
|
||||
* hostapd / Initialization and configuration
|
||||
* Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef HOSTAPD_H
|
||||
#define HOSTAPD_H
|
||||
|
||||
#include "common/defs.h"
|
||||
#include "utils/list.h"
|
||||
#include "ap_config.h"
|
||||
#include "drivers/driver.h"
|
||||
|
||||
struct wpa_ctrl_dst;
|
||||
struct radius_server_data;
|
||||
struct upnp_wps_device_sm;
|
||||
struct hostapd_data;
|
||||
struct sta_info;
|
||||
struct ieee80211_ht_capabilities;
|
||||
struct full_dynamic_vlan;
|
||||
enum wps_event;
|
||||
union wps_event_data;
|
||||
#ifdef CONFIG_MESH
|
||||
struct mesh_conf;
|
||||
#endif /* CONFIG_MESH */
|
||||
|
||||
struct hostapd_iface;
|
||||
|
||||
struct hapd_interfaces {
|
||||
int (*reload_config)(struct hostapd_iface *iface);
|
||||
struct hostapd_config * (*config_read_cb)(const char *config_fname);
|
||||
int (*ctrl_iface_init)(struct hostapd_data *hapd);
|
||||
void (*ctrl_iface_deinit)(struct hostapd_data *hapd);
|
||||
int (*for_each_interface)(struct hapd_interfaces *interfaces,
|
||||
int (*cb)(struct hostapd_iface *iface,
|
||||
void *ctx), void *ctx);
|
||||
int (*driver_init)(struct hostapd_iface *iface);
|
||||
|
||||
size_t count;
|
||||
int global_ctrl_sock;
|
||||
struct wpa_ctrl_dst *global_ctrl_dst;
|
||||
char *global_iface_path;
|
||||
char *global_iface_name;
|
||||
#ifndef CONFIG_NATIVE_WINDOWS
|
||||
gid_t ctrl_iface_group;
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
struct hostapd_iface **iface;
|
||||
|
||||
size_t terminate_on_error;
|
||||
#ifndef CONFIG_NO_VLAN
|
||||
struct dynamic_iface *vlan_priv;
|
||||
#endif /* CONFIG_NO_VLAN */
|
||||
};
|
||||
|
||||
enum hostapd_chan_status {
|
||||
HOSTAPD_CHAN_VALID = 0, /* channel is ready */
|
||||
HOSTAPD_CHAN_INVALID = 1, /* no usable channel found */
|
||||
HOSTAPD_CHAN_ACS = 2, /* ACS work being performed */
|
||||
};
|
||||
|
||||
struct hostapd_probereq_cb {
|
||||
int (*cb)(void *ctx, const u8 *sa, const u8 *da, const u8 *bssid,
|
||||
const u8 *ie, size_t ie_len, int ssi_signal);
|
||||
void *ctx;
|
||||
};
|
||||
|
||||
#define HOSTAPD_RATE_BASIC 0x00000001
|
||||
|
||||
struct hostapd_rate_data {
|
||||
int rate; /* rate in 100 kbps */
|
||||
int flags; /* HOSTAPD_RATE_ flags */
|
||||
};
|
||||
|
||||
struct hostapd_frame_info {
|
||||
u32 channel;
|
||||
u32 datarate;
|
||||
int ssi_signal; /* dBm */
|
||||
};
|
||||
|
||||
enum wps_status {
|
||||
WPS_STATUS_SUCCESS = 1,
|
||||
WPS_STATUS_FAILURE
|
||||
};
|
||||
|
||||
enum pbc_status {
|
||||
WPS_PBC_STATUS_DISABLE,
|
||||
WPS_PBC_STATUS_ACTIVE,
|
||||
WPS_PBC_STATUS_TIMEOUT,
|
||||
WPS_PBC_STATUS_OVERLAP
|
||||
};
|
||||
|
||||
struct wps_stat {
|
||||
enum wps_status status;
|
||||
enum wps_error_indication failure_reason;
|
||||
enum pbc_status pbc_status;
|
||||
u8 peer_addr[ETH_ALEN];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct hostapd_data - hostapd per-BSS data structure
|
||||
*/
|
||||
struct hostapd_data {
|
||||
struct hostapd_iface *iface;
|
||||
struct hostapd_config *iconf;
|
||||
struct hostapd_bss_config *conf;
|
||||
int interface_added; /* virtual interface added for this BSS */
|
||||
unsigned int started:1;
|
||||
unsigned int disabled:1;
|
||||
unsigned int reenable_beacon:1;
|
||||
|
||||
u8 own_addr[ETH_ALEN];
|
||||
|
||||
int num_sta; /* number of entries in sta_list */
|
||||
struct sta_info *sta_list; /* STA info list head */
|
||||
#define STA_HASH_SIZE 256
|
||||
#define STA_HASH(sta) (sta[5])
|
||||
struct sta_info *sta_hash[STA_HASH_SIZE];
|
||||
|
||||
/*
|
||||
* Bitfield for indicating which AIDs are allocated. Only AID values
|
||||
* 1-2007 are used and as such, the bit at index 0 corresponds to AID
|
||||
* 1.
|
||||
*/
|
||||
#define AID_WORDS ((2008 + 31) / 32)
|
||||
u32 sta_aid[AID_WORDS];
|
||||
|
||||
const struct wpa_driver_ops *driver;
|
||||
void *drv_priv;
|
||||
|
||||
void (*new_assoc_sta_cb)(struct hostapd_data *hapd,
|
||||
struct sta_info *sta, int reassoc);
|
||||
|
||||
void *msg_ctx; /* ctx for wpa_msg() calls */
|
||||
void *msg_ctx_parent; /* parent interface ctx for wpa_msg() calls */
|
||||
|
||||
struct radius_client_data *radius;
|
||||
u32 acct_session_id_hi, acct_session_id_lo;
|
||||
struct radius_das_data *radius_das;
|
||||
|
||||
struct iapp_data *iapp;
|
||||
|
||||
struct hostapd_cached_radius_acl *acl_cache;
|
||||
struct hostapd_acl_query_data *acl_queries;
|
||||
|
||||
struct wpa_authenticator *wpa_auth;
|
||||
struct eapol_authenticator *eapol_auth;
|
||||
|
||||
struct rsn_preauth_interface *preauth_iface;
|
||||
struct os_reltime michael_mic_failure;
|
||||
int michael_mic_failures;
|
||||
int tkip_countermeasures;
|
||||
|
||||
int ctrl_sock;
|
||||
struct wpa_ctrl_dst *ctrl_dst;
|
||||
|
||||
void *ssl_ctx;
|
||||
void *eap_sim_db_priv;
|
||||
struct radius_server_data *radius_srv;
|
||||
struct dl_list erp_keys; /* struct eap_server_erp_key */
|
||||
|
||||
int parameter_set_count;
|
||||
|
||||
/* Time Advertisement */
|
||||
u8 time_update_counter;
|
||||
struct wpabuf *time_adv;
|
||||
|
||||
#ifdef CONFIG_FULL_DYNAMIC_VLAN
|
||||
struct full_dynamic_vlan *full_dynamic_vlan;
|
||||
#endif /* CONFIG_FULL_DYNAMIC_VLAN */
|
||||
|
||||
struct l2_packet_data *l2;
|
||||
struct wps_context *wps;
|
||||
|
||||
int beacon_set_done;
|
||||
struct wpabuf *wps_beacon_ie;
|
||||
struct wpabuf *wps_probe_resp_ie;
|
||||
#ifdef CONFIG_WPS
|
||||
unsigned int ap_pin_failures;
|
||||
unsigned int ap_pin_failures_consecutive;
|
||||
struct upnp_wps_device_sm *wps_upnp;
|
||||
unsigned int ap_pin_lockout_time;
|
||||
|
||||
struct wps_stat wps_stats;
|
||||
#endif /* CONFIG_WPS */
|
||||
|
||||
struct hostapd_probereq_cb *probereq_cb;
|
||||
size_t num_probereq_cb;
|
||||
|
||||
void (*public_action_cb)(void *ctx, const u8 *buf, size_t len,
|
||||
int freq);
|
||||
void *public_action_cb_ctx;
|
||||
void (*public_action_cb2)(void *ctx, const u8 *buf, size_t len,
|
||||
int freq);
|
||||
void *public_action_cb2_ctx;
|
||||
|
||||
int (*vendor_action_cb)(void *ctx, const u8 *buf, size_t len,
|
||||
int freq);
|
||||
void *vendor_action_cb_ctx;
|
||||
|
||||
void (*wps_reg_success_cb)(void *ctx, const u8 *mac_addr,
|
||||
const u8 *uuid_e);
|
||||
void *wps_reg_success_cb_ctx;
|
||||
|
||||
void (*wps_event_cb)(void *ctx, enum wps_event event,
|
||||
union wps_event_data *data);
|
||||
void *wps_event_cb_ctx;
|
||||
|
||||
void (*sta_authorized_cb)(void *ctx, const u8 *mac_addr,
|
||||
int authorized, const u8 *p2p_dev_addr);
|
||||
void *sta_authorized_cb_ctx;
|
||||
|
||||
void (*setup_complete_cb)(void *ctx);
|
||||
void *setup_complete_cb_ctx;
|
||||
|
||||
void (*new_psk_cb)(void *ctx, const u8 *mac_addr,
|
||||
const u8 *p2p_dev_addr, const u8 *psk,
|
||||
size_t psk_len);
|
||||
void *new_psk_cb_ctx;
|
||||
|
||||
/* channel switch parameters */
|
||||
struct hostapd_freq_params cs_freq_params;
|
||||
u8 cs_count;
|
||||
int cs_block_tx;
|
||||
unsigned int cs_c_off_beacon;
|
||||
unsigned int cs_c_off_proberesp;
|
||||
int csa_in_progress;
|
||||
|
||||
/* BSS Load */
|
||||
unsigned int bss_load_update_timeout;
|
||||
|
||||
#ifdef CONFIG_P2P
|
||||
struct p2p_data *p2p;
|
||||
struct p2p_group *p2p_group;
|
||||
struct wpabuf *p2p_beacon_ie;
|
||||
struct wpabuf *p2p_probe_resp_ie;
|
||||
|
||||
/* Number of non-P2P association stations */
|
||||
int num_sta_no_p2p;
|
||||
|
||||
/* Periodic NoA (used only when no non-P2P clients in the group) */
|
||||
int noa_enabled;
|
||||
int noa_start;
|
||||
int noa_duration;
|
||||
#endif /* CONFIG_P2P */
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
size_t gas_frag_limit;
|
||||
#endif /* CONFIG_INTERWORKING */
|
||||
#ifdef CONFIG_PROXYARP
|
||||
struct l2_packet_data *sock_dhcp;
|
||||
struct l2_packet_data *sock_ndisc;
|
||||
#endif /* CONFIG_PROXYARP */
|
||||
#ifdef CONFIG_MESH
|
||||
int num_plinks;
|
||||
int max_plinks;
|
||||
void (*mesh_sta_free_cb)(struct sta_info *sta);
|
||||
struct wpabuf *mesh_pending_auth;
|
||||
struct os_reltime mesh_pending_auth_time;
|
||||
#endif /* CONFIG_MESH */
|
||||
|
||||
#ifdef CONFIG_SQLITE
|
||||
struct hostapd_eap_user tmp_eap_user;
|
||||
#endif /* CONFIG_SQLITE */
|
||||
|
||||
#ifdef CONFIG_SAE
|
||||
/** Key used for generating SAE anti-clogging tokens */
|
||||
u8 sae_token_key[8];
|
||||
struct os_reltime last_sae_token_key_update;
|
||||
int dot11RSNASAERetransPeriod; /* msec */
|
||||
#endif /* CONFIG_SAE */
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
unsigned int ext_mgmt_frame_handling:1;
|
||||
unsigned int ext_eapol_frame_io:1;
|
||||
|
||||
struct l2_packet_data *l2_test;
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
};
|
||||
|
||||
|
||||
struct hostapd_sta_info {
|
||||
struct dl_list list;
|
||||
u8 addr[ETH_ALEN];
|
||||
struct os_reltime last_seen;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hostapd_iface - hostapd per-interface data structure
|
||||
*/
|
||||
struct hostapd_iface {
|
||||
struct hapd_interfaces *interfaces;
|
||||
void *owner;
|
||||
char *config_fname;
|
||||
struct hostapd_config *conf;
|
||||
char phy[16]; /* Name of the PHY (radio) */
|
||||
|
||||
enum hostapd_iface_state {
|
||||
HAPD_IFACE_UNINITIALIZED,
|
||||
HAPD_IFACE_DISABLED,
|
||||
HAPD_IFACE_COUNTRY_UPDATE,
|
||||
HAPD_IFACE_ACS,
|
||||
HAPD_IFACE_HT_SCAN,
|
||||
HAPD_IFACE_DFS,
|
||||
HAPD_IFACE_ENABLED
|
||||
} state;
|
||||
|
||||
#ifdef CONFIG_MESH
|
||||
struct mesh_conf *mconf;
|
||||
#endif /* CONFIG_MESH */
|
||||
|
||||
size_t num_bss;
|
||||
struct hostapd_data **bss;
|
||||
|
||||
unsigned int wait_channel_update:1;
|
||||
unsigned int cac_started:1;
|
||||
#ifdef CONFIG_FST
|
||||
struct fst_iface *fst;
|
||||
const struct wpabuf *fst_ies;
|
||||
#endif /* CONFIG_FST */
|
||||
|
||||
/*
|
||||
* When set, indicates that the driver will handle the AP
|
||||
* teardown: delete global keys, station keys, and stations.
|
||||
*/
|
||||
unsigned int driver_ap_teardown:1;
|
||||
|
||||
int num_ap; /* number of entries in ap_list */
|
||||
struct ap_info *ap_list; /* AP info list head */
|
||||
struct ap_info *ap_hash[STA_HASH_SIZE];
|
||||
|
||||
u64 drv_flags;
|
||||
|
||||
/* SMPS modes supported by the driver (WPA_DRIVER_SMPS_MODE_*) */
|
||||
unsigned int smps_modes;
|
||||
|
||||
/*
|
||||
* A bitmap of supported protocols for probe response offload. See
|
||||
* struct wpa_driver_capa in driver.h
|
||||
*/
|
||||
unsigned int probe_resp_offloads;
|
||||
|
||||
/* extended capabilities supported by the driver */
|
||||
const u8 *extended_capa, *extended_capa_mask;
|
||||
unsigned int extended_capa_len;
|
||||
|
||||
unsigned int drv_max_acl_mac_addrs;
|
||||
|
||||
struct hostapd_hw_modes *hw_features;
|
||||
int num_hw_features;
|
||||
struct hostapd_hw_modes *current_mode;
|
||||
/* Rates that are currently used (i.e., filtered copy of
|
||||
* current_mode->channels */
|
||||
int num_rates;
|
||||
struct hostapd_rate_data *current_rates;
|
||||
int *basic_rates;
|
||||
int freq;
|
||||
|
||||
u16 hw_flags;
|
||||
|
||||
/* Number of associated Non-ERP stations (i.e., stations using 802.11b
|
||||
* in 802.11g BSS) */
|
||||
int num_sta_non_erp;
|
||||
|
||||
/* Number of associated stations that do not support Short Slot Time */
|
||||
int num_sta_no_short_slot_time;
|
||||
|
||||
/* Number of associated stations that do not support Short Preamble */
|
||||
int num_sta_no_short_preamble;
|
||||
|
||||
int olbc; /* Overlapping Legacy BSS Condition */
|
||||
|
||||
/* Number of HT associated stations that do not support greenfield */
|
||||
int num_sta_ht_no_gf;
|
||||
|
||||
/* Number of associated non-HT stations */
|
||||
int num_sta_no_ht;
|
||||
|
||||
/* Number of HT associated stations 20 MHz */
|
||||
int num_sta_ht_20mhz;
|
||||
|
||||
/* Number of HT40 intolerant stations */
|
||||
int num_sta_ht40_intolerant;
|
||||
|
||||
/* Overlapping BSS information */
|
||||
int olbc_ht;
|
||||
|
||||
u16 ht_op_mode;
|
||||
|
||||
/* surveying helpers */
|
||||
|
||||
/* number of channels surveyed */
|
||||
unsigned int chans_surveyed;
|
||||
|
||||
/* lowest observed noise floor in dBm */
|
||||
s8 lowest_nf;
|
||||
|
||||
/* channel utilization calculation */
|
||||
u64 last_channel_time;
|
||||
u64 last_channel_time_busy;
|
||||
u8 channel_utilization;
|
||||
|
||||
unsigned int dfs_cac_ms;
|
||||
struct os_reltime dfs_cac_start;
|
||||
|
||||
/* Latched with the actual secondary channel information and will be
|
||||
* used while juggling between HT20 and HT40 modes. */
|
||||
int secondary_ch;
|
||||
|
||||
#ifdef CONFIG_ACS
|
||||
unsigned int acs_num_completed_scans;
|
||||
#endif /* CONFIG_ACS */
|
||||
|
||||
void (*scan_cb)(struct hostapd_iface *iface);
|
||||
int num_ht40_scan_tries;
|
||||
|
||||
struct dl_list sta_seen; /* struct hostapd_sta_info */
|
||||
unsigned int num_sta_seen;
|
||||
};
|
||||
|
||||
/* hostapd.c */
|
||||
int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
|
||||
int (*cb)(struct hostapd_iface *iface,
|
||||
void *ctx), void *ctx);
|
||||
int hostapd_reload_config(struct hostapd_iface *iface);
|
||||
struct hostapd_data *
|
||||
hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
|
||||
struct hostapd_config *conf,
|
||||
struct hostapd_bss_config *bss);
|
||||
int hostapd_setup_interface(struct hostapd_iface *iface);
|
||||
int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
|
||||
void hostapd_interface_deinit(struct hostapd_iface *iface);
|
||||
void hostapd_interface_free(struct hostapd_iface *iface);
|
||||
struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces,
|
||||
const char *config_file);
|
||||
struct hostapd_iface *
|
||||
hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
|
||||
const char *config_fname, int debug);
|
||||
void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
int reassoc);
|
||||
void hostapd_interface_deinit_free(struct hostapd_iface *iface);
|
||||
int hostapd_enable_iface(struct hostapd_iface *hapd_iface);
|
||||
int hostapd_reload_iface(struct hostapd_iface *hapd_iface);
|
||||
int hostapd_disable_iface(struct hostapd_iface *hapd_iface);
|
||||
int hostapd_add_iface(struct hapd_interfaces *ifaces, char *buf);
|
||||
int hostapd_remove_iface(struct hapd_interfaces *ifaces, char *buf);
|
||||
void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator);
|
||||
void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s);
|
||||
const char * hostapd_state_text(enum hostapd_iface_state s);
|
||||
int hostapd_switch_channel(struct hostapd_data *hapd,
|
||||
struct csa_settings *settings);
|
||||
void
|
||||
hostapd_switch_channel_fallback(struct hostapd_iface *iface,
|
||||
const struct hostapd_freq_params *freq_params);
|
||||
void hostapd_cleanup_cs_params(struct hostapd_data *hapd);
|
||||
void hostapd_periodic_iface(struct hostapd_iface *iface);
|
||||
|
||||
/* utils.c */
|
||||
int hostapd_register_probereq_cb(struct hostapd_data *hapd,
|
||||
int (*cb)(void *ctx, const u8 *sa,
|
||||
const u8 *da, const u8 *bssid,
|
||||
const u8 *ie, size_t ie_len,
|
||||
int ssi_signal),
|
||||
void *ctx);
|
||||
void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr);
|
||||
|
||||
/* drv_callbacks.c (TODO: move to somewhere else?) */
|
||||
int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
|
||||
const u8 *ie, size_t ielen, int reassoc);
|
||||
void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr);
|
||||
void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr);
|
||||
void hostapd_event_connect_failed_reason(struct hostapd_data *hapd,
|
||||
const u8 *addr, int reason_code);
|
||||
int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
|
||||
const u8 *bssid, const u8 *ie, size_t ie_len,
|
||||
int ssi_signal);
|
||||
void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
||||
int offset, int width, int cf1, int cf2);
|
||||
|
||||
const struct hostapd_eap_user *
|
||||
hostapd_get_eap_user(struct hostapd_data *hapd, const u8 *identity,
|
||||
size_t identity_len, int phase2);
|
||||
|
||||
struct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces,
|
||||
const char *ifname);
|
||||
|
||||
#ifdef CONFIG_FST
|
||||
void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd,
|
||||
struct fst_wpa_obj *iface_obj);
|
||||
#endif /* CONFIG_FST */
|
||||
|
||||
#endif /* HOSTAPD_H */
|
179
freebsd/contrib/wpa/src/ap/hs20.c
Normal file
179
freebsd/contrib/wpa/src/ap/hs20.c
Normal file
@ -0,0 +1,179 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* Hotspot 2.0 AP ANQP processing
|
||||
* Copyright (c) 2009, Atheros Communications, Inc.
|
||||
* Copyright (c) 2011-2013, Qualcomm Atheros, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "hostapd.h"
|
||||
#include "ap_config.h"
|
||||
#include "ap_drv_ops.h"
|
||||
#include "hs20.h"
|
||||
|
||||
|
||||
u8 * hostapd_eid_hs20_indication(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
u8 conf;
|
||||
if (!hapd->conf->hs20)
|
||||
return eid;
|
||||
*eid++ = WLAN_EID_VENDOR_SPECIFIC;
|
||||
*eid++ = 7;
|
||||
WPA_PUT_BE24(eid, OUI_WFA);
|
||||
eid += 3;
|
||||
*eid++ = HS20_INDICATION_OUI_TYPE;
|
||||
conf = HS20_VERSION; /* Release Number */
|
||||
conf |= HS20_ANQP_DOMAIN_ID_PRESENT;
|
||||
if (hapd->conf->disable_dgaf)
|
||||
conf |= HS20_DGAF_DISABLED;
|
||||
*eid++ = conf;
|
||||
WPA_PUT_LE16(eid, hapd->conf->anqp_domain_id);
|
||||
eid += 2;
|
||||
|
||||
return eid;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_osen(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
u8 *len;
|
||||
u16 capab;
|
||||
|
||||
if (!hapd->conf->osen)
|
||||
return eid;
|
||||
|
||||
*eid++ = WLAN_EID_VENDOR_SPECIFIC;
|
||||
len = eid++; /* to be filled */
|
||||
WPA_PUT_BE24(eid, OUI_WFA);
|
||||
eid += 3;
|
||||
*eid++ = HS20_OSEN_OUI_TYPE;
|
||||
|
||||
/* Group Data Cipher Suite */
|
||||
RSN_SELECTOR_PUT(eid, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
|
||||
eid += RSN_SELECTOR_LEN;
|
||||
|
||||
/* Pairwise Cipher Suite Count and List */
|
||||
WPA_PUT_LE16(eid, 1);
|
||||
eid += 2;
|
||||
RSN_SELECTOR_PUT(eid, RSN_CIPHER_SUITE_CCMP);
|
||||
eid += RSN_SELECTOR_LEN;
|
||||
|
||||
/* AKM Suite Count and List */
|
||||
WPA_PUT_LE16(eid, 1);
|
||||
eid += 2;
|
||||
RSN_SELECTOR_PUT(eid, RSN_AUTH_KEY_MGMT_OSEN);
|
||||
eid += RSN_SELECTOR_LEN;
|
||||
|
||||
/* RSN Capabilities */
|
||||
capab = 0;
|
||||
if (hapd->conf->wmm_enabled) {
|
||||
/* 4 PTKSA replay counters when using WMM */
|
||||
capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
|
||||
}
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
if (hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
|
||||
capab |= WPA_CAPABILITY_MFPC;
|
||||
if (hapd->conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)
|
||||
capab |= WPA_CAPABILITY_MFPR;
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
WPA_PUT_LE16(eid, capab);
|
||||
eid += 2;
|
||||
|
||||
*len = eid - len - 1;
|
||||
|
||||
return eid;
|
||||
}
|
||||
|
||||
|
||||
int hs20_send_wnm_notification(struct hostapd_data *hapd, const u8 *addr,
|
||||
u8 osu_method, const char *url)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
size_t len = 0;
|
||||
int ret;
|
||||
|
||||
/* TODO: should refuse to send notification if the STA is not associated
|
||||
* or if the STA did not indicate support for WNM-Notification */
|
||||
|
||||
if (url) {
|
||||
len = 1 + os_strlen(url);
|
||||
if (5 + len > 255) {
|
||||
wpa_printf(MSG_INFO, "HS 2.0: Too long URL for "
|
||||
"WNM-Notification: '%s'", url);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
buf = wpabuf_alloc(4 + 7 + len);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
wpabuf_put_u8(buf, WLAN_ACTION_WNM);
|
||||
wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ);
|
||||
wpabuf_put_u8(buf, 1); /* Dialog token */
|
||||
wpabuf_put_u8(buf, 1); /* Type - 1 reserved for WFA */
|
||||
|
||||
/* Subscription Remediation subelement */
|
||||
wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
|
||||
wpabuf_put_u8(buf, 5 + len);
|
||||
wpabuf_put_be24(buf, OUI_WFA);
|
||||
wpabuf_put_u8(buf, HS20_WNM_SUB_REM_NEEDED);
|
||||
if (url) {
|
||||
wpabuf_put_u8(buf, len - 1);
|
||||
wpabuf_put_data(buf, url, len - 1);
|
||||
wpabuf_put_u8(buf, osu_method);
|
||||
} else {
|
||||
/* Server URL and Server Method fields not included */
|
||||
wpabuf_put_u8(buf, 0);
|
||||
}
|
||||
|
||||
ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr,
|
||||
wpabuf_head(buf), wpabuf_len(buf));
|
||||
|
||||
wpabuf_free(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int hs20_send_wnm_notification_deauth_req(struct hostapd_data *hapd,
|
||||
const u8 *addr,
|
||||
const struct wpabuf *payload)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
int ret;
|
||||
|
||||
/* TODO: should refuse to send notification if the STA is not associated
|
||||
* or if the STA did not indicate support for WNM-Notification */
|
||||
|
||||
buf = wpabuf_alloc(4 + 6 + wpabuf_len(payload));
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
wpabuf_put_u8(buf, WLAN_ACTION_WNM);
|
||||
wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ);
|
||||
wpabuf_put_u8(buf, 1); /* Dialog token */
|
||||
wpabuf_put_u8(buf, 1); /* Type - 1 reserved for WFA */
|
||||
|
||||
/* Deauthentication Imminent Notice subelement */
|
||||
wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
|
||||
wpabuf_put_u8(buf, 4 + wpabuf_len(payload));
|
||||
wpabuf_put_be24(buf, OUI_WFA);
|
||||
wpabuf_put_u8(buf, HS20_WNM_DEAUTH_IMMINENT_NOTICE);
|
||||
wpabuf_put_buf(buf, payload);
|
||||
|
||||
ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr,
|
||||
wpabuf_head(buf), wpabuf_len(buf));
|
||||
|
||||
wpabuf_free(buf);
|
||||
|
||||
return ret;
|
||||
}
|
22
freebsd/contrib/wpa/src/ap/hs20.h
Normal file
22
freebsd/contrib/wpa/src/ap/hs20.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Hotspot 2.0 AP ANQP processing
|
||||
* Copyright (c) 2011-2013, Qualcomm Atheros, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef HS20_H
|
||||
#define HS20_H
|
||||
|
||||
struct hostapd_data;
|
||||
|
||||
u8 * hostapd_eid_hs20_indication(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_osen(struct hostapd_data *hapd, u8 *eid);
|
||||
int hs20_send_wnm_notification(struct hostapd_data *hapd, const u8 *addr,
|
||||
u8 osu_method, const char *url);
|
||||
int hs20_send_wnm_notification_deauth_req(struct hostapd_data *hapd,
|
||||
const u8 *addr,
|
||||
const struct wpabuf *payload);
|
||||
|
||||
#endif /* HS20_H */
|
107
freebsd/contrib/wpa/src/ap/ieee802_11.h
Normal file
107
freebsd/contrib/wpa/src/ap/ieee802_11.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* hostapd / IEEE 802.11 Management
|
||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef IEEE802_11_H
|
||||
#define IEEE802_11_H
|
||||
|
||||
struct hostapd_iface;
|
||||
struct hostapd_data;
|
||||
struct sta_info;
|
||||
struct hostapd_frame_info;
|
||||
struct ieee80211_ht_capabilities;
|
||||
struct ieee80211_vht_capabilities;
|
||||
struct ieee80211_mgmt;
|
||||
|
||||
int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
|
||||
struct hostapd_frame_info *fi);
|
||||
void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
|
||||
u16 stype, int ok);
|
||||
void hostapd_2040_coex_action(struct hostapd_data *hapd,
|
||||
const struct ieee80211_mgmt *mgmt, size_t len);
|
||||
#ifdef NEED_AP_MLME
|
||||
int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen);
|
||||
int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
char *buf, size_t buflen);
|
||||
#else /* NEED_AP_MLME */
|
||||
static inline int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ieee802_11_get_mib_sta(struct hostapd_data *hapd,
|
||||
struct sta_info *sta,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* NEED_AP_MLME */
|
||||
u16 hostapd_own_capab_info(struct hostapd_data *hapd);
|
||||
void ap_ht2040_timeout(void *eloop_data, void *user_data);
|
||||
u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_qos_map_set(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_vendor_vht(struct hostapd_data *hapd, u8 *eid);
|
||||
int hostapd_ht_operation_update(struct hostapd_iface *iface);
|
||||
void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
|
||||
const u8 *addr, const u8 *trans_id);
|
||||
void hostapd_get_ht_capab(struct hostapd_data *hapd,
|
||||
struct ieee80211_ht_capabilities *ht_cap,
|
||||
struct ieee80211_ht_capabilities *neg_ht_cap);
|
||||
void hostapd_get_vht_capab(struct hostapd_data *hapd,
|
||||
struct ieee80211_vht_capabilities *vht_cap,
|
||||
struct ieee80211_vht_capabilities *neg_vht_cap);
|
||||
u16 copy_sta_ht_capab(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
const u8 *ht_capab);
|
||||
u16 copy_sta_vendor_vht(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
const u8 *ie, size_t len);
|
||||
|
||||
void update_ht_state(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ht40_intolerant_add(struct hostapd_iface *iface, struct sta_info *sta);
|
||||
void ht40_intolerant_remove(struct hostapd_iface *iface, struct sta_info *sta);
|
||||
u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
const u8 *vht_capab);
|
||||
u16 set_sta_vht_opmode(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
const u8 *vht_opmode);
|
||||
void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
|
||||
const u8 *buf, size_t len, int ack);
|
||||
void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
|
||||
const u8 *data, size_t len, int ack);
|
||||
void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
|
||||
int wds);
|
||||
u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd,
|
||||
struct sta_info *sta, u8 *eid);
|
||||
void ieee802_11_sa_query_action(struct hostapd_data *hapd,
|
||||
const u8 *sa, const u8 action_type,
|
||||
const u8 *trans_id);
|
||||
u8 * hostapd_eid_interworking(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_adv_proto(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_roaming_consortium(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_time_adv(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_time_zone(struct hostapd_data *hapd, u8 *eid);
|
||||
int hostapd_update_time_adv(struct hostapd_data *hapd);
|
||||
void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr);
|
||||
u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid);
|
||||
|
||||
int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
#ifdef CONFIG_SAE
|
||||
void sae_clear_retransmit_timer(struct hostapd_data *hapd,
|
||||
struct sta_info *sta);
|
||||
#else /* CONFIG_SAE */
|
||||
static inline void sae_clear_retransmit_timer(struct hostapd_data *hapd,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_SAE */
|
||||
|
||||
#endif /* IEEE802_11_H */
|
29
freebsd/contrib/wpa/src/ap/ieee802_11_auth.h
Normal file
29
freebsd/contrib/wpa/src/ap/ieee802_11_auth.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* hostapd / IEEE 802.11 authentication (ACL)
|
||||
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef IEEE802_11_AUTH_H
|
||||
#define IEEE802_11_AUTH_H
|
||||
|
||||
enum {
|
||||
HOSTAPD_ACL_REJECT = 0,
|
||||
HOSTAPD_ACL_ACCEPT = 1,
|
||||
HOSTAPD_ACL_PENDING = 2,
|
||||
HOSTAPD_ACL_ACCEPT_TIMEOUT = 3
|
||||
};
|
||||
|
||||
int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
|
||||
const u8 *msg, size_t len, u32 *session_timeout,
|
||||
u32 *acct_interim_interval, int *vlan_id,
|
||||
struct hostapd_sta_wpa_psk_short **psk,
|
||||
char **identity, char **radius_cui);
|
||||
int hostapd_acl_init(struct hostapd_data *hapd);
|
||||
void hostapd_acl_deinit(struct hostapd_data *hapd);
|
||||
void hostapd_free_psk_list(struct hostapd_sta_wpa_psk_short *psk);
|
||||
void hostapd_acl_expire(struct hostapd_data *hapd);
|
||||
|
||||
#endif /* IEEE802_11_AUTH_H */
|
510
freebsd/contrib/wpa/src/ap/ieee802_11_shared.c
Normal file
510
freebsd/contrib/wpa/src/ap/ieee802_11_shared.c
Normal file
@ -0,0 +1,510 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* hostapd / IEEE 802.11 Management
|
||||
* Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "hostapd.h"
|
||||
#include "sta_info.h"
|
||||
#include "ap_config.h"
|
||||
#include "ap_drv_ops.h"
|
||||
#include "ieee802_11.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
|
||||
u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd,
|
||||
struct sta_info *sta, u8 *eid)
|
||||
{
|
||||
u8 *pos = eid;
|
||||
u32 timeout, tu;
|
||||
struct os_reltime now, passed;
|
||||
|
||||
*pos++ = WLAN_EID_TIMEOUT_INTERVAL;
|
||||
*pos++ = 5;
|
||||
*pos++ = WLAN_TIMEOUT_ASSOC_COMEBACK;
|
||||
os_get_reltime(&now);
|
||||
os_reltime_sub(&now, &sta->sa_query_start, &passed);
|
||||
tu = (passed.sec * 1000000 + passed.usec) / 1024;
|
||||
if (hapd->conf->assoc_sa_query_max_timeout > tu)
|
||||
timeout = hapd->conf->assoc_sa_query_max_timeout - tu;
|
||||
else
|
||||
timeout = 0;
|
||||
if (timeout < hapd->conf->assoc_sa_query_max_timeout)
|
||||
timeout++; /* add some extra time for local timers */
|
||||
WPA_PUT_LE32(pos, timeout);
|
||||
pos += 4;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
/* MLME-SAQuery.request */
|
||||
void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
|
||||
const u8 *addr, const u8 *trans_id)
|
||||
{
|
||||
struct ieee80211_mgmt mgmt;
|
||||
u8 *end;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.11: Sending SA Query Request to "
|
||||
MACSTR, MAC2STR(addr));
|
||||
wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID",
|
||||
trans_id, WLAN_SA_QUERY_TR_ID_LEN);
|
||||
|
||||
os_memset(&mgmt, 0, sizeof(mgmt));
|
||||
mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
||||
WLAN_FC_STYPE_ACTION);
|
||||
os_memcpy(mgmt.da, addr, ETH_ALEN);
|
||||
os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
|
||||
os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
|
||||
mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
|
||||
mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
|
||||
os_memcpy(mgmt.u.action.u.sa_query_req.trans_id, trans_id,
|
||||
WLAN_SA_QUERY_TR_ID_LEN);
|
||||
end = mgmt.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN;
|
||||
if (hostapd_drv_send_mlme(hapd, &mgmt, end - (u8 *) &mgmt, 0) < 0)
|
||||
wpa_printf(MSG_INFO, "ieee802_11_send_sa_query_req: send failed");
|
||||
}
|
||||
|
||||
|
||||
static void ieee802_11_send_sa_query_resp(struct hostapd_data *hapd,
|
||||
const u8 *sa, const u8 *trans_id)
|
||||
{
|
||||
struct sta_info *sta;
|
||||
struct ieee80211_mgmt resp;
|
||||
u8 *end;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.11: Received SA Query Request from "
|
||||
MACSTR, MAC2STR(sa));
|
||||
wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID",
|
||||
trans_id, WLAN_SA_QUERY_TR_ID_LEN);
|
||||
|
||||
sta = ap_get_sta(hapd, sa);
|
||||
if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignore SA Query Request "
|
||||
"from unassociated STA " MACSTR, MAC2STR(sa));
|
||||
return;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.11: Sending SA Query Response to "
|
||||
MACSTR, MAC2STR(sa));
|
||||
|
||||
os_memset(&resp, 0, sizeof(resp));
|
||||
resp.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
||||
WLAN_FC_STYPE_ACTION);
|
||||
os_memcpy(resp.da, sa, ETH_ALEN);
|
||||
os_memcpy(resp.sa, hapd->own_addr, ETH_ALEN);
|
||||
os_memcpy(resp.bssid, hapd->own_addr, ETH_ALEN);
|
||||
resp.u.action.category = WLAN_ACTION_SA_QUERY;
|
||||
resp.u.action.u.sa_query_req.action = WLAN_SA_QUERY_RESPONSE;
|
||||
os_memcpy(resp.u.action.u.sa_query_req.trans_id, trans_id,
|
||||
WLAN_SA_QUERY_TR_ID_LEN);
|
||||
end = resp.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN;
|
||||
if (hostapd_drv_send_mlme(hapd, &resp, end - (u8 *) &resp, 0) < 0)
|
||||
wpa_printf(MSG_INFO, "ieee80211_mgmt_sa_query_request: send failed");
|
||||
}
|
||||
|
||||
|
||||
void ieee802_11_sa_query_action(struct hostapd_data *hapd, const u8 *sa,
|
||||
const u8 action_type, const u8 *trans_id)
|
||||
{
|
||||
struct sta_info *sta;
|
||||
int i;
|
||||
|
||||
if (action_type == WLAN_SA_QUERY_REQUEST) {
|
||||
ieee802_11_send_sa_query_resp(hapd, sa, trans_id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (action_type != WLAN_SA_QUERY_RESPONSE) {
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.11: Unexpected SA Query "
|
||||
"Action %d", action_type);
|
||||
return;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.11: Received SA Query Response from "
|
||||
MACSTR, MAC2STR(sa));
|
||||
wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID",
|
||||
trans_id, WLAN_SA_QUERY_TR_ID_LEN);
|
||||
|
||||
/* MLME-SAQuery.confirm */
|
||||
|
||||
sta = ap_get_sta(hapd, sa);
|
||||
if (sta == NULL || sta->sa_query_trans_id == NULL) {
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.11: No matching STA with "
|
||||
"pending SA Query request found");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < sta->sa_query_count; i++) {
|
||||
if (os_memcmp(sta->sa_query_trans_id +
|
||||
i * WLAN_SA_QUERY_TR_ID_LEN,
|
||||
trans_id, WLAN_SA_QUERY_TR_ID_LEN) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= sta->sa_query_count) {
|
||||
wpa_printf(MSG_DEBUG, "IEEE 802.11: No matching SA Query "
|
||||
"transaction identifier found");
|
||||
return;
|
||||
}
|
||||
|
||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_DEBUG,
|
||||
"Reply to pending SA Query received");
|
||||
ap_sta_stop_sa_query(hapd, sta);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
|
||||
static void hostapd_ext_capab_byte(struct hostapd_data *hapd, u8 *pos, int idx)
|
||||
{
|
||||
*pos = 0x00;
|
||||
|
||||
switch (idx) {
|
||||
case 0: /* Bits 0-7 */
|
||||
if (hapd->iconf->obss_interval)
|
||||
*pos |= 0x01; /* Bit 0 - Coexistence management */
|
||||
break;
|
||||
case 1: /* Bits 8-15 */
|
||||
if (hapd->conf->proxy_arp)
|
||||
*pos |= 0x10; /* Bit 12 - Proxy ARP */
|
||||
break;
|
||||
case 2: /* Bits 16-23 */
|
||||
if (hapd->conf->wnm_sleep_mode)
|
||||
*pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
|
||||
if (hapd->conf->bss_transition)
|
||||
*pos |= 0x08; /* Bit 19 - BSS Transition */
|
||||
break;
|
||||
case 3: /* Bits 24-31 */
|
||||
#ifdef CONFIG_WNM
|
||||
*pos |= 0x02; /* Bit 25 - SSID List */
|
||||
#endif /* CONFIG_WNM */
|
||||
if (hapd->conf->time_advertisement == 2)
|
||||
*pos |= 0x08; /* Bit 27 - UTC TSF Offset */
|
||||
if (hapd->conf->interworking)
|
||||
*pos |= 0x80; /* Bit 31 - Interworking */
|
||||
break;
|
||||
case 4: /* Bits 32-39 */
|
||||
if (hapd->conf->qos_map_set_len)
|
||||
*pos |= 0x01; /* Bit 32 - QoS Map */
|
||||
if (hapd->conf->tdls & TDLS_PROHIBIT)
|
||||
*pos |= 0x40; /* Bit 38 - TDLS Prohibited */
|
||||
if (hapd->conf->tdls & TDLS_PROHIBIT_CHAN_SWITCH) {
|
||||
/* Bit 39 - TDLS Channel Switching Prohibited */
|
||||
*pos |= 0x80;
|
||||
}
|
||||
break;
|
||||
case 5: /* Bits 40-47 */
|
||||
#ifdef CONFIG_HS20
|
||||
if (hapd->conf->hs20)
|
||||
*pos |= 0x40; /* Bit 46 - WNM-Notification */
|
||||
#endif /* CONFIG_HS20 */
|
||||
break;
|
||||
case 6: /* Bits 48-55 */
|
||||
if (hapd->conf->ssid.utf8_ssid)
|
||||
*pos |= 0x01; /* Bit 48 - UTF-8 SSID */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
u8 *pos = eid;
|
||||
u8 len = 0, i;
|
||||
|
||||
if (hapd->conf->tdls & (TDLS_PROHIBIT | TDLS_PROHIBIT_CHAN_SWITCH))
|
||||
len = 5;
|
||||
if (len < 4 && hapd->conf->interworking)
|
||||
len = 4;
|
||||
if (len < 3 && hapd->conf->wnm_sleep_mode)
|
||||
len = 3;
|
||||
if (len < 1 && hapd->iconf->obss_interval)
|
||||
len = 1;
|
||||
if (len < 7 && hapd->conf->ssid.utf8_ssid)
|
||||
len = 7;
|
||||
#ifdef CONFIG_WNM
|
||||
if (len < 4)
|
||||
len = 4;
|
||||
#endif /* CONFIG_WNM */
|
||||
#ifdef CONFIG_HS20
|
||||
if (hapd->conf->hs20 && len < 6)
|
||||
len = 6;
|
||||
#endif /* CONFIG_HS20 */
|
||||
if (len < hapd->iface->extended_capa_len)
|
||||
len = hapd->iface->extended_capa_len;
|
||||
if (len == 0)
|
||||
return eid;
|
||||
|
||||
*pos++ = WLAN_EID_EXT_CAPAB;
|
||||
*pos++ = len;
|
||||
for (i = 0; i < len; i++, pos++) {
|
||||
hostapd_ext_capab_byte(hapd, pos, i);
|
||||
|
||||
if (i < hapd->iface->extended_capa_len) {
|
||||
*pos &= ~hapd->iface->extended_capa_mask[i];
|
||||
*pos |= hapd->iface->extended_capa[i];
|
||||
}
|
||||
}
|
||||
|
||||
while (len > 0 && eid[1 + len] == 0) {
|
||||
len--;
|
||||
eid[1] = len;
|
||||
}
|
||||
if (len == 0)
|
||||
return eid;
|
||||
|
||||
return eid + 2 + len;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_qos_map_set(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
u8 *pos = eid;
|
||||
u8 len = hapd->conf->qos_map_set_len;
|
||||
|
||||
if (!len)
|
||||
return eid;
|
||||
|
||||
*pos++ = WLAN_EID_QOS_MAP_SET;
|
||||
*pos++ = len;
|
||||
os_memcpy(pos, hapd->conf->qos_map_set, len);
|
||||
pos += len;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_interworking(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
u8 *pos = eid;
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
u8 *len;
|
||||
|
||||
if (!hapd->conf->interworking)
|
||||
return eid;
|
||||
|
||||
*pos++ = WLAN_EID_INTERWORKING;
|
||||
len = pos++;
|
||||
|
||||
*pos = hapd->conf->access_network_type;
|
||||
if (hapd->conf->internet)
|
||||
*pos |= INTERWORKING_ANO_INTERNET;
|
||||
if (hapd->conf->asra)
|
||||
*pos |= INTERWORKING_ANO_ASRA;
|
||||
if (hapd->conf->esr)
|
||||
*pos |= INTERWORKING_ANO_ESR;
|
||||
if (hapd->conf->uesa)
|
||||
*pos |= INTERWORKING_ANO_UESA;
|
||||
pos++;
|
||||
|
||||
if (hapd->conf->venue_info_set) {
|
||||
*pos++ = hapd->conf->venue_group;
|
||||
*pos++ = hapd->conf->venue_type;
|
||||
}
|
||||
|
||||
if (!is_zero_ether_addr(hapd->conf->hessid)) {
|
||||
os_memcpy(pos, hapd->conf->hessid, ETH_ALEN);
|
||||
pos += ETH_ALEN;
|
||||
}
|
||||
|
||||
*len = pos - len - 1;
|
||||
#endif /* CONFIG_INTERWORKING */
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_adv_proto(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
u8 *pos = eid;
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
|
||||
/* TODO: Separate configuration for ANQP? */
|
||||
if (!hapd->conf->interworking)
|
||||
return eid;
|
||||
|
||||
*pos++ = WLAN_EID_ADV_PROTO;
|
||||
*pos++ = 2;
|
||||
*pos++ = 0x7F; /* Query Response Length Limit | PAME-BI */
|
||||
*pos++ = ACCESS_NETWORK_QUERY_PROTOCOL;
|
||||
#endif /* CONFIG_INTERWORKING */
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_roaming_consortium(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
u8 *pos = eid;
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
u8 *len;
|
||||
unsigned int i, count;
|
||||
|
||||
if (!hapd->conf->interworking ||
|
||||
hapd->conf->roaming_consortium == NULL ||
|
||||
hapd->conf->roaming_consortium_count == 0)
|
||||
return eid;
|
||||
|
||||
*pos++ = WLAN_EID_ROAMING_CONSORTIUM;
|
||||
len = pos++;
|
||||
|
||||
/* Number of ANQP OIs (in addition to the max 3 listed here) */
|
||||
if (hapd->conf->roaming_consortium_count > 3 + 255)
|
||||
*pos++ = 255;
|
||||
else if (hapd->conf->roaming_consortium_count > 3)
|
||||
*pos++ = hapd->conf->roaming_consortium_count - 3;
|
||||
else
|
||||
*pos++ = 0;
|
||||
|
||||
/* OU #1 and #2 Lengths */
|
||||
*pos = hapd->conf->roaming_consortium[0].len;
|
||||
if (hapd->conf->roaming_consortium_count > 1)
|
||||
*pos |= hapd->conf->roaming_consortium[1].len << 4;
|
||||
pos++;
|
||||
|
||||
if (hapd->conf->roaming_consortium_count > 3)
|
||||
count = 3;
|
||||
else
|
||||
count = hapd->conf->roaming_consortium_count;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
os_memcpy(pos, hapd->conf->roaming_consortium[i].oi,
|
||||
hapd->conf->roaming_consortium[i].len);
|
||||
pos += hapd->conf->roaming_consortium[i].len;
|
||||
}
|
||||
|
||||
*len = pos - len - 1;
|
||||
#endif /* CONFIG_INTERWORKING */
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_time_adv(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
if (hapd->conf->time_advertisement != 2)
|
||||
return eid;
|
||||
|
||||
if (hapd->time_adv == NULL &&
|
||||
hostapd_update_time_adv(hapd) < 0)
|
||||
return eid;
|
||||
|
||||
if (hapd->time_adv == NULL)
|
||||
return eid;
|
||||
|
||||
os_memcpy(eid, wpabuf_head(hapd->time_adv),
|
||||
wpabuf_len(hapd->time_adv));
|
||||
eid += wpabuf_len(hapd->time_adv);
|
||||
|
||||
return eid;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_time_zone(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (hapd->conf->time_advertisement != 2)
|
||||
return eid;
|
||||
|
||||
len = os_strlen(hapd->conf->time_zone);
|
||||
|
||||
*eid++ = WLAN_EID_TIME_ZONE;
|
||||
*eid++ = len;
|
||||
os_memcpy(eid, hapd->conf->time_zone, len);
|
||||
eid += len;
|
||||
|
||||
return eid;
|
||||
}
|
||||
|
||||
|
||||
int hostapd_update_time_adv(struct hostapd_data *hapd)
|
||||
{
|
||||
const int elen = 2 + 1 + 10 + 5 + 1;
|
||||
struct os_time t;
|
||||
struct os_tm tm;
|
||||
u8 *pos;
|
||||
|
||||
if (hapd->conf->time_advertisement != 2)
|
||||
return 0;
|
||||
|
||||
if (os_get_time(&t) < 0 || os_gmtime(t.sec, &tm) < 0)
|
||||
return -1;
|
||||
|
||||
if (!hapd->time_adv) {
|
||||
hapd->time_adv = wpabuf_alloc(elen);
|
||||
if (hapd->time_adv == NULL)
|
||||
return -1;
|
||||
pos = wpabuf_put(hapd->time_adv, elen);
|
||||
} else
|
||||
pos = wpabuf_mhead_u8(hapd->time_adv);
|
||||
|
||||
*pos++ = WLAN_EID_TIME_ADVERTISEMENT;
|
||||
*pos++ = 1 + 10 + 5 + 1;
|
||||
|
||||
*pos++ = 2; /* UTC time at which the TSF timer is 0 */
|
||||
|
||||
/* Time Value at TSF 0 */
|
||||
/* FIX: need to calculate this based on the current TSF value */
|
||||
WPA_PUT_LE16(pos, tm.year); /* Year */
|
||||
pos += 2;
|
||||
*pos++ = tm.month; /* Month */
|
||||
*pos++ = tm.day; /* Day of month */
|
||||
*pos++ = tm.hour; /* Hours */
|
||||
*pos++ = tm.min; /* Minutes */
|
||||
*pos++ = tm.sec; /* Seconds */
|
||||
WPA_PUT_LE16(pos, 0); /* Milliseconds (not used) */
|
||||
pos += 2;
|
||||
*pos++ = 0; /* Reserved */
|
||||
|
||||
/* Time Error */
|
||||
/* TODO: fill in an estimate on the error */
|
||||
*pos++ = 0;
|
||||
*pos++ = 0;
|
||||
*pos++ = 0;
|
||||
*pos++ = 0;
|
||||
*pos++ = 0;
|
||||
|
||||
*pos++ = hapd->time_update_counter++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid)
|
||||
{
|
||||
u8 *pos = eid;
|
||||
|
||||
#ifdef CONFIG_WNM
|
||||
if (hapd->conf->ap_max_inactivity > 0) {
|
||||
unsigned int val;
|
||||
*pos++ = WLAN_EID_BSS_MAX_IDLE_PERIOD;
|
||||
*pos++ = 3;
|
||||
val = hapd->conf->ap_max_inactivity;
|
||||
if (val > 68000)
|
||||
val = 68000;
|
||||
val *= 1000;
|
||||
val /= 1024;
|
||||
if (val == 0)
|
||||
val = 1;
|
||||
if (val > 65535)
|
||||
val = 65535;
|
||||
WPA_PUT_LE16(pos, val);
|
||||
pos += 2;
|
||||
*pos++ = 0x00; /* TODO: Protected Keep-Alive Required */
|
||||
}
|
||||
#endif /* CONFIG_WNM */
|
||||
|
||||
return pos;
|
||||
}
|
35
freebsd/contrib/wpa/src/ap/p2p_hostapd.h
Normal file
35
freebsd/contrib/wpa/src/ap/p2p_hostapd.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* hostapd / P2P integration
|
||||
* Copyright (c) 2009-2010, Atheros Communications
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef P2P_HOSTAPD_H
|
||||
#define P2P_HOSTAPD_H
|
||||
|
||||
#ifdef CONFIG_P2P
|
||||
|
||||
int hostapd_p2p_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
char *buf, size_t buflen);
|
||||
int hostapd_p2p_set_noa(struct hostapd_data *hapd, u8 count, int start,
|
||||
int duration);
|
||||
void hostapd_p2p_non_p2p_sta_connected(struct hostapd_data *hapd);
|
||||
void hostapd_p2p_non_p2p_sta_disconnected(struct hostapd_data *hapd);
|
||||
|
||||
|
||||
#else /* CONFIG_P2P */
|
||||
|
||||
static inline int hostapd_p2p_get_mib_sta(struct hostapd_data *hapd,
|
||||
struct sta_info *sta,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_P2P */
|
||||
|
||||
u8 * hostapd_eid_p2p_manage(struct hostapd_data *hapd, u8 *eid);
|
||||
|
||||
#endif /* P2P_HOSTAPD_H */
|
241
freebsd/contrib/wpa/src/ap/sta_info.h
Normal file
241
freebsd/contrib/wpa/src/ap/sta_info.h
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* hostapd / Station table
|
||||
* Copyright (c) 2002-2011, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef STA_INFO_H
|
||||
#define STA_INFO_H
|
||||
|
||||
#ifdef CONFIG_MESH
|
||||
/* needed for mesh_plink_state enum */
|
||||
#include "common/defs.h"
|
||||
#endif /* CONFIG_MESH */
|
||||
|
||||
#include "list.h"
|
||||
|
||||
/* STA flags */
|
||||
#define WLAN_STA_AUTH BIT(0)
|
||||
#define WLAN_STA_ASSOC BIT(1)
|
||||
#define WLAN_STA_AUTHORIZED BIT(5)
|
||||
#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */
|
||||
#define WLAN_STA_SHORT_PREAMBLE BIT(7)
|
||||
#define WLAN_STA_PREAUTH BIT(8)
|
||||
#define WLAN_STA_WMM BIT(9)
|
||||
#define WLAN_STA_MFP BIT(10)
|
||||
#define WLAN_STA_HT BIT(11)
|
||||
#define WLAN_STA_WPS BIT(12)
|
||||
#define WLAN_STA_MAYBE_WPS BIT(13)
|
||||
#define WLAN_STA_WDS BIT(14)
|
||||
#define WLAN_STA_ASSOC_REQ_OK BIT(15)
|
||||
#define WLAN_STA_WPS2 BIT(16)
|
||||
#define WLAN_STA_GAS BIT(17)
|
||||
#define WLAN_STA_VHT BIT(18)
|
||||
#define WLAN_STA_WNM_SLEEP_MODE BIT(19)
|
||||
#define WLAN_STA_VHT_OPMODE_ENABLED BIT(20)
|
||||
#define WLAN_STA_VENDOR_VHT BIT(21)
|
||||
#define WLAN_STA_PENDING_DISASSOC_CB BIT(29)
|
||||
#define WLAN_STA_PENDING_DEAUTH_CB BIT(30)
|
||||
#define WLAN_STA_NONERP BIT(31)
|
||||
|
||||
/* Maximum number of supported rates (from both Supported Rates and Extended
|
||||
* Supported Rates IEs). */
|
||||
#define WLAN_SUPP_RATES_MAX 32
|
||||
|
||||
|
||||
struct sta_info {
|
||||
struct sta_info *next; /* next entry in sta list */
|
||||
struct sta_info *hnext; /* next entry in hash table list */
|
||||
u8 addr[6];
|
||||
be32 ipaddr;
|
||||
struct dl_list ip6addr; /* list head for struct ip6addr */
|
||||
u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */
|
||||
u32 flags; /* Bitfield of WLAN_STA_* */
|
||||
u16 capability;
|
||||
u16 listen_interval; /* or beacon_int for APs */
|
||||
u8 supported_rates[WLAN_SUPP_RATES_MAX];
|
||||
int supported_rates_len;
|
||||
u8 qosinfo; /* Valid when WLAN_STA_WMM is set */
|
||||
|
||||
#ifdef CONFIG_MESH
|
||||
enum mesh_plink_state plink_state;
|
||||
u16 peer_lid;
|
||||
u16 my_lid;
|
||||
u16 mpm_close_reason;
|
||||
int mpm_retries;
|
||||
u8 my_nonce[32];
|
||||
u8 peer_nonce[32];
|
||||
u8 aek[32]; /* SHA256 digest length */
|
||||
u8 mtk[16];
|
||||
u8 mgtk[16];
|
||||
u8 sae_auth_retry;
|
||||
#endif /* CONFIG_MESH */
|
||||
|
||||
unsigned int nonerp_set:1;
|
||||
unsigned int no_short_slot_time_set:1;
|
||||
unsigned int no_short_preamble_set:1;
|
||||
unsigned int no_ht_gf_set:1;
|
||||
unsigned int no_ht_set:1;
|
||||
unsigned int ht40_intolerant_set:1;
|
||||
unsigned int ht_20mhz_set:1;
|
||||
unsigned int no_p2p_set:1;
|
||||
unsigned int qos_map_enabled:1;
|
||||
unsigned int remediation:1;
|
||||
unsigned int hs20_deauth_requested:1;
|
||||
unsigned int session_timeout_set:1;
|
||||
unsigned int radius_das_match:1;
|
||||
|
||||
u16 auth_alg;
|
||||
|
||||
enum {
|
||||
STA_NULLFUNC = 0, STA_DISASSOC, STA_DEAUTH, STA_REMOVE,
|
||||
STA_DISASSOC_FROM_CLI
|
||||
} timeout_next;
|
||||
|
||||
u16 deauth_reason;
|
||||
u16 disassoc_reason;
|
||||
|
||||
/* IEEE 802.1X related data */
|
||||
struct eapol_state_machine *eapol_sm;
|
||||
|
||||
u32 acct_session_id_hi;
|
||||
u32 acct_session_id_lo;
|
||||
struct os_reltime acct_session_start;
|
||||
int acct_session_started;
|
||||
int acct_terminate_cause; /* Acct-Terminate-Cause */
|
||||
int acct_interim_interval; /* Acct-Interim-Interval */
|
||||
|
||||
unsigned long last_rx_bytes;
|
||||
unsigned long last_tx_bytes;
|
||||
u32 acct_input_gigawords; /* Acct-Input-Gigawords */
|
||||
u32 acct_output_gigawords; /* Acct-Output-Gigawords */
|
||||
|
||||
u8 *challenge; /* IEEE 802.11 Shared Key Authentication Challenge */
|
||||
|
||||
struct wpa_state_machine *wpa_sm;
|
||||
struct rsn_preauth_interface *preauth_iface;
|
||||
|
||||
int vlan_id; /* 0: none, >0: VID */
|
||||
int vlan_id_bound; /* updated by ap_sta_bind_vlan() */
|
||||
/* PSKs from RADIUS authentication server */
|
||||
struct hostapd_sta_wpa_psk_short *psk;
|
||||
|
||||
char *identity; /* User-Name from RADIUS */
|
||||
char *radius_cui; /* Chargeable-User-Identity from RADIUS */
|
||||
|
||||
struct ieee80211_ht_capabilities *ht_capabilities;
|
||||
struct ieee80211_vht_capabilities *vht_capabilities;
|
||||
u8 vht_opmode;
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
int sa_query_count; /* number of pending SA Query requests;
|
||||
* 0 = no SA Query in progress */
|
||||
int sa_query_timed_out;
|
||||
u8 *sa_query_trans_id; /* buffer of WLAN_SA_QUERY_TR_ID_LEN *
|
||||
* sa_query_count octets of pending SA Query
|
||||
* transaction identifiers */
|
||||
struct os_reltime sa_query_start;
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
#define GAS_DIALOG_MAX 8 /* Max concurrent dialog number */
|
||||
struct gas_dialog_info *gas_dialog;
|
||||
u8 gas_dialog_next;
|
||||
#endif /* CONFIG_INTERWORKING */
|
||||
|
||||
struct wpabuf *wps_ie; /* WPS IE from (Re)Association Request */
|
||||
struct wpabuf *p2p_ie; /* P2P IE from (Re)Association Request */
|
||||
struct wpabuf *hs20_ie; /* HS 2.0 IE from (Re)Association Request */
|
||||
u8 remediation_method;
|
||||
char *remediation_url; /* HS 2.0 Subscription Remediation Server URL */
|
||||
struct wpabuf *hs20_deauth_req;
|
||||
char *hs20_session_info_url;
|
||||
int hs20_disassoc_timer;
|
||||
#ifdef CONFIG_FST
|
||||
struct wpabuf *mb_ies; /* MB IEs from (Re)Association Request */
|
||||
#endif /* CONFIG_FST */
|
||||
|
||||
struct os_reltime connected_time;
|
||||
|
||||
#ifdef CONFIG_SAE
|
||||
struct sae_data *sae;
|
||||
#endif /* CONFIG_SAE */
|
||||
|
||||
u32 session_timeout; /* valid only if session_timeout_set == 1 */
|
||||
|
||||
/* Last Authentication/(Re)Association Request/Action frame sequence
|
||||
* control */
|
||||
u16 last_seq_ctrl;
|
||||
/* Last Authentication/(Re)Association Request/Action frame subtype */
|
||||
u8 last_subtype;
|
||||
};
|
||||
|
||||
|
||||
/* Default value for maximum station inactivity. After AP_MAX_INACTIVITY has
|
||||
* passed since last received frame from the station, a nullfunc data frame is
|
||||
* sent to the station. If this frame is not acknowledged and no other frames
|
||||
* have been received, the station will be disassociated after
|
||||
* AP_DISASSOC_DELAY seconds. Similarly, the station will be deauthenticated
|
||||
* after AP_DEAUTH_DELAY seconds has passed after disassociation. */
|
||||
#define AP_MAX_INACTIVITY (5 * 60)
|
||||
#define AP_DISASSOC_DELAY (1)
|
||||
#define AP_DEAUTH_DELAY (1)
|
||||
/* Number of seconds to keep STA entry with Authenticated flag after it has
|
||||
* been disassociated. */
|
||||
#define AP_MAX_INACTIVITY_AFTER_DISASSOC (1 * 30)
|
||||
/* Number of seconds to keep STA entry after it has been deauthenticated. */
|
||||
#define AP_MAX_INACTIVITY_AFTER_DEAUTH (1 * 5)
|
||||
|
||||
|
||||
struct hostapd_data;
|
||||
|
||||
int ap_for_each_sta(struct hostapd_data *hapd,
|
||||
int (*cb)(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
void *ctx),
|
||||
void *ctx);
|
||||
struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta);
|
||||
struct sta_info * ap_get_sta_p2p(struct hostapd_data *hapd, const u8 *addr);
|
||||
void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_sta_ip6addr_del(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void hostapd_free_stas(struct hostapd_data *hapd);
|
||||
void ap_handle_timer(void *eloop_ctx, void *timeout_ctx);
|
||||
void ap_sta_replenish_timeout(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u32 session_timeout);
|
||||
void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u32 session_timeout);
|
||||
void ap_sta_no_session_timeout(struct hostapd_data *hapd,
|
||||
struct sta_info *sta);
|
||||
void ap_sta_session_warning_timeout(struct hostapd_data *hapd,
|
||||
struct sta_info *sta, int warning_time);
|
||||
struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr);
|
||||
void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u16 reason);
|
||||
void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
u16 reason);
|
||||
#ifdef CONFIG_WPS
|
||||
int ap_sta_wps_cancel(struct hostapd_data *hapd,
|
||||
struct sta_info *sta, void *ctx);
|
||||
#endif /* CONFIG_WPS */
|
||||
int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
const u8 *addr, u16 reason);
|
||||
|
||||
void ap_sta_set_authorized(struct hostapd_data *hapd,
|
||||
struct sta_info *sta, int authorized);
|
||||
static inline int ap_sta_is_authorized(struct sta_info *sta)
|
||||
{
|
||||
return sta->flags & WLAN_STA_AUTHORIZED;
|
||||
}
|
||||
|
||||
void ap_sta_deauth_cb(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
void ap_sta_disassoc_cb(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
|
||||
int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen);
|
||||
|
||||
#endif /* STA_INFO_H */
|
337
freebsd/contrib/wpa/src/common/defs.h
Normal file
337
freebsd/contrib/wpa/src/common/defs.h
Normal file
@ -0,0 +1,337 @@
|
||||
/*
|
||||
* WPA Supplicant - Common definitions
|
||||
* Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef DEFS_H
|
||||
#define DEFS_H
|
||||
|
||||
#ifdef FALSE
|
||||
#undef FALSE
|
||||
#endif
|
||||
#ifdef TRUE
|
||||
#undef TRUE
|
||||
#endif
|
||||
typedef enum { FALSE = 0, TRUE = 1 } Boolean;
|
||||
|
||||
|
||||
#define WPA_CIPHER_NONE BIT(0)
|
||||
#define WPA_CIPHER_WEP40 BIT(1)
|
||||
#define WPA_CIPHER_WEP104 BIT(2)
|
||||
#define WPA_CIPHER_TKIP BIT(3)
|
||||
#define WPA_CIPHER_CCMP BIT(4)
|
||||
#define WPA_CIPHER_AES_128_CMAC BIT(5)
|
||||
#define WPA_CIPHER_GCMP BIT(6)
|
||||
#define WPA_CIPHER_SMS4 BIT(7)
|
||||
#define WPA_CIPHER_GCMP_256 BIT(8)
|
||||
#define WPA_CIPHER_CCMP_256 BIT(9)
|
||||
#define WPA_CIPHER_BIP_GMAC_128 BIT(11)
|
||||
#define WPA_CIPHER_BIP_GMAC_256 BIT(12)
|
||||
#define WPA_CIPHER_BIP_CMAC_256 BIT(13)
|
||||
#define WPA_CIPHER_GTK_NOT_USED BIT(14)
|
||||
|
||||
#define WPA_KEY_MGMT_IEEE8021X BIT(0)
|
||||
#define WPA_KEY_MGMT_PSK BIT(1)
|
||||
#define WPA_KEY_MGMT_NONE BIT(2)
|
||||
#define WPA_KEY_MGMT_IEEE8021X_NO_WPA BIT(3)
|
||||
#define WPA_KEY_MGMT_WPA_NONE BIT(4)
|
||||
#define WPA_KEY_MGMT_FT_IEEE8021X BIT(5)
|
||||
#define WPA_KEY_MGMT_FT_PSK BIT(6)
|
||||
#define WPA_KEY_MGMT_IEEE8021X_SHA256 BIT(7)
|
||||
#define WPA_KEY_MGMT_PSK_SHA256 BIT(8)
|
||||
#define WPA_KEY_MGMT_WPS BIT(9)
|
||||
#define WPA_KEY_MGMT_SAE BIT(10)
|
||||
#define WPA_KEY_MGMT_FT_SAE BIT(11)
|
||||
#define WPA_KEY_MGMT_WAPI_PSK BIT(12)
|
||||
#define WPA_KEY_MGMT_WAPI_CERT BIT(13)
|
||||
#define WPA_KEY_MGMT_CCKM BIT(14)
|
||||
#define WPA_KEY_MGMT_OSEN BIT(15)
|
||||
#define WPA_KEY_MGMT_IEEE8021X_SUITE_B BIT(16)
|
||||
#define WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 BIT(17)
|
||||
|
||||
static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
|
||||
{
|
||||
return !!(akm & (WPA_KEY_MGMT_IEEE8021X |
|
||||
WPA_KEY_MGMT_FT_IEEE8021X |
|
||||
WPA_KEY_MGMT_CCKM |
|
||||
WPA_KEY_MGMT_OSEN |
|
||||
WPA_KEY_MGMT_IEEE8021X_SHA256 |
|
||||
WPA_KEY_MGMT_IEEE8021X_SUITE_B |
|
||||
WPA_KEY_MGMT_IEEE8021X_SUITE_B_192));
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_wpa_psk(int akm)
|
||||
{
|
||||
return !!(akm & (WPA_KEY_MGMT_PSK |
|
||||
WPA_KEY_MGMT_FT_PSK |
|
||||
WPA_KEY_MGMT_PSK_SHA256 |
|
||||
WPA_KEY_MGMT_SAE |
|
||||
WPA_KEY_MGMT_FT_SAE));
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_ft(int akm)
|
||||
{
|
||||
return !!(akm & (WPA_KEY_MGMT_FT_PSK |
|
||||
WPA_KEY_MGMT_FT_IEEE8021X |
|
||||
WPA_KEY_MGMT_FT_SAE));
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_sae(int akm)
|
||||
{
|
||||
return !!(akm & (WPA_KEY_MGMT_SAE |
|
||||
WPA_KEY_MGMT_FT_SAE));
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_sha256(int akm)
|
||||
{
|
||||
return !!(akm & (WPA_KEY_MGMT_PSK_SHA256 |
|
||||
WPA_KEY_MGMT_IEEE8021X_SHA256 |
|
||||
WPA_KEY_MGMT_OSEN |
|
||||
WPA_KEY_MGMT_IEEE8021X_SUITE_B));
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_sha384(int akm)
|
||||
{
|
||||
return !!(akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192);
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_suite_b(int akm)
|
||||
{
|
||||
return !!(akm & (WPA_KEY_MGMT_IEEE8021X_SUITE_B |
|
||||
WPA_KEY_MGMT_IEEE8021X_SUITE_B_192));
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_wpa(int akm)
|
||||
{
|
||||
return wpa_key_mgmt_wpa_ieee8021x(akm) ||
|
||||
wpa_key_mgmt_wpa_psk(akm) ||
|
||||
wpa_key_mgmt_sae(akm);
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_wpa_any(int akm)
|
||||
{
|
||||
return wpa_key_mgmt_wpa(akm) || (akm & WPA_KEY_MGMT_WPA_NONE);
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_cckm(int akm)
|
||||
{
|
||||
return akm == WPA_KEY_MGMT_CCKM;
|
||||
}
|
||||
|
||||
|
||||
#define WPA_PROTO_WPA BIT(0)
|
||||
#define WPA_PROTO_RSN BIT(1)
|
||||
#define WPA_PROTO_WAPI BIT(2)
|
||||
#define WPA_PROTO_OSEN BIT(3)
|
||||
|
||||
#define WPA_AUTH_ALG_OPEN BIT(0)
|
||||
#define WPA_AUTH_ALG_SHARED BIT(1)
|
||||
#define WPA_AUTH_ALG_LEAP BIT(2)
|
||||
#define WPA_AUTH_ALG_FT BIT(3)
|
||||
#define WPA_AUTH_ALG_SAE BIT(4)
|
||||
|
||||
|
||||
enum wpa_alg {
|
||||
WPA_ALG_NONE,
|
||||
WPA_ALG_WEP,
|
||||
WPA_ALG_TKIP,
|
||||
WPA_ALG_CCMP,
|
||||
WPA_ALG_IGTK,
|
||||
WPA_ALG_PMK,
|
||||
WPA_ALG_GCMP,
|
||||
WPA_ALG_SMS4,
|
||||
WPA_ALG_KRK,
|
||||
WPA_ALG_GCMP_256,
|
||||
WPA_ALG_CCMP_256,
|
||||
WPA_ALG_BIP_GMAC_128,
|
||||
WPA_ALG_BIP_GMAC_256,
|
||||
WPA_ALG_BIP_CMAC_256
|
||||
};
|
||||
|
||||
/**
|
||||
* enum wpa_states - wpa_supplicant state
|
||||
*
|
||||
* These enumeration values are used to indicate the current wpa_supplicant
|
||||
* state (wpa_s->wpa_state). The current state can be retrieved with
|
||||
* wpa_supplicant_get_state() function and the state can be changed by calling
|
||||
* wpa_supplicant_set_state(). In WPA state machine (wpa.c and preauth.c), the
|
||||
* wrapper functions wpa_sm_get_state() and wpa_sm_set_state() should be used
|
||||
* to access the state variable.
|
||||
*/
|
||||
enum wpa_states {
|
||||
/**
|
||||
* WPA_DISCONNECTED - Disconnected state
|
||||
*
|
||||
* This state indicates that client is not associated, but is likely to
|
||||
* start looking for an access point. This state is entered when a
|
||||
* connection is lost.
|
||||
*/
|
||||
WPA_DISCONNECTED,
|
||||
|
||||
/**
|
||||
* WPA_INTERFACE_DISABLED - Interface disabled
|
||||
*
|
||||
* This state is entered if the network interface is disabled, e.g.,
|
||||
* due to rfkill. wpa_supplicant refuses any new operations that would
|
||||
* use the radio until the interface has been enabled.
|
||||
*/
|
||||
WPA_INTERFACE_DISABLED,
|
||||
|
||||
/**
|
||||
* WPA_INACTIVE - Inactive state (wpa_supplicant disabled)
|
||||
*
|
||||
* This state is entered if there are no enabled networks in the
|
||||
* configuration. wpa_supplicant is not trying to associate with a new
|
||||
* network and external interaction (e.g., ctrl_iface call to add or
|
||||
* enable a network) is needed to start association.
|
||||
*/
|
||||
WPA_INACTIVE,
|
||||
|
||||
/**
|
||||
* WPA_SCANNING - Scanning for a network
|
||||
*
|
||||
* This state is entered when wpa_supplicant starts scanning for a
|
||||
* network.
|
||||
*/
|
||||
WPA_SCANNING,
|
||||
|
||||
/**
|
||||
* WPA_AUTHENTICATING - Trying to authenticate with a BSS/SSID
|
||||
*
|
||||
* This state is entered when wpa_supplicant has found a suitable BSS
|
||||
* to authenticate with and the driver is configured to try to
|
||||
* authenticate with this BSS. This state is used only with drivers
|
||||
* that use wpa_supplicant as the SME.
|
||||
*/
|
||||
WPA_AUTHENTICATING,
|
||||
|
||||
/**
|
||||
* WPA_ASSOCIATING - Trying to associate with a BSS/SSID
|
||||
*
|
||||
* This state is entered when wpa_supplicant has found a suitable BSS
|
||||
* to associate with and the driver is configured to try to associate
|
||||
* with this BSS in ap_scan=1 mode. When using ap_scan=2 mode, this
|
||||
* state is entered when the driver is configured to try to associate
|
||||
* with a network using the configured SSID and security policy.
|
||||
*/
|
||||
WPA_ASSOCIATING,
|
||||
|
||||
/**
|
||||
* WPA_ASSOCIATED - Association completed
|
||||
*
|
||||
* This state is entered when the driver reports that association has
|
||||
* been successfully completed with an AP. If IEEE 802.1X is used
|
||||
* (with or without WPA/WPA2), wpa_supplicant remains in this state
|
||||
* until the IEEE 802.1X/EAPOL authentication has been completed.
|
||||
*/
|
||||
WPA_ASSOCIATED,
|
||||
|
||||
/**
|
||||
* WPA_4WAY_HANDSHAKE - WPA 4-Way Key Handshake in progress
|
||||
*
|
||||
* This state is entered when WPA/WPA2 4-Way Handshake is started. In
|
||||
* case of WPA-PSK, this happens when receiving the first EAPOL-Key
|
||||
* frame after association. In case of WPA-EAP, this state is entered
|
||||
* when the IEEE 802.1X/EAPOL authentication has been completed.
|
||||
*/
|
||||
WPA_4WAY_HANDSHAKE,
|
||||
|
||||
/**
|
||||
* WPA_GROUP_HANDSHAKE - WPA Group Key Handshake in progress
|
||||
*
|
||||
* This state is entered when 4-Way Key Handshake has been completed
|
||||
* (i.e., when the supplicant sends out message 4/4) and when Group
|
||||
* Key rekeying is started by the AP (i.e., when supplicant receives
|
||||
* message 1/2).
|
||||
*/
|
||||
WPA_GROUP_HANDSHAKE,
|
||||
|
||||
/**
|
||||
* WPA_COMPLETED - All authentication completed
|
||||
*
|
||||
* This state is entered when the full authentication process is
|
||||
* completed. In case of WPA2, this happens when the 4-Way Handshake is
|
||||
* successfully completed. With WPA, this state is entered after the
|
||||
* Group Key Handshake; with IEEE 802.1X (non-WPA) connection is
|
||||
* completed after dynamic keys are received (or if not used, after
|
||||
* the EAP authentication has been completed). With static WEP keys and
|
||||
* plaintext connections, this state is entered when an association
|
||||
* has been completed.
|
||||
*
|
||||
* This state indicates that the supplicant has completed its
|
||||
* processing for the association phase and that data connection is
|
||||
* fully configured.
|
||||
*/
|
||||
WPA_COMPLETED
|
||||
};
|
||||
|
||||
#define MLME_SETPROTECTION_PROTECT_TYPE_NONE 0
|
||||
#define MLME_SETPROTECTION_PROTECT_TYPE_RX 1
|
||||
#define MLME_SETPROTECTION_PROTECT_TYPE_TX 2
|
||||
#define MLME_SETPROTECTION_PROTECT_TYPE_RX_TX 3
|
||||
|
||||
#define MLME_SETPROTECTION_KEY_TYPE_GROUP 0
|
||||
#define MLME_SETPROTECTION_KEY_TYPE_PAIRWISE 1
|
||||
|
||||
|
||||
/**
|
||||
* enum mfp_options - Management frame protection (IEEE 802.11w) options
|
||||
*/
|
||||
enum mfp_options {
|
||||
NO_MGMT_FRAME_PROTECTION = 0,
|
||||
MGMT_FRAME_PROTECTION_OPTIONAL = 1,
|
||||
MGMT_FRAME_PROTECTION_REQUIRED = 2,
|
||||
};
|
||||
#define MGMT_FRAME_PROTECTION_DEFAULT 3
|
||||
|
||||
/**
|
||||
* enum hostapd_hw_mode - Hardware mode
|
||||
*/
|
||||
enum hostapd_hw_mode {
|
||||
HOSTAPD_MODE_IEEE80211B,
|
||||
HOSTAPD_MODE_IEEE80211G,
|
||||
HOSTAPD_MODE_IEEE80211A,
|
||||
HOSTAPD_MODE_IEEE80211AD,
|
||||
HOSTAPD_MODE_IEEE80211ANY,
|
||||
NUM_HOSTAPD_MODES
|
||||
};
|
||||
|
||||
/**
|
||||
* enum wpa_ctrl_req_type - Control interface request types
|
||||
*/
|
||||
enum wpa_ctrl_req_type {
|
||||
WPA_CTRL_REQ_UNKNOWN,
|
||||
WPA_CTRL_REQ_EAP_IDENTITY,
|
||||
WPA_CTRL_REQ_EAP_PASSWORD,
|
||||
WPA_CTRL_REQ_EAP_NEW_PASSWORD,
|
||||
WPA_CTRL_REQ_EAP_PIN,
|
||||
WPA_CTRL_REQ_EAP_OTP,
|
||||
WPA_CTRL_REQ_EAP_PASSPHRASE,
|
||||
WPA_CTRL_REQ_SIM,
|
||||
WPA_CTRL_REQ_PSK_PASSPHRASE,
|
||||
NUM_WPA_CTRL_REQS
|
||||
};
|
||||
|
||||
/* Maximum number of EAP methods to store for EAP server user information */
|
||||
#define EAP_MAX_METHODS 8
|
||||
|
||||
enum mesh_plink_state {
|
||||
PLINK_LISTEN = 1,
|
||||
PLINK_OPEN_SENT,
|
||||
PLINK_OPEN_RCVD,
|
||||
PLINK_CNF_RCVD,
|
||||
PLINK_ESTAB,
|
||||
PLINK_HOLDING,
|
||||
PLINK_BLOCKED,
|
||||
};
|
||||
|
||||
enum set_band {
|
||||
WPA_SETBAND_AUTO,
|
||||
WPA_SETBAND_5G,
|
||||
WPA_SETBAND_2G
|
||||
};
|
||||
|
||||
#endif /* DEFS_H */
|
92
freebsd/contrib/wpa/src/common/eapol_common.h
Normal file
92
freebsd/contrib/wpa/src/common/eapol_common.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* EAPOL definitions shared between hostapd and wpa_supplicant
|
||||
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAPOL_COMMON_H
|
||||
#define EAPOL_COMMON_H
|
||||
|
||||
/* IEEE Std 802.1X-2004 */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
struct ieee802_1x_hdr {
|
||||
u8 version;
|
||||
u8 type;
|
||||
be16 length;
|
||||
/* followed by length octets of data */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
struct ieee8023_hdr {
|
||||
u8 dest[ETH_ALEN];
|
||||
u8 src[ETH_ALEN];
|
||||
u16 ethertype;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#ifdef CONFIG_MACSEC
|
||||
#define EAPOL_VERSION 3
|
||||
#else /* CONFIG_MACSEC */
|
||||
#define EAPOL_VERSION 2
|
||||
#endif /* CONFIG_MACSEC */
|
||||
|
||||
enum { IEEE802_1X_TYPE_EAP_PACKET = 0,
|
||||
IEEE802_1X_TYPE_EAPOL_START = 1,
|
||||
IEEE802_1X_TYPE_EAPOL_LOGOFF = 2,
|
||||
IEEE802_1X_TYPE_EAPOL_KEY = 3,
|
||||
IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT = 4,
|
||||
IEEE802_1X_TYPE_EAPOL_MKA = 5,
|
||||
};
|
||||
|
||||
enum { EAPOL_KEY_TYPE_RC4 = 1, EAPOL_KEY_TYPE_RSN = 2,
|
||||
EAPOL_KEY_TYPE_WPA = 254 };
|
||||
|
||||
|
||||
#define IEEE8021X_REPLAY_COUNTER_LEN 8
|
||||
#define IEEE8021X_KEY_SIGN_LEN 16
|
||||
#define IEEE8021X_KEY_IV_LEN 16
|
||||
|
||||
#define IEEE8021X_KEY_INDEX_FLAG 0x80
|
||||
#define IEEE8021X_KEY_INDEX_MASK 0x03
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
struct ieee802_1x_eapol_key {
|
||||
u8 type;
|
||||
/* Note: key_length is unaligned */
|
||||
u8 key_length[2];
|
||||
/* does not repeat within the life of the keying material used to
|
||||
* encrypt the Key field; 64-bit NTP timestamp MAY be used here */
|
||||
u8 replay_counter[IEEE8021X_REPLAY_COUNTER_LEN];
|
||||
u8 key_iv[IEEE8021X_KEY_IV_LEN]; /* cryptographically random number */
|
||||
u8 key_index; /* key flag in the most significant bit:
|
||||
* 0 = broadcast (default key),
|
||||
* 1 = unicast (key mapping key); key index is in the
|
||||
* 7 least significant bits */
|
||||
/* HMAC-MD5 message integrity check computed with MS-MPPE-Send-Key as
|
||||
* the key */
|
||||
u8 key_signature[IEEE8021X_KEY_SIGN_LEN];
|
||||
|
||||
/* followed by key: if packet body length = 44 + key length, then the
|
||||
* key field (of key_length bytes) contains the key in encrypted form;
|
||||
* if packet body length = 44, key field is absent and key_length
|
||||
* represents the number of least significant octets from
|
||||
* MS-MPPE-Send-Key attribute to be used as the keying material;
|
||||
* RC4 key used in encryption = Key-IV + MS-MPPE-Recv-Key */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#endif /* EAPOL_COMMON_H */
|
275
freebsd/contrib/wpa/src/common/gas.c
Normal file
275
freebsd/contrib/wpa/src/common/gas.c
Normal file
@ -0,0 +1,275 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* Generic advertisement service (GAS) (IEEE 802.11u)
|
||||
* Copyright (c) 2009, Atheros Communications
|
||||
* Copyright (c) 2011-2012, Qualcomm Atheros
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "ieee802_11_defs.h"
|
||||
#include "gas.h"
|
||||
|
||||
|
||||
static struct wpabuf *
|
||||
gas_build_req(u8 action, u8 dialog_token, size_t size)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
|
||||
buf = wpabuf_alloc(100 + size);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
|
||||
wpabuf_put_u8(buf, action);
|
||||
wpabuf_put_u8(buf, dialog_token);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * gas_build_initial_req(u8 dialog_token, size_t size)
|
||||
{
|
||||
return gas_build_req(WLAN_PA_GAS_INITIAL_REQ, dialog_token,
|
||||
size);
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * gas_build_comeback_req(u8 dialog_token)
|
||||
{
|
||||
return gas_build_req(WLAN_PA_GAS_COMEBACK_REQ, dialog_token, 0);
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf *
|
||||
gas_build_resp(u8 action, u8 dialog_token, u16 status_code, u8 frag_id,
|
||||
u8 more, u16 comeback_delay, size_t size)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
|
||||
buf = wpabuf_alloc(100 + size);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
|
||||
wpabuf_put_u8(buf, action);
|
||||
wpabuf_put_u8(buf, dialog_token);
|
||||
wpabuf_put_le16(buf, status_code);
|
||||
if (action == WLAN_PA_GAS_COMEBACK_RESP)
|
||||
wpabuf_put_u8(buf, frag_id | (more ? 0x80 : 0));
|
||||
wpabuf_put_le16(buf, comeback_delay);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf *
|
||||
gas_build_initial_resp(u8 dialog_token, u16 status_code, u16 comeback_delay,
|
||||
size_t size)
|
||||
{
|
||||
return gas_build_resp(WLAN_PA_GAS_INITIAL_RESP, dialog_token,
|
||||
status_code, 0, 0, comeback_delay, size);
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf *
|
||||
gas_build_comeback_resp(u8 dialog_token, u16 status_code, u8 frag_id, u8 more,
|
||||
u16 comeback_delay, size_t size)
|
||||
{
|
||||
return gas_build_resp(WLAN_PA_GAS_COMEBACK_RESP, dialog_token,
|
||||
status_code, frag_id, more, comeback_delay,
|
||||
size);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gas_add_adv_proto_anqp - Add an Advertisement Protocol element
|
||||
* @buf: Buffer to which the element is added
|
||||
* @query_resp_len_limit: Query Response Length Limit in units of 256 octets
|
||||
* @pame_bi: Pre-Association Message Exchange BSSID Independent (0/1)
|
||||
*
|
||||
*
|
||||
* @query_resp_len_limit is 0 for request and 1-0x7f for response. 0x7f means
|
||||
* that the maximum limit is determined by the maximum allowable number of
|
||||
* fragments in the GAS Query Response Fragment ID.
|
||||
*/
|
||||
static void gas_add_adv_proto_anqp(struct wpabuf *buf, u8 query_resp_len_limit,
|
||||
u8 pame_bi)
|
||||
{
|
||||
/* Advertisement Protocol IE */
|
||||
wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO);
|
||||
wpabuf_put_u8(buf, 2); /* Length */
|
||||
wpabuf_put_u8(buf, (query_resp_len_limit & 0x7f) |
|
||||
(pame_bi ? 0x80 : 0));
|
||||
/* Advertisement Protocol */
|
||||
wpabuf_put_u8(buf, ACCESS_NETWORK_QUERY_PROTOCOL);
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * gas_anqp_build_initial_req(u8 dialog_token, size_t size)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
|
||||
buf = gas_build_initial_req(dialog_token, 4 + size);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
gas_add_adv_proto_anqp(buf, 0, 0);
|
||||
|
||||
wpabuf_put(buf, 2); /* Query Request Length to be filled */
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * gas_anqp_build_initial_resp(u8 dialog_token, u16 status_code,
|
||||
u16 comeback_delay, size_t size)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
|
||||
buf = gas_build_initial_resp(dialog_token, status_code, comeback_delay,
|
||||
4 + size);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
gas_add_adv_proto_anqp(buf, 0x7f, 0);
|
||||
|
||||
wpabuf_put(buf, 2); /* Query Response Length to be filled */
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * gas_anqp_build_initial_resp_buf(u8 dialog_token,
|
||||
u16 status_code,
|
||||
u16 comeback_delay,
|
||||
struct wpabuf *payload)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
|
||||
buf = gas_anqp_build_initial_resp(dialog_token, status_code,
|
||||
comeback_delay,
|
||||
payload ? wpabuf_len(payload) : 0);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
if (payload)
|
||||
wpabuf_put_buf(buf, payload);
|
||||
|
||||
gas_anqp_set_len(buf);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * gas_anqp_build_comeback_resp(u8 dialog_token, u16 status_code,
|
||||
u8 frag_id, u8 more,
|
||||
u16 comeback_delay, size_t size)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
|
||||
buf = gas_build_comeback_resp(dialog_token, status_code,
|
||||
frag_id, more, comeback_delay, 4 + size);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
gas_add_adv_proto_anqp(buf, 0x7f, 0);
|
||||
|
||||
wpabuf_put(buf, 2); /* Query Response Length to be filled */
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * gas_anqp_build_comeback_resp_buf(u8 dialog_token,
|
||||
u16 status_code,
|
||||
u8 frag_id, u8 more,
|
||||
u16 comeback_delay,
|
||||
struct wpabuf *payload)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
|
||||
buf = gas_anqp_build_comeback_resp(dialog_token, status_code, frag_id,
|
||||
more, comeback_delay,
|
||||
payload ? wpabuf_len(payload) : 0);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
if (payload)
|
||||
wpabuf_put_buf(buf, payload);
|
||||
|
||||
gas_anqp_set_len(buf);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gas_anqp_set_len - Set Query Request/Response Length
|
||||
* @buf: GAS message
|
||||
*
|
||||
* This function is used to update the Query Request/Response Length field once
|
||||
* the payload has been filled.
|
||||
*/
|
||||
void gas_anqp_set_len(struct wpabuf *buf)
|
||||
{
|
||||
u8 action;
|
||||
size_t offset;
|
||||
u8 *len;
|
||||
|
||||
if (buf == NULL || wpabuf_len(buf) < 2)
|
||||
return;
|
||||
|
||||
action = *(wpabuf_head_u8(buf) + 1);
|
||||
switch (action) {
|
||||
case WLAN_PA_GAS_INITIAL_REQ:
|
||||
offset = 3 + 4;
|
||||
break;
|
||||
case WLAN_PA_GAS_INITIAL_RESP:
|
||||
offset = 7 + 4;
|
||||
break;
|
||||
case WLAN_PA_GAS_COMEBACK_RESP:
|
||||
offset = 8 + 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (wpabuf_len(buf) < offset + 2)
|
||||
return;
|
||||
|
||||
len = wpabuf_mhead_u8(buf) + offset;
|
||||
WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gas_anqp_add_element - Add ANQP element header
|
||||
* @buf: GAS message
|
||||
* @info_id: ANQP Info ID
|
||||
* Returns: Pointer to the Length field for gas_anqp_set_element_len()
|
||||
*/
|
||||
u8 * gas_anqp_add_element(struct wpabuf *buf, u16 info_id)
|
||||
{
|
||||
wpabuf_put_le16(buf, info_id);
|
||||
return wpabuf_put(buf, 2); /* Length to be filled */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gas_anqp_set_element_len - Update ANQP element Length field
|
||||
* @buf: GAS message
|
||||
* @len_pos: Length field position from gas_anqp_add_element()
|
||||
*
|
||||
* This function is called after the ANQP element payload has been added to the
|
||||
* buffer.
|
||||
*/
|
||||
void gas_anqp_set_element_len(struct wpabuf *buf, u8 *len_pos)
|
||||
{
|
||||
WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(buf, 0) - len_pos - 2);
|
||||
}
|
37
freebsd/contrib/wpa/src/common/gas.h
Normal file
37
freebsd/contrib/wpa/src/common/gas.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Generic advertisement service (GAS) (IEEE 802.11u)
|
||||
* Copyright (c) 2009, Atheros Communications
|
||||
* Copyright (c) 2011-2012, Qualcomm Atheros
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef GAS_H
|
||||
#define GAS_H
|
||||
|
||||
struct wpabuf * gas_build_initial_req(u8 dialog_token, size_t size);
|
||||
struct wpabuf * gas_build_comeback_req(u8 dialog_token);
|
||||
struct wpabuf * gas_build_initial_resp(u8 dialog_token, u16 status_code,
|
||||
u16 comeback_delay, size_t size);
|
||||
struct wpabuf * gas_anqp_build_initial_req(u8 dialog_token, size_t size);
|
||||
struct wpabuf * gas_anqp_build_initial_resp(u8 dialog_token, u16 status_code,
|
||||
u16 comeback_delay, size_t size);
|
||||
struct wpabuf * gas_anqp_build_initial_resp_buf(u8 dialog_token,
|
||||
u16 status_code,
|
||||
u16 comeback_delay,
|
||||
struct wpabuf *payload);
|
||||
struct wpabuf * gas_anqp_build_comeback_resp(u8 dialog_token, u16 status_code,
|
||||
u8 frag_id, u8 more,
|
||||
u16 comeback_delay, size_t size);
|
||||
struct wpabuf * gas_anqp_build_comeback_resp_buf(u8 dialog_token,
|
||||
u16 status_code,
|
||||
u8 frag_id, u8 more,
|
||||
u16 comeback_delay,
|
||||
struct wpabuf *payload);
|
||||
void gas_anqp_set_len(struct wpabuf *buf);
|
||||
|
||||
u8 * gas_anqp_add_element(struct wpabuf *buf, u16 info_id);
|
||||
void gas_anqp_set_element_len(struct wpabuf *buf, u8 *len_pos);
|
||||
|
||||
#endif /* GAS_H */
|
457
freebsd/contrib/wpa/src/common/hw_features_common.c
Normal file
457
freebsd/contrib/wpa/src/common/hw_features_common.c
Normal file
@ -0,0 +1,457 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* Common hostapd/wpa_supplicant HW features
|
||||
* Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2015, Qualcomm Atheros, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "defs.h"
|
||||
#include "ieee802_11_defs.h"
|
||||
#include "ieee802_11_common.h"
|
||||
#include "hw_features_common.h"
|
||||
|
||||
|
||||
struct hostapd_channel_data * hw_get_channel_chan(struct hostapd_hw_modes *mode,
|
||||
int chan, int *freq)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (freq)
|
||||
*freq = 0;
|
||||
|
||||
if (!mode)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < mode->num_channels; i++) {
|
||||
struct hostapd_channel_data *ch = &mode->channels[i];
|
||||
if (ch->chan == chan) {
|
||||
if (freq)
|
||||
*freq = ch->freq;
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct hostapd_channel_data * hw_get_channel_freq(struct hostapd_hw_modes *mode,
|
||||
int freq, int *chan)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (chan)
|
||||
*chan = 0;
|
||||
|
||||
if (!mode)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < mode->num_channels; i++) {
|
||||
struct hostapd_channel_data *ch = &mode->channels[i];
|
||||
if (ch->freq == freq) {
|
||||
if (chan)
|
||||
*chan = ch->chan;
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int hw_get_freq(struct hostapd_hw_modes *mode, int chan)
|
||||
{
|
||||
int freq;
|
||||
|
||||
hw_get_channel_chan(mode, chan, &freq);
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
|
||||
int hw_get_chan(struct hostapd_hw_modes *mode, int freq)
|
||||
{
|
||||
int chan;
|
||||
|
||||
hw_get_channel_freq(mode, freq, &chan);
|
||||
|
||||
return chan;
|
||||
}
|
||||
|
||||
|
||||
int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan,
|
||||
int sec_chan)
|
||||
{
|
||||
int ok, j, first;
|
||||
int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 140,
|
||||
149, 157, 184, 192 };
|
||||
size_t k;
|
||||
|
||||
if (pri_chan == sec_chan || !sec_chan)
|
||||
return 1; /* HT40 not used */
|
||||
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"HT40: control channel: %d secondary channel: %d",
|
||||
pri_chan, sec_chan);
|
||||
|
||||
/* Verify that HT40 secondary channel is an allowed 20 MHz
|
||||
* channel */
|
||||
ok = 0;
|
||||
for (j = 0; j < mode->num_channels; j++) {
|
||||
struct hostapd_channel_data *chan = &mode->channels[j];
|
||||
if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
|
||||
chan->chan == sec_chan) {
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
wpa_printf(MSG_ERROR, "HT40 secondary channel %d not allowed",
|
||||
sec_chan);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that HT40 primary,secondary channel pair is allowed per
|
||||
* IEEE 802.11n Annex J. This is only needed for 5 GHz band since
|
||||
* 2.4 GHz rules allow all cases where the secondary channel fits into
|
||||
* the list of allowed channels (already checked above).
|
||||
*/
|
||||
if (mode->mode != HOSTAPD_MODE_IEEE80211A)
|
||||
return 1;
|
||||
|
||||
first = pri_chan < sec_chan ? pri_chan : sec_chan;
|
||||
|
||||
ok = 0;
|
||||
for (k = 0; k < ARRAY_SIZE(allowed); k++) {
|
||||
if (first == allowed[k]) {
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
wpa_printf(MSG_ERROR, "HT40 channel pair (%d, %d) not allowed",
|
||||
pri_chan, sec_chan);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void get_pri_sec_chan(struct wpa_scan_res *bss, int *pri_chan, int *sec_chan)
|
||||
{
|
||||
struct ieee80211_ht_operation *oper;
|
||||
struct ieee802_11_elems elems;
|
||||
|
||||
*pri_chan = *sec_chan = 0;
|
||||
|
||||
ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems, 0);
|
||||
if (elems.ht_operation) {
|
||||
oper = (struct ieee80211_ht_operation *) elems.ht_operation;
|
||||
*pri_chan = oper->primary_chan;
|
||||
if (oper->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) {
|
||||
int sec = oper->ht_param &
|
||||
HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
|
||||
if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
|
||||
*sec_chan = *pri_chan + 4;
|
||||
else if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
|
||||
*sec_chan = *pri_chan - 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int check_40mhz_5g(struct hostapd_hw_modes *mode,
|
||||
struct wpa_scan_results *scan_res, int pri_chan,
|
||||
int sec_chan)
|
||||
{
|
||||
int pri_freq, sec_freq, pri_bss, sec_bss;
|
||||
int bss_pri_chan, bss_sec_chan;
|
||||
size_t i;
|
||||
int match;
|
||||
|
||||
if (!mode || !scan_res || !pri_chan || !sec_chan ||
|
||||
pri_chan == sec_chan)
|
||||
return 0;
|
||||
|
||||
pri_freq = hw_get_freq(mode, pri_chan);
|
||||
sec_freq = hw_get_freq(mode, sec_chan);
|
||||
|
||||
/*
|
||||
* Switch PRI/SEC channels if Beacons were detected on selected SEC
|
||||
* channel, but not on selected PRI channel.
|
||||
*/
|
||||
pri_bss = sec_bss = 0;
|
||||
for (i = 0; i < scan_res->num; i++) {
|
||||
struct wpa_scan_res *bss = scan_res->res[i];
|
||||
if (bss->freq == pri_freq)
|
||||
pri_bss++;
|
||||
else if (bss->freq == sec_freq)
|
||||
sec_bss++;
|
||||
}
|
||||
if (sec_bss && !pri_bss) {
|
||||
wpa_printf(MSG_INFO,
|
||||
"Switch own primary and secondary channel to get secondary channel with no Beacons from other BSSes");
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Match PRI/SEC channel with any existing HT40 BSS on the same
|
||||
* channels that we are about to use (if already mixed order in
|
||||
* existing BSSes, use own preference).
|
||||
*/
|
||||
match = 0;
|
||||
for (i = 0; i < scan_res->num; i++) {
|
||||
struct wpa_scan_res *bss = scan_res->res[i];
|
||||
get_pri_sec_chan(bss, &bss_pri_chan, &bss_sec_chan);
|
||||
if (pri_chan == bss_pri_chan &&
|
||||
sec_chan == bss_sec_chan) {
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
for (i = 0; i < scan_res->num; i++) {
|
||||
struct wpa_scan_res *bss = scan_res->res[i];
|
||||
get_pri_sec_chan(bss, &bss_pri_chan, &bss_sec_chan);
|
||||
if (pri_chan == bss_sec_chan &&
|
||||
sec_chan == bss_pri_chan) {
|
||||
wpa_printf(MSG_INFO, "Switch own primary and "
|
||||
"secondary channel due to BSS "
|
||||
"overlap with " MACSTR,
|
||||
MAC2STR(bss->bssid));
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int check_20mhz_bss(struct wpa_scan_res *bss, int pri_freq, int start,
|
||||
int end)
|
||||
{
|
||||
struct ieee802_11_elems elems;
|
||||
struct ieee80211_ht_operation *oper;
|
||||
|
||||
if (bss->freq < start || bss->freq > end || bss->freq == pri_freq)
|
||||
return 0;
|
||||
|
||||
ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems, 0);
|
||||
if (!elems.ht_capabilities) {
|
||||
wpa_printf(MSG_DEBUG, "Found overlapping legacy BSS: "
|
||||
MACSTR " freq=%d", MAC2STR(bss->bssid), bss->freq);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (elems.ht_operation) {
|
||||
oper = (struct ieee80211_ht_operation *) elems.ht_operation;
|
||||
if (oper->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)
|
||||
return 0;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "Found overlapping 20 MHz HT BSS: "
|
||||
MACSTR " freq=%d", MAC2STR(bss->bssid), bss->freq);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int check_40mhz_2g4(struct hostapd_hw_modes *mode,
|
||||
struct wpa_scan_results *scan_res, int pri_chan,
|
||||
int sec_chan)
|
||||
{
|
||||
int pri_freq, sec_freq;
|
||||
int affected_start, affected_end;
|
||||
size_t i;
|
||||
|
||||
if (!mode || !scan_res || !pri_chan || !sec_chan ||
|
||||
pri_chan == sec_chan)
|
||||
return 0;
|
||||
|
||||
pri_freq = hw_get_freq(mode, pri_chan);
|
||||
sec_freq = hw_get_freq(mode, sec_chan);
|
||||
|
||||
affected_start = (pri_freq + sec_freq) / 2 - 25;
|
||||
affected_end = (pri_freq + sec_freq) / 2 + 25;
|
||||
wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
|
||||
affected_start, affected_end);
|
||||
for (i = 0; i < scan_res->num; i++) {
|
||||
struct wpa_scan_res *bss = scan_res->res[i];
|
||||
int pri = bss->freq;
|
||||
int sec = pri;
|
||||
struct ieee802_11_elems elems;
|
||||
|
||||
/* Check for overlapping 20 MHz BSS */
|
||||
if (check_20mhz_bss(bss, pri_freq, affected_start,
|
||||
affected_end)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Overlapping 20 MHz BSS is found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
get_pri_sec_chan(bss, &pri_chan, &sec_chan);
|
||||
|
||||
if (sec_chan) {
|
||||
if (sec_chan < pri_chan)
|
||||
sec = pri - 20;
|
||||
else
|
||||
sec = pri + 20;
|
||||
}
|
||||
|
||||
if ((pri < affected_start || pri > affected_end) &&
|
||||
(sec < affected_start || sec > affected_end))
|
||||
continue; /* not within affected channel range */
|
||||
|
||||
wpa_printf(MSG_DEBUG, "Neighboring BSS: " MACSTR
|
||||
" freq=%d pri=%d sec=%d",
|
||||
MAC2STR(bss->bssid), bss->freq, pri_chan, sec_chan);
|
||||
|
||||
if (sec_chan) {
|
||||
if (pri_freq != pri || sec_freq != sec) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"40 MHz pri/sec mismatch with BSS "
|
||||
MACSTR
|
||||
" <%d,%d> (chan=%d%c) vs. <%d,%d>",
|
||||
MAC2STR(bss->bssid),
|
||||
pri, sec, pri_chan,
|
||||
sec > pri ? '+' : '-',
|
||||
pri_freq, sec_freq);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems,
|
||||
0);
|
||||
if (elems.ht_capabilities) {
|
||||
struct ieee80211_ht_capabilities *ht_cap =
|
||||
(struct ieee80211_ht_capabilities *)
|
||||
elems.ht_capabilities;
|
||||
|
||||
if (le_to_host16(ht_cap->ht_capabilities_info) &
|
||||
HT_CAP_INFO_40MHZ_INTOLERANT) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"40 MHz Intolerant is set on channel %d in BSS "
|
||||
MACSTR, pri, MAC2STR(bss->bssid));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int hostapd_set_freq_params(struct hostapd_freq_params *data,
|
||||
enum hostapd_hw_mode mode,
|
||||
int freq, int channel, int ht_enabled,
|
||||
int vht_enabled, int sec_channel_offset,
|
||||
int vht_oper_chwidth, int center_segment0,
|
||||
int center_segment1, u32 vht_caps)
|
||||
{
|
||||
os_memset(data, 0, sizeof(*data));
|
||||
data->mode = mode;
|
||||
data->freq = freq;
|
||||
data->channel = channel;
|
||||
data->ht_enabled = ht_enabled;
|
||||
data->vht_enabled = vht_enabled;
|
||||
data->sec_channel_offset = sec_channel_offset;
|
||||
data->center_freq1 = freq + sec_channel_offset * 10;
|
||||
data->center_freq2 = 0;
|
||||
data->bandwidth = sec_channel_offset ? 40 : 20;
|
||||
|
||||
if (data->vht_enabled) switch (vht_oper_chwidth) {
|
||||
case VHT_CHANWIDTH_USE_HT:
|
||||
if (center_segment1 ||
|
||||
(center_segment0 != 0 &&
|
||||
5000 + center_segment0 * 5 != data->center_freq1 &&
|
||||
2407 + center_segment0 * 5 != data->center_freq1))
|
||||
return -1;
|
||||
break;
|
||||
case VHT_CHANWIDTH_80P80MHZ:
|
||||
if (!(vht_caps & VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"80+80 channel width is not supported!");
|
||||
return -1;
|
||||
}
|
||||
if (center_segment1 == center_segment0 + 4 ||
|
||||
center_segment1 == center_segment0 - 4)
|
||||
return -1;
|
||||
data->center_freq2 = 5000 + center_segment1 * 5;
|
||||
/* fall through */
|
||||
case VHT_CHANWIDTH_80MHZ:
|
||||
data->bandwidth = 80;
|
||||
if ((vht_oper_chwidth == 1 && center_segment1) ||
|
||||
(vht_oper_chwidth == 3 && !center_segment1) ||
|
||||
!sec_channel_offset)
|
||||
return -1;
|
||||
if (!center_segment0) {
|
||||
if (channel <= 48)
|
||||
center_segment0 = 42;
|
||||
else if (channel <= 64)
|
||||
center_segment0 = 58;
|
||||
else if (channel <= 112)
|
||||
center_segment0 = 106;
|
||||
else if (channel <= 128)
|
||||
center_segment0 = 122;
|
||||
else if (channel <= 144)
|
||||
center_segment0 = 138;
|
||||
else if (channel <= 161)
|
||||
center_segment0 = 155;
|
||||
data->center_freq1 = 5000 + center_segment0 * 5;
|
||||
} else {
|
||||
/*
|
||||
* Note: HT/VHT config and params are coupled. Check if
|
||||
* HT40 channel band is in VHT80 Pri channel band
|
||||
* configuration.
|
||||
*/
|
||||
if (center_segment0 == channel + 6 ||
|
||||
center_segment0 == channel + 2 ||
|
||||
center_segment0 == channel - 2 ||
|
||||
center_segment0 == channel - 6)
|
||||
data->center_freq1 = 5000 + center_segment0 * 5;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case VHT_CHANWIDTH_160MHZ:
|
||||
data->bandwidth = 160;
|
||||
if (!(vht_caps & (VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
|
||||
VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"160MHZ channel width is not supported!");
|
||||
return -1;
|
||||
}
|
||||
if (center_segment1)
|
||||
return -1;
|
||||
if (!sec_channel_offset)
|
||||
return -1;
|
||||
/*
|
||||
* Note: HT/VHT config and params are coupled. Check if
|
||||
* HT40 channel band is in VHT160 channel band configuration.
|
||||
*/
|
||||
if (center_segment0 == channel + 14 ||
|
||||
center_segment0 == channel + 10 ||
|
||||
center_segment0 == channel + 6 ||
|
||||
center_segment0 == channel + 2 ||
|
||||
center_segment0 == channel - 2 ||
|
||||
center_segment0 == channel - 6 ||
|
||||
center_segment0 == channel - 10 ||
|
||||
center_segment0 == channel - 14)
|
||||
data->center_freq1 = 5000 + center_segment0 * 5;
|
||||
else
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
39
freebsd/contrib/wpa/src/common/hw_features_common.h
Normal file
39
freebsd/contrib/wpa/src/common/hw_features_common.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Common hostapd/wpa_supplicant HW features
|
||||
* Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2015, Qualcomm Atheros, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef HW_FEATURES_COMMON_H
|
||||
#define HW_FEATURES_COMMON_H
|
||||
|
||||
#include "drivers/driver.h"
|
||||
|
||||
struct hostapd_channel_data * hw_get_channel_chan(struct hostapd_hw_modes *mode,
|
||||
int chan, int *freq);
|
||||
struct hostapd_channel_data * hw_get_channel_freq(struct hostapd_hw_modes *mode,
|
||||
int freq, int *chan);
|
||||
|
||||
int hw_get_freq(struct hostapd_hw_modes *mode, int chan);
|
||||
int hw_get_chan(struct hostapd_hw_modes *mode, int freq);
|
||||
|
||||
int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan,
|
||||
int sec_chan);
|
||||
void get_pri_sec_chan(struct wpa_scan_res *bss, int *pri_chan, int *sec_chan);
|
||||
int check_40mhz_5g(struct hostapd_hw_modes *mode,
|
||||
struct wpa_scan_results *scan_res, int pri_chan,
|
||||
int sec_chan);
|
||||
int check_40mhz_2g4(struct hostapd_hw_modes *mode,
|
||||
struct wpa_scan_results *scan_res, int pri_chan,
|
||||
int sec_chan);
|
||||
int hostapd_set_freq_params(struct hostapd_freq_params *data,
|
||||
enum hostapd_hw_mode mode,
|
||||
int freq, int channel, int ht_enabled,
|
||||
int vht_enabled, int sec_channel_offset,
|
||||
int vht_oper_chwidth, int center_segment0,
|
||||
int center_segment1, u32 vht_caps);
|
||||
|
||||
#endif /* HW_FEATURES_COMMON_H */
|
1149
freebsd/contrib/wpa/src/common/ieee802_11_common.c
Normal file
1149
freebsd/contrib/wpa/src/common/ieee802_11_common.c
Normal file
File diff suppressed because it is too large
Load Diff
128
freebsd/contrib/wpa/src/common/ieee802_11_common.h
Normal file
128
freebsd/contrib/wpa/src/common/ieee802_11_common.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* IEEE 802.11 Common routines
|
||||
* Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef IEEE802_11_COMMON_H
|
||||
#define IEEE802_11_COMMON_H
|
||||
|
||||
#define MAX_NOF_MB_IES_SUPPORTED 5
|
||||
|
||||
struct mb_ies_info {
|
||||
struct {
|
||||
const u8 *ie;
|
||||
u8 ie_len;
|
||||
} ies[MAX_NOF_MB_IES_SUPPORTED];
|
||||
u8 nof_ies;
|
||||
};
|
||||
|
||||
/* Parsed Information Elements */
|
||||
struct ieee802_11_elems {
|
||||
const u8 *ssid;
|
||||
const u8 *supp_rates;
|
||||
const u8 *ds_params;
|
||||
const u8 *challenge;
|
||||
const u8 *erp_info;
|
||||
const u8 *ext_supp_rates;
|
||||
const u8 *wpa_ie;
|
||||
const u8 *rsn_ie;
|
||||
const u8 *wmm; /* WMM Information or Parameter Element */
|
||||
const u8 *wmm_tspec;
|
||||
const u8 *wps_ie;
|
||||
const u8 *supp_channels;
|
||||
const u8 *mdie;
|
||||
const u8 *ftie;
|
||||
const u8 *timeout_int;
|
||||
const u8 *ht_capabilities;
|
||||
const u8 *ht_operation;
|
||||
const u8 *mesh_config;
|
||||
const u8 *mesh_id;
|
||||
const u8 *peer_mgmt;
|
||||
const u8 *vht_capabilities;
|
||||
const u8 *vht_operation;
|
||||
const u8 *vht_opmode_notif;
|
||||
const u8 *vendor_ht_cap;
|
||||
const u8 *vendor_vht;
|
||||
const u8 *p2p;
|
||||
const u8 *wfd;
|
||||
const u8 *link_id;
|
||||
const u8 *interworking;
|
||||
const u8 *qos_map_set;
|
||||
const u8 *hs20;
|
||||
const u8 *ext_capab;
|
||||
const u8 *bss_max_idle_period;
|
||||
const u8 *ssid_list;
|
||||
const u8 *osen;
|
||||
const u8 *ampe;
|
||||
const u8 *mic;
|
||||
const u8 *pref_freq_list;
|
||||
|
||||
u8 ssid_len;
|
||||
u8 supp_rates_len;
|
||||
u8 challenge_len;
|
||||
u8 ext_supp_rates_len;
|
||||
u8 wpa_ie_len;
|
||||
u8 rsn_ie_len;
|
||||
u8 wmm_len; /* 7 = WMM Information; 24 = WMM Parameter */
|
||||
u8 wmm_tspec_len;
|
||||
u8 wps_ie_len;
|
||||
u8 supp_channels_len;
|
||||
u8 mdie_len;
|
||||
u8 ftie_len;
|
||||
u8 mesh_config_len;
|
||||
u8 mesh_id_len;
|
||||
u8 peer_mgmt_len;
|
||||
u8 vendor_ht_cap_len;
|
||||
u8 vendor_vht_len;
|
||||
u8 p2p_len;
|
||||
u8 wfd_len;
|
||||
u8 interworking_len;
|
||||
u8 qos_map_set_len;
|
||||
u8 hs20_len;
|
||||
u8 ext_capab_len;
|
||||
u8 ssid_list_len;
|
||||
u8 osen_len;
|
||||
u8 ampe_len;
|
||||
u8 mic_len;
|
||||
u8 pref_freq_list_len;
|
||||
struct mb_ies_info mb_ies;
|
||||
};
|
||||
|
||||
typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;
|
||||
|
||||
ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
|
||||
struct ieee802_11_elems *elems,
|
||||
int show_errors);
|
||||
int ieee802_11_ie_count(const u8 *ies, size_t ies_len);
|
||||
struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
|
||||
u32 oui_type);
|
||||
struct ieee80211_hdr;
|
||||
const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len);
|
||||
|
||||
struct hostapd_wmm_ac_params {
|
||||
int cwmin;
|
||||
int cwmax;
|
||||
int aifs;
|
||||
int txop_limit; /* in units of 32us */
|
||||
int admission_control_mandatory;
|
||||
};
|
||||
|
||||
int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
|
||||
const char *name, const char *val);
|
||||
enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel);
|
||||
int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan);
|
||||
enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
|
||||
int sec_channel, int vht,
|
||||
u8 *op_class, u8 *channel);
|
||||
int ieee80211_is_dfs(int freq);
|
||||
|
||||
int supp_rates_11b_only(struct ieee802_11_elems *elems);
|
||||
int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
|
||||
size_t ies_len);
|
||||
struct wpabuf * mb_ies_by_info(struct mb_ies_info *info);
|
||||
|
||||
const char * fc2str(u16 fc);
|
||||
#endif /* IEEE802_11_COMMON_H */
|
1436
freebsd/contrib/wpa/src/common/ieee802_11_defs.h
Normal file
1436
freebsd/contrib/wpa/src/common/ieee802_11_defs.h
Normal file
File diff suppressed because it is too large
Load Diff
357
freebsd/contrib/wpa/src/common/qca-vendor.h
Normal file
357
freebsd/contrib/wpa/src/common/qca-vendor.h
Normal file
@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Qualcomm Atheros OUI and vendor specific assignments
|
||||
* Copyright (c) 2014-2015, Qualcomm Atheros, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef QCA_VENDOR_H
|
||||
#define QCA_VENDOR_H
|
||||
|
||||
/*
|
||||
* This file is a registry of identifier assignments from the Qualcomm Atheros
|
||||
* OUI 00:13:74 for purposes other than MAC address assignment. New identifiers
|
||||
* can be assigned through normal review process for changes to the upstream
|
||||
* hostap.git repository.
|
||||
*/
|
||||
|
||||
#define OUI_QCA 0x001374
|
||||
|
||||
/**
|
||||
* enum qca_radiotap_vendor_ids - QCA radiotap vendor namespace IDs
|
||||
*/
|
||||
enum qca_radiotap_vendor_ids {
|
||||
QCA_RADIOTAP_VID_WLANTEST = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_nl80211_vendor_subcmds - QCA nl80211 vendor command identifiers
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_UNSPEC: Reserved value 0
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_TEST: Test command/event
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_ROAMING: Set roaming policy for drivers that use
|
||||
* internal BSS-selection. This command uses
|
||||
* @QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY to specify the new roaming policy
|
||||
* for the current connection (i.e., changes policy set by the nl80211
|
||||
* Connect command). @QCA_WLAN_VENDOR_ATTR_MAC_ADDR may optionally be
|
||||
* included to indicate which BSS to use in case roaming is disabled.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY: Recommendation of frequency
|
||||
* ranges to avoid to reduce issues due to interference or internal
|
||||
* co-existence information in the driver. The event data structure is
|
||||
* defined in struct qca_avoid_freq_list.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY: Command to check driver support
|
||||
* for DFS offloading.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_NAN: NAN command/event which is used to pass
|
||||
* NAN Request/Response and NAN Indication messages. These messages are
|
||||
* interpreted between the framework and the firmware component.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY: Set key operation that can be
|
||||
* used to configure PMK to the driver even when not connected. This can
|
||||
* be used to request offloading of key management operations. Only used
|
||||
* if device supports QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH: An extended version of
|
||||
* NL80211_CMD_ROAM event with optional attributes including information
|
||||
* from offloaded key management operation. Uses
|
||||
* enum qca_wlan_vendor_attr_roam_auth attributes. Only used
|
||||
* if device supports QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_DO_ACS: ACS command/event which is used to
|
||||
* invoke the ACS function in device and pass selected channels to
|
||||
* hostapd.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES: Command to get the features
|
||||
* supported by the driver. enum qca_wlan_vendor_features defines
|
||||
* the possible features.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED: Event used by driver,
|
||||
* which supports DFS offloading, to indicate a channel availability check
|
||||
* start.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED: Event used by driver,
|
||||
* which supports DFS offloading, to indicate a channel availability check
|
||||
* completion.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED: Event used by driver,
|
||||
* which supports DFS offloading, to indicate that the channel availability
|
||||
* check aborted, no change to the channel status.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED: Event used by
|
||||
* driver, which supports DFS offloading, to indicate that the
|
||||
* Non-Occupancy Period for this channel is over, channel becomes usable.
|
||||
*
|
||||
* @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED: Event used by driver,
|
||||
* which supports DFS offloading, to indicate a radar pattern has been
|
||||
* detected. The channel is now unusable.
|
||||
*/
|
||||
enum qca_nl80211_vendor_subcmds {
|
||||
QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
|
||||
QCA_NL80211_VENDOR_SUBCMD_TEST = 1,
|
||||
/* subcmds 2..8 not yet allocated */
|
||||
QCA_NL80211_VENDOR_SUBCMD_ROAMING = 9,
|
||||
QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY = 10,
|
||||
QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY = 11,
|
||||
QCA_NL80211_VENDOR_SUBCMD_NAN = 12,
|
||||
QCA_NL80211_VENDOR_SUBMCD_STATS_EXT = 13,
|
||||
QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET = 14,
|
||||
QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET = 15,
|
||||
QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR = 16,
|
||||
QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS = 17,
|
||||
QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS = 18,
|
||||
QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS = 19,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_START = 20,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_STOP = 21,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS = 22,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES = 23,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS = 24,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE = 25,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT = 26,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT = 27,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND = 28,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST = 29,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_BSSID_HOTLIST = 30,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE = 31,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE = 32,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_SIGNIFICANT_CHANGE = 33,
|
||||
QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE = 34,
|
||||
QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE = 35,
|
||||
QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS = 36,
|
||||
QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE = 37,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES = 38,
|
||||
QCA_NL80211_VENDOR_SUBCMD_SCANNING_MAC_OUI = 39,
|
||||
QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG = 40,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST = 41,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX = 42,
|
||||
/* 43..49 - reserved for QCA */
|
||||
QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY = 50,
|
||||
QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH = 51,
|
||||
QCA_NL80211_VENDOR_SUBCMD_APFIND = 52,
|
||||
/* 53 - reserved - was used by QCA, but not in use anymore */
|
||||
QCA_NL80211_VENDOR_SUBCMD_DO_ACS = 54,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES = 55,
|
||||
QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED = 56,
|
||||
QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED = 57,
|
||||
QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED = 58,
|
||||
QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED = 59,
|
||||
QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED = 60,
|
||||
/* 61-90 - reserved for QCA */
|
||||
QCA_NL80211_VENDOR_SUBCMD_DATA_OFFLOAD = 91,
|
||||
QCA_NL80211_VENDOR_SUBCMD_OCB_SET_CONFIG = 92,
|
||||
QCA_NL80211_VENDOR_SUBCMD_OCB_SET_UTC_TIME = 93,
|
||||
QCA_NL80211_VENDOR_SUBCMD_OCB_START_TIMING_ADVERT = 94,
|
||||
QCA_NL80211_VENDOR_SUBCMD_OCB_STOP_TIMING_ADVERT = 95,
|
||||
QCA_NL80211_VENDOR_SUBCMD_OCB_GET_TSF_TIMER = 96,
|
||||
QCA_NL80211_VENDOR_SUBCMD_DCC_GET_STATS = 97,
|
||||
QCA_NL80211_VENDOR_SUBCMD_DCC_CLEAR_STATS = 98,
|
||||
QCA_NL80211_VENDOR_SUBCMD_DCC_UPDATE_NDL = 99,
|
||||
QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT = 100,
|
||||
QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES = 101,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG = 102,
|
||||
QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST = 103,
|
||||
QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL = 104,
|
||||
QCA_NL80211_VENDOR_SUBCMD_SETBAND = 105,
|
||||
};
|
||||
|
||||
|
||||
enum qca_wlan_vendor_attr {
|
||||
QCA_WLAN_VENDOR_ATTR_INVALID = 0,
|
||||
/* used by QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY */
|
||||
QCA_WLAN_VENDOR_ATTR_DFS = 1,
|
||||
/* used by QCA_NL80211_VENDOR_SUBCMD_NAN */
|
||||
QCA_WLAN_VENDOR_ATTR_NAN = 2,
|
||||
/* used by QCA_NL80211_VENDOR_SUBCMD_STATS_EXT */
|
||||
QCA_WLAN_VENDOR_ATTR_STATS_EXT = 3,
|
||||
/* used by QCA_NL80211_VENDOR_SUBCMD_STATS_EXT */
|
||||
QCA_WLAN_VENDOR_ATTR_IFINDEX = 4,
|
||||
/* used by QCA_NL80211_VENDOR_SUBCMD_ROAMING, u32 with values defined
|
||||
* by enum qca_roaming_policy. */
|
||||
QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY = 5,
|
||||
QCA_WLAN_VENDOR_ATTR_MAC_ADDR = 6,
|
||||
/* used by QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES */
|
||||
QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS = 7,
|
||||
QCA_WLAN_VENDOR_ATTR_TEST = 8,
|
||||
/* used by QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES */
|
||||
/* Unsigned 32-bit value. */
|
||||
QCA_WLAN_VENDOR_ATTR_CONCURRENCY_CAPA = 9,
|
||||
/* Unsigned 32-bit value */
|
||||
QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_2_4_BAND = 10,
|
||||
/* Unsigned 32-bit value */
|
||||
QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_5_0_BAND = 11,
|
||||
/* Unsigned 32-bit value from enum qca_set_band. */
|
||||
QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE = 12,
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_MAX = QCA_WLAN_VENDOR_ATTR_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
|
||||
enum qca_roaming_policy {
|
||||
QCA_ROAMING_NOT_ALLOWED,
|
||||
QCA_ROAMING_ALLOWED_WITHIN_ESS,
|
||||
};
|
||||
|
||||
enum qca_wlan_vendor_attr_roam_auth {
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK,
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
enum qca_wlan_vendor_attr_acs_offload {
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST,
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
enum qca_wlan_vendor_acs_hw_mode {
|
||||
QCA_ACS_MODE_IEEE80211B,
|
||||
QCA_ACS_MODE_IEEE80211G,
|
||||
QCA_ACS_MODE_IEEE80211A,
|
||||
QCA_ACS_MODE_IEEE80211AD,
|
||||
QCA_ACS_MODE_IEEE80211ANY,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_features - Vendor device/driver feature flags
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD: Device supports key
|
||||
* management offload, a mechanism where the station's firmware
|
||||
* does the exchange with the AP to establish the temporal keys
|
||||
* after roaming, rather than having the user space wpa_supplicant do it.
|
||||
* @QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY: Device supports automatic
|
||||
* band selection based on channel selection results.
|
||||
* @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits
|
||||
*/
|
||||
enum qca_wlan_vendor_features {
|
||||
QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD = 0,
|
||||
QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY = 1,
|
||||
NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */
|
||||
};
|
||||
|
||||
/**
|
||||
* enum qca_wlan_vendor_attr_data_offload_ind - Vendor Data Offload Indication
|
||||
*
|
||||
* @QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_SESSION: Session corresponding to
|
||||
* the offloaded data.
|
||||
* @QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_PROTOCOL: Protocol of the offloaded
|
||||
* data.
|
||||
* @QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_EVENT: Event type for the data offload
|
||||
* indication.
|
||||
*/
|
||||
enum qca_wlan_vendor_attr_data_offload_ind {
|
||||
QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_INVALID = 0,
|
||||
QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_SESSION,
|
||||
QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_PROTOCOL,
|
||||
QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_EVENT,
|
||||
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
enum qca_vendor_attr_get_preferred_freq_list {
|
||||
QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_INVALID,
|
||||
/* A 32-unsigned value; the interface type/mode for which the preferred
|
||||
* frequency list is requested (see enum qca_iface_type for possible
|
||||
* values); used in GET_PREFERRED_FREQ_LIST command from user-space to
|
||||
* kernel and in the kernel response back to user-space.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE,
|
||||
/* An array of 32-unsigned values; values are frequency (MHz); sent
|
||||
* from kernel space to user space.
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST,
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
enum qca_vendor_attr_probable_oper_channel {
|
||||
QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_INVALID,
|
||||
/* 32-bit unsigned value; indicates the connection/iface type likely to
|
||||
* come on this channel (see enum qca_iface_type).
|
||||
*/
|
||||
QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_IFACE_TYPE,
|
||||
/* 32-bit unsigned value; the frequency (MHz) of the probable channel */
|
||||
QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ,
|
||||
/* keep last */
|
||||
QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_AFTER_LAST,
|
||||
QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_MAX =
|
||||
QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
enum qca_iface_type {
|
||||
QCA_IFACE_TYPE_STA,
|
||||
QCA_IFACE_TYPE_AP,
|
||||
QCA_IFACE_TYPE_P2P_CLIENT,
|
||||
QCA_IFACE_TYPE_P2P_GO,
|
||||
QCA_IFACE_TYPE_IBSS,
|
||||
QCA_IFACE_TYPE_TDLS,
|
||||
};
|
||||
|
||||
enum qca_set_band {
|
||||
QCA_SETBAND_AUTO,
|
||||
QCA_SETBAND_5G,
|
||||
QCA_SETBAND_2G,
|
||||
};
|
||||
|
||||
/* IEEE 802.11 Vendor Specific elements */
|
||||
|
||||
/**
|
||||
* enum qca_vendor_element_id - QCA Vendor Specific element types
|
||||
*
|
||||
* These values are used to identify QCA Vendor Specific elements. The
|
||||
* payload of the element starts with the three octet OUI (OUI_QCA) and
|
||||
* is followed by a single octet type which is defined by this enum.
|
||||
*
|
||||
* @QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST: P2P preferred channel list.
|
||||
* This element can be used to specify preference order for supported
|
||||
* channels. The channels in this list are in preference order (the first
|
||||
* one has the highest preference) and are described as a pair of
|
||||
* (global) Operating Class and Channel Number (each one octet) fields.
|
||||
*
|
||||
* This extends the standard P2P functionality by providing option to have
|
||||
* more than one preferred operating channel. When this element is present,
|
||||
* it replaces the preference indicated in the Operating Channel attribute.
|
||||
* For supporting other implementations, the Operating Channel attribute is
|
||||
* expected to be used with the highest preference channel. Similarly, all
|
||||
* the channels included in this Preferred channel list element are
|
||||
* expected to be included in the Channel List attribute.
|
||||
*
|
||||
* This vendor element may be included in GO Negotiation Request, P2P
|
||||
* Invitation Request, and Provision Discovery Request frames.
|
||||
*/
|
||||
enum qca_vendor_element_id {
|
||||
QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST = 0,
|
||||
};
|
||||
|
||||
#endif /* QCA_VENDOR_H */
|
70
freebsd/contrib/wpa/src/common/sae.h
Normal file
70
freebsd/contrib/wpa/src/common/sae.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Simultaneous authentication of equals
|
||||
* Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef SAE_H
|
||||
#define SAE_H
|
||||
|
||||
#define SAE_KCK_LEN 32
|
||||
#define SAE_PMK_LEN 32
|
||||
#define SAE_PMKID_LEN 16
|
||||
#define SAE_KEYSEED_KEY_LEN 32
|
||||
#define SAE_MAX_PRIME_LEN 512
|
||||
#define SAE_MAX_ECC_PRIME_LEN 66
|
||||
#define SAE_COMMIT_MAX_LEN (2 + 3 * SAE_MAX_PRIME_LEN)
|
||||
#define SAE_CONFIRM_MAX_LEN (2 + SAE_MAX_PRIME_LEN)
|
||||
|
||||
/* Special value returned by sae_parse_commit() */
|
||||
#define SAE_SILENTLY_DISCARD 65535
|
||||
|
||||
struct sae_temporary_data {
|
||||
u8 kck[SAE_KCK_LEN];
|
||||
struct crypto_bignum *own_commit_scalar;
|
||||
struct crypto_bignum *own_commit_element_ffc;
|
||||
struct crypto_ec_point *own_commit_element_ecc;
|
||||
struct crypto_bignum *peer_commit_element_ffc;
|
||||
struct crypto_ec_point *peer_commit_element_ecc;
|
||||
struct crypto_ec_point *pwe_ecc;
|
||||
struct crypto_bignum *pwe_ffc;
|
||||
struct crypto_bignum *sae_rand;
|
||||
struct crypto_ec *ec;
|
||||
int prime_len;
|
||||
const struct dh_group *dh;
|
||||
const struct crypto_bignum *prime;
|
||||
const struct crypto_bignum *order;
|
||||
struct crypto_bignum *prime_buf;
|
||||
struct crypto_bignum *order_buf;
|
||||
struct wpabuf *anti_clogging_token;
|
||||
};
|
||||
|
||||
struct sae_data {
|
||||
enum { SAE_NOTHING, SAE_COMMITTED, SAE_CONFIRMED, SAE_ACCEPTED } state;
|
||||
u16 send_confirm;
|
||||
u8 pmk[SAE_PMK_LEN];
|
||||
struct crypto_bignum *peer_commit_scalar;
|
||||
int group;
|
||||
int sync;
|
||||
struct sae_temporary_data *tmp;
|
||||
};
|
||||
|
||||
int sae_set_group(struct sae_data *sae, int group);
|
||||
void sae_clear_temp_data(struct sae_data *sae);
|
||||
void sae_clear_data(struct sae_data *sae);
|
||||
|
||||
int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
|
||||
const u8 *password, size_t password_len,
|
||||
struct sae_data *sae);
|
||||
int sae_process_commit(struct sae_data *sae);
|
||||
void sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
|
||||
const struct wpabuf *token);
|
||||
u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
|
||||
const u8 **token, size_t *token_len, int *allowed_groups);
|
||||
void sae_write_confirm(struct sae_data *sae, struct wpabuf *buf);
|
||||
int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len);
|
||||
u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group);
|
||||
|
||||
#endif /* SAE_H */
|
10
freebsd/contrib/wpa/src/common/version.h
Normal file
10
freebsd/contrib/wpa/src/common/version.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef VERSION_H
|
||||
#define VERSION_H
|
||||
|
||||
#ifndef VERSION_STR_POSTFIX
|
||||
#define VERSION_STR_POSTFIX ""
|
||||
#endif /* VERSION_STR_POSTFIX */
|
||||
|
||||
#define VERSION_STR "2.5" VERSION_STR_POSTFIX
|
||||
|
||||
#endif /* VERSION_H */
|
1666
freebsd/contrib/wpa/src/common/wpa_common.c
Normal file
1666
freebsd/contrib/wpa/src/common/wpa_common.c
Normal file
File diff suppressed because it is too large
Load Diff
451
freebsd/contrib/wpa/src/common/wpa_common.h
Normal file
451
freebsd/contrib/wpa/src/common/wpa_common.h
Normal file
@ -0,0 +1,451 @@
|
||||
/*
|
||||
* WPA definitions shared between hostapd and wpa_supplicant
|
||||
* Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef WPA_COMMON_H
|
||||
#define WPA_COMMON_H
|
||||
|
||||
/* IEEE 802.11i */
|
||||
#define PMKID_LEN 16
|
||||
#define PMK_LEN 32
|
||||
#define WPA_REPLAY_COUNTER_LEN 8
|
||||
#define WPA_NONCE_LEN 32
|
||||
#define WPA_KEY_RSC_LEN 8
|
||||
#define WPA_GMK_LEN 32
|
||||
#define WPA_GTK_MAX_LEN 32
|
||||
|
||||
#define WPA_ALLOWED_PAIRWISE_CIPHERS \
|
||||
(WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | WPA_CIPHER_TKIP | WPA_CIPHER_NONE | \
|
||||
WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP_256)
|
||||
#define WPA_ALLOWED_GROUP_CIPHERS \
|
||||
(WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | WPA_CIPHER_TKIP | \
|
||||
WPA_CIPHER_GCMP_256 | WPA_CIPHER_CCMP_256 | \
|
||||
WPA_CIPHER_GTK_NOT_USED)
|
||||
|
||||
#define WPA_SELECTOR_LEN 4
|
||||
#define WPA_VERSION 1
|
||||
#define RSN_SELECTOR_LEN 4
|
||||
#define RSN_VERSION 1
|
||||
|
||||
#define RSN_SELECTOR(a, b, c, d) \
|
||||
((((u32) (a)) << 24) | (((u32) (b)) << 16) | (((u32) (c)) << 8) | \
|
||||
(u32) (d))
|
||||
|
||||
#define WPA_AUTH_KEY_MGMT_NONE RSN_SELECTOR(0x00, 0x50, 0xf2, 0)
|
||||
#define WPA_AUTH_KEY_MGMT_UNSPEC_802_1X RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
|
||||
#define WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X RSN_SELECTOR(0x00, 0x50, 0xf2, 2)
|
||||
#define WPA_AUTH_KEY_MGMT_CCKM RSN_SELECTOR(0x00, 0x40, 0x96, 0)
|
||||
#define WPA_CIPHER_SUITE_NONE RSN_SELECTOR(0x00, 0x50, 0xf2, 0)
|
||||
#define WPA_CIPHER_SUITE_TKIP RSN_SELECTOR(0x00, 0x50, 0xf2, 2)
|
||||
#define WPA_CIPHER_SUITE_CCMP RSN_SELECTOR(0x00, 0x50, 0xf2, 4)
|
||||
|
||||
|
||||
#define RSN_AUTH_KEY_MGMT_UNSPEC_802_1X RSN_SELECTOR(0x00, 0x0f, 0xac, 1)
|
||||
#define RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X RSN_SELECTOR(0x00, 0x0f, 0xac, 2)
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
#define RSN_AUTH_KEY_MGMT_FT_802_1X RSN_SELECTOR(0x00, 0x0f, 0xac, 3)
|
||||
#define RSN_AUTH_KEY_MGMT_FT_PSK RSN_SELECTOR(0x00, 0x0f, 0xac, 4)
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
#define RSN_AUTH_KEY_MGMT_802_1X_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 5)
|
||||
#define RSN_AUTH_KEY_MGMT_PSK_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 6)
|
||||
#define RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE RSN_SELECTOR(0x00, 0x0f, 0xac, 7)
|
||||
#define RSN_AUTH_KEY_MGMT_SAE RSN_SELECTOR(0x00, 0x0f, 0xac, 8)
|
||||
#define RSN_AUTH_KEY_MGMT_FT_SAE RSN_SELECTOR(0x00, 0x0f, 0xac, 9)
|
||||
#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B RSN_SELECTOR(0x00, 0x0f, 0xac, 11)
|
||||
#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192 RSN_SELECTOR(0x00, 0x0f, 0xac, 12)
|
||||
#define RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_192 \
|
||||
RSN_SELECTOR(0x00, 0x0f, 0xac, 13)
|
||||
#define RSN_AUTH_KEY_MGMT_CCKM RSN_SELECTOR(0x00, 0x40, 0x96, 0x00)
|
||||
#define RSN_AUTH_KEY_MGMT_OSEN RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x01)
|
||||
|
||||
#define RSN_CIPHER_SUITE_NONE RSN_SELECTOR(0x00, 0x0f, 0xac, 0)
|
||||
#define RSN_CIPHER_SUITE_TKIP RSN_SELECTOR(0x00, 0x0f, 0xac, 2)
|
||||
#if 0
|
||||
#define RSN_CIPHER_SUITE_WRAP RSN_SELECTOR(0x00, 0x0f, 0xac, 3)
|
||||
#endif
|
||||
#define RSN_CIPHER_SUITE_CCMP RSN_SELECTOR(0x00, 0x0f, 0xac, 4)
|
||||
#define RSN_CIPHER_SUITE_AES_128_CMAC RSN_SELECTOR(0x00, 0x0f, 0xac, 6)
|
||||
#define RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED RSN_SELECTOR(0x00, 0x0f, 0xac, 7)
|
||||
#define RSN_CIPHER_SUITE_GCMP RSN_SELECTOR(0x00, 0x0f, 0xac, 8)
|
||||
#define RSN_CIPHER_SUITE_GCMP_256 RSN_SELECTOR(0x00, 0x0f, 0xac, 9)
|
||||
#define RSN_CIPHER_SUITE_CCMP_256 RSN_SELECTOR(0x00, 0x0f, 0xac, 10)
|
||||
#define RSN_CIPHER_SUITE_BIP_GMAC_128 RSN_SELECTOR(0x00, 0x0f, 0xac, 11)
|
||||
#define RSN_CIPHER_SUITE_BIP_GMAC_256 RSN_SELECTOR(0x00, 0x0f, 0xac, 12)
|
||||
#define RSN_CIPHER_SUITE_BIP_CMAC_256 RSN_SELECTOR(0x00, 0x0f, 0xac, 13)
|
||||
|
||||
/* EAPOL-Key Key Data Encapsulation
|
||||
* GroupKey and PeerKey require encryption, otherwise, encryption is optional.
|
||||
*/
|
||||
#define RSN_KEY_DATA_GROUPKEY RSN_SELECTOR(0x00, 0x0f, 0xac, 1)
|
||||
#if 0
|
||||
#define RSN_KEY_DATA_STAKEY RSN_SELECTOR(0x00, 0x0f, 0xac, 2)
|
||||
#endif
|
||||
#define RSN_KEY_DATA_MAC_ADDR RSN_SELECTOR(0x00, 0x0f, 0xac, 3)
|
||||
#define RSN_KEY_DATA_PMKID RSN_SELECTOR(0x00, 0x0f, 0xac, 4)
|
||||
#ifdef CONFIG_PEERKEY
|
||||
#define RSN_KEY_DATA_SMK RSN_SELECTOR(0x00, 0x0f, 0xac, 5)
|
||||
#define RSN_KEY_DATA_NONCE RSN_SELECTOR(0x00, 0x0f, 0xac, 6)
|
||||
#define RSN_KEY_DATA_LIFETIME RSN_SELECTOR(0x00, 0x0f, 0xac, 7)
|
||||
#define RSN_KEY_DATA_ERROR RSN_SELECTOR(0x00, 0x0f, 0xac, 8)
|
||||
#endif /* CONFIG_PEERKEY */
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
#define RSN_KEY_DATA_IGTK RSN_SELECTOR(0x00, 0x0f, 0xac, 9)
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
#define RSN_KEY_DATA_KEYID RSN_SELECTOR(0x00, 0x0f, 0xac, 10)
|
||||
#define RSN_KEY_DATA_MULTIBAND_GTK RSN_SELECTOR(0x00, 0x0f, 0xac, 11)
|
||||
#define RSN_KEY_DATA_MULTIBAND_KEYID RSN_SELECTOR(0x00, 0x0f, 0xac, 12)
|
||||
|
||||
#define WFA_KEY_DATA_IP_ADDR_REQ RSN_SELECTOR(0x50, 0x6f, 0x9a, 4)
|
||||
#define WFA_KEY_DATA_IP_ADDR_ALLOC RSN_SELECTOR(0x50, 0x6f, 0x9a, 5)
|
||||
|
||||
#define WPA_OUI_TYPE RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
|
||||
|
||||
#define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((u8 *) (a), (val))
|
||||
#define RSN_SELECTOR_GET(a) WPA_GET_BE32((const u8 *) (a))
|
||||
|
||||
#define RSN_NUM_REPLAY_COUNTERS_1 0
|
||||
#define RSN_NUM_REPLAY_COUNTERS_2 1
|
||||
#define RSN_NUM_REPLAY_COUNTERS_4 2
|
||||
#define RSN_NUM_REPLAY_COUNTERS_16 3
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
#define WPA_IGTK_LEN 16
|
||||
#define WPA_IGTK_MAX_LEN 32
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
|
||||
/* IEEE 802.11, 7.3.2.25.3 RSN Capabilities */
|
||||
#define WPA_CAPABILITY_PREAUTH BIT(0)
|
||||
#define WPA_CAPABILITY_NO_PAIRWISE BIT(1)
|
||||
/* B2-B3: PTKSA Replay Counter */
|
||||
/* B4-B5: GTKSA Replay Counter */
|
||||
#define WPA_CAPABILITY_MFPR BIT(6)
|
||||
#define WPA_CAPABILITY_MFPC BIT(7)
|
||||
/* B8: Reserved */
|
||||
#define WPA_CAPABILITY_PEERKEY_ENABLED BIT(9)
|
||||
#define WPA_CAPABILITY_SPP_A_MSDU_CAPABLE BIT(10)
|
||||
#define WPA_CAPABILITY_SPP_A_MSDU_REQUIRED BIT(11)
|
||||
#define WPA_CAPABILITY_PBAC BIT(12)
|
||||
#define WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST BIT(13)
|
||||
/* B14-B15: Reserved */
|
||||
|
||||
|
||||
/* IEEE 802.11r */
|
||||
#define MOBILITY_DOMAIN_ID_LEN 2
|
||||
#define FT_R0KH_ID_MAX_LEN 48
|
||||
#define FT_R1KH_ID_LEN 6
|
||||
#define WPA_PMK_NAME_LEN 16
|
||||
|
||||
|
||||
/* IEEE 802.11, 8.5.2 EAPOL-Key frames */
|
||||
#define WPA_KEY_INFO_TYPE_MASK ((u16) (BIT(0) | BIT(1) | BIT(2)))
|
||||
#define WPA_KEY_INFO_TYPE_AKM_DEFINED 0
|
||||
#define WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 BIT(0)
|
||||
#define WPA_KEY_INFO_TYPE_HMAC_SHA1_AES BIT(1)
|
||||
#define WPA_KEY_INFO_TYPE_AES_128_CMAC 3
|
||||
#define WPA_KEY_INFO_KEY_TYPE BIT(3) /* 1 = Pairwise, 0 = Group key */
|
||||
/* bit4..5 is used in WPA, but is reserved in IEEE 802.11i/RSN */
|
||||
#define WPA_KEY_INFO_KEY_INDEX_MASK (BIT(4) | BIT(5))
|
||||
#define WPA_KEY_INFO_KEY_INDEX_SHIFT 4
|
||||
#define WPA_KEY_INFO_INSTALL BIT(6) /* pairwise */
|
||||
#define WPA_KEY_INFO_TXRX BIT(6) /* group */
|
||||
#define WPA_KEY_INFO_ACK BIT(7)
|
||||
#define WPA_KEY_INFO_MIC BIT(8)
|
||||
#define WPA_KEY_INFO_SECURE BIT(9)
|
||||
#define WPA_KEY_INFO_ERROR BIT(10)
|
||||
#define WPA_KEY_INFO_REQUEST BIT(11)
|
||||
#define WPA_KEY_INFO_ENCR_KEY_DATA BIT(12) /* IEEE 802.11i/RSN only */
|
||||
#define WPA_KEY_INFO_SMK_MESSAGE BIT(13)
|
||||
|
||||
|
||||
struct wpa_eapol_key {
|
||||
u8 type;
|
||||
/* Note: key_info, key_length, and key_data_length are unaligned */
|
||||
u8 key_info[2]; /* big endian */
|
||||
u8 key_length[2]; /* big endian */
|
||||
u8 replay_counter[WPA_REPLAY_COUNTER_LEN];
|
||||
u8 key_nonce[WPA_NONCE_LEN];
|
||||
u8 key_iv[16];
|
||||
u8 key_rsc[WPA_KEY_RSC_LEN];
|
||||
u8 key_id[8]; /* Reserved in IEEE 802.11i/RSN */
|
||||
u8 key_mic[16];
|
||||
u8 key_data_length[2]; /* big endian */
|
||||
/* followed by key_data_length bytes of key_data */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
struct wpa_eapol_key_192 {
|
||||
u8 type;
|
||||
/* Note: key_info, key_length, and key_data_length are unaligned */
|
||||
u8 key_info[2]; /* big endian */
|
||||
u8 key_length[2]; /* big endian */
|
||||
u8 replay_counter[WPA_REPLAY_COUNTER_LEN];
|
||||
u8 key_nonce[WPA_NONCE_LEN];
|
||||
u8 key_iv[16];
|
||||
u8 key_rsc[WPA_KEY_RSC_LEN];
|
||||
u8 key_id[8]; /* Reserved in IEEE 802.11i/RSN */
|
||||
u8 key_mic[24];
|
||||
u8 key_data_length[2]; /* big endian */
|
||||
/* followed by key_data_length bytes of key_data */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#define WPA_EAPOL_KEY_MIC_MAX_LEN 24
|
||||
#define WPA_KCK_MAX_LEN 24
|
||||
#define WPA_KEK_MAX_LEN 32
|
||||
#define WPA_TK_MAX_LEN 32
|
||||
|
||||
/**
|
||||
* struct wpa_ptk - WPA Pairwise Transient Key
|
||||
* IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
|
||||
*/
|
||||
struct wpa_ptk {
|
||||
u8 kck[WPA_KCK_MAX_LEN]; /* EAPOL-Key Key Confirmation Key (KCK) */
|
||||
u8 kek[WPA_KEK_MAX_LEN]; /* EAPOL-Key Key Encryption Key (KEK) */
|
||||
u8 tk[WPA_TK_MAX_LEN]; /* Temporal Key (TK) */
|
||||
size_t kck_len;
|
||||
size_t kek_len;
|
||||
size_t tk_len;
|
||||
};
|
||||
|
||||
|
||||
/* WPA IE version 1
|
||||
* 00-50-f2:1 (OUI:OUI type)
|
||||
* 0x01 0x00 (version; little endian)
|
||||
* (all following fields are optional:)
|
||||
* Group Suite Selector (4 octets) (default: TKIP)
|
||||
* Pairwise Suite Count (2 octets, little endian) (default: 1)
|
||||
* Pairwise Suite List (4 * n octets) (default: TKIP)
|
||||
* Authenticated Key Management Suite Count (2 octets, little endian)
|
||||
* (default: 1)
|
||||
* Authenticated Key Management Suite List (4 * n octets)
|
||||
* (default: unspec 802.1X)
|
||||
* WPA Capabilities (2 octets, little endian) (default: 0)
|
||||
*/
|
||||
|
||||
struct wpa_ie_hdr {
|
||||
u8 elem_id;
|
||||
u8 len;
|
||||
u8 oui[4]; /* 24-bit OUI followed by 8-bit OUI type */
|
||||
u8 version[2]; /* little endian */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
|
||||
/* 1/4: PMKID
|
||||
* 2/4: RSN IE
|
||||
* 3/4: one or two RSN IEs + GTK IE (encrypted)
|
||||
* 4/4: empty
|
||||
* 1/2: GTK IE (encrypted)
|
||||
* 2/2: empty
|
||||
*/
|
||||
|
||||
/* RSN IE version 1
|
||||
* 0x01 0x00 (version; little endian)
|
||||
* (all following fields are optional:)
|
||||
* Group Suite Selector (4 octets) (default: CCMP)
|
||||
* Pairwise Suite Count (2 octets, little endian) (default: 1)
|
||||
* Pairwise Suite List (4 * n octets) (default: CCMP)
|
||||
* Authenticated Key Management Suite Count (2 octets, little endian)
|
||||
* (default: 1)
|
||||
* Authenticated Key Management Suite List (4 * n octets)
|
||||
* (default: unspec 802.1X)
|
||||
* RSN Capabilities (2 octets, little endian) (default: 0)
|
||||
* PMKID Count (2 octets) (default: 0)
|
||||
* PMKID List (16 * n octets)
|
||||
* Management Group Cipher Suite (4 octets) (default: AES-128-CMAC)
|
||||
*/
|
||||
|
||||
struct rsn_ie_hdr {
|
||||
u8 elem_id; /* WLAN_EID_RSN */
|
||||
u8 len;
|
||||
u8 version[2]; /* little endian */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
|
||||
#ifdef CONFIG_PEERKEY
|
||||
enum {
|
||||
STK_MUI_4WAY_STA_AP = 1,
|
||||
STK_MUI_4WAY_STAT_STA = 2,
|
||||
STK_MUI_GTK = 3,
|
||||
STK_MUI_SMK = 4
|
||||
};
|
||||
|
||||
enum {
|
||||
STK_ERR_STA_NR = 1,
|
||||
STK_ERR_STA_NRSN = 2,
|
||||
STK_ERR_CPHR_NS = 3,
|
||||
STK_ERR_NO_STSL = 4
|
||||
};
|
||||
#endif /* CONFIG_PEERKEY */
|
||||
|
||||
struct rsn_error_kde {
|
||||
be16 mui;
|
||||
be16 error_type;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
#define WPA_IGTK_KDE_PREFIX_LEN (2 + 6)
|
||||
struct wpa_igtk_kde {
|
||||
u8 keyid[2];
|
||||
u8 pn[6];
|
||||
u8 igtk[WPA_IGTK_MAX_LEN];
|
||||
} STRUCT_PACKED;
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
struct rsn_mdie {
|
||||
u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN];
|
||||
u8 ft_capab;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#define RSN_FT_CAPAB_FT_OVER_DS BIT(0)
|
||||
#define RSN_FT_CAPAB_FT_RESOURCE_REQ_SUPP BIT(1)
|
||||
|
||||
struct rsn_ftie {
|
||||
u8 mic_control[2];
|
||||
u8 mic[16];
|
||||
u8 anonce[WPA_NONCE_LEN];
|
||||
u8 snonce[WPA_NONCE_LEN];
|
||||
/* followed by optional parameters */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#define FTIE_SUBELEM_R1KH_ID 1
|
||||
#define FTIE_SUBELEM_GTK 2
|
||||
#define FTIE_SUBELEM_R0KH_ID 3
|
||||
#define FTIE_SUBELEM_IGTK 4
|
||||
|
||||
struct rsn_rdie {
|
||||
u8 id;
|
||||
u8 descr_count;
|
||||
le16 status_code;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
|
||||
int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
|
||||
const u8 *buf, size_t len, u8 *mic);
|
||||
int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
|
||||
const u8 *addr1, const u8 *addr2,
|
||||
const u8 *nonce1, const u8 *nonce2,
|
||||
struct wpa_ptk *ptk, int akmp, int cipher);
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr,
|
||||
const u8 *ap_addr, u8 transaction_seqnum,
|
||||
const u8 *mdie, size_t mdie_len,
|
||||
const u8 *ftie, size_t ftie_len,
|
||||
const u8 *rsnie, size_t rsnie_len,
|
||||
const u8 *ric, size_t ric_len, u8 *mic);
|
||||
void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
|
||||
const u8 *ssid, size_t ssid_len,
|
||||
const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len,
|
||||
const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name);
|
||||
void wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
|
||||
const u8 *s1kh_id, u8 *pmk_r1_name);
|
||||
void wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name,
|
||||
const u8 *r1kh_id, const u8 *s1kh_id,
|
||||
u8 *pmk_r1, u8 *pmk_r1_name);
|
||||
int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce,
|
||||
const u8 *sta_addr, const u8 *bssid,
|
||||
const u8 *pmk_r1_name,
|
||||
struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher);
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
|
||||
struct wpa_ie_data {
|
||||
int proto;
|
||||
int pairwise_cipher;
|
||||
int group_cipher;
|
||||
int key_mgmt;
|
||||
int capabilities;
|
||||
size_t num_pmkid;
|
||||
const u8 *pmkid;
|
||||
int mgmt_group_cipher;
|
||||
};
|
||||
|
||||
|
||||
int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
|
||||
struct wpa_ie_data *data);
|
||||
int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
|
||||
struct wpa_ie_data *data);
|
||||
|
||||
void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
|
||||
u8 *pmkid, int use_sha256);
|
||||
#ifdef CONFIG_SUITEB
|
||||
int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
|
||||
const u8 *spa, u8 *pmkid);
|
||||
#else /* CONFIG_SUITEB */
|
||||
static inline int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
|
||||
const u8 *spa, u8 *pmkid)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif /* CONFIG_SUITEB */
|
||||
#ifdef CONFIG_SUITEB192
|
||||
int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
|
||||
const u8 *spa, u8 *pmkid);
|
||||
#else /* CONFIG_SUITEB192 */
|
||||
static inline int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len,
|
||||
const u8 *aa, const u8 *spa, u8 *pmkid)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif /* CONFIG_SUITEB192 */
|
||||
|
||||
const char * wpa_cipher_txt(int cipher);
|
||||
const char * wpa_key_mgmt_txt(int key_mgmt, int proto);
|
||||
u32 wpa_akm_to_suite(int akm);
|
||||
int wpa_compare_rsn_ie(int ft_initial_assoc,
|
||||
const u8 *ie1, size_t ie1len,
|
||||
const u8 *ie2, size_t ie2len);
|
||||
int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid);
|
||||
|
||||
struct wpa_ft_ies {
|
||||
const u8 *mdie;
|
||||
size_t mdie_len;
|
||||
const u8 *ftie;
|
||||
size_t ftie_len;
|
||||
const u8 *r1kh_id;
|
||||
const u8 *gtk;
|
||||
size_t gtk_len;
|
||||
const u8 *r0kh_id;
|
||||
size_t r0kh_id_len;
|
||||
const u8 *rsn;
|
||||
size_t rsn_len;
|
||||
const u8 *rsn_pmkid;
|
||||
const u8 *tie;
|
||||
size_t tie_len;
|
||||
const u8 *igtk;
|
||||
size_t igtk_len;
|
||||
const u8 *ric;
|
||||
size_t ric_len;
|
||||
};
|
||||
|
||||
int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse);
|
||||
|
||||
int wpa_cipher_key_len(int cipher);
|
||||
int wpa_cipher_rsc_len(int cipher);
|
||||
int wpa_cipher_to_alg(int cipher);
|
||||
int wpa_cipher_valid_group(int cipher);
|
||||
int wpa_cipher_valid_pairwise(int cipher);
|
||||
int wpa_cipher_valid_mgmt_group(int cipher);
|
||||
u32 wpa_cipher_to_suite(int proto, int cipher);
|
||||
int rsn_cipher_put_suites(u8 *pos, int ciphers);
|
||||
int wpa_cipher_put_suites(u8 *pos, int ciphers);
|
||||
int wpa_pick_pairwise_cipher(int ciphers, int none_allowed);
|
||||
int wpa_pick_group_cipher(int ciphers);
|
||||
int wpa_parse_cipher(const char *value);
|
||||
int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim);
|
||||
int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise);
|
||||
unsigned int wpa_mic_len(int akmp);
|
||||
|
||||
#endif /* WPA_COMMON_H */
|
472
freebsd/contrib/wpa/src/common/wpa_ctrl.h
Normal file
472
freebsd/contrib/wpa/src/common/wpa_ctrl.h
Normal file
@ -0,0 +1,472 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd control interface library
|
||||
* Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef WPA_CTRL_H
|
||||
#define WPA_CTRL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* wpa_supplicant control interface - fixed message prefixes */
|
||||
|
||||
/** Interactive request for identity/password/pin */
|
||||
#define WPA_CTRL_REQ "CTRL-REQ-"
|
||||
|
||||
/** Response to identity/password/pin request */
|
||||
#define WPA_CTRL_RSP "CTRL-RSP-"
|
||||
|
||||
/* Event messages with fixed prefix */
|
||||
/** Authentication completed successfully and data connection enabled */
|
||||
#define WPA_EVENT_CONNECTED "CTRL-EVENT-CONNECTED "
|
||||
/** Disconnected, data connection is not available */
|
||||
#define WPA_EVENT_DISCONNECTED "CTRL-EVENT-DISCONNECTED "
|
||||
/** Association rejected during connection attempt */
|
||||
#define WPA_EVENT_ASSOC_REJECT "CTRL-EVENT-ASSOC-REJECT "
|
||||
/** Authentication rejected during connection attempt */
|
||||
#define WPA_EVENT_AUTH_REJECT "CTRL-EVENT-AUTH-REJECT "
|
||||
/** wpa_supplicant is exiting */
|
||||
#define WPA_EVENT_TERMINATING "CTRL-EVENT-TERMINATING "
|
||||
/** Password change was completed successfully */
|
||||
#define WPA_EVENT_PASSWORD_CHANGED "CTRL-EVENT-PASSWORD-CHANGED "
|
||||
/** EAP-Request/Notification received */
|
||||
#define WPA_EVENT_EAP_NOTIFICATION "CTRL-EVENT-EAP-NOTIFICATION "
|
||||
/** EAP authentication started (EAP-Request/Identity received) */
|
||||
#define WPA_EVENT_EAP_STARTED "CTRL-EVENT-EAP-STARTED "
|
||||
/** EAP method proposed by the server */
|
||||
#define WPA_EVENT_EAP_PROPOSED_METHOD "CTRL-EVENT-EAP-PROPOSED-METHOD "
|
||||
/** EAP method selected */
|
||||
#define WPA_EVENT_EAP_METHOD "CTRL-EVENT-EAP-METHOD "
|
||||
/** EAP peer certificate from TLS */
|
||||
#define WPA_EVENT_EAP_PEER_CERT "CTRL-EVENT-EAP-PEER-CERT "
|
||||
/** EAP peer certificate alternative subject name component from TLS */
|
||||
#define WPA_EVENT_EAP_PEER_ALT "CTRL-EVENT-EAP-PEER-ALT "
|
||||
/** EAP TLS certificate chain validation error */
|
||||
#define WPA_EVENT_EAP_TLS_CERT_ERROR "CTRL-EVENT-EAP-TLS-CERT-ERROR "
|
||||
/** EAP status */
|
||||
#define WPA_EVENT_EAP_STATUS "CTRL-EVENT-EAP-STATUS "
|
||||
/** EAP authentication completed successfully */
|
||||
#define WPA_EVENT_EAP_SUCCESS "CTRL-EVENT-EAP-SUCCESS "
|
||||
/** EAP authentication failed (EAP-Failure received) */
|
||||
#define WPA_EVENT_EAP_FAILURE "CTRL-EVENT-EAP-FAILURE "
|
||||
/** Network block temporarily disabled (e.g., due to authentication failure) */
|
||||
#define WPA_EVENT_TEMP_DISABLED "CTRL-EVENT-SSID-TEMP-DISABLED "
|
||||
/** Temporarily disabled network block re-enabled */
|
||||
#define WPA_EVENT_REENABLED "CTRL-EVENT-SSID-REENABLED "
|
||||
/** New scan started */
|
||||
#define WPA_EVENT_SCAN_STARTED "CTRL-EVENT-SCAN-STARTED "
|
||||
/** New scan results available */
|
||||
#define WPA_EVENT_SCAN_RESULTS "CTRL-EVENT-SCAN-RESULTS "
|
||||
/** Scan command failed */
|
||||
#define WPA_EVENT_SCAN_FAILED "CTRL-EVENT-SCAN-FAILED "
|
||||
/** wpa_supplicant state change */
|
||||
#define WPA_EVENT_STATE_CHANGE "CTRL-EVENT-STATE-CHANGE "
|
||||
/** A new BSS entry was added (followed by BSS entry id and BSSID) */
|
||||
#define WPA_EVENT_BSS_ADDED "CTRL-EVENT-BSS-ADDED "
|
||||
/** A BSS entry was removed (followed by BSS entry id and BSSID) */
|
||||
#define WPA_EVENT_BSS_REMOVED "CTRL-EVENT-BSS-REMOVED "
|
||||
/** No suitable network was found */
|
||||
#define WPA_EVENT_NETWORK_NOT_FOUND "CTRL-EVENT-NETWORK-NOT-FOUND "
|
||||
/** Change in the signal level was reported by the driver */
|
||||
#define WPA_EVENT_SIGNAL_CHANGE "CTRL-EVENT-SIGNAL-CHANGE "
|
||||
/** Regulatory domain channel */
|
||||
#define WPA_EVENT_REGDOM_CHANGE "CTRL-EVENT-REGDOM-CHANGE "
|
||||
|
||||
/** RSN IBSS 4-way handshakes completed with specified peer */
|
||||
#define IBSS_RSN_COMPLETED "IBSS-RSN-COMPLETED "
|
||||
|
||||
/** Notification of frequency conflict due to a concurrent operation.
|
||||
*
|
||||
* The indicated network is disabled and needs to be re-enabled before it can
|
||||
* be used again.
|
||||
*/
|
||||
#define WPA_EVENT_FREQ_CONFLICT "CTRL-EVENT-FREQ-CONFLICT "
|
||||
/** Frequency ranges that the driver recommends to avoid */
|
||||
#define WPA_EVENT_AVOID_FREQ "CTRL-EVENT-AVOID-FREQ "
|
||||
/** WPS overlap detected in PBC mode */
|
||||
#define WPS_EVENT_OVERLAP "WPS-OVERLAP-DETECTED "
|
||||
/** Available WPS AP with active PBC found in scan results */
|
||||
#define WPS_EVENT_AP_AVAILABLE_PBC "WPS-AP-AVAILABLE-PBC "
|
||||
/** Available WPS AP with our address as authorized in scan results */
|
||||
#define WPS_EVENT_AP_AVAILABLE_AUTH "WPS-AP-AVAILABLE-AUTH "
|
||||
/** Available WPS AP with recently selected PIN registrar found in scan results
|
||||
*/
|
||||
#define WPS_EVENT_AP_AVAILABLE_PIN "WPS-AP-AVAILABLE-PIN "
|
||||
/** Available WPS AP found in scan results */
|
||||
#define WPS_EVENT_AP_AVAILABLE "WPS-AP-AVAILABLE "
|
||||
/** A new credential received */
|
||||
#define WPS_EVENT_CRED_RECEIVED "WPS-CRED-RECEIVED "
|
||||
/** M2D received */
|
||||
#define WPS_EVENT_M2D "WPS-M2D "
|
||||
/** WPS registration failed after M2/M2D */
|
||||
#define WPS_EVENT_FAIL "WPS-FAIL "
|
||||
/** WPS registration completed successfully */
|
||||
#define WPS_EVENT_SUCCESS "WPS-SUCCESS "
|
||||
/** WPS enrollment attempt timed out and was terminated */
|
||||
#define WPS_EVENT_TIMEOUT "WPS-TIMEOUT "
|
||||
/* PBC mode was activated */
|
||||
#define WPS_EVENT_ACTIVE "WPS-PBC-ACTIVE "
|
||||
/* PBC mode was disabled */
|
||||
#define WPS_EVENT_DISABLE "WPS-PBC-DISABLE "
|
||||
|
||||
#define WPS_EVENT_ENROLLEE_SEEN "WPS-ENROLLEE-SEEN "
|
||||
|
||||
#define WPS_EVENT_OPEN_NETWORK "WPS-OPEN-NETWORK "
|
||||
|
||||
/* WPS ER events */
|
||||
#define WPS_EVENT_ER_AP_ADD "WPS-ER-AP-ADD "
|
||||
#define WPS_EVENT_ER_AP_REMOVE "WPS-ER-AP-REMOVE "
|
||||
#define WPS_EVENT_ER_ENROLLEE_ADD "WPS-ER-ENROLLEE-ADD "
|
||||
#define WPS_EVENT_ER_ENROLLEE_REMOVE "WPS-ER-ENROLLEE-REMOVE "
|
||||
#define WPS_EVENT_ER_AP_SETTINGS "WPS-ER-AP-SETTINGS "
|
||||
#define WPS_EVENT_ER_SET_SEL_REG "WPS-ER-AP-SET-SEL-REG "
|
||||
|
||||
/* MESH events */
|
||||
#define MESH_GROUP_STARTED "MESH-GROUP-STARTED "
|
||||
#define MESH_GROUP_REMOVED "MESH-GROUP-REMOVED "
|
||||
#define MESH_PEER_CONNECTED "MESH-PEER-CONNECTED "
|
||||
#define MESH_PEER_DISCONNECTED "MESH-PEER-DISCONNECTED "
|
||||
/** Mesh SAE authentication failure. Wrong password suspected. */
|
||||
#define MESH_SAE_AUTH_FAILURE "MESH-SAE-AUTH-FAILURE "
|
||||
#define MESH_SAE_AUTH_BLOCKED "MESH-SAE-AUTH-BLOCKED "
|
||||
|
||||
/* WMM AC events */
|
||||
#define WMM_AC_EVENT_TSPEC_ADDED "TSPEC-ADDED "
|
||||
#define WMM_AC_EVENT_TSPEC_REMOVED "TSPEC-REMOVED "
|
||||
#define WMM_AC_EVENT_TSPEC_REQ_FAILED "TSPEC-REQ-FAILED "
|
||||
|
||||
/** P2P device found */
|
||||
#define P2P_EVENT_DEVICE_FOUND "P2P-DEVICE-FOUND "
|
||||
|
||||
/** P2P device lost */
|
||||
#define P2P_EVENT_DEVICE_LOST "P2P-DEVICE-LOST "
|
||||
|
||||
/** A P2P device requested GO negotiation, but we were not ready to start the
|
||||
* negotiation */
|
||||
#define P2P_EVENT_GO_NEG_REQUEST "P2P-GO-NEG-REQUEST "
|
||||
#define P2P_EVENT_GO_NEG_SUCCESS "P2P-GO-NEG-SUCCESS "
|
||||
#define P2P_EVENT_GO_NEG_FAILURE "P2P-GO-NEG-FAILURE "
|
||||
#define P2P_EVENT_GROUP_FORMATION_SUCCESS "P2P-GROUP-FORMATION-SUCCESS "
|
||||
#define P2P_EVENT_GROUP_FORMATION_FAILURE "P2P-GROUP-FORMATION-FAILURE "
|
||||
#define P2P_EVENT_GROUP_STARTED "P2P-GROUP-STARTED "
|
||||
#define P2P_EVENT_GROUP_REMOVED "P2P-GROUP-REMOVED "
|
||||
#define P2P_EVENT_CROSS_CONNECT_ENABLE "P2P-CROSS-CONNECT-ENABLE "
|
||||
#define P2P_EVENT_CROSS_CONNECT_DISABLE "P2P-CROSS-CONNECT-DISABLE "
|
||||
/* parameters: <peer address> <PIN> */
|
||||
#define P2P_EVENT_PROV_DISC_SHOW_PIN "P2P-PROV-DISC-SHOW-PIN "
|
||||
/* parameters: <peer address> */
|
||||
#define P2P_EVENT_PROV_DISC_ENTER_PIN "P2P-PROV-DISC-ENTER-PIN "
|
||||
/* parameters: <peer address> */
|
||||
#define P2P_EVENT_PROV_DISC_PBC_REQ "P2P-PROV-DISC-PBC-REQ "
|
||||
/* parameters: <peer address> */
|
||||
#define P2P_EVENT_PROV_DISC_PBC_RESP "P2P-PROV-DISC-PBC-RESP "
|
||||
/* parameters: <peer address> <status> */
|
||||
#define P2P_EVENT_PROV_DISC_FAILURE "P2P-PROV-DISC-FAILURE"
|
||||
/* parameters: <freq> <src addr> <dialog token> <update indicator> <TLVs> */
|
||||
#define P2P_EVENT_SERV_DISC_REQ "P2P-SERV-DISC-REQ "
|
||||
/* parameters: <src addr> <update indicator> <TLVs> */
|
||||
#define P2P_EVENT_SERV_DISC_RESP "P2P-SERV-DISC-RESP "
|
||||
#define P2P_EVENT_SERV_ASP_RESP "P2P-SERV-ASP-RESP "
|
||||
#define P2P_EVENT_INVITATION_RECEIVED "P2P-INVITATION-RECEIVED "
|
||||
#define P2P_EVENT_INVITATION_RESULT "P2P-INVITATION-RESULT "
|
||||
#define P2P_EVENT_FIND_STOPPED "P2P-FIND-STOPPED "
|
||||
#define P2P_EVENT_PERSISTENT_PSK_FAIL "P2P-PERSISTENT-PSK-FAIL id="
|
||||
#define P2P_EVENT_PRESENCE_RESPONSE "P2P-PRESENCE-RESPONSE "
|
||||
#define P2P_EVENT_NFC_BOTH_GO "P2P-NFC-BOTH-GO "
|
||||
#define P2P_EVENT_NFC_PEER_CLIENT "P2P-NFC-PEER-CLIENT "
|
||||
#define P2P_EVENT_NFC_WHILE_CLIENT "P2P-NFC-WHILE-CLIENT "
|
||||
#define P2P_EVENT_FALLBACK_TO_GO_NEG "P2P-FALLBACK-TO-GO-NEG "
|
||||
#define P2P_EVENT_FALLBACK_TO_GO_NEG_ENABLED "P2P-FALLBACK-TO-GO-NEG-ENABLED "
|
||||
|
||||
/* parameters: <PMF enabled> <timeout in ms> <Session Information URL> */
|
||||
#define ESS_DISASSOC_IMMINENT "ESS-DISASSOC-IMMINENT "
|
||||
#define P2P_EVENT_REMOVE_AND_REFORM_GROUP "P2P-REMOVE-AND-REFORM-GROUP "
|
||||
|
||||
#define P2P_EVENT_P2PS_PROVISION_START "P2PS-PROV-START "
|
||||
#define P2P_EVENT_P2PS_PROVISION_DONE "P2PS-PROV-DONE "
|
||||
|
||||
#define INTERWORKING_AP "INTERWORKING-AP "
|
||||
#define INTERWORKING_BLACKLISTED "INTERWORKING-BLACKLISTED "
|
||||
#define INTERWORKING_NO_MATCH "INTERWORKING-NO-MATCH "
|
||||
#define INTERWORKING_ALREADY_CONNECTED "INTERWORKING-ALREADY-CONNECTED "
|
||||
#define INTERWORKING_SELECTED "INTERWORKING-SELECTED "
|
||||
|
||||
/* Credential block added; parameters: <id> */
|
||||
#define CRED_ADDED "CRED-ADDED "
|
||||
/* Credential block modified; parameters: <id> <field> */
|
||||
#define CRED_MODIFIED "CRED-MODIFIED "
|
||||
/* Credential block removed; parameters: <id> */
|
||||
#define CRED_REMOVED "CRED-REMOVED "
|
||||
|
||||
#define GAS_RESPONSE_INFO "GAS-RESPONSE-INFO "
|
||||
/* parameters: <addr> <dialog_token> <freq> */
|
||||
#define GAS_QUERY_START "GAS-QUERY-START "
|
||||
/* parameters: <addr> <dialog_token> <freq> <status_code> <result> */
|
||||
#define GAS_QUERY_DONE "GAS-QUERY-DONE "
|
||||
|
||||
/* parameters: <addr> <result> */
|
||||
#define ANQP_QUERY_DONE "ANQP-QUERY-DONE "
|
||||
|
||||
#define HS20_SUBSCRIPTION_REMEDIATION "HS20-SUBSCRIPTION-REMEDIATION "
|
||||
#define HS20_DEAUTH_IMMINENT_NOTICE "HS20-DEAUTH-IMMINENT-NOTICE "
|
||||
|
||||
#define EXT_RADIO_WORK_START "EXT-RADIO-WORK-START "
|
||||
#define EXT_RADIO_WORK_TIMEOUT "EXT-RADIO-WORK-TIMEOUT "
|
||||
|
||||
#define RRM_EVENT_NEIGHBOR_REP_RXED "RRM-NEIGHBOR-REP-RECEIVED "
|
||||
#define RRM_EVENT_NEIGHBOR_REP_FAILED "RRM-NEIGHBOR-REP-REQUEST-FAILED "
|
||||
|
||||
/* hostapd control interface - fixed message prefixes */
|
||||
#define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED "
|
||||
#define WPS_EVENT_NEW_AP_SETTINGS "WPS-NEW-AP-SETTINGS "
|
||||
#define WPS_EVENT_REG_SUCCESS "WPS-REG-SUCCESS "
|
||||
#define WPS_EVENT_AP_SETUP_LOCKED "WPS-AP-SETUP-LOCKED "
|
||||
#define WPS_EVENT_AP_SETUP_UNLOCKED "WPS-AP-SETUP-UNLOCKED "
|
||||
#define WPS_EVENT_AP_PIN_ENABLED "WPS-AP-PIN-ENABLED "
|
||||
#define WPS_EVENT_AP_PIN_DISABLED "WPS-AP-PIN-DISABLED "
|
||||
#define AP_STA_CONNECTED "AP-STA-CONNECTED "
|
||||
#define AP_STA_DISCONNECTED "AP-STA-DISCONNECTED "
|
||||
#define AP_STA_POSSIBLE_PSK_MISMATCH "AP-STA-POSSIBLE-PSK-MISMATCH "
|
||||
|
||||
#define AP_REJECTED_MAX_STA "AP-REJECTED-MAX-STA "
|
||||
#define AP_REJECTED_BLOCKED_STA "AP-REJECTED-BLOCKED-STA "
|
||||
|
||||
#define AP_EVENT_ENABLED "AP-ENABLED "
|
||||
#define AP_EVENT_DISABLED "AP-DISABLED "
|
||||
|
||||
#define INTERFACE_ENABLED "INTERFACE-ENABLED "
|
||||
#define INTERFACE_DISABLED "INTERFACE-DISABLED "
|
||||
|
||||
#define ACS_EVENT_STARTED "ACS-STARTED "
|
||||
#define ACS_EVENT_COMPLETED "ACS-COMPLETED "
|
||||
#define ACS_EVENT_FAILED "ACS-FAILED "
|
||||
|
||||
#define DFS_EVENT_RADAR_DETECTED "DFS-RADAR-DETECTED "
|
||||
#define DFS_EVENT_NEW_CHANNEL "DFS-NEW-CHANNEL "
|
||||
#define DFS_EVENT_CAC_START "DFS-CAC-START "
|
||||
#define DFS_EVENT_CAC_COMPLETED "DFS-CAC-COMPLETED "
|
||||
#define DFS_EVENT_NOP_FINISHED "DFS-NOP-FINISHED "
|
||||
|
||||
#define AP_CSA_FINISHED "AP-CSA-FINISHED "
|
||||
|
||||
/* BSS Transition Management Response frame received */
|
||||
#define BSS_TM_RESP "BSS-TM-RESP "
|
||||
|
||||
/* BSS command information masks */
|
||||
|
||||
#define WPA_BSS_MASK_ALL 0xFFFDFFFF
|
||||
#define WPA_BSS_MASK_ID BIT(0)
|
||||
#define WPA_BSS_MASK_BSSID BIT(1)
|
||||
#define WPA_BSS_MASK_FREQ BIT(2)
|
||||
#define WPA_BSS_MASK_BEACON_INT BIT(3)
|
||||
#define WPA_BSS_MASK_CAPABILITIES BIT(4)
|
||||
#define WPA_BSS_MASK_QUAL BIT(5)
|
||||
#define WPA_BSS_MASK_NOISE BIT(6)
|
||||
#define WPA_BSS_MASK_LEVEL BIT(7)
|
||||
#define WPA_BSS_MASK_TSF BIT(8)
|
||||
#define WPA_BSS_MASK_AGE BIT(9)
|
||||
#define WPA_BSS_MASK_IE BIT(10)
|
||||
#define WPA_BSS_MASK_FLAGS BIT(11)
|
||||
#define WPA_BSS_MASK_SSID BIT(12)
|
||||
#define WPA_BSS_MASK_WPS_SCAN BIT(13)
|
||||
#define WPA_BSS_MASK_P2P_SCAN BIT(14)
|
||||
#define WPA_BSS_MASK_INTERNETW BIT(15)
|
||||
#define WPA_BSS_MASK_WIFI_DISPLAY BIT(16)
|
||||
#define WPA_BSS_MASK_DELIM BIT(17)
|
||||
#define WPA_BSS_MASK_MESH_SCAN BIT(18)
|
||||
#define WPA_BSS_MASK_SNR BIT(19)
|
||||
#define WPA_BSS_MASK_EST_THROUGHPUT BIT(20)
|
||||
#define WPA_BSS_MASK_FST BIT(21)
|
||||
|
||||
|
||||
/* VENDOR_ELEM_* frame id values */
|
||||
enum wpa_vendor_elem_frame {
|
||||
VENDOR_ELEM_PROBE_REQ_P2P = 0,
|
||||
VENDOR_ELEM_PROBE_RESP_P2P = 1,
|
||||
VENDOR_ELEM_PROBE_RESP_P2P_GO = 2,
|
||||
VENDOR_ELEM_BEACON_P2P_GO = 3,
|
||||
VENDOR_ELEM_P2P_PD_REQ = 4,
|
||||
VENDOR_ELEM_P2P_PD_RESP = 5,
|
||||
VENDOR_ELEM_P2P_GO_NEG_REQ = 6,
|
||||
VENDOR_ELEM_P2P_GO_NEG_RESP = 7,
|
||||
VENDOR_ELEM_P2P_GO_NEG_CONF = 8,
|
||||
VENDOR_ELEM_P2P_INV_REQ = 9,
|
||||
VENDOR_ELEM_P2P_INV_RESP = 10,
|
||||
VENDOR_ELEM_P2P_ASSOC_REQ = 11,
|
||||
VENDOR_ELEM_P2P_ASSOC_RESP = 12,
|
||||
VENDOR_ELEM_ASSOC_REQ = 13,
|
||||
NUM_VENDOR_ELEM_FRAMES
|
||||
};
|
||||
|
||||
|
||||
/* wpa_supplicant/hostapd control interface access */
|
||||
|
||||
/**
|
||||
* wpa_ctrl_open - Open a control interface to wpa_supplicant/hostapd
|
||||
* @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used.
|
||||
* Returns: Pointer to abstract control interface data or %NULL on failure
|
||||
*
|
||||
* This function is used to open a control interface to wpa_supplicant/hostapd.
|
||||
* ctrl_path is usually /var/run/wpa_supplicant or /var/run/hostapd. This path
|
||||
* is configured in wpa_supplicant/hostapd and other programs using the control
|
||||
* interface need to use matching path configuration.
|
||||
*/
|
||||
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path);
|
||||
|
||||
/**
|
||||
* wpa_ctrl_open2 - Open a control interface to wpa_supplicant/hostapd
|
||||
* @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used.
|
||||
* @cli_path: Path for client UNIX domain sockets; ignored if UDP socket
|
||||
* is used.
|
||||
* Returns: Pointer to abstract control interface data or %NULL on failure
|
||||
*
|
||||
* This function is used to open a control interface to wpa_supplicant/hostapd
|
||||
* when the socket path for client need to be specified explicitly. Default
|
||||
* ctrl_path is usually /var/run/wpa_supplicant or /var/run/hostapd and client
|
||||
* socket path is /tmp.
|
||||
*/
|
||||
struct wpa_ctrl * wpa_ctrl_open2(const char *ctrl_path, const char *cli_path);
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_close - Close a control interface to wpa_supplicant/hostapd
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
*
|
||||
* This function is used to close a control interface.
|
||||
*/
|
||||
void wpa_ctrl_close(struct wpa_ctrl *ctrl);
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_request - Send a command to wpa_supplicant/hostapd
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
* @cmd: Command; usually, ASCII text, e.g., "PING"
|
||||
* @cmd_len: Length of the cmd in bytes
|
||||
* @reply: Buffer for the response
|
||||
* @reply_len: Reply buffer length
|
||||
* @msg_cb: Callback function for unsolicited messages or %NULL if not used
|
||||
* Returns: 0 on success, -1 on error (send or receive failed), -2 on timeout
|
||||
*
|
||||
* This function is used to send commands to wpa_supplicant/hostapd. Received
|
||||
* response will be written to reply and reply_len is set to the actual length
|
||||
* of the reply. This function will block for up to two seconds while waiting
|
||||
* for the reply. If unsolicited messages are received, the blocking time may
|
||||
* be longer.
|
||||
*
|
||||
* msg_cb can be used to register a callback function that will be called for
|
||||
* unsolicited messages received while waiting for the command response. These
|
||||
* messages may be received if wpa_ctrl_request() is called at the same time as
|
||||
* wpa_supplicant/hostapd is sending such a message. This can happen only if
|
||||
* the program has used wpa_ctrl_attach() to register itself as a monitor for
|
||||
* event messages. Alternatively to msg_cb, programs can register two control
|
||||
* interface connections and use one of them for commands and the other one for
|
||||
* receiving event messages, in other words, call wpa_ctrl_attach() only for
|
||||
* the control interface connection that will be used for event messages.
|
||||
*/
|
||||
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
|
||||
char *reply, size_t *reply_len,
|
||||
void (*msg_cb)(char *msg, size_t len));
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_attach - Register as an event monitor for the control interface
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
* Returns: 0 on success, -1 on failure, -2 on timeout
|
||||
*
|
||||
* This function registers the control interface connection as a monitor for
|
||||
* wpa_supplicant/hostapd events. After a success wpa_ctrl_attach() call, the
|
||||
* control interface connection starts receiving event messages that can be
|
||||
* read with wpa_ctrl_recv().
|
||||
*/
|
||||
int wpa_ctrl_attach(struct wpa_ctrl *ctrl);
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_detach - Unregister event monitor from the control interface
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
* Returns: 0 on success, -1 on failure, -2 on timeout
|
||||
*
|
||||
* This function unregisters the control interface connection as a monitor for
|
||||
* wpa_supplicant/hostapd events, i.e., cancels the registration done with
|
||||
* wpa_ctrl_attach().
|
||||
*/
|
||||
int wpa_ctrl_detach(struct wpa_ctrl *ctrl);
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_recv - Receive a pending control interface message
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
* @reply: Buffer for the message data
|
||||
* @reply_len: Length of the reply buffer
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function will receive a pending control interface message. The received
|
||||
* response will be written to reply and reply_len is set to the actual length
|
||||
* of the reply.
|
||||
|
||||
* wpa_ctrl_recv() is only used for event messages, i.e., wpa_ctrl_attach()
|
||||
* must have been used to register the control interface as an event monitor.
|
||||
*/
|
||||
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len);
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_pending - Check whether there are pending event messages
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
* Returns: 1 if there are pending messages, 0 if no, or -1 on error
|
||||
*
|
||||
* This function will check whether there are any pending control interface
|
||||
* message available to be received with wpa_ctrl_recv(). wpa_ctrl_pending() is
|
||||
* only used for event messages, i.e., wpa_ctrl_attach() must have been used to
|
||||
* register the control interface as an event monitor.
|
||||
*/
|
||||
int wpa_ctrl_pending(struct wpa_ctrl *ctrl);
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_get_fd - Get file descriptor used by the control interface
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
* Returns: File descriptor used for the connection
|
||||
*
|
||||
* This function can be used to get the file descriptor that is used for the
|
||||
* control interface connection. The returned value can be used, e.g., with
|
||||
* select() while waiting for multiple events.
|
||||
*
|
||||
* The returned file descriptor must not be used directly for sending or
|
||||
* receiving packets; instead, the library functions wpa_ctrl_request() and
|
||||
* wpa_ctrl_recv() must be used for this.
|
||||
*/
|
||||
int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl);
|
||||
|
||||
#ifdef ANDROID
|
||||
/**
|
||||
* wpa_ctrl_cleanup() - Delete any local UNIX domain socket files that
|
||||
* may be left over from clients that were previously connected to
|
||||
* wpa_supplicant. This keeps these files from being orphaned in the
|
||||
* event of crashes that prevented them from being removed as part
|
||||
* of the normal orderly shutdown.
|
||||
*/
|
||||
void wpa_ctrl_cleanup(void);
|
||||
#endif /* ANDROID */
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP
|
||||
/* Port range for multiple wpa_supplicant instances and multiple VIFs */
|
||||
#define WPA_CTRL_IFACE_PORT 9877
|
||||
#define WPA_CTRL_IFACE_PORT_LIMIT 50 /* decremented from start */
|
||||
#define WPA_GLOBAL_CTRL_IFACE_PORT 9878
|
||||
#define WPA_GLOBAL_CTRL_IFACE_PORT_LIMIT 20 /* incremented from start */
|
||||
|
||||
char * wpa_ctrl_get_remote_ifname(struct wpa_ctrl *ctrl);
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WPA_CTRL_H */
|
57
freebsd/contrib/wpa/src/crypto/aes-ctr.c
Normal file
57
freebsd/contrib/wpa/src/crypto/aes-ctr.c
Normal file
@ -0,0 +1,57 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* AES-128 CTR
|
||||
*
|
||||
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "aes.h"
|
||||
#include "aes_wrap.h"
|
||||
|
||||
/**
|
||||
* aes_128_ctr_encrypt - AES-128 CTR mode encryption
|
||||
* @key: Key for encryption (16 bytes)
|
||||
* @nonce: Nonce for counter mode (16 bytes)
|
||||
* @data: Data to encrypt in-place
|
||||
* @data_len: Length of data in bytes
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
|
||||
u8 *data, size_t data_len)
|
||||
{
|
||||
void *ctx;
|
||||
size_t j, len, left = data_len;
|
||||
int i;
|
||||
u8 *pos = data;
|
||||
u8 counter[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE];
|
||||
|
||||
ctx = aes_encrypt_init(key, 16);
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
os_memcpy(counter, nonce, AES_BLOCK_SIZE);
|
||||
|
||||
while (left > 0) {
|
||||
aes_encrypt(ctx, counter, buf);
|
||||
|
||||
len = (left < AES_BLOCK_SIZE) ? left : AES_BLOCK_SIZE;
|
||||
for (j = 0; j < len; j++)
|
||||
pos[j] ^= buf[j];
|
||||
pos += len;
|
||||
left -= len;
|
||||
|
||||
for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
|
||||
counter[i]++;
|
||||
if (counter[i])
|
||||
break;
|
||||
}
|
||||
}
|
||||
aes_encrypt_deinit(ctx);
|
||||
return 0;
|
||||
}
|
147
freebsd/contrib/wpa/src/crypto/aes-eax.c
Normal file
147
freebsd/contrib/wpa/src/crypto/aes-eax.c
Normal file
@ -0,0 +1,147 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* AES-128 EAX
|
||||
*
|
||||
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "aes.h"
|
||||
#include "aes_wrap.h"
|
||||
|
||||
/**
|
||||
* aes_128_eax_encrypt - AES-128 EAX mode encryption
|
||||
* @key: Key for encryption (16 bytes)
|
||||
* @nonce: Nonce for counter mode
|
||||
* @nonce_len: Nonce length in bytes
|
||||
* @hdr: Header data to be authenticity protected
|
||||
* @hdr_len: Length of the header data bytes
|
||||
* @data: Data to encrypt in-place
|
||||
* @data_len: Length of data in bytes
|
||||
* @tag: 16-byte tag value
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int aes_128_eax_encrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
|
||||
const u8 *hdr, size_t hdr_len,
|
||||
u8 *data, size_t data_len, u8 *tag)
|
||||
{
|
||||
u8 *buf;
|
||||
size_t buf_len;
|
||||
u8 nonce_mac[AES_BLOCK_SIZE], hdr_mac[AES_BLOCK_SIZE],
|
||||
data_mac[AES_BLOCK_SIZE];
|
||||
int i, ret = -1;
|
||||
|
||||
if (nonce_len > data_len)
|
||||
buf_len = nonce_len;
|
||||
else
|
||||
buf_len = data_len;
|
||||
if (hdr_len > buf_len)
|
||||
buf_len = hdr_len;
|
||||
buf_len += 16;
|
||||
|
||||
buf = os_malloc(buf_len);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
os_memset(buf, 0, 15);
|
||||
|
||||
buf[15] = 0;
|
||||
os_memcpy(buf + 16, nonce, nonce_len);
|
||||
if (omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac))
|
||||
goto fail;
|
||||
|
||||
buf[15] = 1;
|
||||
os_memcpy(buf + 16, hdr, hdr_len);
|
||||
if (omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac))
|
||||
goto fail;
|
||||
|
||||
if (aes_128_ctr_encrypt(key, nonce_mac, data, data_len))
|
||||
goto fail;
|
||||
buf[15] = 2;
|
||||
os_memcpy(buf + 16, data, data_len);
|
||||
if (omac1_aes_128(key, buf, 16 + data_len, data_mac))
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||
tag[i] = nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i];
|
||||
|
||||
ret = 0;
|
||||
fail:
|
||||
bin_clear_free(buf, buf_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* aes_128_eax_decrypt - AES-128 EAX mode decryption
|
||||
* @key: Key for decryption (16 bytes)
|
||||
* @nonce: Nonce for counter mode
|
||||
* @nonce_len: Nonce length in bytes
|
||||
* @hdr: Header data to be authenticity protected
|
||||
* @hdr_len: Length of the header data bytes
|
||||
* @data: Data to encrypt in-place
|
||||
* @data_len: Length of data in bytes
|
||||
* @tag: 16-byte tag value
|
||||
* Returns: 0 on success, -1 on failure, -2 if tag does not match
|
||||
*/
|
||||
int aes_128_eax_decrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
|
||||
const u8 *hdr, size_t hdr_len,
|
||||
u8 *data, size_t data_len, const u8 *tag)
|
||||
{
|
||||
u8 *buf;
|
||||
size_t buf_len;
|
||||
u8 nonce_mac[AES_BLOCK_SIZE], hdr_mac[AES_BLOCK_SIZE],
|
||||
data_mac[AES_BLOCK_SIZE];
|
||||
int i;
|
||||
|
||||
if (nonce_len > data_len)
|
||||
buf_len = nonce_len;
|
||||
else
|
||||
buf_len = data_len;
|
||||
if (hdr_len > buf_len)
|
||||
buf_len = hdr_len;
|
||||
buf_len += 16;
|
||||
|
||||
buf = os_malloc(buf_len);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
os_memset(buf, 0, 15);
|
||||
|
||||
buf[15] = 0;
|
||||
os_memcpy(buf + 16, nonce, nonce_len);
|
||||
if (omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac)) {
|
||||
os_free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[15] = 1;
|
||||
os_memcpy(buf + 16, hdr, hdr_len);
|
||||
if (omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac)) {
|
||||
os_free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[15] = 2;
|
||||
os_memcpy(buf + 16, data, data_len);
|
||||
if (omac1_aes_128(key, buf, 16 + data_len, data_mac)) {
|
||||
os_free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_free(buf);
|
||||
|
||||
for (i = 0; i < AES_BLOCK_SIZE; i++) {
|
||||
if (tag[i] != (nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i]))
|
||||
return -2;
|
||||
}
|
||||
|
||||
return aes_128_ctr_encrypt(key, nonce_mac, data, data_len);
|
||||
}
|
34
freebsd/contrib/wpa/src/crypto/aes-encblock.c
Normal file
34
freebsd/contrib/wpa/src/crypto/aes-encblock.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* AES encrypt_block
|
||||
*
|
||||
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "aes.h"
|
||||
#include "aes_wrap.h"
|
||||
|
||||
/**
|
||||
* aes_128_encrypt_block - Perform one AES 128-bit block operation
|
||||
* @key: Key for AES
|
||||
* @in: Input data (16 bytes)
|
||||
* @out: Output of the AES block operation (16 bytes)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out)
|
||||
{
|
||||
void *ctx;
|
||||
ctx = aes_encrypt_init(key, 16);
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
aes_encrypt(ctx, in, out);
|
||||
aes_encrypt_deinit(ctx);
|
||||
return 0;
|
||||
}
|
172
freebsd/contrib/wpa/src/crypto/aes-omac1.c
Normal file
172
freebsd/contrib/wpa/src/crypto/aes-omac1.c
Normal file
@ -0,0 +1,172 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* One-key CBC MAC (OMAC1) hash with AES
|
||||
*
|
||||
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "aes.h"
|
||||
#include "aes_wrap.h"
|
||||
|
||||
static void gf_mulx(u8 *pad)
|
||||
{
|
||||
int i, carry;
|
||||
|
||||
carry = pad[0] & 0x80;
|
||||
for (i = 0; i < AES_BLOCK_SIZE - 1; i++)
|
||||
pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
|
||||
pad[AES_BLOCK_SIZE - 1] <<= 1;
|
||||
if (carry)
|
||||
pad[AES_BLOCK_SIZE - 1] ^= 0x87;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* omac1_aes_vector - One-Key CBC MAC (OMAC1) hash with AES
|
||||
* @key: Key for the hash operation
|
||||
* @key_len: Key length in octets
|
||||
* @num_elem: Number of elements in the data vector
|
||||
* @addr: Pointers to the data areas
|
||||
* @len: Lengths of the data blocks
|
||||
* @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This is a mode for using block cipher (AES in this case) for authentication.
|
||||
* OMAC1 was standardized with the name CMAC by NIST in a Special Publication
|
||||
* (SP) 800-38B.
|
||||
*/
|
||||
int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
|
||||
const u8 *addr[], const size_t *len, u8 *mac)
|
||||
{
|
||||
void *ctx;
|
||||
u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
|
||||
const u8 *pos, *end;
|
||||
size_t i, e, left, total_len;
|
||||
|
||||
ctx = aes_encrypt_init(key, key_len);
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
os_memset(cbc, 0, AES_BLOCK_SIZE);
|
||||
|
||||
total_len = 0;
|
||||
for (e = 0; e < num_elem; e++)
|
||||
total_len += len[e];
|
||||
left = total_len;
|
||||
|
||||
e = 0;
|
||||
pos = addr[0];
|
||||
end = pos + len[0];
|
||||
|
||||
while (left >= AES_BLOCK_SIZE) {
|
||||
for (i = 0; i < AES_BLOCK_SIZE; i++) {
|
||||
cbc[i] ^= *pos++;
|
||||
if (pos >= end) {
|
||||
/*
|
||||
* Stop if there are no more bytes to process
|
||||
* since there are no more entries in the array.
|
||||
*/
|
||||
if (i + 1 == AES_BLOCK_SIZE &&
|
||||
left == AES_BLOCK_SIZE)
|
||||
break;
|
||||
e++;
|
||||
pos = addr[e];
|
||||
end = pos + len[e];
|
||||
}
|
||||
}
|
||||
if (left > AES_BLOCK_SIZE)
|
||||
aes_encrypt(ctx, cbc, cbc);
|
||||
left -= AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
os_memset(pad, 0, AES_BLOCK_SIZE);
|
||||
aes_encrypt(ctx, pad, pad);
|
||||
gf_mulx(pad);
|
||||
|
||||
if (left || total_len == 0) {
|
||||
for (i = 0; i < left; i++) {
|
||||
cbc[i] ^= *pos++;
|
||||
if (pos >= end) {
|
||||
/*
|
||||
* Stop if there are no more bytes to process
|
||||
* since there are no more entries in the array.
|
||||
*/
|
||||
if (i + 1 == left)
|
||||
break;
|
||||
e++;
|
||||
pos = addr[e];
|
||||
end = pos + len[e];
|
||||
}
|
||||
}
|
||||
cbc[left] ^= 0x80;
|
||||
gf_mulx(pad);
|
||||
}
|
||||
|
||||
for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||
pad[i] ^= cbc[i];
|
||||
aes_encrypt(ctx, pad, mac);
|
||||
aes_encrypt_deinit(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128
|
||||
* @key: 128-bit key for the hash operation
|
||||
* @num_elem: Number of elements in the data vector
|
||||
* @addr: Pointers to the data areas
|
||||
* @len: Lengths of the data blocks
|
||||
* @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This is a mode for using block cipher (AES in this case) for authentication.
|
||||
* OMAC1 was standardized with the name CMAC by NIST in a Special Publication
|
||||
* (SP) 800-38B.
|
||||
*/
|
||||
int omac1_aes_128_vector(const u8 *key, size_t num_elem,
|
||||
const u8 *addr[], const size_t *len, u8 *mac)
|
||||
{
|
||||
return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
|
||||
* @key: 128-bit key for the hash operation
|
||||
* @data: Data buffer for which a MAC is determined
|
||||
* @data_len: Length of data buffer in bytes
|
||||
* @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This is a mode for using block cipher (AES in this case) for authentication.
|
||||
* OMAC1 was standardized with the name CMAC by NIST in a Special Publication
|
||||
* (SP) 800-38B.
|
||||
*/
|
||||
int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
|
||||
{
|
||||
return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* omac1_aes_256 - One-Key CBC MAC (OMAC1) hash with AES-256 (aka AES-CMAC)
|
||||
* @key: 256-bit key for the hash operation
|
||||
* @data: Data buffer for which a MAC is determined
|
||||
* @data_len: Length of data buffer in bytes
|
||||
* @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This is a mode for using block cipher (AES in this case) for authentication.
|
||||
* OMAC1 was standardized with the name CMAC by NIST in a Special Publication
|
||||
* (SP) 800-38B.
|
||||
*/
|
||||
int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
|
||||
{
|
||||
return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
|
||||
}
|
82
freebsd/contrib/wpa/src/crypto/aes-unwrap.c
Normal file
82
freebsd/contrib/wpa/src/crypto/aes-unwrap.c
Normal file
@ -0,0 +1,82 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* AES key unwrap (RFC3394)
|
||||
*
|
||||
* Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "aes.h"
|
||||
#include "aes_wrap.h"
|
||||
|
||||
/**
|
||||
* aes_unwrap - Unwrap key with AES Key Wrap Algorithm (RFC3394)
|
||||
* @kek: Key encryption key (KEK)
|
||||
* @kek_len: Length of KEK in octets
|
||||
* @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
|
||||
* bytes
|
||||
* @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits
|
||||
* @plain: Plaintext key, n * 64 bits
|
||||
* Returns: 0 on success, -1 on failure (e.g., integrity verification failed)
|
||||
*/
|
||||
int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
|
||||
u8 *plain)
|
||||
{
|
||||
u8 a[8], *r, b[AES_BLOCK_SIZE];
|
||||
int i, j;
|
||||
void *ctx;
|
||||
unsigned int t;
|
||||
|
||||
/* 1) Initialize variables. */
|
||||
os_memcpy(a, cipher, 8);
|
||||
r = plain;
|
||||
os_memcpy(r, cipher + 8, 8 * n);
|
||||
|
||||
ctx = aes_decrypt_init(kek, kek_len);
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
|
||||
/* 2) Compute intermediate values.
|
||||
* For j = 5 to 0
|
||||
* For i = n to 1
|
||||
* B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
|
||||
* A = MSB(64, B)
|
||||
* R[i] = LSB(64, B)
|
||||
*/
|
||||
for (j = 5; j >= 0; j--) {
|
||||
r = plain + (n - 1) * 8;
|
||||
for (i = n; i >= 1; i--) {
|
||||
os_memcpy(b, a, 8);
|
||||
t = n * j + i;
|
||||
b[7] ^= t;
|
||||
b[6] ^= t >> 8;
|
||||
b[5] ^= t >> 16;
|
||||
b[4] ^= t >> 24;
|
||||
|
||||
os_memcpy(b + 8, r, 8);
|
||||
aes_decrypt(ctx, b, b);
|
||||
os_memcpy(a, b, 8);
|
||||
os_memcpy(r, b + 8, 8);
|
||||
r -= 8;
|
||||
}
|
||||
}
|
||||
aes_decrypt_deinit(ctx);
|
||||
|
||||
/* 3) Output results.
|
||||
*
|
||||
* These are already in @plain due to the location of temporary
|
||||
* variables. Just verify that the IV matches with the expected value.
|
||||
*/
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (a[i] != 0xa6)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
21
freebsd/contrib/wpa/src/crypto/aes.h
Normal file
21
freebsd/contrib/wpa/src/crypto/aes.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* AES functions
|
||||
* Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef AES_H
|
||||
#define AES_H
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
void * aes_encrypt_init(const u8 *key, size_t len);
|
||||
void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt);
|
||||
void aes_encrypt_deinit(void *ctx);
|
||||
void * aes_decrypt_init(const u8 *key, size_t len);
|
||||
void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain);
|
||||
void aes_decrypt_deinit(void *ctx);
|
||||
|
||||
#endif /* AES_H */
|
71
freebsd/contrib/wpa/src/crypto/aes_wrap.h
Normal file
71
freebsd/contrib/wpa/src/crypto/aes_wrap.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* AES-based functions
|
||||
*
|
||||
* - AES Key Wrap Algorithm (RFC3394)
|
||||
* - One-Key CBC MAC (OMAC1) hash with AES-128 and AES-256
|
||||
* - AES-128 CTR mode encryption
|
||||
* - AES-128 EAX mode encryption/decryption
|
||||
* - AES-128 CBC
|
||||
* - AES-GCM
|
||||
* - AES-CCM
|
||||
*
|
||||
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef AES_WRAP_H
|
||||
#define AES_WRAP_H
|
||||
|
||||
int __must_check aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain,
|
||||
u8 *cipher);
|
||||
int __must_check aes_unwrap(const u8 *kek, size_t kek_len, int n,
|
||||
const u8 *cipher, u8 *plain);
|
||||
int __must_check omac1_aes_vector(const u8 *key, size_t key_len,
|
||||
size_t num_elem, const u8 *addr[],
|
||||
const size_t *len, u8 *mac);
|
||||
int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem,
|
||||
const u8 *addr[], const size_t *len,
|
||||
u8 *mac);
|
||||
int __must_check omac1_aes_128(const u8 *key, const u8 *data, size_t data_len,
|
||||
u8 *mac);
|
||||
int __must_check omac1_aes_256(const u8 *key, const u8 *data, size_t data_len,
|
||||
u8 *mac);
|
||||
int __must_check aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out);
|
||||
int __must_check aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
|
||||
u8 *data, size_t data_len);
|
||||
int __must_check aes_128_eax_encrypt(const u8 *key,
|
||||
const u8 *nonce, size_t nonce_len,
|
||||
const u8 *hdr, size_t hdr_len,
|
||||
u8 *data, size_t data_len, u8 *tag);
|
||||
int __must_check aes_128_eax_decrypt(const u8 *key,
|
||||
const u8 *nonce, size_t nonce_len,
|
||||
const u8 *hdr, size_t hdr_len,
|
||||
u8 *data, size_t data_len, const u8 *tag);
|
||||
int __must_check aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data,
|
||||
size_t data_len);
|
||||
int __must_check aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data,
|
||||
size_t data_len);
|
||||
int __must_check aes_gcm_ae(const u8 *key, size_t key_len,
|
||||
const u8 *iv, size_t iv_len,
|
||||
const u8 *plain, size_t plain_len,
|
||||
const u8 *aad, size_t aad_len,
|
||||
u8 *crypt, u8 *tag);
|
||||
int __must_check aes_gcm_ad(const u8 *key, size_t key_len,
|
||||
const u8 *iv, size_t iv_len,
|
||||
const u8 *crypt, size_t crypt_len,
|
||||
const u8 *aad, size_t aad_len, const u8 *tag,
|
||||
u8 *plain);
|
||||
int __must_check aes_gmac(const u8 *key, size_t key_len,
|
||||
const u8 *iv, size_t iv_len,
|
||||
const u8 *aad, size_t aad_len, u8 *tag);
|
||||
int __must_check aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce,
|
||||
size_t M, const u8 *plain, size_t plain_len,
|
||||
const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth);
|
||||
int __must_check aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce,
|
||||
size_t M, const u8 *crypt, size_t crypt_len,
|
||||
const u8 *aad, size_t aad_len, const u8 *auth,
|
||||
u8 *plain);
|
||||
|
||||
#endif /* AES_WRAP_H */
|
809
freebsd/contrib/wpa/src/crypto/crypto.h
Normal file
809
freebsd/contrib/wpa/src/crypto/crypto.h
Normal file
@ -0,0 +1,809 @@
|
||||
/*
|
||||
* Wrapper functions for crypto libraries
|
||||
* Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*
|
||||
* This file defines the cryptographic functions that need to be implemented
|
||||
* for wpa_supplicant and hostapd. When TLS is not used, internal
|
||||
* implementation of MD5, SHA1, and AES is used and no external libraries are
|
||||
* required. When TLS is enabled (e.g., by enabling EAP-TLS or EAP-PEAP), the
|
||||
* crypto library used by the TLS implementation is expected to be used for
|
||||
* non-TLS needs, too, in order to save space by not implementing these
|
||||
* functions twice.
|
||||
*
|
||||
* Wrapper code for using each crypto library is in its own file (crypto*.c)
|
||||
* and one of these files is build and linked in to provide the functions
|
||||
* defined here.
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_H
|
||||
#define CRYPTO_H
|
||||
|
||||
/**
|
||||
* md4_vector - MD4 hash for data vector
|
||||
* @num_elem: Number of elements in the data vector
|
||||
* @addr: Pointers to the data areas
|
||||
* @len: Lengths of the data blocks
|
||||
* @mac: Buffer for the hash
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
|
||||
|
||||
/**
|
||||
* md5_vector - MD5 hash for data vector
|
||||
* @num_elem: Number of elements in the data vector
|
||||
* @addr: Pointers to the data areas
|
||||
* @len: Lengths of the data blocks
|
||||
* @mac: Buffer for the hash
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
|
||||
|
||||
|
||||
/**
|
||||
* sha1_vector - SHA-1 hash for data vector
|
||||
* @num_elem: Number of elements in the data vector
|
||||
* @addr: Pointers to the data areas
|
||||
* @len: Lengths of the data blocks
|
||||
* @mac: Buffer for the hash
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,
|
||||
u8 *mac);
|
||||
|
||||
/**
|
||||
* fips186_2-prf - NIST FIPS Publication 186-2 change notice 1 PRF
|
||||
* @seed: Seed/key for the PRF
|
||||
* @seed_len: Seed length in bytes
|
||||
* @x: Buffer for PRF output
|
||||
* @xlen: Output length in bytes
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function implements random number generation specified in NIST FIPS
|
||||
* Publication 186-2 for EAP-SIM. This PRF uses a function that is similar to
|
||||
* SHA-1, but has different message padding.
|
||||
*/
|
||||
int __must_check fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x,
|
||||
size_t xlen);
|
||||
|
||||
/**
|
||||
* sha256_vector - SHA256 hash for data vector
|
||||
* @num_elem: Number of elements in the data vector
|
||||
* @addr: Pointers to the data areas
|
||||
* @len: Lengths of the data blocks
|
||||
* @mac: Buffer for the hash
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
|
||||
u8 *mac);
|
||||
|
||||
/**
|
||||
* des_encrypt - Encrypt one block with DES
|
||||
* @clear: 8 octets (in)
|
||||
* @key: 7 octets (in) (no parity bits included)
|
||||
* @cypher: 8 octets (out)
|
||||
*/
|
||||
void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher);
|
||||
|
||||
/**
|
||||
* aes_encrypt_init - Initialize AES for encryption
|
||||
* @key: Encryption key
|
||||
* @len: Key length in bytes (usually 16, i.e., 128 bits)
|
||||
* Returns: Pointer to context data or %NULL on failure
|
||||
*/
|
||||
void * aes_encrypt_init(const u8 *key, size_t len);
|
||||
|
||||
/**
|
||||
* aes_encrypt - Encrypt one AES block
|
||||
* @ctx: Context pointer from aes_encrypt_init()
|
||||
* @plain: Plaintext data to be encrypted (16 bytes)
|
||||
* @crypt: Buffer for the encrypted data (16 bytes)
|
||||
*/
|
||||
void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt);
|
||||
|
||||
/**
|
||||
* aes_encrypt_deinit - Deinitialize AES encryption
|
||||
* @ctx: Context pointer from aes_encrypt_init()
|
||||
*/
|
||||
void aes_encrypt_deinit(void *ctx);
|
||||
|
||||
/**
|
||||
* aes_decrypt_init - Initialize AES for decryption
|
||||
* @key: Decryption key
|
||||
* @len: Key length in bytes (usually 16, i.e., 128 bits)
|
||||
* Returns: Pointer to context data or %NULL on failure
|
||||
*/
|
||||
void * aes_decrypt_init(const u8 *key, size_t len);
|
||||
|
||||
/**
|
||||
* aes_decrypt - Decrypt one AES block
|
||||
* @ctx: Context pointer from aes_encrypt_init()
|
||||
* @crypt: Encrypted data (16 bytes)
|
||||
* @plain: Buffer for the decrypted data (16 bytes)
|
||||
*/
|
||||
void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain);
|
||||
|
||||
/**
|
||||
* aes_decrypt_deinit - Deinitialize AES decryption
|
||||
* @ctx: Context pointer from aes_encrypt_init()
|
||||
*/
|
||||
void aes_decrypt_deinit(void *ctx);
|
||||
|
||||
|
||||
enum crypto_hash_alg {
|
||||
CRYPTO_HASH_ALG_MD5, CRYPTO_HASH_ALG_SHA1,
|
||||
CRYPTO_HASH_ALG_HMAC_MD5, CRYPTO_HASH_ALG_HMAC_SHA1,
|
||||
CRYPTO_HASH_ALG_SHA256, CRYPTO_HASH_ALG_HMAC_SHA256
|
||||
};
|
||||
|
||||
struct crypto_hash;
|
||||
|
||||
/**
|
||||
* crypto_hash_init - Initialize hash/HMAC function
|
||||
* @alg: Hash algorithm
|
||||
* @key: Key for keyed hash (e.g., HMAC) or %NULL if not needed
|
||||
* @key_len: Length of the key in bytes
|
||||
* Returns: Pointer to hash context to use with other hash functions or %NULL
|
||||
* on failure
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
|
||||
size_t key_len);
|
||||
|
||||
/**
|
||||
* crypto_hash_update - Add data to hash calculation
|
||||
* @ctx: Context pointer from crypto_hash_init()
|
||||
* @data: Data buffer to add
|
||||
* @len: Length of the buffer
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len);
|
||||
|
||||
/**
|
||||
* crypto_hash_finish - Complete hash calculation
|
||||
* @ctx: Context pointer from crypto_hash_init()
|
||||
* @hash: Buffer for hash value or %NULL if caller is just freeing the hash
|
||||
* context
|
||||
* @len: Pointer to length of the buffer or %NULL if caller is just freeing the
|
||||
* hash context; on return, this is set to the actual length of the hash value
|
||||
* Returns: 0 on success, -1 if buffer is too small (len set to needed length),
|
||||
* or -2 on other failures (including failed crypto_hash_update() operations)
|
||||
*
|
||||
* This function calculates the hash value and frees the context buffer that
|
||||
* was used for hash calculation.
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
int crypto_hash_finish(struct crypto_hash *ctx, u8 *hash, size_t *len);
|
||||
|
||||
|
||||
enum crypto_cipher_alg {
|
||||
CRYPTO_CIPHER_NULL = 0, CRYPTO_CIPHER_ALG_AES, CRYPTO_CIPHER_ALG_3DES,
|
||||
CRYPTO_CIPHER_ALG_DES, CRYPTO_CIPHER_ALG_RC2, CRYPTO_CIPHER_ALG_RC4
|
||||
};
|
||||
|
||||
struct crypto_cipher;
|
||||
|
||||
/**
|
||||
* crypto_cipher_init - Initialize block/stream cipher function
|
||||
* @alg: Cipher algorithm
|
||||
* @iv: Initialization vector for block ciphers or %NULL for stream ciphers
|
||||
* @key: Cipher key
|
||||
* @key_len: Length of key in bytes
|
||||
* Returns: Pointer to cipher context to use with other cipher functions or
|
||||
* %NULL on failure
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
|
||||
const u8 *iv, const u8 *key,
|
||||
size_t key_len);
|
||||
|
||||
/**
|
||||
* crypto_cipher_encrypt - Cipher encrypt
|
||||
* @ctx: Context pointer from crypto_cipher_init()
|
||||
* @plain: Plaintext to cipher
|
||||
* @crypt: Resulting ciphertext
|
||||
* @len: Length of the plaintext
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
int __must_check crypto_cipher_encrypt(struct crypto_cipher *ctx,
|
||||
const u8 *plain, u8 *crypt, size_t len);
|
||||
|
||||
/**
|
||||
* crypto_cipher_decrypt - Cipher decrypt
|
||||
* @ctx: Context pointer from crypto_cipher_init()
|
||||
* @crypt: Ciphertext to decrypt
|
||||
* @plain: Resulting plaintext
|
||||
* @len: Length of the cipher text
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
int __must_check crypto_cipher_decrypt(struct crypto_cipher *ctx,
|
||||
const u8 *crypt, u8 *plain, size_t len);
|
||||
|
||||
/**
|
||||
* crypto_cipher_decrypt - Free cipher context
|
||||
* @ctx: Context pointer from crypto_cipher_init()
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
void crypto_cipher_deinit(struct crypto_cipher *ctx);
|
||||
|
||||
|
||||
struct crypto_public_key;
|
||||
struct crypto_private_key;
|
||||
|
||||
/**
|
||||
* crypto_public_key_import - Import an RSA public key
|
||||
* @key: Key buffer (DER encoded RSA public key)
|
||||
* @len: Key buffer length in bytes
|
||||
* Returns: Pointer to the public key or %NULL on failure
|
||||
*
|
||||
* This function can just return %NULL if the crypto library supports X.509
|
||||
* parsing. In that case, crypto_public_key_from_cert() is used to import the
|
||||
* public key from a certificate.
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len);
|
||||
|
||||
struct crypto_public_key *
|
||||
crypto_public_key_import_parts(const u8 *n, size_t n_len,
|
||||
const u8 *e, size_t e_len);
|
||||
|
||||
/**
|
||||
* crypto_private_key_import - Import an RSA private key
|
||||
* @key: Key buffer (DER encoded RSA private key)
|
||||
* @len: Key buffer length in bytes
|
||||
* @passwd: Key encryption password or %NULL if key is not encrypted
|
||||
* Returns: Pointer to the private key or %NULL on failure
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
struct crypto_private_key * crypto_private_key_import(const u8 *key,
|
||||
size_t len,
|
||||
const char *passwd);
|
||||
|
||||
/**
|
||||
* crypto_public_key_from_cert - Import an RSA public key from a certificate
|
||||
* @buf: DER encoded X.509 certificate
|
||||
* @len: Certificate buffer length in bytes
|
||||
* Returns: Pointer to public key or %NULL on failure
|
||||
*
|
||||
* This function can just return %NULL if the crypto library does not support
|
||||
* X.509 parsing. In that case, internal code will be used to parse the
|
||||
* certificate and public key is imported using crypto_public_key_import().
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* crypto_public_key_encrypt_pkcs1_v15 - Public key encryption (PKCS #1 v1.5)
|
||||
* @key: Public key
|
||||
* @in: Plaintext buffer
|
||||
* @inlen: Length of plaintext buffer in bytes
|
||||
* @out: Output buffer for encrypted data
|
||||
* @outlen: Length of output buffer in bytes; set to used length on success
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
int __must_check crypto_public_key_encrypt_pkcs1_v15(
|
||||
struct crypto_public_key *key, const u8 *in, size_t inlen,
|
||||
u8 *out, size_t *outlen);
|
||||
|
||||
/**
|
||||
* crypto_private_key_decrypt_pkcs1_v15 - Private key decryption (PKCS #1 v1.5)
|
||||
* @key: Private key
|
||||
* @in: Encrypted buffer
|
||||
* @inlen: Length of encrypted buffer in bytes
|
||||
* @out: Output buffer for encrypted data
|
||||
* @outlen: Length of output buffer in bytes; set to used length on success
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
int __must_check crypto_private_key_decrypt_pkcs1_v15(
|
||||
struct crypto_private_key *key, const u8 *in, size_t inlen,
|
||||
u8 *out, size_t *outlen);
|
||||
|
||||
/**
|
||||
* crypto_private_key_sign_pkcs1 - Sign with private key (PKCS #1)
|
||||
* @key: Private key from crypto_private_key_import()
|
||||
* @in: Plaintext buffer
|
||||
* @inlen: Length of plaintext buffer in bytes
|
||||
* @out: Output buffer for encrypted (signed) data
|
||||
* @outlen: Length of output buffer in bytes; set to used length on success
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
int __must_check crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
|
||||
const u8 *in, size_t inlen,
|
||||
u8 *out, size_t *outlen);
|
||||
|
||||
/**
|
||||
* crypto_public_key_free - Free public key
|
||||
* @key: Public key
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
void crypto_public_key_free(struct crypto_public_key *key);
|
||||
|
||||
/**
|
||||
* crypto_private_key_free - Free private key
|
||||
* @key: Private key from crypto_private_key_import()
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
void crypto_private_key_free(struct crypto_private_key *key);
|
||||
|
||||
/**
|
||||
* crypto_public_key_decrypt_pkcs1 - Decrypt PKCS #1 signature
|
||||
* @key: Public key
|
||||
* @crypt: Encrypted signature data (using the private key)
|
||||
* @crypt_len: Encrypted signature data length
|
||||
* @plain: Buffer for plaintext (at least crypt_len bytes)
|
||||
* @plain_len: Plaintext length (max buffer size on input, real len on output);
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int __must_check crypto_public_key_decrypt_pkcs1(
|
||||
struct crypto_public_key *key, const u8 *crypt, size_t crypt_len,
|
||||
u8 *plain, size_t *plain_len);
|
||||
|
||||
/**
|
||||
* crypto_global_init - Initialize crypto wrapper
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
int __must_check crypto_global_init(void);
|
||||
|
||||
/**
|
||||
* crypto_global_deinit - Deinitialize crypto wrapper
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
void crypto_global_deinit(void);
|
||||
|
||||
/**
|
||||
* crypto_mod_exp - Modular exponentiation of large integers
|
||||
* @base: Base integer (big endian byte array)
|
||||
* @base_len: Length of base integer in bytes
|
||||
* @power: Power integer (big endian byte array)
|
||||
* @power_len: Length of power integer in bytes
|
||||
* @modulus: Modulus integer (big endian byte array)
|
||||
* @modulus_len: Length of modulus integer in bytes
|
||||
* @result: Buffer for the result
|
||||
* @result_len: Result length (max buffer size on input, real len on output)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function calculates result = base ^ power mod modulus. modules_len is
|
||||
* used as the maximum size of modulus buffer. It is set to the used size on
|
||||
* success.
|
||||
*
|
||||
* This function is only used with internal TLSv1 implementation
|
||||
* (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
|
||||
* to implement this.
|
||||
*/
|
||||
int __must_check crypto_mod_exp(const u8 *base, size_t base_len,
|
||||
const u8 *power, size_t power_len,
|
||||
const u8 *modulus, size_t modulus_len,
|
||||
u8 *result, size_t *result_len);
|
||||
|
||||
/**
|
||||
* rc4_skip - XOR RC4 stream to given data with skip-stream-start
|
||||
* @key: RC4 key
|
||||
* @keylen: RC4 key length
|
||||
* @skip: number of bytes to skip from the beginning of the RC4 stream
|
||||
* @data: data to be XOR'ed with RC4 stream
|
||||
* @data_len: buf length
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Generate RC4 pseudo random stream for the given key, skip beginning of the
|
||||
* stream, and XOR the end result with the data buffer to perform RC4
|
||||
* encryption/decryption.
|
||||
*/
|
||||
int rc4_skip(const u8 *key, size_t keylen, size_t skip,
|
||||
u8 *data, size_t data_len);
|
||||
|
||||
/**
|
||||
* crypto_get_random - Generate cryptographically strong pseudy-random bytes
|
||||
* @buf: Buffer for data
|
||||
* @len: Number of bytes to generate
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* If the PRNG does not have enough entropy to ensure unpredictable byte
|
||||
* sequence, this functions must return -1.
|
||||
*/
|
||||
int crypto_get_random(void *buf, size_t len);
|
||||
|
||||
|
||||
/**
|
||||
* struct crypto_bignum - bignum
|
||||
*
|
||||
* Internal data structure for bignum implementation. The contents is specific
|
||||
* to the used crypto library.
|
||||
*/
|
||||
struct crypto_bignum;
|
||||
|
||||
/**
|
||||
* crypto_bignum_init - Allocate memory for bignum
|
||||
* Returns: Pointer to allocated bignum or %NULL on failure
|
||||
*/
|
||||
struct crypto_bignum * crypto_bignum_init(void);
|
||||
|
||||
/**
|
||||
* crypto_bignum_init_set - Allocate memory for bignum and set the value
|
||||
* @buf: Buffer with unsigned binary value
|
||||
* @len: Length of buf in octets
|
||||
* Returns: Pointer to allocated bignum or %NULL on failure
|
||||
*/
|
||||
struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len);
|
||||
|
||||
/**
|
||||
* crypto_bignum_deinit - Free bignum
|
||||
* @n: Bignum from crypto_bignum_init() or crypto_bignum_init_set()
|
||||
* @clear: Whether to clear the value from memory
|
||||
*/
|
||||
void crypto_bignum_deinit(struct crypto_bignum *n, int clear);
|
||||
|
||||
/**
|
||||
* crypto_bignum_to_bin - Set binary buffer to unsigned bignum
|
||||
* @a: Bignum
|
||||
* @buf: Buffer for the binary number
|
||||
* @len: Length of @buf in octets
|
||||
* @padlen: Length in octets to pad the result to or 0 to indicate no padding
|
||||
* Returns: Number of octets written on success, -1 on failure
|
||||
*/
|
||||
int crypto_bignum_to_bin(const struct crypto_bignum *a,
|
||||
u8 *buf, size_t buflen, size_t padlen);
|
||||
|
||||
/**
|
||||
* crypto_bignum_add - c = a + b
|
||||
* @a: Bignum
|
||||
* @b: Bignum
|
||||
* @c: Bignum; used to store the result of a + b
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_bignum_add(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *b,
|
||||
struct crypto_bignum *c);
|
||||
|
||||
/**
|
||||
* crypto_bignum_mod - c = a % b
|
||||
* @a: Bignum
|
||||
* @b: Bignum
|
||||
* @c: Bignum; used to store the result of a % b
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_bignum_mod(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *b,
|
||||
struct crypto_bignum *c);
|
||||
|
||||
/**
|
||||
* crypto_bignum_exptmod - Modular exponentiation: d = a^b (mod c)
|
||||
* @a: Bignum; base
|
||||
* @b: Bignum; exponent
|
||||
* @c: Bignum; modulus
|
||||
* @d: Bignum; used to store the result of a^b (mod c)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_bignum_exptmod(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *b,
|
||||
const struct crypto_bignum *c,
|
||||
struct crypto_bignum *d);
|
||||
|
||||
/**
|
||||
* crypto_bignum_inverse - Inverse a bignum so that a * c = 1 (mod b)
|
||||
* @a: Bignum
|
||||
* @b: Bignum
|
||||
* @c: Bignum; used to store the result
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_bignum_inverse(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *b,
|
||||
struct crypto_bignum *c);
|
||||
|
||||
/**
|
||||
* crypto_bignum_sub - c = a - b
|
||||
* @a: Bignum
|
||||
* @b: Bignum
|
||||
* @c: Bignum; used to store the result of a - b
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_bignum_sub(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *b,
|
||||
struct crypto_bignum *c);
|
||||
|
||||
/**
|
||||
* crypto_bignum_div - c = a / b
|
||||
* @a: Bignum
|
||||
* @b: Bignum
|
||||
* @c: Bignum; used to store the result of a / b
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_bignum_div(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *b,
|
||||
struct crypto_bignum *c);
|
||||
|
||||
/**
|
||||
* crypto_bignum_mulmod - d = a * b (mod c)
|
||||
* @a: Bignum
|
||||
* @b: Bignum
|
||||
* @c: Bignum
|
||||
* @d: Bignum; used to store the result of (a * b) % c
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_bignum_mulmod(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *b,
|
||||
const struct crypto_bignum *c,
|
||||
struct crypto_bignum *d);
|
||||
|
||||
/**
|
||||
* crypto_bignum_cmp - Compare two bignums
|
||||
* @a: Bignum
|
||||
* @b: Bignum
|
||||
* Returns: -1 if a < b, 0 if a == b, or 1 if a > b
|
||||
*/
|
||||
int crypto_bignum_cmp(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *b);
|
||||
|
||||
/**
|
||||
* crypto_bignum_bits - Get size of a bignum in bits
|
||||
* @a: Bignum
|
||||
* Returns: Number of bits in the bignum
|
||||
*/
|
||||
int crypto_bignum_bits(const struct crypto_bignum *a);
|
||||
|
||||
/**
|
||||
* crypto_bignum_is_zero - Is the given bignum zero
|
||||
* @a: Bignum
|
||||
* Returns: 1 if @a is zero or 0 if not
|
||||
*/
|
||||
int crypto_bignum_is_zero(const struct crypto_bignum *a);
|
||||
|
||||
/**
|
||||
* crypto_bignum_is_one - Is the given bignum one
|
||||
* @a: Bignum
|
||||
* Returns: 1 if @a is one or 0 if not
|
||||
*/
|
||||
int crypto_bignum_is_one(const struct crypto_bignum *a);
|
||||
|
||||
/**
|
||||
* crypto_bignum_legendre - Compute the Legendre symbol (a/p)
|
||||
* @a: Bignum
|
||||
* @p: Bignum
|
||||
* Returns: Legendre symbol -1,0,1 on success; -2 on calculation failure
|
||||
*/
|
||||
int crypto_bignum_legendre(const struct crypto_bignum *a,
|
||||
const struct crypto_bignum *p);
|
||||
|
||||
/**
|
||||
* struct crypto_ec - Elliptic curve context
|
||||
*
|
||||
* Internal data structure for EC implementation. The contents is specific
|
||||
* to the used crypto library.
|
||||
*/
|
||||
struct crypto_ec;
|
||||
|
||||
/**
|
||||
* crypto_ec_init - Initialize elliptic curve context
|
||||
* @group: Identifying number for the ECC group (IANA "Group Description"
|
||||
* attribute registrty for RFC 2409)
|
||||
* Returns: Pointer to EC context or %NULL on failure
|
||||
*/
|
||||
struct crypto_ec * crypto_ec_init(int group);
|
||||
|
||||
/**
|
||||
* crypto_ec_deinit - Deinitialize elliptic curve context
|
||||
* @e: EC context from crypto_ec_init()
|
||||
*/
|
||||
void crypto_ec_deinit(struct crypto_ec *e);
|
||||
|
||||
/**
|
||||
* crypto_ec_prime_len - Get length of the prime in octets
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* Returns: Length of the prime defining the group
|
||||
*/
|
||||
size_t crypto_ec_prime_len(struct crypto_ec *e);
|
||||
|
||||
/**
|
||||
* crypto_ec_prime_len_bits - Get length of the prime in bits
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* Returns: Length of the prime defining the group in bits
|
||||
*/
|
||||
size_t crypto_ec_prime_len_bits(struct crypto_ec *e);
|
||||
|
||||
/**
|
||||
* crypto_ec_get_prime - Get prime defining an EC group
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* Returns: Prime (bignum) defining the group
|
||||
*/
|
||||
const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e);
|
||||
|
||||
/**
|
||||
* crypto_ec_get_order - Get order of an EC group
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* Returns: Order (bignum) of the group
|
||||
*/
|
||||
const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e);
|
||||
|
||||
/**
|
||||
* struct crypto_ec_point - Elliptic curve point
|
||||
*
|
||||
* Internal data structure for EC implementation to represent a point. The
|
||||
* contents is specific to the used crypto library.
|
||||
*/
|
||||
struct crypto_ec_point;
|
||||
|
||||
/**
|
||||
* crypto_ec_point_init - Initialize data for an EC point
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* Returns: Pointer to EC point data or %NULL on failure
|
||||
*/
|
||||
struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e);
|
||||
|
||||
/**
|
||||
* crypto_ec_point_deinit - Deinitialize EC point data
|
||||
* @p: EC point data from crypto_ec_point_init()
|
||||
* @clear: Whether to clear the EC point value from memory
|
||||
*/
|
||||
void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear);
|
||||
|
||||
/**
|
||||
* crypto_ec_point_to_bin - Write EC point value as binary data
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* @p: EC point data from crypto_ec_point_init()
|
||||
* @x: Buffer for writing the binary data for x coordinate or %NULL if not used
|
||||
* @y: Buffer for writing the binary data for y coordinate or %NULL if not used
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function can be used to write an EC point as binary data in a format
|
||||
* that has the x and y coordinates in big endian byte order fields padded to
|
||||
* the length of the prime defining the group.
|
||||
*/
|
||||
int crypto_ec_point_to_bin(struct crypto_ec *e,
|
||||
const struct crypto_ec_point *point, u8 *x, u8 *y);
|
||||
|
||||
/**
|
||||
* crypto_ec_point_from_bin - Create EC point from binary data
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* @val: Binary data to read the EC point from
|
||||
* Returns: Pointer to EC point data or %NULL on failure
|
||||
*
|
||||
* This function readers x and y coordinates of the EC point from the provided
|
||||
* buffer assuming the values are in big endian byte order with fields padded to
|
||||
* the length of the prime defining the group.
|
||||
*/
|
||||
struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
|
||||
const u8 *val);
|
||||
|
||||
/**
|
||||
* crypto_bignum_add - c = a + b
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* @a: Bignum
|
||||
* @b: Bignum
|
||||
* @c: Bignum; used to store the result of a + b
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
|
||||
const struct crypto_ec_point *b,
|
||||
struct crypto_ec_point *c);
|
||||
|
||||
/**
|
||||
* crypto_bignum_mul - res = b * p
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* @p: EC point
|
||||
* @b: Bignum
|
||||
* @res: EC point; used to store the result of b * p
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
|
||||
const struct crypto_bignum *b,
|
||||
struct crypto_ec_point *res);
|
||||
|
||||
/**
|
||||
* crypto_ec_point_invert - Compute inverse of an EC point
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* @p: EC point to invert (and result of the operation)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p);
|
||||
|
||||
/**
|
||||
* crypto_ec_point_solve_y_coord - Solve y coordinate for an x coordinate
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* @p: EC point to use for the returning the result
|
||||
* @x: x coordinate
|
||||
* @y_bit: y-bit (0 or 1) for selecting the y value to use
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
|
||||
struct crypto_ec_point *p,
|
||||
const struct crypto_bignum *x, int y_bit);
|
||||
|
||||
/**
|
||||
* crypto_ec_point_compute_y_sqr - Compute y^2 = x^3 + ax + b
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* @x: x coordinate
|
||||
* Returns: y^2 on success, %NULL failure
|
||||
*/
|
||||
struct crypto_bignum *
|
||||
crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
|
||||
const struct crypto_bignum *x);
|
||||
|
||||
/**
|
||||
* crypto_ec_point_is_at_infinity - Check whether EC point is neutral element
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* @p: EC point
|
||||
* Returns: 1 if the specified EC point is the neutral element of the group or
|
||||
* 0 if not
|
||||
*/
|
||||
int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
|
||||
const struct crypto_ec_point *p);
|
||||
|
||||
/**
|
||||
* crypto_ec_point_is_on_curve - Check whether EC point is on curve
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* @p: EC point
|
||||
* Returns: 1 if the specified EC point is on the curve or 0 if not
|
||||
*/
|
||||
int crypto_ec_point_is_on_curve(struct crypto_ec *e,
|
||||
const struct crypto_ec_point *p);
|
||||
|
||||
/**
|
||||
* crypto_ec_point_cmp - Compare two EC points
|
||||
* @e: EC context from crypto_ec_init()
|
||||
* @a: EC point
|
||||
* @b: EC point
|
||||
* Returns: 0 on equal, non-zero otherwise
|
||||
*/
|
||||
int crypto_ec_point_cmp(const struct crypto_ec *e,
|
||||
const struct crypto_ec_point *a,
|
||||
const struct crypto_ec_point *b);
|
||||
|
||||
#endif /* CRYPTO_H */
|
1444
freebsd/contrib/wpa/src/crypto/crypto_openssl.c
Normal file
1444
freebsd/contrib/wpa/src/crypto/crypto_openssl.c
Normal file
File diff suppressed because it is too large
Load Diff
18
freebsd/contrib/wpa/src/crypto/dh_group5.h
Normal file
18
freebsd/contrib/wpa/src/crypto/dh_group5.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Diffie-Hellman group 5 operations
|
||||
* Copyright (c) 2009, 2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef DH_GROUP5_H
|
||||
#define DH_GROUP5_H
|
||||
|
||||
void * dh5_init(struct wpabuf **priv, struct wpabuf **publ);
|
||||
void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ);
|
||||
struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
|
||||
const struct wpabuf *own_private);
|
||||
void dh5_free(void *ctx);
|
||||
|
||||
#endif /* DH_GROUP5_H */
|
19
freebsd/contrib/wpa/src/crypto/md5.h
Normal file
19
freebsd/contrib/wpa/src/crypto/md5.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* MD5 hash implementation and interface functions
|
||||
* Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
#define MD5_MAC_LEN 16
|
||||
|
||||
int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
|
||||
const u8 *addr[], const size_t *len, u8 *mac);
|
||||
int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
|
||||
u8 *mac);
|
||||
|
||||
#endif /* MD5_H */
|
526
freebsd/contrib/wpa/src/crypto/ms_funcs.c
Normal file
526
freebsd/contrib/wpa/src/crypto/ms_funcs.c
Normal file
@ -0,0 +1,526 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* WPA Supplicant / shared MSCHAPV2 helper functions / RFC 2433 / RFC 2759
|
||||
* Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "sha1.h"
|
||||
#include "ms_funcs.h"
|
||||
#include "crypto.h"
|
||||
|
||||
/**
|
||||
* utf8_to_ucs2 - Convert UTF-8 string to UCS-2 encoding
|
||||
* @utf8_string: UTF-8 string (IN)
|
||||
* @utf8_string_len: Length of utf8_string (IN)
|
||||
* @ucs2_buffer: UCS-2 buffer (OUT)
|
||||
* @ucs2_buffer_size: Length of UCS-2 buffer (IN)
|
||||
* @ucs2_string_size: Number of 2-byte words in the resulting UCS-2 string
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
static int utf8_to_ucs2(const u8 *utf8_string, size_t utf8_string_len,
|
||||
u8 *ucs2_buffer, size_t ucs2_buffer_size,
|
||||
size_t *ucs2_string_size)
|
||||
{
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0, j = 0; i < utf8_string_len; i++) {
|
||||
u8 c = utf8_string[i];
|
||||
if (j >= ucs2_buffer_size) {
|
||||
/* input too long */
|
||||
return -1;
|
||||
}
|
||||
if (c <= 0x7F) {
|
||||
WPA_PUT_LE16(ucs2_buffer + j, c);
|
||||
j += 2;
|
||||
} else if (i == utf8_string_len - 1 ||
|
||||
j >= ucs2_buffer_size - 1) {
|
||||
/* incomplete surrogate */
|
||||
return -1;
|
||||
} else {
|
||||
u8 c2 = utf8_string[++i];
|
||||
if ((c & 0xE0) == 0xC0) {
|
||||
/* two-byte encoding */
|
||||
WPA_PUT_LE16(ucs2_buffer + j,
|
||||
((c & 0x1F) << 6) | (c2 & 0x3F));
|
||||
j += 2;
|
||||
} else if (i == utf8_string_len ||
|
||||
j >= ucs2_buffer_size - 1) {
|
||||
/* incomplete surrogate */
|
||||
return -1;
|
||||
} else {
|
||||
/* three-byte encoding */
|
||||
u8 c3 = utf8_string[++i];
|
||||
WPA_PUT_LE16(ucs2_buffer + j,
|
||||
((c & 0xF) << 12) |
|
||||
((c2 & 0x3F) << 6) | (c3 & 0x3F));
|
||||
j += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ucs2_string_size)
|
||||
*ucs2_string_size = j / 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* challenge_hash - ChallengeHash() - RFC 2759, Sect. 8.2
|
||||
* @peer_challenge: 16-octet PeerChallenge (IN)
|
||||
* @auth_challenge: 16-octet AuthenticatorChallenge (IN)
|
||||
* @username: 0-to-256-char UserName (IN)
|
||||
* @username_len: Length of username
|
||||
* @challenge: 8-octet Challenge (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge,
|
||||
const u8 *username, size_t username_len, u8 *challenge)
|
||||
{
|
||||
u8 hash[SHA1_MAC_LEN];
|
||||
const unsigned char *addr[3];
|
||||
size_t len[3];
|
||||
|
||||
addr[0] = peer_challenge;
|
||||
len[0] = 16;
|
||||
addr[1] = auth_challenge;
|
||||
len[1] = 16;
|
||||
addr[2] = username;
|
||||
len[2] = username_len;
|
||||
|
||||
if (sha1_vector(3, addr, len, hash))
|
||||
return -1;
|
||||
os_memcpy(challenge, hash, 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nt_password_hash - NtPasswordHash() - RFC 2759, Sect. 8.3
|
||||
* @password: 0-to-256-unicode-char Password (IN; UTF-8)
|
||||
* @password_len: Length of password
|
||||
* @password_hash: 16-octet PasswordHash (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int nt_password_hash(const u8 *password, size_t password_len,
|
||||
u8 *password_hash)
|
||||
{
|
||||
u8 buf[512], *pos;
|
||||
size_t len, max_len;
|
||||
|
||||
max_len = sizeof(buf);
|
||||
if (utf8_to_ucs2(password, password_len, buf, max_len, &len) < 0)
|
||||
return -1;
|
||||
|
||||
len *= 2;
|
||||
pos = buf;
|
||||
return md4_vector(1, (const u8 **) &pos, &len, password_hash);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hash_nt_password_hash - HashNtPasswordHash() - RFC 2759, Sect. 8.4
|
||||
* @password_hash: 16-octet PasswordHash (IN)
|
||||
* @password_hash_hash: 16-octet PasswordHashHash (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int hash_nt_password_hash(const u8 *password_hash, u8 *password_hash_hash)
|
||||
{
|
||||
size_t len = 16;
|
||||
return md4_vector(1, &password_hash, &len, password_hash_hash);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* challenge_response - ChallengeResponse() - RFC 2759, Sect. 8.5
|
||||
* @challenge: 8-octet Challenge (IN)
|
||||
* @password_hash: 16-octet PasswordHash (IN)
|
||||
* @response: 24-octet Response (OUT)
|
||||
*/
|
||||
void challenge_response(const u8 *challenge, const u8 *password_hash,
|
||||
u8 *response)
|
||||
{
|
||||
u8 zpwd[7];
|
||||
des_encrypt(challenge, password_hash, response);
|
||||
des_encrypt(challenge, password_hash + 7, response + 8);
|
||||
zpwd[0] = password_hash[14];
|
||||
zpwd[1] = password_hash[15];
|
||||
os_memset(zpwd + 2, 0, 5);
|
||||
des_encrypt(challenge, zpwd, response + 16);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generate_nt_response - GenerateNTResponse() - RFC 2759, Sect. 8.1
|
||||
* @auth_challenge: 16-octet AuthenticatorChallenge (IN)
|
||||
* @peer_challenge: 16-octet PeerChallenge (IN)
|
||||
* @username: 0-to-256-char UserName (IN)
|
||||
* @username_len: Length of username
|
||||
* @password: 0-to-256-unicode-char Password (IN; UTF-8)
|
||||
* @password_len: Length of password
|
||||
* @response: 24-octet Response (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *password, size_t password_len,
|
||||
u8 *response)
|
||||
{
|
||||
u8 challenge[8];
|
||||
u8 password_hash[16];
|
||||
|
||||
if (challenge_hash(peer_challenge, auth_challenge, username,
|
||||
username_len, challenge) ||
|
||||
nt_password_hash(password, password_len, password_hash))
|
||||
return -1;
|
||||
challenge_response(challenge, password_hash, response);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generate_nt_response_pwhash - GenerateNTResponse() - RFC 2759, Sect. 8.1
|
||||
* @auth_challenge: 16-octet AuthenticatorChallenge (IN)
|
||||
* @peer_challenge: 16-octet PeerChallenge (IN)
|
||||
* @username: 0-to-256-char UserName (IN)
|
||||
* @username_len: Length of username
|
||||
* @password_hash: 16-octet PasswordHash (IN)
|
||||
* @response: 24-octet Response (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int generate_nt_response_pwhash(const u8 *auth_challenge,
|
||||
const u8 *peer_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *password_hash,
|
||||
u8 *response)
|
||||
{
|
||||
u8 challenge[8];
|
||||
|
||||
if (challenge_hash(peer_challenge, auth_challenge,
|
||||
username, username_len,
|
||||
challenge))
|
||||
return -1;
|
||||
challenge_response(challenge, password_hash, response);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generate_authenticator_response_pwhash - GenerateAuthenticatorResponse() - RFC 2759, Sect. 8.7
|
||||
* @password_hash: 16-octet PasswordHash (IN)
|
||||
* @nt_response: 24-octet NT-Response (IN)
|
||||
* @peer_challenge: 16-octet PeerChallenge (IN)
|
||||
* @auth_challenge: 16-octet AuthenticatorChallenge (IN)
|
||||
* @username: 0-to-256-char UserName (IN)
|
||||
* @username_len: Length of username
|
||||
* @response: 20-octet AuthenticatorResponse (OUT) (note: this value is usually
|
||||
* encoded as a 42-octet ASCII string (S=hexdump_of_response)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int generate_authenticator_response_pwhash(
|
||||
const u8 *password_hash,
|
||||
const u8 *peer_challenge, const u8 *auth_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *nt_response, u8 *response)
|
||||
{
|
||||
static const u8 magic1[39] = {
|
||||
0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
|
||||
0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
|
||||
0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
|
||||
0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74
|
||||
};
|
||||
static const u8 magic2[41] = {
|
||||
0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
|
||||
0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
|
||||
0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
|
||||
0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
|
||||
0x6E
|
||||
};
|
||||
|
||||
u8 password_hash_hash[16], challenge[8];
|
||||
const unsigned char *addr1[3];
|
||||
const size_t len1[3] = { 16, 24, sizeof(magic1) };
|
||||
const unsigned char *addr2[3];
|
||||
const size_t len2[3] = { SHA1_MAC_LEN, 8, sizeof(magic2) };
|
||||
|
||||
addr1[0] = password_hash_hash;
|
||||
addr1[1] = nt_response;
|
||||
addr1[2] = magic1;
|
||||
|
||||
addr2[0] = response;
|
||||
addr2[1] = challenge;
|
||||
addr2[2] = magic2;
|
||||
|
||||
if (hash_nt_password_hash(password_hash, password_hash_hash) ||
|
||||
sha1_vector(3, addr1, len1, response) ||
|
||||
challenge_hash(peer_challenge, auth_challenge, username,
|
||||
username_len, challenge))
|
||||
return -1;
|
||||
return sha1_vector(3, addr2, len2, response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generate_authenticator_response - GenerateAuthenticatorResponse() - RFC 2759, Sect. 8.7
|
||||
* @password: 0-to-256-unicode-char Password (IN; UTF-8)
|
||||
* @password_len: Length of password
|
||||
* @nt_response: 24-octet NT-Response (IN)
|
||||
* @peer_challenge: 16-octet PeerChallenge (IN)
|
||||
* @auth_challenge: 16-octet AuthenticatorChallenge (IN)
|
||||
* @username: 0-to-256-char UserName (IN)
|
||||
* @username_len: Length of username
|
||||
* @response: 20-octet AuthenticatorResponse (OUT) (note: this value is usually
|
||||
* encoded as a 42-octet ASCII string (S=hexdump_of_response)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int generate_authenticator_response(const u8 *password, size_t password_len,
|
||||
const u8 *peer_challenge,
|
||||
const u8 *auth_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *nt_response, u8 *response)
|
||||
{
|
||||
u8 password_hash[16];
|
||||
if (nt_password_hash(password, password_len, password_hash))
|
||||
return -1;
|
||||
return generate_authenticator_response_pwhash(
|
||||
password_hash, peer_challenge, auth_challenge,
|
||||
username, username_len, nt_response, response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nt_challenge_response - NtChallengeResponse() - RFC 2433, Sect. A.5
|
||||
* @challenge: 8-octet Challenge (IN)
|
||||
* @password: 0-to-256-unicode-char Password (IN; UTF-8)
|
||||
* @password_len: Length of password
|
||||
* @response: 24-octet Response (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int nt_challenge_response(const u8 *challenge, const u8 *password,
|
||||
size_t password_len, u8 *response)
|
||||
{
|
||||
u8 password_hash[16];
|
||||
if (nt_password_hash(password, password_len, password_hash))
|
||||
return -1;
|
||||
challenge_response(challenge, password_hash, response);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get_master_key - GetMasterKey() - RFC 3079, Sect. 3.4
|
||||
* @password_hash_hash: 16-octet PasswordHashHash (IN)
|
||||
* @nt_response: 24-octet NTResponse (IN)
|
||||
* @master_key: 16-octet MasterKey (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int get_master_key(const u8 *password_hash_hash, const u8 *nt_response,
|
||||
u8 *master_key)
|
||||
{
|
||||
static const u8 magic1[27] = {
|
||||
0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
|
||||
0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79
|
||||
};
|
||||
const unsigned char *addr[3];
|
||||
const size_t len[3] = { 16, 24, sizeof(magic1) };
|
||||
u8 hash[SHA1_MAC_LEN];
|
||||
|
||||
addr[0] = password_hash_hash;
|
||||
addr[1] = nt_response;
|
||||
addr[2] = magic1;
|
||||
|
||||
if (sha1_vector(3, addr, len, hash))
|
||||
return -1;
|
||||
os_memcpy(master_key, hash, 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get_asymetric_start_key - GetAsymetricStartKey() - RFC 3079, Sect. 3.4
|
||||
* @master_key: 16-octet MasterKey (IN)
|
||||
* @session_key: 8-to-16 octet SessionKey (OUT)
|
||||
* @session_key_len: SessionKeyLength (Length of session_key) (IN)
|
||||
* @is_send: IsSend (IN, BOOLEAN)
|
||||
* @is_server: IsServer (IN, BOOLEAN)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int get_asymetric_start_key(const u8 *master_key, u8 *session_key,
|
||||
size_t session_key_len, int is_send,
|
||||
int is_server)
|
||||
{
|
||||
static const u8 magic2[84] = {
|
||||
0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
|
||||
0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
|
||||
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
|
||||
0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
|
||||
0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
|
||||
0x6b, 0x65, 0x79, 0x2e
|
||||
};
|
||||
static const u8 magic3[84] = {
|
||||
0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
|
||||
0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
|
||||
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
|
||||
0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
|
||||
0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
|
||||
0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
|
||||
0x6b, 0x65, 0x79, 0x2e
|
||||
};
|
||||
static const u8 shs_pad1[40] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const u8 shs_pad2[40] = {
|
||||
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
|
||||
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
|
||||
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
|
||||
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2
|
||||
};
|
||||
u8 digest[SHA1_MAC_LEN];
|
||||
const unsigned char *addr[4];
|
||||
const size_t len[4] = { 16, 40, 84, 40 };
|
||||
|
||||
addr[0] = master_key;
|
||||
addr[1] = shs_pad1;
|
||||
if (is_send) {
|
||||
addr[2] = is_server ? magic3 : magic2;
|
||||
} else {
|
||||
addr[2] = is_server ? magic2 : magic3;
|
||||
}
|
||||
addr[3] = shs_pad2;
|
||||
|
||||
if (sha1_vector(4, addr, len, digest))
|
||||
return -1;
|
||||
|
||||
if (session_key_len > SHA1_MAC_LEN)
|
||||
session_key_len = SHA1_MAC_LEN;
|
||||
os_memcpy(session_key, digest, session_key_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef CONFIG_NO_RC4
|
||||
|
||||
#define PWBLOCK_LEN 516
|
||||
|
||||
/**
|
||||
* encrypt_pw_block_with_password_hash - EncryptPwBlockWithPasswordHash() - RFC 2759, Sect. 8.10
|
||||
* @password: 0-to-256-unicode-char Password (IN; UTF-8)
|
||||
* @password_len: Length of password
|
||||
* @password_hash: 16-octet PasswordHash (IN)
|
||||
* @pw_block: 516-byte PwBlock (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int encrypt_pw_block_with_password_hash(
|
||||
const u8 *password, size_t password_len,
|
||||
const u8 *password_hash, u8 *pw_block)
|
||||
{
|
||||
size_t ucs2_len, offset;
|
||||
u8 *pos;
|
||||
|
||||
os_memset(pw_block, 0, PWBLOCK_LEN);
|
||||
|
||||
if (utf8_to_ucs2(password, password_len, pw_block, 512, &ucs2_len) < 0
|
||||
|| ucs2_len > 256)
|
||||
return -1;
|
||||
|
||||
offset = (256 - ucs2_len) * 2;
|
||||
if (offset != 0) {
|
||||
os_memmove(pw_block + offset, pw_block, ucs2_len * 2);
|
||||
if (os_get_random(pw_block, offset) < 0)
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* PasswordLength is 4 octets, but since the maximum password length is
|
||||
* 256, only first two (in little endian byte order) can be non-zero.
|
||||
*/
|
||||
pos = &pw_block[2 * 256];
|
||||
WPA_PUT_LE16(pos, password_len * 2);
|
||||
rc4_skip(password_hash, 16, 0, pw_block, PWBLOCK_LEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* new_password_encrypted_with_old_nt_password_hash - NewPasswordEncryptedWithOldNtPasswordHash() - RFC 2759, Sect. 8.9
|
||||
* @new_password: 0-to-256-unicode-char NewPassword (IN; UTF-8)
|
||||
* @new_password_len: Length of new_password
|
||||
* @old_password: 0-to-256-unicode-char OldPassword (IN; UTF-8)
|
||||
* @old_password_len: Length of old_password
|
||||
* @encrypted_pw_block: 516-octet EncryptedPwBlock (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int new_password_encrypted_with_old_nt_password_hash(
|
||||
const u8 *new_password, size_t new_password_len,
|
||||
const u8 *old_password, size_t old_password_len,
|
||||
u8 *encrypted_pw_block)
|
||||
{
|
||||
u8 password_hash[16];
|
||||
|
||||
if (nt_password_hash(old_password, old_password_len, password_hash))
|
||||
return -1;
|
||||
if (encrypt_pw_block_with_password_hash(new_password, new_password_len,
|
||||
password_hash,
|
||||
encrypted_pw_block))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NO_RC4 */
|
||||
|
||||
|
||||
/**
|
||||
* nt_password_hash_encrypted_with_block - NtPasswordHashEncryptedWithBlock() - RFC 2759, Sect 8.13
|
||||
* @password_hash: 16-octer PasswordHash (IN)
|
||||
* @block: 16-octet Block (IN)
|
||||
* @cypher: 16-octer Cypher (OUT)
|
||||
*/
|
||||
void nt_password_hash_encrypted_with_block(const u8 *password_hash,
|
||||
const u8 *block, u8 *cypher)
|
||||
{
|
||||
des_encrypt(password_hash, block, cypher);
|
||||
des_encrypt(password_hash + 8, block + 7, cypher + 8);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* old_nt_password_hash_encrypted_with_new_nt_password_hash - OldNtPasswordHashEncryptedWithNewNtPasswordHash() - RFC 2759, Sect. 8.12
|
||||
* @new_password: 0-to-256-unicode-char NewPassword (IN; UTF-8)
|
||||
* @new_password_len: Length of new_password
|
||||
* @old_password: 0-to-256-unicode-char OldPassword (IN; UTF-8)
|
||||
* @old_password_len: Length of old_password
|
||||
* @encrypted_password_hash: 16-octet EncryptedPasswordHash (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int old_nt_password_hash_encrypted_with_new_nt_password_hash(
|
||||
const u8 *new_password, size_t new_password_len,
|
||||
const u8 *old_password, size_t old_password_len,
|
||||
u8 *encrypted_password_hash)
|
||||
{
|
||||
u8 old_password_hash[16], new_password_hash[16];
|
||||
|
||||
if (nt_password_hash(old_password, old_password_len,
|
||||
old_password_hash) ||
|
||||
nt_password_hash(new_password, new_password_len,
|
||||
new_password_hash))
|
||||
return -1;
|
||||
nt_password_hash_encrypted_with_block(old_password_hash,
|
||||
new_password_hash,
|
||||
encrypted_password_hash);
|
||||
return 0;
|
||||
}
|
60
freebsd/contrib/wpa/src/crypto/ms_funcs.h
Normal file
60
freebsd/contrib/wpa/src/crypto/ms_funcs.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* WPA Supplicant / shared MSCHAPV2 helper functions / RFC 2433 / RFC 2759
|
||||
* Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef MS_FUNCS_H
|
||||
#define MS_FUNCS_H
|
||||
|
||||
int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *password, size_t password_len,
|
||||
u8 *response);
|
||||
int generate_nt_response_pwhash(const u8 *auth_challenge,
|
||||
const u8 *peer_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *password_hash,
|
||||
u8 *response);
|
||||
int generate_authenticator_response(const u8 *password, size_t password_len,
|
||||
const u8 *peer_challenge,
|
||||
const u8 *auth_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *nt_response, u8 *response);
|
||||
int generate_authenticator_response_pwhash(
|
||||
const u8 *password_hash,
|
||||
const u8 *peer_challenge, const u8 *auth_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *nt_response, u8 *response);
|
||||
int nt_challenge_response(const u8 *challenge, const u8 *password,
|
||||
size_t password_len, u8 *response);
|
||||
|
||||
void challenge_response(const u8 *challenge, const u8 *password_hash,
|
||||
u8 *response);
|
||||
int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge,
|
||||
const u8 *username, size_t username_len, u8 *challenge);
|
||||
int nt_password_hash(const u8 *password, size_t password_len,
|
||||
u8 *password_hash);
|
||||
int hash_nt_password_hash(const u8 *password_hash, u8 *password_hash_hash);
|
||||
int get_master_key(const u8 *password_hash_hash, const u8 *nt_response,
|
||||
u8 *master_key);
|
||||
int get_asymetric_start_key(const u8 *master_key, u8 *session_key,
|
||||
size_t session_key_len, int is_send,
|
||||
int is_server);
|
||||
int __must_check encrypt_pw_block_with_password_hash(
|
||||
const u8 *password, size_t password_len,
|
||||
const u8 *password_hash, u8 *pw_block);
|
||||
int __must_check new_password_encrypted_with_old_nt_password_hash(
|
||||
const u8 *new_password, size_t new_password_len,
|
||||
const u8 *old_password, size_t old_password_len,
|
||||
u8 *encrypted_pw_block);
|
||||
void nt_password_hash_encrypted_with_block(const u8 *password_hash,
|
||||
const u8 *block, u8 *cypher);
|
||||
int old_nt_password_hash_encrypted_with_new_nt_password_hash(
|
||||
const u8 *new_password, size_t new_password_len,
|
||||
const u8 *old_password, size_t old_password_len,
|
||||
u8 *encrypted_password_hash);
|
||||
|
||||
#endif /* MS_FUNCS_H */
|
441
freebsd/contrib/wpa/src/crypto/random.c
Normal file
441
freebsd/contrib/wpa/src/crypto/random.c
Normal file
@ -0,0 +1,441 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* Random number generator
|
||||
* Copyright (c) 2010-2011, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*
|
||||
* This random number generator is used to provide additional entropy to the
|
||||
* one provided by the operating system (os_get_random()) for session key
|
||||
* generation. The os_get_random() output is expected to be secure and the
|
||||
* implementation here is expected to provide only limited protection against
|
||||
* cases where os_get_random() cannot provide strong randomness. This
|
||||
* implementation shall not be assumed to be secure as the sole source of
|
||||
* randomness. The random_get_bytes() function mixes in randomness from
|
||||
* os_get_random() and as such, calls to os_get_random() can be replaced with
|
||||
* calls to random_get_bytes() without reducing security.
|
||||
*
|
||||
* The design here follows partially the design used in the Linux
|
||||
* drivers/char/random.c, but the implementation here is simpler and not as
|
||||
* strong. This is a compromise to reduce duplicated CPU effort and to avoid
|
||||
* extra code/memory size. As pointed out above, os_get_random() needs to be
|
||||
* guaranteed to be secure for any of the security assumptions to hold.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#ifdef __linux__
|
||||
#include <fcntl.h>
|
||||
#endif /* __linux__ */
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "sha1.h"
|
||||
#include "random.h"
|
||||
|
||||
#define POOL_WORDS 32
|
||||
#define POOL_WORDS_MASK (POOL_WORDS - 1)
|
||||
#define POOL_TAP1 26
|
||||
#define POOL_TAP2 20
|
||||
#define POOL_TAP3 14
|
||||
#define POOL_TAP4 7
|
||||
#define POOL_TAP5 1
|
||||
#define EXTRACT_LEN 16
|
||||
#define MIN_READY_MARK 2
|
||||
|
||||
static u32 pool[POOL_WORDS];
|
||||
static unsigned int input_rotate = 0;
|
||||
static unsigned int pool_pos = 0;
|
||||
static u8 dummy_key[20];
|
||||
#ifdef __linux__
|
||||
static size_t dummy_key_avail = 0;
|
||||
static int random_fd = -1;
|
||||
#endif /* __linux__ */
|
||||
static unsigned int own_pool_ready = 0;
|
||||
#define RANDOM_ENTROPY_SIZE 20
|
||||
static char *random_entropy_file = NULL;
|
||||
static int random_entropy_file_read = 0;
|
||||
|
||||
#define MIN_COLLECT_ENTROPY 1000
|
||||
static unsigned int entropy = 0;
|
||||
static unsigned int total_collected = 0;
|
||||
|
||||
|
||||
static void random_write_entropy(void);
|
||||
|
||||
|
||||
static u32 __ROL32(u32 x, u32 y)
|
||||
{
|
||||
return (x << (y & 31)) | (x >> (32 - (y & 31)));
|
||||
}
|
||||
|
||||
|
||||
static void random_mix_pool(const void *buf, size_t len)
|
||||
{
|
||||
static const u32 twist[8] = {
|
||||
0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
|
||||
0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278
|
||||
};
|
||||
const u8 *pos = buf;
|
||||
u32 w;
|
||||
|
||||
wpa_hexdump_key(MSG_EXCESSIVE, "random_mix_pool", buf, len);
|
||||
|
||||
while (len--) {
|
||||
w = __ROL32(*pos++, input_rotate & 31);
|
||||
input_rotate += pool_pos ? 7 : 14;
|
||||
pool_pos = (pool_pos - 1) & POOL_WORDS_MASK;
|
||||
w ^= pool[pool_pos];
|
||||
w ^= pool[(pool_pos + POOL_TAP1) & POOL_WORDS_MASK];
|
||||
w ^= pool[(pool_pos + POOL_TAP2) & POOL_WORDS_MASK];
|
||||
w ^= pool[(pool_pos + POOL_TAP3) & POOL_WORDS_MASK];
|
||||
w ^= pool[(pool_pos + POOL_TAP4) & POOL_WORDS_MASK];
|
||||
w ^= pool[(pool_pos + POOL_TAP5) & POOL_WORDS_MASK];
|
||||
pool[pool_pos] = (w >> 3) ^ twist[w & 7];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void random_extract(u8 *out)
|
||||
{
|
||||
unsigned int i;
|
||||
u8 hash[SHA1_MAC_LEN];
|
||||
u32 *hash_ptr;
|
||||
u32 buf[POOL_WORDS / 2];
|
||||
|
||||
/* First, add hash back to pool to make backtracking more difficult. */
|
||||
hmac_sha1(dummy_key, sizeof(dummy_key), (const u8 *) pool,
|
||||
sizeof(pool), hash);
|
||||
random_mix_pool(hash, sizeof(hash));
|
||||
/* Hash half the pool to extra data */
|
||||
for (i = 0; i < POOL_WORDS / 2; i++)
|
||||
buf[i] = pool[(pool_pos - i) & POOL_WORDS_MASK];
|
||||
hmac_sha1(dummy_key, sizeof(dummy_key), (const u8 *) buf,
|
||||
sizeof(buf), hash);
|
||||
/*
|
||||
* Fold the hash to further reduce any potential output pattern.
|
||||
* Though, compromise this to reduce CPU use for the most common output
|
||||
* length (32) and return 16 bytes from instead of only half.
|
||||
*/
|
||||
hash_ptr = (u32 *) hash;
|
||||
hash_ptr[0] ^= hash_ptr[4];
|
||||
os_memcpy(out, hash, EXTRACT_LEN);
|
||||
}
|
||||
|
||||
|
||||
void random_add_randomness(const void *buf, size_t len)
|
||||
{
|
||||
struct os_time t;
|
||||
static unsigned int count = 0;
|
||||
|
||||
count++;
|
||||
if (entropy > MIN_COLLECT_ENTROPY && (count & 0x3ff) != 0) {
|
||||
/*
|
||||
* No need to add more entropy at this point, so save CPU and
|
||||
* skip the update.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
wpa_printf(MSG_EXCESSIVE, "Add randomness: count=%u entropy=%u",
|
||||
count, entropy);
|
||||
|
||||
os_get_time(&t);
|
||||
wpa_hexdump_key(MSG_EXCESSIVE, "random pool",
|
||||
(const u8 *) pool, sizeof(pool));
|
||||
random_mix_pool(&t, sizeof(t));
|
||||
random_mix_pool(buf, len);
|
||||
wpa_hexdump_key(MSG_EXCESSIVE, "random pool",
|
||||
(const u8 *) pool, sizeof(pool));
|
||||
entropy++;
|
||||
total_collected++;
|
||||
}
|
||||
|
||||
|
||||
int random_get_bytes(void *buf, size_t len)
|
||||
{
|
||||
int ret;
|
||||
u8 *bytes = buf;
|
||||
size_t left;
|
||||
|
||||
wpa_printf(MSG_MSGDUMP, "Get randomness: len=%u entropy=%u",
|
||||
(unsigned int) len, entropy);
|
||||
|
||||
/* Start with assumed strong randomness from OS */
|
||||
ret = os_get_random(buf, len);
|
||||
wpa_hexdump_key(MSG_EXCESSIVE, "random from os_get_random",
|
||||
buf, len);
|
||||
|
||||
/* Mix in additional entropy extracted from the internal pool */
|
||||
left = len;
|
||||
while (left) {
|
||||
size_t siz, i;
|
||||
u8 tmp[EXTRACT_LEN];
|
||||
random_extract(tmp);
|
||||
wpa_hexdump_key(MSG_EXCESSIVE, "random from internal pool",
|
||||
tmp, sizeof(tmp));
|
||||
siz = left > EXTRACT_LEN ? EXTRACT_LEN : left;
|
||||
for (i = 0; i < siz; i++)
|
||||
*bytes++ ^= tmp[i];
|
||||
left -= siz;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FIPS
|
||||
/* Mix in additional entropy from the crypto module */
|
||||
bytes = buf;
|
||||
left = len;
|
||||
while (left) {
|
||||
size_t siz, i;
|
||||
u8 tmp[EXTRACT_LEN];
|
||||
if (crypto_get_random(tmp, sizeof(tmp)) < 0) {
|
||||
wpa_printf(MSG_ERROR, "random: No entropy available "
|
||||
"for generating strong random bytes");
|
||||
return -1;
|
||||
}
|
||||
wpa_hexdump_key(MSG_EXCESSIVE, "random from crypto module",
|
||||
tmp, sizeof(tmp));
|
||||
siz = left > EXTRACT_LEN ? EXTRACT_LEN : left;
|
||||
for (i = 0; i < siz; i++)
|
||||
*bytes++ ^= tmp[i];
|
||||
left -= siz;
|
||||
}
|
||||
#endif /* CONFIG_FIPS */
|
||||
|
||||
wpa_hexdump_key(MSG_EXCESSIVE, "mixed random", buf, len);
|
||||
|
||||
if (entropy < len)
|
||||
entropy = 0;
|
||||
else
|
||||
entropy -= len;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int random_pool_ready(void)
|
||||
{
|
||||
#ifdef __linux__
|
||||
int fd;
|
||||
ssize_t res;
|
||||
|
||||
/*
|
||||
* Make sure that there is reasonable entropy available before allowing
|
||||
* some key derivation operations to proceed.
|
||||
*/
|
||||
|
||||
if (dummy_key_avail == sizeof(dummy_key))
|
||||
return 1; /* Already initialized - good to continue */
|
||||
|
||||
/*
|
||||
* Try to fetch some more data from the kernel high quality
|
||||
* /dev/random. There may not be enough data available at this point,
|
||||
* so use non-blocking read to avoid blocking the application
|
||||
* completely.
|
||||
*/
|
||||
fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
|
||||
if (fd < 0) {
|
||||
wpa_printf(MSG_ERROR, "random: Cannot open /dev/random: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = read(fd, dummy_key + dummy_key_avail,
|
||||
sizeof(dummy_key) - dummy_key_avail);
|
||||
if (res < 0) {
|
||||
wpa_printf(MSG_ERROR, "random: Cannot read from /dev/random: "
|
||||
"%s", strerror(errno));
|
||||
res = 0;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "random: Got %u/%u bytes from "
|
||||
"/dev/random", (unsigned) res,
|
||||
(unsigned) (sizeof(dummy_key) - dummy_key_avail));
|
||||
dummy_key_avail += res;
|
||||
close(fd);
|
||||
|
||||
if (dummy_key_avail == sizeof(dummy_key)) {
|
||||
if (own_pool_ready < MIN_READY_MARK)
|
||||
own_pool_ready = MIN_READY_MARK;
|
||||
random_write_entropy();
|
||||
return 1;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_INFO, "random: Only %u/%u bytes of strong "
|
||||
"random data available from /dev/random",
|
||||
(unsigned) dummy_key_avail, (unsigned) sizeof(dummy_key));
|
||||
|
||||
if (own_pool_ready >= MIN_READY_MARK ||
|
||||
total_collected + 10 * own_pool_ready > MIN_COLLECT_ENTROPY) {
|
||||
wpa_printf(MSG_INFO, "random: Allow operation to proceed "
|
||||
"based on internal entropy");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_INFO, "random: Not enough entropy pool available for "
|
||||
"secure operations");
|
||||
return 0;
|
||||
#else /* __linux__ */
|
||||
/* TODO: could do similar checks on non-Linux platforms */
|
||||
return 1;
|
||||
#endif /* __linux__ */
|
||||
}
|
||||
|
||||
|
||||
void random_mark_pool_ready(void)
|
||||
{
|
||||
own_pool_ready++;
|
||||
wpa_printf(MSG_DEBUG, "random: Mark internal entropy pool to be "
|
||||
"ready (count=%u/%u)", own_pool_ready, MIN_READY_MARK);
|
||||
random_write_entropy();
|
||||
}
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
static void random_close_fd(void)
|
||||
{
|
||||
if (random_fd >= 0) {
|
||||
eloop_unregister_read_sock(random_fd);
|
||||
close(random_fd);
|
||||
random_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void random_read_fd(int sock, void *eloop_ctx, void *sock_ctx)
|
||||
{
|
||||
ssize_t res;
|
||||
|
||||
if (dummy_key_avail == sizeof(dummy_key)) {
|
||||
random_close_fd();
|
||||
return;
|
||||
}
|
||||
|
||||
res = read(sock, dummy_key + dummy_key_avail,
|
||||
sizeof(dummy_key) - dummy_key_avail);
|
||||
if (res < 0) {
|
||||
wpa_printf(MSG_ERROR, "random: Cannot read from /dev/random: "
|
||||
"%s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "random: Got %u/%u bytes from /dev/random",
|
||||
(unsigned) res,
|
||||
(unsigned) (sizeof(dummy_key) - dummy_key_avail));
|
||||
dummy_key_avail += res;
|
||||
|
||||
if (dummy_key_avail == sizeof(dummy_key)) {
|
||||
random_close_fd();
|
||||
if (own_pool_ready < MIN_READY_MARK)
|
||||
own_pool_ready = MIN_READY_MARK;
|
||||
random_write_entropy();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
|
||||
static void random_read_entropy(void)
|
||||
{
|
||||
char *buf;
|
||||
size_t len;
|
||||
|
||||
if (!random_entropy_file)
|
||||
return;
|
||||
|
||||
buf = os_readfile(random_entropy_file, &len);
|
||||
if (buf == NULL)
|
||||
return; /* entropy file not yet available */
|
||||
|
||||
if (len != 1 + RANDOM_ENTROPY_SIZE) {
|
||||
wpa_printf(MSG_DEBUG, "random: Invalid entropy file %s",
|
||||
random_entropy_file);
|
||||
os_free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
own_pool_ready = (u8) buf[0];
|
||||
random_add_randomness(buf + 1, RANDOM_ENTROPY_SIZE);
|
||||
random_entropy_file_read = 1;
|
||||
os_free(buf);
|
||||
wpa_printf(MSG_DEBUG, "random: Added entropy from %s "
|
||||
"(own_pool_ready=%u)",
|
||||
random_entropy_file, own_pool_ready);
|
||||
}
|
||||
|
||||
|
||||
static void random_write_entropy(void)
|
||||
{
|
||||
char buf[RANDOM_ENTROPY_SIZE];
|
||||
FILE *f;
|
||||
u8 opr;
|
||||
int fail = 0;
|
||||
|
||||
if (!random_entropy_file)
|
||||
return;
|
||||
|
||||
if (random_get_bytes(buf, RANDOM_ENTROPY_SIZE) < 0)
|
||||
return;
|
||||
|
||||
f = fopen(random_entropy_file, "wb");
|
||||
if (f == NULL) {
|
||||
wpa_printf(MSG_ERROR, "random: Could not open entropy file %s "
|
||||
"for writing", random_entropy_file);
|
||||
return;
|
||||
}
|
||||
|
||||
opr = own_pool_ready > 0xff ? 0xff : own_pool_ready;
|
||||
if (fwrite(&opr, 1, 1, f) != 1 ||
|
||||
fwrite(buf, RANDOM_ENTROPY_SIZE, 1, f) != 1)
|
||||
fail = 1;
|
||||
fclose(f);
|
||||
if (fail) {
|
||||
wpa_printf(MSG_ERROR, "random: Could not write entropy data "
|
||||
"to %s", random_entropy_file);
|
||||
return;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "random: Updated entropy file %s "
|
||||
"(own_pool_ready=%u)",
|
||||
random_entropy_file, own_pool_ready);
|
||||
}
|
||||
|
||||
|
||||
void random_init(const char *entropy_file)
|
||||
{
|
||||
os_free(random_entropy_file);
|
||||
if (entropy_file)
|
||||
random_entropy_file = os_strdup(entropy_file);
|
||||
else
|
||||
random_entropy_file = NULL;
|
||||
random_read_entropy();
|
||||
|
||||
#ifdef __linux__
|
||||
if (random_fd >= 0)
|
||||
return;
|
||||
|
||||
random_fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
|
||||
if (random_fd < 0) {
|
||||
wpa_printf(MSG_ERROR, "random: Cannot open /dev/random: %s",
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "random: Trying to read entropy from "
|
||||
"/dev/random");
|
||||
|
||||
eloop_register_read_sock(random_fd, random_read_fd, NULL, NULL);
|
||||
#endif /* __linux__ */
|
||||
|
||||
random_write_entropy();
|
||||
}
|
||||
|
||||
|
||||
void random_deinit(void)
|
||||
{
|
||||
#ifdef __linux__
|
||||
random_close_fd();
|
||||
#endif /* __linux__ */
|
||||
random_write_entropy();
|
||||
os_free(random_entropy_file);
|
||||
random_entropy_file = NULL;
|
||||
}
|
28
freebsd/contrib/wpa/src/crypto/random.h
Normal file
28
freebsd/contrib/wpa/src/crypto/random.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Random number generator
|
||||
* Copyright (c) 2010-2011, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef RANDOM_H
|
||||
#define RANDOM_H
|
||||
|
||||
#ifdef CONFIG_NO_RANDOM_POOL
|
||||
#define random_init(e) do { } while (0)
|
||||
#define random_deinit() do { } while (0)
|
||||
#define random_add_randomness(b, l) do { } while (0)
|
||||
#define random_get_bytes(b, l) os_get_random((b), (l))
|
||||
#define random_pool_ready() 1
|
||||
#define random_mark_pool_ready() do { } while (0)
|
||||
#else /* CONFIG_NO_RANDOM_POOL */
|
||||
void random_init(const char *entropy_file);
|
||||
void random_deinit(void);
|
||||
void random_add_randomness(const void *buf, size_t len);
|
||||
int random_get_bytes(void *buf, size_t len);
|
||||
int random_pool_ready(void);
|
||||
void random_mark_pool_ready(void);
|
||||
#endif /* CONFIG_NO_RANDOM_POOL */
|
||||
|
||||
#endif /* RANDOM_H */
|
56
freebsd/contrib/wpa/src/crypto/rc4.c
Normal file
56
freebsd/contrib/wpa/src/crypto/rc4.c
Normal file
@ -0,0 +1,56 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* RC4 stream cipher
|
||||
* Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0)
|
||||
|
||||
int rc4_skip(const u8 *key, size_t keylen, size_t skip,
|
||||
u8 *data, size_t data_len)
|
||||
{
|
||||
u32 i, j, k;
|
||||
u8 S[256], *pos;
|
||||
size_t kpos;
|
||||
|
||||
/* Setup RC4 state */
|
||||
for (i = 0; i < 256; i++)
|
||||
S[i] = i;
|
||||
j = 0;
|
||||
kpos = 0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
j = (j + S[i] + key[kpos]) & 0xff;
|
||||
kpos++;
|
||||
if (kpos >= keylen)
|
||||
kpos = 0;
|
||||
S_SWAP(i, j);
|
||||
}
|
||||
|
||||
/* Skip the start of the stream */
|
||||
i = j = 0;
|
||||
for (k = 0; k < skip; k++) {
|
||||
i = (i + 1) & 0xff;
|
||||
j = (j + S[i]) & 0xff;
|
||||
S_SWAP(i, j);
|
||||
}
|
||||
|
||||
/* Apply RC4 to data */
|
||||
pos = data;
|
||||
for (k = 0; k < data_len; k++) {
|
||||
i = (i + 1) & 0xff;
|
||||
j = (j + S[i]) & 0xff;
|
||||
S_SWAP(i, j);
|
||||
*pos++ ^= S[(S[i] + S[j]) & 0xff];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
94
freebsd/contrib/wpa/src/crypto/sha1-pbkdf2.c
Normal file
94
freebsd/contrib/wpa/src/crypto/sha1-pbkdf2.c
Normal file
@ -0,0 +1,94 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* SHA1-based key derivation function (PBKDF2) for IEEE 802.11i
|
||||
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "sha1.h"
|
||||
|
||||
static int pbkdf2_sha1_f(const char *passphrase, const u8 *ssid,
|
||||
size_t ssid_len, int iterations, unsigned int count,
|
||||
u8 *digest)
|
||||
{
|
||||
unsigned char tmp[SHA1_MAC_LEN], tmp2[SHA1_MAC_LEN];
|
||||
int i, j;
|
||||
unsigned char count_buf[4];
|
||||
const u8 *addr[2];
|
||||
size_t len[2];
|
||||
size_t passphrase_len = os_strlen(passphrase);
|
||||
|
||||
addr[0] = ssid;
|
||||
len[0] = ssid_len;
|
||||
addr[1] = count_buf;
|
||||
len[1] = 4;
|
||||
|
||||
/* F(P, S, c, i) = U1 xor U2 xor ... Uc
|
||||
* U1 = PRF(P, S || i)
|
||||
* U2 = PRF(P, U1)
|
||||
* Uc = PRF(P, Uc-1)
|
||||
*/
|
||||
|
||||
count_buf[0] = (count >> 24) & 0xff;
|
||||
count_buf[1] = (count >> 16) & 0xff;
|
||||
count_buf[2] = (count >> 8) & 0xff;
|
||||
count_buf[3] = count & 0xff;
|
||||
if (hmac_sha1_vector((u8 *) passphrase, passphrase_len, 2, addr, len,
|
||||
tmp))
|
||||
return -1;
|
||||
os_memcpy(digest, tmp, SHA1_MAC_LEN);
|
||||
|
||||
for (i = 1; i < iterations; i++) {
|
||||
if (hmac_sha1((u8 *) passphrase, passphrase_len, tmp,
|
||||
SHA1_MAC_LEN, tmp2))
|
||||
return -1;
|
||||
os_memcpy(tmp, tmp2, SHA1_MAC_LEN);
|
||||
for (j = 0; j < SHA1_MAC_LEN; j++)
|
||||
digest[j] ^= tmp2[j];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* pbkdf2_sha1 - SHA1-based key derivation function (PBKDF2) for IEEE 802.11i
|
||||
* @passphrase: ASCII passphrase
|
||||
* @ssid: SSID
|
||||
* @ssid_len: SSID length in bytes
|
||||
* @iterations: Number of iterations to run
|
||||
* @buf: Buffer for the generated key
|
||||
* @buflen: Length of the buffer in bytes
|
||||
* Returns: 0 on success, -1 of failure
|
||||
*
|
||||
* This function is used to derive PSK for WPA-PSK. For this protocol,
|
||||
* iterations is set to 4096 and buflen to 32. This function is described in
|
||||
* IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0.
|
||||
*/
|
||||
int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
|
||||
int iterations, u8 *buf, size_t buflen)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
unsigned char *pos = buf;
|
||||
size_t left = buflen, plen;
|
||||
unsigned char digest[SHA1_MAC_LEN];
|
||||
|
||||
while (left > 0) {
|
||||
count++;
|
||||
if (pbkdf2_sha1_f(passphrase, ssid, ssid_len, iterations,
|
||||
count, digest))
|
||||
return -1;
|
||||
plen = left > SHA1_MAC_LEN ? SHA1_MAC_LEN : left;
|
||||
os_memcpy(pos, digest, plen);
|
||||
pos += plen;
|
||||
left -= plen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
69
freebsd/contrib/wpa/src/crypto/sha1-prf.c
Normal file
69
freebsd/contrib/wpa/src/crypto/sha1-prf.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* SHA1-based PRF
|
||||
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "sha1.h"
|
||||
#include "crypto.h"
|
||||
|
||||
|
||||
/**
|
||||
* sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1)
|
||||
* @key: Key for PRF
|
||||
* @key_len: Length of the key in bytes
|
||||
* @label: A unique label for each purpose of the PRF
|
||||
* @data: Extra data to bind into the key
|
||||
* @data_len: Length of the data
|
||||
* @buf: Buffer for the generated pseudo-random key
|
||||
* @buf_len: Number of bytes of key to generate
|
||||
* Returns: 0 on success, -1 of failure
|
||||
*
|
||||
* This function is used to derive new, cryptographically separate keys from a
|
||||
* given key (e.g., PMK in IEEE 802.11i).
|
||||
*/
|
||||
int sha1_prf(const u8 *key, size_t key_len, const char *label,
|
||||
const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
|
||||
{
|
||||
u8 counter = 0;
|
||||
size_t pos, plen;
|
||||
u8 hash[SHA1_MAC_LEN];
|
||||
size_t label_len = os_strlen(label) + 1;
|
||||
const unsigned char *addr[3];
|
||||
size_t len[3];
|
||||
|
||||
addr[0] = (u8 *) label;
|
||||
len[0] = label_len;
|
||||
addr[1] = data;
|
||||
len[1] = data_len;
|
||||
addr[2] = &counter;
|
||||
len[2] = 1;
|
||||
|
||||
pos = 0;
|
||||
while (pos < buf_len) {
|
||||
plen = buf_len - pos;
|
||||
if (plen >= SHA1_MAC_LEN) {
|
||||
if (hmac_sha1_vector(key, key_len, 3, addr, len,
|
||||
&buf[pos]))
|
||||
return -1;
|
||||
pos += SHA1_MAC_LEN;
|
||||
} else {
|
||||
if (hmac_sha1_vector(key, key_len, 3, addr, len,
|
||||
hash))
|
||||
return -1;
|
||||
os_memcpy(&buf[pos], hash, plen);
|
||||
break;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
os_memset(hash, 0, sizeof(hash));
|
||||
|
||||
return 0;
|
||||
}
|
109
freebsd/contrib/wpa/src/crypto/sha1.c
Normal file
109
freebsd/contrib/wpa/src/crypto/sha1.c
Normal file
@ -0,0 +1,109 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* SHA1 hash implementation and interface functions
|
||||
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "sha1.h"
|
||||
#include "crypto.h"
|
||||
|
||||
|
||||
/**
|
||||
* hmac_sha1_vector - HMAC-SHA1 over data vector (RFC 2104)
|
||||
* @key: Key for HMAC operations
|
||||
* @key_len: Length of the key in bytes
|
||||
* @num_elem: Number of elements in the data vector
|
||||
* @addr: Pointers to the data areas
|
||||
* @len: Lengths of the data blocks
|
||||
* @mac: Buffer for the hash (20 bytes)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
|
||||
const u8 *addr[], const size_t *len, u8 *mac)
|
||||
{
|
||||
unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
|
||||
unsigned char tk[20];
|
||||
const u8 *_addr[6];
|
||||
size_t _len[6], i;
|
||||
int ret;
|
||||
|
||||
if (num_elem > 5) {
|
||||
/*
|
||||
* Fixed limit on the number of fragments to avoid having to
|
||||
* allocate memory (which could fail).
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if key is longer than 64 bytes reset it to key = SHA1(key) */
|
||||
if (key_len > 64) {
|
||||
if (sha1_vector(1, &key, &key_len, tk))
|
||||
return -1;
|
||||
key = tk;
|
||||
key_len = 20;
|
||||
}
|
||||
|
||||
/* the HMAC_SHA1 transform looks like:
|
||||
*
|
||||
* SHA1(K XOR opad, SHA1(K XOR ipad, text))
|
||||
*
|
||||
* where K is an n byte key
|
||||
* ipad is the byte 0x36 repeated 64 times
|
||||
* opad is the byte 0x5c repeated 64 times
|
||||
* and text is the data being protected */
|
||||
|
||||
/* start out by storing key in ipad */
|
||||
os_memset(k_pad, 0, sizeof(k_pad));
|
||||
os_memcpy(k_pad, key, key_len);
|
||||
/* XOR key with ipad values */
|
||||
for (i = 0; i < 64; i++)
|
||||
k_pad[i] ^= 0x36;
|
||||
|
||||
/* perform inner SHA1 */
|
||||
_addr[0] = k_pad;
|
||||
_len[0] = 64;
|
||||
for (i = 0; i < num_elem; i++) {
|
||||
_addr[i + 1] = addr[i];
|
||||
_len[i + 1] = len[i];
|
||||
}
|
||||
if (sha1_vector(1 + num_elem, _addr, _len, mac))
|
||||
return -1;
|
||||
|
||||
os_memset(k_pad, 0, sizeof(k_pad));
|
||||
os_memcpy(k_pad, key, key_len);
|
||||
/* XOR key with opad values */
|
||||
for (i = 0; i < 64; i++)
|
||||
k_pad[i] ^= 0x5c;
|
||||
|
||||
/* perform outer SHA1 */
|
||||
_addr[0] = k_pad;
|
||||
_len[0] = 64;
|
||||
_addr[1] = mac;
|
||||
_len[1] = SHA1_MAC_LEN;
|
||||
ret = sha1_vector(2, _addr, _len, mac);
|
||||
os_memset(k_pad, 0, sizeof(k_pad));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hmac_sha1 - HMAC-SHA1 over data buffer (RFC 2104)
|
||||
* @key: Key for HMAC operations
|
||||
* @key_len: Length of the key in bytes
|
||||
* @data: Pointers to the data area
|
||||
* @data_len: Length of the data area
|
||||
* @mac: Buffer for the hash (20 bytes)
|
||||
* Returns: 0 on success, -1 of failure
|
||||
*/
|
||||
int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
|
||||
u8 *mac)
|
||||
{
|
||||
return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
|
||||
}
|
27
freebsd/contrib/wpa/src/crypto/sha1.h
Normal file
27
freebsd/contrib/wpa/src/crypto/sha1.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* SHA1 hash implementation and interface functions
|
||||
* Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef SHA1_H
|
||||
#define SHA1_H
|
||||
|
||||
#define SHA1_MAC_LEN 20
|
||||
|
||||
int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
|
||||
const u8 *addr[], const size_t *len, u8 *mac);
|
||||
int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
|
||||
u8 *mac);
|
||||
int sha1_prf(const u8 *key, size_t key_len, const char *label,
|
||||
const u8 *data, size_t data_len, u8 *buf, size_t buf_len);
|
||||
int sha1_t_prf(const u8 *key, size_t key_len, const char *label,
|
||||
const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len);
|
||||
int __must_check tls_prf_sha1_md5(const u8 *secret, size_t secret_len,
|
||||
const char *label, const u8 *seed,
|
||||
size_t seed_len, u8 *out, size_t outlen);
|
||||
int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
|
||||
int iterations, u8 *buf, size_t buflen);
|
||||
#endif /* SHA1_H */
|
228
freebsd/contrib/wpa/src/crypto/sha256-internal.c
Normal file
228
freebsd/contrib/wpa/src/crypto/sha256-internal.c
Normal file
@ -0,0 +1,228 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* SHA-256 hash implementation and interface functions
|
||||
* Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "sha256.h"
|
||||
#include "sha256_i.h"
|
||||
#include "crypto.h"
|
||||
|
||||
|
||||
/**
|
||||
* sha256_vector - SHA256 hash for data vector
|
||||
* @num_elem: Number of elements in the data vector
|
||||
* @addr: Pointers to the data areas
|
||||
* @len: Lengths of the data blocks
|
||||
* @mac: Buffer for the hash
|
||||
* Returns: 0 on success, -1 of failure
|
||||
*/
|
||||
int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
|
||||
u8 *mac)
|
||||
{
|
||||
struct sha256_state ctx;
|
||||
size_t i;
|
||||
|
||||
sha256_init(&ctx);
|
||||
for (i = 0; i < num_elem; i++)
|
||||
if (sha256_process(&ctx, addr[i], len[i]))
|
||||
return -1;
|
||||
if (sha256_done(&ctx, mac))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ===== start - public domain SHA256 implementation ===== */
|
||||
|
||||
/* This is based on SHA256 implementation in LibTomCrypt that was released into
|
||||
* public domain by Tom St Denis. */
|
||||
|
||||
/* the K array */
|
||||
static const unsigned long K[64] = {
|
||||
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
|
||||
0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
|
||||
0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
|
||||
0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
|
||||
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
|
||||
0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
|
||||
0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
|
||||
0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
|
||||
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
|
||||
0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
|
||||
0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
|
||||
0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
|
||||
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
|
||||
};
|
||||
|
||||
|
||||
/* Various logical functions */
|
||||
#define RORc(x, y) \
|
||||
( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \
|
||||
((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
|
||||
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define Maj(x,y,z) (((x | y) & z) | (x & y))
|
||||
#define S(x, n) RORc((x), (n))
|
||||
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
|
||||
#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
|
||||
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
|
||||
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
|
||||
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
|
||||
#ifndef MIN
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
/* compress 512-bits */
|
||||
static int sha256_compress(struct sha256_state *md, unsigned char *buf)
|
||||
{
|
||||
u32 S[8], W[64], t0, t1;
|
||||
u32 t;
|
||||
int i;
|
||||
|
||||
/* copy state into S */
|
||||
for (i = 0; i < 8; i++) {
|
||||
S[i] = md->state[i];
|
||||
}
|
||||
|
||||
/* copy the state into 512-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++)
|
||||
W[i] = WPA_GET_BE32(buf + (4 * i));
|
||||
|
||||
/* fill W[16..63] */
|
||||
for (i = 16; i < 64; i++) {
|
||||
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
|
||||
W[i - 16];
|
||||
}
|
||||
|
||||
/* Compress */
|
||||
#define RND(a,b,c,d,e,f,g,h,i) \
|
||||
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
|
||||
t1 = Sigma0(a) + Maj(a, b, c); \
|
||||
d += t0; \
|
||||
h = t0 + t1;
|
||||
|
||||
for (i = 0; i < 64; ++i) {
|
||||
RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
|
||||
t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
|
||||
S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
|
||||
}
|
||||
|
||||
/* feedback */
|
||||
for (i = 0; i < 8; i++) {
|
||||
md->state[i] = md->state[i] + S[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the hash state */
|
||||
void sha256_init(struct sha256_state *md)
|
||||
{
|
||||
md->curlen = 0;
|
||||
md->length = 0;
|
||||
md->state[0] = 0x6A09E667UL;
|
||||
md->state[1] = 0xBB67AE85UL;
|
||||
md->state[2] = 0x3C6EF372UL;
|
||||
md->state[3] = 0xA54FF53AUL;
|
||||
md->state[4] = 0x510E527FUL;
|
||||
md->state[5] = 0x9B05688CUL;
|
||||
md->state[6] = 0x1F83D9ABUL;
|
||||
md->state[7] = 0x5BE0CD19UL;
|
||||
}
|
||||
|
||||
/**
|
||||
Process a block of memory though the hash
|
||||
@param md The hash state
|
||||
@param in The data to hash
|
||||
@param inlen The length of the data (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha256_process(struct sha256_state *md, const unsigned char *in,
|
||||
unsigned long inlen)
|
||||
{
|
||||
unsigned long n;
|
||||
|
||||
if (md->curlen >= sizeof(md->buf))
|
||||
return -1;
|
||||
|
||||
while (inlen > 0) {
|
||||
if (md->curlen == 0 && inlen >= SHA256_BLOCK_SIZE) {
|
||||
if (sha256_compress(md, (unsigned char *) in) < 0)
|
||||
return -1;
|
||||
md->length += SHA256_BLOCK_SIZE * 8;
|
||||
in += SHA256_BLOCK_SIZE;
|
||||
inlen -= SHA256_BLOCK_SIZE;
|
||||
} else {
|
||||
n = MIN(inlen, (SHA256_BLOCK_SIZE - md->curlen));
|
||||
os_memcpy(md->buf + md->curlen, in, n);
|
||||
md->curlen += n;
|
||||
in += n;
|
||||
inlen -= n;
|
||||
if (md->curlen == SHA256_BLOCK_SIZE) {
|
||||
if (sha256_compress(md, md->buf) < 0)
|
||||
return -1;
|
||||
md->length += 8 * SHA256_BLOCK_SIZE;
|
||||
md->curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Terminate the hash to get the digest
|
||||
@param md The hash state
|
||||
@param out [out] The destination of the hash (32 bytes)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int sha256_done(struct sha256_state *md, unsigned char *out)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (md->curlen >= sizeof(md->buf))
|
||||
return -1;
|
||||
|
||||
/* increase the length of the message */
|
||||
md->length += md->curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
md->buf[md->curlen++] = (unsigned char) 0x80;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->curlen > 56) {
|
||||
while (md->curlen < SHA256_BLOCK_SIZE) {
|
||||
md->buf[md->curlen++] = (unsigned char) 0;
|
||||
}
|
||||
sha256_compress(md, md->buf);
|
||||
md->curlen = 0;
|
||||
}
|
||||
|
||||
/* pad up to 56 bytes of zeroes */
|
||||
while (md->curlen < 56) {
|
||||
md->buf[md->curlen++] = (unsigned char) 0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
WPA_PUT_BE64(md->buf + 56, md->length);
|
||||
sha256_compress(md, md->buf);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 8; i++)
|
||||
WPA_PUT_BE32(out + (4 * i), md->state[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ===== end - public domain SHA256 implementation ===== */
|
102
freebsd/contrib/wpa/src/crypto/sha256-prf.c
Normal file
102
freebsd/contrib/wpa/src/crypto/sha256-prf.c
Normal file
@ -0,0 +1,102 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* SHA256-based PRF (IEEE 802.11r)
|
||||
* Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "sha256.h"
|
||||
#include "crypto.h"
|
||||
|
||||
|
||||
/**
|
||||
* sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2)
|
||||
* @key: Key for PRF
|
||||
* @key_len: Length of the key in bytes
|
||||
* @label: A unique label for each purpose of the PRF
|
||||
* @data: Extra data to bind into the key
|
||||
* @data_len: Length of the data
|
||||
* @buf: Buffer for the generated pseudo-random key
|
||||
* @buf_len: Number of bytes of key to generate
|
||||
*
|
||||
* This function is used to derive new, cryptographically separate keys from a
|
||||
* given key.
|
||||
*/
|
||||
void sha256_prf(const u8 *key, size_t key_len, const char *label,
|
||||
const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
|
||||
{
|
||||
sha256_prf_bits(key, key_len, label, data, data_len, buf, buf_len * 8);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sha256_prf_bits - IEEE Std 802.11-2012, 11.6.1.7.2 Key derivation function
|
||||
* @key: Key for KDF
|
||||
* @key_len: Length of the key in bytes
|
||||
* @label: A unique label for each purpose of the PRF
|
||||
* @data: Extra data to bind into the key
|
||||
* @data_len: Length of the data
|
||||
* @buf: Buffer for the generated pseudo-random key
|
||||
* @buf_len: Number of bits of key to generate
|
||||
*
|
||||
* This function is used to derive new, cryptographically separate keys from a
|
||||
* given key. If the requested buf_len is not divisible by eight, the least
|
||||
* significant 1-7 bits of the last octet in the output are not part of the
|
||||
* requested output.
|
||||
*/
|
||||
void sha256_prf_bits(const u8 *key, size_t key_len, const char *label,
|
||||
const u8 *data, size_t data_len, u8 *buf,
|
||||
size_t buf_len_bits)
|
||||
{
|
||||
u16 counter = 1;
|
||||
size_t pos, plen;
|
||||
u8 hash[SHA256_MAC_LEN];
|
||||
const u8 *addr[4];
|
||||
size_t len[4];
|
||||
u8 counter_le[2], length_le[2];
|
||||
size_t buf_len = (buf_len_bits + 7) / 8;
|
||||
|
||||
addr[0] = counter_le;
|
||||
len[0] = 2;
|
||||
addr[1] = (u8 *) label;
|
||||
len[1] = os_strlen(label);
|
||||
addr[2] = data;
|
||||
len[2] = data_len;
|
||||
addr[3] = length_le;
|
||||
len[3] = sizeof(length_le);
|
||||
|
||||
WPA_PUT_LE16(length_le, buf_len_bits);
|
||||
pos = 0;
|
||||
while (pos < buf_len) {
|
||||
plen = buf_len - pos;
|
||||
WPA_PUT_LE16(counter_le, counter);
|
||||
if (plen >= SHA256_MAC_LEN) {
|
||||
hmac_sha256_vector(key, key_len, 4, addr, len,
|
||||
&buf[pos]);
|
||||
pos += SHA256_MAC_LEN;
|
||||
} else {
|
||||
hmac_sha256_vector(key, key_len, 4, addr, len, hash);
|
||||
os_memcpy(&buf[pos], hash, plen);
|
||||
pos += plen;
|
||||
break;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mask out unused bits in the last octet if it does not use all the
|
||||
* bits.
|
||||
*/
|
||||
if (buf_len_bits % 8) {
|
||||
u8 mask = 0xff << (8 - buf_len_bits % 8);
|
||||
buf[pos - 1] &= mask;
|
||||
}
|
||||
|
||||
os_memset(hash, 0, sizeof(hash));
|
||||
}
|
30
freebsd/contrib/wpa/src/crypto/sha256.h
Normal file
30
freebsd/contrib/wpa/src/crypto/sha256.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* SHA256 hash implementation and interface functions
|
||||
* Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef SHA256_H
|
||||
#define SHA256_H
|
||||
|
||||
#define SHA256_MAC_LEN 32
|
||||
|
||||
int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
|
||||
const u8 *addr[], const size_t *len, u8 *mac);
|
||||
int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
|
||||
size_t data_len, u8 *mac);
|
||||
void sha256_prf(const u8 *key, size_t key_len, const char *label,
|
||||
const u8 *data, size_t data_len, u8 *buf, size_t buf_len);
|
||||
void sha256_prf_bits(const u8 *key, size_t key_len, const char *label,
|
||||
const u8 *data, size_t data_len, u8 *buf,
|
||||
size_t buf_len_bits);
|
||||
void tls_prf_sha256(const u8 *secret, size_t secret_len,
|
||||
const char *label, const u8 *seed, size_t seed_len,
|
||||
u8 *out, size_t outlen);
|
||||
int hmac_sha256_kdf(const u8 *secret, size_t secret_len,
|
||||
const char *label, const u8 *seed, size_t seed_len,
|
||||
u8 *out, size_t outlen);
|
||||
|
||||
#endif /* SHA256_H */
|
25
freebsd/contrib/wpa/src/crypto/sha256_i.h
Normal file
25
freebsd/contrib/wpa/src/crypto/sha256_i.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SHA-256 internal definitions
|
||||
* Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef SHA256_I_H
|
||||
#define SHA256_I_H
|
||||
|
||||
#define SHA256_BLOCK_SIZE 64
|
||||
|
||||
struct sha256_state {
|
||||
u64 length;
|
||||
u32 state[8], curlen;
|
||||
u8 buf[SHA256_BLOCK_SIZE];
|
||||
};
|
||||
|
||||
void sha256_init(struct sha256_state *md);
|
||||
int sha256_process(struct sha256_state *md, const unsigned char *in,
|
||||
unsigned long inlen);
|
||||
int sha256_done(struct sha256_state *md, unsigned char *out);
|
||||
|
||||
#endif /* SHA256_I_H */
|
24
freebsd/contrib/wpa/src/crypto/sha384.h
Normal file
24
freebsd/contrib/wpa/src/crypto/sha384.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* SHA384 hash implementation and interface functions
|
||||
* Copyright (c) 2015, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef SHA384_H
|
||||
#define SHA384_H
|
||||
|
||||
#define SHA384_MAC_LEN 48
|
||||
|
||||
int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
|
||||
const u8 *addr[], const size_t *len, u8 *mac);
|
||||
int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
|
||||
size_t data_len, u8 *mac);
|
||||
void sha384_prf(const u8 *key, size_t key_len, const char *label,
|
||||
const u8 *data, size_t data_len, u8 *buf, size_t buf_len);
|
||||
void sha384_prf_bits(const u8 *key, size_t key_len, const char *label,
|
||||
const u8 *data, size_t data_len, u8 *buf,
|
||||
size_t buf_len_bits);
|
||||
|
||||
#endif /* SHA384_H */
|
588
freebsd/contrib/wpa/src/crypto/tls.h
Normal file
588
freebsd/contrib/wpa/src/crypto/tls.h
Normal file
@ -0,0 +1,588 @@
|
||||
/*
|
||||
* SSL/TLS interface definition
|
||||
* Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef TLS_H
|
||||
#define TLS_H
|
||||
|
||||
struct tls_connection;
|
||||
|
||||
struct tls_random {
|
||||
const u8 *client_random;
|
||||
size_t client_random_len;
|
||||
const u8 *server_random;
|
||||
size_t server_random_len;
|
||||
};
|
||||
|
||||
enum tls_event {
|
||||
TLS_CERT_CHAIN_SUCCESS,
|
||||
TLS_CERT_CHAIN_FAILURE,
|
||||
TLS_PEER_CERTIFICATE,
|
||||
TLS_ALERT
|
||||
};
|
||||
|
||||
/*
|
||||
* Note: These are used as identifier with external programs and as such, the
|
||||
* values must not be changed.
|
||||
*/
|
||||
enum tls_fail_reason {
|
||||
TLS_FAIL_UNSPECIFIED = 0,
|
||||
TLS_FAIL_UNTRUSTED = 1,
|
||||
TLS_FAIL_REVOKED = 2,
|
||||
TLS_FAIL_NOT_YET_VALID = 3,
|
||||
TLS_FAIL_EXPIRED = 4,
|
||||
TLS_FAIL_SUBJECT_MISMATCH = 5,
|
||||
TLS_FAIL_ALTSUBJECT_MISMATCH = 6,
|
||||
TLS_FAIL_BAD_CERTIFICATE = 7,
|
||||
TLS_FAIL_SERVER_CHAIN_PROBE = 8,
|
||||
TLS_FAIL_DOMAIN_SUFFIX_MISMATCH = 9,
|
||||
TLS_FAIL_DOMAIN_MISMATCH = 10,
|
||||
};
|
||||
|
||||
|
||||
#define TLS_MAX_ALT_SUBJECT 10
|
||||
|
||||
union tls_event_data {
|
||||
struct {
|
||||
int depth;
|
||||
const char *subject;
|
||||
enum tls_fail_reason reason;
|
||||
const char *reason_txt;
|
||||
const struct wpabuf *cert;
|
||||
} cert_fail;
|
||||
|
||||
struct {
|
||||
int depth;
|
||||
const char *subject;
|
||||
const struct wpabuf *cert;
|
||||
const u8 *hash;
|
||||
size_t hash_len;
|
||||
const char *altsubject[TLS_MAX_ALT_SUBJECT];
|
||||
int num_altsubject;
|
||||
} peer_cert;
|
||||
|
||||
struct {
|
||||
int is_local;
|
||||
const char *type;
|
||||
const char *description;
|
||||
} alert;
|
||||
};
|
||||
|
||||
struct tls_config {
|
||||
const char *opensc_engine_path;
|
||||
const char *pkcs11_engine_path;
|
||||
const char *pkcs11_module_path;
|
||||
int fips_mode;
|
||||
int cert_in_cb;
|
||||
const char *openssl_ciphers;
|
||||
unsigned int tls_session_lifetime;
|
||||
|
||||
void (*event_cb)(void *ctx, enum tls_event ev,
|
||||
union tls_event_data *data);
|
||||
void *cb_ctx;
|
||||
};
|
||||
|
||||
#define TLS_CONN_ALLOW_SIGN_RSA_MD5 BIT(0)
|
||||
#define TLS_CONN_DISABLE_TIME_CHECKS BIT(1)
|
||||
#define TLS_CONN_DISABLE_SESSION_TICKET BIT(2)
|
||||
#define TLS_CONN_REQUEST_OCSP BIT(3)
|
||||
#define TLS_CONN_REQUIRE_OCSP BIT(4)
|
||||
#define TLS_CONN_DISABLE_TLSv1_1 BIT(5)
|
||||
#define TLS_CONN_DISABLE_TLSv1_2 BIT(6)
|
||||
#define TLS_CONN_EAP_FAST BIT(7)
|
||||
#define TLS_CONN_DISABLE_TLSv1_0 BIT(8)
|
||||
|
||||
/**
|
||||
* struct tls_connection_params - Parameters for TLS connection
|
||||
* @ca_cert: File or reference name for CA X.509 certificate in PEM or DER
|
||||
* format
|
||||
* @ca_cert_blob: ca_cert as inlined data or %NULL if not used
|
||||
* @ca_cert_blob_len: ca_cert_blob length
|
||||
* @ca_path: Path to CA certificates (OpenSSL specific)
|
||||
* @subject_match: String to match in the subject of the peer certificate or
|
||||
* %NULL to allow all subjects
|
||||
* @altsubject_match: String to match in the alternative subject of the peer
|
||||
* certificate or %NULL to allow all alternative subjects
|
||||
* @suffix_match: String to suffix match in the dNSName or CN of the peer
|
||||
* certificate or %NULL to allow all domain names. This may allow subdomains an
|
||||
* wildcard certificates. Each domain name label must have a full match.
|
||||
* @domain_match: String to match in the dNSName or CN of the peer
|
||||
* certificate or %NULL to allow all domain names. This requires a full,
|
||||
* case-insensitive match.
|
||||
* @client_cert: File or reference name for client X.509 certificate in PEM or
|
||||
* DER format
|
||||
* @client_cert_blob: client_cert as inlined data or %NULL if not used
|
||||
* @client_cert_blob_len: client_cert_blob length
|
||||
* @private_key: File or reference name for client private key in PEM or DER
|
||||
* format (traditional format (RSA PRIVATE KEY) or PKCS#8 (PRIVATE KEY)
|
||||
* @private_key_blob: private_key as inlined data or %NULL if not used
|
||||
* @private_key_blob_len: private_key_blob length
|
||||
* @private_key_passwd: Passphrase for decrypted private key, %NULL if no
|
||||
* passphrase is used.
|
||||
* @dh_file: File name for DH/DSA data in PEM format, or %NULL if not used
|
||||
* @dh_blob: dh_file as inlined data or %NULL if not used
|
||||
* @dh_blob_len: dh_blob length
|
||||
* @engine: 1 = use engine (e.g., a smartcard) for private key operations
|
||||
* (this is OpenSSL specific for now)
|
||||
* @engine_id: engine id string (this is OpenSSL specific for now)
|
||||
* @ppin: pointer to the pin variable in the configuration
|
||||
* (this is OpenSSL specific for now)
|
||||
* @key_id: the private key's id when using engine (this is OpenSSL
|
||||
* specific for now)
|
||||
* @cert_id: the certificate's id when using engine
|
||||
* @ca_cert_id: the CA certificate's id when using engine
|
||||
* @openssl_ciphers: OpenSSL cipher configuration
|
||||
* @flags: Parameter options (TLS_CONN_*)
|
||||
* @ocsp_stapling_response: DER encoded file with cached OCSP stapling response
|
||||
* or %NULL if OCSP is not enabled
|
||||
*
|
||||
* TLS connection parameters to be configured with tls_connection_set_params()
|
||||
* and tls_global_set_params().
|
||||
*
|
||||
* Certificates and private key can be configured either as a reference name
|
||||
* (file path or reference to certificate store) or by providing the same data
|
||||
* as a pointer to the data in memory. Only one option will be used for each
|
||||
* field.
|
||||
*/
|
||||
struct tls_connection_params {
|
||||
const char *ca_cert;
|
||||
const u8 *ca_cert_blob;
|
||||
size_t ca_cert_blob_len;
|
||||
const char *ca_path;
|
||||
const char *subject_match;
|
||||
const char *altsubject_match;
|
||||
const char *suffix_match;
|
||||
const char *domain_match;
|
||||
const char *client_cert;
|
||||
const u8 *client_cert_blob;
|
||||
size_t client_cert_blob_len;
|
||||
const char *private_key;
|
||||
const u8 *private_key_blob;
|
||||
size_t private_key_blob_len;
|
||||
const char *private_key_passwd;
|
||||
const char *dh_file;
|
||||
const u8 *dh_blob;
|
||||
size_t dh_blob_len;
|
||||
|
||||
/* OpenSSL specific variables */
|
||||
int engine;
|
||||
const char *engine_id;
|
||||
const char *pin;
|
||||
const char *key_id;
|
||||
const char *cert_id;
|
||||
const char *ca_cert_id;
|
||||
const char *openssl_ciphers;
|
||||
|
||||
unsigned int flags;
|
||||
const char *ocsp_stapling_response;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* tls_init - Initialize TLS library
|
||||
* @conf: Configuration data for TLS library
|
||||
* Returns: Context data to be used as tls_ctx in calls to other functions,
|
||||
* or %NULL on failure.
|
||||
*
|
||||
* Called once during program startup and once for each RSN pre-authentication
|
||||
* session. In other words, there can be two concurrent TLS contexts. If global
|
||||
* library initialization is needed (i.e., one that is shared between both
|
||||
* authentication types), the TLS library wrapper should maintain a reference
|
||||
* counter and do global initialization only when moving from 0 to 1 reference.
|
||||
*/
|
||||
void * tls_init(const struct tls_config *conf);
|
||||
|
||||
/**
|
||||
* tls_deinit - Deinitialize TLS library
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
*
|
||||
* Called once during program shutdown and once for each RSN pre-authentication
|
||||
* session. If global library deinitialization is needed (i.e., one that is
|
||||
* shared between both authentication types), the TLS library wrapper should
|
||||
* maintain a reference counter and do global deinitialization only when moving
|
||||
* from 1 to 0 references.
|
||||
*/
|
||||
void tls_deinit(void *tls_ctx);
|
||||
|
||||
/**
|
||||
* tls_get_errors - Process pending errors
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* Returns: Number of found error, 0 if no errors detected.
|
||||
*
|
||||
* Process all pending TLS errors.
|
||||
*/
|
||||
int tls_get_errors(void *tls_ctx);
|
||||
|
||||
/**
|
||||
* tls_connection_init - Initialize a new TLS connection
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* Returns: Connection context data, conn for other function calls
|
||||
*/
|
||||
struct tls_connection * tls_connection_init(void *tls_ctx);
|
||||
|
||||
/**
|
||||
* tls_connection_deinit - Free TLS connection data
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
*
|
||||
* Release all resources allocated for TLS connection.
|
||||
*/
|
||||
void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn);
|
||||
|
||||
/**
|
||||
* tls_connection_established - Has the TLS connection been completed?
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* Returns: 1 if TLS connection has been completed, 0 if not.
|
||||
*/
|
||||
int tls_connection_established(void *tls_ctx, struct tls_connection *conn);
|
||||
|
||||
/**
|
||||
* tls_connection_shutdown - Shutdown TLS connection
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Shutdown current TLS connection without releasing all resources. New
|
||||
* connection can be started by using the same conn without having to call
|
||||
* tls_connection_init() or setting certificates etc. again. The new
|
||||
* connection should try to use session resumption.
|
||||
*/
|
||||
int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn);
|
||||
|
||||
enum {
|
||||
TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN = -4,
|
||||
TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED = -3,
|
||||
TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED = -2
|
||||
};
|
||||
|
||||
/**
|
||||
* tls_connection_set_params - Set TLS connection parameters
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @params: Connection parameters
|
||||
* Returns: 0 on success, -1 on failure,
|
||||
* TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on error causing PKCS#11 engine
|
||||
* failure, or
|
||||
* TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED (-3) on failure to verify the
|
||||
* PKCS#11 engine private key, or
|
||||
* TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN (-4) on PIN error causing PKCS#11 engine
|
||||
* failure.
|
||||
*/
|
||||
int __must_check
|
||||
tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
|
||||
const struct tls_connection_params *params);
|
||||
|
||||
/**
|
||||
* tls_global_set_params - Set TLS parameters for all TLS connection
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @params: Global TLS parameters
|
||||
* Returns: 0 on success, -1 on failure,
|
||||
* TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on error causing PKCS#11 engine
|
||||
* failure, or
|
||||
* TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED (-3) on failure to verify the
|
||||
* PKCS#11 engine private key, or
|
||||
* TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN (-4) on PIN error causing PKCS#11 engine
|
||||
* failure.
|
||||
*/
|
||||
int __must_check tls_global_set_params(
|
||||
void *tls_ctx, const struct tls_connection_params *params);
|
||||
|
||||
/**
|
||||
* tls_global_set_verify - Set global certificate verification options
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @check_crl: 0 = do not verify CRLs, 1 = verify CRL for the user certificate,
|
||||
* 2 = verify CRL for all certificates
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int __must_check tls_global_set_verify(void *tls_ctx, int check_crl);
|
||||
|
||||
/**
|
||||
* tls_connection_set_verify - Set certificate verification options
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @verify_peer: 1 = verify peer certificate
|
||||
* @flags: Connection flags (TLS_CONN_*)
|
||||
* @session_ctx: Session caching context or %NULL to use default
|
||||
* @session_ctx_len: Length of @session_ctx in bytes.
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int __must_check tls_connection_set_verify(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
int verify_peer,
|
||||
unsigned int flags,
|
||||
const u8 *session_ctx,
|
||||
size_t session_ctx_len);
|
||||
|
||||
/**
|
||||
* tls_connection_get_random - Get random data from TLS connection
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @data: Structure of client/server random data (filled on success)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int __must_check tls_connection_get_random(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
struct tls_random *data);
|
||||
|
||||
/**
|
||||
* tls_connection_prf - Use TLS-PRF to derive keying material
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @label: Label (e.g., description of the key) for PRF
|
||||
* @server_random_first: seed is 0 = client_random|server_random,
|
||||
* 1 = server_random|client_random
|
||||
* @skip_keyblock: Skip TLS key block from the beginning of PRF output
|
||||
* @out: Buffer for output data from TLS-PRF
|
||||
* @out_len: Length of the output buffer
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* tls_connection_prf() is required so that further keying material can be
|
||||
* derived from the master secret. Example implementation of this function is in
|
||||
* tls_prf_sha1_md5() when it is called with seed set to
|
||||
* client_random|server_random (or server_random|client_random). For TLSv1.2 and
|
||||
* newer, a different PRF is needed, though.
|
||||
*/
|
||||
int __must_check tls_connection_prf(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const char *label,
|
||||
int server_random_first,
|
||||
int skip_keyblock,
|
||||
u8 *out, size_t out_len);
|
||||
|
||||
/**
|
||||
* tls_connection_handshake - Process TLS handshake (client side)
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @in_data: Input data from TLS server
|
||||
* @appl_data: Pointer to application data pointer, or %NULL if dropped
|
||||
* Returns: Output data, %NULL on failure
|
||||
*
|
||||
* The caller is responsible for freeing the returned output data. If the final
|
||||
* handshake message includes application data, this is decrypted and
|
||||
* appl_data (if not %NULL) is set to point this data. The caller is
|
||||
* responsible for freeing appl_data.
|
||||
*
|
||||
* This function is used during TLS handshake. The first call is done with
|
||||
* in_data == %NULL and the library is expected to return ClientHello packet.
|
||||
* This packet is then send to the server and a response from server is given
|
||||
* to TLS library by calling this function again with in_data pointing to the
|
||||
* TLS message from the server.
|
||||
*
|
||||
* If the TLS handshake fails, this function may return %NULL. However, if the
|
||||
* TLS library has a TLS alert to send out, that should be returned as the
|
||||
* output data. In this case, tls_connection_get_failed() must return failure
|
||||
* (> 0).
|
||||
*
|
||||
* tls_connection_established() should return 1 once the TLS handshake has been
|
||||
* completed successfully.
|
||||
*/
|
||||
struct wpabuf * tls_connection_handshake(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data,
|
||||
struct wpabuf **appl_data);
|
||||
|
||||
struct wpabuf * tls_connection_handshake2(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data,
|
||||
struct wpabuf **appl_data,
|
||||
int *more_data_needed);
|
||||
|
||||
/**
|
||||
* tls_connection_server_handshake - Process TLS handshake (server side)
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @in_data: Input data from TLS peer
|
||||
* @appl_data: Pointer to application data pointer, or %NULL if dropped
|
||||
* Returns: Output data, %NULL on failure
|
||||
*
|
||||
* The caller is responsible for freeing the returned output data.
|
||||
*/
|
||||
struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data,
|
||||
struct wpabuf **appl_data);
|
||||
|
||||
/**
|
||||
* tls_connection_encrypt - Encrypt data into TLS tunnel
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @in_data: Plaintext data to be encrypted
|
||||
* Returns: Encrypted TLS data or %NULL on failure
|
||||
*
|
||||
* This function is used after TLS handshake has been completed successfully to
|
||||
* send data in the encrypted tunnel. The caller is responsible for freeing the
|
||||
* returned output data.
|
||||
*/
|
||||
struct wpabuf * tls_connection_encrypt(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data);
|
||||
|
||||
/**
|
||||
* tls_connection_decrypt - Decrypt data from TLS tunnel
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @in_data: Encrypted TLS data
|
||||
* Returns: Decrypted TLS data or %NULL on failure
|
||||
*
|
||||
* This function is used after TLS handshake has been completed successfully to
|
||||
* receive data from the encrypted tunnel. The caller is responsible for
|
||||
* freeing the returned output data.
|
||||
*/
|
||||
struct wpabuf * tls_connection_decrypt(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data);
|
||||
|
||||
struct wpabuf * tls_connection_decrypt2(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data,
|
||||
int *more_data_needed);
|
||||
|
||||
/**
|
||||
* tls_connection_resumed - Was session resumption used
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* Returns: 1 if current session used session resumption, 0 if not
|
||||
*/
|
||||
int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn);
|
||||
|
||||
enum {
|
||||
TLS_CIPHER_NONE,
|
||||
TLS_CIPHER_RC4_SHA /* 0x0005 */,
|
||||
TLS_CIPHER_AES128_SHA /* 0x002f */,
|
||||
TLS_CIPHER_RSA_DHE_AES128_SHA /* 0x0031 */,
|
||||
TLS_CIPHER_ANON_DH_AES128_SHA /* 0x0034 */
|
||||
};
|
||||
|
||||
/**
|
||||
* tls_connection_set_cipher_list - Configure acceptable cipher suites
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @ciphers: Zero (TLS_CIPHER_NONE) terminated list of allowed ciphers
|
||||
* (TLS_CIPHER_*).
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int __must_check tls_connection_set_cipher_list(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
u8 *ciphers);
|
||||
|
||||
/**
|
||||
* tls_get_version - Get the current TLS version number
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @buf: Buffer for returning the TLS version number
|
||||
* @buflen: buf size
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Get the currently used TLS version number.
|
||||
*/
|
||||
int __must_check tls_get_version(void *tls_ctx, struct tls_connection *conn,
|
||||
char *buf, size_t buflen);
|
||||
|
||||
/**
|
||||
* tls_get_cipher - Get current cipher name
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @buf: Buffer for the cipher name
|
||||
* @buflen: buf size
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Get the name of the currently used cipher.
|
||||
*/
|
||||
int __must_check tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
|
||||
char *buf, size_t buflen);
|
||||
|
||||
/**
|
||||
* tls_connection_enable_workaround - Enable TLS workaround options
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function is used to enable connection-specific workaround options for
|
||||
* buffer SSL/TLS implementations.
|
||||
*/
|
||||
int __must_check tls_connection_enable_workaround(void *tls_ctx,
|
||||
struct tls_connection *conn);
|
||||
|
||||
/**
|
||||
* tls_connection_client_hello_ext - Set TLS extension for ClientHello
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @ext_type: Extension type
|
||||
* @data: Extension payload (%NULL to remove extension)
|
||||
* @data_len: Extension payload length
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int __must_check tls_connection_client_hello_ext(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
int ext_type, const u8 *data,
|
||||
size_t data_len);
|
||||
|
||||
/**
|
||||
* tls_connection_get_failed - Get connection failure status
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
*
|
||||
* Returns >0 if connection has failed, 0 if not.
|
||||
*/
|
||||
int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn);
|
||||
|
||||
/**
|
||||
* tls_connection_get_read_alerts - Get connection read alert status
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* Returns: Number of times a fatal read (remote end reported error) has
|
||||
* happened during this connection.
|
||||
*/
|
||||
int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn);
|
||||
|
||||
/**
|
||||
* tls_connection_get_write_alerts - Get connection write alert status
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* Returns: Number of times a fatal write (locally detected error) has happened
|
||||
* during this connection.
|
||||
*/
|
||||
int tls_connection_get_write_alerts(void *tls_ctx,
|
||||
struct tls_connection *conn);
|
||||
|
||||
typedef int (*tls_session_ticket_cb)
|
||||
(void *ctx, const u8 *ticket, size_t len, const u8 *client_random,
|
||||
const u8 *server_random, u8 *master_secret);
|
||||
|
||||
int __must_check tls_connection_set_session_ticket_cb(
|
||||
void *tls_ctx, struct tls_connection *conn,
|
||||
tls_session_ticket_cb cb, void *ctx);
|
||||
|
||||
void tls_connection_set_log_cb(struct tls_connection *conn,
|
||||
void (*log_cb)(void *ctx, const char *msg),
|
||||
void *ctx);
|
||||
|
||||
#define TLS_BREAK_VERIFY_DATA BIT(0)
|
||||
#define TLS_BREAK_SRV_KEY_X_HASH BIT(1)
|
||||
#define TLS_BREAK_SRV_KEY_X_SIGNATURE BIT(2)
|
||||
#define TLS_DHE_PRIME_511B BIT(3)
|
||||
#define TLS_DHE_PRIME_767B BIT(4)
|
||||
#define TLS_DHE_PRIME_15 BIT(5)
|
||||
#define TLS_DHE_PRIME_58B BIT(6)
|
||||
#define TLS_DHE_NON_PRIME BIT(7)
|
||||
|
||||
void tls_connection_set_test_flags(struct tls_connection *conn, u32 flags);
|
||||
|
||||
int tls_get_library_version(char *buf, size_t buf_len);
|
||||
|
||||
void tls_connection_set_success_data(struct tls_connection *conn,
|
||||
struct wpabuf *data);
|
||||
|
||||
void tls_connection_set_success_data_resumed(struct tls_connection *conn);
|
||||
|
||||
const struct wpabuf *
|
||||
tls_connection_get_success_data(struct tls_connection *conn);
|
||||
|
||||
void tls_connection_remove_session(struct tls_connection *conn);
|
||||
|
||||
#endif /* TLS_H */
|
735
freebsd/contrib/wpa/src/crypto/tls_internal.c
Normal file
735
freebsd/contrib/wpa/src/crypto/tls_internal.c
Normal file
@ -0,0 +1,735 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* TLS interface functions and an internal TLS implementation
|
||||
* Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*
|
||||
* This file interface functions for hostapd/wpa_supplicant to use the
|
||||
* integrated TLSv1 implementation.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "tls.h"
|
||||
#include "tls/tlsv1_client.h"
|
||||
#include "tls/tlsv1_server.h"
|
||||
|
||||
|
||||
static int tls_ref_count = 0;
|
||||
|
||||
struct tls_global {
|
||||
int server;
|
||||
struct tlsv1_credentials *server_cred;
|
||||
int check_crl;
|
||||
};
|
||||
|
||||
struct tls_connection {
|
||||
struct tlsv1_client *client;
|
||||
struct tlsv1_server *server;
|
||||
struct tls_global *global;
|
||||
};
|
||||
|
||||
|
||||
void * tls_init(const struct tls_config *conf)
|
||||
{
|
||||
struct tls_global *global;
|
||||
|
||||
if (tls_ref_count == 0) {
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (tlsv1_client_global_init())
|
||||
return NULL;
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (tlsv1_server_global_init())
|
||||
return NULL;
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
}
|
||||
tls_ref_count++;
|
||||
|
||||
global = os_zalloc(sizeof(*global));
|
||||
if (global == NULL)
|
||||
return NULL;
|
||||
|
||||
return global;
|
||||
}
|
||||
|
||||
void tls_deinit(void *ssl_ctx)
|
||||
{
|
||||
struct tls_global *global = ssl_ctx;
|
||||
tls_ref_count--;
|
||||
if (tls_ref_count == 0) {
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
tlsv1_client_global_deinit();
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
tlsv1_cred_free(global->server_cred);
|
||||
tlsv1_server_global_deinit();
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
}
|
||||
os_free(global);
|
||||
}
|
||||
|
||||
|
||||
int tls_get_errors(void *tls_ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct tls_connection * tls_connection_init(void *tls_ctx)
|
||||
{
|
||||
struct tls_connection *conn;
|
||||
struct tls_global *global = tls_ctx;
|
||||
|
||||
conn = os_zalloc(sizeof(*conn));
|
||||
if (conn == NULL)
|
||||
return NULL;
|
||||
conn->global = global;
|
||||
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (!global->server) {
|
||||
conn->client = tlsv1_client_init();
|
||||
if (conn->client == NULL) {
|
||||
os_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (global->server) {
|
||||
conn->server = tlsv1_server_init(global->server_cred);
|
||||
if (conn->server == NULL) {
|
||||
os_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
void tls_connection_set_test_flags(struct tls_connection *conn, u32 flags)
|
||||
{
|
||||
if (conn->server)
|
||||
tlsv1_server_set_test_flags(conn->server, flags);
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
|
||||
|
||||
void tls_connection_set_log_cb(struct tls_connection *conn,
|
||||
void (*log_cb)(void *ctx, const char *msg),
|
||||
void *ctx)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
tlsv1_server_set_log_cb(conn->server, log_cb, ctx);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
}
|
||||
|
||||
|
||||
void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
if (conn == NULL)
|
||||
return;
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client)
|
||||
tlsv1_client_deinit(conn->client);
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
tlsv1_server_deinit(conn->server);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
os_free(conn);
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client)
|
||||
return tlsv1_client_established(conn->client);
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
return tlsv1_server_established(conn->server);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client)
|
||||
return tlsv1_client_shutdown(conn->client);
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
return tlsv1_server_shutdown(conn->server);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
|
||||
const struct tls_connection_params *params)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
struct tlsv1_credentials *cred;
|
||||
|
||||
if (conn->client == NULL)
|
||||
return -1;
|
||||
|
||||
cred = tlsv1_cred_alloc();
|
||||
if (cred == NULL)
|
||||
return -1;
|
||||
|
||||
if (params->subject_match) {
|
||||
wpa_printf(MSG_INFO, "TLS: subject_match not supported");
|
||||
tlsv1_cred_free(cred);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (params->altsubject_match) {
|
||||
wpa_printf(MSG_INFO, "TLS: altsubject_match not supported");
|
||||
tlsv1_cred_free(cred);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (params->suffix_match) {
|
||||
wpa_printf(MSG_INFO, "TLS: suffix_match not supported");
|
||||
tlsv1_cred_free(cred);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (params->domain_match) {
|
||||
wpa_printf(MSG_INFO, "TLS: domain_match not supported");
|
||||
tlsv1_cred_free(cred);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (params->openssl_ciphers) {
|
||||
wpa_printf(MSG_INFO, "TLS: openssl_ciphers not supported");
|
||||
tlsv1_cred_free(cred);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tlsv1_set_ca_cert(cred, params->ca_cert,
|
||||
params->ca_cert_blob, params->ca_cert_blob_len,
|
||||
params->ca_path)) {
|
||||
wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA "
|
||||
"certificates");
|
||||
tlsv1_cred_free(cred);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tlsv1_set_cert(cred, params->client_cert,
|
||||
params->client_cert_blob,
|
||||
params->client_cert_blob_len)) {
|
||||
wpa_printf(MSG_INFO, "TLS: Failed to configure client "
|
||||
"certificate");
|
||||
tlsv1_cred_free(cred);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tlsv1_set_private_key(cred, params->private_key,
|
||||
params->private_key_passwd,
|
||||
params->private_key_blob,
|
||||
params->private_key_blob_len)) {
|
||||
wpa_printf(MSG_INFO, "TLS: Failed to load private key");
|
||||
tlsv1_cred_free(cred);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob,
|
||||
params->dh_blob_len)) {
|
||||
wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters");
|
||||
tlsv1_cred_free(cred);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tlsv1_client_set_cred(conn->client, cred) < 0) {
|
||||
tlsv1_cred_free(cred);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tlsv1_client_set_time_checks(
|
||||
conn->client, !(params->flags & TLS_CONN_DISABLE_TIME_CHECKS));
|
||||
|
||||
return 0;
|
||||
#else /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
return -1;
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
}
|
||||
|
||||
|
||||
int tls_global_set_params(void *tls_ctx,
|
||||
const struct tls_connection_params *params)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
struct tls_global *global = tls_ctx;
|
||||
struct tlsv1_credentials *cred;
|
||||
|
||||
/* Currently, global parameters are only set when running in server
|
||||
* mode. */
|
||||
global->server = 1;
|
||||
tlsv1_cred_free(global->server_cred);
|
||||
global->server_cred = cred = tlsv1_cred_alloc();
|
||||
if (cred == NULL)
|
||||
return -1;
|
||||
|
||||
if (tlsv1_set_ca_cert(cred, params->ca_cert, params->ca_cert_blob,
|
||||
params->ca_cert_blob_len, params->ca_path)) {
|
||||
wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA "
|
||||
"certificates");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tlsv1_set_cert(cred, params->client_cert, params->client_cert_blob,
|
||||
params->client_cert_blob_len)) {
|
||||
wpa_printf(MSG_INFO, "TLS: Failed to configure server "
|
||||
"certificate");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tlsv1_set_private_key(cred, params->private_key,
|
||||
params->private_key_passwd,
|
||||
params->private_key_blob,
|
||||
params->private_key_blob_len)) {
|
||||
wpa_printf(MSG_INFO, "TLS: Failed to load private key");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob,
|
||||
params->dh_blob_len)) {
|
||||
wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
}
|
||||
|
||||
|
||||
int tls_global_set_verify(void *tls_ctx, int check_crl)
|
||||
{
|
||||
struct tls_global *global = tls_ctx;
|
||||
global->check_crl = check_crl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
|
||||
int verify_peer, unsigned int flags,
|
||||
const u8 *session_ctx, size_t session_ctx_len)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
return tlsv1_server_set_verify(conn->server, verify_peer);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn,
|
||||
struct tls_random *data)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client)
|
||||
return tlsv1_client_get_random(conn->client, data);
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
return tlsv1_server_get_random(conn->server, data);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int tls_get_keyblock_size(struct tls_connection *conn)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client)
|
||||
return tlsv1_client_get_keyblock_size(conn->client);
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
return tlsv1_server_get_keyblock_size(conn->server);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
|
||||
const char *label, int server_random_first,
|
||||
int skip_keyblock, u8 *out, size_t out_len)
|
||||
{
|
||||
int ret = -1, skip = 0;
|
||||
u8 *tmp_out = NULL;
|
||||
u8 *_out = out;
|
||||
|
||||
if (skip_keyblock) {
|
||||
skip = tls_get_keyblock_size(conn);
|
||||
if (skip < 0)
|
||||
return -1;
|
||||
tmp_out = os_malloc(skip + out_len);
|
||||
if (!tmp_out)
|
||||
return -1;
|
||||
_out = tmp_out;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client) {
|
||||
ret = tlsv1_client_prf(conn->client, label,
|
||||
server_random_first,
|
||||
_out, out_len);
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server) {
|
||||
ret = tlsv1_server_prf(conn->server, label,
|
||||
server_random_first,
|
||||
_out, out_len);
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
if (ret == 0 && skip_keyblock)
|
||||
os_memcpy(out, _out + skip, out_len);
|
||||
bin_clear_free(tmp_out, skip);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * tls_connection_handshake(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data,
|
||||
struct wpabuf **appl_data)
|
||||
{
|
||||
return tls_connection_handshake2(tls_ctx, conn, in_data, appl_data,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * tls_connection_handshake2(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data,
|
||||
struct wpabuf **appl_data,
|
||||
int *need_more_data)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
u8 *res, *ad;
|
||||
size_t res_len, ad_len;
|
||||
struct wpabuf *out;
|
||||
|
||||
if (conn->client == NULL)
|
||||
return NULL;
|
||||
|
||||
ad = NULL;
|
||||
res = tlsv1_client_handshake(conn->client,
|
||||
in_data ? wpabuf_head(in_data) : NULL,
|
||||
in_data ? wpabuf_len(in_data) : 0,
|
||||
&res_len, &ad, &ad_len, need_more_data);
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
out = wpabuf_alloc_ext_data(res, res_len);
|
||||
if (out == NULL) {
|
||||
os_free(res);
|
||||
os_free(ad);
|
||||
return NULL;
|
||||
}
|
||||
if (appl_data) {
|
||||
if (ad) {
|
||||
*appl_data = wpabuf_alloc_ext_data(ad, ad_len);
|
||||
if (*appl_data == NULL)
|
||||
os_free(ad);
|
||||
} else
|
||||
*appl_data = NULL;
|
||||
} else
|
||||
os_free(ad);
|
||||
|
||||
return out;
|
||||
#else /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
return NULL;
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data,
|
||||
struct wpabuf **appl_data)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
u8 *res;
|
||||
size_t res_len;
|
||||
struct wpabuf *out;
|
||||
|
||||
if (conn->server == NULL)
|
||||
return NULL;
|
||||
|
||||
if (appl_data)
|
||||
*appl_data = NULL;
|
||||
|
||||
res = tlsv1_server_handshake(conn->server, wpabuf_head(in_data),
|
||||
wpabuf_len(in_data), &res_len);
|
||||
if (res == NULL && tlsv1_server_established(conn->server))
|
||||
return wpabuf_alloc(0);
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
out = wpabuf_alloc_ext_data(res, res_len);
|
||||
if (out == NULL) {
|
||||
os_free(res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return out;
|
||||
#else /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return NULL;
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * tls_connection_encrypt(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client) {
|
||||
struct wpabuf *buf;
|
||||
int res;
|
||||
buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
res = tlsv1_client_encrypt(conn->client, wpabuf_head(in_data),
|
||||
wpabuf_len(in_data),
|
||||
wpabuf_mhead(buf),
|
||||
wpabuf_size(buf));
|
||||
if (res < 0) {
|
||||
wpabuf_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
wpabuf_put(buf, res);
|
||||
return buf;
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server) {
|
||||
struct wpabuf *buf;
|
||||
int res;
|
||||
buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
res = tlsv1_server_encrypt(conn->server, wpabuf_head(in_data),
|
||||
wpabuf_len(in_data),
|
||||
wpabuf_mhead(buf),
|
||||
wpabuf_size(buf));
|
||||
if (res < 0) {
|
||||
wpabuf_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
wpabuf_put(buf, res);
|
||||
return buf;
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * tls_connection_decrypt(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data)
|
||||
{
|
||||
return tls_connection_decrypt2(tls_ctx, conn, in_data, NULL);
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * tls_connection_decrypt2(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data,
|
||||
int *need_more_data)
|
||||
{
|
||||
if (need_more_data)
|
||||
*need_more_data = 0;
|
||||
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client) {
|
||||
return tlsv1_client_decrypt(conn->client, wpabuf_head(in_data),
|
||||
wpabuf_len(in_data),
|
||||
need_more_data);
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server) {
|
||||
struct wpabuf *buf;
|
||||
int res;
|
||||
buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
res = tlsv1_server_decrypt(conn->server, wpabuf_head(in_data),
|
||||
wpabuf_len(in_data),
|
||||
wpabuf_mhead(buf),
|
||||
wpabuf_size(buf));
|
||||
if (res < 0) {
|
||||
wpabuf_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
wpabuf_put(buf, res);
|
||||
return buf;
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client)
|
||||
return tlsv1_client_resumed(conn->client);
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
return tlsv1_server_resumed(conn->server);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
|
||||
u8 *ciphers)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client)
|
||||
return tlsv1_client_set_cipher_list(conn->client, ciphers);
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
return tlsv1_server_set_cipher_list(conn->server, ciphers);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
/* TODO */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
if (conn == NULL)
|
||||
return -1;
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client)
|
||||
return tlsv1_client_get_cipher(conn->client, buf, buflen);
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
return tlsv1_server_get_cipher(conn->server, buf, buflen);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_enable_workaround(void *tls_ctx,
|
||||
struct tls_connection *conn)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn,
|
||||
int ext_type, const u8 *data,
|
||||
size_t data_len)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client) {
|
||||
return tlsv1_client_hello_ext(conn->client, ext_type,
|
||||
data, data_len);
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_get_write_alerts(void *tls_ctx,
|
||||
struct tls_connection *conn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_set_session_ticket_cb(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
tls_session_ticket_cb cb,
|
||||
void *ctx)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client) {
|
||||
tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server) {
|
||||
tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int tls_get_library_version(char *buf, size_t buf_len)
|
||||
{
|
||||
return os_snprintf(buf, buf_len, "internal");
|
||||
}
|
||||
|
||||
|
||||
void tls_connection_set_success_data(struct tls_connection *conn,
|
||||
struct wpabuf *data)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void tls_connection_set_success_data_resumed(struct tls_connection *conn)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const struct wpabuf *
|
||||
tls_connection_get_success_data(struct tls_connection *conn)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void tls_connection_remove_session(struct tls_connection *conn)
|
||||
{
|
||||
}
|
4704
freebsd/contrib/wpa/src/drivers/driver.h
Normal file
4704
freebsd/contrib/wpa/src/drivers/driver.h
Normal file
File diff suppressed because it is too large
Load Diff
1675
freebsd/contrib/wpa/src/drivers/driver_bsd.c
Normal file
1675
freebsd/contrib/wpa/src/drivers/driver_bsd.c
Normal file
File diff suppressed because it is too large
Load Diff
222
freebsd/contrib/wpa/src/drivers/driver_common.c
Normal file
222
freebsd/contrib/wpa/src/drivers/driver_common.c
Normal file
@ -0,0 +1,222 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* Common driver-related functions
|
||||
* Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "driver.h"
|
||||
|
||||
void wpa_scan_results_free(struct wpa_scan_results *res)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (res == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < res->num; i++)
|
||||
os_free(res->res[i]);
|
||||
os_free(res->res);
|
||||
os_free(res);
|
||||
}
|
||||
|
||||
|
||||
const char * event_to_string(enum wpa_event_type event)
|
||||
{
|
||||
#define E2S(n) case EVENT_ ## n: return #n
|
||||
switch (event) {
|
||||
E2S(ASSOC);
|
||||
E2S(DISASSOC);
|
||||
E2S(MICHAEL_MIC_FAILURE);
|
||||
E2S(SCAN_RESULTS);
|
||||
E2S(ASSOCINFO);
|
||||
E2S(INTERFACE_STATUS);
|
||||
E2S(PMKID_CANDIDATE);
|
||||
E2S(STKSTART);
|
||||
E2S(TDLS);
|
||||
E2S(FT_RESPONSE);
|
||||
E2S(IBSS_RSN_START);
|
||||
E2S(AUTH);
|
||||
E2S(DEAUTH);
|
||||
E2S(ASSOC_REJECT);
|
||||
E2S(AUTH_TIMED_OUT);
|
||||
E2S(ASSOC_TIMED_OUT);
|
||||
E2S(WPS_BUTTON_PUSHED);
|
||||
E2S(TX_STATUS);
|
||||
E2S(RX_FROM_UNKNOWN);
|
||||
E2S(RX_MGMT);
|
||||
E2S(REMAIN_ON_CHANNEL);
|
||||
E2S(CANCEL_REMAIN_ON_CHANNEL);
|
||||
E2S(RX_PROBE_REQ);
|
||||
E2S(NEW_STA);
|
||||
E2S(EAPOL_RX);
|
||||
E2S(SIGNAL_CHANGE);
|
||||
E2S(INTERFACE_ENABLED);
|
||||
E2S(INTERFACE_DISABLED);
|
||||
E2S(CHANNEL_LIST_CHANGED);
|
||||
E2S(INTERFACE_UNAVAILABLE);
|
||||
E2S(BEST_CHANNEL);
|
||||
E2S(UNPROT_DEAUTH);
|
||||
E2S(UNPROT_DISASSOC);
|
||||
E2S(STATION_LOW_ACK);
|
||||
E2S(IBSS_PEER_LOST);
|
||||
E2S(DRIVER_GTK_REKEY);
|
||||
E2S(SCHED_SCAN_STOPPED);
|
||||
E2S(DRIVER_CLIENT_POLL_OK);
|
||||
E2S(EAPOL_TX_STATUS);
|
||||
E2S(CH_SWITCH);
|
||||
E2S(WNM);
|
||||
E2S(CONNECT_FAILED_REASON);
|
||||
E2S(DFS_RADAR_DETECTED);
|
||||
E2S(DFS_CAC_FINISHED);
|
||||
E2S(DFS_CAC_ABORTED);
|
||||
E2S(DFS_NOP_FINISHED);
|
||||
E2S(SURVEY);
|
||||
E2S(SCAN_STARTED);
|
||||
E2S(AVOID_FREQUENCIES);
|
||||
E2S(NEW_PEER_CANDIDATE);
|
||||
E2S(ACS_CHANNEL_SELECTED);
|
||||
E2S(DFS_CAC_STARTED);
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
#undef E2S
|
||||
}
|
||||
|
||||
|
||||
const char * channel_width_to_string(enum chan_width width)
|
||||
{
|
||||
switch (width) {
|
||||
case CHAN_WIDTH_20_NOHT:
|
||||
return "20 MHz (no HT)";
|
||||
case CHAN_WIDTH_20:
|
||||
return "20 MHz";
|
||||
case CHAN_WIDTH_40:
|
||||
return "40 MHz";
|
||||
case CHAN_WIDTH_80:
|
||||
return "80 MHz";
|
||||
case CHAN_WIDTH_80P80:
|
||||
return "80+80 MHz";
|
||||
case CHAN_WIDTH_160:
|
||||
return "160 MHz";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int ht_supported(const struct hostapd_hw_modes *mode)
|
||||
{
|
||||
if (!(mode->flags & HOSTAPD_MODE_FLAG_HT_INFO_KNOWN)) {
|
||||
/*
|
||||
* The driver did not indicate whether it supports HT. Assume
|
||||
* it does to avoid connection issues.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* IEEE Std 802.11n-2009 20.1.1:
|
||||
* An HT non-AP STA shall support all EQM rates for one spatial stream.
|
||||
*/
|
||||
return mode->mcs_set[0] == 0xff;
|
||||
}
|
||||
|
||||
|
||||
int vht_supported(const struct hostapd_hw_modes *mode)
|
||||
{
|
||||
if (!(mode->flags & HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN)) {
|
||||
/*
|
||||
* The driver did not indicate whether it supports VHT. Assume
|
||||
* it does to avoid connection issues.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* A VHT non-AP STA shall support MCS 0-7 for one spatial stream.
|
||||
* TODO: Verify if this complies with the standard
|
||||
*/
|
||||
return (mode->vht_mcs_set[0] & 0x3) != 3;
|
||||
}
|
||||
|
||||
|
||||
static int wpa_check_wowlan_trigger(const char *start, const char *trigger,
|
||||
int capa_trigger, u8 *param_trigger)
|
||||
{
|
||||
if (os_strcmp(start, trigger) != 0)
|
||||
return 0;
|
||||
if (!capa_trigger)
|
||||
return 0;
|
||||
|
||||
*param_trigger = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
struct wowlan_triggers *
|
||||
wpa_get_wowlan_triggers(const char *wowlan_triggers,
|
||||
const struct wpa_driver_capa *capa)
|
||||
{
|
||||
struct wowlan_triggers *triggers;
|
||||
char *start, *end, *buf;
|
||||
int last;
|
||||
|
||||
if (!wowlan_triggers)
|
||||
return NULL;
|
||||
|
||||
buf = os_strdup(wowlan_triggers);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
triggers = os_zalloc(sizeof(*triggers));
|
||||
if (triggers == NULL)
|
||||
goto out;
|
||||
|
||||
#define CHECK_TRIGGER(trigger) \
|
||||
wpa_check_wowlan_trigger(start, #trigger, \
|
||||
capa->wowlan_triggers.trigger, \
|
||||
&triggers->trigger)
|
||||
|
||||
start = buf;
|
||||
while (*start != '\0') {
|
||||
while (isblank(*start))
|
||||
start++;
|
||||
if (*start == '\0')
|
||||
break;
|
||||
end = start;
|
||||
while (!isblank(*end) && *end != '\0')
|
||||
end++;
|
||||
last = *end == '\0';
|
||||
*end = '\0';
|
||||
|
||||
if (!CHECK_TRIGGER(any) &&
|
||||
!CHECK_TRIGGER(disconnect) &&
|
||||
!CHECK_TRIGGER(magic_pkt) &&
|
||||
!CHECK_TRIGGER(gtk_rekey_failure) &&
|
||||
!CHECK_TRIGGER(eap_identity_req) &&
|
||||
!CHECK_TRIGGER(four_way_handshake) &&
|
||||
!CHECK_TRIGGER(rfkill_release)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Unknown/unsupported wowlan trigger '%s'",
|
||||
start);
|
||||
os_free(triggers);
|
||||
triggers = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (last)
|
||||
break;
|
||||
start = end + 1;
|
||||
}
|
||||
#undef CHECK_TRIGGER
|
||||
|
||||
out:
|
||||
os_free(buf);
|
||||
return triggers;
|
||||
}
|
3221
freebsd/contrib/wpa/src/drivers/driver_ndis.c
Normal file
3221
freebsd/contrib/wpa/src/drivers/driver_ndis.c
Normal file
File diff suppressed because it is too large
Load Diff
59
freebsd/contrib/wpa/src/drivers/driver_ndis.h
Normal file
59
freebsd/contrib/wpa/src/drivers/driver_ndis.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* WPA Supplicant - Windows/NDIS driver interface
|
||||
* Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef DRIVER_NDIS_H
|
||||
#define DRIVER_NDIS_H
|
||||
|
||||
#ifdef CONFIG_NDIS_EVENTS_INTEGRATED
|
||||
struct ndis_events_data;
|
||||
struct ndis_events_data * ndis_events_init(HANDLE *read_pipe, HANDLE *event,
|
||||
const char *ifname,
|
||||
const char *desc);
|
||||
void ndis_events_deinit(struct ndis_events_data *events);
|
||||
#endif /* CONFIG_NDIS_EVENTS_INTEGRATED */
|
||||
|
||||
struct ndis_pmkid_entry {
|
||||
struct ndis_pmkid_entry *next;
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 pmkid[16];
|
||||
};
|
||||
|
||||
struct wpa_driver_ndis_data {
|
||||
void *ctx;
|
||||
char ifname[100]; /* GUID: {7EE3EFE5-C165-472F-986D-F6FBEDFE8C8D} */
|
||||
#ifdef _WIN32_WCE
|
||||
TCHAR *adapter_name;
|
||||
HANDLE event_queue; /* NDISUIO notifier MsgQueue */
|
||||
HANDLE connected_event; /* WpaSupplicantConnected event */
|
||||
#endif /* _WIN32_WCE */
|
||||
u8 own_addr[ETH_ALEN];
|
||||
#ifdef CONFIG_USE_NDISUIO
|
||||
HANDLE ndisuio;
|
||||
#else /* CONFIG_USE_NDISUIO */
|
||||
LPADAPTER adapter;
|
||||
#endif /* CONFIG_USE_NDISUIO */
|
||||
u8 bssid[ETH_ALEN];
|
||||
|
||||
int has_capability;
|
||||
int no_of_pmkid;
|
||||
int radio_enabled;
|
||||
struct wpa_driver_capa capa;
|
||||
struct ndis_pmkid_entry *pmkid;
|
||||
char *adapter_desc;
|
||||
int wired;
|
||||
int native80211;
|
||||
int mode;
|
||||
int wzc_disabled;
|
||||
int oid_bssid_set;
|
||||
#ifdef CONFIG_NDIS_EVENTS_INTEGRATED
|
||||
HANDLE events_pipe, event_avail;
|
||||
struct ndis_events_data *events;
|
||||
#endif /* CONFIG_NDIS_EVENTS_INTEGRATED */
|
||||
};
|
||||
|
||||
#endif /* DRIVER_NDIS_H */
|
277
freebsd/contrib/wpa/src/drivers/driver_nl80211.h
Normal file
277
freebsd/contrib/wpa/src/drivers/driver_nl80211.h
Normal file
@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Driver interaction with Linux nl80211/cfg80211 - definitions
|
||||
* Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2003-2004, Instant802 Networks, Inc.
|
||||
* Copyright (c) 2005-2006, Devicescape Software, Inc.
|
||||
* Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright (c) 2009-2010, Atheros Communications
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef DRIVER_NL80211_H
|
||||
#define DRIVER_NL80211_H
|
||||
|
||||
#include "nl80211_copy.h"
|
||||
#include "utils/list.h"
|
||||
#include "driver.h"
|
||||
|
||||
#ifdef CONFIG_LIBNL20
|
||||
/* libnl 2.0 compatibility code */
|
||||
#define nl_handle nl_sock
|
||||
#define nl80211_handle_alloc nl_socket_alloc_cb
|
||||
#define nl80211_handle_destroy nl_socket_free
|
||||
#endif /* CONFIG_LIBNL20 */
|
||||
|
||||
struct nl80211_global {
|
||||
struct dl_list interfaces;
|
||||
int if_add_ifindex;
|
||||
u64 if_add_wdevid;
|
||||
int if_add_wdevid_set;
|
||||
struct netlink_data *netlink;
|
||||
struct nl_cb *nl_cb;
|
||||
struct nl_handle *nl;
|
||||
int nl80211_id;
|
||||
int ioctl_sock; /* socket for ioctl() use */
|
||||
|
||||
struct nl_handle *nl_event;
|
||||
};
|
||||
|
||||
struct nl80211_wiphy_data {
|
||||
struct dl_list list;
|
||||
struct dl_list bsss;
|
||||
struct dl_list drvs;
|
||||
|
||||
struct nl_handle *nl_beacons;
|
||||
struct nl_cb *nl_cb;
|
||||
|
||||
int wiphy_idx;
|
||||
};
|
||||
|
||||
struct i802_bss {
|
||||
struct wpa_driver_nl80211_data *drv;
|
||||
struct i802_bss *next;
|
||||
int ifindex;
|
||||
int br_ifindex;
|
||||
u64 wdev_id;
|
||||
char ifname[IFNAMSIZ + 1];
|
||||
char brname[IFNAMSIZ];
|
||||
unsigned int beacon_set:1;
|
||||
unsigned int added_if_into_bridge:1;
|
||||
unsigned int added_bridge:1;
|
||||
unsigned int in_deinit:1;
|
||||
unsigned int wdev_id_set:1;
|
||||
unsigned int added_if:1;
|
||||
unsigned int static_ap:1;
|
||||
|
||||
u8 addr[ETH_ALEN];
|
||||
|
||||
int freq;
|
||||
int bandwidth;
|
||||
int if_dynamic;
|
||||
|
||||
void *ctx;
|
||||
struct nl_handle *nl_preq, *nl_mgmt;
|
||||
struct nl_cb *nl_cb;
|
||||
|
||||
struct nl80211_wiphy_data *wiphy_data;
|
||||
struct dl_list wiphy_list;
|
||||
};
|
||||
|
||||
struct wpa_driver_nl80211_data {
|
||||
struct nl80211_global *global;
|
||||
struct dl_list list;
|
||||
struct dl_list wiphy_list;
|
||||
char phyname[32];
|
||||
u8 perm_addr[ETH_ALEN];
|
||||
void *ctx;
|
||||
int ifindex;
|
||||
int if_removed;
|
||||
int if_disabled;
|
||||
int ignore_if_down_event;
|
||||
struct rfkill_data *rfkill;
|
||||
struct wpa_driver_capa capa;
|
||||
u8 *extended_capa, *extended_capa_mask;
|
||||
unsigned int extended_capa_len;
|
||||
int has_capability;
|
||||
|
||||
int operstate;
|
||||
|
||||
int scan_complete_events;
|
||||
enum scan_states {
|
||||
NO_SCAN, SCAN_REQUESTED, SCAN_STARTED, SCAN_COMPLETED,
|
||||
SCAN_ABORTED, SCHED_SCAN_STARTED, SCHED_SCAN_STOPPED,
|
||||
SCHED_SCAN_RESULTS
|
||||
} scan_state;
|
||||
|
||||
u8 auth_bssid[ETH_ALEN];
|
||||
u8 auth_attempt_bssid[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 prev_bssid[ETH_ALEN];
|
||||
int associated;
|
||||
u8 ssid[SSID_MAX_LEN];
|
||||
size_t ssid_len;
|
||||
enum nl80211_iftype nlmode;
|
||||
enum nl80211_iftype ap_scan_as_station;
|
||||
unsigned int assoc_freq;
|
||||
|
||||
int monitor_sock;
|
||||
int monitor_ifidx;
|
||||
int monitor_refcount;
|
||||
|
||||
unsigned int disabled_11b_rates:1;
|
||||
unsigned int pending_remain_on_chan:1;
|
||||
unsigned int in_interface_list:1;
|
||||
unsigned int device_ap_sme:1;
|
||||
unsigned int poll_command_supported:1;
|
||||
unsigned int data_tx_status:1;
|
||||
unsigned int scan_for_auth:1;
|
||||
unsigned int retry_auth:1;
|
||||
unsigned int use_monitor:1;
|
||||
unsigned int ignore_next_local_disconnect:1;
|
||||
unsigned int ignore_next_local_deauth:1;
|
||||
unsigned int hostapd:1;
|
||||
unsigned int start_mode_ap:1;
|
||||
unsigned int start_iface_up:1;
|
||||
unsigned int test_use_roc_tx:1;
|
||||
unsigned int ignore_deauth_event:1;
|
||||
unsigned int vendor_cmd_test_avail:1;
|
||||
unsigned int roaming_vendor_cmd_avail:1;
|
||||
unsigned int dfs_vendor_cmd_avail:1;
|
||||
unsigned int have_low_prio_scan:1;
|
||||
unsigned int force_connect_cmd:1;
|
||||
unsigned int addr_changed:1;
|
||||
unsigned int get_features_vendor_cmd_avail:1;
|
||||
unsigned int set_rekey_offload:1;
|
||||
unsigned int p2p_go_ctwindow_supported:1;
|
||||
unsigned int setband_vendor_cmd_avail:1;
|
||||
unsigned int get_pref_freq_list:1;
|
||||
unsigned int set_prob_oper_freq:1;
|
||||
|
||||
u64 remain_on_chan_cookie;
|
||||
u64 send_action_cookie;
|
||||
|
||||
unsigned int last_mgmt_freq;
|
||||
|
||||
struct wpa_driver_scan_filter *filter_ssids;
|
||||
size_t num_filter_ssids;
|
||||
|
||||
struct i802_bss *first_bss;
|
||||
|
||||
int eapol_tx_sock;
|
||||
|
||||
int eapol_sock; /* socket for EAPOL frames */
|
||||
|
||||
struct nl_handle *rtnl_sk; /* nl_sock for NETLINK_ROUTE */
|
||||
|
||||
int default_if_indices[16];
|
||||
int *if_indices;
|
||||
int num_if_indices;
|
||||
|
||||
/* From failed authentication command */
|
||||
int auth_freq;
|
||||
u8 auth_bssid_[ETH_ALEN];
|
||||
u8 auth_ssid[SSID_MAX_LEN];
|
||||
size_t auth_ssid_len;
|
||||
int auth_alg;
|
||||
u8 *auth_ie;
|
||||
size_t auth_ie_len;
|
||||
u8 auth_wep_key[4][16];
|
||||
size_t auth_wep_key_len[4];
|
||||
int auth_wep_tx_keyidx;
|
||||
int auth_local_state_change;
|
||||
int auth_p2p;
|
||||
};
|
||||
|
||||
struct nl_msg;
|
||||
|
||||
void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
|
||||
struct nl_msg *msg, int flags, uint8_t cmd);
|
||||
struct nl_msg * nl80211_cmd_msg(struct i802_bss *bss, int flags, uint8_t cmd);
|
||||
struct nl_msg * nl80211_drv_msg(struct wpa_driver_nl80211_data *drv, int flags,
|
||||
uint8_t cmd);
|
||||
struct nl_msg * nl80211_bss_msg(struct i802_bss *bss, int flags, uint8_t cmd);
|
||||
int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv, struct nl_msg *msg,
|
||||
int (*valid_handler)(struct nl_msg *, void *),
|
||||
void *valid_data);
|
||||
int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
|
||||
const char *ifname, enum nl80211_iftype iftype,
|
||||
const u8 *addr, int wds,
|
||||
int (*handler)(struct nl_msg *, void *),
|
||||
void *arg, int use_existing);
|
||||
void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv, int ifidx);
|
||||
unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv);
|
||||
enum chan_width convert2width(int width);
|
||||
void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv);
|
||||
struct i802_bss * get_bss_ifindex(struct wpa_driver_nl80211_data *drv,
|
||||
int ifindex);
|
||||
int is_ap_interface(enum nl80211_iftype nlmode);
|
||||
int is_sta_interface(enum nl80211_iftype nlmode);
|
||||
int wpa_driver_nl80211_authenticate_retry(struct wpa_driver_nl80211_data *drv);
|
||||
int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
|
||||
struct wpa_signal_info *sig);
|
||||
int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
|
||||
struct wpa_signal_info *sig_change);
|
||||
int nl80211_get_wiphy_index(struct i802_bss *bss);
|
||||
int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
|
||||
enum nl80211_iftype nlmode);
|
||||
int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
|
||||
const u8 *addr, int cmd, u16 reason_code,
|
||||
int local_state_change);
|
||||
|
||||
int nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv);
|
||||
void nl80211_remove_monitor_interface(struct wpa_driver_nl80211_data *drv);
|
||||
int nl80211_send_monitor(struct wpa_driver_nl80211_data *drv,
|
||||
const void *data, size_t len,
|
||||
int encrypt, int noack);
|
||||
|
||||
int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv);
|
||||
struct hostapd_hw_modes *
|
||||
nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags);
|
||||
|
||||
int process_global_event(struct nl_msg *msg, void *arg);
|
||||
int process_bss_event(struct nl_msg *msg, void *arg);
|
||||
|
||||
#ifdef ANDROID
|
||||
int android_nl_socket_set_nonblocking(struct nl_handle *handle);
|
||||
int android_pno_start(struct i802_bss *bss,
|
||||
struct wpa_driver_scan_params *params);
|
||||
int android_pno_stop(struct i802_bss *bss);
|
||||
extern int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
|
||||
size_t buf_len);
|
||||
|
||||
#ifdef ANDROID_P2P
|
||||
int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration);
|
||||
int wpa_driver_get_p2p_noa(void *priv, u8 *buf, size_t len);
|
||||
int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow);
|
||||
int wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon,
|
||||
const struct wpabuf *proberesp,
|
||||
const struct wpabuf *assocresp);
|
||||
#endif /* ANDROID_P2P */
|
||||
#endif /* ANDROID */
|
||||
|
||||
|
||||
/* driver_nl80211_scan.c */
|
||||
|
||||
struct nl80211_bss_info_arg {
|
||||
struct wpa_driver_nl80211_data *drv;
|
||||
struct wpa_scan_results *res;
|
||||
unsigned int assoc_freq;
|
||||
unsigned int ibss_freq;
|
||||
u8 assoc_bssid[ETH_ALEN];
|
||||
};
|
||||
|
||||
int bss_info_handler(struct nl_msg *msg, void *arg);
|
||||
void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx);
|
||||
int wpa_driver_nl80211_scan(struct i802_bss *bss,
|
||||
struct wpa_driver_scan_params *params);
|
||||
int wpa_driver_nl80211_sched_scan(void *priv,
|
||||
struct wpa_driver_scan_params *params,
|
||||
u32 interval);
|
||||
int wpa_driver_nl80211_stop_sched_scan(void *priv);
|
||||
struct wpa_scan_results * wpa_driver_nl80211_get_scan_results(void *priv);
|
||||
void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv);
|
||||
const u8 * nl80211_get_ie(const u8 *ies, size_t ies_len, u8 ie);
|
||||
|
||||
#endif /* DRIVER_NL80211_H */
|
681
freebsd/contrib/wpa/src/drivers/driver_wired.c
Normal file
681
freebsd/contrib/wpa/src/drivers/driver_wired.c
Normal file
@ -0,0 +1,681 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* Wired Ethernet driver interface
|
||||
* Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004, Gunter Burchardt <tira@isx.de>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#ifdef __linux__
|
||||
#include <netpacket/packet.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if.h>
|
||||
#endif /* __linux__ */
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) */
|
||||
#ifdef __sun__
|
||||
#include <sys/sockio.h>
|
||||
#endif /* __sun__ */
|
||||
|
||||
#include "common.h"
|
||||
#include "eloop.h"
|
||||
#include "driver.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
struct ieee8023_hdr {
|
||||
u8 dest[6];
|
||||
u8 src[6];
|
||||
u16 ethertype;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
static const u8 pae_group_addr[ETH_ALEN] =
|
||||
{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 };
|
||||
|
||||
|
||||
struct wpa_driver_wired_data {
|
||||
char ifname[IFNAMSIZ + 1];
|
||||
void *ctx;
|
||||
|
||||
int sock; /* raw packet socket for driver access */
|
||||
int dhcp_sock; /* socket for dhcp packets */
|
||||
int use_pae_group_addr;
|
||||
|
||||
int pf_sock;
|
||||
int membership, multi, iff_allmulti, iff_up;
|
||||
};
|
||||
|
||||
|
||||
/* TODO: detecting new devices should eventually be changed from using DHCP
|
||||
* snooping to trigger on any packet from a new layer 2 MAC address, e.g.,
|
||||
* based on ebtables, etc. */
|
||||
|
||||
struct dhcp_message {
|
||||
u_int8_t op;
|
||||
u_int8_t htype;
|
||||
u_int8_t hlen;
|
||||
u_int8_t hops;
|
||||
u_int32_t xid;
|
||||
u_int16_t secs;
|
||||
u_int16_t flags;
|
||||
u_int32_t ciaddr;
|
||||
u_int32_t yiaddr;
|
||||
u_int32_t siaddr;
|
||||
u_int32_t giaddr;
|
||||
u_int8_t chaddr[16];
|
||||
u_int8_t sname[64];
|
||||
u_int8_t file[128];
|
||||
u_int32_t cookie;
|
||||
u_int8_t options[308]; /* 312 - cookie */
|
||||
};
|
||||
|
||||
|
||||
static int wired_multicast_membership(int sock, int ifindex,
|
||||
const u8 *addr, int add)
|
||||
{
|
||||
#ifdef __linux__
|
||||
struct packet_mreq mreq;
|
||||
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
|
||||
os_memset(&mreq, 0, sizeof(mreq));
|
||||
mreq.mr_ifindex = ifindex;
|
||||
mreq.mr_type = PACKET_MR_MULTICAST;
|
||||
mreq.mr_alen = ETH_ALEN;
|
||||
os_memcpy(mreq.mr_address, addr, ETH_ALEN);
|
||||
|
||||
if (setsockopt(sock, SOL_PACKET,
|
||||
add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
|
||||
&mreq, sizeof(mreq)) < 0) {
|
||||
wpa_printf(MSG_ERROR, "setsockopt: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#else /* __linux__ */
|
||||
return -1;
|
||||
#endif /* __linux__ */
|
||||
}
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
static void handle_data(void *ctx, unsigned char *buf, size_t len)
|
||||
{
|
||||
#ifdef HOSTAPD
|
||||
struct ieee8023_hdr *hdr;
|
||||
u8 *pos, *sa;
|
||||
size_t left;
|
||||
union wpa_event_data event;
|
||||
|
||||
/* must contain at least ieee8023_hdr 6 byte source, 6 byte dest,
|
||||
* 2 byte ethertype */
|
||||
if (len < 14) {
|
||||
wpa_printf(MSG_MSGDUMP, "handle_data: too short (%lu)",
|
||||
(unsigned long) len);
|
||||
return;
|
||||
}
|
||||
|
||||
hdr = (struct ieee8023_hdr *) buf;
|
||||
|
||||
switch (ntohs(hdr->ethertype)) {
|
||||
case ETH_P_PAE:
|
||||
wpa_printf(MSG_MSGDUMP, "Received EAPOL packet");
|
||||
sa = hdr->src;
|
||||
os_memset(&event, 0, sizeof(event));
|
||||
event.new_sta.addr = sa;
|
||||
wpa_supplicant_event(ctx, EVENT_NEW_STA, &event);
|
||||
|
||||
pos = (u8 *) (hdr + 1);
|
||||
left = len - sizeof(*hdr);
|
||||
drv_event_eapol_rx(ctx, sa, pos, left);
|
||||
break;
|
||||
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG, "Unknown ethertype 0x%04x in data frame",
|
||||
ntohs(hdr->ethertype));
|
||||
break;
|
||||
}
|
||||
#endif /* HOSTAPD */
|
||||
}
|
||||
|
||||
|
||||
static void handle_read(int sock, void *eloop_ctx, void *sock_ctx)
|
||||
{
|
||||
int len;
|
||||
unsigned char buf[3000];
|
||||
|
||||
len = recv(sock, buf, sizeof(buf), 0);
|
||||
if (len < 0) {
|
||||
wpa_printf(MSG_ERROR, "recv: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
handle_data(eloop_ctx, buf, len);
|
||||
}
|
||||
|
||||
|
||||
static void handle_dhcp(int sock, void *eloop_ctx, void *sock_ctx)
|
||||
{
|
||||
int len;
|
||||
unsigned char buf[3000];
|
||||
struct dhcp_message *msg;
|
||||
u8 *mac_address;
|
||||
union wpa_event_data event;
|
||||
|
||||
len = recv(sock, buf, sizeof(buf), 0);
|
||||
if (len < 0) {
|
||||
wpa_printf(MSG_ERROR, "recv: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
/* must contain at least dhcp_message->chaddr */
|
||||
if (len < 44) {
|
||||
wpa_printf(MSG_MSGDUMP, "handle_dhcp: too short (%d)", len);
|
||||
return;
|
||||
}
|
||||
|
||||
msg = (struct dhcp_message *) buf;
|
||||
mac_address = (u8 *) &(msg->chaddr);
|
||||
|
||||
wpa_printf(MSG_MSGDUMP, "Got DHCP broadcast packet from " MACSTR,
|
||||
MAC2STR(mac_address));
|
||||
|
||||
os_memset(&event, 0, sizeof(event));
|
||||
event.new_sta.addr = mac_address;
|
||||
wpa_supplicant_event(eloop_ctx, EVENT_NEW_STA, &event);
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
|
||||
static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr)
|
||||
{
|
||||
#ifdef __linux__
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_ll addr;
|
||||
struct sockaddr_in addr2;
|
||||
int n = 1;
|
||||
|
||||
drv->sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_PAE));
|
||||
if (drv->sock < 0) {
|
||||
wpa_printf(MSG_ERROR, "socket[PF_PACKET,SOCK_RAW]: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (eloop_register_read_sock(drv->sock, handle_read, drv->ctx, NULL)) {
|
||||
wpa_printf(MSG_INFO, "Could not register read socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
|
||||
if (ioctl(drv->sock, SIOCGIFINDEX, &ifr) != 0) {
|
||||
wpa_printf(MSG_ERROR, "ioctl(SIOCGIFINDEX): %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memset(&addr, 0, sizeof(addr));
|
||||
addr.sll_family = AF_PACKET;
|
||||
addr.sll_ifindex = ifr.ifr_ifindex;
|
||||
wpa_printf(MSG_DEBUG, "Opening raw packet socket for ifindex %d",
|
||||
addr.sll_ifindex);
|
||||
|
||||
if (bind(drv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* filter multicast address */
|
||||
if (wired_multicast_membership(drv->sock, ifr.ifr_ifindex,
|
||||
pae_group_addr, 1) < 0) {
|
||||
wpa_printf(MSG_ERROR, "wired: Failed to add multicast group "
|
||||
"membership");
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
|
||||
if (ioctl(drv->sock, SIOCGIFHWADDR, &ifr) != 0) {
|
||||
wpa_printf(MSG_ERROR, "ioctl(SIOCGIFHWADDR): %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
|
||||
wpa_printf(MSG_INFO, "Invalid HW-addr family 0x%04x",
|
||||
ifr.ifr_hwaddr.sa_family);
|
||||
return -1;
|
||||
}
|
||||
os_memcpy(own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
|
||||
|
||||
/* setup dhcp listen socket for sta detection */
|
||||
if ((drv->dhcp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
||||
wpa_printf(MSG_ERROR, "socket call failed for dhcp: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (eloop_register_read_sock(drv->dhcp_sock, handle_dhcp, drv->ctx,
|
||||
NULL)) {
|
||||
wpa_printf(MSG_INFO, "Could not register read socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memset(&addr2, 0, sizeof(addr2));
|
||||
addr2.sin_family = AF_INET;
|
||||
addr2.sin_port = htons(67);
|
||||
addr2.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_REUSEADDR, (char *) &n,
|
||||
sizeof(n)) == -1) {
|
||||
wpa_printf(MSG_ERROR, "setsockopt[SOL_SOCKET,SO_REUSEADDR]: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_BROADCAST, (char *) &n,
|
||||
sizeof(n)) == -1) {
|
||||
wpa_printf(MSG_ERROR, "setsockopt[SOL_SOCKET,SO_BROADCAST]: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_ifrn.ifrn_name, drv->ifname, IFNAMSIZ);
|
||||
if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
(char *) &ifr, sizeof(ifr)) < 0) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"setsockopt[SOL_SOCKET,SO_BINDTODEVICE]: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bind(drv->dhcp_sock, (struct sockaddr *) &addr2,
|
||||
sizeof(struct sockaddr)) == -1) {
|
||||
wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else /* __linux__ */
|
||||
return -1;
|
||||
#endif /* __linux__ */
|
||||
}
|
||||
|
||||
|
||||
static int wired_send_eapol(void *priv, const u8 *addr,
|
||||
const u8 *data, size_t data_len, int encrypt,
|
||||
const u8 *own_addr, u32 flags)
|
||||
{
|
||||
struct wpa_driver_wired_data *drv = priv;
|
||||
struct ieee8023_hdr *hdr;
|
||||
size_t len;
|
||||
u8 *pos;
|
||||
int res;
|
||||
|
||||
len = sizeof(*hdr) + data_len;
|
||||
hdr = os_zalloc(len);
|
||||
if (hdr == NULL) {
|
||||
wpa_printf(MSG_INFO,
|
||||
"malloc() failed for wired_send_eapol(len=%lu)",
|
||||
(unsigned long) len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memcpy(hdr->dest, drv->use_pae_group_addr ? pae_group_addr : addr,
|
||||
ETH_ALEN);
|
||||
os_memcpy(hdr->src, own_addr, ETH_ALEN);
|
||||
hdr->ethertype = htons(ETH_P_PAE);
|
||||
|
||||
pos = (u8 *) (hdr + 1);
|
||||
os_memcpy(pos, data, data_len);
|
||||
|
||||
res = send(drv->sock, (u8 *) hdr, len, 0);
|
||||
os_free(hdr);
|
||||
|
||||
if (res < 0) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"wired_send_eapol - packet len: %lu - failed: send: %s",
|
||||
(unsigned long) len, strerror(errno));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static void * wired_driver_hapd_init(struct hostapd_data *hapd,
|
||||
struct wpa_init_params *params)
|
||||
{
|
||||
struct wpa_driver_wired_data *drv;
|
||||
|
||||
drv = os_zalloc(sizeof(struct wpa_driver_wired_data));
|
||||
if (drv == NULL) {
|
||||
wpa_printf(MSG_INFO,
|
||||
"Could not allocate memory for wired driver data");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
drv->ctx = hapd;
|
||||
os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname));
|
||||
drv->use_pae_group_addr = params->use_pae_group_addr;
|
||||
|
||||
if (wired_init_sockets(drv, params->own_addr)) {
|
||||
os_free(drv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return drv;
|
||||
}
|
||||
|
||||
|
||||
static void wired_driver_hapd_deinit(void *priv)
|
||||
{
|
||||
struct wpa_driver_wired_data *drv = priv;
|
||||
|
||||
if (drv->sock >= 0) {
|
||||
eloop_unregister_read_sock(drv->sock);
|
||||
close(drv->sock);
|
||||
}
|
||||
|
||||
if (drv->dhcp_sock >= 0) {
|
||||
eloop_unregister_read_sock(drv->dhcp_sock);
|
||||
close(drv->dhcp_sock);
|
||||
}
|
||||
|
||||
os_free(drv);
|
||||
}
|
||||
|
||||
|
||||
static int wpa_driver_wired_get_ssid(void *priv, u8 *ssid)
|
||||
{
|
||||
ssid[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int wpa_driver_wired_get_bssid(void *priv, u8 *bssid)
|
||||
{
|
||||
/* Report PAE group address as the "BSSID" for wired connection. */
|
||||
os_memcpy(bssid, pae_group_addr, ETH_ALEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int wpa_driver_wired_get_capa(void *priv, struct wpa_driver_capa *capa)
|
||||
{
|
||||
os_memset(capa, 0, sizeof(*capa));
|
||||
capa->flags = WPA_DRIVER_FLAGS_WIRED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int wpa_driver_wired_get_ifflags(const char *ifname, int *flags)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int s;
|
||||
|
||||
s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
wpa_printf(MSG_ERROR, "socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
|
||||
if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
wpa_printf(MSG_ERROR, "ioctl[SIOCGIFFLAGS]: %s",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
close(s);
|
||||
*flags = ifr.ifr_flags & 0xffff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int wpa_driver_wired_set_ifflags(const char *ifname, int flags)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int s;
|
||||
|
||||
s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
wpa_printf(MSG_ERROR, "socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
|
||||
ifr.ifr_flags = flags & 0xffff;
|
||||
if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
|
||||
wpa_printf(MSG_ERROR, "ioctl[SIOCSIFFLAGS]: %s",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
|
||||
static int wpa_driver_wired_get_ifstatus(const char *ifname, int *status)
|
||||
{
|
||||
struct ifmediareq ifmr;
|
||||
int s;
|
||||
|
||||
s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
wpa_printf(MSG_ERROR, "socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memset(&ifmr, 0, sizeof(ifmr));
|
||||
os_strlcpy(ifmr.ifm_name, ifname, IFNAMSIZ);
|
||||
if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) {
|
||||
wpa_printf(MSG_ERROR, "ioctl[SIOCGIFMEDIA]: %s",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
close(s);
|
||||
*status = (ifmr.ifm_status & (IFM_ACTIVE | IFM_AVALID)) ==
|
||||
(IFM_ACTIVE | IFM_AVALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */
|
||||
|
||||
|
||||
static int wpa_driver_wired_multi(const char *ifname, const u8 *addr, int add)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int s;
|
||||
|
||||
#ifdef __sun__
|
||||
return -1;
|
||||
#endif /* __sun__ */
|
||||
|
||||
s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
wpa_printf(MSG_ERROR, "socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
|
||||
#ifdef __linux__
|
||||
ifr.ifr_hwaddr.sa_family = AF_UNSPEC;
|
||||
os_memcpy(ifr.ifr_hwaddr.sa_data, addr, ETH_ALEN);
|
||||
#endif /* __linux__ */
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
|
||||
{
|
||||
struct sockaddr_dl *dlp;
|
||||
dlp = (struct sockaddr_dl *) &ifr.ifr_addr;
|
||||
dlp->sdl_len = sizeof(struct sockaddr_dl);
|
||||
dlp->sdl_family = AF_LINK;
|
||||
dlp->sdl_index = 0;
|
||||
dlp->sdl_nlen = 0;
|
||||
dlp->sdl_alen = ETH_ALEN;
|
||||
dlp->sdl_slen = 0;
|
||||
os_memcpy(LLADDR(dlp), addr, ETH_ALEN);
|
||||
}
|
||||
#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */
|
||||
#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||
{
|
||||
struct sockaddr *sap;
|
||||
sap = (struct sockaddr *) &ifr.ifr_addr;
|
||||
sap->sa_len = sizeof(struct sockaddr);
|
||||
sap->sa_family = AF_UNSPEC;
|
||||
os_memcpy(sap->sa_data, addr, ETH_ALEN);
|
||||
}
|
||||
#endif /* defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) */
|
||||
|
||||
if (ioctl(s, add ? SIOCADDMULTI : SIOCDELMULTI, (caddr_t) &ifr) < 0) {
|
||||
wpa_printf(MSG_ERROR, "ioctl[SIOC{ADD/DEL}MULTI]: %s",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void * wpa_driver_wired_init(void *ctx, const char *ifname)
|
||||
{
|
||||
struct wpa_driver_wired_data *drv;
|
||||
int flags, status;
|
||||
|
||||
drv = os_zalloc(sizeof(*drv));
|
||||
if (drv == NULL)
|
||||
return NULL;
|
||||
os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
|
||||
drv->ctx = ctx;
|
||||
|
||||
#ifdef __linux__
|
||||
drv->pf_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
|
||||
if (drv->pf_sock < 0)
|
||||
wpa_printf(MSG_ERROR, "socket(PF_PACKET): %s", strerror(errno));
|
||||
#else /* __linux__ */
|
||||
drv->pf_sock = -1;
|
||||
#endif /* __linux__ */
|
||||
|
||||
if (wpa_driver_wired_get_ifflags(ifname, &flags) == 0 &&
|
||||
!(flags & IFF_UP) &&
|
||||
wpa_driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) {
|
||||
drv->iff_up = 1;
|
||||
}
|
||||
|
||||
if (wired_multicast_membership(drv->pf_sock,
|
||||
if_nametoindex(drv->ifname),
|
||||
pae_group_addr, 1) == 0) {
|
||||
wpa_printf(MSG_DEBUG, "%s: Added multicast membership with "
|
||||
"packet socket", __func__);
|
||||
drv->membership = 1;
|
||||
} else if (wpa_driver_wired_multi(ifname, pae_group_addr, 1) == 0) {
|
||||
wpa_printf(MSG_DEBUG, "%s: Added multicast membership with "
|
||||
"SIOCADDMULTI", __func__);
|
||||
drv->multi = 1;
|
||||
} else if (wpa_driver_wired_get_ifflags(ifname, &flags) < 0) {
|
||||
wpa_printf(MSG_INFO, "%s: Could not get interface "
|
||||
"flags", __func__);
|
||||
os_free(drv);
|
||||
return NULL;
|
||||
} else if (flags & IFF_ALLMULTI) {
|
||||
wpa_printf(MSG_DEBUG, "%s: Interface is already configured "
|
||||
"for multicast", __func__);
|
||||
} else if (wpa_driver_wired_set_ifflags(ifname,
|
||||
flags | IFF_ALLMULTI) < 0) {
|
||||
wpa_printf(MSG_INFO, "%s: Failed to enable allmulti",
|
||||
__func__);
|
||||
os_free(drv);
|
||||
return NULL;
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "%s: Enabled allmulti mode",
|
||||
__func__);
|
||||
drv->iff_allmulti = 1;
|
||||
}
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
|
||||
{
|
||||
int status;
|
||||
wpa_printf(MSG_DEBUG, "%s: waiting for link to become active",
|
||||
__func__);
|
||||
while (wpa_driver_wired_get_ifstatus(ifname, &status) == 0 &&
|
||||
status == 0)
|
||||
sleep(1);
|
||||
}
|
||||
#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */
|
||||
|
||||
return drv;
|
||||
}
|
||||
|
||||
|
||||
static void wpa_driver_wired_deinit(void *priv)
|
||||
{
|
||||
struct wpa_driver_wired_data *drv = priv;
|
||||
int flags;
|
||||
|
||||
if (drv->membership &&
|
||||
wired_multicast_membership(drv->pf_sock,
|
||||
if_nametoindex(drv->ifname),
|
||||
pae_group_addr, 0) < 0) {
|
||||
wpa_printf(MSG_DEBUG, "%s: Failed to remove PAE multicast "
|
||||
"group (PACKET)", __func__);
|
||||
}
|
||||
|
||||
if (drv->multi &&
|
||||
wpa_driver_wired_multi(drv->ifname, pae_group_addr, 0) < 0) {
|
||||
wpa_printf(MSG_DEBUG, "%s: Failed to remove PAE multicast "
|
||||
"group (SIOCDELMULTI)", __func__);
|
||||
}
|
||||
|
||||
if (drv->iff_allmulti &&
|
||||
(wpa_driver_wired_get_ifflags(drv->ifname, &flags) < 0 ||
|
||||
wpa_driver_wired_set_ifflags(drv->ifname,
|
||||
flags & ~IFF_ALLMULTI) < 0)) {
|
||||
wpa_printf(MSG_DEBUG, "%s: Failed to disable allmulti mode",
|
||||
__func__);
|
||||
}
|
||||
|
||||
if (drv->iff_up &&
|
||||
wpa_driver_wired_get_ifflags(drv->ifname, &flags) == 0 &&
|
||||
(flags & IFF_UP) &&
|
||||
wpa_driver_wired_set_ifflags(drv->ifname, flags & ~IFF_UP) < 0) {
|
||||
wpa_printf(MSG_DEBUG, "%s: Failed to set the interface down",
|
||||
__func__);
|
||||
}
|
||||
|
||||
if (drv->pf_sock != -1)
|
||||
close(drv->pf_sock);
|
||||
|
||||
os_free(drv);
|
||||
}
|
||||
|
||||
|
||||
const struct wpa_driver_ops wpa_driver_wired_ops = {
|
||||
.name = "wired",
|
||||
.desc = "Wired Ethernet driver",
|
||||
.hapd_init = wired_driver_hapd_init,
|
||||
.hapd_deinit = wired_driver_hapd_deinit,
|
||||
.hapd_send_eapol = wired_send_eapol,
|
||||
.get_ssid = wpa_driver_wired_get_ssid,
|
||||
.get_bssid = wpa_driver_wired_get_bssid,
|
||||
.get_capa = wpa_driver_wired_get_capa,
|
||||
.init = wpa_driver_wired_init,
|
||||
.deinit = wpa_driver_wired_deinit,
|
||||
};
|
88
freebsd/contrib/wpa/src/drivers/drivers.c
Normal file
88
freebsd/contrib/wpa/src/drivers/drivers.c
Normal file
@ -0,0 +1,88 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* Driver interface list
|
||||
* Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "driver.h"
|
||||
|
||||
#ifdef CONFIG_DRIVER_WEXT
|
||||
extern struct wpa_driver_ops wpa_driver_wext_ops; /* driver_wext.c */
|
||||
#endif /* CONFIG_DRIVER_WEXT */
|
||||
#ifdef CONFIG_DRIVER_NL80211
|
||||
extern struct wpa_driver_ops wpa_driver_nl80211_ops; /* driver_nl80211.c */
|
||||
#endif /* CONFIG_DRIVER_NL80211 */
|
||||
#ifdef CONFIG_DRIVER_HOSTAP
|
||||
extern struct wpa_driver_ops wpa_driver_hostap_ops; /* driver_hostap.c */
|
||||
#endif /* CONFIG_DRIVER_HOSTAP */
|
||||
#ifdef CONFIG_DRIVER_BSD
|
||||
extern struct wpa_driver_ops wpa_driver_bsd_ops; /* driver_bsd.c */
|
||||
#endif /* CONFIG_DRIVER_BSD */
|
||||
#ifdef CONFIG_DRIVER_OPENBSD
|
||||
extern struct wpa_driver_ops wpa_driver_openbsd_ops; /* driver_openbsd.c */
|
||||
#endif /* CONFIG_DRIVER_OPENBSD */
|
||||
#ifdef CONFIG_DRIVER_NDIS
|
||||
extern struct wpa_driver_ops wpa_driver_ndis_ops; /* driver_ndis.c */
|
||||
#endif /* CONFIG_DRIVER_NDIS */
|
||||
#ifdef CONFIG_DRIVER_WIRED
|
||||
extern struct wpa_driver_ops wpa_driver_wired_ops; /* driver_wired.c */
|
||||
#endif /* CONFIG_DRIVER_WIRED */
|
||||
#ifdef CONFIG_DRIVER_MACSEC_QCA
|
||||
/* driver_macsec_qca.c */
|
||||
extern struct wpa_driver_ops wpa_driver_macsec_qca_ops;
|
||||
#endif /* CONFIG_DRIVER_MACSEC_QCA */
|
||||
#ifdef CONFIG_DRIVER_ROBOSWITCH
|
||||
/* driver_roboswitch.c */
|
||||
extern struct wpa_driver_ops wpa_driver_roboswitch_ops;
|
||||
#endif /* CONFIG_DRIVER_ROBOSWITCH */
|
||||
#ifdef CONFIG_DRIVER_ATHEROS
|
||||
extern struct wpa_driver_ops wpa_driver_atheros_ops; /* driver_atheros.c */
|
||||
#endif /* CONFIG_DRIVER_ATHEROS */
|
||||
#ifdef CONFIG_DRIVER_NONE
|
||||
extern struct wpa_driver_ops wpa_driver_none_ops; /* driver_none.c */
|
||||
#endif /* CONFIG_DRIVER_NONE */
|
||||
|
||||
|
||||
const struct wpa_driver_ops *const wpa_drivers[] =
|
||||
{
|
||||
#ifdef CONFIG_DRIVER_NL80211
|
||||
&wpa_driver_nl80211_ops,
|
||||
#endif /* CONFIG_DRIVER_NL80211 */
|
||||
#ifdef CONFIG_DRIVER_WEXT
|
||||
&wpa_driver_wext_ops,
|
||||
#endif /* CONFIG_DRIVER_WEXT */
|
||||
#ifdef CONFIG_DRIVER_HOSTAP
|
||||
&wpa_driver_hostap_ops,
|
||||
#endif /* CONFIG_DRIVER_HOSTAP */
|
||||
#ifdef CONFIG_DRIVER_BSD
|
||||
&wpa_driver_bsd_ops,
|
||||
#endif /* CONFIG_DRIVER_BSD */
|
||||
#ifdef CONFIG_DRIVER_OPENBSD
|
||||
&wpa_driver_openbsd_ops,
|
||||
#endif /* CONFIG_DRIVER_OPENBSD */
|
||||
#ifdef CONFIG_DRIVER_NDIS
|
||||
&wpa_driver_ndis_ops,
|
||||
#endif /* CONFIG_DRIVER_NDIS */
|
||||
#ifdef CONFIG_DRIVER_WIRED
|
||||
&wpa_driver_wired_ops,
|
||||
#endif /* CONFIG_DRIVER_WIRED */
|
||||
#ifdef CONFIG_DRIVER_MACSEC_QCA
|
||||
&wpa_driver_macsec_qca_ops,
|
||||
#endif /* CONFIG_DRIVER_MACSEC_QCA */
|
||||
#ifdef CONFIG_DRIVER_ROBOSWITCH
|
||||
&wpa_driver_roboswitch_ops,
|
||||
#endif /* CONFIG_DRIVER_ROBOSWITCH */
|
||||
#ifdef CONFIG_DRIVER_ATHEROS
|
||||
&wpa_driver_atheros_ops,
|
||||
#endif /* CONFIG_DRIVER_ATHEROS */
|
||||
#ifdef CONFIG_DRIVER_NONE
|
||||
&wpa_driver_none_ops,
|
||||
#endif /* CONFIG_DRIVER_NONE */
|
||||
NULL
|
||||
};
|
46
freebsd/contrib/wpa/src/drivers/linux_defines.h
Normal file
46
freebsd/contrib/wpa/src/drivers/linux_defines.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Linux defines for values that are not yet included in common C libraries
|
||||
* Copyright (c) 2014, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef LINUX_DEFINES_H
|
||||
#define LINUX_DEFINES_H
|
||||
|
||||
#ifndef SO_WIFI_STATUS
|
||||
# if defined(__sparc__)
|
||||
# define SO_WIFI_STATUS 0x0025
|
||||
# elif defined(__parisc__)
|
||||
# define SO_WIFI_STATUS 0x4022
|
||||
# else
|
||||
# define SO_WIFI_STATUS 41
|
||||
# endif
|
||||
|
||||
# define SCM_WIFI_STATUS SO_WIFI_STATUS
|
||||
#endif
|
||||
|
||||
#ifndef SO_EE_ORIGIN_TXSTATUS
|
||||
#define SO_EE_ORIGIN_TXSTATUS 4
|
||||
#endif
|
||||
|
||||
#ifndef PACKET_TX_TIMESTAMP
|
||||
#define PACKET_TX_TIMESTAMP 16
|
||||
#endif
|
||||
|
||||
#ifndef IFF_LOWER_UP
|
||||
#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
|
||||
#endif
|
||||
#ifndef IFF_DORMANT
|
||||
#define IFF_DORMANT 0x20000 /* driver signals dormant */
|
||||
#endif
|
||||
|
||||
#ifndef IF_OPER_DORMANT
|
||||
#define IF_OPER_DORMANT 5
|
||||
#endif
|
||||
#ifndef IF_OPER_UP
|
||||
#define IF_OPER_UP 6
|
||||
#endif
|
||||
|
||||
#endif /* LINUX_DEFINES_H */
|
30
freebsd/contrib/wpa/src/eap_common/chap.c
Normal file
30
freebsd/contrib/wpa/src/eap_common/chap.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* CHAP-MD5 (RFC 1994)
|
||||
* Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "chap.h"
|
||||
|
||||
int chap_md5(u8 id, const u8 *secret, size_t secret_len, const u8 *challenge,
|
||||
size_t challenge_len, u8 *response)
|
||||
{
|
||||
const u8 *addr[3];
|
||||
size_t len[3];
|
||||
|
||||
addr[0] = &id;
|
||||
len[0] = 1;
|
||||
addr[1] = secret;
|
||||
len[1] = secret_len;
|
||||
addr[2] = challenge;
|
||||
len[2] = challenge_len;
|
||||
return md5_vector(3, addr, len, response);
|
||||
}
|
17
freebsd/contrib/wpa/src/eap_common/chap.h
Normal file
17
freebsd/contrib/wpa/src/eap_common/chap.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* CHAP-MD5 (RFC 1994)
|
||||
* Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef CHAP_H
|
||||
#define CHAP_H
|
||||
|
||||
#define CHAP_MD5_LEN 16
|
||||
|
||||
int chap_md5(u8 id, const u8 *secret, size_t secret_len, const u8 *challenge,
|
||||
size_t challenge_len, u8 *response);
|
||||
|
||||
#endif /* CHAP_H */
|
290
freebsd/contrib/wpa/src/eap_common/eap_common.c
Normal file
290
freebsd/contrib/wpa/src/eap_common/eap_common.c
Normal file
@ -0,0 +1,290 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* EAP common peer/server definitions
|
||||
* Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "eap_defs.h"
|
||||
#include "eap_common.h"
|
||||
|
||||
/**
|
||||
* eap_hdr_len_valid - Validate EAP header length field
|
||||
* @msg: EAP frame (starting with EAP header)
|
||||
* @min_payload: Minimum payload length needed
|
||||
* Returns: 1 for valid header, 0 for invalid
|
||||
*
|
||||
* This is a helper function that does minimal validation of EAP messages. The
|
||||
* length field is verified to be large enough to include the header and not
|
||||
* too large to go beyond the end of the buffer.
|
||||
*/
|
||||
int eap_hdr_len_valid(const struct wpabuf *msg, size_t min_payload)
|
||||
{
|
||||
const struct eap_hdr *hdr;
|
||||
size_t len;
|
||||
|
||||
if (msg == NULL)
|
||||
return 0;
|
||||
|
||||
hdr = wpabuf_head(msg);
|
||||
|
||||
if (wpabuf_len(msg) < sizeof(*hdr)) {
|
||||
wpa_printf(MSG_INFO, "EAP: Too short EAP frame");
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = be_to_host16(hdr->length);
|
||||
if (len < sizeof(*hdr) + min_payload || len > wpabuf_len(msg)) {
|
||||
wpa_printf(MSG_INFO, "EAP: Invalid EAP length");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_hdr_validate - Validate EAP header
|
||||
* @vendor: Expected EAP Vendor-Id (0 = IETF)
|
||||
* @eap_type: Expected EAP type number
|
||||
* @msg: EAP frame (starting with EAP header)
|
||||
* @plen: Pointer to variable to contain the returned payload length
|
||||
* Returns: Pointer to EAP payload (after type field), or %NULL on failure
|
||||
*
|
||||
* This is a helper function for EAP method implementations. This is usually
|
||||
* called in the beginning of struct eap_method::process() function to verify
|
||||
* that the received EAP request packet has a valid header. This function is
|
||||
* able to process both legacy and expanded EAP headers and in most cases, the
|
||||
* caller can just use the returned payload pointer (into *plen) for processing
|
||||
* the payload regardless of whether the packet used the expanded EAP header or
|
||||
* not.
|
||||
*/
|
||||
const u8 * eap_hdr_validate(int vendor, EapType eap_type,
|
||||
const struct wpabuf *msg, size_t *plen)
|
||||
{
|
||||
const struct eap_hdr *hdr;
|
||||
const u8 *pos;
|
||||
size_t len;
|
||||
|
||||
if (!eap_hdr_len_valid(msg, 1))
|
||||
return NULL;
|
||||
|
||||
hdr = wpabuf_head(msg);
|
||||
len = be_to_host16(hdr->length);
|
||||
pos = (const u8 *) (hdr + 1);
|
||||
|
||||
if (*pos == EAP_TYPE_EXPANDED) {
|
||||
int exp_vendor;
|
||||
u32 exp_type;
|
||||
if (len < sizeof(*hdr) + 8) {
|
||||
wpa_printf(MSG_INFO, "EAP: Invalid expanded EAP "
|
||||
"length");
|
||||
return NULL;
|
||||
}
|
||||
pos++;
|
||||
exp_vendor = WPA_GET_BE24(pos);
|
||||
pos += 3;
|
||||
exp_type = WPA_GET_BE32(pos);
|
||||
pos += 4;
|
||||
if (exp_vendor != vendor || exp_type != (u32) eap_type) {
|
||||
wpa_printf(MSG_INFO, "EAP: Invalid expanded frame "
|
||||
"type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*plen = len - sizeof(*hdr) - 8;
|
||||
return pos;
|
||||
} else {
|
||||
if (vendor != EAP_VENDOR_IETF || *pos != eap_type) {
|
||||
wpa_printf(MSG_INFO, "EAP: Invalid frame type");
|
||||
return NULL;
|
||||
}
|
||||
*plen = len - sizeof(*hdr) - 1;
|
||||
return pos + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_msg_alloc - Allocate a buffer for an EAP message
|
||||
* @vendor: Vendor-Id (0 = IETF)
|
||||
* @type: EAP type
|
||||
* @payload_len: Payload length in bytes (data after Type)
|
||||
* @code: Message Code (EAP_CODE_*)
|
||||
* @identifier: Identifier
|
||||
* Returns: Pointer to the allocated message buffer or %NULL on error
|
||||
*
|
||||
* This function can be used to allocate a buffer for an EAP message and fill
|
||||
* in the EAP header. This function is automatically using expanded EAP header
|
||||
* if the selected Vendor-Id is not IETF. In other words, most EAP methods do
|
||||
* not need to separately select which header type to use when using this
|
||||
* function to allocate the message buffers. The returned buffer has room for
|
||||
* payload_len bytes and has the EAP header and Type field already filled in.
|
||||
*/
|
||||
struct wpabuf * eap_msg_alloc(int vendor, EapType type, size_t payload_len,
|
||||
u8 code, u8 identifier)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
struct eap_hdr *hdr;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(struct eap_hdr) + (vendor == EAP_VENDOR_IETF ? 1 : 8) +
|
||||
payload_len;
|
||||
buf = wpabuf_alloc(len);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
hdr = wpabuf_put(buf, sizeof(*hdr));
|
||||
hdr->code = code;
|
||||
hdr->identifier = identifier;
|
||||
hdr->length = host_to_be16(len);
|
||||
|
||||
if (vendor == EAP_VENDOR_IETF) {
|
||||
wpabuf_put_u8(buf, type);
|
||||
} else {
|
||||
wpabuf_put_u8(buf, EAP_TYPE_EXPANDED);
|
||||
wpabuf_put_be24(buf, vendor);
|
||||
wpabuf_put_be32(buf, type);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_update_len - Update EAP header length
|
||||
* @msg: EAP message from eap_msg_alloc
|
||||
*
|
||||
* This function updates the length field in the EAP header to match with the
|
||||
* current length for the buffer. This allows eap_msg_alloc() to be used to
|
||||
* allocate a larger buffer than the exact message length (e.g., if exact
|
||||
* message length is not yet known).
|
||||
*/
|
||||
void eap_update_len(struct wpabuf *msg)
|
||||
{
|
||||
struct eap_hdr *hdr;
|
||||
hdr = wpabuf_mhead(msg);
|
||||
if (wpabuf_len(msg) < sizeof(*hdr))
|
||||
return;
|
||||
hdr->length = host_to_be16(wpabuf_len(msg));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_get_id - Get EAP Identifier from wpabuf
|
||||
* @msg: Buffer starting with an EAP header
|
||||
* Returns: The Identifier field from the EAP header
|
||||
*/
|
||||
u8 eap_get_id(const struct wpabuf *msg)
|
||||
{
|
||||
const struct eap_hdr *eap;
|
||||
|
||||
if (wpabuf_len(msg) < sizeof(*eap))
|
||||
return 0;
|
||||
|
||||
eap = wpabuf_head(msg);
|
||||
return eap->identifier;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_get_type - Get EAP Type from wpabuf
|
||||
* @msg: Buffer starting with an EAP header
|
||||
* Returns: The EAP Type after the EAP header
|
||||
*/
|
||||
EapType eap_get_type(const struct wpabuf *msg)
|
||||
{
|
||||
if (wpabuf_len(msg) < sizeof(struct eap_hdr) + 1)
|
||||
return EAP_TYPE_NONE;
|
||||
|
||||
return ((const u8 *) wpabuf_head(msg))[sizeof(struct eap_hdr)];
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_ERP
|
||||
int erp_parse_tlvs(const u8 *pos, const u8 *end, struct erp_tlvs *tlvs,
|
||||
int stop_at_keyname)
|
||||
{
|
||||
os_memset(tlvs, 0, sizeof(*tlvs));
|
||||
|
||||
while (pos < end) {
|
||||
u8 tlv_type, tlv_len;
|
||||
|
||||
tlv_type = *pos++;
|
||||
switch (tlv_type) {
|
||||
case EAP_ERP_TV_RRK_LIFETIME:
|
||||
case EAP_ERP_TV_RMSK_LIFETIME:
|
||||
/* 4-octet TV */
|
||||
if (pos + 4 > end) {
|
||||
wpa_printf(MSG_DEBUG, "EAP: Too short TV");
|
||||
return -1;
|
||||
}
|
||||
pos += 4;
|
||||
break;
|
||||
case EAP_ERP_TLV_DOMAIN_NAME:
|
||||
case EAP_ERP_TLV_KEYNAME_NAI:
|
||||
case EAP_ERP_TLV_CRYPTOSUITES:
|
||||
case EAP_ERP_TLV_AUTHORIZATION_INDICATION:
|
||||
case EAP_ERP_TLV_CALLED_STATION_ID:
|
||||
case EAP_ERP_TLV_CALLING_STATION_ID:
|
||||
case EAP_ERP_TLV_NAS_IDENTIFIER:
|
||||
case EAP_ERP_TLV_NAS_IP_ADDRESS:
|
||||
case EAP_ERP_TLV_NAS_IPV6_ADDRESS:
|
||||
if (pos >= end) {
|
||||
wpa_printf(MSG_DEBUG, "EAP: Too short TLV");
|
||||
return -1;
|
||||
}
|
||||
tlv_len = *pos++;
|
||||
if (tlv_len > (unsigned) (end - pos)) {
|
||||
wpa_printf(MSG_DEBUG, "EAP: Truncated TLV");
|
||||
return -1;
|
||||
}
|
||||
if (tlv_type == EAP_ERP_TLV_KEYNAME_NAI) {
|
||||
if (tlvs->keyname) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP: More than one keyName-NAI");
|
||||
return -1;
|
||||
}
|
||||
tlvs->keyname = pos;
|
||||
tlvs->keyname_len = tlv_len;
|
||||
if (stop_at_keyname)
|
||||
return 0;
|
||||
} else if (tlv_type == EAP_ERP_TLV_DOMAIN_NAME) {
|
||||
tlvs->domain = pos;
|
||||
tlvs->domain_len = tlv_len;
|
||||
}
|
||||
pos += tlv_len;
|
||||
break;
|
||||
default:
|
||||
if (tlv_type >= 128 && tlv_type <= 191) {
|
||||
/* Undefined TLV */
|
||||
if (pos >= end) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP: Too short TLV");
|
||||
return -1;
|
||||
}
|
||||
tlv_len = *pos++;
|
||||
if (tlv_len > (unsigned) (end - pos)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP: Truncated TLV");
|
||||
return -1;
|
||||
}
|
||||
pos += tlv_len;
|
||||
break;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "EAP: Unknown TV/TLV type %u",
|
||||
tlv_type);
|
||||
pos = end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ERP */
|
33
freebsd/contrib/wpa/src/eap_common/eap_common.h
Normal file
33
freebsd/contrib/wpa/src/eap_common/eap_common.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* EAP common peer/server definitions
|
||||
* Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_COMMON_H
|
||||
#define EAP_COMMON_H
|
||||
|
||||
#include "wpabuf.h"
|
||||
|
||||
struct erp_tlvs {
|
||||
const u8 *keyname;
|
||||
const u8 *domain;
|
||||
|
||||
u8 keyname_len;
|
||||
u8 domain_len;
|
||||
};
|
||||
|
||||
int eap_hdr_len_valid(const struct wpabuf *msg, size_t min_payload);
|
||||
const u8 * eap_hdr_validate(int vendor, EapType eap_type,
|
||||
const struct wpabuf *msg, size_t *plen);
|
||||
struct wpabuf * eap_msg_alloc(int vendor, EapType type, size_t payload_len,
|
||||
u8 code, u8 identifier);
|
||||
void eap_update_len(struct wpabuf *msg);
|
||||
u8 eap_get_id(const struct wpabuf *msg);
|
||||
EapType eap_get_type(const struct wpabuf *msg);
|
||||
int erp_parse_tlvs(const u8 *pos, const u8 *end, struct erp_tlvs *tlvs,
|
||||
int stop_at_keyname);
|
||||
|
||||
#endif /* EAP_COMMON_H */
|
118
freebsd/contrib/wpa/src/eap_common/eap_defs.h
Normal file
118
freebsd/contrib/wpa/src/eap_common/eap_defs.h
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* EAP server/peer: Shared EAP definitions
|
||||
* Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_DEFS_H
|
||||
#define EAP_DEFS_H
|
||||
|
||||
/* RFC 3748 - Extensible Authentication Protocol (EAP) */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
struct eap_hdr {
|
||||
u8 code;
|
||||
u8 identifier;
|
||||
be16 length; /* including code and identifier; network byte order */
|
||||
/* followed by length-4 octets of data */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
enum { EAP_CODE_REQUEST = 1, EAP_CODE_RESPONSE = 2, EAP_CODE_SUCCESS = 3,
|
||||
EAP_CODE_FAILURE = 4, EAP_CODE_INITIATE = 5, EAP_CODE_FINISH = 6 };
|
||||
|
||||
/* EAP Request and Response data begins with one octet Type. Success and
|
||||
* Failure do not have additional data. */
|
||||
|
||||
/* Type field in EAP-Initiate and EAP-Finish messages */
|
||||
enum eap_erp_type {
|
||||
EAP_ERP_TYPE_REAUTH_START = 1,
|
||||
EAP_ERP_TYPE_REAUTH = 2,
|
||||
};
|
||||
|
||||
/* ERP TV/TLV types */
|
||||
enum eap_erp_tlv_type {
|
||||
EAP_ERP_TLV_KEYNAME_NAI = 1,
|
||||
EAP_ERP_TV_RRK_LIFETIME = 2,
|
||||
EAP_ERP_TV_RMSK_LIFETIME = 3,
|
||||
EAP_ERP_TLV_DOMAIN_NAME = 4,
|
||||
EAP_ERP_TLV_CRYPTOSUITES = 5,
|
||||
EAP_ERP_TLV_AUTHORIZATION_INDICATION = 6,
|
||||
EAP_ERP_TLV_CALLED_STATION_ID = 128,
|
||||
EAP_ERP_TLV_CALLING_STATION_ID = 129,
|
||||
EAP_ERP_TLV_NAS_IDENTIFIER = 130,
|
||||
EAP_ERP_TLV_NAS_IP_ADDRESS = 131,
|
||||
EAP_ERP_TLV_NAS_IPV6_ADDRESS = 132,
|
||||
};
|
||||
|
||||
/* ERP Cryptosuite */
|
||||
enum eap_erp_cryptosuite {
|
||||
EAP_ERP_CS_HMAC_SHA256_64 = 1,
|
||||
EAP_ERP_CS_HMAC_SHA256_128 = 2,
|
||||
EAP_ERP_CS_HMAC_SHA256_256 = 3,
|
||||
};
|
||||
|
||||
/*
|
||||
* EAP Method Types as allocated by IANA:
|
||||
* http://www.iana.org/assignments/eap-numbers
|
||||
*/
|
||||
typedef enum {
|
||||
EAP_TYPE_NONE = 0,
|
||||
EAP_TYPE_IDENTITY = 1 /* RFC 3748 */,
|
||||
EAP_TYPE_NOTIFICATION = 2 /* RFC 3748 */,
|
||||
EAP_TYPE_NAK = 3 /* Response only, RFC 3748 */,
|
||||
EAP_TYPE_MD5 = 4, /* RFC 3748 */
|
||||
EAP_TYPE_OTP = 5 /* RFC 3748 */,
|
||||
EAP_TYPE_GTC = 6, /* RFC 3748 */
|
||||
EAP_TYPE_TLS = 13 /* RFC 2716 */,
|
||||
EAP_TYPE_LEAP = 17 /* Cisco proprietary */,
|
||||
EAP_TYPE_SIM = 18 /* RFC 4186 */,
|
||||
EAP_TYPE_TTLS = 21 /* RFC 5281 */,
|
||||
EAP_TYPE_AKA = 23 /* RFC 4187 */,
|
||||
EAP_TYPE_PEAP = 25 /* draft-josefsson-pppext-eap-tls-eap-06.txt */,
|
||||
EAP_TYPE_MSCHAPV2 = 26 /* draft-kamath-pppext-eap-mschapv2-00.txt */,
|
||||
EAP_TYPE_TLV = 33 /* draft-josefsson-pppext-eap-tls-eap-07.txt */,
|
||||
EAP_TYPE_TNC = 38 /* TNC IF-T v1.0-r3; note: tentative assignment;
|
||||
* type 38 has previously been allocated for
|
||||
* EAP-HTTP Digest, (funk.com) */,
|
||||
EAP_TYPE_FAST = 43 /* RFC 4851 */,
|
||||
EAP_TYPE_PAX = 46 /* RFC 4746 */,
|
||||
EAP_TYPE_PSK = 47 /* RFC 4764 */,
|
||||
EAP_TYPE_SAKE = 48 /* RFC 4763 */,
|
||||
EAP_TYPE_IKEV2 = 49 /* RFC 5106 */,
|
||||
EAP_TYPE_AKA_PRIME = 50 /* RFC 5448 */,
|
||||
EAP_TYPE_GPSK = 51 /* RFC 5433 */,
|
||||
EAP_TYPE_PWD = 52 /* RFC 5931 */,
|
||||
EAP_TYPE_EKE = 53 /* RFC 6124 */,
|
||||
EAP_TYPE_EXPANDED = 254 /* RFC 3748 */
|
||||
} EapType;
|
||||
|
||||
|
||||
/* SMI Network Management Private Enterprise Code for vendor specific types */
|
||||
enum {
|
||||
EAP_VENDOR_IETF = 0,
|
||||
EAP_VENDOR_MICROSOFT = 0x000137 /* Microsoft */,
|
||||
EAP_VENDOR_WFA = 0x00372A /* Wi-Fi Alliance (moved to WBA) */,
|
||||
EAP_VENDOR_HOSTAP = 39068 /* hostapd/wpa_supplicant project */,
|
||||
EAP_VENDOR_WFA_NEW = 40808 /* Wi-Fi Alliance */
|
||||
};
|
||||
|
||||
#define EAP_VENDOR_UNAUTH_TLS EAP_VENDOR_HOSTAP
|
||||
#define EAP_VENDOR_TYPE_UNAUTH_TLS 1
|
||||
|
||||
#define EAP_VENDOR_WFA_UNAUTH_TLS 13
|
||||
|
||||
#define EAP_MSK_LEN 64
|
||||
#define EAP_EMSK_LEN 64
|
||||
#define EAP_EMSK_NAME_LEN 8
|
||||
#define ERP_MAX_KEY_LEN 64
|
||||
|
||||
#endif /* EAP_DEFS_H */
|
87
freebsd/contrib/wpa/src/eap_common/eap_peap_common.c
Normal file
87
freebsd/contrib/wpa/src/eap_common/eap_peap_common.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* EAP-PEAP common routines
|
||||
* Copyright (c) 2008-2011, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "crypto/sha1.h"
|
||||
#include "eap_peap_common.h"
|
||||
|
||||
int peap_prfplus(int version, const u8 *key, size_t key_len,
|
||||
const char *label, const u8 *seed, size_t seed_len,
|
||||
u8 *buf, size_t buf_len)
|
||||
{
|
||||
unsigned char counter = 0;
|
||||
size_t pos, plen;
|
||||
u8 hash[SHA1_MAC_LEN];
|
||||
size_t label_len = os_strlen(label);
|
||||
u8 extra[2];
|
||||
const unsigned char *addr[5];
|
||||
size_t len[5];
|
||||
|
||||
addr[0] = hash;
|
||||
len[0] = 0;
|
||||
addr[1] = (unsigned char *) label;
|
||||
len[1] = label_len;
|
||||
addr[2] = seed;
|
||||
len[2] = seed_len;
|
||||
|
||||
if (version == 0) {
|
||||
/*
|
||||
* PRF+(K, S, LEN) = T1 | T2 | ... | Tn
|
||||
* T1 = HMAC-SHA1(K, S | 0x01 | 0x00 | 0x00)
|
||||
* T2 = HMAC-SHA1(K, T1 | S | 0x02 | 0x00 | 0x00)
|
||||
* ...
|
||||
* Tn = HMAC-SHA1(K, Tn-1 | S | n | 0x00 | 0x00)
|
||||
*/
|
||||
|
||||
extra[0] = 0;
|
||||
extra[1] = 0;
|
||||
|
||||
addr[3] = &counter;
|
||||
len[3] = 1;
|
||||
addr[4] = extra;
|
||||
len[4] = 2;
|
||||
} else {
|
||||
/*
|
||||
* PRF (K,S,LEN) = T1 | T2 | T3 | T4 | ... where:
|
||||
* T1 = HMAC-SHA1(K, S | LEN | 0x01)
|
||||
* T2 = HMAC-SHA1 (K, T1 | S | LEN | 0x02)
|
||||
* T3 = HMAC-SHA1 (K, T2 | S | LEN | 0x03)
|
||||
* T4 = HMAC-SHA1 (K, T3 | S | LEN | 0x04)
|
||||
* ...
|
||||
*/
|
||||
|
||||
extra[0] = buf_len & 0xff;
|
||||
|
||||
addr[3] = extra;
|
||||
len[3] = 1;
|
||||
addr[4] = &counter;
|
||||
len[4] = 1;
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
while (pos < buf_len) {
|
||||
counter++;
|
||||
plen = buf_len - pos;
|
||||
if (hmac_sha1_vector(key, key_len, 5, addr, len, hash) < 0)
|
||||
return -1;
|
||||
if (plen >= SHA1_MAC_LEN) {
|
||||
os_memcpy(&buf[pos], hash, SHA1_MAC_LEN);
|
||||
pos += SHA1_MAC_LEN;
|
||||
} else {
|
||||
os_memcpy(&buf[pos], hash, plen);
|
||||
break;
|
||||
}
|
||||
len[0] = SHA1_MAC_LEN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
16
freebsd/contrib/wpa/src/eap_common/eap_peap_common.h
Normal file
16
freebsd/contrib/wpa/src/eap_common/eap_peap_common.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* EAP-PEAP common routines
|
||||
* Copyright (c) 2008-2011, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_PEAP_COMMON_H
|
||||
#define EAP_PEAP_COMMON_H
|
||||
|
||||
int peap_prfplus(int version, const u8 *key, size_t key_len,
|
||||
const char *label, const u8 *seed, size_t seed_len,
|
||||
u8 *buf, size_t buf_len);
|
||||
|
||||
#endif /* EAP_PEAP_COMMON_H */
|
70
freebsd/contrib/wpa/src/eap_common/eap_psk_common.c
Normal file
70
freebsd/contrib/wpa/src/eap_common/eap_psk_common.c
Normal file
@ -0,0 +1,70 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* EAP server/peer: EAP-PSK shared routines
|
||||
* Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "crypto/aes_wrap.h"
|
||||
#include "eap_defs.h"
|
||||
#include "eap_psk_common.h"
|
||||
|
||||
#define aes_block_size 16
|
||||
|
||||
|
||||
int eap_psk_key_setup(const u8 *psk, u8 *ak, u8 *kdk)
|
||||
{
|
||||
os_memset(ak, 0, aes_block_size);
|
||||
if (aes_128_encrypt_block(psk, ak, ak))
|
||||
return -1;
|
||||
os_memcpy(kdk, ak, aes_block_size);
|
||||
ak[aes_block_size - 1] ^= 0x01;
|
||||
kdk[aes_block_size - 1] ^= 0x02;
|
||||
if (aes_128_encrypt_block(psk, ak, ak) ||
|
||||
aes_128_encrypt_block(psk, kdk, kdk))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int eap_psk_derive_keys(const u8 *kdk, const u8 *rand_p, u8 *tek, u8 *msk,
|
||||
u8 *emsk)
|
||||
{
|
||||
u8 hash[aes_block_size];
|
||||
u8 counter = 1;
|
||||
int i;
|
||||
|
||||
if (aes_128_encrypt_block(kdk, rand_p, hash))
|
||||
return -1;
|
||||
|
||||
hash[aes_block_size - 1] ^= counter;
|
||||
if (aes_128_encrypt_block(kdk, hash, tek))
|
||||
return -1;
|
||||
hash[aes_block_size - 1] ^= counter;
|
||||
counter++;
|
||||
|
||||
for (i = 0; i < EAP_MSK_LEN / aes_block_size; i++) {
|
||||
hash[aes_block_size - 1] ^= counter;
|
||||
if (aes_128_encrypt_block(kdk, hash, &msk[i * aes_block_size]))
|
||||
return -1;
|
||||
hash[aes_block_size - 1] ^= counter;
|
||||
counter++;
|
||||
}
|
||||
|
||||
for (i = 0; i < EAP_EMSK_LEN / aes_block_size; i++) {
|
||||
hash[aes_block_size - 1] ^= counter;
|
||||
if (aes_128_encrypt_block(kdk, hash,
|
||||
&emsk[i * aes_block_size]))
|
||||
return -1;
|
||||
hash[aes_block_size - 1] ^= counter;
|
||||
counter++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
72
freebsd/contrib/wpa/src/eap_common/eap_psk_common.h
Normal file
72
freebsd/contrib/wpa/src/eap_common/eap_psk_common.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* EAP server/peer: EAP-PSK shared routines
|
||||
* Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_PSK_COMMON_H
|
||||
#define EAP_PSK_COMMON_H
|
||||
|
||||
|
||||
#define EAP_PSK_RAND_LEN 16
|
||||
#define EAP_PSK_MAC_LEN 16
|
||||
#define EAP_PSK_TEK_LEN 16
|
||||
#define EAP_PSK_PSK_LEN 16
|
||||
#define EAP_PSK_AK_LEN 16
|
||||
#define EAP_PSK_KDK_LEN 16
|
||||
|
||||
#define EAP_PSK_R_FLAG_CONT 1
|
||||
#define EAP_PSK_R_FLAG_DONE_SUCCESS 2
|
||||
#define EAP_PSK_R_FLAG_DONE_FAILURE 3
|
||||
#define EAP_PSK_E_FLAG 0x20
|
||||
|
||||
#define EAP_PSK_FLAGS_GET_T(flags) (((flags) & 0xc0) >> 6)
|
||||
#define EAP_PSK_FLAGS_SET_T(t) ((u8) (t) << 6)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/* EAP-PSK First Message (AS -> Supplicant) */
|
||||
struct eap_psk_hdr_1 {
|
||||
u8 flags;
|
||||
u8 rand_s[EAP_PSK_RAND_LEN];
|
||||
/* Followed by variable length ID_S */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
/* EAP-PSK Second Message (Supplicant -> AS) */
|
||||
struct eap_psk_hdr_2 {
|
||||
u8 flags;
|
||||
u8 rand_s[EAP_PSK_RAND_LEN];
|
||||
u8 rand_p[EAP_PSK_RAND_LEN];
|
||||
u8 mac_p[EAP_PSK_MAC_LEN];
|
||||
/* Followed by variable length ID_P */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
/* EAP-PSK Third Message (AS -> Supplicant) */
|
||||
struct eap_psk_hdr_3 {
|
||||
u8 flags;
|
||||
u8 rand_s[EAP_PSK_RAND_LEN];
|
||||
u8 mac_s[EAP_PSK_MAC_LEN];
|
||||
/* Followed by variable length PCHANNEL */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
/* EAP-PSK Fourth Message (Supplicant -> AS) */
|
||||
struct eap_psk_hdr_4 {
|
||||
u8 flags;
|
||||
u8 rand_s[EAP_PSK_RAND_LEN];
|
||||
/* Followed by variable length PCHANNEL */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
|
||||
int __must_check eap_psk_key_setup(const u8 *psk, u8 *ak, u8 *kdk);
|
||||
int __must_check eap_psk_derive_keys(const u8 *kdk, const u8 *rand_p, u8 *tek,
|
||||
u8 *msk, u8 *emsk);
|
||||
|
||||
#endif /* EAP_PSK_COMMON_H */
|
112
freebsd/contrib/wpa/src/eap_common/eap_tlv_common.h
Normal file
112
freebsd/contrib/wpa/src/eap_common/eap_tlv_common.h
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* EAP-TLV definitions (draft-josefsson-pppext-eap-tls-eap-10.txt)
|
||||
* Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_TLV_COMMON_H
|
||||
#define EAP_TLV_COMMON_H
|
||||
|
||||
/* EAP-TLV TLVs (draft-josefsson-ppext-eap-tls-eap-10.txt) */
|
||||
#define EAP_TLV_RESULT_TLV 3 /* Acknowledged Result */
|
||||
#define EAP_TLV_NAK_TLV 4
|
||||
#define EAP_TLV_ERROR_CODE_TLV 5
|
||||
#define EAP_TLV_CONNECTION_BINDING_TLV 6
|
||||
#define EAP_TLV_VENDOR_SPECIFIC_TLV 7
|
||||
#define EAP_TLV_URI_TLV 8
|
||||
#define EAP_TLV_EAP_PAYLOAD_TLV 9
|
||||
#define EAP_TLV_INTERMEDIATE_RESULT_TLV 10
|
||||
#define EAP_TLV_PAC_TLV 11 /* RFC 5422, Section 4.2 */
|
||||
#define EAP_TLV_CRYPTO_BINDING_TLV 12
|
||||
#define EAP_TLV_CALLING_STATION_ID_TLV 13
|
||||
#define EAP_TLV_CALLED_STATION_ID_TLV 14
|
||||
#define EAP_TLV_NAS_PORT_TYPE_TLV 15
|
||||
#define EAP_TLV_SERVER_IDENTIFIER_TLV 16
|
||||
#define EAP_TLV_IDENTITY_TYPE_TLV 17
|
||||
#define EAP_TLV_SERVER_TRUSTED_ROOT_TLV 18
|
||||
#define EAP_TLV_REQUEST_ACTION_TLV 19
|
||||
#define EAP_TLV_PKCS7_TLV 20
|
||||
|
||||
#define EAP_TLV_RESULT_SUCCESS 1
|
||||
#define EAP_TLV_RESULT_FAILURE 2
|
||||
|
||||
#define EAP_TLV_TYPE_MANDATORY 0x8000
|
||||
#define EAP_TLV_TYPE_MASK 0x3fff
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
struct eap_tlv_hdr {
|
||||
be16 tlv_type;
|
||||
be16 length;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
struct eap_tlv_nak_tlv {
|
||||
be16 tlv_type;
|
||||
be16 length;
|
||||
be32 vendor_id;
|
||||
be16 nak_type;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
struct eap_tlv_result_tlv {
|
||||
be16 tlv_type;
|
||||
be16 length;
|
||||
be16 status;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
/* RFC 4851, Section 4.2.7 - Intermediate-Result TLV */
|
||||
struct eap_tlv_intermediate_result_tlv {
|
||||
be16 tlv_type;
|
||||
be16 length;
|
||||
be16 status;
|
||||
/* Followed by optional TLVs */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
/* RFC 4851, Section 4.2.8 - Crypto-Binding TLV */
|
||||
struct eap_tlv_crypto_binding_tlv {
|
||||
be16 tlv_type;
|
||||
be16 length;
|
||||
u8 reserved;
|
||||
u8 version;
|
||||
u8 received_version;
|
||||
u8 subtype;
|
||||
u8 nonce[32];
|
||||
u8 compound_mac[20];
|
||||
} STRUCT_PACKED;
|
||||
|
||||
struct eap_tlv_pac_ack_tlv {
|
||||
be16 tlv_type;
|
||||
be16 length;
|
||||
be16 pac_type;
|
||||
be16 pac_len;
|
||||
be16 result;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
/* RFC 4851, Section 4.2.9 - Request-Action TLV */
|
||||
struct eap_tlv_request_action_tlv {
|
||||
be16 tlv_type;
|
||||
be16 length;
|
||||
be16 action;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
/* RFC 5422, Section 4.2.6 - PAC-Type TLV */
|
||||
struct eap_tlv_pac_type_tlv {
|
||||
be16 tlv_type; /* PAC_TYPE_PAC_TYPE */
|
||||
be16 length;
|
||||
be16 pac_type;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#define EAP_TLV_CRYPTO_BINDING_SUBTYPE_REQUEST 0
|
||||
#define EAP_TLV_CRYPTO_BINDING_SUBTYPE_RESPONSE 1
|
||||
|
||||
#define EAP_TLV_ACTION_PROCESS_TLV 1
|
||||
#define EAP_TLV_ACTION_NEGOTIATE_EAP 2
|
||||
|
||||
#endif /* EAP_TLV_COMMON_H */
|
65
freebsd/contrib/wpa/src/eap_common/eap_ttls.h
Normal file
65
freebsd/contrib/wpa/src/eap_common/eap_ttls.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* EAP server/peer: EAP-TTLS (RFC 5281)
|
||||
* Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_TTLS_H
|
||||
#define EAP_TTLS_H
|
||||
|
||||
struct ttls_avp {
|
||||
be32 avp_code;
|
||||
be32 avp_length; /* 8-bit flags, 24-bit length;
|
||||
* length includes AVP header */
|
||||
/* optional 32-bit Vendor-ID */
|
||||
/* Data */
|
||||
};
|
||||
|
||||
struct ttls_avp_vendor {
|
||||
be32 avp_code;
|
||||
be32 avp_length; /* 8-bit flags, 24-bit length;
|
||||
* length includes AVP header */
|
||||
be32 vendor_id;
|
||||
/* Data */
|
||||
};
|
||||
|
||||
#define AVP_FLAGS_VENDOR 0x80
|
||||
#define AVP_FLAGS_MANDATORY 0x40
|
||||
|
||||
#define AVP_PAD(start, pos) \
|
||||
do { \
|
||||
int __pad; \
|
||||
__pad = (4 - (((pos) - (start)) & 3)) & 3; \
|
||||
os_memset((pos), 0, __pad); \
|
||||
pos += __pad; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* RFC 2865 */
|
||||
#define RADIUS_ATTR_USER_NAME 1
|
||||
#define RADIUS_ATTR_USER_PASSWORD 2
|
||||
#define RADIUS_ATTR_CHAP_PASSWORD 3
|
||||
#define RADIUS_ATTR_REPLY_MESSAGE 18
|
||||
#define RADIUS_ATTR_CHAP_CHALLENGE 60
|
||||
#define RADIUS_ATTR_EAP_MESSAGE 79
|
||||
|
||||
/* RFC 2548 */
|
||||
#define RADIUS_VENDOR_ID_MICROSOFT 311
|
||||
#define RADIUS_ATTR_MS_CHAP_RESPONSE 1
|
||||
#define RADIUS_ATTR_MS_CHAP_ERROR 2
|
||||
#define RADIUS_ATTR_MS_CHAP_NT_ENC_PW 6
|
||||
#define RADIUS_ATTR_MS_CHAP_CHALLENGE 11
|
||||
#define RADIUS_ATTR_MS_CHAP2_RESPONSE 25
|
||||
#define RADIUS_ATTR_MS_CHAP2_SUCCESS 26
|
||||
#define RADIUS_ATTR_MS_CHAP2_CPW 27
|
||||
|
||||
#define EAP_TTLS_MSCHAPV2_CHALLENGE_LEN 16
|
||||
#define EAP_TTLS_MSCHAPV2_RESPONSE_LEN 50
|
||||
#define EAP_TTLS_MSCHAP_CHALLENGE_LEN 8
|
||||
#define EAP_TTLS_MSCHAP_RESPONSE_LEN 50
|
||||
#define EAP_TTLS_CHAP_CHALLENGE_LEN 16
|
||||
#define EAP_TTLS_CHAP_PASSWORD_LEN 16
|
||||
|
||||
#endif /* EAP_TTLS_H */
|
27
freebsd/contrib/wpa/src/eap_common/eap_wsc_common.h
Normal file
27
freebsd/contrib/wpa/src/eap_common/eap_wsc_common.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* EAP-WSC definitions for Wi-Fi Protected Setup
|
||||
* Copyright (c) 2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_WSC_COMMON_H
|
||||
#define EAP_WSC_COMMON_H
|
||||
|
||||
#define EAP_VENDOR_TYPE_WSC 1
|
||||
|
||||
#define WSC_FLAGS_MF 0x01
|
||||
#define WSC_FLAGS_LF 0x02
|
||||
|
||||
#define WSC_ID_REGISTRAR "WFA-SimpleConfig-Registrar-1-0"
|
||||
#define WSC_ID_REGISTRAR_LEN 30
|
||||
#define WSC_ID_ENROLLEE "WFA-SimpleConfig-Enrollee-1-0"
|
||||
#define WSC_ID_ENROLLEE_LEN 29
|
||||
|
||||
#define WSC_FRAGMENT_SIZE 1400
|
||||
|
||||
|
||||
struct wpabuf * eap_wsc_build_frag_ack(u8 id, u8 code);
|
||||
|
||||
#endif /* EAP_WSC_COMMON_H */
|
2952
freebsd/contrib/wpa/src/eap_peer/eap.c
Normal file
2952
freebsd/contrib/wpa/src/eap_peer/eap.c
Normal file
File diff suppressed because it is too large
Load Diff
354
freebsd/contrib/wpa/src/eap_peer/eap.h
Normal file
354
freebsd/contrib/wpa/src/eap_peer/eap.h
Normal file
@ -0,0 +1,354 @@
|
||||
/*
|
||||
* EAP peer state machine functions (RFC 4137)
|
||||
* Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_H
|
||||
#define EAP_H
|
||||
|
||||
#include "common/defs.h"
|
||||
#include "eap_common/eap_defs.h"
|
||||
#include "eap_peer/eap_methods.h"
|
||||
|
||||
struct eap_sm;
|
||||
struct wpa_config_blob;
|
||||
struct wpabuf;
|
||||
|
||||
struct eap_method_type {
|
||||
int vendor;
|
||||
u32 method;
|
||||
};
|
||||
|
||||
#ifdef IEEE8021X_EAPOL
|
||||
|
||||
/**
|
||||
* enum eapol_bool_var - EAPOL boolean state variables for EAP state machine
|
||||
*
|
||||
* These variables are used in the interface between EAP peer state machine and
|
||||
* lower layer. These are defined in RFC 4137, Sect. 4.1. Lower layer code is
|
||||
* expected to maintain these variables and register a callback functions for
|
||||
* EAP state machine to get and set the variables.
|
||||
*/
|
||||
enum eapol_bool_var {
|
||||
/**
|
||||
* EAPOL_eapSuccess - EAP SUCCESS state reached
|
||||
*
|
||||
* EAP state machine reads and writes this value.
|
||||
*/
|
||||
EAPOL_eapSuccess,
|
||||
|
||||
/**
|
||||
* EAPOL_eapRestart - Lower layer request to restart authentication
|
||||
*
|
||||
* Set to TRUE in lower layer, FALSE in EAP state machine.
|
||||
*/
|
||||
EAPOL_eapRestart,
|
||||
|
||||
/**
|
||||
* EAPOL_eapFail - EAP FAILURE state reached
|
||||
*
|
||||
* EAP state machine writes this value.
|
||||
*/
|
||||
EAPOL_eapFail,
|
||||
|
||||
/**
|
||||
* EAPOL_eapResp - Response to send
|
||||
*
|
||||
* Set to TRUE in EAP state machine, FALSE in lower layer.
|
||||
*/
|
||||
EAPOL_eapResp,
|
||||
|
||||
/**
|
||||
* EAPOL_eapNoResp - Request has been process; no response to send
|
||||
*
|
||||
* Set to TRUE in EAP state machine, FALSE in lower layer.
|
||||
*/
|
||||
EAPOL_eapNoResp,
|
||||
|
||||
/**
|
||||
* EAPOL_eapReq - EAP request available from lower layer
|
||||
*
|
||||
* Set to TRUE in lower layer, FALSE in EAP state machine.
|
||||
*/
|
||||
EAPOL_eapReq,
|
||||
|
||||
/**
|
||||
* EAPOL_portEnabled - Lower layer is ready for communication
|
||||
*
|
||||
* EAP state machines reads this value.
|
||||
*/
|
||||
EAPOL_portEnabled,
|
||||
|
||||
/**
|
||||
* EAPOL_altAccept - Alternate indication of success (RFC3748)
|
||||
*
|
||||
* EAP state machines reads this value.
|
||||
*/
|
||||
EAPOL_altAccept,
|
||||
|
||||
/**
|
||||
* EAPOL_altReject - Alternate indication of failure (RFC3748)
|
||||
*
|
||||
* EAP state machines reads this value.
|
||||
*/
|
||||
EAPOL_altReject,
|
||||
|
||||
/**
|
||||
* EAPOL_eapTriggerStart - EAP-based trigger to send EAPOL-Start
|
||||
*
|
||||
* EAP state machine writes this value.
|
||||
*/
|
||||
EAPOL_eapTriggerStart
|
||||
};
|
||||
|
||||
/**
|
||||
* enum eapol_int_var - EAPOL integer state variables for EAP state machine
|
||||
*
|
||||
* These variables are used in the interface between EAP peer state machine and
|
||||
* lower layer. These are defined in RFC 4137, Sect. 4.1. Lower layer code is
|
||||
* expected to maintain these variables and register a callback functions for
|
||||
* EAP state machine to get and set the variables.
|
||||
*/
|
||||
enum eapol_int_var {
|
||||
/**
|
||||
* EAPOL_idleWhile - Outside time for EAP peer timeout
|
||||
*
|
||||
* This integer variable is used to provide an outside timer that the
|
||||
* external (to EAP state machine) code must decrement by one every
|
||||
* second until the value reaches zero. This is used in the same way as
|
||||
* EAPOL state machine timers. EAP state machine reads and writes this
|
||||
* value.
|
||||
*/
|
||||
EAPOL_idleWhile
|
||||
};
|
||||
|
||||
/**
|
||||
* struct eapol_callbacks - Callback functions from EAP to lower layer
|
||||
*
|
||||
* This structure defines the callback functions that EAP state machine
|
||||
* requires from the lower layer (usually EAPOL state machine) for updating
|
||||
* state variables and requesting information. eapol_ctx from
|
||||
* eap_peer_sm_init() call will be used as the ctx parameter for these
|
||||
* callback functions.
|
||||
*/
|
||||
struct eapol_callbacks {
|
||||
/**
|
||||
* get_config - Get pointer to the current network configuration
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
*/
|
||||
struct eap_peer_config * (*get_config)(void *ctx);
|
||||
|
||||
/**
|
||||
* get_bool - Get a boolean EAPOL state variable
|
||||
* @variable: EAPOL boolean variable to get
|
||||
* Returns: Value of the EAPOL variable
|
||||
*/
|
||||
Boolean (*get_bool)(void *ctx, enum eapol_bool_var variable);
|
||||
|
||||
/**
|
||||
* set_bool - Set a boolean EAPOL state variable
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
* @variable: EAPOL boolean variable to set
|
||||
* @value: Value for the EAPOL variable
|
||||
*/
|
||||
void (*set_bool)(void *ctx, enum eapol_bool_var variable,
|
||||
Boolean value);
|
||||
|
||||
/**
|
||||
* get_int - Get an integer EAPOL state variable
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
* @variable: EAPOL integer variable to get
|
||||
* Returns: Value of the EAPOL variable
|
||||
*/
|
||||
unsigned int (*get_int)(void *ctx, enum eapol_int_var variable);
|
||||
|
||||
/**
|
||||
* set_int - Set an integer EAPOL state variable
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
* @variable: EAPOL integer variable to set
|
||||
* @value: Value for the EAPOL variable
|
||||
*/
|
||||
void (*set_int)(void *ctx, enum eapol_int_var variable,
|
||||
unsigned int value);
|
||||
|
||||
/**
|
||||
* get_eapReqData - Get EAP-Request data
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
* @len: Pointer to variable that will be set to eapReqDataLen
|
||||
* Returns: Reference to eapReqData (EAP state machine will not free
|
||||
* this) or %NULL if eapReqData not available.
|
||||
*/
|
||||
struct wpabuf * (*get_eapReqData)(void *ctx);
|
||||
|
||||
/**
|
||||
* set_config_blob - Set named configuration blob
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
* @blob: New value for the blob
|
||||
*
|
||||
* Adds a new configuration blob or replaces the current value of an
|
||||
* existing blob.
|
||||
*/
|
||||
void (*set_config_blob)(void *ctx, struct wpa_config_blob *blob);
|
||||
|
||||
/**
|
||||
* get_config_blob - Get a named configuration blob
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
* @name: Name of the blob
|
||||
* Returns: Pointer to blob data or %NULL if not found
|
||||
*/
|
||||
const struct wpa_config_blob * (*get_config_blob)(void *ctx,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* notify_pending - Notify that a pending request can be retried
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
*
|
||||
* An EAP method can perform a pending operation (e.g., to get a
|
||||
* response from an external process). Once the response is available,
|
||||
* this callback function can be used to request EAPOL state machine to
|
||||
* retry delivering the previously received (and still unanswered) EAP
|
||||
* request to EAP state machine.
|
||||
*/
|
||||
void (*notify_pending)(void *ctx);
|
||||
|
||||
/**
|
||||
* eap_param_needed - Notify that EAP parameter is needed
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
* @field: Field indicator (e.g., WPA_CTRL_REQ_EAP_IDENTITY)
|
||||
* @txt: User readable text describing the required parameter
|
||||
*/
|
||||
void (*eap_param_needed)(void *ctx, enum wpa_ctrl_req_type field,
|
||||
const char *txt);
|
||||
|
||||
/**
|
||||
* notify_cert - Notification of a peer certificate
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
* @depth: Depth in certificate chain (0 = server)
|
||||
* @subject: Subject of the peer certificate
|
||||
* @altsubject: Select fields from AltSubject of the peer certificate
|
||||
* @num_altsubject: Number of altsubject values
|
||||
* @cert_hash: SHA-256 hash of the certificate
|
||||
* @cert: Peer certificate
|
||||
*/
|
||||
void (*notify_cert)(void *ctx, int depth, const char *subject,
|
||||
const char *altsubject[], int num_altsubject,
|
||||
const char *cert_hash, const struct wpabuf *cert);
|
||||
|
||||
/**
|
||||
* notify_status - Notification of the current EAP state
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
* @status: Step in the process of EAP authentication
|
||||
* @parameter: Step-specific parameter, e.g., EAP method name
|
||||
*/
|
||||
void (*notify_status)(void *ctx, const char *status,
|
||||
const char *parameter);
|
||||
|
||||
#ifdef CONFIG_EAP_PROXY
|
||||
/**
|
||||
* eap_proxy_cb - Callback signifying any updates from eap_proxy
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
*/
|
||||
void (*eap_proxy_cb)(void *ctx);
|
||||
#endif /* CONFIG_EAP_PROXY */
|
||||
|
||||
/**
|
||||
* set_anon_id - Set or add anonymous identity
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
* @id: Anonymous identity (e.g., EAP-SIM pseudonym) or %NULL to clear
|
||||
* @len: Length of anonymous identity in octets
|
||||
*/
|
||||
void (*set_anon_id)(void *ctx, const u8 *id, size_t len);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct eap_config - Configuration for EAP state machine
|
||||
*/
|
||||
struct eap_config {
|
||||
/**
|
||||
* opensc_engine_path - OpenSC engine for OpenSSL engine support
|
||||
*
|
||||
* Usually, path to engine_opensc.so.
|
||||
*/
|
||||
const char *opensc_engine_path;
|
||||
/**
|
||||
* pkcs11_engine_path - PKCS#11 engine for OpenSSL engine support
|
||||
*
|
||||
* Usually, path to engine_pkcs11.so.
|
||||
*/
|
||||
const char *pkcs11_engine_path;
|
||||
/**
|
||||
* pkcs11_module_path - OpenSC PKCS#11 module for OpenSSL engine
|
||||
*
|
||||
* Usually, path to opensc-pkcs11.so.
|
||||
*/
|
||||
const char *pkcs11_module_path;
|
||||
/**
|
||||
* openssl_ciphers - OpenSSL cipher string
|
||||
*
|
||||
* This is an OpenSSL specific configuration option for configuring the
|
||||
* default ciphers. If not set, "DEFAULT:!EXP:!LOW" is used as the
|
||||
* default.
|
||||
*/
|
||||
const char *openssl_ciphers;
|
||||
/**
|
||||
* wps - WPS context data
|
||||
*
|
||||
* This is only used by EAP-WSC and can be left %NULL if not available.
|
||||
*/
|
||||
struct wps_context *wps;
|
||||
|
||||
/**
|
||||
* cert_in_cb - Include server certificates in callback
|
||||
*/
|
||||
int cert_in_cb;
|
||||
};
|
||||
|
||||
struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
|
||||
const struct eapol_callbacks *eapol_cb,
|
||||
void *msg_ctx, struct eap_config *conf);
|
||||
void eap_peer_sm_deinit(struct eap_sm *sm);
|
||||
int eap_peer_sm_step(struct eap_sm *sm);
|
||||
void eap_sm_abort(struct eap_sm *sm);
|
||||
int eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen,
|
||||
int verbose);
|
||||
const char * eap_sm_get_method_name(struct eap_sm *sm);
|
||||
struct wpabuf * eap_sm_buildIdentity(struct eap_sm *sm, int id, int encrypted);
|
||||
void eap_sm_request_identity(struct eap_sm *sm);
|
||||
void eap_sm_request_password(struct eap_sm *sm);
|
||||
void eap_sm_request_new_password(struct eap_sm *sm);
|
||||
void eap_sm_request_pin(struct eap_sm *sm);
|
||||
void eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len);
|
||||
void eap_sm_request_passphrase(struct eap_sm *sm);
|
||||
void eap_sm_request_sim(struct eap_sm *sm, const char *req);
|
||||
void eap_sm_notify_ctrl_attached(struct eap_sm *sm);
|
||||
u32 eap_get_phase2_type(const char *name, int *vendor);
|
||||
struct eap_method_type * eap_get_phase2_types(struct eap_peer_config *config,
|
||||
size_t *count);
|
||||
void eap_set_fast_reauth(struct eap_sm *sm, int enabled);
|
||||
void eap_set_workaround(struct eap_sm *sm, unsigned int workaround);
|
||||
void eap_set_force_disabled(struct eap_sm *sm, int disabled);
|
||||
void eap_set_external_sim(struct eap_sm *sm, int external_sim);
|
||||
int eap_key_available(struct eap_sm *sm);
|
||||
void eap_notify_success(struct eap_sm *sm);
|
||||
void eap_notify_lower_layer_success(struct eap_sm *sm);
|
||||
const u8 * eap_get_eapSessionId(struct eap_sm *sm, size_t *len);
|
||||
const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len);
|
||||
struct wpabuf * eap_get_eapRespData(struct eap_sm *sm);
|
||||
void eap_register_scard_ctx(struct eap_sm *sm, void *ctx);
|
||||
void eap_invalidate_cached_session(struct eap_sm *sm);
|
||||
|
||||
int eap_is_wps_pbc_enrollee(struct eap_peer_config *conf);
|
||||
int eap_is_wps_pin_enrollee(struct eap_peer_config *conf);
|
||||
|
||||
struct ext_password_data;
|
||||
void eap_sm_set_ext_pw_ctx(struct eap_sm *sm, struct ext_password_data *ext);
|
||||
void eap_set_anon_id(struct eap_sm *sm, const u8 *id, size_t len);
|
||||
int eap_peer_was_failure_expected(struct eap_sm *sm);
|
||||
void eap_peer_erp_free_keys(struct eap_sm *sm);
|
||||
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
|
||||
#endif /* EAP_H */
|
774
freebsd/contrib/wpa/src/eap_peer/eap_config.h
Normal file
774
freebsd/contrib/wpa/src/eap_peer/eap_config.h
Normal file
@ -0,0 +1,774 @@
|
||||
/*
|
||||
* EAP peer configuration data
|
||||
* Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_CONFIG_H
|
||||
#define EAP_CONFIG_H
|
||||
|
||||
/**
|
||||
* struct eap_peer_config - EAP peer configuration/credentials
|
||||
*/
|
||||
struct eap_peer_config {
|
||||
/**
|
||||
* identity - EAP Identity
|
||||
*
|
||||
* This field is used to set the real user identity or NAI (for
|
||||
* EAP-PSK/PAX/SAKE/GPSK).
|
||||
*/
|
||||
u8 *identity;
|
||||
|
||||
/**
|
||||
* identity_len - EAP Identity length
|
||||
*/
|
||||
size_t identity_len;
|
||||
|
||||
/**
|
||||
* anonymous_identity - Anonymous EAP Identity
|
||||
*
|
||||
* This field is used for unencrypted use with EAP types that support
|
||||
* different tunnelled identity, e.g., EAP-TTLS, in order to reveal the
|
||||
* real identity (identity field) only to the authentication server.
|
||||
*
|
||||
* If not set, the identity field will be used for both unencrypted and
|
||||
* protected fields.
|
||||
*
|
||||
* This field can also be used with EAP-SIM/AKA/AKA' to store the
|
||||
* pseudonym identity.
|
||||
*/
|
||||
u8 *anonymous_identity;
|
||||
|
||||
/**
|
||||
* anonymous_identity_len - Length of anonymous_identity
|
||||
*/
|
||||
size_t anonymous_identity_len;
|
||||
|
||||
/**
|
||||
* password - Password string for EAP
|
||||
*
|
||||
* This field can include either the plaintext password (default
|
||||
* option) or a NtPasswordHash (16-byte MD4 hash of the unicode
|
||||
* presentation of the password) if flags field has
|
||||
* EAP_CONFIG_FLAGS_PASSWORD_NTHASH bit set to 1. NtPasswordHash can
|
||||
* only be used with authentication mechanism that use this hash as the
|
||||
* starting point for operation: MSCHAP and MSCHAPv2 (EAP-MSCHAPv2,
|
||||
* EAP-TTLS/MSCHAPv2, EAP-TTLS/MSCHAP, LEAP).
|
||||
*
|
||||
* In addition, this field is used to configure a pre-shared key for
|
||||
* EAP-PSK/PAX/SAKE/GPSK. The length of the PSK must be 16 for EAP-PSK
|
||||
* and EAP-PAX and 32 for EAP-SAKE. EAP-GPSK can use a variable length
|
||||
* PSK.
|
||||
*/
|
||||
u8 *password;
|
||||
|
||||
/**
|
||||
* password_len - Length of password field
|
||||
*/
|
||||
size_t password_len;
|
||||
|
||||
/**
|
||||
* ca_cert - File path to CA certificate file (PEM/DER)
|
||||
*
|
||||
* This file can have one or more trusted CA certificates. If ca_cert
|
||||
* and ca_path are not included, server certificate will not be
|
||||
* verified. This is insecure and a trusted CA certificate should
|
||||
* always be configured when using EAP-TLS/TTLS/PEAP. Full path to the
|
||||
* file should be used since working directory may change when
|
||||
* wpa_supplicant is run in the background.
|
||||
*
|
||||
* Alternatively, a named configuration blob can be used by setting
|
||||
* this to blob://blob_name.
|
||||
*
|
||||
* Alternatively, this can be used to only perform matching of the
|
||||
* server certificate (SHA-256 hash of the DER encoded X.509
|
||||
* certificate). In this case, the possible CA certificates in the
|
||||
* server certificate chain are ignored and only the server certificate
|
||||
* is verified. This is configured with the following format:
|
||||
* hash:://server/sha256/cert_hash_in_hex
|
||||
* For example: "hash://server/sha256/
|
||||
* 5a1bc1296205e6fdbe3979728efe3920798885c1c4590b5f90f43222d239ca6a"
|
||||
*
|
||||
* On Windows, trusted CA certificates can be loaded from the system
|
||||
* certificate store by setting this to cert_store://name, e.g.,
|
||||
* ca_cert="cert_store://CA" or ca_cert="cert_store://ROOT".
|
||||
* Note that when running wpa_supplicant as an application, the user
|
||||
* certificate store (My user account) is used, whereas computer store
|
||||
* (Computer account) is used when running wpasvc as a service.
|
||||
*/
|
||||
u8 *ca_cert;
|
||||
|
||||
/**
|
||||
* ca_path - Directory path for CA certificate files (PEM)
|
||||
*
|
||||
* This path may contain multiple CA certificates in OpenSSL format.
|
||||
* Common use for this is to point to system trusted CA list which is
|
||||
* often installed into directory like /etc/ssl/certs. If configured,
|
||||
* these certificates are added to the list of trusted CAs. ca_cert
|
||||
* may also be included in that case, but it is not required.
|
||||
*/
|
||||
u8 *ca_path;
|
||||
|
||||
/**
|
||||
* client_cert - File path to client certificate file (PEM/DER)
|
||||
*
|
||||
* This field is used with EAP method that use TLS authentication.
|
||||
* Usually, this is only configured for EAP-TLS, even though this could
|
||||
* in theory be used with EAP-TTLS and EAP-PEAP, too. Full path to the
|
||||
* file should be used since working directory may change when
|
||||
* wpa_supplicant is run in the background.
|
||||
*
|
||||
* Alternatively, a named configuration blob can be used by setting
|
||||
* this to blob://blob_name.
|
||||
*/
|
||||
u8 *client_cert;
|
||||
|
||||
/**
|
||||
* private_key - File path to client private key file (PEM/DER/PFX)
|
||||
*
|
||||
* When PKCS#12/PFX file (.p12/.pfx) is used, client_cert should be
|
||||
* commented out. Both the private key and certificate will be read
|
||||
* from the PKCS#12 file in this case. Full path to the file should be
|
||||
* used since working directory may change when wpa_supplicant is run
|
||||
* in the background.
|
||||
*
|
||||
* Windows certificate store can be used by leaving client_cert out and
|
||||
* configuring private_key in one of the following formats:
|
||||
*
|
||||
* cert://substring_to_match
|
||||
*
|
||||
* hash://certificate_thumbprint_in_hex
|
||||
*
|
||||
* For example: private_key="hash://63093aa9c47f56ae88334c7b65a4"
|
||||
*
|
||||
* Note that when running wpa_supplicant as an application, the user
|
||||
* certificate store (My user account) is used, whereas computer store
|
||||
* (Computer account) is used when running wpasvc as a service.
|
||||
*
|
||||
* Alternatively, a named configuration blob can be used by setting
|
||||
* this to blob://blob_name.
|
||||
*/
|
||||
u8 *private_key;
|
||||
|
||||
/**
|
||||
* private_key_passwd - Password for private key file
|
||||
*
|
||||
* If left out, this will be asked through control interface.
|
||||
*/
|
||||
char *private_key_passwd;
|
||||
|
||||
/**
|
||||
* dh_file - File path to DH/DSA parameters file (in PEM format)
|
||||
*
|
||||
* This is an optional configuration file for setting parameters for an
|
||||
* ephemeral DH key exchange. In most cases, the default RSA
|
||||
* authentication does not use this configuration. However, it is
|
||||
* possible setup RSA to use ephemeral DH key exchange. In addition,
|
||||
* ciphers with DSA keys always use ephemeral DH keys. This can be used
|
||||
* to achieve forward secrecy. If the file is in DSA parameters format,
|
||||
* it will be automatically converted into DH params. Full path to the
|
||||
* file should be used since working directory may change when
|
||||
* wpa_supplicant is run in the background.
|
||||
*
|
||||
* Alternatively, a named configuration blob can be used by setting
|
||||
* this to blob://blob_name.
|
||||
*/
|
||||
u8 *dh_file;
|
||||
|
||||
/**
|
||||
* subject_match - Constraint for server certificate subject
|
||||
*
|
||||
* This substring is matched against the subject of the authentication
|
||||
* server certificate. If this string is set, the server sertificate is
|
||||
* only accepted if it contains this string in the subject. The subject
|
||||
* string is in following format:
|
||||
*
|
||||
* /C=US/ST=CA/L=San Francisco/CN=Test AS/emailAddress=as@n.example.com
|
||||
*
|
||||
* Note: Since this is a substring match, this cannot be used securily
|
||||
* to do a suffix match against a possible domain name in the CN entry.
|
||||
* For such a use case, domain_suffix_match should be used instead.
|
||||
*/
|
||||
u8 *subject_match;
|
||||
|
||||
/**
|
||||
* altsubject_match - Constraint for server certificate alt. subject
|
||||
*
|
||||
* Semicolon separated string of entries to be matched against the
|
||||
* alternative subject name of the authentication server certificate.
|
||||
* If this string is set, the server sertificate is only accepted if it
|
||||
* contains one of the entries in an alternative subject name
|
||||
* extension.
|
||||
*
|
||||
* altSubjectName string is in following format: TYPE:VALUE
|
||||
*
|
||||
* Example: EMAIL:server@example.com
|
||||
* Example: DNS:server.example.com;DNS:server2.example.com
|
||||
*
|
||||
* Following types are supported: EMAIL, DNS, URI
|
||||
*/
|
||||
u8 *altsubject_match;
|
||||
|
||||
/**
|
||||
* domain_suffix_match - Constraint for server domain name
|
||||
*
|
||||
* If set, this FQDN is used as a suffix match requirement for the
|
||||
* server certificate in SubjectAltName dNSName element(s). If a
|
||||
* matching dNSName is found, this constraint is met. If no dNSName
|
||||
* values are present, this constraint is matched against SubjectName CN
|
||||
* using same suffix match comparison. Suffix match here means that the
|
||||
* host/domain name is compared one label at a time starting from the
|
||||
* top-level domain and all the labels in domain_suffix_match shall be
|
||||
* included in the certificate. The certificate may include additional
|
||||
* sub-level labels in addition to the required labels.
|
||||
*
|
||||
* For example, domain_suffix_match=example.com would match
|
||||
* test.example.com but would not match test-example.com.
|
||||
*/
|
||||
char *domain_suffix_match;
|
||||
|
||||
/**
|
||||
* domain_match - Constraint for server domain name
|
||||
*
|
||||
* If set, this FQDN is used as a full match requirement for the
|
||||
* server certificate in SubjectAltName dNSName element(s). If a
|
||||
* matching dNSName is found, this constraint is met. If no dNSName
|
||||
* values are present, this constraint is matched against SubjectName CN
|
||||
* using same full match comparison. This behavior is similar to
|
||||
* domain_suffix_match, but has the requirement of a full match, i.e.,
|
||||
* no subdomains or wildcard matches are allowed. Case-insensitive
|
||||
* comparison is used, so "Example.com" matches "example.com", but would
|
||||
* not match "test.Example.com".
|
||||
*/
|
||||
char *domain_match;
|
||||
|
||||
/**
|
||||
* ca_cert2 - File path to CA certificate file (PEM/DER) (Phase 2)
|
||||
*
|
||||
* This file can have one or more trusted CA certificates. If ca_cert2
|
||||
* and ca_path2 are not included, server certificate will not be
|
||||
* verified. This is insecure and a trusted CA certificate should
|
||||
* always be configured. Full path to the file should be used since
|
||||
* working directory may change when wpa_supplicant is run in the
|
||||
* background.
|
||||
*
|
||||
* This field is like ca_cert, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication.
|
||||
*
|
||||
* Alternatively, a named configuration blob can be used by setting
|
||||
* this to blob://blob_name.
|
||||
*/
|
||||
u8 *ca_cert2;
|
||||
|
||||
/**
|
||||
* ca_path2 - Directory path for CA certificate files (PEM) (Phase 2)
|
||||
*
|
||||
* This path may contain multiple CA certificates in OpenSSL format.
|
||||
* Common use for this is to point to system trusted CA list which is
|
||||
* often installed into directory like /etc/ssl/certs. If configured,
|
||||
* these certificates are added to the list of trusted CAs. ca_cert
|
||||
* may also be included in that case, but it is not required.
|
||||
*
|
||||
* This field is like ca_path, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication.
|
||||
*/
|
||||
u8 *ca_path2;
|
||||
|
||||
/**
|
||||
* client_cert2 - File path to client certificate file
|
||||
*
|
||||
* This field is like client_cert, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication. Full path to the
|
||||
* file should be used since working directory may change when
|
||||
* wpa_supplicant is run in the background.
|
||||
*
|
||||
* Alternatively, a named configuration blob can be used by setting
|
||||
* this to blob://blob_name.
|
||||
*/
|
||||
u8 *client_cert2;
|
||||
|
||||
/**
|
||||
* private_key2 - File path to client private key file
|
||||
*
|
||||
* This field is like private_key, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication. Full path to the
|
||||
* file should be used since working directory may change when
|
||||
* wpa_supplicant is run in the background.
|
||||
*
|
||||
* Alternatively, a named configuration blob can be used by setting
|
||||
* this to blob://blob_name.
|
||||
*/
|
||||
u8 *private_key2;
|
||||
|
||||
/**
|
||||
* private_key2_passwd - Password for private key file
|
||||
*
|
||||
* This field is like private_key_passwd, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication.
|
||||
*/
|
||||
char *private_key2_passwd;
|
||||
|
||||
/**
|
||||
* dh_file2 - File path to DH/DSA parameters file (in PEM format)
|
||||
*
|
||||
* This field is like dh_file, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication. Full path to the
|
||||
* file should be used since working directory may change when
|
||||
* wpa_supplicant is run in the background.
|
||||
*
|
||||
* Alternatively, a named configuration blob can be used by setting
|
||||
* this to blob://blob_name.
|
||||
*/
|
||||
u8 *dh_file2;
|
||||
|
||||
/**
|
||||
* subject_match2 - Constraint for server certificate subject
|
||||
*
|
||||
* This field is like subject_match, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication.
|
||||
*/
|
||||
u8 *subject_match2;
|
||||
|
||||
/**
|
||||
* altsubject_match2 - Constraint for server certificate alt. subject
|
||||
*
|
||||
* This field is like altsubject_match, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication.
|
||||
*/
|
||||
u8 *altsubject_match2;
|
||||
|
||||
/**
|
||||
* domain_suffix_match2 - Constraint for server domain name
|
||||
*
|
||||
* This field is like domain_suffix_match, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication.
|
||||
*/
|
||||
char *domain_suffix_match2;
|
||||
|
||||
/**
|
||||
* domain_match2 - Constraint for server domain name
|
||||
*
|
||||
* This field is like domain_match, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication.
|
||||
*/
|
||||
char *domain_match2;
|
||||
|
||||
/**
|
||||
* eap_methods - Allowed EAP methods
|
||||
*
|
||||
* (vendor=EAP_VENDOR_IETF,method=EAP_TYPE_NONE) terminated list of
|
||||
* allowed EAP methods or %NULL if all methods are accepted.
|
||||
*/
|
||||
struct eap_method_type *eap_methods;
|
||||
|
||||
/**
|
||||
* phase1 - Phase 1 (outer authentication) parameters
|
||||
*
|
||||
* String with field-value pairs, e.g., "peapver=0" or
|
||||
* "peapver=1 peaplabel=1".
|
||||
*
|
||||
* 'peapver' can be used to force which PEAP version (0 or 1) is used.
|
||||
*
|
||||
* 'peaplabel=1' can be used to force new label, "client PEAP
|
||||
* encryption", to be used during key derivation when PEAPv1 or newer.
|
||||
*
|
||||
* Most existing PEAPv1 implementation seem to be using the old label,
|
||||
* "client EAP encryption", and wpa_supplicant is now using that as the
|
||||
* default value.
|
||||
*
|
||||
* Some servers, e.g., Radiator, may require peaplabel=1 configuration
|
||||
* to interoperate with PEAPv1; see eap_testing.txt for more details.
|
||||
*
|
||||
* 'peap_outer_success=0' can be used to terminate PEAP authentication
|
||||
* on tunneled EAP-Success. This is required with some RADIUS servers
|
||||
* that implement draft-josefsson-pppext-eap-tls-eap-05.txt (e.g.,
|
||||
* Lucent NavisRadius v4.4.0 with PEAP in "IETF Draft 5" mode).
|
||||
*
|
||||
* include_tls_length=1 can be used to force wpa_supplicant to include
|
||||
* TLS Message Length field in all TLS messages even if they are not
|
||||
* fragmented.
|
||||
*
|
||||
* sim_min_num_chal=3 can be used to configure EAP-SIM to require three
|
||||
* challenges (by default, it accepts 2 or 3).
|
||||
*
|
||||
* result_ind=1 can be used to enable EAP-SIM and EAP-AKA to use
|
||||
* protected result indication.
|
||||
*
|
||||
* fast_provisioning option can be used to enable in-line provisioning
|
||||
* of EAP-FAST credentials (PAC):
|
||||
* 0 = disabled,
|
||||
* 1 = allow unauthenticated provisioning,
|
||||
* 2 = allow authenticated provisioning,
|
||||
* 3 = allow both unauthenticated and authenticated provisioning
|
||||
*
|
||||
* fast_max_pac_list_len=num option can be used to set the maximum
|
||||
* number of PAC entries to store in a PAC list (default: 10).
|
||||
*
|
||||
* fast_pac_format=binary option can be used to select binary format
|
||||
* for storing PAC entries in order to save some space (the default
|
||||
* text format uses about 2.5 times the size of minimal binary format).
|
||||
*
|
||||
* crypto_binding option can be used to control PEAPv0 cryptobinding
|
||||
* behavior:
|
||||
* 0 = do not use cryptobinding (default)
|
||||
* 1 = use cryptobinding if server supports it
|
||||
* 2 = require cryptobinding
|
||||
*
|
||||
* EAP-WSC (WPS) uses following options: pin=Device_Password and
|
||||
* uuid=Device_UUID
|
||||
*
|
||||
* For wired IEEE 802.1X authentication, "allow_canned_success=1" can be
|
||||
* used to configure a mode that allows EAP-Success (and EAP-Failure)
|
||||
* without going through authentication step. Some switches use such
|
||||
* sequence when forcing the port to be authorized/unauthorized or as a
|
||||
* fallback option if the authentication server is unreachable. By
|
||||
* default, wpa_supplicant discards such frames to protect against
|
||||
* potential attacks by rogue devices, but this option can be used to
|
||||
* disable that protection for cases where the server/authenticator does
|
||||
* not need to be authenticated.
|
||||
*/
|
||||
char *phase1;
|
||||
|
||||
/**
|
||||
* phase2 - Phase2 (inner authentication with TLS tunnel) parameters
|
||||
*
|
||||
* String with field-value pairs, e.g., "auth=MSCHAPV2" for EAP-PEAP or
|
||||
* "autheap=MSCHAPV2 autheap=MD5" for EAP-TTLS. "mschapv2_retry=0" can
|
||||
* be used to disable MSCHAPv2 password retry in authentication failure
|
||||
* cases.
|
||||
*/
|
||||
char *phase2;
|
||||
|
||||
/**
|
||||
* pcsc - Parameters for PC/SC smartcard interface for USIM and GSM SIM
|
||||
*
|
||||
* This field is used to configure PC/SC smartcard interface.
|
||||
* Currently, the only configuration is whether this field is %NULL (do
|
||||
* not use PC/SC) or non-NULL (e.g., "") to enable PC/SC.
|
||||
*
|
||||
* This field is used for EAP-SIM and EAP-AKA.
|
||||
*/
|
||||
char *pcsc;
|
||||
|
||||
/**
|
||||
* pin - PIN for USIM, GSM SIM, and smartcards
|
||||
*
|
||||
* This field is used to configure PIN for SIM and smartcards for
|
||||
* EAP-SIM and EAP-AKA. In addition, this is used with EAP-TLS if a
|
||||
* smartcard is used for private key operations.
|
||||
*
|
||||
* If left out, this will be asked through control interface.
|
||||
*/
|
||||
char *pin;
|
||||
|
||||
/**
|
||||
* engine - Enable OpenSSL engine (e.g., for smartcard access)
|
||||
*
|
||||
* This is used if private key operations for EAP-TLS are performed
|
||||
* using a smartcard.
|
||||
*/
|
||||
int engine;
|
||||
|
||||
/**
|
||||
* engine_id - Engine ID for OpenSSL engine
|
||||
*
|
||||
* "opensc" to select OpenSC engine or "pkcs11" to select PKCS#11
|
||||
* engine.
|
||||
*
|
||||
* This is used if private key operations for EAP-TLS are performed
|
||||
* using a smartcard.
|
||||
*/
|
||||
char *engine_id;
|
||||
|
||||
/**
|
||||
* engine2 - Enable OpenSSL engine (e.g., for smartcard) (Phase 2)
|
||||
*
|
||||
* This is used if private key operations for EAP-TLS are performed
|
||||
* using a smartcard.
|
||||
*
|
||||
* This field is like engine, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication.
|
||||
*/
|
||||
int engine2;
|
||||
|
||||
|
||||
/**
|
||||
* pin2 - PIN for USIM, GSM SIM, and smartcards (Phase 2)
|
||||
*
|
||||
* This field is used to configure PIN for SIM and smartcards for
|
||||
* EAP-SIM and EAP-AKA. In addition, this is used with EAP-TLS if a
|
||||
* smartcard is used for private key operations.
|
||||
*
|
||||
* This field is like pin2, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication.
|
||||
*
|
||||
* If left out, this will be asked through control interface.
|
||||
*/
|
||||
char *pin2;
|
||||
|
||||
/**
|
||||
* engine2_id - Engine ID for OpenSSL engine (Phase 2)
|
||||
*
|
||||
* "opensc" to select OpenSC engine or "pkcs11" to select PKCS#11
|
||||
* engine.
|
||||
*
|
||||
* This is used if private key operations for EAP-TLS are performed
|
||||
* using a smartcard.
|
||||
*
|
||||
* This field is like engine_id, but used for phase 2 (inside
|
||||
* EAP-TTLS/PEAP/FAST tunnel) authentication.
|
||||
*/
|
||||
char *engine2_id;
|
||||
|
||||
|
||||
/**
|
||||
* key_id - Key ID for OpenSSL engine
|
||||
*
|
||||
* This is used if private key operations for EAP-TLS are performed
|
||||
* using a smartcard.
|
||||
*/
|
||||
char *key_id;
|
||||
|
||||
/**
|
||||
* cert_id - Cert ID for OpenSSL engine
|
||||
*
|
||||
* This is used if the certificate operations for EAP-TLS are performed
|
||||
* using a smartcard.
|
||||
*/
|
||||
char *cert_id;
|
||||
|
||||
/**
|
||||
* ca_cert_id - CA Cert ID for OpenSSL engine
|
||||
*
|
||||
* This is used if the CA certificate for EAP-TLS is on a smartcard.
|
||||
*/
|
||||
char *ca_cert_id;
|
||||
|
||||
/**
|
||||
* key2_id - Key ID for OpenSSL engine (phase2)
|
||||
*
|
||||
* This is used if private key operations for EAP-TLS are performed
|
||||
* using a smartcard.
|
||||
*/
|
||||
char *key2_id;
|
||||
|
||||
/**
|
||||
* cert2_id - Cert ID for OpenSSL engine (phase2)
|
||||
*
|
||||
* This is used if the certificate operations for EAP-TLS are performed
|
||||
* using a smartcard.
|
||||
*/
|
||||
char *cert2_id;
|
||||
|
||||
/**
|
||||
* ca_cert2_id - CA Cert ID for OpenSSL engine (phase2)
|
||||
*
|
||||
* This is used if the CA certificate for EAP-TLS is on a smartcard.
|
||||
*/
|
||||
char *ca_cert2_id;
|
||||
|
||||
/**
|
||||
* otp - One-time-password
|
||||
*
|
||||
* This field should not be set in configuration step. It is only used
|
||||
* internally when OTP is entered through the control interface.
|
||||
*/
|
||||
u8 *otp;
|
||||
|
||||
/**
|
||||
* otp_len - Length of the otp field
|
||||
*/
|
||||
size_t otp_len;
|
||||
|
||||
/**
|
||||
* pending_req_identity - Whether there is a pending identity request
|
||||
*
|
||||
* This field should not be set in configuration step. It is only used
|
||||
* internally when control interface is used to request needed
|
||||
* information.
|
||||
*/
|
||||
int pending_req_identity;
|
||||
|
||||
/**
|
||||
* pending_req_password - Whether there is a pending password request
|
||||
*
|
||||
* This field should not be set in configuration step. It is only used
|
||||
* internally when control interface is used to request needed
|
||||
* information.
|
||||
*/
|
||||
int pending_req_password;
|
||||
|
||||
/**
|
||||
* pending_req_pin - Whether there is a pending PIN request
|
||||
*
|
||||
* This field should not be set in configuration step. It is only used
|
||||
* internally when control interface is used to request needed
|
||||
* information.
|
||||
*/
|
||||
int pending_req_pin;
|
||||
|
||||
/**
|
||||
* pending_req_new_password - Pending password update request
|
||||
*
|
||||
* This field should not be set in configuration step. It is only used
|
||||
* internally when control interface is used to request needed
|
||||
* information.
|
||||
*/
|
||||
int pending_req_new_password;
|
||||
|
||||
/**
|
||||
* pending_req_passphrase - Pending passphrase request
|
||||
*
|
||||
* This field should not be set in configuration step. It is only used
|
||||
* internally when control interface is used to request needed
|
||||
* information.
|
||||
*/
|
||||
int pending_req_passphrase;
|
||||
|
||||
/**
|
||||
* pending_req_otp - Whether there is a pending OTP request
|
||||
*
|
||||
* This field should not be set in configuration step. It is only used
|
||||
* internally when control interface is used to request needed
|
||||
* information.
|
||||
*/
|
||||
char *pending_req_otp;
|
||||
|
||||
/**
|
||||
* pending_req_otp_len - Length of the pending OTP request
|
||||
*/
|
||||
size_t pending_req_otp_len;
|
||||
|
||||
/**
|
||||
* pac_file - File path or blob name for the PAC entries (EAP-FAST)
|
||||
*
|
||||
* wpa_supplicant will need to be able to create this file and write
|
||||
* updates to it when PAC is being provisioned or refreshed. Full path
|
||||
* to the file should be used since working directory may change when
|
||||
* wpa_supplicant is run in the background.
|
||||
* Alternatively, a named configuration blob can be used by setting
|
||||
* this to blob://blob_name.
|
||||
*/
|
||||
char *pac_file;
|
||||
|
||||
/**
|
||||
* mschapv2_retry - MSCHAPv2 retry in progress
|
||||
*
|
||||
* This field is used internally by EAP-MSCHAPv2 and should not be set
|
||||
* as part of configuration.
|
||||
*/
|
||||
int mschapv2_retry;
|
||||
|
||||
/**
|
||||
* new_password - New password for password update
|
||||
*
|
||||
* This field is used during MSCHAPv2 password update. This is normally
|
||||
* requested from the user through the control interface and not set
|
||||
* from configuration.
|
||||
*/
|
||||
u8 *new_password;
|
||||
|
||||
/**
|
||||
* new_password_len - Length of new_password field
|
||||
*/
|
||||
size_t new_password_len;
|
||||
|
||||
/**
|
||||
* fragment_size - Maximum EAP fragment size in bytes (default 1398)
|
||||
*
|
||||
* This value limits the fragment size for EAP methods that support
|
||||
* fragmentation (e.g., EAP-TLS and EAP-PEAP). This value should be set
|
||||
* small enough to make the EAP messages fit in MTU of the network
|
||||
* interface used for EAPOL. The default value is suitable for most
|
||||
* cases.
|
||||
*/
|
||||
int fragment_size;
|
||||
|
||||
#define EAP_CONFIG_FLAGS_PASSWORD_NTHASH BIT(0)
|
||||
#define EAP_CONFIG_FLAGS_EXT_PASSWORD BIT(1)
|
||||
/**
|
||||
* flags - Network configuration flags (bitfield)
|
||||
*
|
||||
* This variable is used for internal flags to describe further details
|
||||
* for the network parameters.
|
||||
* bit 0 = password is represented as a 16-byte NtPasswordHash value
|
||||
* instead of plaintext password
|
||||
* bit 1 = password is stored in external storage; the value in the
|
||||
* password field is the name of that external entry
|
||||
*/
|
||||
u32 flags;
|
||||
|
||||
/**
|
||||
* ocsp - Whether to use/require OCSP to check server certificate
|
||||
*
|
||||
* 0 = do not use OCSP stapling (TLS certificate status extension)
|
||||
* 1 = try to use OCSP stapling, but not require response
|
||||
* 2 = require valid OCSP stapling response
|
||||
*/
|
||||
int ocsp;
|
||||
|
||||
/**
|
||||
* external_sim_resp - Response from external SIM processing
|
||||
*
|
||||
* This field should not be set in configuration step. It is only used
|
||||
* internally when control interface is used to request external
|
||||
* SIM/USIM processing.
|
||||
*/
|
||||
char *external_sim_resp;
|
||||
|
||||
/**
|
||||
* sim_num - User selected SIM identifier
|
||||
*
|
||||
* This variable is used for identifying which SIM is used if the system
|
||||
* has more than one.
|
||||
*/
|
||||
int sim_num;
|
||||
|
||||
/**
|
||||
* openssl_ciphers - OpenSSL cipher string
|
||||
*
|
||||
* This is an OpenSSL specific configuration option for configuring the
|
||||
* ciphers for this connection. If not set, the default cipher suite
|
||||
* list is used.
|
||||
*/
|
||||
char *openssl_ciphers;
|
||||
|
||||
/**
|
||||
* erp - Whether EAP Re-authentication Protocol (ERP) is enabled
|
||||
*/
|
||||
int erp;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct wpa_config_blob - Named configuration blob
|
||||
*
|
||||
* This data structure is used to provide storage for binary objects to store
|
||||
* abstract information like certificates and private keys inlined with the
|
||||
* configuration data.
|
||||
*/
|
||||
struct wpa_config_blob {
|
||||
/**
|
||||
* name - Blob name
|
||||
*/
|
||||
char *name;
|
||||
|
||||
/**
|
||||
* data - Pointer to binary data
|
||||
*/
|
||||
u8 *data;
|
||||
|
||||
/**
|
||||
* len - Length of binary data
|
||||
*/
|
||||
size_t len;
|
||||
|
||||
/**
|
||||
* next - Pointer to next blob in the configuration
|
||||
*/
|
||||
struct wpa_config_blob *next;
|
||||
};
|
||||
|
||||
#endif /* EAP_CONFIG_H */
|
147
freebsd/contrib/wpa/src/eap_peer/eap_gtc.c
Normal file
147
freebsd/contrib/wpa/src/eap_peer/eap_gtc.c
Normal file
@ -0,0 +1,147 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* EAP peer method: EAP-GTC (RFC 3748)
|
||||
* Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "eap_i.h"
|
||||
|
||||
|
||||
struct eap_gtc_data {
|
||||
int prefix;
|
||||
};
|
||||
|
||||
|
||||
static void * eap_gtc_init(struct eap_sm *sm)
|
||||
{
|
||||
struct eap_gtc_data *data;
|
||||
data = os_zalloc(sizeof(*data));
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
|
||||
if (sm->m && sm->m->vendor == EAP_VENDOR_IETF &&
|
||||
sm->m->method == EAP_TYPE_FAST) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-GTC: EAP-FAST tunnel - use prefix "
|
||||
"with challenge/response");
|
||||
data->prefix = 1;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
static void eap_gtc_deinit(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_gtc_data *data = priv;
|
||||
os_free(data);
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_gtc_process(struct eap_sm *sm, void *priv,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
struct eap_gtc_data *data = priv;
|
||||
struct wpabuf *resp;
|
||||
const u8 *pos, *password, *identity;
|
||||
size_t password_len, identity_len, len, plen;
|
||||
int otp;
|
||||
u8 id;
|
||||
|
||||
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, reqData, &len);
|
||||
if (pos == NULL) {
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
id = eap_get_id(reqData);
|
||||
|
||||
wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Request message", pos, len);
|
||||
if (data->prefix &&
|
||||
(len < 10 || os_memcmp(pos, "CHALLENGE=", 10) != 0)) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-GTC: Challenge did not start with "
|
||||
"expected prefix");
|
||||
|
||||
/* Send an empty response in order to allow tunneled
|
||||
* acknowledgement of the failure. This will also cover the
|
||||
* error case which seems to use EAP-MSCHAPv2 like error
|
||||
* reporting with EAP-GTC inside EAP-FAST tunnel. */
|
||||
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC,
|
||||
0, EAP_CODE_RESPONSE, id);
|
||||
return resp;
|
||||
}
|
||||
|
||||
password = eap_get_config_otp(sm, &password_len);
|
||||
if (password)
|
||||
otp = 1;
|
||||
else {
|
||||
password = eap_get_config_password(sm, &password_len);
|
||||
otp = 0;
|
||||
}
|
||||
|
||||
if (password == NULL) {
|
||||
wpa_printf(MSG_INFO, "EAP-GTC: Password not configured");
|
||||
eap_sm_request_otp(sm, (const char *) pos, len);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->ignore = FALSE;
|
||||
|
||||
ret->methodState = data->prefix ? METHOD_MAY_CONT : METHOD_DONE;
|
||||
ret->decision = DECISION_COND_SUCC;
|
||||
ret->allowNotifications = FALSE;
|
||||
|
||||
plen = password_len;
|
||||
identity = eap_get_config_identity(sm, &identity_len);
|
||||
if (identity == NULL)
|
||||
return NULL;
|
||||
if (data->prefix)
|
||||
plen += 9 + identity_len + 1;
|
||||
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, plen,
|
||||
EAP_CODE_RESPONSE, id);
|
||||
if (resp == NULL)
|
||||
return NULL;
|
||||
if (data->prefix) {
|
||||
wpabuf_put_data(resp, "RESPONSE=", 9);
|
||||
wpabuf_put_data(resp, identity, identity_len);
|
||||
wpabuf_put_u8(resp, '\0');
|
||||
}
|
||||
wpabuf_put_data(resp, password, password_len);
|
||||
wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response",
|
||||
wpabuf_head_u8(resp) + sizeof(struct eap_hdr) +
|
||||
1, plen);
|
||||
|
||||
if (otp) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-GTC: Forgetting used password");
|
||||
eap_clear_config_otp(sm);
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
int eap_peer_gtc_register(void)
|
||||
{
|
||||
struct eap_method *eap;
|
||||
int ret;
|
||||
|
||||
eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
|
||||
EAP_VENDOR_IETF, EAP_TYPE_GTC, "GTC");
|
||||
if (eap == NULL)
|
||||
return -1;
|
||||
|
||||
eap->init = eap_gtc_init;
|
||||
eap->deinit = eap_gtc_deinit;
|
||||
eap->process = eap_gtc_process;
|
||||
|
||||
ret = eap_peer_method_register(eap);
|
||||
if (ret)
|
||||
eap_peer_method_free(eap);
|
||||
return ret;
|
||||
}
|
389
freebsd/contrib/wpa/src/eap_peer/eap_i.h
Normal file
389
freebsd/contrib/wpa/src/eap_peer/eap_i.h
Normal file
@ -0,0 +1,389 @@
|
||||
/*
|
||||
* EAP peer state machines internal structures (RFC 4137)
|
||||
* Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_I_H
|
||||
#define EAP_I_H
|
||||
|
||||
#include "wpabuf.h"
|
||||
#include "utils/list.h"
|
||||
#include "eap_peer/eap.h"
|
||||
#include "eap_common/eap_common.h"
|
||||
|
||||
/* RFC 4137 - EAP Peer state machine */
|
||||
|
||||
typedef enum {
|
||||
DECISION_FAIL, DECISION_COND_SUCC, DECISION_UNCOND_SUCC
|
||||
} EapDecision;
|
||||
|
||||
typedef enum {
|
||||
METHOD_NONE, METHOD_INIT, METHOD_CONT, METHOD_MAY_CONT, METHOD_DONE
|
||||
} EapMethodState;
|
||||
|
||||
/**
|
||||
* struct eap_method_ret - EAP return values from struct eap_method::process()
|
||||
*
|
||||
* These structure contains OUT variables for the interface between peer state
|
||||
* machine and methods (RFC 4137, Sect. 4.2). eapRespData will be returned as
|
||||
* the return value of struct eap_method::process() so it is not included in
|
||||
* this structure.
|
||||
*/
|
||||
struct eap_method_ret {
|
||||
/**
|
||||
* ignore - Whether method decided to drop the current packed (OUT)
|
||||
*/
|
||||
Boolean ignore;
|
||||
|
||||
/**
|
||||
* methodState - Method-specific state (IN/OUT)
|
||||
*/
|
||||
EapMethodState methodState;
|
||||
|
||||
/**
|
||||
* decision - Authentication decision (OUT)
|
||||
*/
|
||||
EapDecision decision;
|
||||
|
||||
/**
|
||||
* allowNotifications - Whether method allows notifications (OUT)
|
||||
*/
|
||||
Boolean allowNotifications;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct eap_method - EAP method interface
|
||||
* This structure defines the EAP method interface. Each method will need to
|
||||
* register its own EAP type, EAP name, and set of function pointers for method
|
||||
* specific operations. This interface is based on section 4.4 of RFC 4137.
|
||||
*/
|
||||
struct eap_method {
|
||||
/**
|
||||
* vendor - EAP Vendor-ID (EAP_VENDOR_*) (0 = IETF)
|
||||
*/
|
||||
int vendor;
|
||||
|
||||
/**
|
||||
* method - EAP type number (EAP_TYPE_*)
|
||||
*/
|
||||
EapType method;
|
||||
|
||||
/**
|
||||
* name - Name of the method (e.g., "TLS")
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* init - Initialize an EAP method
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* Returns: Pointer to allocated private data, or %NULL on failure
|
||||
*
|
||||
* This function is used to initialize the EAP method explicitly
|
||||
* instead of using METHOD_INIT state as specific in RFC 4137. The
|
||||
* method is expected to initialize it method-specific state and return
|
||||
* a pointer that will be used as the priv argument to other calls.
|
||||
*/
|
||||
void * (*init)(struct eap_sm *sm);
|
||||
|
||||
/**
|
||||
* deinit - Deinitialize an EAP method
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @priv: Pointer to private EAP method data from eap_method::init()
|
||||
*
|
||||
* Deinitialize the EAP method and free any allocated private data.
|
||||
*/
|
||||
void (*deinit)(struct eap_sm *sm, void *priv);
|
||||
|
||||
/**
|
||||
* process - Process an EAP request
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @priv: Pointer to private EAP method data from eap_method::init()
|
||||
* @ret: Return values from EAP request validation and processing
|
||||
* @reqData: EAP request to be processed (eapReqData)
|
||||
* Returns: Pointer to allocated EAP response packet (eapRespData)
|
||||
*
|
||||
* This function is a combination of m.check(), m.process(), and
|
||||
* m.buildResp() procedures defined in section 4.4 of RFC 4137 In other
|
||||
* words, this function validates the incoming request, processes it,
|
||||
* and build a response packet. m.check() and m.process() return values
|
||||
* are returned through struct eap_method_ret *ret variable. Caller is
|
||||
* responsible for freeing the returned EAP response packet.
|
||||
*/
|
||||
struct wpabuf * (*process)(struct eap_sm *sm, void *priv,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData);
|
||||
|
||||
/**
|
||||
* isKeyAvailable - Find out whether EAP method has keying material
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @priv: Pointer to private EAP method data from eap_method::init()
|
||||
* Returns: %TRUE if key material (eapKeyData) is available
|
||||
*/
|
||||
Boolean (*isKeyAvailable)(struct eap_sm *sm, void *priv);
|
||||
|
||||
/**
|
||||
* getKey - Get EAP method specific keying material (eapKeyData)
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @priv: Pointer to private EAP method data from eap_method::init()
|
||||
* @len: Pointer to variable to store key length (eapKeyDataLen)
|
||||
* Returns: Keying material (eapKeyData) or %NULL if not available
|
||||
*
|
||||
* This function can be used to get the keying material from the EAP
|
||||
* method. The key may already be stored in the method-specific private
|
||||
* data or this function may derive the key.
|
||||
*/
|
||||
u8 * (*getKey)(struct eap_sm *sm, void *priv, size_t *len);
|
||||
|
||||
/**
|
||||
* get_status - Get EAP method status
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @priv: Pointer to private EAP method data from eap_method::init()
|
||||
* @buf: Buffer for status information
|
||||
* @buflen: Maximum buffer length
|
||||
* @verbose: Whether to include verbose status information
|
||||
* Returns: Number of bytes written to buf
|
||||
*
|
||||
* Query EAP method for status information. This function fills in a
|
||||
* text area with current status information from the EAP method. If
|
||||
* the buffer (buf) is not large enough, status information will be
|
||||
* truncated to fit the buffer.
|
||||
*/
|
||||
int (*get_status)(struct eap_sm *sm, void *priv, char *buf,
|
||||
size_t buflen, int verbose);
|
||||
|
||||
/**
|
||||
* has_reauth_data - Whether method is ready for fast reauthentication
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @priv: Pointer to private EAP method data from eap_method::init()
|
||||
* Returns: %TRUE or %FALSE based on whether fast reauthentication is
|
||||
* possible
|
||||
*
|
||||
* This function is an optional handler that only EAP methods
|
||||
* supporting fast re-authentication need to implement.
|
||||
*/
|
||||
Boolean (*has_reauth_data)(struct eap_sm *sm, void *priv);
|
||||
|
||||
/**
|
||||
* deinit_for_reauth - Release data that is not needed for fast re-auth
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @priv: Pointer to private EAP method data from eap_method::init()
|
||||
*
|
||||
* This function is an optional handler that only EAP methods
|
||||
* supporting fast re-authentication need to implement. This is called
|
||||
* when authentication has been completed and EAP state machine is
|
||||
* requesting that enough state information is maintained for fast
|
||||
* re-authentication
|
||||
*/
|
||||
void (*deinit_for_reauth)(struct eap_sm *sm, void *priv);
|
||||
|
||||
/**
|
||||
* init_for_reauth - Prepare for start of fast re-authentication
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @priv: Pointer to private EAP method data from eap_method::init()
|
||||
*
|
||||
* This function is an optional handler that only EAP methods
|
||||
* supporting fast re-authentication need to implement. This is called
|
||||
* when EAP authentication is started and EAP state machine is
|
||||
* requesting fast re-authentication to be used.
|
||||
*/
|
||||
void * (*init_for_reauth)(struct eap_sm *sm, void *priv);
|
||||
|
||||
/**
|
||||
* get_identity - Get method specific identity for re-authentication
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @priv: Pointer to private EAP method data from eap_method::init()
|
||||
* @len: Length of the returned identity
|
||||
* Returns: Pointer to the method specific identity or %NULL if default
|
||||
* identity is to be used
|
||||
*
|
||||
* This function is an optional handler that only EAP methods
|
||||
* that use method specific identity need to implement.
|
||||
*/
|
||||
const u8 * (*get_identity)(struct eap_sm *sm, void *priv, size_t *len);
|
||||
|
||||
/**
|
||||
* free - Free EAP method data
|
||||
* @method: Pointer to the method data registered with
|
||||
* eap_peer_method_register().
|
||||
*
|
||||
* This function will be called when the EAP method is being
|
||||
* unregistered. If the EAP method allocated resources during
|
||||
* registration (e.g., allocated struct eap_method), they should be
|
||||
* freed in this function. No other method functions will be called
|
||||
* after this call. If this function is not defined (i.e., function
|
||||
* pointer is %NULL), a default handler is used to release the method
|
||||
* data with free(method). This is suitable for most cases.
|
||||
*/
|
||||
void (*free)(struct eap_method *method);
|
||||
|
||||
#define EAP_PEER_METHOD_INTERFACE_VERSION 1
|
||||
/**
|
||||
* version - Version of the EAP peer method interface
|
||||
*
|
||||
* The EAP peer method implementation should set this variable to
|
||||
* EAP_PEER_METHOD_INTERFACE_VERSION. This is used to verify that the
|
||||
* EAP method is using supported API version when using dynamically
|
||||
* loadable EAP methods.
|
||||
*/
|
||||
int version;
|
||||
|
||||
/**
|
||||
* next - Pointer to the next EAP method
|
||||
*
|
||||
* This variable is used internally in the EAP method registration code
|
||||
* to create a linked list of registered EAP methods.
|
||||
*/
|
||||
struct eap_method *next;
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_EAP_METHODS
|
||||
/**
|
||||
* dl_handle - Handle for the dynamic library
|
||||
*
|
||||
* This variable is used internally in the EAP method registration code
|
||||
* to store a handle for the dynamic library. If the method is linked
|
||||
* in statically, this is %NULL.
|
||||
*/
|
||||
void *dl_handle;
|
||||
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
|
||||
|
||||
/**
|
||||
* get_emsk - Get EAP method specific keying extended material (EMSK)
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @priv: Pointer to private EAP method data from eap_method::init()
|
||||
* @len: Pointer to a variable to store EMSK length
|
||||
* Returns: EMSK or %NULL if not available
|
||||
*
|
||||
* This function can be used to get the extended keying material from
|
||||
* the EAP method. The key may already be stored in the method-specific
|
||||
* private data or this function may derive the key.
|
||||
*/
|
||||
u8 * (*get_emsk)(struct eap_sm *sm, void *priv, size_t *len);
|
||||
|
||||
/**
|
||||
* getSessionId - Get EAP method specific Session-Id
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @priv: Pointer to private EAP method data from eap_method::init()
|
||||
* @len: Pointer to a variable to store Session-Id length
|
||||
* Returns: Session-Id or %NULL if not available
|
||||
*
|
||||
* This function can be used to get the Session-Id from the EAP method.
|
||||
* The Session-Id may already be stored in the method-specific private
|
||||
* data or this function may derive the Session-Id.
|
||||
*/
|
||||
u8 * (*getSessionId)(struct eap_sm *sm, void *priv, size_t *len);
|
||||
};
|
||||
|
||||
|
||||
struct eap_erp_key {
|
||||
struct dl_list list;
|
||||
size_t rRK_len;
|
||||
size_t rIK_len;
|
||||
u8 rRK[ERP_MAX_KEY_LEN];
|
||||
u8 rIK[ERP_MAX_KEY_LEN];
|
||||
u32 next_seq;
|
||||
char keyname_nai[];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct eap_sm - EAP state machine data
|
||||
*/
|
||||
struct eap_sm {
|
||||
enum {
|
||||
EAP_INITIALIZE, EAP_DISABLED, EAP_IDLE, EAP_RECEIVED,
|
||||
EAP_GET_METHOD, EAP_METHOD, EAP_SEND_RESPONSE, EAP_DISCARD,
|
||||
EAP_IDENTITY, EAP_NOTIFICATION, EAP_RETRANSMIT, EAP_SUCCESS,
|
||||
EAP_FAILURE
|
||||
} EAP_state;
|
||||
/* Long-term local variables */
|
||||
EapType selectedMethod;
|
||||
EapMethodState methodState;
|
||||
int lastId;
|
||||
struct wpabuf *lastRespData;
|
||||
EapDecision decision;
|
||||
/* Short-term local variables */
|
||||
Boolean rxReq;
|
||||
Boolean rxSuccess;
|
||||
Boolean rxFailure;
|
||||
int reqId;
|
||||
EapType reqMethod;
|
||||
int reqVendor;
|
||||
u32 reqVendorMethod;
|
||||
Boolean ignore;
|
||||
/* Constants */
|
||||
int ClientTimeout;
|
||||
|
||||
/* Miscellaneous variables */
|
||||
Boolean allowNotifications; /* peer state machine <-> methods */
|
||||
struct wpabuf *eapRespData; /* peer to lower layer */
|
||||
Boolean eapKeyAvailable; /* peer to lower layer */
|
||||
u8 *eapKeyData; /* peer to lower layer */
|
||||
size_t eapKeyDataLen; /* peer to lower layer */
|
||||
u8 *eapSessionId; /* peer to lower layer */
|
||||
size_t eapSessionIdLen; /* peer to lower layer */
|
||||
const struct eap_method *m; /* selected EAP method */
|
||||
/* not defined in RFC 4137 */
|
||||
Boolean changed;
|
||||
void *eapol_ctx;
|
||||
const struct eapol_callbacks *eapol_cb;
|
||||
void *eap_method_priv;
|
||||
int init_phase2;
|
||||
int fast_reauth;
|
||||
Boolean reauthInit; /* send EAP-Identity/Re-auth */
|
||||
u32 erp_seq;
|
||||
|
||||
Boolean rxResp /* LEAP only */;
|
||||
Boolean leap_done;
|
||||
Boolean peap_done;
|
||||
u8 req_sha1[20]; /* SHA1() of the current EAP packet */
|
||||
u8 last_sha1[20]; /* SHA1() of the previously received EAP packet; used
|
||||
* in duplicate request detection. */
|
||||
|
||||
void *msg_ctx;
|
||||
void *scard_ctx;
|
||||
void *ssl_ctx;
|
||||
void *ssl_ctx2;
|
||||
|
||||
unsigned int workaround;
|
||||
|
||||
/* Optional challenges generated in Phase 1 (EAP-FAST) */
|
||||
u8 *peer_challenge, *auth_challenge;
|
||||
|
||||
int num_rounds;
|
||||
int force_disabled;
|
||||
|
||||
struct wps_context *wps;
|
||||
|
||||
int prev_failure;
|
||||
struct eap_peer_config *last_config;
|
||||
|
||||
struct ext_password_data *ext_pw;
|
||||
struct wpabuf *ext_pw_buf;
|
||||
|
||||
int external_sim;
|
||||
|
||||
unsigned int expected_failure:1;
|
||||
|
||||
struct dl_list erp_keys; /* struct eap_erp_key */
|
||||
};
|
||||
|
||||
const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len);
|
||||
const u8 * eap_get_config_password(struct eap_sm *sm, size_t *len);
|
||||
const u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash);
|
||||
const u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len);
|
||||
const u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len);
|
||||
void eap_clear_config_otp(struct eap_sm *sm);
|
||||
const char * eap_get_config_phase1(struct eap_sm *sm);
|
||||
const char * eap_get_config_phase2(struct eap_sm *sm);
|
||||
int eap_get_config_fragment_size(struct eap_sm *sm);
|
||||
struct eap_peer_config * eap_get_config(struct eap_sm *sm);
|
||||
void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob);
|
||||
const struct wpa_config_blob *
|
||||
eap_get_config_blob(struct eap_sm *sm, const char *name);
|
||||
void eap_notify_pending(struct eap_sm *sm);
|
||||
int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method);
|
||||
|
||||
#endif /* EAP_I_H */
|
415
freebsd/contrib/wpa/src/eap_peer/eap_leap.c
Normal file
415
freebsd/contrib/wpa/src/eap_peer/eap_leap.c
Normal file
@ -0,0 +1,415 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* EAP peer method: LEAP
|
||||
* Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "crypto/ms_funcs.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/random.h"
|
||||
#include "eap_i.h"
|
||||
|
||||
#define LEAP_VERSION 1
|
||||
#define LEAP_CHALLENGE_LEN 8
|
||||
#define LEAP_RESPONSE_LEN 24
|
||||
#define LEAP_KEY_LEN 16
|
||||
|
||||
|
||||
struct eap_leap_data {
|
||||
enum {
|
||||
LEAP_WAIT_CHALLENGE,
|
||||
LEAP_WAIT_SUCCESS,
|
||||
LEAP_WAIT_RESPONSE,
|
||||
LEAP_DONE
|
||||
} state;
|
||||
|
||||
u8 peer_challenge[LEAP_CHALLENGE_LEN];
|
||||
u8 peer_response[LEAP_RESPONSE_LEN];
|
||||
|
||||
u8 ap_challenge[LEAP_CHALLENGE_LEN];
|
||||
u8 ap_response[LEAP_RESPONSE_LEN];
|
||||
};
|
||||
|
||||
|
||||
static void * eap_leap_init(struct eap_sm *sm)
|
||||
{
|
||||
struct eap_leap_data *data;
|
||||
|
||||
data = os_zalloc(sizeof(*data));
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
data->state = LEAP_WAIT_CHALLENGE;
|
||||
|
||||
sm->leap_done = FALSE;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
static void eap_leap_deinit(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
os_free(priv);
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_leap_process_request(struct eap_sm *sm, void *priv,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
struct eap_leap_data *data = priv;
|
||||
struct wpabuf *resp;
|
||||
const u8 *pos, *challenge, *identity, *password;
|
||||
u8 challenge_len, *rpos;
|
||||
size_t identity_len, password_len, len;
|
||||
int pwhash;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-LEAP: Processing EAP-Request");
|
||||
|
||||
identity = eap_get_config_identity(sm, &identity_len);
|
||||
password = eap_get_config_password2(sm, &password_len, &pwhash);
|
||||
if (identity == NULL || password == NULL)
|
||||
return NULL;
|
||||
|
||||
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_LEAP, reqData, &len);
|
||||
if (pos == NULL || len < 3) {
|
||||
wpa_printf(MSG_INFO, "EAP-LEAP: Invalid EAP-Request frame");
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*pos != LEAP_VERSION) {
|
||||
wpa_printf(MSG_WARNING, "EAP-LEAP: Unsupported LEAP version "
|
||||
"%d", *pos);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
pos++;
|
||||
|
||||
pos++; /* skip unused byte */
|
||||
|
||||
challenge_len = *pos++;
|
||||
if (challenge_len != LEAP_CHALLENGE_LEN || challenge_len > len - 3) {
|
||||
wpa_printf(MSG_INFO, "EAP-LEAP: Invalid challenge "
|
||||
"(challenge_len=%d reqDataLen=%lu)",
|
||||
challenge_len, (unsigned long) wpabuf_len(reqData));
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
challenge = pos;
|
||||
os_memcpy(data->peer_challenge, challenge, LEAP_CHALLENGE_LEN);
|
||||
wpa_hexdump(MSG_MSGDUMP, "EAP-LEAP: Challenge from AP",
|
||||
challenge, LEAP_CHALLENGE_LEN);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-LEAP: Generating Challenge Response");
|
||||
|
||||
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_LEAP,
|
||||
3 + LEAP_RESPONSE_LEN + identity_len,
|
||||
EAP_CODE_RESPONSE, eap_get_id(reqData));
|
||||
if (resp == NULL)
|
||||
return NULL;
|
||||
wpabuf_put_u8(resp, LEAP_VERSION);
|
||||
wpabuf_put_u8(resp, 0); /* unused */
|
||||
wpabuf_put_u8(resp, LEAP_RESPONSE_LEN);
|
||||
rpos = wpabuf_put(resp, LEAP_RESPONSE_LEN);
|
||||
if (pwhash)
|
||||
challenge_response(challenge, password, rpos);
|
||||
else
|
||||
nt_challenge_response(challenge, password, password_len, rpos);
|
||||
os_memcpy(data->peer_response, rpos, LEAP_RESPONSE_LEN);
|
||||
wpa_hexdump(MSG_MSGDUMP, "EAP-LEAP: Response",
|
||||
rpos, LEAP_RESPONSE_LEN);
|
||||
wpabuf_put_data(resp, identity, identity_len);
|
||||
|
||||
data->state = LEAP_WAIT_SUCCESS;
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_leap_process_success(struct eap_sm *sm, void *priv,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
struct eap_leap_data *data = priv;
|
||||
struct wpabuf *resp;
|
||||
u8 *pos;
|
||||
const u8 *identity;
|
||||
size_t identity_len;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-LEAP: Processing EAP-Success");
|
||||
|
||||
identity = eap_get_config_identity(sm, &identity_len);
|
||||
if (identity == NULL)
|
||||
return NULL;
|
||||
|
||||
if (data->state != LEAP_WAIT_SUCCESS) {
|
||||
wpa_printf(MSG_INFO, "EAP-LEAP: EAP-Success received in "
|
||||
"unexpected state (%d) - ignored", data->state);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_LEAP,
|
||||
3 + LEAP_CHALLENGE_LEN + identity_len,
|
||||
EAP_CODE_REQUEST, eap_get_id(reqData));
|
||||
if (resp == NULL)
|
||||
return NULL;
|
||||
wpabuf_put_u8(resp, LEAP_VERSION);
|
||||
wpabuf_put_u8(resp, 0); /* unused */
|
||||
wpabuf_put_u8(resp, LEAP_CHALLENGE_LEN);
|
||||
pos = wpabuf_put(resp, LEAP_CHALLENGE_LEN);
|
||||
if (random_get_bytes(pos, LEAP_CHALLENGE_LEN)) {
|
||||
wpa_printf(MSG_WARNING, "EAP-LEAP: Failed to read random data "
|
||||
"for challenge");
|
||||
wpabuf_free(resp);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
os_memcpy(data->ap_challenge, pos, LEAP_CHALLENGE_LEN);
|
||||
wpa_hexdump(MSG_MSGDUMP, "EAP-LEAP: Challenge to AP/AS", pos,
|
||||
LEAP_CHALLENGE_LEN);
|
||||
wpabuf_put_data(resp, identity, identity_len);
|
||||
|
||||
data->state = LEAP_WAIT_RESPONSE;
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_leap_process_response(struct eap_sm *sm, void *priv,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
struct eap_leap_data *data = priv;
|
||||
const u8 *pos, *password;
|
||||
u8 response_len, pw_hash[16], pw_hash_hash[16],
|
||||
expected[LEAP_RESPONSE_LEN];
|
||||
size_t password_len, len;
|
||||
int pwhash;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-LEAP: Processing EAP-Response");
|
||||
|
||||
password = eap_get_config_password2(sm, &password_len, &pwhash);
|
||||
if (password == NULL)
|
||||
return NULL;
|
||||
|
||||
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_LEAP, reqData, &len);
|
||||
if (pos == NULL || len < 3) {
|
||||
wpa_printf(MSG_INFO, "EAP-LEAP: Invalid EAP-Response frame");
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*pos != LEAP_VERSION) {
|
||||
wpa_printf(MSG_WARNING, "EAP-LEAP: Unsupported LEAP version "
|
||||
"%d", *pos);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
pos++;
|
||||
|
||||
pos++; /* skip unused byte */
|
||||
|
||||
response_len = *pos++;
|
||||
if (response_len != LEAP_RESPONSE_LEN || response_len > len - 3) {
|
||||
wpa_printf(MSG_INFO, "EAP-LEAP: Invalid response "
|
||||
"(response_len=%d reqDataLen=%lu)",
|
||||
response_len, (unsigned long) wpabuf_len(reqData));
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-LEAP: Response from AP",
|
||||
pos, LEAP_RESPONSE_LEN);
|
||||
os_memcpy(data->ap_response, pos, LEAP_RESPONSE_LEN);
|
||||
|
||||
if (pwhash) {
|
||||
if (hash_nt_password_hash(password, pw_hash_hash)) {
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (nt_password_hash(password, password_len, pw_hash) ||
|
||||
hash_nt_password_hash(pw_hash, pw_hash_hash)) {
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
challenge_response(data->ap_challenge, pw_hash_hash, expected);
|
||||
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->allowNotifications = FALSE;
|
||||
|
||||
if (os_memcmp_const(pos, expected, LEAP_RESPONSE_LEN) != 0) {
|
||||
wpa_printf(MSG_WARNING, "EAP-LEAP: AP sent an invalid "
|
||||
"response - authentication failed");
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-LEAP: Expected response from AP",
|
||||
expected, LEAP_RESPONSE_LEN);
|
||||
ret->decision = DECISION_FAIL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->decision = DECISION_UNCOND_SUCC;
|
||||
|
||||
/* LEAP is somewhat odd method since it sends EAP-Success in the middle
|
||||
* of the authentication. Use special variable to transit EAP state
|
||||
* machine to SUCCESS state. */
|
||||
sm->leap_done = TRUE;
|
||||
data->state = LEAP_DONE;
|
||||
|
||||
/* No more authentication messages expected; AP will send EAPOL-Key
|
||||
* frames if encryption is enabled. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_leap_process(struct eap_sm *sm, void *priv,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
const struct eap_hdr *eap;
|
||||
size_t password_len;
|
||||
const u8 *password;
|
||||
|
||||
password = eap_get_config_password(sm, &password_len);
|
||||
if (password == NULL) {
|
||||
wpa_printf(MSG_INFO, "EAP-LEAP: Password not configured");
|
||||
eap_sm_request_password(sm);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* LEAP needs to be able to handle EAP-Success frame which does not
|
||||
* include Type field. Consequently, eap_hdr_validate() cannot be used
|
||||
* here. This validation will be done separately for EAP-Request and
|
||||
* EAP-Response frames.
|
||||
*/
|
||||
eap = wpabuf_head(reqData);
|
||||
if (wpabuf_len(reqData) < sizeof(*eap) ||
|
||||
be_to_host16(eap->length) > wpabuf_len(reqData)) {
|
||||
wpa_printf(MSG_INFO, "EAP-LEAP: Invalid frame");
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->ignore = FALSE;
|
||||
ret->allowNotifications = TRUE;
|
||||
ret->methodState = METHOD_MAY_CONT;
|
||||
ret->decision = DECISION_FAIL;
|
||||
|
||||
sm->leap_done = FALSE;
|
||||
|
||||
switch (eap->code) {
|
||||
case EAP_CODE_REQUEST:
|
||||
return eap_leap_process_request(sm, priv, ret, reqData);
|
||||
case EAP_CODE_SUCCESS:
|
||||
return eap_leap_process_success(sm, priv, ret, reqData);
|
||||
case EAP_CODE_RESPONSE:
|
||||
return eap_leap_process_response(sm, priv, ret, reqData);
|
||||
default:
|
||||
wpa_printf(MSG_INFO, "EAP-LEAP: Unexpected EAP code (%d) - "
|
||||
"ignored", eap->code);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Boolean eap_leap_isKeyAvailable(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_leap_data *data = priv;
|
||||
return data->state == LEAP_DONE;
|
||||
}
|
||||
|
||||
|
||||
static u8 * eap_leap_getKey(struct eap_sm *sm, void *priv, size_t *len)
|
||||
{
|
||||
struct eap_leap_data *data = priv;
|
||||
u8 *key, pw_hash_hash[16], pw_hash[16];
|
||||
const u8 *addr[5], *password;
|
||||
size_t elen[5], password_len;
|
||||
int pwhash;
|
||||
|
||||
if (data->state != LEAP_DONE)
|
||||
return NULL;
|
||||
|
||||
password = eap_get_config_password2(sm, &password_len, &pwhash);
|
||||
if (password == NULL)
|
||||
return NULL;
|
||||
|
||||
key = os_malloc(LEAP_KEY_LEN);
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
if (pwhash) {
|
||||
if (hash_nt_password_hash(password, pw_hash_hash)) {
|
||||
os_free(key);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (nt_password_hash(password, password_len, pw_hash) ||
|
||||
hash_nt_password_hash(pw_hash, pw_hash_hash)) {
|
||||
os_free(key);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
wpa_hexdump_key(MSG_DEBUG, "EAP-LEAP: pw_hash_hash",
|
||||
pw_hash_hash, 16);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-LEAP: peer_challenge",
|
||||
data->peer_challenge, LEAP_CHALLENGE_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-LEAP: peer_response",
|
||||
data->peer_response, LEAP_RESPONSE_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-LEAP: ap_challenge",
|
||||
data->ap_challenge, LEAP_CHALLENGE_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-LEAP: ap_response",
|
||||
data->ap_response, LEAP_RESPONSE_LEN);
|
||||
|
||||
addr[0] = pw_hash_hash;
|
||||
elen[0] = 16;
|
||||
addr[1] = data->ap_challenge;
|
||||
elen[1] = LEAP_CHALLENGE_LEN;
|
||||
addr[2] = data->ap_response;
|
||||
elen[2] = LEAP_RESPONSE_LEN;
|
||||
addr[3] = data->peer_challenge;
|
||||
elen[3] = LEAP_CHALLENGE_LEN;
|
||||
addr[4] = data->peer_response;
|
||||
elen[4] = LEAP_RESPONSE_LEN;
|
||||
md5_vector(5, addr, elen, key);
|
||||
wpa_hexdump_key(MSG_DEBUG, "EAP-LEAP: master key", key, LEAP_KEY_LEN);
|
||||
*len = LEAP_KEY_LEN;
|
||||
|
||||
os_memset(pw_hash, 0, sizeof(pw_hash));
|
||||
os_memset(pw_hash_hash, 0, sizeof(pw_hash_hash));
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
int eap_peer_leap_register(void)
|
||||
{
|
||||
struct eap_method *eap;
|
||||
int ret;
|
||||
|
||||
eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
|
||||
EAP_VENDOR_IETF, EAP_TYPE_LEAP, "LEAP");
|
||||
if (eap == NULL)
|
||||
return -1;
|
||||
|
||||
eap->init = eap_leap_init;
|
||||
eap->deinit = eap_leap_deinit;
|
||||
eap->process = eap_leap_process;
|
||||
eap->isKeyAvailable = eap_leap_isKeyAvailable;
|
||||
eap->getKey = eap_leap_getKey;
|
||||
|
||||
ret = eap_peer_method_register(eap);
|
||||
if (ret)
|
||||
eap_peer_method_free(eap);
|
||||
return ret;
|
||||
}
|
122
freebsd/contrib/wpa/src/eap_peer/eap_md5.c
Normal file
122
freebsd/contrib/wpa/src/eap_peer/eap_md5.c
Normal file
@ -0,0 +1,122 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* EAP peer method: EAP-MD5 (RFC 3748 and RFC 1994)
|
||||
* Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "eap_i.h"
|
||||
#include "eap_common/chap.h"
|
||||
|
||||
|
||||
static void * eap_md5_init(struct eap_sm *sm)
|
||||
{
|
||||
/* No need for private data. However, must return non-NULL to indicate
|
||||
* success. */
|
||||
return (void *) 1;
|
||||
}
|
||||
|
||||
|
||||
static void eap_md5_deinit(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_md5_process(struct eap_sm *sm, void *priv,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
struct wpabuf *resp;
|
||||
const u8 *pos, *challenge, *password;
|
||||
u8 *rpos, id;
|
||||
size_t len, challenge_len, password_len;
|
||||
|
||||
password = eap_get_config_password(sm, &password_len);
|
||||
if (password == NULL) {
|
||||
wpa_printf(MSG_INFO, "EAP-MD5: Password not configured");
|
||||
eap_sm_request_password(sm);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5, reqData, &len);
|
||||
if (pos == NULL || len == 0) {
|
||||
wpa_printf(MSG_INFO, "EAP-MD5: Invalid frame (pos=%p len=%lu)",
|
||||
pos, (unsigned long) len);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* CHAP Challenge:
|
||||
* Value-Size (1 octet) | Value(Challenge) | Name(optional)
|
||||
*/
|
||||
challenge_len = *pos++;
|
||||
if (challenge_len == 0 || challenge_len > len - 1) {
|
||||
wpa_printf(MSG_INFO, "EAP-MD5: Invalid challenge "
|
||||
"(challenge_len=%lu len=%lu)",
|
||||
(unsigned long) challenge_len, (unsigned long) len);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
ret->ignore = FALSE;
|
||||
challenge = pos;
|
||||
wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge",
|
||||
challenge, challenge_len);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-MD5: Generating Challenge Response");
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_COND_SUCC;
|
||||
ret->allowNotifications = TRUE;
|
||||
|
||||
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, 1 + CHAP_MD5_LEN,
|
||||
EAP_CODE_RESPONSE, eap_get_id(reqData));
|
||||
if (resp == NULL)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* CHAP Response:
|
||||
* Value-Size (1 octet) | Value(Response) | Name(optional)
|
||||
*/
|
||||
wpabuf_put_u8(resp, CHAP_MD5_LEN);
|
||||
|
||||
id = eap_get_id(resp);
|
||||
rpos = wpabuf_put(resp, CHAP_MD5_LEN);
|
||||
if (chap_md5(id, password, password_len, challenge, challenge_len,
|
||||
rpos)) {
|
||||
wpa_printf(MSG_INFO, "EAP-MD5: CHAP MD5 operation failed");
|
||||
ret->ignore = TRUE;
|
||||
wpabuf_free(resp);
|
||||
return NULL;
|
||||
}
|
||||
wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", rpos, CHAP_MD5_LEN);
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
int eap_peer_md5_register(void)
|
||||
{
|
||||
struct eap_method *eap;
|
||||
int ret;
|
||||
|
||||
eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
|
||||
EAP_VENDOR_IETF, EAP_TYPE_MD5, "MD5");
|
||||
if (eap == NULL)
|
||||
return -1;
|
||||
|
||||
eap->init = eap_md5_init;
|
||||
eap->deinit = eap_md5_deinit;
|
||||
eap->process = eap_md5_process;
|
||||
|
||||
ret = eap_peer_method_register(eap);
|
||||
if (ret)
|
||||
eap_peer_method_free(eap);
|
||||
return ret;
|
||||
}
|
371
freebsd/contrib/wpa/src/eap_peer/eap_methods.c
Normal file
371
freebsd/contrib/wpa/src/eap_peer/eap_methods.c
Normal file
@ -0,0 +1,371 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* EAP peer: Method registration
|
||||
* Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#ifdef CONFIG_DYNAMIC_EAP_METHODS
|
||||
#include <dlfcn.h>
|
||||
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
|
||||
|
||||
#include "common.h"
|
||||
#include "eap_i.h"
|
||||
#include "eap_methods.h"
|
||||
|
||||
|
||||
static struct eap_method *eap_methods = NULL;
|
||||
|
||||
|
||||
/**
|
||||
* eap_peer_get_eap_method - Get EAP method based on type number
|
||||
* @vendor: EAP Vendor-Id (0 = IETF)
|
||||
* @method: EAP type number
|
||||
* Returns: Pointer to EAP method or %NULL if not found
|
||||
*/
|
||||
const struct eap_method * eap_peer_get_eap_method(int vendor, EapType method)
|
||||
{
|
||||
struct eap_method *m;
|
||||
for (m = eap_methods; m; m = m->next) {
|
||||
if (m->vendor == vendor && m->method == method)
|
||||
return m;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_peer_get_type - Get EAP type for the given EAP method name
|
||||
* @name: EAP method name, e.g., TLS
|
||||
* @vendor: Buffer for returning EAP Vendor-Id
|
||||
* Returns: EAP method type or %EAP_TYPE_NONE if not found
|
||||
*
|
||||
* This function maps EAP type names into EAP type numbers based on the list of
|
||||
* EAP methods included in the build.
|
||||
*/
|
||||
EapType eap_peer_get_type(const char *name, int *vendor)
|
||||
{
|
||||
struct eap_method *m;
|
||||
for (m = eap_methods; m; m = m->next) {
|
||||
if (os_strcmp(m->name, name) == 0) {
|
||||
*vendor = m->vendor;
|
||||
return m->method;
|
||||
}
|
||||
}
|
||||
*vendor = EAP_VENDOR_IETF;
|
||||
return EAP_TYPE_NONE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_get_name - Get EAP method name for the given EAP type
|
||||
* @vendor: EAP Vendor-Id (0 = IETF)
|
||||
* @type: EAP method type
|
||||
* Returns: EAP method name, e.g., TLS, or %NULL if not found
|
||||
*
|
||||
* This function maps EAP type numbers into EAP type names based on the list of
|
||||
* EAP methods included in the build.
|
||||
*/
|
||||
const char * eap_get_name(int vendor, EapType type)
|
||||
{
|
||||
struct eap_method *m;
|
||||
if (vendor == EAP_VENDOR_IETF && type == EAP_TYPE_EXPANDED)
|
||||
return "expanded";
|
||||
for (m = eap_methods; m; m = m->next) {
|
||||
if (m->vendor == vendor && m->method == type)
|
||||
return m->name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_get_names - Get space separated list of names for supported EAP methods
|
||||
* @buf: Buffer for names
|
||||
* @buflen: Buffer length
|
||||
* Returns: Number of characters written into buf (not including nul
|
||||
* termination)
|
||||
*/
|
||||
size_t eap_get_names(char *buf, size_t buflen)
|
||||
{
|
||||
char *pos, *end;
|
||||
struct eap_method *m;
|
||||
int ret;
|
||||
|
||||
if (buflen == 0)
|
||||
return 0;
|
||||
|
||||
pos = buf;
|
||||
end = pos + buflen;
|
||||
|
||||
for (m = eap_methods; m; m = m->next) {
|
||||
ret = os_snprintf(pos, end - pos, "%s%s",
|
||||
m == eap_methods ? "" : " ", m->name);
|
||||
if (os_snprintf_error(end - pos, ret))
|
||||
break;
|
||||
pos += ret;
|
||||
}
|
||||
buf[buflen - 1] = '\0';
|
||||
|
||||
return pos - buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_get_names_as_string_array - Get supported EAP methods as string array
|
||||
* @num: Buffer for returning the number of items in array, not including %NULL
|
||||
* terminator. This parameter can be %NULL if the length is not needed.
|
||||
* Returns: A %NULL-terminated array of strings, or %NULL on error.
|
||||
*
|
||||
* This function returns the list of names for all supported EAP methods as an
|
||||
* array of strings. The caller must free the returned array items and the
|
||||
* array.
|
||||
*/
|
||||
char ** eap_get_names_as_string_array(size_t *num)
|
||||
{
|
||||
struct eap_method *m;
|
||||
size_t array_len = 0;
|
||||
char **array;
|
||||
int i = 0, j;
|
||||
|
||||
for (m = eap_methods; m; m = m->next)
|
||||
array_len++;
|
||||
|
||||
array = os_calloc(array_len + 1, sizeof(char *));
|
||||
if (array == NULL)
|
||||
return NULL;
|
||||
|
||||
for (m = eap_methods; m; m = m->next) {
|
||||
array[i++] = os_strdup(m->name);
|
||||
if (array[i - 1] == NULL) {
|
||||
for (j = 0; j < i; j++)
|
||||
os_free(array[j]);
|
||||
os_free(array);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
array[i] = NULL;
|
||||
|
||||
if (num)
|
||||
*num = array_len;
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_peer_get_methods - Get a list of enabled EAP peer methods
|
||||
* @count: Set to number of available methods
|
||||
* Returns: List of enabled EAP peer methods
|
||||
*/
|
||||
const struct eap_method * eap_peer_get_methods(size_t *count)
|
||||
{
|
||||
int c = 0;
|
||||
struct eap_method *m;
|
||||
|
||||
for (m = eap_methods; m; m = m->next)
|
||||
c++;
|
||||
|
||||
*count = c;
|
||||
return eap_methods;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_EAP_METHODS
|
||||
/**
|
||||
* eap_peer_method_load - Load a dynamic EAP method library (shared object)
|
||||
* @so: File path for the shared object file to load
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int eap_peer_method_load(const char *so)
|
||||
{
|
||||
void *handle;
|
||||
int (*dyn_init)(void);
|
||||
int ret;
|
||||
|
||||
handle = dlopen(so, RTLD_LAZY);
|
||||
if (handle == NULL) {
|
||||
wpa_printf(MSG_ERROR, "EAP: Failed to open dynamic EAP method "
|
||||
"'%s': %s", so, dlerror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
dyn_init = dlsym(handle, "eap_peer_method_dynamic_init");
|
||||
if (dyn_init == NULL) {
|
||||
dlclose(handle);
|
||||
wpa_printf(MSG_ERROR, "EAP: Invalid EAP method '%s' - no "
|
||||
"eap_peer_method_dynamic_init()", so);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dyn_init();
|
||||
if (ret) {
|
||||
dlclose(handle);
|
||||
wpa_printf(MSG_ERROR, "EAP: Failed to add EAP method '%s' - "
|
||||
"ret %d", so, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Store the handle for this shared object. It will be freed with
|
||||
* dlclose() when the EAP method is unregistered. */
|
||||
eap_methods->dl_handle = handle;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP: Loaded dynamic EAP method: '%s'", so);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_peer_method_unload - Unload a dynamic EAP method library (shared object)
|
||||
* @method: Pointer to the dynamically loaded EAP method
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function can be used to unload EAP methods that have been previously
|
||||
* loaded with eap_peer_method_load(). Before unloading the method, all
|
||||
* references to the method must be removed to make sure that no dereferences
|
||||
* of freed memory will occur after unloading.
|
||||
*/
|
||||
int eap_peer_method_unload(struct eap_method *method)
|
||||
{
|
||||
struct eap_method *m, *prev;
|
||||
void *handle;
|
||||
|
||||
m = eap_methods;
|
||||
prev = NULL;
|
||||
while (m) {
|
||||
if (m == method)
|
||||
break;
|
||||
prev = m;
|
||||
m = m->next;
|
||||
}
|
||||
|
||||
if (m == NULL || m->dl_handle == NULL)
|
||||
return -1;
|
||||
|
||||
if (prev)
|
||||
prev->next = m->next;
|
||||
else
|
||||
eap_methods = m->next;
|
||||
|
||||
handle = m->dl_handle;
|
||||
|
||||
if (m->free)
|
||||
m->free(m);
|
||||
else
|
||||
eap_peer_method_free(m);
|
||||
|
||||
dlclose(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
|
||||
|
||||
|
||||
/**
|
||||
* eap_peer_method_alloc - Allocate EAP peer method structure
|
||||
* @version: Version of the EAP peer method interface (set to
|
||||
* EAP_PEER_METHOD_INTERFACE_VERSION)
|
||||
* @vendor: EAP Vendor-ID (EAP_VENDOR_*) (0 = IETF)
|
||||
* @method: EAP type number (EAP_TYPE_*)
|
||||
* @name: Name of the method (e.g., "TLS")
|
||||
* Returns: Allocated EAP method structure or %NULL on failure
|
||||
*
|
||||
* The returned structure should be freed with eap_peer_method_free() when it
|
||||
* is not needed anymore.
|
||||
*/
|
||||
struct eap_method * eap_peer_method_alloc(int version, int vendor,
|
||||
EapType method, const char *name)
|
||||
{
|
||||
struct eap_method *eap;
|
||||
eap = os_zalloc(sizeof(*eap));
|
||||
if (eap == NULL)
|
||||
return NULL;
|
||||
eap->version = version;
|
||||
eap->vendor = vendor;
|
||||
eap->method = method;
|
||||
eap->name = name;
|
||||
return eap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_peer_method_free - Free EAP peer method structure
|
||||
* @method: Method structure allocated with eap_peer_method_alloc()
|
||||
*/
|
||||
void eap_peer_method_free(struct eap_method *method)
|
||||
{
|
||||
os_free(method);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_peer_method_register - Register an EAP peer method
|
||||
* @method: EAP method to register
|
||||
* Returns: 0 on success, -1 on invalid method, or -2 if a matching EAP method
|
||||
* has already been registered
|
||||
*
|
||||
* Each EAP peer method needs to call this function to register itself as a
|
||||
* supported EAP method.
|
||||
*/
|
||||
int eap_peer_method_register(struct eap_method *method)
|
||||
{
|
||||
struct eap_method *m, *last = NULL;
|
||||
|
||||
if (method == NULL || method->name == NULL ||
|
||||
method->version != EAP_PEER_METHOD_INTERFACE_VERSION)
|
||||
return -1;
|
||||
|
||||
for (m = eap_methods; m; m = m->next) {
|
||||
if ((m->vendor == method->vendor &&
|
||||
m->method == method->method) ||
|
||||
os_strcmp(m->name, method->name) == 0)
|
||||
return -2;
|
||||
last = m;
|
||||
}
|
||||
|
||||
if (last)
|
||||
last->next = method;
|
||||
else
|
||||
eap_methods = method;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_peer_unregister_methods - Unregister EAP peer methods
|
||||
*
|
||||
* This function is called at program termination to unregister all EAP peer
|
||||
* methods.
|
||||
*/
|
||||
void eap_peer_unregister_methods(void)
|
||||
{
|
||||
struct eap_method *m;
|
||||
#ifdef CONFIG_DYNAMIC_EAP_METHODS
|
||||
void *handle;
|
||||
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
|
||||
|
||||
while (eap_methods) {
|
||||
m = eap_methods;
|
||||
eap_methods = eap_methods->next;
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_EAP_METHODS
|
||||
handle = m->dl_handle;
|
||||
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
|
||||
|
||||
if (m->free)
|
||||
m->free(m);
|
||||
else
|
||||
eap_peer_method_free(m);
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_EAP_METHODS
|
||||
if (handle)
|
||||
dlclose(handle);
|
||||
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
|
||||
}
|
||||
}
|
111
freebsd/contrib/wpa/src/eap_peer/eap_methods.h
Normal file
111
freebsd/contrib/wpa/src/eap_peer/eap_methods.h
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* EAP peer: Method registration
|
||||
* Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_METHODS_H
|
||||
#define EAP_METHODS_H
|
||||
|
||||
#include "eap_common/eap_defs.h"
|
||||
|
||||
const struct eap_method * eap_peer_get_eap_method(int vendor, EapType method);
|
||||
const struct eap_method * eap_peer_get_methods(size_t *count);
|
||||
|
||||
struct eap_method * eap_peer_method_alloc(int version, int vendor,
|
||||
EapType method, const char *name);
|
||||
void eap_peer_method_free(struct eap_method *method);
|
||||
int eap_peer_method_register(struct eap_method *method);
|
||||
|
||||
|
||||
#ifdef IEEE8021X_EAPOL
|
||||
|
||||
EapType eap_peer_get_type(const char *name, int *vendor);
|
||||
const char * eap_get_name(int vendor, EapType type);
|
||||
size_t eap_get_names(char *buf, size_t buflen);
|
||||
char ** eap_get_names_as_string_array(size_t *num);
|
||||
void eap_peer_unregister_methods(void);
|
||||
|
||||
#else /* IEEE8021X_EAPOL */
|
||||
|
||||
static inline EapType eap_peer_get_type(const char *name, int *vendor)
|
||||
{
|
||||
*vendor = EAP_VENDOR_IETF;
|
||||
return EAP_TYPE_NONE;
|
||||
}
|
||||
|
||||
static inline const char * eap_get_name(int vendor, EapType type)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline size_t eap_get_names(char *buf, size_t buflen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int eap_peer_register_methods(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void eap_peer_unregister_methods(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline char ** eap_get_names_as_string_array(size_t *num)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_EAP_METHODS
|
||||
|
||||
int eap_peer_method_load(const char *so);
|
||||
int eap_peer_method_unload(struct eap_method *method);
|
||||
|
||||
#else /* CONFIG_DYNAMIC_EAP_METHODS */
|
||||
|
||||
static inline int eap_peer_method_load(const char *so)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int eap_peer_method_unload(struct eap_method *method)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DYNAMIC_EAP_METHODS */
|
||||
|
||||
/* EAP peer method registration calls for statically linked in methods */
|
||||
int eap_peer_md5_register(void);
|
||||
int eap_peer_tls_register(void);
|
||||
int eap_peer_unauth_tls_register(void);
|
||||
int eap_peer_wfa_unauth_tls_register(void);
|
||||
int eap_peer_mschapv2_register(void);
|
||||
int eap_peer_peap_register(void);
|
||||
int eap_peer_ttls_register(void);
|
||||
int eap_peer_gtc_register(void);
|
||||
int eap_peer_otp_register(void);
|
||||
int eap_peer_sim_register(void);
|
||||
int eap_peer_leap_register(void);
|
||||
int eap_peer_psk_register(void);
|
||||
int eap_peer_aka_register(void);
|
||||
int eap_peer_aka_prime_register(void);
|
||||
int eap_peer_fast_register(void);
|
||||
int eap_peer_pax_register(void);
|
||||
int eap_peer_sake_register(void);
|
||||
int eap_peer_gpsk_register(void);
|
||||
int eap_peer_wsc_register(void);
|
||||
int eap_peer_ikev2_register(void);
|
||||
int eap_peer_vendor_test_register(void);
|
||||
int eap_peer_tnc_register(void);
|
||||
int eap_peer_pwd_register(void);
|
||||
int eap_peer_eke_register(void);
|
||||
|
||||
#endif /* EAP_METHODS_H */
|
903
freebsd/contrib/wpa/src/eap_peer/eap_mschapv2.c
Normal file
903
freebsd/contrib/wpa/src/eap_peer/eap_mschapv2.c
Normal file
@ -0,0 +1,903 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* EAP peer method: EAP-MSCHAPV2 (draft-kamath-pppext-eap-mschapv2-00.txt)
|
||||
* Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*
|
||||
* This file implements EAP peer part of EAP-MSCHAPV2 method (EAP type 26).
|
||||
* draft-kamath-pppext-eap-mschapv2-00.txt defines the Microsoft EAP CHAP
|
||||
* Extensions Protocol, Version 2, for mutual authentication and key
|
||||
* derivation. This encapsulates MS-CHAP-v2 protocol which is defined in
|
||||
* RFC 2759. Use of EAP-MSCHAPV2 derived keys with MPPE cipher is described in
|
||||
* RFC 3079.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "crypto/ms_funcs.h"
|
||||
#include "crypto/random.h"
|
||||
#include "common/wpa_ctrl.h"
|
||||
#include "mschapv2.h"
|
||||
#include "eap_i.h"
|
||||
#include "eap_config.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
struct eap_mschapv2_hdr {
|
||||
u8 op_code; /* MSCHAPV2_OP_* */
|
||||
u8 mschapv2_id; /* usually same as EAP identifier; must be changed
|
||||
* for challenges, but not for success/failure */
|
||||
u8 ms_length[2]; /* Note: misaligned; length - 5 */
|
||||
/* followed by data */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
/* Response Data field */
|
||||
struct ms_response {
|
||||
u8 peer_challenge[MSCHAPV2_CHAL_LEN];
|
||||
u8 reserved[8];
|
||||
u8 nt_response[MSCHAPV2_NT_RESPONSE_LEN];
|
||||
u8 flags;
|
||||
} STRUCT_PACKED;
|
||||
|
||||
/* Change-Password Data field */
|
||||
struct ms_change_password {
|
||||
u8 encr_password[516];
|
||||
u8 encr_hash[16];
|
||||
u8 peer_challenge[MSCHAPV2_CHAL_LEN];
|
||||
u8 reserved[8];
|
||||
u8 nt_response[MSCHAPV2_NT_RESPONSE_LEN];
|
||||
u8 flags[2];
|
||||
} STRUCT_PACKED;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#define MSCHAPV2_OP_CHALLENGE 1
|
||||
#define MSCHAPV2_OP_RESPONSE 2
|
||||
#define MSCHAPV2_OP_SUCCESS 3
|
||||
#define MSCHAPV2_OP_FAILURE 4
|
||||
#define MSCHAPV2_OP_CHANGE_PASSWORD 7
|
||||
|
||||
#define ERROR_RESTRICTED_LOGON_HOURS 646
|
||||
#define ERROR_ACCT_DISABLED 647
|
||||
#define ERROR_PASSWD_EXPIRED 648
|
||||
#define ERROR_NO_DIALIN_PERMISSION 649
|
||||
#define ERROR_AUTHENTICATION_FAILURE 691
|
||||
#define ERROR_CHANGING_PASSWORD 709
|
||||
|
||||
#define PASSWD_CHANGE_CHAL_LEN 16
|
||||
#define MSCHAPV2_KEY_LEN 16
|
||||
|
||||
|
||||
struct eap_mschapv2_data {
|
||||
u8 auth_response[MSCHAPV2_AUTH_RESPONSE_LEN];
|
||||
int auth_response_valid;
|
||||
|
||||
int prev_error;
|
||||
u8 passwd_change_challenge[PASSWD_CHANGE_CHAL_LEN];
|
||||
int passwd_change_challenge_valid;
|
||||
int passwd_change_version;
|
||||
|
||||
/* Optional challenge values generated in EAP-FAST Phase 1 negotiation
|
||||
*/
|
||||
u8 *peer_challenge;
|
||||
u8 *auth_challenge;
|
||||
|
||||
int phase2;
|
||||
u8 master_key[MSCHAPV2_MASTER_KEY_LEN];
|
||||
int master_key_valid;
|
||||
int success;
|
||||
|
||||
struct wpabuf *prev_challenge;
|
||||
};
|
||||
|
||||
|
||||
static void eap_mschapv2_deinit(struct eap_sm *sm, void *priv);
|
||||
|
||||
|
||||
static void * eap_mschapv2_init(struct eap_sm *sm)
|
||||
{
|
||||
struct eap_mschapv2_data *data;
|
||||
data = os_zalloc(sizeof(*data));
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
|
||||
if (sm->peer_challenge) {
|
||||
data->peer_challenge = os_malloc(MSCHAPV2_CHAL_LEN);
|
||||
if (data->peer_challenge == NULL) {
|
||||
eap_mschapv2_deinit(sm, data);
|
||||
return NULL;
|
||||
}
|
||||
os_memcpy(data->peer_challenge, sm->peer_challenge,
|
||||
MSCHAPV2_CHAL_LEN);
|
||||
}
|
||||
|
||||
if (sm->auth_challenge) {
|
||||
data->auth_challenge = os_malloc(MSCHAPV2_CHAL_LEN);
|
||||
if (data->auth_challenge == NULL) {
|
||||
eap_mschapv2_deinit(sm, data);
|
||||
return NULL;
|
||||
}
|
||||
os_memcpy(data->auth_challenge, sm->auth_challenge,
|
||||
MSCHAPV2_CHAL_LEN);
|
||||
}
|
||||
|
||||
data->phase2 = sm->init_phase2;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
static void eap_mschapv2_deinit(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_mschapv2_data *data = priv;
|
||||
os_free(data->peer_challenge);
|
||||
os_free(data->auth_challenge);
|
||||
wpabuf_free(data->prev_challenge);
|
||||
bin_clear_free(data, sizeof(*data));
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_mschapv2_challenge_reply(
|
||||
struct eap_sm *sm, struct eap_mschapv2_data *data, u8 id,
|
||||
u8 mschapv2_id, const u8 *auth_challenge)
|
||||
{
|
||||
struct wpabuf *resp;
|
||||
struct eap_mschapv2_hdr *ms;
|
||||
u8 *peer_challenge;
|
||||
int ms_len;
|
||||
struct ms_response *r;
|
||||
size_t identity_len, password_len;
|
||||
const u8 *identity, *password;
|
||||
int pwhash;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Generating Challenge Response");
|
||||
|
||||
identity = eap_get_config_identity(sm, &identity_len);
|
||||
password = eap_get_config_password2(sm, &password_len, &pwhash);
|
||||
if (identity == NULL || password == NULL)
|
||||
return NULL;
|
||||
|
||||
ms_len = sizeof(*ms) + 1 + sizeof(*r) + identity_len;
|
||||
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, ms_len,
|
||||
EAP_CODE_RESPONSE, id);
|
||||
if (resp == NULL)
|
||||
return NULL;
|
||||
|
||||
ms = wpabuf_put(resp, sizeof(*ms));
|
||||
ms->op_code = MSCHAPV2_OP_RESPONSE;
|
||||
ms->mschapv2_id = mschapv2_id;
|
||||
if (data->prev_error) {
|
||||
/*
|
||||
* TODO: this does not seem to be enough when processing two
|
||||
* or more failure messages. IAS did not increment mschapv2_id
|
||||
* in its own packets, but it seemed to expect the peer to
|
||||
* increment this for all packets(?).
|
||||
*/
|
||||
ms->mschapv2_id++;
|
||||
}
|
||||
WPA_PUT_BE16(ms->ms_length, ms_len);
|
||||
|
||||
wpabuf_put_u8(resp, sizeof(*r)); /* Value-Size */
|
||||
|
||||
/* Response */
|
||||
r = wpabuf_put(resp, sizeof(*r));
|
||||
peer_challenge = r->peer_challenge;
|
||||
if (data->peer_challenge) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: peer_challenge generated "
|
||||
"in Phase 1");
|
||||
peer_challenge = data->peer_challenge;
|
||||
os_memset(r->peer_challenge, 0, MSCHAPV2_CHAL_LEN);
|
||||
} else if (random_get_bytes(peer_challenge, MSCHAPV2_CHAL_LEN)) {
|
||||
wpabuf_free(resp);
|
||||
return NULL;
|
||||
}
|
||||
os_memset(r->reserved, 0, 8);
|
||||
if (data->auth_challenge) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: auth_challenge generated "
|
||||
"in Phase 1");
|
||||
auth_challenge = data->auth_challenge;
|
||||
}
|
||||
if (mschapv2_derive_response(identity, identity_len, password,
|
||||
password_len, pwhash, auth_challenge,
|
||||
peer_challenge, r->nt_response,
|
||||
data->auth_response, data->master_key)) {
|
||||
wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to derive "
|
||||
"response");
|
||||
wpabuf_free(resp);
|
||||
return NULL;
|
||||
}
|
||||
data->auth_response_valid = 1;
|
||||
data->master_key_valid = 1;
|
||||
|
||||
r->flags = 0; /* reserved, must be zero */
|
||||
|
||||
wpabuf_put_data(resp, identity, identity_len);
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: TX identifier %d mschapv2_id %d "
|
||||
"(response)", id, ms->mschapv2_id);
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_mschapv2_process - Process an EAP-MSCHAPv2 challenge message
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @data: Pointer to private EAP method data from eap_mschapv2_init()
|
||||
* @ret: Return values from EAP request validation and processing
|
||||
* @req: Pointer to EAP-MSCHAPv2 header from the request
|
||||
* @req_len: Length of the EAP-MSCHAPv2 data
|
||||
* @id: EAP identifier used in the request
|
||||
* Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if
|
||||
* no reply available
|
||||
*/
|
||||
static struct wpabuf * eap_mschapv2_challenge(
|
||||
struct eap_sm *sm, struct eap_mschapv2_data *data,
|
||||
struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req,
|
||||
size_t req_len, u8 id)
|
||||
{
|
||||
size_t len, challenge_len;
|
||||
const u8 *pos, *challenge;
|
||||
|
||||
if (eap_get_config_identity(sm, &len) == NULL ||
|
||||
eap_get_config_password(sm, &len) == NULL)
|
||||
return NULL;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Received challenge");
|
||||
if (req_len < sizeof(*req) + 1) {
|
||||
wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Too short challenge data "
|
||||
"(len %lu)", (unsigned long) req_len);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
pos = (const u8 *) (req + 1);
|
||||
challenge_len = *pos++;
|
||||
len = req_len - sizeof(*req) - 1;
|
||||
if (challenge_len != MSCHAPV2_CHAL_LEN) {
|
||||
wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Invalid challenge length "
|
||||
"%lu", (unsigned long) challenge_len);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len < challenge_len) {
|
||||
wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Too short challenge"
|
||||
" packet: len=%lu challenge_len=%lu",
|
||||
(unsigned long) len, (unsigned long) challenge_len);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (data->passwd_change_challenge_valid) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Using challenge from the "
|
||||
"failure message");
|
||||
challenge = data->passwd_change_challenge;
|
||||
} else
|
||||
challenge = pos;
|
||||
pos += challenge_len;
|
||||
len -= challenge_len;
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Authentication Servername",
|
||||
pos, len);
|
||||
|
||||
ret->ignore = FALSE;
|
||||
ret->methodState = METHOD_MAY_CONT;
|
||||
ret->decision = DECISION_FAIL;
|
||||
ret->allowNotifications = TRUE;
|
||||
|
||||
return eap_mschapv2_challenge_reply(sm, data, id, req->mschapv2_id,
|
||||
challenge);
|
||||
}
|
||||
|
||||
|
||||
static void eap_mschapv2_password_changed(struct eap_sm *sm,
|
||||
struct eap_mschapv2_data *data)
|
||||
{
|
||||
struct eap_peer_config *config = eap_get_config(sm);
|
||||
if (config && config->new_password) {
|
||||
wpa_msg(sm->msg_ctx, MSG_INFO,
|
||||
WPA_EVENT_PASSWORD_CHANGED
|
||||
"EAP-MSCHAPV2: Password changed successfully");
|
||||
data->prev_error = 0;
|
||||
bin_clear_free(config->password, config->password_len);
|
||||
if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) {
|
||||
/* TODO: update external storage */
|
||||
} else if (config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH) {
|
||||
config->password = os_malloc(16);
|
||||
config->password_len = 16;
|
||||
if (config->password &&
|
||||
nt_password_hash(config->new_password,
|
||||
config->new_password_len,
|
||||
config->password)) {
|
||||
bin_clear_free(config->password,
|
||||
config->password_len);
|
||||
config->password = NULL;
|
||||
config->password_len = 0;
|
||||
}
|
||||
bin_clear_free(config->new_password,
|
||||
config->new_password_len);
|
||||
} else {
|
||||
config->password = config->new_password;
|
||||
config->password_len = config->new_password_len;
|
||||
}
|
||||
config->new_password = NULL;
|
||||
config->new_password_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_mschapv2_process - Process an EAP-MSCHAPv2 success message
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @data: Pointer to private EAP method data from eap_mschapv2_init()
|
||||
* @ret: Return values from EAP request validation and processing
|
||||
* @req: Pointer to EAP-MSCHAPv2 header from the request
|
||||
* @req_len: Length of the EAP-MSCHAPv2 data
|
||||
* @id: EAP identifier used in th erequest
|
||||
* Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if
|
||||
* no reply available
|
||||
*/
|
||||
static struct wpabuf * eap_mschapv2_success(struct eap_sm *sm,
|
||||
struct eap_mschapv2_data *data,
|
||||
struct eap_method_ret *ret,
|
||||
const struct eap_mschapv2_hdr *req,
|
||||
size_t req_len, u8 id)
|
||||
{
|
||||
struct wpabuf *resp;
|
||||
const u8 *pos;
|
||||
size_t len;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Received success");
|
||||
len = req_len - sizeof(*req);
|
||||
pos = (const u8 *) (req + 1);
|
||||
if (!data->auth_response_valid ||
|
||||
mschapv2_verify_auth_response(data->auth_response, pos, len)) {
|
||||
wpa_printf(MSG_WARNING, "EAP-MSCHAPV2: Invalid authenticator "
|
||||
"response in success request");
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
return NULL;
|
||||
}
|
||||
pos += 2 + 2 * MSCHAPV2_AUTH_RESPONSE_LEN;
|
||||
len -= 2 + 2 * MSCHAPV2_AUTH_RESPONSE_LEN;
|
||||
while (len > 0 && *pos == ' ') {
|
||||
pos++;
|
||||
len--;
|
||||
}
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Success message",
|
||||
pos, len);
|
||||
wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Authentication succeeded");
|
||||
|
||||
/* Note: Only op_code of the EAP-MSCHAPV2 header is included in success
|
||||
* message. */
|
||||
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, 1,
|
||||
EAP_CODE_RESPONSE, id);
|
||||
if (resp == NULL) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Failed to allocate "
|
||||
"buffer for success response");
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wpabuf_put_u8(resp, MSCHAPV2_OP_SUCCESS); /* op_code */
|
||||
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_UNCOND_SUCC;
|
||||
ret->allowNotifications = FALSE;
|
||||
data->success = 1;
|
||||
|
||||
if (data->prev_error == ERROR_PASSWD_EXPIRED)
|
||||
eap_mschapv2_password_changed(sm, data);
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
static int eap_mschapv2_failure_txt(struct eap_sm *sm,
|
||||
struct eap_mschapv2_data *data, char *txt)
|
||||
{
|
||||
char *pos, *msg = "";
|
||||
int retry = 1;
|
||||
struct eap_peer_config *config = eap_get_config(sm);
|
||||
|
||||
/* For example:
|
||||
* E=691 R=1 C=<32 octets hex challenge> V=3 M=Authentication Failure
|
||||
*/
|
||||
|
||||
pos = txt;
|
||||
|
||||
if (pos && os_strncmp(pos, "E=", 2) == 0) {
|
||||
pos += 2;
|
||||
data->prev_error = atoi(pos);
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: error %d",
|
||||
data->prev_error);
|
||||
pos = os_strchr(pos, ' ');
|
||||
if (pos)
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (pos && os_strncmp(pos, "R=", 2) == 0) {
|
||||
pos += 2;
|
||||
retry = atoi(pos);
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: retry is %sallowed",
|
||||
retry == 1 ? "" : "not ");
|
||||
pos = os_strchr(pos, ' ');
|
||||
if (pos)
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (pos && os_strncmp(pos, "C=", 2) == 0) {
|
||||
int hex_len;
|
||||
pos += 2;
|
||||
hex_len = os_strchr(pos, ' ') - (char *) pos;
|
||||
if (hex_len == PASSWD_CHANGE_CHAL_LEN * 2) {
|
||||
if (hexstr2bin(pos, data->passwd_change_challenge,
|
||||
PASSWD_CHANGE_CHAL_LEN)) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: invalid "
|
||||
"failure challenge");
|
||||
} else {
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: failure "
|
||||
"challenge",
|
||||
data->passwd_change_challenge,
|
||||
PASSWD_CHANGE_CHAL_LEN);
|
||||
data->passwd_change_challenge_valid = 1;
|
||||
}
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: invalid failure "
|
||||
"challenge len %d", hex_len);
|
||||
}
|
||||
pos = os_strchr(pos, ' ');
|
||||
if (pos)
|
||||
pos++;
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: required challenge field "
|
||||
"was not present in failure message");
|
||||
}
|
||||
|
||||
if (pos && os_strncmp(pos, "V=", 2) == 0) {
|
||||
pos += 2;
|
||||
data->passwd_change_version = atoi(pos);
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: password changing "
|
||||
"protocol version %d", data->passwd_change_version);
|
||||
pos = os_strchr(pos, ' ');
|
||||
if (pos)
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (pos && os_strncmp(pos, "M=", 2) == 0) {
|
||||
pos += 2;
|
||||
msg = pos;
|
||||
}
|
||||
if (data->prev_error == ERROR_AUTHENTICATION_FAILURE && retry &&
|
||||
config && config->phase2 &&
|
||||
os_strstr(config->phase2, "mschapv2_retry=0")) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP-MSCHAPV2: mark password retry disabled based on local configuration");
|
||||
retry = 0;
|
||||
}
|
||||
wpa_msg(sm->msg_ctx, MSG_WARNING,
|
||||
"EAP-MSCHAPV2: failure message: '%s' (retry %sallowed, error "
|
||||
"%d)",
|
||||
msg, retry == 1 ? "" : "not ", data->prev_error);
|
||||
if (data->prev_error == ERROR_PASSWD_EXPIRED &&
|
||||
data->passwd_change_version == 3 && config) {
|
||||
if (config->new_password == NULL) {
|
||||
wpa_msg(sm->msg_ctx, MSG_INFO,
|
||||
"EAP-MSCHAPV2: Password expired - password "
|
||||
"change required");
|
||||
eap_sm_request_new_password(sm);
|
||||
}
|
||||
} else if (retry == 1 && config) {
|
||||
/* TODO: could prevent the current password from being used
|
||||
* again at least for some period of time */
|
||||
if (!config->mschapv2_retry)
|
||||
eap_sm_request_identity(sm);
|
||||
eap_sm_request_password(sm);
|
||||
config->mschapv2_retry = 1;
|
||||
} else if (config) {
|
||||
/* TODO: prevent retries using same username/password */
|
||||
config->mschapv2_retry = 0;
|
||||
}
|
||||
|
||||
return retry == 1;
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_mschapv2_change_password(
|
||||
struct eap_sm *sm, struct eap_mschapv2_data *data,
|
||||
struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req, u8 id)
|
||||
{
|
||||
#ifdef CONFIG_NO_RC4
|
||||
wpa_printf(MSG_ERROR,
|
||||
"EAP-MSCHAPV2: RC4 not support in the build - cannot change password");
|
||||
return NULL;
|
||||
#else /* CONFIG_NO_RC4 */
|
||||
struct wpabuf *resp;
|
||||
int ms_len;
|
||||
const u8 *username, *password, *new_password;
|
||||
size_t username_len, password_len, new_password_len;
|
||||
struct eap_mschapv2_hdr *ms;
|
||||
struct ms_change_password *cp;
|
||||
u8 password_hash[16], password_hash_hash[16];
|
||||
int pwhash;
|
||||
|
||||
username = eap_get_config_identity(sm, &username_len);
|
||||
password = eap_get_config_password2(sm, &password_len, &pwhash);
|
||||
new_password = eap_get_config_new_password(sm, &new_password_len);
|
||||
if (username == NULL || password == NULL || new_password == NULL)
|
||||
return NULL;
|
||||
|
||||
username = mschapv2_remove_domain(username, &username_len);
|
||||
|
||||
ret->ignore = FALSE;
|
||||
ret->methodState = METHOD_MAY_CONT;
|
||||
ret->decision = DECISION_COND_SUCC;
|
||||
ret->allowNotifications = TRUE;
|
||||
|
||||
ms_len = sizeof(*ms) + sizeof(*cp);
|
||||
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, ms_len,
|
||||
EAP_CODE_RESPONSE, id);
|
||||
if (resp == NULL)
|
||||
return NULL;
|
||||
|
||||
ms = wpabuf_put(resp, sizeof(*ms));
|
||||
ms->op_code = MSCHAPV2_OP_CHANGE_PASSWORD;
|
||||
ms->mschapv2_id = req->mschapv2_id + 1;
|
||||
WPA_PUT_BE16(ms->ms_length, ms_len);
|
||||
cp = wpabuf_put(resp, sizeof(*cp));
|
||||
|
||||
/* Encrypted-Password */
|
||||
if (pwhash) {
|
||||
if (encrypt_pw_block_with_password_hash(
|
||||
new_password, new_password_len,
|
||||
password, cp->encr_password))
|
||||
goto fail;
|
||||
} else {
|
||||
if (new_password_encrypted_with_old_nt_password_hash(
|
||||
new_password, new_password_len,
|
||||
password, password_len, cp->encr_password))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Encrypted-Hash */
|
||||
if (pwhash) {
|
||||
u8 new_password_hash[16];
|
||||
if (nt_password_hash(new_password, new_password_len,
|
||||
new_password_hash))
|
||||
goto fail;
|
||||
nt_password_hash_encrypted_with_block(password,
|
||||
new_password_hash,
|
||||
cp->encr_hash);
|
||||
} else {
|
||||
if (old_nt_password_hash_encrypted_with_new_nt_password_hash(
|
||||
new_password, new_password_len,
|
||||
password, password_len, cp->encr_hash))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Peer-Challenge */
|
||||
if (random_get_bytes(cp->peer_challenge, MSCHAPV2_CHAL_LEN))
|
||||
goto fail;
|
||||
|
||||
/* Reserved, must be zero */
|
||||
os_memset(cp->reserved, 0, 8);
|
||||
|
||||
/* NT-Response */
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: auth_challenge",
|
||||
data->passwd_change_challenge, PASSWD_CHANGE_CHAL_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: peer_challenge",
|
||||
cp->peer_challenge, MSCHAPV2_CHAL_LEN);
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: username",
|
||||
username, username_len);
|
||||
wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-MSCHAPV2: new password",
|
||||
new_password, new_password_len);
|
||||
generate_nt_response(data->passwd_change_challenge, cp->peer_challenge,
|
||||
username, username_len,
|
||||
new_password, new_password_len,
|
||||
cp->nt_response);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: NT-Response",
|
||||
cp->nt_response, MSCHAPV2_NT_RESPONSE_LEN);
|
||||
|
||||
/* Authenticator response is not really needed yet, but calculate it
|
||||
* here so that challenges need not be saved. */
|
||||
generate_authenticator_response(new_password, new_password_len,
|
||||
cp->peer_challenge,
|
||||
data->passwd_change_challenge,
|
||||
username, username_len,
|
||||
cp->nt_response, data->auth_response);
|
||||
data->auth_response_valid = 1;
|
||||
|
||||
/* Likewise, generate master_key here since we have the needed data
|
||||
* available. */
|
||||
if (nt_password_hash(new_password, new_password_len, password_hash) ||
|
||||
hash_nt_password_hash(password_hash, password_hash_hash) ||
|
||||
get_master_key(password_hash_hash, cp->nt_response,
|
||||
data->master_key)) {
|
||||
data->auth_response_valid = 0;
|
||||
goto fail;
|
||||
}
|
||||
data->master_key_valid = 1;
|
||||
|
||||
/* Flags */
|
||||
os_memset(cp->flags, 0, 2);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: TX identifier %d mschapv2_id %d "
|
||||
"(change pw)", id, ms->mschapv2_id);
|
||||
|
||||
return resp;
|
||||
|
||||
fail:
|
||||
wpabuf_free(resp);
|
||||
return NULL;
|
||||
#endif /* CONFIG_NO_RC4 */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_mschapv2_process - Process an EAP-MSCHAPv2 failure message
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @data: Pointer to private EAP method data from eap_mschapv2_init()
|
||||
* @ret: Return values from EAP request validation and processing
|
||||
* @req: Pointer to EAP-MSCHAPv2 header from the request
|
||||
* @req_len: Length of the EAP-MSCHAPv2 data
|
||||
* @id: EAP identifier used in th erequest
|
||||
* Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if
|
||||
* no reply available
|
||||
*/
|
||||
static struct wpabuf * eap_mschapv2_failure(struct eap_sm *sm,
|
||||
struct eap_mschapv2_data *data,
|
||||
struct eap_method_ret *ret,
|
||||
const struct eap_mschapv2_hdr *req,
|
||||
size_t req_len, u8 id)
|
||||
{
|
||||
struct wpabuf *resp;
|
||||
const u8 *msdata = (const u8 *) (req + 1);
|
||||
char *buf;
|
||||
size_t len = req_len - sizeof(*req);
|
||||
int retry = 0;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Received failure");
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Failure data",
|
||||
msdata, len);
|
||||
/*
|
||||
* eap_mschapv2_failure_txt() expects a nul terminated string, so we
|
||||
* must allocate a large enough temporary buffer to create that since
|
||||
* the received message does not include nul termination.
|
||||
*/
|
||||
buf = dup_binstr(msdata, len);
|
||||
if (buf) {
|
||||
retry = eap_mschapv2_failure_txt(sm, data, buf);
|
||||
os_free(buf);
|
||||
}
|
||||
|
||||
ret->ignore = FALSE;
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
ret->allowNotifications = FALSE;
|
||||
|
||||
if (data->prev_error == ERROR_PASSWD_EXPIRED &&
|
||||
data->passwd_change_version == 3) {
|
||||
struct eap_peer_config *config = eap_get_config(sm);
|
||||
if (config && config->new_password)
|
||||
return eap_mschapv2_change_password(sm, data, ret, req,
|
||||
id);
|
||||
if (config && config->pending_req_new_password)
|
||||
return NULL;
|
||||
} else if (retry && data->prev_error == ERROR_AUTHENTICATION_FAILURE) {
|
||||
/* TODO: could try to retry authentication, e.g, after having
|
||||
* changed the username/password. In this case, EAP MS-CHAP-v2
|
||||
* Failure Response would not be sent here. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Note: Only op_code of the EAP-MSCHAPV2 header is included in failure
|
||||
* message. */
|
||||
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, 1,
|
||||
EAP_CODE_RESPONSE, id);
|
||||
if (resp == NULL)
|
||||
return NULL;
|
||||
|
||||
wpabuf_put_u8(resp, MSCHAPV2_OP_FAILURE); /* op_code */
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
static int eap_mschapv2_check_config(struct eap_sm *sm)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (eap_get_config_identity(sm, &len) == NULL) {
|
||||
wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Identity not configured");
|
||||
eap_sm_request_identity(sm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (eap_get_config_password(sm, &len) == NULL) {
|
||||
wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Password not configured");
|
||||
eap_sm_request_password(sm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int eap_mschapv2_check_mslen(struct eap_sm *sm, size_t len,
|
||||
const struct eap_mschapv2_hdr *ms)
|
||||
{
|
||||
size_t ms_len = WPA_GET_BE16(ms->ms_length);
|
||||
|
||||
if (ms_len == len)
|
||||
return 0;
|
||||
|
||||
wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Invalid header: len=%lu "
|
||||
"ms_len=%lu", (unsigned long) len, (unsigned long) ms_len);
|
||||
if (sm->workaround) {
|
||||
/* Some authentication servers use invalid ms_len,
|
||||
* ignore it for interoperability. */
|
||||
wpa_printf(MSG_INFO, "EAP-MSCHAPV2: workaround, ignore"
|
||||
" invalid ms_len %lu (len %lu)",
|
||||
(unsigned long) ms_len,
|
||||
(unsigned long) len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void eap_mschapv2_copy_challenge(struct eap_mschapv2_data *data,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
/*
|
||||
* Store a copy of the challenge message, so that it can be processed
|
||||
* again in case retry is allowed after a possible failure.
|
||||
*/
|
||||
wpabuf_free(data->prev_challenge);
|
||||
data->prev_challenge = wpabuf_dup(reqData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_mschapv2_process - Process an EAP-MSCHAPv2 request
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @priv: Pointer to private EAP method data from eap_mschapv2_init()
|
||||
* @ret: Return values from EAP request validation and processing
|
||||
* @reqData: EAP request to be processed (eapReqData)
|
||||
* Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if
|
||||
* no reply available
|
||||
*/
|
||||
static struct wpabuf * eap_mschapv2_process(struct eap_sm *sm, void *priv,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
struct eap_mschapv2_data *data = priv;
|
||||
struct eap_peer_config *config = eap_get_config(sm);
|
||||
const struct eap_mschapv2_hdr *ms;
|
||||
int using_prev_challenge = 0;
|
||||
const u8 *pos;
|
||||
size_t len;
|
||||
u8 id;
|
||||
|
||||
if (eap_mschapv2_check_config(sm)) {
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (config->mschapv2_retry && data->prev_challenge &&
|
||||
data->prev_error == ERROR_AUTHENTICATION_FAILURE) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Replacing pending packet "
|
||||
"with the previous challenge");
|
||||
|
||||
reqData = data->prev_challenge;
|
||||
using_prev_challenge = 1;
|
||||
config->mschapv2_retry = 0;
|
||||
}
|
||||
|
||||
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, reqData,
|
||||
&len);
|
||||
if (pos == NULL || len < sizeof(*ms) + 1) {
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ms = (const struct eap_mschapv2_hdr *) pos;
|
||||
if (eap_mschapv2_check_mslen(sm, len, ms)) {
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
id = eap_get_id(reqData);
|
||||
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: RX identifier %d mschapv2_id %d",
|
||||
id, ms->mschapv2_id);
|
||||
|
||||
switch (ms->op_code) {
|
||||
case MSCHAPV2_OP_CHALLENGE:
|
||||
if (!using_prev_challenge)
|
||||
eap_mschapv2_copy_challenge(data, reqData);
|
||||
return eap_mschapv2_challenge(sm, data, ret, ms, len, id);
|
||||
case MSCHAPV2_OP_SUCCESS:
|
||||
return eap_mschapv2_success(sm, data, ret, ms, len, id);
|
||||
case MSCHAPV2_OP_FAILURE:
|
||||
return eap_mschapv2_failure(sm, data, ret, ms, len, id);
|
||||
default:
|
||||
wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Unknown op %d - ignored",
|
||||
ms->op_code);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Boolean eap_mschapv2_isKeyAvailable(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_mschapv2_data *data = priv;
|
||||
return data->success && data->master_key_valid;
|
||||
}
|
||||
|
||||
|
||||
static u8 * eap_mschapv2_getKey(struct eap_sm *sm, void *priv, size_t *len)
|
||||
{
|
||||
struct eap_mschapv2_data *data = priv;
|
||||
u8 *key;
|
||||
int key_len;
|
||||
|
||||
if (!data->master_key_valid || !data->success)
|
||||
return NULL;
|
||||
|
||||
key_len = 2 * MSCHAPV2_KEY_LEN;
|
||||
|
||||
key = os_malloc(key_len);
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
/* MSK = server MS-MPPE-Recv-Key | MS-MPPE-Send-Key, i.e.,
|
||||
* peer MS-MPPE-Send-Key | MS-MPPE-Recv-Key */
|
||||
get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 1, 0);
|
||||
get_asymetric_start_key(data->master_key, key + MSCHAPV2_KEY_LEN,
|
||||
MSCHAPV2_KEY_LEN, 0, 0);
|
||||
|
||||
wpa_hexdump_key(MSG_DEBUG, "EAP-MSCHAPV2: Derived key",
|
||||
key, key_len);
|
||||
|
||||
*len = key_len;
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_peer_mschapv2_register - Register EAP-MSCHAPv2 peer method
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function is used to register EAP-MSCHAPv2 peer method into the EAP
|
||||
* method list.
|
||||
*/
|
||||
int eap_peer_mschapv2_register(void)
|
||||
{
|
||||
struct eap_method *eap;
|
||||
int ret;
|
||||
|
||||
eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
|
||||
EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2,
|
||||
"MSCHAPV2");
|
||||
if (eap == NULL)
|
||||
return -1;
|
||||
|
||||
eap->init = eap_mschapv2_init;
|
||||
eap->deinit = eap_mschapv2_deinit;
|
||||
eap->process = eap_mschapv2_process;
|
||||
eap->isKeyAvailable = eap_mschapv2_isKeyAvailable;
|
||||
eap->getKey = eap_mschapv2_getKey;
|
||||
|
||||
ret = eap_peer_method_register(eap);
|
||||
if (ret)
|
||||
eap_peer_method_free(eap);
|
||||
return ret;
|
||||
}
|
103
freebsd/contrib/wpa/src/eap_peer/eap_otp.c
Normal file
103
freebsd/contrib/wpa/src/eap_peer/eap_otp.c
Normal file
@ -0,0 +1,103 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* EAP peer method: EAP-OTP (RFC 3748)
|
||||
* Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "eap_i.h"
|
||||
|
||||
|
||||
static void * eap_otp_init(struct eap_sm *sm)
|
||||
{
|
||||
/* No need for private data. However, must return non-NULL to indicate
|
||||
* success. */
|
||||
return (void *) 1;
|
||||
}
|
||||
|
||||
|
||||
static void eap_otp_deinit(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_otp_process(struct eap_sm *sm, void *priv,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
struct wpabuf *resp;
|
||||
const u8 *pos, *password;
|
||||
size_t password_len, len;
|
||||
int otp;
|
||||
|
||||
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_OTP, reqData, &len);
|
||||
if (pos == NULL) {
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-OTP: Request message",
|
||||
pos, len);
|
||||
|
||||
password = eap_get_config_otp(sm, &password_len);
|
||||
if (password)
|
||||
otp = 1;
|
||||
else {
|
||||
password = eap_get_config_password(sm, &password_len);
|
||||
otp = 0;
|
||||
}
|
||||
|
||||
if (password == NULL) {
|
||||
wpa_printf(MSG_INFO, "EAP-OTP: Password not configured");
|
||||
eap_sm_request_otp(sm, (const char *) pos, len);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->ignore = FALSE;
|
||||
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_COND_SUCC;
|
||||
ret->allowNotifications = FALSE;
|
||||
|
||||
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_OTP, password_len,
|
||||
EAP_CODE_RESPONSE, eap_get_id(reqData));
|
||||
if (resp == NULL)
|
||||
return NULL;
|
||||
wpabuf_put_data(resp, password, password_len);
|
||||
wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-OTP: Response",
|
||||
password, password_len);
|
||||
|
||||
if (otp) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-OTP: Forgetting used password");
|
||||
eap_clear_config_otp(sm);
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
int eap_peer_otp_register(void)
|
||||
{
|
||||
struct eap_method *eap;
|
||||
int ret;
|
||||
|
||||
eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
|
||||
EAP_VENDOR_IETF, EAP_TYPE_OTP, "OTP");
|
||||
if (eap == NULL)
|
||||
return -1;
|
||||
|
||||
eap->init = eap_otp_init;
|
||||
eap->deinit = eap_otp_deinit;
|
||||
eap->process = eap_otp_process;
|
||||
|
||||
ret = eap_peer_method_register(eap);
|
||||
if (ret)
|
||||
eap_peer_method_free(eap);
|
||||
return ret;
|
||||
}
|
1264
freebsd/contrib/wpa/src/eap_peer/eap_peap.c
Normal file
1264
freebsd/contrib/wpa/src/eap_peer/eap_peap.c
Normal file
File diff suppressed because it is too large
Load Diff
49
freebsd/contrib/wpa/src/eap_peer/eap_proxy.h
Normal file
49
freebsd/contrib/wpa/src/eap_peer/eap_proxy.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* EAP proxy definitions
|
||||
* Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_PROXY_H
|
||||
#define EAP_PROXY_H
|
||||
|
||||
struct eap_proxy_sm;
|
||||
struct eapol_callbacks;
|
||||
struct eap_sm;
|
||||
struct eap_peer_config;
|
||||
|
||||
enum eap_proxy_status {
|
||||
EAP_PROXY_FAILURE = 0x00,
|
||||
EAP_PROXY_SUCCESS
|
||||
};
|
||||
|
||||
struct eap_proxy_sm *
|
||||
eap_proxy_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb,
|
||||
void *msg_ctx);
|
||||
|
||||
void eap_proxy_deinit(struct eap_proxy_sm *eap_proxy);
|
||||
|
||||
int eap_proxy_key_available(struct eap_proxy_sm *sm);
|
||||
|
||||
const u8 * eap_proxy_get_eapKeyData(struct eap_proxy_sm *sm, size_t *len);
|
||||
|
||||
struct wpabuf * eap_proxy_get_eapRespData(struct eap_proxy_sm *sm);
|
||||
|
||||
int eap_proxy_sm_step(struct eap_proxy_sm *sm, struct eap_sm *eap_sm);
|
||||
|
||||
enum eap_proxy_status
|
||||
eap_proxy_packet_update(struct eap_proxy_sm *eap_proxy, u8 *eapReqData,
|
||||
int eapReqDataLen);
|
||||
|
||||
int eap_proxy_sm_get_status(struct eap_proxy_sm *sm, char *buf, size_t buflen,
|
||||
int verbose);
|
||||
|
||||
int eap_proxy_get_imsi(struct eap_proxy_sm *eap_proxy, char *imsi_buf,
|
||||
size_t *imsi_len);
|
||||
|
||||
int eap_proxy_notify_config(struct eap_proxy_sm *sm,
|
||||
struct eap_peer_config *config);
|
||||
|
||||
#endif /* EAP_PROXY_H */
|
504
freebsd/contrib/wpa/src/eap_peer/eap_psk.c
Normal file
504
freebsd/contrib/wpa/src/eap_peer/eap_psk.c
Normal file
@ -0,0 +1,504 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* EAP peer method: EAP-PSK (RFC 4764)
|
||||
* Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*
|
||||
* Note: EAP-PSK is an EAP authentication method and as such, completely
|
||||
* different from WPA-PSK. This file is not needed for WPA-PSK functionality.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "crypto/aes_wrap.h"
|
||||
#include "crypto/random.h"
|
||||
#include "eap_common/eap_psk_common.h"
|
||||
#include "eap_i.h"
|
||||
|
||||
|
||||
struct eap_psk_data {
|
||||
enum { PSK_INIT, PSK_MAC_SENT, PSK_DONE } state;
|
||||
u8 rand_p[EAP_PSK_RAND_LEN];
|
||||
u8 rand_s[EAP_PSK_RAND_LEN];
|
||||
u8 ak[EAP_PSK_AK_LEN], kdk[EAP_PSK_KDK_LEN], tek[EAP_PSK_TEK_LEN];
|
||||
u8 *id_s, *id_p;
|
||||
size_t id_s_len, id_p_len;
|
||||
u8 msk[EAP_MSK_LEN];
|
||||
u8 emsk[EAP_EMSK_LEN];
|
||||
};
|
||||
|
||||
|
||||
static void * eap_psk_init(struct eap_sm *sm)
|
||||
{
|
||||
struct eap_psk_data *data;
|
||||
const u8 *identity, *password;
|
||||
size_t identity_len, password_len;
|
||||
|
||||
password = eap_get_config_password(sm, &password_len);
|
||||
if (!password || password_len != 16) {
|
||||
wpa_printf(MSG_INFO, "EAP-PSK: 16-octet pre-shared key not "
|
||||
"configured");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = os_zalloc(sizeof(*data));
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
if (eap_psk_key_setup(password, data->ak, data->kdk)) {
|
||||
os_free(data);
|
||||
return NULL;
|
||||
}
|
||||
wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: AK", data->ak, EAP_PSK_AK_LEN);
|
||||
wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: KDK", data->kdk, EAP_PSK_KDK_LEN);
|
||||
data->state = PSK_INIT;
|
||||
|
||||
identity = eap_get_config_identity(sm, &identity_len);
|
||||
if (identity) {
|
||||
data->id_p = os_malloc(identity_len);
|
||||
if (data->id_p)
|
||||
os_memcpy(data->id_p, identity, identity_len);
|
||||
data->id_p_len = identity_len;
|
||||
}
|
||||
if (data->id_p == NULL) {
|
||||
wpa_printf(MSG_INFO, "EAP-PSK: could not get own identity");
|
||||
os_free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
static void eap_psk_deinit(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_psk_data *data = priv;
|
||||
os_free(data->id_s);
|
||||
os_free(data->id_p);
|
||||
bin_clear_free(data, sizeof(*data));
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_psk_process_1(struct eap_psk_data *data,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
const struct eap_psk_hdr_1 *hdr1;
|
||||
struct eap_psk_hdr_2 *hdr2;
|
||||
struct wpabuf *resp;
|
||||
u8 *buf, *pos;
|
||||
size_t buflen, len;
|
||||
const u8 *cpos;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-PSK: in INIT state");
|
||||
|
||||
cpos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, reqData, &len);
|
||||
hdr1 = (const struct eap_psk_hdr_1 *) cpos;
|
||||
if (cpos == NULL || len < sizeof(*hdr1)) {
|
||||
wpa_printf(MSG_INFO, "EAP-PSK: Invalid first message "
|
||||
"length (%lu; expected %lu or more)",
|
||||
(unsigned long) len,
|
||||
(unsigned long) sizeof(*hdr1));
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "EAP-PSK: Flags=0x%x", hdr1->flags);
|
||||
if (EAP_PSK_FLAGS_GET_T(hdr1->flags) != 0) {
|
||||
wpa_printf(MSG_INFO, "EAP-PSK: Unexpected T=%d (expected 0)",
|
||||
EAP_PSK_FLAGS_GET_T(hdr1->flags));
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
return NULL;
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_S", hdr1->rand_s,
|
||||
EAP_PSK_RAND_LEN);
|
||||
os_memcpy(data->rand_s, hdr1->rand_s, EAP_PSK_RAND_LEN);
|
||||
os_free(data->id_s);
|
||||
data->id_s_len = len - sizeof(*hdr1);
|
||||
data->id_s = os_malloc(data->id_s_len);
|
||||
if (data->id_s == NULL) {
|
||||
wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory for "
|
||||
"ID_S (len=%lu)", (unsigned long) data->id_s_len);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
os_memcpy(data->id_s, (u8 *) (hdr1 + 1), data->id_s_len);
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: ID_S",
|
||||
data->id_s, data->id_s_len);
|
||||
|
||||
if (random_get_bytes(data->rand_p, EAP_PSK_RAND_LEN)) {
|
||||
wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data");
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK,
|
||||
sizeof(*hdr2) + data->id_p_len, EAP_CODE_RESPONSE,
|
||||
eap_get_id(reqData));
|
||||
if (resp == NULL)
|
||||
return NULL;
|
||||
hdr2 = wpabuf_put(resp, sizeof(*hdr2));
|
||||
hdr2->flags = EAP_PSK_FLAGS_SET_T(1); /* T=1 */
|
||||
os_memcpy(hdr2->rand_s, hdr1->rand_s, EAP_PSK_RAND_LEN);
|
||||
os_memcpy(hdr2->rand_p, data->rand_p, EAP_PSK_RAND_LEN);
|
||||
wpabuf_put_data(resp, data->id_p, data->id_p_len);
|
||||
/* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */
|
||||
buflen = data->id_p_len + data->id_s_len + 2 * EAP_PSK_RAND_LEN;
|
||||
buf = os_malloc(buflen);
|
||||
if (buf == NULL) {
|
||||
wpabuf_free(resp);
|
||||
return NULL;
|
||||
}
|
||||
os_memcpy(buf, data->id_p, data->id_p_len);
|
||||
pos = buf + data->id_p_len;
|
||||
os_memcpy(pos, data->id_s, data->id_s_len);
|
||||
pos += data->id_s_len;
|
||||
os_memcpy(pos, hdr1->rand_s, EAP_PSK_RAND_LEN);
|
||||
pos += EAP_PSK_RAND_LEN;
|
||||
os_memcpy(pos, data->rand_p, EAP_PSK_RAND_LEN);
|
||||
if (omac1_aes_128(data->ak, buf, buflen, hdr2->mac_p)) {
|
||||
os_free(buf);
|
||||
wpabuf_free(resp);
|
||||
return NULL;
|
||||
}
|
||||
os_free(buf);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_P", hdr2->rand_p,
|
||||
EAP_PSK_RAND_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", hdr2->mac_p, EAP_PSK_MAC_LEN);
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: ID_P",
|
||||
data->id_p, data->id_p_len);
|
||||
|
||||
data->state = PSK_MAC_SENT;
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_psk_process_3(struct eap_psk_data *data,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
const struct eap_psk_hdr_3 *hdr3;
|
||||
struct eap_psk_hdr_4 *hdr4;
|
||||
struct wpabuf *resp;
|
||||
u8 *buf, *rpchannel, nonce[16], *decrypted;
|
||||
const u8 *pchannel, *tag, *msg;
|
||||
u8 mac[EAP_PSK_MAC_LEN];
|
||||
size_t buflen, left, data_len, len, plen;
|
||||
int failed = 0;
|
||||
const u8 *pos;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-PSK: in MAC_SENT state");
|
||||
|
||||
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK,
|
||||
reqData, &len);
|
||||
hdr3 = (const struct eap_psk_hdr_3 *) pos;
|
||||
if (pos == NULL || len < sizeof(*hdr3)) {
|
||||
wpa_printf(MSG_INFO, "EAP-PSK: Invalid third message "
|
||||
"length (%lu; expected %lu or more)",
|
||||
(unsigned long) len,
|
||||
(unsigned long) sizeof(*hdr3));
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
left = len - sizeof(*hdr3);
|
||||
pchannel = (const u8 *) (hdr3 + 1);
|
||||
wpa_printf(MSG_DEBUG, "EAP-PSK: Flags=0x%x", hdr3->flags);
|
||||
if (EAP_PSK_FLAGS_GET_T(hdr3->flags) != 2) {
|
||||
wpa_printf(MSG_INFO, "EAP-PSK: Unexpected T=%d (expected 2)",
|
||||
EAP_PSK_FLAGS_GET_T(hdr3->flags));
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
return NULL;
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_S", hdr3->rand_s,
|
||||
EAP_PSK_RAND_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_S", hdr3->mac_s, EAP_PSK_MAC_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL", pchannel, left);
|
||||
|
||||
if (left < 4 + 16 + 1) {
|
||||
wpa_printf(MSG_INFO, "EAP-PSK: Too short PCHANNEL data in "
|
||||
"third message (len=%lu, expected 21)",
|
||||
(unsigned long) left);
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* MAC_S = OMAC1-AES-128(AK, ID_S||RAND_P) */
|
||||
buflen = data->id_s_len + EAP_PSK_RAND_LEN;
|
||||
buf = os_malloc(buflen);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
os_memcpy(buf, data->id_s, data->id_s_len);
|
||||
os_memcpy(buf + data->id_s_len, data->rand_p, EAP_PSK_RAND_LEN);
|
||||
if (omac1_aes_128(data->ak, buf, buflen, mac)) {
|
||||
os_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
os_free(buf);
|
||||
if (os_memcmp_const(mac, hdr3->mac_s, EAP_PSK_MAC_LEN) != 0) {
|
||||
wpa_printf(MSG_WARNING, "EAP-PSK: Invalid MAC_S in third "
|
||||
"message");
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
return NULL;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "EAP-PSK: MAC_S verified successfully");
|
||||
|
||||
if (eap_psk_derive_keys(data->kdk, data->rand_p, data->tek,
|
||||
data->msk, data->emsk)) {
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
return NULL;
|
||||
}
|
||||
wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: TEK", data->tek, EAP_PSK_TEK_LEN);
|
||||
wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: MSK", data->msk, EAP_MSK_LEN);
|
||||
wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: EMSK", data->emsk, EAP_EMSK_LEN);
|
||||
|
||||
os_memset(nonce, 0, 12);
|
||||
os_memcpy(nonce + 12, pchannel, 4);
|
||||
pchannel += 4;
|
||||
left -= 4;
|
||||
|
||||
tag = pchannel;
|
||||
pchannel += 16;
|
||||
left -= 16;
|
||||
|
||||
msg = pchannel;
|
||||
|
||||
wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - nonce",
|
||||
nonce, sizeof(nonce));
|
||||
wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - hdr",
|
||||
wpabuf_head(reqData), 5);
|
||||
wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - cipher msg", msg, left);
|
||||
|
||||
decrypted = os_malloc(left);
|
||||
if (decrypted == NULL) {
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
return NULL;
|
||||
}
|
||||
os_memcpy(decrypted, msg, left);
|
||||
|
||||
if (aes_128_eax_decrypt(data->tek, nonce, sizeof(nonce),
|
||||
wpabuf_head(reqData),
|
||||
sizeof(struct eap_hdr) + 1 +
|
||||
sizeof(*hdr3) - EAP_PSK_MAC_LEN, decrypted,
|
||||
left, tag)) {
|
||||
wpa_printf(MSG_WARNING, "EAP-PSK: PCHANNEL decryption failed");
|
||||
os_free(decrypted);
|
||||
return NULL;
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-PSK: Decrypted PCHANNEL message",
|
||||
decrypted, left);
|
||||
|
||||
/* Verify R flag */
|
||||
switch (decrypted[0] >> 6) {
|
||||
case EAP_PSK_R_FLAG_CONT:
|
||||
wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - CONT - unsupported");
|
||||
failed = 1;
|
||||
break;
|
||||
case EAP_PSK_R_FLAG_DONE_SUCCESS:
|
||||
wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_SUCCESS");
|
||||
break;
|
||||
case EAP_PSK_R_FLAG_DONE_FAILURE:
|
||||
wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_FAILURE");
|
||||
wpa_printf(MSG_INFO, "EAP-PSK: Authentication server rejected "
|
||||
"authentication");
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
data_len = 1;
|
||||
if ((decrypted[0] & EAP_PSK_E_FLAG) && left > 1)
|
||||
data_len++;
|
||||
plen = sizeof(*hdr4) + 4 + 16 + data_len;
|
||||
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK, plen,
|
||||
EAP_CODE_RESPONSE, eap_get_id(reqData));
|
||||
if (resp == NULL) {
|
||||
os_free(decrypted);
|
||||
return NULL;
|
||||
}
|
||||
hdr4 = wpabuf_put(resp, sizeof(*hdr4));
|
||||
hdr4->flags = EAP_PSK_FLAGS_SET_T(3); /* T=3 */
|
||||
os_memcpy(hdr4->rand_s, hdr3->rand_s, EAP_PSK_RAND_LEN);
|
||||
rpchannel = wpabuf_put(resp, 4 + 16 + data_len);
|
||||
|
||||
/* nonce++ */
|
||||
inc_byte_array(nonce, sizeof(nonce));
|
||||
os_memcpy(rpchannel, nonce + 12, 4);
|
||||
|
||||
if (decrypted[0] & EAP_PSK_E_FLAG) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-PSK: Unsupported E (Ext) flag");
|
||||
failed = 1;
|
||||
rpchannel[4 + 16] = (EAP_PSK_R_FLAG_DONE_FAILURE << 6) |
|
||||
EAP_PSK_E_FLAG;
|
||||
if (left > 1) {
|
||||
/* Add empty EXT_Payload with same EXT_Type */
|
||||
rpchannel[4 + 16 + 1] = decrypted[1];
|
||||
}
|
||||
} else if (failed)
|
||||
rpchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_FAILURE << 6;
|
||||
else
|
||||
rpchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_SUCCESS << 6;
|
||||
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-PSK: reply message (plaintext)",
|
||||
rpchannel + 4 + 16, data_len);
|
||||
if (aes_128_eax_encrypt(data->tek, nonce, sizeof(nonce),
|
||||
wpabuf_head(resp),
|
||||
sizeof(struct eap_hdr) + 1 + sizeof(*hdr4),
|
||||
rpchannel + 4 + 16, data_len, rpchannel + 4)) {
|
||||
os_free(decrypted);
|
||||
wpabuf_free(resp);
|
||||
return NULL;
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-PSK: reply message (PCHANNEL)",
|
||||
rpchannel, 4 + 16 + data_len);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-PSK: Completed %ssuccessfully",
|
||||
failed ? "un" : "");
|
||||
data->state = PSK_DONE;
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = failed ? DECISION_FAIL : DECISION_UNCOND_SUCC;
|
||||
|
||||
os_free(decrypted);
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_psk_process(struct eap_sm *sm, void *priv,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
struct eap_psk_data *data = priv;
|
||||
const u8 *pos;
|
||||
struct wpabuf *resp = NULL;
|
||||
size_t len;
|
||||
|
||||
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, reqData, &len);
|
||||
if (pos == NULL) {
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->ignore = FALSE;
|
||||
ret->methodState = METHOD_MAY_CONT;
|
||||
ret->decision = DECISION_FAIL;
|
||||
ret->allowNotifications = TRUE;
|
||||
|
||||
switch (data->state) {
|
||||
case PSK_INIT:
|
||||
resp = eap_psk_process_1(data, ret, reqData);
|
||||
break;
|
||||
case PSK_MAC_SENT:
|
||||
resp = eap_psk_process_3(data, ret, reqData);
|
||||
break;
|
||||
case PSK_DONE:
|
||||
wpa_printf(MSG_DEBUG, "EAP-PSK: in DONE state - ignore "
|
||||
"unexpected message");
|
||||
ret->ignore = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ret->methodState == METHOD_DONE) {
|
||||
ret->allowNotifications = FALSE;
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
static Boolean eap_psk_isKeyAvailable(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_psk_data *data = priv;
|
||||
return data->state == PSK_DONE;
|
||||
}
|
||||
|
||||
|
||||
static u8 * eap_psk_getKey(struct eap_sm *sm, void *priv, size_t *len)
|
||||
{
|
||||
struct eap_psk_data *data = priv;
|
||||
u8 *key;
|
||||
|
||||
if (data->state != PSK_DONE)
|
||||
return NULL;
|
||||
|
||||
key = os_malloc(EAP_MSK_LEN);
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
*len = EAP_MSK_LEN;
|
||||
os_memcpy(key, data->msk, EAP_MSK_LEN);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
static u8 * eap_psk_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||
{
|
||||
struct eap_psk_data *data = priv;
|
||||
u8 *id;
|
||||
|
||||
if (data->state != PSK_DONE)
|
||||
return NULL;
|
||||
|
||||
*len = 1 + 2 * EAP_PSK_RAND_LEN;
|
||||
id = os_malloc(*len);
|
||||
if (id == NULL)
|
||||
return NULL;
|
||||
|
||||
id[0] = EAP_TYPE_PSK;
|
||||
os_memcpy(id + 1, data->rand_p, EAP_PSK_RAND_LEN);
|
||||
os_memcpy(id + 1 + EAP_PSK_RAND_LEN, data->rand_s, EAP_PSK_RAND_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-PSK: Derived Session-Id", id, *len);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
static u8 * eap_psk_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
|
||||
{
|
||||
struct eap_psk_data *data = priv;
|
||||
u8 *key;
|
||||
|
||||
if (data->state != PSK_DONE)
|
||||
return NULL;
|
||||
|
||||
key = os_malloc(EAP_EMSK_LEN);
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
*len = EAP_EMSK_LEN;
|
||||
os_memcpy(key, data->emsk, EAP_EMSK_LEN);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
int eap_peer_psk_register(void)
|
||||
{
|
||||
struct eap_method *eap;
|
||||
int ret;
|
||||
|
||||
eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
|
||||
EAP_VENDOR_IETF, EAP_TYPE_PSK, "PSK");
|
||||
if (eap == NULL)
|
||||
return -1;
|
||||
|
||||
eap->init = eap_psk_init;
|
||||
eap->deinit = eap_psk_deinit;
|
||||
eap->process = eap_psk_process;
|
||||
eap->isKeyAvailable = eap_psk_isKeyAvailable;
|
||||
eap->getKey = eap_psk_getKey;
|
||||
eap->getSessionId = eap_psk_get_session_id;
|
||||
eap->get_emsk = eap_psk_get_emsk;
|
||||
|
||||
ret = eap_peer_method_register(eap);
|
||||
if (ret)
|
||||
eap_peer_method_free(eap);
|
||||
return ret;
|
||||
}
|
441
freebsd/contrib/wpa/src/eap_peer/eap_tls.c
Normal file
441
freebsd/contrib/wpa/src/eap_peer/eap_tls.c
Normal file
@ -0,0 +1,441 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* EAP peer method: EAP-TLS (RFC 2716)
|
||||
* Copyright (c) 2004-2008, 2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "crypto/tls.h"
|
||||
#include "eap_i.h"
|
||||
#include "eap_tls_common.h"
|
||||
#include "eap_config.h"
|
||||
|
||||
|
||||
static void eap_tls_deinit(struct eap_sm *sm, void *priv);
|
||||
|
||||
|
||||
struct eap_tls_data {
|
||||
struct eap_ssl_data ssl;
|
||||
u8 *key_data;
|
||||
u8 *session_id;
|
||||
size_t id_len;
|
||||
void *ssl_ctx;
|
||||
u8 eap_type;
|
||||
};
|
||||
|
||||
|
||||
static void * eap_tls_init(struct eap_sm *sm)
|
||||
{
|
||||
struct eap_tls_data *data;
|
||||
struct eap_peer_config *config = eap_get_config(sm);
|
||||
if (config == NULL ||
|
||||
((sm->init_phase2 ? config->private_key2 : config->private_key)
|
||||
== NULL &&
|
||||
(sm->init_phase2 ? config->engine2 : config->engine) == 0)) {
|
||||
wpa_printf(MSG_INFO, "EAP-TLS: Private key not configured");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = os_zalloc(sizeof(*data));
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
|
||||
data->ssl_ctx = sm->init_phase2 && sm->ssl_ctx2 ? sm->ssl_ctx2 :
|
||||
sm->ssl_ctx;
|
||||
|
||||
if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_TLS)) {
|
||||
wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL.");
|
||||
eap_tls_deinit(sm, data);
|
||||
if (config->engine) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting Smartcard "
|
||||
"PIN");
|
||||
eap_sm_request_pin(sm);
|
||||
sm->ignore = TRUE;
|
||||
} else if (config->private_key && !config->private_key_passwd)
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting private "
|
||||
"key passphrase");
|
||||
eap_sm_request_passphrase(sm);
|
||||
sm->ignore = TRUE;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->eap_type = EAP_TYPE_TLS;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
#ifdef EAP_UNAUTH_TLS
|
||||
static void * eap_unauth_tls_init(struct eap_sm *sm)
|
||||
{
|
||||
struct eap_tls_data *data;
|
||||
struct eap_peer_config *config = eap_get_config(sm);
|
||||
|
||||
data = os_zalloc(sizeof(*data));
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
|
||||
data->ssl_ctx = sm->init_phase2 && sm->ssl_ctx2 ? sm->ssl_ctx2 :
|
||||
sm->ssl_ctx;
|
||||
|
||||
if (eap_peer_tls_ssl_init(sm, &data->ssl, config,
|
||||
EAP_UNAUTH_TLS_TYPE)) {
|
||||
wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL.");
|
||||
eap_tls_deinit(sm, data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->eap_type = EAP_UNAUTH_TLS_TYPE;
|
||||
|
||||
return data;
|
||||
}
|
||||
#endif /* EAP_UNAUTH_TLS */
|
||||
|
||||
|
||||
#ifdef CONFIG_HS20
|
||||
static void * eap_wfa_unauth_tls_init(struct eap_sm *sm)
|
||||
{
|
||||
struct eap_tls_data *data;
|
||||
struct eap_peer_config *config = eap_get_config(sm);
|
||||
|
||||
data = os_zalloc(sizeof(*data));
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
|
||||
data->ssl_ctx = sm->init_phase2 && sm->ssl_ctx2 ? sm->ssl_ctx2 :
|
||||
sm->ssl_ctx;
|
||||
|
||||
if (eap_peer_tls_ssl_init(sm, &data->ssl, config,
|
||||
EAP_WFA_UNAUTH_TLS_TYPE)) {
|
||||
wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL.");
|
||||
eap_tls_deinit(sm, data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->eap_type = EAP_WFA_UNAUTH_TLS_TYPE;
|
||||
|
||||
return data;
|
||||
}
|
||||
#endif /* CONFIG_HS20 */
|
||||
|
||||
|
||||
static void eap_tls_free_key(struct eap_tls_data *data)
|
||||
{
|
||||
if (data->key_data) {
|
||||
bin_clear_free(data->key_data, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
|
||||
data->key_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void eap_tls_deinit(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_tls_data *data = priv;
|
||||
if (data == NULL)
|
||||
return;
|
||||
eap_peer_tls_ssl_deinit(sm, &data->ssl);
|
||||
eap_tls_free_key(data);
|
||||
os_free(data->session_id);
|
||||
os_free(data);
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_tls_failure(struct eap_sm *sm,
|
||||
struct eap_tls_data *data,
|
||||
struct eap_method_ret *ret, int res,
|
||||
struct wpabuf *resp, u8 id)
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "EAP-TLS: TLS processing failed");
|
||||
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
|
||||
if (resp) {
|
||||
/*
|
||||
* This is likely an alert message, so send it instead of just
|
||||
* ACKing the error.
|
||||
*/
|
||||
return resp;
|
||||
}
|
||||
|
||||
return eap_peer_tls_build_ack(id, data->eap_type, 0);
|
||||
}
|
||||
|
||||
|
||||
static void eap_tls_success(struct eap_sm *sm, struct eap_tls_data *data,
|
||||
struct eap_method_ret *ret)
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "EAP-TLS: Done");
|
||||
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_UNCOND_SUCC;
|
||||
|
||||
eap_tls_free_key(data);
|
||||
data->key_data = eap_peer_tls_derive_key(sm, &data->ssl,
|
||||
"client EAP encryption",
|
||||
EAP_TLS_KEY_LEN +
|
||||
EAP_EMSK_LEN);
|
||||
if (data->key_data) {
|
||||
wpa_hexdump_key(MSG_DEBUG, "EAP-TLS: Derived key",
|
||||
data->key_data, EAP_TLS_KEY_LEN);
|
||||
wpa_hexdump_key(MSG_DEBUG, "EAP-TLS: Derived EMSK",
|
||||
data->key_data + EAP_TLS_KEY_LEN,
|
||||
EAP_EMSK_LEN);
|
||||
} else {
|
||||
wpa_printf(MSG_INFO, "EAP-TLS: Failed to derive key");
|
||||
}
|
||||
|
||||
os_free(data->session_id);
|
||||
data->session_id = eap_peer_tls_derive_session_id(sm, &data->ssl,
|
||||
EAP_TYPE_TLS,
|
||||
&data->id_len);
|
||||
if (data->session_id) {
|
||||
wpa_hexdump(MSG_DEBUG, "EAP-TLS: Derived Session-Id",
|
||||
data->session_id, data->id_len);
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "EAP-TLS: Failed to derive Session-Id");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData)
|
||||
{
|
||||
size_t left;
|
||||
int res;
|
||||
struct wpabuf *resp;
|
||||
u8 flags, id;
|
||||
const u8 *pos;
|
||||
struct eap_tls_data *data = priv;
|
||||
struct wpabuf msg;
|
||||
|
||||
pos = eap_peer_tls_process_init(sm, &data->ssl, data->eap_type, ret,
|
||||
reqData, &left, &flags);
|
||||
if (pos == NULL)
|
||||
return NULL;
|
||||
id = eap_get_id(reqData);
|
||||
|
||||
if (flags & EAP_TLS_FLAGS_START) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-TLS: Start");
|
||||
left = 0; /* make sure that this frame is empty, even though it
|
||||
* should always be, anyway */
|
||||
}
|
||||
|
||||
resp = NULL;
|
||||
wpabuf_set(&msg, pos, left);
|
||||
res = eap_peer_tls_process_helper(sm, &data->ssl, data->eap_type, 0,
|
||||
id, &msg, &resp);
|
||||
|
||||
if (res < 0) {
|
||||
return eap_tls_failure(sm, data, ret, res, resp, id);
|
||||
}
|
||||
|
||||
if (tls_connection_established(data->ssl_ctx, data->ssl.conn))
|
||||
eap_tls_success(sm, data, ret);
|
||||
|
||||
if (res == 1) {
|
||||
wpabuf_free(resp);
|
||||
return eap_peer_tls_build_ack(id, data->eap_type, 0);
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
static Boolean eap_tls_has_reauth_data(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_tls_data *data = priv;
|
||||
return tls_connection_established(data->ssl_ctx, data->ssl.conn);
|
||||
}
|
||||
|
||||
|
||||
static void eap_tls_deinit_for_reauth(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void * eap_tls_init_for_reauth(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_tls_data *data = priv;
|
||||
eap_tls_free_key(data);
|
||||
os_free(data->session_id);
|
||||
data->session_id = NULL;
|
||||
if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
|
||||
os_free(data);
|
||||
return NULL;
|
||||
}
|
||||
return priv;
|
||||
}
|
||||
|
||||
|
||||
static int eap_tls_get_status(struct eap_sm *sm, void *priv, char *buf,
|
||||
size_t buflen, int verbose)
|
||||
{
|
||||
struct eap_tls_data *data = priv;
|
||||
return eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);
|
||||
}
|
||||
|
||||
|
||||
static Boolean eap_tls_isKeyAvailable(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_tls_data *data = priv;
|
||||
return data->key_data != NULL;
|
||||
}
|
||||
|
||||
|
||||
static u8 * eap_tls_getKey(struct eap_sm *sm, void *priv, size_t *len)
|
||||
{
|
||||
struct eap_tls_data *data = priv;
|
||||
u8 *key;
|
||||
|
||||
if (data->key_data == NULL)
|
||||
return NULL;
|
||||
|
||||
key = os_malloc(EAP_TLS_KEY_LEN);
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
*len = EAP_TLS_KEY_LEN;
|
||||
os_memcpy(key, data->key_data, EAP_TLS_KEY_LEN);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
static u8 * eap_tls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
|
||||
{
|
||||
struct eap_tls_data *data = priv;
|
||||
u8 *key;
|
||||
|
||||
if (data->key_data == NULL)
|
||||
return NULL;
|
||||
|
||||
key = os_malloc(EAP_EMSK_LEN);
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
*len = EAP_EMSK_LEN;
|
||||
os_memcpy(key, data->key_data + EAP_TLS_KEY_LEN, EAP_EMSK_LEN);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
static u8 * eap_tls_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||
{
|
||||
struct eap_tls_data *data = priv;
|
||||
u8 *id;
|
||||
|
||||
if (data->session_id == NULL)
|
||||
return NULL;
|
||||
|
||||
id = os_malloc(data->id_len);
|
||||
if (id == NULL)
|
||||
return NULL;
|
||||
|
||||
*len = data->id_len;
|
||||
os_memcpy(id, data->session_id, data->id_len);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
int eap_peer_tls_register(void)
|
||||
{
|
||||
struct eap_method *eap;
|
||||
int ret;
|
||||
|
||||
eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
|
||||
EAP_VENDOR_IETF, EAP_TYPE_TLS, "TLS");
|
||||
if (eap == NULL)
|
||||
return -1;
|
||||
|
||||
eap->init = eap_tls_init;
|
||||
eap->deinit = eap_tls_deinit;
|
||||
eap->process = eap_tls_process;
|
||||
eap->isKeyAvailable = eap_tls_isKeyAvailable;
|
||||
eap->getKey = eap_tls_getKey;
|
||||
eap->getSessionId = eap_tls_get_session_id;
|
||||
eap->get_status = eap_tls_get_status;
|
||||
eap->has_reauth_data = eap_tls_has_reauth_data;
|
||||
eap->deinit_for_reauth = eap_tls_deinit_for_reauth;
|
||||
eap->init_for_reauth = eap_tls_init_for_reauth;
|
||||
eap->get_emsk = eap_tls_get_emsk;
|
||||
|
||||
ret = eap_peer_method_register(eap);
|
||||
if (ret)
|
||||
eap_peer_method_free(eap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef EAP_UNAUTH_TLS
|
||||
int eap_peer_unauth_tls_register(void)
|
||||
{
|
||||
struct eap_method *eap;
|
||||
int ret;
|
||||
|
||||
eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
|
||||
EAP_VENDOR_UNAUTH_TLS,
|
||||
EAP_VENDOR_TYPE_UNAUTH_TLS, "UNAUTH-TLS");
|
||||
if (eap == NULL)
|
||||
return -1;
|
||||
|
||||
eap->init = eap_unauth_tls_init;
|
||||
eap->deinit = eap_tls_deinit;
|
||||
eap->process = eap_tls_process;
|
||||
eap->isKeyAvailable = eap_tls_isKeyAvailable;
|
||||
eap->getKey = eap_tls_getKey;
|
||||
eap->get_status = eap_tls_get_status;
|
||||
eap->has_reauth_data = eap_tls_has_reauth_data;
|
||||
eap->deinit_for_reauth = eap_tls_deinit_for_reauth;
|
||||
eap->init_for_reauth = eap_tls_init_for_reauth;
|
||||
eap->get_emsk = eap_tls_get_emsk;
|
||||
|
||||
ret = eap_peer_method_register(eap);
|
||||
if (ret)
|
||||
eap_peer_method_free(eap);
|
||||
return ret;
|
||||
}
|
||||
#endif /* EAP_UNAUTH_TLS */
|
||||
|
||||
|
||||
#ifdef CONFIG_HS20
|
||||
int eap_peer_wfa_unauth_tls_register(void)
|
||||
{
|
||||
struct eap_method *eap;
|
||||
int ret;
|
||||
|
||||
eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
|
||||
EAP_VENDOR_WFA_NEW,
|
||||
EAP_VENDOR_WFA_UNAUTH_TLS,
|
||||
"WFA-UNAUTH-TLS");
|
||||
if (eap == NULL)
|
||||
return -1;
|
||||
|
||||
eap->init = eap_wfa_unauth_tls_init;
|
||||
eap->deinit = eap_tls_deinit;
|
||||
eap->process = eap_tls_process;
|
||||
eap->isKeyAvailable = eap_tls_isKeyAvailable;
|
||||
eap->getKey = eap_tls_getKey;
|
||||
eap->get_status = eap_tls_get_status;
|
||||
eap->has_reauth_data = eap_tls_has_reauth_data;
|
||||
eap->deinit_for_reauth = eap_tls_deinit_for_reauth;
|
||||
eap->init_for_reauth = eap_tls_init_for_reauth;
|
||||
eap->get_emsk = eap_tls_get_emsk;
|
||||
|
||||
ret = eap_peer_method_register(eap);
|
||||
if (ret)
|
||||
eap_peer_method_free(eap);
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_HS20 */
|
1110
freebsd/contrib/wpa/src/eap_peer/eap_tls_common.c
Normal file
1110
freebsd/contrib/wpa/src/eap_peer/eap_tls_common.c
Normal file
File diff suppressed because it is too large
Load Diff
132
freebsd/contrib/wpa/src/eap_peer/eap_tls_common.h
Normal file
132
freebsd/contrib/wpa/src/eap_peer/eap_tls_common.h
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* EAP peer: EAP-TLS/PEAP/TTLS/FAST common functions
|
||||
* Copyright (c) 2004-2009, 2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_TLS_COMMON_H
|
||||
#define EAP_TLS_COMMON_H
|
||||
|
||||
/**
|
||||
* struct eap_ssl_data - TLS data for EAP methods
|
||||
*/
|
||||
struct eap_ssl_data {
|
||||
/**
|
||||
* conn - TLS connection context data from tls_connection_init()
|
||||
*/
|
||||
struct tls_connection *conn;
|
||||
|
||||
/**
|
||||
* tls_out - TLS message to be sent out in fragments
|
||||
*/
|
||||
struct wpabuf *tls_out;
|
||||
|
||||
/**
|
||||
* tls_out_pos - The current position in the outgoing TLS message
|
||||
*/
|
||||
size_t tls_out_pos;
|
||||
|
||||
/**
|
||||
* tls_out_limit - Maximum fragment size for outgoing TLS messages
|
||||
*/
|
||||
size_t tls_out_limit;
|
||||
|
||||
/**
|
||||
* tls_in - Received TLS message buffer for re-assembly
|
||||
*/
|
||||
struct wpabuf *tls_in;
|
||||
|
||||
/**
|
||||
* tls_in_left - Number of remaining bytes in the incoming TLS message
|
||||
*/
|
||||
size_t tls_in_left;
|
||||
|
||||
/**
|
||||
* tls_in_total - Total number of bytes in the incoming TLS message
|
||||
*/
|
||||
size_t tls_in_total;
|
||||
|
||||
/**
|
||||
* phase2 - Whether this TLS connection is used in EAP phase 2 (tunnel)
|
||||
*/
|
||||
int phase2;
|
||||
|
||||
/**
|
||||
* include_tls_length - Whether the TLS length field is included even
|
||||
* if the TLS data is not fragmented
|
||||
*/
|
||||
int include_tls_length;
|
||||
|
||||
/**
|
||||
* eap - EAP state machine allocated with eap_peer_sm_init()
|
||||
*/
|
||||
struct eap_sm *eap;
|
||||
|
||||
/**
|
||||
* ssl_ctx - TLS library context to use for the connection
|
||||
*/
|
||||
void *ssl_ctx;
|
||||
|
||||
/**
|
||||
* eap_type - EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST)
|
||||
*/
|
||||
u8 eap_type;
|
||||
};
|
||||
|
||||
|
||||
/* EAP TLS Flags */
|
||||
#define EAP_TLS_FLAGS_LENGTH_INCLUDED 0x80
|
||||
#define EAP_TLS_FLAGS_MORE_FRAGMENTS 0x40
|
||||
#define EAP_TLS_FLAGS_START 0x20
|
||||
#define EAP_TLS_VERSION_MASK 0x07
|
||||
|
||||
/* could be up to 128 bytes, but only the first 64 bytes are used */
|
||||
#define EAP_TLS_KEY_LEN 64
|
||||
|
||||
/* dummy type used as a flag for UNAUTH-TLS */
|
||||
#define EAP_UNAUTH_TLS_TYPE 255
|
||||
#define EAP_WFA_UNAUTH_TLS_TYPE 254
|
||||
|
||||
|
||||
int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
|
||||
struct eap_peer_config *config, u8 eap_type);
|
||||
void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data);
|
||||
u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
|
||||
const char *label, size_t len);
|
||||
u8 * eap_peer_tls_derive_session_id(struct eap_sm *sm,
|
||||
struct eap_ssl_data *data, u8 eap_type,
|
||||
size_t *len);
|
||||
int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
|
||||
EapType eap_type, int peap_version,
|
||||
u8 id, const struct wpabuf *in_data,
|
||||
struct wpabuf **out_data);
|
||||
struct wpabuf * eap_peer_tls_build_ack(u8 id, EapType eap_type,
|
||||
int peap_version);
|
||||
int eap_peer_tls_reauth_init(struct eap_sm *sm, struct eap_ssl_data *data);
|
||||
int eap_peer_tls_status(struct eap_sm *sm, struct eap_ssl_data *data,
|
||||
char *buf, size_t buflen, int verbose);
|
||||
const u8 * eap_peer_tls_process_init(struct eap_sm *sm,
|
||||
struct eap_ssl_data *data,
|
||||
EapType eap_type,
|
||||
struct eap_method_ret *ret,
|
||||
const struct wpabuf *reqData,
|
||||
size_t *len, u8 *flags);
|
||||
void eap_peer_tls_reset_input(struct eap_ssl_data *data);
|
||||
void eap_peer_tls_reset_output(struct eap_ssl_data *data);
|
||||
int eap_peer_tls_decrypt(struct eap_sm *sm, struct eap_ssl_data *data,
|
||||
const struct wpabuf *in_data,
|
||||
struct wpabuf **in_decrypted);
|
||||
int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data,
|
||||
EapType eap_type, int peap_version, u8 id,
|
||||
const struct wpabuf *in_data,
|
||||
struct wpabuf **out_data);
|
||||
int eap_peer_select_phase2_methods(struct eap_peer_config *config,
|
||||
const char *prefix,
|
||||
struct eap_method_type **types,
|
||||
size_t *num_types);
|
||||
int eap_peer_tls_phase2_nak(struct eap_method_type *types, size_t num_types,
|
||||
struct eap_hdr *hdr, struct wpabuf **resp);
|
||||
|
||||
#endif /* EAP_TLS_COMMON_H */
|
1723
freebsd/contrib/wpa/src/eap_peer/eap_ttls.c
Normal file
1723
freebsd/contrib/wpa/src/eap_peer/eap_ttls.c
Normal file
File diff suppressed because it is too large
Load Diff
126
freebsd/contrib/wpa/src/eap_peer/mschapv2.c
Normal file
126
freebsd/contrib/wpa/src/eap_peer/mschapv2.c
Normal file
@ -0,0 +1,126 @@
|
||||
#include <machine/rtems-bsd-user-space.h>
|
||||
|
||||
/*
|
||||
* MSCHAPV2 (RFC 2759)
|
||||
* Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "crypto/ms_funcs.h"
|
||||
#include "mschapv2.h"
|
||||
|
||||
const u8 * mschapv2_remove_domain(const u8 *username, size_t *len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* MSCHAPv2 does not include optional domain name in the
|
||||
* challenge-response calculation, so remove domain prefix
|
||||
* (if present).
|
||||
*/
|
||||
|
||||
for (i = 0; i < *len; i++) {
|
||||
if (username[i] == '\\') {
|
||||
*len -= i + 1;
|
||||
return username + i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return username;
|
||||
}
|
||||
|
||||
|
||||
int mschapv2_derive_response(const u8 *identity, size_t identity_len,
|
||||
const u8 *password, size_t password_len,
|
||||
int pwhash,
|
||||
const u8 *auth_challenge,
|
||||
const u8 *peer_challenge,
|
||||
u8 *nt_response, u8 *auth_response,
|
||||
u8 *master_key)
|
||||
{
|
||||
const u8 *username;
|
||||
size_t username_len;
|
||||
u8 password_hash[16], password_hash_hash[16];
|
||||
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Identity",
|
||||
identity, identity_len);
|
||||
username_len = identity_len;
|
||||
username = mschapv2_remove_domain(identity, &username_len);
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Username",
|
||||
username, username_len);
|
||||
|
||||
wpa_hexdump(MSG_DEBUG, "MSCHAPV2: auth_challenge",
|
||||
auth_challenge, MSCHAPV2_CHAL_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "MSCHAPV2: peer_challenge",
|
||||
peer_challenge, MSCHAPV2_CHAL_LEN);
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: username",
|
||||
username, username_len);
|
||||
/* Authenticator response is not really needed yet, but calculate it
|
||||
* here so that challenges need not be saved. */
|
||||
if (pwhash) {
|
||||
wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: password hash",
|
||||
password, password_len);
|
||||
if (generate_nt_response_pwhash(auth_challenge, peer_challenge,
|
||||
username, username_len,
|
||||
password, nt_response) ||
|
||||
generate_authenticator_response_pwhash(
|
||||
password, peer_challenge, auth_challenge,
|
||||
username, username_len, nt_response,
|
||||
auth_response))
|
||||
return -1;
|
||||
} else {
|
||||
wpa_hexdump_ascii_key(MSG_DEBUG, "MSCHAPV2: password",
|
||||
password, password_len);
|
||||
if (generate_nt_response(auth_challenge, peer_challenge,
|
||||
username, username_len,
|
||||
password, password_len,
|
||||
nt_response) ||
|
||||
generate_authenticator_response(password, password_len,
|
||||
peer_challenge,
|
||||
auth_challenge,
|
||||
username, username_len,
|
||||
nt_response,
|
||||
auth_response))
|
||||
return -1;
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "MSCHAPV2: NT Response",
|
||||
nt_response, MSCHAPV2_NT_RESPONSE_LEN);
|
||||
wpa_hexdump(MSG_DEBUG, "MSCHAPV2: Auth Response",
|
||||
auth_response, MSCHAPV2_AUTH_RESPONSE_LEN);
|
||||
|
||||
/* Generate master_key here since we have the needed data available. */
|
||||
if (pwhash) {
|
||||
if (hash_nt_password_hash(password, password_hash_hash))
|
||||
return -1;
|
||||
} else {
|
||||
if (nt_password_hash(password, password_len, password_hash) ||
|
||||
hash_nt_password_hash(password_hash, password_hash_hash))
|
||||
return -1;
|
||||
}
|
||||
if (get_master_key(password_hash_hash, nt_response, master_key))
|
||||
return -1;
|
||||
wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: Master Key",
|
||||
master_key, MSCHAPV2_MASTER_KEY_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mschapv2_verify_auth_response(const u8 *auth_response,
|
||||
const u8 *buf, size_t buf_len)
|
||||
{
|
||||
u8 recv_response[MSCHAPV2_AUTH_RESPONSE_LEN];
|
||||
if (buf_len < 2 + 2 * MSCHAPV2_AUTH_RESPONSE_LEN ||
|
||||
buf[0] != 'S' || buf[1] != '=' ||
|
||||
hexstr2bin((char *) (buf + 2), recv_response,
|
||||
MSCHAPV2_AUTH_RESPONSE_LEN) ||
|
||||
os_memcmp_const(auth_response, recv_response,
|
||||
MSCHAPV2_AUTH_RESPONSE_LEN) != 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
28
freebsd/contrib/wpa/src/eap_peer/mschapv2.h
Normal file
28
freebsd/contrib/wpa/src/eap_peer/mschapv2.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* MSCHAPV2 (RFC 2759)
|
||||
* Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef MSCHAPV2_H
|
||||
#define MSCHAPV2_H
|
||||
|
||||
#define MSCHAPV2_CHAL_LEN 16
|
||||
#define MSCHAPV2_NT_RESPONSE_LEN 24
|
||||
#define MSCHAPV2_AUTH_RESPONSE_LEN 20
|
||||
#define MSCHAPV2_MASTER_KEY_LEN 16
|
||||
|
||||
const u8 * mschapv2_remove_domain(const u8 *username, size_t *len);
|
||||
int mschapv2_derive_response(const u8 *username, size_t username_len,
|
||||
const u8 *password, size_t password_len,
|
||||
int pwhash,
|
||||
const u8 *auth_challenge,
|
||||
const u8 *peer_challenge,
|
||||
u8 *nt_response, u8 *auth_response,
|
||||
u8 *master_key);
|
||||
int mschapv2_verify_auth_response(const u8 *auth_response,
|
||||
const u8 *buf, size_t buf_len);
|
||||
|
||||
#endif /* MSCHAPV2_H */
|
36
freebsd/contrib/wpa/src/eap_peer/tncc.h
Normal file
36
freebsd/contrib/wpa/src/eap_peer/tncc.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* EAP-TNC - TNCC (IF-IMC and IF-TNCCS)
|
||||
* Copyright (c) 2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef TNCC_H
|
||||
#define TNCC_H
|
||||
|
||||
struct tncc_data;
|
||||
|
||||
struct tncc_data * tncc_init(void);
|
||||
void tncc_deinit(struct tncc_data *tncc);
|
||||
void tncc_init_connection(struct tncc_data *tncc);
|
||||
size_t tncc_total_send_len(struct tncc_data *tncc);
|
||||
u8 * tncc_copy_send_buf(struct tncc_data *tncc, u8 *pos);
|
||||
char * tncc_if_tnccs_start(struct tncc_data *tncc);
|
||||
char * tncc_if_tnccs_end(void);
|
||||
|
||||
enum tncc_process_res {
|
||||
TNCCS_PROCESS_ERROR = -1,
|
||||
TNCCS_PROCESS_OK_NO_RECOMMENDATION = 0,
|
||||
TNCCS_RECOMMENDATION_ERROR,
|
||||
TNCCS_RECOMMENDATION_ALLOW,
|
||||
TNCCS_RECOMMENDATION_NONE,
|
||||
TNCCS_RECOMMENDATION_ISOLATE
|
||||
};
|
||||
|
||||
enum tncc_process_res tncc_process_if_tnccs(struct tncc_data *tncc,
|
||||
const u8 *msg, size_t len);
|
||||
|
||||
struct wpabuf * tncc_process_soh_request(int ver, const u8 *data, size_t len);
|
||||
|
||||
#endif /* TNCC_H */
|
51
freebsd/contrib/wpa/src/eap_server/eap_methods.h
Normal file
51
freebsd/contrib/wpa/src/eap_server/eap_methods.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* EAP server method registration
|
||||
* Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_SERVER_METHODS_H
|
||||
#define EAP_SERVER_METHODS_H
|
||||
|
||||
#include "eap_common/eap_defs.h"
|
||||
|
||||
const struct eap_method * eap_server_get_eap_method(int vendor,
|
||||
EapType method);
|
||||
struct eap_method * eap_server_method_alloc(int version, int vendor,
|
||||
EapType method, const char *name);
|
||||
void eap_server_method_free(struct eap_method *method);
|
||||
int eap_server_method_register(struct eap_method *method);
|
||||
|
||||
EapType eap_server_get_type(const char *name, int *vendor);
|
||||
void eap_server_unregister_methods(void);
|
||||
const char * eap_server_get_name(int vendor, EapType type);
|
||||
|
||||
/* EAP server method registration calls for statically linked in methods */
|
||||
int eap_server_identity_register(void);
|
||||
int eap_server_md5_register(void);
|
||||
int eap_server_tls_register(void);
|
||||
int eap_server_unauth_tls_register(void);
|
||||
int eap_server_wfa_unauth_tls_register(void);
|
||||
int eap_server_mschapv2_register(void);
|
||||
int eap_server_peap_register(void);
|
||||
int eap_server_tlv_register(void);
|
||||
int eap_server_gtc_register(void);
|
||||
int eap_server_ttls_register(void);
|
||||
int eap_server_sim_register(void);
|
||||
int eap_server_aka_register(void);
|
||||
int eap_server_aka_prime_register(void);
|
||||
int eap_server_pax_register(void);
|
||||
int eap_server_psk_register(void);
|
||||
int eap_server_sake_register(void);
|
||||
int eap_server_gpsk_register(void);
|
||||
int eap_server_vendor_test_register(void);
|
||||
int eap_server_fast_register(void);
|
||||
int eap_server_wsc_register(void);
|
||||
int eap_server_ikev2_register(void);
|
||||
int eap_server_tnc_register(void);
|
||||
int eap_server_pwd_register(void);
|
||||
int eap_server_eke_register(void);
|
||||
|
||||
#endif /* EAP_SERVER_METHODS_H */
|
2152
freebsd/contrib/wpa/src/eapol_supp/eapol_supp_sm.c
Normal file
2152
freebsd/contrib/wpa/src/eapol_supp/eapol_supp_sm.c
Normal file
File diff suppressed because it is too large
Load Diff
443
freebsd/contrib/wpa/src/eapol_supp/eapol_supp_sm.h
Normal file
443
freebsd/contrib/wpa/src/eapol_supp/eapol_supp_sm.h
Normal file
@ -0,0 +1,443 @@
|
||||
/*
|
||||
* EAPOL supplicant state machines
|
||||
* Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAPOL_SUPP_SM_H
|
||||
#define EAPOL_SUPP_SM_H
|
||||
|
||||
#include "common/defs.h"
|
||||
|
||||
typedef enum { Unauthorized, Authorized } PortStatus;
|
||||
typedef enum { Auto, ForceUnauthorized, ForceAuthorized } PortControl;
|
||||
|
||||
/**
|
||||
* struct eapol_config - Per network configuration for EAPOL state machines
|
||||
*/
|
||||
struct eapol_config {
|
||||
/**
|
||||
* accept_802_1x_keys - Accept IEEE 802.1X (non-WPA) EAPOL-Key frames
|
||||
*
|
||||
* This variable should be set to 1 when using EAPOL state machines
|
||||
* with non-WPA security policy to generate dynamic WEP keys. When
|
||||
* using WPA, this should be set to 0 so that WPA state machine can
|
||||
* process the EAPOL-Key frames.
|
||||
*/
|
||||
int accept_802_1x_keys;
|
||||
|
||||
#define EAPOL_REQUIRE_KEY_UNICAST BIT(0)
|
||||
#define EAPOL_REQUIRE_KEY_BROADCAST BIT(1)
|
||||
/**
|
||||
* required_keys - Which EAPOL-Key packets are required
|
||||
*
|
||||
* This variable determines which EAPOL-Key packets are required before
|
||||
* marking connection authenticated. This is a bit field of
|
||||
* EAPOL_REQUIRE_KEY_UNICAST and EAPOL_REQUIRE_KEY_BROADCAST flags.
|
||||
*/
|
||||
int required_keys;
|
||||
|
||||
/**
|
||||
* fast_reauth - Whether fast EAP reauthentication is enabled
|
||||
*/
|
||||
int fast_reauth;
|
||||
|
||||
/**
|
||||
* workaround - Whether EAP workarounds are enabled
|
||||
*/
|
||||
unsigned int workaround;
|
||||
|
||||
/**
|
||||
* eap_disabled - Whether EAP is disabled
|
||||
*/
|
||||
int eap_disabled;
|
||||
|
||||
/**
|
||||
* external_sim - Use external processing for SIM/USIM operations
|
||||
*/
|
||||
int external_sim;
|
||||
|
||||
#define EAPOL_LOCAL_WPS_IN_USE BIT(0)
|
||||
#define EAPOL_PEER_IS_WPS20_AP BIT(1)
|
||||
/**
|
||||
* wps - Whether this connection is used for WPS
|
||||
*/
|
||||
int wps;
|
||||
};
|
||||
|
||||
struct eapol_sm;
|
||||
struct wpa_config_blob;
|
||||
|
||||
enum eapol_supp_result {
|
||||
EAPOL_SUPP_RESULT_FAILURE,
|
||||
EAPOL_SUPP_RESULT_SUCCESS,
|
||||
EAPOL_SUPP_RESULT_EXPECTED_FAILURE
|
||||
};
|
||||
|
||||
/**
|
||||
* struct eapol_ctx - Global (for all networks) EAPOL state machine context
|
||||
*/
|
||||
struct eapol_ctx {
|
||||
/**
|
||||
* ctx - Pointer to arbitrary upper level context
|
||||
*/
|
||||
void *ctx;
|
||||
|
||||
/**
|
||||
* preauth - IEEE 802.11i/RSN pre-authentication
|
||||
*
|
||||
* This EAPOL state machine is used for IEEE 802.11i/RSN
|
||||
* pre-authentication
|
||||
*/
|
||||
int preauth;
|
||||
|
||||
/**
|
||||
* cb - Function to be called when EAPOL negotiation has been completed
|
||||
* @eapol: Pointer to EAPOL state machine data
|
||||
* @result: Whether the authentication was completed successfully
|
||||
* @ctx: Pointer to context data (cb_ctx)
|
||||
*
|
||||
* This optional callback function will be called when the EAPOL
|
||||
* authentication has been completed. This allows the owner of the
|
||||
* EAPOL state machine to process the key and terminate the EAPOL state
|
||||
* machine. Currently, this is used only in RSN pre-authentication.
|
||||
*/
|
||||
void (*cb)(struct eapol_sm *eapol, enum eapol_supp_result result,
|
||||
void *ctx);
|
||||
|
||||
/**
|
||||
* cb_ctx - Callback context for cb()
|
||||
*/
|
||||
void *cb_ctx;
|
||||
|
||||
/**
|
||||
* msg_ctx - Callback context for wpa_msg() calls
|
||||
*/
|
||||
void *msg_ctx;
|
||||
|
||||
/**
|
||||
* scard_ctx - Callback context for PC/SC scard_*() function calls
|
||||
*
|
||||
* This context can be updated with eapol_sm_register_scard_ctx().
|
||||
*/
|
||||
void *scard_ctx;
|
||||
|
||||
/**
|
||||
* eapol_send_ctx - Callback context for eapol_send() calls
|
||||
*/
|
||||
void *eapol_send_ctx;
|
||||
|
||||
/**
|
||||
* eapol_done_cb - Function to be called at successful completion
|
||||
* @ctx: Callback context (ctx)
|
||||
*
|
||||
* This function is called at the successful completion of EAPOL
|
||||
* authentication. If dynamic WEP keys are used, this is called only
|
||||
* after all the expected keys have been received.
|
||||
*/
|
||||
void (*eapol_done_cb)(void *ctx);
|
||||
|
||||
/**
|
||||
* eapol_send - Send EAPOL packets
|
||||
* @ctx: Callback context (eapol_send_ctx)
|
||||
* @type: EAPOL type (IEEE802_1X_TYPE_*)
|
||||
* @buf: Pointer to EAPOL payload
|
||||
* @len: Length of the EAPOL payload
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int (*eapol_send)(void *ctx, int type, const u8 *buf, size_t len);
|
||||
|
||||
/**
|
||||
* set_wep_key - Configure WEP keys
|
||||
* @ctx: Callback context (ctx)
|
||||
* @unicast: Non-zero = unicast, 0 = multicast/broadcast key
|
||||
* @keyidx: Key index (0..3)
|
||||
* @key: WEP key
|
||||
* @keylen: Length of the WEP key
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int (*set_wep_key)(void *ctx, int unicast, int keyidx,
|
||||
const u8 *key, size_t keylen);
|
||||
|
||||
/**
|
||||
* set_config_blob - Set or add a named configuration blob
|
||||
* @ctx: Callback context (ctx)
|
||||
* @blob: New value for the blob
|
||||
*
|
||||
* Adds a new configuration blob or replaces the current value of an
|
||||
* existing blob.
|
||||
*/
|
||||
void (*set_config_blob)(void *ctx, struct wpa_config_blob *blob);
|
||||
|
||||
/**
|
||||
* get_config_blob - Get a named configuration blob
|
||||
* @ctx: Callback context (ctx)
|
||||
* @name: Name of the blob
|
||||
* Returns: Pointer to blob data or %NULL if not found
|
||||
*/
|
||||
const struct wpa_config_blob * (*get_config_blob)(void *ctx,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* aborted_cached - Notify that cached PMK attempt was aborted
|
||||
* @ctx: Callback context (ctx)
|
||||
*/
|
||||
void (*aborted_cached)(void *ctx);
|
||||
|
||||
/**
|
||||
* opensc_engine_path - Path to the OpenSSL engine for opensc
|
||||
*
|
||||
* This is an OpenSSL specific configuration option for loading OpenSC
|
||||
* engine (engine_opensc.so); if %NULL, this engine is not loaded.
|
||||
*/
|
||||
const char *opensc_engine_path;
|
||||
|
||||
/**
|
||||
* pkcs11_engine_path - Path to the OpenSSL engine for PKCS#11
|
||||
*
|
||||
* This is an OpenSSL specific configuration option for loading PKCS#11
|
||||
* engine (engine_pkcs11.so); if %NULL, this engine is not loaded.
|
||||
*/
|
||||
const char *pkcs11_engine_path;
|
||||
|
||||
/**
|
||||
* pkcs11_module_path - Path to the OpenSSL OpenSC/PKCS#11 module
|
||||
*
|
||||
* This is an OpenSSL specific configuration option for configuring
|
||||
* path to OpenSC/PKCS#11 engine (opensc-pkcs11.so); if %NULL, this
|
||||
* module is not loaded.
|
||||
*/
|
||||
const char *pkcs11_module_path;
|
||||
|
||||
/**
|
||||
* openssl_ciphers - OpenSSL cipher string
|
||||
*
|
||||
* This is an OpenSSL specific configuration option for configuring the
|
||||
* default ciphers. If not set, "DEFAULT:!EXP:!LOW" is used as the
|
||||
* default.
|
||||
*/
|
||||
const char *openssl_ciphers;
|
||||
|
||||
/**
|
||||
* wps - WPS context data
|
||||
*
|
||||
* This is only used by EAP-WSC and can be left %NULL if not available.
|
||||
*/
|
||||
struct wps_context *wps;
|
||||
|
||||
/**
|
||||
* eap_param_needed - Notify that EAP parameter is needed
|
||||
* @ctx: Callback context (ctx)
|
||||
* @field: Field indicator (e.g., WPA_CTRL_REQ_EAP_IDENTITY)
|
||||
* @txt: User readable text describing the required parameter
|
||||
*/
|
||||
void (*eap_param_needed)(void *ctx, enum wpa_ctrl_req_type field,
|
||||
const char *txt);
|
||||
|
||||
/**
|
||||
* port_cb - Set port authorized/unauthorized callback (optional)
|
||||
* @ctx: Callback context (ctx)
|
||||
* @authorized: Whether the supplicant port is now in authorized state
|
||||
*/
|
||||
void (*port_cb)(void *ctx, int authorized);
|
||||
|
||||
/**
|
||||
* cert_cb - Notification of a peer certificate
|
||||
* @ctx: Callback context (ctx)
|
||||
* @depth: Depth in certificate chain (0 = server)
|
||||
* @subject: Subject of the peer certificate
|
||||
* @altsubject: Select fields from AltSubject of the peer certificate
|
||||
* @num_altsubject: Number of altsubject values
|
||||
* @cert_hash: SHA-256 hash of the certificate
|
||||
* @cert: Peer certificate
|
||||
*/
|
||||
void (*cert_cb)(void *ctx, int depth, const char *subject,
|
||||
const char *altsubject[], int num_altsubject,
|
||||
const char *cert_hash, const struct wpabuf *cert);
|
||||
|
||||
/**
|
||||
* cert_in_cb - Include server certificates in callback
|
||||
*/
|
||||
int cert_in_cb;
|
||||
|
||||
/**
|
||||
* status_cb - Notification of a change in EAP status
|
||||
* @ctx: Callback context (ctx)
|
||||
* @status: Step in the process of EAP authentication
|
||||
* @parameter: Step-specific parameter, e.g., EAP method name
|
||||
*/
|
||||
void (*status_cb)(void *ctx, const char *status,
|
||||
const char *parameter);
|
||||
|
||||
#ifdef CONFIG_EAP_PROXY
|
||||
/**
|
||||
* eap_proxy_cb - Callback signifying any updates from eap_proxy
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
*/
|
||||
void (*eap_proxy_cb)(void *ctx);
|
||||
#endif /* CONFIG_EAP_PROXY */
|
||||
|
||||
/**
|
||||
* set_anon_id - Set or add anonymous identity
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
* @id: Anonymous identity (e.g., EAP-SIM pseudonym)
|
||||
* @len: Length of anonymous identity in octets
|
||||
*/
|
||||
void (*set_anon_id)(void *ctx, const u8 *id, size_t len);
|
||||
};
|
||||
|
||||
|
||||
struct eap_peer_config;
|
||||
struct ext_password_data;
|
||||
|
||||
#ifdef IEEE8021X_EAPOL
|
||||
struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx);
|
||||
void eapol_sm_deinit(struct eapol_sm *sm);
|
||||
void eapol_sm_step(struct eapol_sm *sm);
|
||||
int eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen,
|
||||
int verbose);
|
||||
int eapol_sm_get_mib(struct eapol_sm *sm, char *buf, size_t buflen);
|
||||
void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, int authPeriod,
|
||||
int startPeriod, int maxStart);
|
||||
int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf,
|
||||
size_t len);
|
||||
void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm);
|
||||
void eapol_sm_notify_portEnabled(struct eapol_sm *sm, Boolean enabled);
|
||||
void eapol_sm_notify_portValid(struct eapol_sm *sm, Boolean valid);
|
||||
void eapol_sm_notify_eap_success(struct eapol_sm *sm, Boolean success);
|
||||
void eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail);
|
||||
void eapol_sm_notify_config(struct eapol_sm *sm,
|
||||
struct eap_peer_config *config,
|
||||
const struct eapol_config *conf);
|
||||
int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len);
|
||||
const u8 * eapol_sm_get_session_id(struct eapol_sm *sm, size_t *len);
|
||||
void eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff);
|
||||
void eapol_sm_notify_cached(struct eapol_sm *sm);
|
||||
void eapol_sm_notify_pmkid_attempt(struct eapol_sm *sm);
|
||||
void eapol_sm_register_scard_ctx(struct eapol_sm *sm, void *ctx);
|
||||
void eapol_sm_notify_portControl(struct eapol_sm *sm, PortControl portControl);
|
||||
void eapol_sm_notify_ctrl_attached(struct eapol_sm *sm);
|
||||
void eapol_sm_notify_ctrl_response(struct eapol_sm *sm);
|
||||
void eapol_sm_request_reauth(struct eapol_sm *sm);
|
||||
void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm, int in_eapol_sm);
|
||||
void eapol_sm_invalidate_cached_session(struct eapol_sm *sm);
|
||||
const char * eapol_sm_get_method_name(struct eapol_sm *sm);
|
||||
void eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm,
|
||||
struct ext_password_data *ext);
|
||||
int eapol_sm_failed(struct eapol_sm *sm);
|
||||
void eapol_sm_erp_flush(struct eapol_sm *sm);
|
||||
int eapol_sm_get_eap_proxy_imsi(struct eapol_sm *sm, char *imsi, size_t *len);
|
||||
#else /* IEEE8021X_EAPOL */
|
||||
static inline struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx)
|
||||
{
|
||||
free(ctx);
|
||||
return (struct eapol_sm *) 1;
|
||||
}
|
||||
static inline void eapol_sm_deinit(struct eapol_sm *sm)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_step(struct eapol_sm *sm)
|
||||
{
|
||||
}
|
||||
static inline int eapol_sm_get_status(struct eapol_sm *sm, char *buf,
|
||||
size_t buflen, int verbose)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int eapol_sm_get_mib(struct eapol_sm *sm, char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod,
|
||||
int authPeriod, int startPeriod,
|
||||
int maxStart)
|
||||
{
|
||||
}
|
||||
static inline int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src,
|
||||
const u8 *buf, size_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_notify_portEnabled(struct eapol_sm *sm,
|
||||
Boolean enabled)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_notify_portValid(struct eapol_sm *sm,
|
||||
Boolean valid)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_notify_eap_success(struct eapol_sm *sm,
|
||||
Boolean success)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_notify_config(struct eapol_sm *sm,
|
||||
struct eap_peer_config *config,
|
||||
struct eapol_config *conf)
|
||||
{
|
||||
}
|
||||
static inline int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static inline const u8 *
|
||||
eapol_sm_get_session_id(struct eapol_sm *sm, size_t *len)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline void eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_notify_cached(struct eapol_sm *sm)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_notify_pmkid_attempt(struct eapol_sm *sm)
|
||||
{
|
||||
}
|
||||
#define eapol_sm_register_scard_ctx(sm, ctx) do { } while (0)
|
||||
static inline void eapol_sm_notify_portControl(struct eapol_sm *sm,
|
||||
PortControl portControl)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_notify_ctrl_attached(struct eapol_sm *sm)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_notify_ctrl_response(struct eapol_sm *sm)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_request_reauth(struct eapol_sm *sm)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm,
|
||||
int in_eapol_sm)
|
||||
{
|
||||
}
|
||||
static inline void eapol_sm_invalidate_cached_session(struct eapol_sm *sm)
|
||||
{
|
||||
}
|
||||
static inline const char * eapol_sm_get_method_name(struct eapol_sm *sm)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline void eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm,
|
||||
struct ext_password_data *ext)
|
||||
{
|
||||
}
|
||||
static inline int eapol_sm_failed(struct eapol_sm *sm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void eapol_sm_erp_flush(struct eapol_sm *sm)
|
||||
{
|
||||
}
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
|
||||
#endif /* EAPOL_SUPP_SM_H */
|
296
freebsd/contrib/wpa/src/fst/fst.h
Normal file
296
freebsd/contrib/wpa/src/fst/fst.h
Normal file
@ -0,0 +1,296 @@
|
||||
/*
|
||||
* FST module - interface definitions
|
||||
* Copyright (c) 2014, Qualcomm Atheros, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef FST_H
|
||||
#define FST_H
|
||||
|
||||
#ifdef CONFIG_FST
|
||||
|
||||
#include "common/defs.h"
|
||||
#include "fst/fst_ctrl_iface.h"
|
||||
|
||||
/* FST module hostap integration API */
|
||||
|
||||
#define US_IN_MS 1000
|
||||
#define LLT_UNIT_US 32 /* See 10.32.2.2 Transitioning between states */
|
||||
|
||||
#define FST_LLT_MS_TO_VAL(m) (((u32) (m)) * US_IN_MS / LLT_UNIT_US)
|
||||
#define FST_LLT_VAL_TO_MS(v) (((u32) (v)) * LLT_UNIT_US / US_IN_MS)
|
||||
|
||||
#define FST_MAX_LLT_MS FST_LLT_VAL_TO_MS(-1)
|
||||
#define FST_MAX_PRIO_VALUE ((u8) -1)
|
||||
#define FST_MAX_GROUP_ID_LEN IFNAMSIZ
|
||||
|
||||
#define FST_DEFAULT_LLT_CFG_VALUE 50
|
||||
|
||||
struct hostapd_hw_modes;
|
||||
struct ieee80211_mgmt;
|
||||
struct fst_iface;
|
||||
struct fst_group;
|
||||
struct fst_session;
|
||||
struct fst_get_peer_ctx;
|
||||
struct fst_ctrl_handle;
|
||||
|
||||
struct fst_wpa_obj {
|
||||
void *ctx;
|
||||
|
||||
/**
|
||||
* get_bssid - Get BSSID of the interface
|
||||
* @ctx: User context %ctx
|
||||
* Returns: BSSID for success, %NULL for failure.
|
||||
*
|
||||
* NOTE: For AP it returns the own BSSID, while for STA - the BSSID of
|
||||
* the associated AP.
|
||||
*/
|
||||
const u8 * (*get_bssid)(void *ctx);
|
||||
|
||||
/**
|
||||
* get_channel_info - Get current channel info
|
||||
* @ctx: User context %ctx
|
||||
* @hw_mode: OUT, current HW mode
|
||||
* @channel: OUT, current channel
|
||||
*/
|
||||
void (*get_channel_info)(void *ctx, enum hostapd_hw_mode *hw_mode,
|
||||
u8 *channel);
|
||||
|
||||
/**
|
||||
* get_hw_modes - Get hardware modes
|
||||
* @ctx: User context %ctx
|
||||
* @modes: OUT, pointer on array of hw modes
|
||||
*
|
||||
* Returns: Number of hw modes available.
|
||||
*/
|
||||
int (*get_hw_modes)(void *ctx, struct hostapd_hw_modes **modes);
|
||||
|
||||
/**
|
||||
* set_ies - Set interface's MB IE
|
||||
* @ctx: User context %ctx
|
||||
* @fst_ies: MB IE buffer (owned by FST module)
|
||||
*/
|
||||
void (*set_ies)(void *ctx, const struct wpabuf *fst_ies);
|
||||
|
||||
/**
|
||||
* send_action - Send FST Action frame via the interface
|
||||
* @ctx: User context %ctx
|
||||
* @addr: Address of the destination STA
|
||||
* @data: Action frame buffer
|
||||
* Returns: 0 for success, negative error code for failure.
|
||||
*/
|
||||
int (*send_action)(void *ctx, const u8 *addr, struct wpabuf *data);
|
||||
|
||||
/**
|
||||
* get_mb_ie - Get last MB IE received from STA
|
||||
* @ctx: User context %ctx
|
||||
* @addr: Address of the STA
|
||||
* Returns: MB IE buffer, %NULL if no MB IE received from the STA
|
||||
*/
|
||||
const struct wpabuf * (*get_mb_ie)(void *ctx, const u8 *addr);
|
||||
|
||||
/**
|
||||
* update_mb_ie - Update last MB IE received from STA
|
||||
* @ctx: User context %ctx
|
||||
* @addr: Address of the STA
|
||||
* @buf: Buffer that contains the MB IEs data
|
||||
* @size: Size of data in %buf
|
||||
*/
|
||||
void (*update_mb_ie)(void *ctx, const u8 *addr,
|
||||
const u8 *buf, size_t size);
|
||||
|
||||
/**
|
||||
* get_peer_first - Get MAC address of the 1st connected STA
|
||||
* @ctx: User context %ctx
|
||||
* @get_ctx: Context to be used for %get_peer_next call
|
||||
* @mb_only: %TRUE if only multi-band capable peer should be reported
|
||||
* Returns: Address of the 1st connected STA, %NULL if no STAs connected
|
||||
*/
|
||||
const u8 * (*get_peer_first)(void *ctx,
|
||||
struct fst_get_peer_ctx **get_ctx,
|
||||
Boolean mb_only);
|
||||
/**
|
||||
* get_peer_next - Get MAC address of the next connected STA
|
||||
* @ctx: User context %ctx
|
||||
* @get_ctx: Context received from %get_peer_first or previous
|
||||
* %get_peer_next call
|
||||
* @mb_only: %TRUE if only multi-band capable peer should be reported
|
||||
* Returns: Address of the next connected STA, %NULL if no more STAs
|
||||
* connected
|
||||
*/
|
||||
const u8 * (*get_peer_next)(void *ctx,
|
||||
struct fst_get_peer_ctx **get_ctx,
|
||||
Boolean mb_only);
|
||||
};
|
||||
|
||||
/**
|
||||
* fst_global_init - Global FST module initiator
|
||||
* Returns: 0 for success, negative error code for failure.
|
||||
* Note: The purpose of this function is to allocate and initiate global
|
||||
* FST module data structures (linked lists, static data etc.)
|
||||
* This function should be called prior to the 1st %fst_attach call.
|
||||
*/
|
||||
int fst_global_init(void);
|
||||
|
||||
/**
|
||||
* fst_global_deinit - Global FST module de-initiator
|
||||
* Note: The purpose of this function is to deallocate and de-initiate global
|
||||
* FST module data structures (linked lists, static data etc.)
|
||||
*/
|
||||
void fst_global_deinit(void);
|
||||
|
||||
/**
|
||||
* struct fst_ctrl - Notification interface for FST module
|
||||
*/
|
||||
struct fst_ctrl {
|
||||
/**
|
||||
* init - Initialize the notification interface
|
||||
* Returns: 0 for success, negative error code for failure.
|
||||
*/
|
||||
int (*init)(void);
|
||||
|
||||
/**
|
||||
* deinit - Deinitialize the notification interface
|
||||
*/
|
||||
void (*deinit)(void);
|
||||
|
||||
/**
|
||||
* on_group_created - Notify about FST group creation
|
||||
* Returns: 0 for success, negative error code for failure.
|
||||
*/
|
||||
int (*on_group_created)(struct fst_group *g);
|
||||
|
||||
/**
|
||||
* on_group_deleted - Notify about FST group deletion
|
||||
*/
|
||||
void (*on_group_deleted)(struct fst_group *g);
|
||||
|
||||
/**
|
||||
* on_iface_added - Notify about interface addition
|
||||
* Returns: 0 for success, negative error code for failure.
|
||||
*/
|
||||
int (*on_iface_added)(struct fst_iface *i);
|
||||
|
||||
/**
|
||||
* on_iface_removed - Notify about interface removal
|
||||
*/
|
||||
void (*on_iface_removed)(struct fst_iface *i);
|
||||
|
||||
/**
|
||||
* on_session_added - Notify about FST session addition
|
||||
* Returns: 0 for success, negative error code for failure.
|
||||
*/
|
||||
int (*on_session_added)(struct fst_session *s);
|
||||
|
||||
/**
|
||||
* on_session_removed - Notify about FST session removal
|
||||
*/
|
||||
void (*on_session_removed)(struct fst_session *s);
|
||||
|
||||
/**
|
||||
* on_event - Notify about FST event
|
||||
* @event_type: Event type
|
||||
* @i: Interface object that relates to the event or NULL
|
||||
* @g: Group object that relates to the event or NULL
|
||||
* @extra - Event specific data (see fst_ctrl_iface.h for more info)
|
||||
*/
|
||||
void (*on_event)(enum fst_event_type event_type, struct fst_iface *i,
|
||||
struct fst_session *s,
|
||||
const union fst_event_extra *extra);
|
||||
};
|
||||
|
||||
struct fst_ctrl_handle * fst_global_add_ctrl(const struct fst_ctrl *ctrl);
|
||||
void fst_global_del_ctrl(struct fst_ctrl_handle *h);
|
||||
|
||||
/**
|
||||
* NOTE: These values have to be read from configuration file
|
||||
*/
|
||||
struct fst_iface_cfg {
|
||||
char group_id[FST_MAX_GROUP_ID_LEN + 1];
|
||||
u8 priority;
|
||||
u32 llt;
|
||||
};
|
||||
|
||||
/**
|
||||
* fst_attach - Attach interface to an FST group according to configuration read
|
||||
* @ifname: Interface name
|
||||
* @own_addr: Own interface MAC address
|
||||
* @iface_obj: Callbacks to be used by FST module to communicate with
|
||||
* hostapd/wpa_supplicant
|
||||
* @cfg: FST-related interface configuration read from the configuration file
|
||||
* Returns: FST interface object for success, %NULL for failure.
|
||||
*/
|
||||
struct fst_iface * fst_attach(const char *ifname,
|
||||
const u8 *own_addr,
|
||||
const struct fst_wpa_obj *iface_obj,
|
||||
const struct fst_iface_cfg *cfg);
|
||||
|
||||
/**
|
||||
* fst_detach - Detach an interface
|
||||
* @iface: FST interface object
|
||||
*/
|
||||
void fst_detach(struct fst_iface *iface);
|
||||
|
||||
/* FST module inputs */
|
||||
/**
|
||||
* fst_rx_action - FST Action frames handler
|
||||
* @iface: FST interface object
|
||||
* @mgmt: Action frame arrived
|
||||
* @len: Action frame length
|
||||
*/
|
||||
void fst_rx_action(struct fst_iface *iface, const struct ieee80211_mgmt *mgmt,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* fst_notify_peer_connected - FST STA connect handler
|
||||
* @iface: FST interface object
|
||||
* @addr: Address of the connected STA
|
||||
*/
|
||||
void fst_notify_peer_connected(struct fst_iface *iface, const u8 *addr);
|
||||
|
||||
/**
|
||||
* fst_notify_peer_disconnected - FST STA disconnect handler
|
||||
* @iface: FST interface object
|
||||
* @addr: Address of the disconnected STA
|
||||
*/
|
||||
void fst_notify_peer_disconnected(struct fst_iface *iface, const u8 *addr);
|
||||
|
||||
/* FST module auxiliary routines */
|
||||
|
||||
/**
|
||||
* fst_are_ifaces_aggregated - Determines whether 2 interfaces belong to the
|
||||
* same FST group
|
||||
* @iface1: 1st FST interface object
|
||||
* @iface1: 2nd FST interface object
|
||||
*
|
||||
* Returns: %TRUE if the interfaces belong to the same FST group,
|
||||
* %FALSE otherwise
|
||||
*/
|
||||
Boolean fst_are_ifaces_aggregated(struct fst_iface *iface1,
|
||||
struct fst_iface *iface2);
|
||||
|
||||
#else /* CONFIG_FST */
|
||||
|
||||
static inline int fst_global_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int fst_global_start(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fst_global_stop(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void fst_global_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FST */
|
||||
|
||||
#endif /* FST_H */
|
91
freebsd/contrib/wpa/src/fst/fst_ctrl_aux.h
Normal file
91
freebsd/contrib/wpa/src/fst/fst_ctrl_aux.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* FST module - miscellaneous definitions
|
||||
* Copyright (c) 2014, Qualcomm Atheros, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef FST_CTRL_AUX_H
|
||||
#define FST_CTRL_AUX_H
|
||||
|
||||
#include "common/defs.h"
|
||||
|
||||
/* FST module control interface API */
|
||||
#define FST_INVALID_SESSION_ID ((u32) -1)
|
||||
#define FST_MAX_GROUP_ID_SIZE 32
|
||||
#define FST_MAX_INTERFACE_SIZE 32
|
||||
|
||||
enum fst_session_state {
|
||||
FST_SESSION_STATE_INITIAL,
|
||||
FST_SESSION_STATE_SETUP_COMPLETION,
|
||||
FST_SESSION_STATE_TRANSITION_DONE,
|
||||
FST_SESSION_STATE_TRANSITION_CONFIRMED,
|
||||
FST_SESSION_STATE_LAST
|
||||
};
|
||||
|
||||
enum fst_event_type {
|
||||
EVENT_FST_IFACE_STATE_CHANGED, /* An interface has been either attached
|
||||
* to or detached from an FST group */
|
||||
EVENT_FST_ESTABLISHED, /* FST Session has been established */
|
||||
EVENT_FST_SETUP, /* FST Session request received */
|
||||
EVENT_FST_SESSION_STATE_CHANGED,/* FST Session state has been changed */
|
||||
EVENT_PEER_STATE_CHANGED /* FST related generic event occurred,
|
||||
* see struct fst_hostap_event_data for
|
||||
* more info */
|
||||
};
|
||||
|
||||
enum fst_initiator {
|
||||
FST_INITIATOR_UNDEFINED,
|
||||
FST_INITIATOR_LOCAL,
|
||||
FST_INITIATOR_REMOTE,
|
||||
};
|
||||
|
||||
union fst_event_extra {
|
||||
struct fst_event_extra_iface_state {
|
||||
Boolean attached;
|
||||
char ifname[FST_MAX_INTERFACE_SIZE];
|
||||
char group_id[FST_MAX_GROUP_ID_SIZE];
|
||||
} iface_state; /* for EVENT_FST_IFACE_STATE_CHANGED */
|
||||
struct fst_event_extra_peer_state {
|
||||
Boolean connected;
|
||||
char ifname[FST_MAX_INTERFACE_SIZE];
|
||||
u8 addr[ETH_ALEN];
|
||||
} peer_state; /* for EVENT_PEER_STATE_CHANGED */
|
||||
struct fst_event_extra_session_state {
|
||||
enum fst_session_state old_state;
|
||||
enum fst_session_state new_state;
|
||||
union fst_session_state_switch_extra {
|
||||
struct {
|
||||
enum fst_reason {
|
||||
REASON_TEARDOWN,
|
||||
REASON_SETUP,
|
||||
REASON_SWITCH,
|
||||
REASON_STT,
|
||||
REASON_REJECT,
|
||||
REASON_ERROR_PARAMS,
|
||||
REASON_RESET,
|
||||
REASON_DETACH_IFACE,
|
||||
} reason;
|
||||
u8 reject_code; /* REASON_REJECT */
|
||||
/* REASON_SWITCH,
|
||||
* REASON_TEARDOWN,
|
||||
* REASON_REJECT
|
||||
*/
|
||||
enum fst_initiator initiator;
|
||||
} to_initial;
|
||||
} extra;
|
||||
} session_state; /* for EVENT_FST_SESSION_STATE_CHANGED */
|
||||
};
|
||||
|
||||
/* helpers - prints enum in string form */
|
||||
#define FST_NAME_UNKNOWN "UNKNOWN"
|
||||
|
||||
const char * fst_get_str_name(unsigned index, const char *names[],
|
||||
size_t names_size);
|
||||
|
||||
const char * fst_session_event_type_name(enum fst_event_type);
|
||||
const char * fst_reason_name(enum fst_reason reason);
|
||||
const char * fst_session_state_name(enum fst_session_state state);
|
||||
|
||||
#endif /* FST_CTRL_AUX_H */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user