Compare commits
1 commit
rawhide
...
ktls-addit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4df37453e |
2 changed files with 621 additions and 0 deletions
620
gnutls-3.7.8-ktls-updates.patch
Normal file
620
gnutls-3.7.8-ktls-updates.patch
Normal file
|
|
@ -0,0 +1,620 @@
|
|||
diff -rpu a/lib/alert.c a/lib/alert.c
|
||||
--- a/lib/alert.c 2022-12-09 14:58:19.713666537 +0100
|
||||
+++ a/lib/alert.c 2022-12-09 15:26:30.976250789 +0100
|
||||
@@ -182,15 +182,10 @@ gnutls_alert_send(gnutls_session_t sessi
|
||||
return ret;
|
||||
}
|
||||
|
||||
- if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND)) {
|
||||
- ret =
|
||||
- _gnutls_ktls_send_control_msg(session, GNUTLS_ALERT, data, 2);
|
||||
- } else {
|
||||
- ret =
|
||||
- _gnutls_send_int(session, GNUTLS_ALERT, -1,
|
||||
- EPOCH_WRITE_CURRENT, data, 2,
|
||||
- MBUFFER_FLUSH);
|
||||
- }
|
||||
+ ret = _gnutls_send_int(session, GNUTLS_ALERT, -1,
|
||||
+ EPOCH_WRITE_CURRENT, data, 2,
|
||||
+ MBUFFER_FLUSH);
|
||||
+
|
||||
return (ret < 0) ? ret : 0;
|
||||
}
|
||||
|
||||
diff -rpu a/lib/handshake.c a/lib/handshake.c
|
||||
--- a/lib/handshake.c 2022-12-09 14:58:19.712666534 +0100
|
||||
+++ a/lib/handshake.c 2022-12-09 15:31:51.768496850 +0100
|
||||
@@ -2924,7 +2924,13 @@ int gnutls_handshake(gnutls_session_t se
|
||||
|
||||
#ifdef ENABLE_KTLS
|
||||
if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_DUPLEX)) {
|
||||
- _gnutls_ktls_set_keys(session);
|
||||
+ ret = _gnutls_ktls_set_keys(session, GNUTLS_KTLS_DUPLEX);
|
||||
+ if (ret < 0) {
|
||||
+ /* no need to invalidate the session as keys were not set */
|
||||
+ session->internals.ktls_enabled = 0;
|
||||
+ _gnutls_audit_log(session,
|
||||
+ "disabling KTLS: failed to set keys\n");
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
|
||||
diff -rpu a/lib/includes/gnutls/gnutls.h.in a/lib/includes/gnutls/gnutls.h.in
|
||||
--- a/lib/includes/gnutls/gnutls.h.in 2022-12-09 14:58:19.706666511 +0100
|
||||
+++ a/lib/includes/gnutls/gnutls.h.in 2022-12-09 15:30:04.784082188 +0100
|
||||
@@ -3418,6 +3418,27 @@ int gnutls_fips140_pop_context(void);
|
||||
|
||||
int gnutls_fips140_run_self_tests(void);
|
||||
|
||||
+/**
|
||||
+ * gnutls_transport_ktls_enable_flags_t:
|
||||
+ * @GNUTLS_KTLS_RECV: ktls enabled for recv function.
|
||||
+ * @GNUTLS_KTLS_SEND: ktls enabled for send function.
|
||||
+ * @GNUTLS_KTLS_DUPLEX: ktls enabled for both recv and send functions.
|
||||
+ *
|
||||
+ * Flag enumeration of ktls enable status for recv and send functions.
|
||||
+ * This is used by gnutls_transport_is_ktls_enabled().
|
||||
+ *
|
||||
+ * Since: 3.7.3
|
||||
+ */
|
||||
+typedef enum {
|
||||
+ GNUTLS_KTLS_RECV = 1 << 0,
|
||||
+ GNUTLS_KTLS_SEND = 1 << 1,
|
||||
+ GNUTLS_KTLS_DUPLEX = GNUTLS_KTLS_RECV | GNUTLS_KTLS_SEND,
|
||||
+} gnutls_transport_ktls_enable_flags_t;
|
||||
+
|
||||
+
|
||||
+gnutls_transport_ktls_enable_flags_t
|
||||
+gnutls_transport_is_ktls_enabled(gnutls_session_t session);
|
||||
+
|
||||
/* Gnutls error codes. The mapping to a TLS alert is also shown in
|
||||
* comments.
|
||||
*/
|
||||
diff -rpu a/lib/includes/gnutls/socket.h a/lib/includes/gnutls/socket.h
|
||||
--- a/lib/includes/gnutls/socket.h 2022-12-09 14:58:19.706666511 +0100
|
||||
+++ a/lib/includes/gnutls/socket.h 2022-12-09 15:30:04.785082192 +0100
|
||||
@@ -37,27 +37,6 @@ extern "C" {
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
-/**
|
||||
- * gnutls_transport_ktls_enable_flags_t:
|
||||
- * @GNUTLS_KTLS_RECV: ktls enabled for recv function.
|
||||
- * @GNUTLS_KTLS_SEND: ktls enabled for send function.
|
||||
- * @GNUTLS_KTLS_DUPLEX: ktls enabled for both recv and send functions.
|
||||
- *
|
||||
- * Flag enumeration of ktls enable status for recv and send functions.
|
||||
- * This is used by gnutls_transport_is_ktls_enabled().
|
||||
- *
|
||||
- * Since: 3.7.3
|
||||
- */
|
||||
-typedef enum {
|
||||
- GNUTLS_KTLS_RECV = 1 << 0,
|
||||
- GNUTLS_KTLS_SEND = 1 << 1,
|
||||
- GNUTLS_KTLS_DUPLEX = GNUTLS_KTLS_RECV | GNUTLS_KTLS_SEND,
|
||||
-} gnutls_transport_ktls_enable_flags_t;
|
||||
-
|
||||
-
|
||||
-gnutls_transport_ktls_enable_flags_t
|
||||
-gnutls_transport_is_ktls_enabled(gnutls_session_t session);
|
||||
-
|
||||
void gnutls_transport_set_fastopen(gnutls_session_t session,
|
||||
int fd,
|
||||
struct sockaddr *connect_addr,
|
||||
diff -rpu a/lib/priority.c a/lib/priority.c
|
||||
--- a/lib/priority.c 2022-12-09 14:58:19.712666534 +0100
|
||||
+++ a/lib/priority.c 2022-12-09 15:30:04.787082200 +0100
|
||||
@@ -1541,6 +1541,8 @@ static int global_ini_handler(void *ctx,
|
||||
p = clear_spaces(value, str);
|
||||
if (c_strcasecmp(p, "true") == 0) {
|
||||
cfg->ktls_enabled = true;
|
||||
+ } else if (c_strcasecmp(p, "false") == 0) {
|
||||
+ cfg->ktls_enabled = false;
|
||||
} else {
|
||||
_gnutls_debug_log("cfg: unknown ktls mode %s\n",
|
||||
p);
|
||||
diff -rpu a/lib/record.c a/lib/record.c
|
||||
--- a/lib/record.c 2022-12-09 14:58:19.712666534 +0100
|
||||
+++ a/lib/record.c 2022-12-09 15:26:30.978250796 +0100
|
||||
@@ -2065,11 +2065,17 @@ gnutls_record_send2(gnutls_session_t ses
|
||||
session->internals.rsend_state = RECORD_SEND_KEY_UPDATE_3;
|
||||
FALLTHROUGH;
|
||||
case RECORD_SEND_KEY_UPDATE_3:
|
||||
- ret = _gnutls_send_int(session, GNUTLS_APPLICATION_DATA,
|
||||
- -1, EPOCH_WRITE_CURRENT,
|
||||
- session->internals.record_key_update_buffer.data,
|
||||
- session->internals.record_key_update_buffer.length,
|
||||
- MBUFFER_FLUSH);
|
||||
+ if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND)) {
|
||||
+ return _gnutls_ktls_send(session,
|
||||
+ session->internals.record_key_update_buffer.data,
|
||||
+ session->internals.record_key_update_buffer.length);
|
||||
+ } else {
|
||||
+ ret = _gnutls_send_int(session, GNUTLS_APPLICATION_DATA,
|
||||
+ -1, EPOCH_WRITE_CURRENT,
|
||||
+ session->internals.record_key_update_buffer.data,
|
||||
+ session->internals.record_key_update_buffer.length,
|
||||
+ MBUFFER_FLUSH);
|
||||
+ }
|
||||
_gnutls_buffer_clear(&session->internals.record_key_update_buffer);
|
||||
session->internals.rsend_state = RECORD_SEND_NORMAL;
|
||||
if (ret < 0)
|
||||
@@ -2494,8 +2500,11 @@ gnutls_handshake_write(gnutls_session_t
|
||||
return gnutls_assert_val(0);
|
||||
|
||||
/* When using this, the outgoing handshake messages should
|
||||
- * also be handled manually */
|
||||
- if (!session->internals.h_read_func)
|
||||
+ * also be handled manually unless KTLS is enabled exclusively
|
||||
+ * in GNUTLS_KTLS_RECV mode in which case the outgoing messages
|
||||
+ * are handled by GnuTLS.
|
||||
+ */
|
||||
+ if (!session->internals.h_read_func && !IS_KTLS_ENABLED(session, GNUTLS_KTLS_RECV))
|
||||
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
||||
|
||||
if (session->internals.initial_negotiation_completed) {
|
||||
diff -rpu a/lib/system/ktls.c a/lib/system/ktls.c
|
||||
--- a/lib/system/ktls.c 2022-12-09 14:58:19.710666526 +0100
|
||||
+++ a/lib/system/ktls.c 2022-12-09 15:31:31.358417745 +0100
|
||||
@@ -80,13 +80,13 @@ void _gnutls_ktls_enable(gnutls_session_
|
||||
}
|
||||
}
|
||||
|
||||
-int _gnutls_ktls_set_keys(gnutls_session_t session)
|
||||
+int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable_flags_t in)
|
||||
{
|
||||
gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(session);
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -107,12 +109,14 @@ int _gnutls_ktls_set_keys(gnutls_session
|
||||
return ret;
|
||||
}
|
||||
|
||||
- if(session->internals.ktls_enabled & GNUTLS_KTLS_RECV){
|
||||
+ in &= session->internals.ktls_enabled;
|
||||
+
|
||||
+ if(in & GNUTLS_KTLS_RECV){
|
||||
switch (cipher) {
|
||||
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);
|
||||
@@ -148,7 +152,7 @@ int _gnutls_ktls_set_keys(gnutls_session
|
||||
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);
|
||||
@@ -180,9 +184,83 @@ int _gnutls_ktls_set_keys(gnutls_session
|
||||
}
|
||||
}
|
||||
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,
|
||||
@@ -191,12 +269,12 @@ int _gnutls_ktls_set_keys(gnutls_session
|
||||
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
- if(session->internals.ktls_enabled & GNUTLS_KTLS_SEND){
|
||||
+ if(in & GNUTLS_KTLS_SEND){
|
||||
switch (cipher) {
|
||||
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;
|
||||
|
||||
@@ -232,7 +310,7 @@ int _gnutls_ktls_set_keys(gnutls_session
|
||||
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);
|
||||
@@ -264,12 +342,90 @@ int _gnutls_ktls_set_keys(gnutls_session
|
||||
}
|
||||
}
|
||||
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);
|
||||
+
|
||||
+ // set callback for sending alert messages
|
||||
+ gnutls_alert_set_read_function(session, _gnutls_ktls_send_alert_msg);
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ return in;
|
||||
}
|
||||
|
||||
ssize_t _gnutls_ktls_send_file(gnutls_session_t session, int fd,
|
||||
@@ -353,6 +509,26 @@ int _gnutls_ktls_send_control_msg(gnutls
|
||||
return data_size;
|
||||
}
|
||||
|
||||
+int _gnutls_ktls_send_handshake_msg(gnutls_session_t session,
|
||||
+ gnutls_record_encryption_level_t level,
|
||||
+ gnutls_handshake_description_t htype,
|
||||
+ const void *data, size_t data_size)
|
||||
+{
|
||||
+ return _gnutls_ktls_send_control_msg(session, GNUTLS_HANDSHAKE,
|
||||
+ data, data_size);
|
||||
+}
|
||||
+
|
||||
+int _gnutls_ktls_send_alert_msg(gnutls_session_t session,
|
||||
+ gnutls_record_encryption_level_t level,
|
||||
+ gnutls_alert_level_t alert_level,
|
||||
+ gnutls_alert_description_t alert_desc)
|
||||
+{
|
||||
+ uint8_t data[2];
|
||||
+ data[0] = (uint8_t) alert_level;
|
||||
+ data[1] = (uint8_t) alert_desc;
|
||||
+ return _gnutls_ktls_send_control_msg(session, GNUTLS_ALERT, data, 2);
|
||||
+}
|
||||
+
|
||||
int _gnutls_ktls_recv_control_msg(gnutls_session_t session,
|
||||
unsigned char *record_type, void *data, size_t data_size)
|
||||
{
|
||||
@@ -438,7 +614,13 @@ int _gnutls_ktls_recv_int(gnutls_session
|
||||
ret = 0;
|
||||
break;
|
||||
case GNUTLS_HANDSHAKE:
|
||||
- // ignore post-handshake messages
|
||||
+ ret = gnutls_handshake_write(session,
|
||||
+ GNUTLS_ENCRYPTION_LEVEL_APPLICATION,
|
||||
+ data, ret);
|
||||
+
|
||||
+ if (ret < 0)
|
||||
+ return gnutls_assert_val(ret);
|
||||
+
|
||||
if (type != record_type)
|
||||
return GNUTLS_E_AGAIN;
|
||||
break;
|
||||
@@ -465,7 +647,7 @@ gnutls_transport_is_ktls_enabled(gnutls_
|
||||
void _gnutls_ktls_enable(gnutls_session_t session) {
|
||||
}
|
||||
|
||||
-int _gnutls_ktls_set_keys(gnutls_session_t session) {
|
||||
+int _gnutls_ktls_set_keys(gnutls_session_t sessioni, gnutls_transport_ktls_enable_flags_t in) {
|
||||
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
|
||||
}
|
||||
|
||||
@@ -479,6 +661,15 @@ int _gnutls_ktls_send_control_msg(gnutls
|
||||
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
|
||||
}
|
||||
|
||||
+int _gnutls_ktls_send_handshake_msg(gnutls_session_t session,
|
||||
+ gnutls_record_encryption_level_t level,
|
||||
+ gnutls_handshake_description_t htype,
|
||||
+ const void *data, size_t data_size)
|
||||
+{
|
||||
+ (void)level;
|
||||
+ return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
|
||||
+}
|
||||
+
|
||||
int _gnutls_ktls_recv_int(gnutls_session_t session, content_type_t type,
|
||||
void *data, size_t data_size) {
|
||||
return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
|
||||
diff -rpu a/lib/system/ktls.h a/lib/system/ktls.h
|
||||
--- a/lib/system/ktls.h 2022-12-09 14:58:19.710666526 +0100
|
||||
+++ a/lib/system/ktls.h 2022-12-09 15:26:30.979250800 +0100
|
||||
@@ -4,14 +4,29 @@
|
||||
#include "gnutls_int.h"
|
||||
|
||||
void _gnutls_ktls_enable(gnutls_session_t session);
|
||||
-int _gnutls_ktls_set_keys(gnutls_session_t session);
|
||||
+
|
||||
+int _gnutls_ktls_set_keys(gnutls_session_t session, gnutls_transport_ktls_enable_flags_t in);
|
||||
+
|
||||
ssize_t _gnutls_ktls_send_file(gnutls_session_t session, int fd,
|
||||
off_t *offset, size_t count);
|
||||
+
|
||||
+int _gnutls_ktls_send_handshake_msg(gnutls_session_t session,
|
||||
+ gnutls_record_encryption_level_t level,
|
||||
+ gnutls_handshake_description_t htype,
|
||||
+ const void *data, size_t data_size);
|
||||
+
|
||||
+int _gnutls_ktls_send_alert_msg(gnutls_session_t session,
|
||||
+ gnutls_record_encryption_level_t level,
|
||||
+ gnutls_alert_level_t alert_level,
|
||||
+ gnutls_alert_description_t alert_desc);
|
||||
+
|
||||
int _gnutls_ktls_send_control_msg(gnutls_session_t session, unsigned char record_type,
|
||||
const void *data, size_t data_size);
|
||||
#define _gnutls_ktls_send(x, y, z) _gnutls_ktls_send_control_msg(x, GNUTLS_APPLICATION_DATA, y, z);
|
||||
+
|
||||
int _gnutls_ktls_recv_control_msg(gnutls_session_t session, unsigned char *record_type,
|
||||
void *data, size_t data_size);
|
||||
+
|
||||
int _gnutls_ktls_recv_int(gnutls_session_t session, content_type_t type, void *data, size_t data_size);
|
||||
#define _gnutls_ktls_recv(x, y, z) _gnutls_ktls_recv_int(x, GNUTLS_APPLICATION_DATA, y, z)
|
||||
|
||||
diff -rpu a/lib/tls13/key_update.c a/lib/tls13/key_update.c
|
||||
--- a/lib/tls13/key_update.c 2022-12-09 14:58:19.711666530 +0100
|
||||
+++ a/lib/tls13/key_update.c 2022-12-09 15:31:51.769496854 +0100
|
||||
@@ -27,10 +27,28 @@
|
||||
#include "mem.h"
|
||||
#include "mbuffers.h"
|
||||
#include "secrets.h"
|
||||
+#include "system/ktls.h"
|
||||
|
||||
#define KEY_UPDATES_WINDOW 1000
|
||||
#define KEY_UPDATES_PER_WINDOW 8
|
||||
|
||||
+/*
|
||||
+ * Sets kTLS keys if enabled.
|
||||
+ * If this operation fails with GNUTLS_E_INTERNAL_ERROR, KTLS is disabled
|
||||
+ * because KTLS most likely doesn't support key update.
|
||||
+ */
|
||||
+#define SET_KTLS_KEYS(session, interface)\
|
||||
+{\
|
||||
+if(_gnutls_ktls_set_keys(session, interface) < 0) {\
|
||||
+ session->internals.ktls_enabled = 0;\
|
||||
+ session->internals.invalid_connection = true;\
|
||||
+ session->internals.resumable = false;\
|
||||
+ _gnutls_audit_log(session,\
|
||||
+ "invalidating session: KTLS - couldn't update keys\n");\
|
||||
+ ret = GNUTLS_E_INTERNAL_ERROR;\
|
||||
+}\
|
||||
+}
|
||||
+
|
||||
static int update_keys(gnutls_session_t session, hs_stage_t stage)
|
||||
{
|
||||
int ret;
|
||||
@@ -49,8 +67,20 @@ static int update_keys(gnutls_session_t
|
||||
* write keys */
|
||||
if (session->internals.recv_state == RECV_STATE_EARLY_START) {
|
||||
ret = _tls13_write_connection_state_init(session, stage);
|
||||
+ if (ret < 0)
|
||||
+ return gnutls_assert_val(ret);
|
||||
+
|
||||
+ if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND))
|
||||
+ SET_KTLS_KEYS(session, GNUTLS_KTLS_SEND)
|
||||
} else {
|
||||
ret = _tls13_connection_state_init(session, stage);
|
||||
+ if (ret < 0)
|
||||
+ return gnutls_assert_val(ret);
|
||||
+
|
||||
+ if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_SEND) && stage == STAGE_UPD_OURS)
|
||||
+ SET_KTLS_KEYS(session, GNUTLS_KTLS_SEND)
|
||||
+ else if (IS_KTLS_ENABLED(session, GNUTLS_KTLS_RECV) && stage == STAGE_UPD_PEERS)
|
||||
+ SET_KTLS_KEYS(session, GNUTLS_KTLS_RECV)
|
||||
}
|
||||
if (ret < 0)
|
||||
return gnutls_assert_val(ret);
|
||||
diff -rpu a/src/common.c a/src/common.c
|
||||
--- a/src/common.c 2022-12-09 14:58:19.737666626 +0100
|
||||
+++ a/src/common.c 2022-12-09 15:30:04.788082204 +0100
|
||||
@@ -498,6 +498,7 @@ int print_info(gnutls_session_t session,
|
||||
gnutls_datum_t p;
|
||||
char *desc;
|
||||
gnutls_protocol_t version;
|
||||
+ gnutls_transport_ktls_enable_flags_t ktls_flags;
|
||||
int rc;
|
||||
|
||||
desc = gnutls_session_get_desc(session);
|
||||
@@ -646,6 +647,15 @@ int print_info(gnutls_session_t session,
|
||||
|
||||
print_channel_bindings(session, verbose);
|
||||
|
||||
+ ktls_flags = gnutls_transport_is_ktls_enabled(session);
|
||||
+ if (ktls_flags != 0) {
|
||||
+ log_msg(stdout, "- KTLS: %s\n",
|
||||
+ (ktls_flags & GNUTLS_KTLS_DUPLEX) == GNUTLS_KTLS_DUPLEX ? "send, recv" :
|
||||
+ (ktls_flags & GNUTLS_KTLS_SEND) == GNUTLS_KTLS_SEND ? "send" :
|
||||
+ (ktls_flags & GNUTLS_KTLS_RECV) == GNUTLS_KTLS_RECV ? "recv" :
|
||||
+ "unknown");
|
||||
+ }
|
||||
+
|
||||
fflush(stdout);
|
||||
|
||||
return 0;
|
||||
diff -rpu a/tests/gnutls_ktls.c a/tests/gnutls_ktls.c
|
||||
--- a/tests/gnutls_ktls.c 2022-12-09 14:58:19.751666678 +0100
|
||||
+++ a/tests/gnutls_ktls.c 2022-12-09 15:31:31.359417748 +0100
|
||||
@@ -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 */
|
||||
diff -rpu a/tests/Makefile.am a/tests/Makefile.am
|
||||
--- a/tests/Makefile.am 2022-12-09 14:58:19.748666667 +0100
|
||||
+++ a/tests/Makefile.am 2022-12-09 15:26:30.979250800 +0100
|
||||
@@ -500,6 +500,8 @@ endif
|
||||
if ENABLE_KTLS
|
||||
indirect_tests += gnutls_ktls
|
||||
dist_check_SCRIPTS += ktls.sh
|
||||
+indirect_tests += ktls_keyupdate
|
||||
+dist_check_SCRIPTS += ktls_keyupdate.sh
|
||||
endif
|
||||
|
||||
if !WINDOWS
|
||||
|
|
@ -19,6 +19,7 @@ print(string.sub(hash, 0, 16))
|
|||
|
||||
Version: 3.7.8
|
||||
Release: %{?autorelease}%{!?autorelease:1%{?dist}}
|
||||
Patch: gnutls-3.7.8-ktls-updates.patch
|
||||
Patch: gnutls-3.7.8-gcc_analyzer-suppress_warnings.patch
|
||||
Patch: gnutls-3.6.7-no-now-guile.patch
|
||||
Patch: gnutls-3.2.7-rpath.patch
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue