gnutls/gnutls-3.7.8-ktls_add_ciphersuites.patch
Frantisek Krenzelok c1f8e66db2
KTLS additional ciphersuites
Key update supported for patched kernels [1]

Configuration option `ktls = false` [2]

following ciphersuites are now supported: [3]
* TLS_AES_128_CCM_SHA256
* TLS_CHACHA20_POLY1305_SHA256

Ivalidate session on KTLS error as there is no way to recover and new
sockets as well as session have to be created. [4]

[1] https://gitlab.com/gnutls/gnutls/-/merge_requests/1625
[2] https://gitlab.com/gnutls/gnutls/-/merge_requests/1673/diffs?commit_id=aefd7319c0b7b2410d06238246b7755b289e4837
[3] https://gitlab.com/gnutls/gnutls/-/merge_requests/1676
[4] https://gitlab.com/gnutls/gnutls/-/merge_requests/1664

Signed-off-by: Frantisek Krenzelok <krenzelok.frantisek@gmail.com>
2023-01-20 19:17:15 +01:00

274 lines
9.8 KiB
Diff

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