From: John Baldwin Date: Wed, 10 Jun 2020 20:36:38 +0000 (-0700) Subject: Add helper functions for FreeBSD KTLS. X-Git-Tag: openssl-3.0.0-alpha7~432 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3e5826061baa7948ab1d2835357403d16470108d;p=thirdparty%2Fopenssl.git Add helper functions for FreeBSD KTLS. These are similar to the helpers added in 95badfeb60. I've adjusted the arguments passed to ktls_check_supported_cipher and ktls_configure_crypto so that FreeBSD and Linux can both use the same signature to avoid OS-specific #ifdef's in libssl. This also required moving the check on valid TLS versions into ktls_check_supported_cipher for Linux. This has largely removed OS-specific code and OS-specific #ifdef's for KTLS outside of . Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/12111) --- diff --git a/include/internal/ktls.h b/include/internal/ktls.h index a9b1c741908..e73cb313275 100644 --- a/include/internal/ktls.h +++ b/include/internal/ktls.h @@ -32,10 +32,15 @@ # include # include +# define OPENSSL_NO_KTLS_RX +# define OPENSSL_KTLS_AES_GCM_128 +# define OPENSSL_KTLS_AES_GCM_256 + /* * Only used by the tests in sslapitest.c. */ # define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE 8 +# define TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE 8 typedef struct tls_enable ktls_crypto_info_t; @@ -121,6 +126,100 @@ static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, } return sbytes; } + +# ifdef OSSL_SSL_LOCAL_H +/*- + * Check if a given cipher is supported by the KTLS interface. + * The kernel might still fail the setsockopt() if no suitable + * provider is found, but this checks if the socket option + * supports the cipher suite used at all. + */ +static ossl_inline int ktls_check_supported_cipher(const SSL *s, + const EVP_CIPHER *c, + const EVP_CIPHER_CTX *dd) +{ + + switch (s->version) { + case TLS1_VERSION: + case TLS1_1_VERSION: + case TLS1_2_VERSION: + break; + default: + return 0; + } + + switch (s->s3.tmp.new_cipher->algorithm_enc) { + case SSL_AES128GCM: + case SSL_AES256GCM: + return 1; + case SSL_AES128: + case SSL_AES256: + if (s->ext.use_etm) + return 0; + switch (s->s3.tmp.new_cipher->algorithm_mac) { + case SSL_SHA1: + case SSL_SHA256: + case SSL_SHA384: + return 1; + default: + return 0; + } + default: + return 0; + } +} + +/* Function to configure kernel TLS structure */ +static ossl_inline int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, + EVP_CIPHER_CTX *dd, + void *rl_sequence, + ktls_crypto_info_t *crypto_info, + unsigned char **rec_seq, + unsigned char *iv, + unsigned char *key, + unsigned char *mac_key, + size_t mac_secret_size) +{ + memset(crypto_info, 0, sizeof(*crypto_info)); + switch (s->s3.tmp.new_cipher->algorithm_enc) { + case SSL_AES128GCM: + case SSL_AES256GCM: + crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16; + crypto_info->iv_len = EVP_GCM_TLS_FIXED_IV_LEN; + break; + case SSL_AES128: + case SSL_AES256: + switch (s->s3.tmp.new_cipher->algorithm_mac) { + case SSL_SHA1: + crypto_info->auth_algorithm = CRYPTO_SHA1_HMAC; + break; + case SSL_SHA256: + crypto_info->auth_algorithm = CRYPTO_SHA2_256_HMAC; + break; + case SSL_SHA384: + crypto_info->auth_algorithm = CRYPTO_SHA2_384_HMAC; + break; + default: + return 0; + } + crypto_info->cipher_algorithm = CRYPTO_AES_CBC; + crypto_info->iv_len = EVP_CIPHER_iv_length(c); + crypto_info->auth_key = mac_key; + crypto_info->auth_key_len = mac_secret_size; + break; + default: + return 0; + } + crypto_info->cipher_key = key; + crypto_info->cipher_key_len = EVP_CIPHER_key_length(c); + crypto_info->iv = iv; + crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff; + crypto_info->tls_vminor = (s->version & 0x000000ff); + if (rec_seq != NULL) + *rec_seq = NULL; + return 1; +}; +# endif /* OSSL_SSL_LOCAL_H */ # endif /* __FreeBSD__ */ # if defined(OPENSSL_SYS_LINUX) @@ -315,10 +414,20 @@ static ossl_inline int ktls_read_record(int fd, void *data, size_t length) # endif /* OPENSSL_NO_KTLS_RX */ +# ifdef OSSL_SSL_LOCAL_H /* Function to check supported ciphers in Linux */ -static ossl_inline int ktls_check_supported_cipher(const EVP_CIPHER *c, - const EVP_CIPHER_CTX *dd) +static ossl_inline int ktls_check_supported_cipher(const SSL *s, + const EVP_CIPHER *c, + const EVP_CIPHER_CTX *dd) { + switch (s->version) { + case TLS1_2_VERSION: + case TLS1_3_VERSION: + break; + default: + return 0; + } + /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 */ switch (EVP_CIPHER_nid(c)) { @@ -340,16 +449,20 @@ static ossl_inline int ktls_check_supported_cipher(const EVP_CIPHER *c, } /* 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) +static ossl_inline int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, + EVP_CIPHER_CTX *dd, + void *rl_sequence, + ktls_crypto_info_t *crypto_info, + unsigned char **rec_seq, + unsigned char *iv, + unsigned char *key, + unsigned char *mac_key, + size_t mac_secret_size) { unsigned char geniv[12]; unsigned char *iiv = iv; - if (tls_version == TLS1_2_VERSION && + if (s->version == TLS1_2_VERSION && EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { if (!EVP_CIPHER_CTX_get_iv_state(dd, geniv, EVP_GCM_TLS_FIXED_IV_LEN @@ -364,7 +477,7 @@ static ossl_inline int ktls_configure_crypto(const EVP_CIPHER *c, int tls_versio # 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->gcm128.info.version = s->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); @@ -379,7 +492,7 @@ static ossl_inline int ktls_configure_crypto(const EVP_CIPHER *c, int tls_versio # 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->gcm256.info.version = s->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); @@ -394,7 +507,7 @@ static ossl_inline int ktls_configure_crypto(const EVP_CIPHER *c, int tls_versio # 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->ccm128.info.version = s->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); @@ -411,6 +524,7 @@ static ossl_inline int ktls_configure_crypto(const EVP_CIPHER *c, int tls_versio } } +# endif /* OSSL_SSL_LOCAL_H */ # endif /* OPENSSL_SYS_LINUX */ # endif /* HEADER_INTERNAL_KTLS */ diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 5ccf2e2a503..52b4ffe1323 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -193,13 +193,11 @@ int tls1_change_cipher_state(SSL *s, int which) int reuse_dd = 0; #ifndef OPENSSL_NO_KTLS ktls_crypto_info_t crypto_info; -# ifndef __FreeBSD__ unsigned char *rec_seq; void *rl_sequence; -# ifndef OPENSSL_NO_KTLS_RX +# ifndef OPENSSL_NO_KTLS_RX int count_unprocessed; int bit; -# endif # endif BIO *bio; #endif @@ -463,53 +461,9 @@ int tls1_change_cipher_state(SSL *s, int which) if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) goto skip_ktls; -# ifdef __FreeBSD__ - memset(&crypto_info, 0, sizeof(crypto_info)); - switch (s->s3.tmp.new_cipher->algorithm_enc) { - case SSL_AES128GCM: - case SSL_AES256GCM: - crypto_info.cipher_algorithm = CRYPTO_AES_NIST_GCM_16; - crypto_info.iv_len = EVP_GCM_TLS_FIXED_IV_LEN; - break; - case SSL_AES128: - case SSL_AES256: - if (s->ext.use_etm) - goto skip_ktls; - switch (s->s3.tmp.new_cipher->algorithm_mac) { - case SSL_SHA1: - crypto_info.auth_algorithm = CRYPTO_SHA1_HMAC; - break; - case SSL_SHA256: - crypto_info.auth_algorithm = CRYPTO_SHA2_256_HMAC; - break; - case SSL_SHA384: - crypto_info.auth_algorithm = CRYPTO_SHA2_384_HMAC; - break; - default: - goto skip_ktls; - } - crypto_info.cipher_algorithm = CRYPTO_AES_CBC; - crypto_info.iv_len = EVP_CIPHER_iv_length(c); - crypto_info.auth_key = ms; - crypto_info.auth_key_len = *mac_secret_size; - break; - default: - goto skip_ktls; - } - crypto_info.cipher_key = key; - crypto_info.cipher_key_len = EVP_CIPHER_key_length(c); - crypto_info.iv = iv; - crypto_info.tls_vmajor = (s->version >> 8) & 0x000000ff; - crypto_info.tls_vminor = (s->version & 0x000000ff); -# else /* !defined(__FreeBSD__) */ /* check that cipher is supported */ - if (!ktls_check_supported_cipher(c, dd)) - goto skip_ktls; - - /* check version */ - if (s->version != TLS1_2_VERSION) + if (!ktls_check_supported_cipher(s, c, dd)) goto skip_ktls; -# endif if (which & SSL3_CC_WRITE) bio = s->wbio; @@ -536,18 +490,17 @@ int tls1_change_cipher_state(SSL *s, int which) goto err; } -# ifndef __FreeBSD__ if (which & SSL3_CC_WRITE) rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer); else 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)) + if (!ktls_configure_crypto(s, c, dd, rl_sequence, &crypto_info, &rec_seq, + iv, key, ms, *mac_secret_size)) goto skip_ktls; if (which & SSL3_CC_READ) { -# ifndef OPENSSL_NO_KTLS_RX +# ifndef OPENSSL_NO_KTLS_RX count_unprocessed = count_unprocessed_records(s); if (count_unprocessed < 0) goto skip_ktls; @@ -561,11 +514,10 @@ int tls1_change_cipher_state(SSL *s, int which) } count_unprocessed--; } -# else +# 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 75034f5179f..714ffbff41d 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -798,7 +798,7 @@ int tls13_change_cipher_state(SSL *s, int which) goto skip_ktls; /* check that cipher is supported */ - if (!ktls_check_supported_cipher(cipher, ciph_ctx)) + if (!ktls_check_supported_cipher(s, cipher, ciph_ctx)) goto skip_ktls; bio = s->wbio; @@ -814,9 +814,9 @@ int tls13_change_cipher_state(SSL *s, int which) goto skip_ktls; /* configure kernel crypto structure */ - if (!ktls_configure_crypto(cipher, s->version, ciph_ctx, + if (!ktls_configure_crypto(s, cipher, ciph_ctx, RECORD_LAYER_get_write_sequence(&s->rlayer), - &crypto_info, NULL, iv, key)) + &crypto_info, NULL, iv, key, NULL, 0)) goto skip_ktls; /* ktls works with user provided buffers directly */