blob: b396965a0bbd51b38052540e1880d3bb906ab03b [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
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 <vnet/ipsec/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 IKEV2_DEBUG_PAYLOAD 1
34
35#if IKEV2_DEBUG_PAYLOAD == 1
36#define DBG_PLD(my_args...) clib_warning(my_args)
37#else
38#define DBG_PLD(my_args...)
39#endif
40
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070041typedef enum
42{
Ed Warnickecb9cada2015-12-08 15:45:58 -070043 IKEV2_STATE_UNKNOWN,
44 IKEV2_STATE_SA_INIT,
45 IKEV2_STATE_DELETED,
46 IKEV2_STATE_AUTH_FAILED,
47 IKEV2_STATE_AUTHENTICATED,
48 IKEV2_STATE_NOTIFY_AND_DELETE,
49 IKEV2_STATE_TS_UNACCEPTABLE,
50 IKEV2_STATE_NO_PROPOSAL_CHOSEN,
51} ikev2_state_t;
52
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070053typedef struct
54{
Ed Warnickecb9cada2015-12-08 15:45:58 -070055 ikev2_auth_method_t method:8;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070056 u8 *data;
57 u8 hex; /* hex encoding of the shared secret */
58 EVP_PKEY *key;
Ed Warnickecb9cada2015-12-08 15:45:58 -070059} ikev2_auth_t;
60
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070061typedef enum
62{
Ed Warnickecb9cada2015-12-08 15:45:58 -070063 IKEV2_DH_GROUP_MODP = 0,
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070064 IKEV2_DH_GROUP_ECP = 1,
Ed Warnickecb9cada2015-12-08 15:45:58 -070065} ikev2_dh_group_t;
66
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070067typedef struct
68{
Ed Warnickecb9cada2015-12-08 15:45:58 -070069 ikev2_transform_type_t type;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070070 union
71 {
72 u16 transform_id;
73 ikev2_transform_encr_type_t encr_type:16;
74 ikev2_transform_prf_type_t prf_type:16;
Ed Warnickecb9cada2015-12-08 15:45:58 -070075 ikev2_transform_integ_type_t integ_type:16;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070076 ikev2_transform_dh_type_t dh_type:16;
77 ikev2_transform_esn_type_t esn_type:16;
Ed Warnickecb9cada2015-12-08 15:45:58 -070078 };
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070079 u8 *attrs;
Ed Warnickecb9cada2015-12-08 15:45:58 -070080 u16 key_len;
81 u16 key_trunc;
82 u16 block_size;
83 u8 dh_group;
84 int nid;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070085 const char *dh_p;
86 const char *dh_g;
87 const void *md;
88 const void *cipher;
Ed Warnickecb9cada2015-12-08 15:45:58 -070089} ikev2_sa_transform_t;
90
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070091typedef struct
92{
Ed Warnickecb9cada2015-12-08 15:45:58 -070093 u8 proposal_num;
94 ikev2_protocol_id_t protocol_id:8;
95 u32 spi;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070096 ikev2_sa_transform_t *transforms;
Ed Warnickecb9cada2015-12-08 15:45:58 -070097} ikev2_sa_proposal_t;
98
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -070099typedef struct
100{
101 u8 ts_type;
102 u8 protocol_id;
103 u16 selector_len;
104 u16 start_port;
105 u16 end_port;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700106 ip4_address_t start_addr;
107 ip4_address_t end_addr;
108} ikev2_ts_t;
109
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700110typedef struct
111{
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000112 u32 sw_if_index;
113 ip4_address_t ip4;
114} ikev2_responder_t;
115
116typedef struct
117{
118 ikev2_transform_encr_type_t crypto_alg;
119 ikev2_transform_integ_type_t integ_alg;
120 ikev2_transform_dh_type_t dh_type;
121 u32 crypto_key_size;
122} ikev2_transforms_set;
123
124
125typedef struct
126{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700127 ikev2_id_type_t type:8;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700128 u8 *data;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700129} ikev2_id_t;
130
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700131typedef struct
132{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700133 /* sa proposals vectors */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700134 ikev2_sa_proposal_t *i_proposals;
135 ikev2_sa_proposal_t *r_proposals;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700136
137 /* Traffic Selectors */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700138 ikev2_ts_t *tsi;
139 ikev2_ts_t *tsr;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700140
141 /* keys */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700142 u8 *sk_ai;
143 u8 *sk_ar;
144 u8 *sk_ei;
145 u8 *sk_er;
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000146
147 /* lifetime data */
148 f64 time_to_expiration;
149 u8 is_expired;
150 i8 rekey_retries;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700151} ikev2_child_sa_t;
152
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700153typedef struct
154{
155 u8 protocol_id;
156 u32 spi; /*for ESP and AH SPI size is 4, for IKE size is 0 */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700157} ikev2_delete_t;
158
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700159typedef struct
160{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700161 u8 protocol_id;
162 u32 spi;
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000163 u32 ispi;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700164 ikev2_sa_proposal_t *i_proposal;
165 ikev2_sa_proposal_t *r_proposal;
166 ikev2_ts_t *tsi;
167 ikev2_ts_t *tsr;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700168} ikev2_rekey_t;
169
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700170typedef struct
171{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700172 u16 msg_type;
173 u8 protocol_id;
174 u32 spi;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700175 u8 *data;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700176} ikev2_notify_t;
177
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000178typedef struct
179{
180 u8 *name;
181 u8 is_enabled;
182
183 ikev2_auth_t auth;
184 ikev2_id_t loc_id;
185 ikev2_id_t rem_id;
186 ikev2_ts_t loc_ts;
187 ikev2_ts_t rem_ts;
188 ikev2_responder_t responder;
189 ikev2_transforms_set ike_ts;
190 ikev2_transforms_set esp_ts;
191 u64 lifetime;
192 u64 lifetime_maxdata;
193 u32 lifetime_jitter;
194 u32 handover;
195} ikev2_profile_t;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700196
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700197typedef struct
198{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700199 ikev2_state_t state;
200 u8 unsupported_cp;
201 u8 initial_contact;
202 ip4_address_t iaddr;
203 ip4_address_t raddr;
204 u64 ispi;
205 u64 rspi;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700206 u8 *i_nonce;
207 u8 *r_nonce;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700208
209 /* DH data */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700210 u16 dh_group;
211 u8 *dh_shared_key;
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000212 u8 *dh_private_key;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700213 u8 *i_dh_data;
214 u8 *r_dh_data;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700215
216 /* sa proposals vectors */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700217 ikev2_sa_proposal_t *i_proposals;
218 ikev2_sa_proposal_t *r_proposals;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700219
220 /* keys */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700221 u8 *sk_d;
222 u8 *sk_ai;
223 u8 *sk_ar;
224 u8 *sk_ei;
225 u8 *sk_er;
226 u8 *sk_pi;
227 u8 *sk_pr;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700228
229 /* auth */
230 ikev2_auth_t i_auth;
231 ikev2_auth_t r_auth;
232
233 /* ID */
234 ikev2_id_t i_id;
235 ikev2_id_t r_id;
236
237 /* pending deletes */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700238 ikev2_delete_t *del;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700239
240 /* pending rekeyings */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700241 ikev2_rekey_t *rekey;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700242
243 /* packet data */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700244 u8 *last_sa_init_req_packet_data;
245 u8 *last_sa_init_res_packet_data;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700246
247 /* retransmit */
248 u32 last_msg_id;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700249 u8 *last_res_packet_data;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700250
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000251 u8 is_initiator;
252 u32 last_init_msg_id;
253 ikev2_profile_t *profile;
254
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700255 ikev2_child_sa_t *childs;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700256} ikev2_sa_t;
257
Ed Warnickecb9cada2015-12-08 15:45:58 -0700258
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700259typedef struct
260{
261 /* pool of IKEv2 Security Associations */
262 ikev2_sa_t *sas;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700263
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700264 /* hash */
265 uword *sa_by_rspi;
Matthew Smith2838a232016-06-21 16:05:09 -0500266} ikev2_main_per_thread_data_t;
267
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700268typedef struct
269{
270 /* pool of IKEv2 profiles */
271 ikev2_profile_t *profiles;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700272
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700273 /* vector of supported transform types */
274 ikev2_sa_transform_t *supported_transforms;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700275
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700276 /* hash */
277 mhash_t profile_index_by_name;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700278
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700279 /* local private key */
280 EVP_PKEY *pkey;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700281
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700282 /* convenience */
283 vlib_main_t *vlib_main;
284 vnet_main_t *vnet_main;
Matthew Smith2838a232016-06-21 16:05:09 -0500285
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000286 /* pool of IKEv2 Security Associations created in initiator mode */
287 ikev2_sa_t *sais;
288 /* hash */
289 uword *sa_by_ispi;
290
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700291 ikev2_main_per_thread_data_t *per_thread_data;
Matthew Smith2838a232016-06-21 16:05:09 -0500292
Ed Warnickecb9cada2015-12-08 15:45:58 -0700293} ikev2_main_t;
294
Dave Wallace71612d62017-10-24 01:32:41 -0400295extern ikev2_main_t ikev2_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700296
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700297void ikev2_sa_free_proposal_vector (ikev2_sa_proposal_t ** v);
298ikev2_sa_transform_t *ikev2_sa_get_td_for_type (ikev2_sa_proposal_t * p,
299 ikev2_transform_type_t type);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700300
301/* ikev2_crypto.c */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700302v8 *ikev2_calc_prf (ikev2_sa_transform_t * tr, v8 * key, v8 * data);
303u8 *ikev2_calc_prfplus (ikev2_sa_transform_t * tr, u8 * key, u8 * seed,
304 int len);
305v8 *ikev2_calc_integr (ikev2_sa_transform_t * tr, v8 * key, u8 * data,
306 int len);
307v8 *ikev2_decrypt_data (ikev2_sa_t * sa, u8 * data, int len);
308int ikev2_encrypt_data (ikev2_sa_t * sa, v8 * src, u8 * dst);
309void ikev2_generate_dh (ikev2_sa_t * sa, ikev2_sa_transform_t * t);
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000310void ikev2_complete_dh (ikev2_sa_t * sa, ikev2_sa_transform_t * t);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700311int ikev2_verify_sign (EVP_PKEY * pkey, u8 * sigbuf, u8 * data);
312u8 *ikev2_calc_sign (EVP_PKEY * pkey, u8 * data);
313EVP_PKEY *ikev2_load_cert_file (u8 * file);
314EVP_PKEY *ikev2_load_key_file (u8 * file);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700315void ikev2_crypto_init (ikev2_main_t * km);
316
317/* ikev2_payload.c */
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700318typedef struct
319{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700320 u8 first_payload_type;
321 u16 last_hdr_off;
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700322 u8 *data;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700323} ikev2_payload_chain_t;
324
325#define ikev2_payload_new_chain(V) vec_validate (V, 0)
326#define ikev2_payload_destroy_chain(V) do { \
327 vec_free((V)->data); \
328 vec_free(V); \
329} while (0)
330
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700331void ikev2_payload_add_notify (ikev2_payload_chain_t * c, u16 msg_type,
332 u8 * data);
Radu Nicolaucb33dc22017-02-16 16:49:46 +0000333void ikev2_payload_add_notify_2 (ikev2_payload_chain_t * c, u16 msg_type,
334 u8 * data, ikev2_notify_t * notify);
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700335void ikev2_payload_add_sa (ikev2_payload_chain_t * c,
336 ikev2_sa_proposal_t * proposals);
337void ikev2_payload_add_ke (ikev2_payload_chain_t * c, u16 dh_group,
338 u8 * dh_data);
339void ikev2_payload_add_nonce (ikev2_payload_chain_t * c, u8 * nonce);
340void ikev2_payload_add_id (ikev2_payload_chain_t * c, ikev2_id_t * id,
341 u8 type);
342void ikev2_payload_add_auth (ikev2_payload_chain_t * c, ikev2_auth_t * auth);
343void ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts,
344 u8 type);
345void ikev2_payload_add_delete (ikev2_payload_chain_t * c, ikev2_delete_t * d);
346void ikev2_payload_chain_add_padding (ikev2_payload_chain_t * c, int bs);
347void ikev2_parse_vendor_payload (ike_payload_header_t * ikep);
348ikev2_sa_proposal_t *ikev2_parse_sa_payload (ike_payload_header_t * ikep);
349ikev2_ts_t *ikev2_parse_ts_payload (ike_payload_header_t * ikep);
350ikev2_delete_t *ikev2_parse_delete_payload (ike_payload_header_t * ikep);
351ikev2_notify_t *ikev2_parse_notify_payload (ike_payload_header_t * ikep);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700352
353#endif /* __included_ikev2_priv_h__ */
354
Keith Burns (alagalah)166a9d42016-08-06 11:00:56 -0700355
356/*
357 * fd.io coding-style-patch-verification: ON
358 *
359 * Local Variables:
360 * eval: (c-set-style "gnu")
361 * End:
362 */