]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/if_utun_crypto_ipsec.c
xnu-2782.30.5.tar.gz
[apple/xnu.git] / bsd / net / if_utun_crypto_ipsec.c
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
50 extern lck_mtx_t *sadb_mutex;
51 extern int esp_udp_encap_port; // udp encap listening port
52 extern int ipsec_policy_count;
53 extern int ipsec_bypass;
54 extern int natt_keepalive_interval;
55
56 static int utun_punt_rx_keepalive = 0; // optional global control
57
58 extern errno_t utun_pkt_input (struct utun_pcb *pcb, mbuf_t m);
59
60 static u_int8_t
61 utun_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
73 static u_int16_t
74 utun_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
86 static u_int8_t
87 utun_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
99 static u_int8_t
100 utun_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
118 static u_int8_t
119 utun_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
134 static u_int32_t
135 utun_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
172 static errno_t
173 utun_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
210 static int
211 utun_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
248 static void
249 utun_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
259 static void
260 utun_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
272 static struct sadb_key *
273 utun_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
294 static errno_t
295 utun_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
366 static int
367 utun_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
383 static int
384 utun_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
415 static errno_t
416 utun_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
506 static errno_t
507 utun_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
528 static void
529 utun_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
537 static u_int32_t
538 utun_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
557 static errno_t
558 utun_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
580 void
581 utun_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
621 static errno_t
622 utun_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 */
630 void
631 utun_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 */
648 void
649 utun_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
660 errno_t
661 utun_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
673 errno_t
674 utun_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
685 errno_t
686 utun_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
696 int
697 utun_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
939 int
940 utun_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
1045 int
1046 utun_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 */