Changeset View
Changeset View
Standalone View
Standalone View
security/openssl/files/extra-patch-ktls
diff --git CHANGES CHANGES | diff --git CHANGES CHANGES | ||||
index 9d58cb0c58..6484e7ea52 100644 | index a5522e5fa5..98961effc0 100644 | ||||
--- CHANGES | --- CHANGES | ||||
+++ CHANGES | +++ CHANGES | ||||
@@ -556,6 +556,11 @@ | @@ -606,6 +606,11 @@ | ||||
necessary to configure just to create a source distribution. | necessary to configure just to create a source distribution. | ||||
[Richard Levitte] | [Richard Levitte] | ||||
+ *) Added support for Linux Kernel TLS data-path. The Linux Kernel data-path | + *) Added support for Linux Kernel TLS data-path. The Linux Kernel data-path | ||||
+ improves application performance by removing data copies and providing | + improves application performance by removing data copies and providing | ||||
+ applications with zero-copy system calls such as sendfile and splice. | + applications with zero-copy system calls such as sendfile and splice. | ||||
+ [Boris Pismenny] | + [Boris Pismenny] | ||||
+ | + | ||||
Changes between 1.1.1 and 1.1.1a [20 Nov 2018] | Changes between 1.1.1 and 1.1.1a [20 Nov 2018] | ||||
*) Timing vulnerability in DSA signature generation | *) Timing vulnerability in DSA signature generation | ||||
diff --git Configure Configure | diff --git Configure Configure | ||||
index faf57b155a..2759ba6433 100755 | index 4bea49d7da..e656814a7f 100755 | ||||
--- Configure | --- Configure | ||||
+++ Configure | +++ Configure | ||||
@@ -341,6 +341,7 @@ my @dtls = qw(dtls1 dtls1_2); | @@ -341,6 +341,7 @@ my @dtls = qw(dtls1 dtls1_2); | ||||
# For developers: keep it sorted alphabetically | # For developers: keep it sorted alphabetically | ||||
my @disablables = ( | my @disablables = ( | ||||
+ "ktls", | + "ktls", | ||||
"afalgeng", | "afalgeng", | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
+ accelerators if any are available on the system. | + accelerators if any are available on the system. | ||||
+ This option will be forced off on systems that do not support | + This option will be forced off on systems that do not support | ||||
+ the Kernel TLS data-path. | + the Kernel TLS data-path. | ||||
+ | + | ||||
enable-asan | enable-asan | ||||
Build with the Address sanitiser. This is a developer option | Build with the Address sanitiser. This is a developer option | ||||
only. It may not work on all platforms and should never be | only. It may not work on all platforms and should never be | ||||
diff --git apps/s_client.c apps/s_client.c | diff --git apps/s_client.c apps/s_client.c | ||||
index 121cd1444f..aa5841cd08 100644 | index 00effc8037..5664e7e04e 100644 | ||||
--- apps/s_client.c | --- apps/s_client.c | ||||
+++ apps/s_client.c | +++ apps/s_client.c | ||||
@@ -3284,6 +3284,12 @@ static void print_stuff(BIO *bio, SSL *s, int full) | @@ -3295,6 +3295,12 @@ static void print_stuff(BIO *bio, SSL *s, int full) | ||||
BIO_printf(bio, "Expansion: %s\n", | BIO_printf(bio, "Expansion: %s\n", | ||||
expansion ? SSL_COMP_get_name(expansion) : "NONE"); | expansion ? SSL_COMP_get_name(expansion) : "NONE"); | ||||
#endif | #endif | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+ if (BIO_get_ktls_send(SSL_get_wbio(s))) | + if (BIO_get_ktls_send(SSL_get_wbio(s))) | ||||
+ BIO_printf(bio_err, "Using Kernel TLS for sending\n"); | + BIO_printf(bio_err, "Using Kernel TLS for sending\n"); | ||||
+ if (BIO_get_ktls_recv(SSL_get_rbio(s))) | + if (BIO_get_ktls_recv(SSL_get_rbio(s))) | ||||
+ BIO_printf(bio_err, "Using Kernel TLS for receiving\n"); | + BIO_printf(bio_err, "Using Kernel TLS for receiving\n"); | ||||
▲ Show 20 Lines • Show All 291 Lines • ▼ Show 20 Lines | |||||
+ return 0; | + return 0; | ||||
+ memcpy(ptr, gctx->iv, arg); | + memcpy(ptr, gctx->iv, arg); | ||||
+ return 1; | + return 1; | ||||
+ | + | ||||
case EVP_CTRL_GCM_SET_IV_FIXED: | case EVP_CTRL_GCM_SET_IV_FIXED: | ||||
/* Special case: -1 length restores whole IV */ | /* Special case: -1 length restores whole IV */ | ||||
if (arg == -1) { | if (arg == -1) { | ||||
diff --git doc/man3/BIO_ctrl.pod doc/man3/BIO_ctrl.pod | diff --git doc/man3/BIO_ctrl.pod doc/man3/BIO_ctrl.pod | ||||
index 2e438c3ce9..31b18b2879 100644 | index cf6ba135df..fc51173c8d 100644 | ||||
--- doc/man3/BIO_ctrl.pod | --- doc/man3/BIO_ctrl.pod | ||||
+++ doc/man3/BIO_ctrl.pod | +++ doc/man3/BIO_ctrl.pod | ||||
@@ -5,7 +5,8 @@ | @@ -5,7 +5,8 @@ | ||||
BIO_ctrl, BIO_callback_ctrl, BIO_ptr_ctrl, BIO_int_ctrl, BIO_reset, | BIO_ctrl, BIO_callback_ctrl, BIO_ptr_ctrl, BIO_int_ctrl, BIO_reset, | ||||
BIO_seek, BIO_tell, BIO_flush, BIO_eof, BIO_set_close, BIO_get_close, | BIO_seek, BIO_tell, BIO_flush, BIO_eof, BIO_set_close, BIO_get_close, | ||||
BIO_pending, BIO_wpending, BIO_ctrl_pending, BIO_ctrl_wpending, | BIO_pending, BIO_wpending, BIO_ctrl_pending, BIO_ctrl_wpending, | ||||
-BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb | -BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb | ||||
+BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb, BIO_get_ktls_send, | +BIO_get_info_callback, BIO_set_info_callback, BIO_info_cb, BIO_get_ktls_send, | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
+=head1 HISTORY | +=head1 HISTORY | ||||
+ | + | ||||
+The BIO_get_ktls_send() and BIO_get_ktls_recv() functions were added in | +The BIO_get_ktls_send() and BIO_get_ktls_recv() functions were added in | ||||
+OpenSSL 3.0.0. | +OpenSSL 3.0.0. | ||||
+ | + | ||||
=head1 COPYRIGHT | =head1 COPYRIGHT | ||||
Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. | Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. | ||||
diff --git doc/man3/SSL_CONF_cmd.pod doc/man3/SSL_CONF_cmd.pod | diff --git doc/man3/SSL_CONF_cmd.pod doc/man3/SSL_CONF_cmd.pod | ||||
index 900c4f3a56..a3f447a986 100644 | index 7f0e088687..c7cce5486b 100644 | ||||
--- doc/man3/SSL_CONF_cmd.pod | --- doc/man3/SSL_CONF_cmd.pod | ||||
+++ doc/man3/SSL_CONF_cmd.pod | +++ doc/man3/SSL_CONF_cmd.pod | ||||
@@ -495,6 +495,10 @@ specification. Some applications may be able to mitigate the replay risks in | @@ -495,6 +495,10 @@ specification. Some applications may be able to mitigate the replay risks in | ||||
other ways and in such cases the built-in OpenSSL functionality is not required. | other ways and in such cases the built-in OpenSSL functionality is not required. | ||||
Disabling anti-replay is equivalent to setting B<SSL_OP_NO_ANTI_REPLAY>. | Disabling anti-replay is equivalent to setting B<SSL_OP_NO_ANTI_REPLAY>. | ||||
+B<KTLS>: Enables kernel TLS if support has been compiled in, and it is supported | +B<KTLS>: Enables kernel TLS if support has been compiled in, and it is supported | ||||
+by the negotiated ciphersuites and extensions. Equivalent to | +by the negotiated ciphersuites and extensions. Equivalent to | ||||
▲ Show 20 Lines • Show All 763 Lines • ▼ Show 20 Lines | @@ -13,3 +14,7 @@ SOURCE[../libssl]=\ | ||||
record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \ | record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \ | ||||
statem/statem.c record/ssl3_record_tls13.c | statem/statem.c record/ssl3_record_tls13.c | ||||
+ | + | ||||
+IF[{- !$disabled{ktls} -}] | +IF[{- !$disabled{ktls} -}] | ||||
+ SOURCE[../libssl]=ktls.c | + SOURCE[../libssl]=ktls.c | ||||
+ENDIF | +ENDIF | ||||
diff --git ssl/ktls.c ssl/ktls.c | diff --git ssl/ktls.c ssl/ktls.c | ||||
new file mode 100644 | new file mode 100644 | ||||
index 0000000000..c7a440b79b | index 0000000000..68482ac480 | ||||
--- /dev/null | --- /dev/null | ||||
+++ ssl/ktls.c | +++ ssl/ktls.c | ||||
@@ -0,0 +1,251 @@ | @@ -0,0 +1,321 @@ | ||||
+/* | +/* | ||||
+ * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. | + * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. | ||||
+ * | + * | ||||
+ * Licensed under the Apache License 2.0 (the "License"). You may not use | + * Licensed under the Apache License 2.0 (the "License"). You may not use | ||||
+ * this file except in compliance with the License. You can obtain a copy | + * this file except in compliance with the License. You can obtain a copy | ||||
+ * in the file LICENSE in the source distribution or at | + * in the file LICENSE in the source distribution or at | ||||
+ * https://www.openssl.org/source/license.html | + * https://www.openssl.org/source/license.html | ||||
+ */ | + */ | ||||
+ | + | ||||
+#include "ssl_local.h" | +#include "ssl_local.h" | ||||
+#include "internal/ktls.h" | +#include "internal/ktls.h" | ||||
+ | + | ||||
+#ifndef OPENSSL_NO_KTLS_RX | |||||
+ /* | |||||
+ * Count the number of records that were not processed yet from record boundary. | |||||
+ * | |||||
+ * This function assumes that there are only fully formed records read in the | |||||
+ * record layer. If read_ahead is enabled, then this might be false and this | |||||
+ * function will fail. | |||||
+ */ | |||||
+static int count_unprocessed_records(SSL *s) | |||||
+{ | |||||
+ SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); | |||||
+ PACKET pkt, subpkt; | |||||
+ int count = 0; | |||||
+ | |||||
+ if (!PACKET_buf_init(&pkt, rbuf->buf + rbuf->offset, rbuf->left)) | |||||
+ return -1; | |||||
+ | |||||
+ while (PACKET_remaining(&pkt) > 0) { | |||||
+ /* Skip record type and version */ | |||||
+ if (!PACKET_forward(&pkt, 3)) | |||||
+ return -1; | |||||
+ | |||||
+ /* Read until next record */ | |||||
+ if (!PACKET_get_length_prefixed_2(&pkt, &subpkt)) | |||||
+ return -1; | |||||
+ | |||||
+ count += 1; | |||||
+ } | |||||
+ | |||||
+ return count; | |||||
+} | |||||
+ | |||||
+/* | |||||
+ * The kernel cannot offload receive if a partial TLS record has been read. | |||||
+ * Check the read buffer for unprocessed records. If the buffer contains a | |||||
+ * partial record, fail and return 0. Otherwise, update the sequence | |||||
+ * number at *rec_seq for the count of unprocessed records and return 1. | |||||
+ */ | |||||
+static int check_rx_read_ahead(SSL *s, unsigned char *rec_seq) | |||||
+{ | |||||
+ int bit, count_unprocessed; | |||||
+ | |||||
+ count_unprocessed = count_unprocessed_records(s); | |||||
+ if (count_unprocessed < 0) | |||||
+ return 0; | |||||
+ | |||||
+ /* increment the crypto_info record sequence */ | |||||
+ while (count_unprocessed) { | |||||
+ for (bit = 7; bit >= 0; bit--) { /* increment */ | |||||
+ ++rec_seq[bit]; | |||||
+ if (rec_seq[bit] != 0) | |||||
+ break; | |||||
+ } | |||||
+ count_unprocessed--; | |||||
+ | |||||
+ } | |||||
+ | |||||
+ return 1; | |||||
+} | |||||
+#endif | |||||
+ | |||||
+#if defined(__FreeBSD__) | +#if defined(__FreeBSD__) | ||||
+# include <crypto/cryptodev.h> | +# include <crypto/cryptodev.h> | ||||
+ | + | ||||
+/*- | +/*- | ||||
+ * Check if a given cipher is supported by the KTLS interface. | + * Check if a given cipher is supported by the KTLS interface. | ||||
+ * The kernel might still fail the setsockopt() if no suitable | + * The kernel might still fail the setsockopt() if no suitable | ||||
+ * provider is found, but this checks if the socket option | + * provider is found, but this checks if the socket option | ||||
+ * supports the cipher suite used at all. | + * supports the cipher suite used at all. | ||||
Show All 33 Lines | |||||
+ return 0; | + return 0; | ||||
+ } | + } | ||||
+ default: | + default: | ||||
+ return 0; | + return 0; | ||||
+ } | + } | ||||
+} | +} | ||||
+ | + | ||||
+/* Function to configure kernel TLS structure */ | +/* Function to configure kernel TLS structure */ | ||||
+int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, | +int ktls_configure_crypto(SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, | ||||
+ void *rl_sequence, ktls_crypto_info_t *crypto_info, | + void *rl_sequence, ktls_crypto_info_t *crypto_info, | ||||
+ unsigned char **rec_seq, unsigned char *iv, | + int is_tx, unsigned char *iv, | ||||
+ unsigned char *key, unsigned char *mac_key, | + unsigned char *key, unsigned char *mac_key, | ||||
+ size_t mac_secret_size) | + size_t mac_secret_size) | ||||
+{ | +{ | ||||
+ memset(crypto_info, 0, sizeof(*crypto_info)); | + memset(crypto_info, 0, sizeof(*crypto_info)); | ||||
+ switch (s->s3->tmp.new_cipher->algorithm_enc) { | + switch (s->s3->tmp.new_cipher->algorithm_enc) { | ||||
+ case SSL_AES128GCM: | + case SSL_AES128GCM: | ||||
+ case SSL_AES256GCM: | + case SSL_AES256GCM: | ||||
+ crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16; | + crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16; | ||||
Show All 33 Lines | |||||
+ } | + } | ||||
+ crypto_info->cipher_key = key; | + crypto_info->cipher_key = key; | ||||
+ crypto_info->cipher_key_len = EVP_CIPHER_key_length(c); | + crypto_info->cipher_key_len = EVP_CIPHER_key_length(c); | ||||
+ crypto_info->iv = iv; | + crypto_info->iv = iv; | ||||
+ crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff; | + crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff; | ||||
+ crypto_info->tls_vminor = (s->version & 0x000000ff); | + crypto_info->tls_vminor = (s->version & 0x000000ff); | ||||
+# ifdef TCP_RXTLS_ENABLE | +# ifdef TCP_RXTLS_ENABLE | ||||
+ memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq)); | + memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq)); | ||||
+ if (rec_seq != NULL) | + if (!is_tx && !check_rx_read_ahead(s, crypto_info->rec_seq)) | ||||
+ *rec_seq = crypto_info->rec_seq; | + return 0; | ||||
+# else | +# else | ||||
+ if (rec_seq != NULL) | + if (!is_tx) | ||||
+ *rec_seq = NULL; | + return 0; | ||||
+# endif | +# endif | ||||
+ return 1; | + return 1; | ||||
+}; | +}; | ||||
+ | + | ||||
+#endif /* __FreeBSD__ */ | +#endif /* __FreeBSD__ */ | ||||
+ | + | ||||
+#if defined(OPENSSL_SYS_LINUX) | +#if defined(OPENSSL_SYS_LINUX) | ||||
+ | + | ||||
+/* Function to check supported ciphers in Linux */ | +/* Function to check supported ciphers in Linux */ | ||||
+int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, | +int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, | ||||
+ const EVP_CIPHER_CTX *dd) | + const EVP_CIPHER_CTX *dd) | ||||
+{ | +{ | ||||
+ switch (s->version) { | + switch (s->version) { | ||||
+ case TLS1_2_VERSION: | + case TLS1_2_VERSION: | ||||
+ case TLS1_3_VERSION: | + case TLS1_3_VERSION: | ||||
+ break; | + break; | ||||
+ default: | + default: | ||||
+ return 0; | + return 0; | ||||
+ } | + } | ||||
+ | + | ||||
+ /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 | + /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 | ||||
+ * or Chacha20-Poly1305 | + * or Chacha20-Poly1305 | ||||
+ */ | + */ | ||||
+ switch (EVP_CIPHER_nid(c)) | |||||
+ { | |||||
+# ifdef OPENSSL_KTLS_AES_CCM_128 | +# ifdef OPENSSL_KTLS_AES_CCM_128 | ||||
+ case NID_aes_128_ccm: | + if (EVP_CIPHER_is_a(c, "AES-128-CCM")) { | ||||
+ if (EVP_CIPHER_CTX_tag_length(dd) != EVP_CCM_TLS_TAG_LEN) | + if (s->version == TLS_1_3_VERSION /* broken on 5.x kernels */ | ||||
+ || EVP_CIPHER_CTX_get_tag_length(dd) != EVP_CCM_TLS_TAG_LEN) | |||||
+ return 0; | + return 0; | ||||
+ return 1; | |||||
+ } else | |||||
+# endif | +# endif | ||||
+ if (0 | |||||
+# ifdef OPENSSL_KTLS_AES_GCM_128 | +# ifdef OPENSSL_KTLS_AES_GCM_128 | ||||
+ /* Fall through */ | + || EVP_CIPHER_is_a(c, "AES-128-GCM") | ||||
+ case NID_aes_128_gcm: | |||||
+# endif | +# endif | ||||
+# ifdef OPENSSL_KTLS_AES_GCM_256 | +# ifdef OPENSSL_KTLS_AES_GCM_256 | ||||
+ case NID_aes_256_gcm: | + || EVP_CIPHER_is_a(c, "AES-256-GCM") | ||||
+# endif | +# endif | ||||
+# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 | +# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 | ||||
+ case NID_chacha20_poly1305: | + || EVP_CIPHER_is_a(c, "ChaCha20-Poly1305") | ||||
+# endif | +# endif | ||||
+ ) { | |||||
+ return 1; | + return 1; | ||||
+ default: | + } | ||||
+ return 0; | + return 0; | ||||
+ } | +} | ||||
+} | |||||
+ | + | ||||
+/* Function to configure kernel TLS structure */ | +/* Function to configure kernel TLS structure */ | ||||
+int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, | +int ktls_configure_crypto(SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, | ||||
+ void *rl_sequence, ktls_crypto_info_t *crypto_info, | + void *rl_sequence, ktls_crypto_info_t *crypto_info, | ||||
+ unsigned char **rec_seq, unsigned char *iv, | + int is_tx, unsigned char *iv, | ||||
+ unsigned char *key, unsigned char *mac_key, | + unsigned char *key, unsigned char *mac_key, | ||||
+ size_t mac_secret_size) | + size_t mac_secret_size) | ||||
+{ | +{ | ||||
+ unsigned char geniv[12]; | + unsigned char geniv[12]; | ||||
+ unsigned char *iiv = iv; | + unsigned char *iiv = iv; | ||||
+ | + | ||||
+# ifdef OPENSSL_NO_KTLS_RX | |||||
+ if (!is_tx) | |||||
+ return 0; | |||||
+# endif | |||||
+ | |||||
+ if (s->version == TLS1_2_VERSION && | + if (s->version == TLS1_2_VERSION && | ||||
+ EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { | + EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { | ||||
+ EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV, | + EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV, | ||||
+ EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN, | + EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN, | ||||
+ geniv); | + geniv); | ||||
+ iiv = geniv; | + iiv = geniv; | ||||
+ } | + } | ||||
+ | + | ||||
+ memset(crypto_info, 0, sizeof(*crypto_info)); | + memset(crypto_info, 0, sizeof(*crypto_info)); | ||||
+ switch (EVP_CIPHER_nid(c)) | + switch (EVP_CIPHER_nid(c)) | ||||
+ { | + { | ||||
+# ifdef OPENSSL_KTLS_AES_GCM_128 | +# ifdef OPENSSL_KTLS_AES_GCM_128 | ||||
+ case NID_aes_128_gcm: | + case NID_aes_128_gcm: | ||||
+ crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128; | + crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128; | ||||
+ crypto_info->gcm128.info.version = s->version; | + crypto_info->gcm128.info.version = s->version; | ||||
+ crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128); | + crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128); | ||||
+ memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, | + memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, | ||||
+ TLS_CIPHER_AES_GCM_128_IV_SIZE); | + TLS_CIPHER_AES_GCM_128_IV_SIZE); | ||||
+ memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); | + memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); | ||||
+ memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_key_length(c)); | + memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_key_length(c)); | ||||
+ memcpy(crypto_info->gcm128.rec_seq, rl_sequence, | + memcpy(crypto_info->gcm128.rec_seq, rl_sequence, | ||||
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); | + TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); | ||||
+ if (rec_seq != NULL) | + if (!is_tx && !check_rx_read_ahead(s, crypto_info->gcm128.rec_seq)) | ||||
+ *rec_seq = crypto_info->gcm128.rec_seq; | + return 0; | ||||
+ return 1; | + return 1; | ||||
+# endif | +# endif | ||||
+# ifdef OPENSSL_KTLS_AES_GCM_256 | +# ifdef OPENSSL_KTLS_AES_GCM_256 | ||||
+ case NID_aes_256_gcm: | + case NID_aes_256_gcm: | ||||
+ crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256; | + crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256; | ||||
+ crypto_info->gcm256.info.version = s->version; | + crypto_info->gcm256.info.version = s->version; | ||||
+ crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256); | + crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256); | ||||
+ memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, | + memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, | ||||
+ TLS_CIPHER_AES_GCM_256_IV_SIZE); | + TLS_CIPHER_AES_GCM_256_IV_SIZE); | ||||
+ memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE); | + memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE); | ||||
+ memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_key_length(c)); | + memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_key_length(c)); | ||||
+ memcpy(crypto_info->gcm256.rec_seq, rl_sequence, | + memcpy(crypto_info->gcm256.rec_seq, rl_sequence, | ||||
+ TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); | + TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); | ||||
+ if (rec_seq != NULL) | + if (!is_tx && !check_rx_read_ahead(s, crypto_info->gcm256.rec_seq)) | ||||
+ *rec_seq = crypto_info->gcm256.rec_seq; | + return 0; | ||||
+ return 1; | + return 1; | ||||
+# endif | +# endif | ||||
+# ifdef OPENSSL_KTLS_AES_CCM_128 | +# ifdef OPENSSL_KTLS_AES_CCM_128 | ||||
+ case NID_aes_128_ccm: | + case NID_aes_128_ccm: | ||||
+ crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128; | + crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128; | ||||
+ crypto_info->ccm128.info.version = s->version; | + crypto_info->ccm128.info.version = s->version; | ||||
+ crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128); | + crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128); | ||||
+ memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN, | + memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN, | ||||
+ TLS_CIPHER_AES_CCM_128_IV_SIZE); | + TLS_CIPHER_AES_CCM_128_IV_SIZE); | ||||
+ memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE); | + memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE); | ||||
+ memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_key_length(c)); | + memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_key_length(c)); | ||||
+ memcpy(crypto_info->ccm128.rec_seq, rl_sequence, | + memcpy(crypto_info->ccm128.rec_seq, rl_sequence, | ||||
+ TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); | + TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); | ||||
+ if (rec_seq != NULL) | + if (!is_tx && !check_rx_read_ahead(s, crypto_info->ccm128.rec_seq)) | ||||
+ *rec_seq = crypto_info->ccm128.rec_seq; | + return 0; | ||||
+ return 1; | + return 1; | ||||
+# endif | +# endif | ||||
+# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 | +# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 | ||||
+ case NID_chacha20_poly1305: | + case NID_chacha20_poly1305: | ||||
+ crypto_info->chacha20poly1305.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305; | + crypto_info->chacha20poly1305.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305; | ||||
+ crypto_info->chacha20poly1305.info.version = s->version; | + crypto_info->chacha20poly1305.info.version = s->version; | ||||
+ crypto_info->tls_crypto_info_len = sizeof(crypto_info->chacha20poly1305); | + crypto_info->tls_crypto_info_len = sizeof(crypto_info->chacha20poly1305); | ||||
+ memcpy(crypto_info->chacha20poly1305.iv, iiv, | + memcpy(crypto_info->chacha20poly1305.iv, iiv, | ||||
+ TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE); | + TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE); | ||||
+ memcpy(crypto_info->chacha20poly1305.key, key, EVP_CIPHER_key_length(c)); | + memcpy(crypto_info->chacha20poly1305.key, key, | ||||
+ EVP_CIPHER_get_key_length(c)); | |||||
+ memcpy(crypto_info->chacha20poly1305.rec_seq, rl_sequence, | + memcpy(crypto_info->chacha20poly1305.rec_seq, rl_sequence, | ||||
+ TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE); | + TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE); | ||||
+ if (rec_seq != NULL) | + if (!is_tx | ||||
+ *rec_seq = crypto_info->chacha20poly1305.rec_seq; | + && !check_rx_read_ahead(s, | ||||
+ crypto_info->chacha20poly1305.rec_seq)) | |||||
+ return 0; | |||||
+ return 1; | + return 1; | ||||
+# endif | +# endif | ||||
+ default: | + default: | ||||
+ return 0; | + return 0; | ||||
+ } | + } | ||||
+ | + | ||||
+} | +} | ||||
+ | + | ||||
▲ Show 20 Lines • Show All 347 Lines • ▼ Show 20 Lines | |||||
+ if (SSL3_BUFFER_is_app_buffer(wb)) | + if (SSL3_BUFFER_is_app_buffer(wb)) | ||||
+ SSL3_BUFFER_set_app_buffer(wb, 0); | + SSL3_BUFFER_set_app_buffer(wb, 0); | ||||
+ else | + else | ||||
+ OPENSSL_free(wb->buf); | + OPENSSL_free(wb->buf); | ||||
wb->buf = NULL; | wb->buf = NULL; | ||||
pipes--; | pipes--; | ||||
} | } | ||||
diff --git ssl/record/ssl3_record.c ssl/record/ssl3_record.c | diff --git ssl/record/ssl3_record.c ssl/record/ssl3_record.c | ||||
index f158544789..9dda123d44 100644 | index f158544789..da549995e0 100644 | ||||
--- ssl/record/ssl3_record.c | --- ssl/record/ssl3_record.c | ||||
+++ ssl/record/ssl3_record.c | +++ ssl/record/ssl3_record.c | ||||
@@ -186,9 +186,11 @@ int ssl3_get_record(SSL *s) | @@ -186,6 +186,7 @@ int ssl3_get_record(SSL *s) | ||||
size_t num_recs = 0, max_recs, j; | size_t num_recs = 0, max_recs, j; | ||||
PACKET pkt, sslv2pkt; | PACKET pkt, sslv2pkt; | ||||
size_t first_rec_len; | size_t first_rec_len; | ||||
+ int is_ktls_left; | + int using_ktls; | ||||
rr = RECORD_LAYER_get_rrec(&s->rlayer); | rr = RECORD_LAYER_get_rrec(&s->rlayer); | ||||
rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); | rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); | ||||
+ is_ktls_left = (rbuf->left > 0); | @@ -194,6 +195,12 @@ int ssl3_get_record(SSL *s) | ||||
max_recs = s->max_pipelines; | |||||
if (max_recs == 0) | |||||
max_recs = 1; | max_recs = 1; | ||||
@@ -207,8 +209,32 @@ int ssl3_get_record(SSL *s) | sess = s->session; | ||||
+ /* | |||||
+ * KTLS reads full records. If there is any data left, | |||||
+ * then it is from before enabling ktls. | |||||
+ */ | |||||
+ using_ktls = BIO_get_ktls_recv(s->rbio) && SSL3_BUFFER_get_left(rbuf) == 0; | |||||
+ | |||||
do { | |||||
thisrr = &rr[num_recs]; | |||||
@@ -207,8 +214,32 @@ int ssl3_get_record(SSL *s) | |||||
rret = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, | rret = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, | ||||
SSL3_BUFFER_get_len(rbuf), 0, | SSL3_BUFFER_get_len(rbuf), 0, | ||||
num_recs == 0 ? 1 : 0, &n); | num_recs == 0 ? 1 : 0, &n); | ||||
- if (rret <= 0) | - if (rret <= 0) | ||||
- return rret; /* error or non-blocking */ | - return rret; /* error or non-blocking */ | ||||
+ if (rret <= 0) { | + if (rret <= 0) { | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+ if (!BIO_get_ktls_recv(s->rbio) || rret == 0) | + if (!BIO_get_ktls_recv(s->rbio) || rret == 0) | ||||
Show All 18 Lines | |||||
+ break; | + break; | ||||
+ } | + } | ||||
+#endif | +#endif | ||||
+ return rret; | + return rret; | ||||
+ } | + } | ||||
RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY); | RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY); | ||||
p = RECORD_LAYER_get_packet(&s->rlayer); | p = RECORD_LAYER_get_packet(&s->rlayer); | ||||
@@ -386,7 +412,7 @@ int ssl3_get_record(SSL *s) | @@ -339,7 +370,9 @@ int ssl3_get_record(SSL *s) | ||||
} | |||||
} | |||||
- if (SSL_IS_TLS13(s) && s->enc_read_ctx != NULL) { | |||||
+ if (SSL_IS_TLS13(s) | |||||
+ && s->enc_read_ctx != NULL | |||||
+ && !using_ktls) { | |||||
if (thisrr->type != SSL3_RT_APPLICATION_DATA | |||||
&& (thisrr->type != SSL3_RT_CHANGE_CIPHER_SPEC | |||||
|| !SSL_IS_FIRST_HANDSHAKE(s)) | |||||
@@ -369,7 +402,13 @@ int ssl3_get_record(SSL *s) | |||||
} | |||||
if (SSL_IS_TLS13(s)) { | |||||
- if (thisrr->length > SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH) { | |||||
+ size_t len = SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH; | |||||
+ | |||||
+ /* KTLS strips the inner record type. */ | |||||
+ if (using_ktls) | |||||
+ len = SSL3_RT_MAX_ENCRYPTED_LENGTH; | |||||
+ | |||||
+ if (thisrr->length > len) { | |||||
SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, | |||||
SSL_R_ENCRYPTED_LENGTH_TOO_LONG); | |||||
return -1; | |||||
@@ -386,6 +425,10 @@ int ssl3_get_record(SSL *s) | |||||
len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD; | len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD; | ||||
#endif | #endif | ||||
- if (thisrr->length > len) { | + /* KTLS may use all of the buffer */ | ||||
+ if (thisrr->length > len && !BIO_get_ktls_recv(s->rbio)) { | + if (using_ktls) | ||||
+ len = SSL3_BUFFER_get_left(rbuf); | |||||
+ | |||||
if (thisrr->length > len) { | |||||
SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, | SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, | ||||
SSL_R_ENCRYPTED_LENGTH_TOO_LONG); | SSL_R_ENCRYPTED_LENGTH_TOO_LONG); | ||||
return -1; | @@ -404,6 +447,7 @@ int ssl3_get_record(SSL *s) | ||||
@@ -404,6 +430,7 @@ int ssl3_get_record(SSL *s) | |||||
} else { | } else { | ||||
more = thisrr->length; | more = thisrr->length; | ||||
} | } | ||||
+ | + | ||||
if (more > 0) { | if (more > 0) { | ||||
/* now s->rlayer.packet_length == SSL3_RT_HEADER_LENGTH */ | /* now s->rlayer.packet_length == SSL3_RT_HEADER_LENGTH */ | ||||
@@ -491,6 +518,13 @@ int ssl3_get_record(SSL *s) | @@ -491,6 +535,9 @@ int ssl3_get_record(SSL *s) | ||||
return 1; | return 1; | ||||
} | } | ||||
+ /* | + if (using_ktls) | ||||
+ * KTLS reads full records. If there is any data left, | |||||
+ * then it is from before enabling ktls | |||||
+ */ | |||||
+ if (BIO_get_ktls_recv(s->rbio) && !is_ktls_left) | |||||
+ goto skip_decryption; | + goto skip_decryption; | ||||
+ | + | ||||
/* | /* | ||||
* If in encrypt-then-mac mode calculate mac from encrypted record. All | * If in encrypt-then-mac mode calculate mac from encrypted record. All | ||||
* the details below are public so no timing details can leak. | * the details below are public so no timing details can leak. | ||||
@@ -678,6 +712,8 @@ int ssl3_get_record(SSL *s) | @@ -678,6 +725,8 @@ int ssl3_get_record(SSL *s) | ||||
return -1; | return -1; | ||||
} | } | ||||
+ skip_decryption: | + skip_decryption: | ||||
+ | + | ||||
for (j = 0; j < num_recs; j++) { | for (j = 0; j < num_recs; j++) { | ||||
thisrr = &rr[j]; | thisrr = &rr[j]; | ||||
@@ -739,7 +775,7 @@ int ssl3_get_record(SSL *s) | @@ -698,22 +747,30 @@ int ssl3_get_record(SSL *s) | ||||
if (SSL_IS_TLS13(s) | |||||
&& s->enc_read_ctx != NULL | |||||
&& thisrr->type != SSL3_RT_ALERT) { | |||||
- size_t end; | |||||
+ /* | |||||
+ * The following logic are irrelevant in KTLS: the kernel provides | |||||
+ * unprotected record and thus record type represent the actual | |||||
+ * content type, and padding is already removed and thisrr->type and | |||||
+ * thisrr->length should have the correct values. | |||||
+ */ | |||||
+ if (!using_ktls) { | |||||
+ size_t end; | |||||
- if (thisrr->length == 0 | |||||
- || thisrr->type != SSL3_RT_APPLICATION_DATA) { | |||||
- SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_GET_RECORD, | |||||
- SSL_R_BAD_RECORD_TYPE); | |||||
- return -1; | |||||
+ if (thisrr->length == 0 | |||||
+ || thisrr->type != SSL3_RT_APPLICATION_DATA) { | |||||
+ SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, | |||||
+ SSL_F_SSL3_GET_RECORD, SSL_R_BAD_RECORD_TYPE); | |||||
+ return -1; | |||||
+ } | |||||
+ | |||||
+ /* Strip trailing padding */ | |||||
+ for (end = thisrr->length - 1; end > 0 && thisrr->data[end] == 0; | |||||
+ end--) | |||||
+ continue; | |||||
+ | |||||
+ thisrr->length = end; | |||||
+ thisrr->type = thisrr->data[end]; | |||||
} | |||||
- | |||||
- /* Strip trailing padding */ | |||||
- for (end = thisrr->length - 1; end > 0 && thisrr->data[end] == 0; | |||||
- end--) | |||||
- continue; | |||||
- | |||||
- thisrr->length = end; | |||||
- thisrr->type = thisrr->data[end]; | |||||
if (thisrr->type != SSL3_RT_APPLICATION_DATA | |||||
&& thisrr->type != SSL3_RT_ALERT | |||||
&& thisrr->type != SSL3_RT_HANDSHAKE) { | |||||
@@ -723,7 +780,7 @@ int ssl3_get_record(SSL *s) | |||||
} | |||||
if (s->msg_callback) | |||||
s->msg_callback(0, s->version, SSL3_RT_INNER_CONTENT_TYPE, | |||||
- &thisrr->data[end], 1, s, s->msg_callback_arg); | |||||
+ &thisrr->type, 1, s, s->msg_callback_arg); | |||||
} | |||||
/* | |||||
@@ -739,13 +796,25 @@ int ssl3_get_record(SSL *s) | |||||
return -1; | return -1; | ||||
} | } | ||||
- if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH) { | - if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH) { | ||||
+ if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH && !BIO_get_ktls_recv(s->rbio)) { | + /* | ||||
+ * Usually thisrr->length is the length of a single record, but when | |||||
+ * KTLS handles the decryption, thisrr->length may be larger than | |||||
+ * SSL3_RT_MAX_PLAIN_LENGTH because the kernel may have coalesced | |||||
+ * multiple records. | |||||
+ * Therefore we have to rely on KTLS to check the plaintext length | |||||
+ * limit in the kernel. | |||||
+ */ | |||||
+ if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH && !using_ktls) { | |||||
SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, | SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, | ||||
SSL_R_DATA_LENGTH_TOO_LONG); | SSL_R_DATA_LENGTH_TOO_LONG); | ||||
return -1; | return -1; | ||||
@@ -747,7 +783,8 @@ int ssl3_get_record(SSL *s) | } | ||||
/* If received packet overflows current Max Fragment Length setting */ | - /* If received packet overflows current Max Fragment Length setting */ | ||||
+ /* | |||||
+ * Check if the received packet overflows the current | |||||
+ * Max Fragment Length setting. | |||||
+ * Note: USE_MAX_FRAGMENT_LENGTH_EXT and KTLS are mutually exclusive. | |||||
+ */ | |||||
if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session) | if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session) | ||||
- && thisrr->length > GET_MAX_FRAGMENT_LENGTH(s->session)) { | && thisrr->length > GET_MAX_FRAGMENT_LENGTH(s->session)) { | ||||
+ && thisrr->length > GET_MAX_FRAGMENT_LENGTH(s->session) | |||||
+ && !BIO_get_ktls_recv(s->rbio)) { | |||||
SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, | SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, | ||||
SSL_R_DATA_LENGTH_TOO_LONG); | |||||
return -1; | |||||
diff --git ssl/ssl_conf.c ssl/ssl_conf.c | diff --git ssl/ssl_conf.c ssl/ssl_conf.c | ||||
index 0a3fef7c8c..8013c62f07 100644 | index 0a3fef7c8c..8013c62f07 100644 | ||||
--- ssl/ssl_conf.c | --- ssl/ssl_conf.c | ||||
+++ ssl/ssl_conf.c | +++ ssl/ssl_conf.c | ||||
@@ -391,7 +391,8 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) | @@ -391,7 +391,8 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) | ||||
SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX), | SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX), | ||||
SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA), | SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA), | ||||
SSL_FLAG_TBL("MiddleboxCompat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT), | SSL_FLAG_TBL("MiddleboxCompat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT), | ||||
Show All 11 Lines | @@ -313,6 +313,7 @@ static const ERR_STRING_DATA SSL_str_functs[] = { | ||||
"SSL_renegotiate_abbreviated"}, | "SSL_renegotiate_abbreviated"}, | ||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, 0), ""}, | {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, 0), ""}, | ||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, 0), ""}, | {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, 0), ""}, | ||||
+ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SENDFILE, 0), "SSL_sendfile"}, | + {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SENDFILE, 0), "SSL_sendfile"}, | ||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_DUP, 0), "ssl_session_dup"}, | {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_DUP, 0), "ssl_session_dup"}, | ||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_NEW, 0), "SSL_SESSION_new"}, | {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_NEW, 0), "SSL_SESSION_new"}, | ||||
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_PRINT_FP, 0), | {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_PRINT_FP, 0), | ||||
diff --git ssl/ssl_lib.c ssl/ssl_lib.c | diff --git ssl/ssl_lib.c ssl/ssl_lib.c | ||||
index 9c411a3293..ff5a9e0566 100644 | index 25a1a44785..1fbad29b23 100644 | ||||
--- ssl/ssl_lib.c | --- ssl/ssl_lib.c | ||||
+++ ssl/ssl_lib.c | +++ ssl/ssl_lib.c | ||||
@@ -11,6 +11,7 @@ | @@ -11,6 +11,7 @@ | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include "ssl_local.h" | #include "ssl_local.h" | ||||
+#include "e_os.h" | +#include "e_os.h" | ||||
#include <openssl/objects.h> | #include <openssl/objects.h> | ||||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | |||||
+ s->rwstate = SSL_NOTHING; | + s->rwstate = SSL_NOTHING; | ||||
+ return ret; | + return ret; | ||||
+#endif | +#endif | ||||
+} | +} | ||||
+ | + | ||||
int SSL_write(SSL *s, const void *buf, int num) | int SSL_write(SSL *s, const void *buf, int num) | ||||
{ | { | ||||
int ret; | int ret; | ||||
@@ -2212,6 +2298,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) | @@ -2213,6 +2299,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) | ||||
case SSL_CTRL_SET_MAX_SEND_FRAGMENT: | case SSL_CTRL_SET_MAX_SEND_FRAGMENT: | ||||
if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) | if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) | ||||
return 0; | return 0; | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+ if (s->wbio != NULL && BIO_get_ktls_send(s->wbio)) | + if (s->wbio != NULL && BIO_get_ktls_send(s->wbio)) | ||||
+ return 0; | + return 0; | ||||
+#endif /* OPENSSL_NO_KTLS */ | +#endif /* OPENSSL_NO_KTLS */ | ||||
s->max_send_fragment = larg; | s->max_send_fragment = larg; | ||||
if (s->max_send_fragment < s->split_send_fragment) | if (s->max_send_fragment < s->split_send_fragment) | ||||
s->split_send_fragment = s->max_send_fragment; | s->split_send_fragment = s->max_send_fragment; | ||||
@@ -4469,11 +4559,18 @@ int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size) | @@ -4471,11 +4561,18 @@ int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size) | ||||
return 1; | return 1; | ||||
} | } | ||||
-void SSL_set_record_padding_callback(SSL *ssl, | -void SSL_set_record_padding_callback(SSL *ssl, | ||||
+int SSL_set_record_padding_callback(SSL *ssl, | +int SSL_set_record_padding_callback(SSL *ssl, | ||||
size_t (*cb) (SSL *ssl, int type, | size_t (*cb) (SSL *ssl, int type, | ||||
size_t len, void *arg)) | size_t len, void *arg)) | ||||
{ | { | ||||
- ssl->record_padding_cb = cb; | - ssl->record_padding_cb = cb; | ||||
+ BIO *b; | + BIO *b; | ||||
+ | + | ||||
+ b = SSL_get_wbio(ssl); | + b = SSL_get_wbio(ssl); | ||||
+ if (b == NULL || !BIO_get_ktls_send(b)) { | + if (b == NULL || !BIO_get_ktls_send(b)) { | ||||
+ ssl->record_padding_cb = cb; | + ssl->record_padding_cb = cb; | ||||
+ return 1; | + return 1; | ||||
+ } | + } | ||||
+ return 0; | + return 0; | ||||
} | } | ||||
void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg) | void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg) | ||||
diff --git ssl/ssl_local.h ssl/ssl_local.h | diff --git ssl/ssl_local.h ssl/ssl_local.h | ||||
index 9f346e30e8..3c4bf726bc 100644 | index 9f346e30e8..587064cc18 100644 | ||||
--- ssl/ssl_local.h | --- ssl/ssl_local.h | ||||
+++ ssl/ssl_local.h | +++ ssl/ssl_local.h | ||||
@@ -34,6 +34,8 @@ | @@ -34,6 +34,8 @@ | ||||
# include "internal/dane.h" | # include "internal/dane.h" | ||||
# include "internal/refcount.h" | # include "internal/refcount.h" | ||||
# include "internal/tsan_assist.h" | # include "internal/tsan_assist.h" | ||||
+# include "internal/bio.h" | +# include "internal/bio.h" | ||||
+# include "internal/ktls.h" | +# include "internal/ktls.h" | ||||
# ifdef OPENSSL_BUILD_SHLIBSSL | # ifdef OPENSSL_BUILD_SHLIBSSL | ||||
# undef OPENSSL_EXTERN | # undef OPENSSL_EXTERN | ||||
@@ -2617,6 +2619,17 @@ __owur int ssl_log_secret(SSL *ssl, const char *label, | @@ -2617,6 +2619,17 @@ __owur int ssl_log_secret(SSL *ssl, const char *label, | ||||
#define EARLY_EXPORTER_SECRET_LABEL "EARLY_EXPORTER_SECRET" | #define EARLY_EXPORTER_SECRET_LABEL "EARLY_EXPORTER_SECRET" | ||||
#define EXPORTER_SECRET_LABEL "EXPORTER_SECRET" | #define EXPORTER_SECRET_LABEL "EXPORTER_SECRET" | ||||
+# ifndef OPENSSL_NO_KTLS | +# ifndef OPENSSL_NO_KTLS | ||||
+/* ktls.c */ | +/* ktls.c */ | ||||
+int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, | +int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, | ||||
+ const EVP_CIPHER_CTX *dd); | + const EVP_CIPHER_CTX *dd); | ||||
+int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, | +int ktls_configure_crypto(SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, | ||||
+ void *rl_sequence, ktls_crypto_info_t *crypto_info, | + void *rl_sequence, ktls_crypto_info_t *crypto_info, | ||||
+ unsigned char **rec_seq, unsigned char *iv, | + int is_tx, unsigned char *iv, | ||||
+ unsigned char *key, unsigned char *mac_key, | + unsigned char *key, unsigned char *mac_key, | ||||
+ size_t mac_secret_size); | + size_t mac_secret_size); | ||||
+# endif | +# endif | ||||
+ | + | ||||
/* s3_cbc.c */ | /* s3_cbc.c */ | ||||
__owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); | __owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); | ||||
__owur int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, | __owur int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, | ||||
diff --git ssl/t1_enc.c ssl/t1_enc.c | diff --git ssl/t1_enc.c ssl/t1_enc.c | ||||
index c85c0b0310..7d2eb381af 100644 | index f8e53d4efc..46191908ab 100644 | ||||
--- ssl/t1_enc.c | --- ssl/t1_enc.c | ||||
+++ ssl/t1_enc.c | +++ ssl/t1_enc.c | ||||
@@ -10,10 +10,14 @@ | @@ -10,10 +10,14 @@ | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include "ssl_local.h" | #include "ssl_local.h" | ||||
+#include "record/record_local.h" | +#include "record/record_local.h" | ||||
+#include "internal/ktls.h" | +#include "internal/ktls.h" | ||||
+#include "internal/cryptlib.h" | +#include "internal/cryptlib.h" | ||||
#include <openssl/comp.h> | #include <openssl/comp.h> | ||||
#include <openssl/evp.h> | #include <openssl/evp.h> | ||||
#include <openssl/kdf.h> | #include <openssl/kdf.h> | ||||
#include <openssl/rand.h> | #include <openssl/rand.h> | ||||
+#include <openssl/obj_mac.h> | +#include <openssl/obj_mac.h> | ||||
/* seed1 through seed5 are concatenated */ | /* seed1 through seed5 are concatenated */ | ||||
static int tls1_PRF(SSL *s, | static int tls1_PRF(SSL *s, | ||||
@@ -78,6 +82,41 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km, size_t num) | @@ -94,6 +98,11 @@ int tls1_change_cipher_state(SSL *s, int which) | ||||
return ret; | |||||
} | |||||
+#ifndef OPENSSL_NO_KTLS | |||||
+ /* | |||||
+ * Count the number of records that were not processed yet from record boundary. | |||||
+ * | |||||
+ * This function assumes that there are only fully formed records read in the | |||||
+ * record layer. If read_ahead is enabled, then this might be false and this | |||||
+ * function will fail. | |||||
+ */ | |||||
+# ifndef OPENSSL_NO_KTLS_RX | |||||
+static int count_unprocessed_records(SSL *s) | |||||
+{ | |||||
+ SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); | |||||
+ PACKET pkt, subpkt; | |||||
+ int count = 0; | |||||
+ | |||||
+ if (!PACKET_buf_init(&pkt, rbuf->buf + rbuf->offset, rbuf->left)) | |||||
+ return -1; | |||||
+ | |||||
+ while (PACKET_remaining(&pkt) > 0) { | |||||
+ /* Skip record type and version */ | |||||
+ if (!PACKET_forward(&pkt, 3)) | |||||
+ return -1; | |||||
+ | |||||
+ /* Read until next record */ | |||||
+ if (PACKET_get_length_prefixed_2(&pkt, &subpkt)) | |||||
+ return -1; | |||||
+ | |||||
+ count += 1; | |||||
+ } | |||||
+ | |||||
+ return count; | |||||
+} | |||||
+# endif | |||||
+#endif | |||||
+ | |||||
int tls1_change_cipher_state(SSL *s, int which) | |||||
{ | |||||
unsigned char *p, *mac_secret; | |||||
@@ -94,6 +133,16 @@ int tls1_change_cipher_state(SSL *s, int which) | |||||
EVP_PKEY *mac_key; | EVP_PKEY *mac_key; | ||||
size_t n, i, j, k, cl; | size_t n, i, j, k, cl; | ||||
int reuse_dd = 0; | int reuse_dd = 0; | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+ ktls_crypto_info_t crypto_info; | + ktls_crypto_info_t crypto_info; | ||||
+ unsigned char *rec_seq; | |||||
+ void *rl_sequence; | + void *rl_sequence; | ||||
+# ifndef OPENSSL_NO_KTLS_RX | |||||
+ int count_unprocessed; | |||||
+ int bit; | |||||
+# endif | |||||
+ BIO *bio; | + BIO *bio; | ||||
+#endif | +#endif | ||||
c = s->s3->tmp.new_sym_enc; | c = s->s3->tmp.new_sym_enc; | ||||
m = s->s3->tmp.new_hash; | m = s->s3->tmp.new_hash; | ||||
@@ -312,6 +361,81 @@ int tls1_change_cipher_state(SSL *s, int which) | @@ -312,6 +321,62 @@ int tls1_change_cipher_state(SSL *s, int which) | ||||
ERR_R_INTERNAL_ERROR); | ERR_R_INTERNAL_ERROR); | ||||
goto err; | goto err; | ||||
} | } | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+ if (s->compress || (s->options & SSL_OP_ENABLE_KTLS) == 0) | + if (s->compress || (s->options & SSL_OP_ENABLE_KTLS) == 0) | ||||
+ goto skip_ktls; | + goto skip_ktls; | ||||
+ | + | ||||
+ /* ktls supports only the maximum fragment size */ | + /* ktls supports only the maximum fragment size */ | ||||
Show All 29 Lines | |||||
+ goto err; | + goto err; | ||||
+ } | + } | ||||
+ | + | ||||
+ if (which & SSL3_CC_WRITE) | + if (which & SSL3_CC_WRITE) | ||||
+ rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer); | + rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer); | ||||
+ else | + else | ||||
+ rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); | + rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); | ||||
+ | + | ||||
+ if (!ktls_configure_crypto(s, c, dd, rl_sequence, &crypto_info, &rec_seq, | + if (!ktls_configure_crypto(s, c, dd, rl_sequence, &crypto_info, | ||||
+ iv, key, ms, *mac_secret_size)) | + which & SSL3_CC_WRITE, iv, key, ms, | ||||
+ *mac_secret_size)) | |||||
+ goto skip_ktls; | + goto skip_ktls; | ||||
+ | + | ||||
+ if (which & SSL3_CC_READ) { | |||||
+# ifndef OPENSSL_NO_KTLS_RX | |||||
+ count_unprocessed = count_unprocessed_records(s); | |||||
+ if (count_unprocessed < 0) | |||||
+ goto skip_ktls; | |||||
+ | |||||
+ /* increment the crypto_info record sequence */ | |||||
+ while (count_unprocessed) { | |||||
+ for (bit = 7; bit >= 0; bit--) { /* increment */ | |||||
+ ++rec_seq[bit]; | |||||
+ if (rec_seq[bit] != 0) | |||||
+ break; | |||||
+ } | |||||
+ count_unprocessed--; | |||||
+ } | |||||
+# else | |||||
+ goto skip_ktls; | |||||
+# endif | |||||
+ } | |||||
+ | |||||
+ /* ktls works with user provided buffers directly */ | + /* ktls works with user provided buffers directly */ | ||||
+ if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) { | + if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) { | ||||
+ if (which & SSL3_CC_WRITE) | + if (which & SSL3_CC_WRITE) | ||||
+ ssl3_release_write_buffer(s); | + ssl3_release_write_buffer(s); | ||||
+ SSL_set_options(s, SSL_OP_NO_RENEGOTIATION); | + SSL_set_options(s, SSL_OP_NO_RENEGOTIATION); | ||||
+ } | + } | ||||
+ | + | ||||
+ skip_ktls: | + skip_ktls: | ||||
+#endif /* OPENSSL_NO_KTLS */ | +#endif /* OPENSSL_NO_KTLS */ | ||||
s->statem.enc_write_state = ENC_WRITE_STATE_VALID; | s->statem.enc_write_state = ENC_WRITE_STATE_VALID; | ||||
#ifdef SSL_DEBUG | #ifdef SSL_DEBUG | ||||
diff --git ssl/tls13_enc.c ssl/tls13_enc.c | diff --git ssl/tls13_enc.c ssl/tls13_enc.c | ||||
index b8fb07f210..39530237d8 100644 | index b8fb07f210..109227e556 100644 | ||||
--- ssl/tls13_enc.c | --- ssl/tls13_enc.c | ||||
+++ ssl/tls13_enc.c | +++ ssl/tls13_enc.c | ||||
@@ -9,6 +9,8 @@ | @@ -9,6 +9,8 @@ | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include "ssl_local.h" | #include "ssl_local.h" | ||||
+#include "internal/ktls.h" | +#include "internal/ktls.h" | ||||
+#include "record/record_local.h" | +#include "record/record_local.h" | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
@@ -456,6 +455,7 @@ int tls13_change_cipher_state(SSL *s, int which) | @@ -456,6 +455,7 @@ int tls13_change_cipher_state(SSL *s, int which) | ||||
static const unsigned char early_exporter_master_secret[] = "e exp master"; | static const unsigned char early_exporter_master_secret[] = "e exp master"; | ||||
#endif | #endif | ||||
unsigned char *iv; | unsigned char *iv; | ||||
+ unsigned char key[EVP_MAX_KEY_LENGTH]; | + unsigned char key[EVP_MAX_KEY_LENGTH]; | ||||
unsigned char secret[EVP_MAX_MD_SIZE]; | unsigned char secret[EVP_MAX_MD_SIZE]; | ||||
unsigned char hashval[EVP_MAX_MD_SIZE]; | unsigned char hashval[EVP_MAX_MD_SIZE]; | ||||
unsigned char *hash = hashval; | unsigned char *hash = hashval; | ||||
@@ -469,6 +469,10 @@ int tls13_change_cipher_state(SSL *s, int which) | @@ -469,6 +469,11 @@ int tls13_change_cipher_state(SSL *s, int which) | ||||
int ret = 0; | int ret = 0; | ||||
const EVP_MD *md = NULL; | const EVP_MD *md = NULL; | ||||
const EVP_CIPHER *cipher = NULL; | const EVP_CIPHER *cipher = NULL; | ||||
+#if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13) | +#if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13) | ||||
+ ktls_crypto_info_t crypto_info; | + ktls_crypto_info_t crypto_info; | ||||
+ void *rl_sequence; | |||||
+ BIO *bio; | + BIO *bio; | ||||
+#endif | +#endif | ||||
if (which & SSL3_CC_READ) { | if (which & SSL3_CC_READ) { | ||||
if (s->enc_read_ctx != NULL) { | if (s->enc_read_ctx != NULL) { | ||||
@@ -671,9 +675,13 @@ int tls13_change_cipher_state(SSL *s, int which) | @@ -671,9 +676,13 @@ int tls13_change_cipher_state(SSL *s, int which) | ||||
} | } | ||||
} | } | ||||
+ /* check whether cipher is known */ | + /* check whether cipher is known */ | ||||
+ if(!ossl_assert(cipher != NULL)) | + if(!ossl_assert(cipher != NULL)) | ||||
+ goto err; | + goto err; | ||||
+ | + | ||||
if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher, | if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher, | ||||
- insecret, hash, label, labellen, secret, iv, | - insecret, hash, label, labellen, secret, iv, | ||||
- ciph_ctx)) { | - ciph_ctx)) { | ||||
+ insecret, hash, label, labellen, secret, key, | + insecret, hash, label, labellen, secret, key, | ||||
+ iv, ciph_ctx)) { | + iv, ciph_ctx)) { | ||||
/* SSLfatal() already called */ | /* SSLfatal() already called */ | ||||
goto err; | goto err; | ||||
} | } | ||||
@@ -714,8 +722,52 @@ int tls13_change_cipher_state(SSL *s, int which) | @@ -714,8 +723,62 @@ int tls13_change_cipher_state(SSL *s, int which) | ||||
s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS; | s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS; | ||||
else | else | ||||
s->statem.enc_write_state = ENC_WRITE_STATE_VALID; | s->statem.enc_write_state = ENC_WRITE_STATE_VALID; | ||||
+#ifndef OPENSSL_NO_KTLS | +#ifndef OPENSSL_NO_KTLS | ||||
+# if defined(OPENSSL_KTLS_TLS13) | +# if defined(OPENSSL_KTLS_TLS13) | ||||
+ if (!(which & SSL3_CC_WRITE) | + if (!(which & SSL3_CC_APPLICATION) | ||||
+ || !(which & SSL3_CC_APPLICATION) | |||||
+ || (s->options & SSL_OP_ENABLE_KTLS) == 0) | + || (s->options & SSL_OP_ENABLE_KTLS) == 0) | ||||
+ goto skip_ktls; | + goto skip_ktls; | ||||
+ | + | ||||
+ /* ktls supports only the maximum fragment size */ | + /* ktls supports only the maximum fragment size */ | ||||
+ if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) | + if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) | ||||
+ goto skip_ktls; | + goto skip_ktls; | ||||
+ | + | ||||
+ /* ktls does not support record padding */ | + /* ktls does not support record padding */ | ||||
+ if (s->record_padding_cb != NULL) | + if (s->record_padding_cb != NULL) | ||||
+ goto skip_ktls; | + goto skip_ktls; | ||||
+ | + | ||||
+ /* check that cipher is supported */ | + /* check that cipher is supported */ | ||||
+ if (!ktls_check_supported_cipher(s, cipher, ciph_ctx)) | + if (!ktls_check_supported_cipher(s, cipher, ciph_ctx)) | ||||
+ goto skip_ktls; | + goto skip_ktls; | ||||
+ | + | ||||
+ if (which & SSL3_CC_WRITE) | |||||
+ bio = s->wbio; | + bio = s->wbio; | ||||
+ else | |||||
+ bio = s->rbio; | |||||
+ | + | ||||
+ if (!ossl_assert(bio != NULL)) { | + if (!ossl_assert(bio != NULL)) { | ||||
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_CHANGE_CIPHER_STATE, | + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_CHANGE_CIPHER_STATE, | ||||
+ ERR_R_INTERNAL_ERROR); | + ERR_R_INTERNAL_ERROR); | ||||
+ goto err; | + goto err; | ||||
+ } | + } | ||||
+ | + | ||||
+ /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */ | + /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */ | ||||
+ if (which & SSL3_CC_WRITE) { | |||||
+ if (BIO_flush(bio) <= 0) | + if (BIO_flush(bio) <= 0) | ||||
+ goto skip_ktls; | + goto skip_ktls; | ||||
+ } | |||||
+ | + | ||||
+ /* configure kernel crypto structure */ | + /* configure kernel crypto structure */ | ||||
+ if (!ktls_configure_crypto(s, cipher, ciph_ctx, | + if (which & SSL3_CC_WRITE) | ||||
+ RECORD_LAYER_get_write_sequence(&s->rlayer), | + rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer); | ||||
+ &crypto_info, NULL, iv, key, NULL, 0)) | + else | ||||
+ rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); | |||||
+ | |||||
+ if (!ktls_configure_crypto(s, cipher, ciph_ctx, rl_sequence, &crypto_info, | |||||
+ which & SSL3_CC_WRITE, iv, key, NULL, 0)) | |||||
+ goto skip_ktls; | + goto skip_ktls; | ||||
+ | + | ||||
+ /* ktls works with user provided buffers directly */ | + /* ktls works with user provided buffers directly */ | ||||
+ if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) | + if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) { | ||||
+ if (which & SSL3_CC_WRITE) | |||||
+ ssl3_release_write_buffer(s); | + ssl3_release_write_buffer(s); | ||||
+ } | |||||
+skip_ktls: | +skip_ktls: | ||||
+# endif | +# endif | ||||
+#endif | +#endif | ||||
ret = 1; | ret = 1; | ||||
err: | err: | ||||
+ OPENSSL_cleanse(key, sizeof(key)); | + OPENSSL_cleanse(key, sizeof(key)); | ||||
OPENSSL_cleanse(secret, sizeof(secret)); | OPENSSL_cleanse(secret, sizeof(secret)); | ||||
return ret; | return ret; | ||||
} | } | ||||
@@ -729,6 +781,7 @@ int tls13_update_key(SSL *s, int sending) | @@ -729,6 +792,7 @@ int tls13_update_key(SSL *s, int sending) | ||||
#endif | #endif | ||||
const EVP_MD *md = ssl_handshake_md(s); | const EVP_MD *md = ssl_handshake_md(s); | ||||
size_t hashlen = EVP_MD_size(md); | size_t hashlen = EVP_MD_size(md); | ||||
+ unsigned char key[EVP_MAX_KEY_LENGTH]; | + unsigned char key[EVP_MAX_KEY_LENGTH]; | ||||
unsigned char *insecret, *iv; | unsigned char *insecret, *iv; | ||||
unsigned char secret[EVP_MAX_MD_SIZE]; | unsigned char secret[EVP_MAX_MD_SIZE]; | ||||
EVP_CIPHER_CTX *ciph_ctx; | EVP_CIPHER_CTX *ciph_ctx; | ||||
@@ -753,8 +806,8 @@ int tls13_update_key(SSL *s, int sending) | @@ -753,8 +817,8 @@ int tls13_update_key(SSL *s, int sending) | ||||
if (!derive_secret_key_and_iv(s, sending, ssl_handshake_md(s), | if (!derive_secret_key_and_iv(s, sending, ssl_handshake_md(s), | ||||
s->s3->tmp.new_sym_enc, insecret, NULL, | s->s3->tmp.new_sym_enc, insecret, NULL, | ||||
application_traffic, | application_traffic, | ||||
- sizeof(application_traffic) - 1, secret, iv, | - sizeof(application_traffic) - 1, secret, iv, | ||||
- ciph_ctx)) { | - ciph_ctx)) { | ||||
+ sizeof(application_traffic) - 1, secret, key, | + sizeof(application_traffic) - 1, secret, key, | ||||
+ iv, ciph_ctx)) { | + iv, ciph_ctx)) { | ||||
/* SSLfatal() already called */ | /* SSLfatal() already called */ | ||||
goto err; | goto err; | ||||
} | } | ||||
@@ -764,6 +817,7 @@ int tls13_update_key(SSL *s, int sending) | @@ -764,6 +828,7 @@ int tls13_update_key(SSL *s, int sending) | ||||
s->statem.enc_write_state = ENC_WRITE_STATE_VALID; | s->statem.enc_write_state = ENC_WRITE_STATE_VALID; | ||||
ret = 1; | ret = 1; | ||||
err: | err: | ||||
+ OPENSSL_cleanse(key, sizeof(key)); | + OPENSSL_cleanse(key, sizeof(key)); | ||||
OPENSSL_cleanse(secret, sizeof(secret)); | OPENSSL_cleanse(secret, sizeof(secret)); | ||||
return ret; | return ret; | ||||
} | } | ||||
diff --git test/build.info test/build.info | diff --git test/build.info test/build.info | ||||
index 726bd22127..201d5d6191 100644 | index 6357a7f2fe..3b8d5ee765 100644 | ||||
--- test/build.info | --- test/build.info | ||||
+++ test/build.info | +++ test/build.info | ||||
@@ -546,7 +546,7 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN | @@ -546,7 +546,7 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN | ||||
# We disable this test completely in a shared build because it deliberately | # We disable this test completely in a shared build because it deliberately | ||||
# redefines some internal libssl symbols. This doesn't work in a non-shared | # redefines some internal libssl symbols. This doesn't work in a non-shared | ||||
# build | # build | ||||
- IF[{- !$disabled{shared} -}] | - IF[{- !$disabled{shared} -}] | ||||
+ IF[{- !$disabled{shared} && $disabled{ktls} -}] | + IF[{- !$disabled{shared} && $disabled{ktls} -}] | ||||
PROGRAMS_NO_INST=tls13secretstest | PROGRAMS_NO_INST=tls13secretstest | ||||
SOURCE[tls13secretstest]=tls13secretstest.c | SOURCE[tls13secretstest]=tls13secretstest.c | ||||
SOURCE[tls13secretstest]= ../ssl/tls13_enc.c ../ssl/packet.c | SOURCE[tls13secretstest]= ../ssl/tls13_enc.c ../ssl/packet.c | ||||
diff --git test/recipes/80-test_ssl_old.t test/recipes/80-test_ssl_old.t | |||||
index 19772f61ef..f3cfda0507 100644 | |||||
--- test/recipes/80-test_ssl_old.t | |||||
+++ test/recipes/80-test_ssl_old.t | |||||
@@ -327,11 +327,9 @@ sub testssl { | |||||
} | |||||
- # plan tests => 11; | |||||
- | |||||
subtest 'standard SSL tests' => sub { | |||||
- ###################################################################### | |||||
- plan tests => 13; | |||||
+ ###################################################################### | |||||
+ plan tests => 19; | |||||
SKIP: { | |||||
skip "SSLv3 is not supported by this OpenSSL build", 4 | |||||
@@ -356,8 +354,8 @@ sub testssl { | |||||
} | |||||
SKIP: { | |||||
- skip "Neither SSLv3 nor any TLS version are supported by this OpenSSL build", 8 | |||||
- if $no_anytls; | |||||
+ skip "Neither SSLv3 nor any TLS version are supported by this OpenSSL build", 14 | |||||
+ if $no_anytls; | |||||
SKIP: { | |||||
skip "skipping test of sslv2/sslv3 w/o (EC)DHE test", 1 if $dsa_cert; | |||||
@@ -378,17 +376,29 @@ sub testssl { | |||||
'test sslv2/sslv3 with both client and server authentication via BIO pair and app verify'); | |||||
SKIP: { | |||||
- skip "No IPv4 available on this machine", 1 | |||||
+ skip "No IPv4 available on this machine", 4 | |||||
unless !disabled("sock") && have_IPv4(); | |||||
ok(run(test([@ssltest, "-ipv4"])), | |||||
'test TLS via IPv4'); | |||||
+ ok(run(test([@ssltest, "-ipv4", "-client_ktls"])), | |||||
+ 'test TLS via IPv4 + ktls(client)'); | |||||
+ ok(run(test([@ssltest, "-ipv4", "-server_ktls"])), | |||||
+ 'test TLS via IPv4 + ktls(server)'); | |||||
+ ok(run(test([@ssltest, "-ipv4", "-client_ktls", "-server_ktls"])), | |||||
+ 'test TLS via IPv4 + ktls'); | |||||
} | |||||
SKIP: { | |||||
- skip "No IPv6 available on this machine", 1 | |||||
+ skip "No IPv6 available on this machine", 4 | |||||
unless !disabled("sock") && have_IPv6(); | |||||
ok(run(test([@ssltest, "-ipv6"])), | |||||
'test TLS via IPv6'); | |||||
+ ok(run(test([@ssltest, "-ipv6", "-client_ktls"])), | |||||
+ 'test TLS via IPv6 + ktls(client)'); | |||||
+ ok(run(test([@ssltest, "-ipv6", "-server_ktls"])), | |||||
+ 'test TLS via IPv6 + ktls(client)'); | |||||
+ ok(run(test([@ssltest, "-ipv6", "-client_ktls", "-server_ktls"])), | |||||
+ 'test TLS via IPv6 + ktls'); | |||||
} | |||||
} | |||||
}; | |||||
diff --git test/recipes/90-test_tls13secrets.t test/recipes/90-test_tls13secrets.t | diff --git test/recipes/90-test_tls13secrets.t test/recipes/90-test_tls13secrets.t | ||||
index 5490885309..3478e540ed 100644 | index 5490885309..3478e540ed 100644 | ||||
--- test/recipes/90-test_tls13secrets.t | --- test/recipes/90-test_tls13secrets.t | ||||
+++ test/recipes/90-test_tls13secrets.t | +++ test/recipes/90-test_tls13secrets.t | ||||
@@ -13,7 +13,7 @@ my $test_name = "tls13secrets"; | @@ -13,7 +13,7 @@ my $test_name = "tls13secrets"; | ||||
setup($test_name); | setup($test_name); | ||||
plan skip_all => "$test_name is not supported in this build" | plan skip_all => "$test_name is not supported in this build" | ||||
- if disabled("tls1_3") || disabled("shared"); | - if disabled("tls1_3") || disabled("shared"); | ||||
+ if disabled("tls1_3") || disabled("shared") || !disabled("ktls"); | + if disabled("tls1_3") || disabled("shared") || !disabled("ktls"); | ||||
plan tests => 1; | plan tests => 1; | ||||
diff --git test/sslapitest.c test/sslapitest.c | diff --git test/sslapitest.c test/sslapitest.c | ||||
index 21322ceec5..a8a0327765 100644 | index 6b5d9449a0..47ba76f0a5 100644 | ||||
--- test/sslapitest.c | --- test/sslapitest.c | ||||
+++ test/sslapitest.c | +++ test/sslapitest.c | ||||
@@ -7,6 +7,7 @@ | @@ -7,6 +7,7 @@ | ||||
* https://www.openssl.org/source/license.html | * https://www.openssl.org/source/license.html | ||||
*/ | */ | ||||
+#include <stdio.h> | +#include <stdio.h> | ||||
#include <string.h> | #include <string.h> | ||||
▲ Show 20 Lines • Show All 197 Lines • ▼ Show 20 Lines | |||||
+ } else { | + } else { | ||||
+ if (BIO_get_ktls_send(serverssl->wbio)) | + if (BIO_get_ktls_send(serverssl->wbio)) | ||||
+ ktls_used = 1; | + ktls_used = 1; | ||||
+ } | + } | ||||
+ | + | ||||
+#if defined(OPENSSL_NO_KTLS_RX) | +#if defined(OPENSSL_NO_KTLS_RX) | ||||
+ rx_supported = 0; | + rx_supported = 0; | ||||
+#else | +#else | ||||
+ rx_supported = (tls_version != TLS1_3_VERSION); | + rx_supported = 1; | ||||
+#endif | +#endif | ||||
+ if (!cis_ktls || !rx_supported) { | + if (!cis_ktls || !rx_supported) { | ||||
+ if (!TEST_false(BIO_get_ktls_recv(clientssl->rbio))) | + if (!TEST_false(BIO_get_ktls_recv(clientssl->rbio))) | ||||
+ goto end; | + goto end; | ||||
+ } else { | + } else { | ||||
+ if (BIO_get_ktls_send(clientssl->rbio)) | + if (BIO_get_ktls_send(clientssl->rbio)) | ||||
+ ktls_used = 1; | + ktls_used = 1; | ||||
+ } | + } | ||||
▲ Show 20 Lines • Show All 229 Lines • ▼ Show 20 Lines | |||||
+ | + | ||||
+ return execute_test_ktls_sendfile(cipher->tls_version, cipher->cipher); | + return execute_test_ktls_sendfile(cipher->tls_version, cipher->cipher); | ||||
+} | +} | ||||
+#endif | +#endif | ||||
+ | + | ||||
static int test_large_message_tls(void) | static int test_large_message_tls(void) | ||||
{ | { | ||||
return execute_test_large_message(TLS_server_method(), TLS_client_method(), | return execute_test_large_message(TLS_server_method(), TLS_client_method(), | ||||
@@ -6881,6 +7311,12 @@ int setup_tests(void) | @@ -6944,6 +7374,12 @@ int setup_tests(void) | ||||
return 0; | return 0; | ||||
} | } | ||||
+#if !defined(OPENSSL_NO_KTLS) && !defined(OPENSSL_NO_SOCK) | +#if !defined(OPENSSL_NO_KTLS) && !defined(OPENSSL_NO_SOCK) | ||||
+# if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3) | +# if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3) | ||||
+ ADD_ALL_TESTS(test_ktls, NUM_KTLS_TEST_CIPHERS * 4); | + ADD_ALL_TESTS(test_ktls, NUM_KTLS_TEST_CIPHERS * 4); | ||||
+ ADD_ALL_TESTS(test_ktls_sendfile, NUM_KTLS_TEST_CIPHERS); | + ADD_ALL_TESTS(test_ktls_sendfile, NUM_KTLS_TEST_CIPHERS); | ||||
+# endif | +# endif | ||||
+#endif | +#endif | ||||
ADD_TEST(test_large_message_tls); | ADD_TEST(test_large_message_tls); | ||||
ADD_TEST(test_large_message_tls_read_ahead); | ADD_TEST(test_large_message_tls_read_ahead); | ||||
#ifndef OPENSSL_NO_DTLS | #ifndef OPENSSL_NO_DTLS | ||||
diff --git test/ssltest_old.c test/ssltest_old.c | |||||
index 3601066b50..96b38a4636 100644 | |||||
--- test/ssltest_old.c | |||||
+++ test/ssltest_old.c | |||||
@@ -731,6 +731,8 @@ static void sv_usage(void) | |||||
fprintf(stderr, " -client_sess_in <file> - Read the client session from a file\n"); | |||||
fprintf(stderr, " -should_reuse <number> - The expected state of reusing the session\n"); | |||||
fprintf(stderr, " -no_ticket - do not issue TLS session ticket\n"); | |||||
+ fprintf(stderr, " -client_ktls - try to enable client KTLS\n"); | |||||
+ fprintf(stderr, " -server_ktls - try to enable server KTLS\n"); | |||||
} | |||||
static void print_key_details(BIO *out, EVP_PKEY *key) | |||||
@@ -905,6 +907,7 @@ int main(int argc, char *argv[]) | |||||
int number = 1, reuse = 0; | |||||
int should_reuse = -1; | |||||
int no_ticket = 0; | |||||
+ int client_ktls = 0, server_ktls = 0; | |||||
long bytes = 256L; | |||||
#ifndef OPENSSL_NO_DH | |||||
DH *dh; | |||||
@@ -1215,6 +1218,10 @@ int main(int argc, char *argv[]) | |||||
should_reuse = !!atoi(*(++argv)); | |||||
} else if (strcmp(*argv, "-no_ticket") == 0) { | |||||
no_ticket = 1; | |||||
+ } else if (strcmp(*argv, "-client_ktls") == 0) { | |||||
+ client_ktls = 1; | |||||
+ } else if (strcmp(*argv, "-server_ktls") == 0) { | |||||
+ server_ktls = 1; | |||||
} else { | |||||
int rv; | |||||
arg = argv[0]; | |||||
@@ -1760,6 +1767,10 @@ int main(int argc, char *argv[]) | |||||
if (sn_client) | |||||
SSL_set_tlsext_host_name(c_ssl, sn_client); | |||||
+ if (client_ktls) | |||||
+ SSL_set_options(c_ssl, SSL_OP_ENABLE_KTLS); | |||||
+ if (server_ktls) | |||||
+ SSL_set_options(s_ssl, SSL_OP_ENABLE_KTLS); | |||||
if (!set_protocol_version(server_min_proto, s_ssl, SSL_CTRL_SET_MIN_PROTO_VERSION)) | |||||
goto end; | |||||
diff --git test/ssltestlib.c test/ssltestlib.c | diff --git test/ssltestlib.c test/ssltestlib.c | ||||
index 456afdf471..a13fdbc4cc 100644 | index 456afdf471..a13fdbc4cc 100644 | ||||
--- test/ssltestlib.c | --- test/ssltestlib.c | ||||
+++ test/ssltestlib.c | +++ test/ssltestlib.c | ||||
@@ -16,6 +16,14 @@ | @@ -16,6 +16,14 @@ | ||||
#ifdef OPENSSL_SYS_UNIX | #ifdef OPENSSL_SYS_UNIX | ||||
# include <unistd.h> | # include <unistd.h> | ||||
▲ Show 20 Lines • Show All 161 Lines • Show Last 20 Lines |