#ifndef _NET_IF_UTUN_CRYPTO_H_
#define _NET_IF_UTUN_CRYPTO_H_
typedef enum utun_crypto_ver {
UTUN_CRYPTO_VER_1 = 1,
UTUN_CRYPTO_VER_MAX,
} utun_crypto_ver_t;
#define UTUN_CRYPTO_KEYS_IPSEC_VER_1 UTUN_CRYPTO_VER_1
#define UTUN_CRYPTO_IPSEC_VER_1 UTUN_CRYPTO_VER_1
#define UTUN_CRYPTO_ARGS_VER_MAX UTUN_CRYPTO_VER_MAX
#define UTUN_CRYPTO_KEYS_ARGS_VER_MAX UTUN_CRYPTO_VER_MAX
typedef enum utun_crypto_dir {
UTUN_CRYPTO_DIR_IN = 1,
UTUN_CRYPTO_DIR_OUT,
UTUN_CRYPTO_DIR_MAX,
} utun_crypto_dir_t;
#define UTUN_CRYPTO_CTX_NUM_DIRS 2
#define BITSTOBYTES(n) (n >> 3)
#define BYTESTOBITS(n) (n << 3)
#define MAX_KEY_AUTH_LEN_BITS 512 // corresponds to SHA512
#define MAX_KEY_AUTH_LEN_BYTES (BITSTOBYTES(MAX_KEY_AUTH_LEN_BITS))
#define MAX_KEY_ENC_LEN_BITS 256 // corresponds to AES256
#define MAX_KEY_ENC_LEN_BYTES (BITSTOBYTES(MAX_KEY_ENC_LEN_BITS))
typedef enum utun_crypto_type {
UTUN_CRYPTO_TYPE_IPSEC = 1,
UTUN_CRYPTO_TYPE_DTLS,
UTUN_CRYPTO_TYPE_MAX,
} utun_crypto_type_t;
typedef enum if_utun_crypto_ipsec_mode {
IF_UTUN_CRYPTO_IPSEC_MODE_NONE = 0,
IF_UTUN_CRYPTO_IPSEC_MODE_TRANSPORT,
IF_UTUN_CRYPTO_IPSEC_MODE_TUNNEL,
IF_UTUN_CRYPTO_IPSEC_MODE_MAX,
} if_utun_crypto_ipsec_mode_t;
typedef enum if_utun_crypto_ipsec_proto {
IF_UTUN_CRYPTO_IPSEC_PROTO_NONE = 0,
IF_UTUN_CRYPTO_IPSEC_PROTO_ESP,
IF_UTUN_CRYPTO_IPSEC_PROTO_AH,
IF_UTUN_CRYPTO_IPSEC_PROTO_MAX,
} if_utun_crypto_ipsec_proto_t;
typedef enum if_utun_crypto_ipsec_auth {
IF_UTUN_CRYPTO_IPSEC_AUTH_NONE = 0,
IF_UTUN_CRYPTO_IPSEC_AUTH_MD5,
IF_UTUN_CRYPTO_IPSEC_AUTH_SHA1,
IF_UTUN_CRYPTO_IPSEC_AUTH_SHA256,
IF_UTUN_CRYPTO_IPSEC_AUTH_SHA384,
IF_UTUN_CRYPTO_IPSEC_AUTH_SHA512,
IF_UTUN_CRYPTO_IPSEC_AUTH_MAX,
} if_utun_crypto_ipsec_auth_t;
typedef enum if_utun_crypto_ipsec_enc {
IF_UTUN_CRYPTO_IPSEC_ENC_NONE = 0,
IF_UTUN_CRYPTO_IPSEC_ENC_DES,
IF_UTUN_CRYPTO_IPSEC_ENC_3DES,
IF_UTUN_CRYPTO_IPSEC_ENC_AES128,
IF_UTUN_CRYPTO_IPSEC_ENC_AES256,
IF_UTUN_CRYPTO_IPSEC_ENC_MAX,
} if_utun_crypto_ipsec_enc_t;
typedef enum if_utun_crypto_ipsec_keepalive {
IF_UTUN_CRYPTO_IPSEC_KEEPALIVE_NONE = 0,
IF_UTUN_CRYPTO_IPSEC_KEEPALIVE_NATT,
IF_UTUN_CRYPTO_IPSEC_KEEPALIVE_ESP,
IF_UTUN_CRYPTO_IPSEC_KEEPALIVE_MAX,
} if_utun_crypto_ipsec_keepalive_t;
typedef enum if_utun_crypto_ipsec_natd {
IF_UTUN_CRYPTO_IPSEC_NATD_NONE = 0,
IF_UTUN_CRYPTO_IPSEC_NATD_MINE,
IF_UTUN_CRYPTO_IPSEC_NATD_PEER,
IF_UTUN_CRYPTO_IPSEC_NATD_BOTH,
IF_UTUN_CRYPTO_IPSEC_NATD_MAX,
} if_utun_crypto_ipsec_natd_t;
typedef struct utun_crypto_keys_idx_ipsec_args_v1 {
struct sockaddr_storage src_addr; struct sockaddr_storage dst_addr; if_utun_crypto_ipsec_proto_t proto;
if_utun_crypto_ipsec_mode_t mode;
u_int32_t reqid; u_int32_t spi; u_int32_t spirange_min; u_int32_t spirange_max; } __attribute__((packed)) utun_crypto_keys_idx_ipsec_args_v1_t;
typedef struct utun_crypto_keys_idx_dtls_args_v1 {
u_int32_t unused; } __attribute__((packed)) utun_crypto_keys_idx_dtls_args_v1_t;
typedef struct utun_crypto_keys_idx_args {
utun_crypto_ver_t ver;
utun_crypto_type_t type;
utun_crypto_dir_t dir;
u_int32_t args_ulen;
u_int32_t varargs_buflen;
union {
utun_crypto_keys_idx_ipsec_args_v1_t ipsec_v1;
utun_crypto_keys_idx_dtls_args_v1_t dtls_v1;
} u;
u_int8_t varargs_buf[0];
} __attribute__((aligned(4), packed)) utun_crypto_keys_idx_args_t;
typedef struct utun_crypto_keys_ipsec_args_v1 {
struct sockaddr_storage src_addr; struct sockaddr_storage dst_addr; if_utun_crypto_ipsec_proto_t proto;
if_utun_crypto_ipsec_mode_t mode;
if_utun_crypto_ipsec_auth_t alg_auth;
if_utun_crypto_ipsec_enc_t alg_enc;
if_utun_crypto_ipsec_keepalive_t keepalive;
if_utun_crypto_ipsec_natd_t natd;
u_int8_t replay; u_int8_t punt_rx_keepalive;
u_int16_t interval_tx_keepalive;
u_int16_t key_auth_len; u_int16_t key_enc_len; u_int16_t natt_port; u_int16_t unused;
u_int32_t seq; u_int32_t spi;
u_int32_t pid; u_int32_t reqid; u_int64_t lifetime_hard; u_int64_t lifetime_soft; } __attribute__((packed)) utun_crypto_keys_ipsec_args_v1_t;
typedef struct utun_crypto_ctx_dtls_mat_args_v1 {
u_int32_t unused; } __attribute__((packed)) utun_crypto_keys_dtls_args_v1_t;
typedef struct utun_crypto_keys_args {
utun_crypto_ver_t ver;
utun_crypto_type_t type;
utun_crypto_dir_t dir;
u_int32_t args_ulen;
u_int32_t varargs_buflen;
union {
utun_crypto_keys_ipsec_args_v1_t ipsec_v1;
utun_crypto_keys_dtls_args_v1_t dtls_v1;
} u;
u_int8_t varargs_buf[0];
} __attribute__((aligned(4), packed)) utun_crypto_keys_args_t;
typedef struct utun_crypto_ipsec_args_v1 {
u_int32_t unused; } __attribute__((packed)) utun_crypto_ipsec_args_v1_t;
typedef struct utun_crypto_dtls_args_v1 {
u_int32_t unused; } __attribute__((packed)) utun_crypto_dtls_args_v1_t;
typedef struct utun_crypto_args {
utun_crypto_ver_t ver;
utun_crypto_type_t type;
u_int32_t stop_data_traffic;
u_int32_t args_ulen;
u_int32_t varargs_buflen;
union {
utun_crypto_ipsec_args_v1_t ipsec_v1;
utun_crypto_dtls_args_v1_t dtls_v1;
} u;
u_int8_t varargs_buf[0]; } __attribute__((aligned(4), packed)) utun_crypto_args_t;
#ifdef KERNEL_PRIVATE
#include <sys/kern_control.h>
#include <net/kpi_protocol.h>
#include <net/kpi_interface.h>
#include <net/pfkeyv2.h>
#include <netkey/key.h>
#include <netkey/keydb.h>
struct utun_pcb;
typedef struct utun_crypto_keys_ipsec_state {
u_int32_t spi;
struct secashead *sah;
struct secasvar *sav;
u_int8_t proto;
u_int8_t ifamily;
u_int8_t mode;
u_int8_t unused;
} __attribute__((packed)) utun_crypto_keys_ipsec_state_t;
typedef struct utun_crypto_keys_dtls_state {
u_int32_t unused; } __attribute__((packed)) utun_crypto_keys_dtls_state_t;
typedef struct utun_crypto_keys_state {
union {
utun_crypto_keys_ipsec_state_t ipsec;
utun_crypto_keys_dtls_state_t dtls;
} u;
} __attribute__((aligned(4), packed)) utun_crypto_keys_state_t;
typedef struct utun_crypto_keys {
int valid; utun_crypto_type_t type;
u_int16_t unused;
utun_crypto_keys_state_t state; LIST_ENTRY(utun_crypto_keys) chain;
} __attribute__((aligned(4), packed)) utun_crypto_keys_t;
typedef struct utun_crypto_ctx {
int valid;
utun_crypto_type_t type;
u_int16_t unused;
LIST_HEAD(chain, utun_crypto_keys) keys_listhead;
} __attribute__((aligned(4), packed)) utun_crypto_ctx_t;
#define UTUN_CRYPTO_KEYS_IDX_ARGS_HDR_SIZE ((size_t)(&((utun_crypto_keys_idx_args_t *)0)->u))
#define UTUN_CRYPTO_KEYS_IDX_ARGS_VARARGS_BUF(args) ((u_int8_t *)args + UTUN_CRYPTO_KEYS_IDX_ARGS_HDR_SIZE + args->args_ulen)
#define UTUN_CRYPTO_KEYS_IDX_ARGS_TOTAL_SIZE(args) ((size_t)(UTUN_CRYPTO_KEYS_IDX_ARGS_HDR_SIZE + args->args_ulen + args->varargs_buflen))
#define UTUN_CRYPTO_KEYS_ARGS_HDR_SIZE ((size_t)(&((utun_crypto_keys_args_t *)0)->u))
#define UTUN_CRYPTO_KEYS_ARGS_VARARGS_BUF(args) ((u_int8_t *)args + UTUN_CRYPTO_KEYS_ARGS_HDR_SIZE + args->args_ulen)
#define UTUN_CRYPTO_KEYS_ARGS_TOTAL_SIZE(args) ((size_t)(UTUN_CRYPTO_KEYS_ARGS_HDR_SIZE + args->args_ulen + args->varargs_buflen))
#define UTUN_CRYPTO_ARGS_HDR_SIZE ((size_t)(&((utun_crypto_args_t *)0)->u))
#define UTUN_CRYPTO_ARGS_VARARGS_BUF(args) ((u_int8_t *)args + UTUN_CRYPTO_ARGS_HDR_SIZE + args->args_ulen)
#define UTUN_CRYPTO_ARGS_TOTAL_SIZE(args) ((size_t)(UTUN_CRYPTO_ARGS_HDR_SIZE + args->args_ulen + args->varargs_buflen))
#define UTUN_CRYPTO_DIR_TO_IDX(dir) (dir - 1)
#define UTUN_CRYPTO_IDX_TO_DIR(idx) (idx + 1)
void
utun_cleanup_crypto(struct utun_pcb *pcb);
errno_t
utun_ctl_enable_crypto(__unused kern_ctl_ref kctlref,
__unused u_int32_t unit,
__unused void *unitinfo,
__unused int opt,
void *data,
size_t len);
errno_t
utun_ctl_disable_crypto(__unused kern_ctl_ref kctlref,
__unused u_int32_t unit,
__unused void *unitinfo,
__unused int opt,
void *data,
size_t len);
errno_t
utun_ctl_config_crypto_keys(__unused kern_ctl_ref kctlref,
__unused u_int32_t unit,
__unused void *unitinfo,
__unused int opt,
void *data,
size_t len);
errno_t
utun_ctl_unconfig_crypto_keys(__unused kern_ctl_ref kctlref,
__unused u_int32_t unit,
__unused void *unitinfo,
__unused int opt,
void *data,
size_t len);
errno_t
utun_ctl_generate_crypto_keys_idx(__unused kern_ctl_ref kctlref,
__unused u_int32_t unit,
__unused void *unitinfo,
__unused int opt,
void *data,
size_t *len);
errno_t
utun_ctl_stop_crypto_data_traffic(__unused kern_ctl_ref kctlref,
__unused u_int32_t unit,
__unused void *unitinfo,
__unused int opt,
void *data,
size_t len);
errno_t
utun_ctl_start_crypto_data_traffic(__unused kern_ctl_ref kctlref,
__unused u_int32_t unit,
__unused void *unitinfo,
__unused int opt,
void *data,
size_t len);
int
utun_pkt_crypto_output(struct utun_pcb *pcb, mbuf_t *m);
#endif // KERNEL_PRIVATE
#endif // _NET_IF_UTUN_CRYPTO_H_