diff options
author | Frantisek Krenzelok <krenzelok.frantisek@gmail.com> | 2023-01-11 23:51:36 +0100 |
---|---|---|
committer | Frantisek Krenzelok <krenzelok.frantisek@gmail.com> | 2023-02-20 16:58:09 +0100 |
commit | c990a8631ee822305be3b0fdb83e915f82269782 (patch) | |
tree | e3443703b6fbd161e5b5fce82dd6174d51385c0a | |
parent | bac6e555630763e631f9cd45528f46a23fe4377e (diff) | |
download | gnutls-c990a8631ee822305be3b0fdb83e915f82269782.tar.gz |
WIP:DTLS1_3: Enecryption Implementation
-rw-r--r-- | lib/cipher.c | 28 | ||||
-rw-r--r-- | lib/constate.c | 1 | ||||
-rw-r--r-- | lib/dtls.c | 26 | ||||
-rw-r--r-- | lib/gnutls_int.h | 9 | ||||
-rw-r--r-- | lib/record.c | 33 |
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, ¶ms); 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", |