Cumulative patch from commit e15dcf6d1bc2725388555523effca75b1ffab735

e15dcf6 nl8021: Avoid potential memory leak on error path
17d32eb Allow re-write of ip_addr* configurations to conf file.
bcce934 dbus: Restrict DeviceName size to 32 characters in setter
7c70fe2 Sort options and reduce printf calls in wpa_supplicant usage text
6b418ce Fix wpa_supplicant build with IEEE8021X_EAPOL=y and CONFIG_NO_WPA=y
03269d5 AP: Print interface name in more STA events
9e8fde2 AP: Fix Deauth/Disassoc TX status timeout handling
269f9d5 EAP peer: Use ifdef PCSC_FUNCS to get rid of compiler warnings
c6e0b4b FST: Get rid of gcc extensions in structure/array initialization
2e3a41a hs20-osu-client: Fix check for osu_nai being available
ac2053b OpenSSL: Clean up openssl_digest_vector() to use a single implementation
5c9a337 OpenSSL: Clean up crypto_hash_*() to use a single implementation
587b045 LibreSSL: Fix build with LibreSSL
0daa9f6 EAP-TTLS peer: Fix success after fragmented final Phase 2 message
1eb87ae OpenSSL: Use EVP_CIPHER_CTX_new() to work with OpenSSL 1.1.0
3fb3bea OpenSSL: Update session_secret callback to match OpenSSL 1.1.0 API
814f43c EAP server: Simplify EAP method registration call
49a26bb EAP peer: Simplify EAP method registration call
7ce5603 EAP-WSC peer: Remove unused state values
449a316 bsd: Optimize socket use
4653ceb nl80211: Report disassociated STA / lost peer for the correct BSS
38af042 Drop OpenSSL 0.9.8 patches to add EAP-FAST support

Change-Id: Ib88c54b382c322d6151ed77e08f83329f918e3e8
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 73b547d..071a4dc 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -31,6 +31,50 @@
 #include "sha384.h"
 #include "crypto.h"
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+/* Compatibility wrappers for older versions. */
+
+static int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx)
+{
+	return EVP_CIPHER_CTX_cleanup(ctx);
+}
+
+
+static HMAC_CTX * HMAC_CTX_new(void)
+{
+	HMAC_CTX *ctx;
+
+	ctx = os_zalloc(sizeof(*ctx));
+	if (ctx)
+		HMAC_CTX_init(ctx);
+	return ctx;
+}
+
+
+static void HMAC_CTX_free(HMAC_CTX *ctx)
+{
+	bin_clear_free(ctx, sizeof(*ctx));
+}
+
+
+static EVP_MD_CTX * EVP_MD_CTX_new(void)
+{
+	EVP_MD_CTX *ctx;
+
+	ctx = os_zalloc(sizeof(*ctx));
+	if (ctx)
+		EVP_MD_CTX_init(ctx);
+	return ctx;
+}
+
+
+static void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+{
+	bin_clear_free(ctx, sizeof(*ctx));
+}
+
+#endif /* OpenSSL version < 1.1.0 */
+
 static BIGNUM * get_group5_prime(void)
 {
 #ifdef OPENSSL_IS_BORINGSSL
@@ -65,7 +109,6 @@
 static int openssl_digest_vector(const EVP_MD *type, size_t num_elem,
 				 const u8 *addr[], const size_t *len, u8 *mac)
 {
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	EVP_MD_CTX *ctx;
 	size_t i;
 	unsigned int mac_len;
@@ -100,36 +143,6 @@
 	EVP_MD_CTX_free(ctx);
 
 	return 0;
-#else
-	EVP_MD_CTX ctx;
-	size_t i;
-	unsigned int mac_len;
-
-	if (TEST_FAIL())
-		return -1;
-
-	EVP_MD_CTX_init(&ctx);
-	if (!EVP_DigestInit_ex(&ctx, type, NULL)) {
-		wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestInit_ex failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		return -1;
-	}
-	for (i = 0; i < num_elem; i++) {
-		if (!EVP_DigestUpdate(&ctx, addr[i], len[i])) {
-			wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestUpdate "
-				   "failed: %s",
-				   ERR_error_string(ERR_get_error(), NULL));
-			return -1;
-		}
-	}
-	if (!EVP_DigestFinal(&ctx, mac, &mac_len)) {
-		wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestFinal failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		return -1;
-	}
-
-	return 0;
-#endif
 }
 
 
@@ -169,32 +182,34 @@
 #ifdef OPENSSL_NO_RC4
 	return -1;
 #else /* OPENSSL_NO_RC4 */
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX *ctx;
 	int outl;
 	int res = -1;
 	unsigned char skip_buf[16];
 
-	EVP_CIPHER_CTX_init(&ctx);
-	if (!EVP_CIPHER_CTX_set_padding(&ctx, 0) ||
-	    !EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, NULL, NULL, 1) ||
-	    !EVP_CIPHER_CTX_set_key_length(&ctx, keylen) ||
-	    !EVP_CipherInit_ex(&ctx, NULL, NULL, key, NULL, 1))
+	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_key_length(ctx, keylen) ||
+	    !EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, 1))
 		goto out;
 
 	while (skip >= sizeof(skip_buf)) {
 		size_t len = skip;
 		if (len > sizeof(skip_buf))
 			len = sizeof(skip_buf);
-		if (!EVP_CipherUpdate(&ctx, skip_buf, &outl, skip_buf, len))
+		if (!EVP_CipherUpdate(ctx, skip_buf, &outl, skip_buf, len))
 			goto out;
 		skip -= len;
 	}
 
-	if (EVP_CipherUpdate(&ctx, data, &outl, data, data_len))
+	if (EVP_CipherUpdate(ctx, data, &outl, data, data_len))
 		res = 0;
 
 out:
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	if (ctx)
+		EVP_CIPHER_CTX_reset(ctx);
 	return res;
 #endif /* OPENSSL_NO_RC4 */
 }
@@ -246,14 +261,16 @@
 	EVP_CIPHER_CTX *ctx;
 	const EVP_CIPHER *type;
 
+	if (TEST_FAIL())
+		return NULL;
+
 	type = aes_get_evp_cipher(len);
 	if (type == NULL)
 		return NULL;
 
-	ctx = os_malloc(sizeof(*ctx));
+	ctx = EVP_CIPHER_CTX_new();
 	if (ctx == NULL)
 		return NULL;
-	EVP_CIPHER_CTX_init(ctx);
 	if (EVP_EncryptInit_ex(ctx, type, NULL, key, NULL) != 1) {
 		os_free(ctx);
 		return NULL;
@@ -287,8 +304,8 @@
 		wpa_printf(MSG_ERROR, "OpenSSL: Unexpected padding length %d "
 			   "in AES encrypt", len);
 	}
-	EVP_CIPHER_CTX_cleanup(c);
-	bin_clear_free(c, sizeof(*c));
+	EVP_CIPHER_CTX_reset(c);
+	EVP_CIPHER_CTX_free(c);
 }
 
 
@@ -297,16 +314,18 @@
 	EVP_CIPHER_CTX *ctx;
 	const EVP_CIPHER *type;
 
+	if (TEST_FAIL())
+		return NULL;
+
 	type = aes_get_evp_cipher(len);
 	if (type == NULL)
 		return NULL;
 
-	ctx = os_malloc(sizeof(*ctx));
+	ctx = EVP_CIPHER_CTX_new();
 	if (ctx == NULL)
 		return NULL;
-	EVP_CIPHER_CTX_init(ctx);
 	if (EVP_DecryptInit_ex(ctx, type, NULL, key, NULL) != 1) {
-		os_free(ctx);
+		EVP_CIPHER_CTX_free(ctx);
 		return NULL;
 	}
 	EVP_CIPHER_CTX_set_padding(ctx, 0);
@@ -338,8 +357,8 @@
 		wpa_printf(MSG_ERROR, "OpenSSL: Unexpected padding length %d "
 			   "in AES decrypt", len);
 	}
-	EVP_CIPHER_CTX_cleanup(c);
-	bin_clear_free(c, sizeof(*c));
+	EVP_CIPHER_CTX_reset(c);
+	EVP_CIPHER_CTX_free(c);
 }
 
 
@@ -378,57 +397,56 @@
 
 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
 {
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX *ctx;
 	int clen, len;
 	u8 buf[16];
+	int res = -1;
 
 	if (TEST_FAIL())
 		return -1;
 
-	EVP_CIPHER_CTX_init(&ctx);
-	if (EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
+	ctx = EVP_CIPHER_CTX_new();
+	if (!ctx)
 		return -1;
-	EVP_CIPHER_CTX_set_padding(&ctx, 0);
-
 	clen = data_len;
-	if (EVP_EncryptUpdate(&ctx, data, &clen, data, data_len) != 1 ||
-	    clen != (int) data_len)
-		return -1;
-
 	len = sizeof(buf);
-	if (EVP_EncryptFinal_ex(&ctx, buf, &len) != 1 || len != 0)
-		return -1;
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	if (EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) == 1 &&
+	    EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 &&
+	    EVP_EncryptUpdate(ctx, data, &clen, data, data_len) == 1 &&
+	    clen == (int) data_len &&
+	    EVP_EncryptFinal_ex(ctx, buf, &len) == 1 && len == 0)
+		res = 0;
+	EVP_CIPHER_CTX_reset(ctx);
 
-	return 0;
+	return res;
 }
 
 
 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
 {
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX *ctx;
 	int plen, len;
 	u8 buf[16];
+	int res = -1;
 
 	if (TEST_FAIL())
 		return -1;
 
-	EVP_CIPHER_CTX_init(&ctx);
-	if (EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
+	ctx = EVP_CIPHER_CTX_new();
+	if (!ctx)
 		return -1;
-	EVP_CIPHER_CTX_set_padding(&ctx, 0);
-
 	plen = data_len;
-	if (EVP_DecryptUpdate(&ctx, data, &plen, data, data_len) != 1 ||
-	    plen != (int) data_len)
-		return -1;
-
 	len = sizeof(buf);
-	if (EVP_DecryptFinal_ex(&ctx, buf, &len) != 1 || len != 0)
-		return -1;
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	if (EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) == 1 &&
+	    EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 &&
+	    EVP_DecryptUpdate(ctx, data, &plen, data, data_len) == 1 &&
+	    plen == (int) data_len &&
+	    EVP_DecryptFinal_ex(ctx, buf, &len) == 1 && len == 0)
+		res = 0;
+	EVP_CIPHER_CTX_reset(ctx);
 
-	return 0;
+	return res;
+
 }
 
 
@@ -471,8 +489,8 @@
 
 
 struct crypto_cipher {
-	EVP_CIPHER_CTX enc;
-	EVP_CIPHER_CTX dec;
+	EVP_CIPHER_CTX *enc;
+	EVP_CIPHER_CTX *dec;
 };
 
 
@@ -533,23 +551,25 @@
 		return NULL;
 	}
 
-	EVP_CIPHER_CTX_init(&ctx->enc);
-	EVP_CIPHER_CTX_set_padding(&ctx->enc, 0);
-	if (!EVP_EncryptInit_ex(&ctx->enc, cipher, NULL, NULL, NULL) ||
-	    !EVP_CIPHER_CTX_set_key_length(&ctx->enc, key_len) ||
-	    !EVP_EncryptInit_ex(&ctx->enc, NULL, NULL, key, iv)) {
-		EVP_CIPHER_CTX_cleanup(&ctx->enc);
+	if (!(ctx->enc = EVP_CIPHER_CTX_new()) ||
+	    !EVP_CIPHER_CTX_set_padding(ctx->enc, 0) ||
+	    !EVP_EncryptInit_ex(ctx->enc, cipher, NULL, NULL, NULL) ||
+	    !EVP_CIPHER_CTX_set_key_length(ctx->enc, key_len) ||
+	    !EVP_EncryptInit_ex(ctx->enc, NULL, NULL, key, iv)) {
+		if (ctx->enc)
+			EVP_CIPHER_CTX_reset(ctx->enc);
 		os_free(ctx);
 		return NULL;
 	}
 
-	EVP_CIPHER_CTX_init(&ctx->dec);
-	EVP_CIPHER_CTX_set_padding(&ctx->dec, 0);
-	if (!EVP_DecryptInit_ex(&ctx->dec, cipher, NULL, NULL, NULL) ||
-	    !EVP_CIPHER_CTX_set_key_length(&ctx->dec, key_len) ||
-	    !EVP_DecryptInit_ex(&ctx->dec, NULL, NULL, key, iv)) {
-		EVP_CIPHER_CTX_cleanup(&ctx->enc);
-		EVP_CIPHER_CTX_cleanup(&ctx->dec);
+	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_key_length(ctx->dec, key_len) ||
+	    !EVP_DecryptInit_ex(ctx->dec, NULL, NULL, key, iv)) {
+		EVP_CIPHER_CTX_reset(ctx->enc);
+		if (ctx->dec)
+			EVP_CIPHER_CTX_reset(ctx->dec);
 		os_free(ctx);
 		return NULL;
 	}
@@ -562,7 +582,7 @@
 			  u8 *crypt, size_t len)
 {
 	int outl;
-	if (!EVP_EncryptUpdate(&ctx->enc, crypt, &outl, plain, len))
+	if (!EVP_EncryptUpdate(ctx->enc, crypt, &outl, plain, len))
 		return -1;
 	return 0;
 }
@@ -573,7 +593,7 @@
 {
 	int outl;
 	outl = len;
-	if (!EVP_DecryptUpdate(&ctx->dec, plain, &outl, crypt, len))
+	if (!EVP_DecryptUpdate(ctx->dec, plain, &outl, crypt, len))
 		return -1;
 	return 0;
 }
@@ -581,8 +601,8 @@
 
 void crypto_cipher_deinit(struct crypto_cipher *ctx)
 {
-	EVP_CIPHER_CTX_cleanup(&ctx->enc);
-	EVP_CIPHER_CTX_cleanup(&ctx->dec);
+	EVP_CIPHER_CTX_reset(ctx->enc);
+	EVP_CIPHER_CTX_reset(ctx->dec);
 	os_free(ctx);
 }
 
@@ -718,11 +738,7 @@
 
 
 struct crypto_hash {
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	HMAC_CTX *ctx;
-#else
-	HMAC_CTX ctx;
-#endif
 };
 
 
@@ -757,7 +773,6 @@
 	ctx = os_zalloc(sizeof(*ctx));
 	if (ctx == NULL)
 		return NULL;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	ctx->ctx = HMAC_CTX_new();
 	if (!ctx->ctx) {
 		os_free(ctx);
@@ -769,14 +784,6 @@
 		bin_clear_free(ctx, sizeof(*ctx));
 		return NULL;
 	}
-#else
-	HMAC_CTX_init(&ctx->ctx);
-
-	if (HMAC_Init_ex(&ctx->ctx, key, key_len, md, NULL) != 1) {
-		bin_clear_free(ctx, sizeof(*ctx));
-		return NULL;
-	}
-#endif
 
 	return ctx;
 }
@@ -786,11 +793,7 @@
 {
 	if (ctx == NULL)
 		return;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	HMAC_Update(ctx->ctx, data, len);
-#else
-	HMAC_Update(&ctx->ctx, data, len);
-#endif
 }
 
 
@@ -803,21 +806,14 @@
 		return -2;
 
 	if (mac == NULL || len == NULL) {
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 		HMAC_CTX_free(ctx->ctx);
-#endif
 		bin_clear_free(ctx, sizeof(*ctx));
 		return 0;
 	}
 
 	mdlen = *len;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	res = HMAC_Final(ctx->ctx, mac, &mdlen);
 	HMAC_CTX_free(ctx->ctx);
-#else
-	res = HMAC_Final(&ctx->ctx, mac, &mdlen);
-	HMAC_CTX_cleanup(&ctx->ctx);
-#endif
 	bin_clear_free(ctx, sizeof(*ctx));
 
 	if (res == 1) {
@@ -834,7 +830,6 @@
 			       const u8 *addr[], const size_t *len, u8 *mac,
 			       unsigned int mdlen)
 {
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 	HMAC_CTX *ctx;
 	size_t i;
 	int res;
@@ -857,26 +852,6 @@
 	HMAC_CTX_free(ctx);
 
 	return res == 1 ? 0 : -1;
-#else
-	HMAC_CTX ctx;
-	size_t i;
-	int res;
-
-	if (TEST_FAIL())
-		return -1;
-
-	HMAC_CTX_init(&ctx);
-	if (HMAC_Init_ex(&ctx, key, key_len, type, NULL) != 1)
-		return -1;
-
-	for (i = 0; i < num_elem; i++)
-		HMAC_Update(&ctx, addr[i], len[i]);
-
-	res = HMAC_Final(&ctx, mac, &mdlen);
-	HMAC_CTX_cleanup(&ctx);
-
-	return res == 1 ? 0 : -1;
-#endif
 }