Blob Blame History Raw
From 4380f347b2fff4af10537930400b68df61bee442 Mon Sep 17 00:00:00 2001
From: Frantisek Krenzelok <krenzelok.frantisek@gmail.com>
Date: Thu, 1 Dec 2022 15:37:33 +0100
Subject: [PATCH 1/2] KTLS: add ciphersuites

* TLS_AES_128_CCM_SHA256
* TLS_CHACHA20_POLY1305_SHA256

Signed-off-by: Frantisek Krenzelok <krenzelok.frantisek@gmail.com>
---
 lib/system/ktls.c | 159 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 153 insertions(+), 6 deletions(-)

diff --git a/lib/system/ktls.c b/lib/system/ktls.c
index 703775960..792d09ccf 100644
--- a/lib/system/ktls.c
+++ b/lib/system/ktls.c
@@ -86,7 +86,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable
 	gnutls_datum_t mac_key;
 	gnutls_datum_t iv;
 	gnutls_datum_t cipher_key;
-	unsigned char seq_number[8];
+	unsigned char seq_number[12];
 	int sockin, sockout;
 	int ret;
 
@@ -97,7 +97,9 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable
 	int version = gnutls_protocol_get_version(session);
 	if ((version != GNUTLS_TLS1_3 && version != GNUTLS_TLS1_2) ||
 		(gnutls_cipher_get(session) != GNUTLS_CIPHER_AES_128_GCM &&
-		gnutls_cipher_get(session) != GNUTLS_CIPHER_AES_256_GCM)) {
+		gnutls_cipher_get(session) != GNUTLS_CIPHER_AES_256_GCM &&
+		gnutls_cipher_get(session) != GNUTLS_CIPHER_AES_128_CCM &&
+		gnutls_cipher_get(session) != GNUTLS_CIPHER_CHACHA20_POLY1305)) {
 		return  GNUTLS_E_UNIMPLEMENTED_FEATURE;
 	}
 
@@ -114,7 +116,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable
 			case GNUTLS_CIPHER_AES_128_GCM:
 			{
 				struct tls12_crypto_info_aes_gcm_128 crypto_info;
-				memset(&crypto_info, 0, sizeof(crypto_info));
+				memset(&crypto_info, 0, sizeof (crypto_info));
 
 				crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128;
 				assert(cipher_key.size == TLS_CIPHER_AES_GCM_128_KEY_SIZE);
@@ -150,7 +152,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable
 			case GNUTLS_CIPHER_AES_256_GCM:
 			{
 				struct tls12_crypto_info_aes_gcm_256 crypto_info;
-				memset(&crypto_info, 0, sizeof(crypto_info));
+				memset(&crypto_info, 0, sizeof (crypto_info));
 
 				crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_256;
 				assert (cipher_key.size == TLS_CIPHER_AES_GCM_256_KEY_SIZE);
@@ -182,9 +184,83 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable
 				}
 			}
 			break;
+			case GNUTLS_CIPHER_AES_128_CCM:
+			{
+				struct tls12_crypto_info_aes_ccm_128 crypto_info;
+				memset(&crypto_info, 0, sizeof (crypto_info));
+
+				crypto_info.info.cipher_type = TLS_CIPHER_AES_CCM_128;
+				assert(cipher_key.size == TLS_CIPHER_AES_CCM_128_KEY_SIZE);
+
+				/* for TLS 1.2 IV is generated in kernel */
+				if (version == GNUTLS_TLS1_2) {
+					crypto_info.info.version = TLS_1_2_VERSION;
+					memcpy(crypto_info.iv, seq_number, TLS_CIPHER_AES_CCM_128_IV_SIZE);
+				} else {
+					crypto_info.info.version = TLS_1_3_VERSION;
+					assert(iv.size == TLS_CIPHER_AES_CCM_128_SALT_SIZE
+							+ TLS_CIPHER_AES_CCM_128_IV_SIZE);
+
+					memcpy(crypto_info.iv, iv.data +
+						TLS_CIPHER_AES_CCM_128_SALT_SIZE,
+						TLS_CIPHER_AES_CCM_128_IV_SIZE);
+				}
+
+				memcpy(crypto_info.salt, iv.data,
+				TLS_CIPHER_AES_CCM_128_SALT_SIZE);
+				memcpy(crypto_info.rec_seq, seq_number,
+				TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
+				memcpy(crypto_info.key, cipher_key.data,
+				TLS_CIPHER_AES_CCM_128_KEY_SIZE);
+
+				if (setsockopt (sockin, SOL_TLS, TLS_RX,
+						&crypto_info, sizeof (crypto_info))) {
+					session->internals.ktls_enabled &= ~GNUTLS_KTLS_RECV;
+					return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+				}
+			}
+			break;
+			case GNUTLS_CIPHER_CHACHA20_POLY1305:
+			{
+				struct tls12_crypto_info_chacha20_poly1305 crypto_info;
+				memset(&crypto_info, 0, sizeof (crypto_info));
+
+				crypto_info.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305;
+				assert(cipher_key.size == TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE);
+
+				/* for TLS 1.2 IV is generated in kernel */
+				if (version == GNUTLS_TLS1_2) {
+					crypto_info.info.version = TLS_1_2_VERSION;
+					memcpy(crypto_info.iv, seq_number, TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
+				} else {
+					crypto_info.info.version = TLS_1_3_VERSION;
+					assert(iv.size == TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE
+							+ TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
+
+					memcpy(crypto_info.iv, iv.data +
+						TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE,
+						TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
+				}
+
+				memcpy(crypto_info.salt, iv.data,
+				TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE);
+				memcpy(crypto_info.rec_seq, seq_number,
+				TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
+				memcpy(crypto_info.key, cipher_key.data,
+				TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE);
+
+				if (setsockopt (sockin, SOL_TLS, TLS_RX,
+						&crypto_info, sizeof (crypto_info))) {
+					session->internals.ktls_enabled &= ~GNUTLS_KTLS_RECV;
+					return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+				}
+			}
+			break;
 			default:
 				assert(0);
 		}
+
+
 	}
 
 	ret = gnutls_record_get_state (session, 0, &mac_key, &iv, &cipher_key,
@@ -198,7 +274,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable
 			case GNUTLS_CIPHER_AES_128_GCM:
 			{
 				struct tls12_crypto_info_aes_gcm_128 crypto_info;
-				memset(&crypto_info, 0, sizeof(crypto_info));
+				memset(&crypto_info, 0, sizeof (crypto_info));
 
 				crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128;
 
@@ -234,7 +310,7 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable
 			case GNUTLS_CIPHER_AES_256_GCM:
 			{
 				struct tls12_crypto_info_aes_gcm_256 crypto_info;
-				memset(&crypto_info, 0, sizeof(crypto_info));
+				memset(&crypto_info, 0, sizeof (crypto_info));
 
 				crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_256;
 				assert (cipher_key.size == TLS_CIPHER_AES_GCM_256_KEY_SIZE);
@@ -266,10 +342,81 @@ int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable
 				}
 			}
 			break;
+			case GNUTLS_CIPHER_AES_128_CCM:
+			{
+				struct tls12_crypto_info_aes_ccm_128 crypto_info;
+				memset(&crypto_info, 0, sizeof (crypto_info));
+
+				crypto_info.info.cipher_type = TLS_CIPHER_AES_CCM_128;
+				assert (cipher_key.size == TLS_CIPHER_AES_CCM_128_KEY_SIZE);
+
+				/* for TLS 1.2 IV is generated in kernel */
+				if (version == GNUTLS_TLS1_2) {
+					crypto_info.info.version = TLS_1_2_VERSION;
+					memcpy(crypto_info.iv, seq_number, TLS_CIPHER_AES_CCM_128_IV_SIZE);
+				} else {
+					crypto_info.info.version = TLS_1_3_VERSION;
+					assert (iv.size == TLS_CIPHER_AES_CCM_128_SALT_SIZE +
+							TLS_CIPHER_AES_CCM_128_IV_SIZE);
+
+					memcpy (crypto_info.iv, iv.data + TLS_CIPHER_AES_CCM_128_SALT_SIZE,
+					TLS_CIPHER_AES_CCM_128_IV_SIZE);
+				}
+
+				memcpy (crypto_info.salt, iv.data,
+				TLS_CIPHER_AES_CCM_128_SALT_SIZE);
+				memcpy (crypto_info.rec_seq, seq_number,
+				TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
+				memcpy (crypto_info.key, cipher_key.data,
+				TLS_CIPHER_AES_CCM_128_KEY_SIZE);
+
+				if (setsockopt (sockout, SOL_TLS, TLS_TX,
+						&crypto_info, sizeof (crypto_info))) {
+					session->internals.ktls_enabled &= ~GNUTLS_KTLS_SEND;
+					return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+				}
+			}
+			break;
+			case GNUTLS_CIPHER_CHACHA20_POLY1305:
+			{
+				struct tls12_crypto_info_chacha20_poly1305 crypto_info;
+				memset(&crypto_info, 0, sizeof (crypto_info));
+
+				crypto_info.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305;
+				assert (cipher_key.size == TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE);
+
+				/* for TLS 1.2 IV is generated in kernel */
+				if (version == GNUTLS_TLS1_2) {
+					crypto_info.info.version = TLS_1_2_VERSION;
+					memcpy(crypto_info.iv, seq_number, TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
+				} else {
+					crypto_info.info.version = TLS_1_3_VERSION;
+					assert (iv.size == TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE +
+							TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
+
+					memcpy (crypto_info.iv, iv.data + TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE,
+					TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
+				}
+
+				memcpy (crypto_info.salt, iv.data,
+				TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE);
+				memcpy (crypto_info.rec_seq, seq_number,
+				TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
+				memcpy (crypto_info.key, cipher_key.data,
+				TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE);
+
+				if (setsockopt (sockout, SOL_TLS, TLS_TX,
+						&crypto_info, sizeof (crypto_info))) {
+					session->internals.ktls_enabled &= ~GNUTLS_KTLS_SEND;
+					return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+				}
+			}
+			break;
 			default:
 				assert(0);
 		}
 
+
 		// set callback for sending handshake messages
 		gnutls_handshake_set_read_function(session,
 						   _gnutls_ktls_send_handshake_msg);
-- 
2.38.1


From 24bd0559302f8a7adf9f072f61f2aa03efa664f6 Mon Sep 17 00:00:00 2001
From: Frantisek Krenzelok <krenzelok.frantisek@gmail.com>
Date: Fri, 2 Dec 2022 11:07:48 +0100
Subject: [PATCH 2/2] KTLS: add ciphersuites (tests)

Signed-off-by: Frantisek Krenzelok <krenzelok.frantisek@gmail.com>
---
 tests/gnutls_ktls.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tests/gnutls_ktls.c b/tests/gnutls_ktls.c
index 8f9c5fa36..919270778 100644
--- a/tests/gnutls_ktls.c
+++ b/tests/gnutls_ktls.c
@@ -350,8 +350,12 @@ void doit(void)
 {
 	run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-128-GCM");
 	run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-256-GCM");
+	run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+AES-128-CCM");
+	run("NORMAL:-VERS-ALL:+VERS-TLS1.2:-CIPHER-ALL:+CHACHA20-POLY1305");
 	run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM");
 	run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-256-GCM");
+	run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-CCM");
+	run("NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+CHACHA20-POLY1305");
 }
 
 #endif				/* _WIN32 */
-- 
2.38.1