METHOD(keymat_v2_t, derive_child_keys, bool,
private_tkm_keymat_t *this, proposal_t *proposal, diffie_hellman_t *dh,
- chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i,
- chunk_t *encr_r, chunk_t *integ_r)
+ qske_t *qske, chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i,
+ chunk_t *integ_i, chunk_t *encr_r, chunk_t *integ_r)
{
esa_info_t *esa_info_i, *esa_info_r;
dh_id_type dh_id = 0;
chunk_t nonce = chunk_from_chars("test chunk");
fail_unless(keymat->keymat_v2.derive_child_keys(&keymat->keymat_v2, proposal,
- (diffie_hellman_t *)dh,
+ (diffie_hellman_t *)dh, NULL,
nonce, nonce, &encr_i,
&integ_i, &encr_r, &integ_r),
"Child key derivation failed");
{
keymat_v2_t *keymat_v2 = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
- ok = keymat_v2->derive_child_keys(keymat_v2, proposal, dh,
+ ok = keymat_v2->derive_child_keys(keymat_v2, proposal, dh, NULL,
nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r);
}
if (ike_sa->get_version(ike_sa) == IKEV1)
METHOD(keymat_v2_t, derive_child_keys, bool,
private_keymat_v2_t *this, proposal_t *proposal, diffie_hellman_t *dh,
- chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i,
- chunk_t *encr_r, chunk_t *integ_r)
+ qske_t *qske, chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i,
+ chunk_t *integ_i, chunk_t *encr_r, chunk_t *integ_r)
{
uint16_t enc_alg, int_alg, enc_size = 0, int_size = 0;
- chunk_t seed, secret = chunk_empty;
+ chunk_t seed, secret = chunk_empty, qske_secret = chunk_empty;
prf_plus_t *prf_plus;
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
}
DBG4(DBG_CHD, "DH secret %B", &secret);
}
- seed = chunk_cata("scc", secret, nonce_i, nonce_r);
+ if (qske)
+ {
+ if (!qske->get_shared_secret(qske, &qske_secret))
+ {
+ chunk_clear(&secret);
+ return FALSE;
+ }
+ DBG4(DBG_CHD, "QSKE secret %B", &qske_secret);
+ }
+ seed = chunk_cata("sscc", secret, qske_secret, nonce_i, nonce_r);
DBG4(DBG_CHD, "seed %B", &seed);
prf_plus = prf_plus_create(this->prf, TRUE, seed);
* The keys for the CHILD_SA are allocated in the integ and encr chunks.
* An implementation might hand out encrypted keys only, which are
* decrypted in the kernel before use.
- * If no PFS is used for the CHILD_SA, dh can be NULL.
+ *
+ * If no PFS is used for the CHILD_SA, dh may be NULL.
+ *
+ * If qske is given, the shared secret is appended to the DH secret, if any.
*
* @param proposal selected algorithms
- * @param dh diffie hellman key allocated by create_dh(), or NULL
+ * @param dh optional 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 encr_i chunk to write initiators encryption key to
* @param integ_r chunk to write responders integrity key to
* @return TRUE on success
*/
- bool (*derive_child_keys)(keymat_v2_t *this,
- proposal_t *proposal, diffie_hellman_t *dh,
+ bool (*derive_child_keys)(keymat_v2_t *this, proposal_t *proposal,
+ diffie_hellman_t *dh, qske_t *qske,
chunk_t nonce_i, chunk_t nonce_r,
chunk_t *encr_i, chunk_t *integ_i,
chunk_t *encr_r, chunk_t *integ_r);
this->ipcomp = IPCOMP_NONE;
}
status_i = status_o = FAILED;
- if (this->keymat->derive_child_keys(this->keymat, this->proposal,
- this->dh, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r))
+ if (this->keymat->derive_child_keys(this->keymat, this->proposal, this->dh,
+ NULL, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r))
{
if (this->initiator)
{