diff options
| author | Dmitry Shmidt <dimitrysh@google.com> | 2014-07-28 10:35:20 -0700 |
|---|---|---|
| committer | Dmitry Shmidt <dimitrysh@google.com> | 2014-07-28 10:35:20 -0700 |
| commit | 7f0b69e88015ca077ef7a417fde0a76c10df23a5 (patch) | |
| tree | 7d9b472e39d46cf4a224559dd0dae400bc447b0d /src | |
| parent | 0f4fce149db4f45a9eb6776186c1858f8083e6f4 (diff) | |
| download | android_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.c | 30 | ||||
| -rw-r--r-- | src/eap_common/eap_pwd_common.c | 12 | ||||
| -rw-r--r-- | src/eap_peer/eap.c | 4 | ||||
| -rw-r--r-- | src/eap_peer/eap_i.h | 1 | ||||
| -rw-r--r-- | src/eap_peer/eap_pwd.c | 58 | ||||
| -rw-r--r-- | src/eap_peer/eap_ttls.c | 10 | ||||
| -rw-r--r-- | src/eap_server/eap_server_fast.c | 3 | ||||
| -rw-r--r-- | src/eap_server/eap_server_pwd.c | 70 | ||||
| -rw-r--r-- | src/utils/wpa_debug.c | 28 | ||||
| -rw-r--r-- | src/utils/wpa_debug.h | 16 |
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() |
