Cumulative patch from commit e8c08c9a363340c45baf8e13c758c99078bc0d8b
e8c08c9 EAP-FAST server: Fix potential read-after-buffer (by one byte)
8b65fef Interworking: Remove unnecessary placeholder for PAME-BI
27a725c EAP: Do not allow fast session resumption with different network block
52f4abf P2P: Remove PSK/passphrase from P2P-GROUP-STARTED debug log entry
f8723e1 P2P: Use a helper function for P2P_EVENT_GROUP_STARTED events
905c722 Add wpa_msg_global_ctrl()
1f1fe19 EAP-pwd: Clear identity string and temporary buffer explicitly
f119d66 EAP-pwd: Verify BN_rand_range return code
5197f03 EAP-pwd: Use os_memcmp_const() for hash comparisons
26c10f7 OpenSSL: Use EC_POINT_clear_free instead of EC_POINT_free
3248071 OpenSSL: Use BN_clear_free instead of BN_free
870dfe9 EAP-TTLS: Remove FreeRADIUS workaround for EAP-TTLS/MSCHAPv2
Bug: 15615050, 16493485
Change-Id: I7028a61ad6dbda1f336376cc0568b81046045725
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 817ee2d..f02aaac 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -340,10 +340,10 @@
ret = 0;
error:
- BN_free(bn_base);
- BN_free(bn_exp);
- BN_free(bn_modulus);
- BN_free(bn_result);
+ BN_clear_free(bn_base);
+ BN_clear_free(bn_exp);
+ BN_clear_free(bn_modulus);
+ BN_clear_free(bn_result);
BN_CTX_free(ctx);
return ret;
}
@@ -571,12 +571,12 @@
if (keylen < 0)
goto err;
wpabuf_put(res, keylen);
- BN_free(pub_key);
+ BN_clear_free(pub_key);
return res;
err:
- BN_free(pub_key);
+ BN_clear_free(pub_key);
wpabuf_free(res);
return NULL;
}
@@ -1066,7 +1066,7 @@
{
if (e == NULL)
return;
- BN_free(e->order);
+ BN_clear_free(e->order);
EC_GROUP_free(e->group);
BN_CTX_free(e->bnctx);
os_free(e);
@@ -1138,8 +1138,8 @@
ret = 0;
}
- BN_free(x_bn);
- BN_free(y_bn);
+ BN_clear_free(x_bn);
+ BN_clear_free(y_bn);
return ret;
}
@@ -1155,20 +1155,20 @@
y = BN_bin2bn(val + len, len, NULL);
elem = EC_POINT_new(e->group);
if (x == NULL || y == NULL || elem == NULL) {
- BN_free(x);
- BN_free(y);
- EC_POINT_free(elem);
+ BN_clear_free(x);
+ BN_clear_free(y);
+ EC_POINT_clear_free(elem);
return NULL;
}
if (!EC_POINT_set_affine_coordinates_GFp(e->group, elem, x, y,
e->bnctx)) {
- EC_POINT_free(elem);
+ EC_POINT_clear_free(elem);
elem = NULL;
}
- BN_free(x);
- BN_free(y);
+ BN_clear_free(x);
+ BN_clear_free(y);
return (struct crypto_ec_point *) elem;
}
diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c
index 96c9efd..fdcff7f 100644
--- a/src/eap_common/eap_pwd_common.c
+++ b/src/eap_common/eap_pwd_common.c
@@ -263,18 +263,18 @@
fail:
EC_GROUP_free(grp->group);
grp->group = NULL;
- EC_POINT_free(grp->pwe);
+ EC_POINT_clear_free(grp->pwe);
grp->pwe = NULL;
- BN_free(grp->order);
+ BN_clear_free(grp->order);
grp->order = NULL;
- BN_free(grp->prime);
+ BN_clear_free(grp->prime);
grp->prime = NULL;
ret = 1;
}
/* cleanliness and order.... */
- BN_free(cofactor);
- BN_free(x_candidate);
- BN_free(rnd);
+ BN_clear_free(cofactor);
+ BN_clear_free(x_candidate);
+ BN_clear_free(rnd);
os_free(prfbuf);
return ret;
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index a2faeb2..9880d3b 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -153,11 +153,13 @@
SM_ENTRY(EAP, INITIALIZE);
if (sm->fast_reauth && sm->m && sm->m->has_reauth_data &&
sm->m->has_reauth_data(sm, sm->eap_method_priv) &&
- !sm->prev_failure) {
+ !sm->prev_failure &&
+ sm->last_config == eap_get_config(sm)) {
wpa_printf(MSG_DEBUG, "EAP: maintaining EAP method data for "
"fast reauthentication");
sm->m->deinit_for_reauth(sm, sm->eap_method_priv);
} else {
+ sm->last_config = eap_get_config(sm);
eap_deinit_prev_method(sm, "INITIALIZE");
}
sm->selectedMethod = EAP_TYPE_NONE;
diff --git a/src/eap_peer/eap_i.h b/src/eap_peer/eap_i.h
index 8288ba5..fde809c 100644
--- a/src/eap_peer/eap_i.h
+++ b/src/eap_peer/eap_i.h
@@ -345,6 +345,7 @@
struct wps_context *wps;
int prev_failure;
+ struct eap_peer_config *last_config;
struct ext_password_data *ext_pw;
struct wpabuf *ext_pw_buf;
diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c
index bdcca0b..1c915ed 100644
--- a/src/eap_peer/eap_pwd.c
+++ b/src/eap_peer/eap_pwd.c
@@ -123,7 +123,7 @@
if ((data->password = os_malloc(password_len)) == NULL) {
wpa_printf(MSG_INFO, "EAP-PWD: memory allocation psk fail");
BN_CTX_free(data->bnctx);
- os_free(data->id_peer);
+ bin_clear_free(data->id_peer, data->id_peer_len);
os_free(data);
return NULL;
}
@@ -148,21 +148,21 @@
{
struct eap_pwd_data *data = priv;
- BN_free(data->private_value);
- BN_free(data->server_scalar);
- BN_free(data->my_scalar);
- BN_free(data->k);
+ BN_clear_free(data->private_value);
+ BN_clear_free(data->server_scalar);
+ BN_clear_free(data->my_scalar);
+ BN_clear_free(data->k);
BN_CTX_free(data->bnctx);
- EC_POINT_free(data->my_element);
- EC_POINT_free(data->server_element);
- os_free(data->id_peer);
- os_free(data->id_server);
+ EC_POINT_clear_free(data->my_element);
+ EC_POINT_clear_free(data->server_element);
+ bin_clear_free(data->id_peer, data->id_peer_len);
+ bin_clear_free(data->id_server, data->id_server_len);
bin_clear_free(data->password, data->password_len);
if (data->grp) {
EC_GROUP_free(data->grp->group);
- EC_POINT_free(data->grp->pwe);
- BN_free(data->grp->order);
- BN_free(data->grp->prime);
+ EC_POINT_clear_free(data->grp->pwe);
+ BN_clear_free(data->grp->order);
+ BN_clear_free(data->grp->prime);
os_free(data->grp);
}
wpabuf_free(data->inbuf);
@@ -317,11 +317,15 @@
goto fin;
}
- BN_rand_range(data->private_value, data->grp->order);
- BN_rand_range(mask, data->grp->order);
- BN_add(data->my_scalar, data->private_value, mask);
- BN_mod(data->my_scalar, data->my_scalar, data->grp->order,
- data->bnctx);
+ if (BN_rand_range(data->private_value, data->grp->order) != 1 ||
+ BN_rand_range(mask, data->grp->order) != 1 ||
+ BN_add(data->my_scalar, data->private_value, mask) != 1 ||
+ BN_mod(data->my_scalar, data->my_scalar, data->grp->order,
+ data->bnctx) != 1) {
+ wpa_printf(MSG_INFO,
+ "EAP-pwd (peer): unable to get randomness");
+ goto fin;
+ }
if (!EC_POINT_mul(data->grp->group, data->my_element, NULL,
data->grp->pwe, mask, data->bnctx)) {
@@ -336,7 +340,7 @@
wpa_printf(MSG_INFO, "EAP-PWD (peer): element inversion fail");
goto fin;
}
- BN_free(mask);
+ BN_clear_free(mask);
if (((x = BN_new()) == NULL) ||
((y = BN_new()) == NULL)) {
@@ -471,11 +475,11 @@
fin:
os_free(scalar);
os_free(element);
- BN_free(x);
- BN_free(y);
- BN_free(cofactor);
- EC_POINT_free(K);
- EC_POINT_free(point);
+ BN_clear_free(x);
+ BN_clear_free(y);
+ BN_clear_free(cofactor);
+ EC_POINT_clear_free(K);
+ EC_POINT_clear_free(point);
if (data->outbuf == NULL)
eap_pwd_state(data, FAILURE);
else
@@ -589,7 +593,7 @@
eap_pwd_h_final(hash, conf);
ptr = (u8 *) payload;
- if (os_memcmp(conf, ptr, SHA256_MAC_LEN)) {
+ if (os_memcmp_const(conf, ptr, SHA256_MAC_LEN)) {
wpa_printf(MSG_INFO, "EAP-PWD (peer): confirm did not verify");
goto fin;
}
@@ -680,9 +684,9 @@
wpabuf_put_data(data->outbuf, conf, SHA256_MAC_LEN);
fin:
- os_free(cruft);
- BN_free(x);
- BN_free(y);
+ bin_clear_free(cruft, BN_num_bytes(data->grp->prime));
+ BN_clear_free(x);
+ BN_clear_free(y);
if (data->outbuf == NULL) {
ret->methodState = METHOD_DONE;
ret->decision = DECISION_FAIL;
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
index e110236..771da58 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -501,16 +501,6 @@
wpabuf_put(msg, pos - buf);
*resp = msg;
- if (sm->workaround) {
- /* At least FreeRADIUS seems to be terminating
- * EAP-TTLS/MSHCAPV2 without the expected MS-CHAP-v2 Success
- * packet. */
- wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: EAP workaround - "
- "allow success without tunneled response");
- ret->methodState = METHOD_MAY_CONT;
- ret->decision = DECISION_COND_SUCC;
- }
-
return 0;
#else /* EAP_MSCHAPv2 */
wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPv2 not included in the build");
diff --git a/src/eap_server/eap_server_fast.c b/src/eap_server/eap_server_fast.c
index 1024510..4691e72 100644
--- a/src/eap_server/eap_server_fast.c
+++ b/src/eap_server/eap_server_fast.c
@@ -187,7 +187,7 @@
switch (*pos) {
case PAC_OPAQUE_TYPE_PAD:
pos = end;
- break;
+ goto done;
case PAC_OPAQUE_TYPE_KEY:
if (pos[1] != EAP_FAST_PAC_KEY_LEN) {
wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
@@ -218,6 +218,7 @@
pos += 2 + pos[1];
}
+done:
if (pac_key == NULL) {
wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC-Key included in "
diff --git a/src/eap_server/eap_server_pwd.c b/src/eap_server/eap_server_pwd.c
index 9154ab1..7e1278d 100644
--- a/src/eap_server/eap_server_pwd.c
+++ b/src/eap_server/eap_server_pwd.c
@@ -106,7 +106,7 @@
if (data->password == NULL) {
wpa_printf(MSG_INFO, "EAP-PWD: Memory allocation password "
"fail");
- os_free(data->id_server);
+ bin_clear_free(data->id_server, data->id_server_len);
os_free(data);
return NULL;
}
@@ -117,7 +117,7 @@
if (data->bnctx == NULL) {
wpa_printf(MSG_INFO, "EAP-PWD: bn context allocation fail");
bin_clear_free(data->password, data->password_len);
- os_free(data->id_server);
+ bin_clear_free(data->id_server, data->id_server_len);
os_free(data);
return NULL;
}
@@ -135,21 +135,21 @@
{
struct eap_pwd_data *data = priv;
- BN_free(data->private_value);
- BN_free(data->peer_scalar);
- BN_free(data->my_scalar);
- BN_free(data->k);
+ BN_clear_free(data->private_value);
+ BN_clear_free(data->peer_scalar);
+ BN_clear_free(data->my_scalar);
+ BN_clear_free(data->k);
BN_CTX_free(data->bnctx);
- EC_POINT_free(data->my_element);
- EC_POINT_free(data->peer_element);
- os_free(data->id_peer);
- os_free(data->id_server);
+ EC_POINT_clear_free(data->my_element);
+ EC_POINT_clear_free(data->peer_element);
+ bin_clear_free(data->id_peer, data->id_peer_len);
+ bin_clear_free(data->id_server, data->id_server_len);
bin_clear_free(data->password, data->password_len);
if (data->grp) {
EC_GROUP_free(data->grp->group);
- EC_POINT_free(data->grp->pwe);
- BN_free(data->grp->order);
- BN_free(data->grp->prime);
+ EC_POINT_clear_free(data->grp->pwe);
+ BN_clear_free(data->grp->order);
+ BN_clear_free(data->grp->prime);
os_free(data->grp);
}
wpabuf_free(data->inbuf);
@@ -210,11 +210,15 @@
goto fin;
}
- BN_rand_range(data->private_value, data->grp->order);
- BN_rand_range(mask, data->grp->order);
- BN_add(data->my_scalar, data->private_value, mask);
- BN_mod(data->my_scalar, data->my_scalar, data->grp->order,
- data->bnctx);
+ if (BN_rand_range(data->private_value, data->grp->order) != 1 ||
+ BN_rand_range(mask, data->grp->order) != 1 ||
+ BN_add(data->my_scalar, data->private_value, mask) != 1 ||
+ BN_mod(data->my_scalar, data->my_scalar, data->grp->order,
+ data->bnctx) != 1) {
+ wpa_printf(MSG_INFO,
+ "EAP-pwd (server): unable to get randomness");
+ goto fin;
+ }
if (!EC_POINT_mul(data->grp->group, data->my_element, NULL,
data->grp->pwe, mask, data->bnctx)) {
@@ -230,7 +234,7 @@
"fail");
goto fin;
}
- BN_free(mask);
+ BN_clear_free(mask);
if (((x = BN_new()) == NULL) ||
((y = BN_new()) == NULL)) {
@@ -282,8 +286,8 @@
fin:
os_free(scalar);
os_free(element);
- BN_free(x);
- BN_free(y);
+ BN_clear_free(x);
+ BN_clear_free(y);
if (data->outbuf == NULL)
eap_pwd_state(data, FAILURE);
}
@@ -406,9 +410,9 @@
wpabuf_put_data(data->outbuf, conf, SHA256_MAC_LEN);
fin:
- os_free(cruft);
- BN_free(x);
- BN_free(y);
+ bin_clear_free(cruft, BN_num_bytes(data->grp->prime));
+ BN_clear_free(x);
+ BN_clear_free(y);
if (data->outbuf == NULL)
eap_pwd_state(data, FAILURE);
}
@@ -724,11 +728,11 @@
res = 1;
fin:
- EC_POINT_free(K);
- EC_POINT_free(point);
- BN_free(cofactor);
- BN_free(x);
- BN_free(y);
+ EC_POINT_clear_free(K);
+ EC_POINT_clear_free(point);
+ BN_clear_free(cofactor);
+ BN_clear_free(x);
+ BN_clear_free(y);
if (res)
eap_pwd_state(data, PWD_Confirm_Req);
@@ -835,7 +839,7 @@
eap_pwd_h_final(hash, conf);
ptr = (u8 *) payload;
- if (os_memcmp(conf, ptr, SHA256_MAC_LEN)) {
+ if (os_memcmp_const(conf, ptr, SHA256_MAC_LEN)) {
wpa_printf(MSG_INFO, "EAP-PWD (server): confirm did not "
"verify");
goto fin;
@@ -851,9 +855,9 @@
eap_pwd_state(data, SUCCESS);
fin:
- os_free(cruft);
- BN_free(x);
- BN_free(y);
+ bin_clear_free(cruft, BN_num_bytes(data->grp->prime));
+ BN_clear_free(x);
+ BN_clear_free(y);
}
diff --git a/src/utils/wpa_debug.c b/src/utils/wpa_debug.c
index 647f6b4..68cbace 100644
--- a/src/utils/wpa_debug.c
+++ b/src/utils/wpa_debug.c
@@ -685,6 +685,34 @@
}
+void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...)
+{
+ va_list ap;
+ char *buf;
+ int buflen;
+ int len;
+
+ if (!wpa_msg_cb)
+ return;
+
+ va_start(ap, fmt);
+ buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
+ va_end(ap);
+
+ buf = os_malloc(buflen);
+ if (buf == NULL) {
+ wpa_printf(MSG_ERROR,
+ "wpa_msg_global_ctrl: Failed to allocate message buffer");
+ return;
+ }
+ va_start(ap, fmt);
+ len = vsnprintf(buf, buflen, fmt, ap);
+ va_end(ap);
+ wpa_msg_cb(ctx, level, 1, buf, len);
+ os_free(buf);
+}
+
+
void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...)
{
va_list ap;
diff --git a/src/utils/wpa_debug.h b/src/utils/wpa_debug.h
index 50e8ae9..391f197 100644
--- a/src/utils/wpa_debug.h
+++ b/src/utils/wpa_debug.h
@@ -160,6 +160,7 @@
#define wpa_msg(args...) do { } while (0)
#define wpa_msg_ctrl(args...) do { } while (0)
#define wpa_msg_global(args...) do { } while (0)
+#define wpa_msg_global_ctrl(args...) do { } while (0)
#define wpa_msg_no_global(args...) do { } while (0)
#define wpa_msg_register_cb(f) do { } while (0)
#define wpa_msg_register_ifname_cb(f) do { } while (0)
@@ -212,6 +213,21 @@
PRINTF_FORMAT(3, 4);
/**
+ * wpa_msg_global_ctrl - Conditional global printf for ctrl_iface monitors
+ * @ctx: Pointer to context data; this is the ctx variable registered
+ * with struct wpa_driver_ops::init()
+ * @level: priority level (MSG_*) of the message
+ * @fmt: printf format string, followed by optional arguments
+ *
+ * This function is used to print conditional debugging and error messages.
+ * This function is like wpa_msg_global(), but it sends the output only to the
+ * attached global ctrl_iface monitors. In other words, it can be used for
+ * frequent events that do not need to be sent to syslog.
+ */
+void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...)
+PRINTF_FORMAT(3, 4);
+
+/**
* wpa_msg_no_global - Conditional printf for ctrl_iface monitors
* @ctx: Pointer to context data; this is the ctx variable registered
* with struct wpa_driver_ops::init()