void ikev2_responder_deinit(struct ikev2_responder_data *data)
{
	ikev2_free_keys(&data->keys);
	wpabuf_free(data->i_dh_public);
	wpabuf_free(data->r_dh_private);
	os_free(data->IDi);
	os_free(data->IDr);
	os_free(data->shared_secret);
	wpabuf_free(data->i_sign_msg);
	wpabuf_free(data->r_sign_msg);
	os_free(data->key_pad);
}
Exemple #2
0
int ikev2_derive_sk_keys(const struct ikev2_prf_alg *prf,
			 const struct ikev2_integ_alg *integ,
			 const struct ikev2_encr_alg *encr,
			 const u8 *skeyseed, const u8 *data, size_t data_len,
			 struct ikev2_keys *keys)
{
	u8 *keybuf, *pos;
	size_t keybuf_len;

	/*
	 * {SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr } =
	 *	prf+(SKEYSEED, Ni | Nr | SPIi | SPIr )
	 */
	ikev2_free_keys(keys);
	keys->SK_d_len = prf->key_len;
	keys->SK_integ_len = integ->key_len;
	keys->SK_encr_len = encr->key_len;
	keys->SK_prf_len = prf->key_len;

	keybuf_len = keys->SK_d_len + 2 * keys->SK_integ_len +
		2 * keys->SK_encr_len + 2 * keys->SK_prf_len;
	keybuf = os_malloc(keybuf_len);
	if (keybuf == NULL)
		return -1;

	if (ikev2_prf_plus(prf->id, skeyseed, prf->hash_len,
			   data, data_len, keybuf, keybuf_len)) {
		os_free(keybuf);
		return -1;
	}

	pos = keybuf;

	keys->SK_d = os_malloc(keys->SK_d_len);
	if (keys->SK_d) {
		os_memcpy(keys->SK_d, pos, keys->SK_d_len);
		wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_d",
				keys->SK_d, keys->SK_d_len);
	}
	pos += keys->SK_d_len;

	keys->SK_ai = os_malloc(keys->SK_integ_len);
	if (keys->SK_ai) {
		os_memcpy(keys->SK_ai, pos, keys->SK_integ_len);
		wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_ai",
				keys->SK_ai, keys->SK_integ_len);
	}
	pos += keys->SK_integ_len;

	keys->SK_ar = os_malloc(keys->SK_integ_len);
	if (keys->SK_ar) {
		os_memcpy(keys->SK_ar, pos, keys->SK_integ_len);
		wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_ar",
				keys->SK_ar, keys->SK_integ_len);
	}
	pos += keys->SK_integ_len;

	keys->SK_ei = os_malloc(keys->SK_encr_len);
	if (keys->SK_ei) {
		os_memcpy(keys->SK_ei, pos, keys->SK_encr_len);
		wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_ei",
				keys->SK_ei, keys->SK_encr_len);
	}
	pos += keys->SK_encr_len;

	keys->SK_er = os_malloc(keys->SK_encr_len);
	if (keys->SK_er) {
		os_memcpy(keys->SK_er, pos, keys->SK_encr_len);
		wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_er",
				keys->SK_er, keys->SK_encr_len);
	}
	pos += keys->SK_encr_len;

	keys->SK_pi = os_malloc(keys->SK_prf_len);
	if (keys->SK_pi) {
		os_memcpy(keys->SK_pi, pos, keys->SK_prf_len);
		wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_pi",
				keys->SK_pi, keys->SK_prf_len);
	}
	pos += keys->SK_prf_len;

	keys->SK_pr = os_malloc(keys->SK_prf_len);
	if (keys->SK_pr) {
		os_memcpy(keys->SK_pr, pos, keys->SK_prf_len);
		wpa_hexdump_key(MSG_DEBUG, "IKEV2: SK_pr",
				keys->SK_pr, keys->SK_prf_len);
	}

	os_free(keybuf);

	if (!ikev2_keys_set(keys)) {
		ikev2_free_keys(keys);
		return -1;
	}

	return 0;
}