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 */