summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrantisek Krenzelok <krenzelok.frantisek@gmail.com>2023-01-11 23:51:36 +0100
committerFrantisek Krenzelok <krenzelok.frantisek@gmail.com>2023-02-20 16:58:09 +0100
commitc990a8631ee822305be3b0fdb83e915f82269782 (patch)
treee3443703b6fbd161e5b5fce82dd6174d51385c0a
parentbac6e555630763e631f9cd45528f46a23fe4377e (diff)
downloadgnutls-c990a8631ee822305be3b0fdb83e915f82269782.tar.gz
WIP:DTLS1_3: Enecryption Implementation
-rw-r--r--lib/cipher.c28
-rw-r--r--lib/constate.c1
-rw-r--r--lib/dtls.c26
-rw-r--r--lib/gnutls_int.h9
-rw-r--r--lib/record.c33
5 files changed, 59 insertions, 38 deletions
diff --git a/lib/cipher.c b/lib/cipher.c
index 9f06c7ccf9..71ea578ee0 100644
--- a/lib/cipher.c
+++ b/lib/cipher.c
@@ -68,7 +68,7 @@ decrypt_packet_tls13(gnutls_session_t session,
static int
encrypt_packet_tls13(gnutls_session_t session,
- uint8_t *cipher_data, size_t cipher_size,
+ mbuffer_st *bufel,
gnutls_datum_t *plain,
size_t pad_size,
uint8_t type,
@@ -100,11 +100,8 @@ _gnutls_encrypt(gnutls_session_t session,
/* it fills the header, as it is included in the authenticated
* data of the AEAD cipher. */
ret =
- encrypt_packet_tls13(session,
- _mbuffer_get_udata_ptr(bufel),
- _mbuffer_get_udata_size(bufel),
- &plaintext, min_pad, type,
- params);
+ encrypt_packet_tls13(session, bufel, &plaintext,
+ min_pad, type, params);
if (ret < 0)
return gnutls_assert_val(ret);
} else {
@@ -432,13 +429,15 @@ encrypt_packet(gnutls_session_t session,
static int
encrypt_packet_tls13(gnutls_session_t session,
- uint8_t *cipher_data, size_t cipher_size,
+ mbuffer_st *bufel,
gnutls_datum_t *plain,
size_t pad_size,
uint8_t type,
record_parameters_st *params)
{
int ret;
+ uint8_t *cipher_data = _mbuffer_get_udata_ptr(bufel);
+ size_t cipher_size = _mbuffer_get_udata_size(bufel);
unsigned int tag_size = params->write.aead_tag_size;
const version_entry_st *ver = get_version(session);
uint8_t nonce[MAX_CIPHER_IV_SIZE];
@@ -488,10 +487,17 @@ encrypt_packet_tls13(gnutls_session_t session,
}
/* create authenticated data header */
- aad[0] = GNUTLS_APPLICATION_DATA;
- aad[1] = 0x03;
- aad[2] = 0x03;
- _gnutls_write_uint16(total+tag_size, &aad[3]);
+ if (session->internals.transport == GNUTLS_STREAM) {
+ aad[0] = GNUTLS_APPLICATION_DATA;
+ aad[1] = 0x03;
+ aad[2] = 0x03;
+ _gnutls_write_uint16(total+tag_size, &aad[3]);
+ } else {
+ /* DTLS1.3 uses header as as (AE)AD */
+ uint8_t *header = _mbuffer_get_uhead_ptr(bufel);
+ _gnutls_write_uint16(total+tag_size, &header[3]); // Set length
+ memcpy(aad, header, 5);
+ }
auth_iov[0].iov_base = aad;
auth_iov[0].iov_len = sizeof(aad);
diff --git a/lib/constate.c b/lib/constate.c
index 0abe561507..998b590af6 100644
--- a/lib/constate.c
+++ b/lib/constate.c
@@ -1338,6 +1338,7 @@ _tls13_init_record_state(gnutls_cipher_algorithm_t algo, record_state_st *state)
state->aead_tag_size = gnutls_cipher_get_tag_size(algo);
state->is_aead = 1;
+ state->sequence_number = 0;
return 0;
}
diff --git a/lib/dtls.c b/lib/dtls.c
index 002c7145ef..f5b4a0a4c9 100644
--- a/lib/dtls.c
+++ b/lib/dtls.c
@@ -586,7 +586,10 @@ size_t gnutls_est_record_overhead_size(gnutls_protocol_t version,
if (v->transport == GNUTLS_STREAM)
total = TLS_RECORD_HEADER_SIZE;
else
- total = DTLS_RECORD_HEADER_SIZE;
+ if (cipher == GNUTLS_CIPHER_NULL)
+ total = DTLS_RECORD_HEADER_SIZE;
+ else
+ total = DTLS13_RECORD_HEADER_SIZE;
total += _gnutls_record_overhead(v, c, m, 1);
@@ -629,14 +632,8 @@ static int record_overhead_rt(gnutls_session_t session)
**/
size_t gnutls_record_overhead_size(gnutls_session_t session)
{
- const version_entry_st *v = get_version(session);
int ret;
- size_t total;
-
- if (v->transport == GNUTLS_STREAM)
- total = TLS_RECORD_HEADER_SIZE;
- else
- total = DTLS_RECORD_HEADER_SIZE;
+ size_t total = RECORD_HEADER_SIZE(session);
ret = record_overhead_rt(session);
if (ret >= 0)
@@ -667,13 +664,20 @@ unsigned int gnutls_dtls_get_data_mtu(gnutls_session_t session)
mtu -= RECORD_HEADER_SIZE(session);
- if (session->internals.initial_negotiation_completed == 0)
- return mtu;
-
ret = _gnutls_epoch_get(session, EPOCH_WRITE_CURRENT, &params);
if (ret < 0)
return mtu;
+ if (session->internals.initial_negotiation_completed == 0){
+ if (session->security_parameters.pversion->tls13_sem)
+ return (mtu - params->write.aead_tag_size - 1); //Tag + content_type
+ return mtu;
+ }
+
+ if (session->security_parameters.pversion->tls13_sem &&
+ params->cipher->id != GNUTLS_CIPHER_NULL)
+ mtu -= params->write.aead_tag_size + 1; //Tag + content_type
+
if (params->cipher->type == CIPHER_AEAD || params->cipher->type == CIPHER_STREAM)
return mtu-_gnutls_record_overhead(get_version(session), params->cipher, params->mac, 0);
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 0a2d21256a..aa7c9f7f1d 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -185,9 +185,12 @@ typedef enum record_send_state_t {
#define DEFAULT_MAX_RECORD_SIZE 16384
#define DEFAULT_MAX_EARLY_DATA_SIZE 16384
#define TLS_RECORD_HEADER_SIZE 5
-#define DTLS_RECORD_HEADER_SIZE (TLS_RECORD_HEADER_SIZE+8)
-#define RECORD_HEADER_SIZE(session) (IS_DTLS(session) ? DTLS_RECORD_HEADER_SIZE : TLS_RECORD_HEADER_SIZE)
-#define MAX_RECORD_HEADER_SIZE DTLS_RECORD_HEADER_SIZE
+#define DTLS13_RECORD_HEADER_SIZE 5 //Will be made dynamic
+#define DTLS_RECORD_HEADER_SIZE TLS_RECORD_HEADER_SIZE+8
+#define DTLS_RESOLVE_RECORD_HEADER_SIZE(session) (session->security_parameters.pversion->tls13_sem && session->security_parameters.epoch_write>1) ? DTLS13_RECORD_HEADER_SIZE : DTLS_RECORD_HEADER_SIZE
+
+#define RECORD_HEADER_SIZE(session) (IS_DTLS(session) ? DTLS_RESOLVE_RECORD_HEADER_SIZE(session) : TLS_RECORD_HEADER_SIZE)
+#define MAX_RECORD_HEADER_SIZE TLS_RECORD_HEADER_SIZE+8
#define MIN_RECORD_SIZE 512
#define MIN_RECORD_SIZE_SMALL 64
diff --git a/lib/record.c b/lib/record.c
index 6b9ed8c9e3..5a733d5915 100644
--- a/lib/record.c
+++ b/lib/record.c
@@ -538,20 +538,27 @@ _gnutls_send_tlen_int(gnutls_session_t session, content_type_t type,
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
headers = _mbuffer_get_uhead_ptr(bufel);
- if (vers->tls13_sem && record_params->cipher->id != GNUTLS_CIPHER_NULL)
- headers[0] = GNUTLS_APPLICATION_DATA;
- else
- headers[0] = type;
-
- /* Use the default record version, if it is
- * set. */
- ret = copy_record_version(session, htype, &headers[1]);
- if (ret < 0)
- return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ if (vers->id == GNUTLS_DTLS1_3 && record_params->cipher->id != GNUTLS_CIPHER_NULL) {
+ /* Currently constant will change for dynamic length and CID */
+ headers[0] = 0x2c | (record_params->epoch & 0x0003);
+ _gnutls_write_uint16(record_state->sequence_number, &headers[1]);
+ //size is determined in encrypt_packet_tls13()
+ } else {
+ if (vers->tls13_sem && record_params->cipher->id != GNUTLS_CIPHER_NULL)
+ headers[0] = GNUTLS_APPLICATION_DATA;
+ else
+ headers[0] = type;
+
+ /* Use the default record version, if it is
+ * set. */
+ ret = copy_record_version(session, htype, &headers[1]);
+ if (ret < 0)
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
- /* Adjust header length and add sequence for DTLS */
- if (IS_DTLS(session))
- _gnutls_write_uint64(record_state->sequence_number, &headers[3]);
+ /* Adjust header length and add sequence for DTLS */
+ if (IS_DTLS(session))
+ _gnutls_write_uint64(record_state->sequence_number, &headers[3]);
+ }
_gnutls_record_log
("REC[%p]: Preparing Packet %s(%d) with length: %d and min pad: %d\n",