예제 #1
0
/**
 * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5A.3)
 * @key: Key for PRF
 * @key_len: Length of the key in bytes
 * @label: A unique label for each purpose of the PRF
 * @data: Extra data to bind into the key
 * @data_len: Length of the data
 * @buf: Buffer for the generated pseudo-random key
 * @buf_len: Number of bytes of key to generate
 *
 * This function is used to derive new, cryptographically separate keys from a
 * given key.
 */
void sha256_prf(const u8 *key, size_t key_len, const char *label,
		const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
{
	u16 counter = 0;
	size_t pos, plen;
	u8 hash[SHA256_MAC_LEN];
	const u8 *addr[3];
	size_t len[3];
	u8 counter_le[2];

	addr[0] = counter_le;
	len[0] = 2;
	addr[1] = (u8 *) label;
	len[1] = strlen(label) + 1;
	addr[2] = data;
	len[2] = data_len;

	pos = 0;
	while (pos < buf_len) {
		plen = buf_len - pos;
		WPA_PUT_LE16(counter_le, counter);
		if (plen >= SHA256_MAC_LEN) {
			hmac_sha256_vector(key, key_len, 3, addr, len,
					   &buf[pos]);
			pos += SHA256_MAC_LEN;
		} else {
			hmac_sha256_vector(key, key_len, 3, addr, len, hash);
			memcpy(&buf[pos], hash, plen);
			break;
		}
		counter++;
	}
}
int wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg)
{
	u8 hash[SHA256_MAC_LEN];
	const u8 *addr[2];
	size_t len[2];

	if (wps->last_msg == NULL) {
		wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
			   "building authenticator");
		return -1;
	}

	/* Authenticator = HMAC-SHA256_AuthKey(M_prev || M_curr*)
	 * (M_curr* is M_curr without the Authenticator attribute)
	 */
	addr[0] = wpabuf_head(wps->last_msg);
	len[0] = wpabuf_len(wps->last_msg);
	addr[1] = wpabuf_head(msg);
	len[1] = wpabuf_len(msg);
	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);

	wpa_printf(MSG_DEBUG, "WPS:  * Authenticator");
	wpabuf_put_be16(msg, ATTR_AUTHENTICATOR);
	wpabuf_put_be16(msg, WPS_AUTHENTICATOR_LEN);
	wpabuf_put_data(msg, hash, WPS_AUTHENTICATOR_LEN);

	return 0;
}
int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
			      const struct wpabuf *msg)
{
	u8 hash[SHA256_MAC_LEN];
	const u8 *addr[2];
	size_t len[2];

	if (authenticator == NULL) {
		wpa_printf(MSG_DEBUG, "WPS: No Authenticator attribute "
			   "included");
		return -1;
	}

	if (wps->last_msg == NULL) {
		wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
			   "validating authenticator");
		return -1;
	}

	/* Authenticator = HMAC-SHA256_AuthKey(M_prev || M_curr*)
	 * (M_curr* is M_curr without the Authenticator attribute)
	 */
	addr[0] = wpabuf_head(wps->last_msg);
	len[0] = wpabuf_len(wps->last_msg);
	addr[1] = wpabuf_head(msg);
	len[1] = wpabuf_len(msg) - 4 - WPS_AUTHENTICATOR_LEN;
	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);

	if (os_memcmp(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
		wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator");
		return -1;
	}

	return 0;
}
예제 #4
0
static int eap_gpsk_gkdf_sha256(const u8 *psk /* Y */,
				const u8 *data /* Z */, size_t data_len,
				u8 *buf, size_t len /* X */)
{
	u8 *opos;
	size_t i, n, hashlen, left, clen;
	u8 ibuf[2], hash[SHA256_MAC_LEN];
	const u8 *addr[2];
	size_t vlen[2];

	hashlen = SHA256_MAC_LEN;
	/* M_i = MAC_Y (i || Z); (MAC = HMAC-SHA256) */
	addr[0] = ibuf;
	vlen[0] = sizeof(ibuf);
	addr[1] = data;
	vlen[1] = data_len;

	opos = buf;
	left = len;
	n = (len + hashlen - 1) / hashlen;
	for (i = 1; i <= n; i++) {
		WPA_PUT_BE16(ibuf, i);
		hmac_sha256_vector(psk, 32, 2, addr, vlen, hash);
		clen = left > hashlen ? hashlen : left;
		os_memcpy(opos, hash, clen);
		opos += clen;
		left -= clen;
	}

	return 0;
}
예제 #5
0
static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg)
{
	u8 *hash;
	const u8 *addr[4];
	size_t len[4];

	if (random_get_bytes(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
		return -1;
	wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
	wpa_hexdump(MSG_DEBUG, "WPS: E-S2",
		    wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);

	if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
		wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
			   "E-Hash derivation");
		return -1;
	}

	wpa_printf(MSG_DEBUG, "WPS:  * E-Hash1");
	wpabuf_put_be16(msg, ATTR_E_HASH1);
	wpabuf_put_be16(msg, SHA256_MAC_LEN);
	hash = wpabuf_put(msg, SHA256_MAC_LEN);
	/* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
	addr[0] = wps->snonce;
	len[0] = WPS_SECRET_NONCE_LEN;
	addr[1] = wps->psk1;
	len[1] = WPS_PSK_LEN;
	addr[2] = wpabuf_head(wps->dh_pubkey_e);
	len[2] = wpabuf_len(wps->dh_pubkey_e);
	addr[3] = wpabuf_head(wps->dh_pubkey_r);
	len[3] = wpabuf_len(wps->dh_pubkey_r);
	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
	wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);

	wpa_printf(MSG_DEBUG, "WPS:  * E-Hash2");
	wpabuf_put_be16(msg, ATTR_E_HASH2);
	wpabuf_put_be16(msg, SHA256_MAC_LEN);
	hash = wpabuf_put(msg, SHA256_MAC_LEN);
	/* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
	addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
	addr[1] = wps->psk2;
	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
	wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);

	return 0;
}
예제 #6
0
/** 
 *  @brief  Wrapper function for HMAC-SHA256 (RFC 2104)
 *
 *  @param Key          Key for HMAC operations
 *  @param Key_size     Length of the key in bytes
 *  @param Message      Pointers to the data areas
 *  @param Message_len  Lengths of the data blocks
 *  @param Mac          Buffer for the hash (32 bytes)
 *  @param MacSize      Length of hash buffer
 *  @return             0 on success, -1 on failure
 */
int
MrvHMAC_SHA256(const u8 * Key, u32 Key_size, u8 * Message, u32 Message_len, u8 * Mac,
               u32 MacSize)
{
    const u8 *addr[2];
    size_t len[2];

    addr[0] = Message;
    len[0] = (size_t) Message_len;
    hmac_sha256_vector(Key, Key_size, 1, addr, len, Mac);

    return 0;
}
예제 #7
0
static int eap_eke_prf_hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
				   size_t data_len, u8 *res, size_t len)
{
	u8 hash[SHA256_MAC_LEN];
	u8 idx;
	const u8 *addr[3];
	size_t vlen[3];
	int ret;

	idx = 0;
	addr[0] = hash;
	vlen[0] = SHA256_MAC_LEN;
	addr[1] = data;
	vlen[1] = data_len;
	addr[2] = &idx;
	vlen[2] = 1;

	while (len > 0) {
		idx++;
		if (idx == 1)
			ret = hmac_sha256_vector(key, key_len, 2, &addr[1],
						 &vlen[1], hash);
		else
			ret = hmac_sha256_vector(key, key_len, 3, addr, vlen,
						 hash);
		if (ret < 0)
			return -1;
		if (len > SHA256_MAC_LEN) {
			os_memcpy(res, hash, SHA256_MAC_LEN);
			res += SHA256_MAC_LEN;
			len -= SHA256_MAC_LEN;
		} else {
			os_memcpy(res, hash, len);
			len = 0;
		}
	}

	return 0;
}
예제 #8
0
/**
 * rsn_pmkid_suite_b - Calculate PMK identifier for Suite B AKM
 * @kck: Key confirmation key
 * @kck_len: Length of kck in bytes
 * @aa: Authenticator address
 * @spa: Supplicant address
 * @pmkid: Buffer for PMKID
 * Returns: 0 on success, -1 on failure
 *
 * IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
 * PMKID = Truncate(HMAC-SHA-256(KCK, "PMK Name" || AA || SPA))
 */
int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
		      const u8 *spa, u8 *pmkid)
{
	char *title = "PMK Name";
	const u8 *addr[3];
	const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
	unsigned char hash[SHA256_MAC_LEN];

	addr[0] = (u8 *) title;
	addr[1] = aa;
	addr[2] = spa;

	if (hmac_sha256_vector(kck, kck_len, 3, addr, len, hash) < 0)
		return -1;
	os_memcpy(pmkid, hash, PMKID_LEN);
	return 0;
}
예제 #9
0
static void prf_prime(const u8 *k, const char *seed1,
		      const u8 *seed2, size_t seed2_len,
		      const u8 *seed3, size_t seed3_len,
		      u8 *res, size_t res_len)
{
	const u8 *addr[5];
	size_t len[5];
	u8 hash[SHA256_MAC_LEN];
	u8 iter;

	/*
	 * PRF'(K,S) = T1 | T2 | T3 | T4 | ...
	 * T1 = HMAC-SHA-256 (K, S | 0x01)
	 * T2 = HMAC-SHA-256 (K, T1 | S | 0x02)
	 * T3 = HMAC-SHA-256 (K, T2 | S | 0x03)
	 * T4 = HMAC-SHA-256 (K, T3 | S | 0x04)
	 * ...
	 */

	addr[0] = hash;
	len[0] = 0;
	addr[1] = (const u8 *) seed1;
	len[1] = os_strlen(seed1);
	addr[2] = seed2;
	len[2] = seed2_len;
	addr[3] = seed3;
	len[3] = seed3_len;
	addr[4] = &iter;
	len[4] = 1;

	iter = 0;
	while (res_len) {
		size_t hlen;
		iter++;
		hmac_sha256_vector(k, 32, 5, addr, len, hash);
		len[0] = SHA256_MAC_LEN;
		hlen = res_len > SHA256_MAC_LEN ? SHA256_MAC_LEN : res_len;
		os_memcpy(res, hash, hlen);
		res += hlen;
		res_len -= hlen;
	}
}
예제 #10
0
/**
 * rsn_pmkid - Calculate PMK identifier
 * @pmk: Pairwise master key
 * @pmk_len: Length of pmk in bytes
 * @aa: Authenticator address
 * @spa: Supplicant address
 * @pmkid: Buffer for PMKID
 * @use_sha256: Whether to use SHA256-based KDF
 *
 * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
 * PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AA || SPA)
 */
void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
	       u8 *pmkid, int use_sha256)
{
	char *title = "PMK Name";
	const u8 *addr[3];
	const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
	unsigned char hash[SHA256_MAC_LEN];

	addr[0] = (u8 *) title;
	addr[1] = aa;
	addr[2] = spa;

#ifdef CONFIG_IEEE80211W
	if (use_sha256)
		hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
	else
#endif /* CONFIG_IEEE80211W */
		hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
	os_memcpy(pmkid, hash, PMKID_LEN);
}
예제 #11
0
int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req,
			      const u8 *mac, const u8 *extra, size_t extra_len)
{
	unsigned char hmac[SHA256_MAC_LEN];
	const u8 *addr[2];
	size_t len[2];
	u8 *tmp;

	if (mac == NULL || wpabuf_len(req) < EAP_SIM_MAC_LEN ||
	    mac < wpabuf_head_u8(req) ||
	    mac > wpabuf_head_u8(req) + wpabuf_len(req) - EAP_SIM_MAC_LEN)
		return -1;

	tmp = os_malloc(wpabuf_len(req));
	if (tmp == NULL)
		return -1;

	addr[0] = tmp;
	len[0] = wpabuf_len(req);
	addr[1] = extra;
	len[1] = extra_len;

	/* HMAC-SHA-256-128 */
	os_memcpy(tmp, wpabuf_head(req), wpabuf_len(req));
	os_memset(tmp + (mac - wpabuf_head_u8(req)), 0, EAP_SIM_MAC_LEN);
	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Verify MAC - msg",
		    tmp, wpabuf_len(req));
	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Verify MAC - extra data",
		    extra, extra_len);
	wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA': Verify MAC - K_aut",
			k_aut, EAP_AKA_PRIME_K_AUT_LEN);
	hmac_sha256_vector(k_aut, EAP_AKA_PRIME_K_AUT_LEN, 2, addr, len, hmac);
	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Verify MAC: MAC",
		    hmac, EAP_SIM_MAC_LEN);
	os_free(tmp);

	return (os_memcmp(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1;
}
예제 #12
0
static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
{
	u8 hash[SHA256_MAC_LEN];
	const u8 *addr[4];
	size_t len[4];

	if (r_snonce2 == NULL) {
		wpa_printf(MSG_DEBUG, "WPS: No R-SNonce2 received");
		return -1;
	}

	wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce2", r_snonce2,
			WPS_SECRET_NONCE_LEN);

	/* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
	addr[0] = r_snonce2;
	len[0] = WPS_SECRET_NONCE_LEN;
	addr[1] = wps->psk2;
	len[1] = WPS_PSK_LEN;
	addr[2] = wpabuf_head(wps->dh_pubkey_e);
	len[2] = wpabuf_len(wps->dh_pubkey_e);
	addr[3] = wpabuf_head(wps->dh_pubkey_r);
	len[3] = wpabuf_len(wps->dh_pubkey_r);
	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);

	if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
		wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
			   "not match with the pre-committed value");
		wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
		wps_pwd_auth_fail_event(wps->wps, 1, 2);
		return -1;
	}

	wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the second "
		   "half of the device password");

	return 0;
}
예제 #13
0
static int eap_eke_prf(u8 prf, const u8 *key, size_t key_len, const u8 *data,
		       size_t data_len, const u8 *data2, size_t data2_len,
		       u8 *res)
{
	const u8 *addr[2];
	size_t len[2];
	size_t num_elem = 1;

	addr[0] = data;
	len[0] = data_len;
	if (data2) {
		num_elem++;
		addr[1] = data2;
		len[1] = data2_len;
	}

	if (prf == EAP_EKE_PRF_HMAC_SHA1)
		return hmac_sha1_vector(key, key_len, num_elem, addr, len, res);
	if (prf == EAP_EKE_PRF_HMAC_SHA2_256)
		return hmac_sha256_vector(key, key_len, num_elem, addr, len,
					  res);
	return -1;
}
예제 #14
0
void eap_sim_add_mac_sha256(const u8 *k_aut, const u8 *msg, size_t msg_len,
			    u8 *mac, const u8 *extra, size_t extra_len)
{
	unsigned char hmac[SHA256_MAC_LEN];
	const u8 *addr[2];
	size_t len[2];

	addr[0] = msg;
	len[0] = msg_len;
	addr[1] = extra;
	len[1] = extra_len;

	/* HMAC-SHA-256-128 */
	os_memset(mac, 0, EAP_SIM_MAC_LEN);
	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Add MAC - msg", msg, msg_len);
	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Add MAC - extra data",
		    extra, extra_len);
	wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA': Add MAC - K_aut",
			k_aut, EAP_AKA_PRIME_K_AUT_LEN);
	hmac_sha256_vector(k_aut, EAP_AKA_PRIME_K_AUT_LEN, 2, addr, len, hmac);
	os_memcpy(mac, hmac, EAP_SIM_MAC_LEN);
	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Add MAC: MAC",
		    mac, EAP_SIM_MAC_LEN);
}
예제 #15
0
파일: peerkey.c 프로젝트: 09sea98/rtl8188eu
/**
 * rsn_smkid - Derive SMK identifier
 * @smk: Station master key (32 bytes)
 * @pnonce: Peer Nonce
 * @mac_p: Peer MAC address
 * @inonce: Initiator Nonce
 * @mac_i: Initiator MAC address
 * @use_sha256: Whether to use SHA256-based KDF
 *
 * 8.5.1.4 Station to station (STK) key hierarchy
 * SMKID = HMAC-SHA1-128(SMK, "SMK Name" || PNonce || MAC_P || INonce || MAC_I)
 */
static void rsn_smkid(const u8 *smk, const u8 *pnonce, const u8 *mac_p,
		      const u8 *inonce, const u8 *mac_i, u8 *smkid,
		      int use_sha256)
{
	char *title = "SMK Name";
	const u8 *addr[5];
	const size_t len[5] = { 8, WPA_NONCE_LEN, ETH_ALEN, WPA_NONCE_LEN,
				ETH_ALEN };
	unsigned char hash[SHA256_MAC_LEN];

	addr[0] = (u8 *) title;
	addr[1] = pnonce;
	addr[2] = mac_p;
	addr[3] = inonce;
	addr[4] = mac_i;

#ifdef CONFIG_IEEE80211W
	if (use_sha256)
		hmac_sha256_vector(smk, PMK_LEN, 5, addr, len, hash);
	else
#endif /* CONFIG_IEEE80211W */
		hmac_sha1_vector(smk, PMK_LEN, 5, addr, len, hash);
	os_memcpy(smkid, hash, PMKID_LEN);
}
예제 #16
0
void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
	     const char *label, u8 *res, size_t res_len)
{
	u8 i_buf[4], key_bits[4];
	const u8 *addr[4];
	size_t len[4];
	int i, iter;
	u8 hash[SHA256_MAC_LEN], *opos;
	size_t left;

	WPA_PUT_BE32(key_bits, res_len * 8);

	addr[0] = i_buf;
	len[0] = sizeof(i_buf);
	addr[1] = label_prefix;
	len[1] = label_prefix_len;
	addr[2] = (const u8 *) label;
	len[2] = os_strlen(label);
	addr[3] = key_bits;
	len[3] = sizeof(key_bits);

	iter = (res_len + SHA256_MAC_LEN - 1) / SHA256_MAC_LEN;
	opos = res;
	left = res_len;

	for (i = 1; i <= iter; i++) {
		WPA_PUT_BE32(i_buf, i);
		hmac_sha256_vector(key, SHA256_MAC_LEN, 4, addr, len, hash);
		if (i < iter) {
			os_memcpy(opos, hash, SHA256_MAC_LEN);
			opos += SHA256_MAC_LEN;
			left -= SHA256_MAC_LEN;
		} else
			os_memcpy(opos, hash, left);
	}
}
예제 #17
0
int wps_derive_keys(struct wps_data *wps)
{
    struct wpabuf *pubkey, *dh_shared;
    u8 dhkey[SHA256_MAC_LEN], kdk[SHA256_MAC_LEN];
    const u8 *addr[3];
    size_t len[3];
    u8 keys[WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN + WPS_EMSK_LEN];

    if (wps->dh_privkey == NULL) {
        wpa_printf(MSG_DEBUG, "WPS: Own DH private key not available");
        return -1;
    }

    pubkey = wps->registrar ? wps->dh_pubkey_e : wps->dh_pubkey_r;
    if (pubkey == NULL) {
        wpa_printf(MSG_DEBUG, "WPS: Peer DH public key not available");
        return -1;
    }

    dh_shared = dh5_derive_shared(wps->dh_ctx, pubkey, wps->dh_privkey);
    dh5_free(wps->dh_ctx);
    wps->dh_ctx = NULL;
    dh_shared = wpabuf_zeropad(dh_shared, 192);
    if (dh_shared == NULL) {
        wpa_printf(MSG_DEBUG, "WPS: Failed to derive DH shared key");
        return -1;
    }

    /* Own DH private key is not needed anymore */
    wpabuf_free(wps->dh_privkey);
    wps->dh_privkey = NULL;

    wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH shared key", dh_shared);

    /* DHKey = SHA-256(g^AB mod p) */
    addr[0] = wpabuf_head(dh_shared);
    len[0] = wpabuf_len(dh_shared);
    sha256_vector(1, addr, len, dhkey);
    wpa_hexdump_key(MSG_DEBUG, "WPS: DHKey", dhkey, sizeof(dhkey));
    wpabuf_free(dh_shared);

    /* KDK = HMAC-SHA-256_DHKey(N1 || EnrolleeMAC || N2) */
    addr[0] = wps->nonce_e;
    len[0] = WPS_NONCE_LEN;
    addr[1] = wps->mac_addr_e;
    len[1] = ETH_ALEN;
    addr[2] = wps->nonce_r;
    len[2] = WPS_NONCE_LEN;
    hmac_sha256_vector(dhkey, sizeof(dhkey), 3, addr, len, kdk);
    wpa_hexdump_key(MSG_DEBUG, "WPS: KDK", kdk, sizeof(kdk));

    wps_kdf(kdk, NULL, 0, "Wi-Fi Easy and Secure Key Derivation",
            keys, sizeof(keys));
    os_memcpy(wps->authkey, keys, WPS_AUTHKEY_LEN);
    os_memcpy(wps->keywrapkey, keys + WPS_AUTHKEY_LEN, WPS_KEYWRAPKEY_LEN);
    os_memcpy(wps->emsk, keys + WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN,
            WPS_EMSK_LEN);

    wpa_hexdump_key(MSG_DEBUG, "WPS: AuthKey",
            wps->authkey, WPS_AUTHKEY_LEN);
    wpa_hexdump_key(MSG_DEBUG, "WPS: KeyWrapKey",
            wps->keywrapkey, WPS_KEYWRAPKEY_LEN);
    wpa_hexdump_key(MSG_DEBUG, "WPS: EMSK", wps->emsk, WPS_EMSK_LEN);

    /****** ADD THIS PART ******/

    memset(pixie_authkey,0,sizeof(pixie_authkey));
    if ( get_debug()==4 )
    { //verbose (-vvv)
        printf("[P] AuthKey: ");
    }
    int pixiecnt = 0;
    for (; pixiecnt < WPS_AUTHKEY_LEN; pixiecnt++) {
        if ( get_debug()==4 )
        { //verbose (-vvv)
            printf("%02x", wps->authkey[pixiecnt]);
        }
        sprintf(cmd_pixie_aux, "%02x",  wps->authkey[pixiecnt]);
        strcat(pixie_authkey, cmd_pixie_aux);
        if (pixiecnt != WPS_AUTHKEY_LEN - 1) {
            if ( get_debug()==4 )
            { //verbose (-vvv)
                printf(":");
            }
            strcat(pixie_authkey,":");
        }
    }
    if ( get_debug()==4 )
    { //verbose (-vvv)
        printf("\n");
    }
    /******/

    return 0;
}
예제 #18
0
int wps_derive_keys(struct wps_data *wps)
{
	struct wpabuf *pubkey, *dh_shared;
	u8 dhkey[SHA256_MAC_LEN], kdk[SHA256_MAC_LEN];
	const u8 *addr[3];
	size_t len[3];
	u8 keys[WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN + WPS_EMSK_LEN];

	if (wps->dh_privkey == NULL) {
		wpa_printf(MSG_DEBUG, "WPS: Own DH private key not available");
		return -1;
	}

	pubkey = wps->registrar ? wps->dh_pubkey_e : wps->dh_pubkey_r;
	if (pubkey == NULL) {
		wpa_printf(MSG_DEBUG, "WPS: Peer DH public key not available");
		return -1;
	}

	wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH Private Key", wps->dh_privkey);
	wpa_hexdump_buf(MSG_DEBUG, "WPS: DH peer Public Key", pubkey);
	dh_shared = dh5_derive_shared(wps->dh_ctx, pubkey, wps->dh_privkey);
	dh5_free(wps->dh_ctx);
	wps->dh_ctx = NULL;
	dh_shared = wpabuf_zeropad(dh_shared, 192);
	if (dh_shared == NULL) {
		wpa_printf(MSG_DEBUG, "WPS: Failed to derive DH shared key");
		return -1;
	}

	/* Own DH private key is not needed anymore */
	wpabuf_free(wps->dh_privkey);
	wps->dh_privkey = NULL;

	wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH shared key", dh_shared);

	/* DHKey = SHA-256(g^AB mod p) */
	addr[0] = wpabuf_head(dh_shared);
	len[0] = wpabuf_len(dh_shared);
	sha256_vector(1, addr, len, dhkey);
	wpa_hexdump_key(MSG_DEBUG, "WPS: DHKey", dhkey, sizeof(dhkey));
	wpabuf_free(dh_shared);

	/* KDK = HMAC-SHA-256_DHKey(N1 || EnrolleeMAC || N2) */
	addr[0] = wps->nonce_e;
	len[0] = WPS_NONCE_LEN;
	addr[1] = wps->mac_addr_e;
	len[1] = ETH_ALEN;
	addr[2] = wps->nonce_r;
	len[2] = WPS_NONCE_LEN;
	hmac_sha256_vector(dhkey, sizeof(dhkey), 3, addr, len, kdk);
	wpa_hexdump_key(MSG_DEBUG, "WPS: KDK", kdk, sizeof(kdk));

	wps_kdf(kdk, NULL, 0, "Wi-Fi Easy and Secure Key Derivation",
		keys, sizeof(keys));
	os_memcpy(wps->authkey, keys, WPS_AUTHKEY_LEN);
	os_memcpy(wps->keywrapkey, keys + WPS_AUTHKEY_LEN, WPS_KEYWRAPKEY_LEN);
	os_memcpy(wps->emsk, keys + WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN,
		  WPS_EMSK_LEN);

	wpa_hexdump_key(MSG_DEBUG, "WPS: AuthKey",
			wps->authkey, WPS_AUTHKEY_LEN);
	wpa_hexdump_key(MSG_DEBUG, "WPS: KeyWrapKey",
			wps->keywrapkey, WPS_KEYWRAPKEY_LEN);
	wpa_hexdump_key(MSG_DEBUG, "WPS: EMSK", wps->emsk, WPS_EMSK_LEN);

	return 0;
}
예제 #19
0
/**
 * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104)
 * @key: Key for HMAC operations
 * @key_len: Length of the key in bytes
 * @data: Pointers to the data area
 * @data_len: Length of the data area
 * @mac: Buffer for the hash (20 bytes)
 */
void hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
		 size_t data_len, u8 *mac)
{
	hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
}
예제 #20
0
int main(int argc, char *argv[])
{

	unsigned int i;
	u8 hash[32];
	const u8 *addr[2];
	size_t len[2];
	int errors = 0;

	for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
		printf("SHA256 test case %d:", i + 1);

		addr[0] = (u8 *) tests[i].data;
		len[0] = strlen(tests[i].data);
		sha256_vector(1, addr, len, hash);
		if (memcmp(hash, tests[i].hash, 32) != 0) {
			printf(" FAIL");
			errors++;
		} else
			printf(" OK");

		if (len[0]) {
			addr[0] = (u8 *) tests[i].data;
			len[0] = 1;
			addr[1] = (u8 *) tests[i].data + 1;
			len[1] = strlen(tests[i].data) - 1;
			sha256_vector(2, addr, len, hash);
			if (memcmp(hash, tests[i].hash, 32) != 0) {
				printf(" FAIL");
				errors++;
			} else
				printf(" OK");
		}

		printf("\n");
	}

	for (i = 0; i < sizeof(hmac_tests) / sizeof(hmac_tests[0]); i++) {
		struct hmac_test *t = &hmac_tests[i];
		printf("HMAC-SHA256 test case %d:", i + 1);

		hmac_sha256(t->key, t->key_len, t->data, t->data_len, hash);
		if (memcmp(hash, t->hash, 32) != 0) {
			printf(" FAIL");
			errors++;
		} else
			printf(" OK");

		addr[0] = t->data;
		len[0] = t->data_len;
		hmac_sha256_vector(t->key, t->key_len, 1, addr, len, hash);
		if (memcmp(hash, t->hash, 32) != 0) {
			printf(" FAIL");
			errors++;
		} else
			printf(" OK");

		if (len[0]) {
			addr[0] = t->data;
			len[0] = 1;
			addr[1] = t->data + 1;
			len[1] = t->data_len - 1;
			hmac_sha256_vector(t->key, t->key_len, 2, addr, len,
					   hash);
			if (memcmp(hash, t->hash, 32) != 0) {
				printf(" FAIL");
				errors++;
			} else
				printf(" OK");
		}

		printf("\n");
	}

	printf("Test IEEE 802.11r KDF\n");
	sha256_prf("abc", 3, "KDF test", "data", 4, hash, sizeof(hash));
	/* TODO: add proper test case for this */

	return errors;
}
예제 #21
0
void eap_aka_prime_derive_ck_ik_prime(u8 *ck, u8 *ik, const u8 *sqn_ak,
				      const u8 *network_name,
				      size_t network_name_len)
{
	u8 key[EAP_AKA_CK_LEN + EAP_AKA_IK_LEN];
	u8 hash[SHA256_MAC_LEN];
	const u8 *addr[5];
	size_t len[5];
	u8 fc;
	u8 l0[2], l1[2];

	/* 3GPP TS 33.402 V8.0.0
	 * (CK', IK') = F(CK, IK, <access network identity>)
	 */
	/* TODO: CK', IK' generation should really be moved into the actual
	 * AKA procedure with network name passed in there and option to use
	 * AMF separation bit = 1 (3GPP TS 33.401). */

	/* Change Request 33.402 CR 0033 to version 8.1.1 from
	 * 3GPP TSG-SA WG3 Meeting #53 in September 2008:
	 *
	 * CK' || IK' = HMAC-SHA-256(Key, S)
	 * S = FC || P0 || L0 || P1 || L1 || ... || Pn || Ln
	 * Key = CK || IK
	 * FC = 0x20
	 * P0 = access network identity (3GPP TS 24.302)
	 * L0 = length of acceess network identity (2 octets, big endian)
	 * P1 = SQN xor AK (if AK is not used, AK is treaded as 000..0
	 * L1 = 0x00 0x06
	 */

	fc = 0x20;

	wpa_printf(MSG_DEBUG, "EAP-AKA': Derive (CK',IK') from (CK,IK)");
	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': CK", ck, EAP_AKA_CK_LEN);
	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': IK", ik, EAP_AKA_IK_LEN);
	wpa_printf(MSG_DEBUG, "EAP-AKA': FC = 0x%x", fc);
	wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA': P0 = Access network identity",
			  network_name, network_name_len);
	wpa_hexdump(MSG_DEBUG, "EAP-AKA': P1 = SQN xor AK", sqn_ak, 6);

	os_memcpy(key, ck, EAP_AKA_CK_LEN);
	os_memcpy(key + EAP_AKA_CK_LEN, ik, EAP_AKA_IK_LEN);
	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': Key = CK || IK",
			key, sizeof(key));

	addr[0] = &fc;
	len[0] = 1;
	addr[1] = network_name;
	len[1] = network_name_len;
	WPA_PUT_BE16(l0, network_name_len);
	addr[2] = l0;
	len[2] = 2;
	addr[3] = sqn_ak;
	len[3] = 6;
	WPA_PUT_BE16(l1, 6);
	addr[4] = l1;
	len[4] = 2;

	hmac_sha256_vector(key, sizeof(key), 5, addr, len, hash);
	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': KDF output (CK' || IK')",
			hash, sizeof(hash));

	os_memcpy(ck, hash, EAP_AKA_CK_LEN);
	os_memcpy(ik, hash + EAP_AKA_CK_LEN, EAP_AKA_IK_LEN);
	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': CK'", ck, EAP_AKA_CK_LEN);
	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': IK'", ik, EAP_AKA_IK_LEN);
}