1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  *
  26  * Copyright 2014 Jason King.
  27  * Copyright 2017 Joyent, Inc.
  28  */
  29 
  30 #ifndef _IKEV2_SA_H
  31 #define _IKEV2_SA_H
  32 
  33 #include <sys/types.h>
  34 #include <sys/socket.h>
  35 #include <assert.h>
  36 #include <synch.h>
  37 #include <stddef.h>
  38 #include <security/cryptoki.h>
  39 #include <atomic.h>
  40 #include <pthread.h>
  41 #include <libuutil.h>
  42 
  43 #include "ikev2.h"
  44 #include "defs.h"
  45 
  46 #ifdef  __cplusplus
  47 extern "C" {
  48 #endif
  49 
  50 struct ikev2_sa;
  51 struct ikev2_child_sa;
  52 struct i2sa_bucket;
  53 struct pkt;
  54 struct buf;
  55 
  56 #ifndef IKEV2_SA_T
  57 #define IKEV2_SA_T
  58 typedef struct ikev2_sa ikev2_sa_t;
  59 typedef struct ikev2_child_sa ikev2_child_sa_t;
  60 typedef struct i2sa_bucket i2sa_bucket_t;
  61 #endif /* IKEV2_SA_T */
  62 
  63 struct config_rule_s;
  64 
  65 #define I2SA_NUM_HASH   2       /* The number of IKEv2 SA hashes we have */
  66 
  67 #define I2SA_SALT_LEN   (32)    /* Maximum size of salt */
  68 
  69 /*
  70  * The IKEv2 SA.
  71  *
  72  * This is the central data structure to the IKEv2 daemon.  It is a
  73  * reference-counted node, where the lookup key is either the local
  74  * SPI/cookie, or a hash based on the remote address and remote SPI.  (See
  75  * ikev2_pkt.h for the _SPI() macros.)  It should be allocated with a umem
  76  * cache.  It contains a mutex to lock certain fields if need be.
  77  *
  78  * Because of the distinct sets of lookup keys, it requires two linkages.
  79  */
  80 struct ikev2_sa {
  81         /*
  82          * Fields that should not be zeroed out between trips before
  83          * returning to the umem_cache should go at the top of this struct.
  84          */
  85         pthread_mutex_t lock;
  86 
  87         uu_list_node_t  lspi_node;
  88         uu_list_node_t  rhash_node;
  89 
  90         bunyan_logger_t *i2sa_log;
  91 
  92                         /* Link to the bucket we are in for each hash */
  93         i2sa_bucket_t   *bucket[I2SA_NUM_HASH];
  94 
  95         struct config_rule_s    *i2sa_rule;
  96 
  97         uint64_t                i_spi;    /* Initiator SPI. */
  98         uint64_t                r_spi;    /* Responder SPI. */
  99         uint32_t                flags;
 100         volatile uint32_t       refcnt;
 101 
 102         struct sockaddr_storage laddr;  /* Local address & port. */
 103         struct sockaddr_storage raddr;  /* Remote address & port. */
 104 
 105         vendor_t                vendor;
 106 
 107         /* Current number of outstanding messages prior to outmsgid. */
 108         int             msgwin;
 109 
 110         int             encr;           /* Encryption algorithm */
 111         size_t          encr_key_len;   /* Key length (bytes) for encr */
 112         int             auth;           /* Authentication algorithm */
 113         int             prf;            /* PRF algorithm */
 114         int             dhgrp;          /* Diffie-Hellman group. */
 115 
 116         uint32_t outmsgid;              /* Next msgid for outbound packets. */
 117         uint32_t inmsgid;               /* Next expected inbound msgid. */
 118 
 119         struct pkt      *init;          /* IKE_SA_INIT packet. */
 120         struct pkt      *last_resp_sent;
 121         struct pkt      *last_sent;
 122         struct pkt      *last_recvd;
 123 
 124         time_t          birth;          /* When was AUTH completed */
 125         hrtime_t        softexpire;
 126         hrtime_t        hardexpire;
 127 
 128         ikev2_child_sa_t        *child_sas;
 129 
 130         CK_OBJECT_HANDLE dh_pubkey;
 131         CK_OBJECT_HANDLE dh_privkey;
 132         CK_OBJECT_HANDLE dh_key;
 133         CK_OBJECT_HANDLE sk_d;
 134         CK_OBJECT_HANDLE sk_ai;
 135         CK_OBJECT_HANDLE sk_ar;
 136         CK_OBJECT_HANDLE sk_ei;
 137         CK_OBJECT_HANDLE sk_er;
 138         CK_OBJECT_HANDLE sk_pi;
 139         CK_OBJECT_HANDLE sk_pr;
 140 
 141         uint8_t         salt[I2SA_SALT_LEN];
 142         size_t          saltlen;
 143 };
 144 
 145 struct ikev2_child_sa {
 146         ikev2_child_sa_t        *next;
 147         ikev2_spi_proto_t       satype;
 148         uint32_t                spi;
 149         /* XXX: more to come probably */
 150 };
 151 
 152 /* SA flags */
 153 #define I2SA_INITIATOR          0x1     /* Am I the initiator of this IKE SA? */
 154 #define I2SA_NAT_LOCAL          0x2     /* I am behind a NAT. */
 155 #define I2SA_NAT_REMOTE         0x4     /* My peer is behind a NAT. */
 156 #define I2SA_CONDEMNED          0x8     /* SA is unlinked from a tree. */
 157 #define I2SA_AUTHENTICATED      0x10    /* SA has been authenticated */
 158 
 159 #define I2SA_LOCAL_SPI(i2sa) \
 160         (((i2sa)->flags & I2SA_INITIATOR) ? (i2sa)->i_spi : \
 161             (i2sa)->r_spi)
 162 
 163 #define I2SA_REMOTE_SPI(i2sa) \
 164         (((i2sa)->flags & I2SA_INITIATOR) ? (i2sa)->r_spi : \
 165             (i2sa)->i_spi)
 166 
 167 #define I2SA_IS_NAT(i2sa) \
 168         (!!((i2sa)->flags && (I2SA_NAT_LOCAL|I2SA_NAT_REMOTE)))
 169 
 170 #define I2SA_REFHOLD(i2sa) \
 171         atomic_inc_32(&(i2sa)->refcnt)
 172 
 173 /* Stupid C tricks stolen from <assert.h>. */
 174 #define I2SA_REFRELE(i2sa) \
 175         (void) ((atomic_dec_32_nv(&(i2sa)->refcnt) != 0) || \
 176             (ikev2_sa_free(i2sa), 0))
 177 
 178 extern ikev2_sa_t *ikev2_sa_get(uint64_t, uint64_t,
 179     const struct sockaddr_storage *restrict,
 180     const struct sockaddr_storage *restrict,
 181     const struct pkt *restrict);
 182 extern ikev2_sa_t *ikev2_sa_alloc(boolean_t, struct pkt *restrict,
 183     const struct sockaddr_storage *restrict,
 184     const struct sockaddr_storage *restrict);
 185 
 186 extern void     ikev2_sa_free(ikev2_sa_t *);
 187 extern void     ikev2_sa_condemn(ikev2_sa_t *);
 188 
 189 extern void     ikev2_sa_flush(void);
 190 extern void     ikev2_sa_set_hashsize(uint_t);
 191 
 192 #ifdef  __cplusplus
 193 }
 194 #endif
 195 
 196 #endif  /* _IKEV2_SA_H */