ikev2: add support for custom ipsec-over-udp port
[vpp.git] / src / plugins / ikev2 / ikev2_priv.h
1 /*
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:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  */
15 #ifndef __included_ikev2_priv_h__
16 #define __included_ikev2_priv_h__
17
18 #include <vnet/vnet.h>
19 #include <vnet/ip/ip.h>
20 #include <vnet/ethernet/ethernet.h>
21
22 #include <plugins/ikev2/ikev2.h>
23
24 #include <vppinfra/hash.h>
25 #include <vppinfra/elog.h>
26 #include <vppinfra/error.h>
27
28 #include <openssl/rand.h>
29 #include <openssl/dh.h>
30 #include <openssl/hmac.h>
31 #include <openssl/evp.h>
32
33 #define foreach_ikev2_log_level \
34   _(0x00, LOG_NONE)             \
35   _(0x01, LOG_ERROR)            \
36   _(0x02, LOG_WARNING)          \
37   _(0x03, LOG_INFO)             \
38   _(0x04, LOG_DEBUG)            \
39   _(0x05, LOG_DETAIL)           \
40
41
42 typedef enum ikev2_log_level_t_
43 {
44 #define _(n,f) IKEV2_##f = n,
45   foreach_ikev2_log_level
46 #undef _
47   IKEV2_LOG_MAX
48 } ikev2_log_level_t;
49
50 /* dataplane logging */
51 #define _ikev2_elog(_level, _msg)                                             \
52 do {                                                                          \
53   ikev2_main_t *km = &ikev2_main;                                             \
54   if (PREDICT_FALSE (km->log_level >= _level))                                \
55     {                                                                         \
56       ELOG_TYPE_DECLARE (e) =                                                 \
57         {                                                                     \
58           .format = "ikev2 " _msg,                                            \
59           .format_args = "",                                                  \
60         };                                                                    \
61       ELOG_DATA (&vlib_global_main.elog_main, e);                             \
62     }                                                                         \
63 } while (0)
64
65 #define ikev2_elog_sa_state(_format, _ispi)                                   \
66 do {                                                                          \
67   ikev2_main_t *km = &ikev2_main;                                             \
68   if (PREDICT_FALSE (km->log_level >= IKEV2_LOG_DEBUG))                       \
69     {                                                                         \
70       ELOG_TYPE_DECLARE (e) =                                                 \
71         {                                                                     \
72           .format = "ikev2: " _format,                                        \
73           .format_args = "i8",                                                \
74         };                                                                    \
75       CLIB_PACKED(struct                                                      \
76         {                                                                     \
77           u64 ispi;                                                           \
78         }) *ed;                                                               \
79       ed = ELOG_DATA (&vlib_global_main.elog_main, e);                        \
80       ed->ispi = _ispi;                                                       \
81     }                                                                         \
82 } while (0)                                                                   \
83
84 #define ikev2_elog_exchange(_format, _ispi, _rspi, _addr)                     \
85 do {                                                                          \
86   ikev2_main_t *km = &ikev2_main;                                             \
87   if (PREDICT_FALSE (km->log_level >= IKEV2_LOG_DEBUG))                       \
88     {                                                                         \
89       ELOG_TYPE_DECLARE (e) =                                                 \
90         {                                                                     \
91           .format = "ikev2: " _format,                                        \
92           .format_args = "i8i8i1i1i1i1",                                      \
93         };                                                                    \
94       CLIB_PACKED(struct                                                      \
95         {                                                                     \
96           u64 ispi;                                                           \
97           u64 rspi;                                                           \
98           u8 oct1;                                                            \
99           u8 oct2;                                                            \
100           u8 oct3;                                                            \
101           u8 oct4;                                                            \
102         }) *ed;                                                               \
103       ed = ELOG_DATA (&vlib_global_main.elog_main, e);                        \
104       ed->ispi = _ispi;                                                       \
105       ed->rspi = _rspi;                                                       \
106       ed->oct4 = (_addr) >> 24;                                               \
107       ed->oct3 = (_addr) >> 16;                                               \
108       ed->oct2 = (_addr) >> 8;                                                \
109       ed->oct1 = (_addr);                                                     \
110     }                                                                         \
111 } while (0)                                                                   \
112
113 #define ikev2_elog_uint(_level, _format, _val)                                \
114 do {                                                                          \
115   ikev2_main_t *km = &ikev2_main;                                             \
116   if (PREDICT_FALSE (km->log_level >= _level))                                \
117     {                                                                         \
118       ELOG_TYPE_DECLARE (e) =                                                 \
119         {                                                                     \
120           .format = "ikev2: " _format,                                        \
121           .format_args = "i8",                                                \
122         };                                                                    \
123       CLIB_PACKED(struct                                                      \
124         {                                                                     \
125           u64 val;                                                            \
126         }) *ed;                                                               \
127       ed = ELOG_DATA (&vlib_global_main.elog_main, e);                        \
128       ed->val = _val;                                                         \
129     }                                                                         \
130 } while (0)
131
132 #define ikev2_elog_uint_peers(_level, _format, _val, _ip1, _ip2)              \
133 do {                                                                          \
134   ikev2_main_t *km = &ikev2_main;                                             \
135   if (PREDICT_FALSE (km->log_level >= _level))                                \
136     {                                                                         \
137       ELOG_TYPE_DECLARE (e) =                                                 \
138         {                                                                     \
139           .format = "ikev2: " _format,                                        \
140           .format_args = "i8i1i1i1i1i1i1i1i1",                                \
141         };                                                                    \
142       CLIB_PACKED(struct {                                                    \
143         u64 val;                                                              \
144         u8 i11; u8 i12; u8 i13; u8 i14;                                       \
145         u8 i21; u8 i22; u8 i23; u8 i24; }) *ed;                               \
146       ed = ELOG_DATA (&vlib_global_main.elog_main, e);                        \
147       ed->val = _val;                                                         \
148       ed->i14 = (_ip1) >> 24;                                                 \
149       ed->i13 = (_ip1) >> 16;                                                 \
150       ed->i12 = (_ip1) >> 8;                                                  \
151       ed->i11 = (_ip1);                                                       \
152       ed->i24 = (_ip2) >> 24;                                                 \
153       ed->i23 = (_ip2) >> 16;                                                 \
154       ed->i22 = (_ip2) >> 8;                                                  \
155       ed->i21 = (_ip2);                                                       \
156     }                                                                         \
157 } while (0)
158
159 #define ikev2_elog_peers(_level, _format, _ip1, _ip2)                         \
160 do {                                                                          \
161   ikev2_main_t *km = &ikev2_main;                                             \
162   if (PREDICT_FALSE (km->log_level >= _level))                                \
163     {                                                                         \
164       ELOG_TYPE_DECLARE (e) =                                                 \
165         {                                                                     \
166           .format = "ikev2: " _format,                                        \
167           .format_args = "i1i1i1i1i1i1i1i1",                                  \
168         };                                                                    \
169       CLIB_PACKED(struct {                                                    \
170         u8 i11; u8 i12; u8 i13; u8 i14;                                       \
171         u8 i21; u8 i22; u8 i23; u8 i24; }) *ed;                               \
172       ed = ELOG_DATA (&vlib_global_main.elog_main, e);                        \
173       ed->i14 = (_ip1) >> 24;                                                 \
174       ed->i13 = (_ip1) >> 16;                                                 \
175       ed->i12 = (_ip1) >> 8;                                                  \
176       ed->i11 = (_ip1);                                                       \
177       ed->i24 = (_ip2) >> 24;                                                 \
178       ed->i23 = (_ip2) >> 16;                                                 \
179       ed->i22 = (_ip2) >> 8;                                                  \
180       ed->i21 = (_ip2);                                                       \
181     }                                                                         \
182 } while (0)
183
184 #define ikev2_elog_error(_msg) \
185   _ikev2_elog(IKEV2_LOG_ERROR, "[error] " _msg)
186 #define ikev2_elog_warning(_msg) \
187   _ikev2_elog(IKEV2_LOG_WARNING, "[warning] " _msg)
188 #define ikev2_elog_debug(_msg) \
189   _ikev2_elog(IKEV2_LOG_DEBUG, "[debug] " _msg)
190 #define ikev2_elog_detail(_msg) \
191   _ikev2_elog(IKEV2_LOG_DETAIL, "[detail] " _msg)
192
193 /* logging for main thread */
194 #define ikev2_log_error(...) \
195   vlib_log(VLIB_LOG_LEVEL_ERR, ikev2_main.log_class, __VA_ARGS__)
196 #define ikev2_log_warning(...) \
197   vlib_log(VLIB_LOG_LEVEL_WARNING, ikev2_main.log_class, __VA_ARGS__)
198 #define ikev2_log_debug(...) \
199   vlib_log(VLIB_LOG_LEVEL_DEBUG, ikev2_main.log_class, __VA_ARGS__)
200
201 typedef enum
202 {
203   IKEV2_STATE_UNKNOWN,
204   IKEV2_STATE_SA_INIT,
205   IKEV2_STATE_DELETED,
206   IKEV2_STATE_AUTH_FAILED,
207   IKEV2_STATE_AUTHENTICATED,
208   IKEV2_STATE_NOTIFY_AND_DELETE,
209   IKEV2_STATE_TS_UNACCEPTABLE,
210   IKEV2_STATE_NO_PROPOSAL_CHOSEN,
211 } ikev2_state_t;
212
213 typedef struct
214 {
215   ikev2_auth_method_t method:8;
216   u8 *data;
217   u8 hex;                       /* hex encoding of the shared secret */
218   EVP_PKEY *key;
219 } ikev2_auth_t;
220
221 typedef enum
222 {
223   IKEV2_DH_GROUP_MODP = 0,
224   IKEV2_DH_GROUP_ECP = 1,
225 } ikev2_dh_group_t;
226
227 typedef struct
228 {
229   ikev2_transform_type_t type;
230   union
231   {
232     u16 transform_id;
233     ikev2_transform_encr_type_t encr_type:16;
234     ikev2_transform_prf_type_t prf_type:16;
235     ikev2_transform_integ_type_t integ_type:16;
236     ikev2_transform_dh_type_t dh_type:16;
237     ikev2_transform_esn_type_t esn_type:16;
238   };
239   u8 *attrs;
240   u16 key_len;
241   u16 key_trunc;
242   u16 block_size;
243   u8 dh_group;
244   int nid;
245   const char *dh_p;
246   const char *dh_g;
247   const void *md;
248   const void *cipher;
249 } ikev2_sa_transform_t;
250
251 typedef struct
252 {
253   u8 proposal_num;
254   ikev2_protocol_id_t protocol_id:8;
255   u32 spi;
256   ikev2_sa_transform_t *transforms;
257 } ikev2_sa_proposal_t;
258
259 typedef struct
260 {
261   u8 ts_type;
262   u8 protocol_id;
263   u16 selector_len;
264   u16 start_port;
265   u16 end_port;
266   ip4_address_t start_addr;
267   ip4_address_t end_addr;
268 } ikev2_ts_t;
269
270 typedef struct
271 {
272   u32 sw_if_index;
273   ip4_address_t ip4;
274 } ikev2_responder_t;
275
276 typedef struct
277 {
278   ikev2_transform_encr_type_t crypto_alg;
279   ikev2_transform_integ_type_t integ_alg;
280   ikev2_transform_dh_type_t dh_type;
281   u32 crypto_key_size;
282 } ikev2_transforms_set;
283
284
285 typedef struct
286 {
287   ikev2_id_type_t type:8;
288   u8 *data;
289 } ikev2_id_t;
290
291 typedef struct
292 {
293   /* sa proposals vectors */
294   ikev2_sa_proposal_t *i_proposals;
295   ikev2_sa_proposal_t *r_proposals;
296
297   /* Traffic Selectors */
298   ikev2_ts_t *tsi;
299   ikev2_ts_t *tsr;
300
301   /* keys */
302   u8 *sk_ai;
303   u8 *sk_ar;
304   u8 *sk_ei;
305   u8 *sk_er;
306   u32 salt_ei;
307   u32 salt_er;
308
309   /* installed data */
310   u32 local_sa_id;
311   u32 remote_sa_id;
312
313   /* lifetime data */
314   f64 time_to_expiration;
315   u8 is_expired;
316   i8 rekey_retries;
317 } ikev2_child_sa_t;
318
319 typedef struct
320 {
321   u8 protocol_id;
322   u32 spi;                      /*for ESP and AH SPI size is 4, for IKE size is 0 */
323 } ikev2_delete_t;
324
325 typedef struct
326 {
327   u8 protocol_id;
328   u32 spi;
329   u32 ispi;
330   ikev2_sa_proposal_t *i_proposal;
331   ikev2_sa_proposal_t *r_proposal;
332   ikev2_ts_t *tsi;
333   ikev2_ts_t *tsr;
334 } ikev2_rekey_t;
335
336 typedef struct
337 {
338   u16 msg_type;
339   u8 protocol_id;
340   u32 spi;
341   u8 *data;
342 } ikev2_notify_t;
343
344 typedef struct
345 {
346   u8 *name;
347   u8 is_enabled;
348
349   ikev2_auth_t auth;
350   ikev2_id_t loc_id;
351   ikev2_id_t rem_id;
352   ikev2_ts_t loc_ts;
353   ikev2_ts_t rem_ts;
354   ikev2_responder_t responder;
355   ikev2_transforms_set ike_ts;
356   ikev2_transforms_set esp_ts;
357   u64 lifetime;
358   u64 lifetime_maxdata;
359   u32 lifetime_jitter;
360   u32 handover;
361   u16 dst_port;
362
363   u32 tun_itf;
364   u8 udp_encap;
365 } ikev2_profile_t;
366
367 typedef struct
368 {
369   ikev2_state_t state;
370   u8 unsupported_cp;
371   u8 initial_contact;
372   ip4_address_t iaddr;
373   ip4_address_t raddr;
374   u64 ispi;
375   u64 rspi;
376   u8 *i_nonce;
377   u8 *r_nonce;
378
379   /* DH data */
380   u16 dh_group;
381   u8 *dh_shared_key;
382   u8 *dh_private_key;
383   u8 *i_dh_data;
384   u8 *r_dh_data;
385
386   /* sa proposals vectors */
387   ikev2_sa_proposal_t *i_proposals;
388   ikev2_sa_proposal_t *r_proposals;
389
390   /* keys */
391   u8 *sk_d;
392   u8 *sk_ai;
393   u8 *sk_ar;
394   u8 *sk_ei;
395   u8 *sk_er;
396   u8 *sk_pi;
397   u8 *sk_pr;
398
399   /* auth */
400   ikev2_auth_t i_auth;
401   ikev2_auth_t r_auth;
402
403   /* ID */
404   ikev2_id_t i_id;
405   ikev2_id_t r_id;
406
407   /* pending deletes */
408   ikev2_delete_t *del;
409
410   /* pending rekeyings */
411   ikev2_rekey_t *rekey;
412
413   /* packet data */
414   u8 *last_sa_init_req_packet_data;
415   u8 *last_sa_init_res_packet_data;
416
417   /* retransmit */
418   u32 last_msg_id;
419   u8 *last_res_packet_data;
420
421   u8 is_initiator;
422   u32 last_init_msg_id;
423   u8 is_profile_index_set;
424   u32 profile_index;
425   u8 is_tun_itf_set;
426   u32 tun_itf;
427   u8 udp_encap;
428   u16 dst_port;
429
430   f64 old_id_expiration;
431   u32 current_remote_id_mask;
432   u32 old_remote_id;
433   u8 old_remote_id_present;
434
435   ikev2_child_sa_t *childs;
436 } ikev2_sa_t;
437
438
439 typedef struct
440 {
441   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
442
443   /* pool of IKEv2 Security Associations */
444   ikev2_sa_t *sas;
445
446   /* hash */
447   uword *sa_by_rspi;
448 } ikev2_main_per_thread_data_t;
449
450 typedef struct
451 {
452   /* pool of IKEv2 profiles */
453   ikev2_profile_t *profiles;
454
455   /* vector of supported transform types */
456   ikev2_sa_transform_t *supported_transforms;
457
458   /* hash */
459   mhash_t profile_index_by_name;
460
461   /* local private key */
462   EVP_PKEY *pkey;
463
464   /* convenience */
465   vlib_main_t *vlib_main;
466   vnet_main_t *vnet_main;
467
468   /* pool of IKEv2 Security Associations created in initiator mode */
469   ikev2_sa_t *sais;
470   /* hash */
471   uword *sa_by_ispi;
472
473   ikev2_main_per_thread_data_t *per_thread_data;
474
475   /* interface indices managed by IKE */
476   uword *sw_if_indices;
477
478   /* API message ID base */
479   u16 msg_id_base;
480
481   /* log class used for main thread */
482   vlib_log_class_t log_class;
483
484   /* logging level */
485   ikev2_log_level_t log_level;
486
487   /* custom ipsec-over-udp ports managed by ike */
488   uword *udp_ports;
489 } ikev2_main_t;
490
491 extern ikev2_main_t ikev2_main;
492
493 void ikev2_sa_free_proposal_vector (ikev2_sa_proposal_t ** v);
494 ikev2_sa_transform_t *ikev2_sa_get_td_for_type (ikev2_sa_proposal_t * p,
495                                                 ikev2_transform_type_t type);
496
497 /* ikev2_crypto.c */
498 v8 *ikev2_calc_prf (ikev2_sa_transform_t * tr, v8 * key, v8 * data);
499 u8 *ikev2_calc_prfplus (ikev2_sa_transform_t * tr, u8 * key, u8 * seed,
500                         int len);
501 v8 *ikev2_calc_integr (ikev2_sa_transform_t * tr, v8 * key, u8 * data,
502                        int len);
503 v8 *ikev2_decrypt_data (ikev2_sa_t * sa, u8 * data, int len);
504 int ikev2_encrypt_data (ikev2_sa_t * sa, v8 * src, u8 * dst);
505 void ikev2_generate_dh (ikev2_sa_t * sa, ikev2_sa_transform_t * t);
506 void ikev2_complete_dh (ikev2_sa_t * sa, ikev2_sa_transform_t * t);
507 int ikev2_verify_sign (EVP_PKEY * pkey, u8 * sigbuf, u8 * data);
508 u8 *ikev2_calc_sign (EVP_PKEY * pkey, u8 * data);
509 EVP_PKEY *ikev2_load_cert_file (u8 * file);
510 EVP_PKEY *ikev2_load_key_file (u8 * file);
511 void ikev2_crypto_init (ikev2_main_t * km);
512
513 /* ikev2_payload.c */
514 typedef struct
515 {
516   u8 first_payload_type;
517   u16 last_hdr_off;
518   u8 *data;
519 } ikev2_payload_chain_t;
520
521 #define ikev2_payload_new_chain(V) vec_validate (V, 0)
522 #define ikev2_payload_destroy_chain(V) do { \
523   vec_free((V)->data);                 \
524   vec_free(V);                         \
525 } while (0)
526
527 void ikev2_payload_add_notify (ikev2_payload_chain_t * c, u16 msg_type,
528                                u8 * data);
529 void ikev2_payload_add_notify_2 (ikev2_payload_chain_t * c, u16 msg_type,
530                                  u8 * data, ikev2_notify_t * notify);
531 void ikev2_payload_add_sa (ikev2_payload_chain_t * c,
532                            ikev2_sa_proposal_t * proposals);
533 void ikev2_payload_add_ke (ikev2_payload_chain_t * c, u16 dh_group,
534                            u8 * dh_data);
535 void ikev2_payload_add_nonce (ikev2_payload_chain_t * c, u8 * nonce);
536 void ikev2_payload_add_id (ikev2_payload_chain_t * c, ikev2_id_t * id,
537                            u8 type);
538 void ikev2_payload_add_auth (ikev2_payload_chain_t * c, ikev2_auth_t * auth);
539 void ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts,
540                            u8 type);
541 void ikev2_payload_add_delete (ikev2_payload_chain_t * c, ikev2_delete_t * d);
542 void ikev2_payload_chain_add_padding (ikev2_payload_chain_t * c, int bs);
543 void ikev2_parse_vendor_payload (ike_payload_header_t * ikep);
544 ikev2_sa_proposal_t *ikev2_parse_sa_payload (ike_payload_header_t * ikep);
545 ikev2_ts_t *ikev2_parse_ts_payload (ike_payload_header_t * ikep);
546 ikev2_delete_t *ikev2_parse_delete_payload (ike_payload_header_t * ikep);
547 ikev2_notify_t *ikev2_parse_notify_payload (ike_payload_header_t * ikep);
548 int ikev2_set_log_level (ikev2_log_level_t log_level);
549 #endif /* __included_ikev2_priv_h__ */
550
551
552 /*
553  * fd.io coding-style-patch-verification: ON
554  *
555  * Local Variables:
556  * eval: (c-set-style "gnu")
557  * End:
558  */