ksslproto.h revision 2bd70d4be73561631df9cb3d9eb4c65fa94fa665
/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _INET_KSSL_KSSLPROTO_H
#define _INET_KSSL_KSSLPROTO_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/md5.h>
#include <sys/sha1.h>
#include <sys/crypto/common.h>
#include <sys/crypto/api.h>
#include <inet/kssl/kssl.h> /* Cipher suite definitions */
#include <inet/kssl/ksslapi.h>
#include <inet/kssl/ksslimpl.h>
#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;
ipaddr_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;
uchar_t pad[2 * 64 - sizeof (kmutex_t) - sizeof (uint64_t) \
- sizeof (sslSessionID)];
} kssl_sid_ent_t;
typedef struct RC4ContextStr {
uchar_t i;
uchar_t j;
uchar_t S[256];
} RC4Context;
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 KSSLMACJOBStr {
struct ssl_s *ssl;
buf_t *in;
buf_t *out;
uchar_t *rstart;
int rlen;
uint64_t seq;
SSL3ContentType ct;
uchar_t *digest;
int dir;
} KSSLMACJOB;
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;
ipaddr_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;
uint32_t macjobs_todo;
uint32_t macjobs_done;
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;
} 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 */