aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2014-07-28 10:35:20 -0700
committerDmitry Shmidt <dimitrysh@google.com>2014-07-28 10:35:20 -0700
commit7f0b69e88015ca077ef7a417fde0a76c10df23a5 (patch)
tree7d9b472e39d46cf4a224559dd0dae400bc447b0d /src
parent0f4fce149db4f45a9eb6776186c1858f8083e6f4 (diff)
downloadandroid_external_wpa_supplicant_8-7f0b69e88015ca077ef7a417fde0a76c10df23a5.tar.gz
android_external_wpa_supplicant_8-7f0b69e88015ca077ef7a417fde0a76c10df23a5.tar.bz2
android_external_wpa_supplicant_8-7f0b69e88015ca077ef7a417fde0a76c10df23a5.zip
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>
Diffstat (limited to 'src')
-rw-r--r--src/crypto/crypto_openssl.c30
-rw-r--r--src/eap_common/eap_pwd_common.c12
-rw-r--r--src/eap_peer/eap.c4
-rw-r--r--src/eap_peer/eap_i.h1
-rw-r--r--src/eap_peer/eap_pwd.c58
-rw-r--r--src/eap_peer/eap_ttls.c10
-rw-r--r--src/eap_server/eap_server_fast.c3
-rw-r--r--src/eap_server/eap_server_pwd.c70
-rw-r--r--src/utils/wpa_debug.c28
-rw-r--r--src/utils/wpa_debug.h16
10 files changed, 139 insertions, 93 deletions
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 817ee2d0..f02aaacb 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -340,10 +340,10 @@ int crypto_mod_exp(const u8 *base, size_t base_len,
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 @@ struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
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 @@ void crypto_ec_deinit(struct crypto_ec *e)
{
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 @@ int crypto_ec_point_to_bin(struct crypto_ec *e,
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 @@ struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
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 96c9efd8..fdcff7fa 100644
--- a/src/eap_common/eap_pwd_common.c
+++ b/src/eap_common/eap_pwd_common.c
@@ -263,18 +263,18 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
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 a2faeb2d..9880d3bc 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -153,11 +153,13 @@ SM_STATE(EAP, INITIALIZE)
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 8288ba5b..fde809c3 100644
--- a/src/eap_peer/eap_i.h
+++ b/src/eap_peer/eap_i.h
@@ -345,6 +345,7 @@ struct eap_sm {
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 bdcca0b8..1c915ed4 100644
--- a/src/eap_peer/eap_pwd.c
+++ b/src/eap_peer/eap_pwd.c
@@ -123,7 +123,7 @@ static void * eap_pwd_init(struct eap_sm *sm)
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 @@ static void eap_pwd_deinit(struct eap_sm *sm, void *priv)
{
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 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
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 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
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 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
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_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
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 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
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 e110236a..771da584 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -501,16 +501,6 @@ static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
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 10245101..4691e722 100644
--- a/src/eap_server/eap_server_fast.c
+++ b/src/eap_server/eap_server_fast.c
@@ -187,7 +187,7 @@ static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
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 @@ static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
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 9154ab17..7e1278dd 100644
--- a/src/eap_server/eap_server_pwd.c
+++ b/src/eap_server/eap_server_pwd.c
@@ -106,7 +106,7 @@ static void * eap_pwd_init(struct eap_sm *sm)
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 @@ static void * eap_pwd_init(struct eap_sm *sm)
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 @@ static void eap_pwd_reset(struct eap_sm *sm, void *priv)
{
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 @@ static void eap_pwd_build_commit_req(struct eap_sm *sm,
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 @@ static void eap_pwd_build_commit_req(struct eap_sm *sm,
"fail");
goto fin;
}
- BN_free(mask);
+ BN_clear_free(mask);
if (((x = BN_new()) == NULL) ||
((y = BN_new()) == NULL)) {
@@ -282,8 +286,8 @@ static void eap_pwd_build_commit_req(struct eap_sm *sm,
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 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
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 @@ eap_pwd_process_commit_resp(struct eap_sm *sm, struct eap_pwd_data *data,
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_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
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_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
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 647f6b4b..68cbace6 100644
--- a/src/utils/wpa_debug.c
+++ b/src/utils/wpa_debug.c
@@ -685,6 +685,34 @@ void wpa_msg_global(void *ctx, int level, const char *fmt, ...)
}
+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 50e8ae9d..391f1975 100644
--- a/src/utils/wpa_debug.h
+++ b/src/utils/wpa_debug.h
@@ -160,6 +160,7 @@ void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
#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 @@ void wpa_msg_global(void *ctx, int level, const char *fmt, ...)
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()