diff options
-rw-r--r-- | src/libcharon/sa/keymat_v1.c | 47 | ||||
-rw-r--r-- | src/libcharon/sa/keymat_v1.h | 5 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/quick_mode.c | 3 |
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) { |