]> git.saurik.com Git - apple/xnu.git/blame - bsd/net/if_utun_crypto_ipsec.c
xnu-2050.18.24.tar.gz
[apple/xnu.git] / bsd / net / if_utun_crypto_ipsec.c
CommitLineData
316670eb
A
1/*
2 * Copyright (c) 2011-2012 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
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 = { IFSCOPE_NONE, { 0 }, IPOAF_SELECT_SRCIF };
707
708 if (crypto_keys &&
709 crypto_keys->state.u.ipsec.proto == IPPROTO_ESP &&
710 (sav = IF_UTUN_GET_CRYPTO_KEYS_IPSEC_SAV(crypto_keys)) &&
711 sav->state == SADB_SASTATE_MATURE) {
712 // TODO: update stats to increment outgoing packets
713 // TODO: allow empty packets thru
714
715 proto = ntohl(*(mtod(*pkt, protocol_family_t *)));
716 m_adj(*pkt, sizeof(protocol_family_t));
717
718 bzero(&ro_copy, sizeof(ro_copy));
719
720 if ((proto == AF_UTUN || proto == AF_INET) && crypto_keys->state.u.ipsec.ifamily == IPPROTO_IPV4) {
721 struct ip *ip;
722 struct sockaddr_in *dst4;
723
724 if (proto == AF_INET) {
725 if ((*pkt)->m_len < (__typeof__((*pkt)->m_len))sizeof(*ip)) {
726 if (!(*pkt = m_pullup(*pkt, sizeof(*ip)))) {
727 printf("%s: m_pullup failed\n", __FUNCTION__);
728 return 0;
729 }
730 }
731
732 // split the mbuf chain to put the ip header and payloads in separate mbufs
733 new = ipsec4_splithdr(*pkt);
734 if (!new) {
735 printf("%s: ipsec4_splithdr(1) failed\n", __FUNCTION__);
736 if (ro_copy.ro_rt != NULL) {
737 rtfree(ro_copy.ro_rt);
738 }
739 *pkt = NULL;
740 return 0;
741 }
742 *pkt = new;
743
744 // encapsulate with the outer header
745 if ((err = ipsec4_encapsulate(new, sav))) {
746 printf("%s: ipsec4_encapsulate failed (%d)\n", __FUNCTION__, err);
747 *pkt = NULL;
748 return 0;
749 }
750
751 } else {
752 // otherwise it's AF_UTUN which will be a keepalive packet to be encapsulated, encrypted and sent
753 // encapsulate with the outer header
754 if ((err = ipsec4_encapsulate_utun_esp_keepalive(pkt, sav))) {
755 printf("%s: ipsec4_encapsulate failed (%d)\n", __FUNCTION__, err);
756 return 0;
757 }
758 new = *pkt;
759 }
760
761 ip = mtod(new, __typeof__(ip));
762 // grab sadb_mutex, to update sah's route cache and get a local copy of it
763 lck_mtx_lock(sadb_mutex);
764 ro = &sav->sah->sa_route;
765 dst4 = (struct sockaddr_in *)(void *)&ro->ro_dst;
766 if (ro->ro_rt) {
767 RT_LOCK(ro->ro_rt);
768 }
769 if (ro->ro_rt != NULL &&
770 (ro->ro_rt->generation_id != route_generation ||
771 !(ro->ro_rt->rt_flags & RTF_UP) ||
772 dst4->sin_addr.s_addr != ip->ip_dst.s_addr)) {
773 RT_UNLOCK(ro->ro_rt);
774 rtfree(ro->ro_rt);
775 ro->ro_rt = NULL;
776 }
777 if (ro->ro_rt == NULL) {
778 dst4->sin_family = AF_INET;
779 dst4->sin_len = sizeof(*dst4);
780 dst4->sin_addr = ip->ip_dst;
781 rtalloc(ro);
782 if (ro->ro_rt) {
783 RT_LOCK(ro->ro_rt);
784 } else {
785 printf("%s: rtalloc(1) failed\n", __FUNCTION__);
786 mbuf_freem(new);
787 *pkt = NULL;
788 return 0;
789 }
790 }
791 if (ro->ro_rt->rt_flags & RTF_GATEWAY) {
792 dst4 = (struct sockaddr_in *)(void *)ro->ro_rt->rt_gateway;
793 }
794 RT_UNLOCK(ro->ro_rt);
795 route_copyout(&ro_copy, ro, sizeof(ro_copy));
796 // release sadb_mutex, after updating sah's route cache and getting a local copy
797 lck_mtx_unlock(sadb_mutex);
798
799 // split the mbuf chain to put the ip header and payloads in separate mbufs
800 new = ipsec4_splithdr(*pkt);
801 if (!new) {
802 printf("%s: ipsec4_splithdr(2) failed\n", __FUNCTION__);
803 if (ro_copy.ro_rt != NULL) {
804 rtfree(ro_copy.ro_rt);
805 }
806 *pkt = NULL;
807 return 0;
808 }
809 *pkt = new;
810
811 if ((err = esp4_output(new, sav))) {
812 printf("%s: esp4_output failed (%d)\n", __FUNCTION__, err);
813 if (ro_copy.ro_rt != NULL) {
814 rtfree(ro_copy.ro_rt);
815 }
816 *pkt = NULL;
817 return 0; // drop
818 }
819
820 ip = mtod(new, __typeof__(ip));
821 ip->ip_len = ntohs(ip->ip_len); /* flip len field before calling ip_output */
822 } else if ((proto == AF_UTUN || proto == AF_INET6) && crypto_keys->state.u.ipsec.ifamily == IPPROTO_IPV6) {
823 int plen;
824 struct ip6_hdr *ip6;
825 struct sockaddr_in6 *dst6;
826
827 if (proto == AF_INET6) {
828 // split the mbuf chain to put the ip header and payloads in separate mbufs
829 new = ipsec6_splithdr(*pkt);
830 if (!new) {
831 printf("%s: ipsec6_splithdr(1) failed\n", __FUNCTION__);
832 if (ro_copy.ro_rt != NULL) {
833 rtfree(ro_copy.ro_rt);
834 }
835 *pkt = NULL;
836 return 0;
837 }
838 *pkt = new;
839
840 // encapsulate with the outer header
841 if ((err = ipsec6_encapsulate(new, sav))) {
842 printf("%s: ipsec6_encapsulate failed (%d)\n", __FUNCTION__, err);
843 *pkt = NULL;
844 return 0;
845 }
846
847 } else {
848 // otherwise it's AF_UTUN which will be a keepalive packet to be encapsulated, encrypted and sent
849 // encapsulate with the outer header
850 if ((err = ipsec6_encapsulate_utun_esp_keepalive(pkt, sav))) {
851 printf("%s: ipsec6_encapsulate failed (%d)\n", __FUNCTION__, err);
852 return 0;
853 }
854 new = *pkt;
855 }
856
857 ip6 = mtod(new, __typeof__(ip6));
858 // grab sadb_mutex, before updating sah's route cache
859 lck_mtx_lock(sadb_mutex);
860 ro = &sav->sah->sa_route;
861 dst6 = (struct sockaddr_in6 *)(void *)&ro->ro_dst;
862 if (ro->ro_rt) {
863 RT_LOCK(ro->ro_rt);
864 }
865 if (ro->ro_rt != NULL &&
866 (ro->ro_rt->generation_id != route_generation ||
867 !(ro->ro_rt->rt_flags & RTF_UP) ||
868 !IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ip6->ip6_dst))) {
869 RT_UNLOCK(ro->ro_rt);
870 rtfree(ro->ro_rt);
871 ro->ro_rt = NULL;
872 }
873 if (ro->ro_rt == NULL) {
874 bzero(dst6, sizeof(*dst6));
875 dst6->sin6_family = AF_INET6;
876 dst6->sin6_len = sizeof(*dst6);
877 dst6->sin6_addr = ip6->ip6_dst;
878 rtalloc(ro);
879 if (ro->ro_rt) {
880 RT_LOCK(ro->ro_rt);
881 } else {
882 printf("%s: rtalloc(2) failed\n", __FUNCTION__);
883 mbuf_freem(new);
884 *pkt = NULL;
885 return 0;
886 }
887 }
888 if (ro->ro_rt->rt_flags & RTF_GATEWAY) {
889 dst6 = (struct sockaddr_in6 *)(void *)ro->ro_rt->rt_gateway;
890 }
891 RT_UNLOCK(ro->ro_rt);
892 route_copyout(&ro_copy, ro, sizeof(ro_copy));
893 // release sadb_mutex, after updating sah's route cache and getting a local copy
894 lck_mtx_unlock(sadb_mutex);
895
896 // split the mbuf chain to put the ip header and payloads in separate mbufs
897 new = ipsec6_splithdr(*pkt);
898 if (!new) {
899 printf("%s: ipsec6_splithdr failed\n", __FUNCTION__);
900 if (ro_copy.ro_rt != NULL) {
901 rtfree(ro_copy.ro_rt);
902 }
903 *pkt = NULL;
904 return 0;
905 }
906 *pkt = new;
907
908 if ((err = esp6_output(new, mtod(new, u_char *), new->m_next, sav))) {
909 printf("%s: esp6_output failed (%d)\n", __FUNCTION__, err);
910 if (ro_copy.ro_rt != NULL) {
911 rtfree(ro_copy.ro_rt);
912 }
913 *pkt = NULL;
914 return 0; // drop
915 }
916
917 plen = new->m_pkthdr.len - sizeof(struct ip6_hdr);
918 if (plen > IPV6_MAXPACKET) {
919 printf("%s: esp6_output failed due to invalid len (%d)\n", __FUNCTION__, plen);
920 if (ro_copy.ro_rt != NULL) {
921 rtfree(ro_copy.ro_rt);
922 }
923 mbuf_freem(new);
924 *pkt = NULL;
925 return 0;
926 }
927 ip6 = mtod(new, __typeof__(ip6));
928 ip6->ip6_plen = ntohs(ip6->ip6_plen); /* flip len field before calling ip_output */
929 } else {
930 printf("%s: packet's proto (%d) mismatched the context's proto (%d)\n", __FUNCTION__,
931 proto, crypto_keys->state.u.ipsec.ifamily);
932 mbuf_freem(*pkt);
933 *pkt = NULL;
934 return 0;
935 }
936
937 if (pcb->utun_ifp) {
938 ifnet_stat_increment_out(pcb->utun_ifp, 1, mbuf_pkthdr_len(new), 0);
939 }
940
941 if ((err = ip_output(new, NULL, &ro_copy,
942 (IP_OUTARGS | IP_NOIPSEC), NULL, &ipoa))) {
943 printf("%s: ip_output failed (%d)\n", __FUNCTION__, err);
944 }
945 lck_mtx_lock(sadb_mutex);
946 route_copyin(&ro_copy, ro, sizeof(*ro));
947 lck_mtx_unlock(sadb_mutex);
948 return 0;
949 } else {
950 printf("%s: no suitable crypto-mat\n", __FUNCTION__);
951 }
952 return -1;
953}
954
955// returns 0 if false, 1 if true, and -1 if there was a failure
956int
957utun_pkt_is_ipsec_keepalive (struct utun_pcb *pcb, mbuf_t *pkt, u_int16_t nxt, u_int32_t flags, size_t offs)
958{
959 int result;
960 u_int8_t *data;
961 int size_diff;
962
963 if (!pcb->utun_ctlref) {
964 printf("%s - utun ctlref cleared\n", __FUNCTION__);
965 return 0;
966 }
967
968 if (!(pcb->utun_flags & UTUN_FLAGS_CRYPTO)) {
969 printf("%s - crypto disabled\n", __FUNCTION__);
970 return 0;
971 }
972
973 if ((*pkt)->m_pkthdr.len < 0) {
974 printf("%s - invalid hdr len, len %d, offs %lu\n", __FUNCTION__, (*pkt)->m_pkthdr.len, offs);
975 return 0;
976 }
977
978 if ((size_t)(*pkt)->m_pkthdr.len <= offs) {
979 printf("%s - invalid offset, len %d, offs %lu\n", __FUNCTION__, (*pkt)->m_pkthdr.len, offs);
980 return 0;
981 }
982
983 if ((*pkt)->m_len < 0) {
984 printf("%s - invalid len, len %d, offs %lu\n", __FUNCTION__, (*pkt)->m_len, offs);
985 return 0;
986 }
987
988 // pullup offs + 1 bytes
989 if ((size_t)(*pkt)->m_len < (offs + 1)) {
990 if ((*pkt = m_pullup(*pkt, (offs + 1))) == NULL) {
991 printf("%s: m_pullup failed\n", __FUNCTION__);
992 return -1;
993 }
994 }
995
996 if (pcb->utun_ifp) {
997 ifnet_stat_increment_in(pcb->utun_ifp, 1, mbuf_pkthdr_len(*pkt), 0);
998 }
999
1000 size_diff = (*pkt)->m_pkthdr.len - offs;
1001 data = mtod(*pkt, __typeof(data));
1002 data += offs;
1003
1004 // ESP keepalive meets all these conditions: ESP trailer's next proto indicates IP, the decrypted packet only has one zero'd byte in it.
1005 if (flags & SADB_X_EXT_ESP_KEEPALIVE &&
1006 nxt == IPPROTO_IPV4 &&
1007 size_diff == 1 &&
1008 *data == 0) {
1009 // TODO: update stats to increment keepalives and current timestamp
1010 if (utun_punt_rx_keepalive ||
1011 flags & SADB_X_EXT_PUNT_RX_KEEPALIVE) {
1012
1013 // strip all headers
1014 if ((size_t)(*pkt)->m_len >= (offs + size_diff)) {
1015 ovbcopy((caddr_t)data, (data + offs), size_diff);
1016 (*pkt)->m_data += offs;
1017 (*pkt)->m_len -= offs;
1018 (*pkt)->m_pkthdr.len -= offs;
1019 } else {
1020 struct mbuf *n;
1021
1022 n = m_split(*pkt, offs, M_DONTWAIT);
1023 if (n == NULL) {
1024 /* *pkt is retained by m_split */
1025 mbuf_freem(*pkt);
1026 *pkt = NULL;
1027 return -1;
1028 }
1029 m_adj(n, offs);
1030 mbuf_freem(*pkt);
1031 *pkt = n;
1032 }
1033
1034 // keepalive is being punted up to the control socket, prepend with a special packet type (PF_UTUN)
1035 if (mbuf_prepend(pkt, sizeof(protocol_family_t), MBUF_DONTWAIT) != 0) {
1036 printf("%s - ifnet_output prepend failed\n", __FUNCTION__);
1037 return -1;
1038 }
1039 if ((size_t)(*pkt)->m_len < (sizeof(protocol_family_t) + size_diff)) {
1040 if ((*pkt = m_pullup(*pkt, (sizeof(protocol_family_t) + size_diff))) == NULL) {
1041 printf("%s: m_pullup failed\n", __FUNCTION__);
1042 return -1;
1043 }
1044 }
1045
1046 // mark UTUN/Keepalive packet
1047 *(protocol_family_t *)mbuf_data(*pkt) = htonl(PF_UTUN);
1048
1049 result = ctl_enqueuembuf(pcb->utun_ctlref, pcb->utun_unit, *pkt, CTL_DATA_EOR);
1050 if (result != 0) {
1051 printf("%s: - ctl_enqueuembuf failed: %d\n", __FUNCTION__, result);
1052 mbuf_freem(*pkt);
1053 return -1;
1054 }
1055 *pkt = NULL;
1056 }
1057 return 1;
1058 }
1059 return 0;
1060}
1061
1062int
1063utun_pkt_ipsec_input (struct utun_pcb *pcb, mbuf_t *pkt, protocol_family_t family)
1064{
1065 if (!m_tag_locate(*pkt, KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_IPSEC, NULL)) {
1066 return EINVAL;
1067 }
1068
1069 if (!(pcb->utun_flags & UTUN_FLAGS_CRYPTO)) {
1070 printf("%s - crypto disabled\n", __FUNCTION__);
1071 return EINVAL;
1072 }
1073
1074 if (!pcb->utun_ifp) {
1075 printf("%s - utun ifp cleared\n", __FUNCTION__);
1076 return EINVAL;
1077 }
1078
1079 // place protocol number at the beginning of the mbuf
1080 if (mbuf_prepend(pkt, sizeof(protocol_family_t), MBUF_DONTWAIT) != 0) {
1081 printf("%s - ifnet_output prepend failed\n", __FUNCTION__);
1082 return ENOBUFS;
1083 }
1084 *(protocol_family_t *)mbuf_data(*pkt) = htonl(family);
1085
1086 (void)utun_pkt_input(pcb, *pkt);
1087 return 0;
1088}