diff --git a/src/libcharon/Android.mk b/src/libcharon/Android.mk index 4f3d78c6d..cb7e4b103 100644 --- a/src/libcharon/Android.mk +++ b/src/libcharon/Android.mk @@ -117,6 +117,7 @@ sa/ikev2/tasks/ike_verify_peer_cert.c sa/ikev2/tasks/ike_verify_peer_cert.h libcharon_la_SOURCES += \ sa/ikev1/keymat_v1.c sa/ikev1/keymat_v1.h \ +sa/ikev1/iv_manager.c sa/ikev1/iv_manager.h \ sa/ikev1/task_manager_v1.c sa/ikev1/task_manager_v1.h \ sa/ikev1/authenticators/psk_v1_authenticator.c sa/ikev1/authenticators/psk_v1_authenticator.h \ sa/ikev1/authenticators/pubkey_v1_authenticator.c sa/ikev1/authenticators/pubkey_v1_authenticator.h \ diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index e530205e8..6fa995a30 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -118,6 +118,7 @@ endif if USE_IKEV1 libcharon_la_SOURCES += \ sa/ikev1/keymat_v1.c sa/ikev1/keymat_v1.h \ +sa/ikev1/iv_manager.c sa/ikev1/iv_manager.h \ sa/ikev1/task_manager_v1.c sa/ikev1/task_manager_v1.h \ sa/ikev1/authenticators/psk_v1_authenticator.c sa/ikev1/authenticators/psk_v1_authenticator.h \ sa/ikev1/authenticators/pubkey_v1_authenticator.c sa/ikev1/authenticators/pubkey_v1_authenticator.h \ diff --git a/src/libcharon/sa/ikev1/iv_manager.c b/src/libcharon/sa/ikev1/iv_manager.c new file mode 100644 index 000000000..c9f737ccd --- /dev/null +++ b/src/libcharon/sa/ikev1/iv_manager.c @@ -0,0 +1,355 @@ +/* + * Copyright (C) 2011-2016 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "iv_manager.h" + +#include + +/** + * Max. number of IVs/QMs to track. + */ +#define MAX_EXCHANGES_DEFAULT 3 + +typedef struct private_iv_manager_t private_iv_manager_t; +typedef struct iv_data_t iv_data_t; +typedef struct qm_data_t qm_data_t; + +/** + * Data stored for IVs. + */ +struct iv_data_t { + /** + * message ID + */ + uint32_t mid; + + /** + * current IV + */ + chunk_t iv; + + /** + * last block of encrypted message + */ + chunk_t last_block; +}; + +/** + * Private data of a iv_manager_t object. + */ +struct private_iv_manager_t { + /** + * Implement public interface. + */ + iv_manager_t public; + + /** + * Phase 1 IV. + */ + iv_data_t phase1_iv; + + /** + * Keep track of IVs for exchanges after phase 1. We store only a limited + * number of IVs in an MRU sort of way. Stores iv_data_t objects. + */ + linked_list_t *ivs; + + /** + * Keep track of Nonces during Quick Mode exchanges. Only a limited number + * of QMs are tracked at the same time. Stores qm_data_t objects. + */ + linked_list_t *qms; + + /** + * Max. number of IVs/Quick Modes to track. + */ + int max_exchanges; + + /** + * Hasher used for IV generation. + */ + hasher_t *hasher; + + /* + * Encryption algorithm the block size. + */ + size_t block_size; +}; + +/** + * Data stored for Quick Mode exchanges. + */ +struct qm_data_t { + /** + * Message ID. + */ + uint32_t mid; + + /** + * Ni_b (Nonce from first message). + */ + chunk_t n_i; + + /** + * Nr_b (Nonce from second message). + */ + chunk_t n_r; +}; + +/** + * Destroy an iv_data_t object. + */ +static void iv_data_destroy(iv_data_t *this) +{ + chunk_free(&this->last_block); + chunk_free(&this->iv); + free(this); +} + +/** + * Destroy a qm_data_t object. + */ +static void qm_data_destroy(qm_data_t *this) +{ + chunk_free(&this->n_i); + chunk_free(&this->n_r); + free(this); +} + +/** + * Generate an IV. + */ +static bool generate_iv(private_iv_manager_t *this, iv_data_t *iv) +{ + if (iv->mid == 0 || iv->iv.ptr) + { /* use last block of previous encrypted message */ + chunk_free(&iv->iv); + iv->iv = iv->last_block; + iv->last_block = chunk_empty; + } + else + { + /* initial phase 2 IV = hash(last_phase1_block | mid) */ + uint32_t net;; + chunk_t data; + + net = htonl(iv->mid); + data = chunk_cata("cc", this->phase1_iv.iv, chunk_from_thing(net)); + if (!this->hasher->allocate_hash(this->hasher, data, &iv->iv)) + { + return FALSE; + } + if (iv->iv.len > this->block_size) + { + iv->iv.len = this->block_size; + } + } + DBG4(DBG_IKE, "next IV for MID %u %B", iv->mid, &iv->iv); + return TRUE; +} + +/** + * Try to find an IV for the given message ID, if not found, generate it. + */ +static iv_data_t *lookup_iv(private_iv_manager_t *this, uint32_t mid) +{ + enumerator_t *enumerator; + iv_data_t *iv, *found = NULL; + + if (mid == 0) + { + return &this->phase1_iv; + } + + enumerator = this->ivs->create_enumerator(this->ivs); + while (enumerator->enumerate(enumerator, &iv)) + { + if (iv->mid == mid) + { /* IV gets moved to the front of the list */ + this->ivs->remove_at(this->ivs, enumerator); + found = iv; + break; + } + } + enumerator->destroy(enumerator); + if (!found) + { + INIT(found, + .mid = mid, + ); + if (!generate_iv(this, found)) + { + iv_data_destroy(found); + return NULL; + } + } + this->ivs->insert_first(this->ivs, found); + /* remove least recently used IV if maximum reached */ + if (this->ivs->get_count(this->ivs) > this->max_exchanges && + this->ivs->remove_last(this->ivs, (void**)&iv) == SUCCESS) + { + iv_data_destroy(iv); + } + return found; +} + +METHOD(iv_manager_t, init_iv_chain, bool, + private_iv_manager_t *this, chunk_t data, hasher_t *hasher, + size_t block_size) +{ + this->hasher = hasher; + this->block_size = block_size; + + if (!this->hasher->allocate_hash(this->hasher, data, &this->phase1_iv.iv)) + { + return FALSE; + } + if (this->phase1_iv.iv.len > this->block_size) + { + this->phase1_iv.iv.len = this->block_size; + } + DBG4(DBG_IKE, "initial IV %B", &this->phase1_iv.iv); + return TRUE; +} + +METHOD(iv_manager_t, get_iv, bool, + private_iv_manager_t *this, uint32_t mid, chunk_t *out) +{ + iv_data_t *iv; + + iv = lookup_iv(this, mid); + if (iv) + { + *out = iv->iv; + return TRUE; + } + return FALSE; +} + +METHOD(iv_manager_t, update_iv, bool, + private_iv_manager_t *this, uint32_t mid, chunk_t last_block) +{ + iv_data_t *iv = lookup_iv(this, mid); + if (iv) + { /* update last block */ + chunk_free(&iv->last_block); + iv->last_block = chunk_clone(last_block); + return TRUE; + } + return FALSE; +} + +METHOD(iv_manager_t, confirm_iv, bool, + private_iv_manager_t *this, uint32_t mid) +{ + iv_data_t *iv = lookup_iv(this, mid); + if (iv) + { + return generate_iv(this, iv); + } + return FALSE; +} + +METHOD(iv_manager_t, lookup_quick_mode, void, + private_iv_manager_t *this, uint32_t mid, chunk_t **n_i, chunk_t **n_r) +{ + enumerator_t *enumerator; + qm_data_t *qm, *found = NULL; + + enumerator = this->qms->create_enumerator(this->qms); + while (enumerator->enumerate(enumerator, &qm)) + { + if (qm->mid == mid) + { /* state gets moved to the front of the list */ + this->qms->remove_at(this->qms, enumerator); + found = qm; + break; + } + } + enumerator->destroy(enumerator); + if (!found) + { + INIT(found, + .mid = mid, + ); + } + + *n_i = &found->n_i; + *n_r = &found->n_r; + + this->qms->insert_first(this->qms, found); + /* remove least recently used state if maximum reached */ + if (this->qms->get_count(this->qms) > this->max_exchanges && + this->qms->remove_last(this->qms, (void**)&qm) == SUCCESS) + { + qm_data_destroy(qm); + } +} + +METHOD(iv_manager_t, remove_quick_mode, void, + private_iv_manager_t *this, uint32_t mid) +{ + enumerator_t *enumerator; + qm_data_t *qm; + + enumerator = this->qms->create_enumerator(this->qms); + while (enumerator->enumerate(enumerator, &qm)) + { + if (qm->mid == mid) + { + this->qms->remove_at(this->qms, enumerator); + qm_data_destroy(qm); + break; + } + } + enumerator->destroy(enumerator); +} + +METHOD(iv_manager_t, destroy, void, + private_iv_manager_t *this) +{ + chunk_free(&this->phase1_iv.iv); + chunk_free(&this->phase1_iv.last_block); + this->ivs->destroy_function(this->ivs, (void*)iv_data_destroy); + this->qms->destroy_function(this->qms, (void*)qm_data_destroy); + free(this); +} + +iv_manager_t *iv_manager_create(int max_exchanges) +{ + private_iv_manager_t *this; + + INIT(this, + .public = { + .init_iv_chain = _init_iv_chain, + .get_iv = _get_iv, + .update_iv = _update_iv, + .confirm_iv = _confirm_iv, + .lookup_quick_mode = _lookup_quick_mode, + .remove_quick_mode = _remove_quick_mode, + .destroy = _destroy, + }, + .ivs = linked_list_create(), + .qms = linked_list_create(), + .max_exchanges = max_exchanges, + ); + + if (!this->max_exchanges) + { + this->max_exchanges = lib->settings->get_int(lib->settings, + "%s.max_ikev1_exchanges", MAX_EXCHANGES_DEFAULT, lib->ns); + } + return &this->public; +} diff --git a/src/libcharon/sa/ikev1/iv_manager.h b/src/libcharon/sa/ikev1/iv_manager.h new file mode 100644 index 000000000..c5273fed9 --- /dev/null +++ b/src/libcharon/sa/ikev1/iv_manager.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2011-2016 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup iv_manager iv_manager + * @{ @ingroup ikev1 + */ + +#ifndef IV_MANAGER_H_ +#define IV_MANAGER_H_ + +#include +#include + +typedef struct iv_manager_t iv_manager_t; + +/** + * IV and QM managing instance for IKEv1. Keeps track of phase 2 exchanges + * and IV, as well as the phase 1 IV. + */ +struct iv_manager_t { + + /** + * Set the value of the first phase1 IV. + * + * @param data input to calc initial IV from (g^xi | g^xr) + * @param hasher hasher to be used for IV calculation + * (shared with keymat, must not be destroyed here) + * @param block_size cipher block size of aead + * @return TRUE for success, FALSE otherwise + */ + bool (*init_iv_chain)(iv_manager_t *this, chunk_t data, hasher_t *hasher, + size_t block_size); + + /** + * Returns the IV for a message with the given message ID. + * + * The return chunk contains internal data and is valid until the next + * get_iv/udpate_iv/confirm_iv() call. + * + * @param mid message ID + * @param iv chunk receiving IV, internal data + * @return TRUE if IV allocated successfully + */ + bool (*get_iv)(iv_manager_t *this, uint32_t mid, chunk_t *iv); + + /** + * Updates the IV for the next message with the given message ID. + * + * A call of confirm_iv() is required in order to actually make the IV + * available. This is needed for the inbound case where we store the last + * block of the encrypted message but want to update the IV only after + * verification of the decrypted message. + * + * @param mid message ID + * @param last_block last block of encrypted message (gets cloned) + * @return TRUE if IV updated successfully + */ + bool (*update_iv)(iv_manager_t *this, uint32_t mid, chunk_t last_block); + + /** + * Confirms the updated IV for the given message ID. + * + * To actually make the new IV available via get_iv() this method has to + * be called after update_iv(). + * + * @param mid message ID + * @return TRUE if IV confirmed successfully + */ + bool (*confirm_iv)(iv_manager_t *this, uint32_t mid); + + /** + * Try to find a QM for the given message ID, if not found, generate it. + * The nonces shall be assigned by the caller if they are not set yet. + * + * @param mid message ID + * @param n_i chunk pointer to contain Ni_b (Nonce from first + * message) + * @param n_r chunk pointer to contain Nr_b (Nonce from second + * message) + */ + void (*lookup_quick_mode)(iv_manager_t *this, uint32_t mid, chunk_t **n_i, + chunk_t **n_r); + + /** + * Remove the QM for the given message ID. + * + * @param mid message ID + */ + void (*remove_quick_mode)(iv_manager_t *this, uint32_t mid); + + /* + * Destroy a iv_manager_t. + */ + void (*destroy)(iv_manager_t *this); +}; + +/** + * Create an IV and QM manager which is able to store up to max_exchanges + * initialization vectors and quick modes. + * + * @param max_exchanges maximum number of IVs and QMs to be stored, set + * to 0 to use default (3, or as configured) + * @return IV and QM manager instance + */ +iv_manager_t *iv_manager_create(int max_exchanges); + +#endif /** IV_MANAGER_H_ @}*/ diff --git a/src/libcharon/sa/ikev1/keymat_v1.c b/src/libcharon/sa/ikev1/keymat_v1.c index 29d8acea0..673a7a131 100644 --- a/src/libcharon/sa/ikev1/keymat_v1.c +++ b/src/libcharon/sa/ikev1/keymat_v1.c @@ -16,29 +16,12 @@ #include "keymat_v1.h" #include +#include #include #include -#include typedef struct private_keymat_v1_t private_keymat_v1_t; -/** - * Max. number of IVs/QMs to track. - */ -#define MAX_EXCHANGES_DEFAULT 3 - -/** - * Data stored for IVs - */ -typedef struct { - /** message ID */ - uint32_t mid; - /** current IV */ - chunk_t iv; - /** last block of encrypted message */ - chunk_t last_block; -} iv_data_t; - /** * Private data of an keymat_t object. */ @@ -85,61 +68,11 @@ struct private_keymat_v1_t { chunk_t skeyid_a; /** - * Phase 1 IV + * IV and QM manager */ - iv_data_t phase1_iv; - - /** - * Keep track of IVs for exchanges after phase 1. We store only a limited - * number of IVs in an MRU sort of way. Stores iv_data_t objects. - */ - linked_list_t *ivs; - - /** - * Keep track of Nonces during Quick Mode exchanges. Only a limited number - * of QMs are tracked at the same time. Stores qm_data_t objects. - */ - linked_list_t *qms; - - /** - * Max. number of IVs/Quick Modes to track. - */ - int max_exchanges; + iv_manager_t *iv_manager; }; - -/** - * Destroy an iv_data_t object. - */ -static void iv_data_destroy(iv_data_t *this) -{ - chunk_free(&this->last_block); - chunk_free(&this->iv); - free(this); -} - -/** - * Data stored for Quick Mode exchanges - */ -typedef struct { - /** message ID */ - uint32_t mid; - /** Ni_b (Nonce from first message) */ - chunk_t n_i; - /** Nr_b (Nonce from second message) */ - chunk_t n_r; -} qm_data_t; - -/** - * Destroy a qm_data_t object. - */ -static void qm_data_destroy(qm_data_t *this) -{ - chunk_free(&this->n_i); - chunk_free(&this->n_r); - free(this); -} - /** * Constants used in key derivation. */ @@ -567,17 +500,8 @@ METHOD(keymat_v1_t, derive_ike_keys, bool, /* initial IV = hash(g^xi | g^xr) */ data = chunk_cata("cc", g_xi, g_xr); chunk_free(&dh_me); - if (!this->hasher->allocate_hash(this->hasher, data, &this->phase1_iv.iv)) - { - return FALSE; - } - if (this->phase1_iv.iv.len > this->aead->get_block_size(this->aead)) - { - this->phase1_iv.iv.len = this->aead->get_block_size(this->aead); - } - DBG4(DBG_IKE, "initial IV %B", &this->phase1_iv.iv); - - return TRUE; + return this->iv_manager->init_iv_chain(this->iv_manager, data, this->hasher, + this->aead->get_block_size(this->aead)); } METHOD(keymat_v1_t, derive_child_keys, bool, @@ -844,47 +768,11 @@ static chunk_t get_message_data(message_t *message, generator_t *generator) return generator->get_chunk(generator, &lenpos); } -/** - * Try to find data about a Quick Mode with the given message ID, - * if none is found, state is generated. - */ -static qm_data_t *lookup_quick_mode(private_keymat_v1_t *this, uint32_t mid) -{ - enumerator_t *enumerator; - qm_data_t *qm, *found = NULL; - - enumerator = this->qms->create_enumerator(this->qms); - while (enumerator->enumerate(enumerator, &qm)) - { - if (qm->mid == mid) - { /* state gets moved to the front of the list */ - this->qms->remove_at(this->qms, enumerator); - found = qm; - break; - } - } - enumerator->destroy(enumerator); - if (!found) - { - INIT(found, - .mid = mid, - ); - } - this->qms->insert_first(this->qms, found); - /* remove least recently used state if maximum reached */ - if (this->qms->get_count(this->qms) > this->max_exchanges && - this->qms->remove_last(this->qms, (void**)&qm) == SUCCESS) - { - qm_data_destroy(qm); - } - return found; -} - METHOD(keymat_v1_t, get_hash_phase2, bool, private_keymat_v1_t *this, message_t *message, chunk_t *hash) { uint32_t mid, mid_n; - chunk_t data = chunk_empty; + chunk_t data = chunk_empty, *n_i, *n_r; bool add_message = TRUE; char *name = "Hash"; @@ -908,34 +796,34 @@ METHOD(keymat_v1_t, get_hash_phase2, bool, { case QUICK_MODE: { - qm_data_t *qm = lookup_quick_mode(this, mid); - if (!qm->n_i.ptr) + this->iv_manager->lookup_quick_mode(this->iv_manager, mid, &n_i, + &n_r); + if (!n_i->ptr) { /* Hash(1) = prf(SKEYID_a, M-ID | Message after HASH payload) */ name = "Hash(1)"; - if (!get_nonce(message, &qm->n_i)) + if (!get_nonce(message, n_i)) { return FALSE; } data = chunk_from_thing(mid_n); } - else if (!qm->n_r.ptr) + else if (!n_r->ptr) { /* Hash(2) = prf(SKEYID_a, M-ID | Ni_b | Message after HASH) */ name = "Hash(2)"; - if (!get_nonce(message, &qm->n_r)) + if (!get_nonce(message, n_r)) { return FALSE; } - data = chunk_cata("cc", chunk_from_thing(mid_n), qm->n_i); + data = chunk_cata("cc", chunk_from_thing(mid_n), *n_i); } else { /* Hash(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */ name = "Hash(3)"; data = chunk_cata("cccc", octet_0, chunk_from_thing(mid_n), - qm->n_i, qm->n_r); + *n_i, *n_r); add_message = FALSE; /* we don't need the state anymore */ - this->qms->remove(this->qms, qm, NULL); - qm_data_destroy(qm); + this->iv_manager->remove_quick_mode(this->iv_manager, mid); } break; } @@ -977,119 +865,22 @@ METHOD(keymat_v1_t, get_hash_phase2, bool, return TRUE; } -/** - * Generate an IV - */ -static bool generate_iv(private_keymat_v1_t *this, iv_data_t *iv) -{ - if (iv->mid == 0 || iv->iv.ptr) - { /* use last block of previous encrypted message */ - chunk_free(&iv->iv); - iv->iv = iv->last_block; - iv->last_block = chunk_empty; - } - else - { - /* initial phase 2 IV = hash(last_phase1_block | mid) */ - uint32_t net;; - chunk_t data; - - net = htonl(iv->mid); - data = chunk_cata("cc", this->phase1_iv.iv, chunk_from_thing(net)); - if (!this->hasher->allocate_hash(this->hasher, data, &iv->iv)) - { - return FALSE; - } - if (iv->iv.len > this->aead->get_block_size(this->aead)) - { - iv->iv.len = this->aead->get_block_size(this->aead); - } - } - DBG4(DBG_IKE, "next IV for MID %u %B", iv->mid, &iv->iv); - return TRUE; -} - -/** - * Try to find an IV for the given message ID, if not found, generate it. - */ -static iv_data_t *lookup_iv(private_keymat_v1_t *this, uint32_t mid) -{ - enumerator_t *enumerator; - iv_data_t *iv, *found = NULL; - - if (mid == 0) - { - return &this->phase1_iv; - } - - enumerator = this->ivs->create_enumerator(this->ivs); - while (enumerator->enumerate(enumerator, &iv)) - { - if (iv->mid == mid) - { /* IV gets moved to the front of the list */ - this->ivs->remove_at(this->ivs, enumerator); - found = iv; - break; - } - } - enumerator->destroy(enumerator); - if (!found) - { - INIT(found, - .mid = mid, - ); - if (!generate_iv(this, found)) - { - iv_data_destroy(found); - return NULL; - } - } - this->ivs->insert_first(this->ivs, found); - /* remove least recently used IV if maximum reached */ - if (this->ivs->get_count(this->ivs) > this->max_exchanges && - this->ivs->remove_last(this->ivs, (void**)&iv) == SUCCESS) - { - iv_data_destroy(iv); - } - return found; -} - METHOD(keymat_v1_t, get_iv, bool, private_keymat_v1_t *this, uint32_t mid, chunk_t *out) { - iv_data_t *iv; - - iv = lookup_iv(this, mid); - if (iv) - { - *out = iv->iv; - return TRUE; - } - return FALSE; + return this->iv_manager->get_iv(this->iv_manager, mid, out); } METHOD(keymat_v1_t, update_iv, bool, private_keymat_v1_t *this, uint32_t mid, chunk_t last_block) { - iv_data_t *iv = lookup_iv(this, mid); - if (iv) - { /* update last block */ - chunk_free(&iv->last_block); - iv->last_block = chunk_clone(last_block); - return TRUE; - } - return FALSE; + return this->iv_manager->update_iv(this->iv_manager, mid, last_block); } METHOD(keymat_v1_t, confirm_iv, bool, private_keymat_v1_t *this, uint32_t mid) { - iv_data_t *iv = lookup_iv(this, mid); - if (iv) - { - return generate_iv(this, iv); - } - return FALSE; + return this->iv_manager->confirm_iv(this->iv_manager, mid); } METHOD(keymat_t, get_version, ike_version_t, @@ -1125,10 +916,7 @@ METHOD(keymat_t, destroy, void, DESTROY_IF(this->hasher); chunk_clear(&this->skeyid_d); chunk_clear(&this->skeyid_a); - chunk_free(&this->phase1_iv.iv); - chunk_free(&this->phase1_iv.last_block); - this->ivs->destroy_function(this->ivs, (void*)iv_data_destroy); - this->qms->destroy_function(this->qms, (void*)qm_data_destroy); + this->iv_manager->destroy(this->iv_manager); free(this); } @@ -1158,12 +946,8 @@ keymat_v1_t *keymat_v1_create(bool initiator) .update_iv = _update_iv, .confirm_iv = _confirm_iv, }, - .ivs = linked_list_create(), - .qms = linked_list_create(), .initiator = initiator, - .max_exchanges = lib->settings->get_int(lib->settings, - "%s.max_ikev1_exchanges", MAX_EXCHANGES_DEFAULT, lib->ns), + .iv_manager = iv_manager_create(0), ); - return &this->public; } diff --git a/src/libcharon/sa/ikev1/keymat_v1.h b/src/libcharon/sa/ikev1/keymat_v1.h index b5b959c37..ada5bdb04 100644 --- a/src/libcharon/sa/ikev1/keymat_v1.h +++ b/src/libcharon/sa/ikev1/keymat_v1.h @@ -121,39 +121,17 @@ struct keymat_v1_t { bool (*get_hash_phase2)(keymat_v1_t *this, message_t *message, chunk_t *hash); /** - * Returns the IV for a message with the given message ID. - * - * The return chunk contains internal data and is valid until the next - * get_iv/udpate_iv/confirm_iv call. - * - * @param mid message ID - * @param iv chunk receiving IV, internal data - * @return TRUE if IV allocated successfully + * @see iv_manager_t.get_iv */ bool (*get_iv)(keymat_v1_t *this, uint32_t mid, chunk_t *iv); /** - * Updates the IV for the next message with the given message ID. - * - * A call of confirm_iv() is required in order to actually make the IV - * available. This is needed for the inbound case where we store the last - * block of the encrypted message but want to update the IV only after - * verification of the decrypted message. - * - * @param mid message ID - * @param last_block last block of encrypted message (gets cloned) - * @return TRUE if IV updated successfully + * @see iv_manager_t.update_iv */ bool (*update_iv)(keymat_v1_t *this, uint32_t mid, chunk_t last_block); /** - * Confirms the updated IV for the given message ID. - * - * To actually make the new IV available via get_iv this method has to - * be called after update_iv. - * - * @param mid message ID - * @return TRUE if IV confirmed successfully + * @see iv_manager_t.confirm_iv */ bool (*confirm_iv)(keymat_v1_t *this, uint32_t mid); };