From 07581113450afa6986c64e604cc98a07f98a0830 Mon Sep 17 00:00:00 2001 From: Joshua Oreman Date: Fri, 7 Aug 2009 23:05:00 -0700 Subject: [wpa] Add pre-shared key frontend (WPA "Personal" with just a passphrase) Modified-by: Marty Connor Signed-off-by: Marty Connor --- src/config/general.h | 1 + src/include/gpxe/errfile.h | 1 + src/net/80211/wpa_psk.c | 125 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 src/net/80211/wpa_psk.c diff --git a/src/config/general.h b/src/config/general.h index c0370ca4..8855a872 100644 --- a/src/config/general.h +++ b/src/config/general.h @@ -69,6 +69,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); * */ #define CRYPTO_80211_WEP /* WEP encryption (deprecated and insecure!) */ +#define CRYPTO_80211_WPA_PSK /* WPA "Personal" frontend using a passphrase */ /* * Name resolution modules diff --git a/src/include/gpxe/errfile.h b/src/include/gpxe/errfile.h index e55af1c1..b79ac437 100644 --- a/src/include/gpxe/errfile.h +++ b/src/include/gpxe/errfile.h @@ -162,6 +162,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define ERRFILE_wep ( ERRFILE_NET | 0x00240000 ) #define ERRFILE_eapol ( ERRFILE_NET | 0x00250000 ) #define ERRFILE_wpa ( ERRFILE_NET | 0x00260000 ) +#define ERRFILE_wpa_psk ( ERRFILE_NET | 0x00270000 ) #define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 ) #define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 ) diff --git a/src/net/80211/wpa_psk.c b/src/net/80211/wpa_psk.c new file mode 100644 index 00000000..e7521682 --- /dev/null +++ b/src/net/80211/wpa_psk.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2009 Joshua Oreman . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include +#include +#include +#include + +/** @file + * + * Frontend for WPA using a pre-shared key. + */ + +/** + * Initialise WPA-PSK state + * + * @v dev 802.11 device + * @ret rc Return status code + */ +static int wpa_psk_init ( struct net80211_device *dev ) +{ + return wpa_make_rsn_ie ( dev, &dev->rsn_ie ); +} + +/** + * Start WPA-PSK authentication + * + * @v dev 802.11 device + * @ret rc Return status code + */ +static int wpa_psk_start ( struct net80211_device *dev ) +{ + char passphrase[64+1]; + u8 pmk[WPA_PMK_LEN]; + int len; + struct wpa_common_ctx *ctx = dev->handshaker->priv; + + len = fetch_string_setting ( netdev_settings ( dev->netdev ), + &net80211_key_setting, passphrase, + 64 + 1 ); + + if ( len <= 0 ) { + DBGC ( ctx, "WPA-PSK %p: no passphrase provided!\n", ctx ); + net80211_deauthenticate ( dev, -EACCES ); + return -EACCES; + } + + pbkdf2_sha1 ( passphrase, len, dev->essid, strlen ( dev->essid ), + 4096, pmk, WPA_PMK_LEN ); + + DBGC ( ctx, "WPA-PSK %p: derived PMK from passphrase `%s':\n", ctx, + passphrase ); + DBGC_HD ( ctx, pmk, WPA_PMK_LEN ); + + return wpa_start ( dev, ctx, pmk, WPA_PMK_LEN ); +} + +/** + * Step WPA-PSK authentication + * + * @v dev 802.11 device + * @ret rc Return status code + */ +static int wpa_psk_step ( struct net80211_device *dev ) +{ + struct wpa_common_ctx *ctx = dev->handshaker->priv; + + switch ( ctx->state ) { + case WPA_SUCCESS: + return 1; + case WPA_FAILURE: + return -EACCES; + default: + return 0; + } +} + +/** + * Do-nothing function; you can't change a WPA key post-authentication + * + * @v dev 802.11 device + * @ret rc Return status code + */ +static int wpa_psk_no_change_key ( struct net80211_device *dev __unused ) +{ + return 0; +} + +/** + * Disable handling of received WPA authentication frames + * + * @v dev 802.11 device + */ +static void wpa_psk_stop ( struct net80211_device *dev ) +{ + wpa_stop ( dev ); +} + +/** WPA-PSK security handshaker */ +struct net80211_handshaker wpa_psk_handshaker __net80211_handshaker = { + .protocol = NET80211_SECPROT_PSK, + .init = wpa_psk_init, + .start = wpa_psk_start, + .step = wpa_psk_step, + .change_key = wpa_psk_no_change_key, + .stop = wpa_psk_stop, + .priv_len = sizeof ( struct wpa_common_ctx ), +}; -- cgit v1.2.3-55-g7522