aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/encoding
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2014-06-16 15:46:33 +0200
committerTobias Brunner <tobias@strongswan.org>2014-10-10 09:32:41 +0200
commitc0f4936a23578625e7be7032d2a66db5d6a6c1a3 (patch)
treed485e09c82602cd0b7e4aa13223fce2bff773ec3 /src/libcharon/encoding
parente8ffb256b373de0094903fd227ccc8c5520caf9c (diff)
downloadstrongswan-c0f4936a23578625e7be7032d2a66db5d6a6c1a3.tar.bz2
strongswan-c0f4936a23578625e7be7032d2a66db5d6a6c1a3.tar.xz
message: Fragment and reassemble IKEv2 messages
Diffstat (limited to 'src/libcharon/encoding')
-rw-r--r--src/libcharon/encoding/message.c494
-rw-r--r--src/libcharon/encoding/message.h5
2 files changed, 366 insertions, 133 deletions
diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c
index 262f1050b..43f74238f 100644
--- a/src/libcharon/encoding/message.c
+++ b/src/libcharon/encoding/message.c
@@ -33,6 +33,7 @@
#include <encoding/payloads/payload.h>
#include <encoding/payloads/hash_payload.h>
#include <encoding/payloads/encrypted_payload.h>
+#include <encoding/payloads/encrypted_fragment_payload.h>
#include <encoding/payloads/unknown_payload.h>
#include <encoding/payloads/cp_payload.h>
#include <encoding/payloads/fragment_payload.h>
@@ -819,8 +820,9 @@ typedef struct {
* For IKEv1 the number of the last fragment (in case we receive them out
* of order), since the first one starts with 1 this defines the number of
* fragments we expect.
+ * For IKEv2 we store the total number of fragment we received last.
*/
- u_int8_t last;
+ u_int16_t last;
/**
* Length of all currently received fragments.
@@ -908,7 +910,7 @@ struct private_message_t {
/**
* Array of generated fragments (if any), as packet_t*.
- * If defragmenting (frag != NULL) this contains fragment_t*
+ * If defragmenting (i.e. frag != NULL) this contains fragment_t*
*/
array_t *fragments;
@@ -952,11 +954,10 @@ static void fragment_destroy(fragment_t *this)
free(this);
}
-static void reset_defrag(private_message_t *this, u_int16_t id)
+static void reset_defrag(private_message_t *this)
{
array_destroy_function(this->fragments, (void*)fragment_destroy, NULL);
this->fragments = NULL;
- this->message_id = id;
this->frag->last = 0;
this->frag->len = 0;
}
@@ -1822,35 +1823,64 @@ static message_t *clone_message(private_message_t *this)
message->set_source(message, src->clone(src));
message->set_destination(message, dst->clone(dst));
message->set_exchange_type(message, this->exchange_type);
+ memcpy(((private_message_t*)message)->reserved, this->reserved,
+ sizeof(this->reserved));
return message;
}
/**
* Create a single fragment with the given data
*/
-static message_t *create_fragment(private_message_t *this, u_int8_t num,
- bool last, chunk_t data)
+static message_t *create_fragment(private_message_t *this, payload_type_t next,
+ u_int16_t num, u_int16_t count, chunk_t data)
{
- fragment_payload_t *fragment;
+ enumerator_t *enumerator;
+ payload_t *fragment, *payload;
message_t *message;
peer_cfg_t *peer_cfg;
ike_sa_t *ike_sa;
- fragment = fragment_payload_create_from_data(num, last, data);
message = clone_message(this);
- /* other implementations seem to just use 0 as message ID, so here we go */
- message->set_message_id(message, 0);
- /* always use the initial message type for fragments, even for quick mode
- * or transaction messages. */
- ike_sa = charon->bus->get_sa(charon->bus);
- if (ike_sa && (peer_cfg = ike_sa->get_peer_cfg(ike_sa)) &&
- peer_cfg->use_aggressive(peer_cfg))
- {
- message->set_exchange_type(message, AGGRESSIVE);
+ if (this->major_version == IKEV1_MAJOR_VERSION)
+ {
+ /* other implementations seem to just use 0 as message ID, so here we go */
+ message->set_message_id(message, 0);
+ /* always use the initial message type for fragments, even for quick mode
+ * or transaction messages. */
+ ike_sa = charon->bus->get_sa(charon->bus);
+ if (ike_sa && (peer_cfg = ike_sa->get_peer_cfg(ike_sa)) &&
+ peer_cfg->use_aggressive(peer_cfg))
+ {
+ message->set_exchange_type(message, AGGRESSIVE);
+ }
+ else
+ {
+ message->set_exchange_type(message, ID_PROT);
+ }
+ fragment = (payload_t*)fragment_payload_create_from_data(
+ num, num == count, data);
}
else
{
- message->set_exchange_type(message, ID_PROT);
+ fragment = (payload_t*)encrypted_fragment_payload_create_from_data(
+ num, count, data);
+ if (num == 1)
+ {
+ /* only in the first fragment is this set to the type of the first
+ * payload in the encrypted payload */
+ fragment->set_next_type(fragment, next);
+ /* move unencrypted payloads to the first fragment */
+ enumerator = this->payloads->create_enumerator(this->payloads);
+ while (enumerator->enumerate(enumerator, &payload))
+ {
+ if (payload->get_type(payload) != PLV2_ENCRYPTED)
+ {
+ this->payloads->remove_at(this->payloads, enumerator);
+ message->add_payload(message, payload);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
}
message->add_payload(message, (payload_t*)fragment);
return message;
@@ -1869,29 +1899,18 @@ METHOD(message_t, fragment, status_t,
private_message_t *this, keymat_t *keymat, size_t frag_len,
enumerator_t **fragments)
{
+ encrypted_payload_t *encrypted = NULL;
+ generator_t *generator = NULL;
message_t *fragment;
packet_t *packet;
- u_int8_t num, count;
+ payload_type_t next = PL_NONE;
+ u_int16_t num, count;
host_t *src, *dst;
chunk_t data;
status_t status;
+ u_int32_t *lenpos;
size_t len;
- if (this->major_version == IKEV2_MAJOR_VERSION)
- {
- return INVALID_STATE;
- }
- clear_fragments(this);
-
- if (!is_encoded(this))
- {
- status = generate(this, keymat, NULL);
- if (status != SUCCESS)
- {
- return status;
- }
- }
-
src = this->packet->get_source(this->packet);
dst = this->packet->get_destination(this->packet);
if (!frag_len)
@@ -1901,31 +1920,112 @@ METHOD(message_t, fragment, status_t,
/* frag_len is the complete IP datagram length, account for overhead (we
* assume no IP options/extension headers are used) */
frag_len -= (src->get_family(src) == AF_INET) ? 20 : 40;
- /* 8 (UDP header) + 28 (IKE header) */
- frag_len -= 36;
+ /* 8 (UDP header) */
+ frag_len -= 8;
if (dst->get_port(dst) != IKEV2_UDP_PORT &&
src->get_port(src) != IKEV2_UDP_PORT)
{ /* reduce length due to non-ESP marker */
frag_len -= 4;
}
- data = this->packet->get_data(this->packet);
- if (data.len <= frag_len)
+ if (is_encoded(this))
{
+ if (this->major_version == IKEV2_MAJOR_VERSION)
+ {
+ encrypted = (encrypted_payload_t*)get_payload(this, PLV2_ENCRYPTED);
+ }
+ data = this->packet->get_data(this->packet);
+ len = data.len;
+ }
+ else
+ {
+ status = generate_message(this, keymat, &generator, &encrypted);
+ if (status != SUCCESS)
+ {
+ DESTROY_IF(generator);
+ return status;
+ }
+ data = generator->get_chunk(generator, &lenpos);
+ len = data.len + (encrypted ? encrypted->get_length(encrypted) : 0);
+ }
+
+ /* check if we actually need to fragment the message and if we have an
+ * encrypted payload for IKEv2 */
+ if (len <= frag_len ||
+ (this->major_version == IKEV2_MAJOR_VERSION && !encrypted))
+ {
+ if (generator)
+ {
+ status = finalize_message(this, keymat, generator, encrypted);
+ if (status != SUCCESS)
+ {
+ return status;
+ }
+ }
*fragments = enumerator_create_single(this->packet, NULL);
return SUCCESS;
}
- /* overhead for the fragmentation payload header */
- frag_len -= 8;
+
+ /* frag_len denoted the maximum IKE message size so far, later on it will
+ * denote the maximum content size of a fragment payload, therefore,
+ * account for IKE header */
+ frag_len -= 28;
+
+ if (this->major_version == IKEV1_MAJOR_VERSION)
+ {
+ if (generator)
+ {
+ status = finalize_message(this, keymat, generator, encrypted);
+ if (status != SUCCESS)
+ {
+ return status;
+ }
+ data = this->packet->get_data(this->packet);
+ generator = NULL;
+ }
+ /* overhead for the fragmentation payload header */
+ frag_len -= 8;
+ }
+ else
+ {
+ aead_t *aead;
+
+ if (generator)
+ {
+ generator->destroy(generator);
+ generator = generator_create();
+ }
+ else
+ { /* do not log again if it was generated previously */
+ generator = generator_create_no_dbg();
+ }
+ next = encrypted->payload_interface.get_next_type((payload_t*)encrypted);
+ encrypted->generate_payloads(encrypted, generator);
+ data = generator->get_chunk(generator, &lenpos);
+ if (!is_encoded(this))
+ {
+ encrypted->destroy(encrypted);
+ }
+ aead = keymat->get_aead(keymat, FALSE);
+ /* overhead for the encrypted fragment payload */
+ frag_len -= aead->get_iv_size(aead) + aead->get_icv_size(aead);
+ frag_len -= 8 /* header */;
+ /* padding and padding length */
+ frag_len = round_down(frag_len, aead->get_block_size(aead)) - 1;
+ /* TODO-FRAG: if there are unencrypted payloads, should we account for
+ * their length in the first fragment? we still would have to add
+ * an encrypted fragment payload (albeit empty), even so we couldn't
+ * prevent IP fragmentation in every case */
+ }
count = data.len / frag_len + (data.len % frag_len ? 1 : 0);
this->fragments = array_create(0, count);
- DBG2(DBG_ENC, "splitting IKE message with length of %zu bytes into "
- "%hhu fragments", data.len, count);
+ DBG1(DBG_ENC, "splitting IKE message with length of %zu bytes into "
+ "%hu fragments", len, count);
for (num = 1; num <= count; num++)
{
len = min(data.len, frag_len);
- fragment = create_fragment(this, num, num == count,
+ fragment = create_fragment(this, next, num, count,
chunk_create(data.ptr, len));
status = fragment->generate(fragment, keymat, &packet);
fragment->destroy(fragment);
@@ -1933,12 +2033,14 @@ METHOD(message_t, fragment, status_t,
{
DBG1(DBG_ENC, "failed to generate IKE fragment");
clear_fragments(this);
+ DESTROY_IF(generator);
return FAILED;
}
array_insert(this->fragments, ARRAY_TAIL, packet);
data = chunk_skip(data, len);
}
*fragments = array_create_enumerator(this->fragments);
+ DESTROY_IF(generator);
return SUCCESS;
}
@@ -1970,6 +2072,10 @@ METHOD(message_t, parse_header, status_t,
DBG2(DBG_ENC, "parsing header of message");
+ if (!this->parser)
+ { /* reassembled IKEv2 message, header is inherited from fragments */
+ return SUCCESS;
+ }
this->parser->reset_context(this->parser);
status = this->parser->parse_payload(this->parser, PL_HEADER,
(payload_t**)&ike_header);
@@ -2149,43 +2255,52 @@ static status_t decrypt_and_extract(private_message_t *this, keymat_t *keymat,
DBG1(DBG_ENC, "found encrypted payload, but no transform set");
return INVALID_ARG;
}
- bs = aead->get_block_size(aead);
- encryption->set_transform(encryption, aead);
- chunk = this->packet->get_data(this->packet);
- if (chunk.len < encryption->get_length(encryption) ||
- chunk.len < bs)
+ if (!this->parser)
{
- DBG1(DBG_ENC, "invalid payload length");
- return VERIFY_ERROR;
+ /* reassembled IKEv2 messages are already decrypted, we still call
+ * decrypt() to parse the contained payloads */
+ status = encryption->decrypt(encryption, chunk_empty);
}
- if (keymat->get_version(keymat) == IKEV1)
- { /* instead of associated data we provide the IV, we also update
- * the IV with the last encrypted block */
- keymat_v1_t *keymat_v1 = (keymat_v1_t*)keymat;
- chunk_t iv;
-
- if (keymat_v1->get_iv(keymat_v1, this->message_id, &iv))
+ else
+ {
+ bs = aead->get_block_size(aead);
+ encryption->set_transform(encryption, aead);
+ chunk = this->packet->get_data(this->packet);
+ if (chunk.len < encryption->get_length(encryption) ||
+ chunk.len < bs)
{
- status = encryption->decrypt(encryption, iv);
- if (status == SUCCESS)
+ DBG1(DBG_ENC, "invalid payload length");
+ return VERIFY_ERROR;
+ }
+ if (keymat->get_version(keymat) == IKEV1)
+ { /* instead of associated data we provide the IV, we also update
+ * the IV with the last encrypted block */
+ keymat_v1_t *keymat_v1 = (keymat_v1_t*)keymat;
+ chunk_t iv;
+
+ if (keymat_v1->get_iv(keymat_v1, this->message_id, &iv))
{
- if (!keymat_v1->update_iv(keymat_v1, this->message_id,
- chunk_create(chunk.ptr + chunk.len - bs, bs)))
+ status = encryption->decrypt(encryption, iv);
+ if (status == SUCCESS)
{
- status = FAILED;
+ if (!keymat_v1->update_iv(keymat_v1, this->message_id,
+ chunk_create(chunk.ptr + chunk.len - bs, bs)))
+ {
+ status = FAILED;
+ }
}
}
+ else
+ {
+ status = FAILED;
+ }
}
else
{
- status = FAILED;
+ chunk.len -= encryption->get_length(encryption);
+ status = encryption->decrypt(encryption, chunk);
}
}
- else
- {
- chunk.len -= encryption->get_length(encryption);
- status = encryption->decrypt(encryption, chunk);
- }
if (status != SUCCESS)
{
return status;
@@ -2432,10 +2547,15 @@ METHOD(message_t, parse_body, status_t,
return NOT_SUPPORTED;
}
- status = parse_payloads(this);
- if (status != SUCCESS)
- { /* error is already logged */
- return status;
+ /* reassembled IKEv2 messages are already parsed (except for the payloads
+ * contained in the encrypted payload, which are handled below) */
+ if (this->parser)
+ {
+ status = parse_payloads(this);
+ if (status != SUCCESS)
+ { /* error is already logged */
+ return status;
+ }
}
status = decrypt_payloads(this, keymat);
@@ -2500,46 +2620,22 @@ METHOD(message_t, parse_body, status_t,
return SUCCESS;
}
-METHOD(message_t, add_fragment, status_t,
- private_message_t *this, message_t *message)
+/**
+ * Store the fragment data for the fragment with the given fragment number.
+ */
+static status_t add_fragment(private_message_t *this, u_int16_t num,
+ chunk_t data)
{
- fragment_payload_t *payload;
fragment_t *fragment;
- bio_writer_t *writer;
- host_t *src, *dst;
- chunk_t data;
- u_int8_t num;
int i, insert_at = -1;
- if (!this->frag)
- {
- return INVALID_STATE;
- }
- payload = (fragment_payload_t*)message->get_payload(message, PLV1_FRAGMENT);
- if (!payload)
- {
- return INVALID_ARG;
- }
- if (!this->fragments || this->message_id != payload->get_id(payload))
- {
- reset_defrag(this, payload->get_id(payload));
- /* we don't know the total number of fragments */
- this->fragments = array_create(0, 0);
- }
-
- num = payload->get_number(payload);
- if (!this->frag->last && payload->is_last(payload))
- {
- this->frag->last = num;
- }
-
for (i = 0; i < array_count(this->fragments); i++)
{
array_get(this->fragments, i, &fragment);
if (fragment->num == num)
{
/* ignore a duplicate fragment */
- DBG1(DBG_ENC, "received duplicate fragment #%hhu", num);
+ DBG1(DBG_ENC, "received duplicate fragment #%hu", num);
return NEED_MORE;
}
if (fragment->num > num)
@@ -2548,12 +2644,11 @@ METHOD(message_t, add_fragment, status_t,
break;
}
}
- data = payload->get_data(payload);
this->frag->len += data.len;
if (this->frag->len > this->frag->max_packet)
{
DBG1(DBG_ENC, "fragmented IKE message is too large");
- reset_defrag(this, 0);
+ reset_defrag(this);
return FAILED;
}
INIT(fragment,
@@ -2561,35 +2656,93 @@ METHOD(message_t, add_fragment, status_t,
.data = chunk_clone(data),
);
array_insert(this->fragments, insert_at, fragment);
+ return SUCCESS;
+}
- if (this->frag->last < array_count(this->fragments))
- {
- /* there are some fragments missing */
- DBG1(DBG_ENC, "received fragment #%hhu, waiting for complete IKE "
- "message", num);
- return NEED_MORE;
- }
+/**
+ * Merge the cached fragment data and resets the defragmentation state.
+ * Also updates the IP addresses to those of the last received fragment.
+ */
+static chunk_t merge_fragments(private_message_t *this, message_t *last)
+{
+ fragment_t *fragment;
+ bio_writer_t *writer;
+ host_t *src, *dst;
+ chunk_t data;
+ int i;
writer = bio_writer_create(this->frag->len);
- DBG1(DBG_ENC, "received fragment #%hhu, reassembling fragmented IKE "
- "message", num);
-
for (i = 0; i < array_count(this->fragments); i++)
{
array_get(this->fragments, i, &fragment);
writer->write_data(writer, fragment->data);
}
- src = message->get_source(message);
- dst = message->get_destination(message);
+ data = writer->extract_buf(writer);
+ writer->destroy(writer);
+
+ /* set addresses to those of the last fragment we received */
+ src = last->get_source(last);
+ dst = last->get_destination(last);
this->packet->set_source(this->packet, src->clone(src));
this->packet->set_destination(this->packet, dst->clone(dst));
- this->packet->set_data(this->packet, writer->extract_buf(writer));
- writer->destroy(writer);
- this->parser->destroy(this->parser);
- this->parser = parser_create(this->packet->get_data(this->packet));
- reset_defrag(this, 0);
+
+ reset_defrag(this);
free(this->frag);
this->frag = NULL;
+ return data;
+}
+
+METHOD(message_t, add_fragment_v1, status_t,
+ private_message_t *this, message_t *message)
+{
+ fragment_payload_t *payload;
+ chunk_t data;
+ u_int8_t num;
+ status_t status;
+
+ if (!this->frag)
+ {
+ return INVALID_STATE;
+ }
+ payload = (fragment_payload_t*)message->get_payload(message, PLV1_FRAGMENT);
+ if (!payload)
+ {
+ return INVALID_ARG;
+ }
+ if (!this->fragments || this->message_id != payload->get_id(payload))
+ {
+ reset_defrag(this);
+ this->message_id = payload->get_id(payload);
+ /* we don't know the total number of fragments, assume something */
+ this->fragments = array_create(0, 4);
+ }
+
+ num = payload->get_number(payload);
+ data = payload->get_data(payload);
+ if (!this->frag->last && payload->is_last(payload))
+ {
+ this->frag->last = num;
+ }
+ status = add_fragment(this, num, data);
+ if (status != SUCCESS)
+ {
+ return status;
+ }
+
+ if (array_count(this->fragments) != this->frag->last)
+ {
+ /* there are some fragments missing */
+ DBG1(DBG_ENC, "received fragment #%hhu, waiting for complete IKE "
+ "message", num);
+ return NEED_MORE;
+ }
+
+ DBG1(DBG_ENC, "received fragment #%hhu, reassembling fragmented IKE "
+ "message", num);
+
+ data = merge_fragments(this, message);
+ this->packet->set_data(this->packet, data);
+ this->parser = parser_create(data);
if (parse_header(this) != SUCCESS)
{
@@ -2599,16 +2752,91 @@ METHOD(message_t, add_fragment, status_t,
return SUCCESS;
}
+METHOD(message_t, add_fragment_v2, status_t,
+ private_message_t *this, message_t *message)
+{
+ encrypted_fragment_payload_t *encrypted_fragment;
+ encrypted_payload_t *encrypted;
+ payload_t *payload;
+ enumerator_t *enumerator;
+ chunk_t data;
+ u_int16_t total, num;
+ status_t status;
+
+ if (!this->frag)
+ {
+ return INVALID_STATE;
+ }
+ payload = message->get_payload(message, PLV2_FRAGMENT);
+ if (!payload || this->message_id != message->get_message_id(message))
+ {
+ return INVALID_ARG;
+ }
+ encrypted_fragment = (encrypted_fragment_payload_t*)payload;
+ total = encrypted_fragment->get_total_fragments(encrypted_fragment);
+
+ if (!this->fragments || total > this->frag->last)
+ {
+ reset_defrag(this);
+ this->frag->last = total;
+ this->fragments = array_create(0, total);
+ }
+ num = encrypted_fragment->get_fragment_number(encrypted_fragment);
+ data = encrypted_fragment->get_content(encrypted_fragment);
+ status = add_fragment(this, num, data);
+ if (status != SUCCESS)
+ {
+ return status;
+ }
+
+ if (num == 1)
+ {
+ /* the first fragment denotes the payload type of the first payload in
+ * the original encrypted payload, cache that */
+ this->first_payload = payload->get_next_type(payload);
+ /* move all unencrypted payloads contained in the first fragment */
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
+ {
+ if (payload->get_type(payload) != PLV2_FRAGMENT)
+ {
+ message->remove_payload_at(message, enumerator);
+ this->payloads->insert_last(this->payloads, payload);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ if (array_count(this->fragments) != total)
+ {
+ /* there are some fragments missing */
+ DBG1(DBG_ENC, "received fragment #%hu of %hu, waiting for complete IKE "
+ "message", num, total);
+ return NEED_MORE;
+ }
+
+ DBG1(DBG_ENC, "received fragment #%hu of %hu, reassembling fragmented IKE "
+ "message", num, total);
+
+ data = merge_fragments(this, message);
+ encrypted = encrypted_payload_create_from_plain(this->first_payload, data);
+ this->payloads->insert_last(this->payloads, encrypted);
+ /* update next payload type (could be an unencrypted payload) */
+ this->payloads->get_first(this->payloads, (void**)&payload);
+ this->first_payload = payload->get_type(payload);
+ return SUCCESS;
+}
+
METHOD(message_t, destroy, void,
private_message_t *this)
{
DESTROY_IF(this->ike_sa_id);
+ DESTROY_IF(this->parser);
this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy));
this->packet->destroy(this->packet);
- this->parser->destroy(this->parser);
if (this->frag)
{
- reset_defrag(this, 0);
+ reset_defrag(this);
free(this->frag);
}
else
@@ -2652,7 +2880,7 @@ message_t *message_create_from_packet(packet_t *packet)
.is_encoded = _is_encoded,
.is_fragmented = _is_fragmented,
.fragment = _fragment,
- .add_fragment = _add_fragment,
+ .add_fragment = _add_fragment_v2,
.set_source = _set_source,
.get_source = _get_source,
.set_destination = _set_destination,
@@ -2699,13 +2927,23 @@ message_t *message_create_defrag(message_t *fragment)
{
private_message_t *this;
- if (!fragment->get_payload(fragment, PLV1_FRAGMENT))
+ if (!fragment->get_payload(fragment, PLV1_FRAGMENT) &&
+ !fragment->get_payload(fragment, PLV2_FRAGMENT))
{
return NULL;
}
- this = (private_message_t*)message_create(
- fragment->get_major_version(fragment),
- fragment->get_minor_version(fragment));
+ this = (private_message_t*)clone_message((private_message_t*)fragment);
+ /* we don't need a parser for IKEv2, the one for IKEv1 is created after
+ * reassembling the original message */
+ this->parser->destroy(this->parser);
+ this->parser = NULL;
+ if (fragment->get_major_version(fragment) == IKEV1_MAJOR_VERSION)
+ {
+ /* we store the fragment ID in the message ID field, which should be
+ * zero for fragments, but make sure */
+ this->message_id = 0;
+ this->public.add_fragment = _add_fragment_v1;
+ }
INIT(this->frag,
.max_packet = lib->settings->get_int(lib->settings,
"%s.max_packet", MAX_PACKET, lib->ns),
diff --git a/src/libcharon/encoding/message.h b/src/libcharon/encoding/message.h
index 69a8e93b1..a03aa8e96 100644
--- a/src/libcharon/encoding/message.h
+++ b/src/libcharon/encoding/message.h
@@ -268,8 +268,6 @@ struct message_t {
* Generates the message split into fragments of the given size (total IP
* datagram length).
*
- * @note Only supported for IKEv1 at the moment.
- *
* @param keymat keymat to encrypt/sign message(s)
* @param frag_len fragment length (maximum total IP datagram length), 0
* for default value depending on address family
@@ -277,7 +275,6 @@ struct message_t {
* which are owned by the enumerator
* @return
* - SUCCESS if message could be fragmented
- * - INVALID_STATE if message is IKEv2
* - FAILED if fragmentation failed
* - and the possible return values of generate()
*/
@@ -303,8 +300,6 @@ struct message_t {
* Once the message is completed it should be processed like any other
* inbound message.
*
- * @note Only supported for IKEv1 at the moment.
- *
* @param fragment fragment to add
* @return
* - SUCCESS if message was reassembled