1/*
2 * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#if IPSEC
30
31#include <sys/systm.h>
32#include <sys/socket.h>
33#include <net/if.h>
34#include <net/if_types.h>
35#include <net/if_utun.h>
36#include <sys/mbuf.h>
37#include <netinet/in.h>
38#include <netinet6/in6_var.h>
39#include <netinet6/in6_var.h>
40#include <netinet/ip.h>
41#include <netinet/ip6.h>
42#include <netinet/ip_var.h>
43#include <net/if_utun.h>
44#include <net/if_utun_crypto_ipsec.h>
45#include <netinet6/esp.h>
46#include <netinet6/esp6.h>
47#include <netinet6/ipsec.h>
48#include <net/bpf.h>
49
50extern lck_mtx_t *sadb_mutex;
51extern int        esp_udp_encap_port; // udp encap listening port
52extern int        ipsec_policy_count;
53extern int        ipsec_bypass;
54extern int        natt_keepalive_interval;
55
56static int        utun_punt_rx_keepalive = 0; // optional global control
57
58extern errno_t utun_pkt_input (struct utun_pcb *pcb, mbuf_t m);
59
60static u_int8_t
61utun_ipsec_mode_to_sadb_mode (if_utun_crypto_ipsec_mode_t mode)
62{
63	switch (mode) {
64	case IF_UTUN_CRYPTO_IPSEC_MODE_TRANSPORT:
65		return IPSEC_MODE_TRANSPORT;
66	case IF_UTUN_CRYPTO_IPSEC_MODE_TUNNEL:
67		return IPSEC_MODE_TUNNEL;
68	default:
69		return 0;
70	}
71}
72
73static u_int16_t
74utun_ipsec_proto_to_sadb_proto (if_utun_crypto_ipsec_proto_t proto)
75{
76	switch (proto) {
77		case IF_UTUN_CRYPTO_IPSEC_PROTO_ESP:
78			return IPPROTO_ESP;
79		case IF_UTUN_CRYPTO_IPSEC_PROTO_AH:
80			return IPPROTO_AH;
81		default:
82			return 0;
83    }
84}
85
86static u_int8_t
87utun_ipsec_proto_to_sadb_satype (if_utun_crypto_ipsec_proto_t proto)
88{
89	switch (proto) {
90	case IF_UTUN_CRYPTO_IPSEC_PROTO_ESP:
91		return SADB_SATYPE_ESP;
92	case IF_UTUN_CRYPTO_IPSEC_PROTO_AH:
93		return SADB_SATYPE_AH;
94	default:
95		return 0;
96    }
97}
98
99static u_int8_t
100utun_ipsec_auth_to_sadb_aalg (if_utun_crypto_ipsec_auth_t auth)
101{
102	switch (auth) {
103	case IF_UTUN_CRYPTO_IPSEC_AUTH_MD5:
104		return SADB_AALG_MD5HMAC;
105	case IF_UTUN_CRYPTO_IPSEC_AUTH_SHA1:
106		return SADB_AALG_SHA1HMAC;
107	case IF_UTUN_CRYPTO_IPSEC_AUTH_SHA256:
108		return SADB_X_AALG_SHA2_256;
109	case IF_UTUN_CRYPTO_IPSEC_AUTH_SHA384:
110		return SADB_X_AALG_SHA2_384;
111	case IF_UTUN_CRYPTO_IPSEC_AUTH_SHA512:
112		return SADB_X_AALG_SHA2_512;
113	default:
114		return 0;
115	}
116}
117
118static u_int8_t
119utun_ipsec_enc_to_sadb_ealg (if_utun_crypto_ipsec_enc_t enc)
120{
121	switch (enc) {
122	case IF_UTUN_CRYPTO_IPSEC_ENC_DES:
123		return SADB_EALG_DESCBC;
124	case IF_UTUN_CRYPTO_IPSEC_ENC_3DES:
125		return SADB_EALG_3DESCBC;
126	case IF_UTUN_CRYPTO_IPSEC_ENC_AES128:
127	case IF_UTUN_CRYPTO_IPSEC_ENC_AES256:
128		return SADB_X_EALG_AESCBC;
129	default:
130		return 0;
131	}
132}
133
134static u_int32_t
135utun_ipsec_keepalive_and_nat_info_to_sadb_flags (if_utun_crypto_ipsec_keepalive_t keepalive,
136						 int                              punt_rx_keepalive,
137						 if_utun_crypto_ipsec_natd_t      natd,
138						 u_int16_t                        natt_port)
139{
140	u_int32_t flags = 0;
141
142	if (natt_port && natt_port != 500) {
143		flags |= SADB_X_EXT_NATT;
144
145		switch (keepalive) {
146		case IF_UTUN_CRYPTO_IPSEC_KEEPALIVE_NATT:
147			flags |= SADB_X_EXT_NATT_KEEPALIVE; // normal keepalive packet
148			break;
149		case IF_UTUN_CRYPTO_IPSEC_KEEPALIVE_ESP:
150			flags |= (SADB_X_EXT_ESP_KEEPALIVE | SADB_X_EXT_PUNT_RX_KEEPALIVE); // use an EMPTY ESP as a keepalive
151			break;
152		default:
153			break;
154		}
155
156		switch (natd) {
157		case IF_UTUN_CRYPTO_IPSEC_NATD_PEER:
158			flags |= SADB_X_EXT_NATT_DETECTED_PEER;
159			break;
160		default:
161			break;
162		}
163	}
164
165	if (punt_rx_keepalive) {
166		flags |= SADB_X_EXT_PUNT_RX_KEEPALIVE;
167	}
168
169	return flags;
170}
171
172static errno_t
173utun_ipsec_set_sah (struct secashead        **sah,
174		    u_int8_t                  dir,
175		    u_int16_t                 proto,
176		    u_int8_t                  mode,
177		    u_int32_t                 reqid,
178		    struct sockaddr_storage  *src_addr,
179		    struct sockaddr_storage  *dst_addr)
180{
181	struct secasindex saidx;
182
183	// currently only support tunnel mode and ESP
184	if (proto != IPPROTO_ESP ||
185	    mode != IPSEC_MODE_TUNNEL) {
186		return EINVAL;
187	}
188	if ((((struct sockaddr *)src_addr)->sa_family != AF_INET &&
189	     ((struct sockaddr *)src_addr)->sa_family != AF_INET6) ||
190	    (((struct sockaddr *)dst_addr)->sa_family != AF_INET &&
191	     ((struct sockaddr *)dst_addr)->sa_family != AF_INET6)) {
192		return EINVAL;
193	}
194
195	bzero(&saidx, sizeof(saidx));
196	saidx.proto = proto;
197	saidx.mode = mode;
198	saidx.reqid = reqid;
199	bcopy(src_addr, &saidx.src, sizeof(saidx.src));
200	bcopy(dst_addr, &saidx.dst, sizeof(saidx.dst));
201
202	lck_mtx_lock(sadb_mutex);
203	// TODO: add sah and policy (collision) check and prevention. ensure that there is no conflicting policy.
204	// TDDO: ensure that key_spdaddxxx doesn't add a policy that's conflicting with any of our sahs.
205	*sah = key_newsah2(&saidx, dir);
206	lck_mtx_unlock(sadb_mutex);
207	return 0;
208}
209
210static int
211utun_ipsec_clr_sahs (struct secashead **sah)
212{
213	struct secasvar *sav;
214	struct secasvar *nextsav;
215	u_int            state;
216
217	lck_mtx_lock(sadb_mutex);
218	for (state = 0; state < SADB_SASTATE_MAX; state++) {
219		for (sav = LIST_FIRST(&(*sah)->savtree[state]);
220		     sav != NULL;
221		     sav = nextsav) {
222			nextsav = LIST_NEXT(sav, chain);
223			if (sav->state == SADB_SASTATE_LARVAL ||
224				sav->state == SADB_SASTATE_DEAD) {
225				continue;
226			}
227
228			if (sav->utun_pcb) {
229				sav->utun_pcb = NULL;
230				sav->utun_is_keepalive_fn = NULL;
231				sav->utun_in_fn = NULL;
232				sav->refcnt--; // unlinked from pcb
233			} else {
234				printf("%s: SAV inconsistency\n", __FUNCTION__);
235			}
236
237			key_sa_chgstate(sav, SADB_SASTATE_DEAD);
238			key_freesav(sav, KEY_SADB_LOCKED);
239		}
240	}
241
242	// clear the rest of the SAs
243	key_delsah(*sah);
244	lck_mtx_unlock(sadb_mutex);
245	return 0;
246}
247
248static void
249utun_ipsec_set_udp_encap_listen_port (utun_crypto_dir_t dir,
250				      u_int16_t         natt_port)
251{
252	if (dir == UTUN_CRYPTO_DIR_IN) {
253		if (natt_port && natt_port != 500) {
254			esp_udp_encap_port = natt_port;
255		}
256	}
257}
258
259static void
260utun_set_lifetime (struct sadb_lifetime *lfh,
261		   int                   type,
262		   u_int64_t             l_time)
263{
264	lfh->sadb_lifetime_len = (sizeof(*lfh) >> 3); // convert to words
265	lfh->sadb_lifetime_exttype = type;
266	lfh->sadb_lifetime_allocations = 0;
267	lfh->sadb_lifetime_bytes = 0;
268	lfh->sadb_lifetime_addtime = l_time;
269	lfh->sadb_lifetime_usetime = l_time;
270}
271
272static struct sadb_key *
273utun_ipsec_set_keybuf (u_int16_t  type,
274		       u_int8_t  *key,
275		       u_int16_t  key_len)
276{
277	struct sadb_key *new;
278	int len = sizeof(*new) + BITSTOBYTES(key_len);
279
280	lck_mtx_lock(sadb_mutex);
281	new = utun_alloc(len);
282	if (new == NULL) {
283		return NULL;
284	}
285	lck_mtx_unlock(sadb_mutex);
286	bzero(new, len);
287	new->sadb_key_len = BITSTOBYTES(key_len);
288	new->sadb_key_exttype = type;
289	new->sadb_key_bits = key_len;
290	bcopy(key, &new[1], new->sadb_key_len);
291	return new;
292}
293
294static errno_t
295utun_ipsec_alloc_sav (struct secashead                *sah,
296		      struct secasvar                **sav,
297		      struct utun_pcb                 *pcb,
298		      u_int8_t                         satype,
299		      u_int8_t                         alg_auth,
300		      u_int8_t                         alg_enc,
301		      u_int32_t                        flags,
302		      u_int8_t                         replay,
303		      u_int8_t                        *key_auth,
304		      u_int16_t                        key_auth_len,
305		      u_int8_t                        *key_enc,
306		      u_int16_t                        key_enc_len,
307		      u_int16_t                        natt_port,
308		      u_int32_t                        seq,
309		      u_int32_t                        spi,
310		      u_int32_t                        pid,
311		      u_int64_t                        lifetime_hard,
312		      u_int64_t                        lifetime_soft)
313{
314	struct sadb_key      *keye, *keya;
315	struct sadb_lifetime  lfh, lfs;
316
317	if (*sav) {
318		return EINVAL;
319	}
320
321	bzero(&lfh, sizeof(lfh));
322	utun_set_lifetime(&lfh, SADB_EXT_LIFETIME_HARD, lifetime_hard);
323	bzero(&lfs, sizeof(lfs));
324	utun_set_lifetime(&lfs, SADB_EXT_LIFETIME_SOFT, lifetime_soft);
325
326	if ((keya = utun_ipsec_set_keybuf(SADB_EXT_KEY_AUTH, key_auth, key_auth_len)) == NULL) {
327		return ENOBUFS;
328	}
329	if ((keye = utun_ipsec_set_keybuf(SADB_EXT_KEY_ENCRYPT, key_enc, key_enc_len)) == NULL) {
330		utun_free(keya);
331		return ENOBUFS;
332	}
333
334	lck_mtx_lock(sadb_mutex);
335	if ((*sav = key_newsav2(sah,
336				satype,
337				alg_auth,
338				alg_enc,
339				flags,
340				replay,
341				keya,
342				key_auth_len,
343				keye,
344				key_enc_len,
345				natt_port,
346				seq,
347				spi,
348				pid,
349				&lfh,
350				&lfs)) == NULL) {
351		lck_mtx_unlock(sadb_mutex);
352		utun_free(keya);
353		utun_free(keye);
354		return ENOBUFS;
355	}
356	(*sav)->utun_pcb = (__typeof__((*sav)->utun_pcb))pcb;
357	(*sav)->utun_is_keepalive_fn = (__typeof__((*sav)->utun_is_keepalive_fn))utun_pkt_is_ipsec_keepalive;
358	(*sav)->utun_in_fn = (__typeof__((*sav)->utun_in_fn))utun_pkt_ipsec_input;
359	(*sav)->refcnt++; // for the pcb
360	lck_mtx_unlock(sadb_mutex);
361	utun_free(keya);
362	utun_free(keye);
363	return 0;
364}
365
366static int
367utun_ipsec_free_sav (struct secasvar  **sav)
368{
369	lck_mtx_lock(sadb_mutex);
370	if ((*sav)->utun_pcb) {
371		(*sav)->utun_pcb = NULL;
372		(*sav)->utun_is_keepalive_fn = NULL;
373		(*sav)->utun_in_fn = NULL;
374	}
375	(*sav)->refcnt--; // unlinked from pcb
376	key_sa_chgstate(*sav, SADB_SASTATE_DEAD);
377	key_freesav(*sav, KEY_SADB_LOCKED);
378	lck_mtx_unlock(sadb_mutex);
379	*sav = NULL;
380	return 0;
381}
382
383static int
384utun_ipsec_num_savs (struct secashead **sah)
385{
386	struct secasvar *sav;
387	struct secasvar *nextsav;
388	u_int            state;
389	int              n = 0;
390
391	lck_mtx_lock(sadb_mutex);
392	for (state = 0; state < SADB_SASTATE_MAX; state++) {
393		for (sav = LIST_FIRST(&(*sah)->savtree[state]);
394		     sav != NULL;
395		     sav = nextsav) {
396			nextsav = LIST_NEXT(sav, chain);
397			if (sav->state == SADB_SASTATE_LARVAL ||
398			    sav->state == SADB_SASTATE_DYING ||
399			    sav->state == SADB_SASTATE_DEAD) {
400				continue;
401			}
402
403			if (sav->utun_pcb) {
404				n++;
405			} else {
406				printf("%s: SAV inconsistency\n", __FUNCTION__);
407			}
408		}
409	}
410	lck_mtx_unlock(sadb_mutex);
411
412	return n;
413}
414
415static errno_t
416utun_ctl_config_crypto_keys_ipsec_v1 (struct utun_pcb         *pcb,
417				      utun_crypto_keys_args_t *args,
418				      utun_crypto_keys_t      *crypto_keys)
419{
420	utun_crypto_keys_ipsec_args_v1_t *args_ipsec_v1 = &args->u.ipsec_v1;
421	u_int8_t                         *varargs_buf = UTUN_CRYPTO_KEYS_ARGS_VARARGS_BUF(args);
422	errno_t                           err;
423	struct secashead                 *sah;
424	u_int16_t                         proto;
425	u_int8_t                          mode;
426	u_int8_t                          satype, aalg, ealg;
427	u_int32_t                         flags;
428
429	if (args_ipsec_v1->key_auth_len > MAX_KEY_AUTH_LEN_BITS) {
430		printf("%s: invalid auth key len %d, max %d\n", __FUNCTION__,
431		       args_ipsec_v1->key_auth_len, MAX_KEY_AUTH_LEN_BITS);
432		return EINVAL;
433	}
434	if (args_ipsec_v1->key_enc_len > MAX_KEY_ENC_LEN_BITS) {
435		printf("%s: invalid enc key len %d, max %d\n", __FUNCTION__,
436		       args_ipsec_v1->key_enc_len, MAX_KEY_ENC_LEN_BITS);
437		return EINVAL;
438	}
439	if (args->varargs_buflen != (__typeof__(args->varargs_buflen))((BITSTOBYTES(args_ipsec_v1->key_auth_len) +
440									BITSTOBYTES(args_ipsec_v1->key_enc_len)))) {
441		printf("%s: len check failed (%d,%d, %d)\n", __FUNCTION__,
442		       args->varargs_buflen, args_ipsec_v1->key_auth_len, args_ipsec_v1->key_enc_len);
443		return EINVAL;
444	}
445	sah = IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAH(crypto_keys);
446	if (!sah) {
447		// TODO: make sure we pass through this once
448		proto = utun_ipsec_proto_to_sadb_proto(args_ipsec_v1->proto);
449		mode = utun_ipsec_mode_to_sadb_mode(args_ipsec_v1->mode);
450
451		if ((err = utun_ipsec_set_sah(&IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAH(crypto_keys),
452					      UTUN_CRYPTO_DIR_TO_IPSEC_DIR(args->dir),
453					      proto,
454					      mode,
455					      args_ipsec_v1->reqid,
456					      &args_ipsec_v1->src_addr,
457					      &args_ipsec_v1->dst_addr))) {
458			return err;
459		}
460		sah = IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAH(crypto_keys);
461		if (!sah) {
462			return EBADF;
463		}
464	}
465
466	satype = utun_ipsec_proto_to_sadb_satype(args_ipsec_v1->proto);
467	aalg = utun_ipsec_auth_to_sadb_aalg(args_ipsec_v1->alg_auth);
468	ealg = utun_ipsec_enc_to_sadb_ealg(args_ipsec_v1->alg_enc);
469	flags = utun_ipsec_keepalive_and_nat_info_to_sadb_flags(args_ipsec_v1->keepalive,
470								args_ipsec_v1->punt_rx_keepalive,
471								args_ipsec_v1->natd,
472								args_ipsec_v1->natt_port);
473
474	if ((err = utun_ipsec_alloc_sav(sah,
475					&IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAV(crypto_keys),
476					pcb,
477					satype,
478					aalg,
479					ealg,
480					flags,
481					args_ipsec_v1->replay,
482					varargs_buf,
483					args_ipsec_v1->key_auth_len,
484					(varargs_buf + BITSTOBYTES(args_ipsec_v1->key_auth_len)),
485					args_ipsec_v1->key_enc_len,
486					args_ipsec_v1->natt_port,
487					args_ipsec_v1->seq,
488					args_ipsec_v1->spi,
489					args_ipsec_v1->pid,
490					args_ipsec_v1->lifetime_hard,
491					args_ipsec_v1->lifetime_soft))) {
492		return err;
493	}
494	crypto_keys->state.u.ipsec.proto = sah->saidx.proto;
495	crypto_keys->state.u.ipsec.mode = sah->saidx.mode;
496	if (((struct sockaddr *)&sah->saidx.src)->sa_family == AF_INET) {
497		crypto_keys->state.u.ipsec.ifamily = IPPROTO_IPV4;
498	} else {
499		crypto_keys->state.u.ipsec.ifamily = IPPROTO_IPV6;
500	}
501	crypto_keys->state.u.ipsec.spi = args_ipsec_v1->spi;
502	utun_ipsec_set_udp_encap_listen_port(args->dir, args_ipsec_v1->natt_port);
503	return 0;
504}
505
506static errno_t
507utun_ctl_unconfig_crypto_keys_ipsec_v1 (utun_crypto_keys_t *crypto_keys)
508{
509	if (!IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAH(crypto_keys)) {
510		return EBADF;
511	}
512	if (!IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAV(crypto_keys)) {
513		return EBADF;
514	}
515	if (utun_ipsec_free_sav(&IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAV(crypto_keys))) {
516		return EADDRNOTAVAIL;
517	}
518	if (!utun_ipsec_num_savs(&IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAH(crypto_keys))) {
519		(void)utun_ipsec_clr_sahs(&IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAH(crypto_keys));
520
521		// release sah
522		IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAH(crypto_keys) = NULL;
523	}
524
525	return 0;
526}
527
528static void
529utun_set_spirange (struct sadb_spirange *spirange,
530		   u_int32_t             spirange_min,
531		   u_int32_t             spirange_max)
532{
533	spirange->sadb_spirange_min = spirange_min;
534	spirange->sadb_spirange_max = spirange_max;
535}
536
537static u_int32_t
538utun_ipsec_get_spi (struct sockaddr_storage  *src_addr,
539		    struct sockaddr_storage  *dst_addr,
540		    u_int16_t                 proto,
541		    u_int8_t                  mode,
542		    u_int32_t                 reqid,
543		    u_int32_t         spirange_min,
544		    u_int32_t         spirange_max)
545{
546	struct sadb_spirange spirange;
547	utun_set_spirange(&spirange, spirange_min, spirange_max);
548	// TODO: should this allocate an SAH?
549	return key_getspi2((struct sockaddr *)src_addr,
550			   (struct sockaddr *)dst_addr,
551			   proto,
552			   mode,
553			   reqid,
554			   &spirange);
555}
556
557static errno_t
558utun_ctl_generate_crypto_keys_idx_ipsec_v1 (utun_crypto_keys_idx_args_t *args)
559{
560	utun_crypto_keys_idx_ipsec_args_v1_t *args_ipsec_v1 = &args->u.ipsec_v1;
561	u_int16_t                             proto;
562	u_int8_t                              mode;
563
564	proto = utun_ipsec_proto_to_sadb_proto(args_ipsec_v1->proto);
565	mode = utun_ipsec_mode_to_sadb_mode(args_ipsec_v1->mode);
566
567	args_ipsec_v1->spi = 0;
568	if ((args_ipsec_v1->spi = utun_ipsec_get_spi(&args_ipsec_v1->src_addr,
569						     &args_ipsec_v1->dst_addr,
570						     proto,
571						     mode,
572						     args_ipsec_v1->reqid,
573						     args_ipsec_v1->spirange_min,
574						     args_ipsec_v1->spirange_max)) == 0) {
575		return ENOBUFS;
576	}
577	return 0;
578}
579
580void
581utun_cleanup_all_crypto_ipsec (struct utun_pcb   *pcb)
582{
583	int                 idx;
584	utun_crypto_ctx_t  *crypto_ctx;
585	utun_crypto_keys_t *cur_crypto_keys, *nxt_crypto_keys;
586
587	for (idx = 0; idx < UTUN_CRYPTO_DIR_TO_IDX(UTUN_CRYPTO_DIR_MAX); idx++) {
588		crypto_ctx = &pcb->utun_crypto_ctx[idx];
589		if (!crypto_ctx->valid ||
590		    crypto_ctx->type != UTUN_CRYPTO_TYPE_IPSEC) {
591			continue;
592		}
593
594		// flush all crypto materials
595		for (cur_crypto_keys = (__typeof__(cur_crypto_keys))LIST_FIRST(&crypto_ctx->keys_listhead);
596		     cur_crypto_keys != NULL;
597		     cur_crypto_keys = nxt_crypto_keys) {
598			nxt_crypto_keys = (__typeof__(nxt_crypto_keys))LIST_NEXT(cur_crypto_keys, chain);
599
600			if (!cur_crypto_keys->valid) {
601				continue;
602			}
603
604			if (IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAV(cur_crypto_keys)) {
605				(void)utun_ipsec_free_sav(&IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAV(cur_crypto_keys));
606			}
607
608			if (IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAH(cur_crypto_keys)) {
609				(void)utun_ipsec_clr_sahs(&IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAH(cur_crypto_keys));
610			}
611
612			LIST_REMOVE(cur_crypto_keys, chain);
613			bzero(cur_crypto_keys, sizeof(*cur_crypto_keys));
614			utun_free(cur_crypto_keys);
615		}
616
617		bzero(crypto_ctx, sizeof(*crypto_ctx));
618	}
619}
620
621static errno_t
622utun_ctl_enable_crypto_ipsec_v1 (__unused utun_crypto_args_t *args)
623{
624	return 0;
625}
626
627/*
628 * Summary: enables ipsec crypto info for the specified utun.
629 */
630void
631utun_ctl_enable_crypto_ipsec(__unused struct utun_pcb    *pcb,
632			     utun_crypto_args_t *args)
633{
634	lck_mtx_lock(sadb_mutex);
635	/* Turn off the ipsec bypass, if already on */
636	if (ipsec_bypass) {
637		ipsec_bypass = 0;
638	}
639	if (args->ver == UTUN_CRYPTO_KEYS_IPSEC_VER_1) {
640		(void)utun_ctl_enable_crypto_ipsec_v1(args);
641	}
642	lck_mtx_unlock(sadb_mutex);
643}
644
645/*
646 * Summary: disables ipsec crypto info for the specified utun.
647 */
648void
649utun_ctl_disable_crypto_ipsec(__unused struct utun_pcb   *pcb)
650{
651	utun_cleanup_all_crypto_ipsec(pcb);
652	lck_mtx_lock(sadb_mutex);
653	/* Turn on the ipsec bypass, if there are no other policies */
654	if (!ipsec_policy_count && !ipsec_bypass) // TODO: ipsec_policy_count may be 1 by default
655		ipsec_bypass = 1;
656	utun_punt_rx_keepalive = 0;
657	lck_mtx_unlock(sadb_mutex);
658}
659
660errno_t
661utun_ctl_config_crypto_keys_ipsec (struct utun_pcb         *pcb,
662				   utun_crypto_keys_args_t *args,
663				   utun_crypto_keys_t      *crypto_keys)
664{
665	if (args->ver == UTUN_CRYPTO_KEYS_IPSEC_VER_1) {
666		return(utun_ctl_config_crypto_keys_ipsec_v1(pcb, args, crypto_keys));
667	} else {
668		printf("%s: ver unsupported (%d, %d)\n", __FUNCTION__, args->ver, UTUN_CRYPTO_KEYS_IPSEC_VER_1);
669		return EINVAL;
670	}
671}
672
673errno_t
674utun_ctl_unconfig_crypto_keys_ipsec (utun_crypto_keys_args_t *args,
675				     utun_crypto_keys_t      *crypto_keys)
676{
677	if (args->ver == UTUN_CRYPTO_KEYS_IPSEC_VER_1) {
678		return(utun_ctl_unconfig_crypto_keys_ipsec_v1(crypto_keys));
679	} else {
680		printf("%s: ver unsupported (%d, %d)\n", __FUNCTION__, args->ver, UTUN_CRYPTO_KEYS_IPSEC_VER_1);
681		return EINVAL;
682	}
683}
684
685errno_t
686utun_ctl_generate_crypto_keys_idx_ipsec (utun_crypto_keys_idx_args_t *args)
687{
688	if (args->ver == UTUN_CRYPTO_KEYS_IPSEC_VER_1) {
689		return(utun_ctl_generate_crypto_keys_idx_ipsec_v1(args));
690	} else {
691		printf("%s: ver unsupported (%d, %d)\n", __FUNCTION__, args->ver, UTUN_CRYPTO_KEYS_IPSEC_VER_1);
692		return EINVAL;
693	}
694}
695
696int
697utun_pkt_ipsec_output (struct utun_pcb *pcb, mbuf_t *pkt)
698{
699	utun_crypto_keys_t *crypto_keys = IF_UTUN_GET_TX_CRYPTO_KEYS(pcb);
700	struct secasvar    *sav;
701	protocol_family_t   proto;
702	mbuf_t              new;
703	int                 err;
704	struct route       *ro = NULL;
705	struct route        ro_copy;
706	struct ip_out_args  ipoa =
707	    { IFSCOPE_NONE, { 0 }, IPOAF_SELECT_SRCIF, 0 };
708
709	if (crypto_keys &&
710	    crypto_keys->state.u.ipsec.proto == IPPROTO_ESP &&
711	    (sav = IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAV(crypto_keys)) &&
712	    sav->state == SADB_SASTATE_MATURE) {
713		// TODO: update stats to increment outgoing packets
714		// TODO: allow empty packets thru
715
716		proto = *(mtod(*pkt, protocol_family_t *));
717		m_adj(*pkt, sizeof(protocol_family_t));
718
719		bzero(&ro_copy, sizeof(ro_copy));
720
721		if ((proto == AF_UTUN || proto == AF_INET) && crypto_keys->state.u.ipsec.ifamily == IPPROTO_IPV4) {
722			struct ip          *ip;
723			struct sockaddr_in *dst4;
724
725			if (proto == AF_INET) {
726				if ((*pkt)->m_len < (__typeof__((*pkt)->m_len))sizeof(*ip)) {
727					if (!(*pkt = m_pullup(*pkt, sizeof(*ip)))) {
728						printf("%s: m_pullup failed\n", __FUNCTION__);
729						return 0;
730					}
731				}
732
733				// split the mbuf chain to put the ip header and payloads in separate mbufs
734				new = ipsec4_splithdr(*pkt);
735				if (!new) {
736					printf("%s: ipsec4_splithdr(1) failed\n", __FUNCTION__);
737					ROUTE_RELEASE(&ro_copy);
738					*pkt = NULL;
739					return 0;
740				}
741				*pkt = new;
742
743				// encapsulate with the outer header
744				if ((err = ipsec4_encapsulate(new, sav))) {
745					printf("%s: ipsec4_encapsulate failed (%d)\n", __FUNCTION__, err);
746					*pkt = NULL;
747					return 0;
748				}
749
750			} else {
751				// otherwise it's AF_UTUN which will be a keepalive packet to be encapsulated, encrypted and sent
752				// encapsulate with the outer header
753				if ((err = ipsec4_encapsulate_utun_esp_keepalive(pkt, sav))) {
754					printf("%s: ipsec4_encapsulate failed (%d)\n", __FUNCTION__, err);
755					return 0;
756				}
757				new = *pkt;
758			}
759
760			ip = mtod(new, __typeof__(ip));
761			// grab sadb_mutex, to update sah's route cache and get a local copy of it
762			lck_mtx_lock(sadb_mutex);
763			ro = &sav->sah->sa_route;
764			dst4 = (struct sockaddr_in *)(void *)&ro->ro_dst;
765			if (ro->ro_rt) {
766				RT_LOCK(ro->ro_rt);
767			}
768			if (ROUTE_UNUSABLE(ro) ||
769			    dst4->sin_addr.s_addr != ip->ip_dst.s_addr) {
770				if (ro->ro_rt != NULL)
771					RT_UNLOCK(ro->ro_rt);
772				ROUTE_RELEASE(ro);
773			}
774			if (ro->ro_rt == NULL) {
775				dst4->sin_family = AF_INET;
776				dst4->sin_len = sizeof(*dst4);
777				dst4->sin_addr = ip->ip_dst;
778				rtalloc(ro);
779				if (ro->ro_rt) {
780					RT_LOCK(ro->ro_rt);
781				} else {
782					printf("%s: rtalloc(1) failed\n", __FUNCTION__);
783					mbuf_freem(new);
784					*pkt = NULL;
785					return 0;
786				}
787			}
788			if (ro->ro_rt->rt_flags & RTF_GATEWAY) {
789				dst4 = (struct sockaddr_in *)(void *)ro->ro_rt->rt_gateway;
790			}
791			RT_UNLOCK(ro->ro_rt);
792			route_copyout(&ro_copy, ro, sizeof(ro_copy));
793			// release sadb_mutex, after updating sah's route cache and getting a local copy
794			lck_mtx_unlock(sadb_mutex);
795
796			// split the mbuf chain to put the ip header and payloads in separate mbufs
797			new = ipsec4_splithdr(*pkt);
798			if (!new) {
799				printf("%s: ipsec4_splithdr(2) failed\n", __FUNCTION__);
800				ROUTE_RELEASE(&ro_copy);
801				*pkt = NULL;
802				return 0;
803			}
804			*pkt = new;
805
806			if ((err = esp4_output(new, sav))) {
807				printf("%s: esp4_output failed (%d)\n", __FUNCTION__, err);
808				ROUTE_RELEASE(&ro_copy);
809				*pkt = NULL;
810				return 0; // drop
811			}
812
813			ip = mtod(new, __typeof__(ip));
814			ip->ip_len = ntohs(ip->ip_len);  /* flip len field before calling ip_output */
815		} else if ((proto == AF_UTUN || proto == AF_INET6) && crypto_keys->state.u.ipsec.ifamily == IPPROTO_IPV6) {
816			int                  plen;
817			struct ip6_hdr      *ip6;
818			struct sockaddr_in6 *dst6;
819
820			if (proto == AF_INET6) {
821				// split the mbuf chain to put the ip header and payloads in separate mbufs
822				new = ipsec6_splithdr(*pkt);
823				if (!new) {
824					printf("%s: ipsec6_splithdr(1) failed\n", __FUNCTION__);
825					ROUTE_RELEASE(&ro_copy);
826					*pkt = NULL;
827					return 0;
828				}
829				*pkt = new;
830
831				// encapsulate with the outer header
832				if ((err = ipsec6_encapsulate(new, sav))) {
833					printf("%s: ipsec6_encapsulate failed (%d)\n", __FUNCTION__, err);
834					*pkt = NULL;
835					return 0;
836				}
837
838			} else {
839				// otherwise it's AF_UTUN which will be a keepalive packet to be encapsulated, encrypted and sent
840				// encapsulate with the outer header
841				if ((err = ipsec6_encapsulate_utun_esp_keepalive(pkt, sav))) {
842					printf("%s: ipsec6_encapsulate failed (%d)\n", __FUNCTION__, err);
843					return 0;
844				}
845				new = *pkt;
846			}
847
848			ip6 = mtod(new, __typeof__(ip6));
849			// grab sadb_mutex, before updating sah's route cache
850			lck_mtx_lock(sadb_mutex);
851			ro = &sav->sah->sa_route;
852			dst6 = (struct sockaddr_in6 *)(void *)&ro->ro_dst;
853			if (ro->ro_rt) {
854				RT_LOCK(ro->ro_rt);
855			}
856			if (ROUTE_UNUSABLE(ro) ||
857			    !IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ip6->ip6_dst)) {
858				if (ro->ro_rt != NULL)
859					RT_UNLOCK(ro->ro_rt);
860				ROUTE_RELEASE(ro);
861			}
862			if (ro->ro_rt == NULL) {
863				bzero(dst6, sizeof(*dst6));
864				dst6->sin6_family = AF_INET6;
865				dst6->sin6_len = sizeof(*dst6);
866				dst6->sin6_addr = ip6->ip6_dst;
867				rtalloc(ro);
868				if (ro->ro_rt) {
869					RT_LOCK(ro->ro_rt);
870				} else {
871					printf("%s: rtalloc(2) failed\n", __FUNCTION__);
872					mbuf_freem(new);
873					*pkt = NULL;
874					return 0;
875				}
876			}
877			if (ro->ro_rt->rt_flags & RTF_GATEWAY) {
878				dst6 = (struct sockaddr_in6 *)(void *)ro->ro_rt->rt_gateway;
879			}
880			RT_UNLOCK(ro->ro_rt);
881			route_copyout(&ro_copy, ro, sizeof(ro_copy));
882			// release sadb_mutex, after updating sah's route cache and getting a local copy
883			lck_mtx_unlock(sadb_mutex);
884
885			// split the mbuf chain to put the ip header and payloads in separate mbufs
886			new = ipsec6_splithdr(*pkt);
887			if (!new) {
888				printf("%s: ipsec6_splithdr failed\n", __FUNCTION__);
889				ROUTE_RELEASE(&ro_copy);
890				*pkt = NULL;
891				return 0;
892			}
893			*pkt = new;
894
895			if ((err = esp6_output(new, mtod(new, u_char *), new->m_next, sav))) {
896				printf("%s: esp6_output failed (%d)\n", __FUNCTION__, err);
897				ROUTE_RELEASE(&ro_copy);
898				*pkt = NULL;
899				return 0; // drop
900			}
901
902			plen = new->m_pkthdr.len - sizeof(struct ip6_hdr);
903			if (plen > IPV6_MAXPACKET) {
904				printf("%s: esp6_output failed due to invalid len (%d)\n", __FUNCTION__, plen);
905				ROUTE_RELEASE(&ro_copy);
906				mbuf_freem(new);
907				*pkt = NULL;
908				return 0;
909			}
910			ip6 = mtod(new, __typeof__(ip6));
911			ip6->ip6_plen = ntohs(ip6->ip6_plen);  /* flip len field before calling ip_output */
912		} else {
913			printf("%s: packet's proto (%d) mismatched the context's proto (%d)\n", __FUNCTION__,
914				   proto, crypto_keys->state.u.ipsec.ifamily);
915			mbuf_freem(*pkt);
916			*pkt = NULL;
917			return 0;
918		}
919
920		if (pcb->utun_ifp) {
921			ifnet_stat_increment_out(pcb->utun_ifp, 1, mbuf_pkthdr_len(new), 0);
922		}
923
924		if ((err = ip_output(new, NULL, &ro_copy,
925		    (IP_OUTARGS | IP_NOIPSEC), NULL, &ipoa))) {
926			printf("%s: ip_output failed (%d)\n", __FUNCTION__, err);
927		}
928		lck_mtx_lock(sadb_mutex);
929		route_copyin(&ro_copy, ro, sizeof(*ro));
930		lck_mtx_unlock(sadb_mutex);
931		return 0;
932	} else {
933		printf("%s: no suitable crypto-mat\n", __FUNCTION__);
934	}
935	return -1;
936}
937
938// returns 0 if false, 1 if true, and -1 if there was a failure
939int
940utun_pkt_is_ipsec_keepalive (struct utun_pcb *pcb, mbuf_t *pkt, u_int16_t nxt, u_int32_t flags, size_t offs)
941{
942	int result;
943	u_int8_t *data;
944	int size_diff;
945
946	if (!pcb->utun_ctlref) {
947		printf("%s - utun ctlref cleared\n", __FUNCTION__);
948		return 0;
949	}
950
951	if (!(pcb->utun_flags & UTUN_FLAGS_CRYPTO)) {
952		printf("%s - crypto disabled\n", __FUNCTION__);
953		return 0;
954	}
955
956	if ((*pkt)->m_pkthdr.len < 0) {
957		printf("%s - invalid hdr len, len %d, offs %lu\n", __FUNCTION__, (*pkt)->m_pkthdr.len, offs);
958		return 0;
959	}
960
961	if ((size_t)(*pkt)->m_pkthdr.len <= offs) {
962		printf("%s - invalid offset, len %d, offs %lu\n", __FUNCTION__, (*pkt)->m_pkthdr.len, offs);
963		return 0;
964	}
965
966	if ((*pkt)->m_len < 0) {
967		printf("%s - invalid len, len %d, offs %lu\n", __FUNCTION__, (*pkt)->m_len, offs);
968		return 0;
969	}
970
971	// pullup offs + 1 bytes
972	if ((size_t)(*pkt)->m_len < (offs + 1)) {
973		if ((*pkt = m_pullup(*pkt, (offs + 1))) == NULL) {
974			printf("%s: m_pullup failed\n", __FUNCTION__);
975			return -1;
976		}
977	}
978
979	if (pcb->utun_ifp) {
980		ifnet_stat_increment_in(pcb->utun_ifp, 1, mbuf_pkthdr_len(*pkt), 0);
981	}
982
983	size_diff = (*pkt)->m_pkthdr.len - offs;
984	data = mtod(*pkt, __typeof(data));
985	data += offs;
986
987	// ESP keepalive meets all these conditions: ESP trailer's next proto indicates IP, the decrypted packet only has one zero'd byte in it.
988	if (flags & SADB_X_EXT_ESP_KEEPALIVE &&
989	    nxt == IPPROTO_IPV4 &&
990	    size_diff == 1 &&
991	    *data == 0) {
992		// TODO: update stats to increment keepalives and current timestamp
993		if (utun_punt_rx_keepalive ||
994			flags & SADB_X_EXT_PUNT_RX_KEEPALIVE) {
995
996			// strip all headers
997			if ((size_t)(*pkt)->m_len >= (offs + size_diff)) {
998				ovbcopy((caddr_t)data, (data + offs), size_diff);
999				(*pkt)->m_data += offs;
1000				(*pkt)->m_len -= offs;
1001				(*pkt)->m_pkthdr.len -= offs;
1002			} else {
1003				struct mbuf *n;
1004
1005				n = m_split(*pkt, offs, M_DONTWAIT);
1006				if (n == NULL) {
1007					/* *pkt is retained by m_split */
1008					mbuf_freem(*pkt);
1009					*pkt = NULL;
1010					return -1;
1011				}
1012				m_adj(n, offs);
1013				mbuf_freem(*pkt);
1014				*pkt = n;
1015			}
1016
1017			// keepalive is being punted up to the control socket, prepend with a special packet type (PF_UTUN)
1018			if (mbuf_prepend(pkt, sizeof(protocol_family_t), MBUF_DONTWAIT) != 0) {
1019				printf("%s - ifnet_output prepend failed\n", __FUNCTION__);
1020				return -1;
1021			}
1022			if ((size_t)(*pkt)->m_len < (sizeof(protocol_family_t) + size_diff)) {
1023				if ((*pkt = m_pullup(*pkt, (sizeof(protocol_family_t) + size_diff))) == NULL) {
1024					printf("%s: m_pullup failed\n", __FUNCTION__);
1025					return -1;
1026				}
1027			}
1028
1029			// mark UTUN/Keepalive packet
1030			*(protocol_family_t *)mbuf_data(*pkt) = htonl(PF_UTUN);
1031
1032			result = ctl_enqueuembuf(pcb->utun_ctlref, pcb->utun_unit, *pkt, CTL_DATA_EOR);
1033			if (result != 0) {
1034				printf("%s: - ctl_enqueuembuf failed: %d\n", __FUNCTION__, result);
1035				mbuf_freem(*pkt);
1036				return -1;
1037			}
1038			*pkt = NULL;
1039		}
1040		return 1;
1041	}
1042	return 0;
1043}
1044
1045int
1046utun_pkt_ipsec_input (struct utun_pcb *pcb, mbuf_t *pkt, protocol_family_t family)
1047{
1048	if (!m_tag_locate(*pkt, KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_IPSEC, NULL)) {
1049		return EINVAL;
1050	}
1051
1052	if (!(pcb->utun_flags & UTUN_FLAGS_CRYPTO)) {
1053		printf("%s - crypto disabled\n", __FUNCTION__);
1054		return EINVAL;
1055	}
1056
1057	if (!pcb->utun_ifp) {
1058		printf("%s - utun ifp cleared\n", __FUNCTION__);
1059		return EINVAL;
1060	}
1061
1062	// place protocol number at the beginning of the mbuf
1063	if (mbuf_prepend(pkt, sizeof(protocol_family_t), MBUF_DONTWAIT) != 0) {
1064		printf("%s - ifnet_output prepend failed\n", __FUNCTION__);
1065		return ENOBUFS;
1066	}
1067	*(protocol_family_t *)mbuf_data(*pkt) = family;
1068
1069	(void)utun_pkt_input(pcb, *pkt);
1070	return 0;
1071}
1072
1073#endif /* IPSEC */
1074