From: Tobias Brunner Date: Thu, 28 Jun 2018 09:40:49 +0000 (+0200) Subject: keymat_v2: Add optional qske_t argument to derive_ike_keys() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fd60762514468a4282c8d9eb8ecf179b27835d18;p=thirdparty%2Fstrongswan.git keymat_v2: Add optional qske_t argument to derive_ike_keys() If given, its shared secret is appended to the secret provided by the diffie_hellman_t implementation. --- diff --git a/src/charon-tkm/src/tkm/tkm_keymat.c b/src/charon-tkm/src/tkm/tkm_keymat.c index db2db8b427..937bed8d92 100644 --- a/src/charon-tkm/src/tkm/tkm_keymat.c +++ b/src/charon-tkm/src/tkm/tkm_keymat.c @@ -184,7 +184,7 @@ METHOD(keymat_t, create_nonce_gen, nonce_gen_t*, 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; diff --git a/src/charon-tkm/tests/keymat_tests.c b/src/charon-tkm/tests/keymat_tests.c index eea589c091..ee2737e3da 100644 --- a/src/charon-tkm/tests/keymat_tests.c +++ b/src/charon-tkm/tests/keymat_tests.c @@ -55,7 +55,8 @@ START_TEST(test_derive_ike_keys) 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); diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c index ff75cb5c1a..cbdaa39a20 100644 --- a/src/libcharon/plugins/ha/ha_dispatcher.c +++ b/src/libcharon/plugins/ha/ha_dispatcher.c @@ -234,8 +234,9 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message { 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) { diff --git a/src/libcharon/sa/ikev2/keymat_v2.c b/src/libcharon/sa/ikev2/keymat_v2.c index 56cf00dafa..7ac36e7cfe 100644 --- a/src/libcharon/sa/ikev2/keymat_v2.c +++ b/src/libcharon/sa/ikev2/keymat_v2.c @@ -306,11 +306,11 @@ failure: 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; @@ -318,31 +318,41 @@ METHOD(keymat_v2_t, derive_ike_keys, bool, 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 diff --git a/src/libcharon/sa/ikev2/keymat_v2.h b/src/libcharon/sa/ikev2/keymat_v2.h index 612747051d..a7d0003a65 100644 --- a/src/libcharon/sa/ikev2/keymat_v2.h +++ b/src/libcharon/sa/ikev2/keymat_v2.h @@ -53,8 +53,11 @@ struct keymat_v2_t { * 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 @@ -63,7 +66,7 @@ struct keymat_v2_t { * @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); diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c index 04ce5045e7..00ec9f4564 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.c +++ b/src/libcharon/sa/ikev2/tasks/ike_init.c @@ -782,7 +782,7 @@ static bool derive_keys(private_ike_init_t *this, } } 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; }