Revert "Revert "[wpa_supplicant] cumilative patch from commit 3a..."

Revert submission 28102966-revert-26533062-Supplicant_merge_June24-CUATTSRBBR

Reason for revert: Fixed the regression issue (ag/28389573)

Reverted changes: /q/submissionid:28102966-revert-26533062-Supplicant_merge_June24-CUATTSRBBR

Bug: 329004037
Test: Turn ON/OFF SoftAp multiple times

Change-Id: Ibfff2a847be5678f1a6d77e28506a05936812a91
diff --git a/src/crypto/crypto_module_tests.c b/src/crypto/crypto_module_tests.c
index 4147f41..ffeddba 100644
--- a/src/crypto/crypto_module_tests.c
+++ b/src/crypto/crypto_module_tests.c
@@ -2446,6 +2446,7 @@
 	wpabuf_free(res_pt);
 	wpabuf_free(res_ct);
 	crypto_ec_key_deinit(own_priv);
+	crypto_ec_key_deinit(peer_pub);
 	return res;
 }
 
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 22f6ab4..427677d 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -1,6 +1,6 @@
 /*
  * Wrapper functions for OpenSSL libcrypto
- * Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2024, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -31,6 +31,11 @@
 #else /* OpenSSL version >= 3.0 */
 #include <openssl/cmac.h>
 #endif /* OpenSSL version >= 3.0 */
+#ifdef CONFIG_DPP3
+#if OPENSSL_VERSION_NUMBER >= 0x30200000L
+#include <openssl/hpke.h>
+#endif
+#endif /* CONFIG_DPP3 */
 
 #include "common.h"
 #include "utils/const_time.h"
@@ -471,11 +476,11 @@
 	ctx = EVP_CIPHER_CTX_new();
 	if (ctx == NULL)
 		return NULL;
-	if (EVP_EncryptInit_ex(ctx, type, NULL, key, NULL) != 1) {
+	if (EVP_EncryptInit_ex(ctx, type, NULL, key, NULL) != 1 ||
+	    EVP_CIPHER_CTX_set_padding(ctx, 0) != 1) {
 		EVP_CIPHER_CTX_free(ctx);
 		return NULL;
 	}
-	EVP_CIPHER_CTX_set_padding(ctx, 0);
 	return ctx;
 }
 
@@ -528,11 +533,11 @@
 	ctx = EVP_CIPHER_CTX_new();
 	if (ctx == NULL)
 		return NULL;
-	if (EVP_DecryptInit_ex(ctx, type, NULL, key, NULL) != 1) {
+	if (EVP_DecryptInit_ex(ctx, type, NULL, key, NULL) != 1 ||
+	    EVP_CIPHER_CTX_set_padding(ctx, 0) != 1) {
 		EVP_CIPHER_CTX_free(ctx);
 		return NULL;
 	}
-	EVP_CIPHER_CTX_set_padding(ctx, 0);
 	return ctx;
 }
 
@@ -1313,6 +1318,7 @@
 #else /* OpenSSL version >= 3.0 */
 	HMAC_CTX *ctx;
 #endif /* OpenSSL version >= 3.0 */
+	bool failed;
 };
 
 
@@ -1425,9 +1431,11 @@
 	if (ctx == NULL)
 		return;
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
-	EVP_MAC_update(ctx->ctx, data, len);
+	if (!EVP_MAC_update(ctx->ctx, data, len))
+		ctx->failed = true;
 #else /* OpenSSL version >= 3.0 */
-	HMAC_Update(ctx->ctx, data, len);
+	if (!HMAC_Update(ctx->ctx, data, len))
+		ctx->failed = true;
 #endif /* OpenSSL version >= 3.0 */
 }
 
@@ -1437,6 +1445,7 @@
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
 	size_t mdlen;
 	int res;
+	bool failed;
 
 	if (!ctx)
 		return -2;
@@ -1455,11 +1464,15 @@
 	}
 	res = EVP_MAC_final(ctx->ctx, mac, &mdlen, mdlen);
 	EVP_MAC_CTX_free(ctx->ctx);
+	failed = ctx->failed;
 	bin_clear_free(ctx, sizeof(*ctx));
 
 	if (TEST_FAIL())
 		return -1;
 
+	if (failed)
+		return -2;
+
 	if (res == 1) {
 		*len = mdlen;
 		return 0;
@@ -1469,6 +1482,7 @@
 #else /* OpenSSL version >= 3.0 */
 	unsigned int mdlen;
 	int res;
+	bool failed;
 
 	if (ctx == NULL)
 		return -2;
@@ -1482,11 +1496,15 @@
 	mdlen = *len;
 	res = HMAC_Final(ctx->ctx, mac, &mdlen);
 	HMAC_CTX_free(ctx->ctx);
+	failed = ctx->failed;
 	bin_clear_free(ctx, sizeof(*ctx));
 
 	if (TEST_FAIL())
 		return -1;
 
+	if (failed)
+		return -2;
+
 	if (res == 1) {
 		*len = mdlen;
 		return 0;
@@ -2841,8 +2859,10 @@
 
 	/* Encode using SECG SEC 1, Sec. 2.3.4 format */
 	peer = os_malloc(1 + len);
-	if (!peer)
+	if (!peer) {
+		EVP_PKEY_free(peerkey);
 		return NULL;
+	}
 	peer[0] = inc_y ? 0x04 : 0x02;
 	os_memcpy(peer + 1, key, len);
 
@@ -2997,11 +3017,15 @@
 		NULL, NULL);
 	if (!ctx ||
 	    OSSL_DECODER_from_data(ctx, &der, &der_len) != 1) {
-		wpa_printf(MSG_INFO, "OpenSSL: Decoding EC private key (DER) failed: %s",
+		wpa_printf(MSG_INFO,
+			   "OpenSSL: Decoding EC private key (DER) failed: %s",
 			   ERR_error_string(ERR_get_error(), NULL));
+		if (ctx)
+			OSSL_DECODER_CTX_free(ctx);
 		goto fail;
 	}
 
+	OSSL_DECODER_CTX_free(ctx);
 	return (struct crypto_ec_key *) pkey;
 fail:
 	crypto_ec_key_deinit((struct crypto_ec_key *) pkey);
@@ -5125,13 +5149,13 @@
 }
 
 
-struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id,
-			       enum hpke_kdf_id kdf_id,
-			       enum hpke_aead_id aead_id,
-			       struct crypto_ec_key *peer_pub,
-			       const u8 *info, size_t info_len,
-			       const u8 *aad, size_t aad_len,
-			       const u8 *pt, size_t pt_len)
+static struct wpabuf * hpke_base_seal_int(enum hpke_kem_id kem_id,
+					  enum hpke_kdf_id kdf_id,
+					  enum hpke_aead_id aead_id,
+					  struct crypto_ec_key *peer_pub,
+					  const u8 *info, size_t info_len,
+					  const u8 *aad, size_t aad_len,
+					  const u8 *pt, size_t pt_len)
 {
 	struct hpke_context *ctx;
 	u8 shared_secret[HPKE_MAX_SHARED_SECRET_LEN];
@@ -5289,13 +5313,13 @@
 }
 
 
-struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id,
-			       enum hpke_kdf_id kdf_id,
-			       enum hpke_aead_id aead_id,
-			       struct crypto_ec_key *own_priv,
-			       const u8 *info, size_t info_len,
-			       const u8 *aad, size_t aad_len,
-			       const u8 *enc_ct, size_t enc_ct_len)
+static struct wpabuf * hpke_base_open_int(enum hpke_kem_id kem_id,
+					  enum hpke_kdf_id kdf_id,
+					  enum hpke_aead_id aead_id,
+					  struct crypto_ec_key *own_priv,
+					  const u8 *info, size_t info_len,
+					  const u8 *aad, size_t aad_len,
+					  const u8 *enc_ct, size_t enc_ct_len)
 {
 	struct hpke_context *ctx;
 	u8 shared_secret[HPKE_MAX_SHARED_SECRET_LEN];
@@ -5324,6 +5348,231 @@
 	return pt;
 }
 
+
+#if OPENSSL_VERSION_NUMBER >= 0x30200000L
+
+static bool hpke_set_suite(OSSL_HPKE_SUITE *suite,
+			   enum hpke_kem_id kem_id,
+			   enum hpke_kdf_id kdf_id,
+			   enum hpke_aead_id aead_id)
+{
+	os_memset(suite, 0, sizeof(*suite));
+
+	switch (kem_id) {
+	case HPKE_DHKEM_P256_HKDF_SHA256:
+		suite->kem_id = OSSL_HPKE_KEM_ID_P256;
+		break;
+	case HPKE_DHKEM_P384_HKDF_SHA384:
+		suite->kem_id = OSSL_HPKE_KEM_ID_P384;
+		break;
+	case HPKE_DHKEM_P521_HKDF_SHA512:
+		suite->kem_id = OSSL_HPKE_KEM_ID_P521;
+		break;
+	default:
+		return false;
+	}
+
+	switch (kdf_id) {
+	case HPKE_KDF_HKDF_SHA256:
+		suite->kdf_id = OSSL_HPKE_KDF_ID_HKDF_SHA256;
+		break;
+	case HPKE_KDF_HKDF_SHA384:
+		suite->kdf_id = OSSL_HPKE_KDF_ID_HKDF_SHA384;
+		break;
+	case HPKE_KDF_HKDF_SHA512:
+		suite->kdf_id = OSSL_HPKE_KDF_ID_HKDF_SHA512;
+		break;
+	default:
+		return false;
+	}
+
+	switch (aead_id) {
+	case HPKE_AEAD_AES_128_GCM:
+		suite->aead_id = OSSL_HPKE_AEAD_ID_AES_GCM_128;
+		break;
+	case HPKE_AEAD_AES_256_GCM:
+		suite->aead_id = OSSL_HPKE_AEAD_ID_AES_GCM_256;
+		break;
+	default:
+		return false;
+	}
+
+	if (!OSSL_HPKE_suite_check(*suite)) {
+		wpa_printf(MSG_INFO,
+			   "OpenSSL: HPKE suite kem_id=%d kdf_id=%d aead_id=%d not supported",
+			   kem_id, kdf_id, aead_id);
+		return false;
+	}
+
+	return true;
+}
+
+
+struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id,
+			       enum hpke_kdf_id kdf_id,
+			       enum hpke_aead_id aead_id,
+			       struct crypto_ec_key *peer_pub,
+			       const u8 *info, size_t info_len,
+			       const u8 *aad, size_t aad_len,
+			       const u8 *pt, size_t pt_len)
+{
+	OSSL_HPKE_SUITE suite;
+	OSSL_HPKE_CTX *ctx = NULL;
+	struct wpabuf *res = NULL, *buf, *pub = NULL;
+	size_t enc_len, ct_len;
+	int group;
+
+	group = crypto_ec_key_group(peer_pub);
+	if (group == 28 || group == 29 || group == 30) {
+		/* Use the internal routines for the special DPP use case with
+		 * brainpool curves, */
+		return hpke_base_seal_int(kem_id, kdf_id, aead_id, peer_pub,
+					  info, info_len, aad, aad_len,
+					  pt, pt_len);
+	}
+
+
+	if (!hpke_set_suite(&suite, kem_id, kdf_id, aead_id))
+		return NULL;
+
+	enc_len = OSSL_HPKE_get_public_encap_size(suite);
+	ct_len = OSSL_HPKE_get_ciphertext_size(suite, pt_len);
+	buf = wpabuf_alloc(enc_len + ct_len);
+	if (!buf)
+		goto out;
+
+	pub = crypto_ec_key_get_pubkey_point(peer_pub, 1);
+	if (!pub)
+		goto out;
+
+	ctx = OSSL_HPKE_CTX_new(OSSL_HPKE_MODE_BASE, suite,
+				OSSL_HPKE_ROLE_SENDER, NULL, NULL);
+	if (!ctx)
+		goto out;
+
+	if (OSSL_HPKE_encap(ctx, wpabuf_put(buf, 0), &enc_len,
+			    wpabuf_head(pub), wpabuf_len(pub),
+			    info, info_len) != 1) {
+		wpa_printf(MSG_DEBUG, "OpenSSL: OSSL_HPKE_encap failed: %s",
+			   ERR_error_string(ERR_get_error(), NULL));
+		goto out;
+	}
+	wpabuf_put(buf, enc_len);
+
+	if (OSSL_HPKE_seal(ctx, wpabuf_put(buf, 0), &ct_len, aad, aad_len,
+			   pt, pt_len) != 1) {
+		wpa_printf(MSG_DEBUG, "OpenSSL: OSSL_HPKE_seal failed: %s",
+			   ERR_error_string(ERR_get_error(), NULL));
+		goto out;
+	}
+	wpabuf_put(buf, ct_len);
+	res = buf;
+	buf = NULL;
+
+out:
+	OSSL_HPKE_CTX_free(ctx);
+	wpabuf_free(buf);
+	wpabuf_free(pub);
+	return res;
+}
+
+
+struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id,
+			       enum hpke_kdf_id kdf_id,
+			       enum hpke_aead_id aead_id,
+			       struct crypto_ec_key *own_priv,
+			       const u8 *info, size_t info_len,
+			       const u8 *aad, size_t aad_len,
+			       const u8 *enc_ct, size_t enc_ct_len)
+{
+	OSSL_HPKE_SUITE suite;
+	OSSL_HPKE_CTX *ctx;
+	struct wpabuf *buf = NULL, *res = NULL;
+	size_t len, enc_len;
+	int group;
+
+	group = crypto_ec_key_group(own_priv);
+	if (group == 28 || group == 29 || group == 30) {
+		/* Use the internal routines for the special DPP use case with
+		 * brainpool curves, */
+		return hpke_base_open_int(kem_id, kdf_id, aead_id, own_priv,
+					  info, info_len, aad, aad_len,
+					  enc_ct, enc_ct_len);
+	}
+
+	if (!hpke_set_suite(&suite, kem_id, kdf_id, aead_id))
+		return NULL;
+
+	enc_len = OSSL_HPKE_get_public_encap_size(suite);
+	if (enc_ct_len < enc_len) {
+		wpa_printf(MSG_DEBUG, "OpenSSL: Too short HPKE enc_ct data");
+		return NULL;
+	}
+
+	ctx = OSSL_HPKE_CTX_new(OSSL_HPKE_MODE_BASE, suite,
+				OSSL_HPKE_ROLE_RECEIVER, NULL, NULL);
+	if (!ctx)
+		goto out;
+
+	if (OSSL_HPKE_decap(ctx, enc_ct, enc_len, (EVP_PKEY *) own_priv,
+			    info, info_len) != 1) {
+		wpa_printf(MSG_DEBUG, "OpenSSL: OSSL_HPKE_decap failed: %s",
+			   ERR_error_string(ERR_get_error(), NULL));
+		goto out;
+	}
+
+	len = enc_ct_len;
+	buf = wpabuf_alloc(len);
+	if (!buf)
+		goto out;
+
+	if (OSSL_HPKE_open(ctx, wpabuf_put(buf, 0), &len, aad, aad_len,
+			   enc_ct + enc_len, enc_ct_len - enc_len) != 1) {
+		wpa_printf(MSG_DEBUG, "OpenSSL: OSSL_HPKE_open failed: %s",
+			   ERR_error_string(ERR_get_error(), NULL));
+		goto out;
+	}
+
+	wpabuf_put(buf, len);
+	res = buf;
+	buf = NULL;
+
+out:
+	OSSL_HPKE_CTX_free(ctx);
+	wpabuf_free(buf);
+	return res;
+}
+
+#else /* OpenSSL < 3.2 */
+
+struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id,
+			       enum hpke_kdf_id kdf_id,
+			       enum hpke_aead_id aead_id,
+			       struct crypto_ec_key *peer_pub,
+			       const u8 *info, size_t info_len,
+			       const u8 *aad, size_t aad_len,
+			       const u8 *pt, size_t pt_len)
+{
+	return hpke_base_seal_int(kem_id, kdf_id, aead_id, peer_pub,
+				  info, info_len, aad, aad_len, pt, pt_len);
+}
+
+
+struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id,
+			       enum hpke_kdf_id kdf_id,
+			       enum hpke_aead_id aead_id,
+			       struct crypto_ec_key *own_priv,
+			       const u8 *info, size_t info_len,
+			       const u8 *aad, size_t aad_len,
+			       const u8 *enc_ct, size_t enc_ct_len)
+{
+	return hpke_base_open_int(kem_id, kdf_id, aead_id, own_priv,
+				  info, info_len, aad, aad_len,
+				  enc_ct, enc_ct_len);
+}
+
+#endif /* OpenSSL < 3.2 */
+
 #endif /* CONFIG_DPP3 */
 
 
diff --git a/src/crypto/sha256-internal.c b/src/crypto/sha256-internal.c
index ff1e2ba..81e6e5e 100644
--- a/src/crypto/sha256-internal.c
+++ b/src/crypto/sha256-internal.c
@@ -76,9 +76,6 @@
 #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)
diff --git a/src/crypto/sha512-internal.c b/src/crypto/sha512-internal.c
index c026394..8e98a9c 100644
--- a/src/crypto/sha512-internal.c
+++ b/src/crypto/sha512-internal.c
@@ -97,9 +97,6 @@
 #define Sigma1(x)       (S(x, 14) ^ S(x, 18) ^ S(x, 41))
 #define Gamma0(x)       (S(x, 1) ^ S(x, 8) ^ R(x, 7))
 #define Gamma1(x)       (S(x, 19) ^ S(x, 61) ^ R(x, 6))
-#ifndef MIN
-#define MIN(x, y) (((x) < (y)) ? (x) : (y))
-#endif
 
 #define ROR64c(x, y) \
     ( ((((x) & CONST64(0xFFFFFFFFFFFFFFFF)) >> ((u64) (y) & CONST64(63))) | \
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 103c333..f5d734d 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -19,14 +19,16 @@
 #endif
 #endif
 
+#ifndef OPENSSL_NO_ENGINE
+/* OpenSSL 3.0 has moved away from the engine API */
+#define OPENSSL_SUPPRESS_DEPRECATED
+#include <openssl/engine.h>
+#endif /* OPENSSL_NO_ENGINE */
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 #include <openssl/opensslv.h>
 #include <openssl/pkcs12.h>
 #include <openssl/x509v3.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif /* OPENSSL_NO_ENGINE */
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
 #include <openssl/core_names.h>
 #include <openssl/decoder.h>
@@ -152,6 +154,7 @@
 	unsigned int crl_reload_interval;
 	struct os_reltime crl_last_reload;
 	char *check_cert_subject;
+	char *openssl_ciphers;
 };
 
 struct tls_connection {
@@ -1261,6 +1264,7 @@
 	}
 
 	os_free(data->check_cert_subject);
+	os_free(data->openssl_ciphers);
 	os_free(data);
 }
 
@@ -3249,6 +3253,9 @@
 	}
 #endif
 
+	if (!openssl_ciphers)
+		openssl_ciphers = conn->data->openssl_ciphers;
+
 #ifdef CONFIG_SUITEB
 #ifdef OPENSSL_IS_BORINGSSL
 	/* Start with defaults from BoringSSL */
@@ -5749,6 +5756,14 @@
 		return -1;
 	}
 
+	os_free(data->openssl_ciphers);
+	if (params->openssl_ciphers) {
+		data->openssl_ciphers = os_strdup(params->openssl_ciphers);
+		if (!data->openssl_ciphers)
+			return -1;
+	} else {
+		data->openssl_ciphers = NULL;
+	}
 	if (params->openssl_ciphers &&
 	    SSL_CTX_set_cipher_list(ssl_ctx, params->openssl_ciphers) != 1) {
 		wpa_printf(MSG_INFO,