Esempio n. 1
0
static int eap_tlv_validate_cryptobinding(struct eap_sm *sm,
					  struct eap_peap_data *data,
					  const u8 *crypto_tlv,
					  size_t crypto_tlv_len)
{
	u8 buf[61], mac[SHA1_MAC_LEN];
	const u8 *pos;

	if (eap_peap_derive_cmk(sm, data) < 0) {
		wpa_printf(MSG_DEBUG, "EAP-PEAP: Could not derive CMK");
		return -1;
	}

	if (crypto_tlv_len != 4 + 56) {
		wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid cryptobinding TLV "
			   "length %d", (int) crypto_tlv_len);
		return -1;
	}

	pos = crypto_tlv;
	pos += 4; /* TLV header */
	if (pos[1] != data->peap_version) {
		wpa_printf(MSG_DEBUG, "EAP-PEAP: Cryptobinding TLV Version "
			   "mismatch (was %d; expected %d)",
			   pos[1], data->peap_version);
		return -1;
	}

	if (pos[3] != 0) {
		wpa_printf(MSG_DEBUG, "EAP-PEAP: Unexpected Cryptobinding TLV "
			   "SubType %d", pos[3]);
		return -1;
	}
	pos += 4;
	os_memcpy(data->binding_nonce, pos, 32);
	pos += 32; /* Nonce */

	/* Compound_MAC: HMAC-SHA1-160(cryptobinding TLV | EAP type) */
	os_memcpy(buf, crypto_tlv, 60);
	os_memset(buf + 4 + 4 + 32, 0, 20); /* Compound_MAC */
	buf[60] = EAP_TYPE_PEAP;
	wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Compound_MAC data",
		    buf, sizeof(buf));
	hmac_sha1(data->cmk, 20, buf, sizeof(buf), mac);

	if (os_memcmp(mac, pos, SHA1_MAC_LEN) != 0) {
		wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid Compound_MAC in "
			   "cryptobinding TLV");
		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Received MAC",
			    pos, SHA1_MAC_LEN);
		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Expected MAC",
			    mac, SHA1_MAC_LEN);
		return -1;
	}

	wpa_printf(MSG_DEBUG, "EAP-PEAP: Valid cryptobinding TLV received");

	return 0;
}
Esempio n. 2
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;
}