static void eap_pwd_reset(struct eap_sm *sm, void *priv) { struct eap_pwd_data *data = priv; 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_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_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); wpabuf_free(data->outbuf); bin_clear_free(data, sizeof(*data)); }
static void eap_mschapv2_password_changed(struct eap_sm *sm, struct eap_mschapv2_data *data) { struct eap_peer_config *config = eap_get_config(sm); if (config && config->new_password) { wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_PASSWORD_CHANGED "EAP-MSCHAPV2: Password changed successfully"); data->prev_error = 0; bin_clear_free(config->password, config->password_len); if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) { /* TODO: update external storage */ } else if (config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH) { config->password = os_malloc(16); config->password_len = 16; if (config->password && nt_password_hash(config->new_password, config->new_password_len, config->password)) { bin_clear_free(config->password, config->password_len); config->password = NULL; config->password_len = 0; } bin_clear_free(config->new_password, config->new_password_len); } else { config->password = config->new_password; config->password_len = config->new_password_len; } config->new_password = NULL; config->new_password_len = 0; } }
/** * wps_deinit - Deinitialize WPS Registration protocol data * @data: WPS Registration protocol data from wps_init() */ void wps_deinit(struct wps_data *data) { #ifdef CONFIG_WPS_NFC if (data->registrar && data->nfc_pw_token) wps_registrar_remove_nfc_pw_token(data->wps->registrar, data->nfc_pw_token); #endif /* CONFIG_WPS_NFC */ if (data->wps_pin_revealed) { wpa_printf(MSG_DEBUG, "WPS: Full PIN information revealed and " "negotiation failed"); if (data->registrar) wps_registrar_invalidate_pin(data->wps->registrar, data->uuid_e); } else if (data->registrar) wps_registrar_unlock_pin(data->wps->registrar, data->uuid_e); wpabuf_free(data->dh_privkey); wpabuf_free(data->dh_pubkey_e); wpabuf_free(data->dh_pubkey_r); wpabuf_free(data->last_msg); bin_clear_free(data->dev_password, data->dev_password_len); bin_clear_free(data->alt_dev_password, data->alt_dev_password_len); bin_clear_free(data->new_psk, data->new_psk_len); wps_device_data_free(&data->peer_dev); bin_clear_free(data->new_ap_settings, sizeof(*data->new_ap_settings)); dh5_free(data->dh_ctx); os_free(data); }
static void * eap_pwd_init(struct eap_sm *sm) { struct eap_pwd_data *data; if (sm->user == NULL || sm->user->password == NULL || sm->user->password_len == 0) { wpa_printf(MSG_INFO, "EAP-PWD (server): Password is not " "configured"); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->group_num = sm->pwd_group; wpa_printf(MSG_DEBUG, "EAP-pwd: Selected group number %d", data->group_num); data->state = PWD_ID_Req; data->id_server = (u8 *) os_strdup("server"); if (data->id_server) data->id_server_len = os_strlen((char *) data->id_server); data->password = os_malloc(sm->user->password_len); if (data->password == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: Memory allocation password " "fail"); bin_clear_free(data->id_server, data->id_server_len); os_free(data); return NULL; } data->password_len = sm->user->password_len; os_memcpy(data->password, sm->user->password, data->password_len); data->password_hash = sm->user->password_hash; data->bnctx = BN_CTX_new(); if (data->bnctx == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: bn context allocation fail"); bin_clear_free(data->password, data->password_len); bin_clear_free(data->id_server, data->id_server_len); os_free(data); return NULL; } data->in_frag_pos = data->out_frag_pos = 0; data->inbuf = data->outbuf = NULL; /* use default MTU from RFC 5931 if not configured otherwise */ data->mtu = sm->fragment_size > 0 ? sm->fragment_size : 1020; return data; }
static int get_wildcard_cb(void *ctx, int argc, char *argv[], char *col[]) { struct hostapd_eap_user *user = ctx; int i, id = -1, methods = -1; size_t len; for (i = 0; i < argc; i++) { if (os_strcmp(col[i], "identity") == 0 && argv[i]) id = i; else if (os_strcmp(col[i], "methods") == 0 && argv[i]) methods = i; } if (id < 0 || methods < 0) return 0; len = os_strlen(argv[id]); if (len <= user->identity_len && os_memcmp(argv[id], user->identity, len) == 0 && (user->password == NULL || len > user->password_len)) { bin_clear_free(user->password, user->password_len); user->password_len = os_strlen(argv[id]); user->password = (u8 *) os_strdup(argv[id]); user->next = (void *) 1; set_user_methods(user, argv[methods]); } return 0; }
static u8 * eap_tls_get_emsk(struct eap_sm *sm, void *priv, size_t *len) { struct eap_tls_data *data = priv; u8 *eapKeyData, *emsk; const char *label; if (data->state != SUCCESS) return NULL; if (data->ssl.tls_v13) label = "EXPORTER_EAP_TLS_Key_Material"; else label = "client EAP encryption"; eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, label, EAP_TLS_KEY_LEN + EAP_EMSK_LEN); if (eapKeyData) { emsk = os_malloc(EAP_EMSK_LEN); if (emsk) os_memcpy(emsk, eapKeyData + EAP_TLS_KEY_LEN, EAP_EMSK_LEN); bin_clear_free(eapKeyData, EAP_TLS_KEY_LEN + EAP_EMSK_LEN); } else emsk = NULL; if (emsk) { *len = EAP_EMSK_LEN; wpa_hexdump(MSG_DEBUG, "EAP-TLS: Derived EMSK", emsk, EAP_EMSK_LEN); } else { wpa_printf(MSG_DEBUG, "EAP-TLS: Failed to derive EMSK"); } return emsk; }
static void eap_tls_free_key(struct eap_tls_data *data) { if (data->key_data) { bin_clear_free(data->key_data, EAP_TLS_KEY_LEN + EAP_EMSK_LEN); data->key_data = NULL; } }
void wpa_msg_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_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, WPA_MSG_PER_INTERFACE, buf, len); bin_clear_free(buf, buflen); }
void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...) { va_list ap; char *buf; int buflen; int len; 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_no_global: Failed to allocate " "message buffer"); return; } va_start(ap, fmt); len = vsnprintf(buf, buflen, fmt, ap); va_end(ap); wpa_printf(level, "%s", buf); if (wpa_msg_cb) wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len); bin_clear_free(buf, buflen); }
static void eap_sake_deinit(struct eap_sm *sm, void *priv) { struct eap_sake_data *data = priv; os_free(data->serverid); os_free(data->peerid); bin_clear_free(data, sizeof(*data)); }
static void eap_sim_reset(struct eap_sm *sm, void *priv) { struct eap_sim_data *data = priv; os_free(data->next_pseudonym); os_free(data->next_reauth_id); bin_clear_free(data, sizeof(*data)); }
void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level, const char *fmt, ...) { va_list ap; char *buf; int buflen; int len; 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, "hostapd_logger: Failed to allocate " "message buffer"); return; } va_start(ap, fmt); len = vsnprintf(buf, buflen, fmt, ap); va_end(ap); if (hostapd_logger_cb) hostapd_logger_cb(ctx, addr, module, level, buf, len); else if (addr) wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s", MAC2STR(addr), buf); else wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf); bin_clear_free(buf, buflen); }
static void eap_psk_deinit(struct eap_sm *sm, void *priv) { struct eap_psk_data *data = priv; os_free(data->id_s); os_free(data->id_p); bin_clear_free(data, sizeof(*data)); }
void hostapd_config_free_eap_user(struct hostapd_eap_user *user) { hostapd_config_free_radius_attr(user->accept_attr); os_free(user->identity); bin_clear_free(user->password, user->password_len); os_free(user); }
static void eap_mschapv2_deinit(struct eap_sm *sm, void *priv) { struct eap_mschapv2_data *data = priv; os_free(data->peer_challenge); os_free(data->auth_challenge); wpabuf_free(data->prev_challenge); bin_clear_free(data, sizeof(*data)); }
static void hostapd_config_free_wep(struct hostapd_wep_keys *keys) { int i; for (i = 0; i < NUM_WEP_KEYS; i++) { bin_clear_free(keys->key[i], keys->len[i]); keys->key[i] = NULL; } }
static void eap_ikev2_reset(struct eap_sm *sm, void *priv) { struct eap_ikev2_data *data = priv; wpabuf_free(data->in_buf); wpabuf_free(data->out_buf); ikev2_initiator_deinit(&data->ikev2); bin_clear_free(data, sizeof(*data)); }
static void eap_eke_reset(struct eap_sm *sm, void *priv) { struct eap_eke_data *data = priv; eap_eke_session_clean(&data->sess); os_free(data->peerid); wpabuf_free(data->msgs); bin_clear_free(data, sizeof(*data)); }
static void _pmksa_cache_free_entry(struct rsn_pmksa_cache_entry *entry) { os_free(entry->identity); wpabuf_free(entry->cui); #ifndef CONFIG_NO_RADIUS radius_free_class(&entry->radius_class); #endif /* CONFIG_NO_RADIUS */ bin_clear_free(entry, sizeof(*entry)); }
static void eap_aka_reset(struct eap_sm *sm, void *priv) { struct eap_aka_data *data = priv; os_free(data->next_pseudonym); os_free(data->next_reauth_id); wpabuf_free(data->id_msgs); os_free(data->network_name); bin_clear_free(data, sizeof(*data)); }
static void eap_mschapv2_reset(struct eap_sm *sm, void *priv) { struct eap_mschapv2_data *data = priv; if (data == NULL) return; os_free(data->peer_challenge); bin_clear_free(data, sizeof(*data)); }
static int wps_process_dev_pw_id(struct wps_data *wps, const u8 *dev_pw_id) { u16 id; if (dev_pw_id == NULL) { wpa_printf(MSG_DEBUG, "WPS: Device Password ID"); return -1; } id = WPA_GET_BE16(dev_pw_id); if (wps->dev_pw_id == id) { wpa_printf(MSG_DEBUG, "WPS: Device Password ID %u", id); return 0; } #ifdef CONFIG_P2P if ((id == DEV_PW_DEFAULT && wps->dev_pw_id == DEV_PW_REGISTRAR_SPECIFIED) || (id == DEV_PW_REGISTRAR_SPECIFIED && wps->dev_pw_id == DEV_PW_DEFAULT)) { /* * Common P2P use cases indicate whether the PIN is from the * client or GO using Device Password Id in M1/M2 in a way that * does not look fully compliant with WSC specification. Anyway, * this is deployed and needs to be allowed, so ignore changes * between Registrar-Specified and Default PIN. */ wpa_printf(MSG_DEBUG, "WPS: Allow PIN Device Password ID " "change"); return 0; } #endif /* CONFIG_P2P */ wpa_printf(MSG_DEBUG, "WPS: Registrar trying to change Device Password " "ID from %u to %u", wps->dev_pw_id, id); if (wps->dev_pw_id == DEV_PW_PUSHBUTTON && id == DEV_PW_DEFAULT) { wpa_printf(MSG_DEBUG, "WPS: Workaround - ignore PBC-to-PIN change"); return 0; } if (wps->alt_dev_password && wps->alt_dev_pw_id == id) { wpa_printf(MSG_DEBUG, "WPS: Found a matching Device Password"); bin_clear_free(wps->dev_password, wps->dev_password_len); wps->dev_pw_id = wps->alt_dev_pw_id; wps->dev_password = wps->alt_dev_password; wps->dev_password_len = wps->alt_dev_password_len; wps->alt_dev_password = NULL; wps->alt_dev_password_len = 0; return 0; } return -1; }
void hostapd_config_clear_wpa_psk(struct hostapd_wpa_psk **l) { struct hostapd_wpa_psk *psk, *tmp; for (psk = *l; psk;) { tmp = psk; psk = psk->next; bin_clear_free(tmp, sizeof(*tmp)); } *l = NULL; }
static void eap_peap_reset(struct eap_sm *sm, void *priv) { struct eap_peap_data *data = priv; if (data == NULL) return; if (data->phase2_priv && data->phase2_method) data->phase2_method->reset(sm, data->phase2_priv); eap_server_tls_ssl_deinit(sm, &data->ssl); wpabuf_free(data->pending_phase2_resp); os_free(data->phase2_key); wpabuf_free(data->soh_response); bin_clear_free(data, sizeof(*data)); }
/** * aes_128_eax_encrypt - AES-128 EAX mode encryption * @key: Key for encryption (16 bytes) * @nonce: Nonce for counter mode * @nonce_len: Nonce length in bytes * @hdr: Header data to be authenticity protected * @hdr_len: Length of the header data bytes * @data: Data to encrypt in-place * @data_len: Length of data in bytes * @tag: 16-byte tag value * Returns: 0 on success, -1 on failure */ int aes_128_eax_encrypt(const u8 *key, const u8 *nonce, size_t nonce_len, const u8 *hdr, size_t hdr_len, u8 *data, size_t data_len, u8 *tag) { u8 *buf; size_t buf_len; u8 nonce_mac[AES_BLOCK_SIZE], hdr_mac[AES_BLOCK_SIZE], data_mac[AES_BLOCK_SIZE]; int i, ret = -1; if (nonce_len > data_len) buf_len = nonce_len; else buf_len = data_len; if (hdr_len > buf_len) buf_len = hdr_len; buf_len += 16; buf = os_malloc(buf_len); if (buf == NULL) return -1; os_memset(buf, 0, 15); buf[15] = 0; os_memcpy(buf + 16, nonce, nonce_len); if (omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac)) goto fail; buf[15] = 1; os_memcpy(buf + 16, hdr, hdr_len); if (omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac)) goto fail; if (aes_128_ctr_encrypt(key, nonce_mac, data, data_len)) goto fail; buf[15] = 2; os_memcpy(buf + 16, data, data_len); if (omac1_aes_128(key, buf, 16 + data_len, data_mac)) goto fail; for (i = 0; i < AES_BLOCK_SIZE; i++) tag[i] = nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i]; ret = 0; fail: bin_clear_free(buf, buf_len); return ret; }
static void eap_peap_deinit(struct eap_sm *sm, void *priv) { struct eap_peap_data *data = priv; if (data == NULL) return; if (data->phase2_priv && data->phase2_method) data->phase2_method->deinit(sm, data->phase2_priv); os_free(data->phase2_types); eap_peer_tls_ssl_deinit(sm, &data->ssl); eap_peap_free_key(data); os_free(data->session_id); wpabuf_clear_free(data->pending_phase2_req); wpabuf_clear_free(data->pending_resp); bin_clear_free(data, sizeof(*data)); }
static void eap_fast_reset(struct eap_sm *sm, void *priv) { struct eap_fast_data *data = priv; if (data == NULL) return; if (data->phase2_priv && data->phase2_method) data->phase2_method->reset(sm, data->phase2_priv); eap_server_tls_ssl_deinit(sm, &data->ssl); os_free(data->srv_id); os_free(data->srv_id_info); os_free(data->key_block_p); wpabuf_free(data->pending_phase2_resp); os_free(data->identity); bin_clear_free(data, sizeof(*data)); }
static int get_user_cb(void *ctx, int argc, char *argv[], char *col[]) { struct hostapd_eap_user *user = ctx; int i; for (i = 0; i < argc; i++) { if (os_strcmp(col[i], "password") == 0 && argv[i]) { bin_clear_free(user->password, user->password_len); user->password_len = os_strlen(argv[i]); user->password = (u8 *) os_strdup(argv[i]); user->next = (void *) 1; } else if (os_strcmp(col[i], "methods") == 0 && argv[i]) { set_user_methods(user, argv[i]); } else if (os_strcmp(col[i], "remediation") == 0 && argv[i]) { user->remediation = strlen(argv[i]) > 0; } else if (os_strcmp(col[i], "t_c_timestamp") == 0 && argv[i]) { user->t_c_timestamp = strtol(argv[i], NULL, 10); } } return 0; }
int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, const char *label, int server_random_first, int skip_keyblock, u8 *out, size_t out_len) { int ret = -1, skip = 0; u8 *tmp_out = NULL; u8 *_out = out; if (skip_keyblock) { skip = tls_get_keyblock_size(conn); if (skip < 0) return -1; tmp_out = os_malloc(skip + out_len); if (!tmp_out) return -1; _out = tmp_out; } #ifdef CONFIG_TLS_INTERNAL_CLIENT if (conn->client) { ret = tlsv1_client_prf(conn->client, label, server_random_first, _out, out_len); } #endif /* CONFIG_TLS_INTERNAL_CLIENT */ #ifdef CONFIG_TLS_INTERNAL_SERVER if (conn->server) { ret = tlsv1_server_prf(conn->server, label, server_random_first, _out, out_len); } #endif /* CONFIG_TLS_INTERNAL_SERVER */ if (ret == 0 && skip_keyblock) os_memcpy(out, _out + skip, out_len); bin_clear_free(tmp_out, skip); return ret; }
void wpa_msg(void *ctx, int level, const char *fmt, ...) { va_list ap; char *buf; int buflen; int len; char prefix[130]; 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: Failed to allocate message " "buffer"); return; } va_start(ap, fmt); prefix[0] = '\0'; if (wpa_msg_ifname_cb) { const char *ifname = wpa_msg_ifname_cb(ctx); if (ifname) { int res = os_snprintf(prefix, sizeof(prefix), "%s: ", ifname); if (os_snprintf_error(sizeof(prefix), res)) prefix[0] = '\0'; } } len = vsnprintf(buf, buflen, fmt, ap); va_end(ap); wpa_printf(level, "%s%s", prefix, buf); if (wpa_msg_cb) wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len); bin_clear_free(buf, buflen); }