Changeset View
Changeset View
Standalone View
Standalone View
security/openssl-chelsio/files/patch-chelsio-toe
- This file was added.
Property | Old Value | New Value |
---|---|---|
fbsd:nokeywords | null | yes \ No newline at end of property |
svn:eol-style | null | native \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
diff --git crypto/bio/bss_conn.c crypto/bio/bss_conn.c | |||||
index e9673fe783..20131de7e0 100644 | |||||
--- crypto/bio/bss_conn.c | |||||
+++ crypto/bio/bss_conn.c | |||||
@@ -11,6 +11,7 @@ | |||||
#include <errno.h> | |||||
#include "bio_lcl.h" | |||||
+#include "ssl/ssl_ofld.h" | |||||
#ifndef OPENSSL_NO_SOCK | |||||
@@ -179,6 +180,28 @@ static int conn_state(BIO *b, BIO_CONNECT *c) | |||||
goto exit_loop; | |||||
} else { | |||||
c->state = BIO_CONN_S_OK; | |||||
+#ifdef CHELSIO_TLS_OFFLOAD | |||||
+ int mode, rc; | |||||
+#ifdef __linux__ | |||||
+ rc = ioctl(b->num, IOCTL_TLSOM_GET_TLS_TOM, &mode); | |||||
+ if (!rc && mode) | |||||
+ BIO_set_chofld_flag(b); | |||||
+#else | |||||
+ socklen_t optlen; | |||||
+ optlen = sizeof(mode); | |||||
+ rc = getsockopt(b->num, IPPROTO_TCP, TCP_TLSOM_GET_TLS_TOM, | |||||
+ &mode, &optlen); | |||||
+ if (rc == 0) { | |||||
+ switch (mode) { | |||||
+ case TLS_TOM_BOTH: | |||||
+ case TLS_TOM_TXONLY: | |||||
+ /* For TXONLY, chssl_program_hwkey_context will DTRT. */ | |||||
+ BIO_set_chofld_flag(b); | |||||
+ break; | |||||
+ } | |||||
+ } | |||||
+#endif | |||||
+#endif | |||||
} | |||||
break; | |||||
@@ -343,6 +366,9 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) | |||||
const char **pptr = NULL; | |||||
long ret = 1; | |||||
BIO_CONNECT *data; | |||||
+#ifdef CHELSIO_TLS_OFFLOAD | |||||
+ struct tls_key_context *key_context; | |||||
+#endif | |||||
data = (BIO_CONNECT *)b->ptr; | |||||
@@ -488,6 +514,37 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) | |||||
*fptr = data->info_callback; | |||||
} | |||||
break; | |||||
+ case BIO_CTRL_GET_OFFLOAD_TX: | |||||
+ return BIO_should_offload_tx_flag(b); | |||||
+ case BIO_CTRL_SET_OFFLOAD_TX_CTRL_MSG: | |||||
+ BIO_set_offload_tx_ctrl_msg_flag(b); | |||||
+ b->ptr = (void *)num; | |||||
+ ret = 0; | |||||
+ break; | |||||
+ case BIO_CTRL_CLEAR_OFFLOAD_TX_CTRL_MSG: | |||||
+ BIO_clear_offload_tx_ctrl_msg_flag(b); | |||||
+ ret = 0; | |||||
+ break; | |||||
+ case BIO_CTRL_GET_OFFLOAD_RX: | |||||
+ return BIO_should_offload_rx_flag(b); | |||||
+#ifdef CHELSIO_TLS_OFFLOAD | |||||
+ case BIO_CTRL_SET_OFFLOAD_KEY: | |||||
+ key_context = (struct tls_key_context *)ptr; | |||||
+#ifdef __linux__ | |||||
+ ret = ioctl(b->num, IOCTL_TLSOM_SET_TLS_CONTEXT, key_context); | |||||
+#else | |||||
+ ret = setsockopt(b->num, IPPROTO_TCP, TCP_TLSOM_SET_TLS_CONTEXT, | |||||
+ key_context, sizeof(*key_context)); | |||||
+#endif | |||||
+ break; | |||||
+ case BIO_CTRL_SET_OFFLOAD_CLEAR_KEY: | |||||
+#ifdef __linux__ | |||||
+ ret = ioctl(b->num, IOCTL_TLSOM_CLR_TLS_TOM); | |||||
+#else | |||||
+ ret = setsockopt(b->num, IPPROTO_TCP, TCP_TLSOM_CLR_TLS_TOM, NULL, 0); | |||||
+#endif | |||||
+ break; | |||||
+#endif | |||||
default: | |||||
ret = 0; | |||||
break; | |||||
diff --git crypto/bio/bss_sock.c crypto/bio/bss_sock.c | |||||
index ad38453201..4a0e2a46d4 100644 | |||||
--- crypto/bio/bss_sock.c | |||||
+++ crypto/bio/bss_sock.c | |||||
@@ -11,6 +11,7 @@ | |||||
#include <errno.h> | |||||
#include "bio_lcl.h" | |||||
#include "internal/cryptlib.h" | |||||
+#include "ssl/ssl_ofld.h" | |||||
#ifndef OPENSSL_NO_SOCK | |||||
@@ -124,6 +125,9 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) | |||||
{ | |||||
long ret = 1; | |||||
int *ip; | |||||
+#ifdef CHELSIO_TLS_OFFLOAD | |||||
+ struct tls_key_context *key_context; | |||||
+#endif | |||||
switch (cmd) { | |||||
case BIO_C_SET_FD: | |||||
@@ -131,6 +135,30 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) | |||||
b->num = *((int *)ptr); | |||||
b->shutdown = (int)num; | |||||
b->init = 1; | |||||
+#ifdef CHELSIO_TLS_OFFLOAD | |||||
+ { | |||||
+ int mode, rc; | |||||
+#ifdef __linux__ | |||||
+ rc = ioctl(b->num, IOCTL_TLSOM_GET_TLS_TOM, &mode); | |||||
+ if (!rc && mode) | |||||
+ BIO_set_chofld_flag(b); | |||||
+#else | |||||
+ socklen_t optlen; | |||||
+ optlen = sizeof(mode); | |||||
+ rc = getsockopt(b->num, IPPROTO_TCP, TCP_TLSOM_GET_TLS_TOM, &mode, | |||||
+ &optlen); | |||||
+ if (rc == 0) { | |||||
+ switch (mode) { | |||||
+ case TLS_TOM_BOTH: | |||||
+ case TLS_TOM_TXONLY: | |||||
+ /* For TXONLY, chssl_program_hwkey_context will DTRT. */ | |||||
+ BIO_set_chofld_flag(b); | |||||
+ break; | |||||
+ } | |||||
+ } | |||||
+#endif | |||||
+ } | |||||
+#endif | |||||
break; | |||||
case BIO_C_GET_FD: | |||||
if (b->init) { | |||||
@@ -151,6 +179,37 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) | |||||
case BIO_CTRL_FLUSH: | |||||
ret = 1; | |||||
break; | |||||
+ case BIO_CTRL_GET_OFFLOAD_TX: | |||||
+ return BIO_should_offload_tx_flag(b); | |||||
+ case BIO_CTRL_SET_OFFLOAD_TX_CTRL_MSG: | |||||
+ BIO_set_offload_tx_ctrl_msg_flag(b); | |||||
+ b->ptr = (void *)num; | |||||
+ ret = 0; | |||||
+ break; | |||||
+ case BIO_CTRL_CLEAR_OFFLOAD_TX_CTRL_MSG: | |||||
+ BIO_clear_offload_tx_ctrl_msg_flag(b); | |||||
+ ret = 0; | |||||
+ break; | |||||
+ case BIO_CTRL_GET_OFFLOAD_RX: | |||||
+ return BIO_should_offload_rx_flag(b); | |||||
+#ifdef CHELSIO_TLS_OFFLOAD | |||||
+ case BIO_CTRL_SET_OFFLOAD_KEY: | |||||
+ key_context = (struct tls_key_context *)ptr; | |||||
+#ifdef __linux__ | |||||
+ ret = ioctl(b->num, IOCTL_TLSOM_SET_TLS_CONTEXT, key_context); | |||||
+#else | |||||
+ ret = setsockopt(b->num, IPPROTO_TCP, TCP_TLSOM_SET_TLS_CONTEXT, | |||||
+ key_context, sizeof(*key_context)); | |||||
+#endif | |||||
+ break; | |||||
+ case BIO_CTRL_SET_OFFLOAD_CLEAR_KEY: | |||||
+#ifdef __linux__ | |||||
+ ret = ioctl(b->num, IOCTL_TLSOM_CLR_TLS_TOM); | |||||
+#else | |||||
+ ret = setsockopt(b->num, IPPROTO_TCP, TCP_TLSOM_CLR_TLS_TOM, NULL, 0); | |||||
+#endif | |||||
+ break; | |||||
+#endif | |||||
default: | |||||
ret = 0; | |||||
break; | |||||
diff --git include/openssl/bio.h include/openssl/bio.h | |||||
index 2888b42da8..38a3cabad1 100644 | |||||
--- include/openssl/bio.h | |||||
+++ include/openssl/bio.h | |||||
@@ -144,6 +144,14 @@ extern "C" { | |||||
# endif | |||||
# define BIO_CTRL_DGRAM_SET_PEEK_MODE 71 | |||||
+# define BIO_CTRL_SET_OFFLOAD_TX 72 | |||||
+# define BIO_CTRL_GET_OFFLOAD_TX 73 | |||||
+# define BIO_CTRL_SET_OFFLOAD_TX_CTRL_MSG 74 | |||||
+# define BIO_CTRL_CLEAR_OFFLOAD_TX_CTRL_MSG 75 | |||||
+# define BIO_CTRL_SET_OFFLOAD_RX 76 | |||||
+# define BIO_CTRL_GET_OFFLOAD_RX 77 | |||||
+# define BIO_CTRL_SET_OFFLOAD_KEY 78 | |||||
+# define BIO_CTRL_SET_OFFLOAD_CLEAR_KEY 79 | |||||
/* modifiers */ | |||||
# define BIO_FP_READ 0x02 | |||||
@@ -174,6 +182,16 @@ extern "C" { | |||||
# define BIO_FLAGS_MEM_RDONLY 0x200 | |||||
# define BIO_FLAGS_NONCLEAR_RST 0x400 | |||||
+/* | |||||
+ * This is used with socket BIOs: | |||||
+ * BIO_FLAGS_OFFLOAD_TX means we are using offload with this BIO for TX. | |||||
+ * BIO_FLAGS_OFFLOAD_TX_CTRL_MSG means we are about to send a ctrl message next. | |||||
+ */ | |||||
+#define BIO_FLAGS_OFFLOAD_TX 0x2000 | |||||
+#define BIO_FLAGS_OFFLOAD_TX_CTRL_MSG 0x4000 | |||||
+#define BIO_FLAGS_OFFLOAD_RX 0x8000 | |||||
+#define BIO_FLAGS_CHOFLD_INLINE 0x10000 | |||||
+ | |||||
typedef union bio_addr_st BIO_ADDR; | |||||
typedef struct bio_addrinfo_st BIO_ADDRINFO; | |||||
@@ -189,6 +207,25 @@ void BIO_clear_flags(BIO *b, int flags); | |||||
BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) | |||||
# define BIO_set_retry_write(b) \ | |||||
BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) | |||||
+/* Offload related controls and flags */ | |||||
+# define BIO_set_offload_tx_flag(b) \ | |||||
+ BIO_set_flags(b, BIO_FLAGS_OFFLOAD_TX) | |||||
+# define BIO_should_offload_tx_flag(b) \ | |||||
+ BIO_test_flags(b, BIO_FLAGS_OFFLOAD_TX) | |||||
+# define BIO_set_offload_tx_ctrl_msg_flag(b) \ | |||||
+ BIO_set_flags(b, BIO_FLAGS_OFFLOAD_TX_CTRL_MSG) | |||||
+# define BIO_should_offload_tx_ctrl_msg_flag(b) \ | |||||
+ BIO_test_flags(b, (BIO_FLAGS_OFFLOAD_TX_CTRL_MSG)) | |||||
+# define BIO_clear_offload_tx_ctrl_msg_flag(b) \ | |||||
+ BIO_clear_flags(b, (BIO_FLAGS_OFFLOAD_TX_CTRL_MSG)) | |||||
+# define BIO_set_offload_rx_flag(b) \ | |||||
+ BIO_set_flags(b, BIO_FLAGS_OFFLOAD_RX) | |||||
+# define BIO_should_offload_rx_flag(b) \ | |||||
+ BIO_test_flags(b, BIO_FLAGS_OFFLOAD_RX) | |||||
+# define BIO_set_chofld_flag(b) \ | |||||
+ BIO_set_flags(b, BIO_FLAGS_CHOFLD_INLINE) | |||||
+# define BIO_get_chofld_flag(b) \ | |||||
+ BIO_test_flags(b, BIO_FLAGS_CHOFLD_INLINE) | |||||
/* These are normally used internally in BIOs */ | |||||
# define BIO_clear_retry_flags(b) \ | |||||
@@ -380,6 +417,22 @@ struct bio_dgram_sctp_prinfo { | |||||
# define BIO_get_conn_address(b) ((const BIO_ADDR *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)) | |||||
# define BIO_get_conn_ip_family(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL) | |||||
# define BIO_set_conn_mode(b,n) BIO_ctrl(b,BIO_C_SET_CONNECT_MODE,(n),NULL) | |||||
+# define BIO_set_offload_tx(b, keyblob) \ | |||||
+ BIO_ctrl(b, BIO_CTRL_SET_OFFLOAD_TX, 0, keyblob) | |||||
+# define BIO_get_offload_tx(b) \ | |||||
+ BIO_ctrl(b, BIO_CTRL_GET_OFFLOAD_TX, 0, NULL) | |||||
+# define BIO_set_offload_tx_ctrl_msg(b, record_type) \ | |||||
+ BIO_ctrl(b, BIO_CTRL_SET_OFFLOAD_TX_CTRL_MSG, record_type, NULL) | |||||
+# define BIO_clear_offload_tx_ctrl_msg(b) \ | |||||
+ BIO_ctrl(b, BIO_CTRL_CLEAR_OFFLOAD_TX_CTRL_MSG, 0, NULL) | |||||
+# define BIO_set_offload_rx(b, keyblob) \ | |||||
+ BIO_ctrl(b, BIO_CTRL_SET_OFFLOAD_RX, 0, keyblob) | |||||
+# define BIO_get_offload_rx(b) \ | |||||
+ BIO_ctrl(b, BIO_CTRL_GET_OFFLOAD_RX, 0, NULL) | |||||
+# define BIO_set_offload_key(b, keyblob) \ | |||||
+ BIO_ctrl(b, BIO_CTRL_SET_OFFLOAD_KEY, 0, keyblob) | |||||
+# define BIO_set_offload_clear_key(b) \ | |||||
+ BIO_ctrl(b, BIO_CTRL_SET_OFFLOAD_CLEAR_KEY, 0, NULL) | |||||
/* BIO_s_accept() */ | |||||
# define BIO_set_accept_name(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0, \ | |||||
diff --git include/openssl/ssl.h include/openssl/ssl.h | |||||
index 0a18a43544..82ac6fd093 100644 | |||||
--- include/openssl/ssl.h | |||||
+++ include/openssl/ssl.h | |||||
@@ -1069,6 +1069,7 @@ int SSL_is_init_finished(const SSL *s); | |||||
# define SSL_ST_READ_HEADER 0xF0 | |||||
# define SSL_ST_READ_BODY 0xF1 | |||||
# define SSL_ST_READ_DONE 0xF2 | |||||
+# define SSL_ST_READ_ERROR 0xF3 | |||||
/*- | |||||
* Obtain latest Finished message | |||||
diff --git ssl/build.info ssl/build.info | |||||
index bb2f1deb53..bbd8c2db7f 100644 | |||||
--- ssl/build.info | |||||
+++ ssl/build.info | |||||
@@ -11,5 +11,6 @@ SOURCE[../libssl]=\ | |||||
ssl_ciph.c ssl_stat.c ssl_rsa.c \ | |||||
ssl_asn1.c ssl_txt.c ssl_init.c ssl_conf.c ssl_mcnf.c \ | |||||
bio_ssl.c ssl_err.c tls_srp.c t1_trce.c ssl_utst.c \ | |||||
+ ssl_ofld.c \ | |||||
record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \ | |||||
statem/statem.c record/ssl3_record_tls13.c | |||||
diff --git ssl/record/rec_layer_s3.c ssl/record/rec_layer_s3.c | |||||
index 6d495715b2..1ce19d31e4 100644 | |||||
--- ssl/record/rec_layer_s3.c | |||||
+++ ssl/record/rec_layer_s3.c | |||||
@@ -797,7 +797,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, | |||||
} | |||||
/* Explicit IV length, block ciphers appropriate version flag */ | |||||
- if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) && !SSL_TREAT_AS_TLS13(s)) { | |||||
+ if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) && !SSL_TREAT_AS_TLS13(s) | |||||
+ && !BIO_get_offload_tx(s->wbio)) { | |||||
int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); | |||||
if (mode == EVP_CIPH_CBC_MODE) { | |||||
/* TODO(size_t): Convert me */ | |||||
@@ -951,7 +952,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, | |||||
* in the wb->buf | |||||
*/ | |||||
- if (!SSL_WRITE_ETM(s) && mac_size != 0) { | |||||
+ if (!SSL_WRITE_ETM(s) && mac_size != 0 | |||||
+ && !BIO_get_offload_tx(s->wbio)) { | |||||
unsigned char *mac; | |||||
if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac) | |||||
@@ -999,7 +1001,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, | |||||
} | |||||
goto err; | |||||
} | |||||
- } else { | |||||
+ } else if (!BIO_get_offload_tx(s->wbio)) { | |||||
if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1) { | |||||
if (!ossl_statem_in_error(s)) { | |||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, | |||||
@@ -1149,6 +1151,9 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, | |||||
(unsigned int)SSL3_BUFFER_get_left(&wb[currbuf])); | |||||
if (i >= 0) | |||||
tmpwrit = i; | |||||
+ | |||||
+ if (BIO_get_offload_tx(s->wbio) && type != SSL3_RT_APPLICATION_DATA) | |||||
+ (void)BIO_flush(s->wbio); | |||||
} else { | |||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_WRITE_PENDING, | |||||
SSL_R_BIO_NOT_SET); | |||||
diff --git ssl/record/ssl3_record.c ssl/record/ssl3_record.c | |||||
index e59ac5a676..26c8c5f692 100644 | |||||
--- ssl/record/ssl3_record.c | |||||
+++ ssl/record/ssl3_record.c | |||||
@@ -225,6 +225,11 @@ int ssl3_get_record(SSL *s) | |||||
ERR_R_INTERNAL_ERROR); | |||||
return -1; | |||||
} | |||||
+ | |||||
+ if (BIO_get_offload_rx(s->rbio) && (*p == 0x7F)) { | |||||
+ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_ERROR); | |||||
+ } | |||||
+ | |||||
/* | |||||
* The first record received by the server may be a V2ClientHello. | |||||
*/ | |||||
@@ -393,6 +398,18 @@ int ssl3_get_record(SSL *s) | |||||
} | |||||
} | |||||
+ if (BIO_get_offload_rx(s->rbio) && | |||||
+ RECORD_LAYER_get_rstate(&s->rlayer) == SSL_ST_READ_ERROR) { | |||||
+ i = rr[num_recs].length; | |||||
+ rret = ssl3_read_n(s, i, i, 1, 0, &n); | |||||
+ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER); | |||||
+ if (rret <= 0) | |||||
+ return (rret); | |||||
+ SSLfatal(s, SSL_AD_BAD_RECORD_MAC, SSL_F_SSL3_GET_RECORD, | |||||
+ SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); | |||||
+ return -1; | |||||
+ } | |||||
+ | |||||
/* | |||||
* s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data. | |||||
* Calculate how much more data we need to read for the rest of the | |||||
@@ -495,7 +512,7 @@ int ssl3_get_record(SSL *s) | |||||
* If in encrypt-then-mac mode calculate mac from encrypted record. All | |||||
* the details below are public so no timing details can leak. | |||||
*/ | |||||
- if (SSL_READ_ETM(s) && s->read_hash) { | |||||
+ if (SSL_READ_ETM(s) && s->read_hash && !BIO_get_offload_rx(s->rbio)) { | |||||
unsigned char *mac; | |||||
/* TODO(size_t): convert this to do size_t properly */ | |||||
imac_size = EVP_MD_CTX_size(s->read_hash); | |||||
@@ -526,7 +543,11 @@ int ssl3_get_record(SSL *s) | |||||
first_rec_len = rr[0].length; | |||||
- enc_err = s->method->ssl3_enc->enc(s, rr, num_recs, 0); | |||||
+ if (BIO_get_offload_rx(s->rbio)) { | |||||
+ enc_err = 1; | |||||
+ } else { | |||||
+ enc_err = s->method->ssl3_enc->enc(s, rr, num_recs, 0); | |||||
+ } | |||||
/*- | |||||
* enc_err is: | |||||
@@ -576,6 +597,7 @@ int ssl3_get_record(SSL *s) | |||||
/* r->length is now the compressed data plus mac */ | |||||
if ((sess != NULL) && | |||||
(s->enc_read_ctx != NULL) && | |||||
+ !BIO_get_offload_rx(s->rbio) && | |||||
(!SSL_READ_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)) { | |||||
/* s->read_hash != NULL => mac_size != -1 */ | |||||
unsigned char *mac = NULL; | |||||
diff --git ssl/s3_msg.c ssl/s3_msg.c | |||||
index 42382547fb..a3d549604b 100644 | |||||
--- ssl/s3_msg.c | |||||
+++ ssl/s3_msg.c | |||||
@@ -8,6 +8,7 @@ | |||||
*/ | |||||
#include "ssl_locl.h" | |||||
+#include "ssl_ofld.h" | |||||
int ssl3_do_change_cipher_spec(SSL *s) | |||||
{ | |||||
@@ -33,6 +34,18 @@ int ssl3_do_change_cipher_spec(SSL *s) | |||||
if (!s->method->ssl3_enc->change_cipher_state(s, i)) | |||||
return 0; | |||||
+#ifdef CHELSIO_TLS_OFFLOAD | |||||
+ if (!s->server) { | |||||
+ if (s->wbio) { | |||||
+ chssl_program_hwkey_context(s, SSL3_CC_READ, SSL_ST_CONNECT); | |||||
+ } | |||||
+ } else { | |||||
+ if (s->wbio) { | |||||
+ chssl_program_hwkey_context(s, SSL3_CC_READ, SSL_ST_ACCEPT); | |||||
+ } | |||||
+ } | |||||
+#endif | |||||
+ | |||||
return 1; | |||||
} | |||||
diff --git ssl/ssl_ofld.c ssl/ssl_ofld.c | |||||
new file mode 100644 | |||||
index 0000000000..ba372e2d99 | |||||
--- /dev/null | |||||
+++ ssl/ssl_ofld.c | |||||
@@ -0,0 +1,413 @@ | |||||
+/* | |||||
+ * Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved. | |||||
+ * | |||||
+ * Licensed under the OpenSSL license (the "License"). You may not use | |||||
+ * this file except in compliance with the License. You can obtain a copy | |||||
+ * in the file LICENSE in the source distribution or at | |||||
+ * https://www.openssl.org/source/license.html | |||||
+ */ | |||||
+ | |||||
+#include <stdio.h> | |||||
+#include <sys/socket.h> | |||||
+#include <sys/ioctl.h> | |||||
+#include <openssl/bio.h> | |||||
+#include <openssl/ossl_typ.h> | |||||
+#include <openssl/comp.h> | |||||
+#include <openssl/evp.h> | |||||
+#include <openssl/kdf.h> | |||||
+#include <openssl/rand.h> | |||||
+#include "ssl_locl.h" | |||||
+#include "ssl_ofld.h" | |||||
+ | |||||
+#ifdef CHELSIO_TLS_OFFLOAD | |||||
+int CHSSL_EVP_Digest(const void *data, | |||||
+ void *md, unsigned long algorithm_mac) | |||||
+{ | |||||
+ unsigned char *temp = md; | |||||
+ int ret = 1, i; | |||||
+ | |||||
+ if (algorithm_mac == SSL_SHA1){ | |||||
+ SHA_CTX sha1ctx; | |||||
+ | |||||
+ SHA1_Init(&sha1ctx); | |||||
+ SHA1_Update(&sha1ctx, data, SHA_CBLOCK); | |||||
+ l2n(sha1ctx.h0, temp); | |||||
+ l2n(sha1ctx.h1, temp); | |||||
+ l2n(sha1ctx.h2, temp); | |||||
+ l2n(sha1ctx.h3, temp); | |||||
+ l2n(sha1ctx.h4, temp); | |||||
+ } else if (algorithm_mac == SSL_SHA256) { | |||||
+ SHA256_CTX sha256ctx; | |||||
+ SHA256_Init(&sha256ctx); | |||||
+ SHA256_Update(&sha256ctx, data, SHA256_CBLOCK); | |||||
+ | |||||
+ for (i = 0; i < SHA256_DIGEST_LENGTH / 4; i++) | |||||
+ l2n(sha256ctx.h[i], temp); | |||||
+ } else if (algorithm_mac == SSL_SHA384) { | |||||
+ SHA512_CTX sha384ctx; | |||||
+ | |||||
+ SHA384_Init(&sha384ctx); | |||||
+ SHA384_Update(&sha384ctx, data, SHA512_BLOCK); | |||||
+ | |||||
+ for (i = 0; i < SHA512_DIGEST_LENGTH / 8; i++) | |||||
+ l2n8(sha384ctx.h[i], temp); | |||||
+ } | |||||
+ | |||||
+ return ret; | |||||
+} | |||||
+ | |||||
+static int tls_ofld_enc_mac(SSL *s) | |||||
+{ | |||||
+ const EVP_CIPHER *p; | |||||
+ const SSL_CIPHER *c; | |||||
+ | |||||
+ c = s->s3->tmp.new_cipher; | |||||
+ p = s->s3->tmp.new_sym_enc; | |||||
+ | |||||
+ switch(c->algorithm_enc) { | |||||
+ case SSL_AES128GCM: | |||||
+ case SSL_AES256GCM: | |||||
+ return TLS_OFLD_TRUE; | |||||
+ | |||||
+ case SSL_AES128 : | |||||
+ case SSL_AES256 : | |||||
+ switch(EVP_CIPHER_mode(p)) { | |||||
+ case EVP_CIPH_CTR_MODE: | |||||
+ case EVP_CIPH_CBC_MODE: | |||||
+ break; | |||||
+ default: | |||||
+ return TLS_OFLD_FALSE; | |||||
+ } | |||||
+ break; | |||||
+ | |||||
+ case SSL_eNULL: | |||||
+ break; | |||||
+ | |||||
+ default: | |||||
+ return TLS_OFLD_FALSE; | |||||
+ } | |||||
+ | |||||
+ switch(c->algorithm_mac) { | |||||
+ case SSL_SHA1: | |||||
+ case SSL_SHA256: | |||||
+ case SSL_SHA384: | |||||
+ break; | |||||
+ | |||||
+ default: | |||||
+ /* Revert enc mode to non-offload */ | |||||
+ return TLS_OFLD_FALSE; | |||||
+ } | |||||
+ return TLS_OFLD_TRUE; | |||||
+} | |||||
+ | |||||
+static unsigned char get_auth_mode(SSL *s) | |||||
+{ | |||||
+ const SSL_CIPHER *c = s->s3->tmp.new_cipher; | |||||
+ | |||||
+ if(c==NULL) return CHSSL_SHA_NOP; | |||||
+ | |||||
+ switch(c->algorithm_mac) { | |||||
+ case SSL_SHA1: | |||||
+ return CHSSL_SHA1; | |||||
+ case SSL_SHA256: | |||||
+ return CHSSL_SHA256; | |||||
+ case SSL_SHA384: | |||||
+ return CHSSL_SHA512_384; | |||||
+ case SSL_AEAD: | |||||
+ return CHSSL_GHASH; | |||||
+ default: | |||||
+ return CHSSL_SHA_NOP; | |||||
+ } | |||||
+} | |||||
+ | |||||
+/* | |||||
+ * Cipher Mode expected by HW | |||||
+ */ | |||||
+static unsigned char get_cipher_mode(SSL *s) | |||||
+{ | |||||
+ const EVP_CIPHER *c = s->s3->tmp.new_sym_enc; | |||||
+ | |||||
+ switch(EVP_CIPHER_mode(c)) { | |||||
+ case EVP_CIPH_CBC_MODE: | |||||
+ return CHSSL_AES_CBC; | |||||
+ case EVP_CIPH_GCM_MODE: | |||||
+ return CHSSL_AES_GCM; | |||||
+ case EVP_CIPH_CTR_MODE: | |||||
+ return CHSSL_AES_CTR; | |||||
+ case EVP_CIPH_STREAM_CIPHER: | |||||
+ return CHSSL_CIPH_NOP; | |||||
+ default: | |||||
+ return CHSSL_CIPH_NOP; | |||||
+ } | |||||
+} | |||||
+ | |||||
+/* | |||||
+ * H/W requires Partial Hash of opad and ipad. This function create | |||||
+ * ipad, opad block using key and generates partial result | |||||
+ */ | |||||
+static void chssl_compute_ipad_opad(unsigned char *key, | |||||
+ unsigned char *ipad, | |||||
+ unsigned char *opad, | |||||
+ int k, unsigned long algorithm_mac) | |||||
+{ | |||||
+ int i, blksize; | |||||
+ char iblock[SHA512_BLOCK] = {0}; | |||||
+ char oblock[SHA512_BLOCK] = {0}; | |||||
+ | |||||
+ if (algorithm_mac == SSL_SHA384) | |||||
+ blksize = SHA512_CBLOCK; | |||||
+ else | |||||
+ blksize = SHA256_CBLOCK; | |||||
+ memset (iblock + k, 0x36, blksize - k); | |||||
+ memset (oblock + k, 0x5c, blksize - k); | |||||
+ for(i = 0; i < k; i++) { | |||||
+ iblock[i] = key[i] ^ 0x36; | |||||
+ oblock[i] = key[i] ^ 0x5c; | |||||
+ } | |||||
+ CHSSL_EVP_Digest(iblock, ipad, algorithm_mac); | |||||
+ CHSSL_EVP_Digest(oblock, opad, algorithm_mac); | |||||
+} | |||||
+ | |||||
+static void chssl_compute_cipher_key(unsigned char *key, | |||||
+ int key_len, | |||||
+ unsigned char *ghash) | |||||
+{ | |||||
+ int len,len1; | |||||
+ EVP_CIPHER_CTX *ctx; | |||||
+ unsigned char plaintext[GHASH_SIZE] = {0}; | |||||
+ | |||||
+ ctx = EVP_CIPHER_CTX_new(); | |||||
+ EVP_CIPHER_CTX_reset(ctx); | |||||
+ if(key_len == 16) | |||||
+ EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, NULL); | |||||
+ else | |||||
+ EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, NULL); | |||||
+ EVP_CIPHER_CTX_set_padding(ctx, 0); | |||||
+ EVP_EncryptUpdate(ctx, ghash, &len, plaintext, 16); | |||||
+ EVP_EncryptFinal_ex(ctx, ghash+len, &len1); | |||||
+ EVP_CIPHER_CTX_reset(ctx); | |||||
+ EVP_CIPHER_CTX_free(ctx); | |||||
+} | |||||
+ | |||||
+/* | |||||
+ * Create key Context for receive/transmit and program on HW | |||||
+ */ | |||||
+static int ssl_key_context(SSL *s, struct tls_key_context *kctx, int rw, int state) | |||||
+{ | |||||
+ const EVP_CIPHER *c; | |||||
+ unsigned int mac_key_size = 0, cipher_key_size, iv_size; | |||||
+ unsigned char *key; | |||||
+ unsigned char s_ipad_hash[MAX_MAC_KSZ]= {0x0}; /* blk sz for hashing */ | |||||
+ unsigned char s_opad_hash[MAX_MAC_KSZ]= {0x0}; /* blk sz for hashing */ | |||||
+ unsigned char c_ipad_hash[MAX_MAC_KSZ]= {0x0}; /* blk sz for hashing */ | |||||
+ unsigned char c_opad_hash[MAX_MAC_KSZ]= {0x0}; /* blk sz for hashing */ | |||||
+ | |||||
+ unsigned char s_mac_key[MAX_MAC_KSZ] = {0x0}; | |||||
+ unsigned char c_mac_key[MAX_MAC_KSZ] = {0x0}; | |||||
+ unsigned char s_key[MAX_CIPHER_KSZ] = {0x0}; | |||||
+ unsigned char c_key[MAX_CIPHER_KSZ] = {0x0}; | |||||
+ unsigned char s_iv[MAX_CIPHER_KSZ] = {0x0}; | |||||
+ unsigned char c_iv[MAX_CIPHER_KSZ] = {0x0}; | |||||
+ unsigned char ghash[GHASH_SIZE] = {0x0}; | |||||
+ int pad = 12; | |||||
+ int index = 0; | |||||
+ int ret = 0; | |||||
+ | |||||
+ if (!tls_ofld_enc_mac(s) || s->version < TLS1_VERSION) { | |||||
+ return ret; | |||||
+ } | |||||
+ | |||||
+ if (rw == SSL3_CC_READ && SSL_READ_ETM(s)) | |||||
+ return ret; | |||||
+ else if (rw == SSL3_CC_WRITE && SSL_WRITE_ETM(s)) | |||||
+ return ret; | |||||
+ | |||||
+ c = s->s3->tmp.new_sym_enc; | |||||
+ kctx->l_p_key = rw; | |||||
+ | |||||
+ if (s->new_session) | |||||
+ kctx->l_p_key |= F_KEY_CLR_LOC; | |||||
+ key = s->s3->tmp.key_block; | |||||
+ | |||||
+ mac_key_size = s->s3->tmp.new_mac_secret_size; | |||||
+ | |||||
+ kctx->mac_secret_size = mac_key_size; | |||||
+ | |||||
+ cipher_key_size = EVP_CIPHER_key_length(c); | |||||
+ kctx->cipher_secret_size = cipher_key_size; | |||||
+ | |||||
+ iv_size = (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) ? | |||||
+ EVP_GCM_TLS_FIXED_IV_LEN: | |||||
+ EVP_CIPHER_iv_length(c); | |||||
+ kctx->iv_size = iv_size; | |||||
+ kctx->iv_ctrl = 1; | |||||
+ kctx->iv_algo = 0; | |||||
+ | |||||
+ if ((mac_key_size == SHA256_DIGEST_LENGTH) || | |||||
+ (mac_key_size == SHA384_DIGEST_LENGTH)) | |||||
+ pad = 0; | |||||
+ | |||||
+ if (mac_key_size) { | |||||
+ memcpy(c_mac_key, key, mac_key_size); | |||||
+ key += mac_key_size; | |||||
+ memcpy(s_mac_key, key, mac_key_size); | |||||
+ key += mac_key_size; | |||||
+ } | |||||
+ memcpy(c_key, key, cipher_key_size); | |||||
+ key += cipher_key_size; | |||||
+ memcpy(s_key, key, cipher_key_size); | |||||
+ key += cipher_key_size; | |||||
+ | |||||
+ memcpy(c_iv, key, iv_size); | |||||
+ key += iv_size; | |||||
+ memcpy(s_iv, key, iv_size); | |||||
+ | |||||
+ if ((EVP_CIPHER_mode(c) != EVP_CIPH_GCM_MODE)) { | |||||
+ /* IPAD/OPAD for SHA384/512 calculated over 128B block */ | |||||
+ chssl_compute_ipad_opad(c_mac_key, c_ipad_hash, | |||||
+ c_opad_hash, mac_key_size, | |||||
+ s->s3->tmp.new_cipher->algorithm_mac); | |||||
+ chssl_compute_ipad_opad(s_mac_key, s_ipad_hash, | |||||
+ s_opad_hash, mac_key_size, | |||||
+ s->s3->tmp.new_cipher->algorithm_mac); | |||||
+ } | |||||
+ | |||||
+ if (state == SSL_ST_ACCEPT) { | |||||
+ memcpy(kctx->tx.key, s_key, cipher_key_size); | |||||
+ memcpy(kctx->rx.key, c_key, cipher_key_size); | |||||
+ } else { | |||||
+ memcpy(kctx->tx.key, c_key, cipher_key_size); | |||||
+ memcpy(kctx->rx.key, s_key, cipher_key_size); | |||||
+ } | |||||
+ | |||||
+ if (mac_key_size == SHA384_DIGEST_LENGTH) mac_key_size = MAX_MAC_KSZ; | |||||
+ index = cipher_key_size; | |||||
+ if (mac_key_size) { | |||||
+ if (state == SSL_ST_ACCEPT) | |||||
+ memcpy(kctx->tx.key+index, s_ipad_hash, mac_key_size); | |||||
+ else | |||||
+ memcpy(kctx->tx.key+index, c_ipad_hash, mac_key_size); | |||||
+ | |||||
+ index += (mac_key_size + pad); | |||||
+ if (state == SSL_ST_ACCEPT) | |||||
+ memcpy(kctx->tx.key+index, s_opad_hash, mac_key_size); | |||||
+ else | |||||
+ memcpy(kctx->tx.key+index, c_opad_hash, mac_key_size); | |||||
+ | |||||
+ index += (mac_key_size + pad); | |||||
+ } else { | |||||
+ if (state == SSL_ST_ACCEPT) { | |||||
+ chssl_compute_cipher_key(s_key, cipher_key_size, ghash); | |||||
+ memcpy(kctx->tx.key+index, ghash, GHASH_SIZE); | |||||
+ } else { | |||||
+ chssl_compute_cipher_key(c_key, cipher_key_size, ghash); | |||||
+ memcpy(kctx->tx.key+index, ghash, GHASH_SIZE); | |||||
+ } | |||||
+ index += GHASH_SIZE; | |||||
+ } | |||||
+ kctx->tx_key_info_size = TLS_TX_HDR_SZ + index; | |||||
+ index = cipher_key_size; | |||||
+ if (mac_key_size) { | |||||
+ if (state == SSL_ST_ACCEPT) | |||||
+ memcpy(kctx->rx.key+index, c_ipad_hash, mac_key_size); | |||||
+ else | |||||
+ memcpy(kctx->rx.key+index, s_ipad_hash, mac_key_size); | |||||
+ | |||||
+ index += (mac_key_size + pad); | |||||
+ if (state == SSL_ST_ACCEPT) | |||||
+ memcpy(kctx->rx.key+index, c_opad_hash, mac_key_size); | |||||
+ else | |||||
+ memcpy(kctx->rx.key+index, s_opad_hash, mac_key_size); | |||||
+ | |||||
+ index += (mac_key_size + pad); | |||||
+ } else { | |||||
+ if (state == SSL_ST_ACCEPT) { | |||||
+ chssl_compute_cipher_key(c_key, cipher_key_size, ghash); | |||||
+ memcpy(kctx->rx.key+index, ghash, GHASH_SIZE); | |||||
+ } else { | |||||
+ chssl_compute_cipher_key(s_key, cipher_key_size, ghash); | |||||
+ memcpy(kctx->rx.key+index, ghash, GHASH_SIZE); | |||||
+ } | |||||
+ index += GHASH_SIZE; | |||||
+ } | |||||
+ | |||||
+ kctx->tx_key_info_size = TLS_RX_HDR_SZ + index; | |||||
+ | |||||
+ if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { | |||||
+ if (state == SSL_ST_ACCEPT) { | |||||
+ memcpy(kctx->tx.salt, s_iv, SALT_SIZE); | |||||
+ memcpy(kctx->rx.salt, c_iv, SALT_SIZE); | |||||
+ } else { | |||||
+ memcpy(kctx->tx.salt, c_iv, SALT_SIZE); | |||||
+ memcpy(kctx->rx.salt, s_iv, SALT_SIZE); | |||||
+ } | |||||
+ } | |||||
+ | |||||
+ kctx->proto_ver = s->version; | |||||
+ kctx->state.auth_mode = get_auth_mode(s); | |||||
+ kctx->state.enc_mode = get_cipher_mode(s); | |||||
+ | |||||
+ if (s->max_send_fragment) | |||||
+ kctx->frag_size = s->max_send_fragment; | |||||
+ else | |||||
+ kctx->frag_size = SSL3_RT_MAX_PLAIN_LENGTH; | |||||
+ | |||||
+ /* handle renegotiation here */ | |||||
+ if(!BIO_get_offload_tx(s->wbio)) | |||||
+ kctx->tx_seq_no = 0; | |||||
+ else | |||||
+ kctx->tx_seq_no = 1; | |||||
+ | |||||
+ if(!BIO_get_offload_rx(s->rbio)) | |||||
+ kctx->rx_seq_no = 0; | |||||
+ else | |||||
+ kctx->rx_seq_no = 1; | |||||
+ | |||||
+ if(EVP_CIPHER_mode(c) != EVP_CIPH_GCM_MODE) { | |||||
+ kctx->hmac_ctrl = 1; | |||||
+ } | |||||
+ | |||||
+ return 1; | |||||
+} | |||||
+ | |||||
+void chssl_program_hwkey_context(SSL *s, int rw, int state) | |||||
+{ | |||||
+ int ret = 0; | |||||
+ BIO *wbio; | |||||
+ BIO *rbio; | |||||
+ struct tls_key_context *key_context; | |||||
+ | |||||
+ wbio = s->wbio; | |||||
+ rbio = s->rbio; | |||||
+ if (!BIO_get_chofld_flag(rbio)) | |||||
+ return; | |||||
+ | |||||
+ key_context = (struct tls_key_context *) | |||||
+ OPENSSL_malloc(sizeof(struct tls_key_context)); | |||||
+ if (key_context == NULL) | |||||
+ return; | |||||
+ | |||||
+ memset(key_context, 0, sizeof(struct tls_key_context)); | |||||
+ if((ret = ssl_key_context(s, key_context, rw, state)) <=0) { | |||||
+ /* Clear quiesce after CCS receive */ | |||||
+ if (rw == KEY_WRITE_RX) | |||||
+ BIO_set_offload_clear_key(wbio); | |||||
+ goto end; | |||||
+ } | |||||
+ | |||||
+ /* flush outstanding BIO before key is programmed */ | |||||
+ statem_flush(s); | |||||
+ ret = BIO_set_offload_key(wbio, key_context); | |||||
+ if (ret) | |||||
+ goto end; | |||||
+ if (rw & KEY_WRITE_TX) { | |||||
+ /* XXX: wbio? */ | |||||
+ BIO_set_offload_tx_flag(rbio); | |||||
+ } else { | |||||
+ BIO_set_offload_rx_flag(rbio); | |||||
+ } | |||||
+end: | |||||
+ free(key_context); | |||||
+ return; | |||||
+} | |||||
+#endif | |||||
diff --git ssl/ssl_ofld.h ssl/ssl_ofld.h | |||||
new file mode 100644 | |||||
index 0000000000..6b153bef9b | |||||
--- /dev/null | |||||
+++ ssl/ssl_ofld.h | |||||
@@ -0,0 +1,141 @@ | |||||
+#ifndef _SSL_OFLD_H | |||||
+#define _SSL_OFLD_H | |||||
+ | |||||
+#ifdef CHELSIO_TLS_OFFLOAD | |||||
+void chssl_program_hwkey_context(SSL *s, int rw, int state); | |||||
+ | |||||
+#define MAX_MAC_KSZ 64 /*512 bits */ | |||||
+#define SHA512_BLOCK 128 /* Block size for 512 */ | |||||
+#define MAX_CIPHER_KSZ 32 /* 256 bits */ | |||||
+#define CIPHER_BLOCK_SZ 16 | |||||
+#define IV_SIZE (4+8) /*reserved 8 bytes */ | |||||
+#define SALT_SIZE 4 | |||||
+#define TLS_TX_HDR_SZ 16 | |||||
+#define TLS_RX_HDR_SZ 16 | |||||
+#define GHASH_SIZE 16 | |||||
+#define MAX_TLS_KSZ (2*MAX_MAC_KSZ + MAX_CIPHER_KSZ) | |||||
+ | |||||
+#ifdef __linux__ | |||||
+#define IOCTL_TLSOM_SET_TLS_CONTEXT 201 /* Program Key Context on HW */ | |||||
+#define IOCTL_TLSOM_GET_TLS_TOM 202 /* Query the TLS offload mode */ | |||||
+#define IOCTL_TLSOM_CLR_TLS_TOM 203 /* Clear the Key */ | |||||
+#define IOCTL_TLSOM_CLR_QUIES 204 /* Clear the Quiesec */ | |||||
+#else | |||||
+/* Set with 'struct tls_key_context'. */ | |||||
+#define TCP_TLSOM_SET_TLS_CONTEXT (TCP_VENDOR) | |||||
+ | |||||
+/* Get returns int of enabled (1) / disabled (0). */ | |||||
+#define TCP_TLSOM_GET_TLS_TOM (TCP_VENDOR + 1) | |||||
+ | |||||
+enum { | |||||
+ TLS_TOM_NONE = 0, | |||||
+ TLS_TOM_TXONLY, | |||||
+ TLS_TOM_BOTH | |||||
+}; | |||||
+ | |||||
+/* Set with no value. */ | |||||
+#define TCP_TLSOM_CLR_TLS_TOM (TCP_VENDOR + 2) | |||||
+ | |||||
+/* Set with no value. */ | |||||
+#define TCP_TLSOM_CLR_QUIES (TCP_VENDOR + 3) | |||||
+#endif | |||||
+ | |||||
+enum { | |||||
+ TLS_OFLD_FALSE = 0, | |||||
+ TLS_OFLD_TRUE, | |||||
+}; | |||||
+ | |||||
+/* Can accomodate 16, 11-15 are reserved */ | |||||
+enum { | |||||
+ CHSSL_SHA_NOP, | |||||
+ CHSSL_SHA1, | |||||
+ CHSSL_SHA224, | |||||
+ CHSSL_SHA256, | |||||
+ CHSSL_GHASH, | |||||
+ CHSSL_SHA512_224, | |||||
+ CHSSL_SHA512_256, | |||||
+ CHSSL_SHA512_384, | |||||
+ CHSSL_SHA512_512, | |||||
+ CHSSL_CBCMAC, | |||||
+ CHSSL_CMAC, | |||||
+}; | |||||
+ | |||||
+/* Can accomodate 16, 8-15 are reserved */ | |||||
+enum { | |||||
+ CHSSL_CIPH_NOP, | |||||
+ CHSSL_AES_CBC, | |||||
+ CHSSL_AES_GCM, | |||||
+ CHSSL_AES_CTR, | |||||
+ CHSSL_AES_GEN, | |||||
+ CHSSL_IPSEC_ESP, | |||||
+ CHSSL_AES_XTS, | |||||
+ CHSSL_AES_CCM, | |||||
+}; | |||||
+ | |||||
+#define KEY_WRITE_RX 0x1 /* Program Receive Key */ | |||||
+#define KEY_WRITE_TX 0x2 /* Program Transmit Key */ | |||||
+#define KEY_DELETE_RX 0x4 /* Delete Receive Key */ | |||||
+#define KEY_DELETE_TX 0x8 /* Delete Transmit Key */ | |||||
+ | |||||
+#define S_KEY_CLR_LOC 4 | |||||
+#define M_KEY_CLR_LOC 0xf | |||||
+#define V_KEY_CLR_LOC(x) ((x) << S_KEY_CLR_LOC) | |||||
+#define G_FW_WR_EQUIQ(s) (((x) >> S_KEY_CLR_LOC) & M_KEY_CLR_LOC) | |||||
+#define F_KEY_CLR_LOC V_KEY_CLR_LOC(1U) | |||||
+ | |||||
+#define S_KEY_GET_LOC 0 | |||||
+#define M_KEY_GET_LOC 0xf | |||||
+#define V_KEY_GET_LOC(x) ((x) << S_KEY_GET_LOC) | |||||
+#define G_KEY_GET_LOC(s) (((x) >> S_KEY_GET_LOC) & M_KEY_GET_LOC) | |||||
+ | |||||
+struct tls_ofld_state { | |||||
+ unsigned char enc_mode; | |||||
+ unsigned char mac_mode; | |||||
+ unsigned char key_loc; | |||||
+ unsigned char ofld_mode; | |||||
+ unsigned char auth_mode; | |||||
+ unsigned char resv[3]; | |||||
+}; | |||||
+ | |||||
+struct tls_tx_ctxt { | |||||
+ unsigned char salt[SALT_SIZE]; | |||||
+ unsigned char key[MAX_CIPHER_KSZ]; | |||||
+ unsigned char ipad[MAX_MAC_KSZ]; | |||||
+ unsigned char opad[MAX_MAC_KSZ]; | |||||
+}; | |||||
+ | |||||
+struct tls_rx_ctxt { | |||||
+ unsigned char salt[SALT_SIZE]; | |||||
+ unsigned char key[MAX_CIPHER_KSZ]; | |||||
+ unsigned char ipad[MAX_MAC_KSZ]; | |||||
+ unsigned char opad[MAX_MAC_KSZ]; | |||||
+}; | |||||
+ | |||||
+struct tls_key_context { | |||||
+ struct tls_tx_ctxt tx; | |||||
+ struct tls_rx_ctxt rx; | |||||
+ | |||||
+ unsigned char l_p_key; | |||||
+ unsigned char hmac_ctrl; | |||||
+ unsigned char mac_first; | |||||
+ unsigned char iv_size; | |||||
+ unsigned char iv_ctrl; | |||||
+ unsigned char iv_algo; | |||||
+ unsigned char tx_seq_no; | |||||
+ unsigned char rx_seq_no; | |||||
+ | |||||
+ struct tls_ofld_state state; | |||||
+ | |||||
+ unsigned int tx_key_info_size; | |||||
+ unsigned int rx_key_info_size; | |||||
+ unsigned int frag_size; | |||||
+ unsigned int mac_secret_size; | |||||
+ unsigned int cipher_secret_size; | |||||
+ int proto_ver; | |||||
+ unsigned int sock_fd; | |||||
+ unsigned short dtls_epoch; | |||||
+ unsigned short rsv; | |||||
+}; | |||||
+#endif | |||||
+ | |||||
+#endif /* ssl_ofld.h */ | |||||
diff --git ssl/statem/statem_srvr.c ssl/statem/statem_srvr.c | |||||
index 7d0e9d0ba8..4bb38211f9 100644 | |||||
--- ssl/statem/statem_srvr.c | |||||
+++ ssl/statem/statem_srvr.c | |||||
@@ -650,6 +650,10 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL *s) | |||||
case TLS_ST_SW_SESSION_TICKET: | |||||
st->hand_state = TLS_ST_SW_CHANGE; | |||||
+#ifdef CHELSIO_TLS_OFFLOAD | |||||
+ if (BIO_get_chofld_flag(s->rbio)) | |||||
+ statem_flush(s); | |||||
+#endif | |||||
return WRITE_TRAN_CONTINUE; | |||||
case TLS_ST_SW_CHANGE: | |||||
diff --git ssl/t1_enc.c ssl/t1_enc.c | |||||
index 2db913fb06..d7c90873af 100644 | |||||
--- ssl/t1_enc.c | |||||
+++ ssl/t1_enc.c | |||||
@@ -10,6 +10,7 @@ | |||||
#include <stdio.h> | |||||
#include "ssl_locl.h" | |||||
+#include "ssl_ofld.h" | |||||
#include <openssl/comp.h> | |||||
#include <openssl/evp.h> | |||||
#include <openssl/kdf.h> | |||||
@@ -98,6 +99,7 @@ int tls1_change_cipher_state(SSL *s, int which) | |||||
EVP_PKEY *mac_key; | |||||
size_t n, i, j, k, cl; | |||||
int reuse_dd = 0; | |||||
+ BIO *wbio; | |||||
c = s->s3->tmp.new_sym_enc; | |||||
m = s->s3->tmp.new_hash; | |||||
@@ -318,6 +320,22 @@ int tls1_change_cipher_state(SSL *s, int which) | |||||
} | |||||
s->statem.enc_write_state = ENC_WRITE_STATE_VALID; | |||||
+#ifdef CHELSIO_TLS_OFFLOAD | |||||
+ wbio = s->wbio; | |||||
+ if (!wbio) | |||||
+ goto skip_offload; | |||||
+ | |||||
+ if (which == SSL3_CHANGE_CIPHER_SERVER_WRITE) { | |||||
+ chssl_program_hwkey_context(s, SSL3_CC_WRITE, SSL_ST_ACCEPT); | |||||
+ //statem_flush(s); | |||||
+ } else if (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) { | |||||
+ chssl_program_hwkey_context(s, SSL3_CC_WRITE, SSL_ST_CONNECT); | |||||
+ //statem_flush(s); | |||||
+ } | |||||
+ | |||||
+skip_offload: | |||||
+#endif | |||||
+ | |||||
#ifdef SSL_DEBUG | |||||
printf("which = %04X\nkey=", which); | |||||
{ |