Submitted By: Douglas R. Reno Date: 2021-12-28 Initial Package Version: 2.9 Origin: Fedora Rawhide (https://src.fedoraproject.org/rpms/wpa_supplicant/tree/rawhide) Upstream Status: Applied Description: Fixes several runtime issues with OpenSSL-3.0.0. These include the inability to connect to networks and for connections to crash at random whenever the wireless access point changes its cipher. Also fixes issues with EAP-TLS/MSCHAPv2 and deprecation warnings. The inability to connect to networks is caused by a change in behavior in DES_key_schedule. diff -Naurp wpa_supplicant-2.9.orig/src/crypto/crypto_openssl.c wpa_supplicant-2.9/src/crypto/crypto_openssl.c --- wpa_supplicant-2.9.orig/src/crypto/crypto_openssl.c 2019-08-07 08:25:25.000000000 -0500 +++ wpa_supplicant-2.9/src/crypto/crypto_openssl.c 2021-12-28 11:39:43.145966953 -0600 @@ -195,8 +195,8 @@ int md4_vector(size_t num_elem, const u8 int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) { u8 pkey[8], next, tmp; - int i; - DES_key_schedule ks; + int i, plen, ret = -1; + EVP_CIPHER_CTX *ctx; /* Add parity bits to the key */ next = 0; @@ -207,10 +207,19 @@ int des_encrypt(const u8 *clear, const u } pkey[i] = next | 1; - DES_set_key((DES_cblock *) &pkey, &ks); - DES_ecb_encrypt((DES_cblock *) clear, (DES_cblock *) cypher, &ks, - DES_ENCRYPT); - return 0; + ctx = EVP_CIPHER_CTX_new(); + if (ctx && + EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, pkey, NULL) == 1 && + EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 && + EVP_EncryptUpdate(ctx, cypher, &plen, clear, 8) == 1 && + EVP_EncryptFinal_ex(ctx, &cypher[plen], &plen) == 1) + ret = 0; + else + wpa_printf(MSG_ERROR, "OpenSSL: DES encrypt failed"); + + if (ctx) + EVP_CIPHER_CTX_free(ctx); + return ret; } @@ -228,8 +237,8 @@ int rc4_skip(const u8 *key, size_t keyle ctx = EVP_CIPHER_CTX_new(); if (!ctx || - !EVP_CIPHER_CTX_set_padding(ctx, 0) || !EVP_CipherInit_ex(ctx, EVP_rc4(), NULL, NULL, NULL, 1) || + !EVP_CIPHER_CTX_set_padding(ctx, 0) || !EVP_CIPHER_CTX_set_key_length(ctx, keylen) || !EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, 1)) goto out; @@ -688,9 +697,9 @@ struct crypto_cipher * crypto_cipher_ini return NULL; } - if (!(ctx->enc = EVP_CIPHER_CTX_new()) || - !EVP_CIPHER_CTX_set_padding(ctx->enc, 0) || + if (!(ctx->enc = EVP_CIPHER_CTX_new()) || !EVP_EncryptInit_ex(ctx->enc, cipher, NULL, NULL, NULL) || + !EVP_CIPHER_CTX_set_padding(ctx->enc, 0) || !EVP_CIPHER_CTX_set_key_length(ctx->enc, key_len) || !EVP_EncryptInit_ex(ctx->enc, NULL, NULL, key, iv)) { if (ctx->enc) @@ -700,8 +709,8 @@ struct crypto_cipher * crypto_cipher_ini } if (!(ctx->dec = EVP_CIPHER_CTX_new()) || - !EVP_CIPHER_CTX_set_padding(ctx->dec, 0) || !EVP_DecryptInit_ex(ctx->dec, cipher, NULL, NULL, NULL) || + !EVP_CIPHER_CTX_set_padding(ctx->dec, 0) || !EVP_CIPHER_CTX_set_key_length(ctx->dec, key_len) || !EVP_DecryptInit_ex(ctx->dec, NULL, NULL, key, iv)) { EVP_CIPHER_CTX_free(ctx->enc); diff -Naurp wpa_supplicant-2.9.orig/src/crypto/tls_openssl.c wpa_supplicant-2.9/src/crypto/tls_openssl.c --- wpa_supplicant-2.9.orig/src/crypto/tls_openssl.c 2019-08-07 08:25:25.000000000 -0500 +++ wpa_supplicant-2.9/src/crypto/tls_openssl.c 2021-12-28 11:30:26.624779224 -0600 @@ -1044,6 +1044,8 @@ void * tls_init(const struct tls_config SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv2); SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv3); + SSL_CTX_set_mode(ssl, SSL_MODE_AUTO_RETRY); + #ifdef SSL_MODE_NO_AUTO_CHAIN /* Number of deployed use cases assume the default OpenSSL behavior of * auto chaining the local certificate is in use. BoringSSL removed this @@ -2951,16 +2953,12 @@ static int tls_set_conn_flags(struct tls /* Explicit request to enable TLS versions even if needing to * override systemwide policies. */ - if (flags & TLS_CONN_ENABLE_TLSv1_0) { + if (flags & TLS_CONN_ENABLE_TLSv1_0) version = TLS1_VERSION; - } else if (flags & TLS_CONN_ENABLE_TLSv1_1) { - if (!(flags & TLS_CONN_DISABLE_TLSv1_0)) - version = TLS1_1_VERSION; - } else if (flags & TLS_CONN_ENABLE_TLSv1_2) { - if (!(flags & (TLS_CONN_DISABLE_TLSv1_0 | - TLS_CONN_DISABLE_TLSv1_1))) - version = TLS1_2_VERSION; - } + else if (flags & TLS_CONN_ENABLE_TLSv1_1) + version = TLS1_1_VERSION; + else if (flags & TLS_CONN_ENABLE_TLSv1_2) + version = TLS1_2_VERSION; if (!version) { wpa_printf(MSG_DEBUG, "OpenSSL: Invalid TLS version configuration"); @@ -2974,6 +2972,18 @@ static int tls_set_conn_flags(struct tls } } #endif /* >= 1.1.0 */ +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) && \ + !defined (OPENSSL_IS_BORINGSSL) + if ((flags & (TLS_CONN_ENABLE_TLSv1_0 | TLS_CONN_ENABLE_TLSv1_1)) && + SSL_get_security_level(ssl) >= 2) { + /* + * Need to drop to security level 1 to allow TLS versions older + * than 1.2 to be used when explicitly enabled in configuration. + */ + SSL_set_security_level(conn->ssl, 1); + } +#endif #ifdef CONFIG_SUITEB #ifdef OPENSSL_IS_BORINGSSL @@ -4431,10 +4441,18 @@ struct wpabuf * tls_connection_decrypt(v return NULL; res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf)); if (res < 0) { - tls_show_errors(MSG_INFO, __func__, - "Decryption failed - SSL_read"); - wpabuf_free(buf); - return NULL; + int err = SSL_get_error(conn->ssl, res); + + if (err == SSL_ERROR_WANT_READ) { + wpa_printf(MSG_DEBUG, + "SSL: SSL_connect - want more data"); + res = 0; + } else { + tls_show_errors(MSG_INFO, __func__, + "Decryption failed - SSL_read"); + wpabuf_free(buf); + return NULL; + } } wpabuf_put(buf, res); diff -Naurp wpa_supplicant-2.9.orig/src/eap_peer/eap_peap.c wpa_supplicant-2.9/src/eap_peer/eap_peap.c --- wpa_supplicant-2.9.orig/src/eap_peer/eap_peap.c 2019-08-07 08:25:25.000000000 -0500 +++ wpa_supplicant-2.9/src/eap_peer/eap_peap.c 2021-12-28 11:31:16.609525465 -0600 @@ -787,6 +787,10 @@ static int eap_peap_decrypt(struct eap_s res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted); if (res) return res; + if (wpabuf_len(in_decrypted) == 0) { + wpabuf_free(in_decrypted); + return 1; + } continue_req: wpa_hexdump_buf(MSG_DEBUG, "EAP-PEAP: Decrypted Phase 2 EAP", diff -Naurp wpa_supplicant-2.9.orig/src/eap_peer/eap_ttls.c wpa_supplicant-2.9/src/eap_peer/eap_ttls.c --- wpa_supplicant-2.9.orig/src/eap_peer/eap_ttls.c 2019-08-07 08:25:25.000000000 -0500 +++ wpa_supplicant-2.9/src/eap_peer/eap_ttls.c 2021-12-28 11:32:28.553160721 -0600 @@ -1424,6 +1424,7 @@ static int eap_ttls_decrypt(struct eap_s if ((in_data == NULL || wpabuf_len(in_data) == 0) && data->phase2_start) { +start: return eap_ttls_phase2_start(sm, data, ret, identifier, out_data); } @@ -1438,6 +1439,10 @@ static int eap_ttls_decrypt(struct eap_s retval = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted); if (retval) goto done; + if (wpabuf_len(in_decrypted) == 0) { + wpabuf_free(in_decrypted); + goto start; + } continue_req: data->phase2_start = 0;