chunk_t prf_plus_seed, spi_i, spi_r, keymat = chunk_empty;
chunk_t sk_ei = chunk_empty, sk_er = chunk_empty;
chunk_t sk_ai = chunk_empty, sk_ar = chunk_empty, sk_pi, sk_pr;
- kdf_t *prf_plus = NULL;
+ kdf_t *prf = NULL, *prf_plus = NULL;
uint16_t prf_alg, key_size, enc_alg, enc_size, int_alg;
- prf_t *rekey_prf = NULL;
bool success = FALSE;
spi_i = chunk_alloca(sizeof(uint64_t));
break;
}
fixed_nonce = chunk_cat("cc", nonce_i, nonce_r);
- *((uint64_t*)spi_i.ptr) = id->get_initiator_spi(id);
- *((uint64_t*)spi_r.ptr) = id->get_responder_spi(id);
- prf_plus_seed = chunk_cat("ccc", full_nonce, spi_i, spi_r);
- /* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
- *
- * if we are rekeying, SKEYSEED is built on another way
- */
- if (rekey_function == PRF_UNDEFINED) /* not rekeying */
+ if (rekey_function == PRF_UNDEFINED)
{
/* SKEYSEED = prf(Ni | Nr, g^ir) */
- if (this->prf->set_key(this->prf, fixed_nonce) &&
- this->prf->allocate_bytes(this->prf, secret, &skeyseed))
+ prf = lib->crypto->create_kdf(lib->crypto, KDF_PRF, this->prf_alg);
+ if (!prf)
+ {
+ DBG1(DBG_IKE, "%N with %N not supported",
+ key_derivation_function_names, KDF_PRF,
+ pseudo_random_function_names, rekey_function);
+ chunk_clear(&secret);
+ chunk_free(&full_nonce);
+ chunk_free(&fixed_nonce);
+ return FALSE;
+ }
+ if (prf->set_param(prf, KDF_PARAM_KEY, secret) &&
+ prf->set_param(prf, KDF_PARAM_SALT, fixed_nonce) &&
+ prf->allocate_bytes(prf, 0, &skeyseed))
{
prf_plus = lib->crypto->create_kdf(lib->crypto, KDF_PRF_PLUS,
this->prf_alg);
{
/* SKEYSEED = prf(SK_d (old), [g^ir (new)] | Ni | Nr)
* use OLD SAs PRF functions for both prf_plus and prf */
- rekey_prf = lib->crypto->create_prf(lib->crypto, rekey_function);
- if (!rekey_prf)
+ prf = lib->crypto->create_kdf(lib->crypto, KDF_PRF, rekey_function);
+ if (!prf)
{
- DBG1(DBG_IKE, "PRF of old SA %N not supported!",
+ DBG1(DBG_IKE, "%N with PRF of old SA %N not supported",
+ key_derivation_function_names, KDF_PRF,
pseudo_random_function_names, rekey_function);
chunk_clear(&secret);
chunk_free(&full_nonce);
chunk_free(&fixed_nonce);
- chunk_clear(&prf_plus_seed);
return FALSE;
}
secret = chunk_cat("sc", secret, full_nonce);
- if (rekey_prf->set_key(rekey_prf, rekey_skd) &&
- rekey_prf->allocate_bytes(rekey_prf, secret, &skeyseed))
+ if (prf->set_param(prf, KDF_PARAM_KEY, secret) &&
+ prf->set_param(prf, KDF_PARAM_SALT, rekey_skd) &&
+ prf->allocate_bytes(prf, 0, &skeyseed))
{
prf_plus = lib->crypto->create_kdf(lib->crypto, KDF_PRF_PLUS,
rekey_function);
}
}
DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed);
+ chunk_clear(&secret);
+ chunk_free(&fixed_nonce);
+ DESTROY_IF(prf);
+
+ /* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
+ */
+ *((uint64_t*)spi_i.ptr) = id->get_initiator_spi(id);
+ *((uint64_t*)spi_r.ptr) = id->get_responder_spi(id);
+ prf_plus_seed = chunk_cat("ccc", full_nonce, spi_i, spi_r);
if (prf_plus &&
(!prf_plus->set_param(prf_plus, KDF_PARAM_KEY, skeyseed) ||
prf_plus->destroy(prf_plus);
prf_plus = NULL;
}
-
chunk_clear(&skeyseed);
- chunk_clear(&secret);
chunk_free(&full_nonce);
- chunk_free(&fixed_nonce);
- chunk_clear(&prf_plus_seed);
- DESTROY_IF(rekey_prf);
+ chunk_free(&prf_plus_seed);
if (!prf_plus)
{