diff options
-rw-r--r-- | lib/algorithms/ciphers.c | 2 | ||||
-rw-r--r-- | lib/gnutls_int.h | 1 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 5 | ||||
-rw-r--r-- | lib/record.c | 11 |
4 files changed, 18 insertions, 1 deletions
diff --git a/lib/algorithms/ciphers.c b/lib/algorithms/ciphers.c index 8c73c4cac3..34f94ea7d7 100644 --- a/lib/algorithms/ciphers.c +++ b/lib/algorithms/ciphers.c @@ -165,6 +165,8 @@ static const cipher_entry_st algorithms[] = { .explicit_iv = 0, .xor_nonce = 1, .cipher_iv = 12, + /* in chacha20 we don't need a rekey after 2^24 messages */ + .no_rekey = 1, .tagsize = 16 }, { .name = "CAMELLIA-128-GCM", diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index daee408e83..d3862d5a4f 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -514,6 +514,7 @@ typedef struct cipher_entry_st { uint16_t tagsize; bool xor_nonce; /* In this TLS AEAD cipher xor the implicit_iv with the nonce */ bool only_aead; /* When set, this cipher is only available through the new AEAD API */ + bool no_rekey; /* whether this tls1.3 cipher doesn't need to rekey after 2^24 messages */ } cipher_entry_st; typedef struct gnutls_cipher_suite_entry_st { diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 785ed63543..ddb056fe76 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -370,6 +370,8 @@ typedef enum { * For example x25519. This option is the most performant for client (less CPU spent * generating keys), but if the server doesn't support the advertized option it may * result to more roundtrips needed to discover the server's choice. + * @GNUTLS_NO_AUTO_REKEY: Disable auto-rekeying under TLS1.3. If this option is not specified + * gnutls will force a rekey after 2^24 records have been sent. * * Enumeration of different flags for gnutls_init() function. All the flags * can be combined except @GNUTLS_SERVER and @GNUTLS_CLIENT which are mutually @@ -393,7 +395,8 @@ typedef enum { GNUTLS_NO_TICKETS = (1<<10), GNUTLS_KEY_SHARE_TOP = (1<<11), GNUTLS_KEY_SHARE_TOP2 = (1<<12), - GNUTLS_KEY_SHARE_TOP3 = (1<<13) + GNUTLS_KEY_SHARE_TOP3 = (1<<13), + GNUTLS_NO_AUTO_REKEY = (1<<15) } gnutls_init_flags_t; /* compatibility defines (previous versions of gnutls diff --git a/lib/record.c b/lib/record.c index 3f2d543868..cee139d80c 100644 --- a/lib/record.c +++ b/lib/record.c @@ -581,6 +581,17 @@ _gnutls_send_tlen_int(gnutls_session_t session, content_type_t type, _gnutls_packet2str(type), type, (int) record_params->epoch, (int) cipher_size); + if (vers->tls13_sem && !(session->internals.flags & GNUTLS_NO_AUTO_REKEY) && + !(record_params->cipher->no_rekey)) { + if (unlikely(record_state->sequence_number.i[7] == 0xfd && + record_state->sequence_number.i[6] == 0xff && + record_state->sequence_number.i[5] == 0xff)) { + /* After we have sent 2^24 messages, mark the session + * as needing a key update. */ + session->internals.rsend_state = RECORD_SEND_KEY_UPDATE_1; + } + } + return retval; } |