aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libcharon/sa/keymat_v1.c47
-rw-r--r--src/libcharon/sa/keymat_v1.h5
-rw-r--r--src/libcharon/sa/tasks/quick_mode.c3
3 files changed, 31 insertions, 24 deletions
diff --git a/src/libcharon/sa/keymat_v1.c b/src/libcharon/sa/keymat_v1.c
index 3ec8083cf..97a21e022 100644
--- a/src/libcharon/sa/keymat_v1.c
+++ b/src/libcharon/sa/keymat_v1.c
@@ -503,32 +503,14 @@ METHOD(keymat_v1_t, derive_ike_keys, bool,
METHOD(keymat_v1_t, derive_child_keys, bool,
private_keymat_v1_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)
+ u_int32_t spi_i, u_int32_t spi_r, chunk_t nonce_i, chunk_t nonce_r,
+ chunk_t *encr_i, chunk_t *integ_i, chunk_t *encr_r, chunk_t *integ_r)
{
u_int16_t enc_alg, int_alg, enc_size = 0, int_size = 0;
u_int8_t protocol;
- u_int32_t spi;
prf_plus_t *prf_plus;
chunk_t seed, secret = chunk_empty;
- /* KEYMAT = prf+(SKEYID_d, [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b) */
-
- protocol = proposal->get_protocol(proposal);
- spi = proposal->get_spi(proposal);
-
- if (dh)
- {
- if (dh->get_shared_secret(dh, &secret) != SUCCESS)
- {
- return FALSE;
- }
- DBG4(DBG_CHD, "DH secret %B", &secret);
- }
- seed = chunk_cata("mcccc", secret, chunk_from_thing(protocol),
- chunk_from_thing(spi), nonce_i, nonce_r);
- DBG4(DBG_CHD, "seed %B", &seed);
-
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
&enc_alg, &enc_size))
{
@@ -591,16 +573,37 @@ METHOD(keymat_v1_t, derive_child_keys, bool,
int_size /= 8;
}
+ /* KEYMAT = prf+(SKEYID_d, [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b) */
this->prf->set_key(this->prf, this->skeyid_d);
- prf_plus = prf_plus_create(this->prf, FALSE, seed);
+ protocol = proposal->get_protocol(proposal);
+ if (dh)
+ {
+ if (dh->get_shared_secret(dh, &secret) != SUCCESS)
+ {
+ return FALSE;
+ }
+ DBG4(DBG_CHD, "DH secret %B", &secret);
+ }
+ seed = chunk_cata("ccccc", secret, chunk_from_thing(protocol),
+ chunk_from_thing(spi_r), nonce_i, nonce_r);
+ DBG4(DBG_CHD, "initiator SA seed %B", &seed);
+
+ prf_plus = prf_plus_create(this->prf, FALSE, seed);
prf_plus->allocate_bytes(prf_plus, enc_size, encr_i);
prf_plus->allocate_bytes(prf_plus, int_size, integ_i);
+ prf_plus->destroy(prf_plus);
+
+ seed = chunk_cata("ccccc", secret, chunk_from_thing(protocol),
+ chunk_from_thing(spi_i), nonce_i, nonce_r);
+ DBG4(DBG_CHD, "responder SA seed %B", &seed);
+ prf_plus = prf_plus_create(this->prf, FALSE, seed);
prf_plus->allocate_bytes(prf_plus, enc_size, encr_r);
prf_plus->allocate_bytes(prf_plus, int_size, integ_r);
-
prf_plus->destroy(prf_plus);
+ chunk_clear(&secret);
+
if (enc_size)
{
DBG4(DBG_CHD, "encryption initiator key %B", encr_i);
diff --git a/src/libcharon/sa/keymat_v1.h b/src/libcharon/sa/keymat_v1.h
index e2d5cf657..eb07e3a0c 100644
--- a/src/libcharon/sa/keymat_v1.h
+++ b/src/libcharon/sa/keymat_v1.h
@@ -61,6 +61,8 @@ struct keymat_v1_t {
*
* @param proposal selected algorithms
* @param dh diffie hellman key, NULL if none used
+ * @param spi_i SPI chosen by initiatior
+ * @param spi_r SPI chosen by responder
* @param nonce_i quick mode initiator nonce
* @param nonce_r quick mode responder nonce
* @param encr_i allocated initiators encryption key
@@ -69,7 +71,8 @@ struct keymat_v1_t {
* @param integ_r allocated responders integrity key
*/
bool (*derive_child_keys)(keymat_v1_t *this, proposal_t *proposal,
- diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r,
+ diffie_hellman_t *dh, u_int32_t spi_i, u_int32_t spi_r,
+ chunk_t nonce_i, chunk_t nonce_r,
chunk_t *encr_i, chunk_t *integ_i,
chunk_t *encr_r, chunk_t *integ_r);
diff --git a/src/libcharon/sa/tasks/quick_mode.c b/src/libcharon/sa/tasks/quick_mode.c
index 987b8d5f4..8586d9abf 100644
--- a/src/libcharon/sa/tasks/quick_mode.c
+++ b/src/libcharon/sa/tasks/quick_mode.c
@@ -124,7 +124,8 @@ static bool install(private_quick_mode_t *this)
tsi->insert_last(tsi, this->tsi);
tsr->insert_last(tsr, this->tsr);
if (this->keymat->derive_child_keys(this->keymat, this->proposal, NULL,
- this->nonce_i, this->nonce_r, &encr_i, &integ_i, &encr_r, &integ_r))
+ this->spi_i, this->spi_r, this->nonce_i, this->nonce_r,
+ &encr_i, &integ_i, &encr_r, &integ_r))
{
if (this->initiator)
{