Add build option to remove all internal RC4 uses

The new CONFIG_NO_RC4=y build option can be used to remove all internal
hostapd and wpa_supplicant uses of RC4. It should be noted that external
uses (e.g., within a TLS library) do not get disabled when doing this.

This removes capability of supporting WPA/TKIP, dynamic WEP keys with
IEEE 802.1X, WEP shared key authentication, and MSCHAPv2 password
changes.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2015-08-01 23:37:07 +03:00
parent a1eabc74b8
commit 7cb53ded11
12 changed files with 82 additions and 0 deletions

View file

@ -779,11 +779,17 @@ OBJS += src/crypto/des-internal.c
endif endif
endif endif
ifdef CONFIG_NO_RC4
L_CFLAGS += -DCONFIG_NO_RC4
endif
ifdef NEED_RC4 ifdef NEED_RC4
ifdef CONFIG_INTERNAL_RC4 ifdef CONFIG_INTERNAL_RC4
ifndef CONFIG_NO_RC4
OBJS += src/crypto/rc4.c OBJS += src/crypto/rc4.c
endif endif
endif endif
endif
ifdef NEED_SHA256 ifdef NEED_SHA256
L_CFLAGS += -DCONFIG_SHA256 L_CFLAGS += -DCONFIG_SHA256

View file

@ -761,11 +761,17 @@ OBJS += ../src/crypto/des-internal.o
endif endif
endif endif
ifdef CONFIG_NO_RC4
CFLAGS += -DCONFIG_NO_RC4
endif
ifdef NEED_RC4 ifdef NEED_RC4
ifdef CONFIG_INTERNAL_RC4 ifdef CONFIG_INTERNAL_RC4
ifndef CONFIG_NO_RC4
OBJS += ../src/crypto/rc4.o OBJS += ../src/crypto/rc4.o
endif endif
endif endif
endif
ifdef NEED_SHA256 ifdef NEED_SHA256
CFLAGS += -DCONFIG_SHA256 CFLAGS += -DCONFIG_SHA256
@ -989,9 +995,11 @@ NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS)
NOBJS += ../src/utils/common.o NOBJS += ../src/utils/common.o
ifdef NEED_RC4 ifdef NEED_RC4
ifdef CONFIG_INTERNAL_RC4 ifdef CONFIG_INTERNAL_RC4
ifndef CONFIG_NO_RC4
NOBJS += ../src/crypto/rc4.o NOBJS += ../src/crypto/rc4.o
endif endif
endif endif
endif
ifdef CONFIG_INTERNAL_MD5 ifdef CONFIG_INTERNAL_MD5
NOBJS += ../src/crypto/md5-internal.o NOBJS += ../src/crypto/md5-internal.o
endif endif

View file

@ -192,6 +192,7 @@ u16 hostapd_own_capab_info(struct hostapd_data *hapd)
} }
#ifndef CONFIG_NO_RC4
static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta, static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
u16 auth_transaction, const u8 *challenge, u16 auth_transaction, const u8 *challenge,
int iswep) int iswep)
@ -245,6 +246,7 @@ static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
return 0; return 0;
} }
#endif /* CONFIG_NO_RC4 */
static void send_auth_reply(struct hostapd_data *hapd, static void send_auth_reply(struct hostapd_data *hapd,
@ -926,6 +928,16 @@ static void handle_auth(struct hostapd_data *hapd,
challenge ? " challenge" : "", challenge ? " challenge" : "",
seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : ""); seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
#ifdef CONFIG_NO_RC4
if (auth_alg == WLAN_AUTH_SHARED_KEY) {
wpa_printf(MSG_INFO,
"Unsupported authentication algorithm (%d)",
auth_alg);
resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
goto fail;
}
#endif /* CONFIG_NO_RC4 */
if (hapd->tkip_countermeasures) { if (hapd->tkip_countermeasures) {
resp = WLAN_REASON_MICHAEL_MIC_FAILURE; resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
goto fail; goto fail;
@ -1073,6 +1085,7 @@ static void handle_auth(struct hostapd_data *hapd,
sta->auth_alg = WLAN_AUTH_OPEN; sta->auth_alg = WLAN_AUTH_OPEN;
mlme_authenticate_indication(hapd, sta); mlme_authenticate_indication(hapd, sta);
break; break;
#ifndef CONFIG_NO_RC4
case WLAN_AUTH_SHARED_KEY: case WLAN_AUTH_SHARED_KEY:
resp = auth_shared_key(hapd, sta, auth_transaction, challenge, resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
fc & WLAN_FC_ISWEP); fc & WLAN_FC_ISWEP);
@ -1086,6 +1099,7 @@ static void handle_auth(struct hostapd_data *hapd,
resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN; resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
} }
break; break;
#endif /* CONFIG_NO_RC4 */
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R
case WLAN_AUTH_FT: case WLAN_AUTH_FT:
sta->auth_alg = WLAN_AUTH_FT; sta->auth_alg = WLAN_AUTH_FT;

View file

@ -126,6 +126,7 @@ void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd,
#ifndef CONFIG_FIPS #ifndef CONFIG_FIPS
#ifndef CONFIG_NO_RC4
static void ieee802_1x_tx_key_one(struct hostapd_data *hapd, static void ieee802_1x_tx_key_one(struct hostapd_data *hapd,
struct sta_info *sta, struct sta_info *sta,
@ -261,6 +262,7 @@ static void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
} }
} }
#endif /* CONFIG_NO_RC4 */
#endif /* CONFIG_FIPS */ #endif /* CONFIG_FIPS */
@ -2028,9 +2030,11 @@ static void _ieee802_1x_abort_auth(void *ctx, void *sta_ctx)
static void _ieee802_1x_tx_key(void *ctx, void *sta_ctx) static void _ieee802_1x_tx_key(void *ctx, void *sta_ctx)
{ {
#ifndef CONFIG_FIPS #ifndef CONFIG_FIPS
#ifndef CONFIG_NO_RC4
struct hostapd_data *hapd = ctx; struct hostapd_data *hapd = ctx;
struct sta_info *sta = sta_ctx; struct sta_info *sta = sta_ctx;
ieee802_1x_tx_key(hapd, sta); ieee802_1x_tx_key(hapd, sta);
#endif /* CONFIG_NO_RC4 */
#endif /* CONFIG_FIPS */ #endif /* CONFIG_FIPS */
} }

View file

@ -1540,6 +1540,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
else else
WPA_PUT_BE16(key->key_data_length, WPA_PUT_BE16(key->key_data_length,
key_data_len); key_data_len);
#ifndef CONFIG_NO_RC4
} else if (sm->PTK.kek_len == 16) { } else if (sm->PTK.kek_len == 16) {
u8 ek[32]; u8 ek[32];
os_memcpy(key->key_iv, os_memcpy(key->key_iv,
@ -1555,6 +1556,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
else else
WPA_PUT_BE16(key->key_data_length, WPA_PUT_BE16(key->key_data_length,
key_data_len); key_data_len);
#endif /* CONFIG_NO_RC4 */
} else { } else {
os_free(hdr); os_free(hdr);
os_free(buf); os_free(buf);

View file

@ -122,6 +122,7 @@ void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
} }
#ifndef CONFIG_NO_RC4
int rc4_skip(const u8 *key, size_t keylen, size_t skip, int rc4_skip(const u8 *key, size_t keylen, size_t skip,
u8 *data, size_t data_len) u8 *data, size_t data_len)
{ {
@ -157,6 +158,7 @@ out:
return res; return res;
#endif /* OPENSSL_NO_RC4 */ #endif /* OPENSSL_NO_RC4 */
} }
#endif /* CONFIG_NO_RC4 */
#ifndef CONFIG_FIPS #ifndef CONFIG_FIPS
@ -438,11 +440,13 @@ struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
return NULL; return NULL;
switch (alg) { switch (alg) {
#ifndef CONFIG_NO_RC4
#ifndef OPENSSL_NO_RC4 #ifndef OPENSSL_NO_RC4
case CRYPTO_CIPHER_ALG_RC4: case CRYPTO_CIPHER_ALG_RC4:
cipher = EVP_rc4(); cipher = EVP_rc4();
break; break;
#endif /* OPENSSL_NO_RC4 */ #endif /* OPENSSL_NO_RC4 */
#endif /* CONFIG_NO_RC4 */
#ifndef OPENSSL_NO_AES #ifndef OPENSSL_NO_AES
case CRYPTO_CIPHER_ALG_AES: case CRYPTO_CIPHER_ALG_AES:
switch (key_len) { switch (key_len) {

View file

@ -412,6 +412,8 @@ int get_asymetric_start_key(const u8 *master_key, u8 *session_key,
} }
#ifndef CONFIG_NO_RC4
#define PWBLOCK_LEN 516 #define PWBLOCK_LEN 516
/** /**
@ -477,6 +479,8 @@ int new_password_encrypted_with_old_nt_password_hash(
return 0; return 0;
} }
#endif /* CONFIG_NO_RC4 */
/** /**
* nt_password_hash_encrypted_with_block - NtPasswordHashEncryptedWithBlock() - RFC 2759, Sect 8.13 * nt_password_hash_encrypted_with_block - NtPasswordHashEncryptedWithBlock() - RFC 2759, Sect 8.13

View file

@ -511,6 +511,11 @@ static struct wpabuf * eap_mschapv2_change_password(
struct eap_sm *sm, struct eap_mschapv2_data *data, struct eap_sm *sm, struct eap_mschapv2_data *data,
struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req, u8 id) 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; struct wpabuf *resp;
int ms_len; int ms_len;
const u8 *username, *password, *new_password; const u8 *username, *password, *new_password;
@ -628,6 +633,7 @@ static struct wpabuf * eap_mschapv2_change_password(
fail: fail:
wpabuf_free(resp); wpabuf_free(resp);
return NULL; return NULL;
#endif /* CONFIG_NO_RC4 */
} }

View file

@ -654,7 +654,9 @@ static void eapol_sm_processKey(struct eapol_sm *sm)
struct ieee802_1x_eapol_key *key; struct ieee802_1x_eapol_key *key;
struct eap_key_data keydata; struct eap_key_data keydata;
u8 orig_key_sign[IEEE8021X_KEY_SIGN_LEN], datakey[32]; u8 orig_key_sign[IEEE8021X_KEY_SIGN_LEN], datakey[32];
#ifndef CONFIG_NO_RC4
u8 ekey[IEEE8021X_KEY_IV_LEN + IEEE8021X_ENCR_KEY_LEN]; u8 ekey[IEEE8021X_KEY_IV_LEN + IEEE8021X_ENCR_KEY_LEN];
#endif /* CONFIG_NO_RC4 */
int key_len, res, sign_key_len, encr_key_len; int key_len, res, sign_key_len, encr_key_len;
u16 rx_key_length; u16 rx_key_length;
size_t plen; size_t plen;
@ -748,6 +750,13 @@ static void eapol_sm_processKey(struct eapol_sm *sm)
return; return;
} }
if (key_len == rx_key_length) { if (key_len == rx_key_length) {
#ifdef CONFIG_NO_RC4
if (encr_key_len) {
/* otherwise unused */
}
wpa_printf(MSG_ERROR, "EAPOL: RC4 not supported in the build");
return;
#else /* CONFIG_NO_RC4 */
os_memcpy(ekey, key->key_iv, IEEE8021X_KEY_IV_LEN); os_memcpy(ekey, key->key_iv, IEEE8021X_KEY_IV_LEN);
os_memcpy(ekey + IEEE8021X_KEY_IV_LEN, keydata.encr_key, os_memcpy(ekey + IEEE8021X_KEY_IV_LEN, keydata.encr_key,
encr_key_len); encr_key_len);
@ -756,6 +765,7 @@ static void eapol_sm_processKey(struct eapol_sm *sm)
datakey, key_len); datakey, key_len);
wpa_hexdump_key(MSG_DEBUG, "EAPOL: Decrypted(RC4) key", wpa_hexdump_key(MSG_DEBUG, "EAPOL: Decrypted(RC4) key",
datakey, key_len); datakey, key_len);
#endif /* CONFIG_NO_RC4 */
} else if (key_len == 0) { } else if (key_len == 0) {
/* /*
* IEEE 802.1X-2004 specifies that least significant Key Length * IEEE 802.1X-2004 specifies that least significant Key Length

View file

@ -1344,6 +1344,11 @@ static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,
gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >> gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
WPA_KEY_INFO_KEY_INDEX_SHIFT; WPA_KEY_INFO_KEY_INDEX_SHIFT;
if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) { if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) {
#ifdef CONFIG_NO_RC4
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: RC4 not supported in the build");
return -1;
#else /* CONFIG_NO_RC4 */
u8 ek[32]; u8 ek[32];
if (key_data_len > sizeof(gd->gtk)) { if (key_data_len > sizeof(gd->gtk)) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
@ -1361,6 +1366,7 @@ static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,
return -1; return -1;
} }
os_memset(ek, 0, sizeof(ek)); os_memset(ek, 0, sizeof(ek));
#endif /* CONFIG_NO_RC4 */
} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) { } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
if (maxkeylen % 8) { if (maxkeylen % 8) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
@ -1575,6 +1581,11 @@ static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
/* Decrypt key data here so that this operation does not need /* Decrypt key data here so that this operation does not need
* to be implemented separately for each message type. */ * to be implemented separately for each message type. */
if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) { if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 && sm->ptk.kek_len == 16) {
#ifdef CONFIG_NO_RC4
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"WPA: RC4 not supported in the build");
return -1;
#else /* CONFIG_NO_RC4 */
u8 ek[32]; u8 ek[32];
os_memcpy(ek, key->key_iv, 16); os_memcpy(ek, key->key_iv, 16);
os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len); os_memcpy(ek + 16, sm->ptk.kek, sm->ptk.kek_len);
@ -1585,6 +1596,7 @@ static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
return -1; return -1;
} }
os_memset(ek, 0, sizeof(ek)); os_memset(ek, 0, sizeof(ek));
#endif /* CONFIG_NO_RC4 */
} else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES || } else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES ||
ver == WPA_KEY_INFO_TYPE_AES_128_CMAC || ver == WPA_KEY_INFO_TYPE_AES_128_CMAC ||
sm->key_mgmt == WPA_KEY_MGMT_OSEN || sm->key_mgmt == WPA_KEY_MGMT_OSEN ||

View file

@ -1245,11 +1245,17 @@ DESOBJS += src/crypto/des-internal.c
endif endif
endif endif
ifdef CONFIG_NO_RC4
L_CFLAGS += -DCONFIG_NO_RC4
endif
ifdef NEED_RC4 ifdef NEED_RC4
ifdef CONFIG_INTERNAL_RC4 ifdef CONFIG_INTERNAL_RC4
ifndef CONFIG_NO_RC4
OBJS += src/crypto/rc4.c OBJS += src/crypto/rc4.c
endif endif
endif endif
endif
SHA256OBJS = # none by default SHA256OBJS = # none by default
ifdef NEED_SHA256 ifdef NEED_SHA256

View file

@ -1256,11 +1256,17 @@ DESOBJS += ../src/crypto/des-internal.o
endif endif
endif endif
ifdef CONFIG_NO_RC4
CFLAGS += -DCONFIG_NO_RC4
endif
ifdef NEED_RC4 ifdef NEED_RC4
ifdef CONFIG_INTERNAL_RC4 ifdef CONFIG_INTERNAL_RC4
ifndef CONFIG_NO_RC4
OBJS += ../src/crypto/rc4.o OBJS += ../src/crypto/rc4.o
endif endif
endif endif
endif
SHA256OBJS = # none by default SHA256OBJS = # none by default
ifdef NEED_SHA256 ifdef NEED_SHA256