]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Introduce key usage limits under TLS1.3
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 20 Nov 2017 15:01:29 +0000 (16:01 +0100)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 19 Feb 2018 14:29:36 +0000 (15:29 +0100)
That introduces a transparent key update for sending key after
the safety limit is reached.

Resolves #130

Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
lib/algorithms/ciphers.c
lib/gnutls_int.h
lib/includes/gnutls/gnutls.h.in
lib/record.c

index 8c73c4cac3a3df4ac659b28ff9f14ade8f375d6f..34f94ea7d7a9b7813c21ebf6d3e6ec9b86ae7a77 100644 (file)
@@ -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",
index daee408e83ec47951e050c768cfe492e95eb2776..d3862d5a4f287bcf897661b56d756254b8492eb3 100644 (file)
@@ -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 {
index 785ed63543e1e26e703b70514a3e961e0940fa76..ddb056fe76166e401abd3b97a0ed73b7829be200 100644 (file)
@@ -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
index 3f2d54386819748b101554c8f29bbe22e343e37b..cee139d80c4869361b70057852c9b2b98d824075 100644 (file)
@@ -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;
 }