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