Latest update
This commit is contained in:
+82
-34
@@ -743,6 +743,18 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
s->s3->empty_fragment_done = 1;
|
||||
}
|
||||
|
||||
if (BIO_get_ktls_send(s->wbio)) {
|
||||
/*
|
||||
* ktls doesn't modify the buffer, but to avoid a warning we need to
|
||||
* discard the const qualifier.
|
||||
* This doesn't leak memory because the buffers have been released when
|
||||
* switching to ktls.
|
||||
*/
|
||||
SSL3_BUFFER_set_buf(&s->rlayer.wbuf[0], (unsigned char *)buf);
|
||||
SSL3_BUFFER_set_offset(&s->rlayer.wbuf[0], 0);
|
||||
goto wpacket_init_complete;
|
||||
}
|
||||
|
||||
if (create_empty_fragment) {
|
||||
wb = &s->rlayer.wbuf[0];
|
||||
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
|
||||
@@ -812,6 +824,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
}
|
||||
}
|
||||
|
||||
wpacket_init_complete:
|
||||
|
||||
totlen = 0;
|
||||
/* Clear our SSL3_RECORD structures */
|
||||
memset(wr, 0, sizeof(wr));
|
||||
@@ -853,15 +867,19 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
if (s->compress != NULL)
|
||||
maxcomplen += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
|
||||
|
||||
/* write the header */
|
||||
if (!WPACKET_put_bytes_u8(thispkt, rectype)
|
||||
/*
|
||||
* When using offload kernel will write the header.
|
||||
* Otherwise write the header now
|
||||
*/
|
||||
if (!BIO_get_ktls_send(s->wbio)
|
||||
&& (!WPACKET_put_bytes_u8(thispkt, rectype)
|
||||
|| !WPACKET_put_bytes_u16(thispkt, version)
|
||||
|| !WPACKET_start_sub_packet_u16(thispkt)
|
||||
|| (eivlen > 0
|
||||
&& !WPACKET_allocate_bytes(thispkt, eivlen, NULL))
|
||||
|| (maxcomplen > 0
|
||||
&& !WPACKET_reserve_bytes(thispkt, maxcomplen,
|
||||
&compressdata))) {
|
||||
&compressdata)))) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
@@ -887,12 +905,16 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (!WPACKET_memcpy(thispkt, thiswr->input, thiswr->length)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
if (BIO_get_ktls_send(s->wbio)) {
|
||||
SSL3_RECORD_reset_data(&wr[j]);
|
||||
} else {
|
||||
if (!WPACKET_memcpy(thispkt, thiswr->input, thiswr->length)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
SSL3_RECORD_reset_input(&wr[j]);
|
||||
}
|
||||
SSL3_RECORD_reset_input(&wr[j]);
|
||||
}
|
||||
|
||||
if (SSL_TREAT_AS_TLS13(s)
|
||||
@@ -967,24 +989,26 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
* This will be at most one cipher block or the tag length if using
|
||||
* AEAD. SSL_RT_MAX_CIPHER_BLOCK_SIZE covers either case.
|
||||
*/
|
||||
if (!WPACKET_reserve_bytes(thispkt, SSL_RT_MAX_CIPHER_BLOCK_SIZE,
|
||||
NULL)
|
||||
/*
|
||||
* We also need next the amount of bytes written to this
|
||||
* sub-packet
|
||||
*/
|
||||
if (!BIO_get_ktls_send(s->wbio)) {
|
||||
if (!WPACKET_reserve_bytes(thispkt,
|
||||
SSL_RT_MAX_CIPHER_BLOCK_SIZE,
|
||||
NULL)
|
||||
/*
|
||||
* We also need next the amount of bytes written to this
|
||||
* sub-packet
|
||||
*/
|
||||
|| !WPACKET_get_length(thispkt, &len)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Get a pointer to the start of this record excluding header */
|
||||
recordstart = WPACKET_get_curr(thispkt) - len;
|
||||
SSL3_RECORD_set_data(thiswr, recordstart);
|
||||
SSL3_RECORD_reset_input(thiswr);
|
||||
SSL3_RECORD_set_length(thiswr, len);
|
||||
}
|
||||
|
||||
/* Get a pointer to the start of this record excluding header */
|
||||
recordstart = WPACKET_get_curr(thispkt) - len;
|
||||
|
||||
SSL3_RECORD_set_data(thiswr, recordstart);
|
||||
SSL3_RECORD_reset_input(thiswr);
|
||||
SSL3_RECORD_set_length(thiswr, len);
|
||||
}
|
||||
|
||||
if (s->statem.enc_write_state == ENC_WRITE_STATE_WRITE_PLAIN_ALERTS) {
|
||||
@@ -1000,12 +1024,14 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
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,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
if (!BIO_get_ktls_send(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,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1015,13 +1041,17 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
thispkt = &pkt[j];
|
||||
thiswr = &wr[j];
|
||||
|
||||
if (BIO_get_ktls_send(s->wbio))
|
||||
goto mac_done;
|
||||
|
||||
/* Allocate bytes for the encryption overhead */
|
||||
if (!WPACKET_get_length(thispkt, &origlen)
|
||||
/* Encryption should never shrink the data! */
|
||||
|| origlen > thiswr->length
|
||||
|| (thiswr->length > origlen
|
||||
&& !WPACKET_allocate_bytes(thispkt,
|
||||
thiswr->length - origlen, NULL))) {
|
||||
thiswr->length - origlen,
|
||||
NULL))) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
@@ -1066,13 +1096,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* we should now have thiswr->data pointing to the encrypted data, which
|
||||
* is thiswr->length long
|
||||
*/
|
||||
SSL3_RECORD_set_type(thiswr, type); /* not needed but helps for
|
||||
* debugging */
|
||||
SSL3_RECORD_add_length(thiswr, SSL3_RT_HEADER_LENGTH);
|
||||
/* header is added by the kernel when using offload */
|
||||
SSL3_RECORD_add_length(&wr[j], SSL3_RT_HEADER_LENGTH);
|
||||
|
||||
if (create_empty_fragment) {
|
||||
/*
|
||||
@@ -1089,6 +1114,14 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
||||
return 1;
|
||||
}
|
||||
|
||||
mac_done:
|
||||
/*
|
||||
* we should now have thiswr->data pointing to the encrypted data, which
|
||||
* is thiswr->length long
|
||||
*/
|
||||
SSL3_RECORD_set_type(thiswr, type); /* not needed but helps for
|
||||
* debugging */
|
||||
|
||||
/* now let's set up wb */
|
||||
SSL3_BUFFER_set_left(&s->rlayer.wbuf[j],
|
||||
prefix_len + SSL3_RECORD_get_length(thiswr));
|
||||
@@ -1142,6 +1175,21 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len,
|
||||
clear_sys_error();
|
||||
if (s->wbio != NULL) {
|
||||
s->rwstate = SSL_WRITING;
|
||||
|
||||
/*
|
||||
* To prevent coalescing of control and data messages,
|
||||
* such as in buffer_write, we flush the BIO
|
||||
*/
|
||||
if (BIO_get_ktls_send(s->wbio) && type != SSL3_RT_APPLICATION_DATA) {
|
||||
i = BIO_flush(s->wbio);
|
||||
if (i <= 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
if (BIO_get_ktls_send(s->wbio)
|
||||
&& type != SSL3_RT_APPLICATION_DATA) {
|
||||
BIO_set_ktls_ctrl_msg(s->wbio, type);
|
||||
}
|
||||
/* TODO(size_t): Convert this call */
|
||||
i = BIO_write(s->wbio, (char *)
|
||||
&(SSL3_BUFFER_get_buf(&wb[currbuf])
|
||||
|
||||
@@ -88,6 +88,7 @@ int ssl3_release_write_buffer(SSL *s);
|
||||
#define SSL3_RECORD_get_input(r) ((r)->input)
|
||||
#define SSL3_RECORD_set_input(r, i) ((r)->input = (i))
|
||||
#define SSL3_RECORD_reset_input(r) ((r)->input = (r)->data)
|
||||
#define SSL3_RECORD_reset_data(r) ((r)->data = (r)->input)
|
||||
#define SSL3_RECORD_get_seq_num(r) ((r)->seq_num)
|
||||
#define SSL3_RECORD_get_off(r) ((r)->off)
|
||||
#define SSL3_RECORD_set_off(r, o) ((r)->off = (o))
|
||||
|
||||
+18
-13
@@ -111,23 +111,27 @@ int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len)
|
||||
for (currpipe = 0; currpipe < numwpipes; currpipe++) {
|
||||
SSL3_BUFFER *thiswb = &wb[currpipe];
|
||||
|
||||
if (thiswb->buf != NULL && thiswb->len != len) {
|
||||
if (thiswb->len != len) {
|
||||
OPENSSL_free(thiswb->buf);
|
||||
thiswb->buf = NULL; /* force reallocation */
|
||||
}
|
||||
|
||||
if (thiswb->buf == NULL) {
|
||||
p = OPENSSL_malloc(len);
|
||||
if (p == NULL) {
|
||||
s->rlayer.numwpipes = currpipe;
|
||||
/*
|
||||
* We've got a malloc failure, and we're still initialising
|
||||
* buffers. We assume we're so doomed that we won't even be able
|
||||
* to send an alert.
|
||||
*/
|
||||
SSLfatal(s, SSL_AD_NO_ALERT,
|
||||
SSL_F_SSL3_SETUP_WRITE_BUFFER, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
if (s->wbio == NULL || !BIO_get_ktls_send(s->wbio)) {
|
||||
p = OPENSSL_malloc(len);
|
||||
if (p == NULL) {
|
||||
s->rlayer.numwpipes = currpipe;
|
||||
/*
|
||||
* We've got a malloc failure, and we're still initialising
|
||||
* buffers. We assume we're so doomed that we won't even be able
|
||||
* to send an alert.
|
||||
*/
|
||||
SSLfatal(s, SSL_AD_NO_ALERT,
|
||||
SSL_F_SSL3_SETUP_WRITE_BUFFER, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
p = NULL;
|
||||
}
|
||||
memset(thiswb, 0, sizeof(SSL3_BUFFER));
|
||||
thiswb->buf = p;
|
||||
@@ -160,7 +164,8 @@ int ssl3_release_write_buffer(SSL *s)
|
||||
while (pipes > 0) {
|
||||
wb = &RECORD_LAYER_get_wbuf(&s->rlayer)[pipes - 1];
|
||||
|
||||
OPENSSL_free(wb->buf);
|
||||
if (s->wbio == NULL || !BIO_get_ktls_send(s->wbio))
|
||||
OPENSSL_free(wb->buf);
|
||||
wb->buf = NULL;
|
||||
pipes--;
|
||||
}
|
||||
|
||||
+27
-2
@@ -22,6 +22,7 @@
|
||||
#include <openssl/ct.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/refcount.h"
|
||||
#include "internal/ktls.h"
|
||||
|
||||
static int ssl_undefined_function_1(SSL *ssl, SSL3_RECORD *r, size_t s, int t)
|
||||
{
|
||||
@@ -1211,11 +1212,15 @@ void SSL_free(SSL *s)
|
||||
dane_final(&s->dane);
|
||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
|
||||
|
||||
RECORD_LAYER_release(&s->rlayer);
|
||||
|
||||
/* Ignore return value */
|
||||
ssl_free_wbio_buffer(s);
|
||||
|
||||
BIO_free_all(s->wbio);
|
||||
s->wbio = NULL;
|
||||
BIO_free_all(s->rbio);
|
||||
s->rbio = NULL;
|
||||
|
||||
BUF_MEM_free(s->init_buf);
|
||||
|
||||
@@ -1267,8 +1272,6 @@ void SSL_free(SSL *s)
|
||||
if (s->method != NULL)
|
||||
s->method->ssl_free(s);
|
||||
|
||||
RECORD_LAYER_release(&s->rlayer);
|
||||
|
||||
SSL_CTX_free(s->ctx);
|
||||
|
||||
ASYNC_WAIT_CTX_free(s->waitctx);
|
||||
@@ -1408,6 +1411,15 @@ int SSL_set_fd(SSL *s, int fd)
|
||||
}
|
||||
BIO_set_fd(bio, fd, BIO_NOCLOSE);
|
||||
SSL_set_bio(s, bio, bio);
|
||||
#ifndef OPENSSL_NO_KTLS
|
||||
/*
|
||||
* The new socket is created successfully regardless of ktls_enable.
|
||||
* ktls_enable doesn't change any functionality of the socket, except
|
||||
* changing the setsockopt to enable the processing of ktls_start.
|
||||
* Thus, it is not a problem to call it for non-TLS sockets.
|
||||
*/
|
||||
ktls_enable(fd);
|
||||
#endif /* OPENSSL_NO_KTLS */
|
||||
ret = 1;
|
||||
err:
|
||||
return ret;
|
||||
@@ -1427,6 +1439,15 @@ int SSL_set_wfd(SSL *s, int fd)
|
||||
}
|
||||
BIO_set_fd(bio, fd, BIO_NOCLOSE);
|
||||
SSL_set0_wbio(s, bio);
|
||||
#ifndef OPENSSL_NO_KTLS
|
||||
/*
|
||||
* The new socket is created successfully regardless of ktls_enable.
|
||||
* ktls_enable doesn't change any functionality of the socket, except
|
||||
* changing the setsockopt to enable the processing of ktls_start.
|
||||
* Thus, it is not a problem to call it for non-TLS sockets.
|
||||
*/
|
||||
ktls_enable(fd);
|
||||
#endif /* OPENSSL_NO_KTLS */
|
||||
} else {
|
||||
BIO_up_ref(rbio);
|
||||
SSL_set0_wbio(s, rbio);
|
||||
@@ -2252,6 +2273,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
|
||||
if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
|
||||
return 0;
|
||||
#ifndef OPENSSL_NO_KTLS
|
||||
if (s->wbio != NULL && BIO_get_ktls_send(s->wbio))
|
||||
return 0;
|
||||
#endif /* OPENSSL_NO_KTLS */
|
||||
s->max_send_fragment = larg;
|
||||
if (s->max_send_fragment < s->split_send_fragment)
|
||||
s->split_send_fragment = s->max_send_fragment;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
# include "internal/dane.h"
|
||||
# include "internal/refcount.h"
|
||||
# include "internal/tsan_assist.h"
|
||||
# include "internal/bio.h"
|
||||
|
||||
# ifdef OPENSSL_BUILD_SHLIBSSL
|
||||
# undef OPENSSL_EXTERN
|
||||
|
||||
@@ -10,10 +10,14 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ssl_locl.h"
|
||||
#include "record/record_locl.h"
|
||||
#include "internal/ktls.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/comp.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
|
||||
/* seed1 through seed5 are concatenated */
|
||||
static int tls1_PRF(SSL *s,
|
||||
@@ -98,6 +102,11 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
EVP_PKEY *mac_key;
|
||||
size_t n, i, j, k, cl;
|
||||
int reuse_dd = 0;
|
||||
#ifndef OPENSSL_NO_KTLS
|
||||
struct tls12_crypto_info_aes_gcm_128 crypto_info;
|
||||
BIO *wbio;
|
||||
unsigned char geniv[12];
|
||||
#endif
|
||||
|
||||
c = s->s3->tmp.new_sym_enc;
|
||||
m = s->s3->tmp.new_hash;
|
||||
@@ -319,6 +328,68 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
#ifndef OPENSSL_NO_KTLS
|
||||
if (s->compress)
|
||||
goto skip_ktls;
|
||||
|
||||
if ((which & SSL3_CC_READ) ||
|
||||
((which & SSL3_CC_WRITE) && (s->mode & SSL_MODE_NO_KTLS_TX)))
|
||||
goto skip_ktls;
|
||||
|
||||
/* ktls supports only the maximum fragment size */
|
||||
if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH)
|
||||
goto skip_ktls;
|
||||
|
||||
/* check that cipher is AES_GCM_128 */
|
||||
if (EVP_CIPHER_nid(c) != NID_aes_128_gcm
|
||||
|| EVP_CIPHER_mode(c) != EVP_CIPH_GCM_MODE
|
||||
|| EVP_CIPHER_key_length(c) != TLS_CIPHER_AES_GCM_128_KEY_SIZE)
|
||||
goto skip_ktls;
|
||||
|
||||
/* check version is 1.2 */
|
||||
if (s->version != TLS1_2_VERSION)
|
||||
goto skip_ktls;
|
||||
|
||||
wbio = s->wbio;
|
||||
if (!ossl_assert(wbio != NULL)) {
|
||||
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* All future data will get encrypted by ktls. Flush the BIO or skip ktls */
|
||||
if (BIO_flush(wbio) <= 0)
|
||||
goto skip_ktls;
|
||||
|
||||
/* ktls doesn't support renegotiation */
|
||||
if (BIO_get_ktls_send(s->wbio)) {
|
||||
SSLfatal(s, SSL_AD_NO_RENEGOTIATION, SSL_F_TLS1_CHANGE_CIPHER_STATE,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
memset(&crypto_info, 0, sizeof(crypto_info));
|
||||
crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128;
|
||||
crypto_info.info.version = s->version;
|
||||
|
||||
EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV,
|
||||
EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN,
|
||||
geniv);
|
||||
memcpy(crypto_info.iv, geniv + EVP_GCM_TLS_FIXED_IV_LEN,
|
||||
TLS_CIPHER_AES_GCM_128_IV_SIZE);
|
||||
memcpy(crypto_info.salt, geniv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
|
||||
memcpy(crypto_info.key, key, EVP_CIPHER_key_length(c));
|
||||
memcpy(crypto_info.rec_seq, &s->rlayer.write_sequence,
|
||||
TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
|
||||
|
||||
/* ktls works with user provided buffers directly */
|
||||
if (BIO_set_ktls(wbio, &crypto_info, which & SSL3_CC_WRITE)) {
|
||||
ssl3_release_write_buffer(s);
|
||||
SSL_set_options(s, SSL_OP_NO_RENEGOTIATION);
|
||||
}
|
||||
|
||||
skip_ktls:
|
||||
#endif /* OPENSSL_NO_KTLS */
|
||||
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
|
||||
|
||||
#ifdef SSL_DEBUG
|
||||
|
||||
Reference in New Issue
Block a user