The branch master has been updated via a6d36303e91b79379da2e2ffaa608dba704d3eb8 (commit) via da4db1602d8f7f031f12ddc04de84129138c419c (commit) via cc10b56dbe29e4f254ad1f3abc7ca5216c3069e6 (commit) via 4ffccf6c4deebd6f3ab5d46234c64f957ff1c1c5 (commit) via 95badfeb60603b1bbcfc4d0fef555aed06038d55 (commit) via f434bfaccf033989c765621fdd975ec1bc29c80a (commit) via 996a6ac32bc4dd02098b68445b71f8fa286ef91b (commit) from c8636ebf4a951447754d446810349618ddc77a60 (commit)
- Log ----------------------------------------------------------------- commit a6d36303e91b79379da2e2ffaa608dba704d3eb8 Author: Vadim Fedorenko <vadimj...@gmail.com> Date: Mon May 4 13:46:04 2020 +0300 TLSv1.3: additional checks in SSL_set_record_padding_callback Reviewed-by: Paul Dale <paul.d...@oracle.com> Reviewed-by: Matt Caswell <m...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11589) commit da4db1602d8f7f031f12ddc04de84129138c419c Author: Vadim Fedorenko <vadimj...@gmail.com> Date: Sat Jan 25 21:49:41 2020 +0300 test: TLS1.3 and new ciphers for kTLS Reviewed-by: Paul Dale <paul.d...@oracle.com> Reviewed-by: Matt Caswell <m...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11589) commit cc10b56dbe29e4f254ad1f3abc7ca5216c3069e6 Author: Vadim Fedorenko <vadimj...@gmail.com> Date: Sat Jan 25 21:49:08 2020 +0300 TLSv13: add kTLS support Reviewed-by: Paul Dale <paul.d...@oracle.com> Reviewed-by: Matt Caswell <m...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11589) commit 4ffccf6c4deebd6f3ab5d46234c64f957ff1c1c5 Author: Vadim Fedorenko <vadimj...@gmail.com> Date: Fri Jan 24 16:57:56 2020 +0300 kTLS: add support for AES_CCM128 and AES_GCM256 The support of new algos is added by converting code to use helper functions found in ktls.h. Reviewed-by: Paul Dale <paul.d...@oracle.com> Reviewed-by: Matt Caswell <m...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11589) commit 95badfeb60603b1bbcfc4d0fef555aed06038d55 Author: Vadim Fedorenko <vadimj...@gmail.com> Date: Fri May 1 23:56:48 2020 +0300 kTLS: add Linux-specific kTLS helpers Reviewed-by: Paul Dale <paul.d...@oracle.com> Reviewed-by: Matt Caswell <m...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11589) commit f434bfaccf033989c765621fdd975ec1bc29c80a Author: Vadim Fedorenko <vadimj...@gmail.com> Date: Fri Jan 24 16:08:02 2020 +0300 kTLS: add new algo definitions Reviewed-by: Paul Dale <paul.d...@oracle.com> Reviewed-by: Matt Caswell <m...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11589) commit 996a6ac32bc4dd02098b68445b71f8fa286ef91b Author: Vadim Fedorenko <vadimj...@gmail.com> Date: Fri Jan 24 16:11:02 2020 +0300 kTLS: make ktls_start type independed Reviewed-by: Paul Dale <paul.d...@oracle.com> Reviewed-by: Matt Caswell <m...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11589) ----------------------------------------------------------------------- Summary of changes: crypto/bio/bss_sock.c | 9 +- doc/man3/SSL_CTX_set_record_padding_callback.pod | 10 +- include/internal/ktls.h | 284 ++++++++----- include/openssl/ssl.h | 2 +- ssl/record/rec_layer_s3.c | 1 + ssl/ssl_lib.c | 11 +- ssl/t1_enc.c | 50 ++- ssl/tls13_enc.c | 85 +++- test/build.info | 1 + test/sslapitest.c | 503 ++++++++++++++++++----- 10 files changed, 710 insertions(+), 246 deletions(-) diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c index a72a476803..ff2bde7a58 100644 --- a/crypto/bio/bss_sock.c +++ b/crypto/bio/bss_sock.c @@ -154,10 +154,11 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) long ret = 1; int *ip; # ifndef OPENSSL_NO_KTLS + size_t crypto_info_len; # ifdef __FreeBSD__ struct tls_enable *crypto_info; # else - struct tls12_crypto_info_aes_gcm_128 *crypto_info; + struct tls_crypto_info_all *crypto_info; # endif # endif @@ -191,10 +192,12 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_SET_KTLS: # ifdef __FreeBSD__ crypto_info = (struct tls_enable *)ptr; + crypto_info_len = sizeof(*crypto_info); # else - crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr; + crypto_info = (struct tls_crypto_info_all *)ptr; + crypto_info_len = crypto_info->tls_crypto_info_len; # endif - ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num); + ret = ktls_start(b->num, crypto_info, crypto_info_len, num); if (ret) BIO_set_ktls_flag(b, num); break; diff --git a/doc/man3/SSL_CTX_set_record_padding_callback.pod b/doc/man3/SSL_CTX_set_record_padding_callback.pod index 3df66218fe..445953ef07 100644 --- a/doc/man3/SSL_CTX_set_record_padding_callback.pod +++ b/doc/man3/SSL_CTX_set_record_padding_callback.pod @@ -16,7 +16,7 @@ SSL_set_block_padding - install callback to specify TLS 1.3 record padding #include <openssl/ssl.h> void SSL_CTX_set_record_padding_callback(SSL_CTX *ctx, size_t (*cb)(SSL *s, int type, size_t len, void *arg)); - void SSL_set_record_padding_callback(SSL *ssl, size_t (*cb)(SSL *s, int type, size_t len, void *arg)); + int SSL_set_record_padding_callback(SSL *ssl, size_t (*cb)(SSL *s, int type, size_t len, void *arg)); void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg); void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx); @@ -32,6 +32,8 @@ SSL_set_block_padding - install callback to specify TLS 1.3 record padding SSL_CTX_set_record_padding_callback() or SSL_set_record_padding_callback() can be used to assign a callback function I<cb> to specify the padding for TLS 1.3 records. The value set in B<ctx> is copied to a new SSL by SSL_new(). +Kernel TLS is not possible if the record padding callback is set, and the callback +function cannot be set if Kernel TLS is already configured for the current SSL object. SSL_CTX_set_record_padding_callback_arg() and SSL_set_record_padding_callback_arg() assign a value B<arg> that is passed to the callback when it is invoked. The value @@ -64,6 +66,9 @@ indicates no padding will be added. A return value that causes the record to exceed the maximum record size (SSL3_RT_MAX_PLAIN_LENGTH) will pad out to the maximum record size. +The SSL_CTX_get_record_padding_callback_arg() function returns 1 on success or 0 if +the callback function is not set because Kernel TLS is configured for the SSL object. + =head1 NOTES The default behavior is to add no padding to the record. @@ -84,6 +89,9 @@ L<ssl(7)>, L<SSL_new(3)> The record padding API was added for TLS 1.3 support in OpenSSL 1.1.1. +The return type of SSL_CTX_set_record_padding_callback() function was +changed to int in OpenSSL 3.0. + =head1 COPYRIGHT Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. diff --git a/include/internal/ktls.h b/include/internal/ktls.h index 209dff1689..093a661843 100644 --- a/include/internal/ktls.h +++ b/include/internal/ktls.h @@ -7,6 +7,19 @@ * https://www.openssl.org/source/license.html */ +#if defined(OPENSSL_SYS_LINUX) +# ifndef OPENSSL_NO_KTLS +# include <linux/version.h> +# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) +# define OPENSSL_NO_KTLS +# ifndef PEDANTIC +# warning "KTLS requires Kernel Headers >= 4.13.0" +# warning "Skipping Compilation of KTLS" +# endif +# endif +# endif +#endif + #ifndef OPENSSL_NO_KTLS # ifndef HEADER_INTERNAL_KTLS # define HEADER_INTERNAL_KTLS @@ -40,12 +53,12 @@ static ossl_inline int ktls_enable(int fd) * provided here. */ static ossl_inline int ktls_start(int fd, - struct tls_enable *tls_en, + void *tls_en, size_t len, int is_tx) { if (is_tx) return setsockopt(fd, IPPROTO_TCP, TCP_TXTLS_ENABLE, - tls_en, sizeof(*tls_en)) ? 0 : 1; + tls_en, len) ? 0 : 1; else return 0; } @@ -109,94 +122,57 @@ static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, # endif /* __FreeBSD__ */ # if defined(OPENSSL_SYS_LINUX) -# include <linux/version.h> - -# define K_MAJ 4 -# define K_MIN1 13 -# define K_MIN2 0 -# if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1, K_MIN2) +# include <linux/tls.h> +# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0) +# define OPENSSL_NO_KTLS_RX # ifndef PEDANTIC -# warning "KTLS requires Kernel Headers >= 4.13.0" -# warning "Skipping Compilation of KTLS" +# warning "KTLS requires Kernel Headers >= 4.17.0 for receiving" +# warning "Skipping Compilation of KTLS receive data path" +# endif +# endif +# define OPENSSL_KTLS_AES_GCM_128 +# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) +# define OPENSSL_KTLS_AES_GCM_256 +# define OPENSSL_KTLS_TLS13 +# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) +# define OPENSSL_KTLS_AES_CCM_128 # endif +# endif -# define TLS_TX 1 -# define TLS_RX 2 +# include <sys/sendfile.h> +# include <netinet/tcp.h> +# include <linux/socket.h> +# include "openssl/ssl3.h" +# include "openssl/tls1.h" +# include "openssl/evp.h" -# define TLS_CIPHER_AES_GCM_128 51 -# define TLS_CIPHER_AES_GCM_128_IV_SIZE 8 -# define TLS_CIPHER_AES_GCM_128_KEY_SIZE 16 -# define TLS_CIPHER_AES_GCM_128_SALT_SIZE 4 -# define TLS_CIPHER_AES_GCM_128_TAG_SIZE 16 -# define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE 8 +# ifndef SOL_TLS +# define SOL_TLS 282 +# endif -# define TLS_SET_RECORD_TYPE 1 +# ifndef TCP_ULP +# define TCP_ULP 31 +# endif -struct tls_crypto_info { - unsigned short version; - unsigned short cipher_type; -}; +# ifndef TLS_RX +# define TLS_RX 2 +# endif -struct tls12_crypto_info_aes_gcm_128 { - struct tls_crypto_info info; - unsigned char iv[TLS_CIPHER_AES_GCM_128_IV_SIZE]; - unsigned char key[TLS_CIPHER_AES_GCM_128_KEY_SIZE]; - unsigned char salt[TLS_CIPHER_AES_GCM_128_SALT_SIZE]; - unsigned char rec_seq[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; +struct tls_crypto_info_all { + union { +# ifdef OPENSSL_KTLS_AES_GCM_128 + struct tls12_crypto_info_aes_gcm_128 gcm128; +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + struct tls12_crypto_info_aes_gcm_256 gcm256; +# endif +# ifdef OPENSSL_KTLS_AES_CCM_128 + struct tls12_crypto_info_aes_ccm_128 ccm128; +# endif + }; + size_t tls_crypto_info_len; }; - -/* Dummy functions here */ -static ossl_inline int ktls_enable(int fd) -{ - return 0; -} - -static ossl_inline int ktls_start(int fd, - struct tls12_crypto_info_aes_gcm_128 - *crypto_info, size_t len, int is_tx) -{ - return 0; -} - -static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, - const void *data, size_t length) -{ - return -1; -} - -static ossl_inline int ktls_read_record(int fd, void *data, size_t length) -{ - return -1; -} - -static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags) -{ - return -1; -} - -# else /* KERNEL_VERSION */ - -# include <sys/sendfile.h> -# include <netinet/tcp.h> -# include <linux/tls.h> -# include <linux/socket.h> -# include "openssl/ssl3.h" -# include "openssl/tls1.h" -# include "openssl/evp.h" - -# ifndef SOL_TLS -# define SOL_TLS 282 -# endif - -# ifndef TCP_ULP -# define TCP_ULP 31 -# endif - -# ifndef TLS_RX -# define TLS_RX 2 -# endif - /* * When successful, this socket option doesn't change the behaviour of the * TCP socket, except changing the TCP setsockopt handler to enable the @@ -216,12 +192,11 @@ static ossl_inline int ktls_enable(int fd) * If successful, then data received using this socket will be decrypted, * authenticated and decapsulated using the crypto_info provided here. */ -static ossl_inline int ktls_start(int fd, - struct tls12_crypto_info_aes_gcm_128 - *crypto_info, size_t len, int is_tx) +static ossl_inline int ktls_start(int fd, void *crypto_info, + size_t len, int is_tx) { return setsockopt(fd, SOL_TLS, is_tx ? TLS_TX : TLS_RX, - crypto_info, sizeof(*crypto_info)) ? 0 : 1; + crypto_info, len) ? 0 : 1; } /* @@ -270,20 +245,15 @@ static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t s return sendfile(s, fd, &off, size); } -# define K_MIN1_RX 17 -# if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1_RX, K_MIN2) +# ifdef OPENSSL_NO_KTLS_RX -# ifndef PEDANTIC -# warning "KTLS requires Kernel Headers >= 4.17.0 for receiving" -# warning "Skipping Compilation of KTLS receive data path" -# endif static ossl_inline int ktls_read_record(int fd, void *data, size_t length) { return -1; } -# else +# else /* !defined(OPENSSL_NO_KTLS_RX) */ /* * Receive a TLS record using the crypto_info provided in ktls_start. @@ -338,8 +308,132 @@ static ossl_inline int ktls_read_record(int fd, void *data, size_t length) return ret; } -# endif -# endif +# endif /* OPENSSL_NO_KTLS_RX */ + +/* Function to check supported ciphers in Linux */ +static ossl_inline int ktls_check_supported_cipher(const EVP_CIPHER *c, + const EVP_CIPHER_CTX *dd) +{ + /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 */ + switch (EVP_CIPHER_nid(c)) + { +# ifdef OPENSSL_KTLS_AES_CCM_128 + case NID_aes_128_ccm: + if (EVP_CIPHER_CTX_tag_length(dd) != EVP_CCM_TLS_TAG_LEN) + return 0; # endif -# endif +# ifdef OPENSSL_KTLS_AES_GCM_128 + case NID_aes_128_gcm: +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + case NID_aes_256_gcm: +# endif + return 1; + default: + return 0; + } +} + +/* Function to configure kernel TLS structure */ +static ossl_inline int ktls_configure_crypto(const EVP_CIPHER *c, int tls_version, + EVP_CIPHER_CTX *dd, void *rl_sequence, + struct tls_crypto_info_all *crypto_info, + unsigned char **rec_seq, unsigned char *iv, + unsigned char *key) +{ + unsigned char geniv[12]; + unsigned char *iiv = iv; + + if (tls_version == TLS1_2_VERSION && + EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { + EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV, + EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN, + geniv); + iiv = geniv; + } + + memset(crypto_info, 0, sizeof(*crypto_info)); + switch (EVP_CIPHER_nid(c)) + { +# ifdef OPENSSL_KTLS_AES_GCM_128 + case NID_aes_128_gcm: + crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128; + crypto_info->gcm128.info.version = tls_version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128); + memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, + TLS_CIPHER_AES_GCM_128_IV_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.rec_seq, rl_sequence, + TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->gcm128.rec_seq; + return 1; +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + case NID_aes_256_gcm: + crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256; + crypto_info->gcm256.info.version = tls_version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256); + memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, + TLS_CIPHER_AES_GCM_256_IV_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.rec_seq, rl_sequence, + TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->gcm256.rec_seq; + return 1; +# endif +# ifdef OPENSSL_KTLS_AES_CCM_128 + case NID_aes_128_ccm: + crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128; + crypto_info->ccm128.info.version = tls_version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128); + memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN, + TLS_CIPHER_AES_CCM_128_IV_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.rec_seq, rl_sequence, + TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->ccm128.rec_seq; + return 1; +# endif + default: + return 0; + } + +} + +# endif /* OPENSSL_SYS_LINUX */ +# endif /* HEADER_INTERNAL_KTLS */ +#else /* defined(OPENSSL_NO_KTLS) */ +/* Dummy functions here */ +static ossl_inline int ktls_enable(int fd) +{ + return 0; +} + +static ossl_inline int ktls_start(int fd, void *crypto_info, + size_t len, int is_tx) +{ + return 0; +} + +static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, + const void *data, size_t length) +{ + return -1; +} + +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) +{ + return -1; +} + +static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags) +{ + return -1; +} #endif diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index c039b2a04a..f855f9470d 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -2167,7 +2167,7 @@ void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg); void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx); int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size); -void SSL_set_record_padding_callback(SSL *ssl, +int SSL_set_record_padding_callback(SSL *ssl, size_t (*cb) (SSL *ssl, int type, size_t len, void *arg)); void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg); diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index b1dcd517e2..fac3506b19 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -945,6 +945,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, } if (SSL_TREAT_AS_TLS13(s) + && !BIO_get_ktls_send(s->wbio) && s->enc_write_ctx != NULL && (s->statem.enc_write_state != ENC_WRITE_STATE_WRITE_PLAIN_ALERTS || type != SSL3_RT_ALERT)) { diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index c2c2388716..9fb65b6825 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -4645,11 +4645,18 @@ int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size) return 1; } -void SSL_set_record_padding_callback(SSL *ssl, +int SSL_set_record_padding_callback(SSL *ssl, size_t (*cb) (SSL *ssl, int type, size_t len, void *arg)) { - ssl->record_padding_cb = cb; + BIO *b; + + b = SSL_get_wbio(ssl); + if (b == NULL || !BIO_get_ktls_send(b)) { + ssl->record_padding_cb = cb; + return 1; + } + return 0; } void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg) diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 7f908f3b4c..108c7f1640 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -109,6 +109,7 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km, size_t num) * 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); @@ -132,6 +133,7 @@ static int count_unprocessed_records(SSL *s) return count; } +# endif #endif int tls1_change_cipher_state(SSL *s, int which) @@ -154,10 +156,13 @@ int tls1_change_cipher_state(SSL *s, int which) # ifdef __FreeBSD__ struct tls_enable crypto_info; # else - struct tls12_crypto_info_aes_gcm_128 crypto_info; - unsigned char geniv[12]; + struct tls_crypto_info_all crypto_info; + unsigned char *rec_seq; + void *rl_sequence; +# ifndef OPENSSL_NO_KTLS_RX int count_unprocessed; int bit; +# endif # endif BIO *bio; #endif @@ -441,14 +446,12 @@ int tls1_change_cipher_state(SSL *s, int which) crypto_info.iv = iv; crypto_info.tls_vmajor = (s->version >> 8) & 0x000000ff; crypto_info.tls_vminor = (s->version & 0x000000ff); -# else - /* 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) +# else /* !defined(__FreeBSD__) */ + /* check that cipher is supported */ + if (!ktls_check_supported_cipher(c, dd)) goto skip_ktls; - /* check version is 1.2 */ + /* check version */ if (s->version != TLS1_2_VERSION) goto skip_ktls; # endif @@ -479,25 +482,17 @@ int tls1_change_cipher_state(SSL *s, int which) } # ifndef __FreeBSD__ - 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)); if (which & SSL3_CC_WRITE) - memcpy(crypto_info.rec_seq, &s->rlayer.write_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer); else - memcpy(crypto_info.rec_seq, &s->rlayer.read_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); + + if (!ktls_configure_crypto(c, s->version, dd, rl_sequence, &crypto_info, + &rec_seq, iv, key)) + 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; @@ -505,14 +500,17 @@ int tls1_change_cipher_state(SSL *s, int which) /* increment the crypto_info record sequence */ while (count_unprocessed) { for (bit = 7; bit >= 0; bit--) { /* increment */ - ++crypto_info.rec_seq[bit]; - if (crypto_info.rec_seq[bit] != 0) + ++rec_seq[bit]; + if (rec_seq[bit] != 0) break; } count_unprocessed--; } +# else + goto skip_ktls; +# endif } -# endif +# endif /* !__FreeBSD__ */ /* ktls works with user provided buffers directly */ if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) { diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index 1775152eeb..ba385f6ea2 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -9,6 +9,8 @@ #include <stdlib.h> #include "ssl_local.h" +#include "internal/ktls.h" +#include "record/record_local.h" #include "internal/cryptlib.h" #include <openssl/evp.h> #include <openssl/kdf.h> @@ -409,9 +411,9 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, const unsigned char *hash, const unsigned char *label, size_t labellen, unsigned char *secret, - unsigned char *iv, EVP_CIPHER_CTX *ciph_ctx) + unsigned char *key, unsigned char *iv, + EVP_CIPHER_CTX *ciph_ctx) { - unsigned char key[EVP_MAX_KEY_LENGTH]; size_t ivlen, keylen, taglen; int hashleni = EVP_MD_size(md); size_t hashlen; @@ -420,14 +422,14 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, if (!ossl_assert(hashleni >= 0)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, ERR_R_EVP_LIB); - goto err; + return 0; } hashlen = (size_t)hashleni; if (!tls13_hkdf_expand(s, md, insecret, label, labellen, hash, hashlen, secret, hashlen, 1)) { /* SSLfatal() already called */ - goto err; + return 0; } /* TODO(size_t): convert me */ @@ -447,7 +449,7 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, } else { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, ERR_R_EVP_LIB); - goto err; + return 0; } if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8)) taglen = EVP_CCM8_TLS_TAG_LEN; @@ -461,7 +463,7 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, if (!tls13_derive_key(s, md, secret, key, keylen) || !tls13_derive_iv(s, md, secret, iv, ivlen)) { /* SSLfatal() already called */ - goto err; + return 0; } if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0 @@ -471,13 +473,10 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, || EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, ERR_R_EVP_LIB); - goto err; + return 0; } return 1; - err: - OPENSSL_cleanse(key, sizeof(key)); - return 0; } int tls13_change_cipher_state(SSL *s, int which) @@ -502,6 +501,7 @@ int tls13_change_cipher_state(SSL *s, int which) static const unsigned char early_exporter_master_secret[] = "e exp master"; #endif unsigned char *iv; + unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char secret[EVP_MAX_MD_SIZE]; unsigned char hashval[EVP_MAX_MD_SIZE]; unsigned char *hash = hashval; @@ -515,6 +515,12 @@ int tls13_change_cipher_state(SSL *s, int which) int ret = 0; const EVP_MD *md = NULL; const EVP_CIPHER *cipher = NULL; +#if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13) +# ifndef __FreeBSD__ + struct tls_crypto_info_all crypto_info; + BIO *bio; +# endif +#endif if (which & SSL3_CC_READ) { if (s->enc_read_ctx != NULL) { @@ -729,9 +735,13 @@ int tls13_change_cipher_state(SSL *s, int which) } } + /* check whether cipher is known */ + if(!ossl_assert(cipher != NULL)) + goto err; + if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher, - insecret, hash, label, labellen, secret, iv, - ciph_ctx)) { + insecret, hash, label, labellen, secret, key, + iv, ciph_ctx)) { /* SSLfatal() already called */ goto err; } @@ -772,12 +782,57 @@ int tls13_change_cipher_state(SSL *s, int which) s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS; else s->statem.enc_write_state = ENC_WRITE_STATE_VALID; +#ifndef OPENSSL_NO_KTLS +# if defined(OPENSSL_KTLS_TLS13) +# ifndef __FreeBSD__ + if (!(which & SSL3_CC_WRITE) || !(which & SSL3_CC_APPLICATION) + || ((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; + + /* ktls does not support record padding */ + if (s->record_padding_cb != NULL) + goto skip_ktls; + + /* check that cipher is supported */ + if (!ktls_check_supported_cipher(cipher, ciph_ctx)) + goto skip_ktls; + + bio = s->wbio; + + if (!ossl_assert(bio != NULL)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_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(bio) <= 0) + goto skip_ktls; + + /* configure kernel crypto structure */ + if (!ktls_configure_crypto(cipher, s->version, ciph_ctx, + RECORD_LAYER_get_write_sequence(&s->rlayer), + &crypto_info, NULL, iv, key)) + goto skip_ktls; + + /* ktls works with user provided buffers directly */ + if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) + ssl3_release_write_buffer(s); +# endif +skip_ktls: +# endif +#endif ret = 1; err: if ((which & SSL3_CC_EARLY) != 0) { /* We up-refed this so now we need to down ref */ ssl_evp_cipher_free(cipher); } + OPENSSL_cleanse(key, sizeof(key)); OPENSSL_cleanse(secret, sizeof(secret)); return ret; } @@ -791,6 +846,7 @@ int tls13_update_key(SSL *s, int sending) #endif const EVP_MD *md = ssl_handshake_md(s); size_t hashlen = EVP_MD_size(md); + unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char *insecret, *iv; unsigned char secret[EVP_MAX_MD_SIZE]; EVP_CIPHER_CTX *ciph_ctx; @@ -815,8 +871,8 @@ int tls13_update_key(SSL *s, int sending) if (!derive_secret_key_and_iv(s, sending, ssl_handshake_md(s), s->s3.tmp.new_sym_enc, insecret, NULL, application_traffic, - sizeof(application_traffic) - 1, secret, iv, - ciph_ctx)) { + sizeof(application_traffic) - 1, secret, key, + iv, ciph_ctx)) { /* SSLfatal() already called */ goto err; } @@ -826,6 +882,7 @@ int tls13_update_key(SSL *s, int sending) s->statem.enc_write_state = ENC_WRITE_STATE_VALID; ret = 1; err: + OPENSSL_cleanse(key, sizeof(key)); OPENSSL_cleanse(secret, sizeof(secret)); return ret; } diff --git a/test/build.info b/test/build.info index 6256a34c91..b98d1b52cc 100644 --- a/test/build.info +++ b/test/build.info @@ -675,6 +675,7 @@ IF[{- !$disabled{tests} -}] IF[{- !$disabled{shared} -}] PROGRAMS{noinst}=tls13secretstest SOURCE[tls13secretstest]=tls13secretstest.c + DEFINE[tls13secretstest]=OPENSSL_NO_KTLS SOURCE[tls13secretstest]= ../ssl/tls13_enc.c ../crypto/packet.c INCLUDE[tls13secretstest]=.. ../include ../apps/include DEPEND[tls13secretstest]=../libcrypto ../libssl libtestutil.a diff --git a/test/sslapitest.c b/test/sslapitest.c index 8847ba38ce..23e6b7d0f6 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -856,9 +856,9 @@ static int execute_test_large_message(const SSL_METHOD *smeth, return testresult; } -#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_KTLS) \ - && !defined(OPENSSL_NO_SOCK) - +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_KTLS) && \ + !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_TLS1_2)) +#define TLS_CIPHER_MAX_REC_SEQ_SIZE 8 /* sock must be connected */ static int ktls_chk_platform(int sock) { @@ -867,30 +867,26 @@ static int ktls_chk_platform(int sock) return 1; } -static int ping_pong_query(SSL *clientssl, SSL *serverssl, int cfd, int sfd) +static int ping_pong_query(SSL *clientssl, SSL *serverssl, int cfd, int sfd, int rec_seq_size) { static char count = 1; unsigned char cbuf[16000] = {0}; unsigned char sbuf[16000]; size_t err = 0; - char crec_wseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char crec_wseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char crec_rseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char crec_rseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char srec_wseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char srec_wseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char srec_rseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char srec_rseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; + char crec_wseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char crec_wseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char crec_rseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char crec_rseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char srec_wseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char srec_wseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char srec_rseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char srec_rseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; cbuf[0] = count++; - memcpy(crec_wseq_before, &clientssl->rlayer.write_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - memcpy(crec_rseq_before, &clientssl->rlayer.read_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - memcpy(srec_wseq_before, &serverssl->rlayer.write_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - memcpy(srec_rseq_before, &serverssl->rlayer.read_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + memcpy(crec_wseq_before, &clientssl->rlayer.write_sequence, rec_seq_size); + memcpy(crec_rseq_before, &clientssl->rlayer.read_sequence, rec_seq_size); + memcpy(srec_wseq_before, &serverssl->rlayer.write_sequence, rec_seq_size); + memcpy(srec_rseq_before, &serverssl->rlayer.read_sequence, rec_seq_size); if (!TEST_true(SSL_write(clientssl, cbuf, sizeof(cbuf)) == sizeof(cbuf))) goto end; @@ -910,14 +906,10 @@ static int ping_pong_query(SSL *clientssl, SSL *serverssl, int cfd, int sfd) } } - memcpy(crec_wseq_after, &clientssl->rlayer.write_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - memcpy(crec_rseq_after, &clientssl->rlayer.read_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - memcpy(srec_wseq_after, &serverssl->rlayer.write_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - memcpy(srec_rseq_after, &serverssl->rlayer.read_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + memcpy(crec_wseq_after, &clientssl->rlayer.write_sequence, rec_seq_size); + memcpy(crec_rseq_after, &clientssl->rlayer.read_sequence, rec_seq_size); + memcpy(srec_wseq_after, &serverssl->rlayer.write_sequence, rec_seq_size); + memcpy(srec_rseq_after, &serverssl->rlayer.read_sequence, rec_seq_size); /* verify the payload */ if (!TEST_mem_eq(cbuf, sizeof(cbuf), sbuf, sizeof(sbuf))) @@ -925,42 +917,42 @@ static int ping_pong_query(SSL *clientssl, SSL *serverssl, int cfd, int sfd) /* ktls is used then kernel sequences are used instead of OpenSSL sequences */ if (clientssl->mode & SSL_MODE_NO_KTLS_TX) { - if (!TEST_mem_ne(crec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - crec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_ne(crec_wseq_before, rec_seq_size, + crec_wseq_after, rec_seq_size)) goto end; } else { - if (!TEST_mem_eq(crec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - crec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_eq(crec_wseq_before, rec_seq_size, + crec_wseq_after, rec_seq_size)) goto end; } if (serverssl->mode & SSL_MODE_NO_KTLS_TX) { - if (!TEST_mem_ne(srec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - srec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_ne(srec_wseq_before, rec_seq_size, + srec_wseq_after, rec_seq_size)) goto end; } else { - if (!TEST_mem_eq(srec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - srec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_eq(srec_wseq_before, rec_seq_size, + srec_wseq_after, rec_seq_size)) goto end; } if (clientssl->mode & SSL_MODE_NO_KTLS_RX) { - if (!TEST_mem_ne(crec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - crec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_ne(crec_rseq_before, rec_seq_size, + crec_rseq_after, rec_seq_size)) goto end; } else { - if (!TEST_mem_eq(crec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - crec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_eq(crec_rseq_before, rec_seq_size, + crec_rseq_after, rec_seq_size)) goto end; } if (serverssl->mode & SSL_MODE_NO_KTLS_RX) { - if (!TEST_mem_ne(srec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - srec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_ne(srec_rseq_before, rec_seq_size, + srec_rseq_after, rec_seq_size)) goto end; } else { - if (!TEST_mem_eq(srec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - srec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_eq(srec_rseq_before, rec_seq_size, + srec_rseq_after, rec_seq_size)) goto end; } @@ -970,7 +962,9 @@ end: } static int execute_test_ktls(int cis_ktls_tx, int cis_ktls_rx, - int sis_ktls_tx, int sis_ktls_rx) + int sis_ktls_tx, int sis_ktls_rx, + int tls_version, const char *cipher, + int rec_seq_size) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; @@ -987,10 +981,9 @@ static int execute_test_ktls(int cis_ktls_tx, int cis_ktls_rx, /* Create a session based on SHA-256 */ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), - TLS1_2_VERSION, TLS1_2_VERSION, + tls_version, tls_version, &sctx, &cctx, cert, privkey)) - || !TEST_true(SSL_CTX_set_cipher_list(cctx, - "AES128-GCM-SHA256")) + || !TEST_true(SSL_CTX_set_cipher_list(cctx, cipher)) || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl, &clientssl, sfd, cfd))) goto end; @@ -1051,7 +1044,8 @@ static int execute_test_ktls(int cis_ktls_tx, int cis_ktls_rx, goto end; } - if (!TEST_true(ping_pong_query(clientssl, serverssl, cfd, sfd))) + if (!TEST_true(ping_pong_query(clientssl, serverssl, cfd, sfd, + rec_seq_size))) goto end; testresult = 1; @@ -1074,7 +1068,7 @@ end: #define SENDFILE_CHUNK (4 * 4096) #define min(a,b) ((a) > (b) ? (b) : (a)) -static int test_ktls_sendfile(void) +static int test_ktls_sendfile(int tls_version, const char *cipher) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; @@ -1101,10 +1095,9 @@ static int test_ktls_sendfile(void) /* Create a session based on SHA-256 */ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), - TLS1_2_VERSION, TLS1_2_VERSION, + tls_version, tls_version, &sctx, &cctx, cert, privkey)) - || !TEST_true(SSL_CTX_set_cipher_list(cctx, - "AES128-GCM-SHA256")) + || !TEST_true(SSL_CTX_set_cipher_list(cctx, cipher)) || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl, &clientssl, sfd, cfd))) goto end; @@ -1175,85 +1168,401 @@ end: return testresult; } -static int test_ktls_no_txrx_client_no_txrx_server(void) +static int test_ktls_no_txrx_client_no_txrx_server(int tlsver) { - return execute_test_ktls(0, 0, 0, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 0, 0, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 0, 0, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 0, 0, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_rx_client_no_txrx_server(void) +static int test_ktls_no_rx_client_no_txrx_server(int tlsver) { - return execute_test_ktls(1, 0, 0, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 0, 0, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 0, 0, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 0, 0, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_tx_client_no_txrx_server(void) +static int test_ktls_no_tx_client_no_txrx_server(int tlsver) { - return execute_test_ktls(0, 1, 0, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 1, 0, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 1, 0, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 1, 0, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_client_no_txrx_server(void) +static int test_ktls_client_no_txrx_server(int tlsver) { - return execute_test_ktls(1, 1, 0, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 1, 0, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 1, 0, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 1, 0, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_txrx_client_no_rx_server(void) +static int test_ktls_no_txrx_client_no_rx_server(int tlsver) { - return execute_test_ktls(0, 0, 1, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 0, 1, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 0, 1, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 0, 1, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_rx_client_no_rx_server(void) +static int test_ktls_no_rx_client_no_rx_server(int tlsver) { - return execute_test_ktls(1, 0, 1, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 0, 1, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 0, 1, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 0, 1, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_tx_client_no_rx_server(void) +static int test_ktls_no_tx_client_no_rx_server(int tlsver) { - return execute_test_ktls(0, 1, 1, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 1, 1, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 1, 1, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 1, 1, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_client_no_rx_server(void) +static int test_ktls_client_no_rx_server(int tlsver) { - return execute_test_ktls(1, 1, 1, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 1, 1, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 1, 1, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 1, 1, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_txrx_client_no_tx_server(void) +static int test_ktls_no_txrx_client_no_tx_server(int tlsver) { - return execute_test_ktls(0, 0, 0, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 0, 0, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 0, 0, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 0, 0, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_rx_client_no_tx_server(void) +static int test_ktls_no_rx_client_no_tx_server(int tlsver) { - return execute_test_ktls(1, 0, 0, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 0, 0, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 0, 0, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 0, 0, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_tx_client_no_tx_server(void) +static int test_ktls_no_tx_client_no_tx_server(int tlsver) { - return execute_test_ktls(0, 1, 0, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 1, 0, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 1, 0, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 1, 0, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_client_no_tx_server(void) +static int test_ktls_client_no_tx_server(int tlsver) { - return execute_test_ktls(1, 1, 0, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 1, 0, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 1, 0, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 1, 0, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_txrx_client_server(void) +static int test_ktls_no_txrx_client_server(int tlsver) { - return execute_test_ktls(0, 0, 1, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 0, 1, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 0, 1, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 0, 1, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_rx_client_server(void) +static int test_ktls_no_rx_client_server(int tlsver) { - return execute_test_ktls(1, 0, 1, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 0, 1, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 0, 1, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 0, 1, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_tx_client_server(void) +static int test_ktls_no_tx_client_server(int tlsver) { - return execute_test_ktls(0, 1, 1, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 1, 1, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 1, 1, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 1, 1, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; +} + +static int test_ktls_client_server(int tlsver) +{ + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 1, 1, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 1, 1, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 1, 1, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; +} + +#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3) +static int test_ktls(int test) +{ + int tlsver; + + if (test > 15) { +#if defined(OPENSSL_NO_TLS1_3) + return 1; +#else + test -= 16; + tlsver = TLS1_3_VERSION; +#endif + } else { +#if defined(OPENSSL_NO_TLS1_2) + return 1; +#else + tlsver = TLS1_2_VERSION; +#endif + } + + switch(test) { + case 0: + return test_ktls_no_txrx_client_no_txrx_server(tlsver); + case 1: + return test_ktls_no_rx_client_no_txrx_server(tlsver); + case 2: + return test_ktls_no_tx_client_no_txrx_server(tlsver); + case 3: + return test_ktls_client_no_txrx_server(tlsver); + case 4: + return test_ktls_no_txrx_client_no_rx_server(tlsver); + case 5: + return test_ktls_no_rx_client_no_rx_server(tlsver); + case 6: + return test_ktls_no_tx_client_no_rx_server(tlsver); + case 7: + return test_ktls_client_no_rx_server(tlsver); + case 8: + return test_ktls_no_txrx_client_no_tx_server(tlsver); + case 9: + return test_ktls_no_rx_client_no_tx_server(tlsver); + case 10: + return test_ktls_no_tx_client_no_tx_server(tlsver); + case 11: + return test_ktls_client_no_tx_server(tlsver); + case 12: + return test_ktls_no_txrx_client_server(tlsver); + case 13: + return test_ktls_no_rx_client_server(tlsver); + case 14: + return test_ktls_no_tx_client_server(tlsver); + case 15: + return test_ktls_client_server(tlsver); + default: + return 0; + } } -static int test_ktls_client_server(void) +static int test_ktls_sendfile_anytls(int tst) { - return execute_test_ktls(1, 1, 1, 1); + char *cipher[] = {"AES128-GCM-SHA256","AES128-CCM-SHA256","AES256-GCM-SHA384"}; + int tlsver; + + if (tst > 2) { +#if defined(OPENSSL_NO_TLS1_3) + return 1; +#else + tst -= 3; + tlsver = TLS1_3_VERSION; +#endif + } else { +#if defined(OPENSSL_NO_TLS1_2) + return 1; +#else + tlsver = TLS1_2_VERSION; +#endif + } + +#ifndef OPENSSL_KTLS_AES_GCM_128 + if(tst == 0) return 1; +#endif +#ifndef OPENSSL_KTLS_AES_CCM_128 + if(tst == 1) return 1; +#endif +#ifndef OPENSSL_KTLS_AES_GCM_256 + if(tst == 2) return 1; +#endif + return test_ktls_sendfile(tlsver, cipher[tst]); } + +#endif #endif static int test_large_message_tls(void) @@ -7876,25 +8185,11 @@ int setup_tests(void) if (privkey2 == NULL) goto err; -#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_KTLS) \ - && !defined(OPENSSL_NO_SOCK) - ADD_TEST(test_ktls_no_txrx_client_no_txrx_server); - ADD_TEST(test_ktls_no_rx_client_no_txrx_server); - ADD_TEST(test_ktls_no_tx_client_no_txrx_server); - ADD_TEST(test_ktls_client_no_txrx_server); - ADD_TEST(test_ktls_no_txrx_client_no_rx_server); - ADD_TEST(test_ktls_no_rx_client_no_rx_server); - ADD_TEST(test_ktls_no_tx_client_no_rx_server); - ADD_TEST(test_ktls_client_no_rx_server); - ADD_TEST(test_ktls_no_txrx_client_no_tx_server); - ADD_TEST(test_ktls_no_rx_client_no_tx_server); - ADD_TEST(test_ktls_no_tx_client_no_tx_server); - ADD_TEST(test_ktls_client_no_tx_server); - ADD_TEST(test_ktls_no_txrx_client_server); - ADD_TEST(test_ktls_no_rx_client_server); - ADD_TEST(test_ktls_no_tx_client_server); - ADD_TEST(test_ktls_client_server); - ADD_TEST(test_ktls_sendfile); +#if !defined(OPENSSL_NO_KTLS) && !defined(OPENSSL_NO_SOCK) +#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3) + ADD_ALL_TESTS(test_ktls, 32); + ADD_ALL_TESTS(test_ktls_sendfile_anytls, 6); +#endif #endif ADD_TEST(test_large_message_tls); ADD_TEST(test_large_message_tls_read_ahead);