static void * eap_gpsk_init(struct eap_sm *sm) { struct eap_gpsk_data *data; data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = GPSK_1; data->csuite_count = 0; if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF, EAP_GPSK_CIPHER_AES)) { WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor, EAP_GPSK_VENDOR_IETF); WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier, EAP_GPSK_CIPHER_AES); data->csuite_count++; } if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF, EAP_GPSK_CIPHER_SHA256)) { WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor, EAP_GPSK_VENDOR_IETF); WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier, EAP_GPSK_CIPHER_SHA256); data->csuite_count++; } return data; }
static void * eap_gpsk_init(struct eap_sm *sm) { struct eap_gpsk_data *data; data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = GPSK_1; /* TODO: add support for configuring ID_Server */ data->id_server = (u8 *) os_strdup("hostapd"); if (data->id_server) data->id_server_len = os_strlen((char *) data->id_server); data->csuite_count = 0; if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF, EAP_GPSK_CIPHER_AES)) { WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor, EAP_GPSK_VENDOR_IETF); WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier, EAP_GPSK_CIPHER_AES); data->csuite_count++; } if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF, EAP_GPSK_CIPHER_SHA256)) { WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor, EAP_GPSK_VENDOR_IETF); WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier, EAP_GPSK_CIPHER_SHA256); data->csuite_count++; } return data; }
static int cmd_clear_bss_counters(int s, int argc, char *argv[]) { u8 resp[WLANTEST_CTRL_MAX_RESP_LEN]; u8 buf[100], *pos; int rlen; if (argc < 1) { printf("clear_bss_counters needs one argument: BSSID\n"); return -1; } pos = buf; WPA_PUT_BE32(pos, WLANTEST_CTRL_CLEAR_BSS_COUNTERS); pos += 4; WPA_PUT_BE32(pos, WLANTEST_ATTR_BSSID); pos += 4; WPA_PUT_BE32(pos, ETH_ALEN); pos += 4; if (hwaddr_aton(argv[0], pos) < 0) { printf("Invalid BSSID '%s'\n", argv[0]); return -1; } pos += ETH_ALEN; rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp)); if (rlen < 0) return -1; printf("OK\n"); return 0; }
static void aes_gcm_prepare_j0(const u8 *iv, size_t iv_len, const u8 *H, u8 *J0) { u8 len_buf[16]; #ifndef OT_AESGCM_AES128_IV12_ONLY // DHD20150614 if (iv_len == 12) { #endif // DHD20150614 /* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */ os_memcpy(J0, iv, iv_len); os_memset(J0 + iv_len, 0, AES_BLOCK_SIZE - iv_len); J0[AES_BLOCK_SIZE - 1] = 0x01; #ifndef OT_AESGCM_AES128_IV12_ONLY // DHD20150614 } else { /* * s = 128 * ceil(len(IV)/128) - len(IV) * J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64) */ ghash_start(J0); ghash(H, iv, iv_len, J0); // AIDEN - Used to be: WPA_PUT_BE64(len_buf, 0); WPA_PUT_BE32(len_buf, 0); WPA_PUT_BE32(len_buf + 4, 0); // AIDEN - Used to be: WPA_PUT_BE64(len_buf + 8, iv_len * 8); WPA_PUT_BE32(len_buf + 8, 0); WPA_PUT_BE32(len_buf + 12, iv_len * 8); ghash(H, len_buf, sizeof(len_buf), J0); } #endif // DHD20150614 }
static void aes_gcm_ghash(const u8 *H, const u8 *aad, size_t aad_len, const u8 *crypt, size_t crypt_len, u8 *S) { u8 len_buf[16]; /* * u = 128 * ceil[len(C)/128] - len(C) * v = 128 * ceil[len(A)/128] - len(A) * S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64) * (i.e., zero padded to block size A || C and lengths of each in bits) */ ghash_start(S); ghash(H, aad, aad_len, S); ghash(H, crypt, crypt_len, S); // AIDEN - Used to be: WPA_PUT_BE64(len_buf, aad_len * 8); WPA_PUT_BE32(len_buf, 0); WPA_PUT_BE32(len_buf + 4, aad_len * 8); // AIDEN - Used to be: WPA_PUT_BE64(len_buf + 8, crypt_len * 8); WPA_PUT_BE32(len_buf + 8, 0); WPA_PUT_BE32(len_buf + 12, crypt_len * 8); ghash(H, len_buf, sizeof(len_buf), S); /* wpa_hexdump_key(MSG_EXCESSIVE, "S = GHASH_H(...)", S, 16); */ }
static void shift_right_block(u8 *v) { u32 val; val = WPA_GET_BE32(v + 12); val >>= 1; if (v[11] & 0x01) val |= 0x80000000; WPA_PUT_BE32(v + 12, val); val = WPA_GET_BE32(v + 8); val >>= 1; if (v[7] & 0x01) val |= 0x80000000; WPA_PUT_BE32(v + 8, val); val = WPA_GET_BE32(v + 4); val >>= 1; if (v[3] & 0x01) val |= 0x80000000; WPA_PUT_BE32(v + 4, val); val = WPA_GET_BE32(v); val >>= 1; WPA_PUT_BE32(v, val); }
static void ctrl_list_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen) { u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len; struct wlantest_bss *bss; struct wlantest_sta *sta; bss = ctrl_get_bss(wt, sock, cmd, clen); if (bss == NULL) return; pos = buf; WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS); pos += 4; WPA_PUT_BE32(pos, WLANTEST_ATTR_STA_ADDR); pos += 4; len = pos; /* to be filled */ pos += 4; dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) { if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN) break; os_memcpy(pos, sta->addr, ETH_ALEN); pos += ETH_ALEN; } WPA_PUT_BE32(len, pos - len - 4); ctrl_send(wt, sock, buf, pos - buf); }
static int cmd_send(int s, int argc, char *argv[]) { u8 resp[WLANTEST_CTRL_MAX_RESP_LEN]; u8 buf[WLANTEST_CTRL_MAX_CMD_LEN], *end, *pos, *len_pos; int rlen; enum wlantest_inject_protection prot; int arg; /* <prot> <raw frame as hex dump> */ if (argc < 2) { printf("send needs two arguments: protected/unprotected, " "raw frame as hex dump\n"); return -1; } pos = buf; end = buf + sizeof(buf); WPA_PUT_BE32(pos, WLANTEST_CTRL_SEND); pos += 4; if (os_strcasecmp(argv[0], "normal") == 0) prot = WLANTEST_INJECT_NORMAL; else if (os_strcasecmp(argv[0], "protected") == 0) prot = WLANTEST_INJECT_PROTECTED; else if (os_strcasecmp(argv[0], "unprotected") == 0) prot = WLANTEST_INJECT_UNPROTECTED; else if (os_strcasecmp(argv[0], "incorrect") == 0) prot = WLANTEST_INJECT_INCORRECT_KEY; else { printf("Unknown protection type '%s'\n", argv[1]); printf("Protection types: normal protected unprotected " "incorrect\n"); return -1; } pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_PROTECTION, prot); WPA_PUT_BE32(pos, WLANTEST_ATTR_FRAME); pos += 4; len_pos = pos; pos += 4; for (arg = 1; pos && arg < argc; arg++) pos = add_hex(pos, end, argv[arg]); if (pos == NULL) return -1; WPA_PUT_BE32(len_pos, pos - len_pos - 4); rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp)); if (rlen < 0) return -1; printf("OK\n"); return 0; }
static u8 * attr_hdr_add(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr, size_t len) { if (pos == NULL || end - pos < 8 + len) return NULL; WPA_PUT_BE32(pos, attr); pos += 4; WPA_PUT_BE32(pos, len); pos += 4; return pos; }
/** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (32 bytes) @param pScratchMem [in] Scratch memory; At least 288 bytes @return CRYPT_OK if successful */ static int sha256_done(void *priv, struct sha256_state *md, UINT8 *out, UINT8 *pScratchMem) { int i; UINT32 *ptrU32; UINT32 tmpU32; if (md->curlen >= sizeof(md->buf)) { return -1; } /* increase the length of the message */ md->length += md->curlen * 8; /* append the '1' bit */ md->buf[md->curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros then compress. Then we can fall back to padding zeros and length encoding like normal. */ if (md->curlen > 56) { while (md->curlen < 64) { md->buf[md->curlen++] = (unsigned char)0; } /* pScratchMem = At least 288 bytes of memory */ sha256_compress((void *)priv, md, md->buf, pScratchMem); md->curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->curlen < 56) { md->buf[md->curlen++] = (unsigned char)0; } /* store length */ ptrU32 = (UINT32 *)&md->length; for (i = 0; i < 2; i++) { tmpU32 = *ptrU32++; WPA_PUT_BE32(md->buf + 60 - 4 * i, tmpU32); } /* pScratchMem = At least 288 bytes of memory */ sha256_compress((void *)priv, md, md->buf, pScratchMem); ptrU32 = md->state; /* copy output */ for (i = 8; i > 0; i--) { tmpU32 = *ptrU32++; WPA_PUT_BE32(out, tmpU32); out += sizeof(UINT32); } return 0; }
static u8 * attr_add_be32(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr, u32 val) { if (pos == NULL || end - pos < 12) return NULL; WPA_PUT_BE32(pos, attr); pos += 4; WPA_PUT_BE32(pos, 4); pos += 4; WPA_PUT_BE32(pos, val); pos += 4; return pos; }
static u8 * attr_add_str(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr, const char *str) { size_t len = os_strlen(str); if (pos == NULL || end - pos < 8 + len) return NULL; WPA_PUT_BE32(pos, attr); pos += 4; WPA_PUT_BE32(pos, len); pos += 4; os_memcpy(pos, str, len); pos += len; return pos; }
int radius_msg_add_wfa(struct radius_msg *msg, u8 subtype, const u8 *data, size_t len) { struct radius_attr_hdr *attr; u8 *buf, *pos; size_t alen; alen = 4 + 2 + len; buf = os_malloc(alen); if (buf == NULL) return 0; pos = buf; WPA_PUT_BE32(pos, RADIUS_VENDOR_ID_WFA); pos += 4; *pos++ = subtype; *pos++ = 2 + len; os_memcpy(pos, data, len); attr = radius_msg_add_attr(msg, RADIUS_ATTR_VENDOR_SPECIFIC, buf, alen); os_free(buf); if (attr == NULL) return 0; return 1; }
static u8 * eap_vendor_test_buildReq(struct eap_sm *sm, void *priv, int id, size_t *reqDataLen) { struct eap_vendor_test_data *data = priv; struct eap_hdr *req; u8 *pos; *reqDataLen = sizeof(*req) + 8 + 1; req = VM_MALLOC(*reqDataLen); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-VENDOR-TEST: Failed to allocate " "memory for request"); return NULL; } req->code = EAP_CODE_REQUEST; req->identifier = id; req->length = htons(*reqDataLen); pos = (u8 *) (req + 1); *pos++ = EAP_TYPE_EXPANDED; WPA_PUT_BE24(pos, EAP_VENDOR_ID); pos += 3; WPA_PUT_BE32(pos, EAP_VENDOR_TYPE); pos += 4; *pos = data->state == INIT ? 1 : 3; return (u8 *) req; }
static void ctrl_get_bss_counter(struct wlantest *wt, int sock, u8 *cmd, size_t clen) { u8 *addr; size_t addr_len; struct wlantest_bss *bss; u32 counter; u8 buf[4 + 12], *end, *pos; bss = ctrl_get_bss(wt, sock, cmd, clen); if (bss == NULL) return; addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_COUNTER, &addr_len); if (addr == NULL || addr_len != 4) { ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD); return; } counter = WPA_GET_BE32(addr); if (counter >= NUM_WLANTEST_BSS_COUNTER) { ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD); return; } pos = buf; end = buf + sizeof(buf); WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS); pos += 4; pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER, bss->counters[counter]); ctrl_send(wt, sock, buf, pos - buf); }
/** * eap_msg_alloc - Allocate a buffer for an EAP message * @vendor: Vendor-Id (0 = IETF) * @type: EAP type * @len: Buffer for returning message length * @payload_len: Payload length in bytes (data after Type) * @code: Message Code (EAP_CODE_*) * @identifier: Identifier * @payload: Pointer to payload pointer that will be set to point to the * beginning of the payload or %NULL if payload pointer is not needed * Returns: Pointer to the allocated message buffer or %NULL on error * * This function can be used to allocate a buffer for an EAP message and fill * in the EAP header. This function is automatically using expanded EAP header * if the selected Vendor-Id is not IETF. In other words, most EAP methods do * not need to separately select which header type to use when using this * function to allocate the message buffers. */ struct eap_hdr * eap_msg_alloc(int vendor, EapType type, size_t *len, size_t payload_len, u8 code, u8 identifier, u8 **payload) { struct eap_hdr *hdr; u8 *pos; *len = sizeof(struct eap_hdr) + (vendor == EAP_VENDOR_IETF ? 1 : 8) + payload_len; hdr = malloc(*len); if (hdr) { hdr->code = code; hdr->identifier = identifier; hdr->length = host_to_be16(*len); pos = (u8 *) (hdr + 1); if (vendor == EAP_VENDOR_IETF) { *pos++ = type; } else { *pos++ = EAP_TYPE_EXPANDED; WPA_PUT_BE24(pos, vendor); pos += 3; WPA_PUT_BE32(pos, type); pos += 4; } if (payload) *payload = pos; } return hdr; }
static void ctrl_send_simple(struct wlantest *wt, int sock, enum wlantest_ctrl_cmd cmd) { u8 buf[4]; WPA_PUT_BE32(buf, cmd); ctrl_send(wt, sock, buf, sizeof(buf)); }
/** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (32 bytes) @return CRYPT_OK if successful */ static int SHA256_Final(unsigned char *out, struct sha256_state *md) { int i; if(md->curlen >= sizeof(md->buf)) return -1; /* increase the length of the message */ md->length += md->curlen * 8; /* append the '1' bit */ md->buf[md->curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if(md->curlen > 56) { while(md->curlen < 64) { md->buf[md->curlen++] = (unsigned char)0; } sha256_compress(md, md->buf); md->curlen = 0; } /* pad upto 56 bytes of zeroes */ while(md->curlen < 56) { md->buf[md->curlen++] = (unsigned char)0; } /* store length */ WPA_PUT_BE64(md->buf + 56, md->length); sha256_compress(md, md->buf); /* copy output */ for(i = 0; i < 8; i++) WPA_PUT_BE32(out + (4 * i), md->state[i]); return 0; }
static void inc32(u8 *block) { u32 val; val = WPA_GET_BE32(block + AES_BLOCK_SIZE - 4); val++; WPA_PUT_BE32(block + AES_BLOCK_SIZE - 4, val); }
static int cmd_simple(int s, enum wlantest_ctrl_cmd cmd) { u8 buf[4]; int res; WPA_PUT_BE32(buf, cmd); res = cmd_send_and_recv(s, buf, sizeof(buf), buf, sizeof(buf)); return res < 0 ? -1 : 0; }
void ikev2_update_hdr(struct wpabuf *msg) { struct ikev2_hdr *hdr; /* Update lenth field in HDR */ hdr = wpabuf_mhead(msg); WPA_PUT_BE32(hdr->length, wpabuf_len(msg)); }
int eap_fast_save_pac_bin(struct eap_sm *sm, struct eap_fast_pac *pac_root, const char *pac_file) { size_t len, count = 0; struct eap_fast_pac *pac; u8 *buf, *pos; len = 6; pac = pac_root; while (pac) { if (pac->pac_opaque_len > 65535 || pac->pac_info_len > 65535) return -1; len += 2 + EAP_FAST_PAC_KEY_LEN + 2 + pac->pac_opaque_len + 2 + pac->pac_info_len; pac = pac->next; } buf = os_malloc(len); if (buf == NULL) return -1; pos = buf; WPA_PUT_BE32(pos, EAP_FAST_PAC_BINARY_MAGIC); pos += 4; WPA_PUT_BE16(pos, EAP_FAST_PAC_BINARY_FORMAT_VERSION); pos += 2; pac = pac_root; while (pac) { WPA_PUT_BE16(pos, pac->pac_type); pos += 2; os_memcpy(pos, pac->pac_key, EAP_FAST_PAC_KEY_LEN); pos += EAP_FAST_PAC_KEY_LEN; WPA_PUT_BE16(pos, pac->pac_opaque_len); pos += 2; os_memcpy(pos, pac->pac_opaque, pac->pac_opaque_len); pos += pac->pac_opaque_len; WPA_PUT_BE16(pos, pac->pac_info_len); pos += 2; os_memcpy(pos, pac->pac_info, pac->pac_info_len); pos += pac->pac_info_len; pac = pac->next; count++; } if (eap_fast_write_pac(sm, pac_file, (char *) buf, len)) { os_free(buf); return -1; } wpa_printf(MSG_DEBUG, "EAP-FAST: Wrote %lu PAC entries into '%s' " "(bin)", (unsigned long) count, pac_file); return 0; }
static int cmd_get_sta_counter(int s, int argc, char *argv[]) { u8 resp[WLANTEST_CTRL_MAX_RESP_LEN]; u8 buf[100], *end, *pos; int rlen, i; size_t len; if (argc != 3) { printf("get_sta_counter needs at three arguments: " "counter name, BSSID, and STA address\n"); return -1; } pos = buf; end = buf + sizeof(buf); WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_STA_COUNTER); pos += 4; for (i = 0; sta_counters[i].name; i++) { if (os_strcasecmp(sta_counters[i].name, argv[0]) == 0) break; } if (sta_counters[i].name == NULL) { printf("Unknown STA counter '%s'\n", argv[0]); printf("Counters:"); for (i = 0; sta_counters[i].name; i++) printf(" %s", sta_counters[i].name); printf("\n"); return -1; } pos = attr_add_be32(pos, end, WLANTEST_ATTR_STA_COUNTER, sta_counters[i].num); pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN); if (hwaddr_aton(argv[1], pos) < 0) { printf("Invalid BSSID '%s'\n", argv[1]); return -1; } pos += ETH_ALEN; pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN); if (hwaddr_aton(argv[2], pos) < 0) { printf("Invalid STA address '%s'\n", argv[2]); return -1; } pos += ETH_ALEN; rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp)); if (rlen < 0) return -1; pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len); if (pos == NULL || len != 4) return -1; printf("%u\n", WPA_GET_BE32(pos)); return 0; }
/* Convert from data->tlvs to contiguous buffer of TLVs */ int wps_write_wps_data(struct wps_data * data, u8 **buf, size_t *length) { Boolean err = 0; u8 index; u8 *tmp; struct wps_tlv *tlv; if (!buf | !length) return -1; *buf = 0; *length = 0; if (!data) return -1; for (index = 0; index < data->count && !err; index++) { tlv = data->tlvs[index]; *buf = (u8 *)os_realloc(*buf, *length + 4 + tlv->length); if (!*buf) { err = -1; break; } tmp = *buf + *length; *length += 4 + tlv->length; WPA_PUT_BE16(tmp, tlv->type); WPA_PUT_BE16(tmp+2, tlv->length); switch(tlv->value_type) { case WPS_VALTYPE_BOOL: *(tmp+4) = (u8)tlv->value.bool_; break; case WPS_VALTYPE_U8: *(tmp+4) = tlv->value.u8_; break; case WPS_VALTYPE_U16: WPA_PUT_BE16(tmp+4, tlv->value.u16_); break; case WPS_VALTYPE_U32: WPA_PUT_BE32(tmp+4, tlv->value.u32_); break; case WPS_VALTYPE_PTR: os_memcpy(tmp+4, tlv->value.ptr_, tlv->length); break; default: err = -1; break; } } if (err) { os_free(*buf); *buf = 0; *length = 0; } return err; }
static int cmd_info_bss(int s, int argc, char *argv[]) { u8 resp[WLANTEST_CTRL_MAX_RESP_LEN]; u8 buf[100], *end, *pos; int rlen, i; size_t len; char info[100]; if (argc != 2) { printf("bss_info needs at two arguments: " "field name and BSSID\n"); return -1; } pos = buf; end = buf + sizeof(buf); WPA_PUT_BE32(pos, WLANTEST_CTRL_INFO_BSS); pos += 4; for (i = 0; bss_infos[i].name; i++) { if (os_strcasecmp(bss_infos[i].name, argv[0]) == 0) break; } if (bss_infos[i].name == NULL) { printf("Unknown BSS info '%s'\n", argv[0]); printf("Info fields:"); for (i = 0; bss_infos[i].name; i++) printf(" %s", bss_infos[i].name); printf("\n"); return -1; } pos = attr_add_be32(pos, end, WLANTEST_ATTR_BSS_INFO, bss_infos[i].num); pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN); if (hwaddr_aton(argv[1], pos) < 0) { printf("Invalid BSSID '%s'\n", argv[1]); return -1; } pos += ETH_ALEN; rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp)); if (rlen < 0) return -1; pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_INFO, &len); if (pos == NULL) return -1; if (len >= sizeof(info)) len = sizeof(info) - 1; os_memcpy(info, pos, len); info[len] = '\0'; printf("%s\n", info); return 0; }
static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type, int peap_version, u8 id, int ret, u8 **out_data, size_t *out_len) { size_t len; u8 *pos, *flags; int more_fragments, length_included; wpa_printf(MSG_DEBUG, "SSL: %lu bytes left to be sent out (of total " "%lu bytes)", (unsigned long) data->tls_out_len - data->tls_out_pos, (unsigned long) data->tls_out_len); len = data->tls_out_len - data->tls_out_pos; if (len > data->tls_out_limit) { more_fragments = 1; len = data->tls_out_limit; wpa_printf(MSG_DEBUG, "SSL: sending %lu bytes, more fragments " "will follow", (unsigned long) len); } else more_fragments = 0; length_included = data->tls_out_pos == 0 && (data->tls_out_len > data->tls_out_limit || data->include_tls_length); *out_data = (u8 *) eap_msg_alloc(EAP_VENDOR_IETF, eap_type, out_len, 1 + length_included * 4 + len, EAP_CODE_RESPONSE, id, &pos); if (*out_data == NULL) return -1; flags = pos++; *flags = peap_version; if (more_fragments) *flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS; if (length_included) { *flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED; WPA_PUT_BE32(pos, data->tls_out_len); pos += 4; } os_memcpy(pos, &data->tls_out[data->tls_out_pos], len); data->tls_out_pos += len; if (!more_fragments) { data->tls_out_len = 0; data->tls_out_pos = 0; os_free(data->tls_out); data->tls_out = NULL; } return ret; }
static int eap_gpsk_derive_mid_helper(u32 csuite_specifier, u8 *kdf_out, size_t kdf_out_len, const u8 *psk, const u8 *seed, size_t seed_len, u8 method_type) { u8 *pos, *data; size_t data_len; int (*gkdf)(const u8 *_psk, const u8 *_data, size_t _data_len, u8 *buf, size_t len); gkdf = NULL; switch (csuite_specifier) { case EAP_GPSK_CIPHER_AES: gkdf = eap_gpsk_gkdf_cmac; break; #ifdef EAP_GPSK_SHA256 case EAP_GPSK_CIPHER_SHA256: gkdf = eap_gpsk_gkdf_sha256; break; #endif /* EAP_GPSK_SHA256 */ default: wpa_printf(MSG_DEBUG, "EAP-GPSK: Unknown cipher %d used in " "Session-Id derivation", csuite_specifier); return -1; } #define SID_LABEL "Method ID" /* "Method ID" || EAP_Method_Type || CSuite_Sel || inputString */ data_len = strlen(SID_LABEL) + 1 + 6 + seed_len; data = os_malloc(data_len); if (data == NULL) return -1; pos = data; os_memcpy(pos, SID_LABEL, strlen(SID_LABEL)); pos += strlen(SID_LABEL); #undef SID_LABEL os_memcpy(pos, &method_type, 1); pos += 1; WPA_PUT_BE32(pos, EAP_GPSK_VENDOR_IETF); /* CSuite/Vendor = IETF */ pos += 4; WPA_PUT_BE16(pos, csuite_specifier); /* CSuite/Specifier */ pos += 2; os_memcpy(pos, seed, seed_len); /* inputString */ wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Data to Method ID derivation", data, data_len); if (gkdf(psk, data, data_len, kdf_out, kdf_out_len) < 0) { os_free(data); return -1; } os_free(data); wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Method ID", kdf_out, kdf_out_len); return 0; }
static void ctrl_info_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen) { u8 *addr; size_t addr_len; struct wlantest_bss *bss; struct wlantest_sta *sta; enum wlantest_sta_info info; u8 buf[4 + 108], *end, *pos; char resp[100]; bss = ctrl_get_bss(wt, sock, cmd, clen); sta = ctrl_get_sta(wt, sock, cmd, clen, bss); if (sta == NULL) return; addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_INFO, &addr_len); if (addr == NULL || addr_len != 4) { ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD); return; } info = WPA_GET_BE32(addr); resp[0] = '\0'; switch (info) { case WLANTEST_STA_INFO_PROTO: info_print_proto(resp, sizeof(resp), sta->proto); break; case WLANTEST_STA_INFO_PAIRWISE: info_print_cipher(resp, sizeof(resp), sta->pairwise_cipher); break; case WLANTEST_STA_INFO_KEY_MGMT: info_print_key_mgmt(resp, sizeof(resp), sta->key_mgmt); break; case WLANTEST_STA_INFO_RSN_CAPAB: info_print_rsn_capab(resp, sizeof(resp), sta->rsn_capab); break; case WLANTEST_STA_INFO_STATE: info_print_state(resp, sizeof(resp), sta->state); break; case WLANTEST_STA_INFO_GTK: info_print_gtk(resp, sizeof(resp), sta); break; default: ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD); return; } pos = buf; end = buf + sizeof(buf); WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS); pos += 4; pos = attr_add_str(pos, end, WLANTEST_ATTR_INFO, resp); ctrl_send(wt, sock, buf, pos - buf); }
static void ctrl_version(struct wlantest *wt, int sock) { u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos; pos = buf; WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS); pos += 4; pos = attr_add_str(pos, buf + sizeof(buf), WLANTEST_ATTR_VERSION, VERSION_STR); ctrl_send(wt, sock, buf, pos - buf); }
int wps_build_primary_dev_type(struct wps_device_data *dev, struct wpabuf *msg) { struct wps_dev_type *d; wpa_printf(MSG_DEBUG, "WPS: * Primary Device Type"); wpabuf_put_be16(msg, ATTR_PRIMARY_DEV_TYPE); wpabuf_put_be16(msg, sizeof(*d)); d = wpabuf_put(msg, sizeof(*d)); WPA_PUT_BE16(d->categ_id, dev->categ); WPA_PUT_BE32(d->oui, dev->oui); WPA_PUT_BE16(d->sub_categ_id, dev->sub_categ); return 0; }