1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 2751 danmcd * Common Development and Distribution License (the "License"). 6 2751 danmcd * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 8704 danmcd * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel #include <sys/types.h> 27 0 stevel #include <sys/stream.h> 28 0 stevel #include <sys/stropts.h> 29 0 stevel #include <sys/errno.h> 30 0 stevel #include <sys/strlog.h> 31 0 stevel #include <sys/tihdr.h> 32 0 stevel #include <sys/socket.h> 33 0 stevel #include <sys/ddi.h> 34 0 stevel #include <sys/sunddi.h> 35 0 stevel #include <sys/kmem.h> 36 3448 dh155122 #include <sys/zone.h> 37 0 stevel #include <sys/sysmacros.h> 38 0 stevel #include <sys/cmn_err.h> 39 0 stevel #include <sys/vtrace.h> 40 0 stevel #include <sys/debug.h> 41 0 stevel #include <sys/atomic.h> 42 0 stevel #include <sys/strsun.h> 43 0 stevel #include <sys/random.h> 44 0 stevel #include <netinet/in.h> 45 0 stevel #include <net/if.h> 46 0 stevel #include <netinet/ip6.h> 47 0 stevel #include <net/pfkeyv2.h> 48 10824 Mark #include <net/pfpolicy.h> 49 0 stevel 50 0 stevel #include <inet/common.h> 51 0 stevel #include <inet/mi.h> 52 0 stevel #include <inet/nd.h> 53 0 stevel #include <inet/ip.h> 54 4987 danmcd #include <inet/ip_impl.h> 55 0 stevel #include <inet/ip6.h> 56 11042 Erik #include <inet/ip_if.h> 57 11042 Erik #include <inet/ip_ndp.h> 58 0 stevel #include <inet/sadb.h> 59 0 stevel #include <inet/ipsec_info.h> 60 0 stevel #include <inet/ipsec_impl.h> 61 0 stevel #include <inet/ipsecesp.h> 62 0 stevel #include <inet/ipdrop.h> 63 0 stevel #include <inet/tcp.h> 64 0 stevel #include <sys/kstat.h> 65 0 stevel #include <sys/policy.h> 66 0 stevel #include <sys/strsun.h> 67 10934 sommerfeld #include <sys/strsubr.h> 68 0 stevel #include <inet/udp_impl.h> 69 0 stevel #include <sys/taskq.h> 70 3448 dh155122 #include <sys/note.h> 71 10934 sommerfeld 72 10934 sommerfeld #include <sys/tsol/tnet.h> 73 0 stevel 74 0 stevel /* 75 0 stevel * Table of ND variables supported by ipsecesp. These are loaded into 76 0 stevel * ipsecesp_g_nd in ipsecesp_init_nd. 77 0 stevel * All of these are alterable, within the min/max values given, at run time. 78 0 stevel */ 79 3448 dh155122 static ipsecespparam_t lcl_param_arr[] = { 80 0 stevel /* min max value name */ 81 0 stevel { 0, 3, 0, "ipsecesp_debug"}, 82 0 stevel { 125, 32000, SADB_AGE_INTERVAL_DEFAULT, "ipsecesp_age_interval"}, 83 0 stevel { 1, 10, 1, "ipsecesp_reap_delay"}, 84 0 stevel { 1, SADB_MAX_REPLAY, 64, "ipsecesp_replay_size"}, 85 0 stevel { 1, 300, 15, "ipsecesp_acquire_timeout"}, 86 0 stevel { 1, 1800, 90, "ipsecesp_larval_timeout"}, 87 0 stevel /* Default lifetime values for ACQUIRE messages. */ 88 0 stevel { 0, 0xffffffffU, 0, "ipsecesp_default_soft_bytes"}, 89 0 stevel { 0, 0xffffffffU, 0, "ipsecesp_default_hard_bytes"}, 90 0 stevel { 0, 0xffffffffU, 24000, "ipsecesp_default_soft_addtime"}, 91 0 stevel { 0, 0xffffffffU, 28800, "ipsecesp_default_hard_addtime"}, 92 0 stevel { 0, 0xffffffffU, 0, "ipsecesp_default_soft_usetime"}, 93 0 stevel { 0, 0xffffffffU, 0, "ipsecesp_default_hard_usetime"}, 94 0 stevel { 0, 1, 0, "ipsecesp_log_unknown_spi"}, 95 0 stevel { 0, 2, 1, "ipsecesp_padding_check"}, 96 4987 danmcd { 0, 600, 20, "ipsecesp_nat_keepalive_interval"}, 97 0 stevel }; 98 3448 dh155122 #define ipsecesp_debug ipsecesp_params[0].ipsecesp_param_value 99 3448 dh155122 #define ipsecesp_age_interval ipsecesp_params[1].ipsecesp_param_value 100 3448 dh155122 #define ipsecesp_age_int_max ipsecesp_params[1].ipsecesp_param_max 101 3448 dh155122 #define ipsecesp_reap_delay ipsecesp_params[2].ipsecesp_param_value 102 3448 dh155122 #define ipsecesp_replay_size ipsecesp_params[3].ipsecesp_param_value 103 3448 dh155122 #define ipsecesp_acquire_timeout \ 104 3448 dh155122 ipsecesp_params[4].ipsecesp_param_value 105 3448 dh155122 #define ipsecesp_larval_timeout \ 106 3448 dh155122 ipsecesp_params[5].ipsecesp_param_value 107 3448 dh155122 #define ipsecesp_default_soft_bytes \ 108 3448 dh155122 ipsecesp_params[6].ipsecesp_param_value 109 3448 dh155122 #define ipsecesp_default_hard_bytes \ 110 3448 dh155122 ipsecesp_params[7].ipsecesp_param_value 111 3448 dh155122 #define ipsecesp_default_soft_addtime \ 112 3448 dh155122 ipsecesp_params[8].ipsecesp_param_value 113 3448 dh155122 #define ipsecesp_default_hard_addtime \ 114 3448 dh155122 ipsecesp_params[9].ipsecesp_param_value 115 3448 dh155122 #define ipsecesp_default_soft_usetime \ 116 3448 dh155122 ipsecesp_params[10].ipsecesp_param_value 117 3448 dh155122 #define ipsecesp_default_hard_usetime \ 118 3448 dh155122 ipsecesp_params[11].ipsecesp_param_value 119 3448 dh155122 #define ipsecesp_log_unknown_spi \ 120 3448 dh155122 ipsecesp_params[12].ipsecesp_param_value 121 3448 dh155122 #define ipsecesp_padding_check \ 122 3448 dh155122 ipsecesp_params[13].ipsecesp_param_value 123 4987 danmcd /* For ipsecesp_nat_keepalive_interval, see ipsecesp.h. */ 124 0 stevel 125 0 stevel #define esp0dbg(a) printf a 126 0 stevel /* NOTE: != 0 instead of > 0 so lint doesn't complain. */ 127 3448 dh155122 #define esp1dbg(espstack, a) if (espstack->ipsecesp_debug != 0) printf a 128 3448 dh155122 #define esp2dbg(espstack, a) if (espstack->ipsecesp_debug > 1) printf a 129 3448 dh155122 #define esp3dbg(espstack, a) if (espstack->ipsecesp_debug > 2) printf a 130 0 stevel 131 0 stevel static int ipsecesp_open(queue_t *, dev_t *, int, int, cred_t *); 132 0 stevel static int ipsecesp_close(queue_t *); 133 0 stevel static void ipsecesp_wput(queue_t *, mblk_t *); 134 3448 dh155122 static void *ipsecesp_stack_init(netstackid_t stackid, netstack_t *ns); 135 3448 dh155122 static void ipsecesp_stack_fini(netstackid_t stackid, void *arg); 136 3448 dh155122 static void esp_send_acquire(ipsacq_t *, mblk_t *, netstack_t *); 137 0 stevel 138 4987 danmcd static void esp_prepare_udp(netstack_t *, mblk_t *, ipha_t *); 139 11042 Erik static void esp_outbound_finish(mblk_t *, ip_xmit_attr_t *); 140 11042 Erik static void esp_inbound_restart(mblk_t *, ip_recv_attr_t *); 141 0 stevel 142 3448 dh155122 static boolean_t esp_register_out(uint32_t, uint32_t, uint_t, 143 11042 Erik ipsecesp_stack_t *, cred_t *); 144 0 stevel static boolean_t esp_strip_header(mblk_t *, boolean_t, uint32_t, 145 3448 dh155122 kstat_named_t **, ipsecesp_stack_t *); 146 11042 Erik static mblk_t *esp_submit_req_inbound(mblk_t *, ip_recv_attr_t *, 147 11042 Erik ipsa_t *, uint_t); 148 11042 Erik static mblk_t *esp_submit_req_outbound(mblk_t *, ip_xmit_attr_t *, 149 11042 Erik ipsa_t *, uchar_t *, uint_t); 150 7749 Thejaswini 151 3448 dh155122 /* Setable in /etc/system */ 152 3448 dh155122 uint32_t esp_hash_size = IPSEC_DEFAULT_HASH_SIZE; 153 0 stevel 154 0 stevel static struct module_info info = { 155 0 stevel 5137, "ipsecesp", 0, INFPSZ, 65536, 1024 156 0 stevel }; 157 0 stevel 158 0 stevel static struct qinit rinit = { 159 11042 Erik (pfi_t)putnext, NULL, ipsecesp_open, ipsecesp_close, NULL, &info, 160 0 stevel NULL 161 0 stevel }; 162 0 stevel 163 0 stevel static struct qinit winit = { 164 0 stevel (pfi_t)ipsecesp_wput, NULL, ipsecesp_open, ipsecesp_close, NULL, &info, 165 0 stevel NULL 166 0 stevel }; 167 0 stevel 168 0 stevel struct streamtab ipsecespinfo = { 169 0 stevel &rinit, &winit, NULL, NULL 170 0 stevel }; 171 0 stevel 172 0 stevel static taskq_t *esp_taskq; 173 0 stevel 174 0 stevel /* 175 0 stevel * OTOH, this one is set at open/close, and I'm D_MTQPAIR for now. 176 0 stevel * 177 0 stevel * Question: Do I need this, given that all instance's esps->esps_wq point 178 0 stevel * to IP? 179 0 stevel * 180 0 stevel * Answer: Yes, because I need to know which queue is BOUND to 181 0 stevel * IPPROTO_ESP 182 0 stevel */ 183 0 stevel 184 0 stevel /* 185 0 stevel * Stats. This may eventually become a full-blown SNMP MIB once that spec 186 0 stevel * stabilizes. 187 0 stevel */ 188 0 stevel 189 3448 dh155122 typedef struct esp_kstats_s { 190 0 stevel kstat_named_t esp_stat_num_aalgs; 191 0 stevel kstat_named_t esp_stat_good_auth; 192 0 stevel kstat_named_t esp_stat_bad_auth; 193 0 stevel kstat_named_t esp_stat_bad_padding; 194 0 stevel kstat_named_t esp_stat_replay_failures; 195 0 stevel kstat_named_t esp_stat_replay_early_failures; 196 0 stevel kstat_named_t esp_stat_keysock_in; 197 0 stevel kstat_named_t esp_stat_out_requests; 198 0 stevel kstat_named_t esp_stat_acquire_requests; 199 0 stevel kstat_named_t esp_stat_bytes_expired; 200 0 stevel kstat_named_t esp_stat_out_discards; 201 0 stevel kstat_named_t esp_stat_crypto_sync; 202 0 stevel kstat_named_t esp_stat_crypto_async; 203 0 stevel kstat_named_t esp_stat_crypto_failures; 204 0 stevel kstat_named_t esp_stat_num_ealgs; 205 0 stevel kstat_named_t esp_stat_bad_decrypt; 206 7066 danmcd kstat_named_t esp_stat_sa_port_renumbers; 207 0 stevel } esp_kstats_t; 208 0 stevel 209 3448 dh155122 /* 210 3448 dh155122 * espstack->esp_kstats is equal to espstack->esp_ksp->ks_data if 211 3448 dh155122 * kstat_create_netstack for espstack->esp_ksp succeeds, but when it 212 3448 dh155122 * fails, it will be NULL. Note this is done for all stack instances, 213 3448 dh155122 * so it *could* fail. hence a non-NULL checking is done for 214 3448 dh155122 * ESP_BUMP_STAT and ESP_DEBUMP_STAT 215 3448 dh155122 */ 216 3448 dh155122 #define ESP_BUMP_STAT(espstack, x) \ 217 3448 dh155122 do { \ 218 3448 dh155122 if (espstack->esp_kstats != NULL) \ 219 3448 dh155122 (espstack->esp_kstats->esp_stat_ ## x).value.ui64++; \ 220 3448 dh155122 _NOTE(CONSTCOND) \ 221 3448 dh155122 } while (0) 222 0 stevel 223 3448 dh155122 #define ESP_DEBUMP_STAT(espstack, x) \ 224 3448 dh155122 do { \ 225 3448 dh155122 if (espstack->esp_kstats != NULL) \ 226 3448 dh155122 (espstack->esp_kstats->esp_stat_ ## x).value.ui64--; \ 227 3448 dh155122 _NOTE(CONSTCOND) \ 228 3448 dh155122 } while (0) 229 0 stevel 230 0 stevel static int esp_kstat_update(kstat_t *, int); 231 0 stevel 232 0 stevel static boolean_t 233 3448 dh155122 esp_kstat_init(ipsecesp_stack_t *espstack, netstackid_t stackid) 234 0 stevel { 235 3448 dh155122 espstack->esp_ksp = kstat_create_netstack("ipsecesp", 0, "esp_stat", 236 3448 dh155122 "net", KSTAT_TYPE_NAMED, 237 3448 dh155122 sizeof (esp_kstats_t) / sizeof (kstat_named_t), 238 3448 dh155122 KSTAT_FLAG_PERSISTENT, stackid); 239 0 stevel 240 3448 dh155122 if (espstack->esp_ksp == NULL || espstack->esp_ksp->ks_data == NULL) 241 0 stevel return (B_FALSE); 242 0 stevel 243 3448 dh155122 espstack->esp_kstats = espstack->esp_ksp->ks_data; 244 0 stevel 245 3448 dh155122 espstack->esp_ksp->ks_update = esp_kstat_update; 246 3448 dh155122 espstack->esp_ksp->ks_private = (void *)(uintptr_t)stackid; 247 0 stevel 248 0 stevel #define K64 KSTAT_DATA_UINT64 249 3448 dh155122 #define KI(x) kstat_named_init(&(espstack->esp_kstats->esp_stat_##x), #x, K64) 250 0 stevel 251 0 stevel KI(num_aalgs); 252 0 stevel KI(num_ealgs); 253 0 stevel KI(good_auth); 254 0 stevel KI(bad_auth); 255 0 stevel KI(bad_padding); 256 0 stevel KI(replay_failures); 257 0 stevel KI(replay_early_failures); 258 0 stevel KI(keysock_in); 259 0 stevel KI(out_requests); 260 0 stevel KI(acquire_requests); 261 0 stevel KI(bytes_expired); 262 0 stevel KI(out_discards); 263 0 stevel KI(crypto_sync); 264 0 stevel KI(crypto_async); 265 0 stevel KI(crypto_failures); 266 0 stevel KI(bad_decrypt); 267 7066 danmcd KI(sa_port_renumbers); 268 0 stevel 269 0 stevel #undef KI 270 0 stevel #undef K64 271 0 stevel 272 3448 dh155122 kstat_install(espstack->esp_ksp); 273 0 stevel 274 0 stevel return (B_TRUE); 275 0 stevel } 276 0 stevel 277 0 stevel static int 278 0 stevel esp_kstat_update(kstat_t *kp, int rw) 279 0 stevel { 280 0 stevel esp_kstats_t *ekp; 281 3448 dh155122 netstackid_t stackid = (zoneid_t)(uintptr_t)kp->ks_private; 282 3448 dh155122 netstack_t *ns; 283 3448 dh155122 ipsec_stack_t *ipss; 284 0 stevel 285 0 stevel if ((kp == NULL) || (kp->ks_data == NULL)) 286 0 stevel return (EIO); 287 0 stevel 288 0 stevel if (rw == KSTAT_WRITE) 289 0 stevel return (EACCES); 290 0 stevel 291 3448 dh155122 ns = netstack_find_by_stackid(stackid); 292 3448 dh155122 if (ns == NULL) 293 3448 dh155122 return (-1); 294 3448 dh155122 ipss = ns->netstack_ipsec; 295 3448 dh155122 if (ipss == NULL) { 296 3448 dh155122 netstack_rele(ns); 297 3448 dh155122 return (-1); 298 3448 dh155122 } 299 0 stevel ekp = (esp_kstats_t *)kp->ks_data; 300 0 stevel 301 3448 dh155122 mutex_enter(&ipss->ipsec_alg_lock); 302 3448 dh155122 ekp->esp_stat_num_aalgs.value.ui64 = 303 3448 dh155122 ipss->ipsec_nalgs[IPSEC_ALG_AUTH]; 304 3448 dh155122 ekp->esp_stat_num_ealgs.value.ui64 = 305 3448 dh155122 ipss->ipsec_nalgs[IPSEC_ALG_ENCR]; 306 3448 dh155122 mutex_exit(&ipss->ipsec_alg_lock); 307 0 stevel 308 3448 dh155122 netstack_rele(ns); 309 0 stevel return (0); 310 0 stevel } 311 0 stevel 312 0 stevel #ifdef DEBUG 313 0 stevel /* 314 0 stevel * Debug routine, useful to see pre-encryption data. 315 0 stevel */ 316 0 stevel static char * 317 0 stevel dump_msg(mblk_t *mp) 318 0 stevel { 319 0 stevel char tmp_str[3], tmp_line[256]; 320 0 stevel 321 0 stevel while (mp != NULL) { 322 0 stevel unsigned char *ptr; 323 0 stevel 324 0 stevel printf("mblk address 0x%p, length %ld, db_ref %d " 325 0 stevel "type %d, base 0x%p, lim 0x%p\n", 326 0 stevel (void *) mp, (long)(mp->b_wptr - mp->b_rptr), 327 0 stevel mp->b_datap->db_ref, mp->b_datap->db_type, 328 0 stevel (void *)mp->b_datap->db_base, (void *)mp->b_datap->db_lim); 329 0 stevel ptr = mp->b_rptr; 330 0 stevel 331 0 stevel tmp_line[0] = '\0'; 332 0 stevel while (ptr < mp->b_wptr) { 333 0 stevel uint_t diff; 334 0 stevel 335 0 stevel diff = (ptr - mp->b_rptr); 336 0 stevel if (!(diff & 0x1f)) { 337 0 stevel if (strlen(tmp_line) > 0) { 338 0 stevel printf("bytes: %s\n", tmp_line); 339 0 stevel tmp_line[0] = '\0'; 340 0 stevel } 341 0 stevel } 342 0 stevel if (!(diff & 0x3)) 343 0 stevel (void) strcat(tmp_line, " "); 344 0 stevel (void) sprintf(tmp_str, "%02x", *ptr); 345 0 stevel (void) strcat(tmp_line, tmp_str); 346 0 stevel ptr++; 347 0 stevel } 348 0 stevel if (strlen(tmp_line) > 0) 349 0 stevel printf("bytes: %s\n", tmp_line); 350 0 stevel 351 0 stevel mp = mp->b_cont; 352 0 stevel } 353 0 stevel 354 0 stevel return ("\n"); 355 0 stevel } 356 0 stevel 357 0 stevel #else /* DEBUG */ 358 0 stevel static char * 359 0 stevel dump_msg(mblk_t *mp) 360 0 stevel { 361 0 stevel printf("Find value of mp %p.\n", mp); 362 0 stevel return ("\n"); 363 0 stevel } 364 0 stevel #endif /* DEBUG */ 365 0 stevel 366 0 stevel /* 367 0 stevel * Don't have to lock age_interval, as only one thread will access it at 368 0 stevel * a time, because I control the one function that does with timeout(). 369 0 stevel */ 370 0 stevel static void 371 3448 dh155122 esp_ager(void *arg) 372 0 stevel { 373 3448 dh155122 ipsecesp_stack_t *espstack = (ipsecesp_stack_t *)arg; 374 3448 dh155122 netstack_t *ns = espstack->ipsecesp_netstack; 375 0 stevel hrtime_t begin = gethrtime(); 376 0 stevel 377 3448 dh155122 sadb_ager(&espstack->esp_sadb.s_v4, espstack->esp_pfkey_q, 378 11042 Erik espstack->ipsecesp_reap_delay, ns); 379 3448 dh155122 sadb_ager(&espstack->esp_sadb.s_v6, espstack->esp_pfkey_q, 380 11042 Erik espstack->ipsecesp_reap_delay, ns); 381 0 stevel 382 3448 dh155122 espstack->esp_event = sadb_retimeout(begin, espstack->esp_pfkey_q, 383 3448 dh155122 esp_ager, espstack, 384 3448 dh155122 &espstack->ipsecesp_age_interval, espstack->ipsecesp_age_int_max, 385 3448 dh155122 info.mi_idnum); 386 0 stevel } 387 0 stevel 388 0 stevel /* 389 0 stevel * Get an ESP NDD parameter. 390 0 stevel */ 391 0 stevel /* ARGSUSED */ 392 0 stevel static int 393 0 stevel ipsecesp_param_get(q, mp, cp, cr) 394 0 stevel queue_t *q; 395 0 stevel mblk_t *mp; 396 0 stevel caddr_t cp; 397 0 stevel cred_t *cr; 398 0 stevel { 399 0 stevel ipsecespparam_t *ipsecesppa = (ipsecespparam_t *)cp; 400 0 stevel uint_t value; 401 3448 dh155122 ipsecesp_stack_t *espstack = (ipsecesp_stack_t *)q->q_ptr; 402 0 stevel 403 3448 dh155122 mutex_enter(&espstack->ipsecesp_param_lock); 404 0 stevel value = ipsecesppa->ipsecesp_param_value; 405 3448 dh155122 mutex_exit(&espstack->ipsecesp_param_lock); 406 0 stevel 407 0 stevel (void) mi_mpprintf(mp, "%u", value); 408 0 stevel return (0); 409 0 stevel } 410 0 stevel 411 0 stevel /* 412 0 stevel * This routine sets an NDD variable in a ipsecespparam_t structure. 413 0 stevel */ 414 0 stevel /* ARGSUSED */ 415 0 stevel static int 416 0 stevel ipsecesp_param_set(q, mp, value, cp, cr) 417 0 stevel queue_t *q; 418 0 stevel mblk_t *mp; 419 0 stevel char *value; 420 0 stevel caddr_t cp; 421 0 stevel cred_t *cr; 422 0 stevel { 423 0 stevel ulong_t new_value; 424 0 stevel ipsecespparam_t *ipsecesppa = (ipsecespparam_t *)cp; 425 3448 dh155122 ipsecesp_stack_t *espstack = (ipsecesp_stack_t *)q->q_ptr; 426 0 stevel 427 0 stevel /* 428 0 stevel * Fail the request if the new value does not lie within the 429 0 stevel * required bounds. 430 0 stevel */ 431 0 stevel if (ddi_strtoul(value, NULL, 10, &new_value) != 0 || 432 0 stevel new_value < ipsecesppa->ipsecesp_param_min || 433 0 stevel new_value > ipsecesppa->ipsecesp_param_max) { 434 0 stevel return (EINVAL); 435 0 stevel } 436 0 stevel 437 0 stevel /* Set the new value */ 438 3448 dh155122 mutex_enter(&espstack->ipsecesp_param_lock); 439 0 stevel ipsecesppa->ipsecesp_param_value = new_value; 440 3448 dh155122 mutex_exit(&espstack->ipsecesp_param_lock); 441 0 stevel return (0); 442 0 stevel } 443 0 stevel 444 0 stevel /* 445 0 stevel * Using lifetime NDD variables, fill in an extended combination's 446 0 stevel * lifetime information. 447 0 stevel */ 448 0 stevel void 449 3448 dh155122 ipsecesp_fill_defs(sadb_x_ecomb_t *ecomb, netstack_t *ns) 450 0 stevel { 451 3448 dh155122 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; 452 3448 dh155122 453 3448 dh155122 ecomb->sadb_x_ecomb_soft_bytes = espstack->ipsecesp_default_soft_bytes; 454 3448 dh155122 ecomb->sadb_x_ecomb_hard_bytes = espstack->ipsecesp_default_hard_bytes; 455 3448 dh155122 ecomb->sadb_x_ecomb_soft_addtime = 456 3448 dh155122 espstack->ipsecesp_default_soft_addtime; 457 3448 dh155122 ecomb->sadb_x_ecomb_hard_addtime = 458 3448 dh155122 espstack->ipsecesp_default_hard_addtime; 459 3448 dh155122 ecomb->sadb_x_ecomb_soft_usetime = 460 3448 dh155122 espstack->ipsecesp_default_soft_usetime; 461 3448 dh155122 ecomb->sadb_x_ecomb_hard_usetime = 462 3448 dh155122 espstack->ipsecesp_default_hard_usetime; 463 0 stevel } 464 0 stevel 465 0 stevel /* 466 0 stevel * Initialize things for ESP at module load time. 467 0 stevel */ 468 0 stevel boolean_t 469 0 stevel ipsecesp_ddi_init(void) 470 0 stevel { 471 3448 dh155122 esp_taskq = taskq_create("esp_taskq", 1, minclsyspri, 472 3448 dh155122 IPSEC_TASKQ_MIN, IPSEC_TASKQ_MAX, 0); 473 0 stevel 474 3448 dh155122 /* 475 3448 dh155122 * We want to be informed each time a stack is created or 476 3448 dh155122 * destroyed in the kernel, so we can maintain the 477 3448 dh155122 * set of ipsecesp_stack_t's. 478 3448 dh155122 */ 479 3448 dh155122 netstack_register(NS_IPSECESP, ipsecesp_stack_init, NULL, 480 3448 dh155122 ipsecesp_stack_fini); 481 3448 dh155122 482 3448 dh155122 return (B_TRUE); 483 3448 dh155122 } 484 3448 dh155122 485 3448 dh155122 /* 486 3448 dh155122 * Walk through the param array specified registering each element with the 487 3448 dh155122 * named dispatch handler. 488 3448 dh155122 */ 489 3448 dh155122 static boolean_t 490 3448 dh155122 ipsecesp_param_register(IDP *ndp, ipsecespparam_t *espp, int cnt) 491 3448 dh155122 { 492 3448 dh155122 for (; cnt-- > 0; espp++) { 493 0 stevel if (espp->ipsecesp_param_name != NULL && 494 0 stevel espp->ipsecesp_param_name[0]) { 495 3448 dh155122 if (!nd_load(ndp, 496 3448 dh155122 espp->ipsecesp_param_name, 497 0 stevel ipsecesp_param_get, ipsecesp_param_set, 498 0 stevel (caddr_t)espp)) { 499 3448 dh155122 nd_free(ndp); 500 0 stevel return (B_FALSE); 501 0 stevel } 502 0 stevel } 503 0 stevel } 504 3448 dh155122 return (B_TRUE); 505 3448 dh155122 } 506 3448 dh155122 /* 507 3448 dh155122 * Initialize things for ESP for each stack instance 508 3448 dh155122 */ 509 3448 dh155122 static void * 510 3448 dh155122 ipsecesp_stack_init(netstackid_t stackid, netstack_t *ns) 511 3448 dh155122 { 512 3448 dh155122 ipsecesp_stack_t *espstack; 513 3448 dh155122 ipsecespparam_t *espp; 514 0 stevel 515 3448 dh155122 espstack = (ipsecesp_stack_t *)kmem_zalloc(sizeof (*espstack), 516 3448 dh155122 KM_SLEEP); 517 3448 dh155122 espstack->ipsecesp_netstack = ns; 518 0 stevel 519 3448 dh155122 espp = (ipsecespparam_t *)kmem_alloc(sizeof (lcl_param_arr), KM_SLEEP); 520 3448 dh155122 espstack->ipsecesp_params = espp; 521 3448 dh155122 bcopy(lcl_param_arr, espp, sizeof (lcl_param_arr)); 522 0 stevel 523 3448 dh155122 (void) ipsecesp_param_register(&espstack->ipsecesp_g_nd, espp, 524 3448 dh155122 A_CNT(lcl_param_arr)); 525 0 stevel 526 3448 dh155122 (void) esp_kstat_init(espstack, stackid); 527 0 stevel 528 3448 dh155122 espstack->esp_sadb.s_acquire_timeout = 529 3448 dh155122 &espstack->ipsecesp_acquire_timeout; 530 3448 dh155122 espstack->esp_sadb.s_acqfn = esp_send_acquire; 531 3448 dh155122 sadbp_init("ESP", &espstack->esp_sadb, SADB_SATYPE_ESP, esp_hash_size, 532 3448 dh155122 espstack->ipsecesp_netstack); 533 0 stevel 534 3448 dh155122 mutex_init(&espstack->ipsecesp_param_lock, NULL, MUTEX_DEFAULT, 0); 535 3448 dh155122 536 3448 dh155122 ip_drop_register(&espstack->esp_dropper, "IPsec ESP"); 537 3448 dh155122 return (espstack); 538 0 stevel } 539 0 stevel 540 0 stevel /* 541 0 stevel * Destroy things for ESP at module unload time. 542 0 stevel */ 543 0 stevel void 544 0 stevel ipsecesp_ddi_destroy(void) 545 0 stevel { 546 3448 dh155122 netstack_unregister(NS_IPSECESP); 547 3448 dh155122 taskq_destroy(esp_taskq); 548 3448 dh155122 } 549 0 stevel 550 3448 dh155122 /* 551 3448 dh155122 * Destroy things for ESP for one stack instance 552 3448 dh155122 */ 553 3448 dh155122 static void 554 3448 dh155122 ipsecesp_stack_fini(netstackid_t stackid, void *arg) 555 3448 dh155122 { 556 3448 dh155122 ipsecesp_stack_t *espstack = (ipsecesp_stack_t *)arg; 557 3448 dh155122 558 3448 dh155122 if (espstack->esp_pfkey_q != NULL) { 559 3448 dh155122 (void) quntimeout(espstack->esp_pfkey_q, espstack->esp_event); 560 3448 dh155122 } 561 3448 dh155122 espstack->esp_sadb.s_acqfn = NULL; 562 3448 dh155122 espstack->esp_sadb.s_acquire_timeout = NULL; 563 3448 dh155122 sadbp_destroy(&espstack->esp_sadb, espstack->ipsecesp_netstack); 564 3448 dh155122 ip_drop_unregister(&espstack->esp_dropper); 565 3448 dh155122 mutex_destroy(&espstack->ipsecesp_param_lock); 566 3448 dh155122 nd_free(&espstack->ipsecesp_g_nd); 567 3448 dh155122 568 3448 dh155122 kmem_free(espstack->ipsecesp_params, sizeof (lcl_param_arr)); 569 3448 dh155122 espstack->ipsecesp_params = NULL; 570 3448 dh155122 kstat_delete_netstack(espstack->esp_ksp, stackid); 571 3448 dh155122 espstack->esp_ksp = NULL; 572 3448 dh155122 espstack->esp_kstats = NULL; 573 3448 dh155122 kmem_free(espstack, sizeof (*espstack)); 574 0 stevel } 575 0 stevel 576 0 stevel /* 577 11042 Erik * ESP module open routine, which is here for keysock plumbing. 578 11042 Erik * Keysock is pushed over {AH,ESP} which is an artifact from the Bad Old 579 11042 Erik * Days of export control, and fears that ESP would not be allowed 580 11042 Erik * to be shipped at all by default. Eventually, keysock should 581 11042 Erik * either access AH and ESP via modstubs or krtld dependencies, or 582 11042 Erik * perhaps be folded in with AH and ESP into a single IPsec/netsec 583 11042 Erik * module ("netsec" if PF_KEY provides more than AH/ESP keying tables). 584 0 stevel */ 585 0 stevel /* ARGSUSED */ 586 0 stevel static int 587 0 stevel ipsecesp_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp) 588 0 stevel { 589 3448 dh155122 netstack_t *ns; 590 3448 dh155122 ipsecesp_stack_t *espstack; 591 3448 dh155122 592 7118 sommerfe if (secpolicy_ip_config(credp, B_FALSE) != 0) 593 0 stevel return (EPERM); 594 0 stevel 595 0 stevel if (q->q_ptr != NULL) 596 0 stevel return (0); /* Re-open of an already open instance. */ 597 0 stevel 598 0 stevel if (sflag != MODOPEN) 599 0 stevel return (EINVAL); 600 3448 dh155122 601 3448 dh155122 ns = netstack_find_by_cred(credp); 602 3448 dh155122 ASSERT(ns != NULL); 603 3448 dh155122 espstack = ns->netstack_ipsecesp; 604 3448 dh155122 ASSERT(espstack != NULL); 605 0 stevel 606 3448 dh155122 q->q_ptr = espstack; 607 3448 dh155122 WR(q)->q_ptr = q->q_ptr; 608 0 stevel 609 11042 Erik qprocson(q); 610 0 stevel return (0); 611 0 stevel } 612 0 stevel 613 0 stevel /* 614 0 stevel * ESP module close routine. 615 0 stevel */ 616 0 stevel static int 617 0 stevel ipsecesp_close(queue_t *q) 618 0 stevel { 619 3448 dh155122 ipsecesp_stack_t *espstack = (ipsecesp_stack_t *)q->q_ptr; 620 0 stevel 621 0 stevel /* 622 0 stevel * Clean up q_ptr, if needed. 623 0 stevel */ 624 0 stevel qprocsoff(q); 625 0 stevel 626 0 stevel /* Keysock queue check is safe, because of OCEXCL perimeter. */ 627 0 stevel 628 3448 dh155122 if (q == espstack->esp_pfkey_q) { 629 3448 dh155122 esp1dbg(espstack, 630 3448 dh155122 ("ipsecesp_close: Ummm... keysock is closing ESP.\n")); 631 3448 dh155122 espstack->esp_pfkey_q = NULL; 632 0 stevel /* Detach qtimeouts. */ 633 3448 dh155122 (void) quntimeout(q, espstack->esp_event); 634 0 stevel } 635 0 stevel 636 3448 dh155122 netstack_rele(espstack->ipsecesp_netstack); 637 0 stevel return (0); 638 0 stevel } 639 0 stevel 640 0 stevel /* 641 0 stevel * Add a number of bytes to what the SA has protected so far. Return 642 0 stevel * B_TRUE if the SA can still protect that many bytes. 643 0 stevel * 644 0 stevel * Caller must REFRELE the passed-in assoc. This function must REFRELE 645 0 stevel * any obtained peer SA. 646 0 stevel */ 647 0 stevel static boolean_t 648 0 stevel esp_age_bytes(ipsa_t *assoc, uint64_t bytes, boolean_t inbound) 649 0 stevel { 650 0 stevel ipsa_t *inassoc, *outassoc; 651 0 stevel isaf_t *bucket; 652 0 stevel boolean_t inrc, outrc, isv6; 653 0 stevel sadb_t *sp; 654 0 stevel int outhash; 655 3448 dh155122 netstack_t *ns = assoc->ipsa_netstack; 656 3448 dh155122 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; 657 0 stevel 658 0 stevel /* No peer? No problem! */ 659 0 stevel if (!assoc->ipsa_haspeer) { 660 3448 dh155122 return (sadb_age_bytes(espstack->esp_pfkey_q, assoc, bytes, 661 0 stevel B_TRUE)); 662 0 stevel } 663 0 stevel 664 0 stevel /* 665 0 stevel * Otherwise, we want to grab both the original assoc and its peer. 666 0 stevel * There might be a race for this, but if it's a real race, two 667 0 stevel * expire messages may occur. We limit this by only sending the 668 0 stevel * expire message on one of the peers, we'll pick the inbound 669 0 stevel * arbitrarily. 670 0 stevel * 671 0 stevel * If we need tight synchronization on the peer SA, then we need to 672 0 stevel * reconsider. 673 0 stevel */ 674 0 stevel 675 0 stevel /* Use address length to select IPv6/IPv4 */ 676 0 stevel isv6 = (assoc->ipsa_addrfam == AF_INET6); 677 3448 dh155122 sp = isv6 ? &espstack->esp_sadb.s_v6 : &espstack->esp_sadb.s_v4; 678 0 stevel 679 0 stevel if (inbound) { 680 0 stevel inassoc = assoc; 681 0 stevel if (isv6) { 682 564 sommerfe outhash = OUTBOUND_HASH_V6(sp, *((in6_addr_t *) 683 0 stevel &inassoc->ipsa_dstaddr)); 684 0 stevel } else { 685 564 sommerfe outhash = OUTBOUND_HASH_V4(sp, *((ipaddr_t *) 686 4987 danmcd &inassoc->ipsa_dstaddr)); 687 0 stevel } 688 0 stevel bucket = &sp->sdb_of[outhash]; 689 0 stevel mutex_enter(&bucket->isaf_lock); 690 0 stevel outassoc = ipsec_getassocbyspi(bucket, inassoc->ipsa_spi, 691 0 stevel inassoc->ipsa_srcaddr, inassoc->ipsa_dstaddr, 692 0 stevel inassoc->ipsa_addrfam); 693 0 stevel mutex_exit(&bucket->isaf_lock); 694 0 stevel if (outassoc == NULL) { 695 0 stevel /* Q: Do we wish to set haspeer == B_FALSE? */ 696 0 stevel esp0dbg(("esp_age_bytes: " 697 0 stevel "can't find peer for inbound.\n")); 698 3448 dh155122 return (sadb_age_bytes(espstack->esp_pfkey_q, inassoc, 699 0 stevel bytes, B_TRUE)); 700 0 stevel } 701 0 stevel } else { 702 0 stevel outassoc = assoc; 703 564 sommerfe bucket = INBOUND_BUCKET(sp, outassoc->ipsa_spi); 704 0 stevel mutex_enter(&bucket->isaf_lock); 705 0 stevel inassoc = ipsec_getassocbyspi(bucket, outassoc->ipsa_spi, 706 0 stevel outassoc->ipsa_srcaddr, outassoc->ipsa_dstaddr, 707 0 stevel outassoc->ipsa_addrfam); 708 0 stevel mutex_exit(&bucket->isaf_lock); 709 0 stevel if (inassoc == NULL) { 710 0 stevel /* Q: Do we wish to set haspeer == B_FALSE? */ 711 0 stevel esp0dbg(("esp_age_bytes: " 712 0 stevel "can't find peer for outbound.\n")); 713 3448 dh155122 return (sadb_age_bytes(espstack->esp_pfkey_q, outassoc, 714 0 stevel bytes, B_TRUE)); 715 0 stevel } 716 0 stevel } 717 0 stevel 718 3448 dh155122 inrc = sadb_age_bytes(espstack->esp_pfkey_q, inassoc, bytes, B_TRUE); 719 3448 dh155122 outrc = sadb_age_bytes(espstack->esp_pfkey_q, outassoc, bytes, B_FALSE); 720 0 stevel 721 0 stevel /* 722 0 stevel * REFRELE any peer SA. 723 0 stevel * 724 0 stevel * Because of the multi-line macro nature of IPSA_REFRELE, keep 725 0 stevel * them in { }. 726 0 stevel */ 727 0 stevel if (inbound) { 728 0 stevel IPSA_REFRELE(outassoc); 729 0 stevel } else { 730 0 stevel IPSA_REFRELE(inassoc); 731 0 stevel } 732 0 stevel 733 0 stevel return (inrc && outrc); 734 0 stevel } 735 0 stevel 736 0 stevel /* 737 0 stevel * Do incoming NAT-T manipulations for packet. 738 11042 Erik * Returns NULL if the mblk chain is consumed. 739 11042 Erik */ 740 11042 Erik static mblk_t * 741 0 stevel esp_fix_natt_checksums(mblk_t *data_mp, ipsa_t *assoc) 742 0 stevel { 743 0 stevel ipha_t *ipha = (ipha_t *)data_mp->b_rptr; 744 11042 Erik tcpha_t *tcpha; 745 0 stevel udpha_t *udpha; 746 0 stevel /* Initialize to our inbound cksum adjustment... */ 747 0 stevel uint32_t sum = assoc->ipsa_inbound_cksum; 748 0 stevel 749 0 stevel switch (ipha->ipha_protocol) { 750 0 stevel case IPPROTO_TCP: 751 11042 Erik tcpha = (tcpha_t *)(data_mp->b_rptr + 752 0 stevel IPH_HDR_LENGTH(ipha)); 753 0 stevel 754 0 stevel #define DOWN_SUM(x) (x) = ((x) & 0xFFFF) + ((x) >> 16) 755 11042 Erik sum += ~ntohs(tcpha->tha_sum) & 0xFFFF; 756 0 stevel DOWN_SUM(sum); 757 0 stevel DOWN_SUM(sum); 758 11042 Erik tcpha->tha_sum = ~htons(sum); 759 0 stevel break; 760 0 stevel case IPPROTO_UDP: 761 0 stevel udpha = (udpha_t *)(data_mp->b_rptr + IPH_HDR_LENGTH(ipha)); 762 0 stevel 763 0 stevel if (udpha->uha_checksum != 0) { 764 0 stevel /* Adujst if the inbound one was not zero. */ 765 0 stevel sum += ~ntohs(udpha->uha_checksum) & 0xFFFF; 766 0 stevel DOWN_SUM(sum); 767 0 stevel DOWN_SUM(sum); 768 0 stevel udpha->uha_checksum = ~htons(sum); 769 0 stevel if (udpha->uha_checksum == 0) 770 0 stevel udpha->uha_checksum = 0xFFFF; 771 0 stevel } 772 0 stevel #undef DOWN_SUM 773 0 stevel break; 774 0 stevel case IPPROTO_IP: 775 0 stevel /* 776 0 stevel * This case is only an issue for self-encapsulated 777 0 stevel * packets. So for now, fall through. 778 0 stevel */ 779 0 stevel break; 780 0 stevel } 781 11042 Erik return (data_mp); 782 0 stevel } 783 0 stevel 784 0 stevel 785 0 stevel /* 786 3192 danmcd * Strip ESP header, check padding, and fix IP header. 787 0 stevel * Returns B_TRUE on success, B_FALSE if an error occured. 788 0 stevel */ 789 0 stevel static boolean_t 790 0 stevel esp_strip_header(mblk_t *data_mp, boolean_t isv4, uint32_t ivlen, 791 3448 dh155122 kstat_named_t **counter, ipsecesp_stack_t *espstack) 792 0 stevel { 793 0 stevel ipha_t *ipha; 794 0 stevel ip6_t *ip6h; 795 0 stevel uint_t divpoint; 796 0 stevel mblk_t *scratch; 797 0 stevel uint8_t nexthdr, padlen; 798 0 stevel uint8_t lastpad; 799 3448 dh155122 ipsec_stack_t *ipss = espstack->ipsecesp_netstack->netstack_ipsec; 800 3192 danmcd uint8_t *lastbyte; 801 0 stevel 802 0 stevel /* 803 0 stevel * Strip ESP data and fix IP header. 804 0 stevel * 805 0 stevel * XXX In case the beginning of esp_inbound() changes to not do a 806 0 stevel * pullup, this part of the code can remain unchanged. 807 0 stevel */ 808 0 stevel if (isv4) { 809 0 stevel ASSERT((data_mp->b_wptr - data_mp->b_rptr) >= sizeof (ipha_t)); 810 0 stevel ipha = (ipha_t *)data_mp->b_rptr; 811 0 stevel ASSERT((data_mp->b_wptr - data_mp->b_rptr) >= sizeof (esph_t) + 812 0 stevel IPH_HDR_LENGTH(ipha)); 813 0 stevel divpoint = IPH_HDR_LENGTH(ipha); 814 0 stevel } else { 815 0 stevel ASSERT((data_mp->b_wptr - data_mp->b_rptr) >= sizeof (ip6_t)); 816 0 stevel ip6h = (ip6_t *)data_mp->b_rptr; 817 0 stevel divpoint = ip_hdr_length_v6(data_mp, ip6h); 818 0 stevel } 819 0 stevel 820 0 stevel scratch = data_mp; 821 0 stevel while (scratch->b_cont != NULL) 822 0 stevel scratch = scratch->b_cont; 823 0 stevel 824 0 stevel ASSERT((scratch->b_wptr - scratch->b_rptr) >= 3); 825 0 stevel 826 0 stevel /* 827 0 stevel * "Next header" and padding length are the last two bytes in the 828 0 stevel * ESP-protected datagram, thus the explicit - 1 and - 2. 829 0 stevel * lastpad is the last byte of the padding, which can be used for 830 0 stevel * a quick check to see if the padding is correct. 831 0 stevel */ 832 3192 danmcd lastbyte = scratch->b_wptr - 1; 833 3192 danmcd nexthdr = *lastbyte--; 834 3192 danmcd padlen = *lastbyte--; 835 0 stevel 836 0 stevel if (isv4) { 837 0 stevel /* Fix part of the IP header. */ 838 0 stevel ipha->ipha_protocol = nexthdr; 839 0 stevel /* 840 0 stevel * Reality check the padlen. The explicit - 2 is for the 841 0 stevel * padding length and the next-header bytes. 842 0 stevel */ 843 0 stevel if (padlen >= ntohs(ipha->ipha_length) - sizeof (ipha_t) - 2 - 844 0 stevel sizeof (esph_t) - ivlen) { 845 3448 dh155122 ESP_BUMP_STAT(espstack, bad_decrypt); 846 3448 dh155122 ipsec_rl_strlog(espstack->ipsecesp_netstack, 847 3448 dh155122 info.mi_idnum, 0, 0, 848 3448 dh155122 SL_ERROR | SL_WARN, 849 3192 danmcd "Corrupt ESP packet (padlen too big).\n"); 850 3448 dh155122 esp1dbg(espstack, ("padlen (%d) is greater than:\n", 851 4987 danmcd padlen)); 852 3448 dh155122 esp1dbg(espstack, ("pkt len(%d) - ip hdr - esp " 853 3448 dh155122 "hdr - ivlen(%d) = %d.\n", 854 3448 dh155122 ntohs(ipha->ipha_length), ivlen, 855 0 stevel (int)(ntohs(ipha->ipha_length) - sizeof (ipha_t) - 856 3448 dh155122 2 - sizeof (esph_t) - ivlen))); 857 3448 dh155122 *counter = DROPPER(ipss, ipds_esp_bad_padlen); 858 0 stevel return (B_FALSE); 859 0 stevel } 860 0 stevel 861 0 stevel /* 862 0 stevel * Fix the rest of the header. The explicit - 2 is for the 863 0 stevel * padding length and the next-header bytes. 864 0 stevel */ 865 0 stevel ipha->ipha_length = htons(ntohs(ipha->ipha_length) - padlen - 866 0 stevel 2 - sizeof (esph_t) - ivlen); 867 0 stevel ipha->ipha_hdr_checksum = 0; 868 0 stevel ipha->ipha_hdr_checksum = (uint16_t)ip_csum_hdr(ipha); 869 0 stevel } else { 870 0 stevel if (ip6h->ip6_nxt == IPPROTO_ESP) { 871 0 stevel ip6h->ip6_nxt = nexthdr; 872 0 stevel } else { 873 11042 Erik ip_pkt_t ipp; 874 0 stevel 875 0 stevel bzero(&ipp, sizeof (ipp)); 876 11042 Erik (void) ip_find_hdr_v6(data_mp, ip6h, B_FALSE, &ipp, 877 11042 Erik NULL); 878 0 stevel if (ipp.ipp_dstopts != NULL) { 879 0 stevel ipp.ipp_dstopts->ip6d_nxt = nexthdr; 880 0 stevel } else if (ipp.ipp_rthdr != NULL) { 881 0 stevel ipp.ipp_rthdr->ip6r_nxt = nexthdr; 882 0 stevel } else if (ipp.ipp_hopopts != NULL) { 883 0 stevel ipp.ipp_hopopts->ip6h_nxt = nexthdr; 884 0 stevel } else { 885 0 stevel /* Panic a DEBUG kernel. */ 886 0 stevel ASSERT(ipp.ipp_hopopts != NULL); 887 0 stevel /* Otherwise, pretend it's IP + ESP. */ 888 0 stevel cmn_err(CE_WARN, "ESP IPv6 headers wrong.\n"); 889 0 stevel ip6h->ip6_nxt = nexthdr; 890 0 stevel } 891 0 stevel } 892 0 stevel 893 0 stevel if (padlen >= ntohs(ip6h->ip6_plen) - 2 - sizeof (esph_t) - 894 0 stevel ivlen) { 895 3448 dh155122 ESP_BUMP_STAT(espstack, bad_decrypt); 896 3448 dh155122 ipsec_rl_strlog(espstack->ipsecesp_netstack, 897 3448 dh155122 info.mi_idnum, 0, 0, 898 3448 dh155122 SL_ERROR | SL_WARN, 899 3192 danmcd "Corrupt ESP packet (v6 padlen too big).\n"); 900 3448 dh155122 esp1dbg(espstack, ("padlen (%d) is greater than:\n", 901 4987 danmcd padlen)); 902 4987 danmcd esp1dbg(espstack, 903 4987 danmcd ("pkt len(%u) - ip hdr - esp hdr - ivlen(%d) = " 904 4987 danmcd "%u.\n", (unsigned)(ntohs(ip6h->ip6_plen) 905 4987 danmcd + sizeof (ip6_t)), ivlen, 906 4987 danmcd (unsigned)(ntohs(ip6h->ip6_plen) - 2 - 907 4987 danmcd sizeof (esph_t) - ivlen))); 908 3448 dh155122 *counter = DROPPER(ipss, ipds_esp_bad_padlen); 909 0 stevel return (B_FALSE); 910 0 stevel } 911 0 stevel 912 0 stevel 913 0 stevel /* 914 0 stevel * Fix the rest of the header. The explicit - 2 is for the 915 0 stevel * padding length and the next-header bytes. IPv6 is nice, 916 0 stevel * because there's no hdr checksum! 917 0 stevel */ 918 0 stevel ip6h->ip6_plen = htons(ntohs(ip6h->ip6_plen) - padlen - 919 0 stevel 2 - sizeof (esph_t) - ivlen); 920 0 stevel } 921 0 stevel 922 3448 dh155122 if (espstack->ipsecesp_padding_check > 0 && padlen > 0) { 923 3192 danmcd /* 924 3192 danmcd * Weak padding check: compare last-byte to length, they 925 3192 danmcd * should be equal. 926 3192 danmcd */ 927 3192 danmcd lastpad = *lastbyte--; 928 0 stevel 929 3192 danmcd if (padlen != lastpad) { 930 3448 dh155122 ipsec_rl_strlog(espstack->ipsecesp_netstack, 931 3448 dh155122 info.mi_idnum, 0, 0, SL_ERROR | SL_WARN, 932 3192 danmcd "Corrupt ESP packet (lastpad != padlen).\n"); 933 3448 dh155122 esp1dbg(espstack, 934 3448 dh155122 ("lastpad (%d) not equal to padlen (%d):\n", 935 3448 dh155122 lastpad, padlen)); 936 3448 dh155122 ESP_BUMP_STAT(espstack, bad_padding); 937 3448 dh155122 *counter = DROPPER(ipss, ipds_esp_bad_padding); 938 3192 danmcd return (B_FALSE); 939 3192 danmcd } 940 0 stevel 941 0 stevel /* 942 3192 danmcd * Strong padding check: Check all pad bytes to see that 943 3192 danmcd * they're ascending. Go backwards using a descending counter 944 3192 danmcd * to verify. padlen == 1 is checked by previous block, so 945 3192 danmcd * only bother if we've more than 1 byte of padding. 946 3192 danmcd * Consequently, start the check one byte before the location 947 3192 danmcd * of "lastpad". 948 0 stevel */ 949 3448 dh155122 if (espstack->ipsecesp_padding_check > 1) { 950 3192 danmcd /* 951 3192 danmcd * This assert may have to become an if and a pullup 952 3192 danmcd * if we start accepting multi-dblk mblks. For now, 953 3192 danmcd * though, any packet here will have been pulled up in 954 3192 danmcd * esp_inbound. 955 3192 danmcd */ 956 3192 danmcd ASSERT(MBLKL(scratch) >= lastpad + 3); 957 0 stevel 958 3192 danmcd /* 959 3192 danmcd * Use "--lastpad" because we already checked the very 960 3192 danmcd * last pad byte previously. 961 3192 danmcd */ 962 3192 danmcd while (--lastpad != 0) { 963 3192 danmcd if (lastpad != *lastbyte) { 964 3448 dh155122 ipsec_rl_strlog( 965 3448 dh155122 espstack->ipsecesp_netstack, 966 3448 dh155122 info.mi_idnum, 0, 0, 967 3192 danmcd SL_ERROR | SL_WARN, "Corrupt ESP " 968 3192 danmcd "packet (bad padding).\n"); 969 3448 dh155122 esp1dbg(espstack, 970 3448 dh155122 ("padding not in correct" 971 3448 dh155122 " format:\n")); 972 3448 dh155122 ESP_BUMP_STAT(espstack, bad_padding); 973 3448 dh155122 *counter = DROPPER(ipss, 974 3448 dh155122 ipds_esp_bad_padding); 975 3192 danmcd return (B_FALSE); 976 3192 danmcd } 977 3192 danmcd lastbyte--; 978 0 stevel } 979 0 stevel } 980 0 stevel } 981 0 stevel 982 0 stevel /* Trim off the padding. */ 983 0 stevel ASSERT(data_mp->b_cont == NULL); 984 0 stevel data_mp->b_wptr -= (padlen + 2); 985 0 stevel 986 0 stevel /* 987 0 stevel * Remove the ESP header. 988 0 stevel * 989 0 stevel * The above assertions about data_mp's size will make this work. 990 0 stevel * 991 0 stevel * XXX Question: If I send up and get back a contiguous mblk, 992 0 stevel * would it be quicker to bcopy over, or keep doing the dupb stuff? 993 0 stevel * I go with copying for now. 994 0 stevel */ 995 0 stevel 996 0 stevel if (IS_P2ALIGNED(data_mp->b_rptr, sizeof (uint32_t)) && 997 0 stevel IS_P2ALIGNED(ivlen, sizeof (uint32_t))) { 998 0 stevel uint8_t *start = data_mp->b_rptr; 999 0 stevel uint32_t *src, *dst; 1000 0 stevel 1001 0 stevel src = (uint32_t *)(start + divpoint); 1002 0 stevel dst = (uint32_t *)(start + divpoint + sizeof (esph_t) + ivlen); 1003 0 stevel 1004 0 stevel ASSERT(IS_P2ALIGNED(dst, sizeof (uint32_t)) && 1005 0 stevel IS_P2ALIGNED(src, sizeof (uint32_t))); 1006 0 stevel 1007 0 stevel do { 1008 0 stevel src--; 1009 0 stevel dst--; 1010 0 stevel *dst = *src; 1011 0 stevel } while (src != (uint32_t *)start); 1012 0 stevel 1013 0 stevel data_mp->b_rptr = (uchar_t *)dst; 1014 0 stevel } else { 1015 0 stevel uint8_t *start = data_mp->b_rptr; 1016 0 stevel uint8_t *src, *dst; 1017 0 stevel 1018 0 stevel src = start + divpoint; 1019 0 stevel dst = src + sizeof (esph_t) + ivlen; 1020 0 stevel 1021 0 stevel do { 1022 0 stevel src--; 1023 0 stevel dst--; 1024 0 stevel *dst = *src; 1025 0 stevel } while (src != start); 1026 0 stevel 1027 0 stevel data_mp->b_rptr = dst; 1028 0 stevel } 1029 0 stevel 1030 3448 dh155122 esp2dbg(espstack, ("data_mp after inbound ESP adjustment:\n")); 1031 3448 dh155122 esp2dbg(espstack, (dump_msg(data_mp))); 1032 0 stevel 1033 0 stevel return (B_TRUE); 1034 0 stevel } 1035 0 stevel 1036 0 stevel /* 1037 0 stevel * Updating use times can be tricky business if the ipsa_haspeer flag is 1038 0 stevel * set. This function is called once in an SA's lifetime. 1039 0 stevel * 1040 0 stevel * Caller has to REFRELE "assoc" which is passed in. This function has 1041 0 stevel * to REFRELE any peer SA that is obtained. 1042 0 stevel */ 1043 0 stevel static void 1044 0 stevel esp_set_usetime(ipsa_t *assoc, boolean_t inbound) 1045 0 stevel { 1046 0 stevel ipsa_t *inassoc, *outassoc; 1047 0 stevel isaf_t *bucket; 1048 0 stevel sadb_t *sp; 1049 0 stevel int outhash; 1050 0 stevel boolean_t isv6; 1051 3448 dh155122 netstack_t *ns = assoc->ipsa_netstack; 1052 3448 dh155122 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; 1053 0 stevel 1054 0 stevel /* No peer? No problem! */ 1055 0 stevel if (!assoc->ipsa_haspeer) { 1056 0 stevel sadb_set_usetime(assoc); 1057 0 stevel return; 1058 0 stevel } 1059 0 stevel 1060 0 stevel /* 1061 0 stevel * Otherwise, we want to grab both the original assoc and its peer. 1062 0 stevel * There might be a race for this, but if it's a real race, the times 1063 0 stevel * will be out-of-synch by at most a second, and since our time 1064 0 stevel * granularity is a second, this won't be a problem. 1065 0 stevel * 1066 0 stevel * If we need tight synchronization on the peer SA, then we need to 1067 0 stevel * reconsider. 1068 0 stevel */ 1069 0 stevel 1070 0 stevel /* Use address length to select IPv6/IPv4 */ 1071 0 stevel isv6 = (assoc->ipsa_addrfam == AF_INET6); 1072 3448 dh155122 sp = isv6 ? &espstack->esp_sadb.s_v6 : &espstack->esp_sadb.s_v4; 1073 0 stevel 1074 0 stevel if (inbound) { 1075 0 stevel inassoc = assoc; 1076 0 stevel if (isv6) { 1077 564 sommerfe outhash = OUTBOUND_HASH_V6(sp, *((in6_addr_t *) 1078 0 stevel &inassoc->ipsa_dstaddr)); 1079 0 stevel } else { 1080 564 sommerfe outhash = OUTBOUND_HASH_V4(sp, *((ipaddr_t *) 1081 4987 danmcd &inassoc->ipsa_dstaddr)); 1082 0 stevel } 1083 0 stevel bucket = &sp->sdb_of[outhash]; 1084 0 stevel mutex_enter(&bucket->isaf_lock); 1085 0 stevel outassoc = ipsec_getassocbyspi(bucket, inassoc->ipsa_spi, 1086 0 stevel inassoc->ipsa_srcaddr, inassoc->ipsa_dstaddr, 1087 0 stevel inassoc->ipsa_addrfam); 1088 0 stevel mutex_exit(&bucket->isaf_lock); 1089 0 stevel if (outassoc == NULL) { 1090 0 stevel /* Q: Do we wish to set haspeer == B_FALSE? */ 1091 0 stevel esp0dbg(("esp_set_usetime: " 1092 0 stevel "can't find peer for inbound.\n")); 1093 0 stevel sadb_set_usetime(inassoc); 1094 0 stevel return; 1095 0 stevel } 1096 0 stevel } else { 1097 0 stevel outassoc = assoc; 1098 564 sommerfe bucket = INBOUND_BUCKET(sp, outassoc->ipsa_spi); 1099 0 stevel mutex_enter(&bucket->isaf_lock); 1100 0 stevel inassoc = ipsec_getassocbyspi(bucket, outassoc->ipsa_spi, 1101 0 stevel outassoc->ipsa_srcaddr, outassoc->ipsa_dstaddr, 1102 0 stevel outassoc->ipsa_addrfam); 1103 0 stevel mutex_exit(&bucket->isaf_lock); 1104 0 stevel if (inassoc == NULL) { 1105 0 stevel /* Q: Do we wish to set haspeer == B_FALSE? */ 1106 0 stevel esp0dbg(("esp_set_usetime: " 1107 0 stevel "can't find peer for outbound.\n")); 1108 0 stevel sadb_set_usetime(outassoc); 1109 0 stevel return; 1110 0 stevel } 1111 0 stevel } 1112 0 stevel 1113 0 stevel /* Update usetime on both. */ 1114 0 stevel sadb_set_usetime(inassoc); 1115 0 stevel sadb_set_usetime(outassoc); 1116 0 stevel 1117 0 stevel /* 1118 0 stevel * REFRELE any peer SA. 1119 0 stevel * 1120 0 stevel * Because of the multi-line macro nature of IPSA_REFRELE, keep 1121 0 stevel * them in { }. 1122 0 stevel */ 1123 0 stevel if (inbound) { 1124 0 stevel IPSA_REFRELE(outassoc); 1125 0 stevel } else { 1126 0 stevel IPSA_REFRELE(inassoc); 1127 0 stevel } 1128 0 stevel } 1129 0 stevel 1130 0 stevel /* 1131 0 stevel * Handle ESP inbound data for IPv4 and IPv6. 1132 0 stevel * On success returns B_TRUE, on failure returns B_FALSE and frees the 1133 11042 Erik * mblk chain data_mp. 1134 11042 Erik */ 1135 11042 Erik mblk_t * 1136 11042 Erik esp_inbound(mblk_t *data_mp, void *arg, ip_recv_attr_t *ira) 1137 11042 Erik { 1138 0 stevel esph_t *esph = (esph_t *)arg; 1139 11042 Erik ipsa_t *ipsa = ira->ira_ipsec_esp_sa; 1140 11042 Erik netstack_t *ns = ira->ira_ill->ill_ipst->ips_netstack; 1141 3448 dh155122 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; 1142 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 1143 0 stevel 1144 0 stevel /* 1145 0 stevel * We may wish to check replay in-range-only here as an optimization. 1146 0 stevel * Include the reality check of ipsa->ipsa_replay > 1147 0 stevel * ipsa->ipsa_replay_wsize for times when it's the first N packets, 1148 0 stevel * where N == ipsa->ipsa_replay_wsize. 1149 0 stevel * 1150 0 stevel * Another check that may come here later is the "collision" check. 1151 0 stevel * If legitimate packets flow quickly enough, this won't be a problem, 1152 0 stevel * but collisions may cause authentication algorithm crunching to 1153 0 stevel * take place when it doesn't need to. 1154 0 stevel */ 1155 0 stevel if (!sadb_replay_peek(ipsa, esph->esph_replay)) { 1156 3448 dh155122 ESP_BUMP_STAT(espstack, replay_early_failures); 1157 3448 dh155122 IP_ESP_BUMP_STAT(ipss, in_discards); 1158 11042 Erik ip_drop_packet(data_mp, B_TRUE, ira->ira_ill, 1159 3448 dh155122 DROPPER(ipss, ipds_esp_early_replay), 1160 3448 dh155122 &espstack->esp_dropper); 1161 11042 Erik BUMP_MIB(ira->ira_ill->ill_ip_mib, ipIfStatsInDiscards); 1162 11042 Erik return (NULL); 1163 11042 Erik } 1164 0 stevel 1165 0 stevel /* 1166 0 stevel * Adjust the IP header's payload length to reflect the removal 1167 0 stevel * of the ICV. 1168 0 stevel */ 1169 11042 Erik if (!(ira->ira_flags & IRAF_IS_IPV4)) { 1170 0 stevel ip6_t *ip6h = (ip6_t *)data_mp->b_rptr; 1171 0 stevel ip6h->ip6_plen = htons(ntohs(ip6h->ip6_plen) - 1172 0 stevel ipsa->ipsa_mac_len); 1173 0 stevel } else { 1174 0 stevel ipha_t *ipha = (ipha_t *)data_mp->b_rptr; 1175 0 stevel ipha->ipha_length = htons(ntohs(ipha->ipha_length) - 1176 0 stevel ipsa->ipsa_mac_len); 1177 0 stevel } 1178 0 stevel 1179 0 stevel /* submit the request to the crypto framework */ 1180 11042 Erik return (esp_submit_req_inbound(data_mp, ira, ipsa, 1181 0 stevel (uint8_t *)esph - data_mp->b_rptr)); 1182 0 stevel } 1183 0 stevel 1184 0 stevel /* 1185 0 stevel * Perform the really difficult work of inserting the proposed situation. 1186 0 stevel * Called while holding the algorithm lock. 1187 0 stevel */ 1188 0 stevel static void 1189 11042 Erik esp_insert_prop(sadb_prop_t *prop, ipsacq_t *acqrec, uint_t combs, 1190 11042 Erik netstack_t *ns) 1191 0 stevel { 1192 0 stevel sadb_comb_t *comb = (sadb_comb_t *)(prop + 1); 1193 0 stevel ipsec_action_t *ap; 1194 0 stevel ipsec_prot_t *prot; 1195 11042 Erik ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; 1196 11042 Erik ipsec_stack_t *ipss = ns->netstack_ipsec; 1197 11042 Erik 1198 3448 dh155122 ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock)); 1199 0 stevel 1200 0 stevel prop->sadb_prop_exttype = SADB_EXT_PROPOSAL; 1201 0 stevel prop->sadb_prop_len = SADB_8TO64(sizeof (sadb_prop_t)); 1202 0 stevel *(uint32_t *)(&prop->sadb_prop_replay) = 0; /* Quick zero-out! */ 1203 0 stevel 1204 3448 dh155122 prop->sadb_prop_replay = espstack->ipsecesp_replay_size; 1205 0 stevel 1206 0 stevel /* 1207 11042 Erik * Based upon algorithm properties, and what-not, prioritize a 1208 11042 Erik * proposal, based on the ordering of the ESP algorithms in the 1209 11042 Erik * alternatives in the policy rule or socket that was placed 1210 11042 Erik * in the acquire record. 1211 0 stevel * 1212 0 stevel * For each action in policy list 1213 0 stevel * Add combination. If I've hit limit, return. 1214 0 stevel */ 1215 0 stevel 1216 0 stevel for (ap = acqrec->ipsacq_act; ap != NULL; 1217 0 stevel ap = ap->ipa_next) { 1218 0 stevel ipsec_alginfo_t *ealg = NULL; 1219 0 stevel ipsec_alginfo_t *aalg = NULL; 1220 0 stevel 1221 0 stevel if (ap->ipa_act.ipa_type != IPSEC_POLICY_APPLY) 1222 0 stevel continue; 1223 0 stevel 1224 0 stevel prot = &ap->ipa_act.ipa_apply; 1225 0 stevel 1226 0 stevel if (!(prot->ipp_use_esp)) 1227 0 stevel continue; 1228 0 stevel 1229 0 stevel if (prot->ipp_esp_auth_alg != 0) { 1230 3448 dh155122 aalg = ipss->ipsec_alglists[IPSEC_ALG_AUTH] 1231 0 stevel [prot->ipp_esp_auth_alg]; 1232 0 stevel if (aalg == NULL || !ALG_VALID(aalg)) 1233 0 stevel continue; 1234 0 stevel } 1235 0 stevel 1236 0 stevel ASSERT(prot->ipp_encr_alg > 0); 1237 3448 dh155122 ealg = ipss->ipsec_alglists[IPSEC_ALG_ENCR] 1238 3448 dh155122 [prot->ipp_encr_alg]; 1239 0 stevel if (ealg == NULL || !ALG_VALID(ealg)) 1240 0 stevel continue; 1241 0 stevel 1242 0 stevel comb->sadb_comb_flags = 0; 1243 0 stevel comb->sadb_comb_reserved = 0; 1244 0 stevel comb->sadb_comb_encrypt = ealg->alg_id; 1245 2751 danmcd comb->sadb_comb_encrypt_minbits = 1246 2751 danmcd MAX(prot->ipp_espe_minbits, ealg->alg_ef_minbits); 1247 2751 danmcd comb->sadb_comb_encrypt_maxbits = 1248 2751 danmcd MIN(prot->ipp_espe_maxbits, ealg->alg_ef_maxbits); 1249 10824 Mark 1250 0 stevel if (aalg == NULL) { 1251 0 stevel comb->sadb_comb_auth = 0; 1252 0 stevel comb->sadb_comb_auth_minbits = 0; 1253 0 stevel comb->sadb_comb_auth_maxbits = 0; 1254 0 stevel } else { 1255 0 stevel comb->sadb_comb_auth = aalg->alg_id; 1256 2751 danmcd comb->sadb_comb_auth_minbits = 1257 2751 danmcd MAX(prot->ipp_espa_minbits, aalg->alg_ef_minbits); 1258 2751 danmcd comb->sadb_comb_auth_maxbits = 1259 2751 danmcd MIN(prot->ipp_espa_maxbits, aalg->alg_ef_maxbits); 1260 0 stevel } 1261 0 stevel 1262 0 stevel /* 1263 0 stevel * The following may be based on algorithm 1264 0 stevel * properties, but in the meantime, we just pick 1265 0 stevel * some good, sensible numbers. Key mgmt. can 1266 0 stevel * (and perhaps should) be the place to finalize 1267 0 stevel * such decisions. 1268 0 stevel */ 1269 0 stevel 1270 0 stevel /* 1271 0 stevel * No limits on allocations, since we really don't 1272 0 stevel * support that concept currently. 1273 0 stevel */ 1274 0 stevel comb->sadb_comb_soft_allocations = 0; 1275 0 stevel comb->sadb_comb_hard_allocations = 0; 1276 0 stevel 1277 0 stevel /* 1278 0 stevel * These may want to come from policy rule.. 1279 0 stevel */ 1280 3448 dh155122 comb->sadb_comb_soft_bytes = 1281 3448 dh155122 espstack->ipsecesp_default_soft_bytes; 1282 3448 dh155122 comb->sadb_comb_hard_bytes = 1283 3448 dh155122 espstack->ipsecesp_default_hard_bytes; 1284 3448 dh155122 comb->sadb_comb_soft_addtime = 1285 3448 dh155122 espstack->ipsecesp_default_soft_addtime; 1286 3448 dh155122 comb->sadb_comb_hard_addtime = 1287 3448 dh155122 espstack->ipsecesp_default_hard_addtime; 1288 3448 dh155122 comb->sadb_comb_soft_usetime = 1289 3448 dh155122 espstack->ipsecesp_default_soft_usetime; 1290 3448 dh155122 comb->sadb_comb_hard_usetime = 1291 3448 dh155122 espstack->ipsecesp_default_hard_usetime; 1292 0 stevel 1293 0 stevel prop->sadb_prop_len += SADB_8TO64(sizeof (*comb)); 1294 0 stevel if (--combs == 0) 1295 0 stevel break; /* out of space.. */ 1296 0 stevel comb++; 1297 0 stevel } 1298 0 stevel } 1299 0 stevel 1300 0 stevel /* 1301 0 stevel * Prepare and actually send the SADB_ACQUIRE message to PF_KEY. 1302 0 stevel */ 1303 0 stevel static void 1304 3448 dh155122 esp_send_acquire(ipsacq_t *acqrec, mblk_t *extended, netstack_t *ns) 1305 0 stevel { 1306 3055 danmcd uint_t combs; 1307 0 stevel sadb_msg_t *samsg; 1308 0 stevel sadb_prop_t *prop; 1309 3055 danmcd mblk_t *pfkeymp, *msgmp; 1310 3448 dh155122 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; 1311 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 1312 0 stevel 1313 3448 dh155122 ESP_BUMP_STAT(espstack, acquire_requests); 1314 0 stevel 1315 7073 pwernau if (espstack->esp_pfkey_q == NULL) { 1316 7073 pwernau mutex_exit(&acqrec->ipsacq_lock); 1317 7073 pwernau return; 1318 7073 pwernau } 1319 0 stevel 1320 0 stevel /* Set up ACQUIRE. */ 1321 3448 dh155122 pfkeymp = sadb_setup_acquire(acqrec, SADB_SATYPE_ESP, 1322 3448 dh155122 ns->netstack_ipsec); 1323 3055 danmcd if (pfkeymp == NULL) { 1324 0 stevel esp0dbg(("sadb_setup_acquire failed.\n")); 1325 7073 pwernau mutex_exit(&acqrec->ipsacq_lock); 1326 3055 danmcd return; 1327 0 stevel } 1328 3448 dh155122 ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock)); 1329 3448 dh155122 combs = ipss->ipsec_nalgs[IPSEC_ALG_AUTH] * 1330 3448 dh155122 ipss->ipsec_nalgs[IPSEC_ALG_ENCR]; 1331 3055 danmcd msgmp = pfkeymp->b_cont; 1332 3055 danmcd samsg = (sadb_msg_t *)(msgmp->b_rptr); 1333 0 stevel 1334 0 stevel /* Insert proposal here. */ 1335 0 stevel 1336 0 stevel prop = (sadb_prop_t *)(((uint64_t *)samsg) + samsg->sadb_msg_len); 1337 11042 Erik esp_insert_prop(prop, acqrec, combs, ns); 1338 0 stevel samsg->sadb_msg_len += prop->sadb_prop_len; 1339 0 stevel msgmp->b_wptr += SADB_64TO8(samsg->sadb_msg_len); 1340 0 stevel 1341 3448 dh155122 mutex_exit(&ipss->ipsec_alg_lock); 1342 0 stevel 1343 0 stevel /* 1344 0 stevel * Must mutex_exit() before sending PF_KEY message up, in 1345 0 stevel * order to avoid recursive mutex_enter() if there are no registered 1346 0 stevel * listeners. 1347 0 stevel * 1348 0 stevel * Once I've sent the message, I'm cool anyway. 1349 0 stevel */ 1350 0 stevel mutex_exit(&acqrec->ipsacq_lock); 1351 3055 danmcd if (extended != NULL) { 1352 3448 dh155122 putnext(espstack->esp_pfkey_q, extended); 1353 0 stevel } 1354 3448 dh155122 putnext(espstack->esp_pfkey_q, pfkeymp); 1355 0 stevel } 1356 0 stevel 1357 10934 sommerfeld /* XXX refactor me */ 1358 0 stevel /* 1359 0 stevel * Handle the SADB_GETSPI message. Create a larval SA. 1360 0 stevel */ 1361 0 stevel static void 1362 3448 dh155122 esp_getspi(mblk_t *mp, keysock_in_t *ksi, ipsecesp_stack_t *espstack) 1363 0 stevel { 1364 0 stevel ipsa_t *newbie, *target; 1365 0 stevel isaf_t *outbound, *inbound; 1366 0 stevel int rc, diagnostic; 1367 0 stevel sadb_sa_t *assoc; 1368 0 stevel keysock_out_t *kso; 1369 0 stevel uint32_t newspi; 1370 0 stevel 1371 0 stevel /* 1372 0 stevel * Randomly generate a proposed SPI value 1373 0 stevel */ 1374 7749 Thejaswini if (cl_inet_getspi != NULL) { 1375 8392 Huafeng cl_inet_getspi(espstack->ipsecesp_netstack->netstack_stackid, 1376 8392 Huafeng IPPROTO_ESP, (uint8_t *)&newspi, sizeof (uint32_t), NULL); 1377 7749 Thejaswini } else { 1378 7749 Thejaswini (void) random_get_pseudo_bytes((uint8_t *)&newspi, 1379 7749 Thejaswini sizeof (uint32_t)); 1380 7749 Thejaswini } 1381 3448 dh155122 newbie = sadb_getspi(ksi, newspi, &diagnostic, 1382 7749 Thejaswini espstack->ipsecesp_netstack, IPPROTO_ESP); 1383 0 stevel 1384 0 stevel if (newbie == NULL) { 1385 3448 dh155122 sadb_pfkey_error(espstack->esp_pfkey_q, mp, ENOMEM, diagnostic, 1386 0 stevel ksi->ks_in_serial); 1387 0 stevel return; 1388 0 stevel } else if (newbie == (ipsa_t *)-1) { 1389 3448 dh155122 sadb_pfkey_error(espstack->esp_pfkey_q, mp, EINVAL, diagnostic, 1390 0 stevel ksi->ks_in_serial); 1391 0 stevel return; 1392 0 stevel } 1393 0 stevel 1394 0 stevel /* 1395 0 stevel * XXX - We may randomly collide. We really should recover from this. 1396 0 stevel * Unfortunately, that could require spending way-too-much-time 1397 0 stevel * in here. For now, let the user retry. 1398 0 stevel */ 1399 0 stevel 1400 0 stevel if (newbie->ipsa_addrfam == AF_INET6) { 1401 3448 dh155122 outbound = OUTBOUND_BUCKET_V6(&espstack->esp_sadb.s_v6, 1402 564 sommerfe *(uint32_t *)(newbie->ipsa_dstaddr)); 1403 3448 dh155122 inbound = INBOUND_BUCKET(&espstack->esp_sadb.s_v6, 1404 3448 dh155122 newbie->ipsa_spi); 1405 0 stevel } else { 1406 0 stevel ASSERT(newbie->ipsa_addrfam == AF_INET); 1407 3448 dh155122 outbound = OUTBOUND_BUCKET_V4(&espstack->esp_sadb.s_v4, 1408 564 sommerfe *(uint32_t *)(newbie->ipsa_dstaddr)); 1409 3448 dh155122 inbound = INBOUND_BUCKET(&espstack->esp_sadb.s_v4, 1410 3448 dh155122 newbie->ipsa_spi); 1411 0 stevel } 1412 0 stevel 1413 0 stevel mutex_enter(&outbound->isaf_lock); 1414 0 stevel mutex_enter(&inbound->isaf_lock); 1415 0 stevel 1416 0 stevel /* 1417 0 stevel * Check for collisions (i.e. did sadb_getspi() return with something 1418 0 stevel * that already exists?). 1419 0 stevel * 1420 0 stevel * Try outbound first. Even though SADB_GETSPI is traditionally 1421 0 stevel * for inbound SAs, you never know what a user might do. 1422 0 stevel */ 1423 0 stevel target = ipsec_getassocbyspi(outbound, newbie->ipsa_spi, 1424 0 stevel newbie->ipsa_srcaddr, newbie->ipsa_dstaddr, newbie->ipsa_addrfam); 1425 0 stevel if (target == NULL) { 1426 0 stevel target = ipsec_getassocbyspi(inbound, newbie->ipsa_spi, 1427 0 stevel newbie->ipsa_srcaddr, newbie->ipsa_dstaddr, 1428 0 stevel newbie->ipsa_addrfam); 1429 0 stevel } 1430 0 stevel 1431 0 stevel /* 1432 0 stevel * I don't have collisions elsewhere! 1433 0 stevel * (Nor will I because I'm still holding inbound/outbound locks.) 1434 0 stevel */ 1435 0 stevel 1436 0 stevel if (target != NULL) { 1437 0 stevel rc = EEXIST; 1438 0 stevel IPSA_REFRELE(target); 1439 0 stevel } else { 1440 0 stevel /* 1441 0 stevel * sadb_insertassoc() also checks for collisions, so 1442 0 stevel * if there's a colliding entry, rc will be set 1443 0 stevel * to EEXIST. 1444 0 stevel */ 1445 0 stevel rc = sadb_insertassoc(newbie, inbound); 1446 4987 danmcd newbie->ipsa_hardexpiretime = gethrestime_sec(); 1447 3448 dh155122 newbie->ipsa_hardexpiretime += 1448 3448 dh155122 espstack->ipsecesp_larval_timeout; 1449 0 stevel } 1450 0 stevel 1451 0 stevel /* 1452 0 stevel * Can exit outbound mutex. Hold inbound until we're done 1453 0 stevel * with newbie. 1454 0 stevel */ 1455 0 stevel mutex_exit(&outbound->isaf_lock); 1456 0 stevel 1457 0 stevel if (rc != 0) { 1458 0 stevel mutex_exit(&inbound->isaf_lock); 1459 0 stevel IPSA_REFRELE(newbie); 1460 3448 dh155122 sadb_pfkey_error(espstack->esp_pfkey_q, mp, rc, 1461 3448 dh155122 SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial); 1462 0 stevel return; 1463 0 stevel } 1464 0 stevel 1465 0 stevel 1466 0 stevel /* Can write here because I'm still holding the bucket lock. */ 1467 0 stevel newbie->ipsa_type = SADB_SATYPE_ESP; 1468 0 stevel 1469 0 stevel /* 1470 6668 markfen * Construct successful return message. We have one thing going 1471 0 stevel * for us in PF_KEY v2. That's the fact that 1472 0 stevel * sizeof (sadb_spirange_t) == sizeof (sadb_sa_t) 1473 0 stevel */ 1474 0 stevel assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SPIRANGE]; 1475 0 stevel assoc->sadb_sa_exttype = SADB_EXT_SA; 1476 0 stevel assoc->sadb_sa_spi = newbie->ipsa_spi; 1477 0 stevel *((uint64_t *)(&assoc->sadb_sa_replay)) = 0; 1478 0 stevel mutex_exit(&inbound->isaf_lock); 1479 0 stevel 1480 0 stevel /* Convert KEYSOCK_IN to KEYSOCK_OUT. */ 1481 0 stevel kso = (keysock_out_t *)ksi; 1482 0 stevel kso->ks_out_len = sizeof (*kso); 1483 0 stevel kso->ks_out_serial = ksi->ks_in_serial; 1484 0 stevel kso->ks_out_type = KEYSOCK_OUT; 1485 0 stevel 1486 0 stevel /* 1487 0 stevel * Can safely putnext() to esp_pfkey_q, because this is a turnaround 1488 0 stevel * from the esp_pfkey_q. 1489 0 stevel */ 1490 3448 dh155122 putnext(espstack->esp_pfkey_q, mp); 1491 0 stevel } 1492 0 stevel 1493 0 stevel /* 1494 0 stevel * Insert the ESP header into a packet. Duplicate an mblk, and insert a newly 1495 0 stevel * allocated mblk with the ESP header in between the two. 1496 0 stevel */ 1497 0 stevel static boolean_t 1498 3448 dh155122 esp_insert_esp(mblk_t *mp, mblk_t *esp_mp, uint_t divpoint, 1499 3448 dh155122 ipsecesp_stack_t *espstack) 1500 0 stevel { 1501 0 stevel mblk_t *split_mp = mp; 1502 0 stevel uint_t wheretodiv = divpoint; 1503 0 stevel 1504 0 stevel while ((split_mp->b_wptr - split_mp->b_rptr) < wheretodiv) { 1505 0 stevel wheretodiv -= (split_mp->b_wptr - split_mp->b_rptr); 1506 0 stevel split_mp = split_mp->b_cont; 1507 0 stevel ASSERT(split_mp != NULL); 1508 0 stevel } 1509 0 stevel 1510 0 stevel if (split_mp->b_wptr - split_mp->b_rptr != wheretodiv) { 1511 0 stevel mblk_t *scratch; 1512 0 stevel 1513 0 stevel /* "scratch" is the 2nd half, split_mp is the first. */ 1514 0 stevel scratch = dupb(split_mp); 1515 0 stevel if (scratch == NULL) { 1516 3448 dh155122 esp1dbg(espstack, 1517 3448 dh155122 ("esp_insert_esp: can't allocate scratch.\n")); 1518 0 stevel return (B_FALSE); 1519 0 stevel } 1520 0 stevel /* NOTE: dupb() doesn't set b_cont appropriately. */ 1521 0 stevel scratch->b_cont = split_mp->b_cont; 1522 0 stevel scratch->b_rptr += wheretodiv; 1523 0 stevel split_mp->b_wptr = split_mp->b_rptr + wheretodiv; 1524 0 stevel split_mp->b_cont = scratch; 1525 0 stevel } 1526 0 stevel /* 1527 0 stevel * At this point, split_mp is exactly "wheretodiv" bytes long, and 1528 0 stevel * holds the end of the pre-ESP part of the datagram. 1529 0 stevel */ 1530 0 stevel esp_mp->b_cont = split_mp->b_cont; 1531 0 stevel split_mp->b_cont = esp_mp; 1532 0 stevel 1533 0 stevel return (B_TRUE); 1534 0 stevel } 1535 0 stevel 1536 0 stevel /* 1537 7066 danmcd * Section 7 of RFC 3947 says: 1538 7066 danmcd * 1539 7066 danmcd * 7. Recovering from the Expiring NAT Mappings 1540 7066 danmcd * 1541 7066 danmcd * There are cases where NAT box decides to remove mappings that are still 1542 7066 danmcd * alive (for example, when the keepalive interval is too long, or when the 1543 7066 danmcd * NAT box is rebooted). To recover from this, ends that are NOT behind 1544 7066 danmcd * NAT SHOULD use the last valid UDP encapsulated IKE or IPsec packet from 1545 7066 danmcd * the other end to determine which IP and port addresses should be used. 1546 7066 danmcd * The host behind dynamic NAT MUST NOT do this, as otherwise it opens a 1547 7066 danmcd * DoS attack possibility because the IP address or port of the other host 1548 7066 danmcd * will not change (it is not behind NAT). 1549 7066 danmcd * 1550 7066 danmcd * Keepalives cannot be used for these purposes, as they are not 1551 7066 danmcd * authenticated, but any IKE authenticated IKE packet or ESP packet can be 1552 7066 danmcd * used to detect whether the IP address or the port has changed. 1553 7066 danmcd * 1554 7066 danmcd * The following function will check an SA and its explicitly-set pair to see 1555 7066 danmcd * if the NAT-T remote port matches the received packet (which must have 1556 7066 danmcd * passed ESP authentication, see esp_in_done() for the caller context). If 1557 7066 danmcd * there is a mismatch, the SAs are updated. It is not important if we race 1558 7066 danmcd * with a transmitting thread, as if there is a transmitting thread, it will 1559 7066 danmcd * merely emit a packet that will most-likely be dropped. 1560 7066 danmcd * 1561 7066 danmcd * "ports" are ordered src,dst, and assoc is an inbound SA, where src should 1562 7066 danmcd * match ipsa_remote_nat_port and dst should match ipsa_local_nat_port. 1563 7066 danmcd */ 1564 7066 danmcd #ifdef _LITTLE_ENDIAN 1565 7066 danmcd #define FIRST_16(x) ((x) & 0xFFFF) 1566 7066 danmcd #define NEXT_16(x) (((x) >> 16) & 0xFFFF) 1567 7066 danmcd #else 1568 7066 danmcd #define FIRST_16(x) (((x) >> 16) & 0xFFFF) 1569 7066 danmcd #define NEXT_16(x) ((x) & 0xFFFF) 1570 7066 danmcd #endif 1571 7066 danmcd static void 1572 7066 danmcd esp_port_freshness(uint32_t ports, ipsa_t *assoc) 1573 7066 danmcd { 1574 7066 danmcd uint16_t remote = FIRST_16(ports); 1575 7066 danmcd uint16_t local = NEXT_16(ports); 1576 7066 danmcd ipsa_t *outbound_peer; 1577 7066 danmcd isaf_t *bucket; 1578 7066 danmcd ipsecesp_stack_t *espstack = assoc->ipsa_netstack->netstack_ipsecesp; 1579 7066 danmcd 1580 7066 danmcd /* We found a conn_t, therefore local != 0. */ 1581 7066 danmcd ASSERT(local != 0); 1582 7066 danmcd /* Assume an IPv4 SA. */ 1583 7066 danmcd ASSERT(assoc->ipsa_addrfam == AF_INET); 1584 7066 danmcd 1585 7066 danmcd /* 1586 7066 danmcd * On-the-wire rport == 0 means something's very wrong. 1587 7066 danmcd * An unpaired SA is also useless to us. 1588 7066 danmcd * If we are behind the NAT, don't bother. 1589 7066 danmcd * A zero local NAT port defaults to 4500, so check that too. 1590 7066 danmcd * And, of course, if the ports already match, we don't need to 1591 7066 danmcd * bother. 1592 7066 danmcd */ 1593 7066 danmcd if (remote == 0 || assoc->ipsa_otherspi == 0 || 1594 7066 danmcd (assoc->ipsa_flags & IPSA_F_BEHIND_NAT) || 1595 7066 danmcd (assoc->ipsa_remote_nat_port == 0 && 1596 7066 danmcd remote == htons(IPPORT_IKE_NATT)) || 1597 7066 danmcd remote == assoc->ipsa_remote_nat_port) 1598 7066 danmcd return; 1599 7066 danmcd 1600 7066 danmcd /* Try and snag the peer. NOTE: Assume IPv4 for now. */ 1601 7066 danmcd bucket = OUTBOUND_BUCKET_V4(&(espstack->esp_sadb.s_v4), 1602 7066 danmcd assoc->ipsa_srcaddr[0]); 1603 7066 danmcd mutex_enter(&bucket->isaf_lock); 1604 7066 danmcd outbound_peer = ipsec_getassocbyspi(bucket, assoc->ipsa_otherspi, 1605 7066 danmcd assoc->ipsa_dstaddr, assoc->ipsa_srcaddr, AF_INET); 1606 7066 danmcd mutex_exit(&bucket->isaf_lock); 1607 7066 danmcd 1608 7066 danmcd /* We probably lost a race to a deleting or expiring thread. */ 1609 7066 danmcd if (outbound_peer == NULL) 1610 7066 danmcd return; 1611 7066 danmcd 1612 7066 danmcd /* 1613 7066 danmcd * Hold the mutexes for both SAs so we don't race another inbound 1614 7066 danmcd * thread. A lock-entry order shouldn't matter, since all other 1615 7066 danmcd * per-ipsa locks are individually held-then-released. 1616 7066 danmcd * 1617 7066 danmcd * Luckily, this has nothing to do with the remote-NAT address, 1618 7066 danmcd * so we don't have to re-scribble the cached-checksum differential. 1619 7066 danmcd */ 1620 7066 danmcd mutex_enter(&outbound_peer->ipsa_lock); 1621 7066 danmcd mutex_enter(&assoc->ipsa_lock); 1622 7066 danmcd outbound_peer->ipsa_remote_nat_port = assoc->ipsa_remote_nat_port = 1623 7066 danmcd remote; 1624 7066 danmcd mutex_exit(&assoc->ipsa_lock); 1625 7066 danmcd mutex_exit(&outbound_peer->ipsa_lock); 1626 7066 danmcd IPSA_REFRELE(outbound_peer); 1627 7066 danmcd ESP_BUMP_STAT(espstack, sa_port_renumbers); 1628 7066 danmcd } 1629 7066 danmcd /* 1630 0 stevel * Finish processing of an inbound ESP packet after processing by the 1631 0 stevel * crypto framework. 1632 0 stevel * - Remove the ESP header. 1633 0 stevel * - Send packet back to IP. 1634 0 stevel * If authentication was performed on the packet, this function is called 1635 0 stevel * only if the authentication succeeded. 1636 0 stevel * On success returns B_TRUE, on failure returns B_FALSE and frees the 1637 11042 Erik * mblk chain data_mp. 1638 11042 Erik */ 1639 11042 Erik static mblk_t * 1640 11042 Erik esp_in_done(mblk_t *data_mp, ip_recv_attr_t *ira, ipsec_crypto_t *ic) 1641 11042 Erik { 1642 0 stevel ipsa_t *assoc; 1643 0 stevel uint_t espstart; 1644 0 stevel uint32_t ivlen = 0; 1645 0 stevel uint_t processed_len; 1646 0 stevel esph_t *esph; 1647 0 stevel kstat_named_t *counter; 1648 0 stevel boolean_t is_natt; 1649 11042 Erik netstack_t *ns = ira->ira_ill->ill_ipst->ips_netstack; 1650 11042 Erik ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; 1651 11042 Erik ipsec_stack_t *ipss = ns->netstack_ipsec; 1652 11042 Erik 1653 11042 Erik assoc = ira->ira_ipsec_esp_sa; 1654 0 stevel ASSERT(assoc != NULL); 1655 0 stevel 1656 0 stevel is_natt = ((assoc->ipsa_flags & IPSA_F_NATT) != 0); 1657 0 stevel 1658 0 stevel /* get the pointer to the ESP header */ 1659 0 stevel if (assoc->ipsa_encr_alg == SADB_EALG_NULL) { 1660 0 stevel /* authentication-only ESP */ 1661 11042 Erik espstart = ic->ic_crypto_data.cd_offset; 1662 11042 Erik processed_len = ic->ic_crypto_data.cd_length; 1663 0 stevel } else { 1664 0 stevel /* encryption present */ 1665 0 stevel ivlen = assoc->ipsa_iv_len; 1666 0 stevel if (assoc->ipsa_auth_alg == SADB_AALG_NONE) { 1667 0 stevel /* encryption-only ESP */ 1668 11042 Erik espstart = ic->ic_crypto_data.cd_offset - 1669 4987 danmcd sizeof (esph_t) - assoc->ipsa_iv_len; 1670 11042 Erik processed_len = ic->ic_crypto_data.cd_length + 1671 4987 danmcd ivlen; 1672 0 stevel } else { 1673 0 stevel /* encryption with authentication */ 1674 11042 Erik espstart = ic->ic_crypto_dual_data.dd_offset1; 1675 11042 Erik processed_len = ic->ic_crypto_dual_data.dd_len2 + 1676 0 stevel ivlen; 1677 0 stevel } 1678 0 stevel } 1679 0 stevel 1680 0 stevel esph = (esph_t *)(data_mp->b_rptr + espstart); 1681 0 stevel 1682 10824 Mark if (assoc->ipsa_auth_alg != IPSA_AALG_NONE || 1683 10824 Mark (assoc->ipsa_flags & IPSA_F_COMBINED)) { 1684 10824 Mark /* 1685 10824 Mark * Authentication passed if we reach this point. 1686 10824 Mark * Packets with authentication will have the ICV 1687 10824 Mark * after the crypto data. Adjust b_wptr before 1688 10824 Mark * making padlen checks. 1689 10824 Mark */ 1690 3448 dh155122 ESP_BUMP_STAT(espstack, good_auth); 1691 0 stevel data_mp->b_wptr -= assoc->ipsa_mac_len; 1692 0 stevel 1693 0 stevel /* 1694 0 stevel * Check replay window here! 1695 0 stevel * For right now, assume keysock will set the replay window 1696 0 stevel * size to zero for SAs that have an unspecified sender. 1697 0 stevel * This may change... 1698 0 stevel */ 1699 0 stevel 1700 0 stevel if (!sadb_replay_check(assoc, esph->esph_replay)) { 1701 0 stevel /* 1702 0 stevel * Log the event. As of now we print out an event. 1703 0 stevel * Do not print the replay failure number, or else 1704 0 stevel * syslog cannot collate the error messages. Printing 1705 0 stevel * the replay number that failed opens a denial-of- 1706 0 stevel * service attack. 1707 0 stevel */ 1708 0 stevel ipsec_assocfailure(info.mi_idnum, 0, 0, 1709 0 stevel SL_ERROR | SL_WARN, 1710 0 stevel "Replay failed for ESP spi 0x%x, dst %s.\n", 1711 0 stevel assoc->ipsa_spi, assoc->ipsa_dstaddr, 1712 3448 dh155122 assoc->ipsa_addrfam, espstack->ipsecesp_netstack); 1713 3448 dh155122 ESP_BUMP_STAT(espstack, replay_failures); 1714 3448 dh155122 counter = DROPPER(ipss, ipds_esp_replay); 1715 0 stevel goto drop_and_bail; 1716 0 stevel } 1717 7066 danmcd 1718 11042 Erik if (is_natt) { 1719 11042 Erik ASSERT(ira->ira_flags & IRAF_ESP_UDP_PORTS); 1720 11042 Erik ASSERT(ira->ira_esp_udp_ports != 0); 1721 11042 Erik esp_port_freshness(ira->ira_esp_udp_ports, assoc); 1722 11042 Erik } 1723 0 stevel } 1724 4987 danmcd 1725 4987 danmcd esp_set_usetime(assoc, B_TRUE); 1726 0 stevel 1727 0 stevel if (!esp_age_bytes(assoc, processed_len, B_TRUE)) { 1728 0 stevel /* The ipsa has hit hard expiration, LOG and AUDIT. */ 1729 0 stevel ipsec_assocfailure(info.mi_idnum, 0, 0, 1730 0 stevel SL_ERROR | SL_WARN, 1731 0 stevel "ESP association 0x%x, dst %s had bytes expire.\n", 1732 3448 dh155122 assoc->ipsa_spi, assoc->ipsa_dstaddr, assoc->ipsa_addrfam, 1733 3448 dh155122 espstack->ipsecesp_netstack); 1734 3448 dh155122 ESP_BUMP_STAT(espstack, bytes_expired); 1735 3448 dh155122 counter = DROPPER(ipss, ipds_esp_bytes_expire); 1736 0 stevel goto drop_and_bail; 1737 0 stevel } 1738 0 stevel 1739 0 stevel /* 1740 0 stevel * Remove ESP header and padding from packet. I hope the compiler 1741 0 stevel * spews "branch, predict taken" code for this. 1742 0 stevel */ 1743 0 stevel 1744 11042 Erik if (esp_strip_header(data_mp, (ira->ira_flags & IRAF_IS_IPV4), 1745 11042 Erik ivlen, &counter, espstack)) { 1746 11042 Erik 1747 11042 Erik if (is_system_labeled() && assoc->ipsa_tsl != NULL) { 1748 11042 Erik if (!ip_recv_attr_replace_label(ira, assoc->ipsa_tsl)) { 1749 11042 Erik ip_drop_packet(data_mp, B_TRUE, ira->ira_ill, 1750 11042 Erik DROPPER(ipss, ipds_ah_nomem), 1751 11042 Erik &espstack->esp_dropper); 1752 11042 Erik BUMP_MIB(ira->ira_ill->ill_ip_mib, 1753 11042 Erik ipIfStatsInDiscards); 1754 11042 Erik return (NULL); 1755 11042 Erik } 1756 10934 sommerfeld } 1757 0 stevel if (is_natt) 1758 0 stevel return (esp_fix_natt_checksums(data_mp, assoc)); 1759 10934 sommerfeld 1760 7885 danmcd if (assoc->ipsa_state == IPSA_STATE_IDLE) { 1761 7885 danmcd /* 1762 7885 danmcd * Cluster buffering case. Tell caller that we're 1763 7885 danmcd * handling the packet. 1764 7885 danmcd */ 1765 11042 Erik sadb_buf_pkt(assoc, data_mp, ira); 1766 11042 Erik return (NULL); 1767 11042 Erik } 1768 11042 Erik 1769 11042 Erik return (data_mp); 1770 0 stevel } 1771 0 stevel 1772 3448 dh155122 esp1dbg(espstack, ("esp_in_done: esp_strip_header() failed\n")); 1773 0 stevel drop_and_bail: 1774 3448 dh155122 IP_ESP_BUMP_STAT(ipss, in_discards); 1775 11042 Erik ip_drop_packet(data_mp, B_TRUE, ira->ira_ill, counter, 1776 11042 Erik &espstack->esp_dropper); 1777 11042 Erik BUMP_MIB(ira->ira_ill->ill_ip_mib, ipIfStatsInDiscards); 1778 11042 Erik return (NULL); 1779 0 stevel } 1780 0 stevel 1781 0 stevel /* 1782 0 stevel * Called upon failing the inbound ICV check. The message passed as 1783 0 stevel * argument is freed. 1784 0 stevel */ 1785 0 stevel static void 1786 11042 Erik esp_log_bad_auth(mblk_t *mp, ip_recv_attr_t *ira) 1787 11042 Erik { 1788 11042 Erik ipsa_t *assoc = ira->ira_ipsec_esp_sa; 1789 11042 Erik netstack_t *ns = ira->ira_ill->ill_ipst->ips_netstack; 1790 3448 dh155122 ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; 1791 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 1792 0 stevel 1793 0 stevel /* 1794 0 stevel * Log the event. Don't print to the console, block 1795 0 stevel * potential denial-of-service attack. 1796 0 stevel */ 1797 3448 dh155122 ESP_BUMP_STAT(espstack, bad_auth); 1798 0 stevel 1799 0 stevel ipsec_assocfailure(info.mi_idnum, 0, 0, SL_ERROR | SL_WARN, 1800 0 stevel "ESP Authentication failed for spi 0x%x, dst %s.\n", 1801 3448 dh155122 assoc->ipsa_spi, assoc->ipsa_dstaddr, assoc->ipsa_addrfam, 1802 3448 dh155122 espstack->ipsecesp_netstack); 1803 0 stevel 1804 3448 dh155122 IP_ESP_BUMP_STAT(ipss, in_discards); 1805 11042 Erik ip_drop_packet(mp, B_TRUE, ira->ira_ill, 1806 3448 dh155122 DROPPER(ipss, ipds_esp_bad_auth), 1807 3448 dh155122 &espstack->esp_dropper); 1808 0 stevel } 1809 0 stevel 1810 0 stevel 1811 0 stevel /* 1812 0 stevel * Invoked for outbound packets after ESP processing. If the packet 1813 0 stevel * also requires AH, performs the AH SA selection and AH processing. 1814 0 stevel * Returns B_TRUE if the AH processing was not needed or if it was 1815 0 stevel * performed successfully. Returns B_FALSE and consumes the passed mblk 1816 0 stevel * if AH processing was required but could not be performed. 1817 11042 Erik * 1818 11042 Erik * Returns data_mp unless data_mp was consumed/queued. 1819 11042 Erik */ 1820 11042 Erik static mblk_t * 1821 11042 Erik esp_do_outbound_ah(mblk_t *data_mp, ip_xmit_attr_t *ixa) 1822 11042 Erik { 1823 0 stevel ipsec_action_t *ap; 1824 0 stevel 1825 11042 Erik ap = ixa->ixa_ipsec_action; 1826 0 stevel if (ap == NULL) { 1827 11042 Erik ipsec_policy_t *pp = ixa->ixa_ipsec_policy; 1828 0 stevel ap = pp->ipsp_act; 1829 0 stevel } 1830 0 stevel 1831 0 stevel if (!ap->ipa_want_ah) 1832 11042 Erik return (data_mp); 1833 11042 Erik 1834 11042 Erik /* 1835 11042 Erik * Normally the AH SA would have already been put in place 1836 11042 Erik * but it could have been flushed so we need to look for it. 1837 11042 Erik */ 1838 11042 Erik if (ixa->ixa_ipsec_ah_sa == NULL) { 1839 11042 Erik if (!ipsec_outbound_sa(data_mp, ixa, IPPROTO_AH)) { 1840 11042 Erik sadb_acquire(data_mp, ixa, B_TRUE, B_FALSE); 1841 11042 Erik return (NULL); 1842 11042 Erik } 1843 11042 Erik } 1844 11042 Erik ASSERT(ixa->ixa_ipsec_ah_sa != NULL); 1845 11042 Erik 1846 11042 Erik data_mp = ixa->ixa_ipsec_ah_sa->ipsa_output_func(data_mp, ixa); 1847 11042 Erik return (data_mp); 1848 0 stevel } 1849 0 stevel 1850 0 stevel 1851 0 stevel /* 1852 0 stevel * Kernel crypto framework callback invoked after completion of async 1853 11042 Erik * crypto requests for outbound packets. 1854 11042 Erik */ 1855 11042 Erik static void 1856 11042 Erik esp_kcf_callback_outbound(void *arg, int status) 1857 11042 Erik { 1858 11042 Erik mblk_t *mp = (mblk_t *)arg; 1859 11042 Erik mblk_t *async_mp; 1860 11042 Erik netstack_t *ns; 1861 11042 Erik ipsec_stack_t *ipss; 1862 11042 Erik ipsecesp_stack_t *espstack; 1863 11042 Erik mblk_t *data_mp; 1864 11042 Erik ip_xmit_attr_t ixas; 1865 11042 Erik ipsec_crypto_t *ic; 1866 11042 Erik ill_t *ill; 1867 11042 Erik 1868 11042 Erik /* 1869 11042 Erik * First remove the ipsec_crypto_t mblk 1870 11042 Erik * Note that we need to ipsec_free_crypto_data(mp) once done with ic. 1871 11042 Erik */ 1872 11042 Erik async_mp = ipsec_remove_crypto_data(mp, &ic); 1873 11042 Erik ASSERT(async_mp != NULL); 1874 11042 Erik 1875 11042 Erik /* 1876 11042 Erik * Extract the ip_xmit_attr_t from the first mblk. 1877 11042 Erik * Verifies that the netstack and ill is still around; could 1878 11042 Erik * have vanished while kEf was doing its work. 1879 11042 Erik * On succesful return we have a nce_t and the ill/ipst can't 1880 11042 Erik * disappear until we do the nce_refrele in ixa_cleanup. 1881 11042 Erik */ 1882 11042 Erik data_mp = async_mp->b_cont; 1883 11042 Erik async_mp->b_cont = NULL; 1884 11042 Erik if (!ip_xmit_attr_from_mblk(async_mp, &ixas)) { 1885 11042 Erik /* Disappeared on us - no ill/ipst for MIB */ 1886 11042 Erik /* We have nowhere to do stats since ixa_ipst could be NULL */ 1887 11042 Erik if (ixas.ixa_nce != NULL) { 1888 11042 Erik ill = ixas.ixa_nce->nce_ill; 1889 11042 Erik BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards); 1890 11042 Erik ip_drop_output("ipIfStatsOutDiscards", data_mp, ill); 1891 11042 Erik } 1892 11042 Erik freemsg(data_mp); 1893 11042 Erik goto done; 1894 11042 Erik } 1895 11042 Erik ns = ixas.ixa_ipst->ips_netstack; 1896 11042 Erik espstack = ns->netstack_ipsecesp; 1897 11042 Erik ipss = ns->netstack_ipsec; 1898 11042 Erik ill = ixas.ixa_nce->nce_ill; 1899 11042 Erik 1900 11042 Erik if (status == CRYPTO_SUCCESS) { 1901 11042 Erik /* 1902 11042 Erik * If a ICV was computed, it was stored by the 1903 11042 Erik * crypto framework at the end of the packet. 1904 11042 Erik */ 1905 11042 Erik ipha_t *ipha = (ipha_t *)data_mp->b_rptr; 1906 11042 Erik 1907 11042 Erik esp_set_usetime(ixas.ixa_ipsec_esp_sa, B_FALSE); 1908 11042 Erik /* NAT-T packet. */ 1909 11042 Erik if (IPH_HDR_VERSION(ipha) == IP_VERSION && 1910 11042 Erik ipha->ipha_protocol == IPPROTO_UDP) 1911 11042 Erik esp_prepare_udp(ns, data_mp, ipha); 1912 11042 Erik 1913 11042 Erik /* do AH processing if needed */ 1914 11042 Erik data_mp = esp_do_outbound_ah(data_mp, &ixas); 1915 11042 Erik if (data_mp == NULL) 1916 11042 Erik goto done; 1917 11042 Erik 1918 11042 Erik (void) ip_output_post_ipsec(data_mp, &ixas); 1919 11042 Erik } else { 1920 11042 Erik /* Outbound shouldn't see invalid MAC */ 1921 11042 Erik ASSERT(status != CRYPTO_INVALID_MAC); 1922 11042 Erik 1923 11042 Erik esp1dbg(espstack, 1924 11042 Erik ("esp_kcf_callback_outbound: crypto failed with 0x%x\n", 1925 11042 Erik status)); 1926 11042 Erik ESP_BUMP_STAT(espstack, crypto_failures); 1927 11042 Erik ESP_BUMP_STAT(espstack, out_discards); 1928 11042 Erik ip_drop_packet(data_mp, B_FALSE, ill, 1929 11042 Erik DROPPER(ipss, ipds_esp_crypto_failed), 1930 11042 Erik &espstack->esp_dropper); 1931 11042 Erik BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards); 1932 11042 Erik } 1933 11042 Erik done: 1934 11042 Erik ixa_cleanup(&ixas); 1935 11042 Erik (void) ipsec_free_crypto_data(mp); 1936 11042 Erik } 1937 11042 Erik 1938 11042 Erik /* 1939 11042 Erik * Kernel crypto framework callback invoked after completion of async 1940 11042 Erik * crypto requests for inbound packets. 1941 11042 Erik */ 1942 11042 Erik static void 1943 11042 Erik esp_kcf_callback_inbound(void *arg, int status) 1944 11042 Erik { 1945 11042 Erik mblk_t *mp = (mblk_t *)arg; 1946 11042 Erik mblk_t *async_mp; 1947 11042 Erik netstack_t *ns; 1948 3448 dh155122 ipsecesp_stack_t *espstack; 1949 3448 dh155122 ipsec_stack_t *ipss; 1950 11042 Erik mblk_t *data_mp; 1951 11042 Erik ip_recv_attr_t iras; 1952 11042 Erik ipsec_crypto_t *ic; 1953 11042 Erik 1954 11042 Erik /* 1955 11042 Erik * First remove the ipsec_crypto_t mblk 1956 11042 Erik * Note that we need to ipsec_free_crypto_data(mp) once done with ic. 1957 11042 Erik */ 1958 11042 Erik async_mp = ipsec_remove_crypto_data(mp, &ic); 1959 11042 Erik ASSERT(async_mp != NULL); 1960 11042 Erik 1961 11042 Erik /* 1962 11042 Erik * Extract the ip_recv_attr_t from the first mblk. 1963 11042 Erik * Verifies that the netstack and ill is still around; could 1964 11042 Erik * have vanished while kEf was doing its work. 1965 11042 Erik */ 1966 11042 Erik data_mp = async_mp->b_cont; 1967 11042 Erik async_mp->b_cont = NULL; 1968 11042 Erik if (!ip_recv_attr_from_mblk(async_mp, &iras)) { 1969 11042 Erik /* The ill or ip_stack_t disappeared on us */ 1970 11042 Erik ip_drop_input("ip_recv_attr_from_mblk", data_mp, NULL); 1971 11042 Erik freemsg(data_mp); 1972 11042 Erik goto done; 1973 11042 Erik } 1974 11042 Erik 1975 11042 Erik ns = iras.ira_ill->ill_ipst->ips_netstack; 1976 3448 dh155122 espstack = ns->netstack_ipsecesp; 1977 3448 dh155122 ipss = ns->netstack_ipsec; 1978 3448 dh155122 1979 0 stevel if (status == CRYPTO_SUCCESS) { 1980 11042 Erik data_mp = esp_in_done(data_mp, &iras, ic); 1981 11042 Erik if (data_mp == NULL) 1982 11042 Erik goto done; 1983 11042 Erik 1984 11042 Erik /* finish IPsec processing */ 1985 11042 Erik ip_input_post_ipsec(data_mp, &iras); 1986 0 stevel } else if (status == CRYPTO_INVALID_MAC) { 1987 11042 Erik esp_log_bad_auth(data_mp, &iras); 1988 0 stevel } else { 1989 3448 dh155122 esp1dbg(espstack, 1990 3448 dh155122 ("esp_kcf_callback: crypto failed with 0x%x\n", 1991 0 stevel status)); 1992 3448 dh155122 ESP_BUMP_STAT(espstack, crypto_failures); 1993 11042 Erik IP_ESP_BUMP_STAT(ipss, in_discards); 1994 11042 Erik ip_drop_packet(data_mp, B_TRUE, iras.ira_ill, 1995 3448 dh155122 DROPPER(ipss, ipds_esp_crypto_failed), 1996 3448 dh155122 &espstack->esp_dropper); 1997 11042 Erik BUMP_MIB(iras.ira_ill->ill_ip_mib, ipIfStatsInDiscards); 1998 11042 Erik } 1999 11042 Erik done: 2000 11042 Erik ira_cleanup(&iras, B_TRUE); 2001 11042 Erik (void) ipsec_free_crypto_data(mp); 2002 0 stevel } 2003 0 stevel 2004 0 stevel /* 2005 0 stevel * Invoked on crypto framework failure during inbound and outbound processing. 2006 0 stevel */ 2007 0 stevel static void 2008 11042 Erik esp_crypto_failed(mblk_t *data_mp, boolean_t is_inbound, int kef_rc, 2009 11042 Erik ill_t *ill, ipsecesp_stack_t *espstack) 2010 0 stevel { 2011 3448 dh155122 ipsec_stack_t *ipss = espstack->ipsecesp_netstack->netstack_ipsec; 2012 3448 dh155122 2013 3448 dh155122 esp1dbg(espstack, ("crypto failed for %s ESP with 0x%x\n", 2014 0 stevel is_inbound ? "inbound" : "outbound", kef_rc)); 2015 11042 Erik ip_drop_packet(data_mp, is_inbound, ill, 2016 3448 dh155122 DROPPER(ipss, ipds_esp_crypto_failed), 2017 3448 dh155122 &espstack->esp_dropper); 2018 3448 dh155122 ESP_BUMP_STAT(espstack, crypto_failures); 2019 0 stevel if (is_inbound) 2020 3448 dh155122 IP_ESP_BUMP_STAT(ipss, in_discards); 2021 0 stevel else 2022 3448 dh155122 ESP_BUMP_STAT(espstack, out_discards); 2023 0 stevel } 2024 0 stevel 2025 11042 Erik /* 2026 11042 Erik * A statement-equivalent macro, _cr MUST point to a modifiable 2027 11042 Erik * crypto_call_req_t. 2028 11042 Erik */ 2029 11042 Erik #define ESP_INIT_CALLREQ(_cr, _mp, _callback) \ 2030 11042 Erik (_cr)->cr_flag = CRYPTO_SKIP_REQID|CRYPTO_ALWAYS_QUEUE; \ 2031 11042 Erik (_cr)->cr_callback_arg = (_mp); \ 2032 11042 Erik (_cr)->cr_callback_func = (_callback) 2033 0 stevel 2034 0 stevel #define ESP_INIT_CRYPTO_MAC(mac, icvlen, icvbuf) { \ 2035 0 stevel (mac)->cd_format = CRYPTO_DATA_RAW; \ 2036 0 stevel (mac)->cd_offset = 0; \ 2037 0 stevel (mac)->cd_length = icvlen; \ 2038 0 stevel (mac)->cd_raw.iov_base = (char *)icvbuf; \ 2039 0 stevel (mac)->cd_raw.iov_len = icvlen; \ 2040 0 stevel } 2041 0 stevel 2042 0 stevel #define ESP_INIT_CRYPTO_DATA(data, mp, off, len) { \ 2043 0 stevel if (MBLKL(mp) >= (len) + (off)) { \ 2044 0 stevel (data)->cd_format = CRYPTO_DATA_RAW; \ 2045 0 stevel (data)->cd_raw.iov_base = (char *)(mp)->b_rptr; \ 2046 0 stevel (data)->cd_raw.iov_len = MBLKL(mp); \ 2047 0 stevel (data)->cd_offset = off; \ 2048 0 stevel } else { \ 2049 0 stevel (data)->cd_format = CRYPTO_DATA_MBLK; \ 2050 0 stevel (data)->cd_mp = mp; \ 2051 0 stevel (data)->cd_offset = off; \ 2052 0 stevel } \ 2053 0 stevel (data)->cd_length = len; \ 2054 0 stevel } 2055 0 stevel 2056 0 stevel #define ESP_INIT_CRYPTO_DUAL_DATA(data, mp, off1, len1, off2, len2) { \ 2057 0 stevel (data)->dd_format = CRYPTO_DATA_MBLK; \ 2058 0 stevel (data)->dd_mp = mp; \ 2059 0 stevel (data)->dd_len1 = len1; \ 2060 0 stevel (data)->dd_offset1 = off1; \ 2061 0 stevel (data)->dd_len2 = len2; \ 2062 0 stevel (data)->dd_offset2 = off2; \ 2063 0 stevel } 2064 0 stevel 2065 11042 Erik /* 2066 11042 Erik * Returns data_mp if successfully completed the request. Returns 2067 11042 Erik * NULL if it failed (and increments InDiscards) or if it is pending. 2068 11042 Erik */ 2069 11042 Erik static mblk_t * 2070 11042 Erik esp_submit_req_inbound(mblk_t *esp_mp, ip_recv_attr_t *ira, 2071 11042 Erik ipsa_t *assoc, uint_t esph_offset) 2072 11042 Erik { 2073 0 stevel uint_t auth_offset, msg_len, auth_len; 2074 11042 Erik crypto_call_req_t call_req, *callrp; 2075 11042 Erik mblk_t *mp; 2076 10824 Mark esph_t *esph_ptr; 2077 11042 Erik int kef_rc; 2078 0 stevel uint_t icv_len = assoc->ipsa_mac_len; 2079 0 stevel crypto_ctx_template_t auth_ctx_tmpl; 2080 11042 Erik boolean_t do_auth, do_encr, force; 2081 0 stevel uint_t encr_offset, encr_len; 2082 0 stevel uint_t iv_len = assoc->ipsa_iv_len; 2083 0 stevel crypto_ctx_template_t encr_ctx_tmpl; 2084 11042 Erik ipsec_crypto_t *ic, icstack; 2085 10824 Mark uchar_t *iv_ptr; 2086 11042 Erik netstack_t *ns = ira->ira_ill->ill_ipst->ips_netstack; 2087 11042 Erik ipsec_stack_t *ipss = ns->netstack_ipsec; 2088 11042 Erik ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; 2089 0 stevel 2090 0 stevel do_auth = assoc->ipsa_auth_alg != SADB_AALG_NONE; 2091 0 stevel do_encr = assoc->ipsa_encr_alg != SADB_EALG_NULL; 2092 11042 Erik force = (assoc->ipsa_flags & IPSA_F_ASYNC); 2093 11042 Erik 2094 11042 Erik #ifdef IPSEC_LATENCY_TEST 2095 11042 Erik kef_rc = CRYPTO_SUCCESS; 2096 11042 Erik #else 2097 11042 Erik kef_rc = CRYPTO_FAILED; 2098 11042 Erik #endif 2099 0 stevel 2100 0 stevel /* 2101 0 stevel * An inbound packet is of the form: 2102 11042 Erik * [IP,options,ESP,IV,data,ICV,pad] 2103 11042 Erik */ 2104 10824 Mark esph_ptr = (esph_t *)(esp_mp->b_rptr + esph_offset); 2105 10824 Mark iv_ptr = (uchar_t *)(esph_ptr + 1); 2106 10824 Mark /* Packet length starting at IP header ending after ESP ICV. */ 2107 0 stevel msg_len = MBLKL(esp_mp); 2108 0 stevel 2109 10824 Mark encr_offset = esph_offset + sizeof (esph_t) + iv_len; 2110 10824 Mark encr_len = msg_len - encr_offset; 2111 10824 Mark 2112 10824 Mark /* 2113 10824 Mark * Counter mode algs need a nonce. This is setup in sadb_common_add(). 2114 10824 Mark * If for some reason we are using a SA which does not have a nonce 2115 10824 Mark * then we must fail here. 2116 10824 Mark */ 2117 10824 Mark if ((assoc->ipsa_flags & IPSA_F_COUNTERMODE) && 2118 10824 Mark (assoc->ipsa_nonce == NULL)) { 2119 11042 Erik ip_drop_packet(esp_mp, B_TRUE, ira->ira_ill, 2120 10824 Mark DROPPER(ipss, ipds_esp_nomem), &espstack->esp_dropper); 2121 11042 Erik return (NULL); 2122 11042 Erik } 2123 11042 Erik 2124 11042 Erik if (force) { 2125 11042 Erik /* We are doing asynch; allocate mblks to hold state */ 2126 11042 Erik if ((mp = ip_recv_attr_to_mblk(ira)) == NULL || 2127 11042 Erik (mp = ipsec_add_crypto_data(mp, &ic)) == NULL) { 2128 11042 Erik BUMP_MIB(ira->ira_ill->ill_ip_mib, ipIfStatsInDiscards); 2129 11042 Erik ip_drop_input("ipIfStatsInDiscards", esp_mp, 2130 11042 Erik ira->ira_ill); 2131 11042 Erik return (NULL); 2132 11042 Erik } 2133 11042 Erik linkb(mp, esp_mp); 2134 11042 Erik callrp = &call_req; 2135 11042 Erik ESP_INIT_CALLREQ(callrp, mp, esp_kcf_callback_inbound); 2136 11042 Erik } else { 2137 11042 Erik /* 2138 11042 Erik * If we know we are going to do sync then ipsec_crypto_t 2139 11042 Erik * should be on the stack. 2140 11042 Erik */ 2141 11042 Erik ic = &icstack; 2142 11042 Erik bzero(ic, sizeof (*ic)); 2143 11042 Erik callrp = NULL; 2144 10824 Mark } 2145 0 stevel 2146 0 stevel if (do_auth) { 2147 0 stevel /* authentication context template */ 2148 0 stevel IPSEC_CTX_TMPL(assoc, ipsa_authtmpl, IPSEC_ALG_AUTH, 2149 0 stevel auth_ctx_tmpl); 2150 0 stevel 2151 0 stevel /* ICV to be verified */ 2152 11042 Erik ESP_INIT_CRYPTO_MAC(&ic->ic_crypto_mac, 2153 0 stevel icv_len, esp_mp->b_wptr - icv_len); 2154 0 stevel 2155 0 stevel /* authentication starts at the ESP header */ 2156 0 stevel auth_offset = esph_offset; 2157 0 stevel auth_len = msg_len - auth_offset - icv_len; 2158 0 stevel if (!do_encr) { 2159 0 stevel /* authentication only */ 2160 0 stevel /* initialize input data argument */ 2161 11042 Erik ESP_INIT_CRYPTO_DATA(&ic->ic_crypto_data, 2162 0 stevel esp_mp, auth_offset, auth_len); 2163 0 stevel 2164 0 stevel /* call the crypto framework */ 2165 0 stevel kef_rc = crypto_mac_verify(&assoc->ipsa_amech, 2166 11042 Erik &ic->ic_crypto_data, 2167 0 stevel &assoc->ipsa_kcfauthkey, auth_ctx_tmpl, 2168 11042 Erik &ic->ic_crypto_mac, callrp); 2169 0 stevel } 2170 0 stevel } 2171 0 stevel 2172 0 stevel if (do_encr) { 2173 0 stevel /* encryption template */ 2174 0 stevel IPSEC_CTX_TMPL(assoc, ipsa_encrtmpl, IPSEC_ALG_ENCR, 2175 0 stevel encr_ctx_tmpl); 2176 0 stevel 2177 10824 Mark /* Call the nonce update function. Also passes in IV */ 2178 10824 Mark (assoc->ipsa_noncefunc)(assoc, (uchar_t *)esph_ptr, encr_len, 2179 11042 Erik iv_ptr, &ic->ic_cmm, &ic->ic_crypto_data); 2180 0 stevel 2181 0 stevel if (!do_auth) { 2182 0 stevel /* decryption only */ 2183 0 stevel /* initialize input data argument */ 2184 11042 Erik ESP_INIT_CRYPTO_DATA(&ic->ic_crypto_data, 2185 0 stevel esp_mp, encr_offset, encr_len); 2186 0 stevel 2187 0 stevel /* call the crypto framework */ 2188 10824 Mark kef_rc = crypto_decrypt((crypto_mechanism_t *) 2189 11042 Erik &ic->ic_cmm, &ic->ic_crypto_data, 2190 0 stevel &assoc->ipsa_kcfencrkey, encr_ctx_tmpl, 2191 11042 Erik NULL, callrp); 2192 0 stevel } 2193 0 stevel } 2194 0 stevel 2195 0 stevel if (do_auth && do_encr) { 2196 0 stevel /* dual operation */ 2197 0 stevel /* initialize input data argument */ 2198 11042 Erik ESP_INIT_CRYPTO_DUAL_DATA(&ic->ic_crypto_dual_data, 2199 0 stevel esp_mp, auth_offset, auth_len, 2200 0 stevel encr_offset, encr_len - icv_len); 2201 0 stevel 2202 0 stevel /* specify IV */ 2203 11042 Erik ic->ic_crypto_dual_data.dd_miscdata = (char *)iv_ptr; 2204 0 stevel 2205 0 stevel /* call the framework */ 2206 0 stevel kef_rc = crypto_mac_verify_decrypt(&assoc->ipsa_amech, 2207 11042 Erik &assoc->ipsa_emech, &ic->ic_crypto_dual_data, 2208 0 stevel &assoc->ipsa_kcfauthkey, &assoc->ipsa_kcfencrkey, 2209 11042 Erik auth_ctx_tmpl, encr_ctx_tmpl, &ic->ic_crypto_mac, 2210 11042 Erik NULL, callrp); 2211 0 stevel } 2212 0 stevel 2213 0 stevel switch (kef_rc) { 2214 0 stevel case CRYPTO_SUCCESS: 2215 3448 dh155122 ESP_BUMP_STAT(espstack, crypto_sync); 2216 11042 Erik esp_mp = esp_in_done(esp_mp, ira, ic); 2217 11042 Erik if (force) { 2218 11042 Erik /* Free mp after we are done with ic */ 2219 11042 Erik mp = ipsec_free_crypto_data(mp); 2220 11042 Erik (void) ip_recv_attr_free_mblk(mp); 2221 11042 Erik } 2222 11042 Erik return (esp_mp); 2223 0 stevel case CRYPTO_QUEUED: 2224 11042 Erik /* esp_kcf_callback_inbound() will be invoked on completion */ 2225 3448 dh155122 ESP_BUMP_STAT(espstack, crypto_async); 2226 11042 Erik return (NULL); 2227 0 stevel case CRYPTO_INVALID_MAC: 2228 11042 Erik if (force) { 2229 11042 Erik mp = ipsec_free_crypto_data(mp); 2230 11042 Erik esp_mp = ip_recv_attr_free_mblk(mp); 2231 11042 Erik } 2232 3448 dh155122 ESP_BUMP_STAT(espstack, crypto_sync); 2233 11042 Erik BUMP_MIB(ira->ira_ill->ill_ip_mib, ipIfStatsInDiscards); 2234 11042 Erik esp_log_bad_auth(esp_mp, ira); 2235 11042 Erik /* esp_mp was passed to ip_drop_packet */ 2236 11042 Erik return (NULL); 2237 11042 Erik } 2238 11042 Erik 2239 11042 Erik mp = ipsec_free_crypto_data(mp); 2240 11042 Erik esp_mp = ip_recv_attr_free_mblk(mp); 2241 11042 Erik BUMP_MIB(ira->ira_ill->ill_ip_mib, ipIfStatsInDiscards); 2242 11042 Erik esp_crypto_failed(esp_mp, B_TRUE, kef_rc, ira->ira_ill, espstack); 2243 11042 Erik /* esp_mp was passed to ip_drop_packet */ 2244 11042 Erik return (NULL); 2245 4987 danmcd } 2246 4987 danmcd 2247 4987 danmcd /* 2248 4987 danmcd * Compute the IP and UDP checksums -- common code for both keepalives and 2249 4987 danmcd * actual ESP-in-UDP packets. Be flexible with multiple mblks because ESP 2250 4987 danmcd * uses mblk-insertion to insert the UDP header. 2251 4987 danmcd * TODO - If there is an easy way to prep a packet for HW checksums, make 2252 4987 danmcd * it happen here. 2253 11042 Erik * Note that this is used before both before calling ip_output_simple and 2254 11042 Erik * in the esp datapath. The former could use IXAF_SET_ULP_CKSUM but not the 2255 11042 Erik * latter. 2256 4987 danmcd */ 2257 4987 danmcd static void 2258 4987 danmcd esp_prepare_udp(netstack_t *ns, mblk_t *mp, ipha_t *ipha) 2259 4987 danmcd { 2260 4987 danmcd int offset; 2261 4987 danmcd uint32_t cksum; 2262 4987 danmcd uint16_t *arr; 2263 4987 danmcd mblk_t *udpmp = mp; 2264 6352 wy83408 uint_t hlen = IPH_HDR_LENGTH(ipha); 2265 4987 danmcd 2266 4987 danmcd ASSERT(MBLKL(mp) >= sizeof (ipha_t)); 2267 4987 danmcd 2268 4987 danmcd ipha->ipha_hdr_checksum = 0; 2269 4987 danmcd ipha->ipha_hdr_checksum = ip_csum_hdr(ipha); 2270 4987 danmcd 2271 4987 danmcd if (ns->netstack_udp->us_do_checksum) { 2272 4987 danmcd ASSERT(MBLKL(udpmp) >= sizeof (udpha_t)); 2273 4987 danmcd /* arr points to the IP header. */ 2274 4987 danmcd arr = (uint16_t *)ipha; 2275 4987 danmcd IP_STAT(ns->netstack_ip, ip_out_sw_cksum); 2276 11042 Erik IP_STAT_UPDATE(ns->netstack_ip, ip_out_sw_cksum_bytes, 2277 6352 wy83408 ntohs(htons(ipha->ipha_length) - hlen)); 2278 4987 danmcd /* arr[6-9] are the IP addresses. */ 2279 4987 danmcd cksum = IP_UDP_CSUM_COMP + arr[6] + arr[7] + arr[8] + arr[9] + 2280 6352 wy83408 ntohs(htons(ipha->ipha_length) - hlen); 2281 6352 wy83408 cksum = IP_CSUM(mp, hlen, cksum); 2282 6352 wy83408 offset = hlen + UDP_CHECKSUM_OFFSET; 2283 4987 danmcd while (offset >= MBLKL(udpmp)) { 2284 4987 danmcd offset -= MBLKL(udpmp); 2285 4987 danmcd udpmp = udpmp->b_cont; 2286 4987 danmcd } 2287 4987 danmcd /* arr points to the UDP header's checksum field. */ 2288 4987 danmcd arr = (uint16_t *)(udpmp->b_rptr + offset); 2289 4987 danmcd *arr = cksum; 2290 4987 danmcd } 2291 8704 danmcd } 2292 8704 danmcd 2293 8704 danmcd /* 2294 8704 danmcd * taskq handler so we can send the NAT-T keepalive on a separate thread. 2295 8704 danmcd */ 2296 8704 danmcd static void 2297 8704 danmcd actually_send_keepalive(void *arg) 2298 8704 danmcd { 2299 11042 Erik mblk_t *mp = (mblk_t *)arg; 2300 11042 Erik ip_xmit_attr_t ixas; 2301 11042 Erik netstack_t *ns; 2302 11042 Erik netstackid_t stackid; 2303 11042 Erik 2304 11042 Erik stackid = (netstackid_t)(uintptr_t)mp->b_prev; 2305 11042 Erik mp->b_prev = NULL; 2306 11042 Erik ns = netstack_find_by_stackid(stackid); 2307 11042 Erik if (ns == NULL) { 2308 11042 Erik /* Disappeared */ 2309 11042 Erik ip_drop_output("ipIfStatsOutDiscards", mp, NULL); 2310 11042 Erik freemsg(mp); 2311 11042 Erik return; 2312 11042 Erik } 2313 11042 Erik 2314 11042 Erik bzero(&ixas, sizeof (ixas)); 2315 11042 Erik ixas.ixa_zoneid = ALL_ZONES; 2316 11042 Erik ixas.ixa_cred = kcred; 2317 11042 Erik ixas.ixa_cpid = NOPID; 2318 11042 Erik ixas.ixa_tsl = NULL; 2319 11042 Erik ixas.ixa_ipst = ns->netstack_ip; 2320 11042 Erik /* No ULP checksum; done by esp_prepare_udp */ 2321 11042 Erik ixas.ixa_flags = IXAF_IS_IPV4 | IXAF_NO_IPSEC; 2322 11042 Erik 2323 11042 Erik (void) ip_output_simple(mp, &ixas); 2324 11042 Erik ixa_cleanup(&ixas); 2325 8704 danmcd netstack_rele(ns); 2326 4987 danmcd } 2327 4987 danmcd 2328 4987 danmcd /* 2329 11042 Erik * Send a one-byte UDP NAT-T keepalive. 2330 4987 danmcd */ 2331 4987 danmcd void 2332 4987 danmcd ipsecesp_send_keepalive(ipsa_t *assoc) 2333 4987 danmcd { 2334 11042 Erik mblk_t *mp; 2335 11042 Erik ipha_t *ipha; 2336 11042 Erik udpha_t *udpha; 2337 11042 Erik netstack_t *ns = assoc->ipsa_netstack; 2338 4987 danmcd 2339 7373 sommerfeld ASSERT(MUTEX_NOT_HELD(&assoc->ipsa_lock)); 2340 4987 danmcd 2341 4987 danmcd mp = allocb(sizeof (ipha_t) + sizeof (udpha_t) + 1, BPRI_HI); 2342 4987 danmcd if (mp == NULL) 2343 4987 danmcd return; 2344 4987 danmcd ipha = (ipha_t *)mp->b_rptr; 2345 4987 danmcd ipha->ipha_version_and_hdr_length = IP_SIMPLE_HDR_VERSION; 2346 4987 danmcd ipha->ipha_type_of_service = 0; 2347 4987 danmcd ipha->ipha_length = htons(sizeof (ipha_t) + sizeof (udpha_t) + 1); 2348 4987 danmcd /* Use the low-16 of the SPI so we have some clue where it came from. */ 2349 4987 danmcd ipha->ipha_ident = *(((uint16_t *)(&assoc->ipsa_spi)) + 1); 2350 4987 danmcd ipha->ipha_fragment_offset_and_flags = 0; /* Too small to fragment! */ 2351 4987 danmcd ipha->ipha_ttl = 0xFF; 2352 4987 danmcd ipha->ipha_protocol = IPPROTO_UDP; 2353 4987 danmcd ipha->ipha_hdr_checksum = 0; 2354 4987 danmcd ipha->ipha_src = assoc->ipsa_srcaddr[0]; 2355 4987 danmcd ipha->ipha_dst = assoc->ipsa_dstaddr[0]; 2356 4987 danmcd udpha = (udpha_t *)(ipha + 1); 2357 4987 danmcd udpha->uha_src_port = (assoc->ipsa_local_nat_port != 0) ? 2358 4987 danmcd assoc->ipsa_local_nat_port : htons(IPPORT_IKE_NATT); 2359 4987 danmcd udpha->uha_dst_port = (assoc->ipsa_remote_nat_port != 0) ? 2360 4987 danmcd assoc->ipsa_remote_nat_port : htons(IPPORT_IKE_NATT); 2361 4987 danmcd udpha->uha_length = htons(sizeof (udpha_t) + 1); 2362 4987 danmcd udpha->uha_checksum = 0; 2363 4987 danmcd mp->b_wptr = (uint8_t *)(udpha + 1); 2364 4987 danmcd *(mp->b_wptr++) = 0xFF; 2365 4987 danmcd 2366 11042 Erik esp_prepare_udp(ns, mp, ipha); 2367 11042 Erik 2368 8704 danmcd /* 2369 8704 danmcd * We're holding an isaf_t bucket lock, so pawn off the actual 2370 8704 danmcd * packet transmission to another thread. Just in case syncq 2371 8704 danmcd * processing causes a same-bucket packet to be processed. 2372 8704 danmcd */ 2373 11042 Erik mp->b_prev = (mblk_t *)(uintptr_t)ns->netstack_stackid; 2374 11042 Erik 2375 11042 Erik if (taskq_dispatch(esp_taskq, actually_send_keepalive, mp, 2376 8704 danmcd TQ_NOSLEEP) == 0) { 2377 8704 danmcd /* Assume no memory if taskq_dispatch() fails. */ 2378 11042 Erik mp->b_prev = NULL; 2379 11042 Erik ip_drop_packet(mp, B_FALSE, NULL, 2380 11042 Erik DROPPER(ns->netstack_ipsec, ipds_esp_nomem), 2381 11042 Erik &ns->netstack_ipsecesp->esp_dropper); 2382 11042 Erik } 2383 11042 Erik } 2384 11042 Erik 2385 11042 Erik /* 2386 11042 Erik * Returns mp if successfully completed the request. Returns 2387 11042 Erik * NULL if it failed (and increments InDiscards) or if it is pending. 2388 11042 Erik */ 2389 11042 Erik static mblk_t * 2390 11042 Erik esp_submit_req_outbound(mblk_t *data_mp, ip_xmit_attr_t *ixa, ipsa_t *assoc, 2391 11042 Erik uchar_t *icv_buf, uint_t payload_len) 2392 11042 Erik { 2393 0 stevel uint_t auth_len; 2394 11042 Erik crypto_call_req_t call_req, *callrp; 2395 11042 Erik mblk_t *esp_mp; 2396 10824 Mark esph_t *esph_ptr; 2397 11042 Erik mblk_t *mp; 2398 0 stevel int kef_rc = CRYPTO_FAILED; 2399 0 stevel uint_t icv_len = assoc->ipsa_mac_len; 2400 0 stevel crypto_ctx_template_t auth_ctx_tmpl; 2401 11042 Erik boolean_t do_auth, do_encr, force; 2402 0 stevel uint_t iv_len = assoc->ipsa_iv_len; 2403 0 stevel crypto_ctx_template_t encr_ctx_tmpl; 2404 0 stevel boolean_t is_natt = ((assoc->ipsa_flags & IPSA_F_NATT) != 0); 2405 0 stevel size_t esph_offset = (is_natt ? UDPH_SIZE : 0); 2406 11042 Erik netstack_t *ns = ixa->ixa_ipst->ips_netstack; 2407 11042 Erik ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; 2408 11042 Erik ipsec_crypto_t *ic, icstack; 2409 11042 Erik uchar_t *iv_ptr; 2410 11042 Erik crypto_data_t *cd_ptr = NULL; 2411 11042 Erik ill_t *ill = ixa->ixa_nce->nce_ill; 2412 11042 Erik ipsec_stack_t *ipss = ns->netstack_ipsec; 2413 0 stevel 2414 3448 dh155122 esp3dbg(espstack, ("esp_submit_req_outbound:%s", 2415 4987 danmcd is_natt ? "natt" : "not natt")); 2416 0 stevel 2417 0 stevel do_encr = assoc->ipsa_encr_alg != SADB_EALG_NULL; 2418 0 stevel do_auth = assoc->ipsa_auth_alg != SADB_AALG_NONE; 2419 11042 Erik force = (assoc->ipsa_flags & IPSA_F_ASYNC); 2420 11042 Erik 2421 11042 Erik #ifdef IPSEC_LATENCY_TEST 2422 11042 Erik kef_rc = CRYPTO_SUCCESS; 2423 11042 Erik #else 2424 11042 Erik kef_rc = CRYPTO_FAILED; 2425 11042 Erik #endif 2426 0 stevel 2427 0 stevel /* 2428 0 stevel * Outbound IPsec packets are of the form: 2429 11042 Erik * [IP,options] -> [ESP,IV] -> [data] -> [pad,ICV] 2430 0 stevel * unless it's NATT, then it's 2431 11042 Erik * [IP,options] -> [udp][ESP,IV] -> [data] -> [pad,ICV] 2432 0 stevel * Get a pointer to the mblk containing the ESP header. 2433 0 stevel */ 2434 11042 Erik ASSERT(data_mp->b_cont != NULL); 2435 11042 Erik esp_mp = data_mp->b_cont; 2436 10824 Mark esph_ptr = (esph_t *)(esp_mp->b_rptr + esph_offset); 2437 10824 Mark iv_ptr = (uchar_t *)(esph_ptr + 1); 2438 10824 Mark 2439 10824 Mark /* 2440 10824 Mark * Combined mode algs need a nonce. This is setup in sadb_common_add(). 2441 10824 Mark * If for some reason we are using a SA which does not have a nonce 2442 10824 Mark * then we must fail here. 2443 10824 Mark */ 2444 10824 Mark if ((assoc->ipsa_flags & IPSA_F_COUNTERMODE) && 2445 10824 Mark (assoc->ipsa_nonce == NULL)) { 2446 11042 Erik ip_drop_packet(data_mp, B_FALSE, NULL, 2447 10824 Mark DROPPER(ipss, ipds_esp_nomem), &espstack->esp_dropper); 2448 11042 Erik return (NULL); 2449 11042 Erik } 2450 11042 Erik 2451 11042 Erik if (force) { 2452 11042 Erik /* We are doing asynch; allocate mblks to hold state */ 2453 11042 Erik if ((mp = ip_xmit_attr_to_mblk(ixa)) == NULL || 2454 11042 Erik (mp = ipsec_add_crypto_data(mp, &ic)) == NULL) { 2455 11042 Erik BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards); 2456 11042 Erik ip_drop_output("ipIfStatsOutDiscards", data_mp, ill); 2457 11042 Erik freemsg(data_mp); 2458 11042 Erik return (NULL); 2459 11042 Erik } 2460 11042 Erik 2461 11042 Erik linkb(mp, data_mp); 2462 11042 Erik callrp = &call_req; 2463 11042 Erik ESP_INIT_CALLREQ(callrp, mp, esp_kcf_callback_outbound); 2464 11042 Erik } else { 2465 11042 Erik /* 2466 11042 Erik * If we know we are going to do sync then ipsec_crypto_t 2467 11042 Erik * should be on the stack. 2468 11042 Erik */ 2469 11042 Erik ic = &icstack; 2470 11042 Erik bzero(ic, sizeof (*ic)); 2471 11042 Erik callrp = NULL; 2472 11042 Erik } 2473 11042 Erik 2474 0 stevel 2475 0 stevel if (do_auth) { 2476 0 stevel /* authentication context template */ 2477 0 stevel IPSEC_CTX_TMPL(assoc, ipsa_authtmpl, IPSEC_ALG_AUTH, 2478 0 stevel auth_ctx_tmpl); 2479 0 stevel 2480 0 stevel /* where to store the computed mac */ 2481 11042 Erik ESP_INIT_CRYPTO_MAC(&ic->ic_crypto_mac, 2482 0 stevel icv_len, icv_buf); 2483 0 stevel 2484 0 stevel /* authentication starts at the ESP header */ 2485 134 danmcd auth_len = payload_len + iv_len + sizeof (esph_t); 2486 0 stevel if (!do_encr) { 2487 0 stevel /* authentication only */ 2488 0 stevel /* initialize input data argument */ 2489 11042 Erik ESP_INIT_CRYPTO_DATA(&ic->ic_crypto_data, 2490 0 stevel esp_mp, esph_offset, auth_len); 2491 0 stevel 2492 0 stevel /* call the crypto framework */ 2493 0 stevel kef_rc = crypto_mac(&assoc->ipsa_amech, 2494 11042 Erik &ic->ic_crypto_data, 2495 0 stevel &assoc->ipsa_kcfauthkey, auth_ctx_tmpl, 2496 11042 Erik &ic->ic_crypto_mac, callrp); 2497 0 stevel } 2498 0 stevel } 2499 0 stevel 2500 0 stevel if (do_encr) { 2501 0 stevel /* encryption context template */ 2502 0 stevel IPSEC_CTX_TMPL(assoc, ipsa_encrtmpl, IPSEC_ALG_ENCR, 2503 0 stevel encr_ctx_tmpl); 2504 10824 Mark /* Call the nonce update function. */ 2505 10824 Mark (assoc->ipsa_noncefunc)(assoc, (uchar_t *)esph_ptr, payload_len, 2506 11042 Erik iv_ptr, &ic->ic_cmm, &ic->ic_crypto_data); 2507 0 stevel 2508 0 stevel if (!do_auth) { 2509 0 stevel /* encryption only, skip mblk that contains ESP hdr */ 2510 0 stevel /* initialize input data argument */ 2511 11042 Erik ESP_INIT_CRYPTO_DATA(&ic->ic_crypto_data, 2512 11042 Erik esp_mp->b_cont, 0, payload_len); 2513 10824 Mark 2514 10824 Mark /* 2515 10824 Mark * For combined mode ciphers, the ciphertext is the same 2516 10824 Mark * size as the clear text, the ICV should follow the 2517 10824 Mark * ciphertext. To convince the kcf to allow in-line 2518 10824 Mark * encryption, with an ICV, use ipsec_out_crypto_mac 2519 10824 Mark * to point to the same buffer as the data. The calling 2520 10824 Mark * function need to ensure the buffer is large enough to 2521 10824 Mark * include the ICV. 2522 10824 Mark * 2523 10824 Mark * The IV is already written to the packet buffer, the 2524 10824 Mark * nonce setup function copied it to the params struct 2525 10824 Mark * for the cipher to use. 2526 10824 Mark */ 2527 10824 Mark if (assoc->ipsa_flags & IPSA_F_COMBINED) { 2528 11042 Erik bcopy(&ic->ic_crypto_data, 2529 11042 Erik &ic->ic_crypto_mac, 2530 10824 Mark sizeof (crypto_data_t)); 2531 11042 Erik ic->ic_crypto_mac.cd_length = 2532 10824 Mark payload_len + icv_len; 2533 11042 Erik cd_ptr = &ic->ic_crypto_mac; 2534 10824 Mark } 2535 0 stevel 2536 0 stevel /* call the crypto framework */ 2537 10824 Mark kef_rc = crypto_encrypt((crypto_mechanism_t *) 2538 11042 Erik &ic->ic_cmm, &ic->ic_crypto_data, 2539 0 stevel &assoc->ipsa_kcfencrkey, encr_ctx_tmpl, 2540 11042 Erik cd_ptr, callrp); 2541 10824 Mark 2542 0 stevel } 2543 0 stevel } 2544 0 stevel 2545 0 stevel if (do_auth && do_encr) { 2546 0 stevel /* 2547 0 stevel * Encryption and authentication: 2548 0 stevel * Pass the pointer to the mblk chain starting at the ESP 2549 0 stevel * header to the framework. Skip the ESP header mblk 2550 0 stevel * for encryption, which is reflected by an encryption 2551 0 stevel * offset equal to the length of that mblk. Start 2552 0 stevel * the authentication at the ESP header, i.e. use an 2553 0 stevel * authentication offset of zero. 2554 0 stevel */ 2555 11042 Erik ESP_INIT_CRYPTO_DUAL_DATA(&ic->ic_crypto_dual_data, 2556 0 stevel esp_mp, MBLKL(esp_mp), payload_len, esph_offset, auth_len); 2557 0 stevel 2558 0 stevel /* specify IV */ 2559 11042 Erik ic->ic_crypto_dual_data.dd_miscdata = (char *)iv_ptr; 2560 0 stevel 2561 0 stevel /* call the framework */ 2562 0 stevel kef_rc = crypto_encrypt_mac(&assoc->ipsa_emech, 2563 0 stevel &assoc->ipsa_amech, NULL, 2564 0 stevel &assoc->ipsa_kcfencrkey, &assoc->ipsa_kcfauthkey, 2565 0 stevel encr_ctx_tmpl, auth_ctx_tmpl, 2566 11042 Erik &ic->ic_crypto_dual_data, 2567 11042 Erik &ic->ic_crypto_mac, callrp); 2568 0 stevel } 2569 0 stevel 2570 0 stevel switch (kef_rc) { 2571 0 stevel case CRYPTO_SUCCESS: 2572 3448 dh155122 ESP_BUMP_STAT(espstack, crypto_sync); 2573 4987 danmcd esp_set_usetime(assoc, B_FALSE); 2574 11042 Erik if (force) { 2575 11042 Erik mp = ipsec_free_crypto_data(mp); 2576 11042 Erik data_mp = ip_xmit_attr_free_mblk(mp); 2577 11042 Erik } 2578 4987 danmcd if (is_natt) 2579 11042 Erik esp_prepare_udp(ns, data_mp, (ipha_t *)data_mp->b_rptr); 2580 11042 Erik return (data_mp); 2581 0 stevel case CRYPTO_QUEUED: 2582 11042 Erik /* esp_kcf_callback_outbound() will be invoked on completion */ 2583 3448 dh155122 ESP_BUMP_STAT(espstack, crypto_async); 2584 11042 Erik return (NULL); 2585 11042 Erik } 2586 11042 Erik 2587 11042 Erik if (force) { 2588 11042 Erik mp = ipsec_free_crypto_data(mp); 2589 11042 Erik data_mp = ip_xmit_attr_free_mblk(mp); 2590 11042 Erik } 2591 11042 Erik BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards); 2592 11042 Erik esp_crypto_failed(data_mp, B_FALSE, kef_rc, NULL, espstack); 2593 11042 Erik /* data_mp was passed to ip_drop_packet */ 2594 11042 Erik return (NULL); 2595 0 stevel } 2596 0 stevel 2597 0 stevel /* 2598 0 stevel * Handle outbound IPsec processing for IPv4 and IPv6 2599 11042 Erik * 2600 11042 Erik * Returns data_mp if successfully completed the request. Returns 2601 11042 Erik * NULL if it failed (and increments InDiscards) or if it is pending. 2602 11042 Erik */ 2603 11042 Erik static mblk_t * 2604 11042 Erik esp_outbound(mblk_t *data_mp, ip_xmit_attr_t *ixa) 2605 11042 Erik { 2606 11042 Erik mblk_t *espmp, *tailmp; 2607 0 stevel ipha_t *ipha; 2608 0 stevel ip6_t *ip6h; 2609 10824 Mark esph_t *esph_ptr, *iv_ptr; 2610 0 stevel uint_t af; 2611 0 stevel uint8_t *nhp; 2612 0 stevel uintptr_t divpoint, datalen, adj, padlen, i, alloclen; 2613 0 stevel uintptr_t esplen = sizeof (esph_t); 2614 0 stevel uint8_t protocol; 2615 0 stevel ipsa_t *assoc; 2616 10824 Mark uint_t iv_len, block_size, mac_len = 0; 2617 0 stevel uchar_t *icv_buf; 2618 0 stevel udpha_t *udpha; 2619 0 stevel boolean_t is_natt = B_FALSE; 2620 11042 Erik netstack_t *ns = ixa->ixa_ipst->ips_netstack; 2621 11042 Erik ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; 2622 11042 Erik ipsec_stack_t *ipss = ns->netstack_ipsec; 2623 11042 Erik ill_t *ill = ixa->ixa_nce->nce_ill; 2624 11042 Erik boolean_t need_refrele = B_FALSE; 2625 3448 dh155122 2626 3448 dh155122 ESP_BUMP_STAT(espstack, out_requests); 2627 0 stevel 2628 0 stevel /* 2629 0 stevel * <sigh> We have to copy the message here, because TCP (for example) 2630 0 stevel * keeps a dupb() of the message lying around for retransmission. 2631 0 stevel * Since ESP changes the whole of the datagram, we have to create our 2632 0 stevel * own copy lest we clobber TCP's data. Since we have to copy anyway, 2633 0 stevel * we might as well make use of msgpullup() and get the mblk into one 2634 0 stevel * contiguous piece! 2635 0 stevel */ 2636 11042 Erik tailmp = msgpullup(data_mp, -1); 2637 11042 Erik if (tailmp == NULL) { 2638 0 stevel esp0dbg(("esp_outbound: msgpullup() failed, " 2639 0 stevel "dropping packet.\n")); 2640 11042 Erik ip_drop_packet(data_mp, B_FALSE, ill, 2641 3448 dh155122 DROPPER(ipss, ipds_esp_nomem), 2642 3448 dh155122 &espstack->esp_dropper); 2643 11042 Erik BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards); 2644 11042 Erik return (NULL); 2645 11042 Erik } 2646 11042 Erik freemsg(data_mp); 2647 11042 Erik data_mp = tailmp; 2648 11042 Erik 2649 11042 Erik assoc = ixa->ixa_ipsec_esp_sa; 2650 10934 sommerfeld ASSERT(assoc != NULL); 2651 10934 sommerfeld 2652 10934 sommerfeld /* 2653 10934 sommerfeld * Get the outer IP header in shape to escape this system.. 2654 10934 sommerfeld */ 2655 11042 Erik if (is_system_labeled() && (assoc->ipsa_otsl != NULL)) { 2656 11042 Erik /* 2657 11042 Erik * Need to update packet with any CIPSO option and update 2658 11042 Erik * ixa_tsl to capture the new label. 2659 11042 Erik * We allocate a separate ixa for that purpose. 2660 11042 Erik */ 2661 11042 Erik ixa = ip_xmit_attr_duplicate(ixa); 2662 11042 Erik if (ixa == NULL) { 2663 11042 Erik ip_drop_packet(data_mp, B_FALSE, ill, 2664 11042 Erik DROPPER(ipss, ipds_esp_nomem), 2665 11042 Erik &espstack->esp_dropper); 2666 11042 Erik return (NULL); 2667 11042 Erik } 2668 11042 Erik need_refrele = B_TRUE; 2669 11042 Erik 2670 11042 Erik label_hold(assoc->ipsa_otsl); 2671 11042 Erik ip_xmit_attr_replace_tsl(ixa, assoc->ipsa_otsl); 2672 11042 Erik 2673 11042 Erik data_mp = sadb_whack_label(data_mp, assoc, ixa, 2674 11042 Erik DROPPER(ipss, ipds_esp_nomem), &espstack->esp_dropper); 2675 11042 Erik if (data_mp == NULL) { 2676 11042 Erik /* Packet dropped by sadb_whack_label */ 2677 11042 Erik ixa_refrele(ixa); 2678 11042 Erik return (NULL); 2679 11042 Erik } 2680 11042 Erik } 2681 10934 sommerfeld 2682 0 stevel /* 2683 0 stevel * Reality check.... 2684 0 stevel */ 2685 0 stevel ipha = (ipha_t *)data_mp->b_rptr; /* So we can call esp_acquire(). */ 2686 0 stevel 2687 11042 Erik if (ixa->ixa_flags & IXAF_IS_IPV4) { 2688 11042 Erik ASSERT(IPH_HDR_VERSION(ipha) == IPV4_VERSION); 2689 11042 Erik 2690 0 stevel af = AF_INET; 2691 0 stevel divpoint = IPH_HDR_LENGTH(ipha); 2692 0 stevel datalen = ntohs(ipha->ipha_length) - divpoint; 2693 0 stevel nhp = (uint8_t *)&ipha->ipha_protocol; 2694 0 stevel } else { 2695 11042 Erik ip_pkt_t ipp; 2696 11042 Erik 2697 11042 Erik ASSERT(IPH_HDR_VERSION(ipha) == IPV6_VERSION); 2698 0 stevel 2699 0 stevel af = AF_INET6; 2700 0 stevel ip6h = (ip6_t *)ipha; 2701 0 stevel bzero(&ipp, sizeof (ipp)); 2702 11042 Erik divpoint = ip_find_hdr_v6(data_mp, ip6h, B_FALSE, &ipp, NULL); 2703 0 stevel if (ipp.ipp_dstopts != NULL && 2704 0 stevel ipp.ipp_dstopts->ip6d_nxt != IPPROTO_ROUTING) { 2705 0 stevel /* 2706 0 stevel * Destination options are tricky. If we get in here, 2707 0 stevel * then we have a terminal header following the 2708 0 stevel * destination options. We need to adjust backwards 2709 0 stevel * so we insert ESP BEFORE the destination options 2710 0 stevel * bag. (So that the dstopts get encrypted!) 2711 0 stevel * 2712 0 stevel * Since this is for outbound packets only, we know 2713 0 stevel * that non-terminal destination options only precede 2714 0 stevel * routing headers. 2715 0 stevel */ 2716 0 stevel divpoint -= ipp.ipp_dstoptslen; 2717 0 stevel } 2718 0 stevel datalen = ntohs(ip6h->ip6_plen) + sizeof (ip6_t) - divpoint; 2719 0 stevel 2720 0 stevel if (ipp.ipp_rthdr != NULL) { 2721 0 stevel nhp = &ipp.ipp_rthdr->ip6r_nxt; 2722 0 stevel } else if (ipp.ipp_hopopts != NULL) { 2723 0 stevel nhp = &ipp.ipp_hopopts->ip6h_nxt; 2724 0 stevel } else { 2725 0 stevel ASSERT(divpoint == sizeof (ip6_t)); 2726 0 stevel /* It's probably IP + ESP. */ 2727 0 stevel nhp = &ip6h->ip6_nxt; 2728 0 stevel } 2729 0 stevel } 2730 0 stevel 2731 10824 Mark mac_len = assoc->ipsa_mac_len; 2732 0 stevel 2733 0 stevel if (assoc->ipsa_flags & IPSA_F_NATT) { 2734 10934 sommerfeld /* wedge in UDP header */ 2735 0 stevel is_natt = B_TRUE; 2736 0 stevel esplen += UDPH_SIZE; 2737 0 stevel } 2738 0 stevel 2739 0 stevel /* 2740 0 stevel * Set up ESP header and encryption padding for ENCR PI request. 2741 0 stevel */ 2742 0 stevel 2743 3192 danmcd /* Determine the padding length. Pad to 4-bytes for no-encryption. */ 2744 3192 danmcd if (assoc->ipsa_encr_alg != SADB_EALG_NULL) { 2745 3192 danmcd iv_len = assoc->ipsa_iv_len; 2746 10824 Mark block_size = assoc->ipsa_datalen; 2747 10824 Mark 2748 10824 Mark /* 2749 10824 Mark * Pad the data to the length of the cipher block size. 2750 3192 danmcd * Include the two additional bytes (hence the - 2) for the 2751 3192 danmcd * padding length and the next header. Take this into account 2752 3192 danmcd * when calculating the actual length of the padding. 2753 3192 danmcd */ 2754 3192 danmcd ASSERT(ISP2(iv_len)); 2755 10824 Mark padlen = ((unsigned)(block_size - datalen - 2)) & 2756 10824 Mark (block_size - 1); 2757 0 stevel } else { 2758 3192 danmcd iv_len = 0; 2759 3192 danmcd padlen = ((unsigned)(sizeof (uint32_t) - datalen - 2)) & 2760 3192 danmcd (sizeof (uint32_t) - 1); 2761 0 stevel } 2762 0 stevel 2763 0 stevel /* Allocate ESP header and IV. */ 2764 0 stevel esplen += iv_len; 2765 0 stevel 2766 0 stevel /* 2767 0 stevel * Update association byte-count lifetimes. Don't forget to take 2768 0 stevel * into account the padding length and next-header (hence the + 2). 2769 134 danmcd * 2770 0 stevel * Use the amount of data fed into the "encryption algorithm". This 2771 0 stevel * is the IV, the data length, the padding length, and the final two 2772 0 stevel * bytes (padlen, and next-header). 2773 0 stevel * 2774 0 stevel */ 2775 0 stevel 2776 134 danmcd if (!esp_age_bytes(assoc, datalen + padlen + iv_len + 2, B_FALSE)) { 2777 11042 Erik ip_drop_packet(data_mp, B_FALSE, ill, 2778 3448 dh155122 DROPPER(ipss, ipds_esp_bytes_expire), 2779 3448 dh155122 &espstack->esp_dropper); 2780 11042 Erik BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards); 2781 11042 Erik if (need_refrele) 2782 11042 Erik ixa_refrele(ixa); 2783 11042 Erik return (NULL); 2784 0 stevel } 2785 0 stevel 2786 0 stevel espmp = allocb(esplen, BPRI_HI); 2787 0 stevel if (espmp == NULL) { 2788 3448 dh155122 ESP_BUMP_STAT(espstack, out_discards); 2789 3448 dh155122 esp1dbg(espstack, ("esp_outbound: can't allocate espmp.\n")); 2790 11042 Erik ip_drop_packet(data_mp, B_FALSE, ill, 2791 3448 dh155122 DROPPER(ipss, ipds_esp_nomem), 2792 3448 dh155122 &espstack->esp_dropper); 2793 11042 Erik BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards); 2794 11042 Erik if (need_refrele) 2795 11042 Erik ixa_refrele(ixa); 2796 11042 Erik return (NULL); 2797 0 stevel } 2798 0 stevel espmp->b_wptr += esplen; 2799 10824 Mark esph_ptr = (esph_t *)espmp->b_rptr; 2800 0 stevel 2801 0 stevel if (is_natt) { 2802 3448 dh155122 esp3dbg(espstack, ("esp_outbound: NATT")); 2803 0 stevel 2804 0 stevel udpha = (udpha_t *)espmp->b_rptr; 2805 4987 danmcd udpha->uha_src_port = (assoc->ipsa_local_nat_port != 0) ? 2806 4987 danmcd assoc->ipsa_local_nat_port : htons(IPPORT_IKE_NATT); 2807 4987 danmcd udpha->uha_dst_port = (assoc->ipsa_remote_nat_port != 0) ? 2808 4987 danmcd assoc->ipsa_remote_nat_port : htons(IPPORT_IKE_NATT); 2809 4987 danmcd /* 2810 4987 danmcd * Set the checksum to 0, so that the esp_prepare_udp() call 2811 0 stevel * can do the right thing. 2812 0 stevel */ 2813 0 stevel udpha->uha_checksum = 0; 2814 10824 Mark esph_ptr = (esph_t *)(udpha + 1); 2815 10824 Mark } 2816 10824 Mark 2817 10824 Mark esph_ptr->esph_spi = assoc->ipsa_spi; 2818 10824 Mark 2819 10824 Mark esph_ptr->esph_replay = htonl(atomic_add_32_nv(&assoc->ipsa_replay, 1)); 2820 10824 Mark if (esph_ptr->esph_replay == 0 && assoc->ipsa_replay_wsize != 0) { 2821 0 stevel /* 2822 0 stevel * XXX We have replay counter wrapping. 2823 0 stevel * We probably want to nuke this SA (and its peer). 2824 0 stevel */ 2825 0 stevel ipsec_assocfailure(info.mi_idnum, 0, 0, 2826 0 stevel SL_ERROR | SL_CONSOLE | SL_WARN, 2827 0 stevel "Outbound ESP SA (0x%x, %s) has wrapped sequence.\n", 2828 10824 Mark esph_ptr->esph_spi, assoc->ipsa_dstaddr, af, 2829 3448 dh155122 espstack->ipsecesp_netstack); 2830 0 stevel 2831 3448 dh155122 ESP_BUMP_STAT(espstack, out_discards); 2832 0 stevel sadb_replay_delete(assoc); 2833 11042 Erik ip_drop_packet(data_mp, B_FALSE, ill, 2834 3448 dh155122 DROPPER(ipss, ipds_esp_replay), 2835 3448 dh155122 &espstack->esp_dropper); 2836 11042 Erik BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards); 2837 11042 Erik if (need_refrele) 2838 11042 Erik ixa_refrele(ixa); 2839 11042 Erik return (NULL); 2840 0 stevel } 2841 0 stevel 2842 10824 Mark iv_ptr = (esph_ptr + 1); 2843 10824 Mark /* 2844 10824 Mark * iv_ptr points to the mblk which will contain the IV once we have 2845 10824 Mark * written it there. This mblk will be part of a mblk chain that 2846 10824 Mark * will make up the packet. 2847 10824 Mark * 2848 10824 Mark * For counter mode algorithms, the IV is a 64 bit quantity, it 2849 10824 Mark * must NEVER repeat in the lifetime of the SA, otherwise an 2850 10824 Mark * attacker who had recorded enough packets might be able to 2851 10824 Mark * determine some clear text. 2852 10824 Mark * 2853 10824 Mark * To ensure this does not happen, the IV is stored in the SA and 2854 10824 Mark * incremented for each packet, the IV is then copied into the 2855 10824 Mark * "packet" for transmission to the receiving system. The IV will 2856 10824 Mark * also be copied into the nonce, when the packet is encrypted. 2857 10824 Mark * 2858 10824 Mark * CBC mode algorithms use a random IV for each packet. We do not 2859 10824 Mark * require the highest quality random bits, but for best security 2860 10824 Mark * with CBC mode ciphers, the value must be unlikely to repeat and 2861 10824 Mark * must not be known in advance to an adversary capable of influencing 2862 10824 Mark * the clear text. 2863 10824 Mark */ 2864 10824 Mark if (!update_iv((uint8_t *)iv_ptr, espstack->esp_pfkey_q, assoc, 2865 10824 Mark espstack)) { 2866 11042 Erik ip_drop_packet(data_mp, B_FALSE, ill, 2867 10824 Mark DROPPER(ipss, ipds_esp_iv_wrap), &espstack->esp_dropper); 2868 11042 Erik if (need_refrele) 2869 11042 Erik ixa_refrele(ixa); 2870 11042 Erik return (NULL); 2871 10824 Mark } 2872 0 stevel 2873 0 stevel /* Fix the IP header. */ 2874 0 stevel alloclen = padlen + 2 + mac_len; 2875 0 stevel adj = alloclen + (espmp->b_wptr - espmp->b_rptr); 2876 0 stevel 2877 0 stevel protocol = *nhp; 2878 0 stevel 2879 11042 Erik if (ixa->ixa_flags & IXAF_IS_IPV4) { 2880 0 stevel ipha->ipha_length = htons(ntohs(ipha->ipha_length) + adj); 2881 0 stevel if (is_natt) { 2882 0 stevel *nhp = IPPROTO_UDP; 2883 0 stevel udpha->uha_length = htons(ntohs(ipha->ipha_length) - 2884 0 stevel IPH_HDR_LENGTH(ipha)); 2885 0 stevel } else { 2886 0 stevel *nhp = IPPROTO_ESP; 2887 0 stevel } 2888 0 stevel ipha->ipha_hdr_checksum = 0; 2889 0 stevel ipha->ipha_hdr_checksum = (uint16_t)ip_csum_hdr(ipha); 2890 0 stevel } else { 2891 0 stevel ip6h->ip6_plen = htons(ntohs(ip6h->ip6_plen) + adj); 2892 0 stevel *nhp = IPPROTO_ESP; 2893 0 stevel } 2894 0 stevel 2895 0 stevel /* I've got the two ESP mblks, now insert them. */ 2896 0 stevel 2897 3448 dh155122 esp2dbg(espstack, ("data_mp before outbound ESP adjustment:\n")); 2898 3448 dh155122 esp2dbg(espstack, (dump_msg(data_mp))); 2899 0 stevel 2900 3448 dh155122 if (!esp_insert_esp(data_mp, espmp, divpoint, espstack)) { 2901 3448 dh155122 ESP_BUMP_STAT(espstack, out_discards); 2902 0 stevel /* NOTE: esp_insert_esp() only fails if there's no memory. */ 2903 11042 Erik ip_drop_packet(data_mp, B_FALSE, ill, 2904 3448 dh155122 DROPPER(ipss, ipds_esp_nomem), 2905 3448 dh155122 &espstack->esp_dropper); 2906 0 stevel freeb(espmp); 2907 11042 Erik BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards); 2908 11042 Erik if (need_refrele) 2909 11042 Erik ixa_refrele(ixa); 2910 11042 Erik return (NULL); 2911 0 stevel } 2912 0 stevel 2913 0 stevel /* Append padding (and leave room for ICV). */ 2914 0 stevel for (tailmp = data_mp; tailmp->b_cont != NULL; tailmp = tailmp->b_cont) 2915 0 stevel ; 2916 0 stevel if (tailmp->b_wptr + alloclen > tailmp->b_datap->db_lim) { 2917 0 stevel tailmp->b_cont = allocb(alloclen, BPRI_HI); 2918 0 stevel if (tailmp->b_cont == NULL) { 2919 3448 dh155122 ESP_BUMP_STAT(espstack, out_discards); 2920 0 stevel esp0dbg(("esp_outbound: Can't allocate tailmp.\n")); 2921 11042 Erik ip_drop_packet(data_mp, B_FALSE, ill, 2922 3448 dh155122 DROPPER(ipss, ipds_esp_nomem), 2923 3448 dh155122 &espstack->esp_dropper); 2924 11042 Erik BUMP_MIB(ill->ill_ip_mib, ipIfStatsOutDiscards); 2925 11042 Erik if (need_refrele) 2926 11042 Erik ixa_refrele(ixa); 2927 11042 Erik return (NULL); 2928 0 stevel } 2929 0 stevel tailmp = tailmp->b_cont; 2930 0 stevel } 2931 0 stevel 2932 0 stevel /* 2933 0 stevel * If there's padding, N bytes of padding must be of the form 0x1,