METHOD(keymat_v2_t, derive_ike_keys, bool,
private_tkm_keymat_t *this, proposal_t *proposal, diffie_hellman_t *dh,
- chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
+ qske_t *qske, chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
pseudo_random_function_t rekey_function, chunk_t rekey_skd)
{
uint16_t enc_alg, int_alg, key_size;
ck_assert(dh->dh.set_other_public_value(&dh->dh, pubvalue));
fail_unless(keymat->keymat_v2.derive_ike_keys(&keymat->keymat_v2, proposal,
- &dh->dh, nonce, nonce, ike_sa_id, PRF_UNDEFINED, chunk_empty),
+ &dh->dh, NULL, nonce, nonce, ike_sa_id, PRF_UNDEFINED,
+ chunk_empty),
"Key derivation failed");
chunk_free(&nonce);
{
keymat_v2_t *keymat_v2 = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
- ok = keymat_v2->derive_ike_keys(keymat_v2, proposal, dh, nonce_i,
- nonce_r, ike_sa->get_id(ike_sa), old_prf, old_skd);
+ ok = keymat_v2->derive_ike_keys(keymat_v2, proposal, dh, NULL,
+ nonce_i, nonce_r, ike_sa->get_id(ike_sa),
+ old_prf, old_skd);
}
if (ike_sa->get_version(ike_sa) == IKEV1)
{
METHOD(keymat_v2_t, derive_ike_keys, bool,
private_keymat_v2_t *this, proposal_t *proposal, diffie_hellman_t *dh,
- chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
+ qske_t *qske, chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
pseudo_random_function_t rekey_function, chunk_t rekey_skd)
{
chunk_t skeyseed = chunk_empty, key, secret, full_nonce, fixed_nonce;
- chunk_t prf_plus_seed, spi_i, spi_r;
+ chunk_t qske_secret, prf_plus_seed, spi_i, spi_r;
prf_plus_t *prf_plus = NULL;
uint16_t alg, key_size, int_alg;
prf_t *rekey_prf = NULL;
spi_i = chunk_alloca(sizeof(uint64_t));
spi_r = chunk_alloca(sizeof(uint64_t));
- if (!dh->get_shared_secret(dh, &secret))
- {
- return FALSE;
- }
-
/* Create SAs general purpose PRF first, we may use it here */
if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &alg, NULL))
{
DBG1(DBG_IKE, "no %N selected",
transform_type_names, PSEUDO_RANDOM_FUNCTION);
- chunk_clear(&secret);
return FALSE;
}
this->prf_alg = alg;
DESTROY_IF(this->prf);
this->prf = lib->crypto->create_prf(lib->crypto, alg);
- if (this->prf == NULL)
+ if (!this->prf)
{
DBG1(DBG_IKE, "%N %N not supported!",
transform_type_names, PSEUDO_RANDOM_FUNCTION,
pseudo_random_function_names, alg);
- chunk_clear(&secret);
return FALSE;
}
- DBG4(DBG_IKE, "shared Diffie Hellman secret %B", &secret);
+
+ if (!dh->get_shared_secret(dh, &secret))
+ {
+ return FALSE;
+ }
+ DBG4(DBG_IKE, "DH secret %B", &secret);
+
+ if (qske)
+ {
+ if (!qske->get_shared_secret(qske, &qske_secret))
+ {
+ chunk_clear(&secret);
+ return FALSE;
+ }
+ DBG4(DBG_IKE, "QSKE secret %B", &qske_secret);
+ secret = chunk_cat("ss", secret, qske_secret);
+ }
+
/* full nonce is used as seed for PRF+ ... */
full_nonce = chunk_cat("cc", nonce_i, nonce_r);
/* but the PRF may need a fixed key which only uses the first bytes of
* These keys are not handed out, but are used by the associated signers,
* crypters and authentication functions.
*
+ * If qske is given, its secret is appended to the DH secret.
+ *
* @param proposal selected algorithms
* @param dh diffie hellman key allocated by create_dh()
+ * @param qske optional QSKE implementation allocated by create_qske()
* @param nonce_i initiators nonce value
* @param nonce_r responders nonce value
* @param id IKE_SA identifier
* @return TRUE on success
*/
bool (*derive_ike_keys)(keymat_v2_t *this, proposal_t *proposal,
- diffie_hellman_t *dh, chunk_t nonce_i,
+ diffie_hellman_t *dh, qske_t *qske, chunk_t nonce_i,
chunk_t nonce_r, ike_sa_id_t *id,
pseudo_random_function_t rekey_function,
chunk_t rekey_skd);
}
}
if (!this->keymat->derive_ike_keys(this->keymat, this->proposal, this->dh,
- nonce_i, nonce_r, id, prf_alg, skd))
+ NULL, nonce_i, nonce_r, id, prf_alg, skd))
{
return FALSE;
}