sadb.h revision 1a5e258f5471356ca102c7176637cdce45bac147
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _INET_SADB_H
#define _INET_SADB_H
#ifdef __cplusplus
extern "C" {
#endif
#include <inet/ipsec_info.h>
#define MAXSALTSIZE 8
/*
* For combined mode ciphers, store the crypto_mechanism_t in the
* per-packet ipsec_in_t/ipsec_out_t structures. This is because the PARAMS
* and nonce values change for each packet. For non-combined mode
* ciphers, these values are constant for the life of the SA.
*/
typedef struct ipsa_cm_mech_s {
union {
} paramu;
/*
* The Initialization Vector (also known as IV or Nonce) used to
* initialize the Block Cipher, is made up of a Counter and a Salt.
* The Counter is fixed at 64 bits and is incremented for each packet.
* The Salt value can be any whole byte value upto 64 bits. This is
* algorithm mode specific and can be configured with ipsecalgs(1m).
*
* We only support whole byte salt lengths, this is because the salt is
* stored in an array of uint8_t's. This is enforced by ipsecalgs(1m)
* which configures the salt length as a number of bytes. Checks are
* made to ensure the salt length defined in ipsecalgs(1m) fits in
* the ipsec_nonce_t.
*
* The Salt value remains constant for the life of the SA, the Salt is
* know to both peers, but NOT transmitted on the network. The Counter
* portion of the nonce is transmitted over the network with each packet
* and is confusingly described as the Initialization Vector by RFCs
* 4309/4106.
*
* The maximum Initialization Vector length is 128 bits, if the actual
* size is less, its padded internally by the algorithm.
*
* The nonce structure is defined like this in the SA (ipsa_t)to ensure
* the Initilization Vector (counter) is 64 bit aligned, because it will
* be incremented as an uint64_t. The nonce as used by the algorithms is
* a straight uint8_t array.
*
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | | | | |x|x|x|x| |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* salt_offset <------>
* ipsa_saltlen <------->
* ipsa_nonce_buf------^
* ipsa_salt-------------~~~~~~^
* ipsa_nonce------------~~~~~~^
* ipsa_iv-----------------------------^
*/
typedef struct ipsec_nonce_s {
/*
* IP security association. Synchronization assumes 32-bit loads, so
* the 64-bit quantities can't even be be read w/o locking it down!
*/
/* keying info */
typedef struct ipsa_key_s {
} ipsa_key_t;
typedef struct ipsa_s {
/*
* NOTE: I may need more pointers, depending on future SA
* requirements.
*/
#define SADB_MAX_IDLEPKTS 100
/*
* PF_KEYv2 supports a replay window size of 255. Hence there is a
* need a bit vector to support a replay window of 255. 256 is a nice
* round number, so I support that.
*
* Use an array of uint64_t for best performance on 64-bit
* processors. (And hope that 32-bit compilers can handle things
* okay.) The " >> 6 " is to get the appropriate number of 64-bit
* ints.
*/
/*
* Reference count semantics:
*
* An SA has a reference count of 1 if something's pointing
* to it. This includes being in a hash table. So if an
* SA is in a hash table, it has a reference count of at least 1.
*
* When a ptr. to an IPSA is assigned, you MUST REFHOLD after
* said assignment. When a ptr. to an IPSA is released
* you MUST REFRELE. When the refcount hits 0, REFRELE
* will free the IPSA.
*/
/* Q: Since I may be doing refcnts differently, will I need cv? */
/*
* The following four time fields are the ones monitored by ah_ager()
* and esp_ager() respectively. They are all absolute wall-clock
* times. The times of creation (i.e. add time) and first use are
* pretty straightforward. The soft and hard expire times are
* derived from the times of first use and creation, plus the minimum
* expiration times in the fields that follow this.
*
* For example, if I had a hard add time of 30 seconds, and a hard
* use time of 15, the ipsa_hardexpiretime would be time of add, plus
* 30 seconds. If I USE the SA such that time of first use plus 15
* seconds would be earlier than the add time plus 30 seconds, then
* ipsa_hardexpiretime would become this earlier time.
*/
struct ipsec_nonce_s *ipsa_nonce_buf;
/*
* The following fields are directly reflected in PF_KEYv2 LIFETIME
* extensions. The time_ts are in number-of-seconds, and the bytes
* are in... bytes.
*/
/*
* "Allocations" are a concept mentioned in PF_KEYv2. We do not
* support them, except to record them per the PF_KEYv2 spec.
*/
/*
* Address storage.
* The source address can be INADDR_ANY, IN6ADDR_ANY, etc.
*
* used sockaddr_storage
*/
/* these can only be v4 */
/*
* icmp type and code. *_end are to specify ranges. if only
* a single value, * and *_end are the same value.
*/
/*
* For the kernel crypto framework.
*/
/*
* Input and output processing functions called from IP.
* The mblk_t is the data; the IPsec information is in the attributes
* Returns NULL if the mblk is consumed which it is if there was
* a failure or if pending. If failure then
* the ipIfInDiscards/OutDiscards counters are increased.
*/
/*
* Soft reference to paired SA
*/
} ipsa_t;
/*
* ipsa_t address handling macros. We want these to be inlined, and deal
*
* Assume we only have AF_INET and AF_INET6 addresses for now. Also assume
* that we have 32-bit alignment on everything.
*/
/*
*
* If you have a pointer, you REFHOLD. If you are releasing a pointer, you
* REFRELE. An ipsa_t that is newly inserted into the table should have
* a reference count of 1 (for the table's pointer), plus 1 more for every
* pointer that is referencing the ipsa_t.
*/
#define IPSA_REFHOLD(ipsa) { \
}
/*
* Decrement the reference count on the SA.
* In architectures e.g sun4u, where atomic_add_32_nv is just
* a cas, we need to maintain the right memory barrier semantics
* as that of mutex_exit i.e all the loads and stores should complete
* before the cas is executed. membar_exit() does that here.
*/
#define IPSA_REFRELE(ipsa) { \
membar_exit(); \
}
/*
* Security association hash macros and definitions. For now, assume the
* IPsec model, and hash outbounds on destination address, and inbounds on
* SPI.
*/
#define IPSEC_DEFAULT_HASH_SIZE 256
/*
* Syntactic sugar to find the appropriate hash bucket directly.
*/
/* backward compat. */
#define IPSA_F_TUNNEL SADB_X_SAFLAGS_TUNNEL
/*
* These flags are only defined here to prevent a flag value collision.
*/
/*
* Sets of flags that are allowed to by set or modified by PF_KEY apps.
*/
#define AH_UPDATE_SETTABLE_FLAGS \
/* AH can't set NAT flags (or even use NAT). Add NAT flags to the ESP set. */
#define AH_ADD_SETTABLE_FLAGS \
/* AH can't set NAT flags (or even use NAT). Add NAT flags to the ESP set. */
/* SA states are important for handling UPDATE PF_KEY messages. */
#define IPSA_STATE_LARVAL SADB_SASTATE_LARVAL
#define IPSA_STATE_MATURE SADB_SASTATE_MATURE
#define IPSA_STATE_DYING SADB_SASTATE_DYING
#define IPSA_STATE_DEAD SADB_SASTATE_DEAD
#define IPSA_STATE_IDLE SADB_X_SASTATE_IDLE
/*
* NOTE: If the document authors do things right in defining algorithms, we'll
* etc.
*/
#define IPSA_EALG_DES_CBC SADB_EALG_DESCBC
#define IPSA_EALG_3DES SADB_EALG_3DESCBC
/*
* Protect each ipsa_t bucket (and linkage) with a lock.
*/
typedef struct isaf_s {
} isaf_t;
/*
* traffic, it sends up an SADB_ACQUIRE message and create an ACQUIRE record.
*/
/* waiting for an ACQUIRE to finish. */
typedef struct ipsacq_s {
struct ipsacq_s *ipsacq_next;
struct ipsacq_s **ipsacq_ptpn;
struct ipsec_policy_s *ipsacq_policy;
struct ipsec_action_s *ipsacq_act;
int ipsacq_numpackets; /* How many packets queued up so far. */
/* These two point inside the last mblk inserted. */
/* Cache these instead of point so we can mask off accordingly */
/* These may change per-acquire. */
/* icmp type and code of triggering packet (if applicable) */
/* label associated with triggering packet */
} ipsacq_t;
/*
* Kernel-generated sequence numbers will be no less than 0x80000000 to
* forestall any cretinous problems with manual keying accidentally updating
* an ACQUIRE entry.
*/
#define IACQF_LOWEST_SEQ 0x80000000
#define SADB_AGE_INTERVAL_DEFAULT 8000
/*
* ACQUIRE fanout. Protect each linkage with a lock.
*/
typedef struct iacqf_s {
} iacqf_t;
/*
* A (network protocol, ipsec protocol) specific SADB.
* (i.e., one each for {ah, esp} and {v4, v6}.
*
* Keep outbound assocs in a simple hash table for now.
* One danger point, multiple SAs for a single dest will clog a bucket.
* For the future, consider two-level hashing (2nd hash on IPC?), then probe.
*/
typedef struct sadb_s
{
int sdb_hashsize;
} sadb_t;
/*
* A pair of SADB's (one for v4, one for v6), and related state (including
* acquire callbacks).
*/
typedef struct sadbp_s
{
} sadbp_t;
/*
* A pair of SA's for a single connection, the structure contains a
* pointer to a SA and the SA its paired with (opposite direction) as well
* as the SA's respective hash buckets.
*/
typedef struct ipsap_s
{
} ipsap_t;
typedef struct templist_s
{
struct templist_s *next;
} templist_t;
/* Pointer to an all-zeroes IPv6 address. */
/*
* Form unique id from ip_xmit_attr_t.
*/
#define SA_FORM_UNIQUE_ID(ixa) \
IPPROTO_IPV6 : IPPROTO_ENCAP) : \
(ixa)->ixa_ipsec_proto), \
(ixa)->ixa_ipsec_proto : 0))
/*
* This macro is used to generate unique ids (along with the addresses, both
* inner and outer) for outbound datagrams that require unique SAs.
*
* N.B. casts and unsigned shift amounts discourage unwarranted
* sign extension of dstport, proto, and iproto.
*
* Unique ID is 64-bits allocated as follows (pardon my big-endian bias):
*
* 6 4 43 33 11
* 3 7 09 21 65 0
* +---------------*-------+-------+--------------+---------------+
* | MUST-BE-ZERO |<iprot>|<proto>| <src port> | <dest port> |
* +---------------*-------+-------+--------------+---------------+
*
* If there are inner addresses (tunnel mode) the ports come from the
* inner addresses. If there are no inner addresses, the ports come from
* the outer addresses (transport mode). Tunnel mode MUST have <proto>
* set to either IPPROTO_ENCAP or IPPPROTO_IPV6.
*/
/*
* SA_UNIQUE_MASK generates a mask value to use when comparing the unique value
* from a packet to an SA.
*/
(dstport != 0) ? 0xffff : 0, \
(proto != 0) ? 0xff : 0, \
(iproto != 0) ? 0xff : 0)
/*
* Decompose unique id back into its original fields.
*/
typedef struct ipsa_query_s ipsa_query_t;
#define IPSA_NMATCH 10
/*
* SADB query structure.
*
* Provide a generalized mechanism for matching entries in the SADB;
* one of these structures is initialized using sadb_form_query(),
* and then can be used as a parameter to sadb_match_query() which returns
* B_TRUE if the SA matches the query.
*
* Under the covers, sadb_form_query populates the matchers[] array with
* functions which are called one at a time until one fails to match.
*/
struct ipsa_query_s {
struct sockaddr_in *src;
struct sockaddr_in6 *src6;
struct sockaddr_in *dst;
struct sockaddr_in6 *dst6;
};
#define IPSA_Q_SA 0x00000001
#define IPSA_Q_DST 0x00000002
#define IPSA_Q_SRC 0x00000004
#define IPSA_Q_DSTID 0x00000008
#define IPSA_Q_SRCID 0x00000010
#define IPSA_Q_KMC 0x00000020
/*
* All functions that return an ipsa_t will return it with IPSA_REFHOLD()
* already called.
*/
/* SA retrieval (inbound and outbound) */
/* SA insertion. */
/* SA table construction and destruction. */
/* SA insertion and deletion. */
void sadb_unlinkassoc(ipsa_t *);
/* Support routines to interface a keysock consumer to PF_KEY. */
int sadb_labelchk(struct keysock_in_s *);
ipsa_t *);
void *, timeout_id_t *, int);
int sadb_addrset(ire_t *);
uint8_t);
netstack_t *, sadbp_t *);
void sadb_set_usetime(ipsa_t *);
netstack_t *, uint8_t);
crypto_data_t *);
crypto_data_t *);
crypto_data_t *);
struct ipsec_stack;
void sadb_replay_delete(ipsa_t *);
void sadb_sa_refrele(void *target);
void sadb_clear_buf_pkt(void *ipkt);
/* Note that buf_pkt is the product of ip_recv_attr_to_mblk() */
{ \
(void *) buf_pkt, TQ_NOSLEEP) == 0) { \
/* Dispatch was unsuccessful drop the packets. */ \
&dropper); \
} \
} \
} \
} \
/*
* Two IPsec rate-limiting routines.
*/
/*PRINTFLIKE6*/
extern void ipsec_rl_strlog(netstack_t *, short, short, char,
ushort_t, char *, ...)
__KPRINTFLIKE(6);
void *, int, netstack_t *);
/*
* Algorithm types.
*/
#define IPSEC_NALGTYPES 2
typedef enum ipsec_algtype {
IPSEC_ALG_AUTH = 0,
IPSEC_ALG_ENCR = 1,
IPSEC_ALG_ALL = 2
/*
*/
#define IPSEC_MAX_ALGS 256
#define PROTO_IPSEC_AH 2
#define PROTO_IPSEC_ESP 3
/*
* Common algorithm info.
*/
typedef struct ipsec_alginfo
{
/*
* increment: number of bits from keysize to keysize
* default: # of increments from min to default key len
*/
/*
* Min, max, and default key sizes effectively supported
* by the encryption framework.
*/
#define alg_datalen alg_block_sizes[0]
/*
* Software crypto execution mode.
*/
typedef enum {
IPSEC_ALGS_EXEC_SYNC = 0,
netstack_t *ns);
extern void alg_flag_check(ipsec_alginfo_t *);
extern void ipsec_alg_free(ipsec_alginfo_t *);
extern void ipsec_register_prov_update(void);
extern int sadb_sens_len_from_label(ts_label_t *);
/*
* Context templates management.
*/
ipsec_stack_t *ipss; \
\
} \
} \
}
/* key checking */
typedef struct ipsec_kstats_s {
/*
* (ipss)->ipsec_kstats is equal to (ipss)->ipsec_ksp->ks_data if
* kstat_create_netstack for (ipss)->ipsec_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
* IP_ESP_BUMP_STAT, IP_AH_BUMP_STAT and IP_ACQUIRE_STAT
*/
#define IP_ESP_BUMP_STAT(ipss, x) \
do { \
} while (0)
#define IP_AH_BUMP_STAT(ipss, x) \
do { \
} while (0)
do { \
} while (0)
#ifdef __cplusplus
}
#endif
#endif /* _INET_SADB_H */