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_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 */