summaryrefslogtreecommitdiffstats
path: root/src/include/gpxe/net80211.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/gpxe/net80211.h')
-rw-r--r--src/include/gpxe/net80211.h204
1 files changed, 187 insertions, 17 deletions
diff --git a/src/include/gpxe/net80211.h b/src/include/gpxe/net80211.h
index d924941f..027e091c 100644
--- a/src/include/gpxe/net80211.h
+++ b/src/include/gpxe/net80211.h
@@ -119,6 +119,9 @@ enum net80211_security_proto {
* in the same 4-way handshake as the PSK method.
*/
NET80211_SECPROT_EAP = 2,
+
+ /** Dummy value used when the handshaking type can't be detected */
+ NET80211_SECPROT_UNKNOWN = 3,
};
@@ -169,6 +172,9 @@ enum net80211_crypto_alg {
* against WEP and minor success against TKIP fail.
*/
NET80211_CRYPT_CCMP = 3,
+
+ /** Dummy value used when the cryptosystem can't be detected */
+ NET80211_CRYPT_UNKNOWN = 4,
};
@@ -539,37 +545,171 @@ struct net80211_frag_cache
struct io_buffer *iob[16];
};
-/** Interface to an 802.11 cryptographic algorithm
+
+/** Interface to an 802.11 security handshaking protocol
+ *
+ * Security handshaking protocols handle parsing a user-specified key
+ * into a suitable input to the encryption algorithm, and for WPA and
+ * better systems, manage performing whatever authentication with the
+ * network is necessary.
*
- * Cryptographic algorithms define a net80211_crypto structure
- * statically, using a gPXE linker table to make it available to the
- * 802.11 layer. When the algorithm needs to be used, the 802.11 code
- * will allocate a copy of the static definition plus whatever space
- * the algorithm has requested for private state, and point
- * net80211_device::crypto at it.
+ * At all times when any method in this structure is called with a
+ * net80211_device argument @a dev, a dynamically allocated copy of
+ * the handshaker structure itself with space for the requested amount
+ * of private data may be accessed as @c dev->handshaker. The
+ * structure will not be modified, and will only be freed during
+ * reassociation and device closing after the @a stop method has been
+ * called.
+ */
+struct net80211_handshaker
+{
+ /** The security handshaking protocol implemented */
+ enum net80211_security_proto protocol;
+
+ /** Initialize security handshaking protocol
+ *
+ * @v dev 802.11 device
+ * @ret rc Return status code
+ *
+ * This method is expected to access @c netX/key or other
+ * applicable settings to determine the parameters for
+ * handshaking. If no handshaking is required, it should call
+ * sec80211_install() with the cryptosystem and key that are
+ * to be used, and @c start and @c step should be set to @c
+ * NULL.
+ *
+ * This is always called just before association is performed,
+ * but after its parameters have been set; in particular, you
+ * may rely on the contents of the @a essid field in @a dev.
+ */
+ int ( * init ) ( struct net80211_device *dev );
+
+ /** Start handshaking
+ *
+ * @v dev 802.11 device
+ * @ret rc Return status code
+ *
+ * This method is expected to set up internal state so that
+ * packets sent immediately after association, before @a step
+ * can be called, will be handled appropriately.
+ *
+ * This is always called just before association is attempted.
+ */
+ int ( * start ) ( struct net80211_device *dev );
+
+ /** Process handshaking state
+ *
+ * @v dev 802.11 device
+ * @ret rc Return status code, or positive if done
+ *
+ * This method is expected to perform as much progress on the
+ * protocol it implements as is possible without blocking. It
+ * should return 0 if it wishes to be called again, a negative
+ * return status code on error, or a positive value if
+ * handshaking is complete. In the case of a positive return,
+ * net80211_crypto_install() must have been called.
+ *
+ * If handshaking may require further action (e.g. an AP that
+ * might decide to rekey), handlers must be installed by this
+ * function that will act without further calls to @a step.
+ */
+ int ( * step ) ( struct net80211_device *dev );
+
+ /** Change cryptographic key based on setting
+ *
+ * @v dev 802.11 device
+ * @ret rc Return status code
+ *
+ * This method is called whenever the @c netX/key setting
+ * @e may have been changed. It is expected to determine
+ * whether it did in fact change, and if so, to install the
+ * new key using net80211_crypto_install(). If it is not
+ * possible to do this immediately, this method should return
+ * an error; in that case the 802.11 stack will reassociate,
+ * following the usual init/start/step sequence.
+ *
+ * This method is only relevant when it is possible to
+ * associate successfully with an incorrect key. When it is
+ * not, a failed association will be retried until the user
+ * changes the key setting, and a successful association will
+ * not be dropped due to such a change. When association with
+ * an incorrect key is impossible, this function should return
+ * 0 after performing no action.
+ */
+ int ( * change_key ) ( struct net80211_device *dev );
+
+ /** Stop security handshaking handlers
+ *
+ * @v dev 802.11 device
+ *
+ * This method is called just before freeing a security
+ * handshaker; it could, for example, delete a process that @a
+ * start had created to manage the security of the connection.
+ * If not needed it may be set to NULL.
+ */
+ void ( * stop ) ( struct net80211_device *dev );
+
+ /** Amount of private data requested
+ *
+ * Before @c init is called for the first time, this structure's
+ * @c priv pointer will point to this many bytes of allocated
+ * data, where the allocation will be performed separately for
+ * each net80211_device.
+ */
+ int priv_len;
+
+ /** Whether @a start has been called
+ *
+ * Reset to 0 after @a stop is called.
+ */
+ int started;
+
+ /** Pointer to private data
+ *
+ * In initializing this structure statically for a linker
+ * table, set this to NULL.
+ */
+ void *priv;
+};
+
+#define NET80211_HANDSHAKERS __table ( struct net80211_handshaker, \
+ "net80211_handshakers" )
+#define __net80211_handshaker __table_entry ( NET80211_HANDSHAKERS, 01 )
+
+
+/** Interface to an 802.11 cryptosystem
+ *
+ * Cryptosystems define a net80211_crypto structure statically, using
+ * a gPXE linker table to make it available to the 802.11 layer. When
+ * the cryptosystem needs to be used, the 802.11 code will allocate a
+ * copy of the static definition plus whatever space the algorithm has
+ * requested for private state, and point net80211_device::crypto or
+ * net80211_device::gcrypto at it.
*/
struct net80211_crypto
{
/** The cryptographic algorithm implemented */
enum net80211_crypto_alg algorithm;
- /** Initialize cryptographic algorithm using a given key
+ /** Initialize cryptosystem using a given key
*
- * @v crypto 802.11 cryptographic algorithm
+ * @v crypto 802.11 cryptosystem
* @v key Pointer to key bytes
* @v keylen Number of key bytes
+ * @v rsc Initial receive sequence counter, if applicable
* @ret rc Return status code
*
* This method is passed the communication key provided by the
* security handshake handler, which will already be in the
- * low-level form required.
+ * low-level form required. It may not store a pointer to the
+ * key after returning; it must copy it to its private storage.
*/
- int ( * initialize ) ( struct net80211_crypto *crypto, u8 *key,
- int keylen );
+ int ( * init ) ( struct net80211_crypto *crypto, const void *key,
+ int keylen, const void *rsc );
- /** Encrypt a frame using the cryptographic algorithm
+ /** Encrypt a frame using the cryptosystem
*
- * @v crypto 802.11 cryptographic algorithm
+ * @v crypto 802.11 cryptosystem
* @v iob I/O buffer
* @ret eiob Newly allocated I/O buffer with encrypted packet
*
@@ -593,9 +733,9 @@ struct net80211_crypto
struct io_buffer * ( * encrypt ) ( struct net80211_crypto *crypto,
struct io_buffer *iob );
- /** Decrypt a frame using the cryptographic algorithm
+ /** Decrypt a frame using the cryptosystem
*
- * @v crypto 802.11 cryptographic algorithm
+ * @v crypto 802.11 cryptosystem
* @v eiob Encrypted I/O buffer
* @ret iob Newly allocated I/O buffer with decrypted packet
*
@@ -626,6 +766,9 @@ struct net80211_crypto
void *priv;
};
+#define NET80211_CRYPTOS __table ( struct net80211_crypto, "net80211_cryptos" )
+#define __net80211_crypto __table_entry ( NET80211_CRYPTOS, 01 )
+
struct net80211_probe_ctx;
struct net80211_assoc_ctx;
@@ -732,6 +875,9 @@ struct net80211_device
struct net80211_assoc_ctx *assoc;
} ctx;
+ /** Security handshaker being used */
+ struct net80211_handshaker *handshaker;
+
/** State of our association to the network
*
* Since the association process happens asynchronously, it's
@@ -777,14 +923,33 @@ struct net80211_device
/** Return status code associated with @c state */
int assoc_rc;
+ /** RSN or WPA information element to include with association
+ *
+ * If set to @c NULL, none will be included. It is expected
+ * that this will be set by the @a init function of a security
+ * handshaker if it is needed.
+ */
+ union ieee80211_ie *rsn_ie;
+
/* ---------- Parameters of currently associated network ---------- */
- /** 802.11 cryptographic algorithm for our current network
+ /** 802.11 cryptosystem for our current network
*
* For an open network, this will be set to NULL.
*/
struct net80211_crypto *crypto;
+ /** 802.11 cryptosystem for multicast and broadcast frames
+ *
+ * If this is NULL, the cryptosystem used for receiving
+ * unicast frames will also be used for receiving multicast
+ * and broadcast frames. Transmitted multicast and broadcast
+ * frames are always sent unicast to the AP, who multicasts
+ * them on our behalf; thus they always use the unicast
+ * cryptosystem.
+ */
+ struct net80211_crypto *gcrypto;
+
/** MAC address of the access point most recently associated */
u8 bssid[ETH_ALEN];
@@ -927,6 +1092,10 @@ struct net80211_wlan
};
+/** 802.11 encryption key setting */
+extern struct setting net80211_key_setting __setting;
+
+
/**
* @defgroup net80211_probe 802.11 network location API
* @{
@@ -974,6 +1143,7 @@ int net80211_send_auth ( struct net80211_device *dev,
struct net80211_wlan *wlan, int method );
int net80211_send_assoc ( struct net80211_device *dev,
struct net80211_wlan *wlan );
+void net80211_deauthenticate ( struct net80211_device *dev, int rc );
/** @} */