From 95badfeb60603b1bbcfc4d0fef555aed06038d55 Mon Sep 17 00:00:00 2001 From: Vadim Fedorenko Date: Fri, 1 May 2020 23:56:48 +0300 Subject: [PATCH] kTLS: add Linux-specific kTLS helpers Reviewed-by: Paul Dale Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/11589) --- include/internal/ktls.h | 97 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/include/internal/ktls.h b/include/internal/ktls.h index 4a640b769a..093a661843 100644 --- a/include/internal/ktls.h +++ b/include/internal/ktls.h @@ -309,6 +309,103 @@ static ossl_inline int ktls_read_record(int fd, void *data, size_t length) } # 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 +# 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) */ -- 2.25.1