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
}