ipsecesp.c revision 437220cd296f6d8b6654d6d52508b40b1e2d1ac7
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A#
pragma ident "%Z%%M% %I% %E% SMI" 2N/A * Table of ND variables supported by ipsecesp. These are loaded into 2N/A * ipsecesp_g_nd in ipsecesp_init_nd. 2N/A * All of these are alterable, within the min/max values given, at run time. 2N/A /* min max value name */ 2N/A { 0,
3, 0,
"ipsecesp_debug"},
2N/A {
1,
10,
1,
"ipsecesp_reap_delay"},
2N/A {
1,
300,
15,
"ipsecesp_acquire_timeout"},
2N/A {
1,
1800,
90,
"ipsecesp_larval_timeout"},
2N/A /* Default lifetime values for ACQUIRE messages. */ 2N/A { 0,
0xffffffffU, 0,
"ipsecesp_default_soft_bytes"},
2N/A { 0,
0xffffffffU, 0,
"ipsecesp_default_hard_bytes"},
2N/A { 0,
0xffffffffU,
24000,
"ipsecesp_default_soft_addtime"},
2N/A { 0,
0xffffffffU,
28800,
"ipsecesp_default_hard_addtime"},
2N/A { 0,
0xffffffffU, 0,
"ipsecesp_default_soft_usetime"},
2N/A { 0,
0xffffffffU, 0,
"ipsecesp_default_hard_usetime"},
2N/A { 0,
1, 0,
"ipsecesp_log_unknown_spi"},
2N/A { 0,
2,
1,
"ipsecesp_padding_check"},
2N/A { 0,
600,
20,
"ipsecesp_nat_keepalive_interval"},
/* For ipsecesp_nat_keepalive_interval, see ipsecesp.h. */ /* NOTE: != 0 instead of > 0 so lint doesn't complain. */ 5137,
"ipsecesp", 0,
INFPSZ,
65536,
1024 * OTOH, this one is set at open/close, and I'm D_MTQPAIR for now. * Question: Do I need this, given that all instance's esps->esps_wq point * Answer: Yes, because I need to know which queue is BOUND to * Stats. This may eventually become a full-blown SNMP MIB once that spec * espstack->esp_kstats is equal to espstack->esp_ksp->ks_data if * kstat_create_netstack for espstack->esp_ksp succeeds, but when it * fails, it will be NULL. Note this is done for all stack instances, * so it *could* fail. hence a non-NULL checking is done for * ESP_BUMP_STAT and ESP_DEBUMP_STAT * Debug routine, useful to see pre-encryption data. printf(
"mblk address 0x%p, length %ld, db_ref %d " "type %d, base 0x%p, lim 0x%p\n",
* Don't have to lock age_interval, as only one thread will access it at * a time, because I control the one function that does with timeout(). * Get an ESP NDD parameter. * This routine sets an NDD variable in a ipsecespparam_t structure. * Fail the request if the new value does not lie within the * Using lifetime NDD variables, fill in an extended combination's * Initialize things for ESP at module load time. * We want to be informed each time a stack is created or * destroyed in the kernel, so we can maintain the * set of ipsecesp_stack_t's. * Walk through the param array specified registering each element with the * named dispatch handler. * Initialize things for ESP for each stack instance * Destroy things for ESP at module unload time. * Destroy things for ESP for one stack instance * ESP module open routine. esp0dbg((
"Non-privileged user trying to open ipsecesp.\n"));
return (0);
/* Re-open of an already open instance. */ * ASSUMPTIONS (because I'm MT_OCEXCL): * * I'm being pushed on top of IP for all my opens (incl. #1). * * Only ipsecesp_open() can write into esp_sadb.s_ip_q. * * Because of this, I can check lazily for esp_sadb.s_ip_q. * If these assumptions are wrong, I'm in BIG trouble... /* Allocate an unbind... */ * Send down T_BIND_REQ to bind IPPROTO_ESP. * Handle the ACK here in ESP. * For now, there's not much I can do. I'll be getting a message * passed down to me from keysock (in my wput), and a T_BIND_ACK * up from IP (in my rput). * ESP module close routine. * If esp_sadb.s_ip_q is attached to this instance, send a * T_UNBIND_REQ to IP for the instance before doing * Clean up q_ptr, if needed. /* Keysock queue check is safe, because of OCEXCL perimeter. */ (
"ipsecesp_close: Ummm... keysock is closing ESP.\n"));
* If the esp_sadb.s_ip_q is attached to this instance, find * another. The OCEXCL outer perimeter helps us here. * See if we can use the pfkey_q. /* If it's NULL, I can't do much here. */ * Add a number of bytes to what the SA has protected so far. Return * B_TRUE if the SA can still protect that many bytes. * Caller must REFRELE the passed-in assoc. This function must REFRELE /* No peer? No problem! */ * Otherwise, we want to grab both the original assoc and its peer. * There might be a race for this, but if it's a real race, two * expire messages may occur. We limit this by only sending the * expire message on one of the peers, we'll pick the inbound * If we need tight synchronization on the peer SA, then we need to /* Use address length to select IPv6/IPv4 */ /* Q: Do we wish to set haspeer == B_FALSE? */ "can't find peer for inbound.\n"));
/* Q: Do we wish to set haspeer == B_FALSE? */ "can't find peer for outbound.\n"));
* Because of the multi-line macro nature of IPSA_REFRELE, keep * Do incoming NAT-T manipulations for packet. /* Initialize to our inbound cksum adjustment... */ #
define DOWN_SUM(x) (x) = ((x) &
0xFFFF) + ((x) >>
16)
/* Adujst if the inbound one was not zero. */ * This case is only an issue for self-encapsulated * packets. So for now, fall through. * Strip ESP header, check padding, and fix IP header. * Returns B_TRUE on success, B_FALSE if an error occured. * Strip ESP data and fix IP header. * XXX In case the beginning of esp_inbound() changes to not do a * pullup, this part of the code can remain unchanged. * "Next header" and padding length are the last two bytes in the * ESP-protected datagram, thus the explicit - 1 and - 2. * lastpad is the last byte of the padding, which can be used for * a quick check to see if the padding is correct. /* Fix part of the IP header. */ * Reality check the padlen. The explicit - 2 is for the * padding length and the next-header bytes. "Corrupt ESP packet (padlen too big).\n");
"hdr - ivlen(%d) = %d.\n",
* Fix the rest of the header. The explicit - 2 is for the * padding length and the next-header bytes. /* Panic a DEBUG kernel. */ /* Otherwise, pretend it's IP + ESP. */ "Corrupt ESP packet (v6 padlen too big).\n");
(
"pkt len(%u) - ip hdr - esp hdr - ivlen(%d) = " * Fix the rest of the header. The explicit - 2 is for the * padding length and the next-header bytes. IPv6 is nice, * because there's no hdr checksum! * Weak padding check: compare last-byte to length, they "Corrupt ESP packet (lastpad != padlen).\n");
(
"lastpad (%d) not equal to padlen (%d):\n",
* Strong padding check: Check all pad bytes to see that * they're ascending. Go backwards using a descending counter * to verify. padlen == 1 is checked by previous block, so * only bother if we've more than 1 byte of padding. * Consequently, start the check one byte before the location * This assert may have to become an if and a pullup * if we start accepting multi-dblk mblks. For now, * though, any packet here will have been pulled up in * Use "--lastpad" because we already checked the very * last pad byte previously. "packet (bad padding).\n");
(
"padding not in correct" /* Trim off the padding. */ * The above assertions about data_mp's size will make this work. * XXX Question: If I send up and get back a contiguous mblk, * would it be quicker to bcopy over, or keep doing the dupb stuff? * I go with copying for now. * Updating use times can be tricky business if the ipsa_haspeer flag is * set. This function is called once in an SA's lifetime. * Caller has to REFRELE "assoc" which is passed in. This function has * to REFRELE any peer SA that is obtained. /* No peer? No problem! */ * Otherwise, we want to grab both the original assoc and its peer. * There might be a race for this, but if it's a real race, the times * will be out-of-synch by at most a second, and since our time * granularity is a second, this won't be a problem. * If we need tight synchronization on the peer SA, then we need to /* Use address length to select IPv6/IPv4 */ /* Q: Do we wish to set haspeer == B_FALSE? */ "can't find peer for inbound.\n"));
/* Q: Do we wish to set haspeer == B_FALSE? */ "can't find peer for outbound.\n"));
/* Update usetime on both. */ * Because of the multi-line macro nature of IPSA_REFRELE, keep * Handle ESP inbound data for IPv4 and IPv6. * On success returns B_TRUE, on failure returns B_FALSE and frees the * mblk chain ipsec_in_mp. * We may wish to check replay in-range-only here as an optimization. * Include the reality check of ipsa->ipsa_replay > * ipsa->ipsa_replay_wsize for times when it's the first N packets, * where N == ipsa->ipsa_replay_wsize. * Another check that may come here later is the "collision" check. * If legitimate packets flow quickly enough, this won't be a problem, * but collisions may cause authentication algorithm crunching to * take place when it doesn't need to. * TODO: Extract inbound interface from the IPSEC_IN * message's ii->ipsec_in_rill_index. * Has this packet already been processed by a hardware (
"esp_inbound: pkt processed by ill=%d isv6=%d\n",
* Adjust the IP header's payload length to reflect the removal /* submit the request to the crypto framework */ * Perform the really difficult work of inserting the proposed situation. * Called while holding the algorithm lock. * Based upon algorithm properties, and what-not, prioritize * a proposal. If the IPSEC_OUT message has an algorithm specified, * use it first and foremost. * For each action in policy list * Add combination. If I've hit limit, return. * The following may be based on algorithm * properties, but in the meantime, we just pick * some good, sensible numbers. Key mgmt. can * (and perhaps should) be the place to finalize * No limits on allocations, since we really don't * support that concept currently. * These may want to come from policy rule.. break;
/* out of space.. */ * Prepare and actually send the SADB_ACQUIRE message to PF_KEY. esp0dbg((
"sadb_setup_acquire failed.\n"));
/* Insert proposal here. */ * Must mutex_exit() before sending PF_KEY message up, in * order to avoid recursive mutex_enter() if there are no registered * Once I've sent the message, I'm cool anyway. * Handle the SADB_GETSPI message. Create a larval SA. * Randomly generate a proposed SPI value * XXX - We may randomly collide. We really should recover from this. * Unfortunately, that could require spending way-too-much-time * in here. For now, let the user retry. * Check for collisions (i.e. did sadb_getspi() return with something * Try outbound first. Even though SADB_GETSPI is traditionally * for inbound SAs, you never know what a user might do. * I don't have collisions elsewhere! * sadb_insertassoc() also checks for collisions, so * if there's a colliding entry, rc will be set * Can exit outbound mutex. Hold inbound until we're done /* Can write here because I'm still holding the bucket lock. */ * Construct successful return message. We have one thing going * for us in PF_KEY v2. That's the fact that * sizeof (sadb_spirange_t) == sizeof (sadb_sa_t) /* Convert KEYSOCK_IN to KEYSOCK_OUT. */ * Can safely putnext() to esp_pfkey_q, because this is a turnaround * Insert the ESP header into a packet. Duplicate an mblk, and insert a newly * allocated mblk with the ESP header in between the two. /* "scratch" is the 2nd half, split_mp is the first. */ (
"esp_insert_esp: can't allocate scratch.\n"));
/* NOTE: dupb() doesn't set b_cont appropriately. */ * At this point, split_mp is exactly "wheretodiv" bytes long, and * holds the end of the pre-ESP part of the datagram. * Finish processing of an inbound ESP packet after processing by the * - Remove the ESP header. * - Send packet back to IP. * If authentication was performed on the packet, this function is called * only if the authentication succeeded. * On success returns B_TRUE, on failure returns B_FALSE and frees the * mblk chain ipsec_in_mp. /* get the pointer to the ESP header */ /* authentication-only ESP */ /* encryption-only ESP */ /* encryption with authentication */ /* authentication passed if we reach this point */ * Check replay window here! * For right now, assume keysock will set the replay window * size to zero for SAs that have an unspecified sender. * Log the event. As of now we print out an event. * Do not print the replay failure number, or else * syslog cannot collate the error messages. Printing * the replay number that failed opens a denial-of- "Replay failed for ESP spi 0x%x, dst %s.\n",
/* The ipsa has hit hard expiration, LOG and AUDIT. */ "ESP association 0x%x, dst %s had bytes expire.\n",
* Remove ESP header and padding from packet. I hope the compiler * spews "branch, predict taken" code for this. * TODO: Extract inbound interface from the IPSEC_IN message's * ii->ipsec_in_rill_index. * Called upon failing the inbound ICV check. The message passed as * Log the event. Don't print to the console, block * potential denial-of-service attack. "ESP Authentication failed for spi 0x%x, dst %s.\n",
* TODO: Extract inbound interface from the IPSEC_IN * message's ii->ipsec_in_rill_index. * Invoked for outbound packets after ESP processing. If the packet * also requires AH, performs the AH SA selection and AH processing. * Returns B_TRUE if the AH processing was not needed or if it was * performed successfully. Returns B_FALSE and consumes the passed mblk * if AH processing was required but could not be performed. * Kernel crypto framework callback invoked after completion of async * Verify that the netstack is still around; could have vanished * while kEf was doing its work. /* finish IPsec processing */ * If a ICV was computed, it was stored by the * crypto framework at the end of the packet. /* do AH processing if needed */ /* finish IPsec processing */ (
"esp_kcf_callback: crypto failed with 0x%x\n",
* Invoked on crypto framework failure during inbound and outbound processing. * In case kEF queues and calls back, keep netstackid_t for * verification that the IP instance is still around in * An inbound packet is of the form: * IPSEC_IN -> [IP,options,ESP,IV,data,ICV,pad] /* force asynchronous processing? */ /* authentication context template */ /* authentication starts at the ESP header */ /* authentication only */ /* initialize input data argument */ /* call the crypto framework */ /* force asynchronous processing? */ /* encryption template */ /* skip IV, since it is passed separately */ /* initialize input data argument */ /* call the crypto framework */ /* initialize input data argument */ /* esp_kcf_callback() will be invoked on completion */ * Compute the IP and UDP checksums -- common code for both keepalives and * actual ESP-in-UDP packets. Be flexible with multiple mblks because ESP * uses mblk-insertion to insert the UDP header. * TODO - If there is an easy way to prep a packet for HW checksums, make /* arr points to the IP header. */ /* arr[6-9] are the IP addresses. */ /* arr points to the UDP header's checksum field. */ * Send a one-byte UDP NAT-T keepalive. Construct an IPSEC_OUT too that'll /* Use the low-16 of the SPI so we have some clue where it came from. */ * In case kEF queues and calls back, keep netstackid_t for * verification that the IP instance is still around in * Outbound IPsec packets are of the form: * IPSEC_OUT -> [IP,options] -> [ESP,IV] -> [data] -> [pad,ICV] * unless it's NATT, then it's * IPSEC_OUT -> [IP,options] -> [udp][ESP,IV] -> [data] -> [pad,ICV] * Get a pointer to the mblk containing the ESP header. /* force asynchronous processing? */ /* authentication context template */ /* where to store the computed mac */ /* authentication starts at the ESP header */ /* authentication only */ /* initialize input data argument */ /* call the crypto framework */ /* force asynchronous processing? */ /* encryption context template */ /* encryption only, skip mblk that contains ESP hdr */ /* initialize input data argument */ /* call the crypto framework */ * Encryption and authentication: * Pass the pointer to the mblk chain starting at the ESP * header to the framework. Skip the ESP header mblk * for encryption, which is reflected by an encryption * offset equal to the length of that mblk. Start * the authentication at the ESP header, i.e. use an * authentication offset of zero. /* esp_kcf_callback() will be invoked on completion */ * Handle outbound IPsec processing for IPv4 and IPv6 * On success returns B_TRUE, on failure returns B_FALSE and frees the * mblk chain ipsec_in_mp. * <sigh> We have to copy the message here, because TCP (for example) * keeps a dupb() of the message lying around for retransmission. * Since ESP changes the whole of the datagram, we have to create our * own copy lest we clobber TCP's data. Since we have to copy anyway, * we might as well make use of msgpullup() and get the mblk into one esp0dbg((
"esp_outbound: msgpullup() failed, " * TODO: Find the outbound IRE for this packet and * pass it to ip_drop_packet(). * Destination options are tricky. If we get in here, * then we have a terminal header following the * destination options. We need to adjust backwards * so we insert ESP BEFORE the destination options * bag. (So that the dstopts get encrypted!) * Since this is for outbound packets only, we know * that non-terminal destination options only precede /* It's probably IP + ESP. */ * Set up ESP header and encryption padding for ENCR PI request. /* Determine the padding length. Pad to 4-bytes for no-encryption. */ * Include the two additional bytes (hence the - 2) for the * padding length and the next header. Take this into account * when calculating the actual length of the padding. /* Allocate ESP header and IV. */ * Update association byte-count lifetimes. Don't forget to take * into account the padding length and next-header (hence the + 2). * Use the amount of data fed into the "encryption algorithm". This * is the IV, the data length, the padding length, and the final two * bytes (padlen, and next-header). * TODO: Find the outbound IRE for this packet and * pass it to ip_drop_packet(). * TODO: Find the outbound IRE for this packet and * pass it to ip_drop_packet(). * Set the checksum to 0, so that the esp_prepare_udp() call * can do the right thing. * XXX We have replay counter wrapping. * We probably want to nuke this SA (and its peer). "Outbound ESP SA (0x%x, %s) has wrapped sequence.\n",
* TODO: Find the outbound IRE for this packet and * pass it to ip_drop_packet(). * Set the IV to a random quantity. We do not require the * highest quality random bits, but for best security with CBC * mode ciphers, the value must be unlikely to repeat and also * must not be known in advance to an adversary capable of * influencing the plaintext. /* I've got the two ESP mblks, now insert them. */ /* NOTE: esp_insert_esp() only fails if there's no memory. */ * TODO: Find the outbound IRE for this packet and * pass it to ip_drop_packet(). /* Append padding (and leave room for ICV). */ esp0dbg((
"esp_outbound: Can't allocate tailmp.\n"));
* TODO: Find the outbound IRE for this packet and * pass it to ip_drop_packet(). * If there's padding, N bytes of padding must be of the form 0x1, * The packet is eligible for hardware acceleration if the * following conditions are satisfied: * 1. the packet will not be fragmented * 2. the provider supports the algorithms specified by SA * 3. there is no pending control message being exchanged * 4. snoop is not attached * 5. the destination address is not a multicast address * All five of these conditions are checked by IP prior to * sending the packet to ESP. * But We, and We Alone, can, nay MUST check if the packet * is over NATT, and then disqualify it from hardware * Okay. I've set up the pre-encryption ESP. Let's do it! * IP calls this to validate the ICMP errors that * we got from the network. * Unless we get an entire packet back, this function is useless. * 1.) Partial packets are useless, because the "next header" * is at the end of the decrypted ESP packet. Without the * whole packet, this is useless. * 2.) If we every use a stateful cipher, such as a stream or a * one-time pad, we can't do anything. * Since the chances of us getting an entire packet back are very * very small, we discard here. * ESP module read put routine. /* TPI message of some sort. */ (
"Thank you IP from ESP for T_BIND_ACK\n"));
"ipsecesp: ESP received T_ERROR_ACK from IP.");
* future, perhaps try again. /* Probably from a (rarely sent) T_UNBIND_REQ. */ esp0dbg((
"Unknown M_{,PC}PROTO message.\n"));
/* For now, passthru message. */ * Construct an SADB_REGISTER message with the current algorithms. /* Allocate the KEYSOCK_OUT. */ esp0dbg((
"esp_register_out: couldn't allocate mblk.\n"));
* Allocate the PF_KEY message that follows KEYSOCK_OUT. * Fill SADB_REGISTER message's algorithm descriptors. Hold * down the lock while filling it. * Return only valid algorithms, so the number of algorithms * to send up may be less than the number of algorithm entries * Reality check to make sure I snagged all of the "Missed aalg #%d.\n", i);
* Reality check to make sure I snagged all of the "Missed ealg #%d.\n", i);
/* Now fill the rest of the SADB_REGISTER message. */ * Assume caller has sufficient sequence/pid number info. If it's one * from me over a new alg., I could give two hoots about sequence. * Invoked when the algorithm table changes. Causes SADB_REGISTER * messages continaining the current list of algorithms to be * sent up to the ESP listeners. * Time to send a PF_KEY SADB_REGISTER message to ESP listeners * everywhere. (The function itself checks for NULL esp_pfkey_q.) * taskq_dispatch handler. * Now that weak-key passed, actually ADD the security association, and * send back a reply ADD message. * Locate the appropriate table(s). clone =
B_TRUE;
/* All mcast SAs can be bidirectional */ * If the source address is either one of mine, or unspecified * (which is best summed up by saying "not 'not mine'"), * then the association is potentially bi-directional, * in that it can be used for inbound traffic and outbound * traffic. The best example of such an SA is a multicast * SA (which allows me to receive the outbound traffic). * If the source address literally not mine (either * unspecified or not mine), then this SA may have an * address that WILL be mine after some configuration. * We pay the price for this by making it a bi-directional * Find a ACQUIRE list entry if possible. If we've added an SA that * suits the needs of an ACQUIRE list entry, we can eliminate the * ACQUIRE list entry and transmit the enqueued packets. Use the * high-bit of the sequence number to queue it. Key off destination * addr, and change acqrec's state. * Q: I only check sequence. Should I check dst? * A: Yes, check dest because those are the packets * AHA! I found an ACQUIRE record for this SA. * Grab the msg list, and free the acquire record. * I already am holding the lock for this record, * so all I have to do is free it. * Find PF_KEY message, and see if I'm an update. If so, find entry * in larval list (if there). esp0dbg((
"Larval update, but larval disappeared.\n"));
}
/* Else sadb_common_add unlinks it for me! */ * How much more stack will I create with all of these /* do AH processing if needed */ /* finish IPsec processing */ * Add new ESP security association. This may become a generic AH/ESP /* I need certain extensions present for an ADD message. */ /* Sundry ADD-specific reality checks. */ /* Stuff I don't support, for now. XXX Diagnostic? */ * XXX Policy : I'm not checking identities or sensitivity * labels at this time, but if I did, I'd do them here, before I sent * the weak key check up to the algorithm. * First locate the authentication algorithm. * Sanity check key sizes. * Note: It's not possible to use SADB_AALG_NONE because * this auth_alg is not defined with ALG_FLAG_VALID. If this * ever changes, the same check for SADB_AALG_NONE and * a auth_key != NULL should be made here ( see below). /* check key and fix parity if needed */ * Then locate the encryption algorithm. * Sanity check key sizes. If the encryption algorithm is * SADB_EALG_NULL but the encryption key is NOT * Update a security association. Updates come in two varieties. The first * is an update of lifetimes on a non-larval SA. The second is an update of * a larval SA, which ends up looking a lot more like an add. * Delete a security association. This is REALLY likely to be code common to * both AH and ESP. Find the association, then unlink it. * Convert the entire contents of all of ESP's SA tables into PF_KEY SADB_DUMP * Dump each fanout, bailing if error is non-zero. * First-cut reality check for an inbound PF_KEY message. return (
B_FALSE);
/* False ==> no failures */ return (
B_TRUE);
/* True ==> failures */ * ESP parsing of PF_KEY messages. Keysock did most of the really silly * error cases. What I receive is a fully-formed, syntactically legal * PF_KEY message. I then need to check semantics... * This code may become common to AH and ESP. Stay tuned. * I also make the assumption that db_ref's are cool. If this assumption * is wrong, this means that someone other than keysock or me has been * mucking with PF_KEY messages. * If applicable, convert unspecified AF_INET6 to unspecified * AF_INET. And do other address reality checks. /* else esp_add_sa() took care of things. */ /* Else esp_del_sa() took care of things. */ /* Else sadb_get_sa() took care of things. */ * Hmmm, let's do it! Check for extensions (there should * be none), extract the fields, call esp_register_out(), * then either free or report an error. * Keysock takes care of the PF_KEY bookkeeping for this. * Only way this path hits is if there is a memory * failure. It will not return B_FALSE because of * lack of esp_pfkey_q if I am in wput(). * Find a larval, if not there, find a full one and get /* else esp_update_sa() took care of things. */ * Reserve a new larval entry. * Find larval and/or ACQUIRE record and kill it (them), I'm * most likely an error. Inbound ACQUIRE messages should only /* esp_dump will take care of the return message, etc. */ /* Should never reach me. */ * Handle case where PF_KEY says it can't find a keysock for one of my * If keysock can't find any registered, delete the acquire record * immediately, and handle errors. * Use the write-side of the esp_pfkey_q, in case there is * ESP module write put routine. /* NOTE: Each case must take care of freeing or passing mp. */ /* Not big enough message. */ /* We really don't support any other ioctls, do we? */ (
"Got default message, type %d, passing to IP.\n",
* Process an outbound ESP packet that can be accelerated by a IPsec * hardware acceleration capable Provider. * The caller already inserted and initialized the ESP header. * This function allocates a tagging M_CTL, and adds room at the end * of the packet to hold the ICV if authentication is needed. * On success returns B_TRUE, on failure returns B_FALSE and frees the /* mark packet as being accelerated in IPSEC_OUT */ * add room at the end of the packet for the ICV if needed /* if not enough available room, allocate new mblk */ * Process an inbound accelerated ESP packet. * On success returns B_TRUE, on failure returns B_FALSE and frees the * We only support one level of decapsulation in hardware, so * ESP with authentication. We expect the Provider to have * computed the ICV and placed it in the hardware acceleration * Extract ICV length from attributes M_CTL and sanity check * its value. We allow the mblk to be smaller than da_ipsec_t * for a small ICV, as long as the entire ICV fits within the * Also ensures that the ICV length computed by Provider * corresponds to the ICV length of the agorithm specified by esp0dbg((
"esp_inbound_accelerated: " "ICV len (%u) incorrect or mblk too small (%u)\n",
/* get pointers to IP header */ * Compare ICV in ESP packet vs ICV computed by adapter. * We also remove the ICV from the end of the packet since * it will no longer be needed. * Assume that esp_inbound() already ensured that the pkt * Log the event. Don't print to the console, block * potential denial-of-service attack. "ESP Authentication failed spi %x, dst_addr %s",
"succeeded, checking replay\n"));
* Remove ESP header and padding from packet. "esp_strip_header() failed\n"));
/* The ipsa has hit hard expiration, LOG and AUDIT. */ "ESP association 0x%x, dst %s had bytes expire.\n",
/* done processing the packet */ * Wrapper to allow IP to trigger an ESP association failure message * during inbound SA selection. * Initialize the ESP input and output processing functions.