diff options
Diffstat (limited to 'src/vnet/ipsec/ikev2_payload.c')
-rw-r--r-- | src/vnet/ipsec/ikev2_payload.c | 550 |
1 files changed, 0 insertions, 550 deletions
diff --git a/src/vnet/ipsec/ikev2_payload.c b/src/vnet/ipsec/ikev2_payload.c deleted file mode 100644 index 3aae6d3a1f4..00000000000 --- a/src/vnet/ipsec/ikev2_payload.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (c) 2015 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <ctype.h> - -#include <vnet/vnet.h> -#include <vnet/api_errno.h> -#include <vnet/ip/ip.h> -#include <vnet/interface.h> - -#include <vnet/ipsec/ipsec.h> -#include <vnet/ipsec/ikev2.h> -#include <vnet/ipsec/ikev2_priv.h> - -/* *INDENT-OFF* */ -typedef CLIB_PACKED (struct - { - u8 nextpayload; - u8 flags; - u16 length; - u8 protocol_id; - u8 spi_size; - u16 msg_type; - u8 payload[0];}) ike_notify_payload_header_t; -/* *INDENT-ON* */ - -/* *INDENT-OFF* */ -typedef CLIB_PACKED (struct - { - u8 ts_type; - u8 protocol_id; - u16 selector_len; - u16 start_port; - u16 end_port; - ip4_address_t start_addr; - ip4_address_t end_addr;}) ikev2_ts_payload_entry_t; -/* *INDENT-OFF* */ - -/* *INDENT-OFF* */ -typedef CLIB_PACKED (struct - { - u8 nextpayload; - u8 flags; - u16 length; - u8 num_ts; - u8 reserved[3]; - ikev2_ts_payload_entry_t ts[0];}) - ike_ts_payload_header_t; -/* *INDENT-OFF* */ - -/* *INDENT-OFF* */ -typedef CLIB_PACKED (struct { - u8 last_or_more; - u8 reserved; - u16 proposal_len; - u8 proposal_num; - u8 protocol_id; - u8 spi_size; - u8 num_transforms; u32 spi[0]; -}) ike_sa_proposal_data_t; -/* *INDENT-OFF* */ - -/* *INDENT-OFF* */ -typedef CLIB_PACKED (struct { - u8 last_or_more; - u8 reserved; - u16 transform_len; - u8 transform_type; - u8 reserved2; - u16 transform_id; - u8 attributes[0]; -}) ike_sa_transform_data_t; -/* *INDENT-OFF* */ - -/* *INDENT-OFF* */ -typedef CLIB_PACKED (struct { - u8 nextpayload; - u8 flags; - u16 length; - u8 protocol_id; - u8 spi_size; - u16 num_of_spi; - u32 spi[0]; -}) ike_delete_payload_header_t; -/* *INDENT-OFF* */ - -static ike_payload_header_t * -ikev2_payload_add_hdr (ikev2_payload_chain_t * c, u8 payload_type, int len) -{ - ike_payload_header_t *hdr = - (ike_payload_header_t *) & c->data[c->last_hdr_off]; - u8 *tmp; - - if (c->data) - hdr->nextpayload = payload_type; - else - c->first_payload_type = payload_type; - - c->last_hdr_off = vec_len (c->data); - vec_add2 (c->data, tmp, len); - hdr = (ike_payload_header_t *) tmp; - clib_memset (hdr, 0, len); - - hdr->length = clib_host_to_net_u16 (len); - - return hdr; -} - -static void -ikev2_payload_add_data (ikev2_payload_chain_t * c, u8 * data) -{ - u16 len; - ike_payload_header_t *hdr; - - vec_append (c->data, data); - hdr = (ike_payload_header_t *) & c->data[c->last_hdr_off]; - len = clib_net_to_host_u16 (hdr->length); - hdr->length = clib_host_to_net_u16 (len + vec_len (data)); -} - -void -ikev2_payload_add_notify (ikev2_payload_chain_t * c, u16 msg_type, u8 * data) -{ - ikev2_payload_add_notify_2(c, msg_type, data, 0); -} - -void -ikev2_payload_add_notify_2 (ikev2_payload_chain_t * c, u16 msg_type, - u8 * data, ikev2_notify_t * notify) -{ - ike_notify_payload_header_t *n; - - n = - (ike_notify_payload_header_t *) ikev2_payload_add_hdr (c, - IKEV2_PAYLOAD_NOTIFY, - sizeof (*n)); - n->msg_type = clib_host_to_net_u16 (msg_type); - if (notify) - { - n->protocol_id = notify->protocol_id; - if (notify->spi) - { - n->spi_size = 4; - } - } - ikev2_payload_add_data (c, data); -} - -void -ikev2_payload_add_sa (ikev2_payload_chain_t * c, - ikev2_sa_proposal_t * proposals) -{ - ike_payload_header_t *ph; - ike_sa_proposal_data_t *prop; - ike_sa_transform_data_t *tr; - ikev2_sa_proposal_t *p; - ikev2_sa_transform_t *t; - - u8 *tmp; - u8 *pr_data = 0; - u8 *tr_data = 0; - - ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_SA, sizeof (*ph)); - - vec_foreach (p, proposals) - { - int spi_size = (p->protocol_id == IKEV2_PROTOCOL_ESP) ? 4 : 0; - pr_data = vec_new (u8, sizeof (ike_sa_proposal_data_t) + spi_size); - prop = (ike_sa_proposal_data_t *) pr_data; - prop->last_or_more = proposals - p + 1 < vec_len (proposals) ? 2 : 0; - prop->protocol_id = p->protocol_id; - prop->proposal_num = p->proposal_num; - prop->spi_size = spi_size; - prop->num_transforms = vec_len (p->transforms); - - if (spi_size) - prop->spi[0] = clib_host_to_net_u32 (p->spi); - - DBG_PLD ("proposal num %u protocol_id %u last_or_more %u spi_size %u%s%U", - prop->proposal_num, prop->protocol_id, prop->last_or_more, - prop->spi_size, prop->spi_size ? " spi_data " : "", - format_hex_bytes, prop->spi, prop->spi_size); - - vec_foreach (t, p->transforms) - { - vec_add2 (tr_data, tmp, sizeof (*tr) + vec_len (t->attrs)); - tr = (ike_sa_transform_data_t *) tmp; - tr->last_or_more = - ((t - p->transforms) + 1 < vec_len (p->transforms)) ? 3 : 0; - tr->transform_type = t->type; - tr->transform_id = clib_host_to_net_u16 (t->transform_id); - tr->transform_len = - clib_host_to_net_u16 (sizeof (*tr) + vec_len (t->attrs)); - - if (vec_len (t->attrs) > 0) - clib_memcpy_fast (tr->attributes, t->attrs, vec_len (t->attrs)); - - DBG_PLD - ("transform type %U transform_id %u last_or_more %u attr_size %u%s%U", - format_ikev2_transform_type, tr->transform_type, t->transform_id, - tr->last_or_more, vec_len (t->attrs), - vec_len (t->attrs) ? " attrs " : "", format_hex_bytes, - tr->attributes, vec_len (t->attrs)); - } - - prop->proposal_len = - clib_host_to_net_u16 (vec_len (tr_data) + vec_len (pr_data)); - ikev2_payload_add_data (c, pr_data); - ikev2_payload_add_data (c, tr_data); - vec_free (pr_data); - vec_free (tr_data); - } -} - -void -ikev2_payload_add_ke (ikev2_payload_chain_t * c, u16 dh_group, u8 * dh_data) -{ - ike_ke_payload_header_t *ke; - ke = (ike_ke_payload_header_t *) ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_KE, - sizeof (*ke)); - - ke->dh_group = clib_host_to_net_u16 (dh_group); - ikev2_payload_add_data (c, dh_data); -} - -void -ikev2_payload_add_nonce (ikev2_payload_chain_t * c, u8 * nonce) -{ - ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_NONCE, - sizeof (ike_payload_header_t)); - ikev2_payload_add_data (c, nonce); -} - -void -ikev2_payload_add_id (ikev2_payload_chain_t * c, ikev2_id_t * id, u8 type) -{ - ike_id_payload_header_t *idp; - idp = - (ike_id_payload_header_t *) ikev2_payload_add_hdr (c, type, - sizeof (*idp)); - - idp->id_type = id->type; - ikev2_payload_add_data (c, id->data); -} - -void -ikev2_payload_add_delete (ikev2_payload_chain_t * c, ikev2_delete_t * d) -{ - ike_delete_payload_header_t *dp; - u16 num_of_spi = vec_len (d); - ikev2_delete_t *d2; - dp = - (ike_delete_payload_header_t *) ikev2_payload_add_hdr (c, - IKEV2_PAYLOAD_DELETE, - sizeof (*dp)); - - if (d[0].protocol_id == IKEV2_PROTOCOL_IKE) - { - dp->protocol_id = 1; - } - else - { - dp->protocol_id = d[0].protocol_id; - dp->spi_size = 4; - dp->num_of_spi = clib_host_to_net_u16 (num_of_spi); - vec_foreach (d2, d) - { - u8 *data = vec_new (u8, 4); - u32 spi = clib_host_to_net_u32 (d2->spi); - clib_memcpy (data, &spi, 4); - ikev2_payload_add_data (c, data); - vec_free (data); - } - } -} - -void -ikev2_payload_add_auth (ikev2_payload_chain_t * c, ikev2_auth_t * auth) -{ - ike_auth_payload_header_t *ap; - ap = - (ike_auth_payload_header_t *) ikev2_payload_add_hdr (c, - IKEV2_PAYLOAD_AUTH, - sizeof (*ap)); - - ap->auth_method = auth->method; - ikev2_payload_add_data (c, auth->data); -} - -void -ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts, u8 type) -{ - ike_ts_payload_header_t *tsh; - ikev2_ts_t *ts2; - u8 *data = 0, *tmp; - - tsh = - (ike_ts_payload_header_t *) ikev2_payload_add_hdr (c, type, - sizeof (*tsh)); - tsh->num_ts = vec_len (ts); - - vec_foreach (ts2, ts) - { - ASSERT (ts2->ts_type == 7); /*TS_IPV4_ADDR_RANGE */ - ikev2_ts_payload_entry_t *entry; - vec_add2 (data, tmp, sizeof (*entry)); - entry = (ikev2_ts_payload_entry_t *) tmp; - entry->ts_type = ts2->ts_type; - entry->protocol_id = ts2->protocol_id; - entry->selector_len = clib_host_to_net_u16 (16); - entry->start_port = clib_host_to_net_u16 (ts2->start_port); - entry->end_port = clib_host_to_net_u16 (ts2->end_port); - entry->start_addr.as_u32 = ts2->start_addr.as_u32; - entry->end_addr.as_u32 = ts2->end_addr.as_u32; - } - - ikev2_payload_add_data (c, data); - vec_free (data); -} - -void -ikev2_payload_chain_add_padding (ikev2_payload_chain_t * c, int bs) -{ - u8 *tmp __attribute__ ((unused)); - u8 pad_len = (vec_len (c->data) / bs + 1) * bs - vec_len (c->data); - vec_add2 (c->data, tmp, pad_len); - c->data[vec_len (c->data) - 1] = pad_len - 1; -} - -ikev2_sa_proposal_t * -ikev2_parse_sa_payload (ike_payload_header_t * ikep) -{ - ikev2_sa_proposal_t *v = 0; - ikev2_sa_proposal_t *proposal; - ikev2_sa_transform_t *transform; - - u32 plen = clib_net_to_host_u16 (ikep->length); - - ike_sa_proposal_data_t *sap; - int proposal_ptr = 0; - - do - { - sap = (ike_sa_proposal_data_t *) & ikep->payload[proposal_ptr]; - int i; - int transform_ptr; - - DBG_PLD ("proposal num %u len %u last_or_more %u id %u " - "spi_size %u num_transforms %u", - sap->proposal_num, clib_net_to_host_u16 (sap->proposal_len), - sap->last_or_more, sap->protocol_id, sap->spi_size, - sap->num_transforms); - - /* IKE proposal should not have SPI */ - if (sap->protocol_id == IKEV2_PROTOCOL_IKE && sap->spi_size != 0) - goto data_corrupted; - - /* IKE proposal should not have SPI */ - if (sap->protocol_id == IKEV2_PROTOCOL_ESP && sap->spi_size != 4) - goto data_corrupted; - - transform_ptr = proposal_ptr + sizeof (*sap) + sap->spi_size; - - vec_add2 (v, proposal, 1); - proposal->proposal_num = sap->proposal_num; - proposal->protocol_id = sap->protocol_id; - - if (sap->spi_size == 4) - { - proposal->spi = clib_net_to_host_u32 (sap->spi[0]); - } - - for (i = 0; i < sap->num_transforms; i++) - { - ike_sa_transform_data_t *tr = - (ike_sa_transform_data_t *) & ikep->payload[transform_ptr]; - u16 tlen = clib_net_to_host_u16 (tr->transform_len); - - if (tlen < sizeof (*tr)) - goto data_corrupted; - - vec_add2 (proposal->transforms, transform, 1); - - transform->type = tr->transform_type; - transform->transform_id = clib_net_to_host_u16 (tr->transform_id); - if (tlen > sizeof (*tr)) - vec_add (transform->attrs, tr->attributes, tlen - sizeof (*tr)); - - DBG_PLD - ("transform num %u len %u last_or_more %u type %U id %u%s%U", i, - tlen, tr->last_or_more, format_ikev2_sa_transform, transform, - clib_net_to_host_u16 (tr->transform_id), - tlen > sizeof (*tr) ? " attrs " : "", format_hex_bytes, - tr->attributes, tlen - sizeof (*tr)); - - transform_ptr += tlen; - } - - proposal_ptr += clib_net_to_host_u16 (sap->proposal_len); - } - while (proposal_ptr < (plen - sizeof (*ikep)) && sap->last_or_more == 2); - - /* data validation */ - if (proposal_ptr != (plen - sizeof (*ikep)) || sap->last_or_more) - goto data_corrupted; - - return v; - -data_corrupted: - DBG_PLD ("SA payload data corrupted"); - ikev2_sa_free_proposal_vector (&v); - return 0; -} - -ikev2_ts_t * -ikev2_parse_ts_payload (ike_payload_header_t * ikep) -{ - ike_ts_payload_header_t *tsp = (ike_ts_payload_header_t *) ikep; - ikev2_ts_t *r = 0, *ts; - u8 i; - - for (i = 0; i < tsp->num_ts; i++) - { - if (tsp->ts[i].ts_type != 7) /* TS_IPV4_ADDR_RANGE */ - { - DBG_PLD ("unsupported TS type received (%u)", tsp->ts[i].ts_type); - continue; - } - - vec_add2 (r, ts, 1); - ts->ts_type = tsp->ts[i].ts_type; - ts->protocol_id = tsp->ts[i].protocol_id; - ts->start_port = tsp->ts[i].start_port; - ts->end_port = tsp->ts[i].end_port; - ts->start_addr.as_u32 = tsp->ts[i].start_addr.as_u32; - ts->end_addr.as_u32 = tsp->ts[i].end_addr.as_u32; - } - return r; -} - -ikev2_notify_t * -ikev2_parse_notify_payload (ike_payload_header_t * ikep) -{ - ike_notify_payload_header_t *n = (ike_notify_payload_header_t *) ikep; - u32 plen = clib_net_to_host_u16 (ikep->length); - ikev2_notify_t *r = 0; - u32 spi; - - DBG_PLD ("msg_type %U len %u%s%U", - format_ikev2_notify_msg_type, clib_net_to_host_u16 (n->msg_type), - plen, plen > sizeof (*n) ? " data " : "", - format_hex_bytes, n->payload, plen - sizeof (*n)); - - r = vec_new (ikev2_notify_t, 1); - r->msg_type = clib_net_to_host_u16 (n->msg_type); - r->protocol_id = n->protocol_id; - - if (n->spi_size == 4) - { - clib_memcpy (&spi, n->payload, n->spi_size); - r->spi = clib_net_to_host_u32 (spi); - DBG_PLD ("spi %lx", r->spi); - } - else if (n->spi_size == 0) - { - r->spi = 0; - } - else - { - clib_warning ("invalid SPI Size %d", n->spi_size); - } - - if (plen > (sizeof (*n) + n->spi_size)) - { - vec_add (r->data, n->payload + n->spi_size, - plen - sizeof (*n) - n->spi_size); - } - - return r; -} - -void -ikev2_parse_vendor_payload (ike_payload_header_t * ikep) -{ - u32 plen = clib_net_to_host_u16 (ikep->length); - int i; - int is_string = 1; - - for (i = 0; i < plen - 4; i++) - if (!isprint (ikep->payload[i])) - is_string = 0; - - DBG_PLD ("len %u data %s:%U", - plen, - is_string ? "string" : "hex", - is_string ? format_ascii_bytes : format_hex_bytes, - ikep->payload, plen - sizeof (*ikep)); -} - -ikev2_delete_t * -ikev2_parse_delete_payload (ike_payload_header_t * ikep) -{ - ike_delete_payload_header_t *d = (ike_delete_payload_header_t *) ikep; - u32 plen = clib_net_to_host_u16 (ikep->length); - ikev2_delete_t *r = 0, *del; - u16 num_of_spi = clib_net_to_host_u16 (d->num_of_spi); - u16 i = 0; - - DBG_PLD ("protocol_id %u spi_size %u num_of_spi %u len %u%s%U", - d->protocol_id, d->spi_size, num_of_spi, - plen, plen > sizeof (d) ? " data " : "", - format_hex_bytes, d->spi, plen - sizeof (*d)); - - if (d->protocol_id == IKEV2_PROTOCOL_IKE) - { - r = vec_new (ikev2_delete_t, 1); - r->protocol_id = 1; - } - else - { - r = vec_new (ikev2_delete_t, num_of_spi); - vec_foreach (del, r) - { - del->protocol_id = d->protocol_id; - del->spi = clib_net_to_host_u32 (d->spi[i++]); - } - } - - return r; -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ |