summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-11-20 16:01:29 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-12-04 13:04:47 +0100
commit7b84ba9d8d04ba1d240f0549259d3657803d0065 (patch)
treee4dd375be75c0b93abae3eac1c1b0e2dcddac7b7
parent9a4bcae5b8747b73429b62cba250559320c549b7 (diff)
downloadgnutls-7b84ba9d8d04ba1d240f0549259d3657803d0065.tar.gz
Introduce key usage limits under TLS1.3
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>
-rw-r--r--lib/algorithms/ciphers.c2
-rw-r--r--lib/gnutls_int.h1
-rw-r--r--lib/includes/gnutls/gnutls.h.in5
-rw-r--r--lib/record.c11
4 files changed, 18 insertions, 1 deletions
diff --git a/lib/algorithms/ciphers.c b/lib/algorithms/ciphers.c
index 5f04eba72e..69c2613965 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 c334eaeae5..af3b57ee4b 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;
}