From: Tobias Brunner Date: Tue, 15 Mar 2022 08:49:43 +0000 (+0100) Subject: keymat_v2: Use plugin-provided KDF_PRF to derive SKEYSEED X-Git-Tag: 5.9.6rc1~2^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f619b833accf6014f6aa6efdce98cea9b395b4ca;p=thirdparty%2Fstrongswan.git keymat_v2: Use plugin-provided KDF_PRF to derive SKEYSEED --- diff --git a/src/libcharon/sa/ikev2/keymat_v2.c b/src/libcharon/sa/ikev2/keymat_v2.c index d5c6f88209..fe58de5e03 100644 --- a/src/libcharon/sa/ikev2/keymat_v2.c +++ b/src/libcharon/sa/ikev2/keymat_v2.c @@ -244,9 +244,8 @@ METHOD(keymat_v2_t, derive_ike_keys, bool, chunk_t prf_plus_seed, spi_i, spi_r, keymat = chunk_empty; chunk_t sk_ei = chunk_empty, sk_er = chunk_empty; chunk_t sk_ai = chunk_empty, sk_ar = chunk_empty, sk_pi, sk_pr; - kdf_t *prf_plus = NULL; + kdf_t *prf = NULL, *prf_plus = NULL; uint16_t prf_alg, key_size, enc_alg, enc_size, int_alg; - prf_t *rekey_prf = NULL; bool success = FALSE; spi_i = chunk_alloca(sizeof(uint64_t)); @@ -328,19 +327,24 @@ METHOD(keymat_v2_t, derive_ike_keys, bool, break; } fixed_nonce = chunk_cat("cc", nonce_i, nonce_r); - *((uint64_t*)spi_i.ptr) = id->get_initiator_spi(id); - *((uint64_t*)spi_r.ptr) = id->get_responder_spi(id); - prf_plus_seed = chunk_cat("ccc", full_nonce, spi_i, spi_r); - /* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr) - * - * if we are rekeying, SKEYSEED is built on another way - */ - if (rekey_function == PRF_UNDEFINED) /* not rekeying */ + if (rekey_function == PRF_UNDEFINED) { /* SKEYSEED = prf(Ni | Nr, g^ir) */ - if (this->prf->set_key(this->prf, fixed_nonce) && - this->prf->allocate_bytes(this->prf, secret, &skeyseed)) + prf = lib->crypto->create_kdf(lib->crypto, KDF_PRF, this->prf_alg); + if (!prf) + { + DBG1(DBG_IKE, "%N with %N not supported", + key_derivation_function_names, KDF_PRF, + pseudo_random_function_names, rekey_function); + chunk_clear(&secret); + chunk_free(&full_nonce); + chunk_free(&fixed_nonce); + return FALSE; + } + if (prf->set_param(prf, KDF_PARAM_KEY, secret) && + prf->set_param(prf, KDF_PARAM_SALT, fixed_nonce) && + prf->allocate_bytes(prf, 0, &skeyseed)) { prf_plus = lib->crypto->create_kdf(lib->crypto, KDF_PRF_PLUS, this->prf_alg); @@ -350,26 +354,36 @@ METHOD(keymat_v2_t, derive_ike_keys, bool, { /* SKEYSEED = prf(SK_d (old), [g^ir (new)] | Ni | Nr) * use OLD SAs PRF functions for both prf_plus and prf */ - rekey_prf = lib->crypto->create_prf(lib->crypto, rekey_function); - if (!rekey_prf) + prf = lib->crypto->create_kdf(lib->crypto, KDF_PRF, rekey_function); + if (!prf) { - DBG1(DBG_IKE, "PRF of old SA %N not supported!", + DBG1(DBG_IKE, "%N with PRF of old SA %N not supported", + key_derivation_function_names, KDF_PRF, pseudo_random_function_names, rekey_function); chunk_clear(&secret); chunk_free(&full_nonce); chunk_free(&fixed_nonce); - chunk_clear(&prf_plus_seed); return FALSE; } secret = chunk_cat("sc", secret, full_nonce); - if (rekey_prf->set_key(rekey_prf, rekey_skd) && - rekey_prf->allocate_bytes(rekey_prf, secret, &skeyseed)) + if (prf->set_param(prf, KDF_PARAM_KEY, secret) && + prf->set_param(prf, KDF_PARAM_SALT, rekey_skd) && + prf->allocate_bytes(prf, 0, &skeyseed)) { prf_plus = lib->crypto->create_kdf(lib->crypto, KDF_PRF_PLUS, rekey_function); } } DBG4(DBG_IKE, "SKEYSEED %B", &skeyseed); + chunk_clear(&secret); + chunk_free(&fixed_nonce); + DESTROY_IF(prf); + + /* KEYMAT = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr) + */ + *((uint64_t*)spi_i.ptr) = id->get_initiator_spi(id); + *((uint64_t*)spi_r.ptr) = id->get_responder_spi(id); + prf_plus_seed = chunk_cat("ccc", full_nonce, spi_i, spi_r); if (prf_plus && (!prf_plus->set_param(prf_plus, KDF_PARAM_KEY, skeyseed) || @@ -378,13 +392,9 @@ METHOD(keymat_v2_t, derive_ike_keys, bool, prf_plus->destroy(prf_plus); prf_plus = NULL; } - chunk_clear(&skeyseed); - chunk_clear(&secret); chunk_free(&full_nonce); - chunk_free(&fixed_nonce); - chunk_clear(&prf_plus_seed); - DESTROY_IF(rekey_prf); + chunk_free(&prf_plus_seed); if (!prf_plus) {