/* * 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 * or http://www.opensolaris.org/os/licensing. * 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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _INET_KSSL_KSSLPROTO_H #define _INET_KSSL_KSSLPROTO_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include /* Cipher suite definitions */ #include #include #define SSL3_RANDOM_LENGTH 32 #define SSL3_SESSIONID_BYTES 32 #define SSL3_HDR_LEN 5 #define SSL3_MAX_RECORD_LENGTH 16384 #define SSL3_PRE_MASTER_SECRET_LEN 48 #define SSL3_MASTER_SECRET_LEN 48 #define SSL3_MD5_PAD_LEN 48 #define SSL3_SHA1_PAD_LEN 40 #define SSL_MIN_CHALLENGE_BYTES 16 #define SSL_MAX_CHALLENGE_BYTES 32 #define SHA1_HASH_LEN 20 #define MD5_HASH_LEN 16 #define MAX_HASH_LEN SHA1_HASH_LEN #define KSSL_READ 0 #define KSSL_WRITE 1 #define KSSL_ENCRYPT 0 #define KSSL_DECRYPT 1 #define MSG_INIT 0 #define MSG_INIT_LEN 1 #define MSG_BODY 2 /* * More than enough for the cipher suite that needs the * largest key material (AES_256_CBC_SHA needs 136 bytes). */ #define MAX_KEYBLOCK_LENGTH 160 #define TLS_MASTER_SECRET_LABEL "master secret" #define TLS_CLIENT_WRITE_KEY_LABEL "client write key" #define TLS_SERVER_WRITE_KEY_LABEL "server write key" #define TLS_CLIENT_FINISHED_LABEL "client finished" #define TLS_SERVER_FINISHED_LABEL "server finished" #define TLS_KEY_EXPANSION_LABEL "key expansion" #define TLS_IV_BLOCK_LABEL "IV block" #define TLS_MAX_LABEL_SIZE 24 #define TLS_FINISHED_SIZE 12 /* * The following constants try to insure an input buffer is optimally aligned * for MAC hash computation. SHA1/MD5 code prefers 4 byte alignment of each * 64byte input block to avoid a copy. Our goal is to reach 4 byte alignment * starting form the 3rd MAC block (input buffer starts in the 3rd block). The * 3rd block includes the first 53 (MD5 SSL3 MAC) or 57 (SHA1 SSL3 MAC) bytes * of the input buffer. This means input buffer should start at offset 3 * within a 4 byte word so that its next block is 4 byte aligned. Since the * SSL3 record header is 5 bytes long it should start at at offset 2 within a * 4 byte word. To insure the next record (for buffers that don't fit into 1 * SSL3 record) also starts at offset 2 within a 4 byte word the previous * record length should be 3 mod 8 since 5 + 3 mod 8 is 0 i.e. the next record * starts at the same offset within a 4 byte word as the the previous record. */ #define SSL3_MAX_OPTIMAL_RECORD_LENGTH (SSL3_MAX_RECORD_LENGTH - 1) #define SSL3_OPTIMAL_RECORD_ALIGNMENT 2 /* session state */ typedef struct sslSessionIDStr { uchar_t session_id[SSL3_SESSIONID_BYTES]; uchar_t master_secret[SSL3_MASTER_SECRET_LEN]; clock_t time; in6_addr_t client_addr; boolean_t cached; uint16_t cipher_suite; } sslSessionID; /* An element of the session cache */ typedef struct kssl_sid_ent { kmutex_t se_lock; uint64_t se_used; /* Counter to check hash distribution */ sslSessionID se_sid; } kssl_sid_ent_t; typedef enum { content_change_cipher_spec = 20, content_alert = 21, content_handshake = 22, content_application_data = 23, content_handshake_v2 = 128 } SSL3ContentType; typedef enum { hello_request = 0, client_hello = 1, server_hello = 2, certificate = 11, server_key_exchange = 12, certificate_request = 13, server_hello_done = 14, certificate_verify = 15, client_key_exchange = 16, finished = 20 } SSL3HandshakeType; typedef struct SSL3HandshakeMsgStr { int state; SSL3HandshakeType type; int msglen; int msglen_bytes; mblk_t *head; mblk_t *tail; } SSL3HandshakeMsg; typedef struct KSSLJOBStr { struct ssl_s *ssl; crypto_req_id_t kjob; char *buf; size_t buflen; int status; } KSSLJOB; typedef struct { uchar_t md5[MD5_HASH_LEN]; uchar_t sha1[SHA1_HASH_LEN]; uchar_t tlshash[TLS_FINISHED_SIZE]; } SSL3Hashes; typedef enum { close_notify = 0, unexpected_message = 10, bad_record_mac = 20, decompression_failure = 30, handshake_failure = 40, no_certificate = 41, bad_certificate = 42, unsupported_certificate = 43, certificate_revoked = 44, certificate_expired = 45, certificate_unknown = 46, illegal_parameter = 47, unknown_ca = 48, access_denied = 49, decode_error = 50, decrypt_error = 51, export_restriction = 60, protocol_version = 70, insufficient_security = 71, internal_error = 80, user_canceled = 90, no_renegotiation = 100 } SSL3AlertDescription; typedef enum { alert_warning = 1, alert_fatal = 2 } SSL3AlertLevel; typedef enum { wait_client_hello = 0, wait_client_key = 1, wait_client_key_done = 2, wait_change_cipher = 3, wait_finished = 4, idle_handshake = 5 } SSL3WaitState; typedef enum { sender_client = 0x434c4e54, sender_server = 0x53525652 } SSL3Sender; typedef enum { mac_md5 = 0, mac_sha = 1 } SSL3MACAlgorithm; /* The SSL bulk cipher definition */ typedef enum { cipher_null = 0, cipher_rc4 = 1, cipher_des = 2, cipher_3des = 3, cipher_aes128 = 4, cipher_aes256 = 5, } SSL3BulkCipher; typedef enum { type_stream = 0, type_block = 1 } CipherType; typedef struct ssl3CipherSuiteDefStr { uint16_t suite; SSL3BulkCipher calg; SSL3MACAlgorithm malg; int keyblksz; } ssl3CipherSuiteDef; typedef void (*hashinit_func_t)(void *); typedef void (*hashupdate_func_t)(void *, uchar_t *, uint32_t); typedef void (*hashfinal_func_t)(uchar_t *, void *); typedef struct KSSLMACDefStr { int hashsz; int padsz; hashinit_func_t HashInit; hashupdate_func_t HashUpdate; hashfinal_func_t HashFinal; } KSSLMACDef; typedef struct KSSLCipherDefStr { CipherType type; int bsize; int keysz; crypto_mech_type_t mech_type; } KSSLCipherDef; typedef union KSSL_HASHCTXUnion { SHA1_CTX sha; MD5_CTX md5; } KSSL_HASHCTX; typedef struct KSSLCipherSpecStr { int mac_hashsz; int mac_padsz; void (*MAC_HashInit)(void *); void (*MAC_HashUpdate)(void *, uchar_t *, uint32_t); void (*MAC_HashFinal)(uchar_t *, void *); CipherType cipher_type; int cipher_bsize; int cipher_keysz; crypto_mechanism_t cipher_mech; crypto_mechanism_t hmac_mech; /* for TLS */ crypto_key_t cipher_key; crypto_key_t hmac_key; /* for TLS */ crypto_context_t cipher_ctx; crypto_data_t cipher_data; } KSSLCipherSpec; /* * SSL connection state. This one hangs off of a tcp_t structure. */ typedef struct ssl_s { kmutex_t kssl_lock; struct kssl_entry_s *kssl_entry; mblk_t *rec_ass_head; mblk_t *rec_ass_tail; uint_t kssl_refcnt; in6_addr_t faddr; uint32_t tcp_mss; SSL3WaitState hs_waitstate; boolean_t resumed; boolean_t close_notify; boolean_t fatal_alert; boolean_t fatal_error; boolean_t alert_sent; boolean_t appdata_sent; boolean_t activeinput; SSL3AlertLevel sendalert_level; SSL3AlertDescription sendalert_desc; mblk_t *handshake_sendbuf; mblk_t *alert_sendbuf; kssl_callback_t cke_callback_func; void *cke_callback_arg; uint16_t pending_cipher_suite; SSL3MACAlgorithm pending_malg; SSL3BulkCipher pending_calg; int pending_keyblksz; uint64_t seq_num[2]; SSL3HandshakeMsg msg; KSSLJOB job; KSSLCipherSpec spec[2]; uchar_t pending_keyblock[MAX_KEYBLOCK_LENGTH]; uchar_t mac_secret[2][MAX_HASH_LEN]; KSSL_HASHCTX mac_ctx[2][2]; /* inner 'n outer per dir */ sslSessionID sid; SHA1_CTX hs_sha1; MD5_CTX hs_md5; SSL3Hashes hs_hashes; uchar_t client_random[SSL3_RANDOM_LENGTH]; uchar_t server_random[SSL3_RANDOM_LENGTH]; int sslcnt; uchar_t major_version; uchar_t minor_version; boolean_t secure_renegotiation; } ssl_t; #define IS_TLS(s) (s->major_version == 3 && s->minor_version == 1) #define SSL3_REC_SIZE(mp) (uint8_t *)(mp)->b_rptr + 3 extern int kssl_spec_init(ssl_t *, int); extern void kssl_send_alert(ssl_t *, SSL3AlertLevel, SSL3AlertDescription); #ifdef __cplusplus } #endif #endif /* _INET_KSSL_KSSLPROTO_H */