/*
 * EAP server/peer: EAP-EKE shared routines
 * Copyright (c) 2011-2013, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "common.h"
#include "crypto/aes.h"
#include "crypto/aes_wrap.h"
#include "crypto/crypto.h"
#include "crypto/dh_groups.h"
#include "crypto/random.h"
#include "crypto/sha1.h"
#include "crypto/sha256.h"
#include "eap_common/eap_defs.h"
#include "eap_eke_common.h"


static int eap_eke_dh_len(u8 group)
{
	switch (group) {
	case EAP_EKE_DHGROUP_EKE_2:
		return 128;
	case EAP_EKE_DHGROUP_EKE_5:
		return 192;
	case EAP_EKE_DHGROUP_EKE_14:
		return 256;
	case EAP_EKE_DHGROUP_EKE_15:
		return 384;
	case EAP_EKE_DHGROUP_EKE_16:
		return 512;
	}

	return -1;
}


static int eap_eke_dhcomp_len(u8 dhgroup, u8 encr)
{
	int dhlen;

	dhlen = eap_eke_dh_len(dhgroup);
	if (dhlen < 0)
		return -1;
	if (encr != EAP_EKE_ENCR_AES128_CBC)
		return -1;
	return AES_BLOCK_SIZE + dhlen;
}


static const struct dh_group * eap_eke_dh_group(u8 group)
{
	switch (group) {
	case EAP_EKE_DHGROUP_EKE_2:
		return dh_groups_get(2);
	case EAP_EKE_DHGROUP_EKE_5:
		return dh_groups_get(5);
	case EAP_EKE_DHGROUP_EKE_14:
		return dh_groups_get(14);
	case EAP_EKE_DHGROUP_EKE_15:
		return dh_groups_get(15);
	case EAP_EKE_DHGROUP_EKE_16:
		return dh_groups_get(16);
	}

	return NULL;
}


static int eap_eke_dh_generator(u8 group)
{
	switch (group) {
	case EAP_EKE_DHGROUP_EKE_2:
		return 5;
	case EAP_EKE_DHGROUP_EKE_5:
		return 31;
	case EAP_EKE_DHGROUP_EKE_14:
		return 11;
	case EAP_EKE_DHGROUP_EKE_15:
		return 5;
	case EAP_EKE_DHGROUP_EKE_16:
		return 5;
	}

	return -1;
}


static int eap_eke_pnonce_len(u8 mac)
{
	int mac_len;

	if (mac == EAP_EKE_MAC_HMAC_SHA1)
		mac_len = SHA1_MAC_LEN;
	else if (mac == EAP_EKE_MAC_HMAC_SHA2_256)
		mac_len = SHA256_MAC_LEN;
	else
		return -1;

	return AES_BLOCK_SIZE + 16 + mac_len;
}


static int eap_eke_pnonce_ps_len(u8 mac)
{
	int mac_len;

	if (mac == EAP_EKE_MAC_HMAC_SHA1)
		mac_len = SHA1_MAC_LEN;
	else if (mac == EAP_EKE_MAC_HMAC_SHA2_256)
		mac_len = SHA256_MAC_LEN;
	else
		return -1;

	return AES_BLOCK_SIZE + 2 * 16 + mac_len;
}


static int eap_eke_prf_len(u8 prf)
{
	if (prf == EAP_EKE_PRF_HMAC_SHA1)
		return 20;
	if (prf == EAP_EKE_PRF_HMAC_SHA2_256)
		return 32;
	return -1;
}


static int eap_eke_nonce_len(u8 prf)
{
	int prf_len;

	prf_len = eap_eke_prf_len(prf);
	if (prf_len < 0)
		return -1;

	if (prf_len > 2 * 16)
		return (prf_len + 1) / 2;

	return 16;
}


static int eap_eke_auth_len(u8 prf)
{
	switch (prf) {
	case EAP_EKE_PRF_HMAC_SHA1:
		return SHA1_MAC_LEN;
	case EAP_EKE_PRF_HMAC_SHA2_256:
		return SHA256_MAC_LEN;
	}

	return -1;
}


int eap_eke_dh_init(u8 group, u8 *ret_priv, u8 *ret_pub)
{
	int generator;
	u8 gen;
	const struct dh_group *dh;
	size_t pub_len, i;

	generator = eap_eke_dh_generator(group);
	if (generator < 0 || generator > 255)
		return -1;
	gen = generator;

	dh = eap_eke_dh_group(group);
	if (dh == NULL)
		return -1;

	/* x = random number 2 .. p-1 */
	if (random_get_bytes(ret_priv, dh->prime_len))
		return -1;
	if (os_memcmp(ret_priv, dh->prime, dh->prime_len) > 0) {
		/* Make sure private value is smaller than prime */
		ret_priv[0] = 0;
	}
	for (i = 0; i < dh->prime_len - 1; i++) {
		if (ret_priv[i])
			break;
	}
	if (i == dh->prime_len - 1 && (ret_priv[i] == 0 || ret_priv[i] == 1))
		return -1;
	wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: DH private value",
			ret_priv, dh->prime_len);

	/* y = g ^ x (mod p) */
	pub_len = dh->prime_len;
	if (crypto_mod_exp(&gen, 1, ret_priv, dh->prime_len,
			   dh->prime, dh->prime_len, ret_pub, &pub_len) < 0)
		return -1;
	if (pub_len < dh->prime_len) {
		size_t pad = dh->prime_len - pub_len;
		os_memmove(ret_pub + pad, ret_pub, pub_len);
		os_memset(ret_pub, 0, pad);
	}

	wpa_hexdump(MSG_DEBUG, "EAP-EKE: DH public value",
		    ret_pub, dh->prime_len);

	return 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;
}


static int eap_eke_prf_hmac_sha1(const u8 *key, size_t key_len, const u8 *data,
				 size_t data_len, u8 *res, size_t len)
{
	u8 hash[SHA1_MAC_LEN];
	u8 idx;
	const u8 *addr[3];
	size_t vlen[3];
	int ret;

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

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

	return 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;
}


static int eap_eke_prfplus(u8 prf, const u8 *key, size_t key_len,
			   const u8 *data, size_t data_len, u8 *res, size_t len)
{
	if (prf == EAP_EKE_PRF_HMAC_SHA1)
		return eap_eke_prf_hmac_sha1(key, key_len, data, data_len, res,
					     len);
	if (prf == EAP_EKE_PRF_HMAC_SHA2_256)
		return eap_eke_prf_hmac_sha256(key, key_len, data, data_len,
					       res, len);
	return -1;
}


int eap_eke_derive_key(struct eap_eke_session *sess,
		       const u8 *password, size_t password_len,
		       const u8 *id_s, size_t id_s_len, const u8 *id_p,
		       size_t id_p_len, u8 *key)
{
	u8 zeros[EAP_EKE_MAX_HASH_LEN];
	u8 temp[EAP_EKE_MAX_HASH_LEN];
	size_t key_len = 16; /* Only AES-128-CBC is used here */
	u8 *id;

	/* temp = prf(0+, password) */
	os_memset(zeros, 0, sess->prf_len);
	if (eap_eke_prf(sess->prf, zeros, sess->prf_len,
			password, password_len, NULL, 0, temp) < 0)
		return -1;
	wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: temp = prf(0+, password)",
			temp, sess->prf_len);

	/* key = prf+(temp, ID_S | ID_P) */
	id = os_malloc(id_s_len + id_p_len);
	if (id == NULL)
		return -1;
	os_memcpy(id, id_s, id_s_len);
	os_memcpy(id + id_s_len, id_p, id_p_len);
	wpa_hexdump_ascii(MSG_DEBUG, "EAP-EKE: ID_S | ID_P",
			  id, id_s_len + id_p_len);
	if (eap_eke_prfplus(sess->prf, temp, sess->prf_len,
			    id, id_s_len + id_p_len, key, key_len) < 0) {
		os_free(id);
		return -1;
	}
	os_free(id);
	wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: key = prf+(temp, ID_S | ID_P)",
			key, key_len);

	return 0;
}


int eap_eke_dhcomp(struct eap_eke_session *sess, const u8 *key, const u8 *dhpub,
		   u8 *ret_dhcomp)
{
	u8 pub[EAP_EKE_MAX_DH_LEN];
	int dh_len;
	u8 iv[AES_BLOCK_SIZE];

	dh_len = eap_eke_dh_len(sess->dhgroup);
	if (dh_len < 0)
		return -1;

	/*
	 * DHComponent = Encr(key, y)
	 *
	 * All defined DH groups use primes that have length devisible by 16, so
	 * no need to do extra padding for y (= pub).
	 */
	if (sess->encr != EAP_EKE_ENCR_AES128_CBC)
		return -1;
	if (random_get_bytes(iv, AES_BLOCK_SIZE))
		return -1;
	wpa_hexdump(MSG_DEBUG, "EAP-EKE: IV for Encr(key, y)",
		    iv, AES_BLOCK_SIZE);
	os_memcpy(pub, dhpub, dh_len);
	if (aes_128_cbc_encrypt(key, iv, pub, dh_len) < 0)
		return -1;
	os_memcpy(ret_dhcomp, iv, AES_BLOCK_SIZE);
	os_memcpy(ret_dhcomp + AES_BLOCK_SIZE, pub, dh_len);
	wpa_hexdump(MSG_DEBUG, "EAP-EKE: DHComponent = Encr(key, y)",
		    ret_dhcomp, AES_BLOCK_SIZE + dh_len);

	return 0;
}


int eap_eke_shared_secret(struct eap_eke_session *sess, const u8 *key,
			  const u8 *dhpriv, const u8 *peer_dhcomp)
{
	u8 zeros[EAP_EKE_MAX_HASH_LEN];
	u8 peer_pub[EAP_EKE_MAX_DH_LEN];
	u8 modexp[EAP_EKE_MAX_DH_LEN];
	size_t len;
	const struct dh_group *dh;

	if (sess->encr != EAP_EKE_ENCR_AES128_CBC)
		return -1;

	dh = eap_eke_dh_group(sess->dhgroup);
	if (dh == NULL)
		return -1;

	/* Decrypt peer DHComponent */
	os_memcpy(peer_pub, peer_dhcomp + AES_BLOCK_SIZE, dh->prime_len);
	if (aes_128_cbc_decrypt(key, peer_dhcomp, peer_pub, dh->prime_len) < 0) {
		wpa_printf(MSG_INFO, "EAP-EKE: Failed to decrypt DHComponent");
		return -1;
	}
	wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: Decrypted peer DH pubkey",
			peer_pub, dh->prime_len);

	/* SharedSecret = prf(0+, g ^ (x_s * x_p) (mod p)) */
	len = dh->prime_len;
	if (crypto_mod_exp(peer_pub, dh->prime_len, dhpriv, dh->prime_len,
			   dh->prime, dh->prime_len, modexp, &len) < 0)
		return -1;
	if (len < dh->prime_len) {
		size_t pad = dh->prime_len - len;
		os_memmove(modexp + pad, modexp, len);
		os_memset(modexp, 0, pad);
	}

	os_memset(zeros, 0, sess->auth_len);
	if (eap_eke_prf(sess->prf, zeros, sess->auth_len, modexp, dh->prime_len,
			NULL, 0, sess->shared_secret) < 0)
		return -1;
	wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: SharedSecret",
			sess->shared_secret, sess->auth_len);

	return 0;
}


int eap_eke_derive_ke_ki(struct eap_eke_session *sess,
			 const u8 *id_s, size_t id_s_len,
			 const u8 *id_p, size_t id_p_len)
{
	u8 buf[EAP_EKE_MAX_KE_LEN + EAP_EKE_MAX_KI_LEN];
	size_t ke_len, ki_len;
	u8 *data;
	size_t data_len;
	const char *label = "EAP-EKE Keys";
	size_t label_len;

	/*
	 * Ke | Ki = prf+(SharedSecret, "EAP-EKE Keys" | ID_S | ID_P)
	 * Ke = encryption key
	 * Ki = integrity protection key
	 * Length of each key depends on the selected algorithms.
	 */

	if (sess->encr == EAP_EKE_ENCR_AES128_CBC)
		ke_len = 16;
	else
		return -1;

	if (sess->mac == EAP_EKE_PRF_HMAC_SHA1)
		ki_len = 20;
	else if (sess->mac == EAP_EKE_PRF_HMAC_SHA2_256)
		ki_len = 32;
	else
		return -1;

	label_len = os_strlen(label);
	data_len = label_len + id_s_len + id_p_len;
	data = os_malloc(data_len);
	if (data == NULL)
		return -1;
	os_memcpy(data, label, label_len);
	os_memcpy(data + label_len, id_s, id_s_len);
	os_memcpy(data + label_len + id_s_len, id_p, id_p_len);
	if (eap_eke_prfplus(sess->prf, sess->shared_secret, sess->prf_len,
			    data, data_len, buf, ke_len + ki_len) < 0) {
		os_free(data);
		return -1;
	}

	os_memcpy(sess->ke, buf, ke_len);
	wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: Ke", sess->ke, ke_len);
	os_memcpy(sess->ki, buf + ke_len, ki_len);
	wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: Ki", sess->ki, ki_len);

	os_free(data);
	return 0;
}


int eap_eke_derive_ka(struct eap_eke_session *sess,
		      const u8 *id_s, size_t id_s_len,
		      const u8 *id_p, size_t id_p_len,
		      const u8 *nonce_p, const u8 *nonce_s)
{
	u8 *data, *pos;
	size_t data_len;
	const char *label = "EAP-EKE Ka";
	size_t label_len;

	/*
	 * Ka = prf+(SharedSecret, "EAP-EKE Ka" | ID_S | ID_P | Nonce_P |
	 *	     Nonce_S)
	 * Ka = authentication key
	 * Length of the key depends on the selected algorithms.
	 */

	label_len = os_strlen(label);
	data_len = label_len + id_s_len + id_p_len + 2 * sess->nonce_len;
	data = os_malloc(data_len);
	if (data == NULL)
		return -1;
	pos = data;
	os_memcpy(pos, label, label_len);
	pos += label_len;
	os_memcpy(pos, id_s, id_s_len);
	pos += id_s_len;
	os_memcpy(pos, id_p, id_p_len);
	pos += id_p_len;
	os_memcpy(pos, nonce_p, sess->nonce_len);
	pos += sess->nonce_len;
	os_memcpy(pos, nonce_s, sess->nonce_len);
	if (eap_eke_prfplus(sess->prf, sess->shared_secret, sess->prf_len,
			    data, data_len, sess->ka, sess->prf_len) < 0) {
		os_free(data);
		return -1;
	}
	os_free(data);

	wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: Ka", sess->ka, sess->prf_len);

	return 0;
}


int eap_eke_derive_msk(struct eap_eke_session *sess,
		       const u8 *id_s, size_t id_s_len,
		       const u8 *id_p, size_t id_p_len,
		       const u8 *nonce_p, const u8 *nonce_s,
		       u8 *msk, u8 *emsk)
{
	u8 *data, *pos;
	size_t data_len;
	const char *label = "EAP-EKE Exported Keys";
	size_t label_len;
	u8 buf[EAP_MSK_LEN + EAP_EMSK_LEN];

	/*
	 * MSK | EMSK = prf+(SharedSecret, "EAP-EKE Exported Keys" | ID_S |
	 *		     ID_P | Nonce_P | Nonce_S)
	 */

	label_len = os_strlen(label);
	data_len = label_len + id_s_len + id_p_len + 2 * sess->nonce_len;
	data = os_malloc(data_len);
	if (data == NULL)
		return -1;
	pos = data;
	os_memcpy(pos, label, label_len);
	pos += label_len;
	os_memcpy(pos, id_s, id_s_len);
	pos += id_s_len;
	os_memcpy(pos, id_p, id_p_len);
	pos += id_p_len;
	os_memcpy(pos, nonce_p, sess->nonce_len);
	pos += sess->nonce_len;
	os_memcpy(pos, nonce_s, sess->nonce_len);
	if (eap_eke_prfplus(sess->prf, sess->shared_secret, sess->prf_len,
			    data, data_len, buf, EAP_MSK_LEN + EAP_EMSK_LEN) <
	    0) {
		os_free(data);
		return -1;
	}
	os_free(data);

	os_memcpy(msk, buf, EAP_MSK_LEN);
	os_memcpy(emsk, buf + EAP_MSK_LEN, EAP_EMSK_LEN);
	os_memset(buf, 0, sizeof(buf));

	wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: MSK", msk, EAP_MSK_LEN);
	wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: EMSK", msk, EAP_EMSK_LEN);

	return 0;
}


static int eap_eke_mac(u8 mac, const u8 *key, const u8 *data, size_t data_len,
		       u8 *res)
{
	if (mac == EAP_EKE_MAC_HMAC_SHA1)
		return hmac_sha1(key, SHA1_MAC_LEN, data, data_len, res);
	if (mac == EAP_EKE_MAC_HMAC_SHA2_256)
		return hmac_sha256(key, SHA256_MAC_LEN, data, data_len, res);
	return -1;
}


int eap_eke_prot(struct eap_eke_session *sess,
		 const u8 *data, size_t data_len,
		 u8 *prot, size_t *prot_len)
{
	size_t block_size, icv_len, pad;
	u8 *pos, *iv, *e;

	if (sess->encr == EAP_EKE_ENCR_AES128_CBC)
		block_size = AES_BLOCK_SIZE;
	else
		return -1;

	if (sess->mac == EAP_EKE_PRF_HMAC_SHA1)
		icv_len = SHA1_MAC_LEN;
	else if (sess->mac == EAP_EKE_PRF_HMAC_SHA2_256)
		icv_len = SHA256_MAC_LEN;
	else
		return -1;

	pad = data_len % block_size;
	if (pad)
		pad = block_size - pad;

	if (*prot_len < block_size + data_len + pad + icv_len) {
		wpa_printf(MSG_INFO, "EAP-EKE: Not enough room for Prot() data");
	}
	pos = prot;

	if (random_get_bytes(pos, block_size))
		return -1;
	iv = pos;
	wpa_hexdump(MSG_DEBUG, "EAP-EKE: IV for Prot()", iv, block_size);
	pos += block_size;

	e = pos;
	os_memcpy(pos, data, data_len);
	pos += data_len;
	if (pad) {
		if (random_get_bytes(pos, pad))
			return -1;
		pos += pad;
	}

	if (aes_128_cbc_encrypt(sess->ke, iv, e, data_len + pad) < 0)
		return -1;

	if (eap_eke_mac(sess->mac, sess->ki, e, data_len + pad, pos) < 0)
		return -1;
	pos += icv_len;

	*prot_len = pos - prot;
	return 0;
}


int eap_eke_decrypt_prot(struct eap_eke_session *sess,
			 const u8 *prot, size_t prot_len,
			 u8 *data, size_t *data_len)
{
	size_t block_size, icv_len;
	u8 icv[EAP_EKE_MAX_HASH_LEN];

	if (sess->encr == EAP_EKE_ENCR_AES128_CBC)
		block_size = AES_BLOCK_SIZE;
	else
		return -1;

	if (sess->mac == EAP_EKE_PRF_HMAC_SHA1)
		icv_len = SHA1_MAC_LEN;
	else if (sess->mac == EAP_EKE_PRF_HMAC_SHA2_256)
		icv_len = SHA256_MAC_LEN;
	else
		return -1;

	if (prot_len < 2 * block_size + icv_len)
		return -1;
	if ((prot_len - icv_len) % block_size)
		return -1;

	if (eap_eke_mac(sess->mac, sess->ki, prot + block_size,
			prot_len - block_size - icv_len, icv) < 0)
		return -1;
	if (os_memcmp_const(icv, prot + prot_len - icv_len, icv_len) != 0) {
		wpa_printf(MSG_INFO, "EAP-EKE: ICV mismatch in Prot() data");
		return -1;
	}

	if (*data_len < prot_len - block_size - icv_len) {
		wpa_printf(MSG_INFO, "EAP-EKE: Not enough room for decrypted Prot() data");
		return -1;
	}

	*data_len = prot_len - block_size - icv_len;
	os_memcpy(data, prot + block_size, *data_len);
	if (aes_128_cbc_decrypt(sess->ke, prot, data, *data_len) < 0) {
		wpa_printf(MSG_INFO, "EAP-EKE: Failed to decrypt Prot() data");
		return -1;
	}
	wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: Decrypted Prot() data",
			data, *data_len);

	return 0;
}


int eap_eke_auth(struct eap_eke_session *sess, const char *label,
		 const struct wpabuf *msgs, u8 *auth)
{
	wpa_printf(MSG_DEBUG, "EAP-EKE: Auth(%s)", label);
	wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: Ka for Auth",
			sess->ka, sess->auth_len);
	wpa_hexdump_buf(MSG_MSGDUMP, "EAP-EKE: Messages for Auth", msgs);
	return eap_eke_prf(sess->prf, sess->ka, sess->auth_len,
			   (const u8 *) label, os_strlen(label),
			   wpabuf_head(msgs), wpabuf_len(msgs), auth);
}


int eap_eke_session_init(struct eap_eke_session *sess, u8 dhgroup, u8 encr,
			 u8 prf, u8 mac)
{
	sess->dhgroup = dhgroup;
	sess->encr = encr;
	sess->prf = prf;
	sess->mac = mac;

	sess->prf_len = eap_eke_prf_len(prf);
	if (sess->prf_len < 0)
		return -1;
	sess->nonce_len = eap_eke_nonce_len(prf);
	if (sess->nonce_len < 0)
		return -1;
	sess->auth_len = eap_eke_auth_len(prf);
	if (sess->auth_len < 0)
		return -1;
	sess->dhcomp_len = eap_eke_dhcomp_len(sess->dhgroup, sess->encr);
	if (sess->dhcomp_len < 0)
		return -1;
	sess->pnonce_len = eap_eke_pnonce_len(sess->mac);
	if (sess->pnonce_len < 0)
		return -1;
	sess->pnonce_ps_len = eap_eke_pnonce_ps_len(sess->mac);
	if (sess->pnonce_ps_len < 0)
		return -1;

	return 0;
}


void eap_eke_session_clean(struct eap_eke_session *sess)
{
	os_memset(sess->shared_secret, 0, EAP_EKE_MAX_HASH_LEN);
	os_memset(sess->ke, 0, EAP_EKE_MAX_KE_LEN);
	os_memset(sess->ki, 0, EAP_EKE_MAX_KI_LEN);
	os_memset(sess->ka, 0, EAP_EKE_MAX_KA_LEN);
}
