int wps_build_oob_dev_pw(struct wpabuf *msg, u16 dev_pw_id, const struct wpabuf *pubkey, const u8 *dev_pw, size_t dev_pw_len) { size_t hash_len; const u8 *addr[1]; u8 pubkey_hash[WPS_HASH_LEN]; wpa_printf(MSG_DEBUG, "WPS: * OOB Device Password (dev_pw_id=%u)", dev_pw_id); addr[0] = wpabuf_head(pubkey); hash_len = wpabuf_len(pubkey); if (sha256_vector(1, addr, &hash_len, pubkey_hash) < 0) return -1; #ifdef CONFIG_WPS_TESTING if (wps_corrupt_pkhash) { wpa_hexdump(MSG_DEBUG, "WPS: Real Public Key Hash", pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN); wpa_printf(MSG_INFO, "WPS: Testing - corrupt public key hash"); pubkey_hash[WPS_OOB_PUBKEY_HASH_LEN - 2]++; } #endif /* CONFIG_WPS_TESTING */ wpabuf_put_be16(msg, ATTR_OOB_DEVICE_PASSWORD); wpabuf_put_be16(msg, WPS_OOB_PUBKEY_HASH_LEN + 2 + dev_pw_len); wpa_hexdump(MSG_DEBUG, "WPS: Public Key Hash", pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN); wpabuf_put_data(msg, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN); wpabuf_put_be16(msg, dev_pw_id); if (dev_pw) { wpa_hexdump_key(MSG_DEBUG, "WPS: OOB Device Password", dev_pw, dev_pw_len); wpabuf_put_data(msg, dev_pw, dev_pw_len); } return 0; }
static int eap_tlv_add_cryptobinding(struct eap_sm *sm, struct eap_peap_data *data, struct wpabuf *buf) { u8 *mac; u8 eap_type = EAP_TYPE_PEAP; const u8 *addr[2]; size_t len[2]; u16 tlv_type; /* Compound_MAC: HMAC-SHA1-160(cryptobinding TLV | EAP type) */ addr[0] = wpabuf_put(buf, 0); len[0] = 60; addr[1] = &eap_type; len[1] = 1; tlv_type = EAP_TLV_CRYPTO_BINDING_TLV; wpabuf_put_be16(buf, tlv_type); wpabuf_put_be16(buf, 56); wpabuf_put_u8(buf, 0); /* Reserved */ wpabuf_put_u8(buf, data->peap_version); /* Version */ wpabuf_put_u8(buf, data->peap_version); /* RecvVersion */ wpabuf_put_u8(buf, 1); /* SubType: 0 = Request, 1 = Response */ wpabuf_put_data(buf, data->binding_nonce, 32); /* Nonce */ mac = wpabuf_put(buf, 20); /* Compound_MAC */ wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC CMK", data->cmk, 20); wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC data 1", addr[0], len[0]); wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC data 2", addr[1], len[1]); hmac_sha1_vector(data->cmk, 20, 2, addr, len, mac); wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC", mac, SHA1_MAC_LEN); data->crypto_binding_used = 1; return 0; }
static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg) { if ((wps->wps->ap_auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) && wps->wps->network_key_len == 0) { char hex[65]; u8 psk[32]; /* Generate a random per-device PSK */ if (random_pool_ready() != 1 || random_get_bytes(psk, sizeof(psk)) < 0) { wpa_printf(MSG_INFO, "WPS: Could not generate random PSK"); return -1; } wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK", psk, sizeof(psk)); wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%u)", (unsigned int) wps->new_psk_len * 2); wpa_snprintf_hex(hex, sizeof(hex), psk, sizeof(psk)); wpabuf_put_be16(msg, ATTR_NETWORK_KEY); wpabuf_put_be16(msg, sizeof(psk) * 2); wpabuf_put_data(msg, hex, sizeof(psk) * 2); if (wps->wps->registrar) { wps_cb_new_psk(wps->wps->registrar, wps->peer_dev.mac_addr, wps->p2p_dev_addr, psk, sizeof(psk)); } return 0; } wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%u)", (unsigned int) wps->wps->network_key_len); wpabuf_put_be16(msg, ATTR_NETWORK_KEY); wpabuf_put_be16(msg, wps->wps->network_key_len); wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len); return 0; }
struct wpabuf * tncs_build_soh_request(void) { struct wpabuf *buf; /* * Build a SoH Request TLV (to be used inside SoH EAP Extensions * Method) */ buf = wpabuf_alloc(8 + 4); if (buf == NULL) return NULL; /* Vendor-Specific TLV (Microsoft) - SoH Request */ wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); /* TLV Type */ wpabuf_put_be16(buf, 8); /* Length */ wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* Vendor_Id */ wpabuf_put_be16(buf, 0x02); /* TLV Type - SoH Request TLV */ wpabuf_put_be16(buf, 0); /* Length */ return buf; }
static struct wpabuf * eap_pax_build_std_3(struct eap_sm *sm, struct eap_pax_data *data, u8 id) { struct wpabuf *req; struct eap_pax_hdr *pax; u8 *pos; wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-3 (sending)"); req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PAX, sizeof(*pax) + 2 + EAP_PAX_MAC_LEN + EAP_PAX_ICV_LEN, EAP_CODE_REQUEST, id); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-PAX: Failed to allocate memory " "request"); data->state = FAILURE; return NULL; } pax = wpabuf_put(req, sizeof(*pax)); pax->op_code = EAP_PAX_OP_STD_3; pax->flags = 0; pax->mac_id = data->mac_id; pax->dh_group_id = EAP_PAX_DH_GROUP_NONE; pax->public_key_id = EAP_PAX_PUBLIC_KEY_NONE; wpabuf_put_be16(req, EAP_PAX_MAC_LEN); pos = wpabuf_put(req, EAP_PAX_MAC_LEN); eap_pax_mac(data->mac_id, data->ck, EAP_PAX_CK_LEN, data->rand.r.y, EAP_PAX_RAND_LEN, (u8 *) data->cid, data->cid_len, NULL, 0, pos); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: MAC_CK(B, CID)", pos, EAP_PAX_MAC_LEN); pos += EAP_PAX_MAC_LEN; /* Optional ADE could be added here, if needed */ pos = wpabuf_put(req, EAP_PAX_MAC_LEN); eap_pax_mac(data->mac_id, data->ick, EAP_PAX_ICK_LEN, wpabuf_mhead(req), wpabuf_len(req) - EAP_PAX_ICV_LEN, NULL, 0, NULL, 0, pos); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ICV", pos, EAP_PAX_ICV_LEN); return req; }
static struct wpabuf * eap_pax_build_std_1(struct eap_sm *sm, struct eap_pax_data *data, u8 id) { struct wpabuf *req; struct eap_pax_hdr *pax; u8 *pos; wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-1 (sending)"); if (random_get_bytes(data->rand.r.x, EAP_PAX_RAND_LEN)) { wpa_printf(MSG_ERROR, "EAP-PAX: Failed to get random data"); data->state = FAILURE; return NULL; } req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PAX, sizeof(*pax) + 2 + EAP_PAX_RAND_LEN + EAP_PAX_ICV_LEN, EAP_CODE_REQUEST, id); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-PAX: Failed to allocate memory " "request"); data->state = FAILURE; return NULL; } pax = wpabuf_put(req, sizeof(*pax)); pax->op_code = EAP_PAX_OP_STD_1; pax->flags = 0; pax->mac_id = data->mac_id; pax->dh_group_id = EAP_PAX_DH_GROUP_NONE; pax->public_key_id = EAP_PAX_PUBLIC_KEY_NONE; wpabuf_put_be16(req, EAP_PAX_RAND_LEN); wpabuf_put_data(req, data->rand.r.x, EAP_PAX_RAND_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: A = X (server rand)", data->rand.r.x, EAP_PAX_RAND_LEN); pos = wpabuf_put(req, EAP_PAX_MAC_LEN); eap_pax_mac(data->mac_id, (u8 *) "", 0, wpabuf_mhead(req), wpabuf_len(req) - EAP_PAX_ICV_LEN, NULL, 0, NULL, 0, pos); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ICV", pos, EAP_PAX_ICV_LEN); return req; }
int wps_build_vendor_extension_ms(struct wpabuf *msg, const u8 *uuid) { //u8 ven_ext[VENDOR_EXT_MS_LEN]; wpa_printf(MSG_DEBUG, "WPS: * Microsoft Vendor Extension"); wpabuf_put_be16(msg, ATTR_VENDOR_EXT); wpabuf_put_be16(msg, VENDOR_EXT_MS_LEN); wpabuf_put_be24(msg, VENDOR_ID_MICROSOFT); //TLV#1(VPI), The Profile Request field should only be set to a value of 0x01. wpabuf_put_be16(msg, TLV_VPI); wpabuf_put_be16(msg, 2); wpabuf_put_be16(msg, ((VPI_UPNP<<8)|0x01)); //TLV#2(UUID) wpabuf_put_be16(msg, TLV_UUID); wpabuf_put_be16(msg, WPS_UUID_LEN); wpabuf_put_data(msg, uuid, WPS_UUID_LEN); return 0; }
static struct wpabuf * eap_gpsk_send_gpsk_2(struct eap_gpsk_data *data, u8 identifier, const u8 *csuite_list, size_t csuite_list_len) { struct wpabuf *resp; size_t len, miclen; u8 *rpos, *start; struct eap_gpsk_csuite *csuite; wpa_printf(MSG_DEBUG, "EAP-GPSK: Sending Response/GPSK-2"); miclen = eap_gpsk_mic_len(data->vendor, data->specifier); len = 1 + 2 + data->id_peer_len + 2 + data->id_server_len + 2 * EAP_GPSK_RAND_LEN + 2 + csuite_list_len + sizeof(struct eap_gpsk_csuite) + 2 + miclen; resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, len, EAP_CODE_RESPONSE, identifier); if (resp == NULL) return NULL; wpabuf_put_u8(resp, EAP_GPSK_OPCODE_GPSK_2); start = wpabuf_put(resp, 0); wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Peer", data->id_peer, data->id_peer_len); wpabuf_put_be16(resp, data->id_peer_len); wpabuf_put_data(resp, data->id_peer, data->id_peer_len); wpabuf_put_be16(resp, data->id_server_len); wpabuf_put_data(resp, data->id_server, data->id_server_len); if (os_get_random(data->rand_peer, EAP_GPSK_RAND_LEN)) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to get random data " "for RAND_Peer"); eap_gpsk_state(data, FAILURE); wpabuf_free(resp); return NULL; } wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer", data->rand_peer, EAP_GPSK_RAND_LEN); wpabuf_put_data(resp, data->rand_peer, EAP_GPSK_RAND_LEN); wpabuf_put_data(resp, data->rand_server, EAP_GPSK_RAND_LEN); wpabuf_put_be16(resp, csuite_list_len); wpabuf_put_data(resp, csuite_list, csuite_list_len); csuite = wpabuf_put(resp, sizeof(*csuite)); WPA_PUT_BE32(csuite->vendor, data->vendor); WPA_PUT_BE16(csuite->specifier, data->specifier); if (eap_gpsk_derive_keys(data->psk, data->psk_len, data->vendor, data->specifier, data->rand_peer, data->rand_server, data->id_peer, data->id_peer_len, data->id_server, data->id_server_len, data->msk, data->emsk, data->sk, &data->sk_len, data->pk, &data->pk_len) < 0) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to derive keys"); eap_gpsk_state(data, FAILURE); wpabuf_free(resp); return NULL; } /* No PD_Payload_1 */ wpabuf_put_be16(resp, 0); rpos = wpabuf_put(resp, miclen); if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor, data->specifier, start, rpos - start, rpos) < 0) { eap_gpsk_state(data, FAILURE); wpabuf_free(resp); return NULL; } return resp; }
static struct wpabuf * eap_pwd_build_req(struct eap_sm *sm, void *priv, u8 id) { struct eap_pwd_data *data = priv; struct wpabuf *req; u8 lm_exch; const u8 *buf; u16 totlen = 0; size_t len; /* * if we're buffering response fragments then just ACK */ if (data->in_frag_pos) { wpa_printf(MSG_DEBUG, "EAP-pwd: ACKing a fragment!!"); req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, EAP_PWD_HDR_SIZE, EAP_CODE_REQUEST, id); if (req == NULL) { eap_pwd_state(data, FAILURE); return NULL; } switch (data->state) { case PWD_ID_Req: wpabuf_put_u8(req, EAP_PWD_OPCODE_ID_EXCH); break; case PWD_Commit_Req: wpabuf_put_u8(req, EAP_PWD_OPCODE_COMMIT_EXCH); break; case PWD_Confirm_Req: wpabuf_put_u8(req, EAP_PWD_OPCODE_CONFIRM_EXCH); break; default: eap_pwd_state(data, FAILURE); /* just to be sure */ wpabuf_free(req); return NULL; } return req; } /* * build the data portion of a request */ switch (data->state) { case PWD_ID_Req: eap_pwd_build_id_req(sm, data, id); lm_exch = EAP_PWD_OPCODE_ID_EXCH; break; case PWD_Commit_Req: eap_pwd_build_commit_req(sm, data, id); lm_exch = EAP_PWD_OPCODE_COMMIT_EXCH; break; case PWD_Confirm_Req: eap_pwd_build_confirm_req(sm, data, id); lm_exch = EAP_PWD_OPCODE_CONFIRM_EXCH; break; default: wpa_printf(MSG_INFO, "EAP-pwd: Unknown state %d in build_req", data->state); eap_pwd_state(data, FAILURE); lm_exch = 0; /* hush now, sweet compiler */ break; } if (data->state == FAILURE) return NULL; /* * determine whether that data needs to be fragmented */ len = wpabuf_len(data->outbuf) - data->out_frag_pos; if ((len + EAP_PWD_HDR_SIZE) > data->mtu) { len = data->mtu - EAP_PWD_HDR_SIZE; EAP_PWD_SET_MORE_BIT(lm_exch); /* * if this is the first fragment, need to set the M bit * and add the total length to the eap_pwd_hdr */ if (data->out_frag_pos == 0) { EAP_PWD_SET_LENGTH_BIT(lm_exch); totlen = wpabuf_len(data->outbuf) + EAP_PWD_HDR_SIZE + sizeof(u16); len -= sizeof(u16); wpa_printf(MSG_DEBUG, "EAP-pwd: Fragmenting output, " "total length = %d", totlen); } wpa_printf(MSG_DEBUG, "EAP-pwd: Send a %d byte fragment", (int) len); } /* * alloc an eap request and populate it with the data */ req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, EAP_PWD_HDR_SIZE + len + (totlen ? sizeof(u16) : 0), EAP_CODE_REQUEST, id); if (req == NULL) { eap_pwd_state(data, FAILURE); return NULL; } wpabuf_put_u8(req, lm_exch); if (EAP_PWD_GET_LENGTH_BIT(lm_exch)) wpabuf_put_be16(req, totlen); buf = wpabuf_head_u8(data->outbuf); wpabuf_put_data(req, buf + data->out_frag_pos, len); data->out_frag_pos += len; /* * either not fragged or last fragment, either way free up the data */ if (data->out_frag_pos >= wpabuf_len(data->outbuf)) { wpabuf_free(data->outbuf); data->outbuf = NULL; data->out_frag_pos = 0; } return req; }
int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id, int all_attr) { u8 *len; int i; if (wpabuf_tailroom(buf) < 6) return -1; wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); len = wpabuf_put(buf, 1); wpabuf_put_be32(buf, WPS_DEV_OUI_WFA); if (wps_build_version(buf) < 0) return -1; if (all_attr) { if (wpabuf_tailroom(buf) < 5) return -1; wpabuf_put_be16(buf, ATTR_WPS_STATE); wpabuf_put_be16(buf, 1); wpabuf_put_u8(buf, WPS_STATE_NOT_CONFIGURED); } if (pw_id >= 0) { if (wpabuf_tailroom(buf) < 6) return -1; /* Device Password ID */ wpabuf_put_be16(buf, ATTR_DEV_PASSWORD_ID); wpabuf_put_be16(buf, 2); wpa_printf(MSG_DEBUG, "P2P: WPS IE Device Password ID: %d", pw_id); wpabuf_put_be16(buf, pw_id); } if (all_attr) { if (wpabuf_tailroom(buf) < 5) return -1; wpabuf_put_be16(buf, ATTR_RESPONSE_TYPE); wpabuf_put_be16(buf, 1); wpabuf_put_u8(buf, WPS_RESP_ENROLLEE_INFO); if (wps_build_uuid_e(buf, p2p->cfg->uuid) < 0 || p2p_add_wps_string(buf, ATTR_MANUFACTURER, p2p->cfg->manufacturer) < 0 || p2p_add_wps_string(buf, ATTR_MODEL_NAME, p2p->cfg->model_name) < 0 || p2p_add_wps_string(buf, ATTR_MODEL_NUMBER, p2p->cfg->model_number) < 0 || p2p_add_wps_string(buf, ATTR_SERIAL_NUMBER, p2p->cfg->serial_number) < 0) return -1; if (wpabuf_tailroom(buf) < 4 + WPS_DEV_TYPE_LEN) return -1; wpabuf_put_be16(buf, ATTR_PRIMARY_DEV_TYPE); wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN); wpabuf_put_data(buf, p2p->cfg->pri_dev_type, WPS_DEV_TYPE_LEN); if (p2p_add_wps_string(buf, ATTR_DEV_NAME, p2p->cfg->dev_name) < 0) return -1; if (wpabuf_tailroom(buf) < 6) return -1; wpabuf_put_be16(buf, ATTR_CONFIG_METHODS); wpabuf_put_be16(buf, 2); wpabuf_put_be16(buf, p2p->cfg->config_methods); } if (wps_build_wfa_ext(buf, 0, NULL, 0) < 0) return -1; if (all_attr && p2p->cfg->num_sec_dev_types) { if (wpabuf_tailroom(buf) < 4 + WPS_DEV_TYPE_LEN * p2p->cfg->num_sec_dev_types) return -1; wpabuf_put_be16(buf, ATTR_SECONDARY_DEV_TYPE_LIST); wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN * p2p->cfg->num_sec_dev_types); wpabuf_put_data(buf, p2p->cfg->sec_dev_type, WPS_DEV_TYPE_LEN * p2p->cfg->num_sec_dev_types); } /* Add the WPS vendor extensions */ for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { if (p2p->wps_vendor_ext[i] == NULL) break; if (wpabuf_tailroom(buf) < 4 + wpabuf_len(p2p->wps_vendor_ext[i])) continue; wpabuf_put_be16(buf, ATTR_VENDOR_EXT); wpabuf_put_be16(buf, wpabuf_len(p2p->wps_vendor_ext[i])); wpabuf_put_buf(buf, p2p->wps_vendor_ext[i]); } p2p_buf_update_ie_hdr(buf, len); return 0; }
static struct wpabuf * tncc_build_soh(int ver) { struct wpabuf *buf; u8 *tlv_len, *tlv_len2, *outer_len, *inner_len, *ssoh_len, *end; u8 correlation_id[24]; /* TODO: get correct name */ char *machinename = "*****@*****.**"; if (os_get_random(correlation_id, sizeof(correlation_id))) return NULL; wpa_hexdump(MSG_DEBUG, "TNC: SoH Correlation ID", correlation_id, sizeof(correlation_id)); buf = wpabuf_alloc(200); if (buf == NULL) return NULL; /* Vendor-Specific TLV (Microsoft) - SoH */ wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); /* TLV Type */ tlv_len = wpabuf_put(buf, 2); /* Length */ wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* Vendor_Id */ wpabuf_put_be16(buf, 0x01); /* TLV Type - SoH TLV */ tlv_len2 = wpabuf_put(buf, 2); /* Length */ /* SoH Header */ wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); /* Outer Type */ outer_len = wpabuf_put(buf, 2); wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* IANA SMI Code */ wpabuf_put_be16(buf, ver); /* Inner Type */ inner_len = wpabuf_put(buf, 2); if (ver == 2) { /* SoH Mode Sub-Header */ /* Outer Type */ wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); wpabuf_put_be16(buf, 4 + 24 + 1 + 1); /* Length */ wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* IANA SMI Code */ /* Value: */ wpabuf_put_data(buf, correlation_id, sizeof(correlation_id)); wpabuf_put_u8(buf, 0x01); /* Intent Flag - Request */ wpabuf_put_u8(buf, 0x00); /* Content-Type Flag */ } /* SSoH TLV */ /* System-Health-Id */ wpabuf_put_be16(buf, 0x0002); /* Type */ wpabuf_put_be16(buf, 4); /* Length */ wpabuf_put_be32(buf, 79616); /* Vendor-Specific Attribute */ wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); ssoh_len = wpabuf_put(buf, 2); wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* IANA SMI Code */ /* MS-Packet-Info */ wpabuf_put_u8(buf, SSOH_MS_PACKET_INFO); /* Note: IF-TNCCS-SOH v1.0 r8 claims this field to be: * Reserved(4 bits) r(1 bit) Vers(3 bits), but Windows XP * SP3 seems to be sending 0x11 for SSoH, i.e., r(request/response) bit * would not be in the specified location. * [MS-SOH] 4.0.2: Reserved(3 bits) r(1 bit) Vers(4 bits) */ wpabuf_put_u8(buf, 0x11); /* r=request, vers=1 */ /* MS-Machine-Inventory */ /* TODO: get correct values; 0 = not applicable for OS */ wpabuf_put_u8(buf, SSOH_MS_MACHINE_INVENTORY); wpabuf_put_be32(buf, 0); /* osVersionMajor */ wpabuf_put_be32(buf, 0); /* osVersionMinor */ wpabuf_put_be32(buf, 0); /* osVersionBuild */ wpabuf_put_be16(buf, 0); /* spVersionMajor */ wpabuf_put_be16(buf, 0); /* spVersionMinor */ wpabuf_put_be16(buf, 0); /* procArch */ /* MS-MachineName */ wpabuf_put_u8(buf, SSOH_MS_MACHINENAME); wpabuf_put_be16(buf, os_strlen(machinename) + 1); wpabuf_put_data(buf, machinename, os_strlen(machinename) + 1); /* MS-CorrelationId */ wpabuf_put_u8(buf, SSOH_MS_CORRELATIONID); wpabuf_put_data(buf, correlation_id, sizeof(correlation_id)); /* MS-Quarantine-State */ wpabuf_put_u8(buf, SSOH_MS_QUARANTINE_STATE); wpabuf_put_be16(buf, 1); /* Flags: ExtState=0, f=0, qState=1 */ wpabuf_put_be32(buf, 0xffffffff); /* ProbTime (hi) */ wpabuf_put_be32(buf, 0xffffffff); /* ProbTime (lo) */ wpabuf_put_be16(buf, 1); /* urlLenInBytes */ wpabuf_put_u8(buf, 0); /* null termination for the url */ /* MS-Machine-Inventory-Ex */ wpabuf_put_u8(buf, SSOH_MS_MACHINE_INVENTORY_EX); wpabuf_put_be32(buf, 0); /* Reserved * (note: Windows XP SP3 uses 0xdecafbad) */ wpabuf_put_u8(buf, 1); /* ProductType: Client */ /* Update SSoH Length */ end = wpabuf_put(buf, 0); WPA_PUT_BE16(ssoh_len, end - ssoh_len - 2); /* TODO: SoHReportEntry TLV (zero or more) */ /* Update length fields */ end = wpabuf_put(buf, 0); WPA_PUT_BE16(tlv_len, end - tlv_len - 2); WPA_PUT_BE16(tlv_len2, end - tlv_len2 - 2); WPA_PUT_BE16(outer_len, end - outer_len - 2); WPA_PUT_BE16(inner_len, end - inner_len - 2); return buf; }
static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm, struct eap_fast_data *data) { u8 pac_key[EAP_FAST_PAC_KEY_LEN]; u8 *pac_buf, *pac_opaque; struct wpabuf *buf; u8 *pos; size_t buf_len, srv_id_info_len, pac_len; struct eap_tlv_hdr *pac_tlv; struct pac_tlv_hdr *pac_info; struct eap_tlv_result_tlv *result; struct os_time now; if (random_get_bytes(pac_key, EAP_FAST_PAC_KEY_LEN) < 0 || os_get_time(&now) < 0) return NULL; wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Generated PAC-Key", pac_key, EAP_FAST_PAC_KEY_LEN); pac_len = (2 + EAP_FAST_PAC_KEY_LEN) + (2 + 4) + (2 + sm->identity_len) + 8; pac_buf = os_malloc(pac_len); if (pac_buf == NULL) return NULL; srv_id_info_len = os_strlen(data->srv_id_info); pos = pac_buf; *pos++ = PAC_OPAQUE_TYPE_KEY; *pos++ = EAP_FAST_PAC_KEY_LEN; os_memcpy(pos, pac_key, EAP_FAST_PAC_KEY_LEN); pos += EAP_FAST_PAC_KEY_LEN; *pos++ = PAC_OPAQUE_TYPE_LIFETIME; *pos++ = 4; WPA_PUT_BE32(pos, now.sec + data->pac_key_lifetime); pos += 4; if (sm->identity) { *pos++ = PAC_OPAQUE_TYPE_IDENTITY; *pos++ = sm->identity_len; os_memcpy(pos, sm->identity, sm->identity_len); pos += sm->identity_len; } pac_len = pos - pac_buf; while (pac_len % 8) { *pos++ = PAC_OPAQUE_TYPE_PAD; pac_len++; } pac_opaque = os_malloc(pac_len + 8); if (pac_opaque == NULL) { os_free(pac_buf); return NULL; } if (aes_wrap(data->pac_opaque_encr, sizeof(data->pac_opaque_encr), pac_len / 8, pac_buf, pac_opaque) < 0) { os_free(pac_buf); os_free(pac_opaque); return NULL; } os_free(pac_buf); pac_len += 8; wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Opaque", pac_opaque, pac_len); buf_len = sizeof(*pac_tlv) + sizeof(struct pac_tlv_hdr) + EAP_FAST_PAC_KEY_LEN + sizeof(struct pac_tlv_hdr) + pac_len + data->srv_id_len + srv_id_info_len + 100 + sizeof(*result); buf = wpabuf_alloc(buf_len); if (buf == NULL) { os_free(pac_opaque); return NULL; } /* Result TLV */ wpa_printf(MSG_DEBUG, "EAP-FAST: Add Result TLV (status=SUCCESS)"); result = wpabuf_put(buf, sizeof(*result)); WPA_PUT_BE16((u8 *) &result->tlv_type, EAP_TLV_TYPE_MANDATORY | EAP_TLV_RESULT_TLV); WPA_PUT_BE16((u8 *) &result->length, 2); WPA_PUT_BE16((u8 *) &result->status, EAP_TLV_RESULT_SUCCESS); /* PAC TLV */ wpa_printf(MSG_DEBUG, "EAP-FAST: Add PAC TLV"); pac_tlv = wpabuf_put(buf, sizeof(*pac_tlv)); pac_tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY | EAP_TLV_PAC_TLV); /* PAC-Key */ eap_fast_put_tlv(buf, PAC_TYPE_PAC_KEY, pac_key, EAP_FAST_PAC_KEY_LEN); /* PAC-Opaque */ eap_fast_put_tlv(buf, PAC_TYPE_PAC_OPAQUE, pac_opaque, pac_len); os_free(pac_opaque); /* PAC-Info */ pac_info = wpabuf_put(buf, sizeof(*pac_info)); pac_info->type = host_to_be16(PAC_TYPE_PAC_INFO); /* PAC-Lifetime (inside PAC-Info) */ eap_fast_put_tlv_hdr(buf, PAC_TYPE_CRED_LIFETIME, 4); wpabuf_put_be32(buf, now.sec + data->pac_key_lifetime); /* A-ID (inside PAC-Info) */ eap_fast_put_tlv(buf, PAC_TYPE_A_ID, data->srv_id, data->srv_id_len); /* Note: headers may be misaligned after A-ID */ if (sm->identity) { eap_fast_put_tlv(buf, PAC_TYPE_I_ID, sm->identity, sm->identity_len); } /* A-ID-Info (inside PAC-Info) */ eap_fast_put_tlv(buf, PAC_TYPE_A_ID_INFO, data->srv_id_info, srv_id_info_len); /* PAC-Type (inside PAC-Info) */ eap_fast_put_tlv_hdr(buf, PAC_TYPE_PAC_TYPE, 2); wpabuf_put_be16(buf, PAC_TYPE_TUNNEL_PAC); /* Update PAC-Info and PAC TLV Length fields */ pos = wpabuf_put(buf, 0); pac_info->len = host_to_be16(pos - (u8 *) (pac_info + 1)); pac_tlv->length = host_to_be16(pos - (u8 *) (pac_tlv + 1)); return buf; }
static int p2p_buf_add_service_info(struct wpabuf *buf, struct p2p_data *p2p, u32 adv_id, u16 config_methods, const char *svc_name, u8 **ie_len, u8 **pos, size_t *total_len, u8 *attr_len) { size_t svc_len; size_t remaining; size_t info_len; p2p_dbg(p2p, "Add service info for %s (adv_id=%u)", svc_name, adv_id); svc_len = os_strlen(svc_name); info_len = sizeof(adv_id) + sizeof(config_methods) + sizeof(u8) + svc_len; if (info_len + *total_len > MAX_SVC_ADV_LEN) { p2p_dbg(p2p, "Unsufficient buffer, failed to add advertised service info"); return -1; } if (svc_len > 255) { p2p_dbg(p2p, "Invalid service name length (%u bytes), failed to add advertised service info", (unsigned int) svc_len); return -1; } if (*ie_len) { int ie_data_len = (*pos - *ie_len) - 1; if (ie_data_len < 0 || ie_data_len > 255) { p2p_dbg(p2p, "Invalid IE length, failed to add advertised service info"); return -1; } remaining = 255 - ie_data_len; } else { /* * Adding new P2P IE header takes 6 extra bytes: * - 2 byte IE header (1 byte IE id and 1 byte length) * - 4 bytes of IE_VENDOR_TYPE are reduced from 255 below */ *ie_len = p2p_buf_add_ie_hdr(buf); remaining = 255 - 4; } if (remaining < sizeof(u32) + sizeof(u16) + sizeof(u8)) { /* * Split adv_id, config_methods, and svc_name_len between two * IEs. */ size_t front = remaining; size_t back = sizeof(u32) + sizeof(u16) + sizeof(u8) - front; u8 holder[sizeof(u32) + sizeof(u16) + sizeof(u8)]; WPA_PUT_LE32(holder, adv_id); WPA_PUT_BE16(&holder[sizeof(u32)], config_methods); holder[sizeof(u32) + sizeof(u16)] = svc_len; if (front) wpabuf_put_data(buf, holder, front); p2p_buf_update_ie_hdr(buf, *ie_len); *ie_len = p2p_buf_add_ie_hdr(buf); wpabuf_put_data(buf, &holder[front], back); remaining = 255 - 4 - (sizeof(u32) + sizeof(u16) + sizeof(u8)) - back; } else { wpabuf_put_le32(buf, adv_id); wpabuf_put_be16(buf, config_methods); wpabuf_put_u8(buf, svc_len); remaining -= sizeof(adv_id) + sizeof(config_methods) + sizeof(u8); } if (remaining < svc_len) { /* split svc_name between two or three IEs */ size_t front = remaining; size_t back = svc_len - front; if (front) wpabuf_put_data(buf, svc_name, front); p2p_buf_update_ie_hdr(buf, *ie_len); *ie_len = p2p_buf_add_ie_hdr(buf); /* In rare cases, we must split across 3 attributes */ if (back > 255 - 4) { wpabuf_put_data(buf, &svc_name[front], 255 - 4); back -= 255 - 4; front += 255 - 4; p2p_buf_update_ie_hdr(buf, *ie_len); *ie_len = p2p_buf_add_ie_hdr(buf); } wpabuf_put_data(buf, &svc_name[front], back); remaining = 255 - 4 - back; } else { wpabuf_put_data(buf, svc_name, svc_len); remaining -= svc_len; } p2p_buf_update_ie_hdr(buf, *ie_len); /* set *ie_len to NULL if a new IE has to be added on the next call */ if (!remaining) *ie_len = NULL; /* set *pos to point to the next byte to update */ *pos = wpabuf_put(buf, 0); *total_len += info_len; WPA_PUT_LE16(attr_len, (u16) *total_len); return 0; }
int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg) { struct wpabuf *pubkey = NULL; wpa_printf(MSG_DEBUG, "WPS: * Public Key"); wpabuf_clear_free(wps->dh_privkey); wps->dh_privkey = NULL; if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey && wps->wps->dh_ctx) { wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys"); if (wps->wps->dh_pubkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: wps->wps->dh_pubkey == NULL"); return -1; } wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey); wps->dh_ctx = wps->wps->dh_ctx; wps->wps->dh_ctx = NULL; pubkey = wpabuf_dup(wps->wps->dh_pubkey); #ifdef CONFIG_WPS_NFC } else if ((wps->dev_pw_id >= 0x10 || wps->dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER) && (wps->wps->ap || (wps->wps->ap_nfc_dh_pubkey && wps->wps->ap_nfc_dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER && wps->dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER)) && (wps->dev_pw_id == wps->wps->ap_nfc_dev_pw_id || wps->wps->ap_nfc_dh_pubkey)) { wpa_printf(MSG_DEBUG, "WPS: Using NFC password token DH keys"); if (wps->wps->ap_nfc_dh_privkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: wps->wps->ap_nfc_dh_privkey == NULL"); return -1; } if (wps->wps->ap_nfc_dh_pubkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: wps->wps->ap_nfc_dh_pubkey == NULL"); return -1; } wps->dh_privkey = wpabuf_dup(wps->wps->ap_nfc_dh_privkey); pubkey = wpabuf_dup(wps->wps->ap_nfc_dh_pubkey); if (wps->dh_privkey && pubkey) wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, pubkey); #endif /* CONFIG_WPS_NFC */ } else { wpa_printf(MSG_DEBUG, "WPS: Generate new DH keys"); dh5_free(wps->dh_ctx); wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey); pubkey = wpabuf_zeropad(pubkey, 192); } if (wps->dh_ctx == NULL || wps->dh_privkey == NULL || pubkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: Failed to initialize " "Diffie-Hellman handshake"); wpabuf_free(pubkey); return -1; } wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH Private Key", wps->dh_privkey); wpa_hexdump_buf(MSG_DEBUG, "WPS: DH own Public Key", pubkey); wpabuf_put_be16(msg, ATTR_PUBLIC_KEY); wpabuf_put_be16(msg, wpabuf_len(pubkey)); wpabuf_put_buf(msg, pubkey); if (wps->registrar) { wpabuf_free(wps->dh_pubkey_r); wps->dh_pubkey_r = pubkey; } else { wpabuf_free(wps->dh_pubkey_e); wps->dh_pubkey_e = pubkey; } return 0; }
struct wpabuf * ndef_build_wifi_hr(void) { struct wpabuf *rn, *cr, *ac_payload, *ac, *hr_payload, *hr; struct wpabuf *hc; rn = wpabuf_alloc(2); if (rn == NULL) return NULL; wpabuf_put_be16(rn, os_random() & 0xffff); cr = ndef_build_record(FLAG_MESSAGE_BEGIN | FLAG_TNF_NFC_FORUM, "cr", 2, NULL, 0, rn); wpabuf_free(rn); if (cr == NULL) return NULL; ac_payload = wpabuf_alloc(4); if (ac_payload == NULL) { wpabuf_free(cr); return NULL; } wpabuf_put_u8(ac_payload, 0x01); /* Carrier Flags: CRS=1 "active" */ wpabuf_put_u8(ac_payload, 0x01); /* Carrier Data Reference Length */ wpabuf_put_u8(ac_payload, '0'); /* Carrier Data Reference: "0" */ wpabuf_put_u8(ac_payload, 0); /* Aux Data Reference Count */ ac = ndef_build_record(FLAG_MESSAGE_END | FLAG_TNF_NFC_FORUM, "ac", 2, NULL, 0, ac_payload); wpabuf_free(ac_payload); if (ac == NULL) { wpabuf_free(cr); return NULL; } hr_payload = wpabuf_alloc(1 + wpabuf_len(cr) + wpabuf_len(ac)); if (hr_payload == NULL) { wpabuf_free(cr); wpabuf_free(ac); return NULL; } wpabuf_put_u8(hr_payload, 0x12); /* Connection Handover Version 1.2 */ wpabuf_put_buf(hr_payload, cr); wpabuf_put_buf(hr_payload, ac); wpabuf_free(cr); wpabuf_free(ac); hr = ndef_build_record(FLAG_MESSAGE_BEGIN | FLAG_TNF_NFC_FORUM, "Hr", 2, NULL, 0, hr_payload); wpabuf_free(hr_payload); if (hr == NULL) return NULL; hc = ndef_build_wifi_hc(0); if (hc == NULL) { wpabuf_free(hr); return NULL; } return wpabuf_concat(hr, hc); }
static struct wpabuf * eap_pwd_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, const struct wpabuf *reqData) { struct eap_pwd_data *data = priv; struct wpabuf *resp = NULL; const u8 *pos, *buf; size_t len; u16 tot_len = 0; u8 lm_exch; pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PWD, reqData, &len); if ((pos == NULL) || (len < 1)) { wpa_printf(MSG_DEBUG, "EAP-pwd: Got a frame but pos is %s and " "len is %d", pos == NULL ? "NULL" : "not NULL", (int) len); ret->ignore = TRUE; return NULL; } ret->ignore = FALSE; ret->methodState = METHOD_MAY_CONT; ret->decision = DECISION_FAIL; ret->allowNotifications = FALSE; lm_exch = *pos; pos++; /* skip over the bits and the exch */ len--; /* * we're fragmenting so send out the next fragment */ if (data->out_frag_pos) { /* * this should be an ACK */ if (len) wpa_printf(MSG_INFO, "Bad Response! Fragmenting but " "not an ACK"); wpa_printf(MSG_DEBUG, "EAP-pwd: Got an ACK for a fragment"); /* * check if there are going to be more fragments */ len = wpabuf_len(data->outbuf) - data->out_frag_pos; if ((len + EAP_PWD_HDR_SIZE) > data->mtu) { len = data->mtu - EAP_PWD_HDR_SIZE; EAP_PWD_SET_MORE_BIT(lm_exch); } resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, EAP_PWD_HDR_SIZE + len, EAP_CODE_RESPONSE, eap_get_id(reqData)); if (resp == NULL) { wpa_printf(MSG_INFO, "Unable to allocate memory for " "next fragment!"); return NULL; } wpabuf_put_u8(resp, lm_exch); buf = wpabuf_head_u8(data->outbuf); wpabuf_put_data(resp, buf + data->out_frag_pos, len); data->out_frag_pos += len; /* * this is the last fragment so get rid of the out buffer */ if (data->out_frag_pos >= wpabuf_len(data->outbuf)) { wpabuf_free(data->outbuf); data->outbuf = NULL; data->out_frag_pos = 0; } wpa_printf(MSG_DEBUG, "EAP-pwd: Send %s fragment of %d bytes", data->out_frag_pos == 0 ? "last" : "next", (int) len); return resp; } /* * see if this is a fragment that needs buffering * * if it's the first fragment there'll be a length field */ if (EAP_PWD_GET_LENGTH_BIT(lm_exch)) { tot_len = WPA_GET_BE16(pos); wpa_printf(MSG_DEBUG, "EAP-pwd: Incoming fragments whose " "total length = %d", tot_len); data->inbuf = wpabuf_alloc(tot_len); if (data->inbuf == NULL) { wpa_printf(MSG_INFO, "Out of memory to buffer " "fragments!"); return NULL; } pos += sizeof(u16); len -= sizeof(u16); } /* * buffer and ACK the fragment */ if (EAP_PWD_GET_MORE_BIT(lm_exch)) { data->in_frag_pos += len; if (data->in_frag_pos > wpabuf_size(data->inbuf)) { wpa_printf(MSG_INFO, "EAP-pwd: Buffer overflow attack " "detected (%d vs. %d)!", (int) data->in_frag_pos, (int) wpabuf_len(data->inbuf)); wpabuf_free(data->inbuf); data->in_frag_pos = 0; return NULL; } wpabuf_put_data(data->inbuf, pos, len); resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, EAP_PWD_HDR_SIZE, EAP_CODE_RESPONSE, eap_get_id(reqData)); if (resp != NULL) wpabuf_put_u8(resp, (EAP_PWD_GET_EXCHANGE(lm_exch))); wpa_printf(MSG_DEBUG, "EAP-pwd: ACKing a %d byte fragment", (int) len); return resp; } /* * we're buffering and this is the last fragment */ if (data->in_frag_pos) { wpabuf_put_data(data->inbuf, pos, len); wpa_printf(MSG_DEBUG, "EAP-pwd: Last fragment, %d bytes", (int) len); data->in_frag_pos += len; pos = wpabuf_head_u8(data->inbuf); len = data->in_frag_pos; } wpa_printf(MSG_DEBUG, "EAP-pwd: processing frame: exch %d, len %d", EAP_PWD_GET_EXCHANGE(lm_exch), (int) len); switch (EAP_PWD_GET_EXCHANGE(lm_exch)) { case EAP_PWD_OPCODE_ID_EXCH: eap_pwd_perform_id_exchange(sm, data, ret, reqData, pos, len); break; case EAP_PWD_OPCODE_COMMIT_EXCH: eap_pwd_perform_commit_exchange(sm, data, ret, reqData, pos, len); break; case EAP_PWD_OPCODE_CONFIRM_EXCH: eap_pwd_perform_confirm_exchange(sm, data, ret, reqData, pos, len); break; default: wpa_printf(MSG_INFO, "EAP-pwd: Ignoring message with unknown " "opcode %d", lm_exch); break; } /* * if we buffered the just processed input now's the time to free it */ if (data->in_frag_pos) { wpabuf_free(data->inbuf); data->in_frag_pos = 0; } if (data->outbuf == NULL) return NULL; /* generic failure */ /* * we have output! Do we need to fragment it? */ len = wpabuf_len(data->outbuf); if ((len + EAP_PWD_HDR_SIZE) > data->mtu) { resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, data->mtu, EAP_CODE_RESPONSE, eap_get_id(reqData)); /* * if so it's the first so include a length field */ EAP_PWD_SET_LENGTH_BIT(lm_exch); EAP_PWD_SET_MORE_BIT(lm_exch); tot_len = len; /* * keep the packet at the MTU */ len = data->mtu - EAP_PWD_HDR_SIZE - sizeof(u16); wpa_printf(MSG_DEBUG, "EAP-pwd: Fragmenting output, total " "length = %d", tot_len); } else { resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, EAP_PWD_HDR_SIZE + len, EAP_CODE_RESPONSE, eap_get_id(reqData)); } if (resp == NULL) return NULL; wpabuf_put_u8(resp, lm_exch); if (EAP_PWD_GET_LENGTH_BIT(lm_exch)) { wpabuf_put_be16(resp, tot_len); data->out_frag_pos += len; } buf = wpabuf_head_u8(data->outbuf); wpabuf_put_data(resp, buf, len); /* * if we're not fragmenting then there's no need to carry this around */ if (data->out_frag_pos == 0) { wpabuf_free(data->outbuf); data->outbuf = NULL; data->out_frag_pos = 0; } return resp; }
static struct wpabuf * eap_wsc_build_msg(struct eap_wsc_data *data, struct eap_method_ret *ret, u8 id) { struct wpabuf *resp; u8 flags; size_t send_len, plen; ret->ignore = FALSE; wpa_printf(MSG_DEBUG, "EAP-WSC: Generating Response"); ret->allowNotifications = TRUE; flags = 0; send_len = wpabuf_len(data->out_buf) - data->out_used; if (2 + send_len > data->fragment_size) { send_len = data->fragment_size - 2; flags |= WSC_FLAGS_MF; if (data->out_used == 0) { flags |= WSC_FLAGS_LF; send_len -= 2; } } plen = 2 + send_len; if (flags & WSC_FLAGS_LF) plen += 2; resp = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, plen, EAP_CODE_RESPONSE, id); if (resp == NULL) return NULL; wpabuf_put_u8(resp, data->out_op_code); /* Op-Code */ wpabuf_put_u8(resp, flags); /* Flags */ if (flags & WSC_FLAGS_LF) wpabuf_put_be16(resp, wpabuf_len(data->out_buf)); wpabuf_put_data(resp, wpabuf_head_u8(data->out_buf) + data->out_used, send_len); data->out_used += send_len; ret->methodState = METHOD_MAY_CONT; ret->decision = DECISION_FAIL; if (data->out_used == wpabuf_len(data->out_buf)) { wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %lu bytes " "(message sent completely)", (unsigned long) send_len); wpabuf_free(data->out_buf); data->out_buf = NULL; data->out_used = 0; if ((data->state == FAIL && data->out_op_code == WSC_ACK) || data->out_op_code == WSC_NACK || data->out_op_code == WSC_Done) { eap_wsc_state(data, FAIL); ret->methodState = METHOD_DONE; } else eap_wsc_state(data, MESG); } else { wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %lu bytes " "(%lu more to send)", (unsigned long) send_len, (unsigned long) wpabuf_len(data->out_buf) - data->out_used); eap_wsc_state(data, WAIT_FRAG_ACK); } return resp; }
int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg) { struct wpabuf *pubkey; wpa_printf(MSG_DEBUG, "WPS: * Public Key"); wpabuf_free(wps->dh_privkey); //if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey) { if (wps->wps->dh_privkey) { wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys"); wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey); wps->dh_ctx = wps->wps->dh_ctx; wps->wps->dh_ctx = NULL; pubkey = wpabuf_dup(wps->wps->dh_pubkey); } else { wpa_printf(MSG_DEBUG, "WPS: Generate new DH keys"); wps->dh_privkey = NULL; dh5_free(wps->dh_ctx); wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey); pubkey = wpabuf_zeropad(pubkey, 192); } if (wps->dh_ctx == NULL || wps->dh_privkey == NULL || pubkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: Failed to initialize " "Diffie-Hellman handshake"); wpabuf_free(pubkey); return -1; } wpabuf_put_be16(msg, ATTR_PUBLIC_KEY); wpabuf_put_be16(msg, wpabuf_len(pubkey)); wpabuf_put_buf(msg, pubkey); if (wps->registrar) { wpabuf_free(wps->dh_pubkey_r); wps->dh_pubkey_r = pubkey; unsigned char *v; v = wpabuf_mhead_u8(pubkey); memset(pixie_pkr, 0, sizeof (pixie_pkr)); if (get_debug() == 4) { //verbose (-vvv) printf("[P] PKR: "); } int pixiecnt = 0; for (; pixiecnt < 192; pixiecnt++) { if (get_debug() == 4) { //verbose (-vvv) printf("%02x", v[pixiecnt]); } sprintf(cmd_pixie_aux, "%02x", v[pixiecnt]); strcat(pixie_pkr, cmd_pixie_aux); if (pixiecnt != 191) { if (get_debug() == 4) { //verbose (-vvv) printf(":"); } strcat(pixie_pkr, ":"); } } if (get_debug() == 4) { //verbose (-vvv) printf("\n"); } } else { wpabuf_free(wps->dh_pubkey_e); wps->dh_pubkey_e = pubkey; } return 0; }
int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll, const u8 *auth_macs, size_t auth_macs_count) { #ifdef CONFIG_CUSTOM_WFD if (enable_widi_ve == 1) { int i; u8 *len; wpabuf_put_be16(msg, ATTR_VENDOR_EXT); len = wpabuf_put(msg, 2); /* to be filled */ wpabuf_put_be24(msg, WPS_WIDI_SINK_VENDOR_OUI); /* must match with Source OUI */ wpabuf_put_u8(msg, 0x2); //REMOTE DISPLAY wpabuf_put_be16(msg, 0x0003); //REMOTE DISPLAY Sink Info wpabuf_put_be16(msg, 0x000b); //Length of data that follows for (i=0; i < 11 ;i++) { wpabuf_put_u8(msg, fill_sink_info[i]); //sink info } WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2); } else { #endif /* CONFIG_CUSTOM_WFD */ #ifdef CONFIG_WPS2 u8 *len; wpabuf_put_be16(msg, ATTR_VENDOR_EXT); len = wpabuf_put(msg, 2); /* to be filled */ wpabuf_put_be24(msg, WPS_VENDOR_ID_WFA); wpa_printf(MSG_DEBUG, "WPS: * Version2 (0x%x)", WPS_VERSION); wpabuf_put_u8(msg, WFA_ELEM_VERSION2); wpabuf_put_u8(msg, 1); wpabuf_put_u8(msg, WPS_VERSION); if (req_to_enroll) { wpa_printf(MSG_DEBUG, "WPS: * Request to Enroll (1)"); wpabuf_put_u8(msg, WFA_ELEM_REQUEST_TO_ENROLL); wpabuf_put_u8(msg, 1); wpabuf_put_u8(msg, 1); } if (auth_macs && auth_macs_count) { size_t i; wpa_printf(MSG_DEBUG, "WPS: * AuthorizedMACs (count=%d)", (int) auth_macs_count); wpabuf_put_u8(msg, WFA_ELEM_AUTHORIZEDMACS); wpabuf_put_u8(msg, auth_macs_count * ETH_ALEN); wpabuf_put_data(msg, auth_macs, auth_macs_count * ETH_ALEN); for (i = 0; i < auth_macs_count; i++) wpa_printf(MSG_DEBUG, "WPS: AuthorizedMAC: " MACSTR, MAC2STR(&auth_macs[i * ETH_ALEN])); } WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2); #endif /* CONFIG_WPS2 */ #ifdef CONFIG_CUSTOM_WFD } #endif /* CONFIG_CUSTOM_WFD */ #ifdef CONFIG_WPS_TESTING if (WPS_VERSION > 0x20) { wpa_printf(MSG_DEBUG, "WPS: * Extensibility Testing - extra " "attribute"); wpabuf_put_be16(msg, ATTR_EXTENSIBILITY_TEST); wpabuf_put_be16(msg, 1); wpabuf_put_u8(msg, 42); } #endif /* CONFIG_WPS_TESTING */ return 0; }
static int ikev2_build_sar1(struct ikev2_responder_data *data, struct wpabuf *msg, u8 next_payload) { struct ikev2_payload_hdr *phdr; size_t plen; struct ikev2_proposal *p; struct ikev2_transform *t; wpa_printf(MSG_DEBUG, "IKEV2: Adding SAr1 payload"); /* SAr1 - RFC 4306, Sect. 2.7 and 3.3 */ phdr = wpabuf_put(msg, sizeof(*phdr)); phdr->next_payload = next_payload; phdr->flags = 0; p = wpabuf_put(msg, sizeof(*p)); #ifdef CCNS_PL /* Seems to require that the Proposal # is 1 even though RFC 4306 * Sect 3.3.1 has following requirement "When a proposal is accepted, * all of the proposal numbers in the SA payload MUST be the same and * MUST match the number on the proposal sent that was accepted.". */ p->proposal_num = 1; #else /* CCNS_PL */ p->proposal_num = data->proposal.proposal_num; #endif /* CCNS_PL */ p->protocol_id = IKEV2_PROTOCOL_IKE; p->num_transforms = 4; t = wpabuf_put(msg, sizeof(*t)); t->type = 3; t->transform_type = IKEV2_TRANSFORM_ENCR; WPA_PUT_BE16(t->transform_id, data->proposal.encr); if (data->proposal.encr == ENCR_AES_CBC) { /* Transform Attribute: Key Len = 128 bits */ #ifdef CCNS_PL wpabuf_put_be16(msg, 0x001d); /* ?? */ #else /* CCNS_PL */ wpabuf_put_be16(msg, 0x800e); /* AF=1, AttrType=14 */ #endif /* CCNS_PL */ wpabuf_put_be16(msg, 128); /* 128-bit key */ } plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) t; WPA_PUT_BE16(t->transform_length, plen); t = wpabuf_put(msg, sizeof(*t)); t->type = 3; WPA_PUT_BE16(t->transform_length, sizeof(*t)); t->transform_type = IKEV2_TRANSFORM_PRF; WPA_PUT_BE16(t->transform_id, data->proposal.prf); t = wpabuf_put(msg, sizeof(*t)); t->type = 3; WPA_PUT_BE16(t->transform_length, sizeof(*t)); t->transform_type = IKEV2_TRANSFORM_INTEG; WPA_PUT_BE16(t->transform_id, data->proposal.integ); t = wpabuf_put(msg, sizeof(*t)); WPA_PUT_BE16(t->transform_length, sizeof(*t)); t->transform_type = IKEV2_TRANSFORM_DH; WPA_PUT_BE16(t->transform_id, data->proposal.dh); plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) p; WPA_PUT_BE16(p->proposal_length, plen); plen = (u8 *) wpabuf_put(msg, 0) - (u8 *) phdr; WPA_PUT_BE16(phdr->payload_length, plen); return 0; }
static struct wpabuf * eap_peap_build_phase2_tlv(struct eap_sm *sm, struct eap_peap_data *data, u8 id) { struct wpabuf *buf, *encr_req; size_t mlen; mlen = 6; /* Result TLV */ if (data->peap_version == 0 && data->tlv_request == TLV_REQ_SUCCESS && data->crypto_binding != NO_BINDING) { mlen += 60; /* Cryptobinding TLV */ #ifdef EAP_SERVER_TNC if (data->soh_response) mlen += wpabuf_len(data->soh_response); #endif /* EAP_SERVER_TNC */ } buf = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, mlen, EAP_CODE_REQUEST, id); if (buf == NULL) return NULL; wpabuf_put_u8(buf, 0x80); /* Mandatory */ wpabuf_put_u8(buf, EAP_TLV_RESULT_TLV); /* Length */ wpabuf_put_be16(buf, 2); /* Status */ wpabuf_put_be16(buf, data->tlv_request == TLV_REQ_SUCCESS ? EAP_TLV_RESULT_SUCCESS : EAP_TLV_RESULT_FAILURE); if (data->peap_version == 0 && data->tlv_request == TLV_REQ_SUCCESS && data->crypto_binding != NO_BINDING) { u8 *mac; u8 eap_type = EAP_TYPE_PEAP; const u8 *addr[2]; size_t len[2]; u16 tlv_type; #ifdef EAP_SERVER_TNC if (data->soh_response) { wpa_printf(MSG_DEBUG, "EAP-PEAP: Adding MS-SOH " "Response TLV"); wpabuf_put_buf(buf, data->soh_response); wpabuf_free(data->soh_response); data->soh_response = NULL; } #endif /* EAP_SERVER_TNC */ if (eap_peap_derive_cmk(sm, data) < 0 || random_get_bytes(data->binding_nonce, 32)) { wpabuf_free(buf); return NULL; } /* Compound_MAC: HMAC-SHA1-160(cryptobinding TLV | EAP type) */ addr[0] = wpabuf_put(buf, 0); len[0] = 60; addr[1] = &eap_type; len[1] = 1; tlv_type = EAP_TLV_CRYPTO_BINDING_TLV; wpabuf_put_be16(buf, tlv_type); wpabuf_put_be16(buf, 56); wpabuf_put_u8(buf, 0); /* Reserved */ wpabuf_put_u8(buf, data->peap_version); /* Version */ wpabuf_put_u8(buf, data->recv_version); /* RecvVersion */ wpabuf_put_u8(buf, 0); /* SubType: 0 = Request, 1 = Response */ wpabuf_put_data(buf, data->binding_nonce, 32); /* Nonce */ mac = wpabuf_put(buf, 20); /* Compound_MAC */ wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC CMK", data->cmk, 20); wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC data 1", addr[0], len[0]); wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC data 2", addr[1], len[1]); hmac_sha1_vector(data->cmk, 20, 2, addr, len, mac); wpa_hexdump(MSG_MSGDUMP, "EAP-PEAP: Compound_MAC", mac, SHA1_MAC_LEN); data->crypto_binding_sent = 1; } wpa_hexdump_buf_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 TLV data", buf); encr_req = eap_server_tls_encrypt(sm, &data->ssl, buf); wpabuf_free(buf); return encr_req; }
static void eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data, struct eap_method_ret *ret, const struct wpabuf *reqData, const u8 *payload, size_t payload_len) { struct eap_pwd_id *id; const u8 *password; size_t password_len; u8 pwhashhash[16]; int res; if (data->state != PWD_ID_Req) { ret->ignore = TRUE; eap_pwd_state(data, FAILURE); return; } if (payload_len < sizeof(struct eap_pwd_id)) { ret->ignore = TRUE; eap_pwd_state(data, FAILURE); return; } id = (struct eap_pwd_id *) payload; data->group_num = be_to_host16(id->group_num); wpa_printf(MSG_DEBUG, "EAP-PWD: Server EAP-pwd-ID proposal: group=%u random=%u prf=%u prep=%u", data->group_num, id->random_function, id->prf, id->prep); if ((id->random_function != EAP_PWD_DEFAULT_RAND_FUNC) || (id->prf != EAP_PWD_DEFAULT_PRF)) { ret->ignore = TRUE; eap_pwd_state(data, FAILURE); return; } if (id->prep != EAP_PWD_PREP_NONE && id->prep != EAP_PWD_PREP_MS) { wpa_printf(MSG_DEBUG, "EAP-PWD: Unsupported password pre-processing technique (Prep=%u)", id->prep); eap_pwd_state(data, FAILURE); return; } if (id->prep == EAP_PWD_PREP_NONE && data->password_hash) { wpa_printf(MSG_DEBUG, "EAP-PWD: Unhashed password not available"); eap_pwd_state(data, FAILURE); return; } wpa_printf(MSG_DEBUG, "EAP-PWD (peer): using group %d", data->group_num); data->id_server = os_malloc(payload_len - sizeof(struct eap_pwd_id)); if (data->id_server == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: memory allocation id fail"); eap_pwd_state(data, FAILURE); return; } data->id_server_len = payload_len - sizeof(struct eap_pwd_id); os_memcpy(data->id_server, id->identity, data->id_server_len); wpa_hexdump_ascii(MSG_INFO, "EAP-PWD (peer): server sent id of", data->id_server, data->id_server_len); data->grp = os_zalloc(sizeof(EAP_PWD_group)); if (data->grp == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: failed to allocate memory for " "group"); eap_pwd_state(data, FAILURE); return; } if (id->prep == EAP_PWD_PREP_MS) { if (data->password_hash) { res = hash_nt_password_hash(data->password, pwhashhash); } else { u8 pwhash[16]; res = nt_password_hash(data->password, data->password_len, pwhash); if (res == 0) res = hash_nt_password_hash(pwhash, pwhashhash); os_memset(pwhash, 0, sizeof(pwhash)); } if (res) { eap_pwd_state(data, FAILURE); return; } password = pwhashhash; password_len = sizeof(pwhashhash); } else { password = data->password; password_len = data->password_len; } /* compute PWE */ res = compute_password_element(data->grp, data->group_num, password, password_len, data->id_server, data->id_server_len, data->id_peer, data->id_peer_len, id->token); os_memset(pwhashhash, 0, sizeof(pwhashhash)); if (res) { wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to compute PWE"); eap_pwd_state(data, FAILURE); return; } wpa_printf(MSG_DEBUG, "EAP-PWD (peer): computed %d bit PWE...", BN_num_bits(data->grp->prime)); data->outbuf = wpabuf_alloc(sizeof(struct eap_pwd_id) + data->id_peer_len); if (data->outbuf == NULL) { eap_pwd_state(data, FAILURE); return; } wpabuf_put_be16(data->outbuf, data->group_num); wpabuf_put_u8(data->outbuf, EAP_PWD_DEFAULT_RAND_FUNC); wpabuf_put_u8(data->outbuf, EAP_PWD_DEFAULT_PRF); wpabuf_put_data(data->outbuf, id->token, sizeof(id->token)); wpabuf_put_u8(data->outbuf, EAP_PWD_PREP_NONE); wpabuf_put_data(data->outbuf, data->id_peer, data->id_peer_len); eap_pwd_state(data, PWD_Commit_Req); }
int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll, const u8 *auth_macs, size_t auth_macs_count, u8 multi_ap_subelem) { u8 *len; #ifdef CONFIG_WPS_TESTING if (WPS_VERSION == 0x10) return 0; #endif /* CONFIG_WPS_TESTING */ if (wpabuf_tailroom(msg) < 7 + 3 + (req_to_enroll ? 3 : 0) + (auth_macs ? 2 + auth_macs_count * ETH_ALEN : 0)) return -1; wpabuf_put_be16(msg, ATTR_VENDOR_EXT); len = wpabuf_put(msg, 2); /* to be filled */ wpabuf_put_be24(msg, WPS_VENDOR_ID_WFA); wpa_printf(MSG_DEBUG, "WPS: * Version2 (0x%x)", WPS_VERSION); wpabuf_put_u8(msg, WFA_ELEM_VERSION2); wpabuf_put_u8(msg, 1); wpabuf_put_u8(msg, WPS_VERSION); if (req_to_enroll) { wpa_printf(MSG_DEBUG, "WPS: * Request to Enroll (1)"); wpabuf_put_u8(msg, WFA_ELEM_REQUEST_TO_ENROLL); wpabuf_put_u8(msg, 1); wpabuf_put_u8(msg, 1); } if (auth_macs && auth_macs_count) { size_t i; wpa_printf(MSG_DEBUG, "WPS: * AuthorizedMACs (count=%d)", (int) auth_macs_count); wpabuf_put_u8(msg, WFA_ELEM_AUTHORIZEDMACS); wpabuf_put_u8(msg, auth_macs_count * ETH_ALEN); wpabuf_put_data(msg, auth_macs, auth_macs_count * ETH_ALEN); for (i = 0; i < auth_macs_count; i++) wpa_printf(MSG_DEBUG, "WPS: AuthorizedMAC: " MACSTR, MAC2STR(&auth_macs[i * ETH_ALEN])); } if (multi_ap_subelem) { wpa_printf(MSG_DEBUG, "WPS: * Multi-AP (0x%x)", multi_ap_subelem); wpabuf_put_u8(msg, WFA_ELEM_MULTI_AP); wpabuf_put_u8(msg, 1); /* length */ wpabuf_put_u8(msg, multi_ap_subelem); } WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2); #ifdef CONFIG_WPS_TESTING if (WPS_VERSION > 0x20) { if (wpabuf_tailroom(msg) < 5) return -1; wpa_printf(MSG_DEBUG, "WPS: * Extensibility Testing - extra " "attribute"); wpabuf_put_be16(msg, ATTR_EXTENSIBILITY_TEST); wpabuf_put_be16(msg, 1); wpabuf_put_u8(msg, 42); } #endif /* CONFIG_WPS_TESTING */ return 0; }
static void eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data, struct eap_method_ret *ret, const struct wpabuf *reqData, const u8 *payload, size_t payload_len) { struct eap_pwd_id *id; if (data->state != PWD_ID_Req) { ret->ignore = TRUE; eap_pwd_state(data, FAILURE); return; } if (payload_len < sizeof(struct eap_pwd_id)) { ret->ignore = TRUE; eap_pwd_state(data, FAILURE); return; } id = (struct eap_pwd_id *) payload; data->group_num = be_to_host16(id->group_num); if ((id->random_function != EAP_PWD_DEFAULT_RAND_FUNC) || (id->prf != EAP_PWD_DEFAULT_PRF)) { ret->ignore = TRUE; eap_pwd_state(data, FAILURE); return; } wpa_printf(MSG_DEBUG, "EAP-PWD (peer): using group %d", data->group_num); data->id_server = os_malloc(payload_len - sizeof(struct eap_pwd_id)); if (data->id_server == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: memory allocation id fail"); eap_pwd_state(data, FAILURE); return; } data->id_server_len = payload_len - sizeof(struct eap_pwd_id); os_memcpy(data->id_server, id->identity, data->id_server_len); wpa_hexdump_ascii(MSG_INFO, "EAP-PWD (peer): server sent id of", data->id_server, data->id_server_len); if ((data->grp = (EAP_PWD_group *) os_malloc(sizeof(EAP_PWD_group))) == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: failed to allocate memory for " "group"); eap_pwd_state(data, FAILURE); return; } /* compute PWE */ if (compute_password_element(data->grp, data->group_num, data->password, data->password_len, data->id_server, data->id_server_len, data->id_peer, data->id_peer_len, id->token)) { wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to compute PWE"); eap_pwd_state(data, FAILURE); return; } wpa_printf(MSG_DEBUG, "EAP-PWD (peer): computed %d bit PWE...", BN_num_bits(data->grp->prime)); data->outbuf = wpabuf_alloc(sizeof(struct eap_pwd_id) + data->id_peer_len); if (data->outbuf == NULL) { eap_pwd_state(data, FAILURE); return; } wpabuf_put_be16(data->outbuf, data->group_num); wpabuf_put_u8(data->outbuf, EAP_PWD_DEFAULT_RAND_FUNC); wpabuf_put_u8(data->outbuf, EAP_PWD_DEFAULT_PRF); wpabuf_put_data(data->outbuf, id->token, sizeof(id->token)); wpabuf_put_u8(data->outbuf, EAP_PWD_PREP_NONE); wpabuf_put_data(data->outbuf, data->id_peer, data->id_peer_len); eap_pwd_state(data, PWD_Commit_Req); }
static struct wpabuf * eap_pax_process_std_1(struct eap_pax_data *data, struct eap_method_ret *ret, u8 id, const struct eap_pax_hdr *req, size_t req_plen) { struct wpabuf *resp; const u8 *pos; u8 *rpos; size_t left, plen; wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-1 (received)"); if (data->state != PAX_INIT) { wpa_printf(MSG_INFO, "EAP-PAX: PAX_STD-1 received in " "unexpected state (%d) - ignored", data->state); ret->ignore = TRUE; return NULL; } if (req->flags & EAP_PAX_FLAGS_CE) { wpa_printf(MSG_INFO, "EAP-PAX: PAX_STD-1 with CE flag set - " "ignored"); ret->ignore = TRUE; return NULL; } left = req_plen - sizeof(*req); if (left < 2 + EAP_PAX_RAND_LEN) { wpa_printf(MSG_INFO, "EAP-PAX: PAX_STD-1 with too short " "payload"); ret->ignore = TRUE; return NULL; } pos = (const u8 *) (req + 1); if (WPA_GET_BE16(pos) != EAP_PAX_RAND_LEN) { wpa_printf(MSG_INFO, "EAP-PAX: PAX_STD-1 with incorrect A " "length %d (expected %d)", WPA_GET_BE16(pos), EAP_PAX_RAND_LEN); ret->ignore = TRUE; return NULL; } pos += 2; left -= 2; os_memcpy(data->rand.r.x, pos, EAP_PAX_RAND_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: X (server rand)", data->rand.r.x, EAP_PAX_RAND_LEN); pos += EAP_PAX_RAND_LEN; left -= EAP_PAX_RAND_LEN; if (left > 0) { wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ignored extra payload", pos, left); } if (random_get_bytes(data->rand.r.y, EAP_PAX_RAND_LEN)) { wpa_printf(MSG_ERROR, "EAP-PAX: Failed to get random data"); ret->ignore = TRUE; return NULL; } wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Y (client rand)", data->rand.r.y, EAP_PAX_RAND_LEN); if (eap_pax_initial_key_derivation(req->mac_id, data->ak, data->rand.e, data->mk, data->ck, data->ick, data->mid) < 0) { ret->ignore = TRUE; return NULL; } wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-2 (sending)"); plen = 2 + EAP_PAX_RAND_LEN + 2 + data->cid_len + 2 + EAP_PAX_MAC_LEN + EAP_PAX_ICV_LEN; resp = eap_pax_alloc_resp(req, id, EAP_PAX_OP_STD_2, plen); if (resp == NULL) return NULL; wpabuf_put_be16(resp, EAP_PAX_RAND_LEN); wpabuf_put_data(resp, data->rand.r.y, EAP_PAX_RAND_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: B = Y (client rand)", data->rand.r.y, EAP_PAX_RAND_LEN); wpabuf_put_be16(resp, data->cid_len); wpabuf_put_data(resp, data->cid, data->cid_len); wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-PAX: CID", (u8 *) data->cid, data->cid_len); wpabuf_put_be16(resp, EAP_PAX_MAC_LEN); rpos = wpabuf_put(resp, EAP_PAX_MAC_LEN); eap_pax_mac(req->mac_id, data->ck, EAP_PAX_CK_LEN, data->rand.r.x, EAP_PAX_RAND_LEN, data->rand.r.y, EAP_PAX_RAND_LEN, (u8 *) data->cid, data->cid_len, rpos); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: MAC_CK(A, B, CID)", rpos, EAP_PAX_MAC_LEN); /* Optional ADE could be added here, if needed */ rpos = wpabuf_put(resp, EAP_PAX_ICV_LEN); eap_pax_mac(req->mac_id, data->ick, EAP_PAX_ICK_LEN, wpabuf_head(resp), wpabuf_len(resp) - EAP_PAX_ICV_LEN, NULL, 0, NULL, 0, rpos); wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ICV", rpos, EAP_PAX_ICV_LEN); data->state = PAX_STD_2_SENT; data->mac_id = req->mac_id; data->dh_group_id = req->dh_group_id; data->public_key_id = req->public_key_id; return resp; }
void p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, u16 pw_id, int all_attr) { u8 *len; int i; wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); len = wpabuf_put(buf, 1); wpabuf_put_be32(buf, WPS_DEV_OUI_WFA); wps_build_version(buf); if (all_attr) { wpabuf_put_be16(buf, ATTR_WPS_STATE); wpabuf_put_be16(buf, 1); wpabuf_put_u8(buf, WPS_STATE_NOT_CONFIGURED); } /* Device Password ID */ wpabuf_put_be16(buf, ATTR_DEV_PASSWORD_ID); wpabuf_put_be16(buf, 2); wpa_printf(MSG_DEBUG, "P2P: WPS IE Device Password ID: %d", pw_id); wpabuf_put_be16(buf, pw_id); if (all_attr) { size_t nlen; wpabuf_put_be16(buf, ATTR_RESPONSE_TYPE); wpabuf_put_be16(buf, 1); wpabuf_put_u8(buf, WPS_RESP_ENROLLEE_INFO); #if 0 /* FIX */ wps_build_uuid_e(buf, reg->wps->uuid); wps_build_manufacturer(dev, buf); wps_build_model_name(dev, buf); wps_build_model_number(dev, buf); wps_build_serial_number(dev, buf); #endif wpabuf_put_be16(buf, ATTR_PRIMARY_DEV_TYPE); wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN); wpabuf_put_data(buf, p2p->cfg->pri_dev_type, WPS_DEV_TYPE_LEN); wpabuf_put_be16(buf, ATTR_DEV_NAME); nlen = p2p->cfg->dev_name ? os_strlen(p2p->cfg->dev_name) : 0; wpabuf_put_be16(buf, nlen); if (p2p->cfg->dev_name) wpabuf_put_data(buf, p2p->cfg->dev_name, nlen); wpabuf_put_be16(buf, ATTR_CONFIG_METHODS); wpabuf_put_be16(buf, 2); wpabuf_put_be16(buf, 0); /* FIX: ? */ } wps_build_wfa_ext(buf, 0, NULL, 0); if (all_attr && p2p->cfg->num_sec_dev_types) { wpabuf_put_be16(buf, ATTR_SECONDARY_DEV_TYPE_LIST); wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN * p2p->cfg->num_sec_dev_types); wpabuf_put_data(buf, p2p->cfg->sec_dev_type, WPS_DEV_TYPE_LEN * p2p->cfg->num_sec_dev_types); } /* Add the WPS vendor extensions */ for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { if (p2p->wps_vendor_ext[i] == NULL) break; if (wpabuf_tailroom(buf) < 4 + wpabuf_len(p2p->wps_vendor_ext[i])) continue; wpabuf_put_be16(buf, ATTR_VENDOR_EXT); wpabuf_put_be16(buf, wpabuf_len(p2p->wps_vendor_ext[i])); wpabuf_put_buf(buf, p2p->wps_vendor_ext[i]); } p2p_buf_update_ie_hdr(buf, len); }
void p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, u16 pw_id, int all_attr) { u8 *len; wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); len = wpabuf_put(buf, 1); wpabuf_put_be32(buf, WPS_DEV_OUI_WFA); wps_build_version(buf); if (all_attr) { wpabuf_put_be16(buf, ATTR_WPS_STATE); wpabuf_put_be16(buf, 1); wpabuf_put_u8(buf, WPS_STATE_NOT_CONFIGURED); } /* Device Password ID */ wpabuf_put_be16(buf, ATTR_DEV_PASSWORD_ID); wpabuf_put_be16(buf, 2); wpa_printf(MSG_DEBUG, "P2P: WPS IE Device Password ID: %d", pw_id); wpabuf_put_be16(buf, pw_id); if (all_attr) { size_t nlen; wpabuf_put_be16(buf, ATTR_RESPONSE_TYPE); wpabuf_put_be16(buf, 1); wpabuf_put_u8(buf, WPS_RESP_ENROLLEE_INFO); #if 0 /* FIX */ wps_build_uuid_e(buf, reg->wps->uuid); wps_build_manufacturer(dev, buf); wps_build_model_name(dev, buf); wps_build_model_number(dev, buf); wps_build_serial_number(dev, buf); #endif wpabuf_put_be16(buf, ATTR_PRIMARY_DEV_TYPE); wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN); wpabuf_put_data(buf, p2p->cfg->pri_dev_type, WPS_DEV_TYPE_LEN); wpabuf_put_be16(buf, ATTR_DEV_NAME); nlen = p2p->cfg->dev_name ? os_strlen(p2p->cfg->dev_name) : 0; wpabuf_put_be16(buf, nlen); if (p2p->cfg->dev_name) wpabuf_put_data(buf, p2p->cfg->dev_name, nlen); wpabuf_put_be16(buf, ATTR_CONFIG_METHODS); wpabuf_put_be16(buf, 2); wpabuf_put_be16(buf, 0); /* FIX: ? */ } wps_build_wfa_ext(buf, 0, NULL, 0); p2p_buf_update_ie_hdr(buf, len); }