1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _INET_KSSL_KSSLIMPL_H 27 #define _INET_KSSL_KSSLIMPL_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #include <sys/types.h> 34 #include <netinet/in.h> 35 #include <sys/socket.h> 36 #include <sys/atomic.h> 37 #include <sys/mutex.h> 38 #include <sys/crypto/common.h> 39 #include <sys/kstat.h> 40 #include <sys/sdt.h> 41 #include <inet/kssl/ksslapi.h> 42 #include <inet/kssl/ksslproto.h> 43 44 /* 45 * Certificate structure. The msg field is the BER data of the 46 * certificate. 47 */ 48 typedef struct Certificate { 49 uchar_t *msg; 50 int len; 51 } Certificate_t; 52 53 /* Generic linked chain type */ 54 typedef struct kssl_chain_s { 55 struct kssl_chain_s *next; 56 void *item; 57 } kssl_chain_t; 58 59 /* Proxies chain. follows the generic kssl_chain_t layout */ 60 typedef struct kssl_proxy_s { 61 struct kssl_proxy_s *next; 62 void *proxy_bound; 63 } kssl_proxy_t; 64 65 /* Fallback endpoints chain. Ditto. */ 66 typedef struct kssl_fallback_s { 67 struct kssl_fallback_s *next; 68 void *fallback_bound; 69 } kssl_fallback_t; 70 71 /* 72 * Structure to support using a non-extractable key in 73 * a crypto provider. We keep the token label and pin so 74 * that we can reauthenticate when needed. 75 */ 76 typedef struct kssl_session_info_s { 77 boolean_t is_valid_handle; 78 boolean_t do_reauth; 79 crypto_provider_t prov; 80 crypto_session_id_t sid; 81 crypto_key_t key; 82 crypto_notify_handle_t evnt_handle; 83 char toklabel[CRYPTO_EXT_SIZE_LABEL]; 84 int pinlen; 85 char tokpin[1]; 86 } kssl_session_info_t; 87 88 /* kssl_entry_t structure. */ 89 90 typedef struct kssl_entry_s { 91 uint_t ke_refcnt; /* for hold/release */ 92 boolean_t ke_no_freeall; 93 kmutex_t ke_mutex; 94 95 in6_addr_t ke_laddr; 96 in_port_t ke_ssl_port; /* SSL port */ 97 in_port_t ke_proxy_port; /* SSL proxy port */ 98 99 uint32_t sid_cache_timeout; /* In seconds */ 100 uint32_t sid_cache_nentries; 101 kssl_sid_ent_t *sid_cache; 102 103 uint16_t kssl_cipherSuites[CIPHER_SUITE_COUNT]; 104 int kssl_cipherSuites_nentries; 105 uint16_t kssl_saved_Suites[CIPHER_SUITE_COUNT]; 106 107 boolean_t ke_is_nxkey; 108 kssl_session_info_t *ke_sessinfo; 109 110 crypto_key_t *ke_private_key; /* instance's private key */ 111 Certificate_t *ke_server_certificate; 112 113 Certificate_t **ke_cacert_chain; 114 115 kssl_proxy_t *ke_proxy_head; /* Proxies chain */ 116 kssl_fallback_t *ke_fallback_head; /* Fall-back endpoints chain */ 117 118 } kssl_entry_t; 119 120 typedef struct mech_to_cipher_s { 121 crypto_mech_type_t mech; 122 char *name; 123 uint16_t kssl_suites[CIPHER_SUITE_COUNT]; 124 } mech_to_cipher_t; 125 126 #define KSSL_ENTRY_REFHOLD(kssl_entry) { \ 127 atomic_add_32(&(kssl_entry)->ke_refcnt, 1); \ 128 ASSERT((kssl_entry)->ke_refcnt != 0); \ 129 } 130 131 #define KSSL_ENTRY_REFRELE(kssl_entry) { \ 132 ASSERT((kssl_entry)->ke_refcnt != 0); \ 133 membar_exit(); \ 134 if (atomic_add_32_nv(&(kssl_entry)->ke_refcnt, -1) == 0) { \ 135 kssl_free_entry((kssl_entry)); \ 136 } \ 137 } 138 139 #define KSSL_SSL_REFHOLD(ssl) { \ 140 atomic_add_32(&(ssl)->kssl_refcnt, 1); \ 141 ASSERT((ssl)->kssl_refcnt != 0); \ 142 ASSERT((ssl)->kssl_refcnt < 100000); \ 143 } 144 145 #define KSSL_SSL_REFRELE(ssl) { \ 146 ASSERT((ssl)->kssl_refcnt != 0); \ 147 ASSERT((ssl)->kssl_refcnt < 100000); \ 148 membar_exit(); \ 149 if (atomic_add_32_nv(&(ssl)->kssl_refcnt, -1) == 0) { \ 150 kssl_free_context((ssl)); \ 151 } \ 152 } 153 154 #define CRYPTO_ERR(r) ((r) != CRYPTO_SUCCESS && (r) != CRYPTO_QUEUED) 155 156 /* 157 * Enqueue mblk into KSSL input queue. Watch for mblk b_cont chains 158 * returned by tcp_reass() and enqueue them properly. Caller should 159 * be aware that mp is modified by this macro. 160 */ 161 #define KSSL_ENQUEUE_MP(ssl, mp) { \ 162 DTRACE_PROBE1(kssl_mblk__enqueue_mp, mblk_t *, mp); \ 163 if ((ssl)->rec_ass_tail == NULL) { \ 164 (ssl)->rec_ass_head = (mp); \ 165 while (mp->b_cont) \ 166 mp = mp->b_cont; \ 167 (ssl)->rec_ass_tail = (mp); \ 168 } else { \ 169 (ssl)->rec_ass_tail->b_cont = (mp); \ 170 while (mp->b_cont) \ 171 mp = mp->b_cont; \ 172 (ssl)->rec_ass_tail = (mp); \ 173 } \ 174 } 175 176 #define SSL_MISS 123 /* Internal SSL error */ 177 178 extern crypto_mechanism_t rsa_x509_mech; 179 extern crypto_mechanism_t hmac_md5_mech; 180 extern crypto_mechanism_t hmac_sha1_mech; 181 extern crypto_call_flag_t kssl_call_flag; 182 extern KSSLCipherDef cipher_defs[]; 183 184 extern int kssl_cache_count; 185 extern struct kmem_cache *kssl_cache; 186 187 #define KSSL_TAB_INITSIZE 4 188 extern kssl_entry_t **kssl_entry_tab; 189 extern int kssl_entry_tab_size; 190 extern int kssl_entry_tab_nentries; 191 extern kmutex_t kssl_tab_mutex; 192 193 typedef struct kssl_stats { 194 kstat_named_t sid_cache_lookups; 195 kstat_named_t sid_cache_hits; 196 kstat_named_t sid_cached; 197 kstat_named_t sid_uncached; 198 kstat_named_t full_handshakes; 199 kstat_named_t resumed_sessions; 200 kstat_named_t fallback_connections; 201 kstat_named_t proxy_fallback_failed; 202 kstat_named_t appdata_record_ins; 203 kstat_named_t appdata_record_outs; 204 kstat_named_t alloc_fails; 205 kstat_named_t fatal_alerts; 206 kstat_named_t warning_alerts; 207 kstat_named_t no_suite_found; 208 kstat_named_t compute_mac_failure; 209 kstat_named_t verify_mac_failure; 210 kstat_named_t record_decrypt_failure; 211 kstat_named_t bad_pre_master_secret; 212 kstat_named_t internal_errors; 213 } kssl_stats_t; 214 215 extern kssl_stats_t *kssl_statp; 216 217 #define KSSL_COUNTER(p, v) atomic_add_64(&kssl_statp->p.value.ui64, v) 218 219 #define IS_SSL_PORT 1 220 #define IS_PROXY_PORT 2 221 222 extern void kssl_free_entry(kssl_entry_t *); 223 extern void kssl_free_context(ssl_t *); 224 extern int kssl_compute_record_mac(ssl_t *, int, uint64_t, SSL3ContentType, 225 uchar_t *, uchar_t *, int, uchar_t *); 226 extern int kssl_handle_handshake_message(ssl_t *, mblk_t *, int *, 227 kssl_callback_t, void *); 228 extern int kssl_handle_v2client_hello(ssl_t *, mblk_t *, int); 229 extern void kssl_uncache_sid(sslSessionID *, kssl_entry_t *); 230 extern int kssl_mac_encrypt_record(ssl_t *, SSL3ContentType, uchar_t *, 231 uchar_t *, mblk_t *); 232 extern mblk_t *kssl_get_next_record(ssl_t *); 233 extern int kssl_get_obj_handle(kssl_entry_t *); 234 extern void kssl_prov_evnt(uint32_t, void *); 235 236 #ifdef __cplusplus 237 } 238 #endif 239 240 #endif /* _INET_KSSL_KSSLIMPL_H */ 241