2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
18 #include <vnet/vnet.h>
19 #include <vnet/api_errno.h>
20 #include <vnet/ip/ip.h>
21 #include <vnet/interface.h>
23 #include <vnet/ipsec/ipsec.h>
24 #include <plugins/ikev2/ikev2.h>
25 #include <plugins/ikev2/ikev2_priv.h>
27 typedef CLIB_PACKED (struct {
35 }) ike_notify_payload_header_t;
37 typedef CLIB_PACKED (struct {
38 ip4_address_t start_addr;
39 ip4_address_t end_addr;
40 }) ikev2_ip4_addr_pair_t;
42 typedef CLIB_PACKED (struct {
43 ip6_address_t start_addr;
44 ip6_address_t end_addr;
45 }) ikev2_ip6_addr_pair_t;
47 typedef CLIB_PACKED (struct {
54 }) ikev2_ts_payload_entry_t;
56 typedef CLIB_PACKED (struct {
62 ikev2_ts_payload_entry_t ts[0];
63 }) ike_ts_payload_header_t;
65 typedef CLIB_PACKED (struct {
72 u8 num_transforms; u32 spi[0];
73 }) ike_sa_proposal_data_t;
75 typedef CLIB_PACKED (struct {
83 }) ike_sa_transform_data_t;
85 typedef CLIB_PACKED (struct {
93 }) ike_delete_payload_header_t;
95 static ike_payload_header_t *
96 ikev2_payload_add_hdr (ikev2_payload_chain_t * c, u8 payload_type, int len)
98 ike_payload_header_t *hdr =
99 (ike_payload_header_t *) & c->data[c->last_hdr_off];
103 hdr->nextpayload = payload_type;
105 c->first_payload_type = payload_type;
107 c->last_hdr_off = vec_len (c->data);
108 vec_add2 (c->data, tmp, len);
109 hdr = (ike_payload_header_t *) tmp;
110 clib_memset (hdr, 0, len);
112 hdr->length = clib_host_to_net_u16 (len);
118 ikev2_payload_add_data (ikev2_payload_chain_t * c, u8 * data)
121 ike_payload_header_t *hdr;
123 vec_append (c->data, data);
124 hdr = (ike_payload_header_t *) & c->data[c->last_hdr_off];
125 len = clib_net_to_host_u16 (hdr->length);
126 hdr->length = clib_host_to_net_u16 (len + vec_len (data));
130 ikev2_payload_add_notify (ikev2_payload_chain_t * c, u16 msg_type, u8 * data)
132 ikev2_payload_add_notify_2(c, msg_type, data, 0);
136 ikev2_payload_add_notify_2 (ikev2_payload_chain_t * c, u16 msg_type,
137 u8 * data, ikev2_notify_t * notify)
139 ike_notify_payload_header_t *n;
142 (ike_notify_payload_header_t *) ikev2_payload_add_hdr (c,
143 IKEV2_PAYLOAD_NOTIFY,
145 n->msg_type = clib_host_to_net_u16 (msg_type);
148 n->protocol_id = notify->protocol_id;
154 ikev2_payload_add_data (c, data);
158 ikev2_payload_add_sa (ikev2_payload_chain_t *c, ikev2_sa_proposal_t *proposals,
161 ike_payload_header_t *ph;
162 ike_sa_proposal_data_t *prop;
163 ike_sa_transform_data_t *tr;
164 ikev2_sa_proposal_t *p;
165 ikev2_sa_transform_t *t;
171 ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_SA, sizeof (*ph));
173 vec_foreach (p, proposals)
177 if (p->protocol_id == IKEV2_PROTOCOL_ESP)
179 else if (force_spi && p->protocol_id == IKEV2_PROTOCOL_IKE)
182 pr_data = vec_new (u8, sizeof (ike_sa_proposal_data_t) + spi_size);
183 prop = (ike_sa_proposal_data_t *) pr_data;
184 prop->last_or_more = proposals - p + 1 < vec_len (proposals) ? 2 : 0;
185 prop->protocol_id = p->protocol_id;
186 prop->proposal_num = p->proposal_num;
187 prop->spi_size = spi_size;
188 prop->num_transforms = vec_len (p->transforms);
191 prop->spi[0] = clib_host_to_net_u32 (p->spi);
192 else if (spi_size == 8)
194 u64 s = clib_host_to_net_u64 (p->spi);
195 clib_memcpy_fast (prop->spi, &s, sizeof (s));
198 vec_foreach (t, p->transforms)
200 vec_add2 (tr_data, tmp, sizeof (*tr) + vec_len (t->attrs));
201 tr = (ike_sa_transform_data_t *) tmp;
203 ((t - p->transforms) + 1 < vec_len (p->transforms)) ? 3 : 0;
204 tr->transform_type = t->type;
205 tr->transform_id = clib_host_to_net_u16 (t->transform_id);
207 clib_host_to_net_u16 (sizeof (*tr) + vec_len (t->attrs));
209 if (vec_len (t->attrs) > 0)
210 clib_memcpy_fast (tr->attributes, t->attrs, vec_len (t->attrs));
214 clib_host_to_net_u16 (vec_len (tr_data) + vec_len (pr_data));
215 ikev2_payload_add_data (c, pr_data);
216 ikev2_payload_add_data (c, tr_data);
223 ikev2_payload_add_ke (ikev2_payload_chain_t * c, u16 dh_group, u8 * dh_data)
225 ike_ke_payload_header_t *ke;
226 ke = (ike_ke_payload_header_t *) ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_KE,
229 ke->dh_group = clib_host_to_net_u16 (dh_group);
230 ikev2_payload_add_data (c, dh_data);
234 ikev2_payload_add_nonce (ikev2_payload_chain_t * c, u8 * nonce)
236 ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_NONCE,
237 sizeof (ike_payload_header_t));
238 ikev2_payload_add_data (c, nonce);
242 ikev2_payload_add_id (ikev2_payload_chain_t * c, ikev2_id_t * id, u8 type)
244 ike_id_payload_header_t *idp;
246 (ike_id_payload_header_t *) ikev2_payload_add_hdr (c, type,
249 idp->id_type = id->type;
250 ikev2_payload_add_data (c, id->data);
254 ikev2_payload_add_delete (ikev2_payload_chain_t * c, ikev2_delete_t * d)
256 ike_delete_payload_header_t *dp;
257 u16 num_of_spi = vec_len (d);
260 (ike_delete_payload_header_t *) ikev2_payload_add_hdr (c,
261 IKEV2_PAYLOAD_DELETE,
264 if (d[0].protocol_id == IKEV2_PROTOCOL_IKE)
270 dp->protocol_id = d[0].protocol_id;
272 dp->num_of_spi = clib_host_to_net_u16 (num_of_spi);
275 u8 *data = vec_new (u8, 4);
276 u32 spi = clib_host_to_net_u32 (d2->spi);
277 clib_memcpy (data, &spi, 4);
278 ikev2_payload_add_data (c, data);
285 ikev2_payload_add_auth (ikev2_payload_chain_t * c, ikev2_auth_t * auth)
287 ike_auth_payload_header_t *ap;
289 (ike_auth_payload_header_t *) ikev2_payload_add_hdr (c,
293 ap->auth_method = auth->method;
294 ikev2_payload_add_data (c, auth->data);
298 ikev2_payload_add_ts_entry (u8 ** data, ikev2_ts_t * ts)
301 ikev2_ts_payload_entry_t *entry;
302 int len = sizeof (*entry);
304 if (ts->ts_type == TS_IPV4_ADDR_RANGE)
305 len += sizeof (ikev2_ip4_addr_pair_t);
307 len += sizeof (ikev2_ip6_addr_pair_t);
309 vec_add2 (data[0], tmp, len);
310 entry = (ikev2_ts_payload_entry_t *) tmp;
311 entry->ts_type = ts->ts_type;
312 entry->protocol_id = ts->protocol_id;
313 entry->selector_len = clib_host_to_net_u16 (len);
314 entry->start_port = clib_host_to_net_u16 (ts->start_port);
315 entry->end_port = clib_host_to_net_u16 (ts->end_port);
317 if (ts->ts_type == TS_IPV4_ADDR_RANGE)
319 ikev2_ip4_addr_pair_t *pair = (ikev2_ip4_addr_pair_t*) entry->addr_pair;
320 ip_address_copy_addr (&pair->start_addr, &ts->start_addr);
321 ip_address_copy_addr (&pair->end_addr, &ts->end_addr);
325 ikev2_ip6_addr_pair_t *pair = (ikev2_ip6_addr_pair_t*) entry->addr_pair;
326 ip_address_copy_addr (&pair->start_addr, &ts->start_addr);
327 ip_address_copy_addr (&pair->end_addr, &ts->end_addr);
332 ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts, u8 type)
334 ike_ts_payload_header_t *tsh;
339 (ike_ts_payload_header_t *) ikev2_payload_add_hdr (c, type,
341 tsh->num_ts = vec_len (ts);
343 vec_foreach (ts2, ts)
345 ASSERT (ts2->ts_type == TS_IPV4_ADDR_RANGE ||
346 ts2->ts_type == TS_IPV6_ADDR_RANGE);
347 ikev2_payload_add_ts_entry (&data, ts2);
350 ikev2_payload_add_data (c, data);
355 ikev2_payload_chain_add_padding (ikev2_payload_chain_t * c, int bs)
357 u8 *tmp __attribute__ ((unused));
358 u8 pad_len = (vec_len (c->data) / bs + 1) * bs - vec_len (c->data);
359 vec_add2 (c->data, tmp, pad_len);
360 c->data[vec_len (c->data) - 1] = pad_len - 1;
363 ikev2_sa_proposal_t *
364 ikev2_parse_sa_payload (ike_payload_header_t * ikep, u32 rlen)
366 ikev2_sa_proposal_t *v = 0;
367 ikev2_sa_proposal_t *proposal;
368 ikev2_sa_transform_t *transform;
370 u32 plen = clib_net_to_host_u16 (ikep->length);
371 ike_sa_proposal_data_t *sap;
372 int proposal_ptr = 0;
374 if (sizeof (*ikep) > rlen)
377 rlen -= sizeof (*ikep);
380 if (proposal_ptr + sizeof (*sap) > rlen)
383 sap = (ike_sa_proposal_data_t *) & ikep->payload[proposal_ptr];
384 int i, transform_ptr;
386 /* IKE proposal should have 8 bytes or no SPI */
387 if (sap->protocol_id == IKEV2_PROTOCOL_IKE && sap->spi_size != 0 &&
391 /* IKE proposal should not have SPI */
392 if (sap->protocol_id == IKEV2_PROTOCOL_ESP && sap->spi_size != 4)
395 transform_ptr = proposal_ptr + sizeof (*sap) + sap->spi_size;
396 if (transform_ptr > rlen)
399 vec_add2 (v, proposal, 1);
400 proposal->proposal_num = sap->proposal_num;
401 proposal->protocol_id = sap->protocol_id;
403 if (sap->spi_size == 4)
405 proposal->spi = clib_net_to_host_u32 (sap->spi[0]);
407 else if (sap->spi_size == 8)
410 clib_memcpy_fast (&s, &sap->spi[0], sizeof (s));
411 proposal->spi = clib_net_to_host_u64 (s);
414 for (i = 0; i < sap->num_transforms; i++)
416 ike_sa_transform_data_t *tr =
417 (ike_sa_transform_data_t *) & ikep->payload[transform_ptr];
418 if (transform_ptr + sizeof (*tr) > rlen)
420 u16 tlen = clib_net_to_host_u16 (tr->transform_len);
422 if (tlen < sizeof (*tr))
425 vec_add2 (proposal->transforms, transform, 1);
427 transform->type = tr->transform_type;
428 transform->transform_id = clib_net_to_host_u16 (tr->transform_id);
429 if (transform_ptr + tlen > rlen)
431 if (tlen > sizeof (*tr))
432 vec_add (transform->attrs, tr->attributes, tlen - sizeof (*tr));
433 transform_ptr += tlen;
436 proposal_ptr += clib_net_to_host_u16 (sap->proposal_len);
438 while (proposal_ptr < (plen - sizeof (*ikep)) && sap->last_or_more == 2);
440 /* data validation */
441 if (proposal_ptr != (plen - sizeof (*ikep)) || sap->last_or_more)
447 ikev2_elog_detail ("SA payload data corrupted");
448 ikev2_sa_free_proposal_vector (&v);
453 ikev2_parse_ts_payload (ike_payload_header_t * ikep, u32 rlen)
455 ike_ts_payload_header_t *tsp = (ike_ts_payload_header_t *) ikep;
456 ikev2_ts_t *r = 0, *ts;
457 ikev2_ip4_addr_pair_t *pair4;
458 ikev2_ip6_addr_pair_t *pair6;
460 ikev2_ts_payload_entry_t *pe;
462 if (sizeof (*tsp) > rlen)
465 rlen -= sizeof (*tsp);
466 n_left = tsp->num_ts;
468 while (n_left && p + sizeof (*pe) < rlen)
470 pe = (ikev2_ts_payload_entry_t *) (((u8 *)tsp->ts) + p);
473 if (pe->ts_type != TS_IPV4_ADDR_RANGE &&
474 pe->ts_type != TS_IPV6_ADDR_RANGE)
476 ikev2_elog_uint (IKEV2_LOG_ERROR,
477 "unsupported TS type received (%u)", pe->ts_type);
482 ts->ts_type = pe->ts_type;
483 ts->protocol_id = pe->protocol_id;
484 ts->start_port = pe->start_port;
485 ts->end_port = pe->end_port;
487 if (pe->ts_type == TS_IPV4_ADDR_RANGE)
489 pair4 = (ikev2_ip4_addr_pair_t*) pe->addr_pair;
490 ip_address_set (&ts->start_addr, &pair4->start_addr, AF_IP4);
491 ip_address_set (&ts->end_addr, &pair4->end_addr, AF_IP4);
492 p += sizeof (*pair4);
496 pair6 = (ikev2_ip6_addr_pair_t*) pe->addr_pair;
497 ip_address_set (&ts->start_addr, &pair6->start_addr, AF_IP6);
498 ip_address_set (&ts->end_addr, &pair6->end_addr, AF_IP6);
499 p += sizeof (*pair6);
511 ikev2_parse_notify_payload (ike_payload_header_t * ikep, u32 rlen)
513 ike_notify_payload_header_t *n = (ike_notify_payload_header_t *) ikep;
514 u32 plen = clib_net_to_host_u16 (n->length);
515 ikev2_notify_t *r = 0;
518 if (sizeof (*n) > rlen)
521 r = vec_new (ikev2_notify_t, 1);
522 r->msg_type = clib_net_to_host_u16 (n->msg_type);
523 r->protocol_id = n->protocol_id;
525 if (n->spi_size == 4)
527 if (sizeof (spi) + sizeof (*n) > rlen)
530 clib_memcpy (&spi, n->payload, n->spi_size);
531 r->spi = clib_net_to_host_u32 (spi);
533 else if (n->spi_size == 0)
539 clib_warning ("invalid SPI Size %d", n->spi_size);
543 if (plen > (sizeof (*n) + n->spi_size))
545 if (plen <= sizeof (*n) + n->spi_size)
548 u32 data_len = plen - sizeof (*n) - n->spi_size;
549 vec_add (r->data, n->payload + n->spi_size, data_len);
559 ikev2_parse_vendor_payload (ike_payload_header_t * ikep)
561 u32 plen = clib_net_to_host_u16 (ikep->length);
562 ikev2_elog_uint (IKEV2_LOG_DEBUG, "vendor payload skipped, len %d", plen);
566 ikev2_parse_delete_payload (ike_payload_header_t * ikep, u32 rlen)
568 ike_delete_payload_header_t * d = (ike_delete_payload_header_t *) ikep;
569 ikev2_delete_t *r = 0, *del;
572 if (rlen < sizeof (*d))
575 num_of_spi = clib_net_to_host_u16 (d->num_of_spi);
576 if (d->protocol_id == IKEV2_PROTOCOL_IKE)
578 r = vec_new (ikev2_delete_t, 1);
583 if (sizeof (*d) + num_of_spi * sizeof (u32) > rlen)
586 for (i = 0; i < num_of_spi; i++)
588 vec_add2 (r, del, 1);
589 del->protocol_id = d->protocol_id;
590 del->spi = clib_net_to_host_u32 (d->spi[i]);
598 ikev2_find_ike_notify_payload (ike_header_t * ike, u32 msg_type)
601 ike_notify_payload_header_t *n;
602 ike_payload_header_t *ikep;
603 u32 payload = ike->nextpayload;
605 while (payload != IKEV2_PAYLOAD_NONE)
607 ikep = (ike_payload_header_t *) & ike->payload[p];
608 if (payload == IKEV2_PAYLOAD_NOTIFY)
610 n = (ike_notify_payload_header_t *)ikep;
611 if (n->msg_type == clib_net_to_host_u16 (msg_type))
614 u16 plen = clib_net_to_host_u16 (ikep->length);
615 payload = ikep->nextpayload;
622 * fd.io coding-style-patch-verification: ON
625 * eval: (c-set-style "gnu")